From 0d37f82c9ba51889f156eb239cef1edba59e8003 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 16 Jul 2012 10:50:53 +0000 Subject: Color management: support of configurable input color space This adds a user-defined input color space name for image and movie clip data blocks. Support for this thing for other data blocks is still a TODO. Input color space is being used on loading file to convert loaded image buffer from this space to scene linear space, later this space is never used in a pipeline. Color space name was wrapped into own structure like it's done for display and view settings. This helps keep code de-duplicated in RNA and it'll help when likely more options are added into input color space settings (i.e. flag whether image could be color managed or it's a non-color data). This implied quite of internal refactoring: - Made routines around threaded display buffer calculation more general, so any kind of color transform could be performed using the same technique. - Added function to convert given float buffer from given input color space to output color space. This is a public function which could be used in such a things as compositor node. - Added function to convert ImBuf's content to scene linear space. Currently used only for images and clips. Should be added to any image/movie-related data blocks such as sequencer strips, but that a bit more long-term plan. - If input color space is set to NONE then no buffer transform would be performed on image loading. It'll behave in the same way as using scene linear as input space. --- source/blender/blenkernel/intern/image.c | 4 ++++ source/blender/blenkernel/intern/movieclip.c | 6 ++++++ 2 files changed, 10 insertions(+) (limited to 'source/blender/blenkernel/intern') diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index dfb12503c45..fe364bbf439 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -47,6 +47,7 @@ #include "MEM_guardedalloc.h" +#include "IMB_colormanagement.h" #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" @@ -2189,6 +2190,9 @@ static void image_create_multilayer(Image *ima, ImBuf *ibuf, int framenr) /* common stuff to do with images after loading */ static void image_initialize_after_load(Image *ima, ImBuf *ibuf) { + /* make float buffer stored in ImBuf scene linear space */ + IMB_colormanagement_imbuf_make_scene_linear(ibuf, &ima->colorspace_settings); + /* preview is NULL when it has never been used as an icon before */ if (G.background == 0 && ima->preview == NULL) BKE_icon_changed(BKE_icon_getid(&ima->id)); diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c index de367b6b4d0..a38188e2307 100644 --- a/source/blender/blenkernel/intern/movieclip.c +++ b/source/blender/blenkernel/intern/movieclip.c @@ -74,6 +74,7 @@ #include "BKE_image.h" /* openanim */ #include "BKE_tracking.h" +#include "IMB_colormanagement.h" #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" #include "IMB_moviecache.h" @@ -777,6 +778,11 @@ static ImBuf *movieclip_get_postprocessed_ibuf(MovieClip *clip, MovieClipUser *u ibuf = movieclip_load_movie_file(clip, user, framenr, flag); } + if (ibuf) { + /* make float buffer stored in ImBuf scene linear space */ + IMB_colormanagement_imbuf_make_scene_linear(ibuf, &clip->colorspace_settings); + } + if (ibuf && (cache_flag & MOVIECLIP_CACHE_SKIP) == 0) put_imbuf_cache(clip, user, ibuf, flag); } -- cgit v1.2.3 From 8f85e93ea69a313fa77ad551a7a4c39797f1c0e1 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 17 Jul 2012 11:10:40 +0000 Subject: Color management: fix missed color management settings for new created scenes - Initialize color management settings if creating new scene - Copy settings from active scene if creating with copying settings or if using other copy/link object settings This also should fix issue with Export UV Layout operator --- source/blender/blenkernel/intern/scene.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'source/blender/blenkernel/intern') diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index d9afd1eefb4..960713fd5d1 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -57,6 +57,7 @@ #include "BKE_anim.h" #include "BKE_animsys.h" +#include "BKE_colortools.h" #include "BKE_depsgraph.h" #include "BKE_global.h" #include "BKE_group.h" @@ -132,6 +133,8 @@ Scene *BKE_scene_copy(Scene *sce, int type) MEM_freeN(scen->toolsettings); } else { + ImageFormatData *im_format, *im_formatn; + scen = BKE_libblock_copy(&sce->id); BLI_duplicatelist(&(scen->base), &(sce->base)); @@ -166,6 +169,13 @@ Scene *BKE_scene_copy(Scene *sce, int type) obase = obase->next; base = base->next; } + + /* copy color management settings */ + im_format = &sce->r.im_format; + im_formatn = &scen->r.im_format; + + BKE_color_managed_display_settings_copy(&im_formatn->display_settings, &im_format->display_settings); + BKE_color_managed_view_settings_copy(&im_formatn->view_settings, &im_format->view_settings); } /* tool settings */ @@ -545,6 +555,9 @@ Scene *BKE_scene_add(const char *name) sound_create_scene(sce); + BKE_color_managed_display_settings_init(&sce->r.im_format.display_settings); + BKE_color_managed_view_settings_init(&sce->r.im_format.view_settings); + return sce; } -- cgit v1.2.3 From 8568ce6fc8b907ad9fa664703f808064c7b0c264 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 20 Jul 2012 10:35:46 +0000 Subject: Mask rasteriyer: fixed wrong bounding box calculation for non-cyclic splines --- source/blender/blenkernel/intern/mask.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source/blender/blenkernel/intern') diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index 8facc2c1672..a8c95a4fc71 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -556,6 +556,8 @@ static void spline_feather_collapse_inner_loops(MaskSpline *spline, float (*feat int next = i + 1; float delta; + DO_MINMAX2(feather_points[i], min, max); + if (next == tot_feather_point) { if (spline->flag & MASK_SPLINE_CYCLIC) next = 0; @@ -570,8 +572,6 @@ static void spline_feather_collapse_inner_loops(MaskSpline *spline, float (*feat delta = fabsf(feather_points[i][1] - feather_points[next][1]); if (delta > max_delta_y) max_delta_y = delta; - - DO_MINMAX2(feather_points[i], min, max); } /* use dynamically calculated buckets per side, so we likely wouldn't -- cgit v1.2.3 From 44800e884c9d638fb668089d8569888d8ef0502f Mon Sep 17 00:00:00 2001 From: Lukas Toenne Date: Fri, 20 Jul 2012 17:28:42 +0000 Subject: Masking: prevent crashes in cases when mask spline is axis aligned --- source/blender/blenkernel/intern/mask.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'source/blender/blenkernel/intern') diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index a8c95a4fc71..e63dfdf4445 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -574,12 +574,25 @@ static void spline_feather_collapse_inner_loops(MaskSpline *spline, float (*feat max_delta_y = delta; } + /* prevent divisionsby zero by ensuring bounding box is not collapsed */ + if (max[0] - min[0] < FLT_EPSILON) { + max[0] += 0.01f; + min[0] -= 0.01f; + } + + if (max[1] - min[1] < FLT_EPSILON) { + max[1] += 0.01f; + min[1] -= 0.01f; + } + /* use dynamically calculated buckets per side, so we likely wouldn't * run into a situation when segment doesn't fit two buckets which is * pain collecting candidates for intersection */ + max_delta_x /= max[0] - min[0]; max_delta_y /= max[1] - min[1]; + max_delta = MAX2(max_delta_x, max_delta_y); buckets_per_side = MIN2(512, 0.9f / max_delta); -- cgit v1.2.3 From a0bdc54572c55158a39b40dabf7eb67698f5450c Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 24 Jul 2012 11:49:21 +0000 Subject: Color management: fix memory corruption when using border rendering Image's get render result function used to modify ImBuf directly, without making needed invalidates to color management cache when it's needed. --- source/blender/blenkernel/intern/image.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'source/blender/blenkernel/intern') diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index fe364bbf439..20ad570a882 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -2560,6 +2560,13 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **lock_ image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0); } + /* invalidate color managed buffers if render result changed */ + BLI_lock_thread(LOCK_COLORMANAGE); + if (ibuf->x != rres.rectx || ibuf->y != rres.recty || ibuf->rect_float != rectf) { + IMB_display_buffer_invalidate(ibuf); + } + BLI_unlock_thread(LOCK_COLORMANAGE); + ibuf->x = rres.rectx; ibuf->y = rres.recty; -- cgit v1.2.3 From a6d62e9e87d460473f16ddd1fccc319ffd9b9246 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 24 Jul 2012 12:18:40 +0000 Subject: Correction to previous commit -- make sure float buffer is not being changed while color management transformations are running. --- source/blender/blenkernel/intern/image.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source/blender/blenkernel/intern') diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index 20ad570a882..fa0070de76b 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -2565,7 +2565,6 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **lock_ if (ibuf->x != rres.rectx || ibuf->y != rres.recty || ibuf->rect_float != rectf) { IMB_display_buffer_invalidate(ibuf); } - BLI_unlock_thread(LOCK_COLORMANAGE); ibuf->x = rres.rectx; ibuf->y = rres.recty; @@ -2602,6 +2601,8 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **lock_ ibuf->flags &= ~IB_zbuffloat; } + BLI_unlock_thread(LOCK_COLORMANAGE); + /* since its possible to access the buffer from the image directly, set the profile [#25073] */ ibuf->profile = (iuser->scene->r.color_mgt_flag & R_COLOR_MANAGEMENT) ? IB_PROFILE_LINEAR_RGB : IB_PROFILE_NONE; ibuf->dither = dither; -- cgit v1.2.3 From b6288e94ebb9da8cf6377ede4d0748e861c4d3a1 Mon Sep 17 00:00:00 2001 From: Peter Schlaile Date: Sun, 29 Jul 2012 15:48:38 +0000 Subject: == compositor == This adds an inpaint node to blender. In case, you don't know, inpainting does this: http://en.wikipedia.org/wiki/Inpainting It's use cases in blender are * wire removal * green screen background reconstruction The node isn't tile based (for fundamental reasons), but very fast, since it first builds a manhatten distance map and after that performs color convolution only on the edges. That's something, one should probably add also to the dilate node (in step mode) to make it perform a lot better for dilate iterations greater than 3. It will bring it's computing time from O(n^3) down to O(n^2). Take a look here for the details: http://ostermiller.org/dilate_and_erode.html ) --- source/blender/blenkernel/intern/node.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source/blender/blenkernel/intern') diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 56b1c0a17e8..937015c0cac 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -1892,6 +1892,7 @@ static void registerCompositNodes(bNodeTreeType *ttype) register_node_type_cmp_bilateralblur(ttype); register_node_type_cmp_vecblur(ttype); register_node_type_cmp_dilateerode(ttype); + register_node_type_cmp_inpaint(ttype); register_node_type_cmp_defocus(ttype); register_node_type_cmp_valtorgb(ttype); -- cgit v1.2.3 From 2feac552ebbe22d6ddbb4be0d830238459dc678d Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 30 Jul 2012 16:07:37 +0000 Subject: Color management: initialize input color space for newly opening images --- source/blender/blenkernel/intern/colortools.c | 11 +++++++++++ source/blender/blenkernel/intern/image.c | 5 +++++ 2 files changed, 16 insertions(+) (limited to 'source/blender/blenkernel/intern') diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c index c489c08f4df..ec9198590ed 100644 --- a/source/blender/blenkernel/intern/colortools.c +++ b/source/blender/blenkernel/intern/colortools.c @@ -1244,3 +1244,14 @@ void BKE_color_managed_view_settings_copy(ColorManagedViewSettings *new_settings new_settings->exposure = settings->exposure; new_settings->gamma = settings->gamma; } + +void BKE_color_managed_colorspace_settings_init(ColorManagedColorspaceSettings *colorspace_settings) +{ + BLI_strncpy(colorspace_settings->name, "NONE", sizeof(colorspace_settings->name)); +} + +void BKE_color_managed_colorspace_settings_copy(ColorManagedColorspaceSettings *colorspace_settings, + const ColorManagedColorspaceSettings *settings) +{ + BLI_strncpy(colorspace_settings->name, settings->name, sizeof(colorspace_settings->name)); +} diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index fa0070de76b..e65099cc621 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -71,6 +71,7 @@ #include "BLI_bpath.h" #include "BKE_bmfont.h" +#include "BKE_colortools.h" #include "BKE_global.h" #include "BKE_icons.h" #include "BKE_image.h" @@ -245,6 +246,8 @@ static Image *image_alloc(const char *name, short source, short type) ima->source = source; ima->type = type; + + BKE_color_managed_colorspace_settings_init(&ima->colorspace_settings); } return ima; } @@ -327,6 +330,8 @@ Image *BKE_image_copy(Image *ima) nima->aspx = ima->aspx; nima->aspy = ima->aspy; + BKE_color_managed_colorspace_settings_copy(&nima->colorspace_settings, &ima->colorspace_settings); + return nima; } -- cgit v1.2.3 From de4e940885f20b17a2e527599626105d50cae71d Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 1 Aug 2012 14:19:42 +0000 Subject: Remove mask cache hack added for mango project a while ago We've got new rasterizer which doesn't require cacheing anymore. --- source/blender/blenkernel/intern/mask.c | 47 --------------------------------- 1 file changed, 47 deletions(-) (limited to 'source/blender/blenkernel/intern') diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index ddba9a7a65b..81800016cbd 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -56,21 +56,6 @@ #include "BKE_movieclip.h" #include "BKE_utildefines.h" -#ifdef USE_MANGO_MASK_CACHE_HACK - -#include "BLI_threads.h" - -typedef struct MaskRasterCache { - float *buffer; - int width, height; - short do_aspect_correct; - short do_mask_aa; - short do_feather; - - ListBase layers; -} MaskRasterCache; -#endif - static MaskSplinePoint *mask_spline_point_next(MaskSpline *spline, MaskSplinePoint *points_array, MaskSplinePoint *point) { if (point == &points_array[spline->tot_point - 1]) { @@ -1560,41 +1545,9 @@ void BKE_mask_layer_free_list(ListBase *masklayers) } -#ifdef USE_MANGO_MASK_CACHE_HACK -void BKE_mask_raster_cache_free(Mask *mask) -{ - MaskRasterCache *cache = mask->raster_cache; - - if (cache) { - MaskLayer *layer; - - layer = cache->layers.first; - while (layer) { - MaskLayer *layer_next = layer->next; - - BKE_mask_layer_free(layer); - layer = layer_next; - } - - MEM_freeN(cache->buffer); - MEM_freeN(cache); - - mask->raster_cache = NULL; - } -} -#endif - void BKE_mask_free(Mask *mask) { BKE_mask_layer_free_list(&mask->masklayers); - -#ifdef USE_MANGO_MASK_CACHE_HACK - if (mask->raster_cache) { - BKE_mask_raster_cache_free(mask); - - mask->raster_cache = NULL; - } -#endif } void BKE_mask_unlink(Main *bmain, Mask *mask) -- cgit v1.2.3 From 385c38f6ed13b3d9502644f6912517ea4314630e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 6 Aug 2012 13:59:11 +0000 Subject: misc small edits syncing with trunk --- source/blender/blenkernel/intern/mask.c | 2 -- source/blender/blenkernel/intern/node.c | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'source/blender/blenkernel/intern') diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index 01aa9fa9fa9..f41d8feef0b 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -1528,7 +1528,6 @@ void BKE_mask_layer_free(MaskLayer *masklay) MEM_freeN(masklay); } - void BKE_mask_layer_free_list(ListBase *masklayers) { MaskLayer *masklay = masklayers->first; @@ -1541,7 +1540,6 @@ void BKE_mask_layer_free_list(ListBase *masklayers) masklay = masklay_next; } - } void BKE_mask_free(Mask *mask) diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 8f3c76c3357..8670f86cd67 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -1443,13 +1443,13 @@ void BKE_node_clipboard_clear(void) bNode *node, *node_next; bNodeLink *link, *link_next; - for (link = node_clipboard.links.first; link; link=link_next) { + for (link = node_clipboard.links.first; link; link = link_next) { link_next = link->next; nodeRemLink(NULL, link); } node_clipboard.links.first = node_clipboard.links.last = NULL; - for (node = node_clipboard.nodes.first; node; node=node_next) { + for (node = node_clipboard.nodes.first; node; node = node_next) { node_next = node->next; nodeFreeNode(NULL, node); } -- cgit v1.2.3 From 555b6afe2079c111389fd1bb9232b2e22faef416 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 14 Aug 2012 11:12:31 +0000 Subject: Color Management: convert strips to float if Make Float is enabled but no other filters used Makes it possible to have color corrections in preview for strips which are originally bytes. --- source/blender/blenkernel/intern/sequencer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/blender/blenkernel/intern') diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index cec868cfc10..f342ea088f7 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -1678,7 +1678,7 @@ int BKE_sequencer_input_have_to_preprocess(SeqRenderData UNUSED(context), Sequen float mul; if (seq->flag & (SEQ_FILTERY | SEQ_USE_CROP | SEQ_USE_TRANSFORM | SEQ_FLIPX | - SEQ_FLIPY | SEQ_USE_COLOR_BALANCE | SEQ_MAKE_PREMUL)) + SEQ_FLIPY | SEQ_USE_COLOR_BALANCE | SEQ_MAKE_PREMUL | SEQ_MAKE_FLOAT)) { return TRUE; } -- cgit v1.2.3 From 6f518e0ee9802042459098c4d7ef23aa4a47100a Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 20 Aug 2012 16:15:09 +0000 Subject: Sequencer: clear cache and animation buffers for strips outside of cursor when rendering This avoids having bunch of cached images when doing animation rendering, keeping all the memory available for rendered itself. This keeps memory usage low when rendering huge edits with mixed scenes and movie strips. This should not affect on sped of video encoding, which was confirmed by some own tests. Currently commiting to tomato due to not sure if there's something i can not foresee here. --- source/blender/blenkernel/intern/sequencer.c | 37 +++++++--------------------- 1 file changed, 9 insertions(+), 28 deletions(-) (limited to 'source/blender/blenkernel/intern') diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index edbbbe10300..14dd4f6d053 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -2991,46 +2991,27 @@ void BKE_sequence_invalidate_cache_for_modifier(Scene *scene, Sequence *seq) sequence_invalidate_cache(scene, seq, FALSE); } -void BKE_sequencer_free_imbuf(Scene *scene, ListBase *seqbase, int check_mem_usage, int keep_file_handles) +void BKE_sequencer_free_imbuf(Scene *scene, ListBase *seqbase, int for_render) { Sequence *seq; - if (check_mem_usage) { - /* Let the cache limitor take care of this (schlaile) */ - /* While render let's keep all memory available for render - * (ton) - * At least if free memory is tight... - * This can make a big difference in encoding speed - * (it is around 4 times(!) faster, if we do not waste time - * on freeing _all_ buffers every time on long timelines...) - * (schlaile) - */ - - uintptr_t mem_in_use; - uintptr_t mmap_in_use; - uintptr_t max; - - mem_in_use = MEM_get_memory_in_use(); - mmap_in_use = MEM_get_mapped_memory_in_use(); - max = MEM_CacheLimiter_get_maximum(); - - if (max == 0 || mem_in_use + mmap_in_use <= max) { - return; - } - } - BKE_sequencer_cache_cleanup(); - + for (seq = seqbase->first; seq; seq = seq->next) { + if (for_render && CFRA >= seq->startdisp && CFRA <= seq->enddisp) { + continue; + } + if (seq->strip) { - if (seq->type == SEQ_TYPE_MOVIE && !keep_file_handles) + if (seq->type == SEQ_TYPE_MOVIE) { free_anim_seq(seq); + } if (seq->type == SEQ_TYPE_SPEED) { BKE_sequence_effect_speed_rebuild_map(scene, seq, 1); } } if (seq->type == SEQ_TYPE_META) { - BKE_sequencer_free_imbuf(scene, &seq->seqbase, FALSE, keep_file_handles); + BKE_sequencer_free_imbuf(scene, &seq->seqbase, for_render); } if (seq->type == SEQ_TYPE_SCENE) { /* FIXME: recurs downwards, -- cgit v1.2.3 From abda89bf4d6e145164c0767989ae3f32a77cc9b5 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 21 Aug 2012 08:57:24 +0000 Subject: Fix cycles continuously updating when creating a driver for a scene property, like driving integrator seed with #frame. The scene drivers are evaluated continuously, which would be nice to fix but complicated, now it compares the RNA value to see if it actually changed, and avoids the update in that case, which is a useful optimization by itself. --- source/blender/blenkernel/intern/anim_sys.c | 58 +++++++++++++++++++++-------- 1 file changed, 43 insertions(+), 15 deletions(-) (limited to 'source/blender/blenkernel/intern') diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c index 8e8c98a38e4..a4bf7bd9720 100644 --- a/source/blender/blenkernel/intern/anim_sys.c +++ b/source/blender/blenkernel/intern/anim_sys.c @@ -1145,6 +1145,7 @@ static short animsys_write_rna_setting(PointerRNA *ptr, char *path, int array_in /* set value - only for animatable numerical values */ if (RNA_property_animateable(&new_ptr, prop)) { int array_len = RNA_property_array_length(&new_ptr, prop); + int written = FALSE; if (array_len && array_index >= array_len) { if (G.debug & G_DEBUG) { @@ -1158,25 +1159,52 @@ static short animsys_write_rna_setting(PointerRNA *ptr, char *path, int array_in switch (RNA_property_type(prop)) { case PROP_BOOLEAN: - if (array_len) - RNA_property_boolean_set_index(&new_ptr, prop, array_index, ANIMSYS_FLOAT_AS_BOOL(value)); - else - RNA_property_boolean_set(&new_ptr, prop, ANIMSYS_FLOAT_AS_BOOL(value)); + if (array_len) { + if (RNA_property_boolean_get_index(&new_ptr, prop, array_index) != ANIMSYS_FLOAT_AS_BOOL(value)) { + RNA_property_boolean_set_index(&new_ptr, prop, array_index, ANIMSYS_FLOAT_AS_BOOL(value)); + written = TRUE; + } + } + else { + if (RNA_property_boolean_get(&new_ptr, prop) != ANIMSYS_FLOAT_AS_BOOL(value)) { + RNA_property_boolean_set(&new_ptr, prop, ANIMSYS_FLOAT_AS_BOOL(value)); + written = TRUE; + } + } break; case PROP_INT: - if (array_len) - RNA_property_int_set_index(&new_ptr, prop, array_index, (int)value); - else - RNA_property_int_set(&new_ptr, prop, (int)value); + if (array_len) { + if (RNA_property_int_get_index(&new_ptr, prop, array_index) != (int)value) { + RNA_property_int_set_index(&new_ptr, prop, array_index, (int)value); + written = TRUE; + } + } + else { + if (RNA_property_int_get(&new_ptr, prop) != (int)value) { + RNA_property_int_set(&new_ptr, prop, (int)value); + written = TRUE; + } + } break; case PROP_FLOAT: - if (array_len) - RNA_property_float_set_index(&new_ptr, prop, array_index, value); - else - RNA_property_float_set(&new_ptr, prop, value); + if (array_len) { + if (RNA_property_float_get_index(&new_ptr, prop, array_index) != value) { + RNA_property_float_set_index(&new_ptr, prop, array_index, value); + written = TRUE; + } + } + else { + if (RNA_property_float_get(&new_ptr, prop) != value) { + RNA_property_float_set(&new_ptr, prop, value); + written = TRUE; + } + } break; case PROP_ENUM: - RNA_property_enum_set(&new_ptr, prop, (int)value); + if (RNA_property_enum_get(&new_ptr, prop) != (int)value) { + RNA_property_enum_set(&new_ptr, prop, (int)value); + written = TRUE; + } break; default: /* nothing can be done here... so it is unsuccessful? */ @@ -1186,7 +1214,7 @@ static short animsys_write_rna_setting(PointerRNA *ptr, char *path, int array_in /* RNA property update disabled for now - [#28525] [#28690] [#28774] [#28777] */ #if 0 /* buffer property update for later flushing */ - if (RNA_property_update_check(prop)) { + if (written && RNA_property_update_check(prop)) { short skip_updates_hack = 0; /* optimization hacks: skip property updates for those properties @@ -1206,7 +1234,7 @@ static short animsys_write_rna_setting(PointerRNA *ptr, char *path, int array_in /* as long as we don't do property update, we still tag datablock * as having been updated. this flag does not cause any updates to * be run, it's for e.g. render engines to synchronize data */ - if (new_ptr.id.data) { + if (written && new_ptr.id.data) { ID *id = new_ptr.id.data; id->flag |= LIB_ID_RECALC; DAG_id_type_tag(G.main, GS(id->name)); -- cgit v1.2.3 From dd65a6b67d9bbc01e82e94c399e4721538c714be Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 22 Aug 2012 14:23:08 +0000 Subject: Color Management: pipeline cleanup - Move color management settings to scene, so it's now clear for all areas (such as compositor, sequencer) which settings to use for display buffers - Currently removed per-editor color management settings. It could be nice to have them, but they don't fit nicely into overall pipeline and could be added as a override settings for display only later. - Make sequencer working in space defined by sequencer_workspace role in OCIO configuration file. If this role is not set, sequencer will fallback to legacy sRGB Gamma 2.2 space. Currently use vd16 color space for sequencer. Not sure what exactly this color space is, but it's pretty close to SPI Film view and it's still invertable. - Sequencer will now output linear float buffers, not color managed float buffers. Before this sequencer used to output float buffers in sRGB space, which was sequencer's working space. Now it can not output buffers in this space since other areas are not aware of this space. This also makes it's consistent that all float buffers in Blender are in linear space. - When saving render result into byte file format scene's display transform would be applied on this buffer. When saving files from image editor, there'll be a display transform settings which are default set to scene's settings but could also be overwritten. Additional details are there (would be extended soon): http://wiki.blender.org/index.php/User:Nazg-gul/ColorManagement --- source/blender/blenkernel/intern/colortools.c | 2 -- source/blender/blenkernel/intern/scene.c | 8 ++++---- source/blender/blenkernel/intern/sequencer.c | 27 ++++++++++++++++++--------- 3 files changed, 22 insertions(+), 15 deletions(-) (limited to 'source/blender/blenkernel/intern') diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c index d0901ad93ff..5138d68cf79 100644 --- a/source/blender/blenkernel/intern/colortools.c +++ b/source/blender/blenkernel/intern/colortools.c @@ -1273,8 +1273,6 @@ void BKE_color_managed_view_settings_init(ColorManagedViewSettings *settings) settings->gamma = 1.0f; settings->exposure = 0.0f; - - settings->flag |= COLORMANAGE_VIEW_USE_GLOBAL; } void BKE_color_managed_view_settings_copy(ColorManagedViewSettings *new_settings, diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index c0ec1cc9297..e74413c3198 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -175,8 +175,8 @@ Scene *BKE_scene_copy(Scene *sce, int type) im_format = &sce->r.im_format; im_formatn = &scen->r.im_format; - BKE_color_managed_display_settings_copy(&im_formatn->display_settings, &im_format->display_settings); - BKE_color_managed_view_settings_copy(&im_formatn->view_settings, &im_format->view_settings); + BKE_color_managed_display_settings_copy(&scen->display_settings, &sce->display_settings); + BKE_color_managed_view_settings_copy(&scen->view_settings, &sce->view_settings); } /* tool settings */ @@ -556,8 +556,8 @@ Scene *BKE_scene_add(const char *name) sound_create_scene(sce); - BKE_color_managed_display_settings_init(&sce->r.im_format.display_settings); - BKE_color_managed_view_settings_init(&sce->r.im_format.view_settings); + BKE_color_managed_display_settings_init(&sce->display_settings); + BKE_color_managed_view_settings_init(&sce->view_settings); return sce; } diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index 01ae4a35f3c..9156debc80c 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -72,6 +72,7 @@ #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" +#include "IMB_colormanagement.h" #include "BKE_context.h" #include "BKE_sound.h" @@ -1838,8 +1839,9 @@ static ImBuf *input_preprocess(SeqRenderData context, Sequence *seq, float cfra, } if (seq->flag & SEQ_MAKE_FLOAT) { - if (!ibuf->rect_float) - IMB_float_from_rect_simple(ibuf); + if (!ibuf->rect_float) { + IMB_colormanagement_imbuf_to_sequencer_space(ibuf, TRUE); + } if (ibuf->rect) { imb_freerectImBuf(ibuf); @@ -2350,11 +2352,8 @@ static ImBuf *seq_render_scene_strip(SeqRenderData context, Sequence *seq, float } /* float buffers in the sequencer are not linear */ - if (scene->r.color_mgt_flag & R_COLOR_MANAGEMENT) - ibuf->profile = IB_PROFILE_LINEAR_RGB; - else - ibuf->profile = IB_PROFILE_NONE; - IMB_convert_profile(ibuf, IB_PROFILE_SRGB); + ibuf->profile = IB_PROFILE_LINEAR_RGB; + IMB_colormanagement_imbuf_to_sequencer_space(ibuf, FALSE); } else if (rres.rect32) { ibuf = IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rect); @@ -2460,8 +2459,7 @@ static ImBuf *do_render_strip_uncached(SeqRenderData context, Sequence *seq, flo imb_freerectImBuf(ibuf); /* all sequencer color is done in SRGB space, linear gives odd crossfades */ - if (ibuf->profile == IB_PROFILE_LINEAR_RGB) - IMB_convert_profile(ibuf, IB_PROFILE_NONE); + IMB_colormanagement_imbuf_to_sequencer_space(ibuf, FALSE); copy_to_ibuf_still(context, seq, nr, ibuf); @@ -2653,6 +2651,12 @@ static ImBuf *seq_render_strip_stack(SeqRenderData context, ListBase *seqbasep, if (count == 1) { out = seq_render_strip(context, seq_arr[0], cfra); + + if (out) { + /* put buffer back to linear space */ + IMB_colormanagement_imbuf_from_sequencer_space(out); + } + BKE_sequencer_cache_put(context, seq_arr[0], cfra, SEQ_STRIPELEM_IBUF_COMP, out); return out; @@ -2732,6 +2736,11 @@ static ImBuf *seq_render_strip_stack(SeqRenderData context, ListBase *seqbasep, BKE_sequencer_cache_put(context, seq_arr[i], cfra, SEQ_STRIPELEM_IBUF_COMP, out); } + if (out) { + /* put buffer back to linear space */ + IMB_colormanagement_imbuf_from_sequencer_space(out); + } + return out; } -- cgit v1.2.3 From b2483c3dbe523dac48846ac05d5fdf9c2ba3cdfd Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 22 Aug 2012 15:08:41 +0000 Subject: despeckle node for tomato only --- source/blender/blenkernel/intern/node.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source/blender/blenkernel/intern') diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 37562686a99..22b0cccf175 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -2139,6 +2139,7 @@ static void registerCompositNodes(bNodeTreeType *ttype) register_node_type_cmp_vecblur(ttype); register_node_type_cmp_dilateerode(ttype); register_node_type_cmp_inpaint(ttype); + register_node_type_cmp_despeckle(ttype); register_node_type_cmp_defocus(ttype); register_node_type_cmp_valtorgb(ttype); -- cgit v1.2.3 From 54c64cb443bd1ce452b3d9a5738a7aca8dc952a1 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 24 Aug 2012 14:01:01 +0000 Subject: Color management: initialize input color space on movie clip load --- source/blender/blenkernel/intern/movieclip.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source/blender/blenkernel/intern') diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c index c56bb761579..50628ac857a 100644 --- a/source/blender/blenkernel/intern/movieclip.c +++ b/source/blender/blenkernel/intern/movieclip.c @@ -66,6 +66,7 @@ #include "BKE_animsys.h" #include "BKE_constraint.h" +#include "BKE_colortools.h" #include "BKE_library.h" #include "BKE_global.h" #include "BKE_main.h" @@ -480,6 +481,7 @@ static MovieClip *movieclip_alloc(const char *name) clip->aspx = clip->aspy = 1.0f; BKE_tracking_settings_init(&clip->tracking); + BKE_color_managed_colorspace_settings_init(&clip->colorspace_settings); clip->proxy.build_size_flag = IMB_PROXY_25; clip->proxy.build_tc_flag = IMB_TC_RECORD_RUN | -- cgit v1.2.3 From 614a82cb8cb11533b7f4161ac323d4374986e9cc Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Sat, 25 Aug 2012 16:52:55 +0000 Subject: Tomato Cycles: * Added a Brick Texture Node to Cycles. * Based on the Blender Internal Brick Texture with some modifications. * Tested on CPU and GPU (CUDA & OpenCL) Documentation: http://wiki.blender.org/index.php/User:DingTo/CyclesBrickTexture ToDo: Only works correct on flat surfaces, like a Plane. If you attach the shader to 3D objects like a cube, the mapping is not correct on the Y/Z vector. Thanks to Lukas Toenne for fixing a issue I had with the Node code! :) --- source/blender/blenkernel/intern/node.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source/blender/blenkernel/intern') diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index bf5fc6449f8..3b860cfaa10 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -2265,6 +2265,7 @@ static void registerShaderNodes(bNodeTreeType *ttype) register_node_type_sh_tex_gradient(ttype); register_node_type_sh_tex_magic(ttype); register_node_type_sh_tex_checker(ttype); + register_node_type_sh_tex_brick(ttype); } static void registerTextureNodes(bNodeTreeType *ttype) -- cgit v1.2.3 From f31d17220d611368a0e74da91b2981a3221b60b2 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Sun, 26 Aug 2012 23:57:55 +0000 Subject: Sequencer: fix for wrong color space sequencer effects were working in --- source/blender/blenkernel/intern/seqeffects.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'source/blender/blenkernel/intern') diff --git a/source/blender/blenkernel/intern/seqeffects.c b/source/blender/blenkernel/intern/seqeffects.c index 87906337ca2..e1fd5a1639f 100644 --- a/source/blender/blenkernel/intern/seqeffects.c +++ b/source/blender/blenkernel/intern/seqeffects.c @@ -53,6 +53,7 @@ #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" +#include "IMB_colormanagement.h" #include "RNA_access.h" @@ -120,13 +121,13 @@ static ImBuf *prepare_effect_imbufs(SeqRenderData context, ImBuf *ibuf1, ImBuf * } if (ibuf1 && !ibuf1->rect_float && out->rect_float) { - IMB_float_from_rect_simple(ibuf1); + IMB_colormanagement_imbuf_to_sequencer_space(ibuf1, TRUE); } if (ibuf2 && !ibuf2->rect_float && out->rect_float) { - IMB_float_from_rect_simple(ibuf2); + IMB_colormanagement_imbuf_to_sequencer_space(ibuf2, TRUE); } if (ibuf3 && !ibuf3->rect_float && out->rect_float) { - IMB_float_from_rect_simple(ibuf3); + IMB_colormanagement_imbuf_to_sequencer_space(ibuf3, TRUE); } if (ibuf1 && !ibuf1->rect && !out->rect_float) { @@ -138,7 +139,9 @@ static ImBuf *prepare_effect_imbufs(SeqRenderData context, ImBuf *ibuf1, ImBuf * if (ibuf3 && !ibuf3->rect && !out->rect_float) { IMB_rect_from_float(ibuf3); } - + + out->profile = IB_PROFILE_SRGB; + return out; } -- cgit v1.2.3 From 2e1568d64e86720dd2a4f8d0a98e5feac4631f6e Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 29 Aug 2012 18:08:34 +0000 Subject: Color management: fix for wrong view being used as default in configuration file check Also marked Jpeg2K as non-float format. --- source/blender/blenkernel/intern/image.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source/blender/blenkernel/intern') diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index d74a7f6e374..6d0a67f520f 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -1024,7 +1024,6 @@ int BKE_imtype_supports_float(const char imtype) case R_IMF_IMTYPE_RADHDR: case R_IMF_IMTYPE_OPENEXR: case R_IMF_IMTYPE_MULTILAYER: - case R_IMF_IMTYPE_JP2: return TRUE; } return 0; -- cgit v1.2.3 From 70301f431c7b53e06ba243b19997c7c56f0a9d3a Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 30 Aug 2012 13:40:31 +0000 Subject: Color management: make it behave closer to trunk Avoid using tricks with ibuf->profile to check whether image buffer is in sequencer or linear space. Assume the whole sequencer works in non linear float space and do transformation to linear where it;s needed only. This removes confusion from the code, fixes wrong behavior of some effects. --- source/blender/blenkernel/intern/seqeffects.c | 2 -- source/blender/blenkernel/intern/sequencer.c | 15 ++++----------- 2 files changed, 4 insertions(+), 13 deletions(-) (limited to 'source/blender/blenkernel/intern') diff --git a/source/blender/blenkernel/intern/seqeffects.c b/source/blender/blenkernel/intern/seqeffects.c index e1c3decf24f..0abd3444c54 100644 --- a/source/blender/blenkernel/intern/seqeffects.c +++ b/source/blender/blenkernel/intern/seqeffects.c @@ -140,8 +140,6 @@ static ImBuf *prepare_effect_imbufs(SeqRenderData context, ImBuf *ibuf1, ImBuf * IMB_rect_from_float(ibuf3); } - out->profile = IB_PROFILE_SRGB; - return out; } diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index 84da45294a6..dcf72c37f52 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -2461,7 +2461,8 @@ static ImBuf *do_render_strip_uncached(SeqRenderData context, Sequence *seq, flo imb_freerectImBuf(ibuf); /* all sequencer color is done in SRGB space, linear gives odd crossfades */ - IMB_colormanagement_imbuf_to_sequencer_space(ibuf, FALSE); + if (ibuf->profile == IB_PROFILE_LINEAR_RGB) + IMB_colormanagement_imbuf_to_sequencer_space(ibuf, FALSE); copy_to_ibuf_still(context, seq, nr, ibuf); @@ -2653,18 +2654,13 @@ static ImBuf *seq_render_strip_stack(SeqRenderData context, ListBase *seqbasep, if (count == 1) { out = seq_render_strip(context, seq_arr[0], cfra); - - if (out) { - /* put buffer back to linear space */ - IMB_colormanagement_imbuf_from_sequencer_space(out); - } + out->colormanage_flags |= IMB_COLORMANAGE_NOLINEAR_FLOAT; BKE_sequencer_cache_put(context, seq_arr[0], cfra, SEQ_STRIPELEM_IBUF_COMP, out); return out; } - for (i = count - 1; i >= 0; i--) { int early_out; Sequence *seq = seq_arr[i]; @@ -2738,10 +2734,7 @@ static ImBuf *seq_render_strip_stack(SeqRenderData context, ListBase *seqbasep, BKE_sequencer_cache_put(context, seq_arr[i], cfra, SEQ_STRIPELEM_IBUF_COMP, out); } - if (out) { - /* put buffer back to linear space */ - IMB_colormanagement_imbuf_from_sequencer_space(out); - } + out->colormanage_flags |= IMB_COLORMANAGE_NOLINEAR_FLOAT; return out; } -- cgit v1.2.3 From e15f352831b9cc9fa1a85a0cdadf6d4b4b1f8731 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 4 Sep 2012 09:06:37 +0000 Subject: Merging r50265 through r50373 from trunk into soc-2011-tomato --- source/blender/blenkernel/intern/DerivedMesh.c | 21 +++++++++ source/blender/blenkernel/intern/anim.c | 50 +++++++++++----------- source/blender/blenkernel/intern/anim_sys.c | 37 +++++++++++----- source/blender/blenkernel/intern/armature.c | 27 ++++++------ source/blender/blenkernel/intern/blender.c | 3 -- source/blender/blenkernel/intern/cdderivedmesh.c | 1 - source/blender/blenkernel/intern/constraint.c | 2 +- source/blender/blenkernel/intern/customdata.c | 1 - source/blender/blenkernel/intern/customdata_file.c | 34 ++++++--------- source/blender/blenkernel/intern/depsgraph.c | 1 - source/blender/blenkernel/intern/fcurve.c | 1 - source/blender/blenkernel/intern/font.c | 1 - source/blender/blenkernel/intern/idprop.c | 12 ------ source/blender/blenkernel/intern/image.c | 1 - source/blender/blenkernel/intern/library.c | 1 - source/blender/blenkernel/intern/mask_evaluate.c | 1 - source/blender/blenkernel/intern/mball.c | 2 +- source/blender/blenkernel/intern/movieclip.c | 1 - source/blender/blenkernel/intern/node.c | 2 - source/blender/blenkernel/intern/ocean.c | 2 - source/blender/blenkernel/intern/packedFile.c | 1 - source/blender/blenkernel/intern/pointcache.c | 1 - source/blender/blenkernel/intern/sca.c | 1 - source/blender/blenkernel/intern/seqeffects.c | 1 - source/blender/blenkernel/intern/seqmodifier.c | 1 - source/blender/blenkernel/intern/sequencer.c | 1 - source/blender/blenkernel/intern/sound.c | 1 - source/blender/blenkernel/intern/texture.c | 1 - source/blender/blenkernel/intern/tracking.c | 2 + 29 files changed, 103 insertions(+), 108 deletions(-) (limited to 'source/blender/blenkernel/intern') diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index a29484638c0..1aa54307841 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -3187,4 +3187,25 @@ void DM_debug_print(DerivedMesh *dm) MEM_freeN(str); } +void DM_debug_print_cdlayers(CustomData *data) +{ + int i; + CustomDataLayer *layer; + + printf("{\n"); + + for (i = 0, layer = data->layers; i < data->totlayer; i++, layer++) { + + const char *name = CustomData_layertype_name(layer->type); + const int size = CustomData_sizeof(layer->type); + const char *structname; + int structnum; + CustomData_file_write_info(layer->type, &structname, &structnum); + printf(" dict(name='%s', struct='%s', type=%d, ptr='%p', elem=%d, length=%d),\n", + name, structname, layer->type, (void *)layer->data, size, (int)(MEM_allocN_len(layer->data) / size)); + } + + printf("}\n"); +} + #endif /* NDEBUG */ diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index 9b4f0a31e28..f9954ff1dd0 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -63,7 +63,6 @@ #include "BKE_object.h" #include "BKE_particle.h" #include "BKE_scene.h" -#include "BKE_utildefines.h" #include "BKE_tessmesh.h" #include "BKE_depsgraph.h" #include "BKE_anim.h" @@ -494,36 +493,42 @@ void calc_curvepath(Object *ob) /* in a path vertices are with equal differences: path->len = number of verts */ /* NOW WITH BEVELCURVE!!! */ - if (ob == NULL || ob->type != OB_CURVE) return; + if (ob == NULL || ob->type != OB_CURVE) { + return; + } cu = ob->data; - nurbs = BKE_curve_nurbs_get(cu); - nu = nurbs->first; - if (cu->path) free_path(cu->path); cu->path = NULL; + /* weak! can only use first curve */ bl = cu->bev.first; - if (bl == NULL || !bl->nr) return; + if (bl == NULL || !bl->nr) { + return; + } + + nurbs = BKE_curve_nurbs_get(cu); + nu = nurbs->first; cu->path = path = MEM_callocN(sizeof(Path), "calc_curvepath"); /* if POLY: last vertice != first vertice */ cycl = (bl->poly != -1); - if (cycl) tot = bl->nr; - else tot = bl->nr - 1; + tot = cycl ? bl->nr : bl->nr - 1; path->len = tot + 1; /* exception: vector handle paths and polygon paths should be subdivided at least a factor resolu */ - if (path->len < nu->resolu * SEGMENTSU(nu)) path->len = nu->resolu * SEGMENTSU(nu); + if (path->len < nu->resolu * SEGMENTSU(nu)) { + path->len = nu->resolu * SEGMENTSU(nu); + } dist = (float *)MEM_mallocN((tot + 1) * 4, "calcpathdist"); /* all lengths in *dist */ bevp = bevpfirst = (BevPoint *)(bl + 1); fp = dist; - *fp = 0; + *fp = 0.0f; for (a = 0; a < tot; a++) { fp++; if (cycl && a == tot - 1) @@ -558,19 +563,16 @@ void calc_curvepath(Object *ob) fp++; if (bevp < bevplast) bevp++; bevpn = bevp + 1; - if (bevpn > bevplast) { - if (cycl) bevpn = bevpfirst; - else bevpn = bevplast; + if (UNLIKELY(bevpn > bevplast)) { + bevpn = cycl ? bevpfirst : bevplast; } } - fac1 = *(fp) - *(fp - 1); - fac2 = *(fp) - d; - fac1 = fac2 / fac1; + fac1 = (*(fp) - d) / (*(fp) - *(fp - 1)); fac2 = 1.0f - fac1; - + interp_v3_v3v3(pp->vec, bevp->vec, bevpn->vec, fac2); - pp->vec[3] = fac1 * bevp->alfa + fac2 * bevpn->alfa; + pp->vec[3] = fac1 * bevp->alfa + fac2 * bevpn->alfa; pp->radius = fac1 * bevp->radius + fac2 * bevpn->radius; pp->weight = fac1 * bevp->weight + fac2 * bevpn->weight; interp_qt_qtqt(pp->quat, bevp->quat, bevpn->quat, fac2); @@ -582,18 +584,14 @@ void calc_curvepath(Object *ob) MEM_freeN(dist); } - -/* is this only used internally?*/ -int interval_test(int min, int max, int p1, int cycl) +static int interval_test(const int min, const int max, int p1, const int cycl) { if (cycl) { - if (p1 < min) - p1 = ((p1 - min) % (max - min + 1)) + max + 1; - else if (p1 > max) - p1 = ((p1 - min) % (max - min + 1)) + min; + if (p1 < min) p1 = ((p1 - min) % (max - min + 1)) + max + 1; + else if (p1 > max) p1 = ((p1 - min) % (max - min + 1)) + min; } else { - if (p1 < min) p1 = min; + if (p1 < min) p1 = min; else if (p1 > max) p1 = max; } return p1; diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c index a4bf7bd9720..6a3dae93639 100644 --- a/source/blender/blenkernel/intern/anim_sys.c +++ b/source/blender/blenkernel/intern/anim_sys.c @@ -59,7 +59,6 @@ #include "BKE_main.h" #include "BKE_library.h" #include "BKE_report.h" -#include "BKE_utildefines.h" #include "RNA_access.h" @@ -621,15 +620,30 @@ static char *rna_path_rename_fix(ID *owner_id, const char *prefix, const char *o } /* Check RNA-Paths for a list of F-Curves */ -static void fcurves_path_rename_fix(ID *owner_id, const char *prefix, char *oldName, char *newName, ListBase *curves, int verify_paths) +static void fcurves_path_rename_fix(ID *owner_id, const char *prefix, const char *oldName, const char *newName, + const char *oldKey, const char *newKey, ListBase *curves, int verify_paths) { FCurve *fcu; /* we need to check every curve... */ for (fcu = curves->first; fcu; fcu = fcu->next) { - /* firstly, handle the F-Curve's own path */ - if (fcu->rna_path) - fcu->rna_path = rna_path_rename_fix(owner_id, prefix, oldName, newName, fcu->rna_path, verify_paths); + if (fcu->rna_path) { + char *old_path = fcu->rna_path; + + /* firstly, handle the F-Curve's own path */ + fcu->rna_path = rna_path_rename_fix(owner_id, prefix, oldKey, newKey, fcu->rna_path, verify_paths); + + /* if path changed and the F-Curve is grouped, check if its group also needs renaming + * (i.e. F-Curve is first of a bone's F-Curves; hence renaming this should also trigger rename) + */ + if (fcu->rna_path != old_path) { + bActionGroup *agrp = fcu->grp; + + if ((agrp) && strcmp(oldName, agrp->name)==0) { + BLI_strncpy(agrp->name, newName, sizeof(agrp->name)); + } + } + } } } @@ -675,7 +689,8 @@ static void drivers_path_rename_fix(ID *owner_id, ID *ref_id, const char *prefix } /* Fix all RNA-Paths for Actions linked to NLA Strips */ -static void nlastrips_path_rename_fix(ID *owner_id, const char *prefix, char *oldName, char *newName, ListBase *strips, int verify_paths) +static void nlastrips_path_rename_fix(ID *owner_id, const char *prefix, const char *oldName, const char *newName, + const char *oldKey, const char *newKey, ListBase *strips, int verify_paths) { NlaStrip *strip; @@ -683,11 +698,11 @@ static void nlastrips_path_rename_fix(ID *owner_id, const char *prefix, char *ol for (strip = strips->first; strip; strip = strip->next) { /* fix strip's action */ if (strip->act) - fcurves_path_rename_fix(owner_id, prefix, oldName, newName, &strip->act->curves, verify_paths); + fcurves_path_rename_fix(owner_id, prefix, oldName, newName, oldKey, newKey, &strip->act->curves, verify_paths); /* ignore own F-Curves, since those are local... */ /* check sub-strips (if metas) */ - nlastrips_path_rename_fix(owner_id, prefix, oldName, newName, &strip->strips, verify_paths); + nlastrips_path_rename_fix(owner_id, prefix, oldName, newName, oldKey, newKey, &strip->strips, verify_paths); } } @@ -717,16 +732,16 @@ void BKE_animdata_fix_paths_rename(ID *owner_id, AnimData *adt, ID *ref_id, cons /* Active action and temp action */ if (adt->action) - fcurves_path_rename_fix(owner_id, prefix, oldN, newN, &adt->action->curves, verify_paths); + fcurves_path_rename_fix(owner_id, prefix, oldName, newName, oldN, newN, &adt->action->curves, verify_paths); if (adt->tmpact) - fcurves_path_rename_fix(owner_id, prefix, oldN, newN, &adt->tmpact->curves, verify_paths); + fcurves_path_rename_fix(owner_id, prefix, oldName, newName, oldN, newN, &adt->tmpact->curves, verify_paths); /* Drivers - Drivers are really F-Curves */ drivers_path_rename_fix(owner_id, ref_id, prefix, oldName, newName, oldN, newN, &adt->drivers, verify_paths); /* NLA Data - Animation Data for Strips */ for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next) - nlastrips_path_rename_fix(owner_id, prefix, oldN, newN, &nlt->strips, verify_paths); + nlastrips_path_rename_fix(owner_id, prefix, oldName, newName, oldN, newN, &nlt->strips, verify_paths); /* free the temp names */ MEM_freeN(oldN); diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index 04585791135..aa834ff131b 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -1551,7 +1551,7 @@ void BKE_armature_where_is(bArmature *arm) static void pose_proxy_synchronize(Object *ob, Object *from, int layer_protected) { bPose *pose = ob->pose, *frompose = from->pose; - bPoseChannel *pchan, *pchanp, pchanw; + bPoseChannel *pchan, *pchanp; bConstraint *con; int error = 0; @@ -1587,31 +1587,32 @@ static void pose_proxy_synchronize(Object *ob, Object *from, int layer_protected for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) { pchanp = BKE_pose_channel_find_name(frompose, pchan->name); - + if (UNLIKELY(pchanp == NULL)) { /* happens for proxies that become invalid because of a missing link * for regulat cases it shouldn't happen at all */ } else if (pchan->bone->layer & layer_protected) { ListBase proxylocal_constraints = {NULL, NULL}; - + bPoseChannel pchanw = {NULL}; + /* copy posechannel to temp, but restore important pointers */ pchanw = *pchanp; pchanw.prev = pchan->prev; pchanw.next = pchan->next; pchanw.parent = pchan->parent; pchanw.child = pchan->child; - + /* this is freed so copy a copy, else undo crashes */ if (pchanw.prop) { pchanw.prop = IDP_CopyProperty(pchanw.prop); - + /* use the values from the the existing props */ if (pchan->prop) { IDP_SyncGroupValues(pchanw.prop, pchan->prop); } } - + /* constraints - proxy constraints are flushed... local ones are added after * 1. extract constraints not from proxy (CONSTRAINT_PROXY_LOCAL) from pchan's constraints * 2. copy proxy-pchan's constraints on-to new @@ -1622,30 +1623,30 @@ static void pose_proxy_synchronize(Object *ob, Object *from, int layer_protected extract_proxylocal_constraints(&proxylocal_constraints, &pchan->constraints); copy_constraints(&pchanw.constraints, &pchanp->constraints, FALSE); BLI_movelisttolist(&pchanw.constraints, &proxylocal_constraints); - + /* constraints - set target ob pointer to own object */ for (con = pchanw.constraints.first; con; con = con->next) { bConstraintTypeInfo *cti = constraint_get_typeinfo(con); ListBase targets = {NULL, NULL}; bConstraintTarget *ct; - + if (cti && cti->get_constraint_targets) { cti->get_constraint_targets(con, &targets); - + for (ct = targets.first; ct; ct = ct->next) { if (ct->tar == from) ct->tar = ob; } - + if (cti->flush_constraint_targets) cti->flush_constraint_targets(con, &targets, 0); } } - + /* free stuff from current channel */ BKE_pose_channel_free(pchan); - - /* the final copy */ + + /* copy data in temp back over to the cleaned-out (but still allocated) original channel */ *pchan = pchanw; } else { diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index 06ba0b47587..02ce3a36b14 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -80,13 +80,10 @@ #include "BKE_sound.h" #include "RE_pipeline.h" - #include "BLO_undofile.h" #include "BLO_readfile.h" #include "BLO_writefile.h" -#include "BKE_utildefines.h" - #include "RNA_access.h" #include "WM_api.h" // XXXXX BAD, very BAD dependency (bad level call) - remove asap, elubie diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index 881caec8a58..b176ed429f8 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -50,7 +50,6 @@ #include "BKE_global.h" #include "BKE_mesh.h" #include "BKE_paint.h" -#include "BKE_utildefines.h" #include "BKE_tessmesh.h" #include "BKE_curve.h" diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 00130dd3583..391891d3985 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -4514,7 +4514,7 @@ static void con_relink_id_cb(bConstraint *UNUSED(con), ID **idpoin, short UNUSED * since we've got the actual ID block, let's just inline this * code. * - * See ID_NEW(a) in BKE_utildefines.h + * See ID_NEW(a) in DNA_ID.h */ if ((*idpoin) && (*idpoin)->newid) (*idpoin) = (void *)(*idpoin)->newid; diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index a00bea38e51..342ee5bba41 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -51,7 +51,6 @@ #include "BLI_mempool.h" #include "BLI_utildefines.h" -#include "BKE_utildefines.h" #include "BKE_customdata.h" #include "BKE_customdata_file.h" #include "BKE_global.h" diff --git a/source/blender/blenkernel/intern/customdata_file.c b/source/blender/blenkernel/intern/customdata_file.c index 71801c4729f..78449879f72 100644 --- a/source/blender/blenkernel/intern/customdata_file.c +++ b/source/blender/blenkernel/intern/customdata_file.c @@ -32,6 +32,7 @@ #include "BLI_fileops.h" #include "BLI_string.h" #include "BLI_utildefines.h" +#include "BLI_endian_switch.h" #include "BKE_customdata_file.h" #include "BKE_global.h" @@ -165,9 +166,9 @@ static int cdf_read_header(CDataFile *cdf) header->endian = cdf_endian(); if (cdf->switchendian) { - SWITCH_INT(header->type); - SWITCH_INT(header->totlayer); - SWITCH_INT(header->structbytes); + BLI_endian_switch_int32(&header->type); + BLI_endian_switch_int32(&header->totlayer); + BLI_endian_switch_int32(&header->structbytes); } if (!ELEM(header->type, CDF_TYPE_IMAGE, CDF_TYPE_MESH)) @@ -185,10 +186,10 @@ static int cdf_read_header(CDataFile *cdf) return 0; if (cdf->switchendian) { - SWITCH_INT(image->width); - SWITCH_INT(image->height); - SWITCH_INT(image->tile_size); - SWITCH_INT(image->structbytes); + BLI_endian_switch_int32(&image->width); + BLI_endian_switch_int32(&image->height); + BLI_endian_switch_int32(&image->tile_size); + BLI_endian_switch_int32(&image->structbytes); } offset += image->structbytes; @@ -200,7 +201,7 @@ static int cdf_read_header(CDataFile *cdf) return 0; if (cdf->switchendian) - SWITCH_INT(mesh->structbytes); + BLI_endian_switch_int32(&mesh->structbytes); offset += mesh->structbytes; mesh->structbytes = sizeof(CDataFileMeshHeader); @@ -219,10 +220,10 @@ static int cdf_read_header(CDataFile *cdf) return 0; if (cdf->switchendian) { - SWITCH_INT(layer->type); - SWITCH_INT(layer->datatype); - SWITCH_INT64(layer->datasize); - SWITCH_INT(layer->structbytes); + BLI_endian_switch_int32(&layer->type); + BLI_endian_switch_int32(&layer->datatype); + BLI_endian_switch_uint64(&layer->datasize); + BLI_endian_switch_int32(&layer->structbytes); } if (layer->datatype != CDF_DATA_FLOAT) @@ -317,20 +318,13 @@ int cdf_read_layer(CDataFile *cdf, CDataFileLayer *blay) int cdf_read_data(CDataFile *cdf, unsigned int size, void *data) { - float *fdata; - unsigned int a; - /* read data */ if (!fread(data, size, 1, cdf->readf)) return 0; /* switch endian if necessary */ if (cdf->switchendian) { - fdata = data; - - for (a = 0; a < size / sizeof(float); a++) { - SWITCH_INT(fdata[a]); - } + BLI_endian_switch_float_array(data, size / sizeof(float)); } return 1; diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index 1b53f8980cb..b8d5294eabc 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -75,7 +75,6 @@ #include "BKE_scene.h" #include "BKE_screen.h" #include "BKE_tracking.h" -#include "BKE_utildefines.h" #include "depsgraph_private.h" diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c index 53c12d32bc1..b78ab9b28cd 100644 --- a/source/blender/blenkernel/intern/fcurve.c +++ b/source/blender/blenkernel/intern/fcurve.c @@ -55,7 +55,6 @@ #include "BKE_curve.h" #include "BKE_global.h" #include "BKE_object.h" -#include "BKE_utildefines.h" #include "RNA_access.h" diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c index 0ffd68c9079..8b35974ea62 100644 --- a/source/blender/blenkernel/intern/font.c +++ b/source/blender/blenkernel/intern/font.c @@ -50,7 +50,6 @@ #include "DNA_scene_types.h" #include "DNA_object_types.h" -#include "BKE_utildefines.h" #include "BKE_packedFile.h" #include "BKE_library.h" #include "BKE_font.h" diff --git a/source/blender/blenkernel/intern/idprop.c b/source/blender/blenkernel/intern/idprop.c index 7456f9aab8b..8229df28ab8 100644 --- a/source/blender/blenkernel/intern/idprop.c +++ b/source/blender/blenkernel/intern/idprop.c @@ -293,18 +293,6 @@ static IDProperty *IDP_CopyArray(IDProperty *prop) return newp; } -/*taken from readfile.c*/ -#define SWITCH_LONGINT(a) { \ - char s_i, *p_i; \ - p_i = (char *)& (a); \ - s_i = p_i[0]; p_i[0] = p_i[7]; p_i[7] = s_i; \ - s_i = p_i[1]; p_i[1] = p_i[6]; p_i[6] = s_i; \ - s_i = p_i[2]; p_i[2] = p_i[5]; p_i[5] = s_i; \ - s_i = p_i[3]; p_i[3] = p_i[4]; p_i[4] = s_i; \ - } (void)0 - - - /* ---------- String Type ------------ */ IDProperty *IDP_NewString(const char *st, const char *name, int maxlen) { diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index 6d0a67f520f..987963273bb 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -81,7 +81,6 @@ #include "BKE_scene.h" #include "BKE_node.h" #include "BKE_sequencer.h" /* seq_foreground_frame_get() */ -#include "BKE_utildefines.h" #include "BLF_api.h" diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index 9f770e0a9a7..f099a79b520 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -107,7 +107,6 @@ #include "BKE_gpencil.h" #include "BKE_fcurve.h" #include "BKE_speaker.h" -#include "BKE_utildefines.h" #include "BKE_movieclip.h" #include "BKE_mask.h" diff --git a/source/blender/blenkernel/intern/mask_evaluate.c b/source/blender/blenkernel/intern/mask_evaluate.c index 065dc38c81e..4a8601df0b8 100644 --- a/source/blender/blenkernel/intern/mask_evaluate.c +++ b/source/blender/blenkernel/intern/mask_evaluate.c @@ -61,7 +61,6 @@ #include "BKE_sequencer.h" #include "BKE_tracking.h" #include "BKE_movieclip.h" -#include "BKE_utildefines.h" unsigned int BKE_mask_spline_resolution(MaskSpline *spline, int width, int height) diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c index eebcf12a799..a4fec1c0de4 100644 --- a/source/blender/blenkernel/intern/mball.c +++ b/source/blender/blenkernel/intern/mball.c @@ -157,7 +157,7 @@ struct pgn_elements { /* Forward declarations */ static int vertid(const CORNER *c1, const CORNER *c2, PROCESS *p, MetaBall *mb); -static int setcenter(CENTERLIST *table[], int i, int j, int k); +static int setcenter(CENTERLIST *table[], const int i, const int j, const int k); static CORNER *setcorner(PROCESS *p, int i, int j, int k); static void converge(const float p1[3], const float p2[3], float v1, float v2, float (*function)(float, float, float), float p[3], MetaBall *mb, int f); diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c index 50628ac857a..aa7388abd58 100644 --- a/source/blender/blenkernel/intern/movieclip.c +++ b/source/blender/blenkernel/intern/movieclip.c @@ -70,7 +70,6 @@ #include "BKE_library.h" #include "BKE_global.h" #include "BKE_main.h" -#include "BKE_utildefines.h" #include "BKE_movieclip.h" #include "BKE_image.h" /* openanim */ #include "BKE_tracking.h" diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 52b1e1b869c..ade418e409f 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -58,8 +58,6 @@ #include "BKE_library.h" #include "BKE_main.h" #include "BKE_node.h" -#include "BKE_utildefines.h" -#include "BKE_utildefines.h" #include "RNA_access.h" diff --git a/source/blender/blenkernel/intern/ocean.c b/source/blender/blenkernel/intern/ocean.c index 66b0cff691e..b862a824d50 100644 --- a/source/blender/blenkernel/intern/ocean.c +++ b/source/blender/blenkernel/intern/ocean.c @@ -37,8 +37,6 @@ #include "BKE_image.h" #include "BKE_ocean.h" -#include "BKE_utildefines.h" - #include "BKE_global.h" // XXX TESTING #include "BLI_math_base.h" diff --git a/source/blender/blenkernel/intern/packedFile.c b/source/blender/blenkernel/intern/packedFile.c index 9787a5025f7..03342d0f6d1 100644 --- a/source/blender/blenkernel/intern/packedFile.c +++ b/source/blender/blenkernel/intern/packedFile.c @@ -57,7 +57,6 @@ #include "BKE_packedFile.h" #include "BKE_report.h" #include "BKE_sound.h" -#include "BKE_utildefines.h" #ifdef _WIN32 #define open _open diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index 1588ec10b55..5e12b15a658 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -69,7 +69,6 @@ #include "BKE_scene.h" #include "BKE_smoke.h" #include "BKE_softbody.h" -#include "BKE_utildefines.h" #include "BIK_api.h" diff --git a/source/blender/blenkernel/intern/sca.c b/source/blender/blenkernel/intern/sca.c index c440d21f56d..7d9d2f02c06 100644 --- a/source/blender/blenkernel/intern/sca.c +++ b/source/blender/blenkernel/intern/sca.c @@ -44,7 +44,6 @@ #include "DNA_object_types.h" #include "BLI_blenlib.h" -#include "BKE_utildefines.h" #include "BKE_global.h" #include "BKE_main.h" #include "BKE_library.h" diff --git a/source/blender/blenkernel/intern/seqeffects.c b/source/blender/blenkernel/intern/seqeffects.c index 0abd3444c54..acf38ace00a 100644 --- a/source/blender/blenkernel/intern/seqeffects.c +++ b/source/blender/blenkernel/intern/seqeffects.c @@ -49,7 +49,6 @@ #include "BKE_main.h" #include "BKE_sequencer.h" #include "BKE_texture.h" -#include "BKE_utildefines.h" #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" diff --git a/source/blender/blenkernel/intern/seqmodifier.c b/source/blender/blenkernel/intern/seqmodifier.c index 70f27db0f74..0a195210e38 100644 --- a/source/blender/blenkernel/intern/seqmodifier.c +++ b/source/blender/blenkernel/intern/seqmodifier.c @@ -43,7 +43,6 @@ #include "BKE_colortools.h" #include "BKE_sequencer.h" -#include "BKE_utildefines.h" #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index dcf72c37f52..9aaa9fd79e8 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -62,7 +62,6 @@ #include "BKE_fcurve.h" #include "BKE_scene.h" #include "BKE_mask.h" -#include "BKE_utildefines.h" #include "RNA_access.h" diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c index 2462de07a18..f340bcb5b1e 100644 --- a/source/blender/blenkernel/intern/sound.c +++ b/source/blender/blenkernel/intern/sound.c @@ -50,7 +50,6 @@ # include "AUD_C-API.h" #endif -#include "BKE_utildefines.h" #include "BKE_global.h" #include "BKE_main.h" #include "BKE_sound.h" diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c index 2f54fe6cebd..ee904de4af6 100644 --- a/source/blender/blenkernel/intern/texture.c +++ b/source/blender/blenkernel/intern/texture.c @@ -56,7 +56,6 @@ #include "IMB_imbuf.h" -#include "BKE_utildefines.h" #include "BKE_global.h" #include "BKE_main.h" #include "BKE_ocean.h" diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index 78e7dab045f..2ed9d992c3f 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -411,6 +411,8 @@ void BKE_tracking_clipboard_free(void) track = next_track; } + + tracking_clipboard.tracks.first = tracking_clipboard.tracks.last = NULL; } void BKE_tracking_clipboard_copy_tracks(MovieTracking *tracking, MovieTrackingObject *object) -- cgit v1.2.3 From 3963425006ea738c93ca30b50cc0332dd522f0d9 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 5 Sep 2012 11:42:20 +0000 Subject: Merging r50374 through r50412 from trunk into soc-2011-tomato --- source/blender/blenkernel/intern/DerivedMesh.c | 26 ++-- source/blender/blenkernel/intern/armature.c | 30 ----- source/blender/blenkernel/intern/deform.c | 56 +++++++- source/blender/blenkernel/intern/image.c | 4 +- source/blender/blenkernel/intern/object_deform.c | 156 +++++++++++++++++++++++ source/blender/blenkernel/intern/seqmodifier.c | 36 ++---- source/blender/blenkernel/intern/sequencer.c | 36 +----- 7 files changed, 239 insertions(+), 105 deletions(-) create mode 100644 source/blender/blenkernel/intern/object_deform.c (limited to 'source/blender/blenkernel/intern') diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 1aa54307841..a7f8e1bb161 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -59,6 +59,7 @@ #include "BKE_modifier.h" #include "BKE_mesh.h" #include "BKE_object.h" +#include "BKE_object_deform.h" #include "BKE_paint.h" #include "BKE_texture.h" #include "BKE_multires.h" @@ -1015,14 +1016,14 @@ static void calc_weightpaint_vert_color( unsigned char r_col[4], MDeformVert *dv, ColorBand *coba, const int defbase_tot, const int defbase_act, - const char *dg_flags, - const int selected, const int draw_flag) + const char *defbase_sel, const int defbase_sel_tot, + const int draw_flag) { float input = 0.0f; int make_black = FALSE; - if ((selected > 1) && (draw_flag & CALC_WP_MULTIPAINT)) { + if ((defbase_sel_tot > 1) && (draw_flag & CALC_WP_MULTIPAINT)) { int was_a_nonzero = FALSE; unsigned int i; @@ -1031,7 +1032,7 @@ static void calc_weightpaint_vert_color( /* in multipaint, get the average if auto normalize is inactive * get the sum if it is active */ if (dw->def_nr < defbase_tot) { - if (dg_flags[dw->def_nr]) { + if (defbase_sel[dw->def_nr]) { if (dw->weight) { input += dw->weight; was_a_nonzero = TRUE; @@ -1045,7 +1046,7 @@ static void calc_weightpaint_vert_color( make_black = TRUE; } else if ((draw_flag & CALC_WP_AUTO_NORMALIZE) == FALSE) { - input /= selected; /* get the average */ + input /= defbase_sel_tot; /* get the average */ } } else { @@ -1090,14 +1091,21 @@ static unsigned char *calc_weightpaint_vert_array(Object *ob, DerivedMesh *dm, i /* variables for multipaint */ const int defbase_tot = BLI_countlist(&ob->defbase); const int defbase_act = ob->actdef - 1; - char *dg_flags = MEM_mallocN(defbase_tot * sizeof(char), __func__); - const int selected = get_selected_defgroups(ob, dg_flags, defbase_tot); + + int defbase_sel_tot = 0; + char *defbase_sel = NULL; + + if (draw_flag & CALC_WP_MULTIPAINT) { + defbase_sel = BKE_objdef_selected_get(ob, defbase_tot, &defbase_sel_tot); + } for (i = numVerts; i != 0; i--, wc += 4, dv++) { - calc_weightpaint_vert_color(wc, dv, coba, defbase_tot, defbase_act, dg_flags, selected, draw_flag); + calc_weightpaint_vert_color(wc, dv, coba, defbase_tot, defbase_act, defbase_sel, defbase_sel_tot, draw_flag); } - MEM_freeN(dg_flags); + if (defbase_sel) { + MEM_freeN(defbase_sel); + } } else { int col_i; diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index aa834ff131b..b87342f85fa 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -2517,36 +2517,6 @@ void BKE_pose_where_is(Scene *scene, Object *ob) } } - -/* Returns total selected vgroups, - * wpi.defbase_sel is assumed malloc'd, all values are set */ -int get_selected_defgroups(Object *ob, char *dg_selection, int defbase_tot) -{ - bDeformGroup *defgroup; - unsigned int i; - Object *armob = BKE_object_pose_armature_get(ob); - int dg_flags_sel_tot = 0; - - if (armob) { - bPose *pose = armob->pose; - for (i = 0, defgroup = ob->defbase.first; i < defbase_tot && defgroup; defgroup = defgroup->next, i++) { - bPoseChannel *pchan = BKE_pose_channel_find_name(pose, defgroup->name); - if (pchan && (pchan->bone->flag & BONE_SELECTED)) { - dg_selection[i] = TRUE; - dg_flags_sel_tot++; - } - else { - dg_selection[i] = FALSE; - } - } - } - else { - memset(dg_selection, FALSE, sizeof(char) * defbase_tot); - } - - return dg_flags_sel_tot; -} - /************** Bounding box ********************/ static int minmax_armature(Object *ob, float r_min[3], float r_max[3]) { diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c index 547a64a70d4..4110d4565b2 100644 --- a/source/blender/blenkernel/intern/deform.c +++ b/source/blender/blenkernel/intern/deform.c @@ -33,6 +33,7 @@ #include #include #include +#include #include "MEM_guardedalloc.h" @@ -41,7 +42,10 @@ #include "BKE_deform.h" -#include "BLI_blenlib.h" +#include "BLI_listbase.h" +#include "BLI_math.h" +#include "BLI_path_util.h" +#include "BLI_string.h" #include "BLI_utildefines.h" @@ -204,13 +208,15 @@ void defvert_normalize(MDeformVert *dvert) } } -void defvert_normalize_lock(MDeformVert *dvert, const int def_nr_lock) +void defvert_normalize_lock_single(MDeformVert *dvert, const int def_nr_lock) { if (dvert->totweight <= 0) { /* nothing */ } else if (dvert->totweight == 1) { - dvert->dw[0].weight = 1.0f; + if (def_nr_lock != 0) { + dvert->dw[0].weight = 1.0f; + } } else { MDeformWeight *dw_lock = NULL; @@ -246,6 +252,50 @@ void defvert_normalize_lock(MDeformVert *dvert, const int def_nr_lock) } } +void defvert_normalize_lock_map(MDeformVert *dvert, const char *lock_flags, const int defbase_tot) +{ + if (dvert->totweight <= 0) { + /* nothing */ + } + else if (dvert->totweight == 1) { + if (LIKELY(defbase_tot >= 1) && lock_flags[0]) { + dvert->dw[0].weight = 1.0f; + } + } + else { + MDeformWeight *dw; + unsigned int i; + float tot_weight = 0.0f; + float lock_iweight = 0.0f; + + for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) { + if ((dw->def_nr < defbase_tot) && (lock_flags[dw->def_nr] == FALSE)) { + tot_weight += dw->weight; + } + else { + /* invert after */ + lock_iweight += dw->weight; + } + } + + lock_iweight = maxf(0.0f, 1.0f - lock_iweight); + + if (tot_weight > 0.0f) { + /* paranoid, should be 1.0 but in case of float error clamp anyway */ + + float scalar = (1.0f / tot_weight) * lock_iweight; + for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) { + if ((dw->def_nr < defbase_tot) && (lock_flags[dw->def_nr] == FALSE)) { + dw->weight *= scalar; + + /* in case of division errors with very low weights */ + CLAMP(dw->weight, 0.0f, 1.0f); + } + } + } + } +} + void defvert_flip(MDeformVert *dvert, const int *flip_map, const int flip_map_len) { MDeformWeight *dw; diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index 987963273bb..a0839a502b7 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -2548,7 +2548,9 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **lock_ dither = iuser->scene->r.dither_intensity; /* combined layer gets added as first layer */ - if (rres.have_combined && layer == 0) ; + if (rres.have_combined && layer == 0) { + /* pass */ + } else if (rres.layers.first) { RenderLayer *rl = BLI_findlink(&rres.layers, layer - (rres.have_combined ? 1 : 0)); if (rl) { diff --git a/source/blender/blenkernel/intern/object_deform.c b/source/blender/blenkernel/intern/object_deform.c new file mode 100644 index 00000000000..7f9578250f2 --- /dev/null +++ b/source/blender/blenkernel/intern/object_deform.c @@ -0,0 +1,156 @@ +/* + * ***** 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 ***** + */ + +/** \file blender/blenkernel/intern/object_deform.c + * \ingroup bke + */ + +#include +#include + +#include "MEM_guardedalloc.h" + +#include "BLI_utildefines.h" +#include "BLI_ghash.h" + +#include "BKE_action.h" +#include "BKE_object_deform.h" /* own include */ +#include "BKE_object.h" +#include "BKE_modifier.h" + +#include "DNA_armature_types.h" +#include "DNA_modifier_types.h" +#include "DNA_object_types.h" + +/* --- functions for getting vgroup aligned maps --- */ + +/** + * gets the status of "flag" for each bDeformGroup + * in ob->defbase and returns an array containing them + */ +char *BKE_objdef_lock_flags_get(Object *ob, const int defbase_tot) +{ + char is_locked = FALSE; + int i; + //int defbase_tot = BLI_countlist(&ob->defbase); + char *lock_flags = MEM_mallocN(defbase_tot * sizeof(char), "defflags"); + bDeformGroup *defgroup; + + for (i = 0, defgroup = ob->defbase.first; i < defbase_tot && defgroup; defgroup = defgroup->next, i++) { + lock_flags[i] = ((defgroup->flag & DG_LOCK_WEIGHT) != 0); + is_locked |= lock_flags[i]; + } + if (is_locked) { + return lock_flags; + } + + MEM_freeN(lock_flags); + return NULL; +} + +char *BKE_objdef_validmap_get(Object *ob, const int defbase_tot) +{ + bDeformGroup *dg; + ModifierData *md; + char *vgroup_validmap; + GHash *gh; + int i, step1 = 1; + //int defbase_tot = BLI_countlist(&ob->defbase); + + if (ob->defbase.first == NULL) { + return NULL; + } + + gh = BLI_ghash_str_new("BKE_objdef_validmap_get gh"); + + /* add all names to a hash table */ + for (dg = ob->defbase.first; dg; dg = dg->next) { + BLI_ghash_insert(gh, dg->name, NULL); + } + + BLI_assert(BLI_ghash_size(gh) == defbase_tot); + + /* now loop through the armature modifiers and identify deform bones */ + for (md = ob->modifiers.first; md; md = !md->next && step1 ? (step1 = 0), modifiers_getVirtualModifierList(ob) : md->next) { + if (!(md->mode & (eModifierMode_Realtime | eModifierMode_Virtual))) + continue; + + if (md->type == eModifierType_Armature) { + ArmatureModifierData *amd = (ArmatureModifierData *) md; + + if (amd->object && amd->object->pose) { + bPose *pose = amd->object->pose; + bPoseChannel *chan; + + for (chan = pose->chanbase.first; chan; chan = chan->next) { + if (chan->bone->flag & BONE_NO_DEFORM) + continue; + + if (BLI_ghash_remove(gh, chan->name, NULL, NULL)) { + BLI_ghash_insert(gh, chan->name, SET_INT_IN_POINTER(1)); + } + } + } + } + } + + vgroup_validmap = MEM_mallocN(defbase_tot, "wpaint valid map"); + + /* add all names to a hash table */ + for (dg = ob->defbase.first, i = 0; dg; dg = dg->next, i++) { + vgroup_validmap[i] = (BLI_ghash_lookup(gh, dg->name) != NULL); + } + + BLI_assert(i == BLI_ghash_size(gh)); + + BLI_ghash_free(gh, NULL, NULL); + + return vgroup_validmap; +} + +/* Returns total selected vgroups, + * wpi.defbase_sel is assumed malloc'd, all values are set */ +char *BKE_objdef_selected_get(Object *ob, int defbase_tot, int *r_dg_flags_sel_tot) +{ + char *dg_selection = MEM_mallocN(defbase_tot * sizeof(char), __func__); + bDeformGroup *defgroup; + unsigned int i; + Object *armob = BKE_object_pose_armature_get(ob); + (*r_dg_flags_sel_tot) = 0; + + if (armob) { + bPose *pose = armob->pose; + for (i = 0, defgroup = ob->defbase.first; i < defbase_tot && defgroup; defgroup = defgroup->next, i++) { + bPoseChannel *pchan = BKE_pose_channel_find_name(pose, defgroup->name); + if (pchan && (pchan->bone->flag & BONE_SELECTED)) { + dg_selection[i] = TRUE; + (*r_dg_flags_sel_tot) += 1; + } + else { + dg_selection[i] = FALSE; + } + } + } + else { + memset(dg_selection, FALSE, sizeof(char) * defbase_tot); + } + + return dg_selection; +} diff --git a/source/blender/blenkernel/intern/seqmodifier.c b/source/blender/blenkernel/intern/seqmodifier.c index 0a195210e38..6028b40756d 100644 --- a/source/blender/blenkernel/intern/seqmodifier.c +++ b/source/blender/blenkernel/intern/seqmodifier.c @@ -154,14 +154,11 @@ void colorBalance_init_data(SequenceModifierData *smd) } } -ImBuf *colorBalance_apply(SequenceModifierData *smd, ImBuf *ibuf, ImBuf *mask) +void colorBalance_apply(SequenceModifierData *smd, ImBuf *ibuf, ImBuf *mask) { ColorBalanceModifierData *cbmd = (ColorBalanceModifierData *) smd; - ImBuf *ibuf_new = IMB_dupImBuf(ibuf); - BKE_sequencer_color_balance_apply(&cbmd->color_balance, ibuf_new, cbmd->color_multiply, FALSE, mask); - - return ibuf_new; + BKE_sequencer_color_balance_apply(&cbmd->color_balance, ibuf, cbmd->color_multiply, FALSE, mask); } static SequenceModifierTypeInfo seqModifier_ColorBalance = { @@ -252,10 +249,9 @@ void curves_apply_threaded(int width, int height, unsigned char *rect, float *re } } -ImBuf *curves_apply(struct SequenceModifierData *smd, ImBuf *ibuf, ImBuf *mask) +void curves_apply(struct SequenceModifierData *smd, ImBuf *ibuf, ImBuf *mask) { CurvesModifierData *cmd = (CurvesModifierData *) smd; - ImBuf *ibuf_new = IMB_dupImBuf(ibuf); float black[3] = {0.0f, 0.0f, 0.0f}; float white[3] = {1.0f, 1.0f, 1.0f}; @@ -265,11 +261,9 @@ ImBuf *curves_apply(struct SequenceModifierData *smd, ImBuf *ibuf, ImBuf *mask) curvemapping_premultiply(&cmd->curve_mapping, 0); curvemapping_set_black_white(&cmd->curve_mapping, black, white); - modifier_apply_threaded(ibuf_new, mask, curves_apply_threaded, &cmd->curve_mapping); + modifier_apply_threaded(ibuf, mask, curves_apply_threaded, &cmd->curve_mapping); curvemapping_premultiply(&cmd->curve_mapping, 1); - - return ibuf_new; } static SequenceModifierTypeInfo seqModifier_Curves = { @@ -371,16 +365,13 @@ void hue_correct_apply_threaded(int width, int height, unsigned char *rect, floa } } -ImBuf *hue_correct_apply(struct SequenceModifierData *smd, ImBuf *ibuf, ImBuf *mask) +void hue_correct_apply(struct SequenceModifierData *smd, ImBuf *ibuf, ImBuf *mask) { HueCorrectModifierData *hcmd = (HueCorrectModifierData *) smd; - ImBuf *ibuf_new = IMB_dupImBuf(ibuf); curvemapping_initialize(&hcmd->curve_mapping); - modifier_apply_threaded(ibuf_new, mask, hue_correct_apply_threaded, &hcmd->curve_mapping); - - return ibuf_new; + modifier_apply_threaded(ibuf, mask, hue_correct_apply_threaded, &hcmd->curve_mapping); } static SequenceModifierTypeInfo seqModifier_HueCorrect = { @@ -469,18 +460,15 @@ void brightcontrast_apply_threaded(int width, int height, unsigned char *rect, f } } -ImBuf *brightcontrast_apply(struct SequenceModifierData *smd, ImBuf *ibuf, ImBuf *mask) +void brightcontrast_apply(struct SequenceModifierData *smd, ImBuf *ibuf, ImBuf *mask) { BrightContrastModifierData *bcmd = (BrightContrastModifierData *) smd; BrightContrastThreadData data; - ImBuf *ibuf_new = IMB_dupImBuf(ibuf); data.bright = bcmd->bright; data.contrast = bcmd->contrast; - modifier_apply_threaded(ibuf_new, mask, brightcontrast_apply_threaded, &data); - - return ibuf_new; + modifier_apply_threaded(ibuf, mask, brightcontrast_apply_threaded, &data); } static SequenceModifierTypeInfo seqModifier_BrightContrast = { @@ -595,7 +583,6 @@ ImBuf *BKE_sequence_modifier_apply_stack(SeqRenderData context, Sequence *seq, I for (smd = seq->modifiers.first; smd; smd = smd->next) { SequenceModifierTypeInfo *smti = BKE_sequence_modifier_type_info_get(smd->type); - ImBuf *ibuf_new; /* could happen if modifier is being removed or not exists in current version of blender */ if (!smti) @@ -611,12 +598,7 @@ ImBuf *BKE_sequence_modifier_apply_stack(SeqRenderData context, Sequence *seq, I if (processed_ibuf == ibuf) processed_ibuf = IMB_dupImBuf(ibuf); - ibuf_new = smti->apply(smd, processed_ibuf, mask); - - if (ibuf_new != processed_ibuf) { - IMB_freeImBuf(processed_ibuf); - processed_ibuf = ibuf_new; - } + smti->apply(smd, processed_ibuf, mask); if (mask) IMB_freeImBuf(mask); diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index 9aaa9fd79e8..0ac0db50fb5 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -166,9 +166,6 @@ static void seq_free_strip(Strip *strip) if (strip->transform) { MEM_freeN(strip->transform); } - if (strip->color_balance) { - MEM_freeN(strip->color_balance); - } MEM_freeN(strip); } @@ -1671,26 +1668,6 @@ void BKE_sequencer_color_balance_apply(StripColorBalance *cb, ImBuf *ibuf, float imb_freerectImBuf(ibuf); } -static void sequence_color_balance(SeqRenderData context, Sequence *seq, ImBuf *ibuf, float mul, int cfra) -{ - StripColorBalance *cb = seq->strip->color_balance; - ImBuf *mask_input = NULL; - short make_float = seq->flag & SEQ_MAKE_FLOAT; - - if (seq->mask_sequence) { - if (seq->mask_sequence != seq && !BKE_sequence_check_depend(seq, seq->mask_sequence)) { - int make_float = ibuf->rect_float != NULL; - - mask_input = BKE_sequencer_render_mask_input(context, SEQUENCE_MASK_INPUT_STRIP, seq->mask_sequence, NULL, cfra, make_float); - } - } - - BKE_sequencer_color_balance_apply(cb, ibuf, mul, make_float, mask_input); - - if (mask_input) - IMB_freeImBuf(mask_input); -} - /* * input preprocessing for SEQ_TYPE_IMAGE, SEQ_TYPE_MOVIE, SEQ_TYPE_MOVIECLIP and SEQ_TYPE_SCENE * @@ -1713,9 +1690,7 @@ int BKE_sequencer_input_have_to_preprocess(SeqRenderData UNUSED(context), Sequen { float mul; - if (seq->flag & (SEQ_FILTERY | SEQ_USE_CROP | SEQ_USE_TRANSFORM | SEQ_FLIPX | - SEQ_FLIPY | SEQ_USE_COLOR_BALANCE | SEQ_MAKE_PREMUL | SEQ_MAKE_FLOAT)) - { + if (seq->flag & (SEQ_FILTERY | SEQ_USE_CROP | SEQ_USE_TRANSFORM | SEQ_FLIPX | SEQ_FLIPY | SEQ_MAKE_PREMUL | SEQ_MAKE_FLOAT)) { return TRUE; } @@ -1834,11 +1809,6 @@ static ImBuf *input_preprocess(SeqRenderData context, Sequence *seq, float cfra, mul *= seq->blend_opacity / 100.0f; } - if (seq->flag & SEQ_USE_COLOR_BALANCE && seq->strip->color_balance) { - sequence_color_balance(context, seq, ibuf, mul, cfra); - mul = 1.0; - } - if (seq->flag & SEQ_MAKE_FLOAT) { if (!ibuf->rect_float) { IMB_colormanagement_imbuf_to_sequencer_space(ibuf, TRUE); @@ -4020,10 +3990,6 @@ static Sequence *seq_dupli(Scene *scene, Scene *scene_to, Sequence *seq, int dup seqn->strip->proxy->anim = NULL; } - if (seq->strip->color_balance) { - seqn->strip->color_balance = MEM_dupallocN(seq->strip->color_balance); - } - if (seqn->modifiers.first) { seqn->modifiers.first = seqn->modifiers.last = NULL; -- cgit v1.2.3 From ee5bf889e9e00c93e5790a38cfe90af39b7b2423 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 5 Sep 2012 16:08:36 +0000 Subject: Color Management: RGB curves transform as a part of display transform This replaces per-image editor curve mapping which didn't behave properly (it was possible to open the same image in two image editors and setup different curves in this editors, but only last changed curve was applied on image) After discussion with Brecht decided to have something which works reliable and predictable and ended up with adding RGB curves as a part of display transform, which is applied before OCIO processor (to match old behavior). Setting white/black values from image editor (Ctrl/Shift + LMB) would affect on scene settings. This could break compatibility, but there's no reliable way to convert old semi-working settings into new one. --- source/blender/blenkernel/intern/colortools.c | 11 +++++++++++ source/blender/blenkernel/intern/scene.c | 2 ++ 2 files changed, 13 insertions(+) (limited to 'source/blender/blenkernel/intern') diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c index 252add2c423..65bffe42a1e 100644 --- a/source/blender/blenkernel/intern/colortools.c +++ b/source/blender/blenkernel/intern/colortools.c @@ -175,6 +175,7 @@ void curvemapping_set_black_white(CurveMapping *cumap, const float black[3], con } curvemapping_set_black_white_ex(cumap->black, cumap->white, cumap->bwmul); + cumap->changed_timestamp++; } /* ***************** operations on single curve ************* */ @@ -1289,8 +1290,18 @@ void BKE_color_managed_view_settings_copy(ColorManagedViewSettings *new_settings { BLI_strncpy(new_settings->view_transform, settings->view_transform, sizeof(new_settings->view_transform)); + new_settings->flag = settings->flag; new_settings->exposure = settings->exposure; new_settings->gamma = settings->gamma; + + if (settings->curve_mapping) + new_settings->curve_mapping = curvemapping_copy(settings->curve_mapping); +} + +void BKE_color_managed_view_settings_free(ColorManagedViewSettings *settings) +{ + if (settings->curve_mapping) + curvemapping_free(settings->curve_mapping); } void BKE_color_managed_colorspace_settings_init(ColorManagedColorspaceSettings *colorspace_settings) diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index e74413c3198..1bd8f3dfcd2 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -342,6 +342,8 @@ void BKE_scene_free(Scene *sce) MEM_freeN(sce->fps_info); sound_destroy_scene(sce); + + BKE_color_managed_view_settings_free(&sce->view_settings); } Scene *BKE_scene_add(const char *name) -- cgit v1.2.3 From 0b778a902691b4421067f7826bb6e0b6a4d8cec5 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 6 Sep 2012 09:44:32 +0000 Subject: Merging r50423 through r50449 from trunk into soc-2011-tomato --- source/blender/blenkernel/intern/library.c | 2 +- source/blender/blenkernel/intern/mball.c | 33 +++++++++++---------- source/blender/blenkernel/intern/sequencer.c | 41 ++++++++++++++++++-------- source/blender/blenkernel/intern/shrinkwrap.c | 4 +-- source/blender/blenkernel/intern/writeffmpeg.c | 18 +++++++---- 5 files changed, 63 insertions(+), 35 deletions(-) (limited to 'source/blender/blenkernel/intern') diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index f099a79b520..f8c1a35776a 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -862,7 +862,7 @@ void BKE_libblock_free(ListBase *lb, void *idv) BKE_text_free((Text *)id); break; case ID_SCRIPT: - //XXX free_script((Script *)id); + /* deprecated */ break; case ID_SPK: BKE_speaker_free((Speaker *)id); diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c index a4fec1c0de4..3925c3cc858 100644 --- a/source/blender/blenkernel/intern/mball.c +++ b/source/blender/blenkernel/intern/mball.c @@ -640,21 +640,6 @@ static float densfunc(MetaElem *ball, float x, float y, float z) case MB_BALL: /* do nothing */ break; - case MB_TUBEX: - if (dvec[0] > ball->len) dvec[0] -= ball->len; - else if (dvec[0] < -ball->len) dvec[0] += ball->len; - else dvec[0] = 0.0; - break; - case MB_TUBEY: - if (dvec[1] > ball->len) dvec[1] -= ball->len; - else if (dvec[1] < -ball->len) dvec[1] += ball->len; - else dvec[1] = 0.0; - break; - case MB_TUBEZ: - if (dvec[2] > ball->len) dvec[2] -= ball->len; - else if (dvec[2] < -ball->len) dvec[2] += ball->len; - else dvec[2] = 0.0; - break; case MB_TUBE: if (dvec[0] > ball->expx) dvec[0] -= ball->expx; else if (dvec[0] < -ball->expx) dvec[0] += ball->expx; @@ -686,6 +671,24 @@ static float densfunc(MetaElem *ball, float x, float y, float z) else if (dvec[2] < -ball->expz) dvec[2] += ball->expz; else dvec[2] = 0.0; break; + + /* *** deprecated, could be removed?, do-versioned at least *** */ + case MB_TUBEX: + if (dvec[0] > ball->len) dvec[0] -= ball->len; + else if (dvec[0] < -ball->len) dvec[0] += ball->len; + else dvec[0] = 0.0; + break; + case MB_TUBEY: + if (dvec[1] > ball->len) dvec[1] -= ball->len; + else if (dvec[1] < -ball->len) dvec[1] += ball->len; + else dvec[1] = 0.0; + break; + case MB_TUBEZ: + if (dvec[2] > ball->len) dvec[2] -= ball->len; + else if (dvec[2] < -ball->len) dvec[2] += ball->len; + else dvec[2] = 0.0; + break; + /* *** end deprecated *** */ } dist2 = 1.0f - (len_v3(dvec) / ball->rad2); diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index 0ac0db50fb5..611b175c9ef 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -170,7 +170,8 @@ static void seq_free_strip(Strip *strip) MEM_freeN(strip); } -void BKE_sequence_free(Scene *scene, Sequence *seq) +/* only give option to skip cache locally (static func) */ +static void BKE_sequence_free_ex(Scene *scene, Sequence *seq, const int do_cache) { if (seq->strip) seq_free_strip(seq->strip); @@ -206,21 +207,37 @@ void BKE_sequence_free(Scene *scene, Sequence *seq) /* free cached data used by this strip, * also invalidate cache for all dependent sequences + * + * be _very_ careful here, invalidating cache loops over the scene sequences and + * assumes the listbase is valid for all strips, this may not be the case if lists are being freed. + * this is optional BKE_sequence_invalidate_cache */ - BKE_sequence_invalidate_cache(scene, seq); + if (do_cache) { + if (scene) { + BKE_sequence_invalidate_cache(scene, seq); + } + } MEM_freeN(seq); } +void BKE_sequence_free(Scene *scene, Sequence *seq) +{ + BKE_sequence_free_ex(scene, seq, TRUE); +} + +/* cache must be freed before calling this function + * since it leaves the seqbase in an invalid state */ static void seq_free_sequence_recurse(Scene *scene, Sequence *seq) { - Sequence *iseq; + Sequence *iseq, *iseq_next; - for (iseq = seq->seqbase.first; iseq; iseq = iseq->next) { + for (iseq = seq->seqbase.first; iseq; iseq = iseq_next) { + iseq_next = iseq->next; seq_free_sequence_recurse(scene, iseq); } - BKE_sequence_free(scene, seq); + BKE_sequence_free_ex(scene, seq, FALSE); } @@ -241,7 +258,7 @@ static void seq_free_clipboard_recursive(Sequence *seq_parent) seq_free_clipboard_recursive(seq); } - BKE_sequence_free(NULL, seq_parent); + BKE_sequence_free_ex(NULL, seq_parent, FALSE); } void BKE_sequencer_free_clipboard(void) @@ -270,22 +287,22 @@ Editing *BKE_sequencer_editing_ensure(Scene *scene) void BKE_sequencer_editing_free(Scene *scene) { Editing *ed = scene->ed; - MetaStack *ms; Sequence *seq; if (ed == NULL) return; + /* this may not be the active scene!, could be smarter about this */ + BKE_sequencer_cache_cleanup(); + SEQ_BEGIN (ed, seq) { - BKE_sequence_free(scene, seq); + /* handle cache freeing above */ + BKE_sequence_free_ex(scene, seq, FALSE); } SEQ_END - while ((ms = ed->metastack.first)) { - BLI_remlink(&ed->metastack, ms); - MEM_freeN(ms); - } + BLI_freelistN(&ed->metastack); MEM_freeN(ed); diff --git a/source/blender/blenkernel/intern/shrinkwrap.c b/source/blender/blenkernel/intern/shrinkwrap.c index f9399946570..9a8bcaabe0c 100644 --- a/source/blender/blenkernel/intern/shrinkwrap.c +++ b/source/blender/blenkernel/intern/shrinkwrap.c @@ -313,7 +313,7 @@ static void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc) auxMesh = object_get_derived_final(calc->smd->auxTarget); if (!auxMesh) return; - space_transform_setup(&local2aux, calc->ob, calc->smd->auxTarget); + SPACE_TRANSFORM_SETUP(&local2aux, calc->ob, calc->smd->auxTarget); } //After sucessufuly build the trees, start projection vertexs @@ -500,7 +500,7 @@ void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd, Object *ob, DerivedM //TODO there might be several "bugs" on non-uniform scales matrixs //because it will no longer be nearest surface, not sphere projection //because space has been deformed - space_transform_setup(&calc.local2target, ob, smd->target); + SPACE_TRANSFORM_SETUP(&calc.local2target, ob, smd->target); //TODO: smd->keepDist is in global units.. must change to local calc.keepDist = smd->keepDist; diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c index 3526058e12b..cd07ac3b9ed 100644 --- a/source/blender/blenkernel/intern/writeffmpeg.c +++ b/source/blender/blenkernel/intern/writeffmpeg.c @@ -946,6 +946,7 @@ int BKE_ffmpeg_start(struct Scene *scene, RenderData *rd, int rectx, int recty, } void BKE_ffmpeg_end(void); +static void end_ffmpeg_impl(int is_autosplit); #ifdef WITH_AUDASPACE static void write_audio_frames(double to_pts) @@ -978,7 +979,7 @@ int BKE_ffmpeg_append(RenderData *rd, int start_frame, int frame, int *pixels, i if (ffmpeg_autosplit) { if (avio_tell(outfile->pb) > FFMPEG_AUTOSPLIT_SIZE) { - BKE_ffmpeg_end(); + end_ffmpeg_impl(TRUE); ffmpeg_autosplit_count++; success &= start_ffmpeg_impl(rd, rectx, recty, reports); } @@ -991,7 +992,7 @@ int BKE_ffmpeg_append(RenderData *rd, int start_frame, int frame, int *pixels, i return success; } -void BKE_ffmpeg_end(void) +static void end_ffmpeg_impl(int is_autosplit) { unsigned int i; @@ -1004,9 +1005,11 @@ void BKE_ffmpeg_end(void) #endif #ifdef WITH_AUDASPACE - if (audio_mixdown_device) { - AUD_closeReadDevice(audio_mixdown_device); - audio_mixdown_device = 0; + if (is_autosplit == FALSE) { + if (audio_mixdown_device) { + AUD_closeReadDevice(audio_mixdown_device); + audio_mixdown_device = 0; + } } #endif @@ -1069,6 +1072,11 @@ void BKE_ffmpeg_end(void) } } +void BKE_ffmpeg_end(void) +{ + end_ffmpeg_impl(FALSE); +} + /* properties */ void BKE_ffmpeg_property_del(RenderData *rd, void *type, void *prop_) -- cgit v1.2.3 From 37a70492d145971e9b9800ac89e4a9b72d621d93 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Sat, 8 Sep 2012 10:17:42 +0000 Subject: Merging r50470 through r50477 from trunk into soc-2011-tomato --- source/blender/blenkernel/intern/implicit.c | 4 +-- source/blender/blenkernel/intern/text.c | 3 +- source/blender/blenkernel/intern/writeffmpeg.c | 39 +++++++++++++++++--------- 3 files changed, 30 insertions(+), 16 deletions(-) (limited to 'source/blender/blenkernel/intern') diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index 616214c21ff..1c6974b2615 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -193,7 +193,7 @@ DO_INLINE lfVector *create_lfvector(unsigned int verts) DO_INLINE void del_lfvector(float (*fLongVector)[3]) { if (fLongVector != NULL) { - MEM_freeN (fLongVector); + MEM_freeN(fLongVector); // cloth_aligned_free(&MEMORY_BASE, fLongVector); } } @@ -523,7 +523,7 @@ DO_INLINE fmatrix3x3 *create_bfmatrix(unsigned int verts, unsigned int springs) DO_INLINE void del_bfmatrix(fmatrix3x3 *matrix) { if (matrix != NULL) { - MEM_freeN (matrix); + MEM_freeN(matrix); } } diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c index 7de5f97588b..787def5c20b 100644 --- a/source/blender/blenkernel/intern/text.c +++ b/source/blender/blenkernel/intern/text.c @@ -1684,7 +1684,8 @@ void txt_print_undo(Text *text) printf("%c%c%c", text->undo_buf[i], text->undo_buf[i + 1], text->undo_buf[i + 2]); i += 3; break; - case UNDO_INSERT_4: case UNDO_BS_4: case UNDO_DEL_4: { + case UNDO_INSERT_4: case UNDO_BS_4: case UNDO_DEL_4: + { unsigned int uc; char c[BLI_UTF8_MAX + 1]; size_t c_len; diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c index cd07ac3b9ed..bd25ff8c6e6 100644 --- a/source/blender/blenkernel/intern/writeffmpeg.c +++ b/source/blender/blenkernel/intern/writeffmpeg.c @@ -177,58 +177,71 @@ static AVFrame *alloc_picture(int pix_fmt, int width, int height) static const char **get_file_extensions(int format) { switch (format) { - case FFMPEG_DV: { + case FFMPEG_DV: + { static const char *rv[] = { ".dv", NULL }; return rv; } - case FFMPEG_MPEG1: { + case FFMPEG_MPEG1: + { static const char *rv[] = { ".mpg", ".mpeg", NULL }; return rv; } - case FFMPEG_MPEG2: { + case FFMPEG_MPEG2: + { static const char *rv[] = { ".dvd", ".vob", ".mpg", ".mpeg", NULL }; return rv; } - case FFMPEG_MPEG4: { + case FFMPEG_MPEG4: + { static const char *rv[] = { ".mp4", ".mpg", ".mpeg", NULL }; return rv; } - case FFMPEG_AVI: { + case FFMPEG_AVI: + { static const char *rv[] = { ".avi", NULL }; return rv; } - case FFMPEG_MOV: { + case FFMPEG_MOV: + { static const char *rv[] = { ".mov", NULL }; return rv; } - case FFMPEG_H264: { + case FFMPEG_H264: + { /* FIXME: avi for now... */ static const char *rv[] = { ".avi", NULL }; return rv; } - case FFMPEG_XVID: { + case FFMPEG_XVID: + { /* FIXME: avi for now... */ static const char *rv[] = { ".avi", NULL }; return rv; } - case FFMPEG_FLV: { + case FFMPEG_FLV: + { static const char *rv[] = { ".flv", NULL }; return rv; } - case FFMPEG_MKV: { + case FFMPEG_MKV: + { static const char *rv[] = { ".mkv", NULL }; return rv; } - case FFMPEG_OGG: { + case FFMPEG_OGG: + { static const char *rv[] = { ".ogg", ".ogv", NULL }; return rv; } - case FFMPEG_MP3: { + case FFMPEG_MP3: + { static const char *rv[] = { ".mp3", NULL }; return rv; } - case FFMPEG_WAV: { + case FFMPEG_WAV: + { static const char *rv[] = { ".wav", NULL }; return rv; } -- cgit v1.2.3 From f1a498acee1697a385992a0f01bfdc17dc64163d Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Sun, 9 Sep 2012 08:33:42 +0000 Subject: Merging r50478 through r50483 from trunk into soc-2011-tomato --- source/blender/blenkernel/intern/action.c | 2 +- source/blender/blenkernel/intern/blender.c | 68 +++++++++++++++++++-------- source/blender/blenkernel/intern/constraint.c | 4 +- 3 files changed, 51 insertions(+), 23 deletions(-) (limited to 'source/blender/blenkernel/intern') diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index 6a8ddd8e00a..3e5dff74f3b 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -810,7 +810,7 @@ void framechange_poses_clear_unkeyed(void) /* TODO: proxies may/may not be correctly handled here... (this needs checking) */ for (ob = G.main->object.first; ob; ob = ob->id.next) { /* we only need to do this on objects with a pose */ - if ( (pose = ob->pose) ) { + if ((pose = ob->pose)) { for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) { if (pchan->bone) pchan->bone->flag &= ~BONE_UNKEYED; diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index 02ce3a36b14..2f66dbde97c 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -44,7 +44,8 @@ #include #include #include -#include // for open +#include /* for open */ +#include #include "MEM_guardedalloc.h" @@ -518,8 +519,13 @@ void BKE_write_undo(bContext *C, const char *name) int nr /*, success */ /* UNUSED */; UndoElem *uel; - if ( (U.uiflag & USER_GLOBALUNDO) == 0) return; - if (U.undosteps == 0) return; + if ((U.uiflag & USER_GLOBALUNDO) == 0) { + return; + } + + if (U.undosteps == 0) { + return; + } /* remove all undos after (also when curundo == NULL) */ while (undobase.last != curundo) { @@ -720,38 +726,60 @@ void BKE_undo_save_quit(void) { UndoElem *uel; MemFileChunk *chunk; - int file; char str[FILE_MAX]; - - if ( (U.uiflag & USER_GLOBALUNDO) == 0) return; - + const int flag = O_BINARY + O_WRONLY + O_CREAT + O_TRUNC + O_EXCL; + int file; + + if ((U.uiflag & USER_GLOBALUNDO) == 0) { + return; + } + uel = curundo; if (uel == NULL) { - printf("No undo buffer to save recovery file\n"); + fprintf(stderr, "No undo buffer to save recovery file\n"); return; } - + /* no undo state to save */ - if (undobase.first == undobase.last) return; - + if (undobase.first == undobase.last) { + return; + } + + /* save the undo state as quit.blend */ BLI_make_file_string("/", str, BLI_temporary_dir(), "quit.blend"); - file = BLI_open(str, O_BINARY + O_WRONLY + O_CREAT + O_TRUNC, 0666); + /* first try create the file, if it exists call without 'O_CREAT', + * to avoid writing to a symlink - use 'O_EXCL' (CVE-2008-1103) */ + errno = 0; + file = BLI_open(str, flag, 0666); + if (file == -1) { + if (errno == EEXIST) { + errno = 0; + file = BLI_open(str, flag & ~O_CREAT, 0666); + } + } + if (file == -1) { - //XXX error("Unable to save %s, check you have permissions", str); + fprintf(stderr, "Unable to save '%s': %s\n", + str, errno ? strerror(errno) : "Unknown error opening file"); return; } - chunk = uel->memfile.chunks.first; - while (chunk) { - if (write(file, chunk->buf, chunk->size) != chunk->size) break; - chunk = chunk->next; + for (chunk = uel->memfile.chunks.first; chunk; chunk = chunk->next) { + if (write(file, chunk->buf, chunk->size) != chunk->size) { + break; + } } - + close(file); - if (chunk) ; //XXX error("Unable to save %s, internal error", str); - else printf("Saved session recovery to %s\n", str); + if (chunk) { + fprintf(stderr, "Unable to save '%s': %s\n", + str, errno ? strerror(errno) : "Unknown error writing file"); + } + else { + printf("Saved session recovery to '%s'\n", str); + } } /* sets curscene */ diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 391891d3985..8d7f4e4117a 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -4292,8 +4292,8 @@ bConstraintTypeInfo *get_constraint_typeinfo(int type) } /* only return for valid types */ - if ( (type >= CONSTRAINT_TYPE_NULL) && - (type < NUM_CONSTRAINT_TYPES) ) + if ((type >= CONSTRAINT_TYPE_NULL) && + (type < NUM_CONSTRAINT_TYPES)) { /* there shouldn't be any segfaults here... */ return constraintsTypeInfo[type]; -- cgit v1.2.3 From 832841d50fefa4868f3eaed0959029b18347d72f Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 10 Sep 2012 10:58:59 +0000 Subject: Merging r50484 through r50501 from trunk into soc-2011-tomato --- source/blender/blenkernel/intern/anim.c | 4 ++-- source/blender/blenkernel/intern/blender.c | 3 +-- source/blender/blenkernel/intern/constraint.c | 3 +-- source/blender/blenkernel/intern/editderivedmesh.c | 6 ++++++ 4 files changed, 10 insertions(+), 6 deletions(-) (limited to 'source/blender/blenkernel/intern') diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index f9954ff1dd0..4f68ab82329 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -924,7 +924,7 @@ static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, fl /* simple preventing of too deep nested groups */ if (level > MAX_DUPLI_RECUR) return; - em = me->edit_btmesh; + em = BMEdit_FromObject(par); if (em) { dm = editbmesh_get_derived_cage(scene, par, em, CD_MASK_BAREMESH); @@ -1050,7 +1050,7 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa if (level > MAX_DUPLI_RECUR) return; copy_m4_m4(pmat, par->obmat); - em = me->edit_btmesh; + em = BMEdit_FromObject(par); if (em) { dm = editbmesh_get_derived_cage(scene, par, em, CD_MASK_BAREMESH); diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index 2f66dbde97c..9145c4af850 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -469,11 +469,10 @@ int blender_test_break(void) #define UNDO_DISK 0 -#define MAXUNDONAME 64 typedef struct UndoElem { struct UndoElem *next, *prev; char str[FILE_MAX]; - char name[MAXUNDONAME]; + char name[BKE_UNDO_STR_MAX]; MemFile memfile; uintptr_t undosize; } UndoElem; diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 8d7f4e4117a..6b9e0921c3b 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -416,8 +416,7 @@ void constraint_mat_convertspace(Object *ob, bPoseChannel *pchan, float mat[][4] static void contarget_get_mesh_mat(Object *ob, const char *substring, float mat[][4]) { DerivedMesh *dm = NULL; - Mesh *me = ob->data; - BMEditMesh *em = me->edit_btmesh; + BMEditMesh *em = BMEdit_FromObject(ob); float vec[3] = {0.0f, 0.0f, 0.0f}; float normal[3] = {0.0f, 0.0f, 0.0f}, plane[3]; float imat[3][3], tmat[3][3]; diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c index c6ba6a0d841..befec1907da 100644 --- a/source/blender/blenkernel/intern/editderivedmesh.c +++ b/source/blender/blenkernel/intern/editderivedmesh.c @@ -1747,5 +1747,11 @@ DerivedMesh *getEditDerivedBMesh(BMEditMesh *em, BMEditMesh *BMEdit_FromObject(Object *ob) { BLI_assert(ob->type == OB_MESH); + /* sanity check */ +#ifndef NDEBUG + if (((Mesh *)ob->data)->edit_btmesh) { + BLI_assert(((Mesh *)ob->data)->edit_btmesh->ob == ob); + } +#endif return ((Mesh *)ob->data)->edit_btmesh; } -- cgit v1.2.3 From b0605eed2c9f6424c8d8ae4dc053639ece130831 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 10 Sep 2012 11:46:15 +0000 Subject: Color Management: finish pipeline changes This commit hopefully finishes color management pipeline changes, implements some missed functionality and fixes some bugs. Mainly changes are related on getting rid of old Color Management flag which became counter-intuitive in conjunction with OpenColorIO. Now color management is always assuming to be enabled and non-color managed pipeline is emulated using display device called None. This display has got single view which is basically NO-OP (raw) transformation, not applying any tone curve and displays colors AS-IS. In most cases it behaves the same as disabling Color Management in shading panel, but there is at least one known difference in behavior: compositor and sequence editors would output images in linear space, not in sRGB as it used to be before. It'll be quite tricky to make this behave in exactly the same way as it used to, and not sure if we really need to do it. 3D viewport is supposed to be working in sRGB space, no tonemaps would be applied there. This is another case where compatibility breaks in comparison with old color management pipeline, but supporting display transformation would be tricky since it'll also be needed to make GLSL shaders, textures and so be aware of display transform. Interface is now aware of display transformation, but it only uses default display view, no exposure, gamma or curve mapping is supported there. This is so color widgets could apply display transformation in both directions. Such behavior is a bit counter-intuitive, but it's currently the only way to make color picking working smoothly. In theory we'll need to support color picking color space, but it'll be also a bit tricky since in Blender display transform is configurable from the interface and could be used for artistics needs and in such design it's not possible to figure out invertable color space which could be used for color picking. In other software it's not so big issue since all color spaces, display transform and so are strictly defined by pipeline and in this case it is possible to define color picking space which would be close enough to display space. Sequencer's color space now could be configured from the interface -- it's settings are situated in Scene buttons, Color Management panel. Default space is sRGB. It was made configurable because we used vd16 color space during Mango which was close to Film view used by grading department. Sequencer will convert float buffers to this color space before operating with them hopefully giving better results. Byte buffers wouldn't be converted to this color space an they'll be handled in their own colors[ace. Converting them to sequencer's working space would lead to precision loss without much visible benefits. It shouldn't be an issue since float and byte images would never be blended together -- byte image would be converted to float first if it's needed to be blended with float image. Byte buffers now allowed to be color managed. This was needed to make code in such areas as baking and rendering don't have hardcoded linear to sRGB conversions, making things more clear from code point of view. Input color space is now assigning on image/movie clip load and default roles are used for this. So for float images default space would be rec709 and for byte images default space would be sRGB. Added Non-Color color space which is aimed to be used for such things as normal/heights maps. It's currently the same as raw colorspace, just has got more clear naming for users. Probably we'll also need to make it not affected by display transformation. Think this is all main pipeline-related changes, more details would be there: http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.64/Color_Management Other changes and fixes: - Lots of internal code clean up in color management module. - Made OpenColorIO module using guarded memory allocation. This allowed to fix couple of memory leaks and would help preventing leaks in the future. - Made sure color unpremultiply and dither are supported by all OpenColorIO defined color transformations. - Made compositor's preview images be aware of display transformation. Legacy compositor still uses old Color Management flags, but likely we'll disable compositor for the release and remove legacy code soon, so don't think we'll need to spend time on porting that code to new color management system. - Made OpenGL rendering be aware of display transform when saving render result. Now it behaves in the same way as regular rendering. TODO: - HSV widgets are using linear rgb/sRGB conversions for single channel, not sure how this should be ported to new color pipeline. - Image stamp would use hardcoded linear rgb to sRGB conversion for filling rectangles. Probably it should use default display view for this instead, would check this with Brecht. - Get rid of None color space which was only used for compatibility reasons. - Made it more clear which color spaces could be used as input space. - There're also some remained TODO's in the code marked as OCIO_TODO, but wouldn't consider them as stoppers for at least this commit. --- source/blender/blenkernel/intern/colortools.c | 35 ++++++--- source/blender/blenkernel/intern/image.c | 15 +++- source/blender/blenkernel/intern/scene.c | 25 ++++++ source/blender/blenkernel/intern/seqeffects.c | 6 +- source/blender/blenkernel/intern/sequencer.c | 109 ++++++++++++++++++++++++-- 5 files changed, 167 insertions(+), 23 deletions(-) (limited to 'source/blender/blenkernel/intern') diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c index 65bffe42a1e..27651ac1731 100644 --- a/source/blender/blenkernel/intern/colortools.c +++ b/source/blender/blenkernel/intern/colortools.c @@ -998,7 +998,8 @@ static void save_sample_line(Scopes *scopes, const int idx, const float fx, cons } } -void BKE_histogram_update_sample_line(Histogram *hist, ImBuf *ibuf, const short use_color_management) +void BKE_histogram_update_sample_line(Histogram *hist, ImBuf *ibuf, const ColorManagedViewSettings *view_settings, + const ColorManagedDisplaySettings *display_settings) { int i, x, y; float *fp; @@ -1010,6 +1011,8 @@ void BKE_histogram_update_sample_line(Histogram *hist, ImBuf *ibuf, const short int y1 = 0.5f + hist->co[0][1] * ibuf->y; int y2 = 0.5f + hist->co[1][1] * ibuf->y; + struct ColormanageProcessor *cm_processor = NULL; + hist->channels = 3; hist->x_resolution = 256; hist->xmax = 1.0f; @@ -1017,6 +1020,9 @@ void BKE_histogram_update_sample_line(Histogram *hist, ImBuf *ibuf, const short if (ibuf->rect == NULL && ibuf->rect_float == NULL) return; + if (ibuf->rect_float) + cm_processor = IMB_colormanagement_display_processor_new(view_settings, display_settings); + /* persistent draw */ hist->flag |= HISTO_FLAG_SAMPLELINE; /* keep drawing the flag after */ @@ -1031,10 +1037,8 @@ void BKE_histogram_update_sample_line(Histogram *hist, ImBuf *ibuf, const short if (ibuf->rect_float) { fp = (ibuf->rect_float + (ibuf->channels) * (y * ibuf->x + x)); - if (use_color_management) - linearrgb_to_srgb_v3_v3(rgb, fp); - else - copy_v3_v3(rgb, fp); + copy_v3_v3(rgb, fp); + IMB_colormanagement_processor_apply_v3(cm_processor, rgb); hist->data_luma[i] = rgb_to_luma(rgb); hist->data_r[i] = rgb[0]; @@ -1052,9 +1056,13 @@ void BKE_histogram_update_sample_line(Histogram *hist, ImBuf *ibuf, const short } } } + + if (cm_processor) + IMB_colormanagement_processor_free(cm_processor); } -void scopes_update(Scopes *scopes, ImBuf *ibuf, int use_color_management) +void scopes_update(Scopes *scopes, ImBuf *ibuf, const ColorManagedViewSettings *view_settings, + const ColorManagedDisplaySettings *display_settings) { int x, y, c; unsigned int n, nl; @@ -1067,6 +1075,8 @@ void scopes_update(Scopes *scopes, ImBuf *ibuf, int use_color_management) int ycc_mode = -1; const short is_float = (ibuf->rect_float != NULL); + struct ColormanageProcessor *cm_processor = NULL; + if (ibuf->rect == NULL && ibuf->rect_float == NULL) return; if (scopes->ok == 1) return; @@ -1136,6 +1146,9 @@ void scopes_update(Scopes *scopes, ImBuf *ibuf, int use_color_management) else rc = (unsigned char *)ibuf->rect; + if (ibuf->rect_float) + cm_processor = IMB_colormanagement_display_processor_new(view_settings, display_settings); + for (y = 0; y < ibuf->y; y++) { if (savedlines < scopes->sample_lines && y >= ((savedlines) * ibuf->y) / (scopes->sample_lines + 1)) { saveline = 1; @@ -1146,11 +1159,8 @@ void scopes_update(Scopes *scopes, ImBuf *ibuf, int use_color_management) for (x = 0; x < ibuf->x; x++) { if (is_float) { - if (use_color_management) - linearrgb_to_srgb_v3_v3(rgba, rf); - else - copy_v3_v3(rgba, rf); - rgba[3] = rf[3]; + copy_v4_v4(rgba, rf); + IMB_colormanagement_processor_apply_v4(cm_processor, rgba); } else { for (c = 0; c < 4; c++) @@ -1221,6 +1231,9 @@ void scopes_update(Scopes *scopes, ImBuf *ibuf, int use_color_management) MEM_freeN(bin_b); MEM_freeN(bin_a); + if (cm_processor) + IMB_colormanagement_processor_free(cm_processor); + scopes->ok = 1; } diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index a0839a502b7..3d1133b7475 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -301,6 +301,12 @@ static void image_assign_ibuf(Image *ima, ImBuf *ibuf, int index, int frame) else ibuf->flags &= ~IB_cm_predivide; + if (ima->source == IMA_SRC_GENERATED) { + /* for other image types spaces are set by image_initialize_after_load */ + + IMB_colormanagement_imbuf_assign_spaces(ibuf, &ima->colorspace_settings); + } + /* this function accepts (link == NULL) */ BLI_insertlinkbefore(&ima->ibufs, link, ibuf); @@ -1499,7 +1505,9 @@ void BKE_stamp_buf(Scene *scene, Object *camera, unsigned char *rect, float *rec /* this could be an argument if we want to operate on non linear float imbuf's * for now though this is only used for renders which use scene settings */ - const int do_color_management = (scene->r.color_mgt_flag & R_COLOR_MANAGEMENT) != 0; + + /* OCIO_TODO: for now harcode sRGB to linearrgb conversion, need to be fixed ASAP */ + const int do_color_management = TRUE; #define BUFF_MARGIN_X 2 #define BUFF_MARGIN_Y 1 @@ -2586,7 +2594,7 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **lock_ /* invalidate color managed buffers if render result changed */ BLI_lock_thread(LOCK_COLORMANAGE); if (ibuf->x != rres.rectx || ibuf->y != rres.recty || ibuf->rect_float != rectf) { - IMB_display_buffer_invalidate(ibuf); + ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID; } ibuf->x = rres.rectx; @@ -2626,8 +2634,7 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **lock_ BLI_unlock_thread(LOCK_COLORMANAGE); - /* since its possible to access the buffer from the image directly, set the profile [#25073] */ - ibuf->profile = (iuser->scene->r.color_mgt_flag & R_COLOR_MANAGEMENT) ? IB_PROFILE_LINEAR_RGB : IB_PROFILE_NONE; + ibuf->profile = IB_PROFILE_LINEAR_RGB; ibuf->dither = dither; if (iuser->scene->r.color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE) { diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 1bd8f3dfcd2..2dec72560a2 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -77,6 +77,8 @@ #include "RE_engine.h" +#include "IMB_colormanagement.h" + //XXX #include "BIF_previewrender.h" //XXX #include "BIF_editseq.h" @@ -384,7 +386,14 @@ Scene *BKE_scene_add(const char *name) sce->r.frs_sec_base = 1; sce->r.edgeint = 10; sce->r.ocres = 128; + + /* OCIO_TODO: for forwards compatibiliy only, so if no tonecurve are used, + * images would look in the same way as in current blender + * + * perhaps at some point should be completely deprecated? + */ sce->r.color_mgt_flag |= R_COLOR_MANAGEMENT; + sce->r.gauss = 1.0; /* deprecated but keep for upwards compat */ @@ -1255,3 +1264,19 @@ void BKE_scene_base_flag_from_objects(struct Scene *scene) base = base->next; } } + +void BKE_scene_disable_color_management(Scene *scene) +{ + ColorManagedDisplaySettings *display_settings = &scene->display_settings; + ColorManagedViewSettings *view_settings = &scene->view_settings; + const char *view; + + /* NOTE: None display with Default view should always exist in OCIO configuration, otherwise it wouldn't work as expected */ + BLI_strncpy(display_settings->display_device, "None", sizeof(display_settings->display_device)); + + view = IMB_colormanagement_view_get_default_name(display_settings->display_device); + + if (view) { + BLI_strncpy(view_settings->view_transform, view, sizeof(view_settings->view_transform)); + } +} diff --git a/source/blender/blenkernel/intern/seqeffects.c b/source/blender/blenkernel/intern/seqeffects.c index acf38ace00a..eaf3ec384c8 100644 --- a/source/blender/blenkernel/intern/seqeffects.c +++ b/source/blender/blenkernel/intern/seqeffects.c @@ -120,13 +120,13 @@ static ImBuf *prepare_effect_imbufs(SeqRenderData context, ImBuf *ibuf1, ImBuf * } if (ibuf1 && !ibuf1->rect_float && out->rect_float) { - IMB_colormanagement_imbuf_to_sequencer_space(ibuf1, TRUE); + BKE_sequencer_imbuf_to_sequencer_space(context.scene, ibuf1, TRUE); } if (ibuf2 && !ibuf2->rect_float && out->rect_float) { - IMB_colormanagement_imbuf_to_sequencer_space(ibuf2, TRUE); + BKE_sequencer_imbuf_to_sequencer_space(context.scene, ibuf2, TRUE); } if (ibuf3 && !ibuf3->rect_float && out->rect_float) { - IMB_colormanagement_imbuf_to_sequencer_space(ibuf3, TRUE); + BKE_sequencer_imbuf_to_sequencer_space(context.scene, ibuf3, TRUE); } if (ibuf1 && !ibuf1->rect && !out->rect_float) { diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index 611b175c9ef..5e79de7b4cd 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -309,6 +309,94 @@ void BKE_sequencer_editing_free(Scene *scene) scene->ed = NULL; } +/*********************** Sequencer color space functions *************************/ + +void BKE_sequencer_imbuf_assign_spaces(Scene *scene, ImBuf *ibuf) +{ + IMB_colormanagement_imbuf_assign_spaces(ibuf, NULL); + IMB_colormanagement_imbuf_assign_float_space(ibuf, &scene->sequencer_colorspace_settings); +} + +void BKE_sequencer_imbuf_to_sequencer_space(Scene *scene, ImBuf *ibuf, int make_float) +{ + const char *from_colorspace = IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_SCENE_LINEAR); + const char *to_colorspace = scene->sequencer_colorspace_settings.name; + int predivide = ibuf->flags & IB_cm_predivide; + + if (!ibuf->rect_float) { + if (make_float && ibuf->rect) { + /* when converting byte buffer to float in sequencer we need to make float + * buffer be in sequencer's working space, which is currently only doable + * from linear space. + * + */ + + /* + * OCIO_TODO: would be nice to support direct single transform from byte to sequencer's + */ + + IMB_colormanagement_imbuf_float_from_rect(ibuf); + } + else { + /* if there's only byte buffer in image it's already in compositor's working space, + * nothing to do here + */ + + return; + } + } + + if (from_colorspace && from_colorspace[0] != '\0') { + if (ibuf->rect) + imb_freerectImBuf(ibuf); + + IMB_colormanagement_transform_threaded(ibuf->rect_float, ibuf->x, ibuf->y, ibuf->channels, + from_colorspace, to_colorspace, predivide); + + ibuf->profile = IB_PROFILE_SRGB; + } + else { + /* if no color management enables fallback to legacy conversion */ + IMB_convert_profile(ibuf, IB_PROFILE_NONE); + } +} + +void BKE_sequencer_imbuf_from_sequencer_space(Scene *scene, ImBuf *ibuf) +{ + const char *from_colorspace = scene->sequencer_colorspace_settings.name; + const char *to_colorspace = IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_SCENE_LINEAR); + + if (!ibuf->rect_float) + return; + + if (to_colorspace && to_colorspace[0] != '\0') { + int predivide = ibuf->flags & IB_cm_predivide; + + IMB_colormanagement_transform_threaded(ibuf->rect_float, ibuf->x, ibuf->y, ibuf->channels, + from_colorspace, to_colorspace, predivide); + + ibuf->profile = IB_PROFILE_LINEAR_RGB; + } + else { + /* if no color management enables fallback to legacy conversion */ + IMB_convert_profile(ibuf, IB_PROFILE_LINEAR_RGB); + } +} + +void BKE_sequencer_pixel_from_sequencer_space_v4(struct Scene *scene, float pixel[4]) +{ + const char *from_colorspace = scene->sequencer_colorspace_settings.name; + const char *to_colorspace = IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_SCENE_LINEAR); + + if (to_colorspace && to_colorspace[0] != '\0') { + IMB_colormanagement_transform_v4(pixel, from_colorspace, to_colorspace); + } + else { + /* if no color management enables fallback to legacy conversion */ + srgb_to_linearrgb_v4(pixel, pixel); + } +} + /*********************** sequencer pipeline functions *************************/ SeqRenderData BKE_sequencer_new_render_data(Main *bmain, Scene *scene, int rectx, int recty, int preview_render_size) @@ -1220,7 +1308,12 @@ static ImBuf *seq_proxy_fetch(SeqRenderData context, Sequence *seq, int cfra) } if (BLI_exists(name)) { - return IMB_loadiffname(name, IB_rect); + ImBuf *ibuf = IMB_loadiffname(name, IB_rect); + + if (ibuf) + BKE_sequencer_imbuf_assign_spaces(context.scene, ibuf); + + return ibuf; } else { return NULL; @@ -1828,7 +1921,7 @@ static ImBuf *input_preprocess(SeqRenderData context, Sequence *seq, float cfra, if (seq->flag & SEQ_MAKE_FLOAT) { if (!ibuf->rect_float) { - IMB_colormanagement_imbuf_to_sequencer_space(ibuf, TRUE); + BKE_sequencer_imbuf_to_sequencer_space(context.scene, ibuf, TRUE); } if (ibuf->rect) { @@ -1895,6 +1988,8 @@ static void copy_to_ibuf_still(SeqRenderData context, Sequence *seq, float nr, I * changing the cached image... */ ibuf = IMB_dupImBuf(ibuf); + BKE_sequencer_imbuf_assign_spaces(context.scene, ibuf); + if (nr == 0) { BKE_sequencer_cache_put(context, seq, seq->start, SEQ_STRIPELEM_IBUF_STARTSTILL, ibuf); } @@ -2309,7 +2404,7 @@ static ImBuf *seq_render_scene_strip(SeqRenderData context, Sequence *seq, float /* opengl offscreen render */ BKE_scene_update_for_newframe(context.bmain, scene, scene->lay); ibuf = sequencer_view3d_cb(scene, camera, context.rectx, context.recty, - IB_rect, context.scene->r.seq_prev_type, TRUE, err_out); + IB_rect, context.scene->r.seq_prev_type, TRUE, FALSE, err_out); if (ibuf == NULL) { fprintf(stderr, "seq_render_scene_strip failed to get opengl buffer: %s\n", err_out); } @@ -2341,7 +2436,7 @@ static ImBuf *seq_render_scene_strip(SeqRenderData context, Sequence *seq, float /* float buffers in the sequencer are not linear */ ibuf->profile = IB_PROFILE_LINEAR_RGB; - IMB_colormanagement_imbuf_to_sequencer_space(ibuf, FALSE); + BKE_sequencer_imbuf_to_sequencer_space(context.scene, ibuf, FALSE); } else if (rres.rect32) { ibuf = IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rect); @@ -2448,7 +2543,7 @@ static ImBuf *do_render_strip_uncached(SeqRenderData context, Sequence *seq, flo /* all sequencer color is done in SRGB space, linear gives odd crossfades */ if (ibuf->profile == IB_PROFILE_LINEAR_RGB) - IMB_colormanagement_imbuf_to_sequencer_space(ibuf, FALSE); + BKE_sequencer_imbuf_to_sequencer_space(context.scene, ibuf, FALSE); copy_to_ibuf_still(context, seq, nr, ibuf); @@ -2496,6 +2591,7 @@ static ImBuf *do_render_strip_uncached(SeqRenderData context, Sequence *seq, flo case SEQ_TYPE_MOVIECLIP: { ibuf = seq_render_movieclip_strip(context, seq, nr); + BKE_sequencer_imbuf_assign_spaces(context.scene, ibuf); if (ibuf && use_preprocess) { ImBuf *i = IMB_dupImBuf(ibuf); @@ -2519,6 +2615,9 @@ static ImBuf *do_render_strip_uncached(SeqRenderData context, Sequence *seq, flo } } + if (ibuf) + BKE_sequencer_imbuf_assign_spaces(context.scene, ibuf); + return ibuf; } -- cgit v1.2.3 From ce3566a4cb3d328c646a2876b14530db9dc6a014 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 10 Sep 2012 14:47:47 +0000 Subject: Color Management: add View as Render to image datablocks This is need since some images (like normal maps, textures and so) would want to be viewed without any tone map applied on them. On the same time it's possible that some images would want to be affected by tone maps, and renders would always want to be affected by tone maps. After long discussion with Brecht we decided less painful and most clear way would be to simply add "View as Render" option to image datablocks. If this option is enabled for image, both settings from Display and Render blocks of color management settings would be applied on display. If this option is disabled, only display transform with default view and no exposure/gamma/curves would be applied. Render result and compositor viewers would always have "View as Render" enabled. There's separated setting when image is saving which says whether saved image should be affected by render part of color management settings. This option is enabled by default for render result/node viewer and disabled by default for all the rest images. This option wouldn't have affect when saving to float formats such as EXR. --- source/blender/blenkernel/intern/image.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source/blender/blenkernel/intern') diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index 3d1133b7475..f077fcfbfb3 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -246,6 +246,9 @@ static Image *image_alloc(const char *name, short source, short type) ima->source = source; ima->type = type; + if (source == IMA_SRC_VIEWER) + ima->flag |= IMA_VIEW_AS_RENDER; + BKE_color_managed_colorspace_settings_init(&ima->colorspace_settings); } return ima; -- cgit v1.2.3 From 74885d1d8465fd6b941f09a194b484013ef097c0 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 10 Sep 2012 17:24:48 +0000 Subject: Color Management: port image stamp to new color management system Use the same approach as interface does by using default view which is supposed to be invertible to convert color from display space to scene linear. --- source/blender/blenkernel/intern/image.c | 32 +++++++++++++++------------- source/blender/blenkernel/intern/image_gen.c | 6 +++++- 2 files changed, 22 insertions(+), 16 deletions(-) (limited to 'source/blender/blenkernel/intern') diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index f077fcfbfb3..4e7b9db73e6 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -1505,19 +1505,21 @@ void BKE_stamp_buf(Scene *scene, Object *camera, unsigned char *rect, float *rec int x, y, y_ofs; float h_fixed; const int mono = blf_mono_font_render; // XXX + struct ColorManagedDisplay *display; + const char *display_device; /* this could be an argument if we want to operate on non linear float imbuf's * for now though this is only used for renders which use scene settings */ - /* OCIO_TODO: for now harcode sRGB to linearrgb conversion, need to be fixed ASAP */ - const int do_color_management = TRUE; - #define BUFF_MARGIN_X 2 #define BUFF_MARGIN_Y 1 if (!rect && !rectf) return; + display_device = scene->display_settings.display_device; + display = IMB_colormanagement_display_get_named(display_device); + stampdata(scene, camera, &stamp_data, 1); /* TODO, do_versions */ @@ -1527,7 +1529,7 @@ void BKE_stamp_buf(Scene *scene, Object *camera, unsigned char *rect, float *rec /* set before return */ BLF_size(mono, scene->r.stamp_font_id, 72); - BLF_buffer(mono, rectf, rect, width, height, channels, do_color_management); + BLF_buffer(mono, rectf, rect, width, height, channels, display); BLF_buffer_col(mono, scene->r.fg_stamp[0], scene->r.fg_stamp[1], scene->r.fg_stamp[2], 1.0); pad = BLF_width_max(mono); @@ -1544,7 +1546,7 @@ void BKE_stamp_buf(Scene *scene, Object *camera, unsigned char *rect, float *rec y -= h; /* also a little of space to the background. */ - buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, do_color_management, + buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, display, x - BUFF_MARGIN_X, y - BUFF_MARGIN_Y, w + BUFF_MARGIN_X, y + h + BUFF_MARGIN_Y); /* and draw the text. */ @@ -1561,7 +1563,7 @@ void BKE_stamp_buf(Scene *scene, Object *camera, unsigned char *rect, float *rec y -= h; /* and space for background. */ - buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, do_color_management, + buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, display, 0, y - BUFF_MARGIN_Y, w + BUFF_MARGIN_X, y + h + BUFF_MARGIN_Y); BLF_position(mono, x, y + y_ofs, 0.0); @@ -1577,7 +1579,7 @@ void BKE_stamp_buf(Scene *scene, Object *camera, unsigned char *rect, float *rec y -= h; /* and space for background. */ - buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, do_color_management, + buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, display, 0, y - BUFF_MARGIN_Y, w + BUFF_MARGIN_X, y + h + BUFF_MARGIN_Y); BLF_position(mono, x, y + y_ofs, 0.0); @@ -1593,7 +1595,7 @@ void BKE_stamp_buf(Scene *scene, Object *camera, unsigned char *rect, float *rec y -= h; /* and space for background. */ - buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, do_color_management, + buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, display, 0, y - BUFF_MARGIN_Y, w + BUFF_MARGIN_X, y + h + BUFF_MARGIN_Y); BLF_position(mono, x, y + y_ofs, 0.0); @@ -1608,7 +1610,7 @@ void BKE_stamp_buf(Scene *scene, Object *camera, unsigned char *rect, float *rec BLF_width_and_height(mono, stamp_data.marker, &w, &h); h = h_fixed; /* extra space for background. */ - buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, do_color_management, + buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, display, x - BUFF_MARGIN_X, y - BUFF_MARGIN_Y, w + BUFF_MARGIN_X, y + h + BUFF_MARGIN_Y); /* and pad the text. */ @@ -1624,7 +1626,7 @@ void BKE_stamp_buf(Scene *scene, Object *camera, unsigned char *rect, float *rec BLF_width_and_height(mono, stamp_data.time, &w, &h); h = h_fixed; /* extra space for background */ - buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, do_color_management, + buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, display, x - BUFF_MARGIN_X, y, x + w + BUFF_MARGIN_X, y + h + BUFF_MARGIN_Y); /* and pad the text. */ @@ -1639,7 +1641,7 @@ void BKE_stamp_buf(Scene *scene, Object *camera, unsigned char *rect, float *rec BLF_width_and_height(mono, stamp_data.frame, &w, &h); h = h_fixed; /* extra space for background. */ - buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, do_color_management, + buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, display, x - BUFF_MARGIN_X, y - BUFF_MARGIN_Y, x + w + BUFF_MARGIN_X, y + h + BUFF_MARGIN_Y); /* and pad the text. */ @@ -1654,7 +1656,7 @@ void BKE_stamp_buf(Scene *scene, Object *camera, unsigned char *rect, float *rec BLF_width_and_height(mono, stamp_data.camera, &w, &h); h = h_fixed; /* extra space for background. */ - buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, do_color_management, + buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, display, x - BUFF_MARGIN_X, y - BUFF_MARGIN_Y, x + w + BUFF_MARGIN_X, y + h + BUFF_MARGIN_Y); BLF_position(mono, x, y + y_ofs, 0.0); BLF_draw_buffer(mono, stamp_data.camera); @@ -1667,7 +1669,7 @@ void BKE_stamp_buf(Scene *scene, Object *camera, unsigned char *rect, float *rec BLF_width_and_height(mono, stamp_data.cameralens, &w, &h); h = h_fixed; /* extra space for background. */ - buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, do_color_management, + buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, display, x - BUFF_MARGIN_X, y - BUFF_MARGIN_Y, x + w + BUFF_MARGIN_X, y + h + BUFF_MARGIN_Y); BLF_position(mono, x, y + y_ofs, 0.0); BLF_draw_buffer(mono, stamp_data.cameralens); @@ -1680,7 +1682,7 @@ void BKE_stamp_buf(Scene *scene, Object *camera, unsigned char *rect, float *rec x = width - w - 2; /* extra space for background. */ - buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, do_color_management, + buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, display, x - BUFF_MARGIN_X, y - BUFF_MARGIN_Y, x + w + BUFF_MARGIN_X, y + h + BUFF_MARGIN_Y); /* and pad the text. */ @@ -1696,7 +1698,7 @@ void BKE_stamp_buf(Scene *scene, Object *camera, unsigned char *rect, float *rec y = height - h; /* extra space for background. */ - buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, do_color_management, + buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, display, x - BUFF_MARGIN_X, y - BUFF_MARGIN_Y, x + w + BUFF_MARGIN_X, y + h + BUFF_MARGIN_Y); BLF_position(mono, x, y + y_ofs, 0.0); diff --git a/source/blender/blenkernel/intern/image_gen.c b/source/blender/blenkernel/intern/image_gen.c index 4d7013b9f73..37572eebed6 100644 --- a/source/blender/blenkernel/intern/image_gen.c +++ b/source/blender/blenkernel/intern/image_gen.c @@ -289,7 +289,11 @@ static void checker_board_text(unsigned char *rect, float *rect_float, int width BLF_size(mono, 54, 72); /* hard coded size! */ - BLF_buffer(mono, rect_float, rect, width, height, 4, TRUE); + /* OCIO_TODO: using NULL as display will assume using sRGB display + * this is correct since currently generated images are assumed to be in sRGB space, + * but this would probably needed to be fixed in some way + */ + BLF_buffer(mono, rect_float, rect, width, height, 4, NULL); for (y = 0; y < height; y += step) { text[1] = '1'; -- cgit v1.2.3 From 777a49dfef19d954a000c5d7e422e8650c1854b5 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 11 Sep 2012 09:13:57 +0000 Subject: Merging r50502 through r50521 from trunk into soc-2011-tomato --- source/blender/blenkernel/intern/dynamicpaint.c | 6 +++--- source/blender/blenkernel/intern/fcurve.c | 8 +++----- source/blender/blenkernel/intern/softbody.c | 2 +- 3 files changed, 7 insertions(+), 9 deletions(-) (limited to 'source/blender/blenkernel/intern') diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c index 06807dfcbad..f47ac641cf9 100644 --- a/source/blender/blenkernel/intern/dynamicpaint.c +++ b/source/blender/blenkernel/intern/dynamicpaint.c @@ -2595,7 +2595,7 @@ void dynamicPaint_outputSurfaceImage(DynamicPaintSurface *surface, char *filenam int format = (surface->image_fileformat & MOD_DPAINT_IMGFORMAT_OPENEXR) ? R_IMF_IMTYPE_OPENEXR : R_IMF_IMTYPE_PNG; char output_file[FILE_MAX]; - if (!sData || !sData->type_data) { setError(surface->canvas, "Image save failed: Invalid surface."); return; } + if (!sData->type_data) { setError(surface->canvas, "Image save failed: Invalid surface."); return; } /* if selected format is openexr, but current build doesnt support one */ #ifndef WITH_OPENEXR if (format == R_IMF_IMTYPE_OPENEXR) format = R_IMF_IMTYPE_PNG; @@ -4800,7 +4800,7 @@ static int dynamicPaint_doStep(Scene *scene, Object *ob, DynamicPaintSurface *su PaintBakeData *bData = sData->bData; DynamicPaintCanvasSettings *canvas = surface->canvas; int ret = 1; - if (!sData || sData->total_points < 1) return 0; + if (sData->total_points < 1) return 0; dynamicPaint_surfacePreStep(surface, timescale); /* @@ -4875,7 +4875,7 @@ static int dynamicPaint_doStep(Scene *scene, Object *ob, DynamicPaintSurface *su /* Apply brush on the surface depending on it's collision type */ /* Particle brush: */ if (brush->collision == MOD_DPAINT_COL_PSYS) { - if (brush && brush->psys && brush->psys->part && brush->psys->part->type == PART_EMITTER && + if (brush->psys && brush->psys->part && brush->psys->part->type == PART_EMITTER && psys_check_enabled(brushObj, brush->psys)) { diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c index b78ab9b28cd..5fea74d52de 100644 --- a/source/blender/blenkernel/intern/fcurve.c +++ b/source/blender/blenkernel/intern/fcurve.c @@ -74,12 +74,10 @@ void free_fcurve(FCurve *fcu) { if (fcu == NULL) return; - + /* free curve data */ - if (fcu) { - if (fcu->bezt) MEM_freeN(fcu->bezt); - if (fcu->fpt) MEM_freeN(fcu->fpt); - } + if (fcu->bezt) MEM_freeN(fcu->bezt); + if (fcu->fpt) MEM_freeN(fcu->fpt); /* free RNA-path, as this were allocated when getting the path string */ if (fcu->rna_path) diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c index 008dc332710..4a88bfbfdad 100644 --- a/source/blender/blenkernel/intern/softbody.c +++ b/source/blender/blenkernel/intern/softbody.c @@ -2291,7 +2291,7 @@ static int _softbody_calc_forces_slice_in_a_thread(Scene *scene, Object *ob, flo /* done goal stuff */ /* gravitation */ - if (sb && scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY) { + if (scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY) { float gravity[3]; copy_v3_v3(gravity, scene->physics_settings.gravity); mul_v3_fl(gravity, sb_grav_force_scale(ob)*_final_mass(ob, bp)*sb->effector_weights->global_gravity); /* individual mass of node here */ -- cgit v1.2.3 From 20d84be6b5569947c05ca30f308dcab5f4a0cef9 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 11 Sep 2012 10:34:19 +0000 Subject: Color Management: fix for wrong default color space and view --- source/blender/blenkernel/intern/colortools.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source/blender/blenkernel/intern') diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c index 27651ac1731..19c8c2cd632 100644 --- a/source/blender/blenkernel/intern/colortools.c +++ b/source/blender/blenkernel/intern/colortools.c @@ -1292,7 +1292,7 @@ void BKE_color_managed_view_settings_init(ColorManagedViewSettings *settings) * and proper versioning stuff is added. * for now use NONE to be compatible with all current files */ - BLI_strncpy(settings->view_transform, "NONE", sizeof(settings->view_transform)); + BLI_strncpy(settings->view_transform, "Default", sizeof(settings->view_transform)); settings->gamma = 1.0f; settings->exposure = 0.0f; @@ -1319,7 +1319,7 @@ void BKE_color_managed_view_settings_free(ColorManagedViewSettings *settings) void BKE_color_managed_colorspace_settings_init(ColorManagedColorspaceSettings *colorspace_settings) { - BLI_strncpy(colorspace_settings->name, "NONE", sizeof(colorspace_settings->name)); + BLI_strncpy(colorspace_settings->name, "", sizeof(colorspace_settings->name)); } void BKE_color_managed_colorspace_settings_copy(ColorManagedColorspaceSettings *colorspace_settings, -- cgit v1.2.3 From 5f512bec47cdfafd089fc1cff82cc343b87c7808 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 11 Sep 2012 12:35:25 +0000 Subject: Sequencer: added option to calculate modifiers in linear space It was really annoying mistake in original support of logarithmic color space for sequencer which made adjustment layers be working in linear space. Seems this was only an issue for modifiers in adjustment effect. Now all modifiers are applying in sequencer's color space (in fact, this was fixed in svn rev50275). To preserve compatibility of Mango grading added this option which probably wouldn't be used by others. --- source/blender/blenkernel/intern/seqmodifier.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'source/blender/blenkernel/intern') diff --git a/source/blender/blenkernel/intern/seqmodifier.c b/source/blender/blenkernel/intern/seqmodifier.c index 6028b40756d..1fa009d22a0 100644 --- a/source/blender/blenkernel/intern/seqmodifier.c +++ b/source/blender/blenkernel/intern/seqmodifier.c @@ -581,6 +581,11 @@ ImBuf *BKE_sequence_modifier_apply_stack(SeqRenderData context, Sequence *seq, I SequenceModifierData *smd; ImBuf *processed_ibuf = ibuf; + if (seq->modifiers.first && (seq->flag & SEQ_USE_LINEAR_MODIFIERS)) { + processed_ibuf = IMB_dupImBuf(ibuf); + BKE_sequencer_imbuf_from_sequencer_space(context.scene, processed_ibuf); + } + for (smd = seq->modifiers.first; smd; smd = smd->next) { SequenceModifierTypeInfo *smti = BKE_sequence_modifier_type_info_get(smd->type); @@ -605,6 +610,10 @@ ImBuf *BKE_sequence_modifier_apply_stack(SeqRenderData context, Sequence *seq, I } } + if (seq->modifiers.first && (seq->flag & SEQ_USE_LINEAR_MODIFIERS)) { + BKE_sequencer_imbuf_to_sequencer_space(context.scene, processed_ibuf, FALSE); + } + return processed_ibuf; } -- cgit v1.2.3 From de7a57a242c5305216e917cb9ab3b870dd10de59 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 13 Sep 2012 11:13:13 +0000 Subject: Merging r50522 through r50572 from trunk into soc-2011-tomato --- source/blender/blenkernel/intern/action.c | 8 +-- source/blender/blenkernel/intern/anim.c | 66 +++++++++++++++-------- source/blender/blenkernel/intern/fcurve.c | 20 +++---- source/blender/blenkernel/intern/image.c | 37 +++++++++++++ source/blender/blenkernel/intern/key.c | 16 +++--- source/blender/blenkernel/intern/mask.c | 42 ++++++++++++--- source/blender/blenkernel/intern/mask_rasterize.c | 40 ++++++++++++++ source/blender/blenkernel/intern/movieclip.c | 12 ++++- source/blender/blenkernel/intern/object.c | 2 +- source/blender/blenkernel/intern/pointcache.c | 3 +- source/blender/blenkernel/intern/sequencer.c | 18 +++++-- 11 files changed, 202 insertions(+), 62 deletions(-) (limited to 'source/blender/blenkernel/intern') diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index 3e5dff74f3b..06bf5211abb 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -526,18 +526,12 @@ void BKE_pose_copy_data(bPose **dst, bPose *src, int copycon) bPose *outPose; bPoseChannel *pchan; ListBase listb; - + if (!src) { *dst = NULL; return; } - if (*dst == src) { - printf("BKE_pose_copy_data source and target are the same\n"); - *dst = NULL; - return; - } - outPose = MEM_callocN(sizeof(bPose), "pose"); BLI_duplicatelist(&outPose->chanbase, &src->chanbase); diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index 4f68ab82329..1b301ba43b3 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -74,7 +74,8 @@ /* --------------------- */ /* forward declarations */ -static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBase *duplilist, float par_space_mat[][4], int par_index, int level, int animated); +static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBase *duplilist, float par_space_mat[][4], int par_index, + int level, short animated, short update); /* ******************************************************************** */ /* Animation Visualization */ @@ -699,7 +700,7 @@ int where_on_path(Object *ob, float ctime, float vec[4], float dir[3], float qua /* ******************************************************************** */ /* Dupli-Geometry */ -static DupliObject *new_dupli_object(ListBase *lb, Object *ob, float mat[][4], int lay, int index, int par_index, int type, int animated) +static DupliObject *new_dupli_object(ListBase *lb, Object *ob, float mat[][4], int lay, int index, int par_index, int type, short animated) { DupliObject *dob = MEM_callocN(sizeof(DupliObject), "dupliobject"); @@ -717,7 +718,8 @@ static DupliObject *new_dupli_object(ListBase *lb, Object *ob, float mat[][4], i return dob; } -static void group_duplilist(ListBase *lb, Scene *scene, Object *ob, int par_index, int level, int animated) +static void group_duplilist(ListBase *lb, Scene *scene, Object *ob, int par_index, + int level, short animated, short update) { DupliObject *dob; Group *group; @@ -731,8 +733,14 @@ static void group_duplilist(ListBase *lb, Scene *scene, Object *ob, int par_inde if (level > MAX_DUPLI_RECUR) return; /* handles animated groups, and */ + /* we need to check update for objects that are not in scene... */ - group_handle_recalc_and_update(scene, ob, group); + if (update) { + /* note: update is optional because we don't always need object + * transformations to be correct. Also fixes bug [#29616]. */ + group_handle_recalc_and_update(scene, ob, group); + } + animated = animated || group_is_animated(ob, group); for (go = group->gobject.first; go; go = go->next) { @@ -764,14 +772,14 @@ static void group_duplilist(ListBase *lb, Scene *scene, Object *ob, int par_inde if (go->ob->transflag & OB_DUPLI) { copy_m4_m4(dob->ob->obmat, dob->mat); - object_duplilist_recursive(&group->id, scene, go->ob, lb, ob->obmat, par_index, level + 1, animated); + object_duplilist_recursive(&group->id, scene, go->ob, lb, ob->obmat, par_index, level + 1, animated, update); copy_m4_m4(dob->ob->obmat, dob->omat); } } } } -static void frames_duplilist(ListBase *lb, Scene *scene, Object *ob, int par_index, int level, int animated) +static void frames_duplilist(ListBase *lb, Scene *scene, Object *ob, int par_index, int level, short animated) { extern int enable_cu_speed; /* object.c */ Object copyob; @@ -843,7 +851,8 @@ static void frames_duplilist(ListBase *lb, Scene *scene, Object *ob, int par_ind typedef struct VertexDupliData { ID *id; /* scene or group, for recursive loops */ int level; - int animated; + short animated; + short update; ListBase *lb; float pmat[4][4]; float obmat[4][4]; /* Only used for dupliverts inside dupligroups, where the ob->obmat is modified */ @@ -899,12 +908,13 @@ static void vertex_dupli__mapFunc(void *userData, int index, const float co[3], float tmpmat[4][4]; copy_m4_m4(tmpmat, vdd->ob->obmat); copy_m4_m4(vdd->ob->obmat, obmat); /* pretend we are really this mat */ - object_duplilist_recursive((ID *)vdd->id, vdd->scene, vdd->ob, vdd->lb, obmat, vdd->par_index, vdd->level + 1, vdd->animated); + object_duplilist_recursive((ID *)vdd->id, vdd->scene, vdd->ob, vdd->lb, obmat, vdd->par_index, vdd->level + 1, vdd->animated, vdd->update); copy_m4_m4(vdd->ob->obmat, tmpmat); } } -static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[][4], int par_index, int level, int animated) +static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[][4], int par_index, + int level, short animated, short update) { Object *ob, *ob_iter; Mesh *me = par->data; @@ -983,6 +993,7 @@ static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, fl vdd.id = id; vdd.level = level; vdd.animated = animated; + vdd.update = update; vdd.lb = lb; vdd.ob = ob; vdd.scene = scene; @@ -1027,7 +1038,8 @@ static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, fl dm->release(dm); } -static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[][4], int par_index, int level, int animated) +static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[][4], int par_index, + int level, short animated, short update) { Object *ob, *ob_iter; Base *base = NULL; @@ -1197,7 +1209,7 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa float tmpmat[4][4]; copy_m4_m4(tmpmat, ob->obmat); copy_m4_m4(ob->obmat, obmat); /* pretend we are really this mat */ - object_duplilist_recursive((ID *)id, scene, ob, lb, ob->obmat, par_index, level + 1, animated); + object_duplilist_recursive((ID *)id, scene, ob, lb, ob->obmat, par_index, level + 1, animated, update); copy_m4_m4(ob->obmat, tmpmat); } } @@ -1217,7 +1229,8 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa dm->release(dm); } -static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[][4], int UNUSED(par_index), ParticleSystem *psys, int level, int animated) +static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[][4], int UNUSED(par_index), ParticleSystem *psys, + int level, short animated, short update) { GroupObject *go; Object *ob = NULL, **oblist = NULL, obcopy, *obcopylist = NULL; @@ -1300,7 +1313,9 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p /* gather list of objects or single object */ if (part->ren_as == PART_DRAW_GR) { - group_handle_recalc_and_update(scene, par, part->dup_group); + if (update) { + group_handle_recalc_and_update(scene, par, part->dup_group); + } if (part->draw & PART_DRAW_COUNT_GR) { for (dw = part->dupliweights.first; dw; dw = dw->next) @@ -1555,7 +1570,7 @@ static Object *find_family_object(Object **obar, char *family, char ch) } -static void font_duplilist(ListBase *lb, Scene *scene, Object *par, int par_index, int level, int animated) +static void font_duplilist(ListBase *lb, Scene *scene, Object *par, int par_index, int level, short animated) { Object *ob, *obar[256] = {NULL}; Curve *cu; @@ -1603,7 +1618,8 @@ static void font_duplilist(ListBase *lb, Scene *scene, Object *par, int par_inde /* ------------- */ -static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBase *duplilist, float par_space_mat[][4], int par_index, int level, int animated) +static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBase *duplilist, float par_space_mat[][4], int par_index, + int level, short animated, short update) { if ((ob->transflag & OB_DUPLI) == 0) return; @@ -1623,11 +1639,11 @@ static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBas if (ob->transflag & OB_DUPLIPARTS) { ParticleSystem *psys = ob->particlesystem.first; for (; psys; psys = psys->next) - new_particle_duplilist(duplilist, id, scene, ob, par_space_mat, par_index, psys, level + 1, animated); + new_particle_duplilist(duplilist, id, scene, ob, par_space_mat, par_index, psys, level + 1, animated, update); } else if (ob->transflag & OB_DUPLIVERTS) { if (ob->type == OB_MESH) { - vertex_duplilist(duplilist, id, scene, ob, par_space_mat, par_index, level + 1, animated); + vertex_duplilist(duplilist, id, scene, ob, par_space_mat, par_index, level + 1, animated, update); } else if (ob->type == OB_FONT) { if (GS(id->name) == ID_SCE) { /* TODO - support dupligroups */ @@ -1637,7 +1653,7 @@ static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBas } else if (ob->transflag & OB_DUPLIFACES) { if (ob->type == OB_MESH) - face_duplilist(duplilist, id, scene, ob, par_space_mat, par_index, level + 1, animated); + face_duplilist(duplilist, id, scene, ob, par_space_mat, par_index, level + 1, animated, update); } else if (ob->transflag & OB_DUPLIFRAMES) { if (GS(id->name) == ID_SCE) { /* TODO - support dupligroups */ @@ -1647,7 +1663,7 @@ static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBas else if (ob->transflag & OB_DUPLIGROUP) { DupliObject *dob; - group_duplilist(duplilist, scene, ob, par_index, level + 1, animated); /* now recursive */ + group_duplilist(duplilist, scene, ob, par_index, level + 1, animated, update); /* now recursive */ if (level == 0) { for (dob = duplilist->first; dob; dob = dob->next) @@ -1659,14 +1675,22 @@ static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBas /* Returns a list of DupliObject * note; group dupli's already set transform matrix. see note in group_duplilist() */ -ListBase *object_duplilist(Scene *sce, Object *ob) +ListBase *object_duplilist_ex(Scene *sce, Object *ob, int update) { ListBase *duplilist = MEM_mallocN(sizeof(ListBase), "duplilist"); duplilist->first = duplilist->last = NULL; - object_duplilist_recursive((ID *)sce, sce, ob, duplilist, NULL, 0, 0, 0); + object_duplilist_recursive((ID *)sce, sce, ob, duplilist, NULL, 0, 0, 0, update); return duplilist; } +/* note: previously updating was always done, this is why it defaults to be on + * but there are likely places it can be called without updating */ +ListBase *object_duplilist(Scene *sce, Object *ob) +{ + return object_duplilist_ex(sce, ob, TRUE); +} + + void free_object_duplilist(ListBase *lb) { DupliObject *dob; diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c index 5fea74d52de..2dbc63e6944 100644 --- a/source/blender/blenkernel/intern/fcurve.c +++ b/source/blender/blenkernel/intern/fcurve.c @@ -504,8 +504,8 @@ short calc_fcurve_bounds(FCurve *fcu, float *xmin, float *xmax, float *ymin, flo xmaxv = MAX3(xmaxv, bezt_last->vec[1][0], bezt_last->vec[2][0]); } else { - xminv = MIN2(xminv, bezt_first->vec[1][0]); - xmaxv = MAX2(xmaxv, bezt_last->vec[1][0]); + xminv = minf(xminv, bezt_first->vec[1][0]); + xmaxv = maxf(xmaxv, bezt_last->vec[1][0]); } } } @@ -521,8 +521,8 @@ short calc_fcurve_bounds(FCurve *fcu, float *xmin, float *xmax, float *ymin, flo ymaxv = MAX4(ymaxv, bezt->vec[1][1], bezt->vec[0][1], bezt->vec[2][1]); } else { - yminv = MIN2(yminv, bezt->vec[1][1]); - ymaxv = MAX2(ymaxv, bezt->vec[1][1]); + yminv = minf(yminv, bezt->vec[1][1]); + ymaxv = maxf(ymaxv, bezt->vec[1][1]); } foundvert = TRUE; @@ -533,8 +533,8 @@ short calc_fcurve_bounds(FCurve *fcu, float *xmin, float *xmax, float *ymin, flo else if (fcu->fpt) { /* frame range can be directly calculated from end verts */ if (xmin || xmax) { - xminv = MIN2(xminv, fcu->fpt[0].vec[0]); - xmaxv = MAX2(xmaxv, fcu->fpt[fcu->totvert - 1].vec[0]); + xminv = minf(xminv, fcu->fpt[0].vec[0]); + xmaxv = maxf(xmaxv, fcu->fpt[fcu->totvert - 1].vec[0]); } /* only loop over keyframes to find extents for values if needed */ @@ -591,15 +591,15 @@ void calc_fcurve_range(FCurve *fcu, float *start, float *end, if (bezt_first) { BLI_assert(bezt_last != NULL); - min = MIN2(min, bezt_first->vec[1][0]); - max = MAX2(max, bezt_last->vec[1][0]); + min = minf(min, bezt_first->vec[1][0]); + max = maxf(max, bezt_last->vec[1][0]); foundvert = TRUE; } } else if (fcu->fpt) { - min = MIN2(min, fcu->fpt[0].vec[0]); - max = MAX2(max, fcu->fpt[fcu->totvert - 1].vec[0]); + min = minf(min, fcu->fpt[0].vec[0]); + max = maxf(max, fcu->fpt[fcu->totvert - 1].vec[0]); foundvert = TRUE; } diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index 4e7b9db73e6..0949f54642d 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -2977,3 +2977,40 @@ int BKE_image_has_alpha(struct Image *image) else return 0; } + +void BKE_image_get_size(Image *image, ImageUser *iuser, int *width, int *height) +{ + ImBuf *ibuf = NULL; + void *lock; + + ibuf = BKE_image_acquire_ibuf(image, iuser, &lock); + + if (ibuf && ibuf->x > 0 && ibuf->y > 0) { + *width = ibuf->x; + *height = ibuf->y; + } + else { + *width = IMG_SIZE_FALLBACK; + *height = IMG_SIZE_FALLBACK; + } + + BKE_image_release_ibuf(image, lock); +} + +void BKE_image_get_size_fl(Image *image, ImageUser *iuser, float size[2]) +{ + int width, height; + BKE_image_get_size(image, iuser, &width, &height); + + size[0] = (float)width; + size[1] = (float)height; + +} + +void BKE_image_get_aspect(Image *image, float *aspx, float *aspy) +{ + *aspx = 1.0; + + /* x is always 1 */ + *aspy = image->aspy / image->aspx; +} diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c index 17a3c595ea7..b79608342dd 100644 --- a/source/blender/blenkernel/intern/key.c +++ b/source/blender/blenkernel/intern/key.c @@ -691,8 +691,8 @@ static void cp_cu_key(Curve *cu, Key *key, KeyBlock *actkb, KeyBlock *kb, const if (nu->bp) { step = nu->pntsu * nu->pntsv; - a1 = MAX2(a, start); - a2 = MIN2(a + step, end); + a1 = maxi(a, start); + a2 = mini(a + step, end); if (a1 < a2) cp_key(a1, a2, tot, out, key, actkb, kb, NULL, KEY_MODE_BPOINT); } @@ -700,8 +700,8 @@ static void cp_cu_key(Curve *cu, Key *key, KeyBlock *actkb, KeyBlock *kb, const step = 3 * nu->pntsu; /* exception because keys prefer to work with complete blocks */ - a1 = MAX2(a, start); - a2 = MIN2(a + step, end); + a1 = maxi(a, start); + a2 = mini(a + step, end); if (a1 < a2) cp_key(a1, a2, tot, out, key, actkb, kb, NULL, KEY_MODE_BEZTRIPLE); } @@ -1217,7 +1217,7 @@ static void do_curve_key(Scene *scene, Object *ob, Key *key, char *out, const in remain = step; } - count = MIN2(remain, estep); + count = mini(remain, estep); if (mode == KEY_MODE_BEZTRIPLE) { count += 3 - count % 3; } @@ -1573,7 +1573,7 @@ void key_to_latt(KeyBlock *kb, Lattice *lt) fp = kb->data; tot = lt->pntsu * lt->pntsv * lt->pntsw; - tot = MIN2(kb->totelem, tot); + tot = mini(kb->totelem, tot); for (a = 0; a < tot; a++, fp += 3, bp++) { copy_v3_v3(bp->vec, fp); @@ -1645,7 +1645,7 @@ void key_to_curve(KeyBlock *kb, Curve *UNUSED(cu), ListBase *nurb) tot = BKE_nurbList_verts_count(nurb); - tot = MIN2(kb->totelem, tot); + tot = mini(kb->totelem, tot); while (nu && tot > 0) { @@ -1713,7 +1713,7 @@ void key_to_mesh(KeyBlock *kb, Mesh *me) mvert = me->mvert; fp = kb->data; - tot = MIN2(kb->totelem, me->totvert); + tot = mini(kb->totelem, me->totvert); for (a = 0; a < tot; a++, fp += 3, mvert++) { copy_v3_v3(mvert->co, fp); diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index f73fb3879b8..06d063574a5 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -55,6 +55,7 @@ #include "BKE_sequencer.h" #include "BKE_tracking.h" #include "BKE_movieclip.h" +#include "BKE_image.h" static MaskSplinePoint *mask_spline_point_next(MaskSpline *spline, MaskSplinePoint *points_array, MaskSplinePoint *point) { @@ -1010,14 +1011,26 @@ void BKE_mask_coord_from_frame(float r_co[2], const float co[2], const float fra } void BKE_mask_coord_from_movieclip(MovieClip *clip, MovieClipUser *user, float r_co[2], const float co[2]) { - int width, height; + float aspx, aspy; float frame_size[2]; /* scaling for the clip */ - BKE_movieclip_get_size(clip, user, &width, &height); + BKE_movieclip_get_size_fl(clip, user, frame_size); + BKE_movieclip_get_aspect(clip, &aspx, &aspy); - frame_size[0] = (float)width; - frame_size[1] = (float)height; + frame_size[1] *= (aspy / aspx); + + BKE_mask_coord_from_frame(r_co, co, frame_size); +} +void BKE_mask_coord_from_image(Image *image, ImageUser *iuser, float r_co[2], const float co[2]) +{ + float aspx, aspy; + float frame_size[2]; + + BKE_image_get_size_fl(image, iuser, frame_size); + BKE_image_get_aspect(image, &aspx, &aspy); + + frame_size[1] *= (aspy / aspx); BKE_mask_coord_from_frame(r_co, co, frame_size); } @@ -1040,14 +1053,27 @@ void BKE_mask_coord_to_frame(float r_co[2], const float co[2], const float frame } void BKE_mask_coord_to_movieclip(MovieClip *clip, MovieClipUser *user, float r_co[2], const float co[2]) { - int width, height; + float aspx, aspy; + float frame_size[2]; + + /* scaling for the clip */ + BKE_movieclip_get_size_fl(clip, user, frame_size); + BKE_movieclip_get_aspect(clip, &aspx, &aspy); + + frame_size[1] /= (aspy / aspx); + + BKE_mask_coord_to_frame(r_co, co, frame_size); +} +void BKE_mask_coord_to_image(Image *image, ImageUser *iuser, float r_co[2], const float co[2]) +{ + float aspx, aspy; float frame_size[2]; /* scaling for the clip */ - BKE_movieclip_get_size(clip, user, &width, &height); + BKE_image_get_size_fl(image, iuser, frame_size); + BKE_image_get_aspect(image, &aspx, &aspy); - frame_size[0] = (float)width; - frame_size[1] = (float)height; + frame_size[1] /= (aspy / aspx); BKE_mask_coord_to_frame(r_co, co, frame_size); } diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c index eb96d6726b9..18617f0ef2e 100644 --- a/source/blender/blenkernel/intern/mask_rasterize.c +++ b/source/blender/blenkernel/intern/mask_rasterize.c @@ -26,6 +26,46 @@ /** \file blender/blenkernel/intern/mask_rasterize.c * \ingroup bke + * + * This module exposes a rasterizer that works as a black box - implementation details are confined to this file, + * + * The basic method to access is: + * - create & initialize a handle from a #Mask datablock. + * - execute pixel lookups. + * - free the handle. + * + * This file is admittedly a bit confusticated, in quite few areas speed was chosen over readability, + * though it is commented - so shouldn't be so hard to see whats going on. + * + * + * Implementation: + * + * To rasterize the mask its converted into geometry that use a ray-cast for each pixel lookup. + * + * Initially 'kdopbvh' was used but this ended up being too slow. + * + * To gain some extra speed we take advantage of a few shortcuts that can be made rasterizing masks specifically. + * - all triangles are known to be completely white - so no depth check is done on triangle intersection. + * - all quads are known to be feather outlines - the 1 and 0 depths are known by the vertex order in the quad, + * - there is no color - just a value for each mask pixel. + * - the mask spacial structure always maps to space 0-1 on X and Y axis. + * - bucketing is used to speed up lookups for geometry. + * + * Other Details: + * - used unsigned values all over for some extra speed on some arch's. + * - anti-aliasing is faked, just ensuring at least one pixel feather - avoids oversampling. + * - initializing the spacial structure doesn't need to be as optimized as pixel lookups are. + * - mask lookups need not be pixel aligned so any sub-pixel values from x/y (0 - 1), can be found. + * (perhaps masks can be used as a vector texture in 3D later on) + * + * + * Currently, to build the spacial structure we have to calculate the total number of faces ahead of time. + * + * This is getting a bit complicated with the addition of unfilled splines and end capping - + * If large changes are needed here we would be better off using an iterable + * BLI_mempool for triangles and converting to a contiguous array afterwards. + * + * - Campbell */ #include "MEM_guardedalloc.h" diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c index aa7388abd58..e83e6974102 100644 --- a/source/blender/blenkernel/intern/movieclip.c +++ b/source/blender/blenkernel/intern/movieclip.c @@ -1009,6 +1009,14 @@ void BKE_movieclip_get_size(MovieClip *clip, MovieClipUser *user, int *width, in IMB_freeImBuf(ibuf); } } +void BKE_movieclip_get_size_fl(MovieClip *clip, MovieClipUser *user, float size[2]) +{ + int width, height; + BKE_movieclip_get_size(clip, user, &width, &height); + + size[0] = (float)width; + size[1] = (float)height; +} int BKE_movieclip_get_duration(MovieClip *clip) { @@ -1019,9 +1027,9 @@ int BKE_movieclip_get_duration(MovieClip *clip) return clip->len; } -void BKE_movieclip_aspect(MovieClip *clip, float *aspx, float *aspy) +void BKE_movieclip_get_aspect(MovieClip *clip, float *aspx, float *aspy) { - *aspx = *aspy = 1.0; + *aspx = 1.0; /* x is always 1 */ *aspy = clip->aspy / clip->aspx / clip->tracking.camera.pixel_aspect; diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index dfa3582cee8..5dfecfcb717 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -2700,7 +2700,7 @@ void BKE_object_handle_update(Scene *scene, Object *ob) if (pid->cache->flag & PTCACHE_OUTDATED || (pid->cache->flag & PTCACHE_SIMULATION_VALID) == 0) { scene->physics_settings.quick_cache_step = scene->physics_settings.quick_cache_step ? - MIN2(scene->physics_settings.quick_cache_step, pid->cache->step) : + mini(scene->physics_settings.quick_cache_step, pid->cache->step) : pid->cache->step; } } diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index 5e12b15a658..780528f4a0d 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -1029,7 +1029,8 @@ void BKE_ptcache_ids_from_object(ListBase *lb, Object *ob, Scene *scene, int dup if (scene && (duplis-- > 0) && (ob->transflag & OB_DUPLI)) { ListBase *lb_dupli_ob; - if ((lb_dupli_ob=object_duplilist(scene, ob))) { + /* don't update the dupli groups, we only wan't their pid's */ + if ((lb_dupli_ob = object_duplilist_ex(scene, ob, FALSE))) { DupliObject *dob; for (dob= lb_dupli_ob->first; dob; dob= dob->next) { if (dob->ob != ob) { /* avoids recursive loops with dupliframes: bug 22988 */ diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index 5e79de7b4cd..e870ec5d8ee 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -3049,13 +3049,18 @@ int BKE_sequence_check_depend(Sequence *seq, Sequence *cur) return TRUE; } -static void sequence_invalidate_cache(Scene *scene, Sequence *seq, int invalidate_preprocess) +static void sequence_invalidate_cache(Scene *scene, Sequence *seq, int invalidate_self, int invalidate_preprocess) { Editing *ed = scene->ed; Sequence *cur; /* invalidate cache for current sequence */ - BKE_sequencer_cache_cleanup_sequence(seq); + if (invalidate_self) + BKE_sequencer_cache_cleanup_sequence(seq); + + /* if invalidation is invoked from sequence free routine, effectdata would be NULL here */ + if (seq->effectdata && seq->type == SEQ_TYPE_SPEED) + BKE_sequence_effect_speed_rebuild_map(scene, seq, TRUE); if (invalidate_preprocess) BKE_sequencer_preprocessed_cache_cleanup_sequence(seq); @@ -3076,12 +3081,17 @@ static void sequence_invalidate_cache(Scene *scene, Sequence *seq, int invalidat void BKE_sequence_invalidate_cache(Scene *scene, Sequence *seq) { - sequence_invalidate_cache(scene, seq, TRUE); + sequence_invalidate_cache(scene, seq, TRUE, TRUE); +} + +void BKE_sequence_invalidate_deendent(Scene *scene, Sequence *seq) +{ + sequence_invalidate_cache(scene, seq, FALSE, TRUE); } void BKE_sequence_invalidate_cache_for_modifier(Scene *scene, Sequence *seq) { - sequence_invalidate_cache(scene, seq, FALSE); + sequence_invalidate_cache(scene, seq, TRUE, FALSE); } void BKE_sequencer_free_imbuf(Scene *scene, ListBase *seqbase, int for_render) -- cgit v1.2.3 From 5badefa8cfafe0f6989594dbf827997a7a8597a1 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 13 Sep 2012 14:52:25 +0000 Subject: Color Management: fix crash when strip failed to render In this case sequencer would allocate empty image buffer which used to not to have assigned color spaces but it was marked as non-linear float. Assuming black would always be black in sequencer's color space no additional transformation for display is needed. Solved by removing NOLINEAR_FLOAT flag from image buffers and using check image buffer's float_colorspace for NULL when needed to check whether float buffer is linear or not. --- source/blender/blenkernel/intern/sequencer.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'source/blender/blenkernel/intern') diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index e870ec5d8ee..84881af8f16 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -2659,8 +2659,10 @@ static ImBuf *seq_render_strip(SeqRenderData context, Sequence *seq, float cfra) } } - if (ibuf == NULL) + if (ibuf == NULL) { ibuf = IMB_allocImBuf(context.rectx, context.recty, 32, IB_rect); + BKE_sequencer_imbuf_assign_spaces(context.scene, ibuf); + } if (ibuf->x != context.rectx || ibuf->y != context.recty) use_preprocess = TRUE; @@ -2739,7 +2741,6 @@ static ImBuf *seq_render_strip_stack(SeqRenderData context, ListBase *seqbasep, if (count == 1) { out = seq_render_strip(context, seq_arr[0], cfra); - out->colormanage_flags |= IMB_COLORMANAGE_NOLINEAR_FLOAT; BKE_sequencer_cache_put(context, seq_arr[0], cfra, SEQ_STRIPELEM_IBUF_COMP, out); @@ -2819,8 +2820,6 @@ static ImBuf *seq_render_strip_stack(SeqRenderData context, ListBase *seqbasep, BKE_sequencer_cache_put(context, seq_arr[i], cfra, SEQ_STRIPELEM_IBUF_COMP, out); } - out->colormanage_flags |= IMB_COLORMANAGE_NOLINEAR_FLOAT; - return out; } -- cgit v1.2.3 From 58da4a1760028dbf4b7f0df78ed3d897ba5690c2 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 14 Sep 2012 14:05:05 +0000 Subject: Merging r50576 through r50587 from trunk into soc-2011-tomato --- source/blender/blenkernel/intern/DerivedMesh.c | 2 +- source/blender/blenkernel/intern/fmodifier.c | 4 +-- source/blender/blenkernel/intern/lattice.c | 2 +- source/blender/blenkernel/intern/library.c | 48 ++++++++++++++++++++++++-- source/blender/blenkernel/intern/mask.c | 8 +++-- source/blender/blenkernel/intern/sequencer.c | 2 +- 6 files changed, 56 insertions(+), 10 deletions(-) (limited to 'source/blender/blenkernel/intern') diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index a7f8e1bb161..8c0aea5723f 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -2081,7 +2081,7 @@ static void editbmesh_calc_modifiers(Scene *scene, Object *ob, BMEditMesh *em, D if ((*final_r)->type != DM_TYPE_EDITBMESH) { DM_ensure_tessface(*final_r); } - if (cage_r) { + if (cage_r && *cage_r) { if ((*cage_r)->type != DM_TYPE_EDITBMESH) { if (*cage_r != *final_r) { DM_ensure_tessface(*cage_r); diff --git a/source/blender/blenkernel/intern/fmodifier.c b/source/blender/blenkernel/intern/fmodifier.c index 438188b1e2a..538d2469a93 100644 --- a/source/blender/blenkernel/intern/fmodifier.c +++ b/source/blender/blenkernel/intern/fmodifier.c @@ -965,8 +965,8 @@ FModifierTypeInfo *get_fmodifier_typeinfo(int type) } /* only return for valid types */ - if ( (type >= FMODIFIER_TYPE_NULL) && - (type <= FMODIFIER_NUM_TYPES) ) + if ((type >= FMODIFIER_TYPE_NULL) && + (type < FMODIFIER_NUM_TYPES)) { /* there shouldn't be any segfaults here... */ return fmodifiersTypeInfo[type]; diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c index 0e73d10fa5f..17e4103c7d3 100644 --- a/source/blender/blenkernel/intern/lattice.c +++ b/source/blender/blenkernel/intern/lattice.c @@ -488,7 +488,7 @@ static int where_on_path_deform(Object *ob, float ctime, float vec[4], float dir /* test for cyclic */ bl = cu->bev.first; if (!bl->nr) return 0; - if (bl && bl->poly > -1) cycl = 1; + if (bl->poly > -1) cycl = 1; if (cycl == 0) { ctime1 = CLAMPIS(ctime, 0.0f, 1.0f); diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index f8c1a35776a..45364f5aafa 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -800,6 +800,7 @@ static void animdata_dtar_clear_cb(ID *UNUSED(id), AnimData *adt, void *userdata /* used in headerbuttons.c image.c mesh.c screen.c sound.c and library.c */ void BKE_libblock_free(ListBase *lb, void *idv) { + Main *bmain = G.main; /* should eventually be an arg */ ID *id = idv; #ifdef WITH_PYTHON @@ -899,7 +900,7 @@ void BKE_libblock_free(ListBase *lb, void *idv) BKE_movieclip_free((MovieClip *)id); break; case ID_MSK: - BKE_mask_free((Mask *)id); + BKE_mask_free(bmain, (Mask *)id); break; } @@ -911,7 +912,7 @@ void BKE_libblock_free(ListBase *lb, void *idv) BLI_remlink(lb, id); /* this ID may be a driver target! */ - BKE_animdata_main_cb(G.main, animdata_dtar_clear_cb, (void *)id); + BKE_animdata_main_cb(bmain, animdata_dtar_clear_cb, (void *)id); MEM_freeN(id); } @@ -946,9 +947,52 @@ void free_main(Main *mainvar) ID *id; while ( (id = lb->first) ) { +#if 1 BKE_libblock_free(lb, id); +#else + /* errors freeing ID's can be hard to track down, + * enable this so valgrind will give the line number in its error log */ + switch (a) { + case 0: BKE_libblock_free(lb, id); break; + case 1: BKE_libblock_free(lb, id); break; + case 2: BKE_libblock_free(lb, id); break; + case 3: BKE_libblock_free(lb, id); break; + case 4: BKE_libblock_free(lb, id); break; + case 5: BKE_libblock_free(lb, id); break; + case 6: BKE_libblock_free(lb, id); break; + case 7: BKE_libblock_free(lb, id); break; + case 8: BKE_libblock_free(lb, id); break; + case 9: BKE_libblock_free(lb, id); break; + case 10: BKE_libblock_free(lb, id); break; + case 11: BKE_libblock_free(lb, id); break; + case 12: BKE_libblock_free(lb, id); break; + case 13: BKE_libblock_free(lb, id); break; + case 14: BKE_libblock_free(lb, id); break; + case 15: BKE_libblock_free(lb, id); break; + case 16: BKE_libblock_free(lb, id); break; + case 17: BKE_libblock_free(lb, id); break; + case 18: BKE_libblock_free(lb, id); break; + case 19: BKE_libblock_free(lb, id); break; + case 20: BKE_libblock_free(lb, id); break; + case 21: BKE_libblock_free(lb, id); break; + case 22: BKE_libblock_free(lb, id); break; + case 23: BKE_libblock_free(lb, id); break; + case 24: BKE_libblock_free(lb, id); break; + case 25: BKE_libblock_free(lb, id); break; + case 26: BKE_libblock_free(lb, id); break; + case 27: BKE_libblock_free(lb, id); break; + case 28: BKE_libblock_free(lb, id); break; + case 29: BKE_libblock_free(lb, id); break; + case 30: BKE_libblock_free(lb, id); break; + case 31: BKE_libblock_free(lb, id); break; + case 32: BKE_libblock_free(lb, id); break; + default: + BLI_assert(0); + } +#endif } } + a = set_listbasepointers(mainvar, lbarray); MEM_freeN(mainvar); } diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index 06d063574a5..97b46d4829d 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -910,7 +910,8 @@ void BKE_mask_layer_free_list(ListBase *masklayers) } } -void BKE_mask_free(Mask *mask) +/** free for temp copy, but don't manage unlinking from other pointers */ +void BKE_mask_free_nolib(Mask *mask) { BKE_mask_layer_free_list(&mask->masklayers); } @@ -928,7 +929,7 @@ static void ntree_unlink_mask_cb(void *calldata, struct ID *UNUSED(owner_id), st } } -void BKE_mask_unlink(Main *bmain, Mask *mask) +void BKE_mask_free(Main *bmain, Mask *mask) { bScreen *scr; ScrArea *area; @@ -991,7 +992,8 @@ void BKE_mask_unlink(Main *bmain, Mask *mask) treetype->foreach_nodetree(bmain, (void *)mask, &ntree_unlink_mask_cb); } - BKE_libblock_free(&bmain->mask, mask); + /* free mask data */ + BKE_mask_layer_free_list(&mask->masklayers); } void BKE_mask_coord_from_frame(float r_co[2], const float co[2], const float frame_size[2]) diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index 84881af8f16..0d8b220dd00 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -2254,7 +2254,7 @@ static ImBuf *seq_render_mask(SeqRenderData context, Mask *mask, float nr, short BKE_maskrasterize_handle_init(mr_handle, mask_temp, context.rectx, context.recty, TRUE, TRUE, TRUE); - BKE_mask_free(mask_temp); + BKE_mask_free_nolib(mask_temp); MEM_freeN(mask_temp); BKE_maskrasterize_buffer(mr_handle, context.rectx, context.recty, maskbuf); -- cgit v1.2.3 From d7f55cff20ff31e80d95c7837e9b45205dea273f Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 14 Sep 2012 14:36:47 +0000 Subject: Color Management: image buffer loading reworked Before this color space settings in image/movie clip data blocks defined space in which loaded image buffer is, based on whether this buffer contains float or byte buffer. This didn't work well for formats like 16bit PNG, which are in fact non-linear formats but were represented in Blender as float buffers. Now image buffer loader is responsible to set up input default color space for image/movie clip data blocks, which could be based on format itself only or on particular file properties. This means image/movie clip data blocks' input colorspace will be initialized at time first image buffer is loaded. This also resolves old confusing thing with image buffer's profile flag, which in could have been non-linear for image buffer which contained float buffer only -- this happened in mentioned case of 16 bit PNG format, i.e. Now float buffer would always be linear which should make it easier to get rid of image buffer's profile. --- source/blender/blenkernel/intern/image.c | 23 +++++++---------------- source/blender/blenkernel/intern/movieclip.c | 17 +++++++++-------- source/blender/blenkernel/intern/ocean.c | 7 ++++--- source/blender/blenkernel/intern/sequencer.c | 24 ++++++++++++++++-------- 4 files changed, 36 insertions(+), 35 deletions(-) (limited to 'source/blender/blenkernel/intern') diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index 0949f54642d..ce3e99a0807 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -304,12 +304,6 @@ static void image_assign_ibuf(Image *ima, ImBuf *ibuf, int index, int frame) else ibuf->flags &= ~IB_cm_predivide; - if (ima->source == IMA_SRC_GENERATED) { - /* for other image types spaces are set by image_initialize_after_load */ - - IMB_colormanagement_imbuf_assign_spaces(ibuf, &ima->colorspace_settings); - } - /* this function accepts (link == NULL) */ BLI_insertlinkbefore(&ima->ibufs, link, ibuf); @@ -1910,12 +1904,12 @@ void BKE_makepicstring(char *string, const char *base, const char *relbase, int } /* used by sequencer too */ -struct anim *openanim(const char *name, int flags, int streamindex) +struct anim *openanim(const char *name, int flags, int streamindex, char colorspace[IMA_MAX_SPACE]) { struct anim *anim; struct ImBuf *ibuf; - anim = IMB_open_anim(name, flags, streamindex); + anim = IMB_open_anim(name, flags, streamindex, colorspace); if (anim == NULL) return NULL; ibuf = IMB_anim_absolute(anim, 0, IMB_TC_NONE, IMB_PROXY_NONE); @@ -2224,9 +2218,6 @@ static void image_create_multilayer(Image *ima, ImBuf *ibuf, int framenr) /* common stuff to do with images after loading */ static void image_initialize_after_load(Image *ima, ImBuf *ibuf) { - /* make float buffer stored in ImBuf scene linear space */ - IMB_colormanagement_imbuf_make_scene_linear(ibuf, &ima->colorspace_settings); - /* preview is NULL when it has never been used as an icon before */ if (G.background == 0 && ima->preview == NULL) BKE_icon_changed(BKE_icon_getid(&ima->id)); @@ -2261,7 +2252,7 @@ static ImBuf *image_load_sequence_file(Image *ima, ImageUser *iuser, int frame) flag |= IB_premul; /* read ibuf */ - ibuf = IMB_loadiffname(name, flag); + ibuf = IMB_loadiffname(name, flag, ima->colorspace_settings.name); #if 0 if (ibuf) { @@ -2369,7 +2360,7 @@ static ImBuf *image_load_movie_file(Image *ima, ImageUser *iuser, int frame) BKE_image_user_file_path(iuser, ima, str); /* FIXME: make several stream accessible in image editor, too*/ - ima->anim = openanim(str, IB_rect, 0); + ima->anim = openanim(str, IB_rect, 0, ima->colorspace_settings.name); /* let's initialize this user */ if (ima->anim && iuser && iuser->frames == 0) @@ -2420,8 +2411,8 @@ static ImBuf *image_load_image_file(Image *ima, ImageUser *iuser, int cfra) flag = IB_rect | IB_multilayer; if (ima->flag & IMA_DO_PREMUL) flag |= IB_premul; - ibuf = IMB_ibImageFromMemory((unsigned char *)ima->packedfile->data, - ima->packedfile->size, flag, ""); + ibuf = IMB_ibImageFromMemory((unsigned char *)ima->packedfile->data, ima->packedfile->size, flag, + ima->colorspace_settings.name, ""); } else { flag = IB_rect | IB_multilayer | IB_metadata; @@ -2433,7 +2424,7 @@ static ImBuf *image_load_image_file(Image *ima, ImageUser *iuser, int cfra) BKE_image_user_file_path(iuser, ima, str); /* read ibuf */ - ibuf = IMB_loadiffname(str, flag); + ibuf = IMB_loadiffname(str, flag, ima->colorspace_settings.name); } if (ibuf) { diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c index e83e6974102..cd8b0e4e52c 100644 --- a/source/blender/blenkernel/intern/movieclip.c +++ b/source/blender/blenkernel/intern/movieclip.c @@ -199,19 +199,25 @@ static ImBuf *movieclip_load_sequence_file(MovieClip *clip, MovieClipUser *user, struct ImBuf *ibuf; char name[FILE_MAX]; int loadflag, use_proxy = FALSE; + char *colorspace; use_proxy = (flag & MCLIP_USE_PROXY) && user->render_size != MCLIP_PROXY_RENDER_SIZE_FULL; if (use_proxy) { int undistort = user->render_flag & MCLIP_PROXY_RENDER_UNDISTORT; get_proxy_fname(clip, user->render_size, undistort, framenr, name); + + /* proxies were built using default color space settings */ + colorspace = NULL; } - else + else { get_sequence_fname(clip, framenr, name); + colorspace = clip->colorspace_settings.name; + } loadflag = IB_rect | IB_multilayer; /* read ibuf */ - ibuf = IMB_loadiffname(name, loadflag); + ibuf = IMB_loadiffname(name, loadflag, colorspace); return ibuf; } @@ -225,7 +231,7 @@ static void movieclip_open_anim_file(MovieClip *clip) BLI_path_abs(str, ID_BLEND_PATH(G.main, &clip->id)); /* FIXME: make several stream accessible in image editor, too */ - clip->anim = openanim(str, IB_rect, 0); + clip->anim = openanim(str, IB_rect, 0, clip->colorspace_settings.name); if (clip->anim) { if (clip->flag & MCLIP_USE_PROXY_CUSTOM_DIR) { @@ -781,11 +787,6 @@ static ImBuf *movieclip_get_postprocessed_ibuf(MovieClip *clip, MovieClipUser *u ibuf = movieclip_load_movie_file(clip, user, framenr, flag); } - if (ibuf) { - /* make float buffer stored in ImBuf scene linear space */ - IMB_colormanagement_imbuf_make_scene_linear(ibuf, &clip->colorspace_settings); - } - if (ibuf && (cache_flag & MOVIECLIP_CACHE_SKIP) == 0) put_imbuf_cache(clip, user, ibuf, flag); } diff --git a/source/blender/blenkernel/intern/ocean.c b/source/blender/blenkernel/intern/ocean.c index b862a824d50..46b89f76194 100644 --- a/source/blender/blenkernel/intern/ocean.c +++ b/source/blender/blenkernel/intern/ocean.c @@ -1117,19 +1117,20 @@ void BKE_simulate_ocean_cache(struct OceanCache *och, int frame) /* if image is already loaded in mem, return */ if (och->ibufs_disp[f] != NULL) return; + /* use default color spaces since we know for sure cache files were saved with default settings too */ cache_filename(string, och->bakepath, och->relbase, frame, CACHE_TYPE_DISPLACE); - och->ibufs_disp[f] = IMB_loadiffname(string, 0); + och->ibufs_disp[f] = IMB_loadiffname(string, 0, NULL); //if (och->ibufs_disp[f] == NULL) printf("error loading %s\n", string); //else printf("loaded cache %s\n", string); cache_filename(string, och->bakepath, och->relbase, frame, CACHE_TYPE_FOAM); - och->ibufs_foam[f] = IMB_loadiffname(string, 0); + och->ibufs_foam[f] = IMB_loadiffname(string, 0, NULL); //if (och->ibufs_foam[f] == NULL) printf("error loading %s\n", string); //else printf("loaded cache %s\n", string); cache_filename(string, och->bakepath, och->relbase, frame, CACHE_TYPE_NORMAL); - och->ibufs_norm[f] = IMB_loadiffname(string, 0); + och->ibufs_norm[f] = IMB_loadiffname(string, 0, NULL); //if (och->ibufs_norm[f] == NULL) printf("error loading %s\n", string); //else printf("loaded cache %s\n", string); } diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index 0d8b220dd00..1d4efb01aa2 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -686,7 +686,9 @@ void BKE_sequence_reload_new_file(Scene *scene, Sequence *seq, int lock_range) BLI_path_abs(str, G.main->name); if (seq->anim) IMB_free_anim(seq->anim); - seq->anim = openanim(str, IB_rect | ((seq->flag & SEQ_FILTERY) ? IB_animdeinterlace : 0), seq->streamindex); + + /* OCIO_TODO: support configurable input space for strips */ + seq->anim = openanim(str, IB_rect | ((seq->flag & SEQ_FILTERY) ? IB_animdeinterlace : 0), seq->streamindex, NULL); if (!seq->anim) { return; @@ -1183,7 +1185,8 @@ static void seq_open_anim_file(Sequence *seq) seq->strip->dir, seq->strip->stripdata->name); BLI_path_abs(name, G.main->name); - seq->anim = openanim(name, IB_rect | ((seq->flag & SEQ_FILTERY) ? IB_animdeinterlace : 0), seq->streamindex); + /* OCIO_TODO: support configurable input space for strips */ + seq->anim = openanim(name, IB_rect | ((seq->flag & SEQ_FILTERY) ? IB_animdeinterlace : 0), seq->streamindex, NULL); if (seq->anim == NULL) { return; @@ -1289,8 +1292,9 @@ static ImBuf *seq_proxy_fetch(SeqRenderData context, Sequence *seq, int cfra) if (seq_proxy_get_fname(seq, cfra, render_size, name) == 0) { return NULL; } - - seq->strip->proxy->anim = openanim(name, IB_rect, 0); + + /* proxies are generated in default color space */ + seq->strip->proxy->anim = openanim(name, IB_rect, 0, NULL); } if (seq->strip->proxy->anim == NULL) { return NULL; @@ -1308,7 +1312,8 @@ static ImBuf *seq_proxy_fetch(SeqRenderData context, Sequence *seq, int cfra) } if (BLI_exists(name)) { - ImBuf *ibuf = IMB_loadiffname(name, IB_rect); + /* OCIO_TODO: support configurable spaces for strips */ + ImBuf *ibuf = IMB_loadiffname(name, IB_rect, NULL); if (ibuf) BKE_sequencer_imbuf_assign_spaces(context.scene, ibuf); @@ -1351,7 +1356,8 @@ static void seq_proxy_build_frame(SeqRenderData context, Sequence *seq, int cfra ibuf->planes = 24; BLI_make_existing_file(name); - + + /* OCIO_TODO: support per-strip color space settings */ ok = IMB_saveiff(ibuf, name, IB_rect | IB_zbuf | IB_zbuffloat); if (ok == 0) { perror(name); @@ -2536,7 +2542,8 @@ static ImBuf *do_render_strip_uncached(SeqRenderData context, Sequence *seq, flo BLI_path_abs(name, G.main->name); } - if (s_elem && (ibuf = IMB_loadiffname(name, IB_rect))) { + /* OCIO_TODO: support configurable space for image strips */ + if (s_elem && (ibuf = IMB_loadiffname(name, IB_rect, NULL))) { /* we don't need both (speed reasons)! */ if (ibuf->rect_float && ibuf->rect) imb_freerectImBuf(ibuf); @@ -4046,7 +4053,8 @@ Sequence *BKE_sequencer_add_movie_strip(bContext *C, ListBase *seqbasep, SeqLoad BLI_strncpy(path, seq_load->path, sizeof(path)); BLI_path_abs(path, G.main->name); - an = openanim(path, IB_rect, 0); + /* OCIO_TODO: support configurable input space for strips */ + an = openanim(path, IB_rect, 0, NULL); if (an == NULL) return NULL; -- cgit v1.2.3 From be5a35d91630bc0a4db9d655d9f0a8275b25c7ac Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 14 Sep 2012 14:37:19 +0000 Subject: Color Management: get rid of image buffer's profile flag Currently float buffers are always linear, space of byte buffer is defined by rect_colorspace property. Replaced logic of IMB_rect_from_float and IMB_float_from_rect to use this assumptions (before it was special function used in some areas only, now it's default behavior). Almost all functions from ImBuf module which are actually used are got rid from profile flag. Only remained issue is IMB_float_profile_ensure which only used by CIneon/DPX exporter which is broken for a while already. Need to be fixed separately. This also fixed clone brush when cloning byte image on top of float, before this result would be gamma-corrected twice. --- source/blender/blenkernel/intern/image.c | 5 ----- source/blender/blenkernel/intern/ocean.c | 2 -- source/blender/blenkernel/intern/sequencer.c | 19 ++----------------- source/blender/blenkernel/intern/tracking.c | 3 --- 4 files changed, 2 insertions(+), 27 deletions(-) (limited to 'source/blender/blenkernel/intern') diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index ce3e99a0807..f08af55c36e 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -612,12 +612,10 @@ static ImBuf *add_ibuf_size(unsigned int width, unsigned int height, const char if (floatbuf) { ibuf = IMB_allocImBuf(width, height, depth, IB_rectfloat); rect_float = ibuf->rect_float; - ibuf->profile = IB_PROFILE_LINEAR_RGB; } else { ibuf = IMB_allocImBuf(width, height, depth, IB_rect); rect = (unsigned char *)ibuf->rect; - ibuf->profile = IB_PROFILE_SRGB; } BLI_strncpy(ibuf->name, name, sizeof(ibuf->name)); @@ -2330,7 +2328,6 @@ static ImBuf *image_load_sequence_multilayer(Image *ima, ImageUser *iuser, int f ibuf->flags |= IB_rectfloat; ibuf->mall = IB_rectfloat; ibuf->channels = rpass->channels; - ibuf->profile = IB_PROFILE_LINEAR_RGB; image_initialize_after_load(ima, ibuf); image_assign_ibuf(ima, ibuf, iuser ? iuser->multi_index : 0, frame); @@ -2481,7 +2478,6 @@ static ImBuf *image_get_ibuf_multilayer(Image *ima, ImageUser *iuser) ibuf->rect_float = rpass->rect; ibuf->flags |= IB_rectfloat; ibuf->channels = rpass->channels; - ibuf->profile = IB_PROFILE_LINEAR_RGB; image_assign_ibuf(ima, ibuf, iuser ? iuser->multi_index : IMA_NO_INDEX, 0); } @@ -2630,7 +2626,6 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **lock_ BLI_unlock_thread(LOCK_COLORMANAGE); - ibuf->profile = IB_PROFILE_LINEAR_RGB; ibuf->dither = dither; if (iuser->scene->r.color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE) { diff --git a/source/blender/blenkernel/intern/ocean.c b/source/blender/blenkernel/intern/ocean.c index 46b89f76194..4f3921936e8 100644 --- a/source/blender/blenkernel/intern/ocean.c +++ b/source/blender/blenkernel/intern/ocean.c @@ -1173,8 +1173,6 @@ void BKE_bake_ocean(struct Ocean *o, struct OceanCache *och, void (*update_cb)(v ibuf_disp = IMB_allocImBuf(res_x, res_y, 32, IB_rectfloat); ibuf_normal = IMB_allocImBuf(res_x, res_y, 32, IB_rectfloat); - ibuf_disp->profile = ibuf_foam->profile = ibuf_normal->profile = IB_PROFILE_LINEAR_RGB; - BKE_simulate_ocean(o, och->time[i], och->wave_scale, och->chop_amount); /* add new foam */ diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index 1d4efb01aa2..20db9d5e056 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -313,7 +313,6 @@ void BKE_sequencer_editing_free(Scene *scene) void BKE_sequencer_imbuf_assign_spaces(Scene *scene, ImBuf *ibuf) { - IMB_colormanagement_imbuf_assign_spaces(ibuf, NULL); IMB_colormanagement_imbuf_assign_float_space(ibuf, &scene->sequencer_colorspace_settings); } @@ -335,7 +334,7 @@ void BKE_sequencer_imbuf_to_sequencer_space(Scene *scene, ImBuf *ibuf, int make_ * OCIO_TODO: would be nice to support direct single transform from byte to sequencer's */ - IMB_colormanagement_imbuf_float_from_rect(ibuf); + IMB_float_from_rect(ibuf); } else { /* if there's only byte buffer in image it's already in compositor's working space, @@ -352,12 +351,6 @@ void BKE_sequencer_imbuf_to_sequencer_space(Scene *scene, ImBuf *ibuf, int make_ IMB_colormanagement_transform_threaded(ibuf->rect_float, ibuf->x, ibuf->y, ibuf->channels, from_colorspace, to_colorspace, predivide); - - ibuf->profile = IB_PROFILE_SRGB; - } - else { - /* if no color management enables fallback to legacy conversion */ - IMB_convert_profile(ibuf, IB_PROFILE_NONE); } } @@ -374,12 +367,6 @@ void BKE_sequencer_imbuf_from_sequencer_space(Scene *scene, ImBuf *ibuf) IMB_colormanagement_transform_threaded(ibuf->rect_float, ibuf->x, ibuf->y, ibuf->channels, from_colorspace, to_colorspace, predivide); - - ibuf->profile = IB_PROFILE_LINEAR_RGB; - } - else { - /* if no color management enables fallback to legacy conversion */ - IMB_convert_profile(ibuf, IB_PROFILE_LINEAR_RGB); } } @@ -2441,7 +2428,6 @@ static ImBuf *seq_render_scene_strip(SeqRenderData context, Sequence *seq, float } /* float buffers in the sequencer are not linear */ - ibuf->profile = IB_PROFILE_LINEAR_RGB; BKE_sequencer_imbuf_to_sequencer_space(context.scene, ibuf, FALSE); } else if (rres.rect32) { @@ -2549,8 +2535,7 @@ static ImBuf *do_render_strip_uncached(SeqRenderData context, Sequence *seq, flo imb_freerectImBuf(ibuf); /* all sequencer color is done in SRGB space, linear gives odd crossfades */ - if (ibuf->profile == IB_PROFILE_LINEAR_RGB) - BKE_sequencer_imbuf_to_sequencer_space(context.scene, ibuf, FALSE); + BKE_sequencer_imbuf_to_sequencer_space(context.scene, ibuf, FALSE); copy_to_ibuf_still(context, seq, nr, ibuf); diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index 2ed9d992c3f..c0c5c579133 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -1627,7 +1627,6 @@ ImBuf *BKE_tracking_sample_pattern(int frame_width, int frame_height, ImBuf *sea float *mask = NULL; pattern_ibuf = IMB_allocImBuf(num_samples_x, num_samples_y, 32, IB_rectfloat); - pattern_ibuf->profile = IB_PROFILE_LINEAR_RGB; if (!search_ibuf->rect_float) { IMB_float_from_rect(search_ibuf); @@ -1722,7 +1721,6 @@ ImBuf *BKE_tracking_get_search_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, Mov h = (marker->search_max[1] - marker->search_min[1]) * ibuf->y; searchibuf = IMB_allocImBuf(w, h, 32, ibuf->rect_float ? IB_rectfloat : IB_rect); - searchibuf->profile = ibuf->profile; IMB_rectcpy(searchibuf, ibuf, 0, 0, x, y, w, h); @@ -3317,7 +3315,6 @@ static ImBuf *stabilization_allocate_ibuf(ImBuf *cacheibuf, ImBuf *srcibuf, int } else { cacheibuf = IMB_allocImBuf(srcibuf->x, srcibuf->y, srcibuf->planes, flags); - cacheibuf->profile = srcibuf->profile; } return cacheibuf; -- cgit v1.2.3 From beba8014e444d154124f3739f2f3edbf58c972e6 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Sat, 15 Sep 2012 06:24:48 +0000 Subject: Merging r50602 through r50617 form trunk into soc-2011-tomato --- source/blender/blenkernel/intern/blender.c | 6 ++-- source/blender/blenkernel/intern/cloth.c | 35 ++-------------------- source/blender/blenkernel/intern/dynamicpaint.c | 21 +++++++------ source/blender/blenkernel/intern/implicit.c | 18 ++++++----- source/blender/blenkernel/intern/mask.c | 5 ++-- source/blender/blenkernel/intern/mask_rasterize.c | 6 ++-- source/blender/blenkernel/intern/movieclip.c | 6 ++-- source/blender/blenkernel/intern/object.c | 34 +++++++++++++-------- source/blender/blenkernel/intern/particle_system.c | 5 ++-- source/blender/blenkernel/intern/seqmodifier.c | 32 ++++++++++---------- source/blender/blenkernel/intern/smoke.c | 6 ++-- source/blender/blenkernel/intern/text.c | 24 --------------- source/blender/blenkernel/intern/texture.c | 2 +- source/blender/blenkernel/intern/tracking.c | 4 +-- source/blender/blenkernel/intern/writeffmpeg.c | 2 +- 15 files changed, 83 insertions(+), 123 deletions(-) (limited to 'source/blender/blenkernel/intern') diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index 9145c4af850..99b788e80ce 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -92,7 +92,7 @@ #include "IMB_colormanagement.h" #ifdef WITH_PYTHON -#include "BPY_extern.h" +# include "BPY_extern.h" #endif Global G; @@ -219,8 +219,6 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath /* no load screens? */ if (mode) { /* comes from readfile.c */ - extern void lib_link_screen_restore(Main *, bScreen *, Scene *); - SWAP(ListBase, G.main->wm, bfd->main->wm); SWAP(ListBase, G.main->screen, bfd->main->screen); SWAP(ListBase, G.main->script, bfd->main->script); @@ -234,7 +232,7 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath if (curscreen) curscreen->scene = curscene; /* can run in bgmode */ /* clear_global will free G.main, here we can still restore pointers */ - lib_link_screen_restore(bfd->main, curscreen, curscene); + blo_lib_link_screen_restore(bfd->main, curscreen, curscene); } /* free G.main Main database */ diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index b0de7a5ea6c..4241756a109 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -50,36 +50,7 @@ #include "BKE_modifier.h" #include "BKE_pointcache.h" -#ifdef _WIN32 -void tstart( void ) -{} -void tend( void ) -{ -} -double tval( void ) -{ - return 0; -} -#else -#include -static struct timeval _tstart, _tend; -static struct timezone tz; -void tstart( void ) -{ - gettimeofday(&_tstart, &tz); -} -void tend(void) -{ - gettimeofday(&_tend, &tz); -} -double tval(void) -{ - double t1, t2; - t1 = ( double ) _tstart.tv_sec + ( double ) _tstart.tv_usec/ ( 1000*1000 ); - t2 = ( double ) _tend.tv_sec + ( double ) _tend.tv_usec/ ( 1000*1000 ); - return t2-t1; -} -#endif +// #include "PIL_time.h" /* timing for debug prints */ /* Our available solvers. */ // 255 is the magic reserved number, so NEVER try to put 255 solvers in here! @@ -410,13 +381,13 @@ static int do_step_cloth(Object *ob, ClothModifierData *clmd, DerivedMesh *resul cloth_apply_vgroup ( clmd, result ); cloth_update_springs( clmd ); - tstart(); + // TIMEIT_START(cloth_step) /* call the solver. */ if (solvers [clmd->sim_parms->solver_type].solver) ret = solvers[clmd->sim_parms->solver_type].solver(ob, framenr, clmd, effectors); - tend(); + // TIMEIT_END(cloth_step) pdEndEffectors(&effectors); diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c index f47ac641cf9..1cb29b90133 100644 --- a/source/blender/blenkernel/intern/dynamicpaint.c +++ b/source/blender/blenkernel/intern/dynamicpaint.c @@ -669,7 +669,7 @@ static void boundInsert(Bounds3D *b, float point[3]) } } -float getSurfaceDimension(PaintSurfaceData *sData) +static float getSurfaceDimension(PaintSurfaceData *sData) { Bounds3D *mb = &sData->bData->mesh_bounds; return MAX3((mb->max[0] - mb->min[0]), (mb->max[1] - mb->min[1]), (mb->max[2] - mb->min[2])); @@ -910,7 +910,7 @@ static void free_bakeData(PaintSurfaceData *data) } /* free surface data if it's not used anymore */ -void surface_freeUnusedData(DynamicPaintSurface *surface) +static void surface_freeUnusedData(DynamicPaintSurface *surface) { if (!surface->data) return; @@ -1368,7 +1368,7 @@ static void dynamicPaint_initAdjacencyData(DynamicPaintSurface *surface, int for MEM_freeN(temp_data); } -void dynamicPaint_setInitialColor(DynamicPaintSurface *surface) +static void dynamicPaint_setInitialColor(DynamicPaintSurface *surface) { PaintSurfaceData *sData = surface->data; PaintPoint *pPoint = (PaintPoint *)sData->type_data; @@ -1605,7 +1605,7 @@ static void dynamicPaint_applySurfaceDisplace(DynamicPaintSurface *surface, Deri /* * Apply canvas data to the object derived mesh */ -struct DerivedMesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, +static DerivedMesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, Object *ob, DerivedMesh *dm) { @@ -1830,9 +1830,12 @@ void dynamicPaint_cacheUpdateFrames(DynamicPaintSurface *surface) } } -void canvas_copyDerivedMesh(DynamicPaintCanvasSettings *canvas, DerivedMesh *dm) +static void canvas_copyDerivedMesh(DynamicPaintCanvasSettings *canvas, DerivedMesh *dm) { - if (canvas->dm) canvas->dm->release(canvas->dm); + if (canvas->dm) { + canvas->dm->release(canvas->dm); + } + canvas->dm = CDDM_copy(dm); } @@ -2748,7 +2751,7 @@ static void dynamicPaint_freeBrushMaterials(BrushMaterials *bMats) /* * Get material diffuse color and alpha (including linked textures) in given coordinates */ -void dynamicPaint_doMaterialTex(BrushMaterials *bMats, float color[3], float *alpha, Object *brushOb, const float volume_co[3], const float surface_co[3], int faceIndex, short isQuad, DerivedMesh *orcoDm) +static void dynamicPaint_doMaterialTex(BrushMaterials *bMats, float color[3], float *alpha, Object *brushOb, const float volume_co[3], const float surface_co[3], int faceIndex, short isQuad, DerivedMesh *orcoDm) { Material *mat = bMats->mat; MFace *mface = orcoDm->getTessFaceArray(orcoDm); @@ -3953,7 +3956,7 @@ static void dynamicPaint_prepareAdjacencyData(DynamicPaintSurface *surface, int } /* find two adjacency points (closest_id) and influence (closest_d) to move paint towards when affected by a force */ -void surface_determineForceTargetPoints(PaintSurfaceData *sData, int index, float force[3], float closest_d[2], int closest_id[2]) +static void surface_determineForceTargetPoints(PaintSurfaceData *sData, int index, float force[3], float closest_d[2], int closest_id[2]) { BakeAdjPoint *bNeighs = sData->bData->bNeighs; int numOfNeighs = sData->adj_data->n_num[index]; @@ -4342,7 +4345,7 @@ static void dynamicPaint_doEffectStep(DynamicPaintSurface *surface, float *force } } -void dynamicPaint_doWaveStep(DynamicPaintSurface *surface, float timescale) +static void dynamicPaint_doWaveStep(DynamicPaintSurface *surface, float timescale) { PaintSurfaceData *sData = surface->data; BakeAdjPoint *bNeighs = sData->bData->bNeighs; diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index 1c6974b2615..fcc8b4322a0 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -50,6 +50,7 @@ #define CLOTH_OPENMP_LIMIT 512 +#if 0 /* debug timing */ #ifdef _WIN32 #include static LARGE_INTEGER _itstart, _itend; @@ -81,7 +82,7 @@ double itval(void) static struct timeval _itstart, _itend; static struct timezone itz; -void itstart(void) +static void itstart(void) { gettimeofday(&_itstart, &itz); } @@ -89,7 +90,7 @@ static void itend(void) { gettimeofday(&_itend, &itz); } -double itval(void) +static double itval(void) { double t1, t2; t1 = (double)_itstart.tv_sec + (double)_itstart.tv_usec/(1000*1000); @@ -97,6 +98,7 @@ double itval(void) return t2-t1; } #endif +#endif /* debug timing */ static float I[3][3] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}; static float ZERO[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; @@ -1691,13 +1693,13 @@ static void simulate_implicit_euler(lfVector *Vnew, lfVector *UNUSED(lX), lfVect mul_bfmatrix_lfvector(dFdXmV, dFdX, lV); add_lfvectorS_lfvectorS(B, lF, dt, dFdXmV, (dt*dt), numverts); - - itstart(); - + + // itstart(); + cg_filtered(dV, A, B, z, S); /* conjugate gradient algorithm to solve Ax=b */ // cg_filtered_pre(dV, A, B, z, S, P, Pinv, bigI); - - itend(); + + // itend(); // printf("cg_filtered calc time: %f\n", (float)itval()); cp_lfvector(olddV, dV, numverts); @@ -1713,7 +1715,7 @@ static void simulate_implicit_euler(lfVector *Vnew, lfVector *UNUSED(lX), lfVect * (edge distance constraints) in a lagrangian solver. then add forces to help * guide the implicit solver to that state. this function is called after * collisions*/ -int cloth_calc_helper_forces(Object *UNUSED(ob), ClothModifierData * clmd, float (*initial_cos)[3], float UNUSED(step), float dt) +static int UNUSED_FUNCTION(cloth_calc_helper_forces)(Object *UNUSED(ob), ClothModifierData * clmd, float (*initial_cos)[3], float UNUSED(step), float dt) { Cloth *cloth= clmd->clothObject; float (*cos)[3] = MEM_callocN(sizeof(float)*3*cloth->numverts, "cos cloth_calc_helper_forces"); diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index 97b46d4829d..3564071334c 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -1112,7 +1112,8 @@ static int BKE_mask_evaluate_parent(MaskParent *parent, float ctime, float r_co[ return FALSE; } -int BKE_mask_evaluate_parent_delta(MaskParent *parent, float ctime, float r_delta[2]) +/* could make external but for now its only used internally */ +static int mask_evaluate_parent_delta(MaskParent *parent, float ctime, float r_delta[2]) { float parent_co[2]; @@ -1452,7 +1453,7 @@ void BKE_mask_layer_evaluate(MaskLayer *masklay, const float ctime, const int do *point_deform = *point; point_deform->uw = point->uw ? MEM_dupallocN(point->uw) : NULL; - if (BKE_mask_evaluate_parent_delta(&point->parent, ctime, delta)) { + if (mask_evaluate_parent_delta(&point->parent, ctime, delta)) { add_v2_v2(point_deform->bezt.vec[0], delta); add_v2_v2(point_deform->bezt.vec[1], delta); add_v2_v2(point_deform->bezt.vec[2], delta); diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c index 18617f0ef2e..00898b0fe10 100644 --- a/source/blender/blenkernel/intern/mask_rasterize.c +++ b/source/blender/blenkernel/intern/mask_rasterize.c @@ -253,9 +253,9 @@ void BKE_maskrasterize_handle_free(MaskRasterHandle *mr_handle) } -void maskrasterize_spline_differentiate_point_outset(float (*diff_feather_points)[2], float (*diff_points)[2], - const unsigned int tot_diff_point, const float ofs, - const short do_test) +static void maskrasterize_spline_differentiate_point_outset(float (*diff_feather_points)[2], float (*diff_points)[2], + const unsigned int tot_diff_point, const float ofs, + const short do_test) { unsigned int k_prev = tot_diff_point - 2; unsigned int k_curr = tot_diff_point - 1; diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c index cd8b0e4e52c..97d4c150b84 100644 --- a/source/blender/blenkernel/intern/movieclip.c +++ b/source/blender/blenkernel/intern/movieclip.c @@ -391,7 +391,7 @@ static int moviecache_hashcmp(const void *av, const void *bv) return 0; } -void *moviecache_getprioritydata(void *key_v) +static void *moviecache_getprioritydata(void *key_v) { MovieClipImBufCacheKey *key = (MovieClipImBufCacheKey *) key_v; MovieClipCachePriorityData *priority_data; @@ -402,7 +402,7 @@ void *moviecache_getprioritydata(void *key_v) return priority_data; } -int moviecache_getitempriority(void *last_userkey_v, void *priority_data_v) +static int moviecache_getitempriority(void *last_userkey_v, void *priority_data_v) { MovieClipImBufCacheKey *last_userkey = (MovieClipImBufCacheKey *) last_userkey_v; MovieClipCachePriorityData *priority_data = (MovieClipCachePriorityData *) priority_data_v; @@ -410,7 +410,7 @@ int moviecache_getitempriority(void *last_userkey_v, void *priority_data_v) return -abs(last_userkey->framenr - priority_data->framenr); } -void moviecache_prioritydeleter(void *priority_data_v) +static void moviecache_prioritydeleter(void *priority_data_v) { MovieClipCachePriorityData *priority_data = (MovieClipCachePriorityData *) priority_data_v; diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 5dfecfcb717..4fb235ac9f7 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -305,17 +305,27 @@ void BKE_object_free(Object *ob) ID *id = ob->data; id->us--; if (id->us == 0) { - if (ob->type == OB_MESH) BKE_mesh_unlink(ob->data); - else if (ob->type == OB_CURVE) BKE_curve_unlink(ob->data); - else if (ob->type == OB_MBALL) BKE_mball_unlink(ob->data); + switch (ob->type) { + case OB_MESH: + BKE_mesh_unlink((Mesh *)id); + break; + case OB_CURVE: + BKE_curve_unlink((Curve *)id); + break; + case OB_MBALL: + BKE_mball_unlink((MetaBall *)id); + break; + } } ob->data = NULL; } - - for (a = 0; a < ob->totcol; a++) { - if (ob->mat[a]) ob->mat[a]->id.us--; + + if (ob->mat) { + for (a = 0; a < ob->totcol; a++) { + if (ob->mat[a]) ob->mat[a]->id.us--; + } + MEM_freeN(ob->mat); } - if (ob->mat) MEM_freeN(ob->mat); if (ob->matbits) MEM_freeN(ob->matbits); ob->mat = NULL; ob->matbits = NULL; @@ -1757,8 +1767,8 @@ static void give_parvert(Object *par, int nr, float vec[3]) { BMEditMesh *em; int a, count; - - vec[0] = vec[1] = vec[2] = 0.0f; + + zero_v3(vec); if (par->type == OB_MESH) { Mesh *me = par->data; @@ -1850,7 +1860,7 @@ static void give_parvert(Object *par, int nr, float vec[3]) while (a--) { if (count == nr) { found = 1; - memcpy(vec, bp->vec, sizeof(float) * 3); + copy_v3_v3(vec, bp->vec); break; } count++; @@ -1875,9 +1885,9 @@ static void give_parvert(Object *par, int nr, float vec[3]) while (a--) { if (count == nr) { if (co) - memcpy(vec, co, 3 * sizeof(float)); + copy_v3_v3(vec, co); else - memcpy(vec, bp->vec, 3 * sizeof(float)); + copy_v3_v3(vec, bp->vec); break; } count++; diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index bae8efa758e..2c0452bc2d1 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -3776,7 +3776,7 @@ static void save_hair(ParticleSimulationData *sim, float UNUSED(cfra)) * simulation. This should be called once per particle during a simulation * step, after the velocity has been updated. element_size defines the scale of * the simulation, and is typically the distance to neighbourning particles. */ -void update_courant_num(ParticleSimulationData *sim, ParticleData *pa, +static void update_courant_num(ParticleSimulationData *sim, ParticleData *pa, float dtime, SPHData *sphdata) { float relative_vel[3]; @@ -3788,8 +3788,7 @@ void update_courant_num(ParticleSimulationData *sim, ParticleData *pa, sim->courant_num = speed * dtime / sphdata->element_size; } /* Update time step size to suit current conditions. */ -float update_timestep(ParticleSystem *psys, ParticleSimulationData *sim, - float t_frac) +static float update_timestep(ParticleSystem *psys, ParticleSimulationData *sim, float t_frac) { if (sim->courant_num == 0.0f) psys->dt_frac = 1.0f; diff --git a/source/blender/blenkernel/intern/seqmodifier.c b/source/blender/blenkernel/intern/seqmodifier.c index 1fa009d22a0..b0dcad64722 100644 --- a/source/blender/blenkernel/intern/seqmodifier.c +++ b/source/blender/blenkernel/intern/seqmodifier.c @@ -140,7 +140,7 @@ static void modifier_apply_threaded(ImBuf *ibuf, ImBuf *mask, modifier_apply_thr /* **** Color Balance Modifier **** */ -void colorBalance_init_data(SequenceModifierData *smd) +static void colorBalance_init_data(SequenceModifierData *smd) { ColorBalanceModifierData *cbmd = (ColorBalanceModifierData *) smd; int c; @@ -154,7 +154,7 @@ void colorBalance_init_data(SequenceModifierData *smd) } } -void colorBalance_apply(SequenceModifierData *smd, ImBuf *ibuf, ImBuf *mask) +static void colorBalance_apply(SequenceModifierData *smd, ImBuf *ibuf, ImBuf *mask) { ColorBalanceModifierData *cbmd = (ColorBalanceModifierData *) smd; @@ -173,21 +173,21 @@ static SequenceModifierTypeInfo seqModifier_ColorBalance = { /* **** Curves Modifier **** */ -void curves_init_data(SequenceModifierData *smd) +static void curves_init_data(SequenceModifierData *smd) { CurvesModifierData *cmd = (CurvesModifierData *) smd; curvemapping_set_defaults(&cmd->curve_mapping, 4, 0.0f, 0.0f, 1.0f, 1.0f); } -void curves_free_data(SequenceModifierData *smd) +static void curves_free_data(SequenceModifierData *smd) { CurvesModifierData *cmd = (CurvesModifierData *) smd; curvemapping_free_data(&cmd->curve_mapping); } -void curves_copy_data(SequenceModifierData *target, SequenceModifierData *smd) +static void curves_copy_data(SequenceModifierData *target, SequenceModifierData *smd) { CurvesModifierData *cmd = (CurvesModifierData *) smd; CurvesModifierData *cmd_target = (CurvesModifierData *) target; @@ -195,8 +195,8 @@ void curves_copy_data(SequenceModifierData *target, SequenceModifierData *smd) curvemapping_copy_data(&cmd_target->curve_mapping, &cmd->curve_mapping); } -void curves_apply_threaded(int width, int height, unsigned char *rect, float *rect_float, - unsigned char *mask_rect, float *mask_rect_float, void *data_v) +static void curves_apply_threaded(int width, int height, unsigned char *rect, float *rect_float, + unsigned char *mask_rect, float *mask_rect_float, void *data_v) { CurveMapping *curve_mapping = (CurveMapping *) data_v; int x, y; @@ -249,7 +249,7 @@ void curves_apply_threaded(int width, int height, unsigned char *rect, float *re } } -void curves_apply(struct SequenceModifierData *smd, ImBuf *ibuf, ImBuf *mask) +static void curves_apply(struct SequenceModifierData *smd, ImBuf *ibuf, ImBuf *mask) { CurvesModifierData *cmd = (CurvesModifierData *) smd; @@ -278,7 +278,7 @@ static SequenceModifierTypeInfo seqModifier_Curves = { /* **** Hue Correct Modifier **** */ -void hue_correct_init_data(SequenceModifierData *smd) +static void hue_correct_init_data(SequenceModifierData *smd) { HueCorrectModifierData *hcmd = (HueCorrectModifierData *) smd; int c; @@ -296,14 +296,14 @@ void hue_correct_init_data(SequenceModifierData *smd) hcmd->curve_mapping.cur = 1; } -void hue_correct_free_data(SequenceModifierData *smd) +static void hue_correct_free_data(SequenceModifierData *smd) { HueCorrectModifierData *hcmd = (HueCorrectModifierData *) smd; curvemapping_free_data(&hcmd->curve_mapping); } -void hue_correct_copy_data(SequenceModifierData *target, SequenceModifierData *smd) +static void hue_correct_copy_data(SequenceModifierData *target, SequenceModifierData *smd) { HueCorrectModifierData *hcmd = (HueCorrectModifierData *) smd; HueCorrectModifierData *hcmd_target = (HueCorrectModifierData *) target; @@ -311,7 +311,7 @@ void hue_correct_copy_data(SequenceModifierData *target, SequenceModifierData *s curvemapping_copy_data(&hcmd_target->curve_mapping, &hcmd->curve_mapping); } -void hue_correct_apply_threaded(int width, int height, unsigned char *rect, float *rect_float, +static void hue_correct_apply_threaded(int width, int height, unsigned char *rect, float *rect_float, unsigned char *mask_rect, float *mask_rect_float, void *data_v) { CurveMapping *curve_mapping = (CurveMapping *) data_v; @@ -365,7 +365,7 @@ void hue_correct_apply_threaded(int width, int height, unsigned char *rect, floa } } -void hue_correct_apply(struct SequenceModifierData *smd, ImBuf *ibuf, ImBuf *mask) +static void hue_correct_apply(struct SequenceModifierData *smd, ImBuf *ibuf, ImBuf *mask) { HueCorrectModifierData *hcmd = (HueCorrectModifierData *) smd; @@ -391,8 +391,8 @@ typedef struct BrightContrastThreadData { float contrast; } BrightContrastThreadData; -void brightcontrast_apply_threaded(int width, int height, unsigned char *rect, float *rect_float, - unsigned char *mask_rect, float *mask_rect_float, void *data_v) +static void brightcontrast_apply_threaded(int width, int height, unsigned char *rect, float *rect_float, + unsigned char *mask_rect, float *mask_rect_float, void *data_v) { BrightContrastThreadData *data = (BrightContrastThreadData *) data_v; int x, y; @@ -460,7 +460,7 @@ void brightcontrast_apply_threaded(int width, int height, unsigned char *rect, f } } -void brightcontrast_apply(struct SequenceModifierData *smd, ImBuf *ibuf, ImBuf *mask) +static void brightcontrast_apply(struct SequenceModifierData *smd, ImBuf *ibuf, ImBuf *mask) { BrightContrastModifierData *bcmd = (BrightContrastModifierData *) smd; BrightContrastThreadData data; diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c index ddcba509301..5e67e094e43 100644 --- a/source/blender/blenkernel/intern/smoke.c +++ b/source/blender/blenkernel/intern/smoke.c @@ -80,10 +80,10 @@ /* UNUSED so far, may be enabled later */ /* #define USE_SMOKE_COLLISION_DM */ -#ifdef WITH_SMOKE - #include "smoke_API.h" +#ifdef WITH_SMOKE + #ifdef _WIN32 #include #include @@ -148,7 +148,7 @@ static void fill_scs_points(Object *ob, DerivedMesh *dm, SmokeCollSettings *scs) /* Stubs to use when smoke is disabled */ struct WTURBULENCE *smoke_turbulence_init(int *UNUSED(res), int UNUSED(amplify), int UNUSED(noisetype)) { return NULL; } -struct FLUID_3D *smoke_init(int *UNUSED(res), float *UNUSED(p0)) { return NULL; } +// struct FLUID_3D *smoke_init(int *UNUSED(res), float *UNUSED(p0)) { return NULL; } void smoke_free(struct FLUID_3D *UNUSED(fluid)) {} float *smoke_get_density(struct FLUID_3D *UNUSED(fluid)) { return NULL; } void smoke_turbulence_free(struct WTURBULENCE *UNUSED(wt)) {} diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c index 787def5c20b..af5a8f5d59d 100644 --- a/source/blender/blenkernel/intern/text.c +++ b/source/blender/blenkernel/intern/text.c @@ -3031,30 +3031,6 @@ void txt_uncomment(Text *text) } } - -void txt_move_lines_up(struct Text *text) -{ - TextLine *prev_line; - - if (!text || !text->curl || !text->sell) return; - - txt_order_cursors(text); - - prev_line = text->curl->prev; - - if (!prev_line) return; - - BLI_remlink(&text->lines, prev_line); - BLI_insertlinkafter(&text->lines, text->sell, prev_line); - - txt_make_dirty(text); - txt_clean_text(text); - - if (!undoing) { - txt_undo_add_op(text, UNDO_MOVE_LINES_UP); - } -} - void txt_move_lines(struct Text *text, const int direction) { TextLine *line_other; diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c index ee904de4af6..bdd9b424f3b 100644 --- a/source/blender/blenkernel/intern/texture.c +++ b/source/blender/blenkernel/intern/texture.c @@ -338,7 +338,7 @@ void colorband_table_RGBA(ColorBand *coba, float **array, int *size) do_colorband(coba, (float)a / (float)CM_TABLE, &(*array)[a * 4]); } -int vergcband(const void *a1, const void *a2) +static int vergcband(const void *a1, const void *a2) { const CBData *x1 = a1, *x2 = a2; diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index c0c5c579133..97ebc3a90ba 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -2223,8 +2223,8 @@ static ImBuf *tracking_context_get_frame_ibuf(MovieTrackingContext *context, int return ibuf; } -MovieTrackingMarker *tracking_context_get_keyframed_marker(MovieTrackingContext *context, MovieTrackingTrack *track, - MovieTrackingMarker *marker) +static MovieTrackingMarker *tracking_context_get_keyframed_marker(MovieTrackingContext *context, MovieTrackingTrack *track, + MovieTrackingMarker *marker) { int a = marker - track->markers; MovieTrackingMarker *marker_keyed = marker; diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c index bd25ff8c6e6..4019eba5177 100644 --- a/source/blender/blenkernel/intern/writeffmpeg.c +++ b/source/blender/blenkernel/intern/writeffmpeg.c @@ -847,7 +847,7 @@ static int start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty, Report * parameter. *

*/ -void flush_ffmpeg(void) +static void flush_ffmpeg(void) { int outsize = 0; int ret = 0; -- cgit v1.2.3 From cdb144ade986ef97cc60801610e6e83bcbba60b1 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Sat, 15 Sep 2012 07:53:34 +0000 Subject: Merging r50618 through r50624 from trunk into soc-2011-tomato --- source/blender/blenkernel/intern/DerivedMesh.c | 2 +- source/blender/blenkernel/intern/object.c | 2 +- source/blender/blenkernel/intern/text.c | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) (limited to 'source/blender/blenkernel/intern') diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 8c0aea5723f..07d14513bd0 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -384,7 +384,7 @@ void DM_ensure_tessface(DerivedMesh *dm) } } - else if (dm->dirty && DM_DIRTY_TESS_CDLAYERS) { + else if (dm->dirty & DM_DIRTY_TESS_CDLAYERS) { BLI_assert(CustomData_has_layer(&dm->faceData, CD_POLYINDEX)); DM_update_tessface_data(dm); } diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 4fb235ac9f7..5ba56a85c72 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -3288,7 +3288,7 @@ void BKE_object_groups_clear(Scene *scene, Base *base, Object *object) { Group *group = NULL; - BLI_assert(base->object == object); + BLI_assert((base == NULL) || (base->object == object)); if (scene && base == NULL) { base = BKE_scene_base_find(scene, object); diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c index af5a8f5d59d..3c89fdba13a 100644 --- a/source/blender/blenkernel/intern/text.c +++ b/source/blender/blenkernel/intern/text.c @@ -3070,7 +3070,6 @@ int setcurr_tab_spaces(Text *text, int space) const char *comm = "#"; const char indent = (text->flags & TXT_TABSTOSPACES) ? ' ' : '\t'; static const char *back_words[] = {"return", "break", "continue", "pass", "yield", NULL}; - if (!text) return 0; if (!text->curl) return 0; while (text->curl->line[i] == indent) { -- cgit v1.2.3 From 0bf6007e3bda226ae83c373ffeba029b53c93b70 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Sat, 15 Sep 2012 08:35:26 +0000 Subject: Silence compiler's warnings. --- source/blender/blenkernel/intern/sequencer.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source/blender/blenkernel/intern') diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index 20db9d5e056..8d7ca94ed48 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -311,7 +311,7 @@ void BKE_sequencer_editing_free(Scene *scene) /*********************** Sequencer color space functions *************************/ -void BKE_sequencer_imbuf_assign_spaces(Scene *scene, ImBuf *ibuf) +static void sequencer_imbuf_assign_spaces(Scene *scene, ImBuf *ibuf) { IMB_colormanagement_imbuf_assign_float_space(ibuf, &scene->sequencer_colorspace_settings); } @@ -1303,7 +1303,7 @@ static ImBuf *seq_proxy_fetch(SeqRenderData context, Sequence *seq, int cfra) ImBuf *ibuf = IMB_loadiffname(name, IB_rect, NULL); if (ibuf) - BKE_sequencer_imbuf_assign_spaces(context.scene, ibuf); + sequencer_imbuf_assign_spaces(context.scene, ibuf); return ibuf; } @@ -1981,7 +1981,7 @@ static void copy_to_ibuf_still(SeqRenderData context, Sequence *seq, float nr, I * changing the cached image... */ ibuf = IMB_dupImBuf(ibuf); - BKE_sequencer_imbuf_assign_spaces(context.scene, ibuf); + sequencer_imbuf_assign_spaces(context.scene, ibuf); if (nr == 0) { BKE_sequencer_cache_put(context, seq, seq->start, SEQ_STRIPELEM_IBUF_STARTSTILL, ibuf); @@ -2583,7 +2583,7 @@ static ImBuf *do_render_strip_uncached(SeqRenderData context, Sequence *seq, flo case SEQ_TYPE_MOVIECLIP: { ibuf = seq_render_movieclip_strip(context, seq, nr); - BKE_sequencer_imbuf_assign_spaces(context.scene, ibuf); + sequencer_imbuf_assign_spaces(context.scene, ibuf); if (ibuf && use_preprocess) { ImBuf *i = IMB_dupImBuf(ibuf); @@ -2608,7 +2608,7 @@ static ImBuf *do_render_strip_uncached(SeqRenderData context, Sequence *seq, flo } if (ibuf) - BKE_sequencer_imbuf_assign_spaces(context.scene, ibuf); + sequencer_imbuf_assign_spaces(context.scene, ibuf); return ibuf; } @@ -2653,7 +2653,7 @@ static ImBuf *seq_render_strip(SeqRenderData context, Sequence *seq, float cfra) if (ibuf == NULL) { ibuf = IMB_allocImBuf(context.rectx, context.recty, 32, IB_rect); - BKE_sequencer_imbuf_assign_spaces(context.scene, ibuf); + sequencer_imbuf_assign_spaces(context.scene, ibuf); } if (ibuf->x != context.rectx || ibuf->y != context.recty) -- cgit v1.2.3 From 18326d852b5e82a1c5d1b9c0c45fad213a6d0d01 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 5 Nov 2012 19:42:27 +0000 Subject: Merging r50625 through r51896 from trunk into soc-2011-tomato Merging just in case we'll want to develop some experimental stuff --- source/blender/blenkernel/intern/CCGSubSurf.c | 6 +- source/blender/blenkernel/intern/DerivedMesh.c | 190 +- source/blender/blenkernel/intern/action.c | 489 +--- source/blender/blenkernel/intern/anim.c | 119 +- source/blender/blenkernel/intern/anim_sys.c | 16 +- source/blender/blenkernel/intern/armature.c | 27 +- source/blender/blenkernel/intern/blender.c | 22 +- source/blender/blenkernel/intern/bmfont.c | 4 +- source/blender/blenkernel/intern/boids.c | 30 +- source/blender/blenkernel/intern/booleanops_mesh.c | 12 +- source/blender/blenkernel/intern/brush.c | 52 +- source/blender/blenkernel/intern/bullet.c | 2 +- source/blender/blenkernel/intern/bvhutils.c | 44 +- source/blender/blenkernel/intern/camera.c | 5 +- source/blender/blenkernel/intern/cdderivedmesh.c | 242 +- source/blender/blenkernel/intern/cloth.c | 41 +- source/blender/blenkernel/intern/collision.c | 31 +- source/blender/blenkernel/intern/colortools.c | 103 +- source/blender/blenkernel/intern/constraint.c | 169 +- source/blender/blenkernel/intern/context.c | 5 +- source/blender/blenkernel/intern/curve.c | 51 +- source/blender/blenkernel/intern/customdata.c | 279 +- source/blender/blenkernel/intern/deform.c | 24 +- source/blender/blenkernel/intern/depsgraph.c | 142 +- source/blender/blenkernel/intern/displist.c | 8 +- source/blender/blenkernel/intern/dynamicpaint.c | 97 +- source/blender/blenkernel/intern/editderivedmesh.c | 2 +- source/blender/blenkernel/intern/effect.c | 50 +- source/blender/blenkernel/intern/fcurve.c | 34 +- source/blender/blenkernel/intern/fluidsim.c | 36 +- source/blender/blenkernel/intern/fmodifier.c | 17 +- source/blender/blenkernel/intern/font.c | 30 +- source/blender/blenkernel/intern/gpencil.c | 14 +- source/blender/blenkernel/intern/group.c | 66 +- source/blender/blenkernel/intern/icons.c | 4 +- source/blender/blenkernel/intern/idprop.c | 123 +- source/blender/blenkernel/intern/image.c | 95 +- source/blender/blenkernel/intern/image_gen.c | 2 +- source/blender/blenkernel/intern/implicit.c | 153 +- source/blender/blenkernel/intern/ipo.c | 28 +- source/blender/blenkernel/intern/key.c | 121 +- source/blender/blenkernel/intern/lattice.c | 45 +- source/blender/blenkernel/intern/library.c | 24 +- source/blender/blenkernel/intern/mask.c | 43 +- source/blender/blenkernel/intern/mask_evaluate.c | 6 +- source/blender/blenkernel/intern/mask_rasterize.c | 36 +- source/blender/blenkernel/intern/material.c | 42 +- source/blender/blenkernel/intern/mball.c | 60 +- source/blender/blenkernel/intern/mesh.c | 112 +- source/blender/blenkernel/intern/mesh_validate.c | 11 +- source/blender/blenkernel/intern/modifier.c | 49 +- source/blender/blenkernel/intern/modifiers_bmesh.c | 32 +- source/blender/blenkernel/intern/movieclip.c | 74 +- source/blender/blenkernel/intern/multires.c | 32 +- .../blender/blenkernel/intern/navmesh_conversion.c | 338 +-- source/blender/blenkernel/intern/nla.c | 14 +- source/blender/blenkernel/intern/node.c | 122 +- source/blender/blenkernel/intern/object.c | 266 +- source/blender/blenkernel/intern/ocean.c | 2 +- source/blender/blenkernel/intern/packedFile.c | 11 +- source/blender/blenkernel/intern/paint.c | 12 +- source/blender/blenkernel/intern/particle.c | 105 +- source/blender/blenkernel/intern/particle_system.c | 146 +- source/blender/blenkernel/intern/pointcache.c | 288 +- source/blender/blenkernel/intern/property.c | 65 +- source/blender/blenkernel/intern/report.c | 48 +- source/blender/blenkernel/intern/sca.c | 29 +- source/blender/blenkernel/intern/scene.c | 57 +- source/blender/blenkernel/intern/seqeffects.c | 24 +- source/blender/blenkernel/intern/sequencer.c | 158 +- source/blender/blenkernel/intern/shrinkwrap.c | 197 +- source/blender/blenkernel/intern/smoke.c | 3060 +++++++++++--------- source/blender/blenkernel/intern/softbody.c | 58 +- source/blender/blenkernel/intern/sound.c | 7 +- source/blender/blenkernel/intern/subsurf_ccg.c | 68 +- source/blender/blenkernel/intern/text.c | 71 +- source/blender/blenkernel/intern/texture.c | 25 +- source/blender/blenkernel/intern/tracking.c | 130 +- source/blender/blenkernel/intern/unit.c | 4 +- source/blender/blenkernel/intern/world.c | 2 +- source/blender/blenkernel/intern/writeavi.c | 28 +- source/blender/blenkernel/intern/writeffmpeg.c | 27 +- .../blender/blenkernel/intern/writeframeserver.c | 8 +- 83 files changed, 4760 insertions(+), 4161 deletions(-) (limited to 'source/blender/blenkernel/intern') diff --git a/source/blender/blenkernel/intern/CCGSubSurf.c b/source/blender/blenkernel/intern/CCGSubSurf.c index 387d4775ad4..cc20470b4d5 100644 --- a/source/blender/blenkernel/intern/CCGSubSurf.c +++ b/source/blender/blenkernel/intern/CCGSubSurf.c @@ -868,7 +868,7 @@ CCGSubSurf *ccgSubSurf_new(CCGMeshIFC *ifc, int subdivLevels, CCGAllocatorIFC *a ss->oldVMap = ss->oldEMap = ss->oldFMap = NULL; ss->lenTempArrays = 0; ss->tempVerts = NULL; - ss->tempEdges = NULL; + ss->tempEdges = NULL; return ss; } @@ -1397,7 +1397,7 @@ CCGError ccgSubSurf_processSync(CCGSubSurf *ss) return eCCGError_None; } -#define VERT_getNo(e, lvl) _vert_getNo(e, lvl, vertDataSize, normalDataOffset) +#define VERT_getNo(e, lvl) _vert_getNo(v, lvl, vertDataSize, normalDataOffset) #define EDGE_getNo(e, lvl, x) _edge_getNo(e, lvl, x, vertDataSize, normalDataOffset) #define FACE_getIFNo(f, lvl, S, x, y) _face_getIFNo(f, lvl, S, x, y, subdivLevels, vertDataSize, normalDataOffset) #define FACE_calcIFNo(f, lvl, S, x, y, no) _face_calcIFNo(f, lvl, S, x, y, no, subdivLevels, vertDataSize) @@ -1491,7 +1491,7 @@ static void ccgSubSurf__calcVertNormals(CCGSubSurf *ss, /* XXX can I reduce the number of normalisations here? */ for (ptrIdx = 0; ptrIdx < numEffectedV; ptrIdx++) { CCGVert *v = (CCGVert *) effectedV[ptrIdx]; - float length, *no = _vert_getNo(v, lvl, vertDataSize, normalDataOffset); + float length, *no = VERT_getNo(v, lvl); NormZero(no); diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 07d14513bd0..fd92b7b5d69 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -51,8 +51,6 @@ #include "BLI_utildefines.h" #include "BLI_linklist.h" -#include "BLF_translation.h" - #include "BKE_cdderivedmesh.h" #include "BKE_displist.h" #include "BKE_key.h" @@ -267,9 +265,11 @@ void DM_init_funcs(DerivedMesh *dm) dm->getVertData = DM_get_vert_data; dm->getEdgeData = DM_get_edge_data; dm->getTessFaceData = DM_get_tessface_data; + dm->getPolyData = DM_get_poly_data; dm->getVertDataArray = DM_get_vert_data_layer; dm->getEdgeDataArray = DM_get_edge_data_layer; dm->getTessFaceDataArray = DM_get_tessface_data_layer; + dm->getPolyDataArray = DM_get_poly_data_layer; bvhcache_init(&dm->bvhCache); } @@ -289,6 +289,13 @@ void DM_init(DerivedMesh *dm, DerivedMeshType type, int numVerts, int numEdges, dm->needsFree = 1; dm->auto_bump_scale = -1.0f; dm->dirty = 0; + + /* don't use CustomData_reset(...); because we dont want to touch customdata */ + fill_vn_i(dm->vertData.typemap, CD_NUMTYPES, -1); + fill_vn_i(dm->edgeData.typemap, CD_NUMTYPES, -1); + fill_vn_i(dm->faceData.typemap, CD_NUMTYPES, -1); + fill_vn_i(dm->loopData.typemap, CD_NUMTYPES, -1); + fill_vn_i(dm->polyData.typemap, CD_NUMTYPES, -1); } void DM_from_template(DerivedMesh *dm, DerivedMesh *source, DerivedMeshType type, @@ -385,7 +392,7 @@ void DM_ensure_tessface(DerivedMesh *dm) } else if (dm->dirty & DM_DIRTY_TESS_CDLAYERS) { - BLI_assert(CustomData_has_layer(&dm->faceData, CD_POLYINDEX)); + BLI_assert(CustomData_has_layer(&dm->faceData, CD_ORIGINDEX)); DM_update_tessface_data(dm); } @@ -409,7 +416,7 @@ void DM_update_tessface_data(DerivedMesh *dm) const int hasPCol = CustomData_has_layer(ldata, CD_PREVIEW_MLOOPCOL); const int hasOrigSpace = CustomData_has_layer(ldata, CD_ORIGSPACE_MLOOP); - int *polyindex = CustomData_get_layer(fdata, CD_POLYINDEX); + int *polyindex = CustomData_get_layer(fdata, CD_ORIGINDEX); int mf_idx, totface = dm->getNumTessFaces(dm), @@ -466,11 +473,11 @@ void DM_to_mesh(DerivedMesh *dm, Mesh *me, Object *ob) int totvert, totedge /*, totface */ /* UNUSED */, totloop, totpoly; int did_shapekeys = 0; - memset(&tmp.vdata, 0, sizeof(tmp.vdata)); - memset(&tmp.edata, 0, sizeof(tmp.edata)); - memset(&tmp.fdata, 0, sizeof(tmp.fdata)); - memset(&tmp.ldata, 0, sizeof(tmp.ldata)); - memset(&tmp.pdata, 0, sizeof(tmp.pdata)); + CustomData_reset(&tmp.vdata); + CustomData_reset(&tmp.edata); + CustomData_reset(&tmp.fdata); + CustomData_reset(&tmp.ldata); + CustomData_reset(&tmp.pdata); totvert = tmp.totvert = dm->getNumVerts(dm); totedge = tmp.totedge = dm->getNumEdges(dm); @@ -578,6 +585,13 @@ void DM_set_only_copy(DerivedMesh *dm, CustomDataMask mask) CustomData_set_only_copy(&dm->vertData, mask); CustomData_set_only_copy(&dm->edgeData, mask); CustomData_set_only_copy(&dm->faceData, mask); + /* this wasn't in 2.63 and is disabled for 2.64 because it gives problems with + * weight paint mode when there are modifiers applied, needs further investigation, + * see replies to r50969, Campbell */ +#if 0 + CustomData_set_only_copy(&dm->loopData, mask); + CustomData_set_only_copy(&dm->polyData, mask); +#endif } void DM_add_vert_layer(DerivedMesh *dm, int type, int alloctype, void *layer) @@ -620,6 +634,12 @@ void *DM_get_tessface_data(DerivedMesh *dm, int index, int type) return CustomData_get(&dm->faceData, index, type); } +void *DM_get_poly_data(DerivedMesh *dm, int index, int type) +{ + return CustomData_get(&dm->polyData, index, type); +} + + void *DM_get_vert_data_layer(DerivedMesh *dm, int type) { if (type == CD_MVERT) @@ -808,7 +828,7 @@ DerivedMesh *mesh_create_derived_for_modifier(Scene *scene, Object *ob, if (mti->isDisabled && mti->isDisabled(md, 0)) return NULL; if (build_shapekey_layers && me->key && (kb = BLI_findlink(&me->key->block, ob->shapenr - 1))) { - key_to_mesh(kb, me); + BKE_key_convert_to_mesh(kb, me); } if (mti->type == eModifierTypeType_OnlyDeform) { @@ -878,7 +898,7 @@ static void *get_orco_coords_dm(Object *ob, BMEditMesh *em, int layer, int *free * by a more flexible customdata system, but not simple */ if (!em) { ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth); - KeyBlock *kb = key_get_keyblock(ob_get_key(ob), clmd->sim_parms->shapekey_rest); + KeyBlock *kb = BKE_keyblock_from_key(BKE_key_from_object(ob), clmd->sim_parms->shapekey_rest); if (kb->data) return kb->data; @@ -896,7 +916,7 @@ static DerivedMesh *create_orco_dm(Object *ob, Mesh *me, BMEditMesh *em, int lay float (*orco)[3]; int free; - if (em) dm = CDDM_from_BMEditMesh(em, me, FALSE, FALSE); + if (em) dm = CDDM_from_editbmesh(em, FALSE, FALSE); else dm = CDDM_from_mesh(me, ob); orco = get_orco_coords_dm(ob, em, layer, &free); @@ -1263,7 +1283,7 @@ static void shapekey_layers_to_keyblocks(DerivedMesh *dm, Mesh *me, int actshape int i, j, tot; if (!me->key) - return; + return; tot = CustomData_number_of_layers(&dm->vertData, CD_SHAPEKEY); for (i = 0; i < tot; i++) { @@ -1276,7 +1296,7 @@ static void shapekey_layers_to_keyblocks(DerivedMesh *dm, Mesh *me, int actshape } if (!kb) { - kb = add_keyblock(me->key, layer->name); + kb = BKE_keyblock_add(me->key, layer->name); kb->uid = layer->uid; } @@ -1368,7 +1388,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos ModifierData *firstmd, *md, *previewmd = NULL; CDMaskLink *datamasks, *curr; /* XXX Always copying POLYINDEX, else tessellated data are no more valid! */ - CustomDataMask mask, nextmask, append_mask = CD_MASK_POLYINDEX; + CustomDataMask mask, nextmask, append_mask = CD_MASK_ORIGINDEX; float (*deformedVerts)[3] = NULL; DerivedMesh *dm = NULL, *orcodm, *clothorcodm, *finaldm; int numVerts = me->totvert; @@ -1500,7 +1520,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos if (!modifier_isEnabled(scene, md, required_mode)) continue; if (mti->type == eModifierTypeType_OnlyDeform && !useDeform) continue; if ((mti->flags & eModifierTypeFlag_RequiresOriginalData) && dm) { - modifier_setError(md, "%s", TIP_("Modifier requires original data, bad stack position.")); + modifier_setError(md, "Modifier requires original data, bad stack position"); continue; } if (sculpt_mode && (!has_multires || multires_applied)) { @@ -1513,7 +1533,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos unsupported |= multires_applied; if (unsupported) { - modifier_setError(md, "%s", TIP_("Not supported in sculpt mode.")); + modifier_setError(md, "Not supported in sculpt mode"); continue; } } @@ -1796,7 +1816,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos #if 0 if (num_tessface == 0 && finaldm->getNumTessFaces(finaldm) == 0) #else - if (finaldm->getNumTessFaces(finaldm) == 0) /* || !CustomData_has_layer(&finaldm->faceData, CD_POLYINDEX)) */ + if (finaldm->getNumTessFaces(finaldm) == 0) /* || !CustomData_has_layer(&finaldm->faceData, CD_ORIGINDEX)) */ #endif { finaldm->recalcTessellation(finaldm); @@ -1804,8 +1824,8 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos /* Even if tessellation is not needed, some modifiers might have modified CD layers * (like mloopcol or mloopuv), hence we have to update those. */ else if (finaldm->dirty & DM_DIRTY_TESS_CDLAYERS) { - /* A tessellation already exists, it should always have a CD_POLYINDEX. */ - BLI_assert(CustomData_has_layer(&finaldm->faceData, CD_POLYINDEX)); + /* A tessellation already exists, it should always have a CD_ORIGINDEX. */ + BLI_assert(CustomData_has_layer(&finaldm->faceData, CD_ORIGINDEX)); DM_update_tessface_data(finaldm); } /* Need to watch this, it can cause issues, see bug [#29338] */ @@ -1874,7 +1894,7 @@ int editbmesh_modifier_is_enabled(Scene *scene, ModifierData *md, DerivedMesh *d if (!modifier_isEnabled(scene, md, required_mode)) return 0; if ((mti->flags & eModifierTypeFlag_RequiresOriginalData) && dm) { - modifier_setError(md, "%s", TIP_("Modifier requires original data, bad stack position.")); + modifier_setError(md, "Modifier requires original data, bad stack position"); return 0; } @@ -1969,7 +1989,7 @@ static void editbmesh_calc_modifiers(Scene *scene, Object *ob, BMEditMesh *em, D } else { - dm = CDDM_from_BMEditMesh(em, ob->data, FALSE, FALSE); + dm = CDDM_from_editbmesh(em, FALSE, FALSE); if (deformedVerts) { CDDM_apply_vert_coords(dm, deformedVerts); @@ -2060,12 +2080,18 @@ static void editbmesh_calc_modifiers(Scene *scene, Object *ob, BMEditMesh *em, D } else if (dm) { *final_r = dm; - (*final_r)->calcNormals(*final_r); /* BMESH_ONLY - BMESH_TODO. check if this is needed */ + + /* once we support skipping normal calculation with modifiers we may want to add this back */ +#if 0 // was added for bmesh but is not needed + (*final_r)->calcNormals(*final_r); +#endif } else if (!deformedVerts && cage_r && *cage_r) { /* cage should already have up to date normals */ *final_r = *cage_r; - (*final_r)->calcNormals(*final_r); /* BMESH_ONLY - BMESH_TODO. check if this is needed */ +#if 0 // was added for bmesh but is not needed + (*final_r)->calcNormals(*final_r); +#endif } else { /* this is just a copy of the editmesh, no need to calc normals */ @@ -2242,8 +2268,16 @@ DerivedMesh *mesh_create_derived_view(Scene *scene, Object *ob, CustomDataMask d { DerivedMesh *final; + /* XXX hack + * psys modifier updates particle state when called during dupli-list generation, + * which can lead to wrong transforms. This disables particle system modifier execution. + */ + ob->transflag |= OB_NO_PSYS_UPDATE; + mesh_calc_modifiers(scene, ob, NULL, NULL, &final, 0, 1, 0, dataMask, -1, 0, 0); + ob->transflag &= ~OB_NO_PSYS_UPDATE; + return final; } @@ -2413,7 +2447,7 @@ static int GetNumVertsOfFace(const SMikkTSpaceContext *pContext, const int face_ static void GetPosition(const SMikkTSpaceContext *pContext, float fPos[], const int face_num, const int vert_index) { - //assert(vert_index>=0 && vert_index<4); + //assert(vert_index >= 0 && vert_index < 4); SGLSLMeshToTangent *pMesh = (SGLSLMeshToTangent *) pContext->m_pUserData; const float *co = pMesh->mvert[(&pMesh->mface[face_num].v1)[vert_index]].co; copy_v3_v3(fPos, co); @@ -2421,7 +2455,7 @@ static void GetPosition(const SMikkTSpaceContext *pContext, float fPos[], const static void GetTextureCoordinate(const SMikkTSpaceContext *pContext, float fUV[], const int face_num, const int vert_index) { - //assert(vert_index>=0 && vert_index<4); + //assert(vert_index >= 0 && vert_index < 4); SGLSLMeshToTangent *pMesh = (SGLSLMeshToTangent *) pContext->m_pUserData; if (pMesh->mtface != NULL) { @@ -2436,7 +2470,7 @@ static void GetTextureCoordinate(const SMikkTSpaceContext *pContext, float fUV[] static void GetNormal(const SMikkTSpaceContext *pContext, float fNorm[], const int face_num, const int vert_index) { - //assert(vert_index>=0 && vert_index<4); + //assert(vert_index >= 0 && vert_index < 4); SGLSLMeshToTangent *pMesh = (SGLSLMeshToTangent *) pContext->m_pUserData; const int smoothnormal = (pMesh->mface[face_num].flag & ME_SMOOTH); @@ -2466,7 +2500,7 @@ static void GetNormal(const SMikkTSpaceContext *pContext, float fNorm[], const i } static void SetTSpace(const SMikkTSpaceContext *pContext, const float fvTangent[], const float fSign, const int face_num, const int iVert) { - //assert(vert_index>=0 && vert_index<4); + //assert(vert_index >= 0 && vert_index < 4); SGLSLMeshToTangent *pMesh = (SGLSLMeshToTangent *) pContext->m_pUserData; float *pRes = pMesh->tangent[4 * face_num + iVert]; copy_v3_v3(pRes, fvTangent); @@ -2477,15 +2511,11 @@ static void SetTSpace(const SMikkTSpaceContext *pContext, const float fvTangent[ void DM_add_tangent_layer(DerivedMesh *dm) { /* mesh vars */ - MTFace *mtface, *tf; - MFace *mface, *mf; - MVert *mvert, *v1, *v2, *v3, *v4; - MemArena *arena = NULL; - VertexTangent **vtangents = NULL; + MVert *mvert; + MTFace *mtface; + MFace *mface; float (*orco)[3] = NULL, (*tangent)[4]; - float *uv1, *uv2, *uv3, *uv4, *vtang; - float fno[3], tang[3], uv[4][2]; - int i, j, len, mf_vi[4], totvert, totface, iCalcNewMethod; + int /* totvert, */ totface; float *nors; if (CustomData_get_layer_index(&dm->faceData, CD_TANGENT) != -1) @@ -2494,7 +2524,7 @@ void DM_add_tangent_layer(DerivedMesh *dm) nors = dm->getTessFaceDataArray(dm, CD_NORMAL); /* check we have all the needed layers */ - totvert = dm->getNumVerts(dm); + /* totvert = dm->getNumVerts(dm); */ /* UNUSED */ totface = dm->getNumTessFaces(dm); mvert = dm->getVertArray(dm); @@ -2511,14 +2541,8 @@ void DM_add_tangent_layer(DerivedMesh *dm) DM_add_tessface_layer(dm, CD_TANGENT, CD_CALLOC, NULL); tangent = DM_get_tessface_data_layer(dm, CD_TANGENT); - /* allocate some space */ - arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "tangent layer arena"); - BLI_memarena_use_calloc(arena); - vtangents = MEM_callocN(sizeof(VertexTangent *) * totvert, "VertexTangent"); - /* new computation method */ - iCalcNewMethod = 1; - if (iCalcNewMethod != 0) { + { SGLSLMeshToTangent mesh2tangent = {0}; SMikkTSpaceContext sContext = {0}; SMikkTSpaceInterface sInterface = {0}; @@ -2541,87 +2565,13 @@ void DM_add_tangent_layer(DerivedMesh *dm) sInterface.m_setTSpaceBasic = SetTSpace; /* 0 if failed */ - iCalcNewMethod = genTangSpaceDefault(&sContext); + genTangSpaceDefault(&sContext); } - - if (!iCalcNewMethod) { - /* sum tangents at connected vertices */ - for (i = 0, tf = mtface, mf = mface; i < totface; mf++, tf++, i++) { - v1 = &mvert[mf->v1]; - v2 = &mvert[mf->v2]; - v3 = &mvert[mf->v3]; - - if (mf->v4) { - v4 = &mvert[mf->v4]; - normal_quad_v3(fno, v4->co, v3->co, v2->co, v1->co); - } - else { - v4 = NULL; - normal_tri_v3(fno, v3->co, v2->co, v1->co); - } - - if (mtface) { - uv1 = tf->uv[0]; - uv2 = tf->uv[1]; - uv3 = tf->uv[2]; - uv4 = tf->uv[3]; - } - else { - uv1 = uv[0]; uv2 = uv[1]; uv3 = uv[2]; uv4 = uv[3]; - map_to_sphere(&uv[0][0], &uv[0][1], orco[mf->v1][0], orco[mf->v1][1], orco[mf->v1][2]); - map_to_sphere(&uv[1][0], &uv[1][1], orco[mf->v2][0], orco[mf->v2][1], orco[mf->v2][2]); - map_to_sphere(&uv[2][0], &uv[2][1], orco[mf->v3][0], orco[mf->v3][1], orco[mf->v3][2]); - if (v4) - map_to_sphere(&uv[3][0], &uv[3][1], orco[mf->v4][0], orco[mf->v4][1], orco[mf->v4][2]); - } - - tangent_from_uv(uv1, uv2, uv3, v1->co, v2->co, v3->co, fno, tang); - sum_or_add_vertex_tangent(arena, &vtangents[mf->v1], tang, uv1); - sum_or_add_vertex_tangent(arena, &vtangents[mf->v2], tang, uv2); - sum_or_add_vertex_tangent(arena, &vtangents[mf->v3], tang, uv3); - - if (mf->v4) { - v4 = &mvert[mf->v4]; - - tangent_from_uv(uv1, uv3, uv4, v1->co, v3->co, v4->co, fno, tang); - sum_or_add_vertex_tangent(arena, &vtangents[mf->v1], tang, uv1); - sum_or_add_vertex_tangent(arena, &vtangents[mf->v3], tang, uv3); - sum_or_add_vertex_tangent(arena, &vtangents[mf->v4], tang, uv4); - } - } - - /* write tangent to layer */ - for (i = 0, tf = mtface, mf = mface; i < totface; mf++, tf++, i++, tangent += 4) { - len = (mf->v4) ? 4 : 3; - - if (mtface == NULL) { - map_to_sphere(&uv[0][0], &uv[0][1], orco[mf->v1][0], orco[mf->v1][1], orco[mf->v1][2]); - map_to_sphere(&uv[1][0], &uv[1][1], orco[mf->v2][0], orco[mf->v2][1], orco[mf->v2][2]); - map_to_sphere(&uv[2][0], &uv[2][1], orco[mf->v3][0], orco[mf->v3][1], orco[mf->v3][2]); - if (len == 4) - map_to_sphere(&uv[3][0], &uv[3][1], orco[mf->v4][0], orco[mf->v4][1], orco[mf->v4][2]); - } - - mf_vi[0] = mf->v1; - mf_vi[1] = mf->v2; - mf_vi[2] = mf->v3; - mf_vi[3] = mf->v4; - - for (j = 0; j < len; j++) { - vtang = find_vertex_tangent(vtangents[mf_vi[j]], mtface ? tf->uv[j] : uv[j]); - normalize_v3_v3(tangent[j], vtang); - ((float *) tangent[j])[3] = 1.0f; - } - } - } - - BLI_memarena_free(arena); - MEM_freeN(vtangents); } void DM_calc_auto_bump_scale(DerivedMesh *dm) { - /* int totvert= dm->getNumVerts(dm); */ /* UNUSED */ + /* int totvert = dm->getNumVerts(dm); */ /* UNUSED */ int totface = dm->getNumTessFaces(dm); MVert *mvert = dm->getVertArray(dm); diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index 06bf5211abb..e95451252d0 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -224,7 +224,7 @@ bActionGroup *get_active_actiongroup(bAction *act) { bActionGroup *agrp = NULL; - if (act && act->groups.first) { + if (act && act->groups.first) { for (agrp = act->groups.first; agrp; agrp = agrp->next) { if (agrp->flag & AGRP_ACTIVE) break; @@ -301,7 +301,7 @@ bActionGroup *action_groups_add_new(bAction *act, const char name[]) /* add to action, and validate */ BLI_addtail(&act->groups, agrp); - BLI_uniquename(&act->groups, agrp, "Group", '.', offsetof(bActionGroup, name), sizeof(agrp->name)); + BLI_uniquename(&act->groups, agrp, "Group", '.', offsetof(bActionGroup, name), sizeof(agrp->name)); /* return the new group */ return agrp; @@ -380,7 +380,7 @@ void action_groups_add_channel(bAction *act, bActionGroup *agrp, FCurve *fcurve) void action_groups_remove_channel(bAction *act, FCurve *fcu) { /* sanity checks */ - if (ELEM(NULL, act, fcu)) + if (ELEM(NULL, act, fcu)) return; /* check if any group used this directly */ @@ -539,6 +539,7 @@ void BKE_pose_copy_data(bPose **dst, bPose *src, int copycon) outPose->iksolver = src->iksolver; outPose->ikdata = NULL; outPose->ikparam = MEM_dupallocN(src->ikparam); + outPose->avs = src->avs; for (pchan = outPose->chanbase.first; pchan; pchan = pchan->next) { /* TODO: rename this argument... */ @@ -905,8 +906,8 @@ void calc_action_range(const bAction *act, float *start, float *end, short incl_ calc_fcurve_range(fcu, &nmin, &nmax, FALSE, TRUE); /* compare to the running tally */ - min = MIN2(min, nmin); - max = MAX2(max, nmax); + min = min_ff(min, nmin); + max = max_ff(max, nmax); foundvert = 1; } @@ -924,10 +925,10 @@ void calc_action_range(const bAction *act, float *start, float *end, short incl_ FMod_Limits *fmd = (FMod_Limits *)fcm->data; if (fmd->flag & FCM_LIMIT_XMIN) { - min = MIN2(min, fmd->rect.xmin); + min = min_ff(min, fmd->rect.xmin); } if (fmd->flag & FCM_LIMIT_XMAX) { - max = MAX2(max, fmd->rect.xmax); + max = max_ff(max, fmd->rect.xmax); } } break; @@ -954,7 +955,7 @@ void calc_action_range(const bAction *act, float *start, float *end, short incl_ foundmod = 1; } } - } + } if (foundvert || foundmod) { if (min == max) max += 1.0f; @@ -1214,475 +1215,3 @@ void what_does_obaction(Object *ob, Object *workob, bPose *pose, bAction *act, c } } -/* ********** NLA with non-poses works with ipo channels ********** */ - -#if 0 // XXX OLD ANIMATION SYSTEM (TO BE REMOVED) - -/* ************************ Blending with NLA *************** */ - -static void blend_pose_strides(bPose *dst, bPose *src, float srcweight, short mode) -{ - float dstweight; - - switch (mode) { - case ACTSTRIPMODE_BLEND: - dstweight = 1.0F - srcweight; - break; - case ACTSTRIPMODE_ADD: - dstweight = 1.0F; - break; - default: - dstweight = 1.0F; - } - - interp_v3_v3v3(dst->stride_offset, dst->stride_offset, src->stride_offset, srcweight); -} - - -/* - * bone matching diagram, strips A and B - * - * .------------------------. - * | A | - * '------------------------' - * . . b2 - * . .-------------v----------. - * . | B . | - * . '------------------------' - * . . . - * . . . - * offset: . 0 . A-B . A-b2+B - * . . . - * - * */ - - -static void blend_pose_offset_bone(bActionStrip *strip, bPose *dst, bPose *src, float srcweight, short mode) -{ - /* matching offset bones */ - /* take dst offset, and put src on on that location */ - - if (strip->offs_bone[0] == 0) - return; - - /* are we also blending with matching bones? */ - if (strip->prev && strip->start >= strip->prev->start) { - bPoseChannel *dpchan = BKE_pose_channel_find_name(dst, strip->offs_bone); - if (dpchan) { - bPoseChannel *spchan = BKE_pose_channel_find_name(src, strip->offs_bone); - if (spchan) { - float vec[3]; - - /* dst->ctime has the internal strip->prev action time */ - /* map this time to nla time */ - - float ctime = get_actionstrip_frame(strip, src->ctime, 1); - - if (ctime > strip->prev->end) { - bActionChannel *achan; - - /* add src to dest, minus the position of src on strip->prev->end */ - - ctime = get_actionstrip_frame(strip, strip->prev->end, 0); - - achan = get_action_channel(strip->act, strip->offs_bone); - if (achan && achan->ipo) { - bPoseChannel pchan; - /* Evaluates and sets the internal ipo value */ - calc_ipo(achan->ipo, ctime); - /* This call also sets the pchan flags */ - execute_action_ipo(achan, &pchan); - - /* store offset that moves src to location of pchan */ - sub_v3_v3v3(vec, dpchan->loc, pchan.loc); - - mul_mat3_m4_v3(dpchan->bone->arm_mat, vec); - } - } - else { - /* store offset that moves src to location of dst */ - - sub_v3_v3v3(vec, dpchan->loc, spchan->loc); - mul_mat3_m4_v3(dpchan->bone->arm_mat, vec); - } - - /* if blending, we only add with factor scrweight */ - mul_v3_fl(vec, srcweight); - - add_v3_v3(dst->cyclic_offset, vec); - } - } - } - - add_v3_v3(dst->cyclic_offset, src->cyclic_offset); -} - -/* added "sizecorr" here, to allow armatures to be scaled and still have striding. - * Only works for uniform scaling. In general I'd advise against scaling armatures ever though! (ton) - */ -static float stridechannel_frame(Object *ob, float sizecorr, bActionStrip *strip, Path *path, float pathdist, float *stride_offset) -{ - bAction *act = strip->act; - const char *name = strip->stridechannel; - bActionChannel *achan = get_action_channel(act, name); - int stride_axis = strip->stride_axis; - - if (achan && achan->ipo) { - IpoCurve *icu = NULL; - float minx = 0.0f, maxx = 0.0f, miny = 0.0f, maxy = 0.0f; - int foundvert = 0; - - if (stride_axis == 0) stride_axis = AC_LOC_X; - else if (stride_axis == 1) stride_axis = AC_LOC_Y; - else stride_axis = AC_LOC_Z; - - /* calculate the min/max */ - for (icu = achan->ipo->curve.first; icu; icu = icu->next) { - if (icu->adrcode == stride_axis) { - if (icu->totvert > 1) { - foundvert = 1; - minx = icu->bezt[0].vec[1][0]; - maxx = icu->bezt[icu->totvert - 1].vec[1][0]; - - miny = icu->bezt[0].vec[1][1]; - maxy = icu->bezt[icu->totvert - 1].vec[1][1]; - } - break; - } - } - - if (foundvert && miny != maxy) { - float stridelen = sizecorr * fabs(maxy - miny), striptime; - float actiondist, pdist, pdistNewNormalized, offs; - float vec1[4], vec2[4], dir[3]; - - /* internal cycling, actoffs is in frames */ - offs = stridelen * strip->actoffs / (maxx - minx); - - /* amount path moves object */ - pdist = (float)fmod(pathdist + offs, stridelen); - striptime = pdist / stridelen; - - /* amount stride bone moves */ - actiondist = sizecorr * eval_icu(icu, minx + striptime * (maxx - minx)) - miny; - - pdist = fabs(actiondist) - pdist; - pdistNewNormalized = (pathdist + pdist) / path->totdist; - - /* now we need to go pdist further (or less) on cu path */ - where_on_path(ob, (pathdist) / path->totdist, vec1, dir); /* vec needs size 4 */ - if (pdistNewNormalized <= 1) { - /* search for correction in positive path-direction */ - where_on_path(ob, pdistNewNormalized, vec2, dir); /* vec needs size 4 */ - sub_v3_v3v3(stride_offset, vec2, vec1); - } - else { - /* we reached the end of the path, search backwards instead */ - where_on_path(ob, (pathdist - pdist) / path->totdist, vec2, dir); /* vec needs size 4 */ - sub_v3_v3v3(stride_offset, vec1, vec2); - } - mul_mat3_m4_v3(ob->obmat, stride_offset); - return striptime; - } - } - return 0.0f; -} - -static void cyclic_offs_bone(Object *ob, bPose *pose, bActionStrip *strip, float time) -{ - /* only called when strip has cyclic, so >= 1.0f works... */ - if (time >= 1.0f) { - bActionChannel *achan = get_action_channel(strip->act, strip->offs_bone); - - if (achan && achan->ipo) { - IpoCurve *icu = NULL; - Bone *bone; - float min[3] = {0.0f, 0.0f, 0.0f}, max[3] = {0.0f, 0.0f, 0.0f}; - int index = 0, foundvert = 0; - - /* calculate the min/max */ - for (icu = achan->ipo->curve.first; icu; icu = icu->next) { - if (icu->totvert > 1) { - - if (icu->adrcode == AC_LOC_X) - index = 0; - else if (icu->adrcode == AC_LOC_Y) - index = 1; - else if (icu->adrcode == AC_LOC_Z) - index = 2; - else - continue; - - foundvert = 1; - min[index] = icu->bezt[0].vec[1][1]; - max[index] = icu->bezt[icu->totvert - 1].vec[1][1]; - } - } - if (foundvert) { - /* bring it into armature space */ - sub_v3_v3v3(min, max, min); - bone = BKE_armature_find_bone_name(ob->data, strip->offs_bone); /* weak */ - if (bone) { - mul_mat3_m4_v3(bone->arm_mat, min); - - /* dominant motion, cyclic_offset was cleared in BKE_pose_rest */ - if (strip->flag & (ACTSTRIP_CYCLIC_USEX | ACTSTRIP_CYCLIC_USEY | ACTSTRIP_CYCLIC_USEZ)) { - if (strip->flag & ACTSTRIP_CYCLIC_USEX) pose->cyclic_offset[0] = time * min[0]; - if (strip->flag & ACTSTRIP_CYCLIC_USEY) pose->cyclic_offset[1] = time * min[1]; - if (strip->flag & ACTSTRIP_CYCLIC_USEZ) pose->cyclic_offset[2] = time * min[2]; - } - else { - if (fabsf(min[0]) >= fabsf(min[1]) && fabsf(min[0]) >= fabsf(min[2])) - pose->cyclic_offset[0] = time * min[0]; - else if (fabsf(min[1]) >= fabsf(min[0]) && fabsf(min[1]) >= fabsf(min[2])) - pose->cyclic_offset[1] = time * min[1]; - else - pose->cyclic_offset[2] = time * min[2]; - } - } - } - } - } -} - -/* simple case for now; only the curve path with constraint value > 0.5 */ -/* blending we might do later... */ -static Object *get_parent_path(Object *ob) -{ - bConstraint *con; - - if (ob->parent && ob->parent->type == OB_CURVE) - return ob->parent; - - for (con = ob->constraints.first; con; con = con->next) { - if (con->type == CONSTRAINT_TYPE_FOLLOWPATH) { - if (con->enforce > 0.5f) { - bFollowPathConstraint *data = con->data; - return data->tar; - } - } - } - return NULL; -} - -/* ************** do the action ************ */ - -/* ----- nla, etc. --------- */ - -static void do_nla(Scene *scene, Object *ob, int blocktype) -{ - bPose *tpose = NULL; - Key *key = NULL; - ListBase tchanbase = {NULL, NULL}, chanbase = {NULL, NULL}; - bActionStrip *strip, *striplast = NULL, *stripfirst = NULL; - float striptime, frametime, length, actlength; - float blendfac, stripframe; - float scene_cfra = BKE_scene_frame_get(scene); - int doit, dostride; - - if (blocktype == ID_AR) { - BKE_pose_copy_data(&tpose, ob->pose, 1); - BKE_pose_rest(ob->pose); // potentially destroying current not-keyed pose - } - else { - key = ob_get_key(ob); - } - - /* check on extend to left or right, when no strip is hit by 'cfra' */ - for (strip = ob->nlastrips.first; strip; strip = strip->next) { - /* escape loop on a hit */ - if (scene_cfra >= strip->start && scene_cfra <= strip->end + 0.1f) /* note 0.1 comes back below */ - break; - if (scene_cfra < strip->start) { - if (stripfirst == NULL) - stripfirst = strip; - else if (stripfirst->start > strip->start) - stripfirst = strip; - } - else if (scene_cfra > strip->end) { - if (striplast == NULL) - striplast = strip; - else if (striplast->end < strip->end) - striplast = strip; - } - } - if (strip == NULL) { /* extend */ - if (striplast) - scene_cfra = striplast->end; - else if (stripfirst) - scene_cfra = stripfirst->start; - } - - /* and now go over all strips */ - for (strip = ob->nlastrips.first; strip; strip = strip->next) { - doit = dostride = 0; - - if (strip->act && !(strip->flag & ACTSTRIP_MUTE)) { /* so theres an action */ - - /* Determine if the current frame is within the strip's range */ - length = strip->end - strip->start; - actlength = strip->actend - strip->actstart; - striptime = (scene_cfra - strip->start) / length; - stripframe = (scene_cfra - strip->start); - - if (striptime >= 0.0) { - - if (blocktype == ID_AR) - BKE_pose_rest(tpose); - - /* To handle repeat, we add 0.1 frame extra to make sure the last frame is included */ - if (striptime < 1.0f + 0.1f / length) { - - /* Handle path */ - if ((strip->flag & ACTSTRIP_USESTRIDE) && (blocktype == ID_AR) && (ob->ipoflag & OB_DISABLE_PATH) == 0) { - Object *parent = get_parent_path(ob); - - if (parent) { - Curve *cu = parent->data; - float ctime, pdist; - - if (cu->flag & CU_PATH) { - /* Ensure we have a valid path */ - if (cu->path == NULL || cu->path->data == NULL) makeDispListCurveTypes(scene, parent, 0); - if (cu->path) { - - /* Find the position on the path */ - ctime = bsystem_time(scene, ob, scene_cfra, 0.0); - - if (calc_ipo_spec(cu->ipo, CU_SPEED, &ctime) == 0) { - /* correct for actions not starting on zero */ - ctime = (ctime - strip->actstart) / cu->pathlen; - CLAMP(ctime, 0.0, 1.0); - } - pdist = ctime * cu->path->totdist; - - if (tpose && strip->stridechannel[0]) { - striptime = stridechannel_frame(parent, ob->size[0], strip, cu->path, pdist, tpose->stride_offset); - } - else { - if (strip->stridelen) { - striptime = pdist / strip->stridelen; - striptime = (float)fmod(striptime + strip->actoffs, 1.0); - } - else - striptime = 0; - } - - frametime = (striptime * actlength) + strip->actstart; - frametime = bsystem_time(scene, ob, frametime, 0.0); - - if (blocktype == ID_AR) { - extract_pose_from_action(tpose, strip->act, frametime); - } - else if (blocktype == ID_OB) { - extract_ipochannels_from_action(&tchanbase, &ob->id, strip->act, "Object", frametime); - if (key) - extract_ipochannels_from_action(&tchanbase, &key->id, strip->act, "Shape", frametime); - } - doit = dostride = 1; - } - } - } - } - /* To handle repeat, we add 0.1 frame extra to make sure the last frame is included */ - else { - - /* Mod to repeat */ - if (strip->repeat != 1.0f) { - float cycle = striptime * strip->repeat; - - striptime = (float)fmod(cycle, 1.0f + 0.1f / length); - cycle -= striptime; - - if (blocktype == ID_AR) - cyclic_offs_bone(ob, tpose, strip, cycle); - } - - frametime = (striptime * actlength) + strip->actstart; - frametime = nla_time(scene, frametime, (float)strip->repeat); - - if (blocktype == ID_AR) { - extract_pose_from_action(tpose, strip->act, frametime); - } - else if (blocktype == ID_OB) { - extract_ipochannels_from_action(&tchanbase, &ob->id, strip->act, "Object", frametime); - if (key) - extract_ipochannels_from_action(&tchanbase, &key->id, strip->act, "Shape", frametime); - } - - doit = 1; - } - } - /* Handle extend */ - else { - if (strip->flag & ACTSTRIP_HOLDLASTFRAME) { - /* we want the strip to hold on the exact fraction of the repeat value */ - - frametime = actlength * (strip->repeat - (int)strip->repeat); - if (frametime <= 0.000001f) frametime = actlength; /* rounding errors... */ - frametime = bsystem_time(scene, ob, frametime + strip->actstart, 0.0); - - if (blocktype == ID_AR) - extract_pose_from_action(tpose, strip->act, frametime); - else if (blocktype == ID_OB) { - extract_ipochannels_from_action(&tchanbase, &ob->id, strip->act, "Object", frametime); - if (key) - extract_ipochannels_from_action(&tchanbase, &key->id, strip->act, "Shape", frametime); - } - - /* handle cycle hold */ - if (strip->repeat != 1.0f) { - if (blocktype == ID_AR) - cyclic_offs_bone(ob, tpose, strip, strip->repeat - 1.0f); - } - - doit = 1; - } - } - - /* Handle blendin & blendout */ - if (doit) { - /* Handle blendin */ - - if (strip->blendin > 0.0 && stripframe <= strip->blendin && scene_cfra >= strip->start) { - blendfac = stripframe / strip->blendin; - } - else if (strip->blendout > 0.0 && stripframe >= (length - strip->blendout) && scene_cfra <= strip->end) { - blendfac = (length - stripframe) / (strip->blendout); - } - else - blendfac = 1; - - if (blocktype == ID_AR) { /* Blend this pose with the accumulated pose */ - /* offset bone, for matching cycles */ - blend_pose_offset_bone(strip, ob->pose, tpose, blendfac, strip->mode); - - blend_poses(ob->pose, tpose, blendfac, strip->mode); - if (dostride) - blend_pose_strides(ob->pose, tpose, blendfac, strip->mode); - } - else { - blend_ipochannels(&chanbase, &tchanbase, blendfac, strip->mode); - BLI_freelistN(&tchanbase); - } - } - } - } - } - - if (blocktype == ID_OB) { - execute_ipochannels(&chanbase); - } - else if (blocktype == ID_AR) { - /* apply stride offset to object */ - add_v3_v3(ob->obmat[3], ob->pose->stride_offset); - } - - /* free */ - if (tpose) - BKE_pose_free(tpose); - if (chanbase.first) - BLI_freelistN(&chanbase); -} - -#endif // XXX OLD ANIMATION SYSTEM (TO BE REMOVED) diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index 1b301ba43b3..dffe26bd782 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -40,6 +40,8 @@ #include "BLI_rand.h" #include "BLI_utildefines.h" +#include "BLF_translation.h" + #include "DNA_anim_types.h" #include "DNA_armature_types.h" #include "DNA_group_types.h" @@ -75,7 +77,7 @@ /* forward declarations */ static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBase *duplilist, float par_space_mat[][4], int par_index, - int level, short animated, short update); + int level, short flag); /* ******************************************************************** */ /* Animation Visualization */ @@ -174,10 +176,10 @@ bMotionPath *animviz_verify_motionpaths(ReportList *reports, Scene *scene, Objec /* avoid 0 size allocs */ if (avs->path_sf >= avs->path_ef) { BKE_reportf(reports, RPT_ERROR, - "Motion Path frame extents invalid for %s (%d to %d).%s\n", + "Motion path frame extents invalid for %s (%d to %d)%s", (pchan) ? pchan->name : ob->id.name, avs->path_sf, avs->path_ef, - (avs->path_sf == avs->path_ef) ? " Cannot have single-frame paths." : ""); + (avs->path_sf == avs->path_ef) ? TIP_(", cannot have single-frame paths") : ""); return NULL; } @@ -700,7 +702,11 @@ int where_on_path(Object *ob, float ctime, float vec[4], float dir[3], float qua /* ******************************************************************** */ /* Dupli-Geometry */ -static DupliObject *new_dupli_object(ListBase *lb, Object *ob, float mat[][4], int lay, int index, int par_index, int type, short animated) +#define DUPLILIST_DO_UPDATE 1 +#define DUPLILIST_FOR_RENDER 2 +#define DUPLILIST_ANIMATED 4 + +static DupliObject *new_dupli_object(ListBase *lb, Object *ob, float mat[][4], int lay, int index, int par_index, int type, short flag) { DupliObject *dob = MEM_callocN(sizeof(DupliObject), "dupliobject"); @@ -712,14 +718,14 @@ static DupliObject *new_dupli_object(ListBase *lb, Object *ob, float mat[][4], i dob->index = index; dob->particle_index = par_index; dob->type = type; - dob->animated = (type == OB_DUPLIGROUP) && animated; + dob->animated = (type == OB_DUPLIGROUP) && (flag & DUPLILIST_ANIMATED); ob->lay = lay; return dob; } static void group_duplilist(ListBase *lb, Scene *scene, Object *ob, int par_index, - int level, short animated, short update) + int level, short flag) { DupliObject *dob; Group *group; @@ -735,13 +741,14 @@ static void group_duplilist(ListBase *lb, Scene *scene, Object *ob, int par_inde /* handles animated groups, and */ /* we need to check update for objects that are not in scene... */ - if (update) { + if (flag & DUPLILIST_DO_UPDATE) { /* note: update is optional because we don't always need object * transformations to be correct. Also fixes bug [#29616]. */ group_handle_recalc_and_update(scene, ob, group); } - animated = animated || group_is_animated(ob, group); + if (group_is_animated(ob, group)) + flag |= DUPLILIST_ANIMATED; for (go = group->gobject.first; go; go = go->next) { /* note, if you check on layer here, render goes wrong... it still deforms verts and uses parent imat */ @@ -757,7 +764,7 @@ static void group_duplilist(ListBase *lb, Scene *scene, Object *ob, int par_inde mult_m4_m4m4(mat, ob->obmat, go->ob->obmat); } - dob = new_dupli_object(lb, go->ob, mat, ob->lay, 0, par_index, OB_DUPLIGROUP, animated); + dob = new_dupli_object(lb, go->ob, mat, ob->lay, 0, par_index, OB_DUPLIGROUP, flag); /* check the group instance and object layers match, also that the object visible flags are ok. */ if ((dob->origlay & group->layer) == 0 || @@ -772,14 +779,14 @@ static void group_duplilist(ListBase *lb, Scene *scene, Object *ob, int par_inde if (go->ob->transflag & OB_DUPLI) { copy_m4_m4(dob->ob->obmat, dob->mat); - object_duplilist_recursive(&group->id, scene, go->ob, lb, ob->obmat, par_index, level + 1, animated, update); + object_duplilist_recursive(&group->id, scene, go->ob, lb, ob->obmat, par_index, level + 1, flag); copy_m4_m4(dob->ob->obmat, dob->omat); } } } } -static void frames_duplilist(ListBase *lb, Scene *scene, Object *ob, int par_index, int level, short animated) +static void frames_duplilist(ListBase *lb, Scene *scene, Object *ob, int par_index, int level, short flag) { extern int enable_cu_speed; /* object.c */ Object copyob; @@ -817,7 +824,7 @@ static void frames_duplilist(ListBase *lb, Scene *scene, Object *ob, int par_ind ok = (ok < ob->dupon); } - if (ok) { + if (ok) { DupliObject *dob; /* WARNING: doing animation updates in this way is not terribly accurate, as the dependencies @@ -827,7 +834,7 @@ static void frames_duplilist(ListBase *lb, Scene *scene, Object *ob, int par_ind BKE_animsys_evaluate_animdata(scene, &ob->id, ob->adt, (float)scene->r.cfra, ADT_RECALC_ANIM); /* ob-eval will do drivers, so we don't need to do them */ BKE_object_where_is_calc_time(scene, ob, (float)scene->r.cfra); - dob = new_dupli_object(lb, ob, ob->obmat, ob->lay, scene->r.cfra, par_index, OB_DUPLIFRAMES, animated); + dob = new_dupli_object(lb, ob, ob->obmat, ob->lay, scene->r.cfra, par_index, OB_DUPLIFRAMES, flag); copy_m4_m4(dob->omat, copyob.obmat); } } @@ -851,8 +858,7 @@ static void frames_duplilist(ListBase *lb, Scene *scene, Object *ob, int par_ind typedef struct VertexDupliData { ID *id; /* scene or group, for recursive loops */ int level; - short animated; - short update; + short flag; ListBase *lb; float pmat[4][4]; float obmat[4][4]; /* Only used for dupliverts inside dupligroups, where the ob->obmat is modified */ @@ -896,7 +902,7 @@ static void vertex_dupli__mapFunc(void *userData, int index, const float co[3], origlay = vdd->ob->lay; - dob = new_dupli_object(vdd->lb, vdd->ob, obmat, vdd->par->lay, index, vdd->par_index, OB_DUPLIVERTS, vdd->animated); + dob = new_dupli_object(vdd->lb, vdd->ob, obmat, vdd->par->lay, index, vdd->par_index, OB_DUPLIVERTS, vdd->flag); /* restore the original layer so that each dupli will have proper dob->origlay */ vdd->ob->lay = origlay; @@ -908,13 +914,13 @@ static void vertex_dupli__mapFunc(void *userData, int index, const float co[3], float tmpmat[4][4]; copy_m4_m4(tmpmat, vdd->ob->obmat); copy_m4_m4(vdd->ob->obmat, obmat); /* pretend we are really this mat */ - object_duplilist_recursive((ID *)vdd->id, vdd->scene, vdd->ob, vdd->lb, obmat, vdd->par_index, vdd->level + 1, vdd->animated, vdd->update); + object_duplilist_recursive((ID *)vdd->id, vdd->scene, vdd->ob, vdd->lb, obmat, vdd->par_index, vdd->level + 1, vdd->flag); copy_m4_m4(vdd->ob->obmat, tmpmat); } } static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[][4], int par_index, - int level, short animated, short update) + int level, short flag) { Object *ob, *ob_iter; Mesh *me = par->data; @@ -942,7 +948,7 @@ static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, fl else dm = mesh_get_derived_deform(scene, par, CD_MASK_BAREMESH); - if (G.is_rendering) { + if (flag & DUPLILIST_FOR_RENDER) { vdd.orco = (float(*)[3])BKE_mesh_orco_verts_get(par); BKE_mesh_orco_verts_transform(me, vdd.orco, me->totvert, 0); } @@ -964,7 +970,7 @@ static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, fl } /* Start looping on Scene OR Group objects */ - while (base || go) { + while (base || go) { if (sce) { ob_iter = base->object; oblay = base->lay; @@ -992,8 +998,7 @@ static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, fl vdd.id = id; vdd.level = level; - vdd.animated = animated; - vdd.update = update; + vdd.flag = flag; vdd.lb = lb; vdd.ob = ob; vdd.scene = scene; @@ -1039,7 +1044,7 @@ static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, fl } static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[][4], int par_index, - int level, short animated, short update) + int level, short flag) { Object *ob, *ob_iter; Base *base = NULL; @@ -1076,8 +1081,7 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa mloop = dm->getLoopArray(dm); mvert = dm->getVertArray(dm); - if (G.is_rendering) { - + if (flag & DUPLILIST_FOR_RENDER) { orco = (float(*)[3])BKE_mesh_orco_verts_get(par); BKE_mesh_orco_verts_transform(me, orco, me->totvert, 0); mloopuv = me->mloopuv; @@ -1100,7 +1104,7 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa } /* Start looping on Scene OR Group objects */ - while (base || go) { + while (base || go) { if (sce) { ob_iter = base->object; oblay = base->lay; @@ -1140,21 +1144,17 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa float *v3; /* float *v4; */ /* UNUSED */ float cent[3], quat[4], mat[3][3], mat3[3][3], tmat[4][4], obmat[4][4]; + float f_no[3]; MLoop *loopstart = mloop + mp->loopstart; - if (mp->totloop < 3) { - /* highly unlikely but to be safe */ + if (UNLIKELY(mp->totloop < 3)) { continue; } else { + BKE_mesh_calc_poly_normal(mp, mloop + mp->loopstart, mvert, f_no); v1 = mvert[(mv1 = loopstart[0].v)].co; v2 = mvert[(mv2 = loopstart[1].v)].co; v3 = mvert[(mv3 = loopstart[2].v)].co; -#if 0 - if (mp->totloop > 3) { - v4 = mvert[(mv4 = loopstart[3].v)].co; - } -#endif } /* translation */ @@ -1170,12 +1170,12 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa copy_v3_v3(obmat[3], cent); /* rotation */ - tri_to_quat(quat, v1, v2, v3); + tri_to_quat_ex(quat, v1, v2, v3, f_no); quat_to_mat3(mat, quat); /* scale */ if (par->transflag & OB_DUPLIFACES_SCALE) { - float size = BKE_mesh_calc_poly_area(mp, loopstart, mvert, NULL); + float size = BKE_mesh_calc_poly_area(mp, loopstart, mvert, f_no); size = sqrtf(size) * par->dupfacesca; mul_m3_fl(mat, size); } @@ -1186,8 +1186,8 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa copy_m4_m4(tmat, obmat); mul_m4_m4m3(obmat, tmat, mat); - dob = new_dupli_object(lb, ob, obmat, par->lay, a, par_index, OB_DUPLIFACES, animated); - if (G.is_rendering) { + dob = new_dupli_object(lb, ob, obmat, par->lay, a, par_index, OB_DUPLIFACES, (flag & DUPLILIST_ANIMATED)); + if (flag & DUPLILIST_FOR_RENDER) { w = 1.0f / (float)mp->totloop; if (orco) { @@ -1209,7 +1209,7 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa float tmpmat[4][4]; copy_m4_m4(tmpmat, ob->obmat); copy_m4_m4(ob->obmat, obmat); /* pretend we are really this mat */ - object_duplilist_recursive((ID *)id, scene, ob, lb, ob->obmat, par_index, level + 1, animated, update); + object_duplilist_recursive((ID *)id, scene, ob, lb, ob->obmat, par_index, level + 1, flag); copy_m4_m4(ob->obmat, tmpmat); } } @@ -1230,7 +1230,7 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa } static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[][4], int UNUSED(par_index), ParticleSystem *psys, - int level, short animated, short update) + int level, short flag) { GroupObject *go; Object *ob = NULL, **oblist = NULL, obcopy, *obcopylist = NULL; @@ -1313,7 +1313,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p /* gather list of objects or single object */ if (part->ren_as == PART_DRAW_GR) { - if (update) { + if (flag & DUPLILIST_DO_UPDATE) { group_handle_recalc_and_update(scene, par, part->dup_group); } @@ -1456,9 +1456,9 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p else copy_m4_m4(mat, tmat); - dob = new_dupli_object(lb, go->ob, mat, par->lay, counter, index, OB_DUPLIPARTS, animated); + dob = new_dupli_object(lb, go->ob, mat, par->lay, counter, index, OB_DUPLIPARTS, (flag & DUPLILIST_ANIMATED)); copy_m4_m4(dob->omat, obcopylist[b].obmat); - if (G.is_rendering) + if (flag & DUPLILIST_FOR_RENDER) psys_get_dupli_texture(psys, part, sim.psmd, pa, cpa, dob->uv, dob->orco); } } @@ -1516,9 +1516,9 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p if (part->draw & PART_DRAW_GLOBAL_OB) add_v3_v3v3(mat[3], mat[3], vec); - dob = new_dupli_object(lb, ob, mat, ob->lay, counter, index, GS(id->name) == ID_GR ? OB_DUPLIGROUP : OB_DUPLIPARTS, animated); + dob = new_dupli_object(lb, ob, mat, ob->lay, counter, index, GS(id->name) == ID_GR ? OB_DUPLIGROUP : OB_DUPLIPARTS, (flag & DUPLILIST_ANIMATED)); copy_m4_m4(dob->omat, oldobmat); - if (G.is_rendering) + if (flag & DUPLILIST_FOR_RENDER) psys_get_dupli_texture(psys, part, sim.psmd, pa, cpa, dob->uv, dob->orco); } @@ -1570,7 +1570,7 @@ static Object *find_family_object(Object **obar, char *family, char ch) } -static void font_duplilist(ListBase *lb, Scene *scene, Object *par, int par_index, int level, short animated) +static void font_duplilist(ListBase *lb, Scene *scene, Object *par, int par_index, int level, short flag) { Object *ob, *obar[256] = {NULL}; Curve *cu; @@ -1609,7 +1609,7 @@ static void font_duplilist(ListBase *lb, Scene *scene, Object *par, int par_inde copy_m4_m4(obmat, par->obmat); copy_v3_v3(obmat[3], vec); - new_dupli_object(lb, ob, obmat, par->lay, a, par_index, OB_DUPLIVERTS, animated); + new_dupli_object(lb, ob, obmat, par->lay, a, par_index, OB_DUPLIVERTS, flag); } } @@ -1619,7 +1619,7 @@ static void font_duplilist(ListBase *lb, Scene *scene, Object *par, int par_inde /* ------------- */ static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBase *duplilist, float par_space_mat[][4], int par_index, - int level, short animated, short update) + int level, short flag) { if ((ob->transflag & OB_DUPLI) == 0) return; @@ -1639,31 +1639,31 @@ static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBas if (ob->transflag & OB_DUPLIPARTS) { ParticleSystem *psys = ob->particlesystem.first; for (; psys; psys = psys->next) - new_particle_duplilist(duplilist, id, scene, ob, par_space_mat, par_index, psys, level + 1, animated, update); + new_particle_duplilist(duplilist, id, scene, ob, par_space_mat, par_index, psys, level + 1, flag); } else if (ob->transflag & OB_DUPLIVERTS) { if (ob->type == OB_MESH) { - vertex_duplilist(duplilist, id, scene, ob, par_space_mat, par_index, level + 1, animated, update); + vertex_duplilist(duplilist, id, scene, ob, par_space_mat, par_index, level + 1, flag); } else if (ob->type == OB_FONT) { if (GS(id->name) == ID_SCE) { /* TODO - support dupligroups */ - font_duplilist(duplilist, scene, ob, par_index, level + 1, animated); + font_duplilist(duplilist, scene, ob, par_index, level + 1, flag); } } } else if (ob->transflag & OB_DUPLIFACES) { if (ob->type == OB_MESH) - face_duplilist(duplilist, id, scene, ob, par_space_mat, par_index, level + 1, animated, update); + face_duplilist(duplilist, id, scene, ob, par_space_mat, par_index, level + 1, flag); } else if (ob->transflag & OB_DUPLIFRAMES) { if (GS(id->name) == ID_SCE) { /* TODO - support dupligroups */ - frames_duplilist(duplilist, scene, ob, par_index, level + 1, animated); + frames_duplilist(duplilist, scene, ob, par_index, level + 1, flag); } } else if (ob->transflag & OB_DUPLIGROUP) { DupliObject *dob; - group_duplilist(duplilist, scene, ob, par_index, level + 1, animated, update); /* now recursive */ + group_duplilist(duplilist, scene, ob, par_index, level + 1, flag); /* now recursive */ if (level == 0) { for (dob = duplilist->first; dob; dob = dob->next) @@ -1675,19 +1675,24 @@ static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBas /* Returns a list of DupliObject * note; group dupli's already set transform matrix. see note in group_duplilist() */ -ListBase *object_duplilist_ex(Scene *sce, Object *ob, int update) +ListBase *object_duplilist_ex(Scene *sce, Object *ob, int update, int for_render) { ListBase *duplilist = MEM_mallocN(sizeof(ListBase), "duplilist"); + int flag = 0; + + if (update) flag |= DUPLILIST_DO_UPDATE; + if (for_render) flag |= DUPLILIST_FOR_RENDER; + duplilist->first = duplilist->last = NULL; - object_duplilist_recursive((ID *)sce, sce, ob, duplilist, NULL, 0, 0, 0, update); + object_duplilist_recursive((ID *)sce, sce, ob, duplilist, NULL, 0, 0, flag); return duplilist; } /* note: previously updating was always done, this is why it defaults to be on * but there are likely places it can be called without updating */ -ListBase *object_duplilist(Scene *sce, Object *ob) +ListBase *object_duplilist(Scene *sce, Object *ob, int for_render) { - return object_duplilist_ex(sce, ob, TRUE); + return object_duplilist_ex(sce, ob, TRUE, for_render); } diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c index 6a3dae93639..66ed31c5b72 100644 --- a/source/blender/blenkernel/intern/anim_sys.c +++ b/source/blender/blenkernel/intern/anim_sys.c @@ -188,9 +188,9 @@ short BKE_animdata_set_action(ReportList *reports, ID *id, bAction *act) else { /* cannot set */ BKE_reportf(reports, RPT_ERROR, - "Couldn't set Action '%s' onto ID '%s', as it doesn't have suitably rooted paths for this purpose", - act->id.name + 2, id->name); - //ok = 0; + "Could not set action '%s' onto ID '%s', as it does not have suitably rooted paths " + "for this purpose", act->id.name + 2, id->name); + /* ok = 0; */ } } else { @@ -419,7 +419,7 @@ void action_move_fcurves_by_basepath(bAction *srcAct, bAction *dstAct, const cha /* should F-Curve be moved over? * - we only need the start of the path to match basepath */ - if (animpath_matches_basepath(fcu->rna_path, basepath)) { + if (animpath_matches_basepath(fcu->rna_path, basepath)) { bActionGroup *agrp = NULL; /* if grouped... */ @@ -574,7 +574,7 @@ static char *rna_path_rename_fix(ID *owner_id, const char *prefix, const char *o */ if ( (prefixPtr && oldNamePtr) && (prefixPtr + prefixLen == oldNamePtr) ) { /* if we haven't aren't able to resolve the path now, try again after fixing it */ - if (!verify_paths || check_rna_path_is_valid(owner_id, oldpath) == 0) { + if (!verify_paths || check_rna_path_is_valid(owner_id, oldpath) == 0) { DynStr *ds = BLI_dynstr_new(); char *postfixPtr = oldNamePtr + oldNameLen; char *newPath = NULL; @@ -639,7 +639,7 @@ static void fcurves_path_rename_fix(ID *owner_id, const char *prefix, const char if (fcu->rna_path != old_path) { bActionGroup *agrp = fcu->grp; - if ((agrp) && strcmp(oldName, agrp->name)==0) { + if ((agrp) && strcmp(oldName, agrp->name) == 0) { BLI_strncpy(agrp->name, newName, sizeof(agrp->name)); } } @@ -724,7 +724,7 @@ void BKE_animdata_fix_paths_rename(ID *owner_id, AnimData *adt, ID *ref_id, cons /* pad the names with [" "] so that only exact matches are made */ oldN = BLI_sprintfN("[\"%s\"]", oldName); newN = BLI_sprintfN("[\"%s\"]", newName); - } + } else { oldN = BLI_sprintfN("[%d]", oldSubscript); newN = BLI_sprintfN("[%d]", newSubscript); @@ -1239,7 +1239,7 @@ static short animsys_write_rna_setting(PointerRNA *ptr, char *path, int array_in if (new_ptr.type == &RNA_PoseBone) { /* bone transforms - update pose (i.e. tag depsgraph) */ skip_updates_hack = 1; - } + } if (skip_updates_hack == 0) RNA_property_update_cache_add(&new_ptr, prop); diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index b87342f85fa..b3cbc1f2b16 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -534,10 +534,12 @@ Mat4 *b_bone_spline_setup(bPoseChannel *pchan, int rest) mul_m4_v3(imat, h2); /* if next bone is B-bone too, use average handle direction */ - if (next->bone->segments > 1) - ; - else + if (next->bone->segments > 1) { + /* pass */ + } + else { h2[1] -= length; + } normalize_v3(h2); /* find the next roll to interpolate as well */ @@ -945,7 +947,7 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm, float } } - if (use_dverts || armature_def_nr >= 0) { + if (use_dverts || armature_def_nr != -1) { if (dm) dvert = dm->getVertData(dm, i, CD_MDEFORMVERT); else if (dverts && i < target_totvert) @@ -956,7 +958,7 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm, float else dvert = NULL; - if (armature_def_nr >= 0 && dvert) { + if (armature_def_nr != -1 && dvert) { armature_weight = defvert_find_weight(dvert, armature_def_nr); if (invert_vgroup) @@ -1423,19 +1425,20 @@ void BKE_rotMode_change_values(float quat[4], float eul[3], float axis[3], float * *************************************************************************** */ /* Computes vector and roll based on a rotation. * "mat" must contain only a rotation, and no scaling. */ -void mat3_to_vec_roll(float mat[][3], float vec[3], float *roll) +void mat3_to_vec_roll(float mat[][3], float r_vec[3], float *r_roll) { - if (vec) - copy_v3_v3(vec, mat[1]); + if (r_vec) { + copy_v3_v3(r_vec, mat[1]); + } - if (roll) { + if (r_roll) { float vecmat[3][3], vecmatinv[3][3], rollmat[3][3]; vec_roll_to_mat3(mat[1], 0.0f, vecmat); invert_m3_m3(vecmatinv, vecmat); mul_m3_m3m3(rollmat, vecmatinv, mat); - *roll = (float)atan2(rollmat[2][0], rollmat[2][2]); + *r_roll = atan2f(rollmat[2][0], rollmat[2][2]); } } @@ -1459,7 +1462,7 @@ void vec_roll_to_mat3(const float vec[3], const float roll, float mat[][3]) * so a value inbetween these is needed. * * was 0.000001, causes bug [#30438] (which is same as [#27675, imho). - * Reseting it to org value seems to cause no more [#23954]... + * Resetting it to org value seems to cause no more [#23954]... * * was 0.0000000000001, caused bug [#31333], smaller values give unstable * roll when toggling editmode again... @@ -1590,7 +1593,7 @@ static void pose_proxy_synchronize(Object *ob, Object *from, int layer_protected if (UNLIKELY(pchanp == NULL)) { /* happens for proxies that become invalid because of a missing link - * for regulat cases it shouldn't happen at all */ + * for regular cases it shouldn't happen at all */ } else if (pchan->bone->layer & layer_protected) { ListBase proxylocal_constraints = {NULL, NULL}; diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index 99b788e80ce..e1e868b234e 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -119,7 +119,7 @@ void free_blender(void) BKE_sequencer_cache_destruct(); IMB_moviecache_destruct(); - free_nodesystem(); + free_nodesystem(); } void initglobals(void) @@ -237,7 +237,7 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath /* free G.main Main database */ // CTX_wm_manager_set(C, NULL); - clear_global(); + clear_global(); /* clear old property update cache, in case some old references are left dangling */ RNA_property_update_cache_free(); @@ -338,7 +338,7 @@ static int handle_subversion_warning(Main *main, ReportList *reports) (main->minversionfile == BLENDER_VERSION && main->minsubversionfile > BLENDER_SUBVERSION)) { - BKE_reportf(reports, RPT_ERROR, "File written by newer Blender binary: %d.%d, expect loss of data!", + BKE_reportf(reports, RPT_ERROR, "File written by newer Blender binary (%d.%d), expect loss of data!", main->minversionfile, main->minsubversionfile); } @@ -407,9 +407,9 @@ int BKE_read_file(bContext *C, const char *filepath, ReportList *reports) } else setup_app_data(C, bfd, filepath); // frees BFD - } + } else - BKE_reports_prependf(reports, "Loading %s failed: ", filepath); + BKE_reports_prependf(reports, "Loading '%s' failed: ", filepath); return (bfd ? retval : BKE_READ_FILE_FAIL); } @@ -485,7 +485,7 @@ static int read_undosave(bContext *C, UndoElem *uel) int success = 0, fileflags; /* This is needed so undoing/redoing doesn't crash with threaded previews going */ - WM_jobs_stop_all(CTX_wm_manager(C)); + WM_jobs_kill_all_except(CTX_wm_manager(C), CTX_wm_screen(C)); BLI_strncpy(mainstr, G.main->name, sizeof(mainstr)); /* temporal store */ @@ -612,7 +612,7 @@ void BKE_write_undo(bContext *C, const char *name) } } -/* 1= an undo, -1 is a redo. we have to make sure 'curundo' remains at current situation */ +/* 1 = an undo, -1 is a redo. we have to make sure 'curundo' remains at current situation */ void BKE_undo_step(bContext *C, int step) { @@ -621,7 +621,9 @@ void BKE_undo_step(bContext *C, int step) } else if (step == 1) { /* curundo should never be NULL, after restart or load file it should call undo_save */ - if (curundo == NULL || curundo->prev == NULL) ; // XXX error("No undo available"); + if (curundo == NULL || curundo->prev == NULL) { + // XXX error("No undo available"); + } else { if (G.debug & G_DEBUG) printf("undo %s\n", curundo->name); curundo = curundo->prev; @@ -631,7 +633,9 @@ void BKE_undo_step(bContext *C, int step) else { /* curundo has to remain current situation! */ - if (curundo == NULL || curundo->next == NULL) ; // XXX error("No redo available"); + if (curundo == NULL || curundo->next == NULL) { + // XXX error("No redo available"); + } else { read_undosave(C, curundo->next); curundo = curundo->next; diff --git a/source/blender/blenkernel/intern/bmfont.c b/source/blender/blenkernel/intern/bmfont.c index 18161bc6fcb..df7fb2c1807 100644 --- a/source/blender/blenkernel/intern/bmfont.c +++ b/source/blender/blenkernel/intern/bmfont.c @@ -96,13 +96,13 @@ void readBitmapFontVersion0(ImBuf * ibuf, unsigned char * rect, int step) ysize = (bytes + (ibuf->x - 1)) / ibuf->x; if (ysize < ibuf->y) { - /* we're first going to copy all data into a liniar buffer. + /* we're first going to copy all data into a linear buffer. * step can be 4 or 1 bytes, and the data is not sequential because * the bitmap was flipped vertically. */ buffer = MEM_mallocN(bytes, "readBitmapFontVersion0:buffer"); - index = 0; + index = 0; for (i = 0; i < bytes; i++) { buffer[i] = rect[index]; index += step; diff --git a/source/blender/blenkernel/intern/boids.c b/source/blender/blenkernel/intern/boids.c index 79d5e092a10..b6f1b88c912 100644 --- a/source/blender/blenkernel/intern/boids.c +++ b/source/blender/blenkernel/intern/boids.c @@ -101,13 +101,15 @@ static int rule_goal_avoid(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, break; } } - else if (rule->type == eBoidRuleType_Goal && eob == bpa->ground) - ; /* skip current object */ + else if (rule->type == eBoidRuleType_Goal && eob == bpa->ground) { + /* skip current object */ + } else if (pd->forcefield == PFIELD_BOID && mul * pd->f_strength > 0.0f && get_effector_data(cur, &cur_efd, &epoint, 0)) { float temp = mul * pd->f_strength * effector_falloff(cur, &cur_efd, &epoint, bbd->part->effector_weights); - if (temp == 0.0f) - ; /* do nothing */ + if (temp == 0.0f) { + /* do nothing */ + } else if (temp > priority) { priority = temp; eff = cur; @@ -954,7 +956,8 @@ void boid_brain(BoidBrainData *bbd, int p, ParticleData *pa) // } //} - bbd->wanted_co[0]=bbd->wanted_co[1]=bbd->wanted_co[2]=bbd->wanted_speed=0.0f; + zero_v3(bbd->wanted_co); + bbd->wanted_speed = 0.0f; /* create random seed for every particle & frame */ rand = (int)(PSYS_FRAND(psys->seed + p) * 1000); @@ -988,7 +991,8 @@ void boid_brain(BoidBrainData *bbd, int p, ParticleData *pa) add_v3_v3(wanted_co, bbd->wanted_co); wanted_speed += bbd->wanted_speed; n++; - bbd->wanted_co[0]=bbd->wanted_co[1]=bbd->wanted_co[2]=bbd->wanted_speed=0.0f; + zero_v3(bbd->wanted_co); + bbd->wanted_speed = 0.0f; } } @@ -1168,7 +1172,7 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa) /* constrain direction with maximum angular velocity */ angle = saacos(dot_v3v3(old_dir, wanted_dir)); - angle = minf(angle, val.max_ave); + angle = min_ff(angle, val.max_ave); cross_v3_v3v3(nor, old_dir, wanted_dir); axis_angle_to_quat(q, nor, angle); @@ -1264,9 +1268,9 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa) { float grav[3]; - grav[0]= 0.0f; - grav[1]= 0.0f; - grav[2]= bbd->sim->scene->physics_settings.gravity[2] < 0.0f ? -1.0f : 0.0f; + grav[0] = 0.0f; + grav[1] = 0.0f; + grav[2] = bbd->sim->scene->physics_settings.gravity[2] < 0.0f ? -1.0f : 0.0f; /* don't take forward acceleration into account (better banking) */ if (dot_v3v3(bpa->data.acc, pa->state.vel) > 0.0f) { @@ -1307,9 +1311,9 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa) { float grav[3]; - grav[0]= 0.0f; - grav[1]= 0.0f; - grav[2]= bbd->sim->scene->physics_settings.gravity[2] < 0.0f ? -1.0f : 0.0f; + grav[0] = 0.0f; + grav[1] = 0.0f; + grav[2] = bbd->sim->scene->physics_settings.gravity[2] < 0.0f ? -1.0f : 0.0f; /* gather apparent gravity */ diff --git a/source/blender/blenkernel/intern/booleanops_mesh.c b/source/blender/blenkernel/intern/booleanops_mesh.c index be79077bb58..461b945282f 100644 --- a/source/blender/blenkernel/intern/booleanops_mesh.c +++ b/source/blender/blenkernel/intern/booleanops_mesh.c @@ -142,7 +142,7 @@ CSG_AddMeshToBlender( /* Create a new blender mesh object - using 'base' as * a template for the new object. */ - ob_new= AddNewBlenderMesh(mesh->base); + ob_new = AddNewBlenderMesh(mesh->base); me_new = ob_new->data; @@ -180,7 +180,7 @@ CSG_PerformOp( if ((mesh1 == NULL) || (mesh2 == NULL) || (output == NULL)) { return 0; - } + } if ((int_op_type < 1) || (int_op_type > 3)) return 0; switch (int_op_type) { @@ -203,8 +203,8 @@ CSG_PerformOp( mesh1->m_face_iterator, mesh1->m_vertex_iterator, mesh2->m_face_iterator, - mesh2->m_vertex_iterator, - InterpFaceVertexData + mesh2->m_vertex_iterator, + InterpFaceVertexData ); } else { @@ -215,8 +215,8 @@ CSG_PerformOp( mesh1->m_face_iterator, mesh1->m_vertex_iterator, mesh2->m_face_iterator, - mesh2->m_vertex_iterator, - InterpNoUserData + mesh2->m_vertex_iterator, + InterpNoUserData ); } diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index fde95e0767e..98b206712d6 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -529,7 +529,7 @@ void BKE_brush_imbuf_new(const Scene *scene, Brush *brush, short flt, short texf unsigned char *dst, crgb[3]; const float alpha = BKE_brush_alpha_get(scene, brush); float brush_rgb[3]; - + imbflag = (flt) ? IB_rectfloat : IB_rect; xoff = -bufsize / 2.0f + 0.5f; yoff = -bufsize / 2.0f + 0.5f; @@ -563,7 +563,7 @@ void BKE_brush_imbuf_new(const Scene *scene, Brush *brush, short flt, short texf else { BKE_brush_sample_tex(scene, brush, xy, rgba, 0); mul_v3_v3v3(dstf, rgba, brush_rgb); - dstf[3] = rgba[3] *alpha *BKE_brush_curve_strength_clamp(brush, len_v2(xy), radius); + dstf[3] = rgba[3] * alpha * BKE_brush_curve_strength_clamp(brush, len_v2(xy), radius); } } } @@ -594,7 +594,7 @@ void BKE_brush_imbuf_new(const Scene *scene, Brush *brush, short flt, short texf else if (texfall == 2) { BKE_brush_sample_tex(scene, brush, xy, rgba, 0); mul_v3_v3(rgba, brush->rgb); - alpha_f = rgba[3] *alpha *BKE_brush_curve_strength_clamp(brush, len_v2(xy), radius); + alpha_f = rgba[3] * alpha * BKE_brush_curve_strength_clamp(brush, len_v2(xy), radius); rgb_float_to_uchar(dst, rgba); @@ -602,7 +602,7 @@ void BKE_brush_imbuf_new(const Scene *scene, Brush *brush, short flt, short texf } else { BKE_brush_sample_tex(scene, brush, xy, rgba, 0); - alpha_f = rgba[3] *alpha *BKE_brush_curve_strength_clamp(brush, len_v2(xy), radius); + alpha_f = rgba[3] * alpha * BKE_brush_curve_strength_clamp(brush, len_v2(xy), radius); dst[0] = crgb[0]; dst[1] = crgb[1]; @@ -618,18 +618,18 @@ void BKE_brush_imbuf_new(const Scene *scene, Brush *brush, short flt, short texf /* Unified Size and Strength */ -// XXX: be careful about setting size and unprojected radius -// because they depend on one another -// these functions do not set the other corresponding value -// this can lead to odd behavior if size and unprojected -// radius become inconsistent. -// the biggest problem is that it isn't possible to change -// unprojected radius because a view context is not -// available. my ussual solution to this is to use the -// ratio of change of the size to change the unprojected -// radius. Not completely convinced that is correct. -// In anycase, a better solution is needed to prevent -// inconsistency. +/* XXX: be careful about setting size and unprojected radius + * because they depend on one another + * these functions do not set the other corresponding value + * this can lead to odd behavior if size and unprojected + * radius become inconsistent. + * the biggest problem is that it isn't possible to change + * unprojected radius because a view context is not + * available. my ussual solution to this is to use the + * ratio of change of the size to change the unprojected + * radius. Not completely convinced that is correct. + * In anycase, a better solution is needed to prevent + * inconsistency. */ void BKE_brush_size_set(Scene *scene, Brush *brush, int size) { @@ -741,7 +741,7 @@ void BKE_brush_scale_unprojected_radius(float *unprojected_radius, } /* scale brush size to reflect a change in the brush's unprojected radius */ -void BKE_brush_scale_size(int *BKE_brush_size_get, +void BKE_brush_scale_size(int *r_brush_size, float new_unprojected_radius, float old_unprojected_radius) { @@ -749,7 +749,7 @@ void BKE_brush_scale_size(int *BKE_brush_size_get, /* avoid division by zero */ if (old_unprojected_radius != 0) scale /= new_unprojected_radius; - (*BKE_brush_size_get) = (int)((float)(*BKE_brush_size_get) * scale); + (*r_brush_size) = (int)((float)(*r_brush_size) * scale); } /* Brush Painting */ @@ -876,8 +876,8 @@ static void brush_painter_do_partial(BrushPainter *painter, ImBuf *oldtexibuf, /* not sure if it's actually needed or it's a mistake in coords/sizes * calculation in brush_painter_fixed_tex_partial_update(), but without this * limitation memory gets corrupted at fast strokes with quite big spacing (sergey) */ - w = MIN2(w, ibuf->x); - h = MIN2(h, ibuf->y); + w = min_ii(w, ibuf->x); + h = min_ii(h, ibuf->y); if (painter->cache.flt) { for (; y < h; y++) { @@ -1052,13 +1052,13 @@ void BKE_brush_painter_break_stroke(BrushPainter *painter) static void brush_pressure_apply(BrushPainter *painter, Brush *brush, float pressure) { if (BKE_brush_use_alpha_pressure(painter->scene, brush)) - brush_alpha_set(painter->scene, brush, maxf(0.0f, painter->startalpha * pressure)); + brush_alpha_set(painter->scene, brush, max_ff(0.0f, painter->startalpha * pressure)); if (BKE_brush_use_size_pressure(painter->scene, brush)) - BKE_brush_size_set(painter->scene, brush, maxf(1.0f, painter->startsize * pressure)); + BKE_brush_size_set(painter->scene, brush, max_ff(1.0f, painter->startsize * pressure)); if (brush->flag & BRUSH_JITTER_PRESSURE) - brush->jitter = maxf(0.0f, painter->startjitter * pressure); + brush->jitter = max_ff(0.0f, painter->startjitter * pressure); if (brush->flag & BRUSH_SPACING_PRESSURE) - brush->spacing = maxf(1.0f, painter->startspacing * (1.5f - pressure)); + brush->spacing = max_ff(1.0f, painter->startspacing * (1.5f - pressure)); } void BKE_brush_jitter_pos(const Scene *scene, Brush *brush, const float pos[2], float jitterpos[2]) @@ -1158,7 +1158,7 @@ int BKE_brush_painter_paint(BrushPainter *painter, BrushFunc func, const float p /* compute brush spacing adapted to brush radius, spacing may depend * on pressure, so update it */ brush_pressure_apply(painter, brush, painter->lastpressure); - spacing = maxf(1.0f, radius) * brush->spacing * 0.01f; + spacing = max_ff(1.0f, radius) * brush->spacing * 0.01f; /* setup starting distance, direction vector and accumulated distance */ startdistance = painter->accumdistance; @@ -1176,7 +1176,7 @@ int BKE_brush_painter_paint(BrushPainter *painter, BrushFunc func, const float p t = step / len; press = (1.0f - t) * painter->lastpressure + t * pressure; brush_pressure_apply(painter, brush, press); - spacing = maxf(1.0f, radius) * brush->spacing * 0.01f; + spacing = max_ff(1.0f, radius) * brush->spacing * 0.01f; BKE_brush_jitter_pos(scene, brush, paintpos, finalpos); diff --git a/source/blender/blenkernel/intern/bullet.c b/source/blender/blenkernel/intern/bullet.c index 7defa7e1be3..088031e16a7 100644 --- a/source/blender/blenkernel/intern/bullet.c +++ b/source/blender/blenkernel/intern/bullet.c @@ -54,7 +54,7 @@ BulletSoftBody *bsbNew(void) bsb->viterations = 0; - bsb->piterations = 2; + bsb->piterations = 2; bsb->diterations = 0; bsb->citerations = 4; diff --git a/source/blender/blenkernel/intern/bvhutils.c b/source/blender/blenkernel/intern/bvhutils.c index 32ae6d04934..ad828a70dd8 100644 --- a/source/blender/blenkernel/intern/bvhutils.c +++ b/source/blender/blenkernel/intern/bvhutils.c @@ -358,8 +358,8 @@ float nearest_point_in_tri_surface(const float v0[3], const float v1[3], const f * BVH from meshs callbacks */ -// Callback to bvh tree nearest point. The tree must bust have been built using bvhtree_from_mesh_faces. -// userdata must be a BVHMeshCallbackUserdata built from the same mesh as the tree. +/* Callback to bvh tree nearest point. The tree must bust have been built using bvhtree_from_mesh_faces. + * userdata must be a BVHMeshCallbackUserdata built from the same mesh as the tree. */ static void mesh_faces_nearest_point(void *userdata, int index, const float co[3], BVHTreeNearest *nearest) { const BVHTreeFromMesh *data = (BVHTreeFromMesh *) userdata; @@ -395,8 +395,8 @@ static void mesh_faces_nearest_point(void *userdata, int index, const float co[3 } while (t2); } -// Callback to bvh tree raycast. The tree must bust have been built using bvhtree_from_mesh_faces. -// userdata must be a BVHMeshCallbackUserdata built from the same mesh as the tree. +/* Callback to bvh tree raycast. The tree must bust have been built using bvhtree_from_mesh_faces. + * userdata must be a BVHMeshCallbackUserdata built from the same mesh as the tree. */ static void mesh_faces_spherecast(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit) { const BVHTreeFromMesh *data = (BVHTreeFromMesh *) userdata; @@ -435,8 +435,8 @@ static void mesh_faces_spherecast(void *userdata, int index, const BVHTreeRay *r } while (t2); } -// Callback to bvh tree nearest point. The tree must bust have been built using bvhtree_from_mesh_edges. -// userdata must be a BVHMeshCallbackUserdata built from the same mesh as the tree. +/* Callback to bvh tree nearest point. The tree must bust have been built using bvhtree_from_mesh_edges. + * userdata must be a BVHMeshCallbackUserdata built from the same mesh as the tree. */ static void mesh_edges_nearest_point(void *userdata, int index, const float co[3], BVHTreeNearest *nearest) { const BVHTreeFromMesh *data = (BVHTreeFromMesh *) userdata; @@ -463,12 +463,12 @@ static void mesh_edges_nearest_point(void *userdata, int index, const float co[3 /* * BVH builders */ -// Builds a bvh tree.. where nodes are the vertexs of the given mesh +/* Builds a bvh tree.. where nodes are the vertexs of the given mesh */ BVHTree *bvhtree_from_mesh_verts(BVHTreeFromMesh *data, DerivedMesh *mesh, float epsilon, int tree_type, int axis) { BVHTree *tree = bvhcache_find(&mesh->bvhCache, BVHTREE_FROM_VERTICES); - //Not in cache + /* Not in cache */ if (tree == NULL) { int i; int numVerts = mesh->getNumVerts(mesh); @@ -484,7 +484,7 @@ BVHTree *bvhtree_from_mesh_verts(BVHTreeFromMesh *data, DerivedMesh *mesh, float BLI_bvhtree_balance(tree); - //Save on cache for later use + /* Save on cache for later use */ // printf("BVHTree built and saved on cache\n"); bvhcache_insert(&mesh->bvhCache, tree, BVHTREE_FROM_VERTICES); } @@ -495,15 +495,15 @@ BVHTree *bvhtree_from_mesh_verts(BVHTreeFromMesh *data, DerivedMesh *mesh, float } - //Setup BVHTreeFromMesh + /* Setup BVHTreeFromMesh */ memset(data, 0, sizeof(*data)); data->tree = tree; if (data->tree) { data->cached = TRUE; - //a NULL nearest callback works fine - //remeber the min distance to point is the same as the min distance to BV of point + /* a NULL nearest callback works fine + * remeber the min distance to point is the same as the min distance to BV of point */ data->nearest_callback = NULL; data->raycast_callback = NULL; @@ -517,12 +517,12 @@ BVHTree *bvhtree_from_mesh_verts(BVHTreeFromMesh *data, DerivedMesh *mesh, float return data->tree; } -// Builds a bvh tree.. where nodes are the faces of the given mesh. +/* Builds a bvh tree.. where nodes are the faces of the given mesh. */ BVHTree *bvhtree_from_mesh_faces(BVHTreeFromMesh *data, DerivedMesh *mesh, float epsilon, int tree_type, int axis) { BVHTree *tree = bvhcache_find(&mesh->bvhCache, BVHTREE_FROM_FACES); - //Not in cache + /* Not in cache */ if (tree == NULL) { int i; int numFaces = mesh->getNumTessFaces(mesh); @@ -616,7 +616,7 @@ BVHTree *bvhtree_from_mesh_faces(BVHTreeFromMesh *data, DerivedMesh *mesh, float } BLI_bvhtree_balance(tree); - //Save on cache for later use + /* Save on cache for later use */ // printf("BVHTree built and saved on cache\n"); bvhcache_insert(&mesh->bvhCache, tree, BVHTREE_FROM_FACES); } @@ -627,7 +627,7 @@ BVHTree *bvhtree_from_mesh_faces(BVHTreeFromMesh *data, DerivedMesh *mesh, float } - //Setup BVHTreeFromMesh + /* Setup BVHTreeFromMesh */ memset(data, 0, sizeof(*data)); data->tree = tree; @@ -647,12 +647,12 @@ BVHTree *bvhtree_from_mesh_faces(BVHTreeFromMesh *data, DerivedMesh *mesh, float } -// Builds a bvh tree.. where nodes are the faces of the given mesh. +/* Builds a bvh tree.. where nodes are the faces of the given mesh. */ BVHTree *bvhtree_from_mesh_edges(BVHTreeFromMesh *data, DerivedMesh *mesh, float epsilon, int tree_type, int axis) { BVHTree *tree = bvhcache_find(&mesh->bvhCache, BVHTREE_FROM_EDGES); - //Not in cache + /* Not in cache */ if (tree == NULL) { int i; int numEdges = mesh->getNumEdges(mesh); @@ -672,7 +672,7 @@ BVHTree *bvhtree_from_mesh_edges(BVHTreeFromMesh *data, DerivedMesh *mesh, float } BLI_bvhtree_balance(tree); - //Save on cache for later use + /* Save on cache for later use */ // printf("BVHTree built and saved on cache\n"); bvhcache_insert(&mesh->bvhCache, tree, BVHTREE_FROM_EDGES); } @@ -683,7 +683,7 @@ BVHTree *bvhtree_from_mesh_edges(BVHTreeFromMesh *data, DerivedMesh *mesh, float } - //Setup BVHTreeFromMesh + /* Setup BVHTreeFromMesh */ memset(data, 0, sizeof(*data)); data->tree = tree; @@ -703,7 +703,7 @@ BVHTree *bvhtree_from_mesh_edges(BVHTreeFromMesh *data, DerivedMesh *mesh, float } -// Frees data allocated by a call to bvhtree_from_mesh_*. +/* Frees data allocated by a call to bvhtree_from_mesh_*. */ void free_bvhtree_from_mesh(struct BVHTreeFromMesh *data) { if (data->tree) { @@ -728,7 +728,7 @@ static void bvhcacheitem_set_if_match(void *_cached, void *_search) BVHCacheItem *search = (BVHCacheItem *)_search; if (search->type == cached->type) { - search->tree = cached->tree; + search->tree = cached->tree; } } diff --git a/source/blender/blenkernel/intern/camera.c b/source/blender/blenkernel/intern/camera.c index ed7ac0e1a32..9118baeae6f 100644 --- a/source/blender/blenkernel/intern/camera.c +++ b/source/blender/blenkernel/intern/camera.c @@ -151,7 +151,7 @@ float BKE_camera_object_dof_distance(Object *ob) Camera *cam = (Camera *)ob->data; if (ob->type != OB_CAMERA) return 0.0f; - if (cam->dof_ob) { + if (cam->dof_ob) { /* too simple, better to return the distance on the view axis only * return len_v3v3(ob->obmat[3], cam->dof_ob->obmat[3]); */ float mat[4][4], imat[4][4], obmat[4][4]; @@ -262,11 +262,12 @@ void BKE_camera_params_from_view3d(CameraParams *params, View3D *v3d, RegionView } else if (rv3d->persp == RV3D_ORTHO) { /* orthographic view */ + int sensor_size = BKE_camera_sensor_size(params->sensor_fit, params->sensor_x, params->sensor_y); params->clipend *= 0.5f; // otherwise too extreme low zbuffer quality params->clipsta = -params->clipend; params->is_ortho = TRUE; - params->ortho_scale = rv3d->dist; + params->ortho_scale = rv3d->dist * sensor_size / v3d->lens; params->zoom = 2.0f; } else { diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index b176ed429f8..2e0b3a3c64a 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -273,6 +273,8 @@ static PBVH *cdDM_getPBVH(Object *ob, DerivedMesh *dm) cddm->pbvh = BLI_pbvh_new(); cddm->pbvh_draw = can_pbvh_draw(ob, dm); + pbvh_show_diffuse_color_set(cddm->pbvh, ob->sculpt->show_diffuse_color); + BKE_mesh_tessface_ensure(me); BLI_pbvh_build_mesh(cddm->pbvh, me->mface, me->mvert, @@ -379,7 +381,7 @@ static void cdDM_drawUVEdges(DerivedMesh *dm) for (i = 0; i < dm->numTessFaceData; i++, mf++) { if (!(mf->flag & ME_HIDE)) { draw = 1; - } + } else { draw = 0; } @@ -438,7 +440,7 @@ static void cdDM_drawEdges(DerivedMesh *dm, int drawLooseEdges, int drawAllEdges (drawLooseEdges || !(medge->flag & ME_LOOSEEDGE))) { draw = TRUE; - } + } else { draw = FALSE; } @@ -486,7 +488,7 @@ static void cdDM_drawLooseEdges(DerivedMesh *dm) for (i = 0; i < dm->numEdgeData; i++, medge++) { if (medge->flag & ME_LOOSEEDGE) { draw = 1; - } + } else { draw = 0; } @@ -552,7 +554,7 @@ static void cdDM_drawFacesSolid(DerivedMesh *dm, glShadeModel(shademodel = new_shademodel); glBegin(glmode = new_glmode); - } + } if (drawCurrentMat) { if (shademodel == GL_FLAT) { @@ -612,14 +614,29 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm, CDDerivedMesh *cddm = (CDDerivedMesh *) dm; MVert *mv = cddm->mvert; MFace *mf = DM_get_tessface_data_layer(dm, CD_MFACE); - MCol *realcol = dm->getTessFaceDataArray(dm, CD_TEXTURE_MCOL); float *nors = dm->getTessFaceDataArray(dm, CD_NORMAL); MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE); - int i, j, orig, *index = DM_get_tessface_data_layer(dm, CD_ORIGINDEX); - int startFace = 0 /*, lastFlag = 0xdeadbeef */ /* UNUSED */; - MCol *mcol = dm->getTessFaceDataArray(dm, CD_PREVIEW_MCOL); - if (!mcol) - mcol = dm->getTessFaceDataArray(dm, CD_MCOL); + MCol *mcol; + int i, orig; + int colType, startFace = 0; + + /* double lookup */ + const int *index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX); + const int *index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX); + if ((index_mf_to_mpoly && index_mp_to_orig) == FALSE) { + index_mf_to_mpoly = index_mp_to_orig = NULL; + } + + colType = CD_TEXTURE_MCOL; + mcol = dm->getTessFaceDataArray(dm, colType); + if (!mcol) { + colType = CD_PREVIEW_MCOL; + mcol = dm->getTessFaceDataArray(dm, colType); + } + if (!mcol) { + colType = CD_MCOL; + mcol = dm->getTessFaceDataArray(dm, colType); + } cdDM_update_normals_from_pbvh(dm); @@ -634,8 +651,8 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm, draw_option = drawParams(tf ? &tf[i] : NULL, (mcol != NULL), mf->mat_nr); } else { - if (index) { - orig = *index++; + if (index_mf_to_mpoly) { + orig = DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, i); if (orig == ORIGINDEX_NONE) { if (nors) nors += 3; continue; } if (drawParamsMapped) { draw_option = drawParamsMapped(userData, orig); } else { if (nors) nors += 3; continue; } @@ -697,42 +714,11 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm, } } else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */ - MCol *col = realcol; - if (!col) - col = mcol; - GPU_vertex_setup(dm); GPU_normal_setup(dm); GPU_uv_setup(dm); - if (col != NULL) { -#if 0 - if (realcol && dm->drawObject->colType == CD_TEXTURE_MCOL) { - col = 0; - } - else if (mcol && dm->drawObject->colType == CD_MCOL) { - col = 0; - } - - if (col != 0) -#endif - { - unsigned char *colors = MEM_mallocN(dm->getNumTessFaces(dm) * 4 * 3 * sizeof(unsigned char), "cdDM_drawFacesTex_common"); - for (i = 0; i < dm->getNumTessFaces(dm); i++) { - for (j = 0; j < 4; j++) { - /* bgr -> rgb is intentional (and stupid), but how its stored internally */ - colors[i * 12 + j * 3] = col[i * 4 + j].b; - colors[i * 12 + j * 3 + 1] = col[i * 4 + j].g; - colors[i * 12 + j * 3 + 2] = col[i * 4 + j].r; - } - } - GPU_color3_upload(dm, colors); - MEM_freeN(colors); - if (realcol) - dm->drawObject->colType = CD_TEXTURE_MCOL; - else if (mcol) - dm->drawObject->colType = CD_MCOL; - } - GPU_color_setup(dm); + if (mcol) { + GPU_color_setup(dm, colType); } if (!GPU_buffer_legacy(dm)) { @@ -753,15 +739,18 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm, draw_option = drawParams(tf ? &tf[actualFace] : NULL, (mcol != NULL), mf[actualFace].mat_nr); } else { - if (index) { - orig = index[actualFace]; - if (orig == ORIGINDEX_NONE) continue; - if (drawParamsMapped) + if (index_mf_to_mpoly) { + orig = DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, actualFace); + if (orig == ORIGINDEX_NONE) { + continue; + } + if (drawParamsMapped) { draw_option = drawParamsMapped(userData, orig); + } } - else - if (drawParamsMapped) + else if (drawParamsMapped) { draw_option = drawParamsMapped(userData, actualFace); + } } /* flush buffer if current triangle isn't drawable or it's last triangle */ @@ -779,7 +768,7 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm, int count = (i - startFace + (draw_option != DM_DRAW_OPTION_SKIP ? 1 : 0)) * 3; if (count) { - if (col) + if (mcol && draw_option != DM_DRAW_OPTION_NO_MCOL) GPU_color_switch(1); else GPU_color_switch(0); @@ -814,16 +803,32 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm, CDDerivedMesh *cddm = (CDDerivedMesh *) dm; MVert *mv = cddm->mvert; MFace *mf = cddm->mface; - MCol *mc; + MCol *mcol; float *nors = DM_get_tessface_data_layer(dm, CD_NORMAL); - int useColors = flag & DM_DRAW_USE_COLORS; - int i, orig, *index = DM_get_tessface_data_layer(dm, CD_ORIGINDEX); + int colType, useColors = flag & DM_DRAW_USE_COLORS; + int i, orig; + + + /* double lookup */ + const int *index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX); + const int *index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX); + if ((index_mf_to_mpoly && index_mp_to_orig) == FALSE) { + index_mf_to_mpoly = index_mp_to_orig = NULL; + } - mc = DM_get_tessface_data_layer(dm, CD_ID_MCOL); - if (!mc) - mc = DM_get_tessface_data_layer(dm, CD_PREVIEW_MCOL); - if (!mc) - mc = DM_get_tessface_data_layer(dm, CD_MCOL); + + colType = CD_ID_MCOL; + mcol = DM_get_tessface_data_layer(dm, colType); + if (!mcol) { + colType = CD_PREVIEW_MCOL; + mcol = DM_get_tessface_data_layer(dm, colType); + } + if (!mcol) { + colType = CD_MCOL; + mcol = DM_get_tessface_data_layer(dm, colType); + } + + printf("%s: %p(%d/%d)\n", __func__, mcol, CD_ID_MCOL, colType); cdDM_update_normals_from_pbvh(dm); @@ -835,7 +840,7 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm, int drawSmooth = (flag & DM_DRAW_ALWAYS_SMOOTH) ? 1 : (mf->flag & ME_SMOOTH); DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL; - orig = (index == NULL) ? i : *index++; + orig = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, i) : i; if (orig == ORIGINDEX_NONE) draw_option = setMaterial(mf->mat_nr + 1, NULL); @@ -845,8 +850,8 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm, if (draw_option != DM_DRAW_OPTION_SKIP) { unsigned char *cp = NULL; - if (useColors && mc) - cp = (unsigned char *)&mc[i * 4]; + if (useColors && mcol) + cp = (unsigned char *)&mcol[i * 4]; /* no need to set shading mode to flat because * normals are already used to change shading */ @@ -906,8 +911,9 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm, int prevstart = 0; GPU_vertex_setup(dm); GPU_normal_setup(dm); - if (useColors && mc) - GPU_color_setup(dm); + if (useColors && mcol) { + GPU_color_setup(dm, colType); + } if (!GPU_buffer_legacy(dm)) { int tottri = dm->drawObject->tot_triangle_point / 3; glShadeModel(GL_SMOOTH); @@ -934,7 +940,7 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm, if (i != tottri - 1) next_actualFace = dm->drawObject->triangle_to_mface[i + 1]; - orig = (index == NULL) ? actualFace : index[actualFace]; + orig = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, actualFace) : actualFace; if (orig == ORIGINDEX_NONE) draw_option = setMaterial(mface->mat_nr + 1, NULL); @@ -1039,7 +1045,14 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, /* MTFace *tf = dm->getTessFaceDataArray(dm, CD_MTFACE); */ /* UNUSED */ float (*nors)[3] = dm->getTessFaceDataArray(dm, CD_NORMAL); int a, b, do_draw, matnr, new_matnr; - int orig, *index = dm->getTessFaceDataArray(dm, CD_ORIGINDEX); + int orig; + + /* double lookup */ + const int *index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX); + const int *index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX); + if ((index_mf_to_mpoly && index_mp_to_orig) == FALSE) { + index_mf_to_mpoly = index_mp_to_orig = NULL; + } cdDM_update_normals_from_pbvh(dm); @@ -1072,7 +1085,7 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, continue; } else if (setDrawOptions) { - orig = (index) ? index[a] : a; + orig = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, a) : a; if (orig == ORIGINDEX_NONE) { /* since the material is set by setMaterial(), faces with no @@ -1176,13 +1189,13 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, datatypes[numdata].size = 2; datatypes[numdata].type = GL_FLOAT; numdata++; - } + } for (b = 0; b < attribs.totmcol; b++) { datatypes[numdata].index = attribs.mcol[b].gl_index; datatypes[numdata].size = 4; datatypes[numdata].type = GL_UNSIGNED_BYTE; numdata++; - } + } if (attribs.tottang) { datatypes[numdata].index = attribs.tang.gl_index; datatypes[numdata].size = 4; @@ -1242,7 +1255,7 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a; copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset + elementsize * 2], (char *)col); offset += sizeof(unsigned char) * 4; - } + } if (attribs.tottang) { float *tang = attribs.tang.array[a * 4 + 0]; copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset], tang); @@ -1283,7 +1296,7 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a; copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset + elementsize * 2], (char *)col); offset += sizeof(unsigned char) * 4; - } + } if (attribs.tottang) { float *tang = attribs.tang.array[a * 4 + 2]; copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset], tang); @@ -1333,7 +1346,14 @@ static void cdDM_drawMappedFacesMat(DerivedMesh *dm, MFace *mf = cddm->mface; float (*nors)[3] = dm->getTessFaceDataArray(dm, CD_NORMAL); int a, matnr, new_matnr; - int orig, *index = dm->getTessFaceDataArray(dm, CD_ORIGINDEX); + int orig; + + /* double lookup */ + const int *index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX); + const int *index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX); + if ((index_mf_to_mpoly && index_mp_to_orig) == FALSE) { + index_mf_to_mpoly = index_mp_to_orig = NULL; + } cdDM_update_normals_from_pbvh(dm); @@ -1362,7 +1382,7 @@ static void cdDM_drawMappedFacesMat(DerivedMesh *dm, /* skipping faces */ if (setFace) { - orig = (index) ? index[a] : a; + orig = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, a) : a; if (orig != ORIGINDEX_NONE && !setFace(userData, orig)) continue; @@ -1525,11 +1545,6 @@ void CDDM_recalc_tessellation_ex(DerivedMesh *dm, const int do_face_nor_cpy) dm->numTessFaceData, dm->numLoopData, dm->numPolyData, do_face_nor_cpy); - if (!CustomData_get_layer(&dm->faceData, CD_ORIGINDEX)) { - int *polyIndex = CustomData_get_layer(&dm->faceData, CD_POLYINDEX); - CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_REFERENCE, polyIndex, dm->numTessFaceData); - } - cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE); /* Tessellation recreated faceData, and the active layer indices need to get re-propagated @@ -1641,7 +1656,6 @@ DerivedMesh *CDDM_new(int numVerts, int numEdges, int numTessFaces, int numLoops CustomData_add_layer(&dm->vertData, CD_ORIGINDEX, CD_CALLOC, NULL, numVerts); CustomData_add_layer(&dm->edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges); CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_CALLOC, NULL, numTessFaces); - CustomData_add_layer(&dm->faceData, CD_POLYINDEX, CD_CALLOC, NULL, numTessFaces); CustomData_add_layer(&dm->polyData, CD_ORIGINDEX, CD_CALLOC, NULL, numPolys); CustomData_add_layer(&dm->vertData, CD_MVERT, CD_CALLOC, NULL, numVerts); @@ -1665,7 +1679,6 @@ DerivedMesh *CDDM_from_mesh(Mesh *mesh, Object *UNUSED(ob)) DerivedMesh *dm = &cddm->dm; CustomDataMask mask = CD_MASK_MESH & (~CD_MASK_MDISPS); int alloctype; - int *polyindex = NULL; /* this does a referenced copy, with an exception for fluidsim */ @@ -1680,7 +1693,7 @@ DerivedMesh *CDDM_from_mesh(Mesh *mesh, Object *UNUSED(ob)) mesh->totvert); CustomData_merge(&mesh->edata, &dm->edgeData, mask, alloctype, mesh->totedge); - CustomData_merge(&mesh->fdata, &dm->faceData, mask | CD_MASK_POLYINDEX, alloctype, + CustomData_merge(&mesh->fdata, &dm->faceData, mask | CD_MASK_ORIGINDEX, alloctype, mesh->totface); CustomData_merge(&mesh->ldata, &dm->loopData, mask, alloctype, mesh->totloop); @@ -1693,17 +1706,12 @@ DerivedMesh *CDDM_from_mesh(Mesh *mesh, Object *UNUSED(ob)) cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY); cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE); - /* commented since even when CD_POLYINDEX was first added this line fails + /* commented since even when CD_ORIGINDEX was first added this line fails * on the default cube, (after editmode toggle too) - campbell */ #if 0 - BLI_assert(CustomData_has_layer(&cddm->dm.faceData, CD_POLYINDEX)); + BLI_assert(CustomData_has_layer(&cddm->dm.faceData, CD_ORIGINDEX)); #endif - polyindex = CustomData_get_layer(&dm->faceData, CD_POLYINDEX); - if (!CustomData_has_layer(&cddm->dm.faceData, CD_ORIGINDEX)) { - CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_REFERENCE, polyindex, mesh->totface); - } - return dm; } @@ -1789,10 +1797,10 @@ DerivedMesh *CDDM_from_curve_displist(Object *ob, ListBase *dispbase, int **orco } static void loops_to_customdata_corners(BMesh *bm, CustomData *facedata, - int cdindex, BMLoop *l3[3], + int cdindex, const BMLoop *l3[3], int numCol, int numTex) { - BMLoop *l; + const BMLoop *l; BMFace *f = l3[0]->f; MTFace *texface; MTexPoly *texpoly; @@ -1835,13 +1843,16 @@ static void loops_to_customdata_corners(BMesh *bm, CustomData *facedata, } } -DerivedMesh *CDDM_from_BMEditMesh(BMEditMesh *em, Mesh *UNUSED(me), int use_mdisps, int use_tessface) +/* used for both editbmesh and bmesh */ +static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, int use_mdisps, + /* EditBMesh vars for use_tessface */ + int use_tessface, + const int em_tottri, const BMLoop *(*em_looptris)[3] + ) { - BMesh *bm = em->bm; - DerivedMesh *dm = CDDM_new(bm->totvert, bm->totedge, - use_tessface ? em->tottri : 0, + use_tessface ? em_tottri : 0, bm->totloop, bm->totface); @@ -1887,7 +1898,7 @@ DerivedMesh *CDDM_from_BMEditMesh(BMEditMesh *em, Mesh *UNUSED(me), int use_mdis /* add tessellation mface layers */ if (use_tessface) { - CustomData_from_bmeshpoly(&dm->faceData, &dm->polyData, &dm->loopData, em->tottri); + CustomData_from_bmeshpoly(&dm->faceData, &dm->polyData, &dm->loopData, em_tottri); } index = dm->getVertDataArray(dm, CD_ORIGINDEX); @@ -1949,11 +1960,10 @@ DerivedMesh *CDDM_from_BMEditMesh(BMEditMesh *em, Mesh *UNUSED(me), int use_mdis BM_mesh_elem_index_ensure(bm, BM_FACE); - polyindex = dm->getTessFaceDataArray(dm, CD_POLYINDEX); index = dm->getTessFaceDataArray(dm, CD_ORIGINDEX); for (i = 0; i < dm->numTessFaceData; i++, index++, polyindex++) { MFace *mf = &mface[i]; - BMLoop **l = em->looptris[i]; + const BMLoop **l = em_looptris[i]; efa = l[0]->f; mf->v1 = BM_elem_index_get(l[0]->v); @@ -1963,8 +1973,8 @@ DerivedMesh *CDDM_from_BMEditMesh(BMEditMesh *em, Mesh *UNUSED(me), int use_mdis mf->mat_nr = efa->mat_nr; mf->flag = BM_face_flag_to_mflag(efa); - *index = add_orig ? BM_elem_index_get(efa) : *(int *)CustomData_bmesh_get(&bm->pdata, efa->head.data, CD_ORIGINDEX); - *polyindex = BM_elem_index_get(efa); + /* map mfaces to polygons in the same cddm intentionally */ + *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); @@ -2003,6 +2013,20 @@ DerivedMesh *CDDM_from_BMEditMesh(BMEditMesh *em, Mesh *UNUSED(me), int use_mdis return dm; } +struct DerivedMesh *CDDM_from_bmesh(struct BMesh *bm, int use_mdisps) +{ + return cddm_from_bmesh_ex(bm, use_mdisps, FALSE, + /* these vars are for editmesh only */ + 0, NULL); +} + +DerivedMesh *CDDM_from_editbmesh(BMEditMesh *em, int use_mdisps, int use_tessface) +{ + return cddm_from_bmesh_ex(em->bm, use_mdisps, + /* editmesh */ + use_tessface, em->tottri, (const BMLoop *(*)[3])em->looptris); +} + static DerivedMesh *cddm_copy_ex(DerivedMesh *source, int faces_from_tessfaces) { CDDerivedMesh *cddm = cdDM_create("CDDM_copy cddm"); @@ -2017,6 +2041,7 @@ static DerivedMesh *cddm_copy_ex(DerivedMesh *source, int faces_from_tessfaces) source->getVertDataArray(source, CD_ORIGINDEX); source->getEdgeDataArray(source, CD_ORIGINDEX); source->getTessFaceDataArray(source, CD_ORIGINDEX); + source->getPolyDataArray(source, CD_ORIGINDEX); /* this initializes dm, and copies all non mvert/medge/mface layers */ DM_from_template(dm, source, DM_TYPE_CDDM, numVerts, numEdges, numTessFaces, @@ -2071,6 +2096,7 @@ DerivedMesh *CDDM_from_template(DerivedMesh *source, source->getVertDataArray(source, CD_ORIGINDEX); source->getEdgeDataArray(source, CD_ORIGINDEX); source->getTessFaceDataArray(source, CD_ORIGINDEX); + source->getPolyDataArray(source, CD_ORIGINDEX); /* this does a copy of all non mvert/medge/mface layers */ DM_from_template(dm, source, DM_TYPE_CDDM, numVerts, numEdges, numTessFaces, numLoops, numPolys); @@ -2088,8 +2114,6 @@ DerivedMesh *CDDM_from_template(DerivedMesh *source, CustomData_add_layer(&dm->edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges); if (!CustomData_get_layer(&dm->faceData, CD_ORIGINDEX)) CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_CALLOC, NULL, numTessFaces); - if (!CustomData_get_layer(&dm->faceData, CD_POLYINDEX)) - CustomData_add_layer(&dm->faceData, CD_POLYINDEX, CD_CALLOC, NULL, numTessFaces); cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT); cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE); @@ -2154,8 +2178,8 @@ void CDDM_calc_normals_mapping_ex(DerivedMesh *dm, const short only_face_normals CDDM_recalc_tessellation_ex(dm, FALSE); } else { - /* A tessellation already exists, it should always have a CD_POLYINDEX */ - BLI_assert(CustomData_has_layer(&dm->faceData, CD_POLYINDEX)); + /* A tessellation already exists, it should always have a CD_ORIGINDEX */ + BLI_assert(CustomData_has_layer(&dm->faceData, CD_ORIGINDEX)); CustomData_free_layers(&dm->faceData, CD_NORMAL, dm->numTessFaceData); } @@ -2165,7 +2189,7 @@ void CDDM_calc_normals_mapping_ex(DerivedMesh *dm, const short only_face_normals /* calculate face normals */ BKE_mesh_calc_normals_mapping_ex(cddm->mvert, dm->numVertData, CDDM_get_loops(dm), CDDM_get_polys(dm), dm->numLoopData, dm->numPolyData, NULL, cddm->mface, dm->numTessFaceData, - CustomData_get_layer(&dm->faceData, CD_POLYINDEX), face_nors, + CustomData_get_layer(&dm->faceData, CD_ORIGINDEX), face_nors, only_face_normals); CustomData_add_layer(&dm->faceData, CD_NORMAL, CD_ASSIGN, @@ -2339,7 +2363,7 @@ DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, const int *vtargetmap) BLI_array_append(oldp, i); } - /*create new cddm*/ + /*create new cddm*/ cddm2 = (CDDerivedMesh *) CDDM_from_template((DerivedMesh *)cddm, BLI_array_count(mvert), BLI_array_count(medge), 0, BLI_array_count(mloop), BLI_array_count(mpoly)); /*update edge indices and copy customdata*/ @@ -2364,7 +2388,7 @@ DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, const int *vtargetmap) CustomData_copy_data(&dm->loopData, &cddm2->dm.loopData, oldl[i], i, 1); } - /*copy vertex customdata*/ + /*copy vertex customdata*/ mv = mvert; for (i = 0; i < cddm2->dm.numVertData; i++, mv++) { CustomData_copy_data(&dm->vertData, &cddm2->dm.vertData, oldv[i], i, 1); @@ -2439,7 +2463,7 @@ void CDDM_calc_edges_tessface(DerivedMesh *dm) numEdges = BLI_edgehash_size(eh); /* write new edges into a temporary CustomData */ - memset(&edgeData, 0, sizeof(edgeData)); + CustomData_reset(&edgeData); CustomData_add_layer(&edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges); CustomData_add_layer(&edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges); @@ -2504,7 +2528,7 @@ void CDDM_calc_edges(DerivedMesh *dm) numEdges = BLI_edgehash_size(eh); /* write new edges into a temporary CustomData */ - memset(&edgeData, 0, sizeof(edgeData)); + CustomData_reset(&edgeData); CustomData_add_layer(&edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges); CustomData_add_layer(&edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges); diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 4241756a109..f1d73c7777a 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -41,8 +41,6 @@ #include "BLI_utildefines.h" #include "BLI_linklist.h" -#include "BLF_translation.h" - #include "BKE_cdderivedmesh.h" #include "BKE_cloth.h" #include "BKE_effect.h" @@ -331,7 +329,7 @@ static int do_init_cloth(Object *ob, ClothModifierData *clmd, DerivedMesh *resul cache= clmd->point_cache; /* initialize simulation data if it didn't exist already */ - if (clmd->clothObject == NULL) { + if (clmd->clothObject == NULL) { if (!cloth_from_object(ob, clmd, result, framenr, 1)) { BKE_ptcache_invalidate(cache); return 0; @@ -773,11 +771,13 @@ static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm ) else verts->goal= 0.0f; + /* Reset vertex flags */ + verts->flags &= ~CLOTH_VERT_FLAG_PINNED; + verts->flags &= ~CLOTH_VERT_FLAG_NOSELFCOLL; + dvert = dm->getVertData ( dm, i, CD_MDEFORMVERT ); if ( dvert ) { - for ( j = 0; j < dvert->totweight; j++ ) { - verts->flags &= ~CLOTH_VERT_FLAG_PINNED; if (( dvert->dw[j].def_nr == (clmd->sim_parms->vgroup_mass-1)) && (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL )) { verts->goal = dvert->dw [j].weight; @@ -789,7 +789,7 @@ static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm ) */ verts->goal = powf(verts->goal, 4.0f); - if ( verts->goal >=SOFTGOALSNAP ) + if ( verts->goal >= SOFTGOALSNAP ) verts->flags |= CLOTH_VERT_FLAG_PINNED; } @@ -804,7 +804,6 @@ static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm ) } } - verts->flags &= ~CLOTH_VERT_FLAG_NOSELFCOLL; if (clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_SELF ) { if ( dvert->dw[j].def_nr == (clmd->coll_parms->vgroup_selfcol-1)) { if (dvert->dw [j].weight > 0.0f) { @@ -823,7 +822,7 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d int i = 0; MVert *mvert = NULL; ClothVertex *verts = NULL; - float (*shapekey_rest)[3]= NULL; + float (*shapekey_rest)[3] = NULL; float tnull[3] = {0, 0, 0}; Cloth *cloth = NULL; float maxdist = 0; @@ -844,7 +843,7 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d clmd->clothObject->edgehash = NULL; } else if (!clmd->clothObject) { - modifier_setError(&(clmd->modifier), "%s", TIP_("Out of memory on allocating clmd->clothObject.")); + modifier_setError(&(clmd->modifier), "Out of memory on allocating clmd->clothObject"); return 0; } @@ -906,7 +905,7 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d if ( !cloth_build_springs ( clmd, dm ) ) { cloth_free_modifier ( clmd ); - modifier_setError(&(clmd->modifier), "%s", TIP_("Can't build springs.")); + modifier_setError(&(clmd->modifier), "Cannot build springs"); printf("cloth_free_modifier cloth_build_springs\n"); return 0; } @@ -948,7 +947,7 @@ static void cloth_from_mesh ( ClothModifierData *clmd, DerivedMesh *dm ) clmd->clothObject->verts = MEM_callocN ( sizeof ( ClothVertex ) * clmd->clothObject->numverts, "clothVertex" ); if ( clmd->clothObject->verts == NULL ) { cloth_free_modifier ( clmd ); - modifier_setError(&(clmd->modifier), "%s", TIP_("Out of memory on allocating clmd->clothObject->verts.")); + modifier_setError(&(clmd->modifier), "Out of memory on allocating clmd->clothObject->verts"); printf("cloth_free_modifier clmd->clothObject->verts\n"); return; } @@ -958,7 +957,7 @@ static void cloth_from_mesh ( ClothModifierData *clmd, DerivedMesh *dm ) clmd->clothObject->mfaces = MEM_callocN ( sizeof ( MFace ) * clmd->clothObject->numfaces, "clothMFaces" ); if ( clmd->clothObject->mfaces == NULL ) { cloth_free_modifier ( clmd ); - modifier_setError(&(clmd->modifier), "%s", TIP_("Out of memory on allocating clmd->clothObject->mfaces.")); + modifier_setError(&(clmd->modifier), "Out of memory on allocating clmd->clothObject->mfaces"); printf("cloth_free_modifier clmd->clothObject->mfaces\n"); return; } @@ -1049,29 +1048,25 @@ static void cloth_update_springs( ClothModifierData *clmd ) spring->stiffness = 0.0f; - if(spring->type == CLOTH_SPRING_TYPE_STRUCTURAL) - { + if (spring->type == CLOTH_SPRING_TYPE_STRUCTURAL) { spring->stiffness = (cloth->verts[spring->kl].struct_stiff + cloth->verts[spring->ij].struct_stiff) / 2.0f; } - else if(spring->type == CLOTH_SPRING_TYPE_SHEAR) - { + else if (spring->type == CLOTH_SPRING_TYPE_SHEAR) { spring->stiffness = (cloth->verts[spring->kl].shear_stiff + cloth->verts[spring->ij].shear_stiff) / 2.0f; } - else if(spring->type == CLOTH_SPRING_TYPE_BENDING) - { + else if (spring->type == CLOTH_SPRING_TYPE_BENDING) { spring->stiffness = (cloth->verts[spring->kl].bend_stiff + cloth->verts[spring->ij].bend_stiff) / 2.0f; } - else if(spring->type == CLOTH_SPRING_TYPE_GOAL) - { + else if (spring->type == CLOTH_SPRING_TYPE_GOAL) { /* Warning: Appending NEW goal springs does not work because implicit solver would need reset! */ /* Activate / Deactivate existing springs */ - if ((!(cloth->verts[spring->ij].flags & CLOTH_VERT_FLAG_PINNED)) && (cloth->verts[spring->ij].goal > ALMOST_ZERO)) + if ((!(cloth->verts[spring->ij].flags & CLOTH_VERT_FLAG_PINNED)) && + (cloth->verts[spring->ij].goal > ALMOST_ZERO)) { spring->flags &= ~CLOTH_SPRING_FLAG_DEACTIVATE; } - else - { + else { spring->flags |= CLOTH_SPRING_FLAG_DEACTIVATE; } } diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index af9bb971d05..b488e683947 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -161,8 +161,6 @@ void bvhtree_update_from_mvert(BVHTree * bvhtree, MFace *faces, int numfaces, MV /*********************************** Collision modifier code end ***********************************/ -#define mySWAP(a, b) do { double tmp = b ; b = a ; a = tmp ; } while (0) - // w3 is not perfect static void collision_compute_barycentric ( float pv[3], float p1[3], float p2[3], float p3[3], float *w1, float *w2, float *w3 ) @@ -200,6 +198,9 @@ static void collision_compute_barycentric ( float pv[3], float p1[3], float p2[3 w3[0] = 1.0f - w1[0] - w2[0]; } +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdouble-promotion" + DO_INLINE void collision_interpolateOnTriangle ( float to[3], float v1[3], float v2[3], float v3[3], double w1, double w2, double w3 ) { zero_v3(to); @@ -274,7 +275,7 @@ static int cloth_collision_response_static ( ClothModifierData *clmd, CollisionM /* Decrease in magnitude of relative tangential velocity due to coulomb friction * in original formula "magrelVel" should be the "change of relative velocity in normal direction" */ - magtangent = minf(clmd->coll_parms->friction * 0.01f * magrelVel, sqrtf(dot_v3v3(vrel_t_pre, vrel_t_pre))); + magtangent = min_ff(clmd->coll_parms->friction * 0.01f * magrelVel, sqrtf(dot_v3v3(vrel_t_pre, vrel_t_pre))); /* Apply friction impulse. */ if ( magtangent > ALMOST_ZERO ) { @@ -314,8 +315,8 @@ static int cloth_collision_response_static ( ClothModifierData *clmd, CollisionM /* stay on the safe side and clamp repulse */ if ( impulse > ALMOST_ZERO ) - repulse = MIN2 ( repulse, 5.0*impulse ); - repulse = MAX2 ( impulse, repulse ); + repulse = min_ff( repulse, 5.0*impulse ); + repulse = max_ff(impulse, repulse); impulse = repulse / ( 1.0f + w1*w1 + w2*w2 + w3*w3 ); /* original 2.0 / 0.25 */ VECADDMUL ( i1, collpair->normal, impulse ); @@ -333,12 +334,12 @@ static int cloth_collision_response_static ( ClothModifierData *clmd, CollisionM * We don't use dt!! */ float spf = (float)clmd->sim_parms->stepsPerFrame / clmd->sim_parms->timescale; - float d = clmd->coll_parms->epsilon*8.0f/9.0f + epsilon2*8.0f/9.0f - collpair->distance; + float d = clmd->coll_parms->epsilon*8.0f/9.0f + epsilon2*8.0f/9.0f - (float)collpair->distance; if ( d > ALMOST_ZERO) { /* stay on the safe side and clamp repulse */ float repulse = d*1.0f/spf; - float impulse = repulse / ( 3.0 * ( 1.0f + w1*w1 + w2*w2 + w3*w3 )); /* original 2.0 / 0.25 */ + float impulse = repulse / ( 3.0f * ( 1.0f + w1*w1 + w2*w2 + w3*w3 )); /* original 2.0 / 0.25 */ VECADDMUL ( i1, collpair->normal, impulse ); VECADDMUL ( i2, collpair->normal, impulse ); @@ -370,6 +371,8 @@ static int cloth_collision_response_static ( ClothModifierData *clmd, CollisionM return result; } +#pragma GCC diagnostic pop + //Determines collisions on overlap, collisions are written to collpair[i] and collision+number_collision_found is returned static CollPair* cloth_collision(ModifierData *md1, ModifierData *md2, BVHTreeOverlap *overlap, CollPair *collpair, float UNUSED(dt)) @@ -460,7 +463,8 @@ static CollPair* cloth_collision(ModifierData *md1, ModifierData *md2, distance = 2.0 * (double)( epsilon1 + epsilon2 + ALMOST_ZERO ); #endif - if (distance <= (epsilon1 + epsilon2 + ALMOST_ZERO)) { + // distance -1 means no collision result + if (distance != -1.0 && (distance <= (double)(epsilon1 + epsilon2 + ALMOST_ZERO))) { normalize_v3_v3(collpair->normal, collpair->vector); collpair->distance = distance; @@ -516,7 +520,7 @@ static void add_collision_object(Object ***objs, unsigned int *numobj, unsigned if (((modifier_type == eModifierType_Collision) && ob->pd && ob->pd->deflect) || (modifier_type != eModifierType_Collision)) cmd= (CollisionModifierData *)modifiers_findByType(ob, modifier_type); - if (cmd) { + if (cmd) { /* extend array */ if (*numobj >= *maxobj) { *maxobj *= 2; @@ -535,7 +539,7 @@ static void add_collision_object(Object ***objs, unsigned int *numobj, unsigned /* add objects */ for (go= group->gobject.first; go; go= go->next) add_collision_object(objs, numobj, maxobj, go->ob, self, level+1, modifier_type); - } + } } // return all collision objects in scene @@ -581,7 +585,7 @@ static void add_collider_cache_object(ListBase **objs, Object *ob, Object *self, if (ob->pd && ob->pd->deflect) cmd =(CollisionModifierData *)modifiers_findByType(ob, eModifierType_Collision); - if (cmd && cmd->bvhtree) { + if (cmd && cmd->bvhtree) { if (*objs == NULL) *objs = MEM_callocN(sizeof(ListBase), "ColliderCache array"); @@ -739,8 +743,7 @@ int cloth_bvh_objcollision(Object *ob, ClothModifierData * clmd, float step, flo collision_move_object ( collmd, step + dt, step ); } - do - { + do { CollPair **collisions, **collisions_index; ret2 = 0; @@ -871,7 +874,7 @@ int cloth_bvh_objcollision(Object *ob, ClothModifierData * clmd, float step, flo VECADD ( verts[i].tx, verts[i].tx, temp ); } else { - mul_v3_fl(temp, correction * -0.5); + mul_v3_fl(temp, correction * -0.5f); VECADD ( verts[j].tx, verts[j].tx, temp ); sub_v3_v3v3(verts[i].tx, verts[i].tx, temp); diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c index 19c8c2cd632..75276adf518 100644 --- a/source/blender/blenkernel/intern/colortools.c +++ b/source/blender/blenkernel/intern/colortools.c @@ -65,10 +65,10 @@ void curvemapping_set_defaults(CurveMapping *cumap, int tot, float minx, float m cumap->flag = CUMA_DO_CLIP; if (tot == 4) cumap->cur = 3; /* rhms, hack for 'col' curve? */ - clipminx = minf(minx, maxx); - clipminy = minf(miny, maxy); - clipmaxx = maxf(minx, maxx); - clipmaxy = maxf(miny, maxy); + clipminx = min_ff(minx, maxx); + clipminy = min_ff(miny, maxy); + clipmaxx = max_ff(minx, maxx); + clipmaxy = max_ff(miny, maxy); BLI_rctf_init(&cumap->curr, clipminx, clipmaxx, clipminy, clipmaxy); cumap->clipr = cumap->curr; @@ -85,7 +85,7 @@ void curvemapping_set_defaults(CurveMapping *cumap, int tot, float minx, float m cumap->cm[a].curve[0].y = miny; cumap->cm[a].curve[1].x = maxx; cumap->cm[a].curve[1].y = maxy; - } + } cumap->changed_timestamp = 0; } @@ -160,7 +160,7 @@ void curvemapping_set_black_white_ex(const float black[3], const float white[3], int a; for (a = 0; a < 3; a++) { - const float delta = maxf(white[a] - black[a], 1e-5f); + const float delta = max_ff(white[a] - black[a], 1e-5f); r_bwmul[a] = 1.0f / delta; } } @@ -182,14 +182,14 @@ void curvemapping_set_black_white(CurveMapping *cumap, const float black[3], con /* ********** NOTE: requires curvemapping_changed() call after ******** */ /* remove specified point */ -void curvemap_remove_point(CurveMap *cuma, CurveMapPoint *point) +int curvemap_remove_point(CurveMap *cuma, CurveMapPoint *point) { CurveMapPoint *cmp; int a, b, removed = 0; /* must have 2 points minimum */ if (cuma->totpoint <= 2) - return; + return FALSE; cmp = MEM_mallocN((cuma->totpoint) * sizeof(CurveMapPoint), "curve points"); @@ -205,6 +205,7 @@ void curvemap_remove_point(CurveMap *cuma, CurveMapPoint *point) MEM_freeN(cuma->curve); cuma->curve = cmp; cuma->totpoint -= removed; + return (removed != 0); } /* removes with flag set */ @@ -262,7 +263,7 @@ CurveMapPoint *curvemap_insert(CurveMap *cuma, float x, float y) return newcmp; } -void curvemap_reset(CurveMap *cuma, rctf *clipr, int preset, int slope) +void curvemap_reset(CurveMap *cuma, const rctf *clipr, int preset, int slope) { if (cuma->curve) MEM_freeN(cuma->curve); @@ -481,7 +482,7 @@ static float curvemap_calc_extend(const CurveMap *cuma, float x, const float fir } /* only creates a table for a single channel in CurveMapping */ -static void curvemap_make_table(CurveMap *cuma, rctf *clipr) +static void curvemap_make_table(CurveMap *cuma, const rctf *clipr) { CurveMapPoint *cmp = cuma->curve; BezTriple *bezt; @@ -498,8 +499,8 @@ static void curvemap_make_table(CurveMap *cuma, rctf *clipr) bezt = MEM_callocN(cuma->totpoint * sizeof(BezTriple), "beztarr"); for (a = 0; a < cuma->totpoint; a++) { - cuma->mintable = minf(cuma->mintable, cmp[a].x); - cuma->maxtable = maxf(cuma->maxtable, cmp[a].x); + cuma->mintable = min_ff(cuma->mintable, cmp[a].x); + cuma->maxtable = max_ff(cuma->maxtable, cmp[a].x); bezt[a].vec[1][0] = cmp[a].x; bezt[a].vec[1][1] = cmp[a].y; if (cmp[a].flag & CUMA_VECTOR) @@ -555,7 +556,7 @@ static void curvemap_make_table(CurveMap *cuma, rctf *clipr) sub_v3_v3v3(bezt[a].vec[2], bezt[a].vec[1], vec); } } - } + } /* make the bezier curve */ if (cuma->table) MEM_freeN(cuma->table); @@ -679,7 +680,7 @@ void curvemapping_changed(CurveMapping *cumap, int rem_doubles) CurveMap *cuma = cumap->cm + cumap->cur; CurveMapPoint *cmp = cuma->curve; rctf *clipr = &cumap->clipr; - float thresh = 0.01f * BLI_RCT_SIZE_X(clipr); + float thresh = 0.01f * BLI_rctf_size_x(clipr); float dx = 0.0f, dy = 0.0f; int a; @@ -690,13 +691,13 @@ void curvemapping_changed(CurveMapping *cumap, int rem_doubles) for (a = 0; a < cuma->totpoint; a++) { if (cmp[a].flag & CUMA_SELECT) { if (cmp[a].x < clipr->xmin) - dx = minf(dx, cmp[a].x - clipr->xmin); + dx = min_ff(dx, cmp[a].x - clipr->xmin); else if (cmp[a].x > clipr->xmax) - dx = maxf(dx, cmp[a].x - clipr->xmax); + dx = max_ff(dx, cmp[a].x - clipr->xmax); if (cmp[a].y < clipr->ymin) - dy = minf(dy, cmp[a].y - clipr->ymin); + dy = min_ff(dy, cmp[a].y - clipr->ymin); else if (cmp[a].y > clipr->ymax) - dy = maxf(dy, cmp[a].y - clipr->ymax); + dy = max_ff(dy, cmp[a].y - clipr->ymax); } } for (a = 0; a < cuma->totpoint; a++) { @@ -731,7 +732,7 @@ void curvemapping_changed(CurveMapping *cumap, int rem_doubles) } if (a != cuma->totpoint - 1) curvemap_remove(cuma, 2); - } + } curvemap_make_table(cuma, clipr); } @@ -835,64 +836,6 @@ void curvemapping_evaluate_premulRGB(const CurveMapping *cumap, unsigned char ve vecout_byte[2] = FTOCHAR(vecout[2]); } - -/* only used for image editor curves */ -void curvemapping_do_ibuf(CurveMapping *cumap, ImBuf *ibuf) -{ - ImBuf *tmpbuf; - int pixel; - float *pix_in; - float col[3]; - int stride = 4; - float *pix_out; - - if (ibuf == NULL) - return; - if (ibuf->rect_float == NULL) - IMB_float_from_rect(ibuf); - else if (ibuf->rect == NULL) - imb_addrectImBuf(ibuf); - - if (!ibuf->rect || !ibuf->rect_float) - return; - - /* work on a temp buffer, so can color manage afterwards. - * No worse off memory wise than comp nodes */ - tmpbuf = IMB_dupImBuf(ibuf); - - curvemapping_premultiply(cumap, 0); - - pix_in = ibuf->rect_float; - pix_out = tmpbuf->rect_float; - - if (ibuf->channels) - stride = ibuf->channels; - - for (pixel = ibuf->x * ibuf->y; pixel > 0; pixel--, pix_in += stride, pix_out += stride) { - if (stride < 3) { - col[0] = curvemap_evaluateF(cumap->cm, *pix_in); - - pix_out[1] = pix_out[2] = pix_out[3] = pix_out[0] = col[0]; - } - else { - curvemapping_evaluate_premulRGBF(cumap, col, pix_in); - pix_out[0] = col[0]; - pix_out[1] = col[1]; - pix_out[2] = col[2]; - if (stride > 3) - pix_out[3] = pix_in[3]; - else - pix_out[3] = 1.f; - } - } - - IMB_rect_from_float(tmpbuf); - SWAP(unsigned int *, tmpbuf->rect, ibuf->rect); - IMB_freeImBuf(tmpbuf); - - curvemapping_premultiply(cumap, 1); -} - int curvemapping_RGBA_does_something(const CurveMapping *cumap) { int a; @@ -1289,9 +1232,9 @@ void BKE_color_managed_display_settings_copy(ColorManagedDisplaySettings *new_se void BKE_color_managed_view_settings_init(ColorManagedViewSettings *settings) { /* OCIO_TODO: use default view transform here when OCIO is completely integrated - * and proper versioning stuff is added. - * for now use NONE to be compatible with all current files - */ + * and proper versioning stuff is added. + * for now use NONE to be compatible with all current files + */ BLI_strncpy(settings->view_transform, "Default", sizeof(settings->view_transform)); settings->gamma = 1.0f; diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 6b9e0921c3b..e300b5e0f19 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -221,51 +221,6 @@ void constraints_clear_evalob(bConstraintOb *cob) /* -------------- Space-Conversion API -------------- */ -#if 0 /* XXX Old code, does the same as one in armature.c, will remove it later. */ -static void constraint_pchan_diff_mat(bPoseChannel *pchan, float diff_mat[4][4]) -{ - if (pchan->parent) { - float offs_bone[4][4]; - - /* construct offs_bone the same way it is done in armature.c */ - copy_m4_m3(offs_bone, pchan->bone->bone_mat); - copy_v3_v3(offs_bone[3], pchan->bone->head); - offs_bone[3][1] += pchan->bone->parent->length; - - if (pchan->bone->flag & BONE_HINGE) { - /* pose_mat = par_pose-space_location * chan_mat */ - float tmat[4][4]; - - /* the rotation of the parent restposition */ - copy_m4_m4(tmat, pchan->bone->parent->arm_mat); - - /* the location of actual parent transform */ - copy_v3_v3(tmat[3], offs_bone[3]); - zero_v3(offs_bone[3]); - mul_m4_v3(pchan->parent->pose_mat, tmat[3]); - - mult_m4_m4m4(diff_mat, tmat, offs_bone); - } - else { - /* pose_mat = par_pose_mat * bone_mat * chan_mat */ - if (pchan->bone->flag & BONE_NO_SCALE) { - float tmat[4][4]; - copy_m4_m4(tmat, pchan->parent->pose_mat); - normalize_m4(tmat); - mult_m4_m4m4(diff_mat, tmat, offs_bone); - } - else { - mult_m4_m4m4(diff_mat, pchan->parent->pose_mat, offs_bone); - } - } - } - else { - /* pose_mat = chan_mat * arm_mat */ - copy_m4_m4(diff_mat, pchan->bone->arm_mat); - } -} -#endif - /* This function is responsible for the correct transformations/conversions * of a matrix from one space to another for constraint evaluation. * For now, this is only implemented for Objects and PoseChannels. @@ -307,18 +262,6 @@ void constraint_mat_convertspace(Object *ob, bPoseChannel *pchan, float mat[][4] else if (to == CONSTRAINT_SPACE_LOCAL) { if (pchan->bone) { BKE_armature_mat_pose_to_bone(pchan, mat, mat); -#if 0 /* XXX Old code, will remove it later. */ - constraint_pchan_diff_mat(pchan, diff_mat); - - invert_m4_m4(imat, diff_mat); - mult_m4_m4m4(mat, imat, mat); - - /* override with local location */ - if ((pchan->parent) && (pchan->bone->flag & BONE_NO_LOCAL_LOCATION)) { - BKE_armature_mat_pose_to_bone_ex(ob, pchan, pchan->pose_mat, tempmat); - copy_v3_v3(mat[3], tempmat[3]); - } -#endif } } /* pose to local with parent */ @@ -336,24 +279,19 @@ void constraint_mat_convertspace(Object *ob, bPoseChannel *pchan, float mat[][4] if (pchan->bone) { /* we need the posespace_matrix = local_matrix + (parent_posespace_matrix + restpos) */ BKE_armature_mat_bone_to_pose(pchan, mat, mat); -#if 0 - constraint_pchan_diff_mat(pchan, diff_mat); - - mult_m4_m4m4(mat, diff_mat, mat); -#endif } /* use pose-space as stepping stone for other spaces */ if (ELEM(to, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_PARLOCAL)) { /* call self with slightly different values */ constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, to); - } + } } break; case CONSTRAINT_SPACE_PARLOCAL: /* -------------- FROM LOCAL WITH PARENT ---------- */ { /* local + parent to pose */ - if (pchan->bone) { + if (pchan->bone) { copy_m4_m4(diff_mat, pchan->bone->arm_mat); mult_m4_m4m4(mat, mat, diff_mat); } @@ -432,7 +370,7 @@ static void contarget_get_mesh_mat(Object *ob, const char *substring, float mat[ /* get DerivedMesh */ if (em) { /* target is in editmode, so get a special derived mesh */ - dm = CDDM_from_BMEditMesh(em, ob->data, FALSE, FALSE); + dm = CDDM_from_editbmesh(em, FALSE, FALSE); freeDM = 1; } else { @@ -604,15 +542,15 @@ static void constraint_target_to_mat4(Object *ob, const char *substring, float m float tempmat[4][4], loc[3]; /* interpolate along length of bone */ - interp_v3_v3v3(loc, pchan->pose_head, pchan->pose_tail, headtail); + interp_v3_v3v3(loc, pchan->pose_head, pchan->pose_tail, headtail); /* use interpolated distance for subtarget */ - copy_m4_m4(tempmat, pchan->pose_mat); + copy_m4_m4(tempmat, pchan->pose_mat); copy_v3_v3(tempmat[3], loc); mult_m4_m4m4(mat, ob->obmat, tempmat); } - } + } else copy_m4_m4(mat, ob->obmat); @@ -976,11 +914,11 @@ static void vectomat(const float vec[3], const float target_up[3], short axis, s else negate_v3(n); /* n specifies the transformation of the track axis */ - if (flags & TARGET_Z_UP) { + if (flags & TARGET_Z_UP) { /* target Z axis is the global up axis */ copy_v3_v3(u, target_up); } - else { + else { /* world Z axis is the global up axis */ u[0] = 0; u[1] = 0; @@ -1030,12 +968,11 @@ static void trackto_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *tar if (VALID_CONS_TARGET(ct)) { float size[3], vec[3]; float totmat[3][3]; - float tmat[4][4]; /* Get size property, since ob->size is only the object's own relative size, not its global one */ mat4_to_size(size, cob->matrix); - /* Clear the object's rotation */ + /* Clear the object's rotation */ cob->matrix[0][0] = size[0]; cob->matrix[0][1] = 0; cob->matrix[0][2] = 0; @@ -1053,9 +990,8 @@ static void trackto_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *tar vectomat(vec, ct->matrix[2], (short)data->reserved1, (short)data->reserved2, data->flags, totmat); - - copy_m4_m4(tmat, cob->matrix); - mul_m4_m3m4(cob->matrix, totmat, tmat); + + mul_m4_m3m4(cob->matrix, totmat, cob->matrix); } } @@ -1470,7 +1406,7 @@ static void sizelimit_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *U if (data->flag & LIMIT_XMIN) { if (size[0] < data->xmin) - size[0] = data->xmin; + size[0] = data->xmin; } if (data->flag & LIMIT_XMAX) { if (size[0] > data->xmax) @@ -1478,7 +1414,7 @@ static void sizelimit_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *U } if (data->flag & LIMIT_YMIN) { if (size[1] < data->ymin) - size[1] = data->ymin; + size[1] = data->ymin; } if (data->flag & LIMIT_YMAX) { if (size[1] > data->ymax) @@ -1486,7 +1422,7 @@ static void sizelimit_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *U } if (data->flag & LIMIT_ZMIN) { if (size[2] < data->zmin) - size[2] = data->zmin; + size[2] = data->zmin; } if (data->flag & LIMIT_ZMAX) { if (size[2] > data->zmax) @@ -2004,7 +1940,7 @@ static void pycon_get_tarmat(bConstraint *con, bConstraintOb *cob, bConstraintTa /* this check is to make sure curve objects get updated on file load correctly.*/ if (cu->path == NULL || cu->path->data == NULL) /* only happens on reload file, but violates depsgraph still... fix! */ - BKE_displist_make_curveTypes(cob->scene, ct->tar, 0); + BKE_displist_make_curveTypes(cob->scene, ct->tar, 0); } /* firstly calculate the matrix the normal way, then let the py-function override @@ -2281,7 +2217,6 @@ static void locktrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t float totmat[3][3]; float tmpmat[3][3]; float invmat[3][3]; - float tmat[4][4]; float mdet; /* Vector object -> target */ @@ -2509,8 +2444,6 @@ static void locktrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t totmat[1][0] = tmpmat[1][0]; totmat[1][1] = tmpmat[1][1]; totmat[1][2] = tmpmat[1][2]; totmat[2][0] = tmpmat[2][0]; totmat[2][1] = tmpmat[2][1]; totmat[2][2] = tmpmat[2][2]; - copy_m4_m4(tmat, cob->matrix); - mdet = determinant_m3(totmat[0][0], totmat[0][1], totmat[0][2], totmat[1][0], totmat[1][1], totmat[1][2], totmat[2][0], totmat[2][1], totmat[2][2]); @@ -2519,7 +2452,7 @@ static void locktrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t } /* apply out transformaton to the object */ - mul_m4_m3m4(cob->matrix, totmat, tmat); + mul_m4_m3m4(cob->matrix, totmat, cob->matrix); } } @@ -2717,7 +2650,6 @@ static void stretchto_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t if (VALID_CONS_TARGET(ct)) { float size[3], scale[3], vec[3], xx[3], zz[3], orth[3]; float totmat[3][3]; - float tmat[4][4]; float dist; /* store scaling before destroying obmat */ @@ -2770,7 +2702,7 @@ static void stretchto_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t default: /* should not happen, but in case*/ return; } /* switch (data->volmode) */ - + /* Clear the object's rotation and scale */ cob->matrix[0][0] = size[0] * scale[0]; cob->matrix[0][1] = 0; @@ -2793,10 +2725,10 @@ static void stretchto_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t /* othogonal to "new Y" "old X! plane */ cross_v3_v3v3(orth, vec, xx); normalize_v3(orth); - + /* new Z*/ copy_v3_v3(totmat[2], orth); - + /* we decided to keep X plane*/ cross_v3_v3v3(xx, orth, vec); normalize_v3_v3(totmat[0], xx); @@ -2806,18 +2738,17 @@ static void stretchto_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t /* othogonal to "new Y" "old Z! plane */ cross_v3_v3v3(orth, vec, zz); normalize_v3(orth); - + /* new X */ negate_v3_v3(totmat[0], orth); - + /* we decided to keep Z */ cross_v3_v3v3(zz, orth, vec); normalize_v3_v3(totmat[2], zz); break; } /* switch (data->plane) */ - copy_m4_m4(tmat, cob->matrix); - mul_m4_m3m4(cob->matrix, totmat, tmat); + mul_m4_m3m4(cob->matrix, totmat, cob->matrix); } } @@ -2944,7 +2875,7 @@ static void minmax_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *targ if (data->flag & MINMAX_STICKY) { if (data->flag & MINMAX_STUCK) { copy_v3_v3(obmat[3], data->cache); - } + } else { copy_v3_v3(data->cache, obmat[3]); data->flag |= MINMAX_STUCK; @@ -2954,11 +2885,11 @@ static void minmax_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *targ /* get out of localspace */ mult_m4_m4m4(tmat, ct->matrix, obmat); copy_m4_m4(cob->matrix, tmat); - } - else { + } + else { copy_v3_v3(cob->matrix[3], obmat[3]); } - } + } else { data->flag &= ~MINMAX_STUCK; } @@ -3298,7 +3229,7 @@ static void transform_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t /* extract components of owner's matrix */ copy_v3_v3(loc, cob->matrix[3]); mat4_to_eulO(eul, cob->rotOrder, cob->matrix); - mat4_to_size(size, cob->matrix); + mat4_to_size(size, cob->matrix); /* determine where in range current transforms lie */ if (data->expo) { @@ -3622,7 +3553,7 @@ static void damptrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t cross_v3_v3v3(raxis, obvec, tarvec); rangle = dot_v3v3(obvec, tarvec); - rangle = acos(maxf(-1.0f, minf(1.0f, rangle))); + rangle = acos(max_ff(-1.0f, min_ff(1.0f, rangle))); /* construct rotation matrix from the axis-angle rotation found above * - this call takes care to make sure that the axis provided is a unit vector first @@ -4061,32 +3992,36 @@ static void followtrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase copy_v3_v3(cob->matrix[3], disp); } - if (data->depth_ob && data->depth_ob->derivedFinal) { + if (data->depth_ob) { Object *depth_ob = data->depth_ob; - BVHTreeFromMesh treeData = NULL_BVHTreeFromMesh; - BVHTreeRayHit hit; - float ray_start[3], ray_end[3], ray_nor[3], imat[4][4]; - int result; + DerivedMesh *target = object_get_derived_final(depth_ob); + if (target) { + BVHTreeFromMesh treeData = NULL_BVHTreeFromMesh; + BVHTreeRayHit hit; + float ray_start[3], ray_end[3], ray_nor[3], imat[4][4]; + int result; - invert_m4_m4(imat, depth_ob->obmat); + invert_m4_m4(imat, depth_ob->obmat); - mul_v3_m4v3(ray_start, imat, camob->obmat[3]); - mul_v3_m4v3(ray_end, imat, cob->matrix[3]); + mul_v3_m4v3(ray_start, imat, camob->obmat[3]); + mul_v3_m4v3(ray_end, imat, cob->matrix[3]); - sub_v3_v3v3(ray_nor, ray_end, ray_start); + sub_v3_v3v3(ray_nor, ray_end, ray_start); - bvhtree_from_mesh_faces(&treeData, depth_ob->derivedFinal, 0.0f, 4, 6); + bvhtree_from_mesh_faces(&treeData, target, 0.0f, 4, 6); - hit.dist = FLT_MAX; - hit.index = -1; + hit.dist = FLT_MAX; + hit.index = -1; - result = BLI_bvhtree_ray_cast(treeData.tree, ray_start, ray_nor, 0.0f, &hit, treeData.raycast_callback, &treeData); + result = BLI_bvhtree_ray_cast(treeData.tree, ray_start, ray_nor, 0.0f, &hit, treeData.raycast_callback, &treeData); - if (result != -1) { - mul_v3_m4v3(cob->matrix[3], depth_ob->obmat, hit.co); - } + if (result != -1) { + mul_v3_m4v3(cob->matrix[3], depth_ob->obmat, hit.co); + } - free_bvhtree_from_mesh(&treeData); + free_bvhtree_from_mesh(&treeData); + target->release(target); + } } } } @@ -4666,7 +4601,7 @@ short proxylocked_constraints_owner(Object *ob, bPoseChannel *pchan) else { /* FIXME: constraints on object-level are not handled well yet */ return 1; - } + } } return 0; @@ -4706,7 +4641,7 @@ void get_constraint_target_matrix(struct Scene *scene, bConstraint *con, int n, unit_m4(cob->matrix); unit_m4(cob->startmat); } - } + } break; case CONSTRAINT_OBTYPE_BONE: /* this may occur in some cases */ { @@ -4842,7 +4777,7 @@ void solve_constraints(ListBase *conlist, bConstraintOb *cob, float ctime) * since some constraints may not convert the solution back to the input space before blending * but all are guaranteed to end up in good "worldspace" result */ - /* Note: all kind of stuff here before (caused trouble), much easier to just interpolate, or did I miss something? -jahka */ + /* Note: all kind of stuff here before (caused trouble), much easier to just interpolate, or did I miss something? -jahka (r.32105) */ if (enf < 1.0f) { float solution[4][4]; copy_m4_m4(solution, cob->matrix); diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c index be81c70f261..719ae7357b4 100644 --- a/source/blender/blenkernel/intern/context.c +++ b/source/blender/blenkernel/intern/context.c @@ -234,9 +234,8 @@ struct bContextDataResult { static void *ctx_wm_python_context_get(const bContext *C, const char *member, void *fall_through) { #ifdef WITH_PYTHON - bContextDataResult result; - - if (C && CTX_py_dict_get(C)) { + if (UNLIKELY(C && CTX_py_dict_get(C))) { + bContextDataResult result; memset(&result, 0, sizeof(bContextDataResult)); BPY_context_member_get((bContext *)C, member, &result); if (result.ptr.data) diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index a2f88781cbb..67aaaceaa38 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -429,6 +429,33 @@ void BKE_curve_texspace_calc(Curve *cu) } } +int BKE_nurbList_index_get_co(ListBase *nurb, const int index, float r_co[3]) +{ + Nurb *nu; + int tot = 0; + + for (nu = nurb->first; nu; nu = nu->next) { + int tot_nu; + if (nu->type == CU_BEZIER) { + tot_nu = nu->pntsu; + if (index - tot < tot_nu) { + copy_v3_v3(r_co, nu->bezt[index - tot].vec[1]); + return TRUE; + } + } + else { + tot_nu = nu->pntsu * nu->pntsv; + if (index - tot < tot_nu) { + copy_v3_v3(r_co, nu->bp[index - tot].vec); + return TRUE; + } + } + tot += tot_nu; + } + + return FALSE; +} + int BKE_nurbList_verts_count(ListBase *nurb) { Nurb *nu; @@ -793,8 +820,8 @@ static void basisNurb(float t, short order, short pnts, float *knots, float *bas /* this is for float inaccuracy */ if (t < knots[0]) t = knots[0]; - else - if (t > knots[opp2]) t = knots[opp2]; + else if (t > knots[opp2]) + t = knots[opp2]; /* this part is order '1' */ o2 = order + 1; @@ -1023,10 +1050,13 @@ void BKE_nurb_makeFaces(Nurb *nu, float *coord_array, int rowstride, int resolu, MEM_freeN(jend); } +/** + * \param coord_array Has to be 3 * 4 * pntsu * resolu in size and zero-ed + * \param tilt_array set when non-NULL + * \param radius_array set when non-NULL + */ void BKE_nurb_makeCurve(Nurb *nu, float *coord_array, float *tilt_array, float *radius_array, float *weight_array, int resolu, int stride) -/* coord_array has to be 3*4*pntsu*resolu in size and zero-ed - * tilt_array and radius_array will be written to if valid */ { BPoint *bp; float u, ustart, uend, ustep, sumdiv; @@ -1449,7 +1479,7 @@ void BKE_curve_bevel_make(Scene *scene, Object *ob, ListBase *disp, int forRende } } else if (cu->ext1 == 0.0f && cu->ext2 == 0.0f) { - ; + /* pass */ } else if (cu->ext2 == 0.0f) { dl = MEM_callocN(sizeof(DispList), "makebevelcurve2"); @@ -1918,7 +1948,7 @@ static void bevel_list_smooth(BevList *bl, int smooth_iter) if (bl->poly == -1) { /* check its not cyclic */ /* skip the first point */ - /* bevp0= bevp1; */ + /* bevp0 = bevp1; */ bevp1 = bevp2; bevp2++; nr--; @@ -1947,7 +1977,7 @@ static void bevel_list_smooth(BevList *bl, int smooth_iter) interp_qt_qtqt(bevp1->quat, bevp1->quat, q, 0.5); normalize_qt(bevp1->quat); - /* bevp0= bevp1; */ /* UNUSED */ + /* bevp0 = bevp1; */ /* UNUSED */ bevp1 = bevp2; bevp2++; } @@ -2082,7 +2112,7 @@ static void make_bevel_list_3D_tangent(BevList *bl) BevPoint *bevp2, *bevp1, *bevp0; /* standard for all make_bevel_list_3D_* funcs */ int nr; - float bevp0_tan[3], cross_tmp[3]; + float bevp0_tan[3]; bevel_list_calc_bisect(bl); if (bl->poly == -1) /* check its not cyclic */ @@ -2096,6 +2126,7 @@ static void make_bevel_list_3D_tangent(BevList *bl) nr = bl->nr; while (nr--) { + float cross_tmp[3]; cross_v3_v3v3(cross_tmp, bevp1->tan, bevp1->dir); cross_v3_v3v3(bevp1->tan, cross_tmp, bevp1->dir); normalize_v3(bevp1->tan); @@ -2123,7 +2154,7 @@ static void make_bevel_list_3D_tangent(BevList *bl) normalize_v3(cross_tmp); tri_to_quat(bevp1->quat, zero, cross_tmp, bevp1->tan); /* XXX - could be faster */ - /* bevp0= bevp1; */ /* UNUSED */ + /* bevp0 = bevp1; */ /* UNUSED */ bevp1 = bevp2; bevp2++; } @@ -2741,7 +2772,7 @@ static void calchandleNurb_intern(BezTriple *bezt, BezTriple *prev, BezTriple *n if (skip_align) { /* handles need to be updated during animation and applying stuff like hooks, - * but in such situatios it's quite difficult to distinguish in which order + * but in such situations it's quite difficult to distinguish in which order * align handles should be aligned so skip them for now */ return; } diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index 342ee5bba41..93c776ae30e 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -65,11 +65,20 @@ /* number of layers to add when growing a CustomData object */ #define CUSTOMDATA_GROW 5 +/* ensure typemap size is ok */ +BLI_STATIC_ASSERT(sizeof(((CustomData *)NULL)->typemap) / + sizeof(((CustomData *)NULL)->typemap[0]) == CD_NUMTYPES, + "size mismatch"); + + /********************* Layer type information **********************/ typedef struct LayerTypeInfo { int size; /* the memory size of one element of this layer's data */ - const char *structname; /* name of the struct used, for file writing */ - int structnum; /* number of structs per element, for file writing */ + + /** name of the struct used, for file writing */ + const char *structname; + /** number of structs per element, for file writing */ + int structnum; /** * default layer name. @@ -271,28 +280,6 @@ static void layerInterp_mdeformvert(void **sources, const float *weights, BLI_linklist_free(dest_dw, linklist_free_simple); } - -static void layerInterp_msticky(void **sources, const float *weights, - const float *UNUSED(sub_weights), int count, void *dest) -{ - float co[2], w; - MSticky *mst; - int i; - - co[0] = co[1] = 0.0f; - for (i = 0; i < count; i++) { - w = weights ? weights[i] : 1.0f; - mst = (MSticky *)sources[i]; - - madd_v2_v2fl(co, mst->co, w); - } - - /* delay writing to the destination incase dest is in sources */ - mst = (MSticky *)dest; - copy_v2_v2(mst->co, co); -} - - static void layerCopy_tface(const void *source, void *dest, int count) { const MTFace *source_tf = (const MTFace *)source; @@ -1055,8 +1042,8 @@ static void layerInterp_mvert_skin(void **sources, const float *weights, static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = { /* 0: CD_MVERT */ {sizeof(MVert), "MVert", 1, NULL, NULL, NULL, NULL, NULL, NULL}, - /* 1: CD_MSTICKY */ - {sizeof(MSticky), "MSticky", 1, NULL, NULL, NULL, layerInterp_msticky, NULL, + /* 1: CD_MSTICKY */ /* DEPRECATED */ + {sizeof(float) * 2, "", 1, NULL, NULL, NULL, NULL, NULL, NULL}, /* 2: CD_MDEFORMVERT */ {sizeof(MDeformVert), "MDeformVert", 1, NULL, layerCopy_mdeformvert, @@ -1077,8 +1064,8 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = { /* 8: CD_NORMAL */ /* 3 floats per normal vector */ {sizeof(float) * 3, "vec3f", 1, NULL, NULL, NULL, NULL, NULL, NULL}, - /* 9: CD_POLYINDEX */ - {sizeof(int), "MIntProperty", 1, NULL, NULL, NULL, NULL, NULL, NULL}, + /* 9: CD_POLYINDEX (deprecated) */ + {sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL, NULL}, /* 10: CD_PROP_FLT */ {sizeof(MFloatProperty), "MFloatProperty", 1, "Float", layerCopy_propFloat, NULL, NULL, NULL}, /* 11: CD_PROP_INT */ @@ -1098,7 +1085,7 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = { layerEqual_mloopuv, layerMultiply_mloopuv, layerInitMinMax_mloopuv, layerAdd_mloopuv, layerDoMinMax_mloopuv, layerCopyValue_mloopuv}, /* 17: CD_MLOOPCOL */ - {sizeof(MLoopCol), "MLoopCol", 1, "Col", NULL, NULL, layerInterp_mloopcol, NULL, + {sizeof(MLoopCol), "MLoopCol", 1, "Col", NULL, NULL, layerInterp_mloopcol, NULL, layerDefault_mloopcol, layerEqual_mloopcol, layerMultiply_mloopcol, layerInitMinMax_mloopcol, layerAdd_mloopcol, layerDoMinMax_mloopcol, layerCopyValue_mloopcol}, /* 18: CD_TANGENT */ @@ -1155,7 +1142,7 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = { {sizeof(GridPaintMask), "GridPaintMask", 1, NULL, layerCopy_grid_paint_mask, layerFree_grid_paint_mask, NULL, NULL, NULL}, /* 36: CD_SKIN_NODE */ - {sizeof(MVertSkin), "MVertSkin", 1, "Skin", NULL, NULL, + {sizeof(MVertSkin), "MVertSkin", 1, NULL, NULL, NULL, layerInterp_mvert_skin, NULL, layerDefault_mvert_skin} }; @@ -1196,7 +1183,7 @@ const CustomDataMask CD_MASK_DERIVEDMESH = CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_MTEXPOLY | CD_MASK_PREVIEW_MLOOPCOL | CD_MASK_PROP_STR | CD_MASK_ORIGSPACE | CD_MASK_ORIGSPACE_MLOOP | CD_MASK_ORCO | CD_MASK_TANGENT | CD_MASK_PREVIEW_MCOL | CD_MASK_NORMAL | CD_MASK_SHAPEKEY | CD_MASK_RECAST | - CD_MASK_ORIGINDEX | CD_MASK_POLYINDEX | CD_MASK_MVERT_SKIN; + CD_MASK_ORIGINDEX | CD_MASK_MVERT_SKIN; const CustomDataMask CD_MASK_BMESH = CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_MTEXPOLY | CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | @@ -1243,9 +1230,6 @@ void CustomData_update_typemap(CustomData *data) { int i, lasttype = -1; - /* since we cant do in a pre-processor do here as an assert */ - BLI_assert(sizeof(data->typemap) / sizeof(int) >= CD_NUMTYPES); - for (i = 0; i < CD_NUMTYPES; i++) { data->typemap[i] = -1; } @@ -1258,6 +1242,13 @@ void CustomData_update_typemap(CustomData *data) } } +static int customdata_typemap_is_valid(const CustomData *data) +{ + CustomData data_copy = *data; + CustomData_update_typemap(&data_copy); + return (memcmp(data->typemap, data_copy.typemap, sizeof(data->typemap)) == 0); +} + void CustomData_merge(const struct CustomData *source, struct CustomData *dest, CustomDataMask mask, int alloctype, int totelem) { @@ -1323,7 +1314,7 @@ void CustomData_merge(const struct CustomData *source, struct CustomData *dest, void CustomData_copy(const struct CustomData *source, struct CustomData *dest, CustomDataMask mask, int alloctype, int totelem) { - memset(dest, 0, sizeof(*dest)); + CustomData_reset(dest); if (source->external) dest->external = MEM_dupallocN(source->external); @@ -1354,6 +1345,12 @@ static void CustomData_external_free(CustomData *data) } } +void CustomData_reset(CustomData *data) +{ + memset(data, 0, sizeof(*data)); + fill_vn_i(data->typemap, CD_NUMTYPES, -1); +} + void CustomData_free(CustomData *data, int totelem) { int i; @@ -1365,8 +1362,7 @@ void CustomData_free(CustomData *data, int totelem) MEM_freeN(data->layers); CustomData_external_free(data); - - memset(data, 0, sizeof(*data)); + CustomData_reset(data); } static void customData_update_offsets(CustomData *data) @@ -1385,9 +1381,10 @@ static void customData_update_offsets(CustomData *data) CustomData_update_typemap(data); } -int CustomData_get_layer_index(const CustomData *data, int type) +/* to use when we're in the middle of modifying layers */ +static int CustomData_get_layer_index__notypemap(const CustomData *data, int type) { - int i; + int i; for (i = 0; i < data->totlayer; ++i) if (data->layers[i].type == type) @@ -1396,11 +1393,21 @@ int CustomData_get_layer_index(const CustomData *data, int type) return -1; } +/* -------------------------------------------------------------------- */ +/* index values to access the layers (offset from the layer start) */ + +int CustomData_get_layer_index(const CustomData *data, int type) +{ + BLI_assert(customdata_typemap_is_valid(data)); + return data->typemap[type]; +} + int CustomData_get_layer_index_n(const struct CustomData *data, int type, int n) { int i = CustomData_get_layer_index(data, type); if (i != -1) { + BLI_assert(i + n < data->totlayer); i = (data->layers[i + n].type == type) ? (i + n) : (-1); } @@ -1420,91 +1427,62 @@ int CustomData_get_named_layer_index(const CustomData *data, int type, const cha int CustomData_get_active_layer_index(const CustomData *data, int type) { - if (!data->totlayer) - return -1; - - if (data->typemap[type] != -1) { - return data->typemap[type] + data->layers[data->typemap[type]].active; - } - - return -1; + const int layer_index = data->typemap[type]; + BLI_assert(customdata_typemap_is_valid(data)); + return (layer_index != -1) ? layer_index + data->layers[layer_index].active: -1; } int CustomData_get_render_layer_index(const CustomData *data, int type) { - int i; - - for (i = 0; i < data->totlayer; ++i) - if (data->layers[i].type == type) - return i + data->layers[i].active_rnd; - - return -1; + const int layer_index = data->typemap[type]; + BLI_assert(customdata_typemap_is_valid(data)); + return (layer_index != -1) ? layer_index + data->layers[layer_index].active_rnd : -1; } int CustomData_get_clone_layer_index(const CustomData *data, int type) { - int i; - - for (i = 0; i < data->totlayer; ++i) - if (data->layers[i].type == type) - return i + data->layers[i].active_clone; - - return -1; + const int layer_index = data->typemap[type]; + BLI_assert(customdata_typemap_is_valid(data)); + return (layer_index != -1) ? layer_index + data->layers[layer_index].active_clone : -1; } int CustomData_get_stencil_layer_index(const CustomData *data, int type) { - int i; + const int layer_index = data->typemap[type]; + BLI_assert(customdata_typemap_is_valid(data)); + return (layer_index != -1) ? layer_index + data->layers[layer_index].active_mask : -1; +} - for (i = 0; i < data->totlayer; ++i) - if (data->layers[i].type == type) - return i + data->layers[i].active_mask; - return -1; -} +/* -------------------------------------------------------------------- */ +/* index values per layer type */ int CustomData_get_active_layer(const CustomData *data, int type) { - int i; - - for (i = 0; i < data->totlayer; ++i) - if (data->layers[i].type == type) - return data->layers[i].active; - - return -1; + const int layer_index = data->typemap[type]; + BLI_assert(customdata_typemap_is_valid(data)); + return (layer_index != -1) ? data->layers[layer_index].active : -1; } int CustomData_get_render_layer(const CustomData *data, int type) { - int i; - - for (i = 0; i < data->totlayer; ++i) - if (data->layers[i].type == type) - return data->layers[i].active_rnd; - - return -1; + const int layer_index = data->typemap[type]; + BLI_assert(customdata_typemap_is_valid(data)); + return (layer_index != -1) ? data->layers[layer_index].active_rnd : -1; } int CustomData_get_clone_layer(const CustomData *data, int type) { - int i; - - for (i = 0; i < data->totlayer; ++i) - if (data->layers[i].type == type) - return data->layers[i].active_clone; - - return -1; + const int layer_index = data->typemap[type]; + BLI_assert(customdata_typemap_is_valid(data)); + return (layer_index != -1) ? data->layers[layer_index].active_clone : -1; } int CustomData_get_stencil_layer(const CustomData *data, int type) { - int i; - - for (i = 0; i < data->totlayer; ++i) - if (data->layers[i].type == type) - return data->layers[i].active_mask; - - return -1; + const int layer_index = data->typemap[type]; + BLI_assert(customdata_typemap_is_valid(data)); + return (layer_index != -1) ? data->layers[layer_index].active_mask : -1; } void CustomData_set_layer_active(CustomData *data, int type, int n) @@ -1735,7 +1713,7 @@ int CustomData_free_layer(CustomData *data, int type, int totelem, int index) /* if layer was last of type in array, set new active layer */ if ((index >= data->totlayer) || (data->layers[index].type != type)) { - i = CustomData_get_layer_index(data, type); + i = CustomData_get_layer_index__notypemap(data, type); if (i >= 0) for (; i < data->totlayer && data->layers[i].type == type; i++) { @@ -1750,7 +1728,6 @@ int CustomData_free_layer(CustomData *data, int type, int totelem, int index) customData_resize(data, -CUSTOMDATA_GROW); customData_update_offsets(data); - CustomData_update_typemap(data); return 1; } @@ -2021,7 +1998,7 @@ void CustomData_interp(const CustomData *source, CustomData *dest, } /* if there are no more dest layers, we're done */ - if (dest_i >= dest->totlayer) return; + if (dest_i >= dest->totlayer) break; /* if we found a matching layer, copy the data */ if (dest->layers[dest_i].type == source->layers[src_i].type) { @@ -2380,7 +2357,9 @@ void CustomData_bmesh_free_block(CustomData *data, void **block) const LayerTypeInfo *typeInfo; int i; - if (!*block) return; + if (*block == NULL) + return; + for (i = 0; i < data->totlayer; ++i) { if (!(data->layers[i].flag & CD_FLAG_NOFREE)) { typeInfo = layerType_getInfo(data->layers[i].type); @@ -2416,7 +2395,7 @@ void CustomData_bmesh_copy_data(const CustomData *source, CustomData *dest, const LayerTypeInfo *typeInfo; int dest_i, src_i; - if (!*dest_block) { + if (*dest_block == NULL) { CustomData_bmesh_alloc_block(dest, dest_block); if (*dest_block) memset(*dest_block, 0, dest->totsize); @@ -2497,10 +2476,49 @@ int CustomData_layer_has_math(struct CustomData *data, int layer_n) if (typeInfo->equal && typeInfo->add && typeInfo->multiply && typeInfo->initminmax && typeInfo->dominmax) { - return 1; + return TRUE; } - return 0; + return FALSE; +} + +int CustomData_layer_has_interp(struct CustomData *data, int layer_n) +{ + const LayerTypeInfo *typeInfo = layerType_getInfo(data->layers[layer_n].type); + + if (typeInfo->interp) { + return TRUE; + } + + return FALSE; +} + +int CustomData_has_math(struct CustomData *data) +{ + int i; + + /* interpolates a layer at a time */ + for (i = 0; i < data->totlayer; ++i) { + if (CustomData_layer_has_math(data, i)) { + return TRUE; + } + } + + return FALSE; +} + +int CustomData_has_interp(struct CustomData *data) +{ + int i; + + /* interpolates a layer at a time */ + for (i = 0; i < data->totlayer; ++i) { + if (CustomData_layer_has_interp(data, i)) { + return TRUE; + } + } + + return FALSE; } /* copies the "value" (e.g. mloopuv uv or mloopcol colors) from one block to @@ -2600,8 +2618,8 @@ void CustomData_bmesh_set_layer_n(CustomData *data, void *block, int n, void *so memcpy(dest, source, typeInfo->size); } -void CustomData_bmesh_interp(CustomData *data, void **src_blocks, float *weights, - float *sub_weights, int count, void *dest_block) +void CustomData_bmesh_interp(CustomData *data, void **src_blocks, const float *weights, + const float *sub_weights, int count, void *dest_block) { int i, j; void *source_buf[SOURCE_BUF_SIZE]; @@ -2636,7 +2654,7 @@ void CustomData_bmesh_set_default(CustomData *data, void **block) const LayerTypeInfo *typeInfo; int i; - if (!*block) + if (*block == NULL) CustomData_bmesh_alloc_block(data, block); for (i = 0; i < data->totlayer; ++i) { @@ -2656,7 +2674,7 @@ void CustomData_to_bmesh_block(const CustomData *source, CustomData *dest, const LayerTypeInfo *typeInfo; int dest_i, src_i, src_offset; - if (!*dest_block) + if (*dest_block == NULL) CustomData_bmesh_alloc_block(dest, dest_block); /* copies a layer at a time */ @@ -2888,7 +2906,9 @@ void CustomData_external_reload(CustomData *data, ID *UNUSED(id), CustomDataMask layer = &data->layers[i]; typeInfo = layerType_getInfo(layer->type); - if (!(mask & CD_TYPE_AS_MASK(layer->type))) ; + if (!(mask & CD_TYPE_AS_MASK(layer->type))) { + /* pass */ + } else if ((layer->flag & CD_FLAG_EXTERNAL) && (layer->flag & CD_FLAG_IN_MEMORY)) { if (typeInfo->free) typeInfo->free(layer->data, totelem, typeInfo->size); @@ -2914,10 +2934,15 @@ void CustomData_external_read(CustomData *data, ID *id, CustomDataMask mask, int layer = &data->layers[i]; typeInfo = layerType_getInfo(layer->type); - if (!(mask & CD_TYPE_AS_MASK(layer->type))) ; - else if (layer->flag & CD_FLAG_IN_MEMORY) ; - else if ((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->read) + if (!(mask & CD_TYPE_AS_MASK(layer->type))) { + /* pass */ + } + else if (layer->flag & CD_FLAG_IN_MEMORY) { + /* pass */ + } + else if ((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->read) { update = 1; + } } if (!update) @@ -2935,15 +2960,23 @@ void CustomData_external_read(CustomData *data, ID *id, CustomDataMask mask, int layer = &data->layers[i]; typeInfo = layerType_getInfo(layer->type); - if (!(mask & CD_TYPE_AS_MASK(layer->type))) ; - else if (layer->flag & CD_FLAG_IN_MEMORY) ; + if (!(mask & CD_TYPE_AS_MASK(layer->type))) { + /* pass */ + } + else if (layer->flag & CD_FLAG_IN_MEMORY) { + /* pass */ + } else if ((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->read) { blay = cdf_layer_find(cdf, layer->type, layer->name); if (blay) { if (cdf_read_layer(cdf, blay)) { - if (typeInfo->read(cdf, layer->data, totelem)) ; - else break; + if (typeInfo->read(cdf, layer->data, totelem)) { + /* pass */ + } + else { + break; + } layer->flag |= CD_FLAG_IN_MEMORY; } else @@ -2974,9 +3007,12 @@ void CustomData_external_write(CustomData *data, ID *id, CustomDataMask mask, in layer = &data->layers[i]; typeInfo = layerType_getInfo(layer->type); - if (!(mask & CD_TYPE_AS_MASK(layer->type))) ; - else if ((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->write) + if (!(mask & CD_TYPE_AS_MASK(layer->type))) { + /* pass */ + } + else if ((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->write) { update = 1; + } } if (!update) @@ -3017,11 +3053,16 @@ void CustomData_external_write(CustomData *data, ID *id, CustomDataMask mask, in blay = cdf_layer_find(cdf, layer->type, layer->name); if (cdf_write_layer(cdf, blay)) { - if (typeInfo->write(cdf, layer->data, totelem)) ; - else break; + if (typeInfo->write(cdf, layer->data, totelem)) { + /* pass */ + } + else { + break; + } } - else + else { break; + } } } diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c index 4110d4565b2..7c13ca388e0 100644 --- a/source/blender/blenkernel/intern/deform.c +++ b/source/blender/blenkernel/intern/deform.c @@ -278,7 +278,7 @@ void defvert_normalize_lock_map(MDeformVert *dvert, const char *lock_flags, cons } } - lock_iweight = maxf(0.0f, 1.0f - lock_iweight); + lock_iweight = max_ff(0.0f, 1.0f - lock_iweight); if (tot_weight > 0.0f) { /* paranoid, should be 1.0 but in case of float error clamp anyway */ @@ -431,7 +431,7 @@ int *defgroup_flip_map_single(Object *ob, int *flip_map_len, int use_default, in if (strcmp(name, dg->name)) { flip_num = defgroup_name_index(ob, name); - if (flip_num >= 0) { + if (flip_num != -1) { map[defgroup] = flip_num; map[flip_num] = defgroup; } @@ -790,3 +790,23 @@ void defvert_clear(MDeformVert *dvert) dvert->totweight = 0; } + +/** + * \return The first group index shared by both deform verts + * or -1 if none are found. + */ +int defvert_find_shared(const MDeformVert *dvert_a, const MDeformVert *dvert_b) +{ + if (dvert_a->totweight && dvert_b->totweight) { + MDeformWeight *dw = dvert_a->dw; + unsigned int i; + + for (i = dvert_a->totweight; i != 0; i--, dw++) { + if (dw->weight > 0.0f && defvert_find_weight(dvert_b, dw->def_nr) > 0.0f) { + return dw->def_nr; + } + } + } + + return -1; +} diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index b8d5294eabc..950a0ca3d60 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -150,8 +150,8 @@ void queue_delete(DagNodeQueue *queue) MEM_freeN(temp); } - MEM_freeN(queue->freenodes); - MEM_freeN(queue); + MEM_freeN(queue->freenodes); + MEM_freeN(queue); } /* insert in queue, remove in front */ @@ -190,8 +190,8 @@ void push_queue(DagNodeQueue *queue, DagNode *node) } queue->freenodes->count = DAGQUEUEALLOC; - elem = queue->freenodes->first; - queue->freenodes->first = elem->next; + elem = queue->freenodes->first; + queue->freenodes->first = elem->next; } elem->next = NULL; elem->node = node; @@ -211,7 +211,7 @@ void push_stack(DagNodeQueue *queue, DagNode *node) DagNodeQueueElem *elem; int i; - elem = queue->freenodes->first; + elem = queue->freenodes->first; if (elem != NULL) { queue->freenodes->first = elem->next; if (queue->freenodes->last == elem) { @@ -235,8 +235,8 @@ void push_stack(DagNodeQueue *queue, DagNode *node) } queue->freenodes->count = DAGQUEUEALLOC; - elem = queue->freenodes->first; - queue->freenodes->first = elem->next; + elem = queue->freenodes->first; + queue->freenodes->first = elem->next; } elem->next = queue->first; elem->node = node; @@ -302,7 +302,7 @@ DagForest *dag_init(void) } /* isdata = object data... */ -// XXX this needs to be extended to be more flexible (so that not only objects are evaluated via depsgraph)... +/* XXX this needs to be extended to be more flexible (so that not only objects are evaluated via depsgraph)... */ static void dag_add_driver_relation(AnimData *adt, DagForest *dag, DagNode *node, int isdata) { FCurve *fcu; @@ -400,8 +400,7 @@ static void dag_add_material_driver_relations(DagForest *dag, DagNode *node, Mat } } -static void dag_add_collision_field_relation(DagForest *dag, Scene *scene, Object *ob, DagNode *node) -{ +static void dag_add_collision_field_relation(DagForest *dag, Scene *scene, Object *ob, DagNode *node, int skip_forcefield){ Base *base; DagNode *node2; @@ -411,7 +410,9 @@ static void dag_add_collision_field_relation(DagForest *dag, Scene *scene, Objec if ((base->lay & ob->lay) && base->object->pd) { Object *ob1 = base->object; if ((ob1->pd->deflect || ob1->pd->forcefield) && (ob1 != ob)) { - node2 = dag_get_node(dag, ob1); + if (skip_forcefield && ob1->pd->forcefield == skip_forcefield) + continue; + node2 = dag_get_node(dag, ob1); dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Field Collision"); } } @@ -443,7 +444,6 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O if (ob->type == OB_ARMATURE) { if (ob->pose) { bPoseChannel *pchan; - bConstraint *con; for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { for (con = pchan->constraints.first; con; con = con->next) { @@ -464,7 +464,7 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O if (ct->tar->type == OB_MESH) node3->customdata_mask |= CD_MASK_MDEFORMVERT; } - else if (ELEM3(con->type, CONSTRAINT_TYPE_FOLLOWPATH, CONSTRAINT_TYPE_CLAMPTO, CONSTRAINT_TYPE_SPLINEIK)) + else if (ELEM3(con->type, CONSTRAINT_TYPE_FOLLOWPATH, CONSTRAINT_TYPE_CLAMPTO, CONSTRAINT_TYPE_SPLINEIK)) dag_add_relation(dag, node3, node, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, cti->name); else dag_add_relation(dag, node3, node, DAG_RL_OB_DATA, cti->name); @@ -501,7 +501,7 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O if (ob->adt) dag_add_driver_relation(ob->adt, dag, node, (ob->type == OB_ARMATURE)); // XXX isdata arg here doesn't give an accurate picture of situation - key = ob_get_key(ob); + key = BKE_key_from_object(ob); if (key && key->adt) dag_add_driver_relation(key->adt, dag, node, 1); @@ -570,12 +570,14 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O /* softbody collision */ if ((ob->type == OB_MESH) || (ob->type == OB_CURVE) || (ob->type == OB_LATTICE)) { if (ob->particlesystem.first || - modifiers_isModifierEnabled(ob, eModifierType_Softbody) || - modifiers_isModifierEnabled(ob, eModifierType_Cloth) || - modifiers_isModifierEnabled(ob, eModifierType_Smoke) || - modifiers_isModifierEnabled(ob, eModifierType_DynamicPaint)) + modifiers_isModifierEnabled(ob, eModifierType_Softbody) || + modifiers_isModifierEnabled(ob, eModifierType_Cloth) || + modifiers_isModifierEnabled(ob, eModifierType_DynamicPaint)) { - dag_add_collision_field_relation(dag, scene, ob, node); /* TODO: use effectorweight->group */ + dag_add_collision_field_relation(dag, scene, ob, node, 0); /* TODO: use effectorweight->group */ + } + else if (modifiers_isModifierEnabled(ob, eModifierType_Smoke)) { + dag_add_collision_field_relation(dag, scene, ob, node, PFIELD_SMOKEFLOW); } } @@ -604,7 +606,7 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O if (mom != ob) { node2 = dag_get_node(dag, mom); - dag_add_relation(dag, node, node2, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Metaball"); // mom depends on children! + dag_add_relation(dag, node, node2, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Metaball"); /* mom depends on children! */ } } break; @@ -816,7 +818,7 @@ DagForest *build_dag(Main *bmain, Scene *sce, short mask) tag_main_idcode(bmain, ID_MA, FALSE); /* add base node for scene. scene is always the first node in DAG */ - scenenode = dag_add_node(dag, sce); + scenenode = dag_add_node(dag, sce); /* add current scene objects */ for (base = sce->base.first; base; base = base->next) { @@ -870,7 +872,7 @@ DagForest *build_dag(Main *bmain, Scene *sce, short mask) } /* cycle detection and solving */ - // solve_cycles(dag); + // solve_cycles(dag); return dag; } @@ -879,23 +881,23 @@ DagForest *build_dag(Main *bmain, Scene *sce, short mask) void free_forest(DagForest *Dag) { /* remove all nodes and deps */ DagNode *tempN; - DagAdjList *tempA; + DagAdjList *tempA; DagAdjList *itA; DagNode *itN = Dag->DagNode.first; while (itN) { - itA = itN->child; + itA = itN->child; while (itA) { tempA = itA; itA = itA->next; - MEM_freeN(tempA); + MEM_freeN(tempA); } - itA = itN->parent; + itA = itN->parent; while (itA) { tempA = itA; itA = itA->next; - MEM_freeN(tempA); + MEM_freeN(tempA); } tempN = itN; @@ -919,8 +921,8 @@ DagNode *dag_find_node(DagForest *forest, void *fob) return NULL; } -static int ugly_hack_sorry = 1; // prevent type check -static int dag_print_dependencies = 0; // debugging +static int ugly_hack_sorry = 1; /* prevent type check */ +static int dag_print_dependencies = 0; /* debugging */ /* no checking of existence, use dag_find_node first or dag_get_node */ DagNode *dag_add_node(DagForest *forest, void *fob) @@ -932,7 +934,7 @@ DagNode *dag_add_node(DagForest *forest, void *fob) node->ob = fob; node->color = DAG_WHITE; - if (ugly_hack_sorry) node->type = GS(((ID *) fob)->name); // sorry, done for pose sorting + if (ugly_hack_sorry) node->type = GS(((ID *) fob)->name); /* sorry, done for pose sorting */ if (forest->numNodes) { ((DagNode *) forest->DagNode.last)->next = node; forest->DagNode.last = node; @@ -1151,7 +1153,7 @@ static void dag_check_cycle(DagForest *dag) for (node = dag->DagNode.first; node; node = node->next) { while (node->parent) { itA = node->parent->next; - MEM_freeN(node->parent); + MEM_freeN(node->parent); node->parent = itA; } } @@ -1240,7 +1242,7 @@ void graph_bfs(void) itA = itA->next; } if (pos[node->BFS_dist] > node->k) { - pos[node->BFS_dist] += 1; + pos[node->BFS_dist] += 1; node->k = (float) pos[node->BFS_dist]; } else { @@ -1301,7 +1303,7 @@ int pre_and_post_source_BFS(DagForest *dag, short mask, DagNode *source, graph_a pre_func(node->ob, data); } - else { // back or cross edge + else { /* back or cross edge */ retval = 1; } itA = itA->next; @@ -1332,7 +1334,7 @@ DagNodeQueue *graph_dfs(void) /* int is_cycle = 0; */ /* UNUSED */ /* *fprintf(stderr, "starting DFS\n ------------\n"); - */ + */ nqueue = queue_create(DAGQUEUEALLOC); retqueue = queue_create(MainDag->numNodes); for (i = 0; i < 50; i++) @@ -1384,7 +1386,7 @@ DagNodeQueue *graph_dfs(void) break; } else { - if (itA->node->color == DAG_GRAY) { // back edge + if (itA->node->color == DAG_GRAY) { /* back edge */ fprintf(stderr, "dfs back edge :%15s %15s\n", ((ID *) node->ob)->name, ((ID *) itA->node->ob)->name); /* is_cycle = 1; */ /* UNUSED */ } @@ -1462,7 +1464,7 @@ int pre_and_post_source_DFS(DagForest *dag, short mask, DagNode *source, graph_a int retval = 0; /* * fprintf(stderr, "starting DFS\n ------------\n"); - */ + */ nqueue = queue_create(DAGQUEUEALLOC); /* Init @@ -1516,7 +1518,7 @@ int pre_and_post_source_DFS(DagForest *dag, short mask, DagNode *source, graph_a // } } itA = itA->next; - } + } if (!skip) { node = pop_queue(nqueue); @@ -1535,7 +1537,7 @@ int pre_and_post_source_DFS(DagForest *dag, short mask, DagNode *source, graph_a } -// used to get the obs owning a datablock +/* used to get the obs owning a datablock */ DagNodeQueue *get_obparents(struct DagForest *dag, void *ob) { DagNode *node, *node1; @@ -1546,7 +1548,7 @@ DagNodeQueue *get_obparents(struct DagForest *dag, void *ob) if (node == NULL) { return NULL; } - else if (node->ancestor_count == 1) { // simple case + else if (node->ancestor_count == 1) { /* simple case */ nqueue = queue_create(1); push_queue(nqueue, node); } @@ -1555,7 +1557,7 @@ DagNodeQueue *get_obparents(struct DagForest *dag, void *ob) node1 = dag->DagNode.first; do { - if (node1->DFS_fntm > node->DFS_fntm) { // a parent is finished after child. must check adj list + if (node1->DFS_fntm > node->DFS_fntm) { /* a parent is finished after child. must check adj list */ itA = node->child; while (itA != NULL) { if ((itA->node == node) && (itA->type == DAG_RL_DATA)) { @@ -1583,7 +1585,7 @@ DagNodeQueue *get_first_ancestors(struct DagForest *dag, void *ob) node1 = dag->DagNode.first; do { - if (node1->DFS_fntm > node->DFS_fntm) { + if (node1->DFS_fntm > node->DFS_fntm) { itA = node->child; while (itA != NULL) { if (itA->node == node) { @@ -1595,10 +1597,10 @@ DagNodeQueue *get_first_ancestors(struct DagForest *dag, void *ob) node1 = node1->next; } while (node1); - return nqueue; + return nqueue; } -// standard DFS list +/* standard DFS list */ DagNodeQueue *get_all_childs(struct DagForest *dag, void *ob) { DagNode *node; @@ -1609,7 +1611,7 @@ DagNodeQueue *get_all_childs(struct DagForest *dag, void *ob) int skip = 0; nqueue = queue_create(DAGQUEUEALLOC); - retqueue = queue_create(dag->numNodes); // was MainDag... why? (ton) + retqueue = queue_create(dag->numNodes); /* was MainDag... why? (ton) */ node = dag->DagNode.first; while (node) { @@ -1619,8 +1621,8 @@ DagNodeQueue *get_all_childs(struct DagForest *dag, void *ob) time = 1; - node = dag_find_node(dag, ob); // could be done in loop above (ton) - if (node) { // can be null for newly added objects + node = dag_find_node(dag, ob); /* could be done in loop above (ton) */ + if (node) { /* can be null for newly added objects */ node->color = DAG_GRAY; time++; @@ -1641,9 +1643,9 @@ DagNodeQueue *get_all_childs(struct DagForest *dag, void *ob) push_stack(nqueue, itA->node); skip = 1; break; - } + } itA = itA->next; - } + } if (!skip) { node = pop_queue(nqueue); @@ -1671,7 +1673,7 @@ short are_obs_related(struct DagForest *dag, void *ob1, void *ob2) while (itA != NULL) { if (itA->node->ob == ob2) { return itA->node->type; - } + } itA = itA->next; } return DAG_NO_RELATION; @@ -1699,7 +1701,7 @@ void graph_print_queue(DagNodeQueue *nqueue) queueElem = nqueue->first; while (queueElem) { fprintf(stderr, "** %s %i %i-%i ", ((ID *) queueElem->node->ob)->name, queueElem->node->color, queueElem->node->DFS_dvtm, queueElem->node->DFS_fntm); - queueElem = queueElem->next; + queueElem = queueElem->next; } fprintf(stderr, "\n"); } @@ -1719,7 +1721,7 @@ void graph_print_queue_dist(DagNodeQueue *nqueue) fputc('|', stderr); fputc('\n', stderr); count = 0; - queueElem = queueElem->next; + queueElem = queueElem->next; } fprintf(stderr, "\n"); } @@ -1857,14 +1859,14 @@ void DAG_scene_sort(Main *bmain, Scene *sce) push_stack(nqueue, itA->node); skip = 1; break; - } + } itA = itA->next; - } + } if (!skip) { if (node) { node = pop_queue(nqueue); - if (node->ob == sce) // we are done + if (node->ob == sce) /* we are done */ break; node->color = DAG_BLACK; @@ -1876,7 +1878,7 @@ void DAG_scene_sort(Main *bmain, Scene *sce) BLI_remlink(&sce->base, base); BLI_addhead(&tempbase, base); } - } + } } } @@ -2021,7 +2023,7 @@ static unsigned int flush_layer_node(Scene *sce, DagNode *node, int curtime) for (itA = node->child; itA; itA = itA->next) { if (itA->node->type == ID_OB) { if (itA->node->lasttime != curtime) { - itA->lay = flush_layer_node(sce, itA->node, curtime); // lay is only set once for each relation + itA->lay = flush_layer_node(sce, itA->node, curtime); /* lay is only set once for each relation */ } else itA->lay = itA->node->lay; @@ -2069,12 +2071,12 @@ static void dag_scene_flush_layers(Scene *sce, int lay) Base *base; int lasttime; - firstnode = sce->theDag->DagNode.first; // always scene node + firstnode = sce->theDag->DagNode.first; /* always scene node */ for (itA = firstnode->child; itA; itA = itA->next) itA->lay = 0; - sce->theDag->time++; // so we know which nodes were accessed + sce->theDag->time++; /* so we know which nodes were accessed */ lasttime = sce->theDag->time; /* update layer flags in nodes */ @@ -2146,13 +2148,13 @@ void DAG_scene_flush_update(Main *bmain, Scene *sce, unsigned int lay, const sho DAG_scene_sort(bmain, sce); } - firstnode = sce->theDag->DagNode.first; // always scene node + firstnode = sce->theDag->DagNode.first; /* always scene node */ /* first we flush the layer flags */ dag_scene_flush_layers(sce, lay); /* then we use the relationships + layer info to flush update events */ - sce->theDag->time++; // so we know which nodes were accessed + sce->theDag->time++; /* so we know which nodes were accessed */ lasttime = sce->theDag->time; for (itA = firstnode->child; itA; itA = itA->next) if (itA->node->lasttime != lasttime && itA->node->type == ID_OB) @@ -2160,7 +2162,7 @@ void DAG_scene_flush_update(Main *bmain, Scene *sce, unsigned int lay, const sho /* if update is not due to time change, do pointcache clears */ if (!time) { - sce->theDag->time++; // so we know which nodes were accessed + sce->theDag->time++; /* so we know which nodes were accessed */ lasttime = sce->theDag->time; for (itA = firstnode->child; itA; itA = itA->next) { if (itA->node->lasttime != lasttime && itA->node->type == ID_OB) { @@ -2378,7 +2380,7 @@ static void dag_object_time_update_flags(Object *ob) } } } - } + } if (ob->recalc & OB_RECALC_OB) lib_id_recalc_tag(G.main, &ob->id); @@ -2650,7 +2652,7 @@ static void dag_id_flush_update(Scene *sce, ID *id) /* set flags based on ShapeKey */ if (idtype == ID_KE) { for (obt = bmain->object.first; obt; obt = obt->id.next) { - Key *key = ob_get_key(obt); + Key *key = BKE_key_from_object(obt); if (!(ob && obt == ob) && ((ID *)key == id)) { obt->flag |= (OB_RECALC_OB | OB_RECALC_DATA); lib_id_recalc_tag(bmain, &obt->id); @@ -2928,9 +2930,9 @@ void DAG_pose_sort(Object *ob) int skip = 0; dag = dag_init(); - ugly_hack_sorry = 0; // no ID structs + ugly_hack_sorry = 0; /* no ID structs */ - rootnode = dag_add_node(dag, NULL); // node->ob becomes NULL + rootnode = dag_add_node(dag, NULL); /* node->ob becomes NULL */ /* we add the hierarchy and the constraints */ for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) { @@ -2975,7 +2977,7 @@ void DAG_pose_sort(Object *ob) dag_add_relation(dag, node2, node3, 0, "IK Constraint"); segcount++; - if (segcount == data->rootbone || segcount > 255) break; // 255 is weak + if (segcount == data->rootbone || segcount > 255) break; /* 255 is weak */ parchan = parchan->parent; } } @@ -3018,21 +3020,21 @@ void DAG_pose_sort(Object *ob) push_stack(nqueue, itA->node); skip = 1; break; - } + } itA = itA->next; - } + } if (!skip) { if (node) { node = pop_queue(nqueue); - if (node->ob == NULL) // we are done + if (node->ob == NULL) /* we are done */ break; node->color = DAG_BLACK; /* put node in new list */ BLI_remlink(&pose->chanbase, node->ob); BLI_addhead(&tempbase, node->ob); - } + } } } diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index 64959fd3aa1..e13d05d0a2f 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -299,7 +299,9 @@ static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase, i else resolu = nu->resolu; - if (!BKE_nurb_check_valid_u(nu)) ; + if (!BKE_nurb_check_valid_u(nu)) { + /* pass */ + } else if (nu->type == CU_BEZIER) { /* count */ len = 0; @@ -1384,8 +1386,8 @@ static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispba ListBase top_capbase = {NULL, NULL}; for (dlb = dlbev.first; dlb; dlb = dlb->next) { - const float bevfac1 = minf(cu->bevfac1, cu->bevfac2); - const float bevfac2 = maxf(cu->bevfac1, cu->bevfac2); + const float bevfac1 = min_ff(cu->bevfac1, cu->bevfac2); + const float bevfac2 = max_ff(cu->bevfac1, cu->bevfac2); float firstblend = 0.0f, lastblend = 0.0f; int i, start, steps; diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c index 1cb29b90133..89d728c0419 100644 --- a/source/blender/blenkernel/intern/dynamicpaint.c +++ b/source/blender/blenkernel/intern/dynamicpaint.c @@ -32,6 +32,8 @@ #include "BLI_threads.h" #include "BLI_utildefines.h" +#include "BLF_translation.h" + #include "DNA_anim_types.h" #include "DNA_armature_types.h" #include "DNA_constraint_types.h" @@ -87,6 +89,9 @@ #include #endif +/* could enable at some point but for now there are far too many conversions */ +#pragma GCC diagnostic ignored "-Wdouble-promotion" + /* precalculated gaussian factors for 5x super sampling */ static float gaussianFactors[5] = {0.996849f, 0.596145f, @@ -120,8 +125,16 @@ static int neighY[8] = {0, 1, 1, 1, 0, -1, -1, -1}; /* drying limits */ #define MIN_WETNESS 0.001f #define MAX_WETNESS 5.0f -/* dissolve macro */ -#define VALUE_DISSOLVE(VALUE, TIME, SCALE, LOG) (VALUE) = (LOG) ? (VALUE) *(pow(MIN_WETNESS, 1.0f / (1.2f * ((float)(TIME)) / (SCALE)))) : (VALUE) -1.0f / (TIME)*(SCALE) + + +/* dissolve inline function */ +BLI_INLINE void value_dissolve(float *r_value, const float time, const float scale, const int is_log) +{ + *r_value = (is_log) ? + (*r_value) * (powf(MIN_WETNESS, 1.0f / (1.2f * time / scale))) : + (*r_value) - 1.0f / time * scale; +} + /***************************** Internal Structs ***************************/ @@ -569,7 +582,7 @@ static void scene_setSubframe(Scene *scene, float subframe) static int surface_getBrushFlags(DynamicPaintSurface *surface, Scene *scene) { Base *base = NULL; - GroupObject *go = NULL; + GroupObject *go = NULL; Object *brushObj = NULL; ModifierData *md = NULL; @@ -757,7 +770,7 @@ static void surfaceGenerateGrid(struct DynamicPaintSurface *surface) volume = td[0] * td[1] * td[2]; /* determine final grid size by trying to fit average 10.000 points per grid cell */ - dim_factor = (float)pow(volume / ((double)sData->total_points / 10000.0), 1.0 / (double)axis); + dim_factor = (float)pow((double)volume / ((double)sData->total_points / 10000.0), 1.0 / (double)axis); /* define final grid size using dim_factor, use min 3 for active axises */ for (i = 0; i < 3; i++) { @@ -848,7 +861,7 @@ static void surfaceGenerateGrid(struct DynamicPaintSurface *surface) grid->s_num = MEM_reallocN(grid->s_num, sizeof(int) * grid_cells); if (error || !grid->s_num) { - setError(surface->canvas, "Not enough free memory."); + setError(surface->canvas, N_("Not enough free memory")); freeGrid(sData); } } @@ -1235,7 +1248,7 @@ static void dynamicPaint_allocateSurfaceType(DynamicPaintSurface *surface) break; } - if (sData->type_data == NULL) setError(surface->canvas, "Not enough free memory!"); + if (sData->type_data == NULL) setError(surface->canvas, N_("Not enough free memory")); } static int surface_usesAdjDistance(DynamicPaintSurface *surface) @@ -1292,7 +1305,7 @@ static void dynamicPaint_initAdjacencyData(DynamicPaintSurface *surface, int for if (!ad->n_index || !ad->n_num || !ad->n_target || !temp_data) { dynamicPaint_freeAdjData(sData); if (temp_data) MEM_freeN(temp_data); - setError(surface->canvas, "Not enough free memory."); + setError(surface->canvas, N_("Not enough free memory")); return; } @@ -1762,10 +1775,10 @@ static DerivedMesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, } /* apply weights into a vertex group, if doesnt exists add a new layer */ - if (defgrp_index >= 0 && !dvert && (surface->output_name[0] != '\0')) + if (defgrp_index != -1 && !dvert && (surface->output_name[0] != '\0')) dvert = CustomData_add_layer_named(&result->vertData, CD_MDEFORMVERT, CD_CALLOC, NULL, sData->total_points, surface->output_name); - if (defgrp_index >= 0 && dvert) { + if (defgrp_index != -1 && dvert) { int i; for (i = 0; i < sData->total_points; i++) { MDeformVert *dv = &dvert[i]; @@ -1944,7 +1957,7 @@ static int dynamicPaint_findNeighbourPixel(PaintUVPoint *tempPoints, DerivedMesh { /* Note: Current method only uses polygon edges to detect neighboring pixels. * -> It doesn't always lead to the optimum pixel but is accurate enough - * and faster/simplier than including possible face tip point links) + * and faster/simpler than including possible face tip point links) */ int x, y; @@ -2165,8 +2178,10 @@ int dynamicPaint_createUVSurface(DynamicPaintSurface *surface) int *final_index; int aa_samples; - if (!dm) return setError(canvas, "Canvas mesh not updated."); - if (surface->format != MOD_DPAINT_SURFACE_F_IMAGESEQ) return setError(canvas, "Can't bake non-\"image sequence\" formats."); + if (!dm) + return setError(canvas, N_("Canvas mesh not updated")); + if (surface->format != MOD_DPAINT_SURFACE_F_IMAGESEQ) + return setError(canvas, N_("Cannot bake non-'image sequence' formats")); numOfFaces = dm->getNumTessFaces(dm); mface = dm->getTessFaceArray(dm); @@ -2176,8 +2191,10 @@ int dynamicPaint_createUVSurface(DynamicPaintSurface *surface) tface = CustomData_get_layer_named(&dm->faceData, CD_MTFACE, uvname); /* Check for validity */ - if (!tface) return setError(canvas, "No UV data on canvas."); - if (surface->image_resolution < 16 || surface->image_resolution > 8192) return setError(canvas, "Invalid resolution."); + if (!tface) + return setError(canvas, N_("No UV data on canvas")); + if (surface->image_resolution < 16 || surface->image_resolution > 8192) + return setError(canvas, N_("Invalid resolution")); w = h = surface->image_resolution; @@ -2189,7 +2206,8 @@ int dynamicPaint_createUVSurface(DynamicPaintSurface *surface) /* Init data struct */ if (surface->data) dynamicPaint_freeSurfaceData(surface); sData = surface->data = MEM_callocN(sizeof(PaintSurfaceData), "PaintSurfaceData"); - if (!surface->data) return setError(canvas, "Not enough free memory."); + if (!surface->data) + return setError(canvas, N_("Not enough free memory")); aa_samples = (surface->flags & MOD_DPAINT_ANTIALIAS) ? 5 : 1; tempPoints = (struct PaintUVPoint *) MEM_callocN(w * h * sizeof(struct PaintUVPoint), "Temp PaintUVPoint"); @@ -2547,7 +2565,8 @@ int dynamicPaint_createUVSurface(DynamicPaintSurface *surface) } } } - if (error == 1) setError(canvas, "Not enough free memory."); + if (error == 1) + setError(canvas, N_("Not enough free memory")); if (faceBB) MEM_freeN(faceBB); if (tempPoints) MEM_freeN(tempPoints); @@ -2598,7 +2617,10 @@ void dynamicPaint_outputSurfaceImage(DynamicPaintSurface *surface, char *filenam int format = (surface->image_fileformat & MOD_DPAINT_IMGFORMAT_OPENEXR) ? R_IMF_IMTYPE_OPENEXR : R_IMF_IMTYPE_PNG; char output_file[FILE_MAX]; - if (!sData->type_data) { setError(surface->canvas, "Image save failed: Invalid surface."); return; } + if (!sData->type_data) { + setError(surface->canvas, N_("Image save failed: invalid surface")); + return; + } /* if selected format is openexr, but current build doesnt support one */ #ifndef WITH_OPENEXR if (format == R_IMF_IMTYPE_OPENEXR) format = R_IMF_IMTYPE_PNG; @@ -2612,7 +2634,10 @@ void dynamicPaint_outputSurfaceImage(DynamicPaintSurface *surface, char *filenam /* Init image buffer */ ibuf = IMB_allocImBuf(surface->image_resolution, surface->image_resolution, 32, IB_rectfloat); - if (ibuf == NULL) { setError(surface->canvas, "Image save failed: Not enough free memory."); return; } + if (ibuf == NULL) { + setError(surface->canvas, N_("Image save failed: not enough free memory")); + return; + } #pragma omp parallel for schedule(static) for (index = 0; index < sData->total_points; index++) { @@ -2852,15 +2877,15 @@ static void mesh_faces_nearest_point_dp(void *userdata, int index, const float c /***************************** Brush Painting Calls ******************************/ -/* - * Mix color values to canvas point. +/** + * Mix color values to canvas point. * - * surface : canvas surface - * index : surface point index - * paintFlags : paint object flags - * paintColor,Alpha,Wetness : to be mixed paint values - * timescale : value used to adjust time dependand - * operations when using substeps + * \param surface canvas surface + * \param index surface point index + * \param paintFlags paint object flags + * \param paintColor,Alpha,Wetness to be mixed paint values + * \param timescale value used to adjust time dependent + * operations when using substeps */ static void dynamicPaint_mixPaintColors(DynamicPaintSurface *surface, int index, int paintFlags, const float paintColor[3], float *paintAlpha, float *paintWetness, float *timescale) @@ -4161,7 +4186,7 @@ static int dynamicPaint_prepareEffectStep(DynamicPaintSurface *surface, Scene *s pdEndEffectors(&effectors); } - /* Get number of required steps using averate point distance + /* Get number of required steps using average point distance * so that just a few ultra close pixels wont up substeps to max */ /* adjust number of required substep by fastest active effect */ @@ -4224,7 +4249,7 @@ static void dynamicPaint_doEffectStep(DynamicPaintSurface *surface, float *force /* Only continue if surrounding point has higher wetness */ if (ePoint->wetness < pPoint->wetness || ePoint->wetness < MIN_WETNESS) continue; - w_factor = 1.0f / numOfNeighs *MIN2(ePoint->wetness, 1.0f) * speed_scale; + w_factor = 1.0f / numOfNeighs * MIN2(ePoint->wetness, 1.0f) * speed_scale; CLAMP(w_factor, 0.0f, 1.0f); /* mix new wetness and color */ @@ -4473,7 +4498,7 @@ static void dynamicPaint_surfacePreStep(DynamicPaintSurface *surface, float time int i; float dry_ratio, f_color[4]; float p_wetness = pPoint->wetness; - VALUE_DISSOLVE(pPoint->wetness, surface->dry_speed, timescale, (surface->flags & MOD_DPAINT_DRY_LOG)); + value_dissolve(&pPoint->wetness, surface->dry_speed, timescale, (surface->flags & MOD_DPAINT_DRY_LOG)); if (pPoint->wetness < 0.0f) pPoint->wetness = 0.0f; if (pPoint->wetness < surface->color_dry_threshold) { @@ -4518,10 +4543,10 @@ static void dynamicPaint_surfacePreStep(DynamicPaintSurface *surface, float time } if (surface->flags & MOD_DPAINT_DISSOLVE) { - VALUE_DISSOLVE(pPoint->alpha, surface->diss_speed, timescale, (surface->flags & MOD_DPAINT_DISSOLVE_LOG)); + value_dissolve(&pPoint->alpha, surface->diss_speed, timescale, (surface->flags & MOD_DPAINT_DISSOLVE_LOG)); if (pPoint->alpha < 0.0f) pPoint->alpha = 0.0f; - VALUE_DISSOLVE(pPoint->e_alpha, surface->diss_speed, timescale, (surface->flags & MOD_DPAINT_DISSOLVE_LOG)); + value_dissolve(&pPoint->e_alpha, surface->diss_speed, timescale, (surface->flags & MOD_DPAINT_DISSOLVE_LOG)); if (pPoint->e_alpha < 0.0f) pPoint->e_alpha = 0.0f; } } @@ -4533,7 +4558,7 @@ static void dynamicPaint_surfacePreStep(DynamicPaintSurface *surface, float time float *point = &((float *)sData->type_data)[index]; /* log or linear */ - VALUE_DISSOLVE(*point, surface->diss_speed, timescale, (surface->flags & MOD_DPAINT_DISSOLVE_LOG)); + value_dissolve(point, surface->diss_speed, timescale, (surface->flags & MOD_DPAINT_DISSOLVE_LOG)); if (*point < 0.0f) *point = 0.0f; } } @@ -4649,7 +4674,7 @@ static int dynamicPaint_generateBakeData(DynamicPaintSurface *surface, Scene *sc if (bData->realCoord) MEM_freeN(bData->realCoord); if (canvas_verts) MEM_freeN(canvas_verts); - return setError(surface->canvas, "Not enough free memory."); + return setError(surface->canvas, N_("Not enough free memory")); } new_bdata = 1; @@ -4811,7 +4836,7 @@ static int dynamicPaint_doStep(Scene *scene, Object *ob, DynamicPaintSurface *su */ { Base *base = NULL; - GroupObject *go = NULL; + GroupObject *go = NULL; Object *brushObj = NULL; ModifierData *md = NULL; @@ -4878,7 +4903,7 @@ static int dynamicPaint_doStep(Scene *scene, Object *ob, DynamicPaintSurface *su /* Apply brush on the surface depending on it's collision type */ /* Particle brush: */ if (brush->collision == MOD_DPAINT_COL_PSYS) { - if (brush->psys && brush->psys->part && brush->psys->part->type == PART_EMITTER && + if (brush->psys && brush->psys->part && ELEM(brush->psys->part->type, PART_EMITTER, PART_FLUID) && psys_check_enabled(brushObj, brush->psys)) { @@ -4934,7 +4959,7 @@ static int dynamicPaint_doStep(Scene *scene, Object *ob, DynamicPaintSurface *su /* Allocate memory for surface previous points to read unchanged values from */ prevPoint = MEM_mallocN(sData->total_points * sizeof(struct PaintPoint), "PaintSurfaceDataCopy"); if (!prevPoint) - return setError(canvas, "Not enough free memory."); + return setError(canvas, N_("Not enough free memory")); /* Prepare effects and get number of required steps */ steps = dynamicPaint_prepareEffectStep(surface, scene, ob, &force, timescale); diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c index befec1907da..8d430eb58b5 100644 --- a/source/blender/blenkernel/intern/editderivedmesh.c +++ b/source/blender/blenkernel/intern/editderivedmesh.c @@ -152,7 +152,7 @@ static void BMEdit_RecalcTessellation_intern(BMEditMesh *tm) BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { /* don't consider two-edged faces */ - if (efa->len < 3) { + if (UNLIKELY(efa->len < 3)) { /* do nothing */ } diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c index 4f4bafd00b4..1f6db19ac27 100644 --- a/source/blender/blenkernel/intern/effect.c +++ b/source/blender/blenkernel/intern/effect.c @@ -54,6 +54,7 @@ #include "BLI_math.h" #include "BLI_blenlib.h" +#include "BLI_noise.h" #include "BLI_jitter.h" #include "BLI_rand.h" #include "BLI_utildefines.h" @@ -84,6 +85,7 @@ #include "BKE_object.h" #include "BKE_particle.h" #include "BKE_scene.h" +#include "BKE_smoke.h" #include "RE_render_ext.h" @@ -137,6 +139,9 @@ PartDeflect *object_add_collision_fields(int type) case PFIELD_TEXTURE: pd->f_size = 1.0f; break; + case PFIELD_SMOKEFLOW: + pd->f_flow = 1.0f; + break; } pd->flag = PFIELD_DO_LOCATION|PFIELD_DO_ROTATION; @@ -161,7 +166,7 @@ void free_partdeflect(PartDeflect *pd) pd->tex->id.us--; if (pd->rng) - rng_free(pd->rng); + BLI_rng_free(pd->rng); MEM_freeN(pd); } @@ -170,9 +175,9 @@ static void precalculate_effector(EffectorCache *eff) { unsigned int cfra = (unsigned int)(eff->scene->r.cfra >= 0 ? eff->scene->r.cfra : -eff->scene->r.cfra); if (!eff->pd->rng) - eff->pd->rng = rng_new(eff->pd->seed + cfra); + eff->pd->rng = BLI_rng_new(eff->pd->seed + cfra); else - rng_srandom(eff->pd->rng, eff->pd->seed + cfra); + BLI_rng_srandom(eff->pd->rng, eff->pd->seed + cfra); if (eff->pd->forcefield == PFIELD_GUIDE && eff->ob->type==OB_CURVE) { Curve *cu= eff->ob->data; @@ -200,7 +205,7 @@ static void precalculate_effector(EffectorCache *eff) float old_vel[3]; BKE_object_where_is_calc_time(eff->scene, eff->ob, cfra - 1.0f); - copy_v3_v3(old_vel, eff->ob->obmat[3]); + copy_v3_v3(old_vel, eff->ob->obmat[3]); BKE_object_where_is_calc_time(eff->scene, eff->ob, cfra); sub_v3_v3v3(eff->velocity, eff->ob->obmat[3], old_vel); } @@ -450,8 +455,8 @@ static float eff_calc_visibility(ListBase *colliders, EffectorCache *eff, Effect // noise function for wind e.g. static float wind_func(struct RNG *rng, float strength) { - int random = (rng_getInt(rng)+1) % 128; // max 2357 - float force = rng_getFloat(rng) + 1.0f; + int random = (BLI_rng_get_int(rng)+1) % 128; // max 2357 + float force = BLI_rng_get_float(rng) + 1.0f; float ret; float sign = 0; @@ -713,8 +718,8 @@ static void get_effector_tot(EffectorCache *eff, EffectorData *efd, EffectedPoin if (eff->pd->forcefield == PFIELD_CHARGE) { /* Only the charge of the effected particle is used for - * interaction, not fall-offs. If the fall-offs aren't the - * same this will be unphysical, but for animation this + * interaction, not fall-offs. If the fall-offs aren't the + * same this will be unphysical, but for animation this * could be the wanted behavior. If you want physical * correctness the fall-off should be spherical 2.0 anyways. */ @@ -823,7 +828,7 @@ static void do_physical_effector(EffectorCache *eff, EffectorData *efd, Effected { PartDeflect *pd = eff->pd; RNG *rng = pd->rng; - float force[3]={0, 0, 0}; + float force[3] = {0, 0, 0}; float temp[3]; float fac; float strength = pd->f_strength; @@ -922,12 +927,27 @@ static void do_physical_effector(EffectorCache *eff, EffectorData *efd, Effected mul_v3_fl(force, -efd->falloff * fac * (strength * fac + damp)); break; + case PFIELD_SMOKEFLOW: + zero_v3(force); + if (pd->f_source) { + float density; + if ((density = smoke_get_velocity_at(pd->f_source, point->loc, force)) >= 0.0f) { + float influence = strength * efd->falloff; + if (pd->flag & PFIELD_SMOKE_DENSITY) + influence *= density; + mul_v3_fl(force, influence); + /* apply flow */ + madd_v3_v3fl(total_force, point->vel, -pd->f_flow * influence); + } + } + break; + } if (pd->flag & PFIELD_DO_LOCATION) { madd_v3_v3fl(total_force, force, 1.0f/point->vel_to_sec); - if (ELEM(pd->forcefield, PFIELD_HARMONIC, PFIELD_DRAG)==0 && pd->f_flow != 0.0f) { + if (ELEM3(pd->forcefield, PFIELD_HARMONIC, PFIELD_DRAG, PFIELD_SMOKEFLOW)==0 && pd->f_flow != 0.0f) { madd_v3_v3fl(total_force, point->vel, -pd->f_flow * efd->falloff); } } @@ -993,12 +1013,14 @@ void pdDoEffectors(ListBase *effectors, ListBase *colliders, EffectorWeights *we if (efd.falloff > 0.0f) efd.falloff *= eff_calc_visibility(colliders, eff, &efd, point); - if (efd.falloff <= 0.0f) - ; /* don't do anything */ - else if (eff->pd->forcefield == PFIELD_TEXTURE) + if (efd.falloff <= 0.0f) { + /* don't do anything */ + } + else if (eff->pd->forcefield == PFIELD_TEXTURE) { do_texture_effector(eff, &efd, point, force); + } else { - float temp1[3]={0, 0, 0}, temp2[3]; + float temp1[3] = {0, 0, 0}, temp2[3]; copy_v3_v3(temp1, force); do_physical_effector(eff, &efd, point, force); diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c index 2dbc63e6944..ec61311d89e 100644 --- a/source/blender/blenkernel/intern/fcurve.c +++ b/source/blender/blenkernel/intern/fcurve.c @@ -504,14 +504,14 @@ short calc_fcurve_bounds(FCurve *fcu, float *xmin, float *xmax, float *ymin, flo xmaxv = MAX3(xmaxv, bezt_last->vec[1][0], bezt_last->vec[2][0]); } else { - xminv = minf(xminv, bezt_first->vec[1][0]); - xmaxv = maxf(xmaxv, bezt_last->vec[1][0]); + xminv = min_ff(xminv, bezt_first->vec[1][0]); + xmaxv = max_ff(xmaxv, bezt_last->vec[1][0]); } } } /* only loop over keyframes to find extents for values if needed */ - if (ymin || ymax) { + if (ymin || ymax) { BezTriple *bezt; for (bezt = fcu->bezt, i = 0; i < fcu->totvert; bezt++, i++) { @@ -521,8 +521,8 @@ short calc_fcurve_bounds(FCurve *fcu, float *xmin, float *xmax, float *ymin, flo ymaxv = MAX4(ymaxv, bezt->vec[1][1], bezt->vec[0][1], bezt->vec[2][1]); } else { - yminv = minf(yminv, bezt->vec[1][1]); - ymaxv = maxf(ymaxv, bezt->vec[1][1]); + yminv = min_ff(yminv, bezt->vec[1][1]); + ymaxv = max_ff(ymaxv, bezt->vec[1][1]); } foundvert = TRUE; @@ -533,8 +533,8 @@ short calc_fcurve_bounds(FCurve *fcu, float *xmin, float *xmax, float *ymin, flo else if (fcu->fpt) { /* frame range can be directly calculated from end verts */ if (xmin || xmax) { - xminv = minf(xminv, fcu->fpt[0].vec[0]); - xmaxv = maxf(xmaxv, fcu->fpt[fcu->totvert - 1].vec[0]); + xminv = min_ff(xminv, fcu->fpt[0].vec[0]); + xmaxv = max_ff(xmaxv, fcu->fpt[fcu->totvert - 1].vec[0]); } /* only loop over keyframes to find extents for values if needed */ @@ -591,15 +591,15 @@ void calc_fcurve_range(FCurve *fcu, float *start, float *end, if (bezt_first) { BLI_assert(bezt_last != NULL); - min = minf(min, bezt_first->vec[1][0]); - max = maxf(max, bezt_last->vec[1][0]); + min = min_ff(min, bezt_first->vec[1][0]); + max = max_ff(max, bezt_last->vec[1][0]); foundvert = TRUE; } } else if (fcu->fpt) { - min = minf(min, fcu->fpt[0].vec[0]); - max = maxf(max, fcu->fpt[fcu->totvert - 1].vec[0]); + min = min_ff(min, fcu->fpt[0].vec[0]); + max = max_ff(max, fcu->fpt[fcu->totvert - 1].vec[0]); foundvert = TRUE; } @@ -1039,7 +1039,7 @@ static float dtar_get_prop_val(ChannelDriver *driver, DriverTarget *dtar) if (RNA_path_resolve_full(&id_ptr, dtar->rna_path, &ptr, &prop, &index)) { if (RNA_property_array_check(prop)) { /* array */ - if (index < RNA_property_array_length(&ptr, prop)) { + if (index < RNA_property_array_length(&ptr, prop)) { switch (RNA_property_type(prop)) { case PROP_BOOLEAN: value = (float)RNA_property_boolean_get_index(&ptr, prop, index); @@ -1143,7 +1143,7 @@ static float dvar_eval_rotDiff(ChannelDriver *driver, DriverVar *dvar) /* stop here... */ return 0.0f; - } + } /* use the final posed locations */ mat4_to_quat(q1, pchan->pose_mat); @@ -1549,7 +1549,7 @@ ChannelDriver *fcurve_copy_driver(ChannelDriver *driver) for (dvar = ndriver->variables.first; dvar; dvar = dvar->next) { /* need to go over all targets so that we don't leave any dangling paths */ DRIVER_TARGETS_LOOPER(dvar) - { + { /* make a copy of target's rna path if available */ if (dtar->rna_path) dtar->rna_path = MEM_dupallocN(dtar->rna_path); @@ -1832,7 +1832,7 @@ static int findzero(float x, float q0, float q1, float q2, float q3, float *o) return 1; } - return 0; + return 0; } } @@ -1916,7 +1916,7 @@ static float fcurve_eval_keyframes(FCurve *fcu, BezTriple *bezts, float evaltime cvalue = prevbezt->vec[1][1]; } } - } + } else { /* Use the first handle (earlier) of first BezTriple to calculate the * gradient and thus the value of the curve at evaltime @@ -1968,7 +1968,7 @@ static float fcurve_eval_keyframes(FCurve *fcu, BezTriple *bezts, float evaltime cvalue = lastbezt->vec[1][1]; } } - } + } else { /* Use the gradient of the second handle (later) of last BezTriple to calculate the * gradient and thus the value of the curve at evaltime diff --git a/source/blender/blenkernel/intern/fluidsim.c b/source/blender/blenkernel/intern/fluidsim.c index 9be599ac66c..efc9869c5ca 100644 --- a/source/blender/blenkernel/intern/fluidsim.c +++ b/source/blender/blenkernel/intern/fluidsim.c @@ -41,7 +41,7 @@ #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" #include "DNA_object_fluidsim.h" -#include "DNA_object_force.h" // for pointcache +#include "DNA_object_force.h" // for pointcache #include "DNA_object_types.h" #include "DNA_particle_types.h" #include "DNA_scene_types.h" // N_T @@ -66,14 +66,14 @@ //------------------------------------------------------------------------------- void initElbeemMesh(struct Scene *scene, struct Object *ob, - int *numVertices, float **vertices, - int *numTriangles, int **triangles, - int useGlobalCoords, int modifierIndex) + int *numVertices, float **vertices, + int *numTriangles, int **triangles, + int useGlobalCoords, int modifierIndex) { DerivedMesh *dm = NULL; MVert *mvert; MFace *mface; - int countTris=0, i, totvert, totface; + int countTris = 0, i, totvert, totface; float *verts; int *tris; @@ -87,35 +87,35 @@ void initElbeemMesh(struct Scene *scene, struct Object *ob, totface = dm->getNumTessFaces(dm); *numVertices = totvert; - verts = MEM_callocN(totvert*3*sizeof(float), "elbeemmesh_vertices"); - for (i=0; iobmat, &verts[i*3]); } + verts = MEM_callocN(totvert * 3 * sizeof(float), "elbeemmesh_vertices"); + for (i = 0; i < totvert; i++) { + copy_v3_v3(&verts[i * 3], mvert[i].co); + if (useGlobalCoords) { mul_m4_v3(ob->obmat, &verts[i * 3]); } } *vertices = verts; - for (i=0; icoefficients); - } + } /* set the new data */ data->coefficients = nc; @@ -185,7 +182,7 @@ static void fcm_generator_verify(FModifier *fcm) /* free the old data */ MEM_freeN(data->coefficients); - } + } /* set the new data */ data->coefficients = nc; @@ -279,7 +276,7 @@ static FModifierTypeInfo FMI_GENERATOR = { /* Built-In Function Generator F-Curve Modifier --------------------------- */ /* This uses the general equation for equations: - * y = amplitude * fn(phase_multiplier*x + phase_offset) + y_offset + * y = amplitude * fn(phase_multiplier * x + phase_offset) + y_offset * * where amplitude, phase_multiplier/offset, y_offset are user-defined coefficients, * x is the evaluation 'time', and 'y' is the resultant value @@ -319,7 +316,7 @@ static void fcm_fn_generator_evaluate(FCurve *UNUSED(fcu), FModifier *fcm, float * WARNING: must perform special argument validation hereto guard against crashes */ switch (data->type) { - /* simple ones */ + /* simple ones */ case FCM_GENERATOR_FN_SIN: /* sine wave */ fn = sin; break; @@ -1025,7 +1022,7 @@ FModifier *add_fmodifier(ListBase *modifiers, int type) fcm->data = MEM_callocN(fmi->size, fmi->structName); /* init custom settings if necessary */ - if (fmi->new_data) + if (fmi->new_data) fmi->new_data(fcm->data); /* return modifier for further editing */ @@ -1102,7 +1099,7 @@ int remove_fmodifier(ListBase *modifiers, FModifier *fcm) if (modifiers) { BLI_freelinkN(modifiers, fcm); return 1; - } + } else { /* XXX this case can probably be removed some day, as it shouldn't happen... */ printf("remove_fmodifier() - no modifier stack given\n"); diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c index 8b35974ea62..d4634748c71 100644 --- a/source/blender/blenkernel/intern/font.c +++ b/source/blender/blenkernel/intern/font.c @@ -177,7 +177,7 @@ static VFontData *vfont_get_data(Main *bmain, VFont *vfont) } } - return vfont->data; + return vfont->data; } VFont *BKE_vfont_load(Main *bmain, const char *name) @@ -306,23 +306,23 @@ static void build_underline(Curve *cu, float x1, float y1, float x2, float y2, i nu2->bp = bp; nu2->bp[0].vec[0] = x1; - nu2->bp[0].vec[1] = y1; + nu2->bp[0].vec[1] = y1; nu2->bp[0].vec[2] = 0; nu2->bp[0].vec[3] = 1.0f; nu2->bp[1].vec[0] = x2; nu2->bp[1].vec[1] = y1; - nu2->bp[1].vec[2] = 0; + nu2->bp[1].vec[2] = 0; nu2->bp[1].vec[3] = 1.0f; nu2->bp[2].vec[0] = x2; - nu2->bp[2].vec[1] = y2; + nu2->bp[2].vec[1] = y2; nu2->bp[2].vec[2] = 0; nu2->bp[2].vec[3] = 1.0f; nu2->bp[3].vec[0] = x1; nu2->bp[3].vec[1] = y2; - nu2->bp[3].vec[2] = 0; + nu2->bp[3].vec[2] = 0; nu2->bp[3].vec[3] = 1.0f; - BLI_addtail(&(cu->nurb), nu2); + BLI_addtail(&(cu->nurb), nu2); } @@ -545,7 +545,7 @@ struct CharTrans *BKE_vfont_to_curve(Main *bmain, Scene *scene, Object *ob, int /* The VFont Data can not be found */ if (!vfd) { if (mem) - MEM_freeN(mem); + MEM_freeN(mem); return NULL; } @@ -671,7 +671,7 @@ makebreak: yof -= linedist; - maxlen = maxf(maxlen, (xof - tb->x / cu->fsize)); + maxlen = max_ff(maxlen, (xof - tb->x / cu->fsize)); linedata[lnr] = xof - tb->x / cu->fsize; linedata2[lnr] = cnr; linedata3[lnr] = tb->w / cu->fsize; @@ -731,7 +731,7 @@ makebreak: if (ascii == 32) { wsfac = cu->wordspace; wsnr++; - } + } else { wsfac = 1.0f; } @@ -754,7 +754,7 @@ makebreak: for (i = 0; i <= slen; i++, tmp++, ct++) { ascii = *tmp; if (ascii == '\n' || ascii == '\r' || ct->dobreak) cu->lines++; - } + } /* linedata is now: width of line * linedata2 is now: number of characters @@ -792,7 +792,7 @@ makebreak: // } ct++; } - } + } else if ((cu->spacemode == CU_JUSTIFY) && (cu->tb[0].w != 0.0f)) { float curofs = 0.0f; for (i = 0; i <= slen; i++) { @@ -928,8 +928,12 @@ makebreak: * 3: curs down */ ct = chartransdata + cu->pos; - if ((mode == FO_CURSUP || mode == FO_PAGEUP) && ct->linenr == 0) ; - else if ((mode == FO_CURSDOWN || mode == FO_PAGEDOWN) && ct->linenr == lnr) ; + if ((mode == FO_CURSUP || mode == FO_PAGEUP) && ct->linenr == 0) { + /* pass */ + } + else if ((mode == FO_CURSDOWN || mode == FO_PAGEDOWN) && ct->linenr == lnr) { + /* pass */ + } else { switch (mode) { case FO_CURSUP: lnr = ct->linenr - 1; break; diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c index 2ec5801746c..a7d0152a799 100644 --- a/source/blender/blenkernel/intern/gpencil.c +++ b/source/blender/blenkernel/intern/gpencil.c @@ -87,6 +87,7 @@ void free_gpencil_frames(bGPDlayer *gpl) free_gpencil_strokes(gpf); BLI_freelinkN(&gpl->frames, gpf); } + gpl->actframe = NULL; } /* Free all of the gp-layers for a viewport (list should be &gpd->layers or so) */ @@ -163,7 +164,7 @@ bGPDframe *gpencil_frame_addnew(bGPDlayer *gpl, int cframe) } /* add a new gp-layer and make it the active layer */ -bGPDlayer *gpencil_layer_addnew(bGPdata *gpd) +bGPDlayer *gpencil_layer_addnew(bGPdata *gpd, const char *name, int setactive) { bGPDlayer *gpl; @@ -182,11 +183,12 @@ bGPDlayer *gpencil_layer_addnew(bGPdata *gpd) gpl->thickness = 3; /* auto-name */ - strcpy(gpl->info, "GP_Layer"); + strcpy(gpl->info, name); BLI_uniquename(&gpd->layers, gpl, "GP_Layer", '.', offsetof(bGPDlayer, info), sizeof(gpl->info)); /* make this one the active one */ - gpencil_layer_setactive(gpd, gpl); + if (setactive) + gpencil_layer_setactive(gpd, gpl); /* return layer */ return gpl; @@ -509,15 +511,13 @@ void gpencil_layer_setactive(bGPdata *gpd, bGPDlayer *active) } /* delete the active gp-layer */ -void gpencil_layer_delactive(bGPdata *gpd) +void gpencil_layer_delete(bGPdata *gpd, bGPDlayer *gpl) { - bGPDlayer *gpl = gpencil_layer_getactive(gpd); - /* error checking */ if (ELEM(NULL, gpd, gpl)) return; - /* free layer */ + /* free layer */ free_gpencil_frames(gpl); BLI_freelinkN(&gpd->layers, gpl); } diff --git a/source/blender/blenkernel/intern/group.c b/source/blender/blenkernel/intern/group.c index 500df1b7b75..20d874e7243 100644 --- a/source/blender/blenkernel/intern/group.c +++ b/source/blender/blenkernel/intern/group.c @@ -98,7 +98,7 @@ void BKE_group_unlink(Group *group) base->object->flag &= ~OB_FROMGROUP; base->flag &= ~OB_FROMGROUP; } - } + } for (srl = sce->r.layers.first; srl; srl = srl->next) { if (srl->light_override == group) @@ -110,16 +110,6 @@ void BKE_group_unlink(Group *group) if (ob->dup_group == group) { ob->dup_group = NULL; -#if 0 /* XXX OLD ANIMSYS, NLASTRIPS ARE NO LONGER USED */ - { - bActionStrip *strip; - /* duplicator strips use a group object, we remove it */ - for (strip = ob->nlastrips.first; strip; strip = strip->next) { - if (strip->object) - strip->object = NULL; - } - } -#endif } for (psys = ob->particlesystem.first; psys; psys = psys->next) { @@ -383,57 +373,3 @@ void group_handle_recalc_and_update(Scene *scene, Object *UNUSED(parent), Group } } } - -#if 0 -Object *group_get_member_with_action(Group *group, bAction *act) -{ - GroupObject *go; - - if (group == NULL || act == NULL) return NULL; - - for (go = group->gobject.first; go; go = go->next) { - if (go->ob) { - if (go->ob->action == act) - return go->ob; - if (go->ob->nlastrips.first) { - bActionStrip *strip; - - for (strip = go->ob->nlastrips.first; strip; strip = strip->next) { - if (strip->act == act) - return go->ob; - } - } - } - } - return NULL; -} - -/* if group has NLA, we try to map the used objects in NLA to group members */ -/* this assuming that object has received a new group link */ -void group_relink_nla_objects(Object *ob) -{ - Group *group; - GroupObject *go; - bActionStrip *strip; - - if (ob == NULL || ob->dup_group == NULL) return; - group = ob->dup_group; - - for (strip = ob->nlastrips.first; strip; strip = strip->next) { - if (strip->object) { - for (go = group->gobject.first; go; go = go->next) { - if (go->ob) { - if (strcmp(go->ob->id.name, strip->object->id.name) == 0) - break; - } - } - if (go) - strip->object = go->ob; - else - strip->object = NULL; - } - - } -} - -#endif diff --git a/source/blender/blenkernel/intern/icons.c b/source/blender/blenkernel/intern/icons.c index 8a49cba7649..d8c3e260399 100644 --- a/source/blender/blenkernel/intern/icons.c +++ b/source/blender/blenkernel/intern/icons.c @@ -65,7 +65,7 @@ static void icon_free(void *val) Icon *icon = val; if (icon) { - if (icon->drawinfo_free) { + if (icon->drawinfo_free) { icon->drawinfo_free(icon->drawinfo); } else if (icon->drawinfo) { @@ -255,7 +255,7 @@ void BKE_icon_changed(int id) prv->changed_timestamp[i]++; } } - } + } } int BKE_icon_getid(struct ID *id) diff --git a/source/blender/blenkernel/intern/idprop.c b/source/blender/blenkernel/intern/idprop.c index 8229df28ab8..5dd0f08dc71 100644 --- a/source/blender/blenkernel/intern/idprop.c +++ b/source/blender/blenkernel/intern/idprop.c @@ -484,7 +484,7 @@ void IDP_ReplaceInGroup(IDProperty *group, IDProperty *prop) BLI_remlink(&group->data.group, loop); IDP_FreeProperty(loop); - MEM_freeN(loop); + MEM_freeN(loop); } else { group->len++; @@ -492,6 +492,30 @@ void IDP_ReplaceInGroup(IDProperty *group, IDProperty *prop) } } +/* + * If a property is missing in \a dest, add it. + */ +void IDP_MergeGroup(IDProperty *dest, IDProperty *src, const int do_overwrite) +{ + IDProperty *prop; + + if (do_overwrite) { + for (prop = src->data.group.first; prop; prop = prop->next) { + IDProperty *copy = IDP_CopyProperty(prop); + IDP_ReplaceInGroup(dest, copy); + } + } + else { + for (prop = src->data.group.first; prop; prop = prop->next) { + if (IDP_GetPropertyFromGroup(dest, prop->name) == NULL) { + IDProperty *copy = IDP_CopyProperty(prop); + dest->len++; + BLI_addtail(&dest->data.group, copy); + } + } + } +} + /* returns 0 if an id property with the same name exists and it failed, * or 1 if it succeeded in adding to the group.*/ int IDP_AddToGroup(IDProperty *group, IDProperty *prop) @@ -608,60 +632,77 @@ IDProperty *IDP_GetProperties(ID *id, int create_if_needed) } } -int IDP_EqualsProperties(IDProperty *prop1, IDProperty *prop2) +/** + * \param is_strict When FALSE treat missing items as a match */ +int IDP_EqualsProperties_ex(IDProperty *prop1, IDProperty *prop2, const int is_strict) { if (prop1 == NULL && prop2 == NULL) return 1; else if (prop1 == NULL || prop2 == NULL) - return 0; + return is_strict ? 0 : 1; else if (prop1->type != prop2->type) return 0; - if (prop1->type == IDP_INT) - return (IDP_Int(prop1) == IDP_Int(prop2)); - else if (prop1->type == IDP_FLOAT) - return (IDP_Float(prop1) == IDP_Float(prop2)); - else if (prop1->type == IDP_DOUBLE) - return (IDP_Double(prop1) == IDP_Double(prop2)); - else if (prop1->type == IDP_STRING) - return ((prop1->len == prop2->len) && strncmp(IDP_String(prop1), IDP_String(prop2), prop1->len) == 0); - else if (prop1->type == IDP_ARRAY) { - if (prop1->len == prop2->len && prop1->subtype == prop2->subtype) - return memcmp(IDP_Array(prop1), IDP_Array(prop2), idp_size_table[(int)prop1->subtype] * prop1->len); - else - return 0; - } - else if (prop1->type == IDP_GROUP) { - IDProperty *link1, *link2; - - if (BLI_countlist(&prop1->data.group) != BLI_countlist(&prop2->data.group)) - return 0; - - for (link1 = prop1->data.group.first; link1; link1 = link1->next) { - link2 = IDP_GetPropertyFromGroup(prop2, link1->name); - - if (!IDP_EqualsProperties(link1, link2)) + switch (prop1->type) { + case IDP_INT: + return (IDP_Int(prop1) == IDP_Int(prop2)); + case IDP_FLOAT: + return (IDP_Float(prop1) == IDP_Float(prop2)); + case IDP_DOUBLE: + return (IDP_Double(prop1) == IDP_Double(prop2)); + case IDP_STRING: + return ((prop1->len == prop2->len) && strncmp(IDP_String(prop1), IDP_String(prop2), prop1->len) == 0); + case IDP_ARRAY: + if (prop1->len == prop2->len && prop1->subtype == prop2->subtype) { + return memcmp(IDP_Array(prop1), IDP_Array(prop2), idp_size_table[(int)prop1->subtype] * prop1->len); + } + else { return 0; - } + } + case IDP_GROUP: + { + IDProperty *link1, *link2; - return 1; - } - else if (prop1->type == IDP_IDPARRAY) { - IDProperty *array1 = IDP_IDPArray(prop1); - IDProperty *array2 = IDP_IDPArray(prop2); - int i; + if (is_strict && BLI_countlist(&prop1->data.group) != BLI_countlist(&prop2->data.group)) + return 0; - if (prop1->len != prop2->len) - return 0; - - for (i = 0; i < prop1->len; i++) - if (!IDP_EqualsProperties(&array1[i], &array2[i])) + for (link1 = prop1->data.group.first; link1; link1 = link1->next) { + link2 = IDP_GetPropertyFromGroup(prop2, link1->name); + + if (!IDP_EqualsProperties_ex(link1, link2, is_strict)) + return 0; + } + + return 1; + } + case IDP_IDPARRAY: + { + IDProperty *array1 = IDP_IDPArray(prop1); + IDProperty *array2 = IDP_IDPArray(prop2); + int i; + + if (prop1->len != prop2->len) return 0; + + for (i = 0; i < prop1->len; i++) + if (!IDP_EqualsProperties(&array1[i], &array2[i])) + return 0; + return 1; + } + default: + /* should never get here */ + BLI_assert(0); + break; } - + return 1; } +int IDP_EqualsProperties(IDProperty *prop1, IDProperty *prop2) +{ + return IDP_EqualsProperties_ex(prop1, prop2, TRUE); +} + /* 'val' is never NULL, don't check */ IDProperty *IDP_New(const int type, const IDPropertyTemplate *val, const char *name) { @@ -679,7 +720,7 @@ IDProperty *IDP_New(const int type, const IDPropertyTemplate *val, const char *n case IDP_DOUBLE: prop = MEM_callocN(sizeof(IDProperty), "IDProperty float"); *(double *)&prop->data.val = val->d; - break; + break; case IDP_ARRAY: { /* for now, we only support float and int and double arrays */ diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index f08af55c36e..ef751ce3493 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -603,7 +603,8 @@ Image *BKE_image_load_exists(const char *filepath) return BKE_image_load(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]) +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) { ImBuf *ibuf; unsigned char *rect = NULL; @@ -612,10 +613,26 @@ static ImBuf *add_ibuf_size(unsigned int width, unsigned int height, const char if (floatbuf) { ibuf = IMB_allocImBuf(width, height, depth, IB_rectfloat); rect_float = ibuf->rect_float; + + if (colorspace_settings->name[0] == '\0') { + const char *colorspace = IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_DEFAULT_FLOAT); + + BLI_strncpy(colorspace_settings->name, colorspace, sizeof(colorspace_settings->name)); + } + + IMB_colormanagement_check_is_data(ibuf, colorspace_settings->name); } else { ibuf = IMB_allocImBuf(width, height, depth, IB_rect); rect = (unsigned char *)ibuf->rect; + + if (colorspace_settings->name[0] == '\0') { + const char *colorspace = IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_DEFAULT_BYTE); + + BLI_strncpy(colorspace_settings->name, colorspace, sizeof(colorspace_settings->name)); + } + + IMB_colormanagement_assign_rect_colorspace(ibuf, colorspace_settings->name); } BLI_strncpy(ibuf->name, name, sizeof(ibuf->name)); @@ -650,7 +667,7 @@ Image *BKE_image_add_generated(unsigned int width, unsigned int height, const ch ima->gen_type = gen_type; ima->gen_flag |= (floatbuf ? IMA_GEN_FLOAT : 0); - ibuf = add_ibuf_size(width, height, ima->name, depth, floatbuf, gen_type, color); + 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); ima->ok = IMA_OK_LOADED; @@ -1016,7 +1033,7 @@ int BKE_imtype_supports_quality(const char imtype) return 0; } -int BKE_imtype_supports_float(const char imtype) +int BKE_imtype_requires_linear_float(const char imtype) { switch (imtype) { case R_IMF_IMTYPE_CINEON: @@ -1046,6 +1063,7 @@ char BKE_imtype_valid_channels(const char imtype) case R_IMF_IMTYPE_DDS: case R_IMF_IMTYPE_JP2: case R_IMF_IMTYPE_QUICKTIME: + case R_IMF_IMTYPE_DPX: chan_flag |= IMA_CHAN_FLAG_ALPHA; } @@ -1074,10 +1092,11 @@ char BKE_imtype_valid_depths(const char imtype) return R_IMF_CHAN_DEPTH_16 | R_IMF_CHAN_DEPTH_32; case R_IMF_IMTYPE_MULTILAYER: return R_IMF_CHAN_DEPTH_32; - /* eeh, cineone does some strange 10bits per channel */ + /* eeh, cineon does some strange 10bits per channel */ case R_IMF_IMTYPE_DPX: + return R_IMF_CHAN_DEPTH_8 | R_IMF_CHAN_DEPTH_10 | R_IMF_CHAN_DEPTH_12 | R_IMF_CHAN_DEPTH_16; case R_IMF_IMTYPE_CINEON: - return R_IMF_CHAN_DEPTH_12; + return R_IMF_CHAN_DEPTH_10; case R_IMF_IMTYPE_JP2: return R_IMF_CHAN_DEPTH_8 | R_IMF_CHAN_DEPTH_12 | R_IMF_CHAN_DEPTH_16; /* most formats are 8bit only */ @@ -1227,6 +1246,9 @@ void BKE_imformat_defaults(ImageFormatData *im_format) im_format->imtype = R_IMF_IMTYPE_PNG; im_format->quality = 90; im_format->compress = 90; + + BKE_color_managed_display_settings_init(&im_format->display_settings); + BKE_color_managed_view_settings_init(&im_format->view_settings); } void BKE_imbuf_to_image_format(struct ImageFormatData *im_format, const ImBuf *imbuf) @@ -1805,9 +1827,33 @@ int BKE_imbuf_write(ImBuf *ibuf, const char *name, ImageFormatData *imf) #ifdef WITH_CINEON else if (imtype == R_IMF_IMTYPE_CINEON) { ibuf->ftype = CINEON; + if (imf->cineon_flag & R_IMF_CINEON_FLAG_LOG) { + ibuf->ftype |= CINEON_LOG; + } + if (imf->depth == R_IMF_CHAN_DEPTH_16) { + ibuf->ftype |= CINEON_16BIT; + } + else if (imf->depth == R_IMF_CHAN_DEPTH_12) { + ibuf->ftype |= CINEON_12BIT; + } + else if (imf->depth == R_IMF_CHAN_DEPTH_10) { + ibuf->ftype |= CINEON_10BIT; + } } else if (imtype == R_IMF_IMTYPE_DPX) { ibuf->ftype = DPX; + if (imf->cineon_flag & R_IMF_CINEON_FLAG_LOG) { + ibuf->ftype |= CINEON_LOG; + } + if (imf->depth == R_IMF_CHAN_DEPTH_16) { + ibuf->ftype |= CINEON_16BIT; + } + else if (imf->depth == R_IMF_CHAN_DEPTH_12) { + ibuf->ftype |= CINEON_12BIT; + } + else if (imf->depth == R_IMF_CHAN_DEPTH_10) { + ibuf->ftype |= CINEON_10BIT; + } } #endif else if (imtype == R_IMF_IMTYPE_TARGA) { @@ -2100,6 +2146,15 @@ void BKE_image_signal(Image *ima, ImageUser *iuser, int signal) } } break; + case IMA_SIGNAL_COLORMANAGE: + image_free_buffers(ima); + + ima->ok = 1; + + if (iuser) + iuser->ok = 1; + + break; } /* don't use notifiers because they are not 100% sure to succeeded @@ -2201,8 +2256,10 @@ void BKE_image_backup_render(Scene *scene, Image *ima) /* in that case we have to build a render-result */ static void image_create_multilayer(Image *ima, ImBuf *ibuf, int framenr) { + const char *colorspace = ima->colorspace_settings.name; + int predivide = ima->flag & IMA_CM_PREDIVIDE; - ima->rr = RE_MultilayerConvert(ibuf->userdata, ibuf->x, ibuf->y); + ima->rr = RE_MultilayerConvert(ibuf->userdata, colorspace, predivide, ibuf->x, ibuf->y); #ifdef WITH_OPENEXR IMB_exr_close(ibuf->userdata); @@ -2541,7 +2598,7 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **lock_ *lock_r = re; } - /* this gives active layer, composite or seqence result */ + /* this gives active layer, composite or sequence result */ rect = (unsigned int *)rres.rect32; rectf = rres.rectf; rectz = rres.rectz; @@ -2595,15 +2652,21 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **lock_ /* free rect buffer if float buffer changes, so it can be recreated with * the updated result, and also in case we got byte buffer from sequencer, * so we don't keep reference to freed buffer */ - - /* todo: this fix breaks save buffers render progress - if (ibuf->rect_float != rectf || rect || !rectf) */ - if (ibuf->rect_float != rectf || rect) imb_freerectImBuf(ibuf); - if (rect) + if (rect) { ibuf->rect = rect; + } + else { + /* byte buffer of render result has been freed, make sure image buffers + * does not reference to this buffer anymore + * need check for whether byte buffer was allocated and owned by image itself + * or if it's reusing buffer from render result + */ + if ((ibuf->mall & IB_rect) == 0) + ibuf->rect = NULL; + } if (rectf) { ibuf->rect_float = rectf; @@ -2782,7 +2845,8 @@ ImBuf *BKE_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, color); + ibuf = add_ibuf_size(ima->gen_x, ima->gen_y, ima->name, 24, (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; } @@ -2998,5 +3062,8 @@ void BKE_image_get_aspect(Image *image, float *aspx, float *aspy) *aspx = 1.0; /* x is always 1 */ - *aspy = image->aspy / image->aspx; + if (image) + *aspy = image->aspy / image->aspx; + else + *aspy = 1.0f; } diff --git a/source/blender/blenkernel/intern/image_gen.c b/source/blender/blenkernel/intern/image_gen.c index 37572eebed6..468a88775c6 100644 --- a/source/blender/blenkernel/intern/image_gen.c +++ b/source/blender/blenkernel/intern/image_gen.c @@ -244,7 +244,7 @@ static void checker_board_color_tint(unsigned char *rect, float *rect_float, int } } - } + } } static void checker_board_grid_fill(unsigned char *rect, float *rect_float, int width, int height, float blend) diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index fcc8b4322a0..90cd7bc2df5 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -48,7 +48,9 @@ #include "BKE_global.h" -#define CLOTH_OPENMP_LIMIT 512 +#ifdef _OPENMP +# define CLOTH_OPENMP_LIMIT 512 +#endif #if 0 /* debug timing */ #ifdef _WIN32 @@ -588,7 +590,7 @@ DO_INLINE void mul_bfmatrix_lfvector( float (*to)[3], fmatrix3x3 *from, lfVector for (i = from[0].vcount; i < from[0].vcount+from[0].scount; i++) { muladd_fmatrix_fvector(to[from[i].c], from[i].m, fLongVector[from[i].r]); } - } + } #pragma omp section { for (i = 0; i < from[0].vcount+from[0].scount; i++) { @@ -621,7 +623,7 @@ DO_INLINE void add_bfmatrix_bfmatrix( fmatrix3x3 *to, fmatrix3x3 *from, fmatrix /* process diagonal elements */ for (i = 0; i < matrix[0].vcount+matrix[0].scount; i++) { - add_fmatrix_fmatrix(to[i].m, from[i].m, matrix[i].m); + add_fmatrix_fmatrix(to[i].m, from[i].m, matrix[i].m); } } @@ -632,7 +634,7 @@ DO_INLINE void addadd_bfmatrix_bfmatrix( fmatrix3x3 *to, fmatrix3x3 *from, fmat /* process diagonal elements */ for (i = 0; i < matrix[0].vcount+matrix[0].scount; i++) { - addadd_fmatrix_fmatrix(to[i].m, from[i].m, matrix[i].m); + addadd_fmatrix_fmatrix(to[i].m, from[i].m, matrix[i].m); } } @@ -643,7 +645,7 @@ DO_INLINE void subadd_bfmatrix_bfmatrix( fmatrix3x3 *to, fmatrix3x3 *from, fmat /* process diagonal elements */ for (i = 0; i < matrix[0].vcount+matrix[0].scount; i++) { - subadd_fmatrix_fmatrix(to[i].m, from[i].m, matrix[i].m); + subadd_fmatrix_fmatrix(to[i].m, from[i].m, matrix[i].m); } } @@ -654,7 +656,7 @@ DO_INLINE void sub_bfmatrix_bfmatrix( fmatrix3x3 *to, fmatrix3x3 *from, fmatrix /* process diagonal elements */ for (i = 0; i < matrix[0].vcount+matrix[0].scount; i++) { - sub_fmatrix_fmatrix(to[i].m, from[i].m, matrix[i].m); + sub_fmatrix_fmatrix(to[i].m, from[i].m, matrix[i].m); } } @@ -665,7 +667,7 @@ DO_INLINE void sub_bfmatrix_Smatrix( fmatrix3x3 *to, fmatrix3x3 *from, fmatrix3 /* process diagonal elements */ for (i = 0; i < matrix[0].vcount; i++) { - sub_fmatrix_fmatrix(to[matrix[i].c].m, from[matrix[i].c].m, matrix[i].m); + sub_fmatrix_fmatrix(to[matrix[i].c].m, from[matrix[i].c].m, matrix[i].m); } } @@ -676,7 +678,7 @@ DO_INLINE void addsub_bfmatrix_bfmatrix( fmatrix3x3 *to, fmatrix3x3 *from, fmat /* process diagonal elements */ for (i = 0; i < matrix[0].vcount+matrix[0].scount; i++) { - addsub_fmatrix_fmatrix(to[i].m, from[i].m, matrix[i].m); + addsub_fmatrix_fmatrix(to[i].m, from[i].m, matrix[i].m); } } @@ -689,7 +691,7 @@ DO_INLINE void subadd_bfmatrixS_bfmatrixS( fmatrix3x3 *to, fmatrix3x3 *from, flo /* process diagonal elements */ for (i = 0; i < matrix[0].vcount+matrix[0].scount; i++) { - subadd_fmatrixS_fmatrixS(to[i].m, from[i].m, aS, matrix[i].m, bS); + subadd_fmatrixS_fmatrixS(to[i].m, from[i].m, aS, matrix[i].m, bS); } } @@ -709,7 +711,7 @@ static void update_matrixS(ClothVertex *verts, int numverts, fmatrix3x3 *S) int i = 0; /* Clear matrix from old vertex constraints */ - for(i = 0; i < S[0].vcount; i++) + for (i = 0; i < S[0].vcount; i++) S[i].c = S[i].r = 0; /* Set new vertex constraints */ @@ -747,7 +749,7 @@ int implicit_init(Object *UNUSED(ob), ClothModifierData *clmd) id = (Implicit_Data *)MEM_callocN(sizeof(Implicit_Data), "implicit vecmat"); cloth->implicit = id; - /* process diagonal elements */ + /* process diagonal elements */ id->A = create_bfmatrix(cloth->numverts, cloth->numsprings); id->dFdV = create_bfmatrix(cloth->numverts, cloth->numsprings); id->dFdX = create_bfmatrix(cloth->numverts, cloth->numsprings); @@ -842,41 +844,40 @@ int implicit_free(ClothModifierData *clmd) DO_INLINE float fb(float length, float L) { - float x = length/L; - return (-11.541f*pow(x, 4)+34.193f*pow(x, 3)-39.083f*pow(x, 2)+23.116f*x-9.713f); + float x = length / L; + return (-11.541f * powf(x, 4) + 34.193f * powf(x, 3) - 39.083f * powf(x, 2) + 23.116f * x - 9.713f); } DO_INLINE float fbderiv(float length, float L) { float x = length/L; - return (-46.164f*pow(x, 3)+102.579f*pow(x, 2)-78.166f*x+23.116f); + return (-46.164f * powf(x, 3) + 102.579f * powf(x, 2) - 78.166f * x + 23.116f); } DO_INLINE float fbstar(float length, float L, float kb, float cb) { - float tempfb = kb * fb(length, L); - - float fbstar = cb * (length - L); + float tempfb_fl = kb * fb(length, L); + float fbstar_fl = cb * (length - L); - if (tempfb < fbstar) - return fbstar; + if (tempfb_fl < fbstar_fl) + return fbstar_fl; else - return tempfb; + return tempfb_fl; } // function to calculae bending spring force (taken from Choi & Co) DO_INLINE float fbstar_jacobi(float length, float L, float kb, float cb) { - float tempfb = kb * fb(length, L); - float fbstar = cb * (length - L); + float tempfb_fl = kb * fb(length, L); + float fbstar_fl = cb * (length - L); - if (tempfb < fbstar) { + if (tempfb_fl < fbstar_fl) { return cb; } else { - return kb * fbderiv(length, L); - } + return kb * fbderiv(length, L); + } } DO_INLINE void filter(lfVector *V, fmatrix3x3 *S) @@ -916,7 +917,7 @@ static int cg_filtered(lfVector *ldV, fmatrix3x3 *lA, lfVector *lB, lfVector *z cp_lfvector(d, r, numverts); s = dot_lfvector(r, r, numverts); - starget = s * sqrt(conjgrad_epsilon); + starget = s * sqrtf(conjgrad_epsilon); while (s>starget && conjgrad_loopcount < conjgrad_looplimit) { // Mul(q, A, d); // q = A*d; @@ -1147,9 +1148,9 @@ DO_INLINE void dfdx_spring_type1(float to[3][3], float extent[3], float length, // dir is unit length direction, rest is spring's restlength, k is spring constant. // return (outerprod(dir, dir)*k + (I - outerprod(dir, dir))*(k - ((k*L)/length))); float temp[3][3]; - float temp1 = k*(1.0 - (L/length)); + float temp1 = k * (1.0f - (L / length)); - mul_fvectorT_fvectorS(temp, extent, extent, 1.0 / dot); + mul_fvectorT_fvectorS(temp, extent, extent, 1.0f / dot); sub_fmatrix_fmatrix(to, I, temp); mul_fmatrix_S(to, temp1); @@ -1217,7 +1218,7 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, float stretch_force[3] = {0, 0, 0}; float bending_force[3] = {0, 0, 0}; float damping_force[3] = {0, 0, 0}; - float nulldfdx[3][3]={ {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; + float nulldfdx[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; float scaling = 0.0; @@ -1245,7 +1246,7 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, s->flags |= CSPRING_FLAG_DEACTIVATE; return; } - } + } */ mul_fvector_S(dir, extent, 1.0f/length); } @@ -1306,7 +1307,7 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, VECADDS(s->f, s->f, extent, -k); - mul_fvector_S(damping_force, dir, clmd->sim_parms->goalfrict * 0.01 * dot_v3v3(vel, dir)); + mul_fvector_S(damping_force, dir, clmd->sim_parms->goalfrict * 0.01f * dot_v3v3(vel, dir)); VECADD(s->f, s->f, damping_force); // HERE IS THE PROBLEM!!!! @@ -1317,10 +1318,10 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, if (length < L) { s->flags |= CLOTH_SPRING_FLAG_NEEDED; - k = clmd->sim_parms->bending; + k = clmd->sim_parms->bending; - scaling = k + s->stiffness * ABS(clmd->sim_parms->max_bend-k); - cb = k = scaling / (20.0*(clmd->sim_parms->avg_spring_len + FLT_EPSILON)); + scaling = k + s->stiffness * ABS(clmd->sim_parms->max_bend-k); + cb = k = scaling / (20.0f * (clmd->sim_parms->avg_spring_len + FLT_EPSILON)); mul_fvector_S(bending_force, dir, fbstar(length, L, k, cb)); VECADD(s->f, s->f, bending_force); @@ -1336,7 +1337,7 @@ DO_INLINE void cloth_apply_spring_force(ClothModifierData *UNUSED(clmd), ClothSp if (!(s->type & CLOTH_SPRING_TYPE_BENDING)) { sub_fmatrix_fmatrix(dFdV[s->ij].m, dFdV[s->ij].m, s->dfdv); sub_fmatrix_fmatrix(dFdV[s->kl].m, dFdV[s->kl].m, s->dfdv); - add_fmatrix_fmatrix(dFdV[s->matrix_index].m, dFdV[s->matrix_index].m, s->dfdv); + add_fmatrix_fmatrix(dFdV[s->matrix_index].m, dFdV[s->matrix_index].m, s->dfdv); } VECADD(lF[s->ij], lF[s->ij], s->f); @@ -1347,7 +1348,7 @@ DO_INLINE void cloth_apply_spring_force(ClothModifierData *UNUSED(clmd), ClothSp sub_fmatrix_fmatrix(dFdX[s->kl].m, dFdX[s->kl].m, s->dfdx); sub_fmatrix_fmatrix(dFdX[s->ij].m, dFdX[s->ij].m, s->dfdx); add_fmatrix_fmatrix(dFdX[s->matrix_index].m, dFdX[s->matrix_index].m, s->dfdx); - } + } } @@ -1355,15 +1356,15 @@ static void CalcFloat( float *v1, float *v2, float *v3, float *n) { float n1[3], n2[3]; - n1[0]= v1[0]-v2[0]; - n2[0]= v2[0]-v3[0]; - n1[1]= v1[1]-v2[1]; - n2[1]= v2[1]-v3[1]; - n1[2]= v1[2]-v2[2]; - n2[2]= v2[2]-v3[2]; - n[0]= n1[1]*n2[2]-n1[2]*n2[1]; - n[1]= n1[2]*n2[0]-n1[0]*n2[2]; - n[2]= n1[0]*n2[1]-n1[1]*n2[0]; + n1[0] = v1[0]-v2[0]; + n2[0] = v2[0]-v3[0]; + n1[1] = v1[1]-v2[1]; + n2[1] = v2[1]-v3[1]; + n1[2] = v1[2]-v2[2]; + n2[2] = v2[2]-v3[2]; + n[0] = n1[1]*n2[2]-n1[2]*n2[1]; + n[1] = n1[2]*n2[0]-n1[0]*n2[2]; + n[2] = n1[0]*n2[1]-n1[1]*n2[0]; } static void CalcFloat4( float *v1, float *v2, float *v3, float *v4, float *n) @@ -1371,17 +1372,17 @@ static void CalcFloat4( float *v1, float *v2, float *v3, float *v4, float *n) /* real cross! */ float n1[3], n2[3]; - n1[0]= v1[0]-v3[0]; - n1[1]= v1[1]-v3[1]; - n1[2]= v1[2]-v3[2]; + n1[0] = v1[0]-v3[0]; + n1[1] = v1[1]-v3[1]; + n1[2] = v1[2]-v3[2]; - n2[0]= v2[0]-v4[0]; - n2[1]= v2[1]-v4[1]; - n2[2]= v2[2]-v4[2]; + n2[0] = v2[0]-v4[0]; + n2[1] = v2[1]-v4[1]; + n2[2] = v2[2]-v4[2]; - n[0]= n1[1]*n2[2]-n1[2]*n2[1]; - n[1]= n1[2]*n2[0]-n1[0]*n2[2]; - n[2]= n1[0]*n2[1]-n1[1]*n2[0]; + n[0] = n1[1]*n2[2]-n1[2]*n2[1]; + n[1] = n1[2]*n2[0]-n1[0]*n2[2]; + n[2] = n1[0]*n2[1]-n1[1]*n2[0]; } static float calculateVertexWindForce(float wind[3], float vertexnormal[3]) @@ -1448,7 +1449,7 @@ static void hair_velocity_smoothing(ClothModifierData *clmd, lfVector *lF, lfVec i = HAIR_GRID_INDEX(lX[v], gmin, gmax, 0); j = HAIR_GRID_INDEX(lX[v], gmin, gmax, 1); k = HAIR_GRID_INDEX(lX[v], gmin, gmax, 2); - if (i < 0 || j < 0 || k < 0 || i > 10 || j >= 10 || k >= 10) + if (i < 0 || j < 0 || k < 0 || i >= 10 || j >= 10 || k >= 10) continue; grid[i][j][k].velocity[0] += lV[v][0]; @@ -1478,7 +1479,7 @@ static void hair_velocity_smoothing(ClothModifierData *clmd, lfVector *lF, lfVec colg[i][j][k].velocity[0] += vel[0]; colg[i][j][k].velocity[1] += vel[1]; colg[i][j][k].velocity[2] += vel[2]; - colg[i][j][k].density += 1.0; + colg[i][j][k].density += 1.0f; } } } @@ -1512,7 +1513,7 @@ static void hair_velocity_smoothing(ClothModifierData *clmd, lfVector *lF, lfVec i = HAIR_GRID_INDEX(lX[v], gmin, gmax, 0); j = HAIR_GRID_INDEX(lX[v], gmin, gmax, 1); k = HAIR_GRID_INDEX(lX[v], gmin, gmax, 2); - if (i < 0 || j < 0 || k < 0 || i > 10 || j >= 10 || k >= 10) + if (i < 0 || j < 0 || k < 0 || i >= 10 || j >= 10 || k >= 10) continue; lF[v][0] += smoothfac * (grid[i][j][k].velocity[0] - lV[v][0]); @@ -1543,7 +1544,7 @@ static void cloth_calc_force(ClothModifierData *clmd, float UNUSED(frame), lfVec lfVector *winvec; EffectedPoint epoint; - tm2[0][0]= tm2[1][1]= tm2[2][2]= -spring_air; + tm2[0][0] = tm2[1][1] = tm2[2][2] = -spring_air; /* global acceleration (gravitation) */ if (clmd->scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY) { @@ -1587,11 +1588,11 @@ static void cloth_calc_force(ClothModifierData *clmd, float UNUSED(frame), lfVec } for (i = 0; i < cloth->numfaces; i++) { - float trinormal[3]={0, 0, 0}; // normalized triangle normal - float triunnormal[3]={0, 0, 0}; // not-normalized-triangle normal - float tmp[3]={0, 0, 0}; + float trinormal[3] = {0, 0, 0}; // normalized triangle normal + float triunnormal[3] = {0, 0, 0}; // not-normalized-triangle normal + float tmp[3] = {0, 0, 0}; float factor = (mfaces[i].v4) ? 0.25 : 1.0 / 3.0; - factor *= 0.02; + factor *= 0.02f; // calculate face normal if (mfaces[i].v4) @@ -1627,9 +1628,9 @@ static void cloth_calc_force(ClothModifierData *clmd, float UNUSED(frame), lfVec /* Hair has only edges */ if (cloth->numfaces == 0) { ClothSpring *spring; - float edgevec[3]={0, 0, 0}; //edge vector - float edgeunnormal[3]={0, 0, 0}; // not-normalized-edge normal - float tmp[3]={0, 0, 0}; + float edgevec[3] = {0, 0, 0}; //edge vector + float edgeunnormal[3] = {0, 0, 0}; // not-normalized-edge normal + float tmp[3] = {0, 0, 0}; float factor = 0.01; search = cloth->springs; @@ -1661,7 +1662,7 @@ static void cloth_calc_force(ClothModifierData *clmd, float UNUSED(frame), lfVec while (search) { // only handle active springs ClothSpring *spring = search->link; - if( !(spring->flags & CLOTH_SPRING_FLAG_DEACTIVATE)) + if (!(spring->flags & CLOTH_SPRING_FLAG_DEACTIVATE)) cloth_calc_spring_force(clmd, search->link, lF, lX, lV, dFdV, dFdX, time); search = search->next; @@ -1729,8 +1730,8 @@ static int UNUSED_FUNCTION(cloth_calc_helper_forces)(Object *UNUSED(ob), ClothMo for (i=0; inumverts; i++, cv++) { copy_v3_v3(cos[i], cv->tx); - if (cv->goal == 1.0f || len_v3v3(initial_cos[i], cv->tx) != 0.0) { - masses[i] = 1e+10; + if (cv->goal == 1.0f || len_squared_v3v3(initial_cos[i], cv->tx) != 0.0f) { + masses[i] = 1e+10; } else { masses[i] = cv->mass; @@ -1757,18 +1758,18 @@ static int UNUSED_FUNCTION(cloth_calc_helper_forces)(Object *UNUSED(ob), ClothMo normalize_v3(vec); c = (len - spring->restlen); - if (c == 0.0) + if (c == 0.0f) continue; - l = c / ((1.0/masses[v1]) + (1.0/masses[v2])); + l = c / ((1.0f / masses[v1]) + (1.0f / masses[v2])); - mul_v3_fl(vec, -(1.0/masses[v1])*l); + mul_v3_fl(vec, -(1.0f / masses[v1]) * l); add_v3_v3(cos[v1], vec); sub_v3_v3v3(vec, cos[v2], cos[v1]); normalize_v3(vec); - mul_v3_fl(vec, -(1.0/masses[v2])*l); + mul_v3_fl(vec, -(1.0f / masses[v2]) * l); add_v3_v3(cos[v2], vec); } } @@ -1813,7 +1814,7 @@ int implicit_solver(Object *ob, float frame, ClothModifierData *clmd, ListBase * sub_v3_v3v3(id->V[i], verts[i].xconst, verts[i].xold); // mul_v3_fl(id->V[i], clmd->sim_parms->stepsPerFrame); } - } + } } while (step < tf) { @@ -1838,7 +1839,7 @@ int implicit_solver(Object *ob, float frame, ClothModifierData *clmd, ListBase * mul_fvector_S(tvect, tvect, step+dt); VECADD(tvect, tvect, verts[i].xold); copy_v3_v3(id->Xnew[i], tvect); - } + } } copy_v3_v3(verts[i].txold, id->X[i]); @@ -1896,7 +1897,7 @@ int implicit_solver(Object *ob, float frame, ClothModifierData *clmd, ListBase * cp_lfvector(id->V, id->Vnew, numverts); // calculate - cloth_calc_force(clmd, frame, id->F, id->X, id->V, id->dFdV, id->dFdX, effectors, step+dt, id->M); + cloth_calc_force(clmd, frame, id->F, id->X, id->V, id->dFdV, id->dFdX, effectors, step+dt, id->M); simulate_implicit_euler(id->Vnew, id->X, id->V, id->F, id->dFdV, id->dFdX, dt / 2.0f, id->A, id->B, id->dV, id->S, id->z, id->olddV, id->P, id->Pinv, id->M, id->bigI); } @@ -1945,6 +1946,6 @@ void implicit_set_positions(ClothModifierData *clmd) copy_v3_v3(id->V[i], verts[i].v); } if (G.debug_value > 0) - printf("implicit_set_positions\n"); + printf("implicit_set_positions\n"); } diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c index b2a9e229be9..59dd02849dd 100644 --- a/source/blender/blenkernel/intern/ipo.c +++ b/source/blender/blenkernel/intern/ipo.c @@ -32,7 +32,7 @@ /* NOTE: * - * This file is no longer used to provide tools for the depreceated IPO system. Instead, it + * This file is no longer used to provide tools for the deprecated IPO system. Instead, it * is only used to house the conversion code to the new system. * * -- Joshua Leung, Jan 2009 @@ -569,7 +569,7 @@ static const char *material_adrcodes_to_paths(int adrcode, int *array_index) return mtex_adrcodes_to_paths(adrcode, array_index); } - return NULL; + return NULL; } /* Camera Types */ @@ -727,7 +727,7 @@ static const char *world_adrcodes_to_paths(int adrcode, int *array_index) return mtex_adrcodes_to_paths(adrcode, array_index); } - return NULL; + return NULL; } /* Particle Types */ @@ -873,7 +873,7 @@ static char *get_rna_access(int blocktype, int adrcode, char actname[], char con propname = "eval_time"; break; - /* XXX problematic blocktypes */ + /* XXX problematic blocktypes */ case ID_SEQ: /* sequencer strip */ //SEQ_FAC1: switch (adrcode) { @@ -981,21 +981,21 @@ static char *get_rna_access(int blocktype, int adrcode, char actname[], char con static short adrcode_to_dtar_transchan(short adrcode) { switch (adrcode) { - case OB_LOC_X: + case OB_LOC_X: return DTAR_TRANSCHAN_LOCX; case OB_LOC_Y: return DTAR_TRANSCHAN_LOCY; case OB_LOC_Z: return DTAR_TRANSCHAN_LOCZ; - case OB_ROT_X: + case OB_ROT_X: return DTAR_TRANSCHAN_ROTX; case OB_ROT_Y: return DTAR_TRANSCHAN_ROTY; case OB_ROT_Z: return DTAR_TRANSCHAN_ROTZ; - case OB_SIZE_X: + case OB_SIZE_X: return DTAR_TRANSCHAN_SCALEX; case OB_SIZE_Y: return DTAR_TRANSCHAN_SCALEX; @@ -1359,8 +1359,8 @@ static void icu_to_fcurves(ID *id, ListBase *groups, ListBase *list, IpoCurve *i /* correct values for sequencer curves, that were not locked to frame */ if (seq && (seq->flag & SEQ_IPO_FRAME_LOCKED) == 0) { - double mul = (seq->enddisp - seq->startdisp) / 100.0f; - double offset = seq->startdisp; + const float mul = (seq->enddisp - seq->startdisp) / 100.0f; + const float offset = seq->startdisp; dst->vec[0][0] *= mul; dst->vec[0][0] += offset; @@ -1645,7 +1645,7 @@ static void nlastrips_to_animdata(ID *id, ListBase *strips) /* by default, we now always extrapolate, while in the past this was optional */ if ((as->flag & ACTSTRIP_HOLDLASTFRAME) == 0) strip->extendmode = NLASTRIP_EXTEND_NOTHING; - } + } /* try to add this strip to the current NLA-Track (i.e. the 'last' one on the stack atm) */ if (BKE_nlatrack_add_strip(nlt, strip) == 0) { @@ -1757,15 +1757,15 @@ void do_versions_ipos_to_animato(Main *main) { /* If we have any empty action actuators, assume they were - converted IPO Actuators using the object IPO */ + * converted IPO Actuators using the object IPO */ bActuator *act; bActionActuator *aa; for (act = ob->actuators.first; act; act = act->next) { /* Any actuators set to ACT_IPO at this point are actually Action Actuators that - need this converted IPO to finish converting the actuator. */ + * need this converted IPO to finish converting the actuator. */ if (act->type == ACT_IPO) { - aa = (bActionActuator*)act->data; + aa = (bActionActuator *)act->data; aa->act = ob->adt->action; act->type = ACT_ACTION; } @@ -2093,7 +2093,7 @@ void do_versions_ipos_to_animato(Main *main) bAction *new_act; /* add a new action for this, and convert all data into that action */ - new_act = add_empty_action(id->name+2); + new_act = add_empty_action(id->name + 2); ipo_to_animato(NULL, ipo, NULL, NULL, NULL, NULL, &new_act->curves, &drivers); new_act->idroot = ipo->blocktype; } diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c index b79608342dd..782d796b8a7 100644 --- a/source/blender/blenkernel/intern/key.c +++ b/source/blender/blenkernel/intern/key.c @@ -94,7 +94,7 @@ void BKE_key_free(Key *key) } -void free_key_nolib(Key *key) +void BKE_key_free_nolib(Key *key) { KeyBlock *kb; @@ -121,7 +121,7 @@ void free_key_nolib(Key *key) /* from misc_util: flip the bytes from x */ /* #define GS(x) (((unsigned char *)(x))[0] << 8 | ((unsigned char *)(x))[1]) */ -Key *add_key(ID *id) /* common function */ +Key *BKE_key_add(ID *id) /* common function */ { Key *key; char *el; @@ -133,7 +133,7 @@ Key *add_key(ID *id) /* common function */ key->uidgen = 1; - /* XXX the code here uses some defines which will soon be depreceated... */ + /* XXX the code here uses some defines which will soon be deprecated... */ switch (GS(id->name)) { case ID_ME: el = key->elemstr; @@ -196,7 +196,7 @@ Key *BKE_key_copy(Key *key) } -Key *copy_key_nolib(Key *key) +Key *BKE_key_copy_nolib(Key *key) { Key *keyn; KeyBlock *kbn, *kb; @@ -241,7 +241,7 @@ void BKE_key_make_local(Key *key) * currently being called. */ -void sort_keys(Key *key) +void BKE_key_sort(Key *key) { KeyBlock *kb; KeyBlock *kb2; @@ -389,7 +389,7 @@ static int setkeys(float fac, ListBase *lb, KeyBlock *k[], float t[4], int cycl) if (k1->next == NULL) k[0] = k1; k1 = k1->next; } - /* k1= k[1]; */ /* UNUSED */ + /* k1 = k[1]; */ /* UNUSED */ t[0] = k[0]->pos; t[1] += dpos; t[2] = k[2]->pos + dpos; @@ -609,7 +609,7 @@ static void cp_key(const int start, int end, const int tot, char *poin, Key *key } } else k1 += start * key->elemsize; - } + } if (mode == KEY_MODE_BEZTRIPLE) { elemstr[0] = 1; @@ -691,8 +691,8 @@ static void cp_cu_key(Curve *cu, Key *key, KeyBlock *actkb, KeyBlock *kb, const if (nu->bp) { step = nu->pntsu * nu->pntsv; - a1 = maxi(a, start); - a2 = mini(a + step, end); + a1 = max_ii(a, start); + a2 = min_ii(a + step, end); if (a1 < a2) cp_key(a1, a2, tot, out, key, actkb, kb, NULL, KEY_MODE_BPOINT); } @@ -700,8 +700,8 @@ static void cp_cu_key(Curve *cu, Key *key, KeyBlock *actkb, KeyBlock *kb, const step = 3 * nu->pntsu; /* exception because keys prefer to work with complete blocks */ - a1 = maxi(a, start); - a2 = mini(a + step, end); + a1 = max_ii(a, start); + a2 = min_ii(a + step, end); if (a1 < a2) cp_key(a1, a2, tot, out, key, actkb, kb, NULL, KEY_MODE_BEZTRIPLE); } @@ -711,7 +711,7 @@ static void cp_cu_key(Curve *cu, Key *key, KeyBlock *actkb, KeyBlock *kb, const } } -void do_rel_key(const int start, int end, const int tot, char *basispoin, Key *key, KeyBlock *actkb, const int mode) +void BKE_key_evaluate_relative(const int start, int end, const int tot, char *basispoin, Key *key, KeyBlock *actkb, const int mode) { KeyBlock *kb; int *ofsp, ofs[3], elemsize, b; @@ -1043,7 +1043,7 @@ static float *get_weights_array(Object *ob, char *vgroup) /* find the group (weak loop-in-loop) */ defgrp_index = defgroup_name_index(ob, vgroup); - if (defgrp_index >= 0) { + if (defgrp_index != -1) { float *weights; int i; @@ -1071,7 +1071,7 @@ static float *get_weights_array(Object *ob, char *vgroup) static void do_mesh_key(Scene *scene, Object *ob, Key *key, char *out, const int tot) { - KeyBlock *k[4], *actkb = ob_get_keyblock(ob); + KeyBlock *k[4], *actkb = BKE_keyblock_from_object(ob); float t[4]; int flag = 0; @@ -1106,7 +1106,7 @@ static void do_mesh_key(Scene *scene, Object *ob, Key *key, char *out, const int kb->weights = get_weights_array(ob, kb->vgroup); } - do_rel_key(0, tot, tot, (char *)out, key, actkb, KEY_MODE_DUMMY); + BKE_key_evaluate_relative(0, tot, tot, (char *)out, key, actkb, KEY_MODE_DUMMY); for (kb = key->block.first; kb; kb = kb->next) { if (kb->weights) MEM_freeN(kb->weights); @@ -1154,11 +1154,11 @@ static void do_rel_cu_key(Curve *cu, Key *key, KeyBlock *actkb, char *out, const for (a = 0, nu = cu->nurb.first; nu; nu = nu->next, a += step) { if (nu->bp) { step = nu->pntsu * nu->pntsv; - do_rel_key(a, a + step, tot, out, key, actkb, KEY_MODE_BPOINT); + BKE_key_evaluate_relative(a, a + step, tot, out, key, actkb, KEY_MODE_BPOINT); } else if (nu->bezt) { step = 3 * nu->pntsu; - do_rel_key(a, a + step, tot, out, key, actkb, KEY_MODE_BEZTRIPLE); + BKE_key_evaluate_relative(a, a + step, tot, out, key, actkb, KEY_MODE_BEZTRIPLE); } else { step = 0; @@ -1169,7 +1169,7 @@ static void do_rel_cu_key(Curve *cu, Key *key, KeyBlock *actkb, char *out, const static void do_curve_key(Scene *scene, Object *ob, Key *key, char *out, const int tot) { Curve *cu = ob->data; - KeyBlock *k[4], *actkb = ob_get_keyblock(ob); + KeyBlock *k[4], *actkb = BKE_keyblock_from_object(ob); float t[4]; int flag = 0; @@ -1217,7 +1217,7 @@ static void do_curve_key(Scene *scene, Object *ob, Key *key, char *out, const in remain = step; } - count = mini(remain, estep); + count = min_ii(remain, estep); if (mode == KEY_MODE_BEZTRIPLE) { count += 3 - count % 3; } @@ -1251,7 +1251,7 @@ static void do_curve_key(Scene *scene, Object *ob, Key *key, char *out, const in static void do_latt_key(Scene *scene, Object *ob, Key *key, char *out, const int tot) { Lattice *lt = ob->data; - KeyBlock *k[4], *actkb = ob_get_keyblock(ob); + KeyBlock *k[4], *actkb = BKE_keyblock_from_object(ob); float t[4]; int flag; @@ -1268,7 +1268,7 @@ static void do_latt_key(Scene *scene, Object *ob, Key *key, char *out, const int do_key(a, a + 1, tot, out, key, actkb, k, t, KEY_MODE_DUMMY); else cp_key(a, a + 1, tot, out, key, actkb, k[2], NULL, KEY_MODE_DUMMY); - } + } } else { if (key->type == KEY_RELATIVE) { @@ -1277,7 +1277,7 @@ static void do_latt_key(Scene *scene, Object *ob, Key *key, char *out, const int for (kb = key->block.first; kb; kb = kb->next) kb->weights = get_weights_array(ob, kb->vgroup); - do_rel_key(0, tot, tot, out, key, actkb, KEY_MODE_DUMMY); + BKE_key_evaluate_relative(0, tot, tot, out, key, actkb, KEY_MODE_DUMMY); for (kb = key->block.first; kb; kb = kb->next) { if (kb->weights) MEM_freeN(kb->weights); @@ -1302,8 +1302,8 @@ static void do_latt_key(Scene *scene, Object *ob, Key *key, char *out, const int /* returns key coordinates (+ tilt) when key applied, NULL otherwise */ float *do_ob_key(Scene *scene, Object *ob) { - Key *key = ob_get_key(ob); - KeyBlock *actkb = ob_get_keyblock(ob); + Key *key = BKE_key_from_object(ob); + KeyBlock *actkb = BKE_keyblock_from_object(ob); char *out; int tot = 0, size = 0; @@ -1386,7 +1386,7 @@ float *do_ob_key(Scene *scene, Object *ob) return (float *)out; } -Key *ob_get_key(Object *ob) +Key *BKE_key_from_object(Object *ob) { if (ob == NULL) return NULL; @@ -1405,7 +1405,7 @@ Key *ob_get_key(Object *ob) return NULL; } -KeyBlock *add_keyblock(Key *key, const char *name) +KeyBlock *BKE_keyblock_add(Key *key, const char *name) { KeyBlock *kb; float curpos = -0.1; @@ -1439,7 +1439,7 @@ KeyBlock *add_keyblock(Key *key, const char *name) /** * \note caller may want to set this to current time, but don't do it here since we need to sort - * which could cause problems in some cases, see #add_keyblock_ctime */ + * which could cause problems in some cases, see #BKE_keyblock_add_ctime */ kb->pos = curpos + 0.1f; /* only used for absolute shape keys */ return kb; @@ -1453,22 +1453,22 @@ KeyBlock *add_keyblock(Key *key, const char *name) * \param name Optional name for the new keyblock. * \param do_force always use ctime even for relative keys. */ -KeyBlock *add_keyblock_ctime(Key *key, const char *name, const short do_force) +KeyBlock *BKE_keyblock_add_ctime(Key *key, const char *name, const short do_force) { - KeyBlock *kb = add_keyblock(key, name); + KeyBlock *kb = BKE_keyblock_add(key, name); if (do_force || (key->type != KEY_RELATIVE)) { kb->pos = key->ctime / 100.0f; - sort_keys(key); + BKE_key_sort(key); } return kb; } /* only the active keyblock */ -KeyBlock *ob_get_keyblock(Object *ob) +KeyBlock *BKE_keyblock_from_object(Object *ob) { - Key *key = ob_get_key(ob); + Key *key = BKE_key_from_object(ob); if (key) { KeyBlock *kb = BLI_findlink(&key->block, ob->shapenr - 1); @@ -1478,9 +1478,9 @@ KeyBlock *ob_get_keyblock(Object *ob) return NULL; } -KeyBlock *ob_get_reference_keyblock(Object *ob) +KeyBlock *BKE_keyblock_from_object_reference(Object *ob) { - Key *key = ob_get_key(ob); + Key *key = BKE_key_from_object(ob); if (key) return key->refkey; @@ -1489,7 +1489,7 @@ KeyBlock *ob_get_reference_keyblock(Object *ob) } /* get the appropriate KeyBlock given an index */ -KeyBlock *key_get_keyblock(Key *key, int index) +KeyBlock *BKE_keyblock_from_key(Key *key, int index) { KeyBlock *kb; int i; @@ -1509,18 +1509,29 @@ KeyBlock *key_get_keyblock(Key *key, int index) } /* get the appropriate KeyBlock given a name to search for */ -KeyBlock *key_get_named_keyblock(Key *key, const char name[]) +KeyBlock *BKE_keyblock_find_name(Key *key, const char name[]) { - if (key && name) - return BLI_findstring(&key->block, name, offsetof(KeyBlock, name)); - - return NULL; + return BLI_findstring(&key->block, name, offsetof(KeyBlock, name)); +} + +/** + * \brief copy shape-key attributes, but not key data.or name/uid + */ +void BKE_keyblock_copy_settings(KeyBlock *kb_dst, const KeyBlock *kb_src) +{ + kb_dst->pos = kb_src->pos; + kb_dst->curval = kb_src->curval; + kb_dst->type = kb_src->type; + kb_dst->relative = kb_src->relative; + BLI_strncpy(kb_dst->vgroup, kb_src->vgroup, sizeof(kb_dst->vgroup)); + kb_dst->slidermin = kb_src->slidermin; + kb_dst->slidermax = kb_src->slidermax; } /* Get RNA-Path for 'value' setting of the given ShapeKey * NOTE: the user needs to free the returned string once they're finish with it */ -char *key_get_curValue_rnaPath(Key *key, KeyBlock *kb) +char *BKE_keyblock_curval_rnapath_get(Key *key, KeyBlock *kb) { PointerRNA ptr; PropertyRNA *prop; @@ -1542,7 +1553,7 @@ char *key_get_curValue_rnaPath(Key *key, KeyBlock *kb) /* conversion functions */ /************************* Lattice ************************/ -void latt_to_key(Lattice *lt, KeyBlock *kb) +void BKE_key_convert_from_lattice(Lattice *lt, KeyBlock *kb) { BPoint *bp; float *fp; @@ -1563,7 +1574,7 @@ void latt_to_key(Lattice *lt, KeyBlock *kb) } } -void key_to_latt(KeyBlock *kb, Lattice *lt) +void BKE_key_convert_to_lattice(KeyBlock *kb, Lattice *lt) { BPoint *bp; float *fp; @@ -1573,7 +1584,7 @@ void key_to_latt(KeyBlock *kb, Lattice *lt) fp = kb->data; tot = lt->pntsu * lt->pntsv * lt->pntsw; - tot = mini(kb->totelem, tot); + tot = min_ii(kb->totelem, tot); for (a = 0; a < tot; a++, fp += 3, bp++) { copy_v3_v3(bp->vec, fp); @@ -1581,7 +1592,7 @@ void key_to_latt(KeyBlock *kb, Lattice *lt) } /************************* Curve ************************/ -void curve_to_key(Curve *cu, KeyBlock *kb, ListBase *nurb) +void BKE_key_convert_from_curve(Curve *cu, KeyBlock *kb, ListBase *nurb) { Nurb *nu; BezTriple *bezt; @@ -1632,7 +1643,7 @@ void curve_to_key(Curve *cu, KeyBlock *kb, ListBase *nurb) } } -void key_to_curve(KeyBlock *kb, Curve *UNUSED(cu), ListBase *nurb) +void BKE_key_convert_to_curve(KeyBlock *kb, Curve *UNUSED(cu), ListBase *nurb) { Nurb *nu; BezTriple *bezt; @@ -1645,7 +1656,7 @@ void key_to_curve(KeyBlock *kb, Curve *UNUSED(cu), ListBase *nurb) tot = BKE_nurbList_verts_count(nurb); - tot = mini(kb->totelem, tot); + tot = min_ii(kb->totelem, tot); while (nu && tot > 0) { @@ -1683,7 +1694,7 @@ void key_to_curve(KeyBlock *kb, Curve *UNUSED(cu), ListBase *nurb) } /************************* Mesh ************************/ -void mesh_to_key(Mesh *me, KeyBlock *kb) +void BKE_key_convert_from_mesh(Mesh *me, KeyBlock *kb) { MVert *mvert; float *fp; @@ -1704,7 +1715,7 @@ void mesh_to_key(Mesh *me, KeyBlock *kb) } } -void key_to_mesh(KeyBlock *kb, Mesh *me) +void BKE_key_convert_to_mesh(KeyBlock *kb, Mesh *me) { MVert *mvert; float *fp; @@ -1713,7 +1724,7 @@ void key_to_mesh(KeyBlock *kb, Mesh *me) mvert = me->mvert; fp = kb->data; - tot = mini(kb->totelem, me->totvert); + tot = min_ii(kb->totelem, me->totvert); for (a = 0; a < tot; a++, fp += 3, mvert++) { copy_v3_v3(mvert->co, fp); @@ -1721,7 +1732,7 @@ void key_to_mesh(KeyBlock *kb, Mesh *me) } /************************* vert coords ************************/ -float (*key_to_vertcos(Object * ob, KeyBlock * kb))[3] +float (*BKE_key_convert_to_vertcos(Object * ob, KeyBlock * kb))[3] { float (*vertCos)[3], *co; float *fp = kb->data; @@ -1743,7 +1754,7 @@ float (*key_to_vertcos(Object * ob, KeyBlock * kb))[3] if (tot == 0) return NULL; - vertCos = MEM_callocN(tot * sizeof(*vertCos), "key_to_vertcos vertCos"); + vertCos = MEM_callocN(tot * sizeof(*vertCos), "BKE_key_convert_to_vertcos vertCos"); /* Copy coords to array */ co = (float *)vertCos; @@ -1797,7 +1808,7 @@ float (*key_to_vertcos(Object * ob, KeyBlock * kb))[3] return vertCos; } -void vertcos_to_key(Object *ob, KeyBlock *kb, float (*vertCos)[3]) +void BKE_key_convert_from_vertcos(Object *ob, KeyBlock *kb, float (*vertCos)[3]) { float *co = (float *)vertCos, *fp; int tot = 0, a, elemsize; @@ -1826,7 +1837,7 @@ void vertcos_to_key(Object *ob, KeyBlock *kb, float (*vertCos)[3]) return; } - fp = kb->data = MEM_callocN(tot * elemsize, "key_to_vertcos vertCos"); + fp = kb->data = MEM_callocN(tot * elemsize, "BKE_key_convert_to_vertcos vertCos"); /* Copy coords to keyblock */ @@ -1877,7 +1888,7 @@ void vertcos_to_key(Object *ob, KeyBlock *kb, float (*vertCos)[3]) } } -void offset_to_key(Object *ob, KeyBlock *kb, float (*ofs)[3]) +void BKE_key_convert_from_offset(Object *ob, KeyBlock *kb, float (*ofs)[3]) { int a; float *co = (float *)ofs, *fp = kb->data; diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c index 17e4103c7d3..a15ca7cb5ce 100644 --- a/source/blender/blenkernel/intern/lattice.c +++ b/source/blender/blenkernel/intern/lattice.c @@ -64,19 +64,19 @@ #include "BKE_deform.h" -void calc_lat_fudu(int flag, int res, float *fu, float *du) +void calc_lat_fudu(int flag, int res, float *r_fu, float *r_du) { if (res == 1) { - *fu = 0.0; - *du = 0.0; + *r_fu = 0.0; + *r_du = 0.0; } else if (flag & LT_GRID) { - *fu = -0.5f * (res - 1); - *du = 1.0f; + *r_fu = -0.5f * (res - 1); + *r_du = 1.0f; } else { - *fu = -1.0f; - *du = 2.0f / (res - 1); + *r_fu = -1.0f; + *r_du = 2.0f / (res - 1); } } @@ -348,7 +348,7 @@ void calc_latt_deform(Object *ob, float co[3], float weight) int ui, vi, wi, uu, vv, ww; /* vgroup influence */ - int defgroup_nr = -1; + int defgrp_index = -1; float co_prev[3], weight_blend = 0.0f; MDeformVert *dvert = BKE_lattice_deform_verts_get(ob); @@ -357,7 +357,7 @@ void calc_latt_deform(Object *ob, float co[3], float weight) if (lt->latticedata == NULL) return; if (lt->vgroup[0] && dvert) { - defgroup_nr = defgroup_name_index(ob, lt->vgroup); + defgrp_index = defgroup_name_index(ob, lt->vgroup); copy_v3_v3(co_prev, co); } @@ -431,8 +431,8 @@ void calc_latt_deform(Object *ob, float co[3], float weight) madd_v3_v3fl(co, <->latticedata[idx_u * 3], u); - if (defgroup_nr != -1) - weight_blend += (u * defvert_find_weight(dvert + idx_u, defgroup_nr)); + if (defgrp_index != -1) + weight_blend += (u * defvert_find_weight(dvert + idx_u, defgrp_index)); } } } @@ -440,7 +440,7 @@ void calc_latt_deform(Object *ob, float co[3], float weight) } } - if (defgroup_nr != -1) + if (defgrp_index != -1) interp_v3_v3v3(co, co_prev, co, weight_blend); } @@ -669,9 +669,9 @@ void curve_deform_verts(Scene *scene, Object *cuOb, Object *target, if (vgroup && vgroup[0] && use_vgroups) { Mesh *me = target->data; - int index = defgroup_name_index(target, vgroup); + const int defgrp_index = defgroup_name_index(target, vgroup); - if (index != -1 && (me->dvert || dm)) { + if (defgrp_index != -1 && (me->dvert || dm)) { MDeformVert *dvert = me->dvert; float vec[3]; float weight; @@ -681,7 +681,7 @@ void curve_deform_verts(Scene *scene, Object *cuOb, Object *target, dvert = me->dvert; for (a = 0; a < numVerts; a++, dvert++) { if (dm) dvert = dm->getVertData(dm, a, CD_MDEFORMVERT); - weight = defvert_find_weight(dvert, index); + weight = defvert_find_weight(dvert, defgrp_index); if (weight > 0.0f) { mul_m4_v3(cd.curvespace, vertexCos[a]); @@ -699,7 +699,7 @@ void curve_deform_verts(Scene *scene, Object *cuOb, Object *target, for (a = 0; a < numVerts; a++, dvert++) { if (dm) dvert = dm->getVertData(dm, a, CD_MDEFORMVERT); - if (defvert_find_weight(dvert, index) > 0.0f) { + if (defvert_find_weight(dvert, defgrp_index) > 0.0f) { mul_m4_v3(cd.curvespace, vertexCos[a]); minmax_v3v3_v3(cd.dmin, cd.dmax, vertexCos[a]); } @@ -709,7 +709,7 @@ void curve_deform_verts(Scene *scene, Object *cuOb, Object *target, for (a = 0; a < numVerts; a++, dvert++) { if (dm) dvert = dm->getVertData(dm, a, CD_MDEFORMVERT); - weight = defvert_find_weight(dvert, index); + weight = defvert_find_weight(dvert, defgrp_index); if (weight > 0.0f) { /* already in 'cd.curvespace', prev for loop */ @@ -815,16 +815,16 @@ void lattice_deform_verts(Object *laOb, Object *target, DerivedMesh *dm, if (vgroup && vgroup[0] && use_vgroups) { Mesh *me = target->data; - int index = defgroup_name_index(target, vgroup); + const int defgrp_index = defgroup_name_index(target, vgroup); float weight; - if (index >= 0 && (me->dvert || dm)) { + if (defgrp_index >= 0 && (me->dvert || dm)) { MDeformVert *dvert = me->dvert; for (a = 0; a < numVerts; a++, dvert++) { if (dm) dvert = dm->getVertData(dm, a, CD_MDEFORMVERT); - weight = defvert_find_weight(dvert, index); + weight = defvert_find_weight(dvert, defgrp_index); if (weight > 0.0f) calc_latt_deform(laOb, vertexCos[a], weight * fac); @@ -879,9 +879,10 @@ void outside_lattice(Lattice *lt) for (v = 0; v < lt->pntsv; v++) { for (u = 0; u < lt->pntsu; u++, bp++) { - if (u == 0 || v == 0 || w == 0 || u == lt->pntsu - 1 || v == lt->pntsv - 1 || w == lt->pntsw - 1) ; + if (u == 0 || v == 0 || w == 0 || u == lt->pntsu - 1 || v == lt->pntsv - 1 || w == lt->pntsw - 1) { + /* pass */ + } else { - bp->hide = 1; bp->f1 &= ~SELECT; diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index 45364f5aafa..942e71b5052 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -796,6 +796,18 @@ static void animdata_dtar_clear_cb(ID *UNUSED(id), AnimData *adt, void *userdata } } +void BKE_libblock_free_data(ID *id) +{ + Main *bmain = G.main; /* should eventually be an arg */ + + if (id->properties) { + IDP_FreeProperty(id->properties); + MEM_freeN(id->properties); + } + + /* this ID may be a driver target! */ + BKE_animdata_main_cb(bmain, animdata_dtar_clear_cb, (void *)id); +} /* used in headerbuttons.c image.c mesh.c screen.c sound.c and library.c */ void BKE_libblock_free(ListBase *lb, void *idv) @@ -904,15 +916,9 @@ void BKE_libblock_free(ListBase *lb, void *idv) break; } - if (id->properties) { - IDP_FreeProperty(id->properties); - MEM_freeN(id->properties); - } - BLI_remlink(lb, id); - /* this ID may be a driver target! */ - BKE_animdata_main_cb(bmain, animdata_dtar_clear_cb, (void *)id); + BKE_libblock_free_data(id); MEM_freeN(id); } @@ -1200,7 +1206,7 @@ static int check_for_dupid(ListBase *lb, ID *id, char *name) 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; */ + /* 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 (1) { @@ -1547,7 +1553,7 @@ void rename_id(ID *id, const char *name) BLI_strncpy(id->name + 2, name, sizeof(id->name) - 2); lb = which_libbase(G.main, GS(id->name) ); - new_id(lb, id, name); + new_id(lb, id, name); } void name_uiprefix_id(char *name, ID *id) diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index 3564071334c..b7f4c4bd61e 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -378,8 +378,8 @@ float BKE_mask_spline_project_co(MaskSpline *spline, MaskSplinePoint *point, if (len_squared_v2(v1) > proj_eps_squared) { ang1 = angle_v2v2(v1, n1); - if (ang1 > M_PI / 2.0f) - ang1 = M_PI - ang1; + if (ang1 > (float)M_PI / 2.0f) + ang1 = (float)M_PI - ang1; if (ang < 0.0f || ang1 < ang) { ang = ang1; @@ -405,8 +405,8 @@ float BKE_mask_spline_project_co(MaskSpline *spline, MaskSplinePoint *point, if (len_squared_v2(v2) > proj_eps_squared) { ang2 = angle_v2v2(v2, n2); - if (ang2 > M_PI / 2.0f) - ang2 = M_PI - ang2; + if (ang2 > (float)M_PI / 2.0f) + ang2 = (float)M_PI - ang2; if (ang2 < ang) { ang = ang2; @@ -555,7 +555,7 @@ float BKE_mask_point_weight_scalar(MaskSpline *spline, MaskSplinePoint *point, c if (!bezt_next) { return bezt->weight; } - else if (u <= 0.0) { + else if (u <= 0.0f) { return bezt->weight; } else if (u >= 1.0f) { @@ -576,7 +576,7 @@ float BKE_mask_point_weight(MaskSpline *spline, MaskSplinePoint *point, const fl if (!bezt_next) { return bezt->weight; } - else if (u <= 0.0) { + else if (u <= 0.0f) { return bezt->weight; } else if (u >= 1.0f) { @@ -916,19 +916,6 @@ void BKE_mask_free_nolib(Mask *mask) BKE_mask_layer_free_list(&mask->masklayers); } - -static void ntree_unlink_mask_cb(void *calldata, struct ID *UNUSED(owner_id), struct bNodeTree *ntree) -{ - ID *id = (ID *)calldata; - bNode *node; - - for (node = ntree->nodes.first; node; node = node->next) { - if (node->id == id) { - node->id = NULL; - } - } -} - void BKE_mask_free(Main *bmain, Mask *mask) { bScreen *scr; @@ -975,21 +962,11 @@ void BKE_mask_free(Main *bmain, Mask *mask) } SEQ_END } - - - if (scene->nodetree) { - bNode *node; - for (node = scene->nodetree->nodes.first; node; node = node->next) { - if (node->id == &mask->id) { - node->id = NULL; - } - } - } } { bNodeTreeType *treetype = ntreeGetType(NTREE_COMPOSIT); - treetype->foreach_nodetree(bmain, (void *)mask, &ntree_unlink_mask_cb); + treetype->foreach_nodetree(bmain, (void *)mask, &BKE_node_tree_unlink_id_cb); } /* free mask data */ @@ -1548,7 +1525,7 @@ void BKE_mask_parent_init(MaskParent *parent) } -/* *** own animation/shapekey implimentation *** +/* *** own animation/shapekey implementation *** * BKE_mask_layer_shape_XXX */ int BKE_mask_layer_shape_totvert(MaskLayer *masklay) @@ -1828,7 +1805,7 @@ static void interp_weights_uv_v2_calc(float r_uv[2], const float pt[2], const fl float pt_on_line[2]; r_uv[0] = closest_to_line_v2(pt_on_line, pt, pt_a, pt_b); r_uv[1] = (len_v2v2(pt_on_line, pt) / len_v2v2(pt_a, pt_b)) * - ((line_point_side_v2(pt_a, pt_b, pt) < 0.0f) ? -1.0 : 1.0); /* this line only sets the sign */ + ((line_point_side_v2(pt_a, pt_b, pt) < 0.0f) ? -1.0f : 1.0f); /* this line only sets the sign */ } @@ -1978,5 +1955,5 @@ void BKE_mask_layer_shape_changed_remove(MaskLayer *masklay, int index, int coun int BKE_mask_get_duration(Mask *mask) { - return maxi(1, mask->efra - mask->sfra); + return max_ii(1, mask->efra - mask->sfra); } diff --git a/source/blender/blenkernel/intern/mask_evaluate.c b/source/blender/blenkernel/intern/mask_evaluate.c index 4a8601df0b8..e67df9c6419 100644 --- a/source/blender/blenkernel/intern/mask_evaluate.c +++ b/source/blender/blenkernel/intern/mask_evaluate.c @@ -69,7 +69,7 @@ unsigned int BKE_mask_spline_resolution(MaskSpline *spline, int width, int heigh unsigned int i, resol = 1; if (width != 0 && height != 0) { - max_segment = 1.0f / (float)maxi(width, height); + max_segment = 1.0f / (float)max_ii(width, height); } for (i = 0; i < spline->tot_point; i++) { @@ -131,7 +131,7 @@ unsigned int BKE_mask_spline_feather_resolution(MaskSpline *spline, int width, i if (u_diff > FLT_EPSILON) { float jump = fabsf(w_diff / u_diff); - max_jump = MAX2(max_jump, jump); + max_jump = max_ff(max_jump, jump); } prev_u = point->uw[j].u; @@ -418,7 +418,7 @@ void BKE_mask_spline_feather_collapse_inner_loops(MaskSpline *spline, float (*fe max_delta = MAX2(max_delta_x, max_delta_y); - buckets_per_side = MIN2(512, 0.9f / max_delta); + buckets_per_side = min_ii(512, 0.9f / max_delta); if (buckets_per_side == 0) { /* happens when some segment fills the whole bounding box across some of dimension */ diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c index 00898b0fe10..88393fab79c 100644 --- a/source/blender/blenkernel/intern/mask_rasterize.c +++ b/source/blender/blenkernel/intern/mask_rasterize.c @@ -104,7 +104,7 @@ /* for debugging add... */ #ifndef NDEBUG -/* printf("%u %u %u %u\n", _t[0], _t[1], _t[2], _t[3]); \ */ +/* printf("%u %u %u %u\n", _t[0], _t[1], _t[2], _t[3]); \ */ # define FACE_ASSERT(face, vert_max) \ { \ unsigned int *_t = face; \ @@ -410,8 +410,8 @@ static void layer_bucket_init(MaskRasterLayer *layer, const float pixel_size) { MemArena *arena = BLI_memarena_new(1 << 16, __func__); - const float bucket_dim_x = BLI_RCT_SIZE_X(&layer->bounds); - const float bucket_dim_y = BLI_RCT_SIZE_Y(&layer->bounds); + const float bucket_dim_x = BLI_rctf_size_x(&layer->bounds); + const float bucket_dim_y = BLI_rctf_size_y(&layer->bounds); layer->buckets_x = (bucket_dim_x / pixel_size) / (float)BUCKET_PIXELS_PER_CELL; layer->buckets_y = (bucket_dim_y / pixel_size) / (float)BUCKET_PIXELS_PER_CELL; @@ -428,7 +428,7 @@ static void layer_bucket_init(MaskRasterLayer *layer, const float pixel_size) /* width and height of each bucket */ const float bucket_size_x = (bucket_dim_x + FLT_EPSILON) / layer->buckets_x; const float bucket_size_y = (bucket_dim_y + FLT_EPSILON) / layer->buckets_y; - const float bucket_max_rad = (maxf(bucket_size_x, bucket_size_y) * M_SQRT2) + FLT_EPSILON; + const float bucket_max_rad = (max_ff(bucket_size_x, bucket_size_y) * (float)M_SQRT2) + FLT_EPSILON; const float bucket_max_rad_squared = bucket_max_rad * bucket_max_rad; unsigned int *face = &layer->face_array[0][0]; @@ -451,10 +451,10 @@ static void layer_bucket_init(MaskRasterLayer *layer, const float pixel_size) const float *v2 = cos[face[1]]; const float *v3 = cos[face[2]]; - xmin = minf(v1[0], minf(v2[0], v3[0])); - xmax = maxf(v1[0], maxf(v2[0], v3[0])); - ymin = minf(v1[1], minf(v2[1], v3[1])); - ymax = maxf(v1[1], maxf(v2[1], v3[1])); + xmin = min_ff(v1[0], min_ff(v2[0], v3[0])); + xmax = max_ff(v1[0], max_ff(v2[0], v3[0])); + ymin = min_ff(v1[1], min_ff(v2[1], v3[1])); + ymax = max_ff(v1[1], max_ff(v2[1], v3[1])); } else { const float *v1 = cos[face[0]]; @@ -462,10 +462,10 @@ static void layer_bucket_init(MaskRasterLayer *layer, const float pixel_size) const float *v3 = cos[face[2]]; const float *v4 = cos[face[3]]; - xmin = minf(v1[0], minf(v2[0], minf(v3[0], v4[0]))); - xmax = maxf(v1[0], maxf(v2[0], maxf(v3[0], v4[0]))); - ymin = minf(v1[1], minf(v2[1], minf(v3[1], v4[1]))); - ymax = maxf(v1[1], maxf(v2[1], maxf(v3[1], v4[1]))); + xmin = min_ff(v1[0], min_ff(v2[0], min_ff(v3[0], v4[0]))); + xmax = max_ff(v1[0], max_ff(v2[0], max_ff(v3[0], v4[0]))); + ymin = min_ff(v1[1], min_ff(v2[1], min_ff(v3[1], v4[1]))); + ymax = max_ff(v1[1], max_ff(v2[1], max_ff(v3[1], v4[1]))); } @@ -503,7 +503,7 @@ static void layer_bucket_init(MaskRasterLayer *layer, const float pixel_size) BLI_assert(bucket_index < bucket_tot); /* check if the bucket intersects with the face */ - /* note: there is a tradeoff here since checking box/tri intersections isn't + /* note: there is a trade off here since checking box/tri intersections isn't * as optimal as it could be, but checking pixels against faces they will never intersect * with is likely the greater slowdown here - so check if the cell intersects the face */ if (layer_bucket_isect_test(layer, face_index, @@ -560,7 +560,7 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas const short do_feather) { const rctf default_bounds = {0.0f, 1.0f, 0.0f, 1.0f}; - const float pixel_size = 1.0f / MIN2(width, height); + const float pixel_size = 1.0f / (float)min_ii(width, height); const float asp_xy[2] = {(do_aspect_correct && width > height) ? (float)height / (float)width : 1.0f, (do_aspect_correct && width < height) ? (float)width / (float)height : 1.0f}; @@ -1208,7 +1208,7 @@ static float maskrasterize_layer_isect(unsigned int *face, float (*cos)[3], cons /* needs work */ #if 1 - /* quad check fails for bowtie, so keep using 2 tri checks */ + /* quad check fails for bow-tie, so keep using 2 tri checks */ //if (isect_point_quad_v2(xy, cos[face[0]], cos[face[1]], cos[face[2]], cos[face[3]])) if (isect_point_tri_v2(xy, cos[face[0]], cos[face[1]], cos[face[2]]) || isect_point_tri_v2(xy, cos[face[0]], cos[face[2]], cos[face[3]])) @@ -1216,7 +1216,7 @@ static float maskrasterize_layer_isect(unsigned int *face, float (*cos)[3], cons return maskrasterize_layer_z_depth_quad(xy, cos[face[0]], cos[face[1]], cos[face[2]], cos[face[3]]); } #elif 1 - /* don't use isect_point_tri_v2_cw because we could have bowtie quads */ + /* don't use isect_point_tri_v2_cw because we could have bow-tie quads */ if (isect_point_tri_v2(xy, cos[face[0]], cos[face[1]], cos[face[2]])) { return maskrasterize_layer_z_depth_tri(xy, cos[face[0]], cos[face[1]], cos[face[2]]); @@ -1335,10 +1335,10 @@ float BKE_maskrasterize_handle_sample(MaskRasterHandle *mr_handle, const float x value -= value_layer; break; case MASK_BLEND_LIGHTEN: - value = maxf(value, value_layer); + value = max_ff(value, value_layer); break; case MASK_BLEND_DARKEN: - value = minf(value, value_layer); + value = min_ff(value, value_layer); break; case MASK_BLEND_MUL: value *= value_layer; diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index 7523c59a879..ea317956255 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -38,6 +38,7 @@ #include "DNA_anim_types.h" #include "DNA_curve_types.h" +#include "DNA_group_types.h" #include "DNA_material_types.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" @@ -214,7 +215,7 @@ Material *BKE_material_add(const char *name) init_material(ma); - return ma; + return ma; } /* XXX keep synced with next function */ @@ -903,7 +904,7 @@ short find_material_index(Object *ob, Material *ma) break; if (a < *totcolp) return a + 1; - return 0; + return 0; } int object_add_material_slot(Object *ob) @@ -941,7 +942,7 @@ static void do_init_render_material(Material *ma, int r_mode, float *amb) if (ma->texco & (TEXCO_ORCO | TEXCO_REFL | TEXCO_NORM | TEXCO_STRAND | TEXCO_STRESS)) needuv = 1; else if (ma->texco & (TEXCO_GLOB | TEXCO_UV | TEXCO_OBJECT | TEXCO_SPEED)) needuv = 1; - else if (ma->texco & (TEXCO_LAVECTOR | TEXCO_VIEW | TEXCO_STICKY)) needuv = 1; + else if (ma->texco & (TEXCO_LAVECTOR | TEXCO_VIEW)) needuv = 1; if ((ma->mapto & MAP_NORM) && (mtex->normapspace == MTEX_NSPACE_TANGENT)) needtang = 1; @@ -969,7 +970,7 @@ static void do_init_render_material(Material *ma, int r_mode, float *amb) ma->ambr = ma->amb * amb[0]; ma->ambg = ma->amb * amb[1]; ma->ambb = ma->amb * amb[2]; - } + } /* will become or-ed result of all node modes */ ma->mode_l = ma->mode; ma->mode_l &= ~MA_SHLESS; @@ -980,6 +981,17 @@ static void do_init_render_material(Material *ma, int r_mode, float *amb) /* parses the geom+tex nodes */ if (ma->nodetree && ma->use_nodes) ntreeShaderGetTexcoMode(ma->nodetree, r_mode, &ma->texco, &ma->mode_l); + + /* local group override */ + if ((ma->shade_flag & MA_GROUP_LOCAL) && ma->id.lib && ma->group && ma->group->id.lib) { + Group *group; + + for (group = G.main->group.first; group; group = group->id.next) { + if (!group->id.lib && strcmp(group->id.name, ma->group->id.name) == 0) { + ma->group = group; + } + } + } } static void init_render_nodetree(bNodeTree *ntree, Material *basemat, int r_mode, float *amb) @@ -1147,7 +1159,7 @@ void material_drivers_update(Scene *scene, Material *ma, float ctime) /* ****************** */ #if 0 /* UNUSED */ -static char colname_array[125][20]= { +static char colname_array[125][20] = { "Black", "DarkRed", "HalfRed", "Red", "Red", "DarkGreen", "DarkOlive", "Brown", "Chocolate", "OrangeRed", "HalfGreen", "GreenOlive", "DryOlive", "Goldenrod", "DarkOrange", @@ -1327,9 +1339,9 @@ void ramp_blend(int type, float r_col[3], const float fac, const float col[3]) r_col[2] = facm * (r_col[2]) + fac * (r_col[2]) / col[2]; break; case MA_RAMP_DIFF: - r_col[0] = facm * (r_col[0]) + fac *fabsf(r_col[0] - col[0]); - r_col[1] = facm * (r_col[1]) + fac *fabsf(r_col[1] - col[1]); - r_col[2] = facm * (r_col[2]) + fac *fabsf(r_col[2] - col[2]); + r_col[0] = facm * (r_col[0]) + fac * fabsf(r_col[0] - col[0]); + r_col[1] = facm * (r_col[1]) + fac * fabsf(r_col[1] - col[1]); + r_col[2] = facm * (r_col[2]) + fac * fabsf(r_col[2] - col[2]); break; case MA_RAMP_DARK: tmp = col[0] + ((1 - col[0]) * facm); @@ -1490,7 +1502,7 @@ void ramp_blend(int type, float r_col[3], const float fac, const float col[3]) } /** - * \brief copy/paste buffer, if we had a propper py api that would be better + * \brief copy/paste buffer, if we had a proper py api that would be better * \note matcopybuf.nodetree does _NOT_ use ID's * \todo matcopybuf.nodetree's node->id's are NOT validated, this will crash! */ @@ -1603,7 +1615,7 @@ static int encode_tfaceflag(MTFace *tf, int convertall) /* calculate the flag */ int flag = tf->mode; - /* options that change the material offline render */ + /* options that change the material offline render */ if (!convertall) { flag &= ~TF_OBCOL; } @@ -1627,7 +1639,7 @@ static int encode_tfaceflag(MTFace *tf, int convertall) /* set the material options based in the tface flag */ static void decode_tfaceflag(Material *ma, int flag, int convertall) { - int alphablend; + int alphablend; GameSettings *game = &ma->game; /* flag is shifted in 1 to make 0 != no flag yet (see encode_tfaceflag) */ @@ -1786,13 +1798,13 @@ static short convert_tfacenomaterial(Main *main, Mesh *me, MTFace *tf, int flag) * for now store the flag into the material and change light/tex/collision * store the flag as a negative number */ ma->game.flag = -flag; - id_us_min((ID *)ma); + id_us_min((ID *)ma); } else printf("Error: Unable to create Material \"%s\" for Mesh \"%s\".", idname + 2, me->id.name + 2); } /* set as converted, no need to go bad to this face */ - tf->mode |= TF_CONVERTED; + tf->mode |= TF_CONVERTED; return mat_nr; } @@ -1845,7 +1857,7 @@ static void convert_tfacematerial(Main *main, Material *ma) if (mat_new) { /* rename the material*/ strcpy(mat_new->id.name, idname); - id_us_min((ID *)mat_new); + id_us_min((ID *)mat_new); mat_nr = mesh_addmaterial(me, mat_new); decode_tfaceflag(mat_new, flag, 1); @@ -2033,7 +2045,7 @@ int do_version_tface(Main *main, int fileload) nowarning = 0; } else - convert_tfacematerial(main, ma); continue; + convert_tfacematerial(main, ma); continue; } /* no conflicts in this material - 90% of cases diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c index 3925c3cc858..805e77cf84f 100644 --- a/source/blender/blenkernel/intern/mball.c +++ b/source/blender/blenkernel/intern/mball.c @@ -186,7 +186,7 @@ void BKE_mball_unlink(MetaBall *mb) /* do not free mball itself */ void BKE_mball_free(MetaBall *mb) { - BKE_mball_unlink(mb); + BKE_mball_unlink(mb); if (mb->adt) { BKE_free_animdata((ID *)mb); @@ -562,7 +562,7 @@ Object *BKE_mball_basis_find(Scene *scene, Object *basis) basis = ob; basisnr = obnr; } - } + } } } @@ -691,7 +691,7 @@ static float densfunc(MetaElem *ball, float x, float y, float z) /* *** end deprecated *** */ } - dist2 = 1.0f - (len_v3(dvec) / ball->rad2); + dist2 = 1.0f - (len_squared_v3(dvec) / ball->rad2); if ((ball->flag & MB_NEGATIVE) == 0) { return (dist2 < 0.0f) ? -0.5f : (ball->s * dist2 * dist2 * dist2) - 0.5f; @@ -732,7 +732,7 @@ static octal_node *find_metaball_octal_node(octal_node *node, float x, float y, return find_metaball_octal_node(node->nodes[2], x, y, z, depth--); else return node; - } + } } } else { @@ -762,7 +762,7 @@ static octal_node *find_metaball_octal_node(octal_node *node, float x, float y, return find_metaball_octal_node(node->nodes[6], x, y, z, depth--); else return node; - } + } } } @@ -861,7 +861,7 @@ static void *new_pgn_element(int size) } BLI_freelistN(&lb); - return NULL; + return NULL; } size = 4 * ( (size + 3) / 4); @@ -1319,12 +1319,16 @@ static void addtovertices(VERTICES *vertices, VERTEX v) static void vnormal(const float point[3], PROCESS *p, float r_no[3]) { - float delta = 0.2f * p->delta; - float f = p->function(point[0], point[1], point[2]); + const float delta = 0.2f * p->delta; + const float f = p->function(point[0], point[1], point[2]); r_no[0] = p->function(point[0] + delta, point[1], point[2]) - f; r_no[1] = p->function(point[0], point[1] + delta, point[2]) - f; r_no[2] = p->function(point[0], point[1], point[2] + delta) - f; + +#if 1 + normalize_v3(r_no); +#else f = normalize_v3(r_no); if (0) { @@ -1343,6 +1347,7 @@ static void vnormal(const float point[3], PROCESS *p, float r_no[3]) normalize_v3(r_no); } } +#endif } @@ -1500,7 +1505,7 @@ static void find_first_points(PROCESS *mbproc, MetaBall *mb, int a) float f = 0.0f; ml = G_mb.mainb[a]; - f = 1.0 - (mb->thresh / ml->s); + f = 1.0f - (mb->thresh / ml->s); /* Skip, when Stiffness of MetaElement is too small ... MetaElement can't be * visible alone ... but still can influence others MetaElements :-) */ @@ -1628,7 +1633,7 @@ static void polygonize(PROCESS *mbproc, MetaBall *mb) for (a = 0; a < G_mb.totelem; a++) { /* try to find 8 points on the surface for each MetaElem */ - find_first_points(mbproc, mb, a); + find_first_points(mbproc, mb, a); } /* polygonize all MetaElems of current MetaBall */ @@ -2038,7 +2043,7 @@ static void subdivide_metaball_octal_node(octal_node *node, float size_x, float } - /* ml belongs to the (4)5th node too */ + /* ml belongs to the (4)5th node too */ if (ml->bb->vec[6][2] >= z) { fill_metaball_octal_node(node, ml, 4); } @@ -2226,7 +2231,7 @@ static void init_metaball_octal_tree(int depth) } } - /* size of first node */ + /* size of first node */ size[0] = node->x_max - node->x_min; size[1] = node->y_max - node->y_min; size[2] = node->z_max - node->z_min; @@ -2388,7 +2393,7 @@ int BKE_mball_center_bounds(MetaBall *mb, float r_cent[3]) return 0; } -void BKE_mball_translate(MetaBall *mb, float offset[3]) +void BKE_mball_translate(MetaBall *mb, const float offset[3]) { MetaElem *ml; @@ -2396,3 +2401,32 @@ void BKE_mball_translate(MetaBall *mb, float offset[3]) add_v3_v3(&ml->x, offset); } } + +/* *** select funcs *** */ +void BKE_mball_select_all(struct MetaBall *mb) +{ + MetaElem *ml; + + for (ml = mb->editelems->first; ml; ml = ml->next) { + ml->flag |= SELECT; + } +} + +void BKE_mball_deselect_all(MetaBall *mb) +{ + MetaElem *ml; + + for (ml = mb->editelems->first; ml; ml = ml->next) { + ml->flag &= ~SELECT; + } +} + +void BKE_mball_select_swap(struct MetaBall *mb) +{ + MetaElem *ml; + + for (ml = mb->editelems->first; ml; ml = ml->next) { + ml->flag ^= SELECT; + } +} + diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index 8c3ec7e2e40..6d44473583f 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -367,7 +367,6 @@ void mesh_update_customdata_pointers(Mesh *me, const short do_ensure_tess_cd) me->mvert = CustomData_get_layer(&me->vdata, CD_MVERT); me->dvert = CustomData_get_layer(&me->vdata, CD_MDEFORMVERT); - me->msticky = CustomData_get_layer(&me->vdata, CD_MSTICKY); me->medge = CustomData_get_layer(&me->edata, CD_MEDGE); @@ -470,15 +469,17 @@ void free_dverts(MDeformVert *dvert, int totvert) static void mesh_tessface_clear_intern(Mesh *mesh, int free_customdata) { - if (free_customdata) + if (free_customdata) { CustomData_free(&mesh->fdata, mesh->totface); + } + else { + CustomData_reset(&mesh->fdata); + } mesh->mface = NULL; mesh->mtface = NULL; mesh->mcol = NULL; mesh->totface = 0; - - memset(&mesh->fdata, 0, sizeof(mesh->fdata)); } Mesh *BKE_mesh_add(const char *name) @@ -492,7 +493,13 @@ Mesh *BKE_mesh_add(const char *name) me->texflag = ME_AUTOSPACE; me->flag = ME_TWOSIDED; me->drawflag = ME_DRAWEDGES | ME_DRAWFACES | ME_DRAWCREASES; - + + CustomData_reset(&me->vdata); + CustomData_reset(&me->edata); + CustomData_reset(&me->fdata); + CustomData_reset(&me->pdata); + CustomData_reset(&me->ldata); + return me; } @@ -577,7 +584,7 @@ static void expand_local_mesh(Mesh *me) for (i = 0; i < me->pdata.totlayer; i++) { if (me->pdata.layers[i].type == CD_MTEXPOLY) { - MTexPoly *txface = (MTexPoly *)me->fdata.layers[i].data; + MTexPoly *txface = (MTexPoly *)me->pdata.layers[i].data; for (a = 0; a < me->totpoly; a++, txface++) { /* special case: ima always local immediately */ @@ -736,7 +743,7 @@ float *BKE_mesh_orco_verts_get(Object *ob) /* Get appropriate vertex coordinates */ vcos = MEM_callocN(sizeof(*vcos) * me->totvert, "orco mesh"); mvert = tme->mvert; - totvert = MIN2(tme->totvert, me->totvert); + totvert = min_ii(tme->totvert, me->totvert); for (a = 0; a < totvert; a++, mvert++) { copy_v3_v3(vcos[a], mvert->co); @@ -789,7 +796,7 @@ int test_index_face(MFace *mface, CustomData *fdata, int mfindex, int nr) nr--; } - /* check corrupt cases, bowtie geometry, cant handle these because edge data wont exist so just return 0 */ + /* check corrupt cases, bow-tie geometry, cant handle these because edge data wont exist so just return 0 */ if (nr == 3) { if ( /* real edges */ @@ -1865,7 +1872,7 @@ void BKE_mesh_calc_normals_mapping_ex(MVert *mverts, int numVerts, /* only calc poly normals */ mp = mpolys; for (i = 0; i < numPolys; i++, mp++) { - mesh_calc_poly_normal(mp, mloop + mp->loopstart, mverts, pnors[i]); + BKE_mesh_calc_poly_normal(mp, mloop + mp->loopstart, mverts, pnors[i]); } } @@ -1915,7 +1922,7 @@ void BKE_mesh_calc_normals(MVert *mverts, int numVerts, MLoop *mloop, MPoly *mpo mp = mpolys; for (i = 0; i < numPolys; i++, mp++) { - mesh_calc_poly_normal(mp, mloop + mp->loopstart, mverts, pnors[i]); + BKE_mesh_calc_poly_normal(mp, mloop + mp->loopstart, mverts, pnors[i]); ml = mloop + mp->loopstart; BLI_array_empty(vertcos); @@ -1944,8 +1951,9 @@ void BKE_mesh_calc_normals(MVert *mverts, int numVerts, MLoop *mloop, MPoly *mpo MVert *mv = &mverts[i]; float *no = tnorms[i]; - if (normalize_v3(no) == 0.0f) + if (UNLIKELY(normalize_v3(no) == 0.0f)) { normalize_v3_v3(no, mv->co); + } normal_float_to_short_v3(mv->no, no); } @@ -1981,8 +1989,9 @@ void BKE_mesh_calc_normals_tessface(MVert *mverts, int numVerts, MFace *mfaces, MVert *mv = &mverts[i]; float *no = tnorms[i]; - if (normalize_v3(no) == 0.0f) + if (UNLIKELY(normalize_v3(no) == 0.0f)) { normalize_v3_v3(no, mv->co); + } normal_float_to_short_v3(mv->no, no); } @@ -2038,11 +2047,11 @@ static void bm_corners_to_loops_ex(ID *id, CustomData *fdata, CustomData *ldata, MDisps *ld = CustomData_get(ldata, loopstart, CD_MDISPS); MDisps *fd = CustomData_get(fdata, findex, CD_MDISPS); float (*disps)[3] = fd->disps; - int i, tot = mf->v4 ? 4 : 3; + int tot = mf->v4 ? 4 : 3; int side, corners; if (CustomData_external_test(fdata, CD_MDISPS)) { - if (id) { + if (id && fdata->external) { CustomData_external_add(ldata, id, CD_MDISPS, totloop, fdata->external->filename); } @@ -2124,8 +2133,6 @@ void BKE_mesh_convert_mfaces_to_mpolys_ex(ID *id, CustomData *fdata, CustomData /* just in case some of these layers are filled in (can happen with python created meshes) */ CustomData_free(ldata, totloop_i); CustomData_free(pdata, totpoly_i); - memset(ldata, 0, sizeof(*ldata)); - memset(pdata, 0, sizeof(*pdata)); totpoly = totface_i; mpoly = MEM_callocN(sizeof(MPoly) * totpoly, "mpoly converted"); @@ -2162,7 +2169,7 @@ void BKE_mesh_convert_mfaces_to_mpolys_ex(ID *id, CustomData *fdata, CustomData me->flag &= ~ME_FGON; } - polyindex = CustomData_get_layer(fdata, CD_POLYINDEX); + polyindex = CustomData_get_layer(fdata, CD_ORIGINDEX); j = 0; /* current loop index */ ml = mloop; @@ -2504,12 +2511,9 @@ int BKE_mesh_recalc_tessellation(CustomData *fdata, ScanFillContext sf_ctx; ScanFillVert *sf_vert, *sf_vert_last, *sf_vert_first; ScanFillFace *sf_tri; - int *mface_orig_index = NULL; - BLI_array_declare(mface_orig_index); int *mface_to_poly_map = NULL; BLI_array_declare(mface_to_poly_map); int lindex[4]; /* only ever use 3 in this case */ - int *poly_orig_index; int poly_index, j, mface_index; const int numTex = CustomData_number_of_layers(pdata, CD_MTEXPOLY); @@ -2527,7 +2531,6 @@ int BKE_mesh_recalc_tessellation(CustomData *fdata, mface_index = 0; mp = mpoly; - poly_orig_index = CustomData_get_layer(pdata, CD_ORIGINDEX); for (poly_index = 0; poly_index < totpoly; poly_index++, mp++) { if (mp->totloop < 3) { /* do nothing */ @@ -2547,10 +2550,6 @@ int BKE_mesh_recalc_tessellation(CustomData *fdata, mf->v4 = 0; \ mf->mat_nr = mp->mat_nr; \ mf->flag = mp->flag; \ - if (poly_orig_index) { \ - BLI_array_append(mface_orig_index, \ - poly_orig_index[poly_index]); \ - } \ (void)0 /* ALMOST IDENTICAL TO DEFINE ABOVE (see EXCEPTION) */ @@ -2566,10 +2565,6 @@ int BKE_mesh_recalc_tessellation(CustomData *fdata, mf->v4 = mp->loopstart + 3; /* EXCEPTION */ \ mf->mat_nr = mp->mat_nr; \ mf->flag = mp->flag; \ - if (poly_orig_index) { \ - BLI_array_append(mface_orig_index, \ - poly_orig_index[poly_index]); \ - } \ mf->edcode |= TESSFACE_IS_QUAD; /* EXCEPTION */ \ (void)0 @@ -2616,9 +2611,6 @@ int BKE_mesh_recalc_tessellation(CustomData *fdata, if (totfilltri) { BLI_array_grow_items(mface_to_poly_map, totfilltri); BLI_array_grow_items(mface, totfilltri); - if (poly_orig_index) { - BLI_array_grow_items(mface_orig_index, totfilltri); - } for (sf_tri = sf_ctx.fillfacebase.first; sf_tri; sf_tri = sf_tri->next, mf++) { mface_to_poly_map[mface_index] = poly_index; @@ -2637,10 +2629,6 @@ int BKE_mesh_recalc_tessellation(CustomData *fdata, mf->edcode |= TESSFACE_SCANFILL; /* tag for sorting loop indices */ #endif - if (poly_orig_index) { - mface_orig_index[mface_index] = poly_orig_index[poly_index]; - } - mface_index++; } } @@ -2650,7 +2638,6 @@ int BKE_mesh_recalc_tessellation(CustomData *fdata, } CustomData_free(fdata, totface); - memset(fdata, 0, sizeof(CustomData)); totface = mface_index; @@ -2658,23 +2645,13 @@ int BKE_mesh_recalc_tessellation(CustomData *fdata, if (LIKELY((MEM_allocN_len(mface) / sizeof(*mface)) != totface)) { mface = MEM_reallocN(mface, sizeof(*mface) * totface); mface_to_poly_map = MEM_reallocN(mface_to_poly_map, sizeof(*mface_to_poly_map) * totface); - if (mface_orig_index) { - mface_orig_index = MEM_reallocN(mface_orig_index, sizeof(*mface_orig_index) * totface); - } } CustomData_add_layer(fdata, CD_MFACE, CD_ASSIGN, mface, totface); - /* CD_POLYINDEX will contain an array of indices from tessfaces to the polygons + /* CD_ORIGINDEX will contain an array of indices from tessfaces to the polygons * they are directly tessellated from */ - CustomData_add_layer(fdata, CD_POLYINDEX, CD_ASSIGN, mface_to_poly_map, totface); - if (mface_orig_index) { - /* If polys had a CD_ORIGINDEX layer, then the tessellated faces will get this - * layer as well, pointing to polys from the original mesh (not the polys - * that just got tessellated) */ - CustomData_add_layer(fdata, CD_ORIGINDEX, CD_ASSIGN, mface_orig_index, totface); - } - + CustomData_add_layer(fdata, CD_ORIGINDEX, CD_ASSIGN, mface_to_poly_map, totface); CustomData_from_bmeshpoly(fdata, pdata, ldata, totface); if (do_face_nor_cpy) { @@ -2805,7 +2782,6 @@ int BKE_mesh_mpoly_to_mface(struct CustomData *fdata, struct CustomData *ldata, } CustomData_free(fdata, totface); - memset(fdata, 0, sizeof(CustomData)); totface = k; @@ -2899,8 +2875,8 @@ static void mesh_calc_ngon_normal(MPoly *mpoly, MLoop *loopstart, } } -void mesh_calc_poly_normal(MPoly *mpoly, MLoop *loopstart, - MVert *mvarray, float no[3]) +void BKE_mesh_calc_poly_normal(MPoly *mpoly, MLoop *loopstart, + MVert *mvarray, float no[3]) { if (mpoly->totloop > 4) { mesh_calc_ngon_normal(mpoly, loopstart, mvarray, no); @@ -3015,7 +2991,7 @@ void BKE_mesh_calc_poly_center(MPoly *mpoly, MLoop *loopstart, /* note, passing polynormal is only a speedup so we can skip calculating it */ float BKE_mesh_calc_poly_area(MPoly *mpoly, MLoop *loopstart, - MVert *mvarray, float polynormal[3]) + MVert *mvarray, const float polynormal[3]) { if (mpoly->totloop == 3) { return area_tri_v3(mvarray[loopstart[0].v].co, @@ -3034,7 +3010,7 @@ float BKE_mesh_calc_poly_area(MPoly *mpoly, MLoop *loopstart, int i; MLoop *l_iter = loopstart; float area, polynorm_local[3], (*vertexcos)[3]; - float *no = polynormal ? polynormal : polynorm_local; + const float *no = polynormal ? polynormal : polynorm_local; BLI_array_fixedstack_declare(vertexcos, BM_NGON_STACK_SIZE, mpoly->totloop, __func__); /* pack vertex cos into an array for area_poly_v3 */ @@ -3044,7 +3020,7 @@ float BKE_mesh_calc_poly_area(MPoly *mpoly, MLoop *loopstart, /* need normal for area_poly_v3 as well */ if (polynormal == NULL) { - mesh_calc_poly_normal(mpoly, loopstart, mvarray, no); + BKE_mesh_calc_poly_normal(mpoly, loopstart, mvarray, polynorm_local); } /* finally calculate the area */ @@ -3174,6 +3150,32 @@ int BKE_mesh_center_bounds(Mesh *me, float cent[3]) return 0; } +int BKE_mesh_center_centroid(Mesh *me, float cent[3]) +{ + int i = me->totpoly; + MPoly *mpoly; + float poly_area; + float total_area = 0.0f; + float poly_cent[3]; + + zero_v3(cent); + + /* calculate a weighted average of polygon centroids */ + for (mpoly = me->mpoly; i--; mpoly++) { + BKE_mesh_calc_poly_center(mpoly, me->mloop + mpoly->loopstart, me->mvert, poly_cent); + poly_area = BKE_mesh_calc_poly_area(mpoly, me->mloop + mpoly->loopstart, me->mvert, NULL); + + madd_v3_v3fl(cent, poly_cent, poly_area); + total_area += poly_area; + } + /* otherwise we get NAN for 0 polys */ + if (me->totpoly) { + mul_v3_fl(cent, 1.0f / total_area); + } + + return (me->totpoly != 0); +} + void BKE_mesh_translate(Mesh *me, float offset[3], int do_keys) { int i = me->totvert; diff --git a/source/blender/blenkernel/intern/mesh_validate.c b/source/blender/blenkernel/intern/mesh_validate.c index 79e3fc19d20..128b9ae242e 100644 --- a/source/blender/blenkernel/intern/mesh_validate.c +++ b/source/blender/blenkernel/intern/mesh_validate.c @@ -228,7 +228,6 @@ int BKE_mesh_validate_arrays(Mesh *mesh, } for (i = 1; i < totvert; i++, mv++) { - int j; int fix_normal = TRUE; for (j = 0; j < 3; j++) { @@ -717,7 +716,6 @@ int BKE_mesh_validate_arrays(Mesh *mesh, MDeformVert *dv; for (i = 0, dv = dverts; i < totvert; i++, dv++) { MDeformWeight *dw; - unsigned int j; for (j = 0, dw = dv->dw; j < dv->totweight; j++, dw++) { /* note, greater then max defgroups is accounted for in our code, but not < 0 */ @@ -914,7 +912,7 @@ void BKE_mesh_calc_edges(Mesh *mesh, int update) { CustomData edata; EdgeHashIterator *ehi; - MPoly *mp = mesh->mpoly; + MPoly *mp; MEdge *med, *med_orig; EdgeHash *eh = BLI_edgehash_new(); int i, totedge, totpoly = mesh->totpoly; @@ -932,7 +930,7 @@ void BKE_mesh_calc_edges(Mesh *mesh, int update) } /* mesh loops (bmesh only) */ - for (i = 0; i < totpoly; i++, mp++) { + for (mp = mesh->mpoly, i = 0; i < totpoly; mp++, i++) { MLoop *l = &mesh->mloop[mp->loopstart]; int j, l_prev = (l + (mp->totloop - 1))->v; for (j = 0; j < mp->totloop; j++, l++) { @@ -946,7 +944,7 @@ void BKE_mesh_calc_edges(Mesh *mesh, int update) totedge = BLI_edgehash_size(eh); /* write new edges into a temporary CustomData */ - memset(&edata, 0, sizeof(edata)); + CustomData_reset(&edata); CustomData_add_layer(&edata, CD_MEDGE, CD_CALLOC, NULL, totedge); med = CustomData_get_layer(&edata, CD_MEDGE); @@ -970,8 +968,7 @@ void BKE_mesh_calc_edges(Mesh *mesh, int update) if (mesh->totpoly) { /* second pass, iterate through all loops again and assign * the newly created edges to them. */ - MPoly *mp = mesh->mpoly; - for (i = 0; i < mesh->totpoly; i++, mp++) { + for (mp = mesh->mpoly, i = 0; i < mesh->totpoly; mp++, i++) { MLoop *l = &mesh->mloop[mp->loopstart]; MLoop *l_prev = (l + (mp->totloop - 1)); int j; diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 65538e5bea2..9c7cbc42bdd 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -55,6 +55,8 @@ #include "BLI_linklist.h" #include "BLI_string.h" +#include "BLF_translation.h" + #include "BKE_cloth.h" #include "BKE_key.h" #include "BKE_multires.h" @@ -259,12 +261,13 @@ int modifier_nonGeometrical(ModifierData *md) return (mti->type == eModifierTypeType_NonGeometrical); } -void modifier_setError(ModifierData *md, const char *format, ...) +void modifier_setError(ModifierData *md, const char *_format, ...) { char buffer[512]; va_list ap; + const char *format = TIP_(_format); - va_start(ap, format); + va_start(ap, _format); vsnprintf(buffer, sizeof(buffer), format, ap); va_end(ap); buffer[sizeof(buffer) - 1] = '\0'; @@ -482,7 +485,7 @@ ModifierData *modifiers_getVirtualModifierList(Object *ob) } /* shape key modifier, not yet for curves */ - if (ELEM(ob->type, OB_MESH, OB_LATTICE) && ob_get_key(ob)) { + if (ELEM(ob->type, OB_MESH, OB_LATTICE) && BKE_key_from_object(ob)) { if (ob->type == OB_MESH && (ob->shapeflag & OB_SHAPE_EDIT_MODE)) smd.modifier.mode |= eModifierMode_Editmode | eModifierMode_OnCage; else @@ -494,8 +497,8 @@ ModifierData *modifiers_getVirtualModifierList(Object *ob) return md; } -/* Takes an object and returns its first selected armature, else just its - * armature + +/* Takes an object and returns its first selected armature, else just its armature * This should work for multiple armatures per object */ Object *modifiers_isDeformedByArmature(Object *ob) @@ -518,9 +521,8 @@ Object *modifiers_isDeformedByArmature(Object *ob) return NULL; } -/* Takes an object and returns its first selected lattice, else just its - * lattice - * This should work for multiple lattics per object +/* Takes an object and returns its first selected lattice, else just its lattice + * This should work for multiple lattices per object */ Object *modifiers_isDeformedByLattice(Object *ob) { @@ -542,7 +544,28 @@ Object *modifiers_isDeformedByLattice(Object *ob) return NULL; } - +/* Takes an object and returns its first selected curve, else just its curve + * This should work for multiple curves per object + */ +Object *modifiers_isDeformedByCurve(Object *ob) +{ + ModifierData *md = modifiers_getVirtualModifierList(ob); + CurveModifierData *cmd = NULL; + + /* return the first selected curve, this lets us use multiple curves */ + for (; md; md = md->next) { + if (md->type == eModifierType_Curve) { + cmd = (CurveModifierData *) md; + if (cmd->object && (cmd->object->flag & SELECT)) + return cmd->object; + } + } + + if (cmd) /* if were still here then return the last curve */ + return cmd->object; + + return NULL; +} int modifiers_usesArmature(Object *ob, bArmature *arm) { @@ -574,10 +597,12 @@ int modifiers_isCorrectableDeformed(Object *ob) ModifierData *md = modifiers_getVirtualModifierList(ob); for (; md; md = md->next) { - if (ob->mode == OB_MODE_EDIT && (md->mode & eModifierMode_Editmode) == 0) ; - else - if (modifier_isCorrectableDeformed(md)) + if (ob->mode == OB_MODE_EDIT && (md->mode & eModifierMode_Editmode) == 0) { + /* pass */ + } + else if (modifier_isCorrectableDeformed(md)) { return 1; + } } return 0; } diff --git a/source/blender/blenkernel/intern/modifiers_bmesh.c b/source/blender/blenkernel/intern/modifiers_bmesh.c index 72c3cda9272..98eac9b95af 100644 --- a/source/blender/blenkernel/intern/modifiers_bmesh.c +++ b/source/blender/blenkernel/intern/modifiers_bmesh.c @@ -49,12 +49,13 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) MLoop *mloop, *ml; BMVert *v, **vtable, **verts = NULL; BMEdge *e, **etable, **edges = NULL; - float has_face_normals; + float (*face_normals)[3]; BMFace *f; BMIter liter; BLI_array_declare(verts); BLI_array_declare(edges); int i, j, k, totvert, totedge /* , totface */ /* UNUSED */ ; + int is_init = (bm->totvert == 0) && (bm->totedge == 0) && (bm->totface == 0); /*merge custom data layout*/ CustomData_bmesh_merge(&dm->vertData, &bm->vdata, CD_MASK_DERIVEDMESH, CD_CALLOC, bm, BM_VERT); @@ -72,8 +73,8 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) BM_data_layer_add(bm, &bm->edata, CD_BWEIGHT); BM_data_layer_add(bm, &bm->vdata, CD_BWEIGHT); - vtable = MEM_callocN(sizeof(void **) * totvert, "vert table in BMDM_Copy"); - etable = MEM_callocN(sizeof(void **) * totedge, "edge table in BMDM_Copy"); + vtable = MEM_callocN(sizeof(void **) * totvert, __func__); + etable = MEM_callocN(sizeof(void **) * totedge, __func__); /*do verts*/ mv = mvert = dm->dupVertArray(dm); @@ -81,6 +82,7 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) v = BM_vert_create(bm, mv->co, NULL); normal_short_to_float_v3(v->no, mv->no); v->head.hflag = BM_vert_flag_from_mflag(mv->flag); + BM_elem_index_set(v, i); /* set_inline */ CustomData_to_bmesh_block(&dm->vertData, &bm->vdata, i, &v->head.data); @@ -89,13 +91,16 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) vtable[i] = v; } MEM_freeN(mvert); + if (is_init) bm->elem_index_dirty &= ~BM_VERT; /*do edges*/ me = medge = dm->dupEdgeArray(dm); for (i = 0; i < totedge; i++, me++) { + //BLI_assert(BM_edge_exists(vtable[me->v1], vtable[me->v2]) == NULL); e = BM_edge_create(bm, vtable[me->v1], vtable[me->v2], NULL, FALSE); e->head.hflag = BM_edge_flag_from_mflag(me->flag); + BM_elem_index_set(e, i); /* set_inline */ CustomData_to_bmesh_block(&dm->edgeData, &bm->edata, i, &e->head.data); etable[i] = e; @@ -106,11 +111,13 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) BM_elem_float_data_set(&bm->edata, e, CD_BWEIGHT, (float)me->bweight / 255.0f); } MEM_freeN(medge); + if (is_init) bm->elem_index_dirty &= ~BM_EDGE; - /*do faces*/ + /* do faces */ + /* note: i_alt is aligned with bmesh faces which may not always align with mpolys */ mp = dm->getPolyArray(dm); mloop = dm->getLoopArray(dm); - has_face_normals = CustomData_has_layer(&dm->polyData, CD_NORMAL); + face_normals = CustomData_get_layer(&dm->polyData, CD_NORMAL); /* can be NULL */ for (i = 0; i < dm->numPolyData; i++, mp++) { BMLoop *l; @@ -129,10 +136,12 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) f = BM_face_create_ngon(bm, verts[0], verts[1], edges, mp->totloop, FALSE); - if (!f) + if (UNLIKELY(f == NULL)) { continue; + } f->head.hflag = BM_face_flag_from_mflag(mp->flag); + BM_elem_index_set(f, bm->totface - 1); /* set_inline */ f->mat_nr = mp->mat_nr; l = BM_iter_new(&liter, bm, BM_LOOPS_OF_FACE, f); @@ -143,13 +152,14 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) CustomData_to_bmesh_block(&dm->polyData, &bm->pdata, i, &f->head.data); - if (has_face_normals) { - float *fno; - - fno = CustomData_bmesh_get(&bm->pdata, &f->head.data, CD_NORMAL); - copy_v3_v3(f->no, fno); + if (face_normals) { + copy_v3_v3(f->no, face_normals[i]); + } + else { + BM_face_normal_update(f); } } + if (is_init) bm->elem_index_dirty &= ~BM_FACE; MEM_freeN(vtable); MEM_freeN(etable); diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c index 97d4c150b84..6e8f2697ee1 100644 --- a/source/blender/blenkernel/intern/movieclip.c +++ b/source/blender/blenkernel/intern/movieclip.c @@ -52,6 +52,7 @@ #include "DNA_screen_types.h" #include "DNA_space_types.h" #include "DNA_movieclip_types.h" +#include "DNA_node_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" #include "DNA_view3d_types.h" @@ -71,6 +72,7 @@ #include "BKE_global.h" #include "BKE_main.h" #include "BKE_movieclip.h" +#include "BKE_node.h" #include "BKE_image.h" /* openanim */ #include "BKE_tracking.h" @@ -292,11 +294,11 @@ static void movieclip_calc_length(MovieClip *clip) clip->len = framenr + 1; } else { - for (;; ) { + for (;;) { get_sequence_fname(clip, framenr, name); if (!BLI_exists(name)) { - clip->len = framenr + 1; + clip->len = framenr; break; } @@ -518,6 +520,24 @@ static void movieclip_load_get_szie(MovieClip *clip) } } +static void detect_clip_source(MovieClip *clip) +{ + ImBuf *ibuf; + char name[FILE_MAX]; + + BLI_strncpy(name, clip->name, sizeof(name)); + BLI_path_abs(name, G.main->name); + + ibuf = IMB_testiffname(name, IB_rect | IB_multilayer); + if (ibuf) { + clip->source = MCLIP_SRC_SEQUENCE; + IMB_freeImBuf(ibuf); + } + else { + clip->source = MCLIP_SRC_MOVIE; + } +} + /* checks if image was already loaded, then returns same image * otherwise creates new. * does not load ibuf itself @@ -563,10 +583,7 @@ MovieClip *BKE_movieclip_file_add(const char *name) clip = movieclip_alloc(libname); BLI_strncpy(clip->name, name, sizeof(clip->name)); - if (BLI_testextensie_array(name, imb_ext_movie)) - clip->source = MCLIP_SRC_MOVIE; - else - clip->source = MCLIP_SRC_SEQUENCE; + detect_clip_source(clip); movieclip_load_get_szie(clip); if (clip->lastsize[0]) { @@ -614,34 +631,27 @@ static ImBuf *get_undistorted_ibuf(MovieClip *clip, struct MovieDistortion *dist else undistibuf = BKE_tracking_undistort_frame(&clip->tracking, ibuf, ibuf->x, ibuf->y, 0.0f); - if (undistibuf->userflags & IB_RECT_INVALID) { - ibuf->userflags &= ~IB_RECT_INVALID; - IMB_rect_from_float(undistibuf); - } - IMB_scaleImBuf(undistibuf, ibuf->x, ibuf->y); return undistibuf; } -static int need_undistortion_postprocess(MovieClipUser *user, int flag) +static int need_undistortion_postprocess(MovieClipUser *user) { int result = 0; /* only full undistorted render can be used as on-fly undistorting image */ - if (flag & MCLIP_USE_PROXY) { - result |= (user->render_size == MCLIP_PROXY_RENDER_SIZE_FULL) && - (user->render_flag & MCLIP_PROXY_RENDER_UNDISTORT) != 0; - } + result |= (user->render_size == MCLIP_PROXY_RENDER_SIZE_FULL) && + (user->render_flag & MCLIP_PROXY_RENDER_UNDISTORT) != 0; return result; } -static int need_postprocessed_frame(MovieClipUser *user, int flag, int postprocess_flag) +static int need_postprocessed_frame(MovieClipUser *user, int postprocess_flag) { int result = postprocess_flag; - result |= need_undistortion_postprocess(user, flag); + result |= need_undistortion_postprocess(user); return result; } @@ -688,7 +698,7 @@ static ImBuf *get_postprocessed_cached_frame(MovieClip *clip, MovieClipUser *use if (cache->postprocessed.flag != postprocess_flag) return NULL; - if (need_undistortion_postprocess(user, flag)) { + if (need_undistortion_postprocess(user)) { if (!check_undistortion_cache_flags(clip)) return NULL; } @@ -719,7 +729,7 @@ static ImBuf *put_postprocessed_frame_to_cache(MovieClip *clip, MovieClipUser *u cache->postprocessed.render_flag = 0; } - if (need_undistortion_postprocess(user, flag)) { + if (need_undistortion_postprocess(user)) { copy_v2_v2(cache->postprocessed.principal, camera->principal); copy_v3_v3(&cache->postprocessed.k1, &camera->k1); cache->postprocessed.undistortion_used = TRUE; @@ -763,7 +773,7 @@ static ImBuf *movieclip_get_postprocessed_ibuf(MovieClip *clip, MovieClipUser *u BLI_lock_thread(LOCK_MOVIECLIP); /* try to obtain cached postprocessed frame first */ - if (need_postprocessed_frame(user, flag, postprocess_flag)) { + if (need_postprocessed_frame(user, postprocess_flag)) { ibuf = get_postprocessed_cached_frame(clip, user, flag, postprocess_flag); if (!ibuf) @@ -1087,15 +1097,24 @@ void BKE_movieclip_reload(MovieClip *clip) clip->tracking.stabilization.ok = FALSE; /* update clip source */ - if (BLI_testextensie_array(clip->name, imb_ext_movie)) - clip->source = MCLIP_SRC_MOVIE; - else - clip->source = MCLIP_SRC_SEQUENCE; + detect_clip_source(clip); clip->lastsize[0] = clip->lastsize[1] = 0; movieclip_load_get_szie(clip); movieclip_calc_length(clip); + + /* same as for image update -- don't use notifiers because they are not 100% sure to succeeded + * (node trees which are not currently visible wouldn't be refreshed) + */ + { + Scene *scene; + for (scene = G.main->scene.first; scene; scene = scene->id.next) { + if (scene->nodetree) { + nodeUpdateID(scene->nodetree, &clip->id); + } + } + } } void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClipScopes *scopes) @@ -1326,6 +1345,11 @@ void BKE_movieclip_unlink(Main *bmain, MovieClip *clip) } } + { + bNodeTreeType *treetype = ntreeGetType(NTREE_COMPOSIT); + treetype->foreach_nodetree(bmain, (void *)clip, &BKE_node_tree_unlink_id_cb); + } + clip->id.us = 0; } diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c index 1c06d95a70b..66f2ff12258 100644 --- a/source/blender/blenkernel/intern/multires.c +++ b/source/blender/blenkernel/intern/multires.c @@ -666,7 +666,9 @@ static void multires_del_higher(MultiresModifierData *mmd, Object *ob, int lvl) mdisp->totdisp = totdisp; mdisp->level = lvl; - multires_grid_paint_mask_downsample(&gpm[g], lvl); + if (gpm) { + multires_grid_paint_mask_downsample(&gpm[g], lvl); + } } } } @@ -893,15 +895,16 @@ static void multires_subdivide(MultiresModifierData *mmd, Object *ob, int totlvl CCGKey highGridKey, lowGridKey; CCGSubSurf *ss; int i, numGrids, highGridSize; + int has_mask = CustomData_has_layer(&me->ldata, CD_GRID_PAINT_MASK); /* create subsurf DM from original mesh at high level */ cddm = CDDM_from_mesh(me, NULL); DM_set_only_copy(cddm, CD_MASK_BAREMESH); - highdm = subsurf_dm_create_local(ob, cddm, totlvl, simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv, TRUE); + highdm = subsurf_dm_create_local(ob, cddm, totlvl, simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv, has_mask); ss = ((CCGDerivedMesh *)highdm)->ss; /* create multires DM from original mesh at low level */ - lowdm = multires_dm_create_local(ob, cddm, lvl, lvl, simple, TRUE); + lowdm = multires_dm_create_local(ob, cddm, lvl, lvl, simple, has_mask); cddm->release(cddm); /* copy subsurf grids and replace them with low displaced grids */ @@ -1042,7 +1045,7 @@ static void multiresModifier_disp_run(DerivedMesh *dm, Mesh *me, DerivedMesh *dm k = 0; /*current loop/mdisp index within the mloop array*/ - #pragma omp parallel for private(i) if (totloop*gridSize*gridSize >= CCG_OMP_LIMIT) + #pragma omp parallel for private(i) if (totloop * gridSize * gridSize >= CCG_OMP_LIMIT) for (i = 0; i < totpoly; ++i) { const int numVerts = mpoly[i].totloop; @@ -1158,23 +1161,23 @@ void multires_modifier_update_mdisps(struct DerivedMesh *dm) int totlvl = ccgdm->multires.totlvl; if (lvl < totlvl) { - Mesh *me = ob->data; DerivedMesh *lowdm, *cddm, *highdm; CCGElem **highGridData, **lowGridData, **subGridData, **gridData, *diffGrid; CCGKey highGridKey, lowGridKey; CCGSubSurf *ss; int i, j, numGrids, highGridSize, lowGridSize; + int has_mask = CustomData_has_layer(&me->ldata, CD_GRID_PAINT_MASK); /* create subsurf DM from original mesh at high level */ if (ob->derivedDeform) cddm = CDDM_copy(ob->derivedDeform); else cddm = CDDM_from_mesh(me, NULL); DM_set_only_copy(cddm, CD_MASK_BAREMESH); - highdm = subsurf_dm_create_local(ob, cddm, totlvl, mmd->simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv, TRUE); + highdm = subsurf_dm_create_local(ob, cddm, totlvl, mmd->simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv, has_mask); ss = ((CCGDerivedMesh *)highdm)->ss; /* create multires DM from original mesh and displacements */ - lowdm = multires_dm_create_local(ob, cddm, lvl, totlvl, mmd->simple, TRUE); + lowdm = multires_dm_create_local(ob, cddm, lvl, totlvl, mmd->simple, has_mask); cddm->release(cddm); /* gather grid data */ @@ -1226,12 +1229,13 @@ void multires_modifier_update_mdisps(struct DerivedMesh *dm) } else { DerivedMesh *cddm, *subdm; + int has_mask = CustomData_has_layer(&me->ldata, CD_GRID_PAINT_MASK); if (ob->derivedDeform) cddm = CDDM_copy(ob->derivedDeform); else cddm = CDDM_from_mesh(me, NULL); DM_set_only_copy(cddm, CD_MASK_BAREMESH); - subdm = subsurf_dm_create_local(ob, cddm, mmd->totlvl, mmd->simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv, TRUE); + subdm = subsurf_dm_create_local(ob, cddm, mmd->totlvl, mmd->simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv, has_mask); cddm->release(cddm); multiresModifier_disp_run(dm, me, NULL, CALC_DISPLACEMENTS, subdm->getGridData(subdm), mmd->totlvl); @@ -1321,7 +1325,7 @@ void multires_set_space(DerivedMesh *dm, Object *ob, int from, int to) k = 0; /*current loop/mdisp index within the mloop array*/ - //#pragma omp parallel for private(i) if (dm->numLoopData*gridSize*gridSize >= CCG_OMP_LIMIT) + //#pragma omp parallel for private(i) if (dm->numLoopData * gridSize * gridSize >= CCG_OMP_LIMIT) for (i = 0; i < dm->numPolyData; ++i) { const int numVerts = mpoly[i].totloop; @@ -1626,7 +1630,7 @@ void multires_free(Multires *mr) } while (lvl) { - multires_free_level(lvl); + multires_free_level(lvl); lvl = lvl->next; } @@ -2081,8 +2085,8 @@ void multires_load_old(Object *ob, Mesh *me) CustomData_add_layer(&me->vdata, l->type, CD_REFERENCE, l->data, me->totvert); for (i = 0, l = me->mr->fdata.layers; i < me->mr->fdata.totlayer; ++i, ++l) CustomData_add_layer(&me->fdata, l->type, CD_REFERENCE, l->data, me->totface); - memset(&me->mr->vdata, 0, sizeof(CustomData)); - memset(&me->mr->fdata, 0, sizeof(CustomData)); + CustomData_reset(&me->mr->vdata); + CustomData_reset(&me->mr->fdata); multires_load_old_vcols(me); multires_load_old_face_flags(me); @@ -2107,7 +2111,7 @@ void multires_load_old(Object *ob, Mesh *me) * reference subsurfed dm with this option, before calling multiresModifier_disp_run(), * which implicitly expects both subsurfs from its first dm and oldGridData parameters to * be of the same "format"! */ - dm = multires_make_derived_from_derived(orig, mmd, ob, MULTIRES_ALLOC_PAINT_MASK); + dm = multires_make_derived_from_derived(orig, mmd, ob, 0); multires_load_old_dm(dm, me, mmd->totlvl + 1); @@ -2196,7 +2200,7 @@ static void multires_apply_smat(Scene *scene, Object *ob, float smat[3][3]) dGridSize = multires_side_tot[high_mmd.totlvl]; dSkip = (dGridSize - 1) / (gridSize - 1); - #pragma omp parallel for private(i) if (me->totface*gridSize*gridSize*4 >= CCG_OMP_LIMIT) + #pragma omp parallel for private(i) if (me->totface * gridSize * gridSize * 4 >= CCG_OMP_LIMIT) for (i = 0; i < me->totpoly; ++i) { const int numVerts = mpoly[i].totloop; MDisps *mdisp = &mdisps[mpoly[i].loopstart]; diff --git a/source/blender/blenkernel/intern/navmesh_conversion.c b/source/blender/blenkernel/intern/navmesh_conversion.c index a21878d1d7d..3bf5f863557 100644 --- a/source/blender/blenkernel/intern/navmesh_conversion.c +++ b/source/blender/blenkernel/intern/navmesh_conversion.c @@ -36,44 +36,44 @@ #include "DNA_meshdata_types.h" -#include "BKE_navmesh_conversion.h" -#include "BKE_cdderivedmesh.h" - #include "BLI_utildefines.h" #include "BLI_math.h" +#include "BKE_navmesh_conversion.h" +#include "BKE_cdderivedmesh.h" + #include "recast-capi.h" -BLI_INLINE float area2(const float* a, const float* b, const float* c) +BLI_INLINE float area2(const float *a, const float *b, const float *c) { return (b[0] - a[0]) * (c[2] - a[2]) - (c[0] - a[0]) * (b[2] - a[2]); } -BLI_INLINE int left(const float* a, const float* b, const float* c) +BLI_INLINE int left(const float *a, const float *b, const float *c) { return area2(a, b, c) < 0; } -int polyNumVerts(const unsigned short* p, const int vertsPerPoly) +int polyNumVerts(const unsigned short *p, const int vertsPerPoly) { int i, nv = 0; - for (i=0; i 0) + if (d > 0.0f) t /= d; - if (t < 0) - t = 0; - else if (t > 1) - t = 1; - dx[0] = a[0] + t*abx[0] - point[0]; - dx[2] = a[2] + t*abx[2] - point[2]; - - return dx[0]*dx[0] + dx[2]*dx[2]; + if (t < 0.0f) + t = 0.0f; + else if (t > 1.0f) + t = 1.0f; + dx[0] = a[0] + t * abx[0] - point[0]; + dx[2] = a[2] + t * abx[2] - point[2]; + + return dx[0] * dx[0] + dx[2] * dx[2]; } -int buildRawVertIndicesData(DerivedMesh* dm, int *nverts_r, float **verts_r, - int *ntris_r, unsigned short **tris_r, int **trisToFacesMap_r, - int **recastData) +int buildRawVertIndicesData(DerivedMesh *dm, int *nverts_r, float **verts_r, + int *ntris_r, unsigned short **tris_r, int **trisToFacesMap_r, + int **recastData) { int vi, fi, triIdx; int nverts, ntris; @@ -117,49 +118,49 @@ int buildRawVertIndicesData(DerivedMesh* dm, int *nverts_r, float **verts_r, MFace *faces; nverts = dm->getNumVerts(dm); - if (nverts>=0xffff) { + if (nverts >= 0xffff) { printf("Converting navmesh: Error! Too many vertices. Max number of vertices %d\n", 0xffff); return 0; } - verts = MEM_callocN(sizeof(float)*3*nverts, "buildRawVertIndicesData verts"); + verts = MEM_callocN(sizeof(float) * 3 * nverts, "buildRawVertIndicesData verts"); dm->getVertCos(dm, (float(*)[3])verts); - //flip coordinates - for (vi=0; vigetNumTessFaces(dm); faces = dm->getTessFaceArray(dm); ntris = nfaces; - for (fi=0; fiv4) ntris++; } - //copy and transform to triangles (reorder on the run) - trisToFacesMap = MEM_callocN(sizeof(int)*ntris, "buildRawVertIndicesData trisToFacesMap"); - tris = MEM_callocN(sizeof(unsigned short)*3*ntris, "buildRawVertIndicesData tris"); + /* copy and transform to triangles (reorder on the run) */ + trisToFacesMap = MEM_callocN(sizeof(int) * ntris, "buildRawVertIndicesData trisToFacesMap"); + tris = MEM_callocN(sizeof(unsigned short) * 3 * ntris, "buildRawVertIndicesData tris"); tri = tris; triIdx = 0; - for (fi=0; fiv1; - tri[3*triIdx+1] = (unsigned short) face->v3; - tri[3*triIdx+2] = (unsigned short) face->v2; - trisToFacesMap[triIdx++]=fi; + for (fi = 0; fi < nfaces; fi++) { + MFace *face = &faces[fi]; + tri[3 * triIdx + 0] = (unsigned short) face->v1; + tri[3 * triIdx + 1] = (unsigned short) face->v3; + tri[3 * triIdx + 2] = (unsigned short) face->v2; + trisToFacesMap[triIdx++] = fi; if (face->v4) { - tri[3*triIdx+0] = (unsigned short) face->v1; - tri[3*triIdx+1] = (unsigned short) face->v4; - tri[3*triIdx+2] = (unsigned short) face->v3; - trisToFacesMap[triIdx++]=fi; + tri[3 * triIdx + 0] = (unsigned short) face->v1; + tri[3 * triIdx + 1] = (unsigned short) face->v4; + tri[3 * triIdx + 2] = (unsigned short) face->v3; + trisToFacesMap[triIdx++] = fi; } } - //carefully, recast data is just reference to data in derived mesh - *recastData = (int*)CustomData_get_layer(&dm->polyData, CD_RECAST); + /* carefully, recast data is just reference to data in derived mesh */ + *recastData = (int *)CustomData_get_layer(&dm->polyData, CD_RECAST); *nverts_r = nverts; *verts_r = verts; @@ -170,122 +171,122 @@ int buildRawVertIndicesData(DerivedMesh* dm, int *nverts_r, float **verts_r, return 1; } -int buildPolygonsByDetailedMeshes(const int vertsPerPoly, const int npolys, - unsigned short* polys, const unsigned short* dmeshes, - const float* verts, const unsigned short* dtris, - const int* dtrisToPolysMap) +int buildPolygonsByDetailedMeshes(const int vertsPerPoly, const int npolys, + unsigned short *polys, const unsigned short *dmeshes, + const float *verts, const unsigned short *dtris, + const int *dtrisToPolysMap) { int polyidx; int capacity = vertsPerPoly; - unsigned short* newPoly = MEM_callocN(sizeof(unsigned short)*capacity, "buildPolygonsByDetailedMeshes newPoly"); - memset(newPoly, 0xff, sizeof(unsigned short)*capacity); + unsigned short *newPoly = MEM_callocN(sizeof(unsigned short) * capacity, "buildPolygonsByDetailedMeshes newPoly"); + memset(newPoly, 0xff, sizeof(unsigned short) * capacity); - for (polyidx=0; polyidxtolerance) + if (distSq > tolerance) adjustedPoly[adjustedNv++] = cur; } - memcpy(newPoly, adjustedPoly, adjustedNv*sizeof(unsigned short)); + memcpy(newPoly, adjustedPoly, adjustedNv * sizeof(unsigned short)); MEM_freeN(adjustedPoly); nv = adjustedNv; allBorderTraversed = 1; - for (i=0; irecastData[((struct SortContext *)ctx)->trisToFacesMap[*(int*)a]] - - ((struct SortContext *)ctx)->recastData[((struct SortContext *)ctx)->trisToFacesMap[*(int*)b]] ); + return (((struct SortContext *)ctx)->recastData[((struct SortContext *)ctx)->trisToFacesMap[*(int *)a]] - + ((struct SortContext *)ctx)->recastData[((struct SortContext *)ctx)->trisToFacesMap[*(int *)b]]); } -int buildNavMeshData(const int nverts, const float* verts, +int buildNavMeshData(const int nverts, const float *verts, const int ntris, const unsigned short *tris, - const int* recastData, const int* trisToFacesMap, + const int *recastData, const int *trisToFacesMap, int *ndtris_r, unsigned short **dtris_r, int *npolys_r, unsigned short **dmeshes_r, unsigned short **polys_r, int *vertsPerPoly_r, int **dtrisToPolysMap_r, int **dtrisToTrisMap_r) @@ -333,86 +333,86 @@ int buildNavMeshData(const int nverts, const float* verts, return 0; } - trisMapping = MEM_callocN(sizeof(int)*ntris, "buildNavMeshData trisMapping"); + trisMapping = MEM_callocN(sizeof(int) * ntris, "buildNavMeshData trisMapping"); - //sort the triangles by polygon idx - for (i=0; i0) { + for (i = 0; i < ntris; i++) { + if (recastData[trisToFacesMap[trisMapping[i]]] > 0) { validTriStart = i; break; } } - if (validTriStart<0) { + if (validTriStart < 0) { printf("Converting navmesh: Error! No valid polygons in mesh\n"); MEM_freeN(trisMapping); return 0; } - ndtris = ntris-validTriStart; - //fill dtris to faces mapping - dtrisToTrisMap = MEM_callocN(sizeof(int)*ndtris, "buildNavMeshData dtrisToTrisMap"); - memcpy(dtrisToTrisMap, &trisMapping[validTriStart], ndtris*sizeof(int)); + ndtris = ntris - validTriStart; + /* fill dtris to faces mapping */ + dtrisToTrisMap = MEM_callocN(sizeof(int) * ndtris, "buildNavMeshData dtrisToTrisMap"); + memcpy(dtrisToTrisMap, &trisMapping[validTriStart], ndtris * sizeof(int)); MEM_freeN(trisMapping); - //create detailed mesh triangles - copy only valid triangles - //and reserve memory for adjacency info - dtris = MEM_callocN(sizeof(unsigned short)*3*2*ndtris, "buildNavMeshData dtris"); - memset(dtris, 0xffff, sizeof(unsigned short)*3*2*ndtris); - for (i=0; iactstart; } else { - /* - the 'fmod(..., actlength*scale)' is needed to get the repeats working + /* - the 'fmod(..., actlength * scale)' is needed to get the repeats working * - the '/ scale' is needed to ensure that scaling influences the timing within the repeat */ return strip->actend - fmodf(cframe - strip->start, actlength * scale) / scale; @@ -446,7 +446,7 @@ static float nlastrip_get_frame_actionclip(NlaStrip *strip, float cframe, short return strip->actend; } else { - /* - the 'fmod(..., actlength*scale)' is needed to get the repeats working + /* - the 'fmod(..., actlength * scale)' is needed to get the repeats working * - the '/ scale' is needed to ensure that scaling influences the timing within the repeat */ return strip->actstart + fmodf(cframe - strip->start, actlength * scale) / scale; @@ -496,7 +496,7 @@ float nlastrip_get_frame(NlaStrip *strip, float cframe, short mode) case NLASTRIP_TYPE_CLIP: /* action-clip (default) */ default: return nlastrip_get_frame_actionclip(strip, cframe, mode); - } + } } @@ -1162,7 +1162,7 @@ static short nlastrip_is_first(AnimData *adt, NlaStrip *strip) if (ns->start < strip->start) return 0; } - } + } /* should be first now */ return 1; @@ -1491,7 +1491,7 @@ void BKE_nla_action_pushdown(AnimData *adt) /* add a new NLA strip to the track, which references the active action */ strip = add_nlastrip_to_stack(adt, adt->action); - /* do other necessary work on strip */ + /* do other necessary work on strip */ if (strip) { /* clear reference to action now that we've pushed it onto the stack */ id_us_min(&adt->action->id); @@ -1545,7 +1545,7 @@ short BKE_nla_tweakmode_enter(AnimData *adt) /* now try to find active strip */ activeStrip = BKE_nlastrip_find_active(nlt); break; - } + } } /* There are situations where we may have multiple strips selected and we want to enter tweakmode on all @@ -1563,7 +1563,7 @@ short BKE_nla_tweakmode_enter(AnimData *adt) activeStrip = BKE_nlastrip_find_active(nlt); break; } - } + } } if ((activeTrack) && (activeStrip == NULL)) { /* no active strip in active or last selected track; compromise for first selected (assuming only single)... */ diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index ade418e409f..153eb5271c5 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -147,6 +147,7 @@ static bNodeSocket *make_socket(bNodeTree *UNUSED(ntree), int in_out, const char sock->limit = (in_out == SOCK_IN ? 1 : 0xFFF); sock->type = type; sock->storage = NULL; + sock->flag |= SOCK_COLLAPSED; sock->default_value = node_socket_make_default_value(type); node_socket_init_default_value(type, sock->default_value); @@ -326,10 +327,13 @@ bNode *nodeAddNode(bNodeTree *ntree, struct bNodeTemplate *ntemp) ntype->initfunc(ntree, node, ntemp); /* initialize the node name with the node label. - * note: do this after the initfunc so nodes get - * their data set which may be used in naming + * note: do this after the initfunc so nodes get their data set which may be used in naming * (node groups for example) */ - BLI_strncpy(node->name, nodeLabel(node), NODE_MAXSTR); + /* XXX Do not use nodeLabel() here, it returns translated content, which should *only* be used + * in UI, *never* in data... + * This solution may be a bit rougher than nodeLabel()'s returned string, but it's simpler + * than adding a "no translate" flag to this func (and labelfunc() as well). */ + BLI_strncpy(node->name, node->typeinfo->name, NODE_MAXSTR); nodeUniqueName(ntree, node); ntree->update |= NTREE_UPDATE_NODES; @@ -343,6 +347,7 @@ bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node) { bNode *nnode = MEM_callocN(sizeof(bNode), "dupli node"); bNodeSocket *sock, *oldsock; + bNodeLink *link, *oldlink; *nnode = *node; /* can be called for nodes outside a node tree (e.g. clipboard) */ @@ -382,6 +387,15 @@ bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node) sock->cache = NULL; } + BLI_duplicatelist(&nnode->internal_links, &node->internal_links); + oldlink = node->internal_links.first; + for (link = nnode->internal_links.first; link; link = link->next, oldlink = oldlink->next) { + link->fromnode = nnode; + link->tonode = nnode; + link->fromsock = link->fromsock->new_sock; + link->tosock = link->tosock->new_sock; + } + /* don't increase node->id users, freenode doesn't decrement either */ if (node->typeinfo->copystoragefunc) @@ -389,7 +403,17 @@ bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node) node->new_node = nnode; nnode->new_node = NULL; - nnode->preview = NULL; + + /* only shader nodes get pleasant preview updating this way, compo uses own system */ + if (node->preview) { + if (ntree->type == NTREE_SHADER) { + nnode->preview = MEM_dupallocN(node->preview); + if (node->preview->rect) + nnode->preview->rect = MEM_dupallocN(node->preview->rect); + } + else + nnode->preview = NULL; + } if (ntree) ntree->update |= NTREE_UPDATE_NODES; @@ -520,15 +544,12 @@ void nodeRemSocketLinks(bNodeTree *ntree, bNodeSocket *sock) void nodeInternalRelink(bNodeTree *ntree, bNode *node) { bNodeLink *link, *link_next; - ListBase intlinks; - if (!node->typeinfo->internal_connect) + if (node->internal_links.first == NULL) return; - intlinks = node->typeinfo->internal_connect(ntree, node); - /* store link pointers in output sockets, for efficient lookup */ - for (link = intlinks.first; link; link = link->next) + for (link = node->internal_links.first; link; link = link->next) link->tosock->link = link; /* redirect downstream links */ @@ -562,8 +583,6 @@ void nodeInternalRelink(bNodeTree *ntree, bNode *node) if (link->tonode == node) nodeRemLink(ntree, link); } - - BLI_freelistN(&intlinks); } void nodeToView(bNode *node, float x, float y, float *rx, float *ry) @@ -710,7 +729,7 @@ static bNodeTree *ntreeCopyTree_internal(bNodeTree *ntree, const short do_id_use } node->new_node = NULL; - /* nnode= */ nodeCopyNode(newtree, node); /* sets node->new */ + /* nnode = */ nodeCopyNode(newtree, node); /* sets node->new */ /* make sure we don't copy new nodes again! */ if (node == last) @@ -815,7 +834,7 @@ void nodeFreePreview(bNode *node) MEM_freeN(node->preview->rect); MEM_freeN(node->preview); node->preview = NULL; - } + } } static void node_init_preview(bNode *node, int xsize, int ysize) @@ -858,7 +877,7 @@ void ntreeInitPreview(bNodeTree *ntree, int xsize, int ysize) node_init_preview(node, xsize, ysize); if (node->type == NODE_GROUP && (node->flag & NODE_GROUP_EDIT)) ntreeInitPreview((bNodeTree *)node->id, xsize, ysize); - } + } } static void nodeClearPreview(bNode *node) @@ -880,13 +899,13 @@ void ntreeClearPreview(bNodeTree *ntree) nodeClearPreview(node); if (node->type == NODE_GROUP && (node->flag & NODE_GROUP_EDIT)) ntreeClearPreview((bNodeTree *)node->id); - } + } } /* hack warning! this function is only used for shader previews, and * since it gets called multiple times per pixel for Ztransp we only * add the color once. Preview gets cleared before it starts render though */ -void nodeAddToPreview(bNode *node, float col[4], int x, int y, int do_manage) +void nodeAddToPreview(bNode *node, const float col[4], int x, int y, int do_manage) { bNodePreview *preview = node->preview; if (preview) { @@ -985,6 +1004,8 @@ void nodeFreeNode(bNodeTree *ntree, bNode *node) MEM_freeN(sock); } + BLI_freelistN(&node->internal_links); + nodeFreePreview(node); MEM_freeN(node); @@ -996,6 +1017,7 @@ void nodeFreeNode(bNodeTree *ntree, bNode *node) /* do not free ntree itself here, BKE_libblock_free calls this function too */ void ntreeFreeTree_ex(bNodeTree *ntree, const short do_id_user) { + bNodeTree *tntree; bNode *node, *next; bNodeSocket *sock; @@ -1030,9 +1052,18 @@ void ntreeFreeTree_ex(bNodeTree *ntree, const short do_id_user) next = node->next; /* ntreeUserIncrefID inline */ + + /* XXX, this is correct, however when freeing the entire database + * this ends up accessing freed data which isn't properly unlinking + * its self from scene nodes, SO - for now prefer invalid usercounts + * on free rather then bad memory access - Campbell */ +#if 0 if (do_id_user) { id_us_min(node->id); } +#else + (void)do_id_user; +#endif nodeFreeNode(ntree, node); } @@ -1043,6 +1074,14 @@ void ntreeFreeTree_ex(bNodeTree *ntree, const short do_id_user) for (sock = ntree->outputs.first; sock; sock = sock->next) node_socket_free_default_value(sock->type, sock->default_value); BLI_freelistN(&ntree->outputs); + + /* if ntree is not part of library, free the libblock data explicitly */ + for (tntree = G.main->nodetree.first; tntree; tntree = tntree->id.next) + if (tntree == ntree) + break; + if (tntree == NULL) { + BKE_libblock_free_data(&ntree->id); + } } /* same as ntreeFreeTree_ex but always manage users */ void ntreeFreeTree(bNodeTree *ntree) @@ -1545,11 +1584,11 @@ int BKE_node_clipboard_validate(void) /* lists must be aligned */ BLI_assert(BLI_countlist(&node_clipboard.nodes) == - BLI_countlist(&node_clipboard.nodes_extra_info)); + BLI_countlist(&node_clipboard.nodes_extra_info)); for (node = node_clipboard.nodes.first, node_info = node_clipboard.nodes_extra_info.first; - node; - node = node->next, node_info = node_info->next) + node; + node = node->next, node_info = node_info->next) { /* validate the node against the stored node info */ @@ -1629,21 +1668,21 @@ int BKE_node_clipboard_get_type(void) /* ************** dependency stuff *********** */ /* node is guaranteed to be not checked before */ -static int node_get_deplist_recurs(bNode *node, bNode ***nsort) +static int node_get_deplist_recurs(bNodeTree *ntree, bNode *node, bNode ***nsort) { bNode *fromnode; - bNodeSocket *sock; + bNodeLink *link; int level = 0xFFF; node->done = TRUE; /* check linked nodes */ - for (sock = node->inputs.first; sock; sock = sock->next) { - if (sock->link) { - fromnode = sock->link->fromnode; + for (link = ntree->links.first; link; link = link->next) { + if (link->tonode == node) { + fromnode = link->fromnode; if (fromnode) { if (fromnode->done == 0) - fromnode->level = node_get_deplist_recurs(fromnode, nsort); + fromnode->level = node_get_deplist_recurs(ntree, fromnode, nsort); if (fromnode->level <= level) level = fromnode->level - 1; } @@ -1653,7 +1692,7 @@ static int node_get_deplist_recurs(bNode *node, bNode ***nsort) /* check parent node */ if (node->parent) { if (node->parent->done == 0) - node->parent->level = node_get_deplist_recurs(node->parent, nsort); + node->parent->level = node_get_deplist_recurs(ntree, node->parent, nsort); if (node->parent->level <= level) level = node->parent->level - 1; } @@ -1687,7 +1726,7 @@ void ntreeGetDependencyList(struct bNodeTree *ntree, struct bNode ***deplist, in /* recursive check */ for (node = ntree->nodes.first; node; node = node->next) { if (node->done == 0) { - node->level = node_get_deplist_recurs(node, &nsort); + node->level = node_get_deplist_recurs(ntree, node, &nsort); } } } @@ -1705,7 +1744,7 @@ static void ntree_update_node_level(bNodeTree *ntree) /* recursive check */ for (node = ntree->nodes.first; node; node = node->next) { if (node->done == 0) { - node->level = node_get_deplist_recurs(node, NULL); + node->level = node_get_deplist_recurs(ntree, node, NULL); } } } @@ -1804,6 +1843,8 @@ void ntreeUpdateTree(bNodeTree *ntree) ntreetype->update_node(ntree, node); else if (node->typeinfo->updatefunc) node->typeinfo->updatefunc(ntree, node); + + nodeUpdateInternalLinks(ntree, node); } } @@ -1841,6 +1882,9 @@ void nodeUpdate(bNodeTree *ntree, bNode *node) ntreetype->update_node(ntree, node); else if (node->typeinfo->updatefunc) node->typeinfo->updatefunc(ntree, node); + + nodeUpdateInternalLinks(ntree, node); + /* clear update flag */ node->update = 0; } @@ -1880,9 +1924,21 @@ int nodeUpdateID(bNodeTree *ntree, ID *id) } } + for (node = ntree->nodes.first; node; node = node->next) { + nodeUpdateInternalLinks(ntree, node); + } + return change; } +void nodeUpdateInternalLinks(bNodeTree *ntree, bNode *node) +{ + BLI_freelistN(&node->internal_links); + + if (node->typeinfo && node->typeinfo->update_internal_links) + node->typeinfo->update_internal_links(ntree, node); +} + /* ************* node type access ********** */ @@ -1955,7 +2011,7 @@ void node_type_base(bNodeTreeType *ttype, bNodeType *ntype, int type, const char /* Default muting stuff. */ if (ttype) - ntype->internal_connect = ttype->internal_connect; + ntype->update_internal_links = ttype->update_internal_links; /* default size values */ ntype->width = 140; @@ -2051,9 +2107,9 @@ void node_type_exec_new(struct bNodeType *ntype, ntype->newexecfunc = newexecfunc; } -void node_type_internal_connect(bNodeType *ntype, ListBase (*internal_connect)(bNodeTree *, bNode *)) +void node_type_internal_links(bNodeType *ntype, void (*update_internal_links)(bNodeTree *, bNode *)) { - ntype->internal_connect = internal_connect; + ntype->update_internal_links = update_internal_links; } void node_type_gpu(struct bNodeType *ntype, int (*gpufunc)(struct GPUMaterial *mat, struct bNode *node, struct GPUNodeStack *in, struct GPUNodeStack *out)) @@ -2186,6 +2242,7 @@ static void registerCompositNodes(bNodeTreeType *ttype) register_node_type_cmp_bokehimage(ttype); register_node_type_cmp_bokehblur(ttype); register_node_type_cmp_switch(ttype); + register_node_type_cmp_pixelate(ttype); register_node_type_cmp_mask(ttype); register_node_type_cmp_trackpos(ttype); @@ -2234,8 +2291,11 @@ static void registerShaderNodes(bNodeTreeType *ttype) register_node_type_sh_layer_weight(ttype); register_node_type_sh_tex_coord(ttype); register_node_type_sh_particle_info(ttype); + register_node_type_sh_bump(ttype); + register_node_type_sh_script(ttype); register_node_type_sh_background(ttype); + register_node_type_sh_bsdf_anisotropic(ttype); register_node_type_sh_bsdf_diffuse(ttype); register_node_type_sh_bsdf_glossy(ttype); register_node_type_sh_bsdf_glass(ttype); diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 5ba56a85c72..0611e84bdf3 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -300,11 +300,11 @@ void BKE_object_free(Object *ob) BKE_object_free_display(ob); - /* disconnect specific data */ + /* disconnect specific data, but not for lib data (might be indirect data, can get relinked) */ if (ob->data) { ID *id = ob->data; id->us--; - if (id->us == 0) { + if (id->us == 0 && id->lib == NULL) { switch (ob->type) { case OB_MESH: BKE_mesh_unlink((Mesh *)id); @@ -340,7 +340,7 @@ void BKE_object_free(Object *ob) BKE_pose_free(ob->pose); if (ob->mpath) animviz_free_motionpath(ob->mpath); - free_properties(&ob->prop); + BKE_bproperty_free_list(&ob->prop); BKE_object_free_modifiers(ob); free_sensors(&ob->sensors); @@ -454,7 +454,7 @@ void BKE_object_unlink(Object *ob) if (pchan->custom == ob) pchan->custom = NULL; } - } + } else if (ELEM(OB_MBALL, ob->type, obt->type)) { if (BKE_mball_is_basis_for(obt, ob)) obt->recalc |= OB_RECALC_DATA; @@ -689,8 +689,8 @@ void BKE_object_unlink(Object *ob) if (so->treestore) { TreeStoreElem *tselem = so->treestore->data; - int a; - for (a = 0; a < so->treestore->usedelem; a++, tselem++) { + int i; + for (i = 0; i < so->treestore->usedelem; i++, tselem++) { if (tselem->id == (ID *)ob) tselem->id = NULL; } } @@ -854,7 +854,9 @@ Object *BKE_object_add_only_object(int type, const char *name) ob->step_height = 0.15f; ob->jump_speed = 10.0f; ob->fall_speed = 55.0f; - + ob->col_group = 0x01; + ob->col_mask = 0xff; + /* NT fluid sim defaults */ ob->fluidsimSettings = NULL; @@ -889,23 +891,44 @@ Object *BKE_object_add(struct Scene *scene, int type) return ob; } -SoftBody *copy_softbody(SoftBody *sb) +SoftBody *copy_softbody(SoftBody *sb, int copy_caches) { SoftBody *sbn; if (sb == NULL) return(NULL); sbn = MEM_dupallocN(sb); - sbn->totspring = sbn->totpoint = 0; - sbn->bpoint = NULL; - sbn->bspring = NULL; + + if (copy_caches == FALSE) { + sbn->totspring = sbn->totpoint = 0; + sbn->bpoint = NULL; + sbn->bspring = NULL; + } + else { + sbn->totspring = sb->totspring; + sbn->totpoint = sb->totpoint; + + if (sbn->bpoint) { + int i; + + sbn->bpoint = MEM_dupallocN(sbn->bpoint); + + for (i = 0; i < sbn->totpoint; i++) { + if (sbn->bpoint[i].springs) + sbn->bpoint[i].springs = MEM_dupallocN(sbn->bpoint[i].springs); + } + } + + if (sb->bspring) + sbn->bspring = MEM_dupallocN(sb->bspring); + } sbn->keys = NULL; sbn->totkey = sbn->totpointkey = 0; sbn->scratch = NULL; - sbn->pointcache = BKE_ptcache_copy_list(&sbn->ptcaches, &sb->ptcaches); + sbn->pointcache = BKE_ptcache_copy_list(&sbn->ptcaches, &sb->ptcaches, copy_caches); if (sb->effector_weights) sbn->effector_weights = MEM_dupallocN(sb->effector_weights); @@ -978,7 +1001,7 @@ static ParticleSystem *copy_particlesystem(ParticleSystem *psys) psysn->childcachebufs.first = psysn->childcachebufs.last = NULL; psysn->renderdata = NULL; - psysn->pointcache = BKE_ptcache_copy_list(&psysn->ptcaches, &psys->ptcaches); + psysn->pointcache = BKE_ptcache_copy_list(&psysn->ptcaches, &psys->ptcaches, FALSE); /* XXX - from reading existing code this seems correct but intended usage of * pointcache should /w cloth should be added in 'ParticleSystem' - campbell */ @@ -1039,7 +1062,7 @@ void BKE_object_copy_particlesystems(Object *obn, Object *ob) void BKE_object_copy_softbody(Object *obn, Object *ob) { if (ob->soft) - obn->soft = copy_softbody(ob->soft); + obn->soft = copy_softbody(ob->soft, FALSE); } static void copy_object_pose(Object *obn, Object *ob) @@ -1079,12 +1102,12 @@ static void copy_object_pose(Object *obn, Object *ob) } } -static int object_pose_context(Object *ob) +int BKE_object_pose_context_check(Object *ob) { - if ( (ob) && - (ob->type == OB_ARMATURE) && - (ob->pose) && - (ob->mode & OB_MODE_POSE)) + if ((ob) && + (ob->type == OB_ARMATURE) && + (ob->pose) && + (ob->mode & OB_MODE_POSE)) { return 1; } @@ -1098,12 +1121,12 @@ Object *BKE_object_pose_armature_get(Object *ob) if (ob == NULL) return NULL; - if (object_pose_context(ob)) + if (BKE_object_pose_context_check(ob)) return ob; ob = modifiers_isDeformedByArmature(ob); - if (object_pose_context(ob)) + if (BKE_object_pose_context_check(ob)) return ob; return NULL; @@ -1120,7 +1143,7 @@ void BKE_object_transform_copy(Object *ob_tar, const Object *ob_src) copy_v3_v3(ob_tar->size, ob_src->size); } -Object *BKE_object_copy(Object *ob) +static Object *object_copy_do(Object *ob, int copy_caches) { Object *obn; ModifierData *md; @@ -1147,7 +1170,7 @@ Object *BKE_object_copy(Object *ob) } obn->prop.first = obn->prop.last = NULL; - copy_properties(&obn->prop, &ob->prop); + BKE_bproperty_copy_list(&obn->prop, &ob->prop); copy_sensors(&obn->sensors, &ob->sensors); copy_controllers(&obn->controllers, &ob->controllers); @@ -1181,7 +1204,7 @@ Object *BKE_object_copy(Object *ob) if (obn->pd->rng) obn->pd->rng = MEM_dupallocN(ob->pd->rng); } - obn->soft = copy_softbody(ob->soft); + obn->soft = copy_softbody(ob->soft, copy_caches); obn->bsoft = copy_bulletsoftbody(ob->bsoft); BKE_object_copy_particlesystems(obn, ob); @@ -1197,6 +1220,18 @@ Object *BKE_object_copy(Object *ob) return obn; } +/* copy objects, will re-initialize cached simulation data */ +Object *BKE_object_copy(Object *ob) +{ + return object_copy_do(ob, FALSE); +} + +/* copy objects, will duplicate cached simulation data */ +Object *BKE_object_copy_with_caches(Object *ob) +{ + return object_copy_do(ob, TRUE); +} + static void extern_local_object(Object *ob) { ParticleSystem *psys; @@ -1748,7 +1783,7 @@ static void ob_parbone(Object *ob, Object *par, float mat[][4]) /* Make sure the bone is still valid */ pchan = BKE_pose_channel_find_name(par->pose, ob->parsubstr); - if (!pchan) { + if (!pchan || !pchan->bone) { printf("Object %s with Bone parent: bone %s doesn't exist\n", ob->id.name + 2, ob->parsubstr); unit_m4(mat); return; @@ -1766,7 +1801,6 @@ static void ob_parbone(Object *ob, Object *par, float mat[][4]) static void give_parvert(Object *par, int nr, float vec[3]) { BMEditMesh *em; - int a, count; zero_v3(vec); @@ -1795,18 +1829,28 @@ static void give_parvert(Object *par, int nr, float vec[3]) dm = (em) ? em->derivedFinal : par->derivedFinal; if (dm) { - MVert *mvert = dm->getVertArray(dm); - int *index = (int *)dm->getVertDataArray(dm, CD_ORIGINDEX); - int i, vindex, numVerts = dm->getNumVerts(dm); - - /* get the average of all verts with (original index == nr) */ - count = 0; - for (i = 0; i < numVerts; i++) { - vindex = (index) ? index[i] : i; - - if (vindex == nr) { - add_v3_v3(vec, mvert[i].co); - count++; + int count = 0; + int numVerts = dm->getNumVerts(dm); + + if (nr < numVerts) { + MVert *mvert = dm->getVertArray(dm); + int *index = (int *)dm->getVertDataArray(dm, CD_ORIGINDEX); + int i; + + /* get the average of all verts with (original index == nr) */ + if (index) { + for (i = 0; i < numVerts; i++) { + if (index[i] == nr) { + add_v3_v3(vec, mvert[i].co); + count++; + } + } + } + else { + if (nr < numVerts) { + add_v3_v3(vec, mvert[nr].co); + count++; + } } } @@ -1828,71 +1872,31 @@ static void give_parvert(Object *par, int nr, float vec[3]) } } else if (ELEM(par->type, OB_CURVE, OB_SURF)) { - Nurb *nu; - Curve *cu; - BPoint *bp; - BezTriple *bezt; - int found = 0; - ListBase *nurbs; - - cu = par->data; - nurbs = BKE_curve_nurbs_get(cu); - nu = nurbs->first; - - count = 0; - while (nu && !found) { - if (nu->type == CU_BEZIER) { - bezt = nu->bezt; - a = nu->pntsu; - while (a--) { - if (count == nr) { - found = 1; - copy_v3_v3(vec, bezt->vec[1]); - break; - } - count++; - bezt++; - } - } - else { - bp = nu->bp; - a = nu->pntsu * nu->pntsv; - while (a--) { - if (count == nr) { - found = 1; - copy_v3_v3(vec, bp->vec); - break; - } - count++; - bp++; - } - } - nu = nu->next; - } + Curve *cu = par->data; + ListBase *nurb = BKE_curve_nurbs_get(cu);; + BKE_nurbList_index_get_co(nurb, nr, vec); } else if (par->type == OB_LATTICE) { - Lattice *latt = par->data; - BPoint *bp; - DispList *dl = BKE_displist_find(&par->disp, DL_VERTS); - float *co = dl ? dl->verts : NULL; - + Lattice *latt = par->data; + DispList *dl = BKE_displist_find(&par->disp, DL_VERTS); + float (*co)[3] = dl ? (float (*)[3])dl->verts : NULL; + int tot; + if (latt->editlatt) latt = latt->editlatt->latt; - - a = latt->pntsu * latt->pntsv * latt->pntsw; - count = 0; - bp = latt->def; - while (a--) { - if (count == nr) { - if (co) - copy_v3_v3(vec, co); - else - copy_v3_v3(vec, bp->vec); - break; + + tot = latt->pntsu * latt->pntsv * latt->pntsw; + + /* ensure dl is correct size */ + BLI_assert(dl == NULL || dl->nr == tot); + + if (nr < tot) { + if (co) { + copy_v3_v3(vec, co[nr]); + } + else { + copy_v3_v3(vec, latt->def[nr].vec); } - count++; - if (co) co += 3; - else bp++; } } } @@ -2259,7 +2263,7 @@ void BKE_object_minmax(Object *ob, float min_r[3], float max_r[3], const short u Curve *cu = ob->data; /* Use the object bounding box so that modifier output - gets taken into account */ + * gets taken into account */ if (ob->bb) bb = *(ob->bb); else { @@ -2298,11 +2302,9 @@ void BKE_object_minmax(Object *ob, float min_r[3], float max_r[3], const short u bPoseChannel *pchan; for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { - - if ((use_hidden == FALSE) && (PBONE_VISIBLE(arm, pchan->bone) == FALSE)) { - /* pass */ - } - else { + /* XXX pchan->bone may be NULL for duplicated bones, see duplicateEditBoneObjects() comment + * (editarmature.c:2592)... Skip in this case too! */ + if (pchan->bone && !((use_hidden == FALSE) && (PBONE_VISIBLE(arm, pchan->bone) == FALSE))) { mul_v3_m4v3(vec, ob->obmat, pchan->pose_head); minmax_v3v3_v3(min_r, max_r, vec); mul_v3_m4v3(vec, ob->obmat, pchan->pose_tail); @@ -2360,7 +2362,7 @@ int BKE_object_minmax_dupli(Scene *scene, Object *ob, float r_min[3], float r_ma ListBase *lb; DupliObject *dob; - lb = object_duplilist(scene, ob); + lb = object_duplilist(scene, ob, FALSE); for (dob = lb->first; dob; dob = dob->next) { if ((use_hidden == FALSE) && (dob->no_draw != 0)) { /* pass */ @@ -2437,7 +2439,7 @@ void BKE_scene_foreach_display_point( ListBase *lb; DupliObject *dob; - lb = object_duplilist(scene, ob); + lb = object_duplilist(scene, ob, FALSE); for (dob = lb->first; dob; dob = dob->next) { if (dob->no_draw == 0) { BKE_object_foreach_display_point(dob->ob, dob->mat, func_cb, user_data); @@ -2571,9 +2573,7 @@ void BKE_object_handle_update(Scene *scene, Object *ob) if (ob->recalc & OB_RECALC_DATA) { ID *data_id = (ID *)ob->data; AnimData *adt = BKE_animdata_from_id(data_id); - float ctime = (float)scene->r.cfra; // XXX this is bad... - ListBase pidlist; - PTCacheID *pid; + float ctime = (float)scene->r.cfra; /* XXX this is bad... */ if (G.debug & G_DEBUG) printf("recalcdata %s\n", ob->id.name + 2); @@ -2696,26 +2696,8 @@ void BKE_object_handle_update(Scene *scene, Object *ob) psys_get_modifier(ob, psys)->flag &= ~eParticleSystemFlag_psys_updated; } } - - /* check if quick cache is needed */ - BKE_ptcache_ids_from_object(&pidlist, ob, scene, MAX_DUPLI_RECUR); - - for (pid = pidlist.first; pid; pid = pid->next) { - if ((pid->cache->flag & PTCACHE_BAKED) || - (pid->cache->flag & PTCACHE_QUICK_CACHE) == 0) - { - continue; - } - - if (pid->cache->flag & PTCACHE_OUTDATED || (pid->cache->flag & PTCACHE_SIMULATION_VALID) == 0) { - scene->physics_settings.quick_cache_step = - scene->physics_settings.quick_cache_step ? - mini(scene->physics_settings.quick_cache_step, pid->cache->step) : - pid->cache->step; - } - } - - BLI_freelistN(&pidlist); + + /* quick cache removed */ } /* the no-group proxy case, we call update */ @@ -2899,22 +2881,22 @@ static KeyBlock *insert_meshkey(Scene *scene, Object *ob, const char *name, int int newkey = 0; if (key == NULL) { - key = me->key = add_key((ID *)me); + key = me->key = BKE_key_add((ID *)me); key->type = KEY_RELATIVE; newkey = 1; } if (newkey || from_mix == FALSE) { /* create from mesh */ - kb = add_keyblock_ctime(key, name, FALSE); - mesh_to_key(me, kb); + kb = BKE_keyblock_add_ctime(key, name, FALSE); + BKE_key_convert_from_mesh(me, kb); } else { /* copy from current values */ float *data = do_ob_key(scene, ob); /* create new block with prepared data */ - kb = add_keyblock_ctime(key, name, FALSE); + kb = BKE_keyblock_add_ctime(key, name, FALSE); kb->data = data; kb->totelem = me->totvert; } @@ -2930,20 +2912,20 @@ static KeyBlock *insert_lattkey(Scene *scene, Object *ob, const char *name, int int newkey = 0; if (key == NULL) { - key = lt->key = add_key((ID *)lt); + key = lt->key = BKE_key_add((ID *)lt); key->type = KEY_RELATIVE; newkey = 1; } if (newkey || from_mix == FALSE) { - kb = add_keyblock_ctime(key, name, FALSE); + kb = BKE_keyblock_add_ctime(key, name, FALSE); if (!newkey) { KeyBlock *basekb = (KeyBlock *)key->block.first; kb->data = MEM_dupallocN(basekb->data); kb->totelem = basekb->totelem; } else { - latt_to_key(lt, kb); + BKE_key_convert_from_lattice(lt, kb); } } else { @@ -2951,7 +2933,7 @@ static KeyBlock *insert_lattkey(Scene *scene, Object *ob, const char *name, int float *data = do_ob_key(scene, ob); /* create new block with prepared data */ - kb = add_keyblock_ctime(key, name, FALSE); + kb = BKE_keyblock_add_ctime(key, name, FALSE); kb->totelem = lt->pntsu * lt->pntsv * lt->pntsw; kb->data = data; } @@ -2968,21 +2950,21 @@ static KeyBlock *insert_curvekey(Scene *scene, Object *ob, const char *name, int int newkey = 0; if (key == NULL) { - key = cu->key = add_key((ID *)cu); + key = cu->key = BKE_key_add((ID *)cu); key->type = KEY_RELATIVE; newkey = 1; } if (newkey || from_mix == FALSE) { /* create from curve */ - kb = add_keyblock_ctime(key, name, FALSE); + kb = BKE_keyblock_add_ctime(key, name, FALSE); if (!newkey) { KeyBlock *basekb = (KeyBlock *)key->block.first; kb->data = MEM_dupallocN(basekb->data); kb->totelem = basekb->totelem; } else { - curve_to_key(cu, kb, lb); + BKE_key_convert_from_curve(cu, kb, lb); } } else { @@ -2990,7 +2972,7 @@ static KeyBlock *insert_curvekey(Scene *scene, Object *ob, const char *name, int float *data = do_ob_key(scene, ob); /* create new block with prepared data */ - kb = add_keyblock_ctime(key, name, FALSE); + kb = BKE_keyblock_add_ctime(key, name, FALSE); kb->totelem = BKE_nurbList_verts_count(lb); kb->data = data; } @@ -3020,7 +3002,7 @@ int BKE_object_is_modified(Scene *scene, Object *ob) { int flag = 0; - if (ob_get_key(ob)) { + if (BKE_key_from_object(ob)) { flag |= eModifierMode_Render; } else { diff --git a/source/blender/blenkernel/intern/ocean.c b/source/blender/blenkernel/intern/ocean.c index 4f3921936e8..7bc736d394e 100644 --- a/source/blender/blenkernel/intern/ocean.c +++ b/source/blender/blenkernel/intern/ocean.c @@ -475,7 +475,7 @@ void BKE_ocean_eval_ij(struct Ocean *oc, struct OceanResult *ocr, int i, int j) if (oc->_do_normals) { ocr->normal[0] = oc->_N_x[i * oc->_N + j]; - ocr->normal[1] = oc->_N_y /*oc->_N_y[i*oc->_N+j] (MEM01)*/; + ocr->normal[1] = oc->_N_y /* oc->_N_y[i * oc->_N + j] (MEM01) */; ocr->normal[2] = oc->_N_z[i * oc->_N + j]; normalize_v3(ocr->normal); diff --git a/source/blender/blenkernel/intern/packedFile.c b/source/blender/blenkernel/intern/packedFile.c index 03342d0f6d1..dec49f417ae 100644 --- a/source/blender/blenkernel/intern/packedFile.c +++ b/source/blender/blenkernel/intern/packedFile.c @@ -201,7 +201,7 @@ PackedFile *newPackedFile(ReportList *reports, const char *filename, const char file = BLI_open(name, O_BINARY | O_RDONLY, 0); if (file <= 0) { - BKE_reportf(reports, RPT_ERROR, "Unable to pack file, source path not found: \"%s\"", name); + BKE_reportf(reports, RPT_ERROR, "Unable to pack file, source path '%s' not found", name); } else { filelen = BLI_file_descriptor_size(file); @@ -238,7 +238,8 @@ void packAll(Main *bmain, ReportList *reports) ima->packedfile = newPackedFile(reports, ima->name, ID_BLEND_PATH(bmain, &ima->id)); } else if (ELEM(ima->source, IMA_SRC_SEQUENCE, IMA_SRC_MOVIE)) { - BKE_reportf(reports, RPT_WARNING, "Image '%s' skipped, movies and image sequences not supported.", ima->id.name + 2); + BKE_reportf(reports, RPT_WARNING, "Image '%s' skipped, movies and image sequences not supported", + ima->id.name + 2); } } } @@ -310,20 +311,20 @@ int writePackedFile(ReportList *reports, const char *filename, PackedFile *pf, i file = BLI_open(name, O_BINARY + O_WRONLY + O_CREAT + O_TRUNC, 0666); if (file >= 0) { if (write(file, pf->data, pf->size) != pf->size) { - BKE_reportf(reports, RPT_ERROR, "Error writing file: %s", name); + BKE_reportf(reports, RPT_ERROR, "Error writing file '%s'", name); ret_value = RET_ERROR; } close(file); } else { - BKE_reportf(reports, RPT_ERROR, "Error creating file: %s", name); + BKE_reportf(reports, RPT_ERROR, "Error creating file '%s'", name); ret_value = RET_ERROR; } if (remove_tmp) { if (ret_value == RET_ERROR) { if (BLI_rename(tempname, name) != 0) { - BKE_reportf(reports, RPT_ERROR, "Error restoring tempfile. Check files: '%s' '%s'", tempname, name); + BKE_reportf(reports, RPT_ERROR, "Error restoring temp file (check files '%s' '%s')", tempname, name); } } else { diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c index 3267253e744..36f96045ced 100644 --- a/source/blender/blenkernel/intern/paint.c +++ b/source/blender/blenkernel/intern/paint.c @@ -36,6 +36,7 @@ #include "DNA_meshdata_types.h" #include "DNA_scene_types.h" #include "DNA_brush_types.h" +#include "DNA_space_types.h" #include "BLI_bitmap.h" #include "BLI_utildefines.h" @@ -87,6 +88,7 @@ Paint *paint_get_active(Scene *sce) Paint *paint_get_active_from_context(const bContext *C) { Scene *sce = CTX_data_scene(C); + SpaceImage *sima; if (sce) { ToolSettings *ts = sce->toolsettings; @@ -95,12 +97,12 @@ Paint *paint_get_active_from_context(const bContext *C) if (sce->basact && sce->basact->object) obact = sce->basact->object; - if (CTX_wm_space_image(C) != NULL) { + if ((sima = CTX_wm_space_image(C)) != NULL) { if (obact && obact->mode == OB_MODE_EDIT) { - if (ts->use_uv_sculpt) - return &ts->uvsculpt->paint; - else + if (sima->mode == SI_MODE_PAINT) return &ts->imapaint.paint; + else if (ts->use_uv_sculpt) + return &ts->uvsculpt->paint; } else { return &ts->imapaint.paint; @@ -190,7 +192,7 @@ void BKE_paint_free(Paint *paint) } /* called when copying scene settings, so even if 'src' and 'tar' are the same - * still do a id_us_plus(), rather then if we were copying betweem 2 existing + * still do a id_us_plus(), rather then if we were copying between 2 existing * scenes where a matching value should decrease the existing user count as * with paint_brush_set() */ void BKE_paint_copy(Paint *src, Paint *tar) diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 26952db8fba..d645204d29c 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -48,6 +48,7 @@ #include "DNA_dynamicpaint_types.h" #include "BLI_blenlib.h" +#include "BLI_noise.h" #include "BLI_math.h" #include "BLI_utildefines.h" #include "BLI_kdtree.h" @@ -97,8 +98,8 @@ int count_particles(ParticleSystem *psys) int tot = 0; LOOP_SHOWN_PARTICLES { - if (pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN) == 0) ; - else if (pa->alive == PARS_DEAD && (part->flag & PART_DIED) == 0) ; + if (pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN) == 0) {} + else if (pa->alive == PARS_DEAD && (part->flag & PART_DIED) == 0) {} else tot++; } return tot; @@ -110,13 +111,13 @@ int count_particles_mod(ParticleSystem *psys, int totgr, int cur) int tot = 0; LOOP_SHOWN_PARTICLES { - if (pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN) == 0) ; - else if (pa->alive == PARS_DEAD && (part->flag & PART_DIED) == 0) ; + if (pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN) == 0) {} + else if (pa->alive == PARS_DEAD && (part->flag & PART_DIED) == 0) {} else if (p % totgr == cur) tot++; } return tot; } -/* we allocate path cache memory in chunks instead of a big continguous +/* we allocate path cache memory in chunks instead of a big contiguous * chunk, windows' memory allocater fails to find big blocks of memory often */ #define PATH_CACHE_BUF_SIZE 1024 @@ -335,7 +336,7 @@ void psys_check_group_weights(ParticleSettings *part) BLI_addtail(&part->dupliweights, dw); } - go = go->next; + go = go->next; } dw = part->dupliweights.first; @@ -560,7 +561,7 @@ void psys_free(Object *ob, ParticleSystem *psys) ob->transflag &= ~OB_DUPLIPARTS; if (psys->part) { - psys->part->id.us--; + psys->part->id.us--; psys->part = NULL; } @@ -617,7 +618,10 @@ typedef struct ParticleRenderData { int do_simplify; int timeoffset; ParticleRenderElem *elems; - int *origindex; + + /* ORIGINDEX */ + const int *index_mf_to_mpoly; + const int *index_mp_to_orig; } ParticleRenderData; static float psys_render_viewport_falloff(double rate, float dist, float width) @@ -790,9 +794,13 @@ int psys_render_simplify_distribution(ParticleThreadContext *ctx, int tot) float *facearea, (*facecenter)[3], size[3], fac, powrate, scaleclamp; float co1[3], co2[3], co3[3], co4[3], lambda, arearatio, t, area, viewport; double vprate; - int *origindex, *facetotvert; + int *facetotvert; int a, b, totorigface, totface, newtot, skipped; + /* double lookup */ + const int *index_mf_to_mpoly; + const int *index_mp_to_orig; + if (part->ren_as != PART_DRAW_PATH || !(part->draw & PART_DRAW_REN_STRAND)) return tot; if (!ctx->sim.psys->renderdata) @@ -806,13 +814,18 @@ int psys_render_simplify_distribution(ParticleThreadContext *ctx, int tot) mvert = dm->getVertArray(dm); mface = dm->getTessFaceArray(dm); - origindex = dm->getTessFaceDataArray(dm, CD_ORIGINDEX); totface = dm->getNumTessFaces(dm); totorigface = me->totpoly; if (totface == 0 || totorigface == 0) return tot; + index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX); + index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX); + if ((index_mf_to_mpoly && index_mp_to_orig) == FALSE) { + index_mf_to_mpoly = index_mp_to_orig = NULL; + } + facearea = MEM_callocN(sizeof(float) * totorigface, "SimplifyFaceArea"); facecenter = MEM_callocN(sizeof(float[3]) * totorigface, "SimplifyFaceCenter"); facetotvert = MEM_callocN(sizeof(int) * totorigface, "SimplifyFaceArea"); @@ -823,20 +836,22 @@ int psys_render_simplify_distribution(ParticleThreadContext *ctx, int tot) data->do_simplify = TRUE; data->elems = elems; - data->origindex = origindex; + data->index_mf_to_mpoly = index_mf_to_mpoly; + data->index_mp_to_orig = index_mp_to_orig; /* compute number of children per original face */ for (a = 0; a < tot; a++) { - b = (origindex) ? origindex[ctx->index[a]] : ctx->index[a]; - if (b != -1) + b = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, ctx->index[a]) : ctx->index[a]; + if (b != ORIGINDEX_NONE) { elems[b].totchild++; + } } /* compute areas and centers of original faces */ for (mf = mface, a = 0; a < totface; a++, mf++) { - b = (origindex) ? origindex[a] : a; + b = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, a) : a; - if (b != -1) { + if (b != ORIGINDEX_NONE) { copy_v3_v3(co1, mvert[mf->v1].co); copy_v3_v3(co2, mvert[mf->v2].co); copy_v3_v3(co3, mvert[mf->v3].co); @@ -898,7 +913,7 @@ int psys_render_simplify_distribution(ParticleThreadContext *ctx, int tot) elem->scalemax = sqrt(elem->scalemax); /* clamp scaling */ - scaleclamp = MIN2(elem->totchild, 10.0f); + scaleclamp = (float)min_ii(elem->totchild, 10); elem->scalemin = MIN2(scaleclamp, elem->scalemin); elem->scalemax = MIN2(scaleclamp, elem->scalemax); @@ -930,8 +945,9 @@ int psys_render_simplify_distribution(ParticleThreadContext *ctx, int tot) skipped = 0; for (a = 0, newtot = 0; a < tot; a++) { - b = (origindex) ? origindex[ctx->index[a]] : ctx->index[a]; - if (b != -1) { + b = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, ctx->index[a]) : ctx->index[a]; + + if (b != ORIGINDEX_NONE) { if (elems[b].curchild++ < ceil(elems[b].lambda * elems[b].totchild)) { ctx->index[newtot] = ctx->index[a]; ctx->skip[newtot] = skipped; @@ -962,10 +978,10 @@ int psys_render_simplify_params(ParticleSystem *psys, ChildParticle *cpa, float data = psys->renderdata; if (!data->do_simplify) return 0; - - b = (data->origindex) ? data->origindex[cpa->num] : cpa->num; - if (b == -1) + b = (data->index_mf_to_mpoly) ? DM_origindex_mface_mpoly(data->index_mf_to_mpoly, data->index_mp_to_orig, cpa->num) : cpa->num; + if (b == ORIGINDEX_NONE) { return 0; + } elem = &data->elems[b]; @@ -1403,7 +1419,8 @@ static void interpolate_pathcache(ParticleCacheKey *first, float t, ParticleCach /************************************************/ /* interpolate a location on a face based on face coordinates */ void psys_interpolate_face(MVert *mvert, MFace *mface, MTFace *tface, float (*orcodata)[3], - float *w, float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor) + float w[4], float vec[3], float nor[3], float utan[3], float vtan[3], + float orco[3], float ornor[3]) { float *v1 = 0, *v2 = 0, *v3 = 0, *v4 = 0; float e1[3], e2[3], s1, s2, t1, t2; @@ -1622,17 +1639,22 @@ int psys_particle_dm_face_lookup(Object *ob, DerivedMesh *dm, int index, const f Mesh *me = (Mesh *)ob->data; MPoly *mpoly; OrigSpaceFace *osface; - int *origindex; int quad, findex, totface; float uv[2], (*faceuv)[2]; + /* double lookup */ + const int *index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX); + const int *index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX); + if ((index_mf_to_mpoly && index_mp_to_orig) == FALSE) { + index_mf_to_mpoly = index_mp_to_orig = NULL; + } + mpoly = dm->getPolyArray(dm); - origindex = dm->getTessFaceDataArray(dm, CD_ORIGINDEX); osface = dm->getTessFaceDataArray(dm, CD_ORIGSPACE); totface = dm->getNumTessFaces(dm); - if (osface == NULL || origindex == NULL) { + if (osface == NULL || index_mf_to_mpoly == NULL) { /* Assume we don't need osface data */ if (index < totface) { //printf("\tNO CD_ORIGSPACE, assuming not needed\n"); @@ -1666,7 +1688,8 @@ int psys_particle_dm_face_lookup(Object *ob, DerivedMesh *dm, int index, const f } else { /* if we have no node, try every face */ for (findex = 0; findex < totface; findex++) { - if (origindex[findex] == index) { + const int findex_orig = DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, findex); + if (findex_orig == index) { faceuv = osface[findex].uv; quad = (mpoly[findex].totloop == 4); @@ -1746,7 +1769,9 @@ static int psys_map_index_on_dm(DerivedMesh *dm, int from, int index, int index_ } /* interprets particle data to get a point on a mesh in object space */ -void psys_particle_on_dm(DerivedMesh *dm, int from, int index, int index_dmcache, const float fw[4], float foffset, float vec[3], float nor[3], float utan[3], float vtan[3], float orco[3], float ornor[3]) +void psys_particle_on_dm(DerivedMesh *dm, int from, int index, int index_dmcache, + const float fw[4], float foffset, float vec[3], float nor[3], float utan[3], float vtan[3], + float orco[3], float ornor[3]) { float tmpnor[3], mapfw[4]; float (*orcodata)[3]; @@ -1842,7 +1867,9 @@ ParticleSystemModifierData *psys_get_modifier(Object *ob, ParticleSystem *psys) /* Particles on a shape */ /************************************************/ /* ready for future use */ -static void psys_particle_on_shape(int UNUSED(distr), int UNUSED(index), float *UNUSED(fuv), float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor) +static void psys_particle_on_shape(int UNUSED(distr), int UNUSED(index), + float *UNUSED(fuv), float vec[3], float nor[3], float utan[3], float vtan[3], + float orco[3], float ornor[3]) { /* TODO */ float zerovec[3] = {0.0f, 0.0f, 0.0f}; @@ -1868,7 +1895,9 @@ static void psys_particle_on_shape(int UNUSED(distr), int UNUSED(index), float * /************************************************/ /* Particles on emitter */ /************************************************/ -void psys_particle_on_emitter(ParticleSystemModifierData *psmd, int from, int index, int index_dmcache, float *fuv, float foffset, float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor) +void psys_particle_on_emitter(ParticleSystemModifierData *psmd, int from, int index, int index_dmcache, + float fuv[4], float foffset, float vec[3], float nor[3], float utan[3], float vtan[3], + float orco[3], float ornor[3]) { if (psmd) { if (psmd->psys->part->distr == PART_DISTR_GRID && psmd->psys->part->from != PART_FROM_VERT) { @@ -2456,7 +2485,7 @@ static int psys_threads_init_path(ParticleThread *threads, Scene *scene, float c totthread = 1; for (i = 0; i < totthread; i++) { - threads[i].rng_path = rng_new(seed); + threads[i].rng_path = BLI_rng_new(seed); threads[i].tot = totthread; } @@ -3298,7 +3327,7 @@ void copy_particle_key(ParticleKey *to, ParticleKey *from, int time) to->time = to_time; } } -void psys_get_from_key(ParticleKey *key, float *loc, float *vel, float *rot, float *time) +void psys_get_from_key(ParticleKey *key, float loc[3], float vel[3], float rot[4], float *time) { if (loc) copy_v3_v3(loc, key->co); if (vel) copy_v3_v3(vel, key->vel); @@ -3776,7 +3805,7 @@ static void get_cpa_texture(DerivedMesh *dm, ParticleSystem *psys, ParticleSetti ptex->gravity = ptex->field = ptex->time = ptex->clump = ptex->kink = ptex->effector = ptex->rough1 = ptex->rough2 = ptex->roughe = 1.f; - ptex->length = 1.0f - part->randlength *PSYS_FRAND(child_index + 26); + ptex->length = 1.0f - part->randlength * PSYS_FRAND(child_index + 26); ptex->length *= part->clength_thres < PSYS_FRAND(child_index + 27) ? part->clength : 1.0f; for (m = 0; m < MAX_MTEX; m++, mtexp++) { @@ -3968,7 +3997,7 @@ float psys_get_child_size(ParticleSystem *psys, ChildParticle *cpa, float UNUSED size *= part->childsize; if (part->childrandsize != 0.0f) - size *= 1.0f - part->childrandsize *PSYS_FRAND(cpa - psys->child + 26); + size *= 1.0f - part->childrandsize * PSYS_FRAND(cpa - psys->child + 26); return size; } @@ -4319,7 +4348,7 @@ int psys_get_particle_state(ParticleSimulationData *sim, int p, ParticleKey *sta if (pa) { if (!always) { if ((cfra < pa->time && (part->flag & PART_UNBORN) == 0) || - (cfra > pa->dietime && (part->flag & PART_DIED) == 0)) + (cfra >= pa->dietime && (part->flag & PART_DIED) == 0)) { return 0; } @@ -4414,7 +4443,9 @@ int psys_get_particle_state(ParticleSimulationData *sim, int p, ParticleKey *sta } } -void psys_get_dupli_texture(ParticleSystem *psys, ParticleSettings *part, ParticleSystemModifierData *psmd, ParticleData *pa, ChildParticle *cpa, float *uv, float *orco) +void psys_get_dupli_texture(ParticleSystem *psys, ParticleSettings *part, + ParticleSystemModifierData *psmd, ParticleData *pa, ChildParticle *cpa, + float uv[2], float orco[3]) { MFace *mface; MTFace *mtface; @@ -4539,8 +4570,8 @@ void psys_make_billboard(ParticleBillboardData *bb, float xvec[3], float yvec[3] /* can happen with bad pointcache or physics calculation * since this becomes geometry, nan's and inf's crash raytrace code. * better not allow this. */ - if (!finite(bb->vec[0]) || !finite(bb->vec[1]) || !finite(bb->vec[2]) || - !finite(bb->vel[0]) || !finite(bb->vel[1]) || !finite(bb->vel[2]) ) + if ((!finite(bb->vec[0])) || (!finite(bb->vec[1])) || (!finite(bb->vec[2])) || + (!finite(bb->vel[0])) || (!finite(bb->vel[1])) || (!finite(bb->vel[2])) ) { zero_v3(bb->vec); zero_v3(bb->vel); diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 2c0452bc2d1..2b95946f571 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -346,7 +346,7 @@ void psys_calc_dmcache(Object *ob, DerivedMesh *dm, ParticleSystem *psys) if (!dm->deformedOnly) { /* Will use later to speed up subsurf/derivedmesh */ LinkNode *node, *nodedmelem, **nodearray; - int totdmelem, totelem, i, *origindex; + int totdmelem, totelem, i, *origindex, *origindex_poly = NULL; if (psys->part->from == PART_FROM_VERT) { totdmelem= dm->getNumVerts(dm); @@ -356,23 +356,37 @@ void psys_calc_dmcache(Object *ob, DerivedMesh *dm, ParticleSystem *psys) else { /* FROM_FACE/FROM_VOLUME */ totdmelem= dm->getNumTessFaces(dm); totelem= me->totpoly; - origindex= dm->getTessFaceDataArray(dm, CD_ORIGINDEX); + origindex = dm->getTessFaceDataArray(dm, CD_ORIGINDEX); + /* for face lookups we need the poly origindex too */ + origindex_poly = dm->getPolyDataArray(dm, CD_ORIGINDEX); + if (origindex_poly == NULL) { + origindex = NULL; + } } nodedmelem= MEM_callocN(sizeof(LinkNode)*totdmelem, "psys node elems"); nodearray= MEM_callocN(sizeof(LinkNode *)*totelem, "psys node array"); for (i=0, node=nodedmelem; ilink= SET_INT_IN_POINTER(i); + int origindex_final; + node->link = SET_INT_IN_POINTER(i); + + origindex_final = *origindex; - if (*origindex != -1) { - if (nodearray[*origindex]) { + /* if we have a poly source, do an index lookup */ + if (origindex_poly && origindex_final != ORIGINDEX_NONE) { + origindex_final = origindex_poly[origindex_final]; + } + + if (origindex_final != ORIGINDEX_NONE) { + if (nodearray[origindex_final]) { /* prepend */ - node->next = nodearray[*origindex]; - nodearray[*origindex]= node; + node->next = nodearray[origindex_final]; + nodearray[origindex_final] = node; + } + else { + nodearray[origindex_final] = node; } - else - nodearray[*origindex]= node; } } @@ -556,8 +570,7 @@ static void distribute_grid(DerivedMesh *dm, ParticleSystem *psys) else /* store number of intersections */ (pa+(int)(lambda*size[a])*a0mul)->hair_index++; } - - if (mface->v4) { + else if (mface->v4) { copy_v3_v3(v4, mvert[mface->v4].co); if (isect_axial_line_tri_v3(a, co1, co2, v4, v1, v3, &lambda)) { @@ -632,10 +645,10 @@ static void hammersley_create(float *out, int n, int seed, float amount) double p, t, offs[2]; int k, kk; - rng = rng_new(31415926 + n + seed); - offs[0]= rng_getDouble(rng) + (double)amount; - offs[1]= rng_getDouble(rng) + (double)amount; - rng_free(rng); + rng = BLI_rng_new(31415926 + n + seed); + offs[0] = BLI_rng_get_double(rng) + (double)amount; + offs[1] = BLI_rng_get_double(rng) + (double)amount; + BLI_rng_free(rng); for (k = 0; k < n; k++) { t = 0; @@ -643,8 +656,8 @@ static void hammersley_create(float *out, int n, int seed, float amount) if (kk & 1) /* kk mod 2 = 1 */ t += p; - out[2*k + 0]= fmod((double)k/(double)n + offs[0], 1.0); - out[2*k + 1]= fmod(t + offs[1], 1.0); + out[2*k + 0] = fmod((double)k/(double)n + offs[0], 1.0); + out[2*k + 1] = fmod(t + offs[1], 1.0); } } @@ -661,13 +674,13 @@ static void init_mv_jit(float *jit, int num, int seed2, float amount) rad2= (float)(1.0f/((float)num)); rad3= (float)sqrt((float)num)/((float)num); - rng = rng_new(31415926 + num + seed2); + rng = BLI_rng_new(31415926 + num + seed2); x= 0; num2 = 2 * num; for (i=0; ijitoff[i] = fmod(ctx->jitoff[i],(float)ctx->jitlevel); - psys_uv_to_w(ctx->jit[2*(int)ctx->jitoff[i]], ctx->jit[2*(int)ctx->jitoff[i]+1], mface->v4, pa->fuv); - ctx->jitoff[i]++; + if (!isnan(ctx->jitoff[i])) { + psys_uv_to_w(ctx->jit[2*(int)ctx->jitoff[i]], ctx->jit[2*(int)ctx->jitoff[i]+1], mface->v4, pa->fuv); + ctx->jitoff[i]++; + } } break; case PART_DISTR_RAND: - randu= rng_getFloat(thread->rng); - randv= rng_getFloat(thread->rng); + randu= BLI_rng_get_float(thread->rng); + randv= BLI_rng_get_float(thread->rng); rng_skip_tot -= 2; psys_uv_to_w(randu, randv, mface->v4, pa->fuv); @@ -879,8 +894,8 @@ static void distribute_threads_exec(ParticleThread *thread, ParticleData *pa, Ch mf= dm->getTessFaceData(dm, ctx->index[p], CD_MFACE); - randu= rng_getFloat(thread->rng); - randv= rng_getFloat(thread->rng); + randu= BLI_rng_get_float(thread->rng); + randv= BLI_rng_get_float(thread->rng); rng_skip_tot -= 2; psys_uv_to_w(randu, randv, mf->v4, cpa->fuv); @@ -932,7 +947,7 @@ static void distribute_threads_exec(ParticleThread *thread, ParticleData *pa, Ch } if (rng_skip_tot > 0) /* should never be below zero */ - rng_skip(thread->rng, rng_skip_tot); + BLI_rng_skip(thread->rng, rng_skip_tot); } static void *distribute_threads_exec_cb(void *data) @@ -949,12 +964,12 @@ static void *distribute_threads_exec_cb(void *data) for (p=0; pctx->skip) /* simplification skip */ - rng_skip(thread->rng, PSYS_RND_DIST_SKIP * thread->ctx->skip[p]); + BLI_rng_skip(thread->rng, PSYS_RND_DIST_SKIP * thread->ctx->skip[p]); if ((p+thread->num) % thread->tot == 0) distribute_threads_exec(thread, NULL, cpa, p); else /* thread skip */ - rng_skip(thread->rng, PSYS_RND_DIST_SKIP); + BLI_rng_skip(thread->rng, PSYS_RND_DIST_SKIP); } } else { @@ -971,8 +986,8 @@ static void *distribute_threads_exec_cb(void *data) static int *COMPARE_ORIG_INDEX = NULL; static int distribute_compare_orig_index(const void *p1, const void *p2) { - int index1 = COMPARE_ORIG_INDEX[*(const int*)p1]; - int index2 = COMPARE_ORIG_INDEX[*(const int*)p2]; + int index1 = COMPARE_ORIG_INDEX[*(const int *)p1]; + int index2 = COMPARE_ORIG_INDEX[*(const int *)p2]; if (index1 < index2) return -1; @@ -998,7 +1013,7 @@ static void distribute_invalid(Scene *scene, ParticleSystem *psys, int from) if (psys->child && totchild) { for (p=0,cpa=psys->child; pfuv[0]=cpa->fuv[1]=cpa->fuv[2]=cpa->fuv[3]= 0.0; + cpa->fuv[0]=cpa->fuv[1]=cpa->fuv[2]=cpa->fuv[3] = 0.0; cpa->foffset= 0.0f; cpa->parent=0; cpa->pa[0]=cpa->pa[1]=cpa->pa[2]=cpa->pa[3]=0; @@ -1009,7 +1024,7 @@ static void distribute_invalid(Scene *scene, ParticleSystem *psys, int from) else { PARTICLE_P; LOOP_PARTICLES { - pa->fuv[0]=pa->fuv[1]=pa->fuv[2]= pa->fuv[3]= 0.0; + pa->fuv[0] = pa->fuv[1] = pa->fuv[2] = pa->fuv[3] = 0.0; pa->foffset= 0.0f; pa->num= -1; } @@ -1111,7 +1126,7 @@ static int distribute_threads_init_data(ParticleThread *threads, Scene *scene, D if (from == PART_FROM_VERT) { MVert *mv= dm->getVertDataArray(dm, CD_MVERT); - float (*orcodata)[3]= dm->getVertDataArray(dm, CD_ORCO); + float (*orcodata)[3] = dm->getVertDataArray(dm, CD_ORCO); int totvert = dm->getNumVerts(dm); tree=BLI_kdtree_new(totvert); @@ -1243,9 +1258,9 @@ static int distribute_threads_init_data(ParticleThread *threads, Scene *scene, D inv_totweight = (totweight > 0.f ? 1.f/totweight : 0.f); /* Calculate cumulative weights */ - element_sum[0]= 0.0f; + element_sum[0] = 0.0f; for (i=0; iflag&PART_TRAND) || (part->simplify_flag&PART_SIMPLIFY_ENABLE)) { @@ -1254,9 +1269,9 @@ static int distribute_threads_init_data(ParticleThread *threads, Scene *scene, D for (p=0; p element_sum[i+1])) + while ((i < totelem) && (pos > (double)element_sum[i + 1])) i++; - particle_element[p]= MIN2(totelem-1, i); + particle_element[p] = MIN2(totelem-1, i); /* avoid zero weight face */ if (p == totpart-1 && element_weight[particle_element[p]] == 0.0f) - particle_element[p]= particle_element[p-1]; + particle_element[p] = particle_element[p-1]; - jitter_offset[particle_element[p]]= pos; + jitter_offset[particle_element[p]] = pos; } } @@ -1351,7 +1366,7 @@ static int distribute_threads_init_data(ParticleThread *threads, Scene *scene, D seed= 31415926 + ctx->sim.psys->seed; for (i=0; ivel); - break; + break; case PART_AVE_HORIZONTAL: { float zvec[3]; @@ -1620,9 +1635,9 @@ void psys_get_birth_coordinates(ParticleSimulationData *sim, ParticleData *pa, P ParticleSystem *psys = sim->psys; ParticleSettings *part; ParticleTexture ptex; - float fac, phasefac, nor[3]={0,0,0},loc[3],vel[3]={0.0,0.0,0.0},rot[4],q2[4]; - float r_vel[3],r_ave[3],r_rot[4],vec[3],p_vel[3]={0.0,0.0,0.0}; - float x_vec[3]={1.0,0.0,0.0}, utan[3]={0.0,1.0,0.0}, vtan[3]={0.0,0.0,1.0}, rot_vec[3]={0.0,0.0,0.0}; + float fac, phasefac, nor[3] = {0,0,0},loc[3],vel[3] = {0.0,0.0,0.0},rot[4],q2[4]; + float r_vel[3],r_ave[3],r_rot[4],vec[3],p_vel[3] = {0.0,0.0,0.0}; + float x_vec[3] = {1.0,0.0,0.0}, utan[3] = {0.0,1.0,0.0}, vtan[3] = {0.0,0.0,1.0}, rot_vec[3] = {0.0,0.0,0.0}; float q_phase[4]; int p = pa - psys->particles; part=psys->part; @@ -2535,7 +2550,7 @@ static void sph_force_cb(void *sphdata_v, ParticleKey *state, float *force, floa madd_v3_v3fl(force, vec, -(pressure + near_pressure*q)*q); /* Viscosity */ - if (visc > 0.f || stiff_visc > 0.f) { + if (visc > 0.f || stiff_visc > 0.f) { sub_v3_v3v3(dv, vel, state->vel); u = dot_v3v3(vec, dv); @@ -2734,7 +2749,7 @@ static void basic_integrate(ParticleSimulationData *sim, int p, float dfra, floa } static void basic_rotate(ParticleSettings *part, ParticleData *pa, float dfra, float timestep) { - float rotfac, rot1[4], rot2[4]={1.0,0.0,0.0,0.0}, dtime=dfra*timestep, extrotfac; + float rotfac, rot1[4], rot2[4] = {1.0,0.0,0.0,0.0}, dtime=dfra*timestep, extrotfac; if ((part->flag & PART_ROTATIONS) == 0) { unit_qt(pa->state.rot); @@ -3164,8 +3179,7 @@ void BKE_psys_collision_neartest_cb(void *userdata, int index, const BVHTreeRay if (col->hit == col->current && col->pce.index == index && col->pce.tot == 3) return; - do - { + do { collision = collision_sphere_to_tri(col, ray->radius, &pce, &t); if (col->pce.inside == 0) { collision += collision_sphere_to_edges(col, ray->radius, &pce, &t); @@ -3775,7 +3789,7 @@ static void save_hair(ParticleSimulationData *sim, float UNUSED(cfra)) /* Calculate the speed of the particle relative to the local scale of the * simulation. This should be called once per particle during a simulation * step, after the velocity has been updated. element_size defines the scale of - * the simulation, and is typically the distance to neighbourning particles. */ + * the simulation, and is typically the distance to neighboring particles. */ static void update_courant_num(ParticleSimulationData *sim, ParticleData *pa, float dtime, SPHData *sphdata) { @@ -4074,7 +4088,7 @@ static void particles_fluid_step(ParticleSimulationData *sim, int UNUSED(cfra)) { FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(sim->ob, eModifierType_Fluidsim); - if ( fluidmd && fluidmd->fss) { + if ( fluidmd && fluidmd->fss) { FluidsimSettings *fss= fluidmd->fss; ParticleSettings *part = psys->part; ParticleData *pa=NULL; @@ -4119,7 +4133,7 @@ static void particles_fluid_step(ParticleSimulationData *sim, int UNUSED(cfra)) int ptype=0; gzread(gzf, &ptype, sizeof( ptype )); - if (ptype&readMask) { + if (ptype & readMask) { activeParts++; gzread(gzf, &(pa->size), sizeof(float)); diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index 780528f4a0d..f195b3d71b0 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -249,9 +249,9 @@ static int ptcache_particle_write(int index, void *psys_v, void **data, int cfr if (data[BPHYS_DATA_INDEX] && (cfra < pa->time - step || cfra > pa->dietime + step)) return 0; - times[0]= pa->time; - times[1]= pa->dietime; - times[2]= pa->lifetime; + times[0] = pa->time; + times[1] = pa->dietime; + times[2] = pa->lifetime; PTCACHE_DATA_FROM(data, BPHYS_DATA_INDEX, &index); PTCACHE_DATA_FROM(data, BPHYS_DATA_LOCATION, pa->state.co); @@ -532,20 +532,31 @@ static int ptcache_smoke_totpoint(void *smoke_v, int UNUSED(cfra)) SmokeDomainSettings *sds = smd->domain; if (sds->fluid) { - return sds->res[0]*sds->res[1]*sds->res[2]; + return sds->base_res[0]*sds->base_res[1]*sds->base_res[2]; } else return 0; } + +#define SMOKE_CACHE_VERSION "1.04" + static int ptcache_smoke_write(PTCacheFile *pf, void *smoke_v) { SmokeModifierData *smd= (SmokeModifierData *)smoke_v; SmokeDomainSettings *sds = smd->domain; int ret = 0; + int fluid_fields = smoke_get_data_flags(sds); + + /* version header */ + ptcache_file_write(pf, SMOKE_CACHE_VERSION, 4, sizeof(char)); + ptcache_file_write(pf, &fluid_fields, 1, sizeof(int)); + ptcache_file_write(pf, &sds->active_fields, 1, sizeof(int)); + ptcache_file_write(pf, &sds->res, 3, sizeof(int)); + ptcache_file_write(pf, &sds->dx, 1, sizeof(float)); if (sds->fluid) { size_t res = sds->res[0]*sds->res[1]*sds->res[2]; - float dt, dx, *dens, *densold, *heat, *heatold, *vx, *vy, *vz, *vxold, *vyold, *vzold; + float dt, dx, *dens, *react, *fuel, *flame, *heat, *heatold, *vx, *vy, *vz, *r, *g, *b; unsigned char *obstacles; unsigned int in_len = sizeof(float)*(unsigned int)res; unsigned char *out = (unsigned char *)MEM_callocN(LZO_OUT_LEN(in_len)*4, "pointcache_lzo_buffer"); @@ -553,22 +564,40 @@ static int ptcache_smoke_write(PTCacheFile *pf, void *smoke_v) int mode=1; // light if (sds->cache_comp == SM_CACHE_HEAVY) mode=2; // heavy - smoke_export(sds->fluid, &dt, &dx, &dens, &densold, &heat, &heatold, &vx, &vy, &vz, &vxold, &vyold, &vzold, &obstacles); + smoke_export(sds->fluid, &dt, &dx, &dens, &react, &flame, &fuel, &heat, &heatold, &vx, &vy, &vz, &r, &g, &b, &obstacles); ptcache_file_compressed_write(pf, (unsigned char *)sds->shadow, in_len, out, mode); ptcache_file_compressed_write(pf, (unsigned char *)dens, in_len, out, mode); - ptcache_file_compressed_write(pf, (unsigned char *)densold, in_len, out, mode); - ptcache_file_compressed_write(pf, (unsigned char *)heat, in_len, out, mode); - ptcache_file_compressed_write(pf, (unsigned char *)heatold, in_len, out, mode); + if (fluid_fields & SM_ACTIVE_HEAT) { + ptcache_file_compressed_write(pf, (unsigned char *)heat, in_len, out, mode); + ptcache_file_compressed_write(pf, (unsigned char *)heatold, in_len, out, mode); + } + if (fluid_fields & SM_ACTIVE_FIRE) { + ptcache_file_compressed_write(pf, (unsigned char *)flame, in_len, out, mode); + ptcache_file_compressed_write(pf, (unsigned char *)fuel, in_len, out, mode); + ptcache_file_compressed_write(pf, (unsigned char *)react, in_len, out, mode); + } + if (fluid_fields & SM_ACTIVE_COLORS) { + ptcache_file_compressed_write(pf, (unsigned char *)r, in_len, out, mode); + ptcache_file_compressed_write(pf, (unsigned char *)g, in_len, out, mode); + ptcache_file_compressed_write(pf, (unsigned char *)b, in_len, out, mode); + } ptcache_file_compressed_write(pf, (unsigned char *)vx, in_len, out, mode); ptcache_file_compressed_write(pf, (unsigned char *)vy, in_len, out, mode); ptcache_file_compressed_write(pf, (unsigned char *)vz, in_len, out, mode); - ptcache_file_compressed_write(pf, (unsigned char *)vxold, in_len, out, mode); - ptcache_file_compressed_write(pf, (unsigned char *)vyold, in_len, out, mode); - ptcache_file_compressed_write(pf, (unsigned char *)vzold, in_len, out, mode); ptcache_file_compressed_write(pf, (unsigned char *)obstacles, (unsigned int)res, out, mode); ptcache_file_write(pf, &dt, 1, sizeof(float)); ptcache_file_write(pf, &dx, 1, sizeof(float)); + ptcache_file_write(pf, &sds->p0, 3, sizeof(float)); + ptcache_file_write(pf, &sds->p1, 3, sizeof(float)); + ptcache_file_write(pf, &sds->dp0, 3, sizeof(float)); + ptcache_file_write(pf, &sds->shift, 3, sizeof(int)); + ptcache_file_write(pf, &sds->obj_shift_f, 3, sizeof(float)); + ptcache_file_write(pf, &sds->obmat, 16, sizeof(float)); + ptcache_file_write(pf, &sds->base_res, 3, sizeof(int)); + ptcache_file_write(pf, &sds->res_min, 3, sizeof(int)); + ptcache_file_write(pf, &sds->res_max, 3, sizeof(int)); + ptcache_file_write(pf, &sds->active_color, 3, sizeof(float)); MEM_freeN(out); @@ -579,7 +608,7 @@ static int ptcache_smoke_write(PTCacheFile *pf, void *smoke_v) int res_big_array[3]; int res_big; int res = sds->res[0]*sds->res[1]*sds->res[2]; - float *dens, *densold, *tcu, *tcv, *tcw; + float *dens, *react, *fuel, *flame, *tcu, *tcv, *tcw, *r, *g, *b; unsigned int in_len = sizeof(float)*(unsigned int)res; unsigned int in_len_big; unsigned char *out; @@ -593,11 +622,20 @@ static int ptcache_smoke_write(PTCacheFile *pf, void *smoke_v) in_len_big = sizeof(float) * (unsigned int)res_big; - smoke_turbulence_export(sds->wt, &dens, &densold, &tcu, &tcv, &tcw); + smoke_turbulence_export(sds->wt, &dens, &react, &flame, &fuel, &r, &g, &b, &tcu, &tcv, &tcw); out = (unsigned char *)MEM_callocN(LZO_OUT_LEN(in_len_big), "pointcache_lzo_buffer"); ptcache_file_compressed_write(pf, (unsigned char *)dens, in_len_big, out, mode); - ptcache_file_compressed_write(pf, (unsigned char *)densold, in_len_big, out, mode); + if (fluid_fields & SM_ACTIVE_FIRE) { + ptcache_file_compressed_write(pf, (unsigned char *)flame, in_len_big, out, mode); + ptcache_file_compressed_write(pf, (unsigned char *)fuel, in_len_big, out, mode); + ptcache_file_compressed_write(pf, (unsigned char *)react, in_len_big, out, mode); + } + if (fluid_fields & SM_ACTIVE_COLORS) { + ptcache_file_compressed_write(pf, (unsigned char *)r, in_len_big, out, mode); + ptcache_file_compressed_write(pf, (unsigned char *)g, in_len_big, out, mode); + ptcache_file_compressed_write(pf, (unsigned char *)b, in_len_big, out, mode); + } MEM_freeN(out); out = (unsigned char *)MEM_callocN(LZO_OUT_LEN(in_len), "pointcache_lzo_buffer"); @@ -615,34 +653,95 @@ static int ptcache_smoke_read(PTCacheFile *pf, void *smoke_v) { SmokeModifierData *smd= (SmokeModifierData *)smoke_v; SmokeDomainSettings *sds = smd->domain; + char version[4]; + int ch_res[3]; + float ch_dx; + int fluid_fields = smoke_get_data_flags(sds); + int cache_fields = 0; + int active_fields = 0; + int reallocate = 0; + + /* version header */ + ptcache_file_read(pf, version, 4, sizeof(char)); + if (strncmp(version, SMOKE_CACHE_VERSION, 4)) return 0; + /* fluid info */ + ptcache_file_read(pf, &cache_fields, 1, sizeof(int)); + ptcache_file_read(pf, &active_fields, 1, sizeof(int)); + ptcache_file_read(pf, &ch_res, 3, sizeof(int)); + ptcache_file_read(pf, &ch_dx, 1, sizeof(float)); + + /* check if resolution has changed */ + if (sds->res[0] != ch_res[0] || + sds->res[1] != ch_res[1] || + sds->res[2] != ch_res[2]) { + if (sds->flags & MOD_SMOKE_ADAPTIVE_DOMAIN) + reallocate = 1; + else + return 0; + } + /* check if active fields have changed */ + if (fluid_fields != cache_fields || + active_fields != sds->active_fields) + reallocate = 1; + + /* reallocate fluid if needed*/ + if (reallocate) { + sds->active_fields = active_fields; + smoke_reallocate_fluid(sds, ch_dx, ch_res, 1); + sds->dx = ch_dx; + VECCOPY(sds->res, ch_res); + sds->total_cells = ch_res[0]*ch_res[1]*ch_res[2]; + if (sds->flags & MOD_SMOKE_HIGHRES) { + smoke_reallocate_highres_fluid(sds, ch_dx, ch_res, 1); + } + } if (sds->fluid) { size_t res = sds->res[0]*sds->res[1]*sds->res[2]; - float dt, dx, *dens, *densold, *heat, *heatold, *vx, *vy, *vz, *vxold, *vyold, *vzold; + float dt, dx, *dens, *react, *fuel, *flame, *heat, *heatold, *vx, *vy, *vz, *r, *g, *b; unsigned char *obstacles; unsigned int out_len = (unsigned int)res * sizeof(float); - smoke_export(sds->fluid, &dt, &dx, &dens, &densold, &heat, &heatold, &vx, &vy, &vz, &vxold, &vyold, &vzold, &obstacles); + smoke_export(sds->fluid, &dt, &dx, &dens, &react, &flame, &fuel, &heat, &heatold, &vx, &vy, &vz, &r, &g, &b, &obstacles); ptcache_file_compressed_read(pf, (unsigned char *)sds->shadow, out_len); - ptcache_file_compressed_read(pf, (unsigned char*)dens, out_len); - ptcache_file_compressed_read(pf, (unsigned char*)densold, out_len); - ptcache_file_compressed_read(pf, (unsigned char*)heat, out_len); - ptcache_file_compressed_read(pf, (unsigned char*)heatold, out_len); - ptcache_file_compressed_read(pf, (unsigned char*)vx, out_len); - ptcache_file_compressed_read(pf, (unsigned char*)vy, out_len); - ptcache_file_compressed_read(pf, (unsigned char*)vz, out_len); - ptcache_file_compressed_read(pf, (unsigned char*)vxold, out_len); - ptcache_file_compressed_read(pf, (unsigned char*)vyold, out_len); - ptcache_file_compressed_read(pf, (unsigned char*)vzold, out_len); - ptcache_file_compressed_read(pf, (unsigned char*)obstacles, (unsigned int)res); + ptcache_file_compressed_read(pf, (unsigned char *)dens, out_len); + if (cache_fields & SM_ACTIVE_HEAT) { + ptcache_file_compressed_read(pf, (unsigned char *)heat, out_len); + ptcache_file_compressed_read(pf, (unsigned char *)heatold, out_len); + } + if (cache_fields & SM_ACTIVE_FIRE) { + ptcache_file_compressed_read(pf, (unsigned char *)flame, out_len); + ptcache_file_compressed_read(pf, (unsigned char *)fuel, out_len); + ptcache_file_compressed_read(pf, (unsigned char *)react, out_len); + } + if (cache_fields & SM_ACTIVE_COLORS) { + ptcache_file_compressed_read(pf, (unsigned char *)r, out_len); + ptcache_file_compressed_read(pf, (unsigned char *)g, out_len); + ptcache_file_compressed_read(pf, (unsigned char *)b, out_len); + } + ptcache_file_compressed_read(pf, (unsigned char *)vx, out_len); + ptcache_file_compressed_read(pf, (unsigned char *)vy, out_len); + ptcache_file_compressed_read(pf, (unsigned char *)vz, out_len); + ptcache_file_compressed_read(pf, (unsigned char *)obstacles, (unsigned int)res); ptcache_file_read(pf, &dt, 1, sizeof(float)); ptcache_file_read(pf, &dx, 1, sizeof(float)); - - if (pf->data_types & (1<wt) { + ptcache_file_read(pf, &sds->p0, 3, sizeof(float)); + ptcache_file_read(pf, &sds->p1, 3, sizeof(float)); + ptcache_file_read(pf, &sds->dp0, 3, sizeof(float)); + ptcache_file_read(pf, &sds->shift, 3, sizeof(int)); + ptcache_file_read(pf, &sds->obj_shift_f, 3, sizeof(float)); + ptcache_file_read(pf, &sds->obmat, 16, sizeof(float)); + ptcache_file_read(pf, &sds->base_res, 3, sizeof(int)); + ptcache_file_read(pf, &sds->res_min, 3, sizeof(int)); + ptcache_file_read(pf, &sds->res_max, 3, sizeof(int)); + ptcache_file_read(pf, &sds->active_color, 3, sizeof(float)); + } + + if (pf->data_types & (1<wt) { int res = sds->res[0]*sds->res[1]*sds->res[2]; int res_big, res_big_array[3]; - float *dens, *densold, *tcu, *tcv, *tcw; + float *dens, *react, *fuel, *flame, *tcu, *tcv, *tcw, *r, *g, *b; unsigned int out_len = sizeof(float)*(unsigned int)res; unsigned int out_len_big; @@ -650,16 +749,23 @@ static int ptcache_smoke_read(PTCacheFile *pf, void *smoke_v) res_big = res_big_array[0]*res_big_array[1]*res_big_array[2]; out_len_big = sizeof(float) * (unsigned int)res_big; - smoke_turbulence_export(sds->wt, &dens, &densold, &tcu, &tcv, &tcw); + smoke_turbulence_export(sds->wt, &dens, &react, &flame, &fuel, &r, &g, &b, &tcu, &tcv, &tcw); - ptcache_file_compressed_read(pf, (unsigned char*)dens, out_len_big); - ptcache_file_compressed_read(pf, (unsigned char*)densold, out_len_big); + ptcache_file_compressed_read(pf, (unsigned char *)dens, out_len_big); + if (cache_fields & SM_ACTIVE_FIRE) { + ptcache_file_compressed_read(pf, (unsigned char *)flame, out_len_big); + ptcache_file_compressed_read(pf, (unsigned char *)fuel, out_len_big); + } + if (cache_fields & SM_ACTIVE_COLORS) { + ptcache_file_compressed_read(pf, (unsigned char *)r, out_len_big); + ptcache_file_compressed_read(pf, (unsigned char *)g, out_len_big); + ptcache_file_compressed_read(pf, (unsigned char *)b, out_len_big); + } - ptcache_file_compressed_read(pf, (unsigned char*)tcu, out_len); - ptcache_file_compressed_read(pf, (unsigned char*)tcv, out_len); - ptcache_file_compressed_read(pf, (unsigned char*)tcw, out_len); + ptcache_file_compressed_read(pf, (unsigned char *)tcu, out_len); + ptcache_file_compressed_read(pf, (unsigned char *)tcv, out_len); + ptcache_file_compressed_read(pf, (unsigned char *)tcw, out_len); } - } return 1; } @@ -753,7 +859,7 @@ static int ptcache_dynamicpaint_read(PTCacheFile *pf, void *dp_v) return 0; } - ptcache_file_compressed_read(pf, (unsigned char*)surface->data->type_data, data_len*surface->data->total_points); + ptcache_file_compressed_read(pf, (unsigned char *)surface->data->type_data, data_len*surface->data->total_points); } return 1; @@ -1030,7 +1136,7 @@ void BKE_ptcache_ids_from_object(ListBase *lb, Object *ob, Scene *scene, int dup ListBase *lb_dupli_ob; /* don't update the dupli groups, we only wan't their pid's */ - if ((lb_dupli_ob = object_duplilist_ex(scene, ob, FALSE))) { + if ((lb_dupli_ob = object_duplilist_ex(scene, ob, FALSE, FALSE))) { DupliObject *dob; for (dob= lb_dupli_ob->first; dob; dob= dob->next) { if (dob->ob != ob) { /* avoids recursive loops with dupliframes: bug 22988 */ @@ -1257,7 +1363,7 @@ static int ptcache_file_compressed_write(PTCacheFile *pf, unsigned char *in, uns if (mode == 1) { LZO_HEAP_ALLOC(wrkmem, LZO1X_MEM_COMPRESS); - r = lzo1x_1_compress(in, (lzo_uint)in_len, out, (lzo_uint *)&out_len, wrkmem); + r = lzo1x_1_compress(in, (lzo_uint)in_len, out, (lzo_uint *)&out_len, wrkmem); if (!(r == LZO_E_OK) || (out_len >= in_len)) compressed = 0; else @@ -1593,7 +1699,7 @@ static PTCacheMem *ptcache_disk_frame_to_mem(PTCacheID *pid, int cfra) for (i=0; itotpoint*ptcache_data_size[i]; if (pf->data_types & (1<data[i]), out_len); + ptcache_file_compressed_read(pf, (unsigned char *)(pm->data[i]), out_len); } } else { @@ -1624,7 +1730,7 @@ static PTCacheMem *ptcache_disk_frame_to_mem(PTCacheID *pid, int cfra) extra->data = MEM_callocN(extra->totdata * ptcache_extra_datasize[extra->type], "Pointcache extradata->data"); if (pf->flag & PTCACHE_TYPEFLAG_COMPRESS) - ptcache_file_compressed_read(pf, (unsigned char*)(extra->data), extra->totdata*ptcache_extra_datasize[extra->type]); + ptcache_file_compressed_read(pf, (unsigned char *)(extra->data), extra->totdata*ptcache_extra_datasize[extra->type]); else ptcache_file_read(pf, extra->data, extra->totdata, ptcache_extra_datasize[extra->type]); @@ -1681,7 +1787,7 @@ static int ptcache_mem_frame_to_disk(PTCacheID *pid, PTCacheMem *pm) if (pm->data[i]) { unsigned int in_len = pm->totpoint*ptcache_data_size[i]; unsigned char *out = (unsigned char *)MEM_callocN(LZO_OUT_LEN(in_len)*4, "pointcache_lzo_buffer"); - ptcache_file_compressed_write(pf, (unsigned char*)(pm->data[i]), in_len, out, pid->cache->compression); + ptcache_file_compressed_write(pf, (unsigned char *)(pm->data[i]), in_len, out, pid->cache->compression); MEM_freeN(out); } } @@ -1714,7 +1820,7 @@ static int ptcache_mem_frame_to_disk(PTCacheID *pid, PTCacheMem *pm) if (pid->cache->compression) { unsigned int in_len = extra->totdata * ptcache_extra_datasize[extra->type]; unsigned char *out = (unsigned char *)MEM_callocN(LZO_OUT_LEN(in_len)*4, "pointcache_lzo_buffer"); - ptcache_file_compressed_write(pf, (unsigned char*)(extra->data), in_len, out, pid->cache->compression); + ptcache_file_compressed_write(pf, (unsigned char *)(extra->data), in_len, out, pid->cache->compression); MEM_freeN(out); } else { @@ -1925,18 +2031,16 @@ int BKE_ptcache_read(PTCacheID *pid, float cfra) pid->cache->simframe = cfra2; } - if ((pid->cache->flag & PTCACHE_QUICK_CACHE)==0) { - cfrai = (int)cfra; - /* clear invalid cache frames so that better stuff can be simulated */ - if (pid->cache->flag & PTCACHE_OUTDATED) { - BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_AFTER, cfrai); - } - else if (pid->cache->flag & PTCACHE_FRAMES_SKIPPED) { - if (cfra <= pid->cache->last_exact) - pid->cache->flag &= ~PTCACHE_FRAMES_SKIPPED; + cfrai = (int)cfra; + /* clear invalid cache frames so that better stuff can be simulated */ + if (pid->cache->flag & PTCACHE_OUTDATED) { + BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_AFTER, cfrai); + } + else if (pid->cache->flag & PTCACHE_FRAMES_SKIPPED) { + if (cfra <= pid->cache->last_exact) + pid->cache->flag &= ~PTCACHE_FRAMES_SKIPPED; - BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_AFTER, MAX2(cfrai, pid->cache->last_exact)); - } + BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_AFTER, MAX2(cfrai, pid->cache->last_exact)); } return ret; @@ -2167,7 +2271,7 @@ void BKE_ptcache_id_clear(PTCacheID *pid, int mode, unsigned int cfra) /* clear all files in the temp dir with the prefix of the ID and the ".bphys" suffix */ switch (mode) { case PTCACHE_CLEAR_ALL: - case PTCACHE_CLEAR_BEFORE: + case PTCACHE_CLEAR_BEFORE: case PTCACHE_CLEAR_AFTER: if (pid->cache->flag & PTCACHE_DISK_CACHE) { ptcache_path(pid, path); @@ -2271,7 +2375,7 @@ void BKE_ptcache_id_clear(PTCacheID *pid, int mode, unsigned int cfra) } } } - if (pid->cache->cached_frames && cfra>=sta && cfra<=end) + if (pid->cache->cached_frames && cfra >= sta && cfra <= end) pid->cache->cached_frames[cfra-sta] = 0; break; } @@ -2358,7 +2462,7 @@ void BKE_ptcache_id_time(PTCacheID *pid, Scene *scene, float cfra, int *startfra if (MEM_allocN_len(cache->cached_frames) != sizeof(char) * (cache->endframe-cache->startframe+1)) { MEM_freeN(cache->cached_frames); cache->cached_frames = NULL; - } + } } if (cache->cached_frames==NULL && cache->endframe > cache->startframe) { @@ -2431,8 +2535,6 @@ int BKE_ptcache_id_reset(Scene *scene, PTCacheID *pid, int mode) if (mode == PTCACHE_RESET_DEPSGRAPH) { if (!(cache->flag & PTCACHE_BAKED) && !BKE_ptcache_get_continue_physics()) { - if (cache->flag & PTCACHE_QUICK_CACHE) - clear= 1; after= 1; } @@ -2466,10 +2568,10 @@ int BKE_ptcache_id_reset(Scene *scene, PTCacheID *pid, int mode) sbFreeSimulation(pid->calldata); else if (pid->type == PTCACHE_TYPE_PARTICLES) psys_reset(pid->calldata, PSYS_RESET_DEPSGRAPH); - else if (pid->type == PTCACHE_TYPE_SMOKE_DOMAIN) + /*else if (pid->type == PTCACHE_TYPE_SMOKE_DOMAIN) smokeModifier_reset(pid->calldata); else if (pid->type == PTCACHE_TYPE_SMOKE_HIGHRES) - smokeModifier_reset_turbulence(pid->calldata); + smokeModifier_reset_turbulence(pid->calldata);*/ else if (pid->type == PTCACHE_TYPE_DYNAMICPAINT) dynamicPaint_clearSurface((DynamicPaintSurface*)pid->calldata); } @@ -2496,7 +2598,7 @@ int BKE_ptcache_object_reset(Scene *scene, Object *ob, int mode) } for (psys=ob->particlesystem.first; psys; psys=psys->next) { - /* children or just redo can be calculated without reseting anything */ + /* children or just redo can be calculated without resetting anything */ if (psys->recalc & PSYS_RECALC_REDO || psys->recalc & PSYS_RECALC_CHILD) skip = 1; /* Baked cloth hair has to be checked too, because we don't want to reset */ @@ -2663,36 +2765,65 @@ void BKE_ptcache_free_list(ListBase *ptcaches) } } -static PointCache *ptcache_copy(PointCache *cache) +static PointCache *ptcache_copy(PointCache *cache, int copy_data) { PointCache *ncache; ncache= MEM_dupallocN(cache); - /* hmm, should these be copied over instead? */ ncache->mem_cache.first = NULL; ncache->mem_cache.last = NULL; - ncache->cached_frames = NULL; - ncache->edit = NULL; - ncache->flag= 0; - ncache->simframe= 0; + if (copy_data == FALSE) { + ncache->mem_cache.first = NULL; + ncache->mem_cache.last = NULL; + ncache->cached_frames = NULL; + + ncache->flag= 0; + ncache->simframe= 0; + } + else { + PTCacheMem *pm; + + for (pm = cache->mem_cache.first; pm; pm = pm->next) { + PTCacheMem *pmn = MEM_dupallocN(pm); + int i; + + for (i = 0; i < BPHYS_TOT_DATA; i++) { + if (pmn->data[i]) + pmn->data[i] = MEM_dupallocN(pm->data[i]); + } + + BKE_ptcache_mem_pointers_init(pm); + + BLI_addtail(&ncache->mem_cache, pmn); + } + + if (ncache->cached_frames) + ncache->cached_frames = MEM_dupallocN(cache->cached_frames); + } + + /* hmm, should these be copied over instead? */ + ncache->edit = NULL; return ncache; } + /* returns first point cache */ -PointCache *BKE_ptcache_copy_list(ListBase *ptcaches_new, ListBase *ptcaches_old) +PointCache *BKE_ptcache_copy_list(ListBase *ptcaches_new, ListBase *ptcaches_old, int copy_data) { PointCache *cache = ptcaches_old->first; ptcaches_new->first = ptcaches_new->last = NULL; for (; cache; cache=cache->next) - BLI_addtail(ptcaches_new, ptcache_copy(cache)); + BLI_addtail(ptcaches_new, ptcache_copy(cache, copy_data)); return ptcaches_new->first; } +/* Disabled this code; this is being called on scene_update_tagged, and that in turn gets called on + * every user action changing stuff, and then it runs a complete bake??? (ton) */ /* Baking */ void BKE_ptcache_quick_cache_all(Main *bmain, Scene *scene) @@ -2876,7 +3007,7 @@ void BKE_ptcache_bake(PTCacheBaker* baker) } if ((cache->flag & PTCACHE_REDO_NEEDED || (cache->flag & PTCACHE_SIMULATION_VALID)==0) && - ((cache->flag & PTCACHE_QUICK_CACHE)==0 || render || bake)) + (render || bake)) { BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_ALL, 0); } @@ -3195,8 +3326,9 @@ void BKE_ptcache_load_external(PTCacheID *pid) cache->endframe = end; cache->totpoint = 0; - if (pid->type == PTCACHE_TYPE_SMOKE_DOMAIN) - ; /*necessary info in every file*/ + if (pid->type == PTCACHE_TYPE_SMOKE_DOMAIN) { + /* necessary info in every file */ + } /* read totpoint from info file (frame 0) */ else if (info) { pf= ptcache_file_open(pid, PTCACHE_FILE_READ, 0); @@ -3244,7 +3376,7 @@ void BKE_ptcache_update_info(PTCacheID *pid) if (cache->flag & PTCACHE_EXTERNAL) { int cfra = cache->startframe; - for (; cfra<=cache->endframe; cfra++) { + for (; cfra <= cache->endframe; cfra++) { if (BKE_ptcache_id_exist(pid, cfra)) totframes++; } @@ -3271,7 +3403,7 @@ void BKE_ptcache_update_info(PTCacheID *pid) else { int cfra = cache->startframe; - for (; cfra<=cache->endframe; cfra++) { + for (; cfra <= cache->endframe; cfra++) { if (BKE_ptcache_id_exist(pid, cfra)) totframes++; } @@ -3280,7 +3412,7 @@ void BKE_ptcache_update_info(PTCacheID *pid) } } else { - PTCacheMem *pm = cache->mem_cache.first; + PTCacheMem *pm = cache->mem_cache.first; float bytes = 0.0f; int i, mb; diff --git a/source/blender/blenkernel/intern/property.c b/source/blender/blenkernel/intern/property.c index 46ddce4b51b..8da4f11fed3 100644 --- a/source/blender/blenkernel/intern/property.c +++ b/source/blender/blenkernel/intern/property.c @@ -27,9 +27,12 @@ /** \file blender/blenkernel/intern/property.c * \ingroup bke + * + * This module deals with bProperty only, + * they are used on blender objects in the game engine + * (where they get converted into C++ classes - CValue and subclasses) */ - #include #include #include @@ -45,7 +48,7 @@ #include "BKE_property.h" -void free_property(bProperty *prop) +void BKE_bproperty_free(bProperty *prop) { if (prop->poin && prop->poin != &prop->data) MEM_freeN(prop->poin); @@ -53,17 +56,17 @@ void free_property(bProperty *prop) } -void free_properties(ListBase *lb) +void BKE_bproperty_free_list(ListBase *lb) { bProperty *prop; while ( (prop = lb->first) ) { BLI_remlink(lb, prop); - free_property(prop); + BKE_bproperty_free(prop); } } -bProperty *copy_property(bProperty *prop) +bProperty *BKE_bproperty_copy(bProperty *prop) { bProperty *propn; @@ -76,13 +79,13 @@ bProperty *copy_property(bProperty *prop) return propn; } -void copy_properties(ListBase *lbn, ListBase *lbo) +void BKE_bproperty_copy_list(ListBase *lbn, ListBase *lbo) { bProperty *prop, *propn; - free_properties(lbn); /* in case we are copying to an object with props */ + BKE_bproperty_free_list(lbn); /* in case we are copying to an object with props */ prop = lbo->first; while (prop) { - propn = copy_property(prop); + propn = BKE_bproperty_copy(prop); BLI_addtail(lbn, propn); prop = prop->next; } @@ -90,7 +93,7 @@ void copy_properties(ListBase *lbn, ListBase *lbo) } -void init_property(bProperty *prop) +void BKE_bproperty_init(bProperty *prop) { /* also use when property changes type */ @@ -113,22 +116,22 @@ void init_property(bProperty *prop) } -bProperty *new_property(int type) +bProperty *BKE_bproperty_new(int type) { bProperty *prop; prop = MEM_callocN(sizeof(bProperty), "property"); prop->type = type; - init_property(prop); + BKE_bproperty_init(prop); strcpy(prop->name, "prop"); return prop; } -/* used by unique_property() only */ -static bProperty *get_property__internal(bProperty *first, bProperty *self, const char *name) +/* used by BKE_bproperty_unique() only */ +static bProperty *bproperty_get(bProperty *first, bProperty *self, const char *name) { bProperty *p; for (p = first; p; p = p->next) { @@ -137,7 +140,7 @@ static bProperty *get_property__internal(bProperty *first, bProperty *self, cons } return NULL; } -void unique_property(bProperty *first, bProperty *prop, int force) +void BKE_bproperty_unique(bProperty *first, bProperty *prop, int force) { bProperty *p; @@ -151,13 +154,13 @@ void unique_property(bProperty *first, bProperty *prop, int force) if (force) { /* change other names to make them unique */ - while ((p = get_property__internal(first, prop, prop->name))) { - unique_property(first, p, 0); + while ((p = bproperty_get(first, prop, prop->name))) { + BKE_bproperty_unique(first, p, 0); } } else { /* change our own name until its unique */ - if (get_property__internal(first, prop, prop->name)) { + if (bproperty_get(first, prop, prop->name)) { /* there is a collision */ char new_name[sizeof(prop->name)]; char base_name[sizeof(prop->name)]; @@ -175,33 +178,34 @@ void unique_property(bProperty *first, bProperty *prop, int force) BLI_snprintf(num, sizeof(num), "%d", i++); BLI_strncpy(new_name, base_name, sizeof(prop->name) - strlen(num)); strcat(new_name, num); - } while (get_property__internal(first, prop, new_name)); + } while (bproperty_get(first, prop, new_name)); BLI_strncpy(prop->name, new_name, sizeof(prop->name)); } } } -bProperty *get_ob_property(Object *ob, const char *name) +bProperty *BKE_bproperty_object_get(Object *ob, const char *name) { return BLI_findstring(&ob->prop, name, offsetof(bProperty, name)); } -void set_ob_property(Object *ob, bProperty *propc) +void BKE_bproperty_object_set(Object *ob, bProperty *propc) { bProperty *prop; - prop = get_ob_property(ob, propc->name); + prop = BKE_bproperty_object_get(ob, propc->name); if (prop) { - free_property(prop); + BKE_bproperty_free(prop); BLI_remlink(&ob->prop, prop); } - BLI_addtail(&ob->prop, copy_property(propc)); + BLI_addtail(&ob->prop, BKE_bproperty_copy(propc)); } /* negative: prop is smaller * positive: prop is larger */ -int compare_property(bProperty *prop, const char *str) +#if 0 /* UNUSED */ +int BKE_bproperty_cmp(bProperty *prop, const char *str) { // extern int Gdfra; /* sector.c */ float fvalue, ftest; @@ -237,8 +241,9 @@ int compare_property(bProperty *prop, const char *str) return 0; } +#endif -void set_property(bProperty *prop, const char *str) +void BKE_bproperty_set(bProperty *prop, const char *str) { // extern int Gdfra; /* sector.c */ @@ -262,7 +267,7 @@ void set_property(bProperty *prop, const char *str) } -void add_property(bProperty *prop, const char *str) +void BKE_bproperty_add(bProperty *prop, const char *str) { // extern int Gdfra; /* sector.c */ @@ -282,7 +287,7 @@ void add_property(bProperty *prop, const char *str) } /* reads value of property, sets it in chars in str */ -void set_property_valstr(bProperty *prop, char *str) +void BKE_bproperty_set_valstr(bProperty *prop, char *str) { // extern int Gdfra; /* sector.c */ @@ -303,11 +308,13 @@ void set_property_valstr(bProperty *prop, char *str) } } +#if 0 /* UNUSED */ void cp_property(bProperty *prop1, bProperty *prop2) { char str[128]; - set_property_valstr(prop2, str); + BKE_bproperty_set_valstr(prop2, str); - set_property(prop1, str); + BKE_bproperty_set(prop1, str); } +#endif diff --git a/source/blender/blenkernel/intern/report.c b/source/blender/blenkernel/intern/report.c index 3a66ec23412..d925d736358 100644 --- a/source/blender/blenkernel/intern/report.c +++ b/source/blender/blenkernel/intern/report.c @@ -34,6 +34,8 @@ #include "BLI_dynstr.h" #include "BLI_utildefines.h" +#include "BLF_translation.h" + #include "BKE_report.h" #include "BKE_global.h" /* G.background only */ @@ -44,15 +46,24 @@ static const char *report_type_str(int type) { switch (type) { - case RPT_DEBUG: return "Debug"; - case RPT_INFO: return "Info"; - case RPT_OPERATOR: return "Operator"; - case RPT_WARNING: return "Warning"; - case RPT_ERROR: return "Error"; - case RPT_ERROR_INVALID_INPUT: return "Invalid Input Error"; - case RPT_ERROR_INVALID_CONTEXT: return "Invalid Context Error"; - case RPT_ERROR_OUT_OF_MEMORY: return "Out Of Memory Error"; - default: return "Undefined Type"; + case RPT_DEBUG: + return TIP_("Debug"); + case RPT_INFO: + return TIP_("Info"); + case RPT_OPERATOR: + return TIP_("Operator"); + case RPT_WARNING: + return TIP_("Warning"); + case RPT_ERROR: + return TIP_("Error"); + case RPT_ERROR_INVALID_INPUT: + return TIP_("Invalid Input Error"); + case RPT_ERROR_INVALID_CONTEXT: + return TIP_("Invalid Context Error"); + case RPT_ERROR_OUT_OF_MEMORY: + return TIP_("Out Of Memory Error"); + default: + return TIP_("Undefined Type"); } } @@ -87,10 +98,11 @@ void BKE_reports_clear(ReportList *reports) reports->list.first = reports->list.last = NULL; } -void BKE_report(ReportList *reports, ReportType type, const char *message) +void BKE_report(ReportList *reports, ReportType type, const char *_message) { Report *report; int len; + const char *message = TIP_(_message); /* in background mode always print otherwise there are cases the errors wont be displayed, * but still add to the report list since this is used for python exception handling */ @@ -114,14 +126,16 @@ void BKE_report(ReportList *reports, ReportType type, const char *message) } } -void BKE_reportf(ReportList *reports, ReportType type, const char *format, ...) +void BKE_reportf(ReportList *reports, ReportType type, const char *_format, ...) { DynStr *ds; Report *report; va_list args; + const char *format = TIP_(_format); if (G.background || !reports || ((reports->flag & RPT_PRINT) && (type >= reports->printlevel))) { - va_start(args, format); + printf("%s: ", report_type_str(type)); + va_start(args, _format); vprintf(format, args); va_end(args); fprintf(stdout, "\n"); /* otherise each report needs to include a \n */ @@ -132,7 +146,7 @@ void BKE_reportf(ReportList *reports, ReportType type, const char *format, ...) report = MEM_callocN(sizeof(Report), "Report"); ds = BLI_dynstr_new(); - va_start(args, format); + va_start(args, _format); BLI_dynstr_vappendf(ds, format, args); va_end(args); @@ -147,10 +161,11 @@ void BKE_reportf(ReportList *reports, ReportType type, const char *format, ...) } } -void BKE_reports_prepend(ReportList *reports, const char *prepend) +void BKE_reports_prepend(ReportList *reports, const char *_prepend) { Report *report; DynStr *ds; + const char *prepend = TIP_(_prepend); if (!reports) return; @@ -169,18 +184,19 @@ void BKE_reports_prepend(ReportList *reports, const char *prepend) } } -void BKE_reports_prependf(ReportList *reports, const char *prepend, ...) +void BKE_reports_prependf(ReportList *reports, const char *_prepend, ...) { Report *report; DynStr *ds; va_list args; + const char *prepend = TIP_(_prepend); if (!reports) return; for (report = reports->list.first; report; report = report->next) { ds = BLI_dynstr_new(); - va_start(args, prepend); + va_start(args, _prepend); BLI_dynstr_vappendf(ds, prepend, args); va_end(args); diff --git a/source/blender/blenkernel/intern/sca.c b/source/blender/blenkernel/intern/sca.c index 7d9d2f02c06..eb4e0d9c679 100644 --- a/source/blender/blenkernel/intern/sca.c +++ b/source/blender/blenkernel/intern/sca.c @@ -210,7 +210,7 @@ void unlink_controllers(ListBase *lb) bController *cont; for (cont= lb->first; cont; cont= cont->next) - unlink_controller(cont); + unlink_controller(cont); } void free_controller(bController *cont) @@ -536,7 +536,7 @@ void clear_sca_new_poins(void) ob= G.main->object.first; while (ob) { clear_sca_new_poins_ob(ob); - ob= ob->id.next; + ob= ob->id.next; } } @@ -552,7 +552,7 @@ void set_sca_new_poins_ob(Object *ob) if (sens->flag & SENS_NEW) { for (a=0; atotlinks; a++) { if (sens->links[a] && sens->links[a]->mynew) - sens->links[a]= sens->links[a]->mynew; + sens->links[a] = sens->links[a]->mynew; } } sens= sens->next; @@ -563,7 +563,7 @@ void set_sca_new_poins_ob(Object *ob) if (cont->flag & CONT_NEW) { for (a=0; atotlinks; a++) { if ( cont->links[a] && cont->links[a]->mynew) - cont->links[a]= cont->links[a]->mynew; + cont->links[a] = cont->links[a]->mynew; } } cont= cont->next; @@ -624,7 +624,7 @@ void set_sca_new_poins(void) ob= G.main->object.first; while (ob) { set_sca_new_poins_ob(ob); - ob= ob->id.next; + ob= ob->id.next; } } @@ -696,7 +696,7 @@ void sca_remove_ob_poin(Object *obt, Object *ob) if (sta->target == ob) sta->target = NULL; } act= act->next; - } + } } /* ******************** INTERFACE ******************* */ @@ -875,3 +875,20 @@ void unlink_logicbricks(void **poin, void ***ppoin, short *tot) return; } } + +const char *sca_state_name_get(Object *ob, short bit) +{ + bController *cont; + unsigned int mask; + + mask = (1<controllers.first; + while (cont) { + if (cont->state_mask & mask) { + return cont->name; + } + cont = cont->next; + } + return NULL; +} + diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 2dec72560a2..a1918b77a1e 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -54,6 +54,7 @@ #include "BLI_blenlib.h" #include "BLI_utildefines.h" #include "BLI_callbacks.h" +#include "BLI_string.h" #include "BKE_anim.h" #include "BKE_animsys.h" @@ -135,8 +136,6 @@ Scene *BKE_scene_copy(Scene *sce, int type) MEM_freeN(scen->toolsettings); } else { - ImageFormatData *im_format, *im_formatn; - scen = BKE_libblock_copy(&sce->id); BLI_duplicatelist(&(scen->base), &(sce->base)); @@ -174,11 +173,12 @@ Scene *BKE_scene_copy(Scene *sce, int type) } /* copy color management settings */ - im_format = &sce->r.im_format; - im_formatn = &scen->r.im_format; - BKE_color_managed_display_settings_copy(&scen->display_settings, &sce->display_settings); BKE_color_managed_view_settings_copy(&scen->view_settings, &sce->view_settings); + BKE_color_managed_view_settings_copy(&scen->r.im_format.view_settings, &sce->r.im_format.view_settings); + + BLI_strncpy(scen->sequencer_colorspace_settings.name, sce->sequencer_colorspace_settings.name, + sizeof(scen->sequencer_colorspace_settings.name)); } /* tool settings */ @@ -325,7 +325,7 @@ void BKE_scene_free(Scene *sce) BKE_paint_free(&sce->toolsettings->imapaint.paint); MEM_freeN(sce->toolsettings); - sce->toolsettings = NULL; + sce->toolsettings = NULL; } if (sce->theDag) { @@ -354,6 +354,7 @@ Scene *BKE_scene_add(const char *name) Scene *sce; ParticleEditSettings *pset; int a; + const char *colorspace_name; sce = BKE_libblock_alloc(&bmain->scene, ID_SCE, name); sce->lay = sce->layact = 1; @@ -367,8 +368,8 @@ Scene *BKE_scene_add(const char *name) sce->r.ysch = 1080; sce->r.xasp = 1; sce->r.yasp = 1; - sce->r.xparts = 8; - sce->r.yparts = 8; + sce->r.tilex = 256; + sce->r.tiley = 256; sce->r.mblur_samples = 1; sce->r.filtertype = R_FILTER_MITCH; sce->r.size = 50; @@ -387,7 +388,7 @@ Scene *BKE_scene_add(const char *name) sce->r.edgeint = 10; sce->r.ocres = 128; - /* OCIO_TODO: for forwards compatibiliy only, so if no tonecurve are used, + /* OCIO_TODO: for forwards compatibility only, so if no tonecurve are used, * images would look in the same way as in current blender * * perhaps at some point should be completely deprecated? @@ -435,7 +436,7 @@ Scene *BKE_scene_add(const char *name) sce->toolsettings->cornertype = 1; sce->toolsettings->degr = 90; sce->toolsettings->step = 9; - sce->toolsettings->turn = 1; + sce->toolsettings->turn = 1; sce->toolsettings->extr_offs = 1; sce->toolsettings->doublimit = 0.001; sce->toolsettings->segments = 32; @@ -445,6 +446,7 @@ Scene *BKE_scene_add(const char *name) sce->toolsettings->uvcalc_cubesize = 1.0f; sce->toolsettings->uvcalc_mapdir = 1; sce->toolsettings->uvcalc_mapalign = 1; + sce->toolsettings->uvcalc_margin = 0.001f; sce->toolsettings->unwrapper = 1; sce->toolsettings->select_thresh = 0.01f; sce->toolsettings->jointrilimit = 0.8f; @@ -567,8 +569,13 @@ Scene *BKE_scene_add(const char *name) sound_create_scene(sce); + /* color management */ + colorspace_name = IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_DEFAULT_SEQUENCER); + BKE_color_managed_display_settings_init(&sce->display_settings); BKE_color_managed_view_settings_init(&sce->view_settings); + BLI_strncpy(sce->sequencer_colorspace_settings.name, colorspace_name, + sizeof(sce->sequencer_colorspace_settings.name)); return sce; } @@ -748,7 +755,7 @@ int BKE_scene_base_iter_next(Scene **scene, int val, Base **base, Object **ob) * this enters eternal loop because of * makeDispListMBall getting called inside of group_duplilist */ if ((*base)->object->dup_group == NULL) { - duplilist = object_duplilist((*scene), (*base)->object); + duplilist = object_duplilist((*scene), (*base)->object, FALSE); dupob = duplilist->first; @@ -951,7 +958,7 @@ float BKE_scene_frame_get_from_ctime(Scene *scene, const float frame) { float ctime = frame; ctime += scene->r.subframe; - ctime *= scene->r.framelen; + ctime *= scene->r.framelen; return ctime; } @@ -1035,7 +1042,7 @@ void BKE_scene_update_tagged(Main *bmain, Scene *scene) /* flush recalc flags to dependencies */ DAG_ids_flush_tagged(bmain); - scene->physics_settings.quick_cache_step = 0; + /* removed calls to quick_cache, see pointcache.c */ /* clear "LIB_DOIT" flag from all materials, to prevent infinite recursion problems later * when trying to find materials with drivers that need evaluating [#32017] @@ -1058,10 +1065,6 @@ void BKE_scene_update_tagged(Main *bmain, Scene *scene) BKE_animsys_evaluate_animdata(scene, &scene->id, adt, ctime, 0); } - /* quick point cache updates */ - if (scene->physics_settings.quick_cache_step) - BKE_ptcache_quick_cache_all(bmain, scene); - /* notify editors and python about recalc */ BLI_callback_exec(bmain, &scene->id, BLI_CB_EVT_SCENE_UPDATE_POST); DAG_ids_check_recalc(bmain, scene, FALSE); @@ -1110,6 +1113,11 @@ void BKE_scene_update_for_newframe(Main *bmain, Scene *sce, unsigned int lay) BKE_animsys_evaluate_all_animation(bmain, sce, ctime); /*...done with recusrive funcs */ + /* clear "LIB_DOIT" flag from all materials, to prevent infinite recursion problems later + * when trying to find materials with drivers that need evaluating [#32017] + */ + tag_main_idcode(bmain, ID_MA, FALSE); + /* BKE_object_handle_update() on all objects, groups and sets */ scene_update_tagged_recursive(bmain, sce, sce); @@ -1186,7 +1194,7 @@ int BKE_scene_remove_render_layer(Main *bmain, Scene *scene, SceneRenderLayer *s int get_render_subsurf_level(RenderData *r, int lvl) { if (r->mode & R_SIMPLIFY) - return MIN2(r->simplify_subsurf, lvl); + return min_ii(r->simplify_subsurf, lvl); else return lvl; } @@ -1202,7 +1210,7 @@ int get_render_child_particle_number(RenderData *r, int num) int get_render_shadow_samples(RenderData *r, int samples) { if ((r->mode & R_SIMPLIFY) && samples > 0) - return MIN2(r->simplify_shadowsamples, samples); + return min_ii(r->simplify_shadowsamples, samples); else return samples; } @@ -1270,9 +1278,11 @@ void BKE_scene_disable_color_management(Scene *scene) ColorManagedDisplaySettings *display_settings = &scene->display_settings; ColorManagedViewSettings *view_settings = &scene->view_settings; const char *view; + const char *none_display_name; + + none_display_name = IMB_colormanagement_display_get_none_name(); - /* NOTE: None display with Default view should always exist in OCIO configuration, otherwise it wouldn't work as expected */ - BLI_strncpy(display_settings->display_device, "None", sizeof(display_settings->display_device)); + BLI_strncpy(display_settings->display_device, none_display_name, sizeof(display_settings->display_device)); view = IMB_colormanagement_view_get_default_name(display_settings->display_device); @@ -1280,3 +1290,8 @@ void BKE_scene_disable_color_management(Scene *scene) BLI_strncpy(view_settings->view_transform, view, sizeof(view_settings->view_transform)); } } + +int BKE_scene_check_color_management_enabled(const Scene *scene) +{ + return strcmp(scene->display_settings.display_device, "None") != 0; +} diff --git a/source/blender/blenkernel/intern/seqeffects.c b/source/blender/blenkernel/intern/seqeffects.c index eaf3ec384c8..469881020c1 100644 --- a/source/blender/blenkernel/intern/seqeffects.c +++ b/source/blender/blenkernel/intern/seqeffects.c @@ -62,14 +62,14 @@ static void slice_get_byte_buffers(const SeqRenderData *context, const ImBuf *ib { int offset = 4 * start_line * context->rectx; - *rect1 = (unsigned char*) ibuf1->rect + offset; - *rect_out = (unsigned char*) out->rect + offset; + *rect1 = (unsigned char *)ibuf1->rect + offset; + *rect_out = (unsigned char *)out->rect + offset; if (ibuf2) - *rect2 = (unsigned char*) ibuf2->rect + offset; + *rect2 = (unsigned char *)ibuf2->rect + offset; if (ibuf3) - *rect3 = (unsigned char*) ibuf3->rect + offset; + *rect3 = (unsigned char *)ibuf3->rect + offset; } static void slice_get_float_buffers(const SeqRenderData *context, const ImBuf *ibuf1, const ImBuf *ibuf2, @@ -600,7 +600,7 @@ static void makeGammaTables(float gamma) color_step = 1.0f / RE_GAMMA_TABLE_SIZE; inv_color_step = (float) RE_GAMMA_TABLE_SIZE; - /* We could squeeze out the two range tables to gain some memory */ + /* We could squeeze out the two range tables to gain some memory */ for (i = 0; i < RE_GAMMA_TABLE_SIZE; i++) { color_domain_table[i] = i * color_step; gamma_range_table[i] = pow(color_domain_table[i], valid_gamma); @@ -609,9 +609,9 @@ static void makeGammaTables(float gamma) /* The end of the table should match 1.0 carefully. In order to avoid * rounding errors, we just set this explicitly. The last segment may - * have a different length than the other segments, but our - * interpolation is insensitive to that - */ + * have a different length than the other segments, but our + * interpolation is insensitive to that + */ color_domain_table[RE_GAMMA_TABLE_SIZE] = 1.0; gamma_range_table[RE_GAMMA_TABLE_SIZE] = 1.0; inv_gamma_range_table[RE_GAMMA_TABLE_SIZE] = 1.0; @@ -1178,7 +1178,7 @@ static void do_mul_effect_float(float facf0, float facf1, int x, int y, float *r fac3 = facf1; /* formula: - * fac*(a*b) + (1-fac)*a => fac*a*(b-1)+a + * fac * (a * b) + (1 - fac) * a => fac * a * (b - 1) + a */ while (y--) { @@ -1353,7 +1353,7 @@ static float check_zone(WipeZone *wipezone, int x, int y, Sequence *seq, float f hyp2 = fabsf(angle * x + y + (-(yo - posy * 0.5f) - angle * (xo - posx * 0.5f))) * wipezone->pythangle; } - hwidth = minf(hwidth, fabsf(b3 - b1) / 2.0f); + hwidth = min_ff(hwidth, fabsf(b3 - b1) / 2.0f); if (b2 < b1 && b2 < b3) { output = in_band(hwidth, hyp, 0, 1); @@ -2373,7 +2373,7 @@ static ImBuf *do_solid_color(SeqRenderData context, Sequence *seq, float UNUSED( rect[1] = col1[1]; rect[2] = col1[2]; rect[3] = 255; - } + } } } @@ -2609,7 +2609,7 @@ static void store_icu_yrange_speed(Sequence *seq, short UNUSED(adrcode), float * *ymin = 0.0; *ymax = seq->len; } - } + } } void BKE_sequence_effect_speed_rebuild_map(Scene *scene, Sequence *seq, int force) diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index 8d7ca94ed48..80ea00fc703 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -53,6 +53,8 @@ #include "BLI_threads.h" #include "BLI_utildefines.h" +#include "BLF_translation.h" + #include "BKE_animsys.h" #include "BKE_global.h" #include "BKE_image.h" @@ -313,7 +315,7 @@ void BKE_sequencer_editing_free(Scene *scene) static void sequencer_imbuf_assign_spaces(Scene *scene, ImBuf *ibuf) { - IMB_colormanagement_imbuf_assign_float_space(ibuf, &scene->sequencer_colorspace_settings); + IMB_colormanagement_assign_float_colorspace(ibuf, scene->sequencer_colorspace_settings.name); } void BKE_sequencer_imbuf_to_sequencer_space(Scene *scene, ImBuf *ibuf, int make_float) @@ -461,7 +463,7 @@ static void seq_array(Editing *ed, Sequence ***seqarray, int *tot, int use_point seq_build_array(&ed->seqbase, &array, 0); } -void BKE_seqence_iterator_begin(Editing *ed, SeqIterator *iter, int use_pointer) +void BKE_sequence_iterator_begin(Editing *ed, SeqIterator *iter, int use_pointer) { memset(iter, 0, sizeof(*iter)); seq_array(ed, &iter->array, &iter->tot, use_pointer); @@ -473,7 +475,7 @@ void BKE_seqence_iterator_begin(Editing *ed, SeqIterator *iter, int use_pointer) } } -void BKE_seqence_iterator_next(SeqIterator *iter) +void BKE_sequence_iterator_next(SeqIterator *iter) { if (++iter->cur < iter->tot) iter->seq = iter->array[iter->cur]; @@ -481,7 +483,7 @@ void BKE_seqence_iterator_next(SeqIterator *iter) iter->valid = 0; } -void BKE_seqence_iterator_end(SeqIterator *iter) +void BKE_sequence_iterator_end(SeqIterator *iter) { if (iter->array) MEM_freeN(iter->array); @@ -507,8 +509,8 @@ static void seq_update_sound_bounds_recursive_rec(Scene *scene, Sequence *metase * since sound is played outside of evaluating the imbufs, */ for (seq = metaseq->seqbase.first; seq; seq = seq->next) { if (seq->type == SEQ_TYPE_META) { - seq_update_sound_bounds_recursive_rec(scene, seq, maxi(start, metaseq_start(seq)), - mini(end, metaseq_end(seq))); + seq_update_sound_bounds_recursive_rec(scene, seq, max_ii(start, metaseq_start(seq)), + min_ii(end, metaseq_end(seq))); } else if (ELEM(seq->type, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SCENE)) { if (seq->scene_sound) { @@ -717,7 +719,7 @@ void BKE_sequence_reload_new_file(Scene *scene, Sequence *seq, int lock_range) #ifdef WITH_AUDASPACE if (!seq->sound) return; - seq->len = ceil(AUD_getInfo(seq->sound->playback_handle).length * FPS); + seq->len = ceil((double)AUD_getInfo(seq->sound->playback_handle).length * FPS); seq->len -= seq->anim_startofs; seq->len -= seq->anim_endofs; if (seq->len < 0) { @@ -843,7 +845,7 @@ static int seqbase_unique_name_recursive_cb(Sequence *seq, void *arg_pt) return 1; } -void BKE_seqence_base_unique_name_recursive(ListBase *seqbasep, Sequence *seq) +void BKE_sequence_base_unique_name_recursive(ListBase *seqbasep, Sequence *seq) { SeqUniqueInfo sui; char *dot; @@ -991,7 +993,7 @@ static float give_stripelem_index(Sequence *seq, float cfra) if (seq->type & SEQ_TYPE_EFFECT) { end = seq->enddisp; - } + } if (end < sta) { return -1; @@ -1835,8 +1837,6 @@ static ImBuf *input_preprocess(SeqRenderData context, Sequence *seq, float cfra, StripCrop c = {0}; StripTransform t = {0}; int sx, sy, dx, dy; - double xscale = 1.0; - double yscale = 1.0; if (is_proxy_image) { double f = seq_rendersize_to_scale_factor(context.preview_render_size); @@ -1853,14 +1853,6 @@ static ImBuf *input_preprocess(SeqRenderData context, Sequence *seq, float cfra, t = *seq->strip->transform; } - xscale = context.scene->r.xsch ? ((double) context.rectx / (double) context.scene->r.xsch) : 1.0; - yscale = context.scene->r.ysch ? ((double) context.recty / (double) context.scene->r.ysch) : 1.0; - - c.left *= xscale; c.right *= xscale; - c.top *= yscale; c.bottom *= yscale; - - t.xofs *= xscale; t.yofs *= yscale; - sx = ibuf->x - c.left - c.right; sy = ibuf->y - c.top - c.bottom; dx = sx; @@ -1892,7 +1884,7 @@ static ImBuf *input_preprocess(SeqRenderData context, Sequence *seq, float cfra, ibuf = i; } - } + } if (seq->flag & SEQ_FLIPX) { IMB_flipx(ibuf); @@ -1975,17 +1967,20 @@ static ImBuf *copy_from_ibuf_still(SeqRenderData context, Sequence *seq, float n static void copy_to_ibuf_still(SeqRenderData context, Sequence *seq, float nr, ImBuf *ibuf) { + /* warning: ibuf may be NULL if the video fails to load */ if (nr == 0 || nr == seq->len - 1) { /* we have to store a copy, since the passed ibuf * could be preprocessed afterwards (thereby silently * changing the cached image... */ ibuf = IMB_dupImBuf(ibuf); - sequencer_imbuf_assign_spaces(context.scene, ibuf); + if (ibuf) { + sequencer_imbuf_assign_spaces(context.scene, ibuf); + } if (nr == 0) { BKE_sequencer_cache_put(context, seq, seq->start, SEQ_STRIPELEM_IBUF_STARTSTILL, ibuf); - } + } if (nr == seq->len - 1) { BKE_sequencer_cache_put(context, seq, seq->start, SEQ_STRIPELEM_IBUF_ENDSTILL, ibuf); @@ -2186,7 +2181,7 @@ static ImBuf *seq_render_movieclip_strip(SeqRenderData context, Sequence *seq, f memset(&user, 0, sizeof(MovieClipUser)); - BKE_movieclip_user_set_frame(&user, nr + seq->anim_startofs); + BKE_movieclip_user_set_frame(&user, nr + seq->anim_startofs + seq->clip->start_frame); user.render_size = MCLIP_PROXY_RENDER_SIZE_FULL; @@ -2344,9 +2339,11 @@ static ImBuf *seq_render_scene_strip(SeqRenderData context, Sequence *seq, float * -jahka */ - int rendering = G.is_rendering; - int doseq; - int doseq_gl = G.is_rendering ? /*(scene->r.seq_flag & R_SEQ_GL_REND)*/ 0 : /*(scene->r.seq_flag & R_SEQ_GL_PREV)*/ 1; + const short is_rendering = G.is_rendering; + const int do_seq_gl = G.is_rendering ? + 0 /* (context.scene->r.seq_flag & R_SEQ_GL_REND) */ : + (context.scene->r.seq_flag & R_SEQ_GL_PREV); + int do_seq; int have_seq = FALSE; Scene *scene; @@ -2363,9 +2360,10 @@ static ImBuf *seq_render_scene_strip(SeqRenderData context, Sequence *seq, float oldcfra = scene->r.cfra; scene->r.cfra = frame; - if (seq->scene_camera) + if (seq->scene_camera) { camera = seq->scene_camera; - else { + } + else { BKE_scene_camera_switch_update(scene); camera = scene->camera; } @@ -2376,7 +2374,7 @@ static ImBuf *seq_render_scene_strip(SeqRenderData context, Sequence *seq, float } /* prevent eternal loop */ - doseq = context.scene->r.scemode & R_DOSEQ; + do_seq = context.scene->r.scemode & R_DOSEQ; context.scene->r.scemode &= ~R_DOSEQ; #ifdef DURIAN_CAMERA_SWITCH @@ -2386,8 +2384,11 @@ static ImBuf *seq_render_scene_strip(SeqRenderData context, Sequence *seq, float #else (void)oldmarkers; #endif - - if (sequencer_view3d_cb && BLI_thread_is_main() && doseq_gl && (scene == context.scene || have_seq == 0) && camera) { + + if ((sequencer_view3d_cb && do_seq_gl && camera) && + (BLI_thread_is_main() == TRUE) && + ((have_seq == FALSE) || (scene == context.scene))) + { char err_out[256] = "unknown"; /* for old scened this can be uninitialized, * should probably be added to do_versions at some point if the functionality stays */ @@ -2407,14 +2408,14 @@ static ImBuf *seq_render_scene_strip(SeqRenderData context, Sequence *seq, float RenderResult rres; /* XXX: this if can be removed when sequence preview rendering uses the job system */ - if (rendering || context.scene != scene) { + if (is_rendering || context.scene != scene) { if (re == NULL) re = RE_NewRender(scene->id.name); RE_BlenderFrame(re, context.bmain, scene, NULL, camera, scene->lay, frame, FALSE); /* restore previous state after it was toggled on & off by RE_BlenderFrame */ - G.is_rendering = rendering; + G.is_rendering = is_rendering; } RE_AcquireResultImage(re, &rres); @@ -2441,7 +2442,7 @@ static ImBuf *seq_render_scene_strip(SeqRenderData context, Sequence *seq, float } /* restore */ - context.scene->r.scemode |= doseq; + context.scene->r.scemode |= do_seq; scene->r.cfra = oldcfra; @@ -2583,17 +2584,19 @@ static ImBuf *do_render_strip_uncached(SeqRenderData context, Sequence *seq, flo case SEQ_TYPE_MOVIECLIP: { ibuf = seq_render_movieclip_strip(context, seq, nr); - sequencer_imbuf_assign_spaces(context.scene, ibuf); - if (ibuf && use_preprocess) { + if (ibuf) { + /* duplicate frame so movie cache wouldn't be confused by sequencer's stuff */ ImBuf *i = IMB_dupImBuf(ibuf); - IMB_freeImBuf(ibuf); - ibuf = i; + + if (ibuf->rect_float) + BKE_sequencer_imbuf_to_sequencer_space(context.scene, ibuf, FALSE); + + copy_to_ibuf_still(context, seq, nr, ibuf); } - copy_to_ibuf_still(context, seq, nr, ibuf); break; } @@ -2830,7 +2833,7 @@ ImBuf *BKE_sequencer_give_ibuf(SeqRenderData context, float cfra, int chanshown) count = BLI_countlist(&ed->metastack); if ((chanshown < 0) && (count > 0)) { - count = MAX2(count + chanshown, 0); + count = max_ii(count + chanshown, 0); seqbasep = ((MetaStack *)BLI_findlink(&ed->metastack, count))->oldbasep; } else { @@ -3040,10 +3043,27 @@ int BKE_sequence_check_depend(Sequence *seq, Sequence *cur) return TRUE; } +static void sequence_do_invalidate_dependent(Sequence *seq, ListBase *seqbase) +{ + Sequence *cur; + + for (cur = seqbase->first; cur; cur = cur->next) { + if (cur == seq) + continue; + + if (BKE_sequence_check_depend(seq, cur)) { + BKE_sequencer_cache_cleanup_sequence(cur); + BKE_sequencer_preprocessed_cache_cleanup_sequence(cur); + } + + if (cur->seqbase.first) + sequence_do_invalidate_dependent(seq, &cur->seqbase); + } +} + static void sequence_invalidate_cache(Scene *scene, Sequence *seq, int invalidate_self, int invalidate_preprocess) { Editing *ed = scene->ed; - Sequence *cur; /* invalidate cache for current sequence */ if (invalidate_self) @@ -3057,17 +3077,11 @@ static void sequence_invalidate_cache(Scene *scene, Sequence *seq, int invalidat BKE_sequencer_preprocessed_cache_cleanup_sequence(seq); /* invalidate cache for all dependent sequences */ - SEQ_BEGIN (ed, cur) - { - if (cur == seq) - continue; - if (BKE_sequence_check_depend(seq, cur)) { - BKE_sequencer_cache_cleanup_sequence(cur); - BKE_sequencer_preprocessed_cache_cleanup_sequence(cur); - } - } - SEQ_END + /* NOTE: can not use SEQ_BEGIN/SEQ_END here because that macro will change sequence's depth, + * which makes transformation routines work incorrect + */ + sequence_do_invalidate_dependent(seq, &ed->seqbase); } void BKE_sequence_invalidate_cache(Scene *scene, Sequence *seq) @@ -3075,7 +3089,7 @@ void BKE_sequence_invalidate_cache(Scene *scene, Sequence *seq) sequence_invalidate_cache(scene, seq, TRUE, TRUE); } -void BKE_sequence_invalidate_deendent(Scene *scene, Sequence *seq) +void BKE_sequence_invalidate_dependent(Scene *scene, Sequence *seq) { sequence_invalidate_cache(scene, seq, FALSE, TRUE); } @@ -3188,7 +3202,7 @@ int BKE_sequence_tx_get_final_left(Sequence *seq, int metaclip) { if (metaclip && seq->tmp) { /* return the range clipped by the parents range */ - return maxi(BKE_sequence_tx_get_final_left(seq, 0), BKE_sequence_tx_get_final_left((Sequence *)seq->tmp, TRUE)); + return max_ii(BKE_sequence_tx_get_final_left(seq, 0), BKE_sequence_tx_get_final_left((Sequence *)seq->tmp, TRUE)); } else { return (seq->start - seq->startstill) + seq->startofs; @@ -3199,7 +3213,7 @@ int BKE_sequence_tx_get_final_right(Sequence *seq, int metaclip) { if (metaclip && seq->tmp) { /* return the range clipped by the parents range */ - return mini(BKE_sequence_tx_get_final_right(seq, 0), BKE_sequence_tx_get_final_right((Sequence *)seq->tmp, TRUE)); + return min_ii(BKE_sequence_tx_get_final_right(seq, 0), BKE_sequence_tx_get_final_right((Sequence *)seq->tmp, TRUE)); } else { return ((seq->start + seq->len) + seq->endstill) - seq->endofs; @@ -3451,7 +3465,7 @@ int BKE_sequence_base_shuffle(ListBase *seqbasep, Sequence *test, Scene *evil_sc for (seq = seqbasep->first; seq; seq = seq->next) { if (seq->machine == orig_machine) - new_frame = MAX2(new_frame, seq->enddisp); + new_frame = max_ii(new_frame, seq->enddisp); } test->machine = orig_machine; @@ -3476,10 +3490,10 @@ static int shuffle_seq_time_offset_test(ListBase *seqbasep, char dir) for (seq_other = seqbasep->first; seq_other; seq_other = seq_other->next) { if (!seq_other->tmp && seq_overlap(seq, seq_other)) { if (dir == 'L') { - offset = MIN2(offset, seq_other->startdisp - seq->enddisp); + offset = min_ii(offset, seq_other->startdisp - seq->enddisp); } else { - offset = MAX2(offset, seq_other->enddisp - seq->startdisp); + offset = max_ii(offset, seq_other->enddisp - seq->startdisp); } } } @@ -3664,26 +3678,26 @@ int BKE_sequence_swap(Sequence *seq_a, Sequence *seq_b, const char **error_str) char name[sizeof(seq_a->name)]; if (seq_a->len != seq_b->len) { - *error_str = "Strips must be the same length"; + *error_str = N_("Strips must be the same length"); return 0; } - /* type checking, could be more advanced but disalow sound vs non-sound copy */ + /* type checking, could be more advanced but disallow sound vs non-sound copy */ if (seq_a->type != seq_b->type) { if (seq_a->type == SEQ_TYPE_SOUND_RAM || seq_b->type == SEQ_TYPE_SOUND_RAM) { - *error_str = "Strips were not compatible"; + *error_str = N_("Strips were not compatible"); return 0; } /* disallow effects to swap with non-effects strips */ if ((seq_a->type & SEQ_TYPE_EFFECT) != (seq_b->type & SEQ_TYPE_EFFECT)) { - *error_str = "Strips were not compatible"; + *error_str = N_("Strips were not compatible"); return 0; } if ((seq_a->type & SEQ_TYPE_EFFECT) && (seq_b->type & SEQ_TYPE_EFFECT)) { if (BKE_sequence_effect_get_num_inputs(seq_a->type) != BKE_sequence_effect_get_num_inputs(seq_b->type)) { - *error_str = "Strips must have the same number of inputs"; + *error_str = N_("Strips must have the same number of inputs"); return 0; } } @@ -3880,7 +3894,7 @@ static void seq_load_apply(Scene *scene, Sequence *seq, SeqLoadInfo *seq_load) { if (seq) { BLI_strncpy(seq->name + 2, seq_load->name, sizeof(seq->name) - 2); - BKE_seqence_base_unique_name_recursive(&scene->ed->seqbase, seq); + BKE_sequence_base_unique_name_recursive(&scene->ed->seqbase, seq); if (seq_load->flag & SEQ_LOAD_FRAME_ADVANCE) { seq_load->start_frame += (seq->enddisp - seq->startdisp); @@ -3967,10 +3981,10 @@ Sequence *BKE_sequencer_add_sound_strip(bContext *C, ListBase *seqbasep, SeqLoad sound = sound_new_file(bmain, seq_load->path); /* handles relative paths */ if (sound == NULL || sound->playback_handle == NULL) { - /* +#if 0 if (op) BKE_report(op->reports, RPT_ERROR, "Unsupported audio format"); - */ +#endif return NULL; } @@ -3979,10 +3993,10 @@ Sequence *BKE_sequencer_add_sound_strip(bContext *C, ListBase *seqbasep, SeqLoad if (info.specs.channels == AUD_CHANNELS_INVALID) { sound_delete(bmain, sound); - /* +#if 0 if (op) BKE_report(op->reports, RPT_ERROR, "Unsupported audio format"); - */ +#endif return NULL; } @@ -3991,11 +4005,11 @@ Sequence *BKE_sequencer_add_sound_strip(bContext *C, ListBase *seqbasep, SeqLoad seq->type = SEQ_TYPE_SOUND_RAM; seq->sound = sound; BLI_strncpy(seq->name + 2, "Sound", SEQ_NAME_MAXSTR - 2); - BKE_seqence_base_unique_name_recursive(&scene->ed->seqbase, seq); + BKE_sequence_base_unique_name_recursive(&scene->ed->seqbase, seq); /* basic defaults */ seq->strip = strip = MEM_callocN(sizeof(Strip), "strip"); - seq->len = ceil(info.length * FPS); + seq->len = (int)ceil((double)info.length * FPS); strip->us = 1; /* we only need 1 element to store the filename */ @@ -4051,7 +4065,7 @@ Sequence *BKE_sequencer_add_movie_strip(bContext *C, ListBase *seqbasep, SeqLoad seq->anim = an; seq->anim_preseek = IMB_anim_get_preseek(an); BLI_strncpy(seq->name + 2, "Movie", SEQ_NAME_MAXSTR - 2); - BKE_seqence_base_unique_name_recursive(&scene->ed->seqbase, seq); + BKE_sequence_base_unique_name_recursive(&scene->ed->seqbase, seq); /* basic defaults */ seq->strip = strip = MEM_callocN(sizeof(Strip), "strip"); @@ -4163,7 +4177,7 @@ static Sequence *seq_dupli(Scene *scene, Scene *scene_to, Sequence *seq, int dup } if (dupe_flag & SEQ_DUPE_UNIQUE_NAME) - BKE_seqence_base_unique_name_recursive(&scene->ed->seqbase, seqn); + BKE_sequence_base_unique_name_recursive(&scene->ed->seqbase, seqn); if (dupe_flag & SEQ_DUPE_ANIM) BKE_sequencer_dupe_animdata(scene, seq->name + 2, seqn->name + 2); @@ -4218,7 +4232,7 @@ void BKE_sequence_base_dupli_recursive(Scene *scene, Scene *scene_to, ListBase * /* called on draw, needs to be fast, * we could cache and use a flag if we want to make checks for file paths resolving for eg. */ -int BKE_seqence_is_valid_check(Sequence *seq) +int BKE_sequence_is_valid_check(Sequence *seq) { switch (seq->type) { case SEQ_TYPE_MASK: diff --git a/source/blender/blenkernel/intern/shrinkwrap.c b/source/blender/blenkernel/intern/shrinkwrap.c index 9a8bcaabe0c..96faec389df 100644 --- a/source/blender/blenkernel/intern/shrinkwrap.c +++ b/source/blender/blenkernel/intern/shrinkwrap.c @@ -84,7 +84,7 @@ #endif /* get derived mesh */ -//TODO is anyfunction that does this? returning the derivedFinal without we caring if its in edit mode or not? +/* TODO is anyfunction that does this? returning the derivedFinal without we caring if its in edit mode or not? */ DerivedMesh *object_get_derived_final(Object *ob) { Mesh *me = ob->data; @@ -149,7 +149,7 @@ static void shrinkwrap_calc_nearest_vertex(ShrinkwrapCalcData *calc) return; } - //Setup nearest + /* Setup nearest */ nearest.index = -1; nearest.dist = FLT_MAX; #ifndef __APPLE__ @@ -159,10 +159,12 @@ static void shrinkwrap_calc_nearest_vertex(ShrinkwrapCalcData *calc) float *co = calc->vertexCos[i]; float tmp_co[3]; float weight = defvert_array_find_weight_safe(calc->dvert, i, calc->vgroup); - if (weight == 0.0f) continue; + if (weight == 0.0f) { + continue; + } - //Convert the vertex to tree coordinates + /* Convert the vertex to tree coordinates */ if (calc->vert) { copy_v3_v3(tmp_co, calc->vert[i].co); } @@ -171,11 +173,11 @@ static void shrinkwrap_calc_nearest_vertex(ShrinkwrapCalcData *calc) } space_transform_apply(&calc->local2target, tmp_co); - //Use local proximity heuristics (to reduce the nearest search) - // - //If we already had an hit before.. we assume this vertex is going to have a close hit to that other vertex - //so we can initiate the "nearest.dist" with the expected value to that last hit. - //This will lead in prunning of the search tree. + /* Use local proximity heuristics (to reduce the nearest search) + * + * If we already had an hit before.. we assume this vertex is going to have a close hit to that other vertex + * so we can initiate the "nearest.dist" with the expected value to that last hit. + * This will lead in prunning of the search tree. */ if (nearest.index != -1) nearest.dist = len_squared_v3v3(tmp_co, nearest.co); else @@ -184,23 +186,27 @@ static void shrinkwrap_calc_nearest_vertex(ShrinkwrapCalcData *calc) BLI_bvhtree_find_nearest(treeData.tree, tmp_co, &nearest, treeData.nearest_callback, &treeData); - //Found the nearest vertex + /* Found the nearest vertex */ if (nearest.index != -1) { - //Adjusting the vertex weight, so that after interpolating it keeps a certain distance from the nearest position - float dist = sasqrt(nearest.dist); - if (dist > FLT_EPSILON) weight *= (dist - calc->keepDist) / dist; + /* Adjusting the vertex weight, + * so that after interpolating it keeps a certain distance from the nearest position */ + if (nearest.dist > FLT_EPSILON) { + const float dist = sqrtf(nearest.dist); + weight *= (dist - calc->keepDist) / dist; + } - //Convert the coordinates back to mesh coordinates + /* Convert the coordinates back to mesh coordinates */ copy_v3_v3(tmp_co, nearest.co); space_transform_invert(&calc->local2target, tmp_co); - interp_v3_v3v3(co, co, tmp_co, weight); //linear interpolation + interp_v3_v3v3(co, co, tmp_co, weight); /* linear interpolation */ } } free_bvhtree_from_mesh(&treeData); } + /* * This function raycast a single vertex and updates the hit if the "hit" is considered valid. * Returns TRUE if "hit" was updated. @@ -209,16 +215,24 @@ static void shrinkwrap_calc_nearest_vertex(ShrinkwrapCalcData *calc) * MOD_SHRINKWRAP_CULL_TARGET_FRONTFACE (front faces hits are ignored) * MOD_SHRINKWRAP_CULL_TARGET_BACKFACE (back faces hits are ignored) */ -int normal_projection_project_vertex(char options, const float vert[3], const float dir[3], const SpaceTransform *transf, BVHTree *tree, BVHTreeRayHit *hit, BVHTree_RayCastCallback callback, void *userdata) +int normal_projection_project_vertex(char options, const float vert[3], const float dir[3], + const SpaceTransform *transf, + BVHTree *tree, BVHTreeRayHit *hit, + BVHTree_RayCastCallback callback, void *userdata) { + /* don't use this because this dist value could be incompatible + * this value used by the callback for comparing prev/new dist values. + * also, at the moment there is no need to have a corrected 'dist' value */ +// #define USE_DIST_CORRECT + float tmp_co[3], tmp_no[3]; const float *co, *no; BVHTreeRayHit hit_tmp; - //Copy from hit (we need to convert hit rays from one space coordinates to the other + /* Copy from hit (we need to convert hit rays from one space coordinates to the other */ memcpy(&hit_tmp, hit, sizeof(hit_tmp)); - //Apply space transform (TODO readjust dist) + /* Apply space transform (TODO readjust dist) */ if (transf) { copy_v3_v3(tmp_co, vert); space_transform_apply(transf, tmp_co); @@ -228,7 +242,9 @@ int normal_projection_project_vertex(char options, const float vert[3], const fl space_transform_apply_normal(transf, tmp_no); no = tmp_no; +#ifdef USE_DIST_CORRECT hit_tmp.dist *= mat4_to_scale(((SpaceTransform *)transf)->local2target); +#endif } else { co = vert; @@ -249,7 +265,7 @@ int normal_projection_project_vertex(char options, const float vert[3], const fl /* apply backface */ const float dot = dot_v3v3(dir, hit_tmp.no); if (((options & MOD_SHRINKWRAP_CULL_TARGET_FRONTFACE) && dot <= 0.0f) || - ((options & MOD_SHRINKWRAP_CULL_TARGET_BACKFACE) && dot >= 0.0f)) + ((options & MOD_SHRINKWRAP_CULL_TARGET_BACKFACE) && dot >= 0.0f)) { return FALSE; /* Ignore hit */ } @@ -258,9 +274,13 @@ int normal_projection_project_vertex(char options, const float vert[3], const fl if (transf) { /* Inverting space transform (TODO make coeherent with the initial dist readjust) */ space_transform_invert(transf, hit_tmp.co); - hit_tmp.dist = len_v3v3((float *)vert, hit_tmp.co); +#ifdef USE_DIST_CORRECT + hit_tmp.dist = len_v3v3(vert, hit_tmp.co); +#endif } + BLI_assert(hit_tmp.dist <= hit->dist); + memcpy(hit, &hit_tmp, sizeof(hit_tmp)); return TRUE; } @@ -272,41 +292,46 @@ static void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc) { int i; - //Options about projection direction + /* Options about projection direction */ const char use_normal = calc->smd->shrinkOpts; float proj_axis[3] = {0.0f, 0.0f, 0.0f}; - //Raycast and tree stuff + /* Raycast and tree stuff */ + + /** \note 'hit.dist' is kept in the targets space, this is only used + * for finding the best hit, to get the real dist, + * measure the len_v3v3() from the input coord to hit.co */ BVHTreeRayHit hit; BVHTreeFromMesh treeData = NULL_BVHTreeFromMesh; - //auxiliary target + /* auxiliary target */ DerivedMesh *auxMesh = NULL; BVHTreeFromMesh auxData = NULL_BVHTreeFromMesh; SpaceTransform local2aux; - //If the user doesn't allows to project in any direction of projection axis - //then theres nothing todo. + /* If the user doesn't allows to project in any direction of projection axis + * then theres nothing todo. */ if ((use_normal & (MOD_SHRINKWRAP_PROJECT_ALLOW_POS_DIR | MOD_SHRINKWRAP_PROJECT_ALLOW_NEG_DIR)) == 0) return; - //Prepare data to retrieve the direction in which we should project each vertex + /* Prepare data to retrieve the direction in which we should project each vertex */ if (calc->smd->projAxis == MOD_SHRINKWRAP_PROJECT_OVER_NORMAL) { if (calc->vert == NULL) return; } else { - //The code supports any axis that is a combination of X,Y,Z - //although currently UI only allows to set the 3 different axis + /* The code supports any axis that is a combination of X,Y,Z + * although currently UI only allows to set the 3 different axis */ if (calc->smd->projAxis & MOD_SHRINKWRAP_PROJECT_OVER_X_AXIS) proj_axis[0] = 1.0f; if (calc->smd->projAxis & MOD_SHRINKWRAP_PROJECT_OVER_Y_AXIS) proj_axis[1] = 1.0f; if (calc->smd->projAxis & MOD_SHRINKWRAP_PROJECT_OVER_Z_AXIS) proj_axis[2] = 1.0f; normalize_v3(proj_axis); - //Invalid projection direction - if (dot_v3v3(proj_axis, proj_axis) < FLT_EPSILON) - return; + /* Invalid projection direction */ + if (len_squared_v3(proj_axis) < FLT_EPSILON) { + return; + } } if (calc->smd->auxTarget) { @@ -316,7 +341,7 @@ static void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc) SPACE_TRANSFORM_SETUP(&local2aux, calc->ob, calc->smd->auxTarget); } - //After sucessufuly build the trees, start projection vertexs + /* After sucessufuly build the trees, start projection vertexs */ if (bvhtree_from_mesh_faces(&treeData, calc->target, 0.0, 4, 6) && (auxMesh == NULL || bvhtree_from_mesh_faces(&auxData, auxMesh, 0.0, 4, 6))) { @@ -327,9 +352,11 @@ static void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc) for (i = 0; i < calc->numVerts; ++i) { float *co = calc->vertexCos[i]; float tmp_co[3], tmp_no[3]; - float weight = defvert_array_find_weight_safe(calc->dvert, i, calc->vgroup); + const float weight = defvert_array_find_weight_safe(calc->dvert, i, calc->vgroup); - if (weight == 0.0f) continue; + if (weight == 0.0f) { + continue; + } if (calc->vert) { /* calc->vert contains verts from derivedMesh */ @@ -351,26 +378,36 @@ static void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc) hit.index = -1; - hit.dist = 10000.0f; //TODO: we should use FLT_MAX here, but sweepsphere code isn't prepared for that + hit.dist = 10000.0f; /* TODO: we should use FLT_MAX here, but sweepsphere code isn't prepared for that */ - //Project over positive direction of axis + /* Project over positive direction of axis */ if (use_normal & MOD_SHRINKWRAP_PROJECT_ALLOW_POS_DIR) { - if (auxData.tree) - normal_projection_project_vertex(0, tmp_co, tmp_no, &local2aux, auxData.tree, &hit, auxData.raycast_callback, &auxData); + if (auxData.tree) { + normal_projection_project_vertex(0, tmp_co, tmp_no, + &local2aux, auxData.tree, &hit, + auxData.raycast_callback, &auxData); + } - normal_projection_project_vertex(calc->smd->shrinkOpts, tmp_co, tmp_no, &calc->local2target, treeData.tree, &hit, treeData.raycast_callback, &treeData); + normal_projection_project_vertex(calc->smd->shrinkOpts, tmp_co, tmp_no, + &calc->local2target, treeData.tree, &hit, + treeData.raycast_callback, &treeData); } - //Project over negative direction of axis - if (use_normal & MOD_SHRINKWRAP_PROJECT_ALLOW_NEG_DIR && hit.index == -1) { + /* Project over negative direction of axis */ + if (use_normal & MOD_SHRINKWRAP_PROJECT_ALLOW_NEG_DIR) { float inv_no[3]; negate_v3_v3(inv_no, tmp_no); - if (auxData.tree) - normal_projection_project_vertex(0, tmp_co, inv_no, &local2aux, auxData.tree, &hit, auxData.raycast_callback, &auxData); + if (auxData.tree) { + normal_projection_project_vertex(0, tmp_co, inv_no, + &local2aux, auxData.tree, &hit, + auxData.raycast_callback, &auxData); + } - normal_projection_project_vertex(calc->smd->shrinkOpts, tmp_co, inv_no, &calc->local2target, treeData.tree, &hit, treeData.raycast_callback, &treeData); + normal_projection_project_vertex(calc->smd->shrinkOpts, tmp_co, inv_no, + &calc->local2target, treeData.tree, &hit, + treeData.raycast_callback, &treeData); } @@ -381,7 +418,7 @@ static void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc) } } - //free data structures + /* free data structures */ free_bvhtree_from_mesh(&treeData); free_bvhtree_from_mesh(&auxData); } @@ -399,19 +436,19 @@ static void shrinkwrap_calc_nearest_surface_point(ShrinkwrapCalcData *calc) BVHTreeFromMesh treeData = NULL_BVHTreeFromMesh; BVHTreeNearest nearest = NULL_BVHTreeNearest; - //Create a bvh-tree of the given target + /* Create a bvh-tree of the given target */ BENCH(bvhtree_from_mesh_faces(&treeData, calc->target, 0.0, 2, 6)); if (treeData.tree == NULL) { OUT_OF_MEMORY(); return; } - //Setup nearest + /* Setup nearest */ nearest.index = -1; nearest.dist = FLT_MAX; - //Find the nearest vertex + /* Find the nearest vertex */ #ifndef __APPLE__ #pragma omp parallel for default(none) private(i) firstprivate(nearest) shared(calc,treeData) schedule(static) #endif @@ -421,7 +458,7 @@ static void shrinkwrap_calc_nearest_surface_point(ShrinkwrapCalcData *calc) float weight = defvert_array_find_weight_safe(calc->dvert, i, calc->vgroup); if (weight == 0.0f) continue; - //Convert the vertex to tree coordinates + /* Convert the vertex to tree coordinates */ if (calc->vert) { copy_v3_v3(tmp_co, calc->vert[i].co); } @@ -430,11 +467,11 @@ static void shrinkwrap_calc_nearest_surface_point(ShrinkwrapCalcData *calc) } space_transform_apply(&calc->local2target, tmp_co); - //Use local proximity heuristics (to reduce the nearest search) - // - //If we already had an hit before.. we assume this vertex is going to have a close hit to that other vertex - //so we can initiate the "nearest.dist" with the expected value to that last hit. - //This will lead in prunning of the search tree. + /* Use local proximity heuristics (to reduce the nearest search) + * + * If we already had an hit before.. we assume this vertex is going to have a close hit to that other vertex + * so we can initiate the "nearest.dist" with the expected value to that last hit. + * This will lead in prunning of the search tree. */ if (nearest.index != -1) nearest.dist = len_squared_v3v3(tmp_co, nearest.co); else @@ -442,24 +479,28 @@ static void shrinkwrap_calc_nearest_surface_point(ShrinkwrapCalcData *calc) BLI_bvhtree_find_nearest(treeData.tree, tmp_co, &nearest, treeData.nearest_callback, &treeData); - //Found the nearest vertex + /* Found the nearest vertex */ if (nearest.index != -1) { if (calc->smd->shrinkOpts & MOD_SHRINKWRAP_KEEP_ABOVE_SURFACE) { - //Make the vertex stay on the front side of the face + /* Make the vertex stay on the front side of the face */ madd_v3_v3v3fl(tmp_co, nearest.co, nearest.no, calc->keepDist); } else { - //Adjusting the vertex weight, so that after interpolating it keeps a certain distance from the nearest position + /* Adjusting the vertex weight, + * so that after interpolating it keeps a certain distance from the nearest position */ float dist = sasqrt(nearest.dist); - if (dist > FLT_EPSILON) - interp_v3_v3v3(tmp_co, tmp_co, nearest.co, (dist - calc->keepDist) / dist); //linear interpolation - else + if (dist > FLT_EPSILON) { + /* linear interpolation */ + interp_v3_v3v3(tmp_co, tmp_co, nearest.co, (dist - calc->keepDist) / dist); + } + else { copy_v3_v3(tmp_co, nearest.co); + } } - //Convert the coordinates back to mesh coordinates + /* Convert the coordinates back to mesh coordinates */ space_transform_invert(&calc->local2target, tmp_co); - interp_v3_v3v3(co, co, tmp_co, weight); //linear interpolation + interp_v3_v3v3(co, co, tmp_co, weight); /* linear interpolation */ } } @@ -467,24 +508,25 @@ static void shrinkwrap_calc_nearest_surface_point(ShrinkwrapCalcData *calc) } /* Main shrinkwrap function */ -void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd, Object *ob, DerivedMesh *dm, float (*vertexCos)[3], int numVerts) +void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd, Object *ob, DerivedMesh *dm, + float (*vertexCos)[3], int numVerts) { DerivedMesh *ss_mesh = NULL; ShrinkwrapCalcData calc = NULL_ShrinkwrapCalcData; - //remove loop dependencies on derived meshs (TODO should this be done elsewhere?) + /* remove loop dependencies on derived meshs (TODO should this be done elsewhere?) */ if (smd->target == ob) smd->target = NULL; if (smd->auxTarget == ob) smd->auxTarget = NULL; - //Configure Shrinkwrap calc data + /* Configure Shrinkwrap calc data */ calc.smd = smd; calc.ob = ob; calc.numVerts = numVerts; calc.vertexCos = vertexCos; - //DeformVertex + /* DeformVertex */ calc.vgroup = defgroup_name_index(calc.ob, calc.smd->vgroup_name); if (dm) { calc.dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT); @@ -497,12 +539,12 @@ void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd, Object *ob, DerivedM if (smd->target) { calc.target = object_get_derived_final(smd->target); - //TODO there might be several "bugs" on non-uniform scales matrixs - //because it will no longer be nearest surface, not sphere projection - //because space has been deformed + /* TODO there might be several "bugs" on non-uniform scales matrixs + * because it will no longer be nearest surface, not sphere projection + * because space has been deformed */ SPACE_TRANSFORM_SETUP(&calc.local2target, ob, smd->target); - //TODO: smd->keepDist is in global units.. must change to local + /* TODO: smd->keepDist is in global units.. must change to local */ calc.keepDist = smd->keepDist; } @@ -511,15 +553,15 @@ void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd, Object *ob, DerivedM calc.vgroup = defgroup_name_index(calc.ob, smd->vgroup_name); if (dm != NULL && smd->shrinkType == MOD_SHRINKWRAP_PROJECT) { - //Setup arrays to get vertexs positions, normals and deform weights + /* Setup arrays to get vertexs positions, normals and deform weights */ calc.vert = dm->getVertDataArray(dm, CD_MVERT); calc.dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT); - //Using vertexs positions/normals as if a subsurface was applied + /* Using vertexs positions/normals as if a subsurface was applied */ if (smd->subsurfLevels) { SubsurfModifierData ssmd = {{NULL}}; - ssmd.subdivType = ME_CC_SUBSURF; //catmull clark - ssmd.levels = smd->subsurfLevels; //levels + ssmd.subdivType = ME_CC_SUBSURF; /* catmull clark */ + ssmd.levels = smd->subsurfLevels; /* levels */ ss_mesh = subsurf_make_derived_from_derived(dm, &ssmd, NULL, (ob->mode & OB_MODE_EDIT) ? SUBSURF_IN_EDIT_MODE : 0); @@ -532,13 +574,13 @@ void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd, Object *ob, DerivedM } } - //Just to make sure we are not leaving any memory behind + /* Just to make sure we are not leaving any memory behind */ assert(ssmd.emCache == NULL); assert(ssmd.mCache == NULL); } } - //Projecting target defined - lets work! + /* Projecting target defined - lets work! */ if (calc.target) { switch (smd->shrinkType) { case MOD_SHRINKWRAP_NEAREST_SURFACE: @@ -555,8 +597,7 @@ void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd, Object *ob, DerivedM } } - //free memory + /* free memory */ if (ss_mesh) ss_mesh->release(ss_mesh); } - diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c index 5e67e094e43..443aed1fc41 100644 --- a/source/blender/blenkernel/intern/smoke.c +++ b/source/blender/blenkernel/intern/smoke.c @@ -51,18 +51,7 @@ #include "BLI_kdtree.h" #include "BLI_kdopbvh.h" #include "BLI_utildefines.h" - -#include "BKE_bvhutils.h" -#include "BKE_cdderivedmesh.h" -#include "BKE_collision.h" -#include "BKE_customdata.h" -#include "BKE_DerivedMesh.h" -#include "BKE_effect.h" -#include "BKE_modifier.h" -#include "BKE_particle.h" -#include "BKE_pointcache.h" -#include "BKE_smoke.h" - +#include "BLI_voxel.h" #include "DNA_customdata_types.h" #include "DNA_group_types.h" @@ -75,8 +64,20 @@ #include "DNA_scene_types.h" #include "DNA_smoke_types.h" +#include "BKE_bvhutils.h" +#include "BKE_cdderivedmesh.h" +#include "BKE_collision.h" +#include "BKE_customdata.h" +#include "BKE_deform.h" +#include "BKE_DerivedMesh.h" +#include "BKE_effect.h" +#include "BKE_modifier.h" +#include "BKE_particle.h" +#include "BKE_pointcache.h" #include "BKE_smoke.h" +#include "RE_shader_ext.h" + /* UNUSED so far, may be enabled later */ /* #define USE_SMOKE_COLLISION_DM */ @@ -94,38 +95,38 @@ static LARGE_INTEGER liFrequency; static LARGE_INTEGER liStartTime; static LARGE_INTEGER liCurrentTime; -static void tstart ( void ) +static void tstart(void) { - QueryPerformanceFrequency ( &liFrequency ); - QueryPerformanceCounter ( &liStartTime ); + QueryPerformanceFrequency(&liFrequency); + QueryPerformanceCounter(&liStartTime); } -static void tend ( void ) +static void tend(void) { - QueryPerformanceCounter ( &liCurrentTime ); + QueryPerformanceCounter(&liCurrentTime); } -static double UNUSED_FUNCTION(tval)( void ) +static double tval(void) { - return ((double)( (liCurrentTime.QuadPart - liStartTime.QuadPart)* (double)1000.0/(double)liFrequency.QuadPart )); + return ((double)( (liCurrentTime.QuadPart - liStartTime.QuadPart) * (double)1000.0 / (double)liFrequency.QuadPart)); } #else #include static struct timeval _tstart, _tend; static struct timezone tz; -static void tstart ( void ) +static void tstart(void) { - gettimeofday ( &_tstart, &tz ); + gettimeofday(&_tstart, &tz); } -static void tend ( void ) +static void tend(void) { - gettimeofday ( &_tend,&tz ); + gettimeofday(&_tend, &tz); } -static double UNUSED_FUNCTION(tval)( void ) +static double UNUSED_FUNCTION(tval) (void) { double t1, t2; - t1 = ( double ) _tstart.tv_sec*1000 + ( double ) _tstart.tv_usec/ ( 1000 ); - t2 = ( double ) _tend.tv_sec*1000 + ( double ) _tend.tv_usec/ ( 1000 ); - return t2-t1; + t1 = ( double ) _tstart.tv_sec * 1000 + ( double ) _tstart.tv_usec / (1000); + t2 = ( double ) _tend.tv_sec * 1000 + ( double ) _tend.tv_usec / (1000); + return t2 - t1; } #endif @@ -134,608 +135,238 @@ struct Scene; struct DerivedMesh; struct SmokeModifierData; -#define TRI_UVOFFSET (1./4.) - // timestep default value for nice appearance 0.1f #define DT_DEFAULT 0.1f -/* forward declerations */ -static void calcTriangleDivs(Object *ob, MVert *verts, int numverts, MFace *tris, int numfaces, int numtris, int **tridivs, float cell_len); -static void get_cell(const float p0[3], const int res[3], float dx, const float pos[3], int cell[3], int correct); -static void fill_scs_points(Object *ob, DerivedMesh *dm, SmokeCollSettings *scs); +#define ADD_IF_LOWER_POS(a, b) (MIN2((a) + (b), MAX2((a), (b)))) +#define ADD_IF_LOWER_NEG(a, b) (MAX2((a) + (b), MIN2((a), (b)))) +#define ADD_IF_LOWER(a, b) (((b) > 0) ? ADD_IF_LOWER_POS((a), (b)) : ADD_IF_LOWER_NEG((a), (b))) #else /* WITH_SMOKE */ /* Stubs to use when smoke is disabled */ -struct WTURBULENCE *smoke_turbulence_init(int *UNUSED(res), int UNUSED(amplify), int UNUSED(noisetype)) { return NULL; } -// struct FLUID_3D *smoke_init(int *UNUSED(res), float *UNUSED(p0)) { return NULL; } +struct WTURBULENCE *smoke_turbulence_init(int *UNUSED(res), int UNUSED(amplify), int UNUSED(noisetype), int UNUSED(use_fire), int UNUSED(use_colors)) { return NULL; } +//struct FLUID_3D *smoke_init(int *UNUSED(res), float *UNUSED(dx), float *UNUSED(dtdef), int UNUSED(use_heat), int UNUSED(use_fire), int UNUSED(use_colors)) { return NULL; } void smoke_free(struct FLUID_3D *UNUSED(fluid)) {} float *smoke_get_density(struct FLUID_3D *UNUSED(fluid)) { return NULL; } void smoke_turbulence_free(struct WTURBULENCE *UNUSED(wt)) {} void smoke_initWaveletBlenderRNA(struct WTURBULENCE *UNUSED(wt), float *UNUSED(strength)) {} -void smoke_initBlenderRNA(struct FLUID_3D *UNUSED(fluid), float *UNUSED(alpha), float *UNUSED(beta), float *UNUSED(dt_factor), float *UNUSED(vorticity), int *UNUSED(border_colli)) {} -long long smoke_get_mem_req(int UNUSED(xres), int UNUSED(yres), int UNUSED(zres), int UNUSED(amplify)) { return 0; } -void smokeModifier_do(SmokeModifierData *UNUSED(smd), Scene *UNUSED(scene), Object *UNUSED(ob), DerivedMesh *UNUSED(dm)) {} +void smoke_initBlenderRNA(struct FLUID_3D *UNUSED(fluid), float *UNUSED(alpha), float *UNUSED(beta), float *UNUSED(dt_factor), float *UNUSED(vorticity), + int *UNUSED(border_colli), float *UNUSED(burning_rate), float *UNUSED(flame_smoke), float *UNUSED(flame_smoke_color), + float *UNUSED(flame_vorticity), float *UNUSED(flame_ignition_temp), float *UNUSED(flame_max_temp)) {} +struct DerivedMesh *smokeModifier_do(SmokeModifierData *UNUSED(smd), Scene *UNUSED(scene), Object *UNUSED(ob), DerivedMesh *UNUSED(dm)) { return NULL; } +float smoke_get_velocity_at(struct Object *UNUSED(ob), float UNUSED(position[3]), float UNUSED(velocity[3])) { return 0.0f; } +void flame_get_spectrum(unsigned char *UNUSED(spec), int UNUSED(width), float UNUSED(t1), float UNUSED(t2)) {} #endif /* WITH_SMOKE */ #ifdef WITH_SMOKE -static int smokeModifier_init (SmokeModifierData *smd, Object *ob, Scene *scene, DerivedMesh *dm) +void smoke_reallocate_fluid(SmokeDomainSettings *sds, float dx, int res[3], int free_old) { - if((smd->type & MOD_SMOKE_TYPE_DOMAIN) && smd->domain && !smd->domain->fluid) - { - size_t i; - float min[3] = {FLT_MAX, FLT_MAX, FLT_MAX}, max[3] = {-FLT_MAX, -FLT_MAX, -FLT_MAX}; - float size[3]; - MVert *verts = dm->getVertArray(dm); - float scale = 0.0; - int res; - - res = smd->domain->maxres; - - // get BB of domain - for(i = 0; i < dm->getNumVerts(dm); i++) - { - float tmp[3]; - - copy_v3_v3(tmp, verts[i].co); - mul_m4_v3(ob->obmat, tmp); - - // min BB - min[0] = MIN2(min[0], tmp[0]); - min[1] = MIN2(min[1], tmp[1]); - min[2] = MIN2(min[2], tmp[2]); - - // max BB - max[0] = MAX2(max[0], tmp[0]); - max[1] = MAX2(max[1], tmp[1]); - max[2] = MAX2(max[2], tmp[2]); - } - - copy_v3_v3(smd->domain->p0, min); - copy_v3_v3(smd->domain->p1, max); - - // calc other res with max_res provided - sub_v3_v3v3(size, max, min); - - // prevent crash when initializing a plane as domain - if((size[0] < FLT_EPSILON) || (size[1] < FLT_EPSILON) || (size[2] < FLT_EPSILON)) - return 0; - - if(size[0] > size[1]) - { - if(size[0] > size[2]) - { - scale = res / size[0]; - smd->domain->scale = size[0]; - smd->domain->dx = 1.0f / res; - smd->domain->res[0] = res; - smd->domain->res[1] = (int)(size[1] * scale + 0.5); - smd->domain->res[2] = (int)(size[2] * scale + 0.5); - } - else { - scale = res / size[2]; - smd->domain->scale = size[2]; - smd->domain->dx = 1.0f / res; - smd->domain->res[2] = res; - smd->domain->res[0] = (int)(size[0] * scale + 0.5); - smd->domain->res[1] = (int)(size[1] * scale + 0.5); - } - } - else { - if(size[1] > size[2]) - { - scale = res / size[1]; - smd->domain->scale = size[1]; - smd->domain->dx = 1.0f / res; - smd->domain->res[1] = res; - smd->domain->res[0] = (int)(size[0] * scale + 0.5); - smd->domain->res[2] = (int)(size[2] * scale + 0.5); - } - else { - scale = res / size[2]; - smd->domain->scale = size[2]; - smd->domain->dx = 1.0f / res; - smd->domain->res[2] = res; - smd->domain->res[0] = (int)(size[0] * scale + 0.5); - smd->domain->res[1] = (int)(size[1] * scale + 0.5); - } - } - - // TODO: put in failsafe if res<=0 - dg - - // dt max is 0.1 - smd->domain->fluid = smoke_init(smd->domain->res, smd->domain->p0, DT_DEFAULT); - smd->time = scene->r.cfra; - - if(smd->domain->flags & MOD_SMOKE_HIGHRES) - { - smd->domain->wt = smoke_turbulence_init(smd->domain->res, smd->domain->amplify + 1, smd->domain->noise); - smd->domain->res_wt[0] = smd->domain->res[0] * (smd->domain->amplify + 1); - smd->domain->res_wt[1] = smd->domain->res[1] * (smd->domain->amplify + 1); - smd->domain->res_wt[2] = smd->domain->res[2] * (smd->domain->amplify + 1); - smd->domain->dx_wt = smd->domain->dx / (smd->domain->amplify + 1); - } - - if(!smd->domain->shadow) - smd->domain->shadow = MEM_callocN(sizeof(float) * smd->domain->res[0] * smd->domain->res[1] * smd->domain->res[2], "SmokeDomainShadow"); - - smoke_initBlenderRNA(smd->domain->fluid, &(smd->domain->alpha), &(smd->domain->beta), &(smd->domain->time_scale), &(smd->domain->vorticity), &(smd->domain->border_collisions)); - - if(smd->domain->wt) - { - smoke_initWaveletBlenderRNA(smd->domain->wt, &(smd->domain->strength)); - } - return 1; - } - else if((smd->type & MOD_SMOKE_TYPE_FLOW) && smd->flow) - { - // handle flow object here - // XXX TODO - - smd->time = scene->r.cfra; - - return 1; - } - else if((smd->type & MOD_SMOKE_TYPE_COLL)) - { - // todo: delete this when loading colls work -dg - - if(!smd->coll) - { - smokeModifier_createType(smd); - } - - if(!smd->coll->points) - { - // init collision points - SmokeCollSettings *scs = smd->coll; - - smd->time = scene->r.cfra; - - // copy obmat - copy_m4_m4(scs->mat, ob->obmat); - copy_m4_m4(scs->mat_old, ob->obmat); - - DM_ensure_tessface(dm); - fill_scs_points(ob, dm, scs); - } - - if(!smd->coll->bvhtree) - { - smd->coll->bvhtree = NULL; // bvhtree_build_from_smoke ( ob->obmat, dm->getTessFaceArray(dm), dm->getNumTessFaces(dm), dm->getVertArray(dm), dm->getNumVerts(dm), 0.0 ); - } - return 1; + int use_heat = (sds->active_fields & SM_ACTIVE_HEAT); + int use_fire = (sds->active_fields & (SM_ACTIVE_HEAT | SM_ACTIVE_FIRE)); + int use_colors = (sds->active_fields & SM_ACTIVE_COLORS); + + if (free_old && sds->fluid) + smoke_free(sds->fluid); + if (!MIN3(res[0], res[1], res[2])) { + sds->fluid = NULL; + return; } - - return 2; + sds->fluid = smoke_init(res, dx, DT_DEFAULT, use_heat, use_fire, use_colors); + smoke_initBlenderRNA(sds->fluid, &(sds->alpha), &(sds->beta), &(sds->time_scale), &(sds->vorticity), &(sds->border_collisions), + &(sds->burning_rate), &(sds->flame_smoke), sds->flame_smoke_color, &(sds->flame_vorticity), &(sds->flame_ignition), &(sds->flame_max_temp)); + + /* reallocate shadow buffer */ + if (sds->shadow) + MEM_freeN(sds->shadow); + sds->shadow = MEM_callocN(sizeof(float) * res[0] * res[1] * res[2], "SmokeDomainShadow"); } -static void fill_scs_points(Object *ob, DerivedMesh *dm, SmokeCollSettings *scs) +void smoke_reallocate_highres_fluid(SmokeDomainSettings *sds, float dx, int res[3], int free_old) { - MVert *mvert = dm->getVertArray(dm); - MFace *mface = dm->getTessFaceArray(dm); - int i = 0, divs = 0; - - // DG TODO: need to do this dynamically according to the domain object! - float cell_len = scs->dx; - int newdivs = 0; - int quads = 0, facecounter = 0; + int use_fire = (sds->active_fields & (SM_ACTIVE_HEAT | SM_ACTIVE_FIRE)); + int use_colors = (sds->active_fields & SM_ACTIVE_COLORS); - // count quads - for(i = 0; i < dm->getNumTessFaces(dm); i++) - { - if(mface[i].v4) - quads++; + if (free_old && sds->wt) + smoke_turbulence_free(sds->wt); + if (!MIN3(res[0], res[1], res[2])) { + sds->wt = NULL; + return; } + sds->wt = smoke_turbulence_init(res, sds->amplify + 1, sds->noise, use_fire, use_colors); + sds->res_wt[0] = res[0] * (sds->amplify + 1); + sds->res_wt[1] = res[1] * (sds->amplify + 1); + sds->res_wt[2] = res[2] * (sds->amplify + 1); + sds->dx_wt = dx / (sds->amplify + 1); + smoke_initWaveletBlenderRNA(sds->wt, &(sds->strength)); +} - scs->numtris = dm->getNumTessFaces(dm) + quads; - scs->tridivs = NULL; - calcTriangleDivs(ob, mvert, dm->getNumVerts(dm), mface, dm->getNumTessFaces(dm), scs->numtris, &(scs->tridivs), cell_len); +/* convert global position to domain cell space */ +static void smoke_pos_to_cell(SmokeDomainSettings *sds, float pos[3]) +{ + mul_m4_v3(sds->imat, pos); + sub_v3_v3(pos, sds->p0); + pos[0] *= 1.0f / sds->cell_size[0]; + pos[1] *= 1.0f / sds->cell_size[1]; + pos[2] *= 1.0f / sds->cell_size[2]; +} - // count triangle divisions - for(i = 0; i < dm->getNumTessFaces(dm) + quads; i++) - { - divs += (scs->tridivs[3 * i] + 1) * (scs->tridivs[3 * i + 1] + 1) * (scs->tridivs[3 * i + 2] + 1); - } +/* set domain resolution and dimensions from object derivedmesh */ +static void smoke_set_domain_from_derivedmesh(SmokeDomainSettings *sds, Object *ob, DerivedMesh *dm) +{ + size_t i; + float min[3] = {FLT_MAX, FLT_MAX, FLT_MAX}, max[3] = {-FLT_MAX, -FLT_MAX, -FLT_MAX}; + float size[3]; + MVert *verts = dm->getVertArray(dm); + float scale = 0.0; + int res; - scs->points = MEM_callocN(sizeof(float) * (dm->getNumVerts(dm) + divs) * 3, "SmokeCollPoints"); - scs->points_old = MEM_callocN(sizeof(float) * (dm->getNumVerts(dm) + divs) * 3, "SmokeCollPointsOld"); + res = sds->maxres; - for(i = 0; i < dm->getNumVerts(dm); i++) + // get BB of domain + for (i = 0; i < dm->getNumVerts(dm); i++) { - float tmpvec[3]; - copy_v3_v3(tmpvec, mvert[i].co); - // mul_m4_v3(ob->obmat, tmpvec); // DG: use local coordinates, we save MAT anyway - copy_v3_v3(&scs->points[i * 3], tmpvec); + // min BB + min[0] = MIN2(min[0], verts[i].co[0]); + min[1] = MIN2(min[1], verts[i].co[1]); + min[2] = MIN2(min[2], verts[i].co[2]); + + // max BB + max[0] = MAX2(max[0], verts[i].co[0]); + max[1] = MAX2(max[1], verts[i].co[1]); + max[2] = MAX2(max[2], verts[i].co[2]); } - - for(i = 0, facecounter = 0; i < dm->getNumTessFaces(dm); i++) - { - int again = 0; - do - { - int j, k; - int divs1 = scs->tridivs[3 * facecounter + 0]; - int divs2 = scs->tridivs[3 * facecounter + 1]; - //int divs3 = scs->tridivs[3 * facecounter + 2]; - float side1[3], side2[3], trinormorg[3], trinorm[3]; - - if(again == 1 && mface[i].v4) - { - sub_v3_v3v3(side1, mvert[ mface[i].v3 ].co, mvert[ mface[i].v1 ].co); - sub_v3_v3v3(side2, mvert[ mface[i].v4 ].co, mvert[ mface[i].v1 ].co); - } - else { - sub_v3_v3v3(side1, mvert[ mface[i].v2 ].co, mvert[ mface[i].v1 ].co); - sub_v3_v3v3(side2, mvert[ mface[i].v3 ].co, mvert[ mface[i].v1 ].co); - } - cross_v3_v3v3(trinormorg, side1, side2); - normalize_v3(trinormorg); - copy_v3_v3(trinorm, trinormorg); - mul_v3_fl(trinorm, 0.25 * cell_len); + /* set domain bounds */ + copy_v3_v3(sds->p0, min); + copy_v3_v3(sds->p1, max); + sds->dx = 1.0f / res; - for(j = 0; j <= divs1; j++) - { - for(k = 0; k <= divs2; k++) - { - float p1[3], p2[3], p3[3], p[3]={0,0,0}; - const float uf = (float)(j + TRI_UVOFFSET) / (float)(divs1 + 0.0); - const float vf = (float)(k + TRI_UVOFFSET) / (float)(divs2 + 0.0); - float tmpvec[3]; - - if(uf+vf > 1.0) - { - // printf("bigger - divs1: %d, divs2: %d\n", divs1, divs2); - continue; - } + /* calculate domain dimensions */ + sub_v3_v3v3(size, max, min); + copy_v3_v3(sds->cell_size, size); + mul_v3_v3(size, ob->size); + copy_v3_v3(sds->global_size, size); + copy_v3_v3(sds->dp0, min); - copy_v3_v3(p1, mvert[ mface[i].v1 ].co); - if(again == 1 && mface[i].v4) - { - copy_v3_v3(p2, mvert[ mface[i].v3 ].co); - copy_v3_v3(p3, mvert[ mface[i].v4 ].co); - } - else { - copy_v3_v3(p2, mvert[ mface[i].v2 ].co); - copy_v3_v3(p3, mvert[ mface[i].v3 ].co); - } + invert_m4_m4(sds->imat, ob->obmat); - mul_v3_fl(p1, (1.0-uf-vf)); - mul_v3_fl(p2, uf); - mul_v3_fl(p3, vf); - - add_v3_v3v3(p, p1, p2); - add_v3_v3(p, p3); - - if(newdivs > divs) - printf("mem problem\n"); - - // mMovPoints.push_back(p + trinorm); - add_v3_v3v3(tmpvec, p, trinorm); - // mul_m4_v3(ob->obmat, tmpvec); // DG: use local coordinates, we save MAT anyway - copy_v3_v3(&scs->points[3 * (dm->getNumVerts(dm) + newdivs)], tmpvec); - newdivs++; - - if(newdivs > divs) - printf("mem problem\n"); - - // mMovPoints.push_back(p - trinorm); - copy_v3_v3(tmpvec, p); - sub_v3_v3(tmpvec, trinorm); - // mul_m4_v3(ob->obmat, tmpvec); // DG: use local coordinates, we save MAT anyway - copy_v3_v3(&scs->points[3 * (dm->getNumVerts(dm) + newdivs)], tmpvec); - newdivs++; - } - } - - if(again == 0 && mface[i].v4) - again++; - else - again = 0; - - facecounter++; + // prevent crash when initializing a plane as domain + if ((size[0] < FLT_EPSILON) || (size[1] < FLT_EPSILON) || (size[2] < FLT_EPSILON)) + return; - } while(again!=0); + /* 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->base_res[0] = res; + sds->base_res[1] = (int)(size[1] * scale + 0.5); + sds->base_res[2] = (int)(size[2] * scale + 0.5); } - - scs->numverts = dm->getNumVerts(dm); - // DG TODO: also save triangle count? - - scs->numpoints = dm->getNumVerts(dm) + newdivs; - - for(i = 0; i < scs->numpoints * 3; i++) - { - scs->points_old[i] = scs->points[i]; + else if (size[1] > MAX2(size[0], size[2])) { + scale = res / size[1]; + sds->scale = size[1] / ob->size[1]; + sds->base_res[0] = (int)(size[0] * scale + 0.5); + sds->base_res[1] = res; + sds->base_res[2] = (int)(size[2] * scale + 0.5); + } + else { + scale = res / size[2]; + sds->scale = size[2] / ob->size[2]; + sds->base_res[0] = (int)(size[0] * scale + 0.5); + sds->base_res[1] = (int)(size[1] * scale + 0.5); + sds->base_res[2] = res; } -} + /* set cell size */ + sds->cell_size[0] /= (float)sds->base_res[0]; + sds->cell_size[1] /= (float)sds->base_res[1]; + sds->cell_size[2] /= (float)sds->base_res[2]; +} -static void fill_scs_points_anim(Object *UNUSED(ob), DerivedMesh *dm, SmokeCollSettings *scs) +static int smokeModifier_init(SmokeModifierData *smd, Object *ob, Scene *scene, DerivedMesh *dm) { - MVert *mvert = dm->getVertArray(dm); - MFace *mface = dm->getTessFaceArray(dm); - int quads = 0, numtris = 0, facecounter = 0; - unsigned int i = 0; - int divs = 0, newdivs = 0; - - // DG TODO: need to do this dynamically according to the domain object! - float cell_len = scs->dx; - - // count quads - for(i = 0; i < dm->getNumTessFaces(dm); i++) + if ((smd->type & MOD_SMOKE_TYPE_DOMAIN) && smd->domain && !smd->domain->fluid) { - if(mface[i].v4) - quads++; - } + SmokeDomainSettings *sds = smd->domain; + int res[3]; + /* set domain dimensions from derivedmesh */ + smoke_set_domain_from_derivedmesh(sds, ob, dm); + /* reset domain values */ + zero_v3_int(sds->shift); + zero_v3(sds->shift_f); + add_v3_fl(sds->shift_f, 0.5f); + zero_v3(sds->prev_loc); + mul_m4_v3(ob->obmat, sds->prev_loc); + + /* set resolutions */ + if (smd->domain->flags & MOD_SMOKE_ADAPTIVE_DOMAIN) { + res[0] = res[1] = res[2] = 1; /* use minimum res for adaptive init */ + } + else { + VECCOPY(res, sds->base_res); + } + VECCOPY(sds->res, res); + sds->total_cells = sds->res[0] * sds->res[1] * sds->res[2]; + sds->res_min[0] = sds->res_min[1] = sds->res_min[2] = 0; + VECCOPY(sds->res_max, res); - numtris = dm->getNumTessFaces(dm) + quads; + /* allocate fluid */ + smoke_reallocate_fluid(sds, sds->dx, sds->res, 0); - // check if mesh changed topology - if(scs->numtris != numtris) - return; - if(scs->numverts != dm->getNumVerts(dm)) - return; + smd->time = scene->r.cfra; - // update new positions - for(i = 0; i < dm->getNumVerts(dm); i++) - { - float tmpvec[3]; - copy_v3_v3(tmpvec, mvert[i].co); - copy_v3_v3(&scs->points[i * 3], tmpvec); - } + /* allocate highres fluid */ + if (sds->flags & MOD_SMOKE_HIGHRES) { + smoke_reallocate_highres_fluid(sds, sds->dx, sds->res, 0); + } + /* allocate shadow buffer */ + if (!sds->shadow) + sds->shadow = MEM_callocN(sizeof(float) * sds->res[0] * sds->res[1] * sds->res[2], "SmokeDomainShadow"); - // for every triangle // update div points - for(i = 0, facecounter = 0; i < dm->getNumTessFaces(dm); i++) + return 1; + } + else if ((smd->type & MOD_SMOKE_TYPE_FLOW) && smd->flow) { - int again = 0; - do - { - int j, k; - int divs1 = scs->tridivs[3 * facecounter + 0]; - int divs2 = scs->tridivs[3 * facecounter + 1]; - float srcside1[3], srcside2[3], destside1[3], destside2[3], src_trinormorg[3], dest_trinormorg[3], src_trinorm[3], dest_trinorm[3]; - - if(again == 1 && mface[i].v4) - { - sub_v3_v3v3(srcside1, &scs->points_old[mface[i].v3 * 3], &scs->points_old[mface[i].v1 * 3]); - sub_v3_v3v3(destside1, &scs->points[mface[i].v3 * 3], &scs->points[mface[i].v1 * 3]); - - sub_v3_v3v3(srcside2, &scs->points_old[mface[i].v4 * 3], &scs->points_old[mface[i].v1 * 3]); - sub_v3_v3v3(destside2, &scs->points[mface[i].v4 * 3], &scs->points[mface[i].v1 * 3]); - } - else { - sub_v3_v3v3(srcside1, &scs->points_old[mface[i].v2 * 3], &scs->points_old[mface[i].v1 * 3]); - sub_v3_v3v3(destside1, &scs->points[mface[i].v2 * 3], &scs->points[mface[i].v1 * 3]); - - sub_v3_v3v3(srcside2, &scs->points_old[mface[i].v3 * 3], &scs->points_old[mface[i].v1 * 3]); - sub_v3_v3v3(destside2, &scs->points[mface[i].v3 * 3], &scs->points[mface[i].v1 * 3]); - } - - cross_v3_v3v3(src_trinormorg, srcside1, srcside2); - cross_v3_v3v3(dest_trinormorg, destside1, destside2); - - normalize_v3(src_trinormorg); - normalize_v3(dest_trinormorg); - - copy_v3_v3(src_trinorm, src_trinormorg); - copy_v3_v3(dest_trinorm, dest_trinormorg); - - mul_v3_fl(src_trinorm, 0.25 * cell_len); - mul_v3_fl(dest_trinorm, 0.25 * cell_len); - - for(j = 0; j <= divs1; j++) - { - for(k = 0; k <= divs2; k++) - { - float src_p1[3], src_p2[3], src_p3[3], src_p[3]={0,0,0}; - float dest_p1[3], dest_p2[3], dest_p3[3], dest_p[3]={0,0,0}; - const float uf = (float)(j + TRI_UVOFFSET) / (float)(divs1 + 0.0); - const float vf = (float)(k + TRI_UVOFFSET) / (float)(divs2 + 0.0); - float src_tmpvec[3], dest_tmpvec[3]; - - if(uf+vf > 1.0) - { - // printf("bigger - divs1: %d, divs2: %d\n", divs1, divs2); - continue; - } - - copy_v3_v3(src_p1, &scs->points_old[mface[i].v1 * 3]); - copy_v3_v3(dest_p1, &scs->points[mface[i].v1 * 3]); - if(again == 1 && mface[i].v4) - { - copy_v3_v3(src_p2, &scs->points_old[mface[i].v3 * 3]); - copy_v3_v3(dest_p2, &scs->points[mface[i].v3 * 3]); - - copy_v3_v3(src_p3,&scs->points_old[mface[i].v4 * 3]); - copy_v3_v3(dest_p3, &scs->points[mface[i].v4 * 3]); - } - else { - copy_v3_v3(src_p2, &scs->points_old[mface[i].v2 * 3]); - copy_v3_v3(dest_p2, &scs->points[mface[i].v2 * 3]); - copy_v3_v3(src_p3, &scs->points_old[mface[i].v3 * 3]); - copy_v3_v3(dest_p3, &scs->points[mface[i].v3 * 3]); - } - - mul_v3_fl(src_p1, (1.0-uf-vf)); - mul_v3_fl(dest_p1, (1.0-uf-vf)); - - mul_v3_fl(src_p2, uf); - mul_v3_fl(dest_p2, uf); - - mul_v3_fl(src_p3, vf); - mul_v3_fl(dest_p3, vf); - - add_v3_v3v3(src_p, src_p1, src_p2); - add_v3_v3v3(dest_p, dest_p1, dest_p2); - - add_v3_v3(src_p, src_p3); - add_v3_v3(dest_p, dest_p3); - - if(newdivs > divs) - printf("mem problem\n"); - - // mMovPoints.push_back(p + trinorm); - add_v3_v3v3(src_tmpvec, src_p, src_trinorm); - add_v3_v3v3(dest_tmpvec, dest_p, dest_trinorm); - - // mul_m4_v3(ob->obmat, tmpvec); // DG: use local coordinates, we save MAT anyway - copy_v3_v3(&scs->points_old[3 * (dm->getNumVerts(dm) + newdivs)], src_tmpvec); - copy_v3_v3(&scs->points[3 * (dm->getNumVerts(dm) + newdivs)], dest_tmpvec); - newdivs++; - - if(newdivs > divs) - printf("mem problem\n"); - - // mMovPoints.push_back(p - trinorm); - copy_v3_v3(src_tmpvec, src_p); - copy_v3_v3(dest_tmpvec, dest_p); - - sub_v3_v3(src_tmpvec, src_trinorm); - sub_v3_v3(dest_tmpvec, dest_trinorm); - - // mul_m4_v3(ob->obmat, tmpvec); // DG: use local coordinates, we save MAT anyway - copy_v3_v3(&scs->points_old[3 * (dm->getNumVerts(dm) + newdivs)], src_tmpvec); - copy_v3_v3(&scs->points[3 * (dm->getNumVerts(dm) + newdivs)], dest_tmpvec); - newdivs++; - } - } - - if(again == 0 && mface[i].v4) - again++; - else - again = 0; - - facecounter++; + smd->time = scene->r.cfra; - } while(again!=0); + return 1; } - - // scs->numpoints = dm->getNumVerts(dm) + newdivs; - -} - -/*! init triangle divisions */ -static void calcTriangleDivs(Object *ob, MVert *verts, int UNUSED(numverts), MFace *faces, int numfaces, int numtris, int **tridivs, float cell_len) -{ - // mTriangleDivs1.resize( faces.size() ); - // mTriangleDivs2.resize( faces.size() ); - // mTriangleDivs3.resize( faces.size() ); - - size_t i = 0, facecounter = 0; - float maxscale[3] = {1,1,1}; // = channelFindMaxVf(mcScale); get max scale value - float maxpart = ABS(maxscale[0]); - float scaleFac = 0; - float fsTri = 0; - if(ABS(maxscale[1])>maxpart) maxpart = ABS(maxscale[1]); - if(ABS(maxscale[2])>maxpart) maxpart = ABS(maxscale[2]); - scaleFac = 1.0 / maxpart; - // featureSize = mLevel[mMaxRefine].nodeSize - fsTri = cell_len * 0.75 * scaleFac; // fsTri = cell_len * 0.9; - - if(*tridivs) - MEM_freeN(*tridivs); - - *tridivs = MEM_callocN(sizeof(int) * numtris * 3, "Smoke_Tridivs"); - - for(i = 0, facecounter = 0; i < numfaces; i++) + else if ((smd->type & MOD_SMOKE_TYPE_COLL)) { - float p0[3], p1[3], p2[3]; - float side1[3]; - float side2[3]; - float side3[3]; - int divs1=0, divs2=0, divs3=0; - - copy_v3_v3(p0, verts[faces[i].v1].co); - mul_m4_v3(ob->obmat, p0); - copy_v3_v3(p1, verts[faces[i].v2].co); - mul_m4_v3(ob->obmat, p1); - copy_v3_v3(p2, verts[faces[i].v3].co); - mul_m4_v3(ob->obmat, p2); - - sub_v3_v3v3(side1, p1, p0); - sub_v3_v3v3(side2, p2, p0); - sub_v3_v3v3(side3, p1, p2); - - if(dot_v3v3(side1, side1) > fsTri*fsTri) - { - float tmp = normalize_v3(side1); - divs1 = (int)ceil(tmp/fsTri); - } - if(dot_v3v3(side2, side2) > fsTri*fsTri) - { - float tmp = normalize_v3(side2); - divs2 = (int)ceil(tmp/fsTri); - - /* - // debug - if(i==0) - printf("b tmp: %f, fsTri: %f, divs2: %d\n", tmp, fsTri, divs2); - */ - + if (!smd->coll) + { + smokeModifier_createType(smd); } - (*tridivs)[3 * facecounter + 0] = divs1; - (*tridivs)[3 * facecounter + 1] = divs2; - (*tridivs)[3 * facecounter + 2] = divs3; - - // TODO quad case - if(faces[i].v4) - { - divs1=0, divs2=0, divs3=0; - - facecounter++; - - copy_v3_v3(p0, verts[faces[i].v3].co); - mul_m4_v3(ob->obmat, p0); - copy_v3_v3(p1, verts[faces[i].v4].co); - mul_m4_v3(ob->obmat, p1); - copy_v3_v3(p2, verts[faces[i].v1].co); - mul_m4_v3(ob->obmat, p2); - - sub_v3_v3v3(side1, p1, p0); - sub_v3_v3v3(side2, p2, p0); - sub_v3_v3v3(side3, p1, p2); - - if(dot_v3v3(side1, side1) > fsTri*fsTri) - { - float tmp = normalize_v3(side1); - divs1 = (int)ceil(tmp/fsTri); - } - if(dot_v3v3(side2, side2) > fsTri*fsTri) - { - float tmp = normalize_v3(side2); - divs2 = (int)ceil(tmp/fsTri); - } + smd->time = scene->r.cfra; - (*tridivs)[3 * facecounter + 0] = divs1; - (*tridivs)[3 * facecounter + 1] = divs2; - (*tridivs)[3 * facecounter + 2] = divs3; - } - facecounter++; + return 1; } + + return 2; } #endif /* WITH_SMOKE */ static void smokeModifier_freeDomain(SmokeModifierData *smd) { - if(smd->domain) + if (smd->domain) { - if(smd->domain->shadow) - MEM_freeN(smd->domain->shadow); - smd->domain->shadow = NULL; + if (smd->domain->shadow) + MEM_freeN(smd->domain->shadow); + smd->domain->shadow = NULL; - if(smd->domain->fluid) + if (smd->domain->fluid) smoke_free(smd->domain->fluid); - if(smd->domain->wt) + if (smd->domain->wt) smoke_turbulence_free(smd->domain->wt); - if(smd->domain->effector_weights) - MEM_freeN(smd->domain->effector_weights); + if (smd->domain->effector_weights) + MEM_freeN(smd->domain->effector_weights); smd->domain->effector_weights = NULL; BKE_ptcache_free_list(&(smd->domain->ptcaches[0])); @@ -748,16 +379,10 @@ static void smokeModifier_freeDomain(SmokeModifierData *smd) static void smokeModifier_freeFlow(SmokeModifierData *smd) { - if(smd->flow) + if (smd->flow) { -/* - if(smd->flow->bvh) - { - free_bvhtree_from_mesh(smd->flow->bvh); - MEM_freeN(smd->flow->bvh); - } - smd->flow->bvh = NULL; -*/ + if (smd->flow->dm) smd->flow->dm->release(smd->flow->dm); + if (smd->flow->verts_old) MEM_freeN(smd->flow->verts_old); MEM_freeN(smd->flow); smd->flow = NULL; } @@ -765,40 +390,22 @@ static void smokeModifier_freeFlow(SmokeModifierData *smd) static void smokeModifier_freeCollision(SmokeModifierData *smd) { - if(smd->coll) + if (smd->coll) { SmokeCollSettings *scs = smd->coll; - if(scs->numpoints) + if (scs->numverts) { - if(scs->points) - { - MEM_freeN(scs->points); - scs->points = NULL; - } - if(scs->points_old) - { - MEM_freeN(scs->points_old); - scs->points_old = NULL; - } - if(scs->tridivs) + if (scs->verts_old) { - MEM_freeN(scs->tridivs); - scs->tridivs = NULL; + MEM_freeN(scs->verts_old); + scs->verts_old = NULL; } } - if(scs->bvhtree) - { - BLI_bvhtree_free(scs->bvhtree); - scs->bvhtree = NULL; - } - -#ifdef USE_SMOKE_COLLISION_DM - if(smd->coll->dm) + if (smd->coll->dm) smd->coll->dm->release(smd->coll->dm); smd->coll->dm = NULL; -#endif MEM_freeN(smd->coll); smd->coll = NULL; @@ -807,7 +414,7 @@ static void smokeModifier_freeCollision(SmokeModifierData *smd) void smokeModifier_reset_turbulence(struct SmokeModifierData *smd) { - if(smd && smd->domain && smd->domain->wt) + if (smd && smd->domain && smd->domain->wt) { smoke_turbulence_free(smd->domain->wt); smd->domain->wt = NULL; @@ -816,15 +423,15 @@ void smokeModifier_reset_turbulence(struct SmokeModifierData *smd) void smokeModifier_reset(struct SmokeModifierData *smd) { - if(smd) + if (smd) { - if(smd->domain) + if (smd->domain) { - if(smd->domain->shadow) + if (smd->domain->shadow) MEM_freeN(smd->domain->shadow); smd->domain->shadow = NULL; - if(smd->domain->fluid) + if (smd->domain->fluid) { smoke_free(smd->domain->fluid); smd->domain->fluid = NULL; @@ -833,39 +440,23 @@ void smokeModifier_reset(struct SmokeModifierData *smd) smokeModifier_reset_turbulence(smd); smd->time = -1; - - // printf("reset domain end\n"); + smd->domain->total_cells = 0; + smd->domain->active_fields = 0; } - else if(smd->flow) + else if (smd->flow) { - /* - if(smd->flow->bvh) - { - free_bvhtree_from_mesh(smd->flow->bvh); - MEM_freeN(smd->flow->bvh); - } - smd->flow->bvh = NULL; - */ + if (smd->flow->verts_old) MEM_freeN(smd->flow->verts_old); + smd->flow->verts_old = NULL; + smd->flow->numverts = 0; } - else if(smd->coll) + else if (smd->coll) { SmokeCollSettings *scs = smd->coll; - if(scs->numpoints && scs->points) + if (scs->numverts && scs->verts_old) { - MEM_freeN(scs->points); - scs->points = NULL; - - if(scs->points_old) - { - MEM_freeN(scs->points_old); - scs->points_old = NULL; - } - if(scs->tridivs) - { - MEM_freeN(scs->tridivs); - scs->tridivs = NULL; - } + MEM_freeN(scs->verts_old); + scs->verts_old = NULL; } } } @@ -873,7 +464,7 @@ void smokeModifier_reset(struct SmokeModifierData *smd) void smokeModifier_free(SmokeModifierData *smd) { - if(smd) + if (smd) { smokeModifier_freeDomain(smd); smokeModifier_freeFlow(smd); @@ -883,11 +474,11 @@ void smokeModifier_free(SmokeModifierData *smd) void smokeModifier_createType(struct SmokeModifierData *smd) { - if(smd) + if (smd) { - if(smd->type & MOD_SMOKE_TYPE_DOMAIN) + if (smd->type & MOD_SMOKE_TYPE_DOMAIN) { - if(smd->domain) + if (smd->domain) smokeModifier_freeDomain(smd); smd->domain = MEM_callocN(sizeof(SmokeDomainSettings), "SmokeDomain"); @@ -903,13 +494,12 @@ void smokeModifier_createType(struct SmokeModifierData *smd) smd->domain->ptcaches[1].first = smd->domain->ptcaches[1].last = NULL; /* set some standard values */ smd->domain->fluid = NULL; - smd->domain->wt = NULL; + smd->domain->wt = NULL; smd->domain->eff_group = NULL; smd->domain->fluid_group = NULL; smd->domain->coll_group = NULL; smd->domain->maxres = 32; - smd->domain->amplify = 1; - smd->domain->omega = 1.0; + smd->domain->amplify = 1; smd->domain->alpha = -0.001; smd->domain->beta = 0.1; smd->domain->time_scale = 1.0; @@ -919,14 +509,28 @@ void smokeModifier_createType(struct SmokeModifierData *smd) smd->domain->strength = 2.0; smd->domain->noise = MOD_SMOKE_NOISEWAVE; smd->domain->diss_speed = 5; - // init 3dview buffer + smd->domain->active_fields = 0; + + smd->domain->adapt_margin = 4; + smd->domain->adapt_res = 0; + smd->domain->adapt_threshold = 0.02f; + + smd->domain->burning_rate = 0.75f; + smd->domain->flame_smoke = 1.0f; + smd->domain->flame_vorticity = 0.5f; + smd->domain->flame_ignition = 1.25f; + smd->domain->flame_max_temp = 1.75f; + /* color */ + smd->domain->flame_smoke_color[0] = 0.7f; + smd->domain->flame_smoke_color[1] = 0.7f; + smd->domain->flame_smoke_color[2] = 0.7f; smd->domain->viewsettings = MOD_SMOKE_VIEW_SHOWBIG; smd->domain->effector_weights = BKE_add_effector_weights(NULL); } - else if(smd->type & MOD_SMOKE_TYPE_FLOW) + else if (smd->type & MOD_SMOKE_TYPE_FLOW) { - if(smd->flow) + if (smd->flow) smokeModifier_freeFlow(smd); smd->flow = MEM_callocN(sizeof(SmokeFlowSettings), "SmokeFlow"); @@ -934,31 +538,35 @@ void smokeModifier_createType(struct SmokeModifierData *smd) smd->flow->smd = smd; /* set some standard values */ - smd->flow->density = 1.0; - smd->flow->temp = 1.0; + smd->flow->density = 1.0f; + smd->flow->fuel_amount = 1.0f; + smd->flow->temp = 1.0f; smd->flow->flags = MOD_SMOKE_FLOW_ABSOLUTE; - smd->flow->vel_multi = 1.0; + smd->flow->vel_multi = 1.0f; + smd->flow->surface_distance = 1.5f; + smd->flow->source = MOD_SMOKE_FLOW_SOURCE_MESH; + smd->flow->texture_size = 1.0f; + + smd->flow->color[0] = 0.7f; + smd->flow->color[1] = 0.7f; + smd->flow->color[2] = 0.7f; + smd->flow->dm = NULL; smd->flow->psys = NULL; } - else if(smd->type & MOD_SMOKE_TYPE_COLL) + else if (smd->type & MOD_SMOKE_TYPE_COLL) { - if(smd->coll) + if (smd->coll) smokeModifier_freeCollision(smd); smd->coll = MEM_callocN(sizeof(SmokeCollSettings), "SmokeColl"); smd->coll->smd = smd; - smd->coll->points = NULL; - smd->coll->points_old = NULL; - smd->coll->tridivs = NULL; - smd->coll->vel = NULL; - smd->coll->numpoints = 0; - smd->coll->numtris = 0; - smd->coll->bvhtree = NULL; + smd->coll->verts_old = NULL; + smd->coll->numverts = 0; smd->coll->type = 0; // static obstacle - smd->coll->dx = 1.0f / 50.0f; + smd->coll->dm = NULL; #ifdef USE_SMOKE_COLLISION_DM smd->coll->dm = NULL; @@ -971,39 +579,67 @@ void smokeModifier_copy(struct SmokeModifierData *smd, struct SmokeModifierData { tsmd->type = smd->type; tsmd->time = smd->time; - + smokeModifier_createType(tsmd); if (tsmd->domain) { - tsmd->domain->maxres = smd->domain->maxres; - tsmd->domain->amplify = smd->domain->amplify; - tsmd->domain->omega = smd->domain->omega; + tsmd->domain->fluid_group = smd->domain->fluid_group; + tsmd->domain->coll_group = smd->domain->coll_group; + + tsmd->domain->adapt_margin = smd->domain->adapt_margin; + tsmd->domain->adapt_res = smd->domain->adapt_res; + tsmd->domain->adapt_threshold = smd->domain->adapt_threshold; + tsmd->domain->alpha = smd->domain->alpha; tsmd->domain->beta = smd->domain->beta; + tsmd->domain->amplify = smd->domain->amplify; + tsmd->domain->maxres = smd->domain->maxres; tsmd->domain->flags = smd->domain->flags; - tsmd->domain->strength = smd->domain->strength; + tsmd->domain->viewsettings = smd->domain->viewsettings; tsmd->domain->noise = smd->domain->noise; tsmd->domain->diss_speed = smd->domain->diss_speed; - tsmd->domain->viewsettings = smd->domain->viewsettings; - tsmd->domain->fluid_group = smd->domain->fluid_group; - tsmd->domain->coll_group = smd->domain->coll_group; + tsmd->domain->strength = smd->domain->strength; + + tsmd->domain->border_collisions = smd->domain->border_collisions; tsmd->domain->vorticity = smd->domain->vorticity; tsmd->domain->time_scale = smd->domain->time_scale; - tsmd->domain->border_collisions = smd->domain->border_collisions; - + + tsmd->domain->burning_rate = smd->domain->burning_rate; + tsmd->domain->flame_smoke = smd->domain->flame_smoke; + tsmd->domain->flame_vorticity = smd->domain->flame_vorticity; + tsmd->domain->flame_ignition = smd->domain->flame_ignition; + tsmd->domain->flame_max_temp = smd->domain->flame_max_temp; + copy_v3_v3(tsmd->domain->flame_smoke_color, smd->domain->flame_smoke_color); + MEM_freeN(tsmd->domain->effector_weights); tsmd->domain->effector_weights = MEM_dupallocN(smd->domain->effector_weights); - } + } else if (tsmd->flow) { + tsmd->flow->psys = smd->flow->psys; + tsmd->flow->noise_texture = smd->flow->noise_texture; + + tsmd->flow->vel_multi = smd->flow->vel_multi; + tsmd->flow->vel_normal = smd->flow->vel_normal; + tsmd->flow->vel_random = smd->flow->vel_random; + tsmd->flow->density = smd->flow->density; + copy_v3_v3(tsmd->flow->color, smd->flow->color); + tsmd->flow->fuel_amount = smd->flow->fuel_amount; tsmd->flow->temp = smd->flow->temp; - tsmd->flow->psys = smd->flow->psys; + tsmd->flow->volume_density = smd->flow->volume_density; + tsmd->flow->surface_distance = smd->flow->surface_distance; + + tsmd->flow->texture_size = smd->flow->texture_size; + tsmd->flow->texture_offset = smd->flow->texture_offset; + BLI_strncpy(tsmd->flow->uvlayer_name, tsmd->flow->uvlayer_name, sizeof(tsmd->flow->uvlayer_name)); + tsmd->flow->vgroup_density = smd->flow->vgroup_density; + tsmd->flow->type = smd->flow->type; + tsmd->flow->source = smd->flow->source; + tsmd->flow->texture_type = smd->flow->texture_type; tsmd->flow->flags = smd->flow->flags; - tsmd->flow->vel_multi = smd->flow->vel_multi; } else if (tsmd->coll) { - ; /* leave it as initialized, collision settings is mostly caches */ } } @@ -1011,24 +647,24 @@ void smokeModifier_copy(struct SmokeModifierData *smd, struct SmokeModifierData #ifdef WITH_SMOKE // forward decleration -static void smoke_calc_transparency(float *result, float *input, float *p0, float *p1, int res[3], float dx, float *light, bresenham_callback cb, float correct); +static void smoke_calc_transparency(SmokeDomainSettings *sds, Scene *scene); static float calc_voxel_transp(float *result, float *input, int res[3], int *pixel, float *tRay, float correct); static int get_lamp(Scene *scene, float *light) -{ - Base *base_tmp = NULL; +{ + Base *base_tmp = NULL; int found_lamp = 0; // try to find a lamp, preferably local - for(base_tmp = scene->base.first; base_tmp; base_tmp= base_tmp->next) { - if(base_tmp->object->type == OB_LAMP) { + for (base_tmp = scene->base.first; base_tmp; base_tmp = base_tmp->next) { + if (base_tmp->object->type == OB_LAMP) { Lamp *la = base_tmp->object->data; - if(la->type == LA_LOCAL) { + if (la->type == LA_LOCAL) { copy_v3_v3(light, base_tmp->object->obmat[3]); return 1; } - else if(!found_lamp) { + else if (!found_lamp) { copy_v3_v3(light, base_tmp->object->obmat[3]); found_lamp = 1; } @@ -1038,48 +674,131 @@ static int get_lamp(Scene *scene, float *light) return found_lamp; } -static void smoke_calc_domain(Scene *UNUSED(scene), Object *UNUSED(ob), SmokeModifierData *UNUSED(smd)) +static void obstacles_from_derivedmesh(Object *coll_ob, SmokeDomainSettings *sds, SmokeCollSettings *scs, unsigned char *obstacle_map, float *velocityX, float *velocityY, float *velocityZ, float dt) { -#if 0 - SmokeDomainSettings *sds = smd->domain; - GroupObject *go = NULL; - Base *base = NULL; - - /* do collisions, needs to be done before emission, so that smoke isn't emitted inside collision cells */ - if(1) + if (!scs->dm) return; { - unsigned int i; - Object **collobjs = NULL; - unsigned int numcollobj = 0; - collobjs = get_collisionobjects(scene, ob, sds->coll_group, &numcollobj); + DerivedMesh *dm = NULL; + MVert *mvert = NULL; + MFace *mface = NULL; + BVHTreeFromMesh treeData = {0}; + int numverts, i, z; + + float surface_distance = 0.6; + + float *vert_vel = NULL; + int has_velocity = 0; + + tstart(); + + dm = CDDM_copy(scs->dm); + CDDM_calc_normals(dm); + mvert = dm->getVertArray(dm); + mface = dm->getTessFaceArray(dm); + numverts = dm->getNumVerts(dm); + + // DG TODO + // if (scs->type > SM_COLL_STATIC) + // if line above is used, the code is in trouble if the object moves but is declared as "does not move" - for(i = 0; i < numcollobj; i++) { - Object *collob= collobjs[i]; - SmokeModifierData *smd2 = (SmokeModifierData*)modifiers_findByType(collob, eModifierType_Smoke); - - // check for active smoke modifier - // if(md && md->mode & (eModifierMode_Realtime | eModifierMode_Render)) - // SmokeModifierData *smd2 = (SmokeModifierData *)md; - - if((smd2->type & MOD_SMOKE_TYPE_COLL) && smd2->coll && smd2->coll->points && smd2->coll->points_old) + vert_vel = MEM_callocN(sizeof(float) * numverts * 3, "smoke_obs_velocity"); + + if (scs->numverts != numverts || !scs->verts_old) { + if (scs->verts_old) MEM_freeN(scs->verts_old); + + scs->verts_old = MEM_callocN(sizeof(float) * numverts * 3, "smoke_obs_verts_old"); + scs->numverts = numverts; + } + else { + has_velocity = 1; + } + } + + /* Transform collider vertices to + * domain grid space for fast lookups */ + for (i = 0; i < numverts; i++) { + float n[3]; + float co[3]; + + /* vert pos */ + mul_m4_v3(coll_ob->obmat, mvert[i].co); + smoke_pos_to_cell(sds, mvert[i].co); + + /* vert normal */ + normal_short_to_float_v3(n, mvert[i].no); + mul_mat3_m4_v3(coll_ob->obmat, n); + mul_mat3_m4_v3(sds->imat, n); + normalize_v3(n); + normal_float_to_short_v3(mvert[i].no, n); + + /* vert velocity */ + VECADD(co, mvert[i].co, sds->shift); + if (has_velocity) { - // ??? anything to do here? + sub_v3_v3v3(&vert_vel[i * 3], co, &scs->verts_old[i * 3]); + mul_v3_fl(&vert_vel[i * 3], sds->dx / dt); + } + copy_v3_v3(&scs->verts_old[i * 3], co); + } - // TODO: only something to do for ANIMATED obstacles: need to update positions + if (bvhtree_from_mesh_faces(&treeData, dm, 0.0f, 4, 6)) { + #pragma omp parallel for schedule(static) + for (z = sds->res_min[2]; z < sds->res_max[2]; z++) { + int x, y; + for (x = sds->res_min[0]; x < sds->res_max[0]; x++) + for (y = sds->res_min[1]; y < sds->res_max[1]; y++) { + int index = smoke_get_index(x - sds->res_min[0], sds->res[0], y - sds->res_min[1], sds->res[1], z - sds->res_min[2]); + + float ray_start[3] = {(float)x + 0.5f, (float)y + 0.5f, (float)z + 0.5f}; + BVHTreeNearest nearest = {0}; + nearest.index = -1; + nearest.dist = surface_distance * surface_distance; /* find_nearest uses squared distance */ + + /* find the nearest point on the mesh */ + if (BLI_bvhtree_find_nearest(treeData.tree, ray_start, &nearest, treeData.nearest_callback, &treeData) != -1) { + float weights[4]; + int v1, v2, v3, f_index = nearest.index; + + /* calculate barycentric weights for nearest point */ + v1 = mface[f_index].v1; + v2 = (nearest.flags & BVH_ONQUAD) ? mface[f_index].v3 : mface[f_index].v2; + v3 = (nearest.flags & BVH_ONQUAD) ? mface[f_index].v4 : mface[f_index].v3; + interp_weights_face_v3(weights, mvert[v1].co, mvert[v2].co, mvert[v3].co, NULL, nearest.co); + + // DG TODO + if (has_velocity) + { + /* apply object velocity */ + { + float hit_vel[3]; + interp_v3_v3v3v3(hit_vel, &vert_vel[v1 * 3], &vert_vel[v2 * 3], &vert_vel[v3 * 3], weights); + velocityX[index] += hit_vel[0]; + velocityY[index] += hit_vel[1]; + velocityZ[index] += hit_vel[2]; + } + } + + /* tag obstacle cells */ + obstacle_map[index] = 1; + if (has_velocity) + obstacle_map[index] |= 8; + } + } } } + /* free bvh tree */ + free_bvhtree_from_mesh(&treeData); + dm->release(dm); - if(collobjs) - MEM_freeN(collobjs); + if (vert_vel) MEM_freeN(vert_vel); } - -#endif } /* Animated obstacles: dx_step = ((x_new - x_old) / totalsteps) * substep */ -static void update_obstacles(Scene *scene, Object *ob, SmokeDomainSettings *sds, float dt, int substep, int totalsteps) +static void update_obstacles(Scene *scene, Object *ob, SmokeDomainSettings *sds, float dt, + int UNUSED(substep), int UNUSED(totalsteps)) { Object **collobjs = NULL; unsigned int numcollobj = 0; @@ -1092,437 +811,1087 @@ static void update_obstacles(Scene *scene, Object *ob, SmokeDomainSettings *sds, float *velxOrig = smoke_get_velocity_x(sds->fluid); float *velyOrig = smoke_get_velocity_y(sds->fluid); float *velzOrig = smoke_get_velocity_z(sds->fluid); - // float *density = smoke_get_density(sds->fluid); + float *density = smoke_get_density(sds->fluid); + float *fuel = smoke_get_fuel(sds->fluid); + float *flame = smoke_get_flame(sds->fluid); + float *r = smoke_get_color_r(sds->fluid); + float *g = smoke_get_color_g(sds->fluid); + float *b = smoke_get_color_b(sds->fluid); unsigned int z; smoke_get_ob_velocity(sds->fluid, &velx, &vely, &velz); // TODO: delete old obstacle flags - for(z = 0; z < sds->res[0] * sds->res[1] * sds->res[2]; z++) + for (z = 0; z < sds->res[0] * sds->res[1] * sds->res[2]; z++) + { + if (obstacles[z] & 8) // Do not delete static obstacles + { + obstacles[z] = 0; + } + + velx[z] = 0; + vely[z] = 0; + velz[z] = 0; + } + + + collobjs = get_collisionobjects(scene, ob, sds->coll_group, &numcollobj, eModifierType_Smoke); + + // update obstacle tags in cells + for (collIndex = 0; collIndex < numcollobj; collIndex++) { - if(obstacles[z]) + Object *collob = collobjs[collIndex]; + SmokeModifierData *smd2 = (SmokeModifierData *)modifiers_findByType(collob, eModifierType_Smoke); + + // DG TODO: check if modifier is active? + + if ((smd2->type & MOD_SMOKE_TYPE_COLL) && smd2->coll) { - // density[z] = 0; + SmokeCollSettings *scs = smd2->coll; + obstacles_from_derivedmesh(collob, sds, scs, obstacles, velx, vely, velz, dt); + } + } + + if (collobjs) + MEM_freeN(collobjs); + /* obstacle cells should not contain any velocity from the smoke simulation */ + for (z = 0; z < sds->res[0] * sds->res[1] * sds->res[2]; z++) + { + if (obstacles[z]) + { velxOrig[z] = 0; velyOrig[z] = 0; velzOrig[z] = 0; + density[z] = 0; + if (fuel) { + fuel[z] = 0; + flame[z] = 0; + } + if (r) { + r[z] = 0; + g[z] = 0; + b[z] = 0; + } + } + } +} + + +typedef struct EmissionMap { + float *influence; + float *velocity; + int min[3], max[3], res[3]; + int total_cells, valid; +} EmissionMap; + +static void em_boundInsert(EmissionMap *em, float point[3]) +{ + int i = 0; + if (!em->valid) { + VECCOPY(em->min, point); + VECCOPY(em->max, point); + em->valid = 1; + } + else { + for (; i < 3; i++) { + if (point[i] < em->min[i]) em->min[i] = (int)floor(point[i]); + if (point[i] > em->max[i]) em->max[i] = (int)ceil(point[i]); + } + } +} + +static void clampBoundsInDomain(SmokeDomainSettings *sds, int min[3], int max[3], float *min_vel, float *max_vel, int margin, float dt) +{ + int i; + for (i = 0; i < 3; i++) { + int adapt = (sds->flags & MOD_SMOKE_ADAPTIVE_DOMAIN) ? sds->adapt_res : 0; + /* add margin */ + min[i] -= margin; + max[i] += margin; + + /* adapt to velocity */ + if (min_vel && min_vel[i] < 0.0f) { + min[i] += (int)ceil(min_vel[i] * dt); + } + if (max_vel && max_vel[i] > 0.0f) { + max[i] += (int)ceil(max_vel[i] * dt); + } + + /* clamp within domain max size */ + CLAMP(min[i], -adapt, sds->base_res[i] + adapt); + CLAMP(max[i], -adapt, sds->base_res[i] + adapt); + } +} + +static void em_allocateData(EmissionMap *em, int use_velocity) { + int i, res[3]; + + for (i = 0; i < 3; i++) { + res[i] = em->max[i] - em->min[i]; + if (res[i] <= 0) + return; + } + em->total_cells = res[0] * res[1] * res[2]; + copy_v3_v3_int(em->res, res); + + + em->influence = MEM_callocN(sizeof(float) * em->total_cells, "smoke_flow_influence"); + if (use_velocity) + em->velocity = MEM_callocN(sizeof(float) * em->total_cells * 3, "smoke_flow_velocity"); +} + +static void em_freeData(EmissionMap *em) { + if (em->influence) + MEM_freeN(em->influence); + if (em->velocity) + MEM_freeN(em->velocity); +} + + +static void emit_from_particles(Object *flow_ob, SmokeDomainSettings *sds, SmokeFlowSettings *sfs, EmissionMap *em, Scene *scene, float time, float dt) +{ + if (sfs && sfs->psys && sfs->psys->part && ELEM(sfs->psys->part->type, PART_EMITTER, PART_FLUID)) // is particle system selected + { + ParticleSimulationData sim; + ParticleSystem *psys = sfs->psys; + float *particle_pos; + float *particle_vel; + int totpart = psys->totpart, totchild; + int p = 0; + int valid_particles = 0; + + sim.scene = scene; + sim.ob = flow_ob; + sim.psys = psys; + + if (psys->part->type == PART_HAIR) + { + // TODO: PART_HAIR not supported whatsoever + totchild = 0; + } + else + totchild = psys->totchild * psys->part->disp / 100; + + particle_pos = MEM_callocN(sizeof(float) * (totpart + totchild) * 3, "smoke_flow_particles"); + particle_vel = MEM_callocN(sizeof(float) * (totpart + totchild) * 3, "smoke_flow_particles"); + + /* calculate local position for each particle */ + for (p = 0; p < totpart + totchild; p++) + { + ParticleKey state; + float *pos; + if (p < totpart) { + if (psys->particles[p].flag & (PARS_NO_DISP | PARS_UNEXIST)) + continue; + } + else { + /* handle child particle */ + ChildParticle *cpa = &psys->child[p - totpart]; + if (psys->particles[cpa->parent].flag & (PARS_NO_DISP | PARS_UNEXIST)) + continue; + } + + state.time = time; + if (psys_get_particle_state(&sim, p, &state, 0) == 0) + continue; + + /* location */ + pos = &particle_pos[valid_particles * 3]; + copy_v3_v3(pos, state.co); + smoke_pos_to_cell(sds, pos); + + /* velocity */ + copy_v3_v3(&particle_vel[valid_particles * 3], state.vel); + mul_mat3_m4_v3(sds->imat, &particle_vel[valid_particles * 3]); + + /* calculate emission map bounds */ + em_boundInsert(em, pos); + valid_particles++; + } + + /* set emission map */ + clampBoundsInDomain(sds, em->min, em->max, NULL, NULL, 1, dt); + em_allocateData(em, sfs->flags & MOD_SMOKE_FLOW_INITVELOCITY); + + for (p = 0; p < valid_particles; p++) + { + int cell[3]; + size_t i = 0; + size_t index = 0; + int badcell = 0; + + /* 1. get corresponding cell */ + cell[0] = floor(particle_pos[p * 3]) - em->min[0]; + cell[1] = floor(particle_pos[p * 3 + 1]) - em->min[1]; + cell[2] = floor(particle_pos[p * 3 + 2]) - em->min[2]; + /* check if cell is valid (in the domain boundary) */ + for (i = 0; i < 3; i++) { + if ((cell[i] > em->res[i] - 1) || (cell[i] < 0)) { + badcell = 1; + break; + } + } + if (badcell) + continue; + /* get cell index */ + index = smoke_get_index(cell[0], em->res[0], cell[1], em->res[1], cell[2]); + /* Add influence to emission map */ + em->influence[index] = 1.0f; + /* Uses particle velocity as initial velocity for smoke */ + if (sfs->flags & MOD_SMOKE_FLOW_INITVELOCITY && (psys->part->phystype != PART_PHYS_NO)) + { + VECADDFAC(&em->velocity[index * 3], &em->velocity[index * 3], &particle_vel[p * 3], sfs->vel_multi); + } + } // particles loop + + /* free data */ + if (particle_pos) + MEM_freeN(particle_pos); + if (particle_vel) + MEM_freeN(particle_vel); + } +} + +static void get_texture_value(Tex *texture, float tex_co[3], TexResult *texres) +{ + int result_type; + + /* no node textures for now */ + result_type = multitex_ext_safe(texture, tex_co, texres); + + /* if the texture gave an RGB value, we assume it didn't give a valid + * intensity, since this is in the context of modifiers don't use perceptual color conversion. + * if the texture didn't give an RGB value, copy the intensity across + */ + if (result_type & TEX_RGB) { + texres->tin = (1.0f / 3.0f) * (texres->tr + texres->tg + texres->tb); + } + else { + copy_v3_fl(&texres->tr, texres->tin); + } +} + +static void emit_from_derivedmesh(Object *flow_ob, SmokeDomainSettings *sds, SmokeFlowSettings *sfs, EmissionMap *em, float dt) +{ + if (!sfs->dm) return; + { + DerivedMesh *dm = sfs->dm; + int defgrp_index = sfs->vgroup_density - 1; + MDeformVert *dvert = NULL; + MVert *mvert = NULL; + MVert *mvert_orig = NULL; + MFace *mface = NULL; + MTFace *tface = NULL; + BVHTreeFromMesh treeData = {0}; + int numOfVerts, i, z; + float flow_center[3] = {0}; + + float *vert_vel = NULL; + int has_velocity = 0; + + CDDM_calc_normals(dm); + mvert = dm->getVertArray(dm); + mvert_orig = dm->dupVertArray(dm); /* copy original mvert and restore when done */ + mface = dm->getTessFaceArray(dm); + numOfVerts = dm->getNumVerts(dm); + dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT); + tface = CustomData_get_layer_named(&dm->faceData, CD_MTFACE, sfs->uvlayer_name); + + if (sfs->flags & MOD_SMOKE_FLOW_INITVELOCITY) { + vert_vel = MEM_callocN(sizeof(float) * numOfVerts * 3, "smoke_flow_velocity"); + + if (sfs->numverts != numOfVerts || !sfs->verts_old) { + if (sfs->verts_old) MEM_freeN(sfs->verts_old); + sfs->verts_old = MEM_callocN(sizeof(float) * numOfVerts * 3, "smoke_flow_verts_old"); + sfs->numverts = numOfVerts; + } + else { + has_velocity = 1; + } } - if(obstacles[z] & 8) // Do not delete static obstacles - { - obstacles[z] = 0; + /* Transform dm vertices to + * domain grid space for fast lookups */ + for (i = 0; i < numOfVerts; i++) { + float n[3]; + /* vert pos */ + mul_m4_v3(flow_ob->obmat, mvert[i].co); + smoke_pos_to_cell(sds, mvert[i].co); + /* vert normal */ + normal_short_to_float_v3(n, mvert[i].no); + mul_mat3_m4_v3(flow_ob->obmat, n); + mul_mat3_m4_v3(sds->imat, n); + normalize_v3(n); + normal_float_to_short_v3(mvert[i].no, n); + /* vert velocity */ + if (sfs->flags & MOD_SMOKE_FLOW_INITVELOCITY) { + float co[3]; + VECADD(co, mvert[i].co, sds->shift); + if (has_velocity) { + sub_v3_v3v3(&vert_vel[i * 3], co, &sfs->verts_old[i * 3]); + mul_v3_fl(&vert_vel[i * 3], sds->dx / dt); + } + copy_v3_v3(&sfs->verts_old[i * 3], co); + } + + /* calculate emission map bounds */ + em_boundInsert(em, mvert[i].co); } + mul_m4_v3(flow_ob->obmat, flow_center); + smoke_pos_to_cell(sds, flow_center); + + /* set emission map */ + clampBoundsInDomain(sds, em->min, em->max, NULL, NULL, sfs->surface_distance, dt); + em_allocateData(em, sfs->flags & MOD_SMOKE_FLOW_INITVELOCITY); + + if (bvhtree_from_mesh_faces(&treeData, dm, 0.0f, 4, 6)) { + #pragma omp parallel for schedule(static) + for (z = em->min[2]; z < em->max[2]; z++) { + int x, y; + for (x = em->min[0]; x < em->max[0]; x++) + for (y = em->min[1]; y < em->max[1]; y++) { + int index = smoke_get_index(x - em->min[0], em->res[0], y - em->min[1], em->res[1], z - em->min[2]); + + float ray_start[3] = {(float)x + 0.5f, (float)y + 0.5f, (float)z + 0.5f}; + float ray_dir[3] = {1.0f, 0.0f, 0.0f}; + + BVHTreeRayHit hit = {0}; + BVHTreeNearest nearest = {0}; + + float volume_factor = 0.0f; + float sample_str = 0.0f; + + hit.index = -1; + hit.dist = 9999; + nearest.index = -1; + nearest.dist = sfs->surface_distance * sfs->surface_distance; /* find_nearest uses squared distance */ + + /* Check volume collision */ + if (sfs->volume_density) { + if (BLI_bvhtree_ray_cast(treeData.tree, ray_start, ray_dir, 0.0f, &hit, treeData.raycast_callback, &treeData) != -1) { + float dot = ray_dir[0] * hit.no[0] + ray_dir[1] * hit.no[1] + ray_dir[2] * hit.no[2]; + /* If ray and hit face normal are facing same direction + * hit point is inside a closed mesh. */ + if (dot >= 0) { + /* Also cast a ray in opposite direction to make sure + * point is at least surrounded by two faces */ + negate_v3(ray_dir); + hit.index = -1; + hit.dist = 9999; + + BLI_bvhtree_ray_cast(treeData.tree, ray_start, ray_dir, 0.0f, &hit, treeData.raycast_callback, &treeData); + if (hit.index != -1) { + volume_factor = sfs->volume_density; + nearest.dist = hit.dist * hit.dist; + } + } + } + } - velx[z] = 0; - vely[z] = 0; - velz[z] = 0; + /* find the nearest point on the mesh */ + if (BLI_bvhtree_find_nearest(treeData.tree, ray_start, &nearest, treeData.nearest_callback, &treeData) != -1) { + float weights[4]; + int v1, v2, v3, f_index = nearest.index; + float n1[3], n2[3], n3[3], hit_normal[3]; + + /* emit from surface based on distance */ + if (sfs->surface_distance) { + sample_str = sqrtf(nearest.dist) / sfs->surface_distance; + CLAMP(sample_str, 0.0f, 1.0f); + sample_str = pow(1.0f - sample_str, 0.5f); + } + else + sample_str = 0.0f; + + /* calculate barycentric weights for nearest point */ + v1 = mface[f_index].v1; + v2 = (nearest.flags & BVH_ONQUAD) ? mface[f_index].v3 : mface[f_index].v2; + v3 = (nearest.flags & BVH_ONQUAD) ? mface[f_index].v4 : mface[f_index].v3; + interp_weights_face_v3(weights, mvert[v1].co, mvert[v2].co, mvert[v3].co, NULL, nearest.co); + + if (sfs->flags & MOD_SMOKE_FLOW_INITVELOCITY) { + /* apply normal directional velocity */ + if (sfs->vel_normal) { + /* interpolate vertex normal vectors to get nearest point normal */ + normal_short_to_float_v3(n1, mvert[v1].no); + normal_short_to_float_v3(n2, mvert[v2].no); + normal_short_to_float_v3(n3, mvert[v3].no); + interp_v3_v3v3v3(hit_normal, n1, n2, n3, weights); + normalize_v3(hit_normal); + /* apply normal directional and random velocity + * - TODO: random disabled for now since it doesnt really work well as pressure calc smoothens it out... */ + em->velocity[index * 3] += hit_normal[0] * sfs->vel_normal * 0.25f; + em->velocity[index * 3 + 1] += hit_normal[1] * sfs->vel_normal * 0.25f; + em->velocity[index * 3 + 2] += hit_normal[2] * sfs->vel_normal * 0.25f; + /* TODO: for fire emitted from mesh surface we can use + * Vf = Vs + (Ps/Pf - 1)*S to model gaseous expansion from solid to fuel */ + } + /* apply object velocity */ + if (has_velocity && sfs->vel_multi) { + float hit_vel[3]; + interp_v3_v3v3v3(hit_vel, &vert_vel[v1 * 3], &vert_vel[v2 * 3], &vert_vel[v3 * 3], weights); + em->velocity[index * 3] += hit_vel[0] * sfs->vel_multi; + em->velocity[index * 3 + 1] += hit_vel[1] * sfs->vel_multi; + em->velocity[index * 3 + 2] += hit_vel[2] * sfs->vel_multi; + } + } + + /* apply vertex group influence if used */ + if (defgrp_index != -1 && dvert) { + float weight_mask = defvert_find_weight(&dvert[v1], defgrp_index) * weights[0] + + defvert_find_weight(&dvert[v2], defgrp_index) * weights[1] + + defvert_find_weight(&dvert[v3], defgrp_index) * weights[2]; + sample_str *= weight_mask; + } + + /* apply emission texture */ + if ((sfs->flags & MOD_SMOKE_FLOW_TEXTUREEMIT) && sfs->noise_texture) { + float tex_co[3] = {0}; + TexResult texres; + + if (sfs->texture_type == MOD_SMOKE_FLOW_TEXTURE_MAP_AUTO) { + tex_co[0] = ((float)(x - flow_center[0]) / sds->base_res[0]) / sfs->texture_size; + tex_co[1] = ((float)(y - flow_center[1]) / sds->base_res[1]) / sfs->texture_size; + tex_co[2] = ((float)(z - flow_center[2]) / sds->base_res[2] - sfs->texture_offset) / sfs->texture_size; + } + else if (tface) { + interp_v2_v2v2v2(tex_co, tface[f_index].uv[0], tface[f_index].uv[(nearest.flags & BVH_ONQUAD) ? 2 : 1], + tface[f_index].uv[(nearest.flags & BVH_ONQUAD) ? 3 : 2], weights); + /* map between -1.0f and 1.0f */ + tex_co[0] = tex_co[0] * 2.0f - 1.0f; + tex_co[1] = tex_co[1] * 2.0f - 1.0f; + tex_co[2] = sfs->texture_offset; + } + texres.nor = NULL; + get_texture_value(sfs->noise_texture, tex_co, &texres); + sample_str *= texres.tin; + } + } + + /* multiply initial velocity by emitter influence */ + if (sfs->flags & MOD_SMOKE_FLOW_INITVELOCITY) { + mul_v3_fl(&em->velocity[index * 3], sample_str); + } + + /* apply final influence based on volume factor */ + em->influence[index] = MAX2(volume_factor, sample_str); + } + } + } + /* free bvh tree */ + free_bvhtree_from_mesh(&treeData); + /* restore original mverts */ + CustomData_set_layer(&dm->vertData, CD_MVERT, mvert_orig); + if (mvert) + MEM_freeN(mvert); + + if (vert_vel) MEM_freeN(vert_vel); } +} - collobjs = get_collisionobjects(scene, ob, sds->coll_group, &numcollobj, eModifierType_Smoke); +static void adjustDomainResolution(SmokeDomainSettings *sds, int new_shift[3], EmissionMap *emaps, unsigned int numflowobj, float dt) +{ + int min[3] = {32767, 32767, 32767}, max[3] = {-32767, -32767, -32767}, res[3]; + int total_cells = 1, res_changed = 0, shift_changed = 0; + float min_vel[3], max_vel[3]; + int x, y, z, i; + float *density = smoke_get_density(sds->fluid); + float *fuel = smoke_get_fuel(sds->fluid); + float *vx = smoke_get_velocity_x(sds->fluid); + float *vy = smoke_get_velocity_y(sds->fluid); + float *vz = smoke_get_velocity_z(sds->fluid); + + INIT_MINMAX(min_vel, max_vel); + + /* Calculate bounds for current domain content */ + for (x = sds->res_min[0]; x < sds->res_max[0]; x++) + for (y = sds->res_min[1]; y < sds->res_max[1]; y++) + for (z = sds->res_min[2]; z < sds->res_max[2]; z++) + { + int xn = x - new_shift[0]; + int yn = y - new_shift[1]; + int zn = z - new_shift[2]; + int index = smoke_get_index(x - sds->res_min[0], sds->res[0], y - sds->res_min[1], sds->res[1], z - sds->res_min[2]); + float max_den = (fuel) ? MAX2(density[index], fuel[index]) : density[index]; + + /* content bounds (use shifted coordinates) */ + if (max_den >= sds->adapt_threshold) { + if (min[0] > xn) min[0] = xn; + if (min[1] > yn) min[1] = yn; + if (min[2] > zn) min[2] = zn; + if (max[0] < xn) max[0] = xn; + if (max[1] < yn) max[1] = yn; + if (max[2] < zn) max[2] = zn; + } + /* velocity bounds */ + if (min_vel[0] > vx[index]) min_vel[0] = vx[index]; + if (min_vel[1] > vy[index]) min_vel[1] = vy[index]; + if (min_vel[2] > vz[index]) min_vel[2] = vz[index]; + if (max_vel[0] < vx[index]) max_vel[0] = vx[index]; + if (max_vel[1] < vy[index]) max_vel[1] = vy[index]; + if (max_vel[2] < vz[index]) max_vel[2] = vz[index]; + } - // update obstacle tags in cells - for(collIndex = 0; collIndex < numcollobj; collIndex++) + /* also apply emission maps */ + for (i = 0; i < numflowobj; i++) { - Object *collob= collobjs[collIndex]; - SmokeModifierData *smd2 = (SmokeModifierData*)modifiers_findByType(collob, eModifierType_Smoke); + EmissionMap *em = &emaps[i]; - // DG TODO: check if modifier is active? - - if((smd2->type & MOD_SMOKE_TYPE_COLL) && smd2->coll && smd2->coll->points && smd2->coll->points_old) - { - SmokeCollSettings *scs = smd2->coll; - unsigned int i; + for (x = em->min[0]; x < em->max[0]; x++) + for (y = em->min[1]; y < em->max[1]; y++) + for (z = em->min[2]; z < em->max[2]; z++) + { + int index = smoke_get_index(x - em->min[0], em->res[0], y - em->min[1], em->res[1], z - em->min[2]); + float max_den = em->influence[index]; + + /* density bounds */ + if (max_den >= sds->adapt_threshold) { + if (min[0] > x) min[0] = x; + if (min[1] > y) min[1] = y; + if (min[2] > z) min[2] = z; + if (max[0] < x) max[0] = x; + if (max[1] < y) max[1] = y; + if (max[2] < z) max[2] = z; + } + /* velocity bounds */ + if (em->velocity) { + if (min_vel[0] > em->velocity[index * 3]) min_vel[0] = em->velocity[index * 3]; + if (min_vel[1] > em->velocity[index * 3 + 1]) min_vel[1] = em->velocity[index * 3 + 1]; + if (min_vel[2] > em->velocity[index * 3 + 2]) min_vel[2] = em->velocity[index * 3 + 2]; + if (max_vel[0] < em->velocity[index * 3]) max_vel[0] = em->velocity[index * 3]; + if (max_vel[1] < em->velocity[index * 3 + 1]) max_vel[1] = em->velocity[index * 3 + 1]; + if (max_vel[2] < em->velocity[index * 3 + 2]) max_vel[2] = em->velocity[index * 3 + 2]; + } + } + } - /* - // DG TODO: support static cobstacles, but basicly we could even support static + rigid with one set of code - if(scs->type > SM_COLL_STATIC) - */ + /* calculate new bounds based on these values */ + clampBoundsInDomain(sds, min, max, min_vel, max_vel, sds->adapt_margin + 1, dt); - /* Handle collisions */ - for(i = 0; i < scs->numpoints; i++) - { - // 1. get corresponding cell - int cell[3]; - float pos[3], oldpos[3], vel[3]; - float cPos[3], cOldpos[3]; /* current position in substeps */ - int badcell = 0; - size_t index; - int j; - - // translate local points into global positions - copy_v3_v3(cPos, &scs->points[3 * i]); - mul_m4_v3(scs->mat, cPos); - copy_v3_v3(pos, cPos); - - copy_v3_v3(cOldpos, &scs->points_old[3 * i]); - mul_m4_v3(scs->mat_old, cOldpos); - copy_v3_v3(oldpos, cOldpos); - - /* support for rigid bodies, armatures etc */ - { - float tmp[3]; + for (i = 0; i < 3; i++) { + /* calculate new resolution */ + res[i] = max[i] - min[i]; + total_cells *= res[i]; - /* x_current = x_old + (x_new - x_old) * step_current / steps_total */ - float mulStep = (float)(((float)substep) / ((float)totalsteps)); + if (new_shift[i]) + shift_changed = 1; - sub_v3_v3v3(tmp, cPos, cOldpos); - mul_v3_fl(tmp, mulStep); - add_v3_v3(cOldpos, tmp); - } + /* if no content set minimum dimensions */ + if (res[i] <= 0) { + int j; + for (j = 0; j < 3; j++) { + min[j] = 0; + max[j] = 1; + res[j] = 1; + } + res_changed = 1; + total_cells = 1; + break; + } + if (min[i] != sds->res_min[i] || max[i] != sds->res_max[i]) + res_changed = 1; + } - sub_v3_v3v3(vel, pos, oldpos); - /* Scale velocity to incorperate the object movement during this step */ - mul_v3_fl(vel, 1.0 / (totalsteps * dt * sds->scale)); - // mul_v3_fl(vel, 1.0 / dt); + if (res_changed || shift_changed) { + struct FLUID_3D *fluid_old = sds->fluid; + struct WTURBULENCE *turb_old = sds->wt; + /* allocate new fluid data */ + smoke_reallocate_fluid(sds, sds->dx, res, 0); + if (sds->flags & MOD_SMOKE_HIGHRES) { + smoke_reallocate_highres_fluid(sds, sds->dx, res, 0); + } - // DG TODO: cap velocity to maxVelMag (or maxvel) + /* copy values from old fluid to new */ + if (sds->total_cells > 1 && total_cells > 1) { + /* low res smoke */ + float *o_dens, *o_react, *o_flame, *o_fuel, *o_heat, *o_heatold, *o_vx, *o_vy, *o_vz, *o_r, *o_g, *o_b; + float *n_dens, *n_react, *n_flame, *n_fuel, *n_heat, *n_heatold, *n_vx, *n_vy, *n_vz, *n_r, *n_g, *n_b; + float dummy; + unsigned char *dummy_p; + /* high res smoke */ + int wt_res_old[3]; + float *o_wt_dens, *o_wt_react, *o_wt_flame, *o_wt_fuel, *o_wt_tcu, *o_wt_tcv, *o_wt_tcw, *o_wt_r, *o_wt_g, *o_wt_b; + float *n_wt_dens, *n_wt_react, *n_wt_flame, *n_wt_fuel, *n_wt_tcu, *n_wt_tcv, *n_wt_tcw, *n_wt_r, *n_wt_g, *n_wt_b; + + smoke_export(fluid_old, &dummy, &dummy, &o_dens, &o_react, &o_flame, &o_fuel, &o_heat, &o_heatold, &o_vx, &o_vy, &o_vz, &o_r, &o_g, &o_b, &dummy_p); + smoke_export(sds->fluid, &dummy, &dummy, &n_dens, &n_react, &n_flame, &n_fuel, &n_heat, &n_heatold, &n_vx, &n_vy, &n_vz, &n_r, &n_g, &n_b, &dummy_p); + + if (sds->flags & MOD_SMOKE_HIGHRES) { + smoke_turbulence_export(turb_old, &o_wt_dens, &o_wt_react, &o_wt_flame, &o_wt_fuel, &o_wt_r, &o_wt_g, &o_wt_b, &o_wt_tcu, &o_wt_tcv, &o_wt_tcw); + smoke_turbulence_get_res(turb_old, wt_res_old); + smoke_turbulence_export(sds->wt, &n_wt_dens, &n_wt_react, &n_wt_flame, &n_wt_fuel, &n_wt_r, &n_wt_g, &n_wt_b, &n_wt_tcu, &n_wt_tcv, &n_wt_tcw); + } - // oldpos + velocity * dt = newpos - get_cell(sds->p0, sds->res, sds->dx*sds->scale, cOldpos /* use current position here instead of "pos" */, cell, 0); - // check if cell is valid (in the domain boundary) - for(j = 0; j < 3; j++) - if((cell[j] > sds->res[j] - 1) || (cell[j] < 0)) + for (x = sds->res_min[0]; x < sds->res_max[0]; x++) + for (y = sds->res_min[1]; y < sds->res_max[1]; y++) + for (z = sds->res_min[2]; z < sds->res_max[2]; z++) { - badcell = 1; - break; - } - - if(badcell) - continue; + /* old grid index */ + int xo = x - sds->res_min[0]; + int yo = y - sds->res_min[1]; + int zo = z - sds->res_min[2]; + int index_old = smoke_get_index(xo, sds->res[0], yo, sds->res[1], zo); + /* new grid index */ + int xn = x - min[0] - new_shift[0]; + int yn = y - min[1] - new_shift[1]; + int zn = z - min[2] - new_shift[2]; + int index_new = smoke_get_index(xn, res[0], yn, res[1], zn); + + /* skip if outside new domain */ + if (xn < 0 || xn >= res[0] || + yn < 0 || yn >= res[1] || + zn < 0 || zn >= res[2]) + continue; - // 2. set cell values (heat, density and velocity) - index = smoke_get_index(cell[0], sds->res[0], cell[1], sds->res[1], cell[2]); + /* copy data */ + n_dens[index_new] = o_dens[index_old]; + /* heat */ + if (n_heat && o_heat) { + n_heat[index_new] = o_heat[index_old]; + n_heatold[index_new] = o_heatold[index_old]; + } + /* fuel */ + if (n_fuel && o_fuel) { + n_flame[index_new] = o_flame[index_old]; + n_fuel[index_new] = o_fuel[index_old]; + n_react[index_new] = o_react[index_old]; + } + /* color */ + if (o_r && n_r) { + n_r[index_new] = o_r[index_old]; + n_g[index_new] = o_g[index_old]; + n_b[index_new] = o_b[index_old]; + } + n_vx[index_new] = o_vx[index_old]; + n_vy[index_new] = o_vy[index_old]; + n_vz[index_new] = o_vz[index_old]; - // Don't overwrite existing obstacles - if(obstacles[index]) - continue; - - // printf("cell[0]: %d, cell[1]: %d, cell[2]: %d\n", cell[0], cell[1], cell[2]); - // printf("res[0]: %d, res[1]: %d, res[2]: %d, index: %d\n\n", sds->res[0], sds->res[1], sds->res[2], index); - obstacles[index] = 1 | 8 /* ANIMATED */; + if (sds->flags & MOD_SMOKE_HIGHRES && turb_old) { + int block_size = sds->amplify + 1; + int i, j, k; + /* old grid index */ + int xx_o = xo * block_size; + int yy_o = yo * block_size; + int zz_o = zo * block_size; + /* new grid index */ + int xx_n = xn * block_size; + int yy_n = yn * block_size; + int zz_n = zn * block_size; + + n_wt_tcu[index_new] = o_wt_tcu[index_old]; + n_wt_tcv[index_new] = o_wt_tcv[index_old]; + n_wt_tcw[index_new] = o_wt_tcw[index_old]; + + for (i = 0; i < block_size; i++) + for (j = 0; j < block_size; j++) + for (k = 0; k < block_size; k++) + { + int big_index_old = smoke_get_index(xx_o + i, wt_res_old[0], yy_o + j, wt_res_old[1], zz_o + k); + int big_index_new = smoke_get_index(xx_n + i, sds->res_wt[0], yy_n + j, sds->res_wt[1], zz_n + k); + /* copy data */ + n_wt_dens[big_index_new] = o_wt_dens[big_index_old]; + if (n_wt_flame && o_wt_flame) { + n_wt_flame[big_index_new] = o_wt_flame[big_index_old]; + n_wt_fuel[big_index_new] = o_wt_fuel[big_index_old]; + n_wt_react[big_index_new] = o_wt_react[big_index_old]; + } + if (n_wt_r && o_wt_r) { + n_wt_r[big_index_new] = o_wt_r[big_index_old]; + n_wt_g[big_index_new] = o_wt_g[big_index_old]; + n_wt_b[big_index_new] = o_wt_b[big_index_old]; + } + } + } + } + } + smoke_free(fluid_old); + if (turb_old) + smoke_turbulence_free(turb_old); + + /* set new domain dimensions */ + VECCOPY(sds->res_min, min); + VECCOPY(sds->res_max, max); + VECCOPY(sds->res, res); + sds->total_cells = total_cells; + } +} - if(len_v3(vel) > FLT_EPSILON) - { - // Collision object is moving +BLI_INLINE void apply_outflow_fields(int index, float *density, float *heat, float *fuel, float *react, float *color_r, float *color_g, float *color_b) +{ + density[index] = 0.f; + if (heat) { + heat[index] = 0.f; + } + if (fuel) { + fuel[index] = 0.f; + react[index] = 0.f; + } + if (color_r) { + color_r[index] = 0.f; + color_g[index] = 0.f; + color_b[index] = 0.f; + } +} - velx[index] = vel[0]; // use "+="? - vely[index] = vel[1]; - velz[index] = vel[2]; - } - } +BLI_INLINE void apply_inflow_fields(SmokeFlowSettings *sfs, float emission_value, int index, float *density, float *heat, float *fuel, float *react, float *color_r, float *color_g, float *color_b) +{ + int absolute_flow = (sfs->flags & MOD_SMOKE_FLOW_ABSOLUTE); + float dens_old = density[index]; + // float fuel_old = (fuel) ? fuel[index] : 0.0f; /* UNUSED */ + float dens_flow = (sfs->type == MOD_SMOKE_FLOW_TYPE_FIRE) ? 0.0f : emission_value * sfs->density; + float fuel_flow = emission_value * sfs->fuel_amount; + /* add heat */ + if (heat) { + heat[index] = MAX2(emission_value * sfs->temp, heat[index]); + } + /* absolute */ + if (absolute_flow) { + if (sfs->type != MOD_SMOKE_FLOW_TYPE_FIRE) { + if (dens_flow > density[index]) + density[index] = dens_flow; + } + if (sfs->type != MOD_SMOKE_FLOW_TYPE_SMOKE && fuel && fuel_flow) { + if (fuel_flow > fuel[index]) + fuel[index] = fuel_flow; + } + } + /* additive */ + else { + if (sfs->type != MOD_SMOKE_FLOW_TYPE_FIRE) { + density[index] += dens_flow; + CLAMP(density[index], 0.0f, 1.0f); + } + if (sfs->type != MOD_SMOKE_FLOW_TYPE_SMOKE && fuel && sfs->fuel_amount) { + fuel[index] += fuel_flow; + CLAMP(fuel[index], 0.0f, 10.0f); } } - if(collobjs) - MEM_freeN(collobjs); + /* set color */ + if (color_r && dens_flow) { + float total_dens = density[index] / (dens_old + dens_flow); + color_r[index] = (color_r[index] + sfs->color[0] * dens_flow) * total_dens; + color_g[index] = (color_g[index] + sfs->color[1] * dens_flow) * total_dens; + color_b[index] = (color_b[index] + sfs->color[2] * dens_flow) * total_dens; + } + + /* set fire reaction coordinate */ + if (fuel && fuel[index]) { + /* instead of using 1.0 for all new fuel add slight falloff + * to reduce flow blockiness */ + float value = 1.0f - pow(1.0f - emission_value, 2.0f); + + if (value > react[index]) { + float f = fuel_flow / fuel[index]; + react[index] = value * f + (1.0f - f) * react[index]; + } + } } -static void update_flowsfluids(Scene *scene, Object *ob, SmokeDomainSettings *sds, float time) +static void update_flowsfluids(Scene *scene, Object *ob, SmokeDomainSettings *sds, float time, float dt) { Object **flowobjs = NULL; + EmissionMap *emaps = NULL; unsigned int numflowobj = 0; unsigned int flowIndex; + int new_shift[3] = {0}; + int active_fields = sds->active_fields; + + /* calculate domain shift for current frame if using adaptive domain */ + if (sds->flags & MOD_SMOKE_ADAPTIVE_DOMAIN) { + int total_shift[3]; + float frame_shift_f[3]; + float ob_loc[3] = {0}; + + mul_m4_v3(ob->obmat, ob_loc); + + VECSUB(frame_shift_f, ob_loc, sds->prev_loc); + copy_v3_v3(sds->prev_loc, ob_loc); + /* convert global space shift to local "cell" space */ + mul_mat3_m4_v3(sds->imat, frame_shift_f); + frame_shift_f[0] = frame_shift_f[0] / sds->cell_size[0]; + frame_shift_f[1] = frame_shift_f[1] / sds->cell_size[1]; + frame_shift_f[2] = frame_shift_f[2] / sds->cell_size[2]; + /* add to total shift */ + VECADD(sds->shift_f, sds->shift_f, frame_shift_f); + /* convert to integer */ + total_shift[0] = floor(sds->shift_f[0]); + total_shift[1] = floor(sds->shift_f[1]); + total_shift[2] = floor(sds->shift_f[2]); + VECSUB(new_shift, total_shift, sds->shift); + copy_v3_v3_int(sds->shift, total_shift); + + /* calculate new domain boundary points so that smoke doesnt slide on sub-cell movement */ + sds->p0[0] = sds->dp0[0] - sds->cell_size[0] * (sds->shift_f[0] - total_shift[0] - 0.5f); + sds->p0[1] = sds->dp0[1] - sds->cell_size[1] * (sds->shift_f[1] - total_shift[1] - 0.5f); + sds->p0[2] = sds->dp0[2] - sds->cell_size[2] * (sds->shift_f[2] - total_shift[2] - 0.5f); + sds->p1[0] = sds->p0[0] + sds->cell_size[0] * sds->base_res[0]; + sds->p1[1] = sds->p0[1] + sds->cell_size[1] * sds->base_res[1]; + sds->p1[2] = sds->p0[2] + sds->cell_size[2] * sds->base_res[2]; + } flowobjs = get_collisionobjects(scene, ob, sds->fluid_group, &numflowobj, eModifierType_Smoke); - // update obstacle tags in cells - for(flowIndex = 0; flowIndex < numflowobj; flowIndex++) + /* init emission maps for each flow */ + emaps = MEM_callocN(sizeof(struct EmissionMap) * numflowobj, "smoke_flow_maps"); + + /* Prepare flow emission maps */ + for (flowIndex = 0; flowIndex < numflowobj; flowIndex++) { - Object *collob= flowobjs[flowIndex]; - SmokeModifierData *smd2 = (SmokeModifierData*)modifiers_findByType(collob, eModifierType_Smoke); + Object *collob = flowobjs[flowIndex]; + SmokeModifierData *smd2 = (SmokeModifierData *)modifiers_findByType(collob, eModifierType_Smoke); // check for initialized smoke object - if((smd2->type & MOD_SMOKE_TYPE_FLOW) && smd2->flow) + if ((smd2->type & MOD_SMOKE_TYPE_FLOW) && smd2->flow) { // we got nice flow object SmokeFlowSettings *sfs = smd2->flow; + EmissionMap *em = &emaps[flowIndex]; - if(sfs && sfs->psys && sfs->psys->part && sfs->psys->part->type==PART_EMITTER) // is particle system selected - { - ParticleSimulationData sim; - ParticleSystem *psys = sfs->psys; - int totpart=psys->totpart, totchild; - int p = 0; - float *density = smoke_get_density(sds->fluid); - float *bigdensity = smoke_turbulence_get_density(sds->wt); - float *heat = smoke_get_heat(sds->fluid); - float *velocity_x = smoke_get_velocity_x(sds->fluid); - float *velocity_y = smoke_get_velocity_y(sds->fluid); - float *velocity_z = smoke_get_velocity_z(sds->fluid); - unsigned char *obstacle = smoke_get_obstacle(sds->fluid); - // DG TODO UNUSED unsigned char *obstacleAnim = smoke_get_obstacle_anim(sds->fluid); - int bigres[3]; - short absolute_flow = (sfs->flags & MOD_SMOKE_FLOW_ABSOLUTE); - short high_emission_smoothing = bigdensity ? (sds->flags & MOD_SMOKE_HIGH_SMOOTH) : 0; - - /* - * A temporary volume map used to store whole emissive - * area to be added to smoke density and interpolated - * for high resolution smoke. - */ - float *temp_emission_map = NULL; - - sim.scene = scene; - sim.ob = collob; - sim.psys = psys; - - // initialize temp emission map - if(!(sfs->type & MOD_SMOKE_FLOW_TYPE_OUTFLOW)) - { - int i; - temp_emission_map = MEM_callocN(sizeof(float) * sds->res[0]*sds->res[1]*sds->res[2], "SmokeTempEmission"); - // set whole volume to 0.0f - for (i=0; ires[0]*sds->res[1]*sds->res[2]; i++) { - temp_emission_map[i] = 0.0f; - } - } + if (sfs->source == MOD_SMOKE_FLOW_SOURCE_PARTICLES) { + emit_from_particles(collob, sds, sfs, em, scene, time, dt); + } + else { + emit_from_derivedmesh(collob, sds, sfs, em, dt); + } - // mostly copied from particle code - if(psys->part->type==PART_HAIR) - { - /* - if(psys->childcache) - { - totchild = psys->totchildcache; + /* update required data fields */ + if (em->total_cells && sfs->type != MOD_SMOKE_FLOW_TYPE_OUTFLOW) { + /* activate heat field if flow produces any heat */ + if (sfs->temp) { + active_fields |= SM_ACTIVE_HEAT; + } + /* activate fuel field if flow adds any fuel */ + if (sfs->type != MOD_SMOKE_FLOW_TYPE_SMOKE && sfs->fuel_amount) { + active_fields |= SM_ACTIVE_FIRE; + } + /* activate color field if flows add smoke with varying colors */ + if (sfs->type != MOD_SMOKE_FLOW_TYPE_FIRE && sfs->density) { + if (!(active_fields & SM_ACTIVE_COLOR_SET)) { + copy_v3_v3(sds->active_color, sfs->color); + active_fields |= SM_ACTIVE_COLOR_SET; + } + else if (!equals_v3v3(sds->active_color, sfs->color)) { + active_fields |= SM_ACTIVE_COLORS; } - else - */ - - // TODO: PART_HAIR not supported whatsoever - totchild=0; } - else - totchild=psys->totchild*psys->part->disp/100; + } + } + } - for(p=0; pactive_color, sds->flame_smoke_color); + active_fields |= SM_ACTIVE_COLOR_SET; + } + else if (!equals_v3v3(sds->active_color, sds->flame_smoke_color)) { + active_fields |= SM_ACTIVE_COLORS; + } + } - if(p < totpart) - { - if(psys->particles[p].flag & (PARS_NO_DISP|PARS_UNEXIST)) - continue; - } - else { - /* handle child particle */ - ChildParticle *cpa = &psys->child[p - totpart]; + /* Adjust domain size if needed */ + if (sds->flags & MOD_SMOKE_ADAPTIVE_DOMAIN) { + adjustDomainResolution(sds, new_shift, emaps, numflowobj, dt); + } - if(psys->particles[cpa->parent].flag & (PARS_NO_DISP|PARS_UNEXIST)) - continue; - } + /* Initialize new data fields if any */ + if (active_fields & SM_ACTIVE_HEAT) { + smoke_ensure_heat(sds->fluid); + } + if (active_fields & SM_ACTIVE_FIRE) { + smoke_ensure_fire(sds->fluid, sds->wt); + } + if (active_fields & SM_ACTIVE_COLORS) { + /* initialize all smoke with "active_color" */ + smoke_ensure_colors(sds->fluid, sds->wt, sds->active_color[0], sds->active_color[1], sds->active_color[2]); + } + sds->active_fields = active_fields; - state.time = time; - if(psys_get_particle_state(&sim, p, &state, 0) == 0) - continue; + /* Apply emission data */ + if (sds->fluid) { + for (flowIndex = 0; flowIndex < numflowobj; flowIndex++) + { + Object *collob = flowobjs[flowIndex]; + SmokeModifierData *smd2 = (SmokeModifierData *)modifiers_findByType(collob, eModifierType_Smoke); - // copy_v3_v3(pos, pa->state.co); - // mul_m4_v3(ob->imat, pos); - // 1. get corresponding cell - get_cell(sds->p0, sds->res, sds->dx*sds->scale, state.co, cell, 0); - // check if cell is valid (in the domain boundary) - for(i = 0; i < 3; i++) - { - if((cell[i] > sds->res[i] - 1) || (cell[i] < 0)) - { - badcell = 1; - break; - } - } - if(badcell) - continue; - // 2. set cell values (heat, density and velocity) - index = smoke_get_index(cell[0], sds->res[0], cell[1], sds->res[1], cell[2]); - if(!(sfs->type & MOD_SMOKE_FLOW_TYPE_OUTFLOW) && !(obstacle[index])) // this is inflow - { - // heat[index] += sfs->temp * 0.1; - // density[index] += sfs->density * 0.1; - heat[index] = sfs->temp; - - // Add emitter density to temp emission map - temp_emission_map[index] = sfs->density; - - // Uses particle velocity as initial velocity for smoke - if(sfs->flags & MOD_SMOKE_FLOW_INITVELOCITY && (psys->part->phystype != PART_PHYS_NO)) - { - velocity_x[index] = state.vel[0]*sfs->vel_multi; - velocity_y[index] = state.vel[1]*sfs->vel_multi; - velocity_z[index] = state.vel[2]*sfs->vel_multi; - } - } - else if(sfs->type & MOD_SMOKE_FLOW_TYPE_OUTFLOW) // outflow - { - heat[index] = 0.f; - density[index] = 0.f; - velocity_x[index] = 0.f; - velocity_y[index] = 0.f; - velocity_z[index] = 0.f; - // we need different handling for the high-res feature - if(bigdensity) - { - // init all surrounding cells according to amplification, too - int i, j, k; - smoke_turbulence_get_res(sds->wt, bigres); - - for(i = 0; i < sds->amplify + 1; i++) - for(j = 0; j < sds->amplify + 1; j++) - for(k = 0; k < sds->amplify + 1; k++) - { - index = smoke_get_index((sds->amplify + 1)* cell[0] + i, bigres[0], (sds->amplify + 1)* cell[1] + j, bigres[1], (sds->amplify + 1)* cell[2] + k); - bigdensity[index] = 0.f; - } - } - } - } // particles loop + // check for initialized smoke object + if ((smd2->type & MOD_SMOKE_TYPE_FLOW) && smd2->flow) + { + // we got nice flow object + SmokeFlowSettings *sfs = smd2->flow; + EmissionMap *em = &emaps[flowIndex]; + + float *density = smoke_get_density(sds->fluid); + float *color_r = smoke_get_color_r(sds->fluid); + float *color_g = smoke_get_color_g(sds->fluid); + float *color_b = smoke_get_color_b(sds->fluid); + float *fuel = smoke_get_fuel(sds->fluid); + float *react = smoke_get_react(sds->fluid); + float *bigdensity = smoke_turbulence_get_density(sds->wt); + float *bigfuel = smoke_turbulence_get_fuel(sds->wt); + float *bigreact = smoke_turbulence_get_react(sds->wt); + float *bigcolor_r = smoke_turbulence_get_color_r(sds->wt); + float *bigcolor_g = smoke_turbulence_get_color_g(sds->wt); + float *bigcolor_b = smoke_turbulence_get_color_b(sds->wt); + float *heat = smoke_get_heat(sds->fluid); + float *velocity_x = smoke_get_velocity_x(sds->fluid); + float *velocity_y = smoke_get_velocity_y(sds->fluid); + float *velocity_z = smoke_get_velocity_z(sds->fluid); + //unsigned char *obstacle = smoke_get_obstacle(sds->fluid); + // DG TODO UNUSED unsigned char *obstacleAnim = smoke_get_obstacle_anim(sds->fluid); + int bigres[3]; + short high_emission_smoothing = (sds->flags & MOD_SMOKE_HIGH_SMOOTH); + float *velocity_map = em->velocity; + float *emission_map = em->influence; - // apply emission values - if(!(sfs->type & MOD_SMOKE_FLOW_TYPE_OUTFLOW)) - { - // initialize variables - int ii, jj, kk, x, y, z, block_size; - size_t index, index_big; + int ii, jj, kk, gx, gy, gz, ex, ey, ez, dx, dy, dz, block_size; + size_t e_index, d_index, index_big; - smoke_turbulence_get_res(sds->wt, bigres); - block_size = sds->amplify + 1; // high res block size + // loop through every emission map cell + for (gx = em->min[0]; gx < em->max[0]; gx++) + for (gy = em->min[1]; gy < em->max[1]; gy++) + for (gz = em->min[2]; gz < em->max[2]; gz++) + { + /* get emission map index */ + ex = gx - em->min[0]; + ey = gy - em->min[1]; + ez = gz - em->min[2]; + e_index = smoke_get_index(ex, em->res[0], ey, em->res[1], ez); + if (!emission_map[e_index]) continue; + /* get domain index */ + dx = gx - sds->res_min[0]; + dy = gy - sds->res_min[1]; + dz = gz - sds->res_min[2]; + d_index = smoke_get_index(dx, sds->res[0], dy, sds->res[1], dz); + + if (sfs->type == MOD_SMOKE_FLOW_TYPE_OUTFLOW) { // outflow + apply_outflow_fields(d_index, density, heat, fuel, react, color_r, color_g, color_b); + } + else { // inflow + apply_inflow_fields(sfs, emission_map[e_index], d_index, density, heat, fuel, react, color_r, color_g, color_b); + + /* initial velocity */ + if (sfs->flags & MOD_SMOKE_FLOW_INITVELOCITY) { + velocity_x[d_index] = ADD_IF_LOWER(velocity_x[d_index], velocity_map[e_index * 3]); + velocity_y[d_index] = ADD_IF_LOWER(velocity_y[d_index], velocity_map[e_index * 3 + 1]); + velocity_z[d_index] = ADD_IF_LOWER(velocity_z[d_index], velocity_map[e_index * 3 + 2]); + } + } - // loop through every low res cell - for(x = 0; x < sds->res[0]; x++) - for(y = 0; y < sds->res[1]; y++) - for(z = 0; z < sds->res[2]; z++) - { + /* loop through high res blocks if high res enabled */ + if (bigdensity) { // neighbor cell emission densities (for high resolution smoke smooth interpolation) float c000, c001, c010, c011, c100, c101, c110, c111; - c000 = (x>0 && y>0 && z>0) ? temp_emission_map[smoke_get_index(x-1, sds->res[0], y-1, sds->res[1], z-1)] : 0; - c001 = (x>0 && y>0) ? temp_emission_map[smoke_get_index(x-1, sds->res[0], y-1, sds->res[1], z)] : 0; - c010 = (x>0 && z>0) ? temp_emission_map[smoke_get_index(x-1, sds->res[0], y, sds->res[1], z-1)] : 0; - c011 = (x>0) ? temp_emission_map[smoke_get_index(x-1, sds->res[0], y, sds->res[1], z)] : 0; + smoke_turbulence_get_res(sds->wt, bigres); + block_size = sds->amplify + 1; // high res block size - c100 = (y>0 && z>0) ? temp_emission_map[smoke_get_index(x, sds->res[0], y-1, sds->res[1], z-1)] : 0; - c101 = (y>0) ? temp_emission_map[smoke_get_index(x, sds->res[0], y-1, sds->res[1], z)] : 0; - c110 = (z>0) ? temp_emission_map[smoke_get_index(x, sds->res[0], y, sds->res[1], z-1)] : 0; - c111 = temp_emission_map[smoke_get_index(x, sds->res[0], y, sds->res[1], z)]; // this cell + c000 = (ex > 0 && ey > 0 && ez > 0) ? emission_map[smoke_get_index(ex - 1, em->res[0], ey - 1, em->res[1], ez - 1)] : 0; + c001 = (ex > 0 && ey > 0) ? emission_map[smoke_get_index(ex - 1, em->res[0], ey - 1, em->res[1], ez)] : 0; + c010 = (ex > 0 && ez > 0) ? emission_map[smoke_get_index(ex - 1, em->res[0], ey, em->res[1], ez - 1)] : 0; + c011 = (ex > 0) ? emission_map[smoke_get_index(ex - 1, em->res[0], ey, em->res[1], ez)] : 0; - // get cell index - index = smoke_get_index(x, sds->res[0], y, sds->res[1], z); + c100 = (ey > 0 && ez > 0) ? emission_map[smoke_get_index(ex, em->res[0], ey - 1, em->res[1], ez - 1)] : 0; + c101 = (ey > 0) ? emission_map[smoke_get_index(ex, em->res[0], ey - 1, em->res[1], ez)] : 0; + c110 = (ez > 0) ? emission_map[smoke_get_index(ex, em->res[0], ey, em->res[1], ez - 1)] : 0; + c111 = emission_map[smoke_get_index(ex, em->res[0], ey, em->res[1], ez)]; // this cell - // add emission to low resolution density - if (absolute_flow) - { - if (temp_emission_map[index]>0) - density[index] = temp_emission_map[index]; - } - else - { - density[index] += temp_emission_map[index]; + for (ii = 0; ii < block_size; ii++) + for (jj = 0; jj < block_size; jj++) + for (kk = 0; kk < block_size; kk++) + { - if (density[index]>1) - density[index]=1.0f; - } + float fx, fy, fz, interpolated_value; + int shift_x, shift_y, shift_z; - smoke_turbulence_get_res(sds->wt, bigres); - /* loop through high res blocks if high res enabled */ - if (bigdensity) - for(ii = 0; ii < block_size; ii++) - for(jj = 0; jj < block_size; jj++) - for(kk = 0; kk < block_size; kk++) + /* + * Do volume interpolation if emitter smoothing + * is enabled + */ + if (high_emission_smoothing) { - - float fx,fy,fz, interpolated_value; - int shift_x, shift_y, shift_z; - - - /* - * Do volume interpolation if emitter smoothing - * is enabled - */ - if (high_emission_smoothing) - { - // convert block position to relative - // for interpolation smoothing - fx = (float)ii/block_size + 0.5f/block_size; - fy = (float)jj/block_size + 0.5f/block_size; - fz = (float)kk/block_size + 0.5f/block_size; - - // calculate trilinear interpolation - interpolated_value = c000 * (1-fx) * (1-fy) * (1-fz) + - c100 * fx * (1-fy) * (1-fz) + - c010 * (1-fx) * fy * (1-fz) + - c001 * (1-fx) * (1-fy) * fz + - c101 * fx * (1-fy) * fz + - c011 * (1-fx) * fy * fz + - c110 * fx * fy * (1-fz) + - c111 * fx * fy * fz; - - - // add some contrast / sharpness - // depending on hi-res block size - - interpolated_value = (interpolated_value-0.4f*sfs->density)*(block_size/2) + 0.4f*sfs->density; - if (interpolated_value<0.0f) interpolated_value = 0.0f; - if (interpolated_value>1.0f) interpolated_value = 1.0f; - - // shift smoke block index - // (because pixel center is actually - // in halfway of the low res block) - shift_x = (x < 1) ? 0 : block_size/2; - shift_y = (y < 1) ? 0 : block_size/2; - shift_z = (z < 1) ? 0 : block_size/2; - } - else - { - // without interpolation use same low resolution - // block value for all hi-res blocks - interpolated_value = c111; - shift_x = 0; - shift_y = 0; - shift_z = 0; + /* get relative block position + * for interpolation smoothing */ + fx = (float)ii / block_size + 0.5f / block_size; + fy = (float)jj / block_size + 0.5f / block_size; + fz = (float)kk / block_size + 0.5f / block_size; + + /* calculate trilinear interpolation */ + interpolated_value = c000 * (1 - fx) * (1 - fy) * (1 - fz) + + c100 * fx * (1 - fy) * (1 - fz) + + c010 * (1 - fx) * fy * (1 - fz) + + c001 * (1 - fx) * (1 - fy) * fz + + c101 * fx * (1 - fy) * fz + + c011 * (1 - fx) * fy * fz + + c110 * fx * fy * (1 - fz) + + c111 * fx * fy * fz; + + + /* add some contrast / sharpness + * depending on hi-res block size */ + interpolated_value = (interpolated_value - 0.4f) * (block_size / 2) + 0.4f; + CLAMP(interpolated_value, 0.0f, 1.0f); + + /* shift smoke block index + * (because pixel center is actually + * in halfway of the low res block) */ + shift_x = (dx < 1) ? 0 : block_size / 2; + shift_y = (dy < 1) ? 0 : block_size / 2; + shift_z = (dz < 1) ? 0 : block_size / 2; + } + else { + /* without interpolation use same low resolution + * block value for all hi-res blocks */ + interpolated_value = c111; + shift_x = 0; + shift_y = 0; + shift_z = 0; + } + + /* get shifted index for current high resolution block */ + index_big = smoke_get_index(block_size * dx + ii - shift_x, bigres[0], block_size * dy + jj - shift_y, bigres[1], block_size * dz + kk - shift_z); + + if (sfs->type == MOD_SMOKE_FLOW_TYPE_OUTFLOW) { // outflow + if (interpolated_value) { + apply_outflow_fields(index_big, bigdensity, NULL, bigfuel, bigreact, bigcolor_r, bigcolor_g, bigcolor_b); } - - // get shifted index for current high resolution block - index_big = smoke_get_index(block_size * x + ii - shift_x, bigres[0], block_size * y + jj - shift_y, bigres[1], block_size * z + kk - shift_z); - - // add emission data to high resolution density - if (absolute_flow) - { - if (interpolated_value > 0) - bigdensity[index_big] = interpolated_value; - } - else - { - bigdensity[index_big] += interpolated_value; - - if (bigdensity[index_big]>1) - bigdensity[index_big]=1.0f; - } - } // end of hires loop - - } // end of low res loop - - // free temporary emission map - if (temp_emission_map) - MEM_freeN(temp_emission_map); - - } // end emission - } + } + else { // inflow + apply_inflow_fields(sfs, interpolated_value, index_big, bigdensity, NULL, bigfuel, bigreact, bigcolor_r, bigcolor_g, bigcolor_b); + } + } // hires loop + } // bigdensity + } // low res loop + + // free emission maps + em_freeData(em); + + } // end emission } } - if(flowobjs) + if (flowobjs) MEM_freeN(flowobjs); + if (emaps) + MEM_freeN(emaps); } static void update_effectors(Scene *scene, Object *ob, SmokeDomainSettings *sds, float UNUSED(dt)) { - ListBase *effectors = pdInitEffectors(scene, ob, NULL, sds->effector_weights); + ListBase *effectors; + /* make sure smoke flow influence is 0.0f */ + sds->effector_weights->weight[PFIELD_SMOKEFLOW] = 0.0f; + effectors = pdInitEffectors(scene, ob, NULL, sds->effector_weights); - if(effectors) + if (effectors) { float *density = smoke_get_density(sds->fluid); float *force_x = smoke_get_force_x(sds->fluid); @@ -1532,76 +1901,113 @@ static void update_effectors(Scene *scene, Object *ob, SmokeDomainSettings *sds, float *velocity_y = smoke_get_velocity_y(sds->fluid); float *velocity_z = smoke_get_velocity_z(sds->fluid); unsigned char *obstacle = smoke_get_obstacle(sds->fluid); - int x, y, z; + int x; // precalculate wind forces - for(x = 0; x < sds->res[0]; x++) - for(y = 0; y < sds->res[1]; y++) - for(z = 0; z < sds->res[2]; z++) - { - EffectedPoint epoint; - float voxelCenter[3] = {0,0,0}, vel[3] = {0,0,0}, retvel[3] = {0,0,0}; - unsigned int index = smoke_get_index(x, sds->res[0], y, sds->res[1], z); - - if((density[index] < FLT_EPSILON) || obstacle[index]) - continue; - - vel[0] = velocity_x[index]; - vel[1] = velocity_y[index]; - vel[2] = velocity_z[index]; - - voxelCenter[0] = sds->p0[0] + sds->dx * sds->scale * x + sds->dx * sds->scale * 0.5; - voxelCenter[1] = sds->p0[1] + sds->dx * sds->scale * y + sds->dx * sds->scale * 0.5; - voxelCenter[2] = sds->p0[2] + sds->dx * sds->scale * z + sds->dx * sds->scale * 0.5; - - pd_point_from_loc(scene, voxelCenter, vel, index, &epoint); - pdDoEffectors(effectors, NULL, sds->effector_weights, &epoint, retvel, NULL); - - // TODO dg - do in force! - force_x[index] = MIN2(MAX2(-1.0, retvel[0] * 0.2), 1.0); - force_y[index] = MIN2(MAX2(-1.0, retvel[1] * 0.2), 1.0); - force_z[index] = MIN2(MAX2(-1.0, retvel[2] * 0.2), 1.0); + #pragma omp parallel for schedule(static) + for (x = 0; x < sds->res[0]; x++) + { + int y, z; + for (y = 0; y < sds->res[1]; y++) + for (z = 0; z < sds->res[2]; z++) + { + EffectedPoint epoint; + float mag; + float voxelCenter[3] = {0, 0, 0}, vel[3] = {0, 0, 0}, retvel[3] = {0, 0, 0}; + unsigned int index = smoke_get_index(x, sds->res[0], y, sds->res[1], z); + + if ((density[index] < FLT_EPSILON) || obstacle[index]) + continue; + + vel[0] = velocity_x[index]; + vel[1] = velocity_y[index]; + vel[2] = velocity_z[index]; + + /* convert vel to global space */ + mag = len_v3(vel); + mul_mat3_m4_v3(sds->obmat, vel); + normalize_v3(vel); + mul_v3_fl(vel, mag); + + voxelCenter[0] = sds->p0[0] + sds->cell_size[0] * ((float)(x + sds->res_min[0]) + 0.5f); + voxelCenter[1] = sds->p0[1] + sds->cell_size[1] * ((float)(y + sds->res_min[1]) + 0.5f); + voxelCenter[2] = sds->p0[2] + sds->cell_size[2] * ((float)(z + sds->res_min[2]) + 0.5f); + mul_m4_v3(sds->obmat, voxelCenter); + + pd_point_from_loc(scene, voxelCenter, vel, index, &epoint); + pdDoEffectors(effectors, NULL, sds->effector_weights, &epoint, retvel, NULL); + + /* convert retvel to local space */ + mag = len_v3(retvel); + mul_mat3_m4_v3(sds->imat, retvel); + normalize_v3(retvel); + mul_v3_fl(retvel, mag); + + // TODO dg - do in force! + force_x[index] = MIN2(MAX2(-1.0, retvel[0] * 0.2), 1.0); + force_y[index] = MIN2(MAX2(-1.0, retvel[1] * 0.2), 1.0); + force_z[index] = MIN2(MAX2(-1.0, retvel[2] * 0.2), 1.0); + } } } pdEndEffectors(&effectors); } -static void step(Scene *scene, Object *ob, SmokeModifierData *smd, float fps) +static void step(Scene *scene, Object *ob, SmokeModifierData *smd, DerivedMesh *domain_dm, float fps) { + SmokeDomainSettings *sds = smd->domain; /* stability values copied from wturbulence.cpp */ const int maxSubSteps = 25; float maxVel; // maxVel should be 1.5 (1.5 cell max movement) * dx (cell size) - float dt = DT_DEFAULT; + float dt; float maxVelMag = 0.0f; int totalSubsteps; int substep = 0; float dtSubdiv; + float gravity[3] = {0.0f, 0.0f, -1.0f}; + float gravity_mag; - SmokeDomainSettings *sds = smd->domain; - - /* get max velocity and lower the dt value if it is too high */ - size_t size= sds->res[0] * sds->res[1] * sds->res[2]; - +#if 0 /* UNUSED */ + /* get max velocity and lower the dt value if it is too high */ + size_t size = sds->res[0] * sds->res[1] * sds->res[2]; float *velX = smoke_get_velocity_x(sds->fluid); float *velY = smoke_get_velocity_y(sds->fluid); float *velZ = smoke_get_velocity_z(sds->fluid); size_t i; +#endif - /* adapt timestep for different framerates, dt = 0.1 is at 25fps */ - dt *= (25.0f / fps); + /* update object state */ + invert_m4_m4(sds->imat, ob->obmat); + copy_m4_m4(sds->obmat, ob->obmat); + smoke_set_domain_from_derivedmesh(sds, ob, domain_dm); + + /* use global gravity if enabled */ + if (scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY) { + copy_v3_v3(gravity, scene->physics_settings.gravity); + /* map default value to 1.0 */ + mul_v3_fl(gravity, 1.0f / 9.810f); + } + /* convert gravity to domain space */ + gravity_mag = len_v3(gravity); + mul_mat3_m4_v3(sds->imat, gravity); + normalize_v3(gravity); + mul_v3_fl(gravity, gravity_mag); + /* adapt timestep for different framerates, dt = 0.1 is at 25fps */ + dt = DT_DEFAULT * (25.0f / fps); // maximum timestep/"CFL" constraint: dt < 5.0 *dx / maxVel maxVel = (sds->dx * 5.0); - for(i = 0; i < size; i++) - { - float vtemp = (velX[i]*velX[i]+velY[i]*velY[i]+velZ[i]*velZ[i]); - if(vtemp > maxVelMag) +#if 0 + for (i = 0; i < size; i++) { + float vtemp = (velX[i] * velX[i] + velY[i] * velY[i] + velZ[i] * velZ[i]); + if (vtemp > maxVelMag) maxVelMag = vtemp; } +#endif maxVelMag = sqrt(maxVelMag) * dt * sds->time_scale; totalSubsteps = (int)((maxVelMag / maxVel) + 1.0f); /* always round up */ @@ -1609,146 +2015,155 @@ static void step(Scene *scene, Object *ob, SmokeModifierData *smd, float fps) totalSubsteps = (totalSubsteps > maxSubSteps) ? maxSubSteps : totalSubsteps; /* Disable substeps for now, since it results in numerical instability */ - totalSubsteps = 1.0f; + totalSubsteps = 1.0f; dtSubdiv = (float)dt / (float)totalSubsteps; // printf("totalSubsteps: %d, maxVelMag: %f, dt: %f\n", totalSubsteps, maxVelMag, dt); - for(substep = 0; substep < totalSubsteps; substep++) + for (substep = 0; substep < totalSubsteps; substep++) { // calc animated obstacle velocities + update_flowsfluids(scene, ob, sds, smd->time, dtSubdiv); update_obstacles(scene, ob, sds, dtSubdiv, substep, totalSubsteps); - update_flowsfluids(scene, ob, sds, smd->time); - update_effectors(scene, ob, sds, dtSubdiv); // DG TODO? problem --> uses forces instead of velocity, need to check how they need to be changed with variable dt - smoke_step(sds->fluid, dtSubdiv); + if (sds->total_cells > 1) { + update_effectors(scene, ob, sds, dtSubdiv); // DG TODO? problem --> uses forces instead of velocity, need to check how they need to be changed with variable dt + smoke_step(sds->fluid, gravity, dtSubdiv); + } + } +} - // move animated obstacle: Done in update_obstacles() */ +static DerivedMesh *createDomainGeometry(SmokeDomainSettings *sds, Object *ob) +{ + DerivedMesh *result; + MVert *mverts; + MPoly *mpolys; + MLoop *mloops; + float min[3]; + float max[3]; + float *co; + MPoly *mp; + MLoop *ml; + + int num_verts = 8; + int num_faces = 6; + int i; + float ob_loc[3] = {0}; + float ob_cache_loc[3] = {0}; + + /* dont generate any mesh if there isnt any content */ + if (sds->total_cells <= 1) { + num_verts = 0; + num_faces = 0; + } - // where to delete old obstacles from array? Done in update_obstacles() */ + result = CDDM_new(num_verts, 0, 0, num_faces * 4, num_faces); + mverts = CDDM_get_verts(result); + mpolys = CDDM_get_polys(result); + mloops = CDDM_get_loops(result); + + + if (num_verts) { + /* volume bounds */ + VECMADD(min, sds->p0, sds->cell_size, sds->res_min); + VECMADD(max, sds->p0, sds->cell_size, sds->res_max); + + /* set vertices */ + /* top slab */ + co = mverts[0].co; co[0] = min[0]; co[1] = min[1]; co[2] = max[2]; + co = mverts[1].co; co[0] = max[0]; co[1] = min[1]; co[2] = max[2]; + co = mverts[2].co; co[0] = max[0]; co[1] = max[1]; co[2] = max[2]; + co = mverts[3].co; co[0] = min[0]; co[1] = max[1]; co[2] = max[2]; + /* bottom slab */ + co = mverts[4].co; co[0] = min[0]; co[1] = min[1]; co[2] = min[2]; + co = mverts[5].co; co[0] = max[0]; co[1] = min[1]; co[2] = min[2]; + co = mverts[6].co; co[0] = max[0]; co[1] = max[1]; co[2] = min[2]; + co = mverts[7].co; co[0] = min[0]; co[1] = max[1]; co[2] = min[2]; + + /* create faces */ + /* top */ + mp = &mpolys[0]; ml = &mloops[0 * 4]; mp->loopstart = 0 * 4; mp->totloop = 4; + ml[0].v = 0; ml[1].v = 1; ml[2].v = 2; ml[3].v = 3; + /* right */ + mp = &mpolys[1]; ml = &mloops[1 * 4]; mp->loopstart = 1 * 4; mp->totloop = 4; + ml[0].v = 2; ml[1].v = 1; ml[2].v = 5; ml[3].v = 6; + /* bottom */ + mp = &mpolys[2]; ml = &mloops[2 * 4]; mp->loopstart = 2 * 4; mp->totloop = 4; + ml[0].v = 7; ml[1].v = 6; ml[2].v = 5; ml[3].v = 4; + /* left */ + mp = &mpolys[3]; ml = &mloops[3 * 4]; mp->loopstart = 3 * 4; mp->totloop = 4; + ml[0].v = 0; ml[1].v = 3; ml[2].v = 7; ml[3].v = 4; + /* front */ + mp = &mpolys[4]; ml = &mloops[4 * 4]; mp->loopstart = 4 * 4; mp->totloop = 4; + ml[0].v = 3; ml[1].v = 2; ml[2].v = 6; ml[3].v = 7; + /* back */ + mp = &mpolys[5]; ml = &mloops[5 * 4]; mp->loopstart = 5 * 4; mp->totloop = 4; + ml[0].v = 1; ml[1].v = 0; ml[2].v = 4; ml[3].v = 5; + + /* calculate required shift to match domain's global position + * it was originally simulated at (if object moves without smoke step) */ + invert_m4_m4(ob->imat, ob->obmat); + mul_m4_v3(ob->obmat, ob_loc); + mul_m4_v3(sds->obmat, ob_cache_loc); + VECSUB(sds->obj_shift_f, ob_cache_loc, ob_loc); + /* convert shift to local space and apply to vertices */ + mul_mat3_m4_v3(ob->imat, sds->obj_shift_f); + /* apply */ + for (i = 0; i < num_verts; i++) { + add_v3_v3(mverts[i].co, sds->obj_shift_f); + } } + + + CDDM_calc_edges(result); + return result; } -void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedMesh *dm) -{ - if((smd->type & MOD_SMOKE_TYPE_FLOW)) +static void smokeModifier_process(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedMesh *dm) +{ + if ((smd->type & MOD_SMOKE_TYPE_FLOW)) { - if(scene->r.cfra >= smd->time) + if (scene->r.cfra >= smd->time) smokeModifier_init(smd, ob, scene, dm); - if(scene->r.cfra > smd->time) + if (smd->flow->dm) smd->flow->dm->release(smd->flow->dm); + smd->flow->dm = CDDM_copy(dm); + DM_ensure_tessface(smd->flow->dm); + + if (scene->r.cfra > smd->time) { - // XXX TODO smd->time = scene->r.cfra; - - // rigid movement support - /* - copy_m4_m4(smd->flow->mat_old, smd->flow->mat); - copy_m4_m4(smd->flow->mat, ob->obmat); - */ } - else if(scene->r.cfra < smd->time) + else if (scene->r.cfra < smd->time) { smd->time = scene->r.cfra; smokeModifier_reset(smd); } } - else if(smd->type & MOD_SMOKE_TYPE_COLL) + else if (smd->type & MOD_SMOKE_TYPE_COLL) { - /* Check if domain resolution changed */ - /* DG TODO: can this be solved more elegant using dependancy graph? */ - { - SmokeCollSettings *scs = smd->coll; - Base *base = scene->base.first; - int changed = 0; - float dx = FLT_MAX; - float scale = 1.0f; - int haveDomain = 0; - - for ( ; base; base = base->next) - { - SmokeModifierData *smd2 = (SmokeModifierData *)modifiers_findByType(base->object, eModifierType_Smoke); - - if (smd2 && (smd2->type & MOD_SMOKE_TYPE_DOMAIN) && smd2->domain) - { - SmokeDomainSettings *sds = smd2->domain; - - if(sds->dx * sds->scale < dx) - { - dx = sds->dx; - scale = sds->scale; - changed = 1; - } - - haveDomain = 1; - } - } - - if(!haveDomain) - return; - - if(changed) - { - if(dx*scale != scs->dx) - { - scs->dx = dx*scale; - smokeModifier_reset(smd); - } - } - } - - if(scene->r.cfra >= smd->time) + if (scene->r.cfra >= smd->time) smokeModifier_init(smd, ob, scene, dm); - if(scene->r.cfra > smd->time) + if (smd->coll) { - unsigned int i; - SmokeCollSettings *scs = smd->coll; - float *points_old = scs->points_old; - float *points = scs->points; - unsigned int numpoints = scs->numpoints; - - // XXX TODO <-- DG: what is TODO here? - smd->time = scene->r.cfra; - - // rigid movement support - copy_m4_m4(scs->mat_old, scs->mat); - copy_m4_m4(scs->mat, ob->obmat); - - if(scs->type != SM_COLL_ANIMATED) // if(not_animated) - { - // nothing to do, "mat" is already up to date - } - else - { - // XXX TODO: need to update positions + divs - - if(scs->numverts != dm->getNumVerts(dm)) - { - // DG TODO: reset modifier? - return; - } + if (smd->coll->dm) + smd->coll->dm->release(smd->coll->dm); - for(i = 0; i < numpoints * 3; i++) - { - points_old[i] = points[i]; - } - - DM_ensure_tessface(dm); - fill_scs_points_anim(ob, dm, scs); - } + smd->coll->dm = CDDM_copy(dm); + DM_ensure_tessface(smd->coll->dm); } - else if(scene->r.cfra < smd->time) + + smd->time = scene->r.cfra; + if (scene->r.cfra < smd->time) { - smd->time = scene->r.cfra; smokeModifier_reset(smd); } } - else if(smd->type & MOD_SMOKE_TYPE_DOMAIN) + else if (smd->type & MOD_SMOKE_TYPE_DOMAIN) { SmokeDomainSettings *sds = smd->domain; - float light[3]; PointCache *cache = NULL; PTCacheID pid; int startframe, endframe, framenr; @@ -1762,41 +2177,39 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM BKE_ptcache_id_from_smoke(&pid, ob, smd); BKE_ptcache_id_time(&pid, scene, framenr, &startframe, &endframe, ×cale); - if(!smd->domain->fluid || framenr == startframe) + if (!smd->domain->fluid || framenr == startframe) { BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED); + smokeModifier_reset(smd); BKE_ptcache_validate(cache, framenr); cache->flag &= ~PTCACHE_REDO_NEEDED; } - if(!smd->domain->fluid && (framenr != startframe) && (smd->domain->flags & MOD_SMOKE_FILE_LOAD)==0 && (cache->flag & PTCACHE_BAKED)==0) + if (!smd->domain->fluid && (framenr != startframe) && (smd->domain->flags & MOD_SMOKE_FILE_LOAD) == 0 && (cache->flag & PTCACHE_BAKED) == 0) return; smd->domain->flags &= ~MOD_SMOKE_FILE_LOAD; - CLAMP(framenr, startframe, endframe); /* If already viewing a pre/after frame, no need to reload */ if ((smd->time == framenr) && (framenr != scene->r.cfra)) return; - // printf("startframe: %d, framenr: %d\n", startframe, framenr); - - if(smokeModifier_init(smd, ob, scene, dm)==0) + if (smokeModifier_init(smd, ob, scene, dm) == 0) { printf("bad smokeModifier_init\n"); return; } /* try to read from cache */ - if(BKE_ptcache_read(&pid, (float)framenr) == PTCACHE_READ_EXACT) { + if (BKE_ptcache_read(&pid, (float)framenr) == PTCACHE_READ_EXACT) { BKE_ptcache_validate(cache, framenr); smd->time = framenr; return; } - + /* only calculate something when we advanced a single frame */ - if(framenr != (int)smd->time+1) + if (framenr != (int)smd->time + 1) return; /* don't simulate if viewing start frame, but scene frame is not real start frame */ @@ -1805,54 +2218,48 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM tstart(); - smoke_calc_domain(scene, ob, smd); - /* if on second frame, write cache for first frame */ - if((int)smd->time == startframe && (cache->flag & PTCACHE_OUTDATED || cache->last_exact==0)) { + if ((int)smd->time == startframe && (cache->flag & PTCACHE_OUTDATED || cache->last_exact == 0)) { // create shadows straight after domain initialization so we get nice shadows for startframe, too - if(get_lamp(scene, light)) - smoke_calc_transparency(sds->shadow, smoke_get_density(sds->fluid), sds->p0, sds->p1, sds->res, sds->dx, light, calc_voxel_transp, -7.0*sds->dx); + smoke_calc_transparency(sds, scene); - if(sds->wt) + if (sds->wt && sds->total_cells > 1) { - if(sds->flags & MOD_SMOKE_DISSOLVE) + if (sds->flags & MOD_SMOKE_DISSOLVE) smoke_dissolve_wavelet(sds->wt, sds->diss_speed, sds->flags & MOD_SMOKE_DISSOLVE_LOG); smoke_turbulence_step(sds->wt, sds->fluid); } BKE_ptcache_write(&pid, startframe); } - + // set new time smd->time = scene->r.cfra; /* do simulation */ - // low res - // simulate the actual smoke (c++ code in intern/smoke) // DG: interesting commenting this line + deactivating loading of noise files - if(framenr!=startframe) + if (framenr != startframe) { - if(sds->flags & MOD_SMOKE_DISSOLVE) + if (sds->flags & MOD_SMOKE_DISSOLVE) smoke_dissolve(sds->fluid, sds->diss_speed, sds->flags & MOD_SMOKE_DISSOLVE_LOG); - - step(scene, ob, smd, scene->r.frs_sec / scene->r.frs_sec_base); + + step(scene, ob, smd, dm, scene->r.frs_sec / scene->r.frs_sec_base); } // create shadows before writing cache so they get stored - if(get_lamp(scene, light)) - smoke_calc_transparency(sds->shadow, smoke_get_density(sds->fluid), sds->p0, sds->p1, sds->res, sds->dx, light, calc_voxel_transp, -7.0*sds->dx); + smoke_calc_transparency(sds, scene); - if(sds->wt) + if (sds->wt) { - if(sds->flags & MOD_SMOKE_DISSOLVE) + if (sds->flags & MOD_SMOKE_DISSOLVE) smoke_dissolve_wavelet(sds->wt, sds->diss_speed, sds->flags & MOD_SMOKE_DISSOLVE_LOG); smoke_turbulence_step(sds->wt, sds->fluid); } - + BKE_ptcache_validate(cache, framenr); - if(framenr != startframe) + if (framenr != startframe) BKE_ptcache_write(&pid, framenr); tend(); @@ -1860,38 +2267,33 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM } } -static float calc_voxel_transp(float *result, float *input, int res[3], int *pixel, float *tRay, float correct) -{ - const size_t index = smoke_get_index(pixel[0], res[0], pixel[1], res[1], pixel[2]); +struct DerivedMesh *smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedMesh *dm){ + smokeModifier_process(smd, scene, ob, dm); - // T_ray *= T_vox - *tRay *= exp(input[index]*correct); - - if(result[index] < 0.0f) + /* return generated geometry for adaptive domain */ + if (smd->type & MOD_SMOKE_TYPE_DOMAIN && smd->domain && + smd->domain->flags & MOD_SMOKE_ADAPTIVE_DOMAIN && + smd->domain->base_res[0]) { -// #pragma omp critical - result[index] = *tRay; - } - - return *tRay; + return createDomainGeometry(smd->domain, ob); + } + else return CDDM_copy(dm); } -long long smoke_get_mem_req(int xres, int yres, int zres, int amplify) +static float calc_voxel_transp(float *result, float *input, int res[3], int *pixel, float *tRay, float correct) { - int totalCells = xres * yres * zres; - int amplifiedCells = totalCells * amplify * amplify * amplify; - - // print out memory requirements - long long int coarseSize = sizeof(float) * totalCells * 22 + - sizeof(unsigned char) * totalCells; + const size_t index = smoke_get_index(pixel[0], res[0], pixel[1], res[1], pixel[2]); - long long int fineSize = sizeof(float) * amplifiedCells * 7 + // big grids - sizeof(float) * totalCells * 8 + // small grids - sizeof(float) * 128 * 128 * 128; // noise tile + // T_ray *= T_vox + *tRay *= exp(input[index] * correct); - long long int totalMB = (coarseSize + fineSize) / (1024 * 1024); + if (result[index] < 0.0f) + { +// #pragma omp critical + result[index] = *tRay; + } - return totalMB; + return *tRay; } static void bresenham_linie_3D(int x1, int y1, int z1, int x2, int y2, int z2, float *tRay, bresenham_callback cb, float *result, float *input, int res[3], float correct) @@ -1921,7 +2323,7 @@ static void bresenham_linie_3D(int x1, int y1, int z1, int x2, int y2, int z2, f err_1 = dy2 - l; err_2 = dz2 - l; for (i = 0; i < l; i++) { - if(cb(result, input, res, pixel, tRay, correct) <= FLT_EPSILON) + if (cb(result, input, res, pixel, tRay, correct) <= FLT_EPSILON) break; if (err_1 > 0) { pixel[1] += y_inc; @@ -1935,12 +2337,12 @@ static void bresenham_linie_3D(int x1, int y1, int z1, int x2, int y2, int z2, f err_2 += dz2; pixel[0] += x_inc; } - } + } else if ((m >= l) && (m >= n)) { err_1 = dx2 - m; err_2 = dz2 - m; for (i = 0; i < m; i++) { - if(cb(result, input, res, pixel, tRay, correct) <= FLT_EPSILON) + if (cb(result, input, res, pixel, tRay, correct) <= FLT_EPSILON) break; if (err_1 > 0) { pixel[0] += x_inc; @@ -1954,12 +2356,12 @@ static void bresenham_linie_3D(int x1, int y1, int z1, int x2, int y2, int z2, f err_2 += dz2; pixel[1] += y_inc; } - } + } else { err_1 = dy2 - n; err_2 = dx2 - n; for (i = 0; i < n; i++) { - if(cb(result, input, res, pixel, tRay, correct) <= FLT_EPSILON) + if (cb(result, input, res, pixel, tRay, correct) <= FLT_EPSILON) break; if (err_1 > 0) { pixel[1] += y_inc; @@ -1977,80 +2379,142 @@ static void bresenham_linie_3D(int x1, int y1, int z1, int x2, int y2, int z2, f cb(result, input, res, pixel, tRay, correct); } -static void get_cell(const float p0[3], const int res[3], float dx, const float pos[3], int cell[3], int correct) +static void smoke_calc_transparency(SmokeDomainSettings *sds, Scene *scene) { - float tmp[3]; - - sub_v3_v3v3(tmp, pos, p0); - mul_v3_fl(tmp, 1.0 / dx); + float bv[6] = {0}; + float light[3]; + int a, z, slabsize = sds->res[0] * sds->res[1], size = sds->res[0] * sds->res[1] * sds->res[2]; + float *density = smoke_get_density(sds->fluid); + float correct = -7.0 * sds->dx; - if (correct) { - cell[0] = MIN2(res[0] - 1, MAX2(0, (int)floor(tmp[0]))); - cell[1] = MIN2(res[1] - 1, MAX2(0, (int)floor(tmp[1]))); - cell[2] = MIN2(res[2] - 1, MAX2(0, (int)floor(tmp[2]))); - } - else { - cell[0] = (int)floor(tmp[0]); - cell[1] = (int)floor(tmp[1]); - cell[2] = (int)floor(tmp[2]); - } -} + if (!get_lamp(scene, light)) return; -static void smoke_calc_transparency(float *result, float *input, float *p0, float *p1, int res[3], float dx, float *light, bresenham_callback cb, float correct) -{ - float bv[6]; - int a, z, slabsize=res[0]*res[1], size= res[0]*res[1]*res[2]; + /* convert light pos to sim cell space */ + mul_m4_v3(sds->imat, light); + light[0] = (light[0] - sds->p0[0]) / sds->cell_size[0] - 0.5f - (float)sds->res_min[0]; + light[1] = (light[1] - sds->p0[1]) / sds->cell_size[1] - 0.5f - (float)sds->res_min[1]; + light[2] = (light[2] - sds->p0[2]) / sds->cell_size[2] - 0.5f - (float)sds->res_min[2]; - for(a=0; ashadow[a] = -1.0f; - bv[0] = p0[0]; - bv[1] = p1[0]; - // y - bv[2] = p0[1]; - bv[3] = p1[1]; - // z - bv[4] = p0[2]; - bv[5] = p1[2]; + /* calculate domain bounds in sim cell space */ + // 0,2,4 = 0.0f + bv[1] = (float)sds->res[0]; // x + bv[3] = (float)sds->res[1]; // y + bv[5] = (float)sds->res[2]; // z // #pragma omp parallel for schedule(static,1) - for(z = 0; z < res[2]; z++) + for (z = 0; z < sds->res[2]; z++) { - size_t index = z*slabsize; - int x,y; + size_t index = z * slabsize; + int x, y; - for(y = 0; y < res[1]; y++) - for(x = 0; x < res[0]; x++, index++) + for (y = 0; y < sds->res[1]; y++) + for (x = 0; x < sds->res[0]; x++, index++) { float voxelCenter[3]; float pos[3]; int cell[3]; float tRay = 1.0; - if(result[index] >= 0.0f) - continue; - voxelCenter[0] = p0[0] + dx * x + dx * 0.5; - voxelCenter[1] = p0[1] + dx * y + dx * 0.5; - voxelCenter[2] = p0[2] + dx * z + dx * 0.5; + if (sds->shadow[index] >= 0.0f) + continue; + voxelCenter[0] = (float)x; + voxelCenter[1] = (float)y; + voxelCenter[2] = (float)z; - // get starting position (in voxel coords) - if(BLI_bvhtree_bb_raycast(bv, light, voxelCenter, pos) > FLT_EPSILON) + // get starting cell (light pos) + if (BLI_bvhtree_bb_raycast(bv, light, voxelCenter, pos) > FLT_EPSILON) { - // we're ouside - get_cell(p0, res, dx, pos, cell, 1); + // we're ouside -> use point on side of domain + cell[0] = (int)floor(pos[0]); + cell[1] = (int)floor(pos[1]); + cell[2] = (int)floor(pos[2]); } else { - // we're inside - get_cell(p0, res, dx, light, cell, 1); + // we're inside -> use light itself + cell[0] = (int)floor(light[0]); + cell[1] = (int)floor(light[1]); + cell[2] = (int)floor(light[2]); } + /* clamp within grid bounds */ + CLAMP(cell[0], 0, sds->res[0] - 1); + CLAMP(cell[1], 0, sds->res[1] - 1); + CLAMP(cell[2], 0, sds->res[2] - 1); - bresenham_linie_3D(cell[0], cell[1], cell[2], x, y, z, &tRay, cb, result, input, res, correct); + bresenham_linie_3D(cell[0], cell[1], cell[2], x, y, z, &tRay, calc_voxel_transp, sds->shadow, density, sds->res, correct); // convention -> from a RGBA float array, use G value for tRay // #pragma omp critical - result[index] = tRay; + sds->shadow[index] = tRay; } } } +/* get smoke velocity and density at given coordinates + * returns fluid density or -1.0f if outside domain*/ +float smoke_get_velocity_at(struct Object *ob, float position[3], float velocity[3]) +{ + SmokeModifierData *smd = (SmokeModifierData *)modifiers_findByType(ob, eModifierType_Smoke); + zero_v3(velocity); + + if (smd && (smd->type & MOD_SMOKE_TYPE_DOMAIN) && smd->domain && smd->domain->fluid) { + SmokeDomainSettings *sds = smd->domain; + float time_mult = 25.f * DT_DEFAULT; + float vel_mag; + float *velX = smoke_get_velocity_x(sds->fluid); + float *velY = smoke_get_velocity_y(sds->fluid); + float *velZ = smoke_get_velocity_z(sds->fluid); + float density = 0.0f, fuel = 0.0f; + float pos[3]; + copy_v3_v3(pos, position); + smoke_pos_to_cell(sds, pos); + + /* check if point is outside domain max bounds */ + if (pos[0] < sds->res_min[0] || pos[1] < sds->res_min[1] || pos[2] < sds->res_min[2]) return -1.0f; + if (pos[0] > sds->res_max[0] || pos[1] > sds->res_max[1] || pos[2] > sds->res_max[2]) return -1.0f; + + /* map pos between 0.0 - 1.0 */ + pos[0] = (pos[0] - sds->res_min[0]) / ((float)sds->res[0]); + pos[1] = (pos[1] - sds->res_min[1]) / ((float)sds->res[1]); + pos[2] = (pos[2] - sds->res_min[2]) / ((float)sds->res[2]); + + + /* check if point is outside active area */ + if (smd->domain->flags & MOD_SMOKE_ADAPTIVE_DOMAIN) { + if (pos[0] < 0.0f || pos[1] < 0.0f || pos[2] < 0.0f) return 0.0f; + if (pos[0] > 1.0f || pos[1] > 1.0f || pos[2] > 1.0f) return 0.0f; + } + + /* get interpolated velocity */ + velocity[0] = BLI_voxel_sample_trilinear(velX, sds->res, pos) * sds->global_size[0] * time_mult; + velocity[1] = BLI_voxel_sample_trilinear(velY, sds->res, pos) * sds->global_size[1] * time_mult; + velocity[2] = BLI_voxel_sample_trilinear(velZ, sds->res, pos) * sds->global_size[2] * time_mult; + + /* convert velocity direction to global space */ + vel_mag = len_v3(velocity); + mul_mat3_m4_v3(sds->obmat, velocity); + normalize_v3(velocity); + mul_v3_fl(velocity, vel_mag); + + /* use max value of fuel or smoke density */ + density = BLI_voxel_sample_trilinear(smoke_get_density(sds->fluid), sds->res, pos); + if (smoke_has_fuel(sds->fluid)) { + fuel = BLI_voxel_sample_trilinear(smoke_get_fuel(sds->fluid), sds->res, pos); + } + return MAX2(density, fuel); + } + return -1.0f; +} + +int smoke_get_data_flags(SmokeDomainSettings *sds) { + int flags = 0; + if (smoke_has_heat(sds->fluid)) flags |= SM_ACTIVE_HEAT; + if (smoke_has_fuel(sds->fluid)) flags |= SM_ACTIVE_FIRE; + if (smoke_has_colors(sds->fluid)) flags |= SM_ACTIVE_COLORS; + + return flags; +} + #endif /* WITH_SMOKE */ diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c index 4a88bfbfdad..bb0cfe1a5c6 100644 --- a/source/blender/blenkernel/intern/softbody.c +++ b/source/blender/blenkernel/intern/softbody.c @@ -143,13 +143,15 @@ typedef struct SB_thread_context { } SB_thread_context; #define NLF_BUILD 1 -#define NLF_SOLVE 2 +#if 0 +# define NLF_SOLVE 2 +#endif #define MID_PRESERVE 1 #define SOFTGOALSNAP 0.999f /* if bp-> goal is above make it a *forced follow original* and skip all ODE stuff for this bp - * removes *unnecessary* stiffnes from ODE system + * removes *unnecessary* stiffness from ODE system */ #define HEUNWARNLIMIT 1 /* 500 would be fine i think for detecting severe *stiff* stuff */ @@ -1168,7 +1170,7 @@ static int sb_detect_face_pointCached(float face_v1[3], float face_v2[3], float *damp=df*tune*ob->pd->pdef_sbdamp; - df = 0.01f*exp(- 100.0f*df); + df = 0.01f * expf(-100.0f * df); Vec3PlusStVec(force, -df, d_nvect); deflected = 3; } @@ -1596,7 +1598,7 @@ static void _scan_for_ext_spring_forces(Scene *scene, Object *ob, float timenow, /*see if we have wind*/ if (do_effector) { EffectedPoint epoint; - float speed[3]={0.0f, 0.0f, 0.0f}; + float speed[3] = {0.0f, 0.0f, 0.0f}; float pos[3]; mid_v3_v3v3(pos, sb->bpoint[bs->v1].pos, sb->bpoint[bs->v2].pos); mid_v3_v3v3(vel, sb->bpoint[bs->v1].vec, sb->bpoint[bs->v2].vec); @@ -1747,8 +1749,8 @@ static int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3], Object *ob= NULL; GHash *hash; GHashIterator *ihash; - float nv1[3], nv2[3], nv3[3], nv4[3], edge1[3], edge2[3], d_nvect[3], dv1[3], ve[3], avel[3]={0.0, 0.0, 0.0}, - vv1[3], vv2[3], vv3[3], vv4[3], coledge[3]={0.0f, 0.0f, 0.0f}, mindistedge = 1000.0f, + float nv1[3], nv2[3], nv3[3], nv4[3], edge1[3], edge2[3], d_nvect[3], dv1[3], ve[3], avel[3] = {0.0, 0.0, 0.0}, + vv1[3], vv2[3], vv3[3], vv4[3], coledge[3] = {0.0f, 0.0f, 0.0f}, mindistedge = 1000.0f, outerforceaccu[3], innerforceaccu[3], facedist, /* n_mag, */ /* UNUSED */ force_mag_norm, minx, miny, minz, maxx, maxy, maxz, innerfacethickness = -0.5f, outerfacethickness = 0.2f, @@ -2207,7 +2209,7 @@ static int _softbody_calc_forces_slice_in_a_thread(Scene *scene, Object *ob, flo bp = &sb->bpoint[ifirst]; for (bb=number_of_points_here; bb>0; bb--, bp++) { /* clear forces accumulator */ - bp->force[0]= bp->force[1]= bp->force[2]= 0.0; + bp->force[0] = bp->force[1] = bp->force[2] = 0.0; /* naive ball self collision */ /* needs to be done if goal snaps or not */ if (do_selfcollision) { @@ -2302,8 +2304,8 @@ static int _softbody_calc_forces_slice_in_a_thread(Scene *scene, Object *ob, flo if (do_effector) { EffectedPoint epoint; float kd; - float force[3]= {0.0f, 0.0f, 0.0f}; - float speed[3]= {0.0f, 0.0f, 0.0f}; + float force[3] = {0.0f, 0.0f, 0.0f}; + float speed[3] = {0.0f, 0.0f, 0.0f}; float eval_sb_fric_force_scale = sb_fric_force_scale(ob); /* just for calling function once */ pd_point_from_soft(scene, bp->pos, bp->vec, sb->bpoint-bp, &epoint); pdDoEffectors(do_effector, NULL, sb->effector_weights, &epoint, force, speed); @@ -2555,7 +2557,7 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa for (a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) { /* clear forces accumulator */ - bp->force[0]= bp->force[1]= bp->force[2]= 0.0; + bp->force[0] = bp->force[1] = bp->force[2] = 0.0; if (nl_flags & NLF_BUILD) { //int ia =3*(sb->totpoint-a); //int op =3*sb->totpoint; @@ -2710,8 +2712,8 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa /* particle field & vortex */ if (do_effector) { EffectedPoint epoint; - float force[3]= {0.0f, 0.0f, 0.0f}; - float speed[3]= {0.0f, 0.0f, 0.0f}; + float force[3] = {0.0f, 0.0f, 0.0f}; + float speed[3] = {0.0f, 0.0f, 0.0f}; float eval_sb_fric_force_scale = sb_fric_force_scale(ob); /* just for calling function once */ pd_point_from_soft(scene, bp->pos, bp->vec, sb->bpoint-bp, &epoint); pdDoEffectors(do_effector, NULL, sb->effector_weights, &epoint, force, speed); @@ -2903,7 +2905,7 @@ static void softbody_apply_forces(Object *ob, float forcetime, int mode, float * /* or heun ~ 2nd order runge-kutta steps, mode 1, 2 */ SoftBody *sb= ob->soft; /* is supposed to be there */ BodyPoint *bp; - float dx[3]={0}, dv[3], aabbmin[3], aabbmax[3], cm[3]={0.0f, 0.0f, 0.0f}; + float dx[3] = {0}, dv[3], aabbmin[3], aabbmax[3], cm[3] = {0.0f, 0.0f, 0.0f}; float timeovermass/*, freezeloc=0.00001f, freezeforce=0.00000000001f*/; float maxerrpos= 0.0f, maxerrvel = 0.0f; int a, fuzzy=0; @@ -3192,7 +3194,7 @@ static void interpolate_exciter(Object *ob, int timescale, int time) - xxxx_to_softbody(Object *ob) : a full (new) copy, creates SB geometry */ -static void get_scalar_from_vertexgroup(Object *ob, int vertID, short groupindex, float *target) +static void get_scalar_from_vertexgroup(Object *ob, int vertID, int groupindex, float *target) /* result 0 on success, else indicates error number -- kind of *inverse* result defintion, -- but this way we can signal error condition to caller @@ -3295,7 +3297,7 @@ static void mesh_to_softbody(Scene *scene, Object *ob) if ((ob->softflag & OB_SB_GOAL) && sb->vertgroup) { /* even this is a deprecated evil hack */ /* I'd like to have it .. if (sb->namedVG_Goal[0]) */ - get_scalar_from_vertexgroup(ob, a, (short) (sb->vertgroup-1), &bp->goal); + get_scalar_from_vertexgroup(ob, a, sb->vertgroup - 1, &bp->goal); /* do this always, regardless successful read from vertex group */ /* this is where '2.5 every thing is animatable' goes wrong in the first place jow_go_for2_5 */ /* 1st coding action to take : move this to frame level */ @@ -3314,10 +3316,10 @@ static void mesh_to_softbody(Scene *scene, Object *ob) */ if (sb->namedVG_Mass[0]) { - int grp= defgroup_name_index (ob, sb->namedVG_Mass); - /* printf("VGN %s %d\n", sb->namedVG_Mass, grp); */ - if (grp > -1) { - get_scalar_from_vertexgroup(ob, a, (short) (grp), &bp->mass); + int defgrp_index = defgroup_name_index (ob, sb->namedVG_Mass); + /* printf("VGN %s %d\n", sb->namedVG_Mass, defgrp_index); */ + if (defgrp_index != -1) { + get_scalar_from_vertexgroup(ob, a, defgrp_index, &bp->mass); /* 2.5 bp->mass = bp->mass * sb->nodemass; */ /* printf("bp->mass %f\n", bp->mass); */ @@ -3327,10 +3329,10 @@ static void mesh_to_softbody(Scene *scene, Object *ob) bp->springweight = 1.0f; if (sb->namedVG_Spring_K[0]) { - int grp= defgroup_name_index (ob, sb->namedVG_Spring_K); - //printf("VGN %s %d\n", sb->namedVG_Spring_K, grp); - if (grp > -1) { - get_scalar_from_vertexgroup(ob, a, (short) (grp), &bp->springweight); + int defgrp_index = defgroup_name_index (ob, sb->namedVG_Spring_K); + //printf("VGN %s %d\n", sb->namedVG_Spring_K, defgrp_index); + if (defgrp_index != -1) { + get_scalar_from_vertexgroup(ob, a, defgrp_index , &bp->springweight); //printf("bp->springweight %f\n", bp->springweight); } @@ -3863,7 +3865,7 @@ static void softbody_reset(Object *ob, SoftBody *sb, float (*vertexCos)[3], int copy_v3_v3(bp->origS, bp->pos); copy_v3_v3(bp->origE, bp->pos); copy_v3_v3(bp->origT, bp->pos); - bp->vec[0]= bp->vec[1]= bp->vec[2]= 0.0f; + bp->vec[0] = bp->vec[1] = bp->vec[2] = 0.0f; /* the bp->prev*'s are for rolling back from a canceled try to propagate in time * adaptive step size algo in a nutshell: @@ -3923,7 +3925,7 @@ static void softbody_step(Scene *scene, Object *ob, SoftBody *sb, float dtime) sst=PIL_check_seconds_timer(); /* Integration back in time is possible in theory, but pretty useless here. - * So we refuse to do so. Since we do not know anything about 'outside' canges + * So we refuse to do so. Since we do not know anything about 'outside' changes * especially colliders we refuse to go more than 10 frames. */ if (dtime < 0 || dtime > 10.5f) return; @@ -4006,8 +4008,8 @@ static void softbody_step(Scene *scene, Object *ob, SoftBody *sb, float dtime) } loops++; if (sb->solverflags & SBSO_MONITOR ) { - sct=PIL_check_seconds_timer(); - if (sct-sst > 0.5f) printf("%3.0f%% \r", 100.0f*timedone/dtime); + sct = PIL_check_seconds_timer(); + if (sct - sst > 0.5) printf("%3.0f%% \r", 100.0f * timedone / dtime); } /* ask for user break */ if (SB_localInterruptCallBack && SB_localInterruptCallBack()) break; @@ -4043,7 +4045,7 @@ static void softbody_step(Scene *scene, Object *ob, SoftBody *sb, float dtime) if (sb->solverflags & SBSO_MONITOR ) { sct=PIL_check_seconds_timer(); - if ((sct-sst > 0.5f) || (G.debug & G_DEBUG)) printf(" solver time %f sec %s\n", sct-sst, ob->id.name); + if ((sct - sst > 0.5) || (G.debug & G_DEBUG)) printf(" solver time %f sec %s\n", sct-sst, ob->id.name); } } diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c index f340bcb5b1e..aad205bb5bf 100644 --- a/source/blender/blenkernel/intern/sound.c +++ b/source/blender/blenkernel/intern/sound.c @@ -701,7 +701,7 @@ void sound_update_scene(struct Scene *scene) if (AUD_removeSet(scene->speaker_handles, strip->speaker_handle)) { if (speaker->sound) - AUD_moveSequence(strip->speaker_handle, strip->start / FPS, -1, 0); + AUD_moveSequence(strip->speaker_handle, (double)strip->start / FPS, -1, 0); else { AUD_removeSequence(scene->sound_scene, strip->speaker_handle); strip->speaker_handle = NULL; @@ -709,7 +709,9 @@ void sound_update_scene(struct Scene *scene) } else { if (speaker->sound) { - strip->speaker_handle = AUD_addSequence(scene->sound_scene, speaker->sound->playback_handle, strip->start / FPS, -1, 0); + strip->speaker_handle = AUD_addSequence(scene->sound_scene, + speaker->sound->playback_handle, + (double)strip->start / FPS, -1, 0); AUD_setRelativeSequence(strip->speaker_handle, 0); } } @@ -792,7 +794,6 @@ void sound_stop_scene(struct Scene *UNUSED(scene)) {} void sound_seek_scene(struct Main *UNUSED(bmain), struct Scene *UNUSED(scene)) {} float sound_sync_scene(struct Scene *UNUSED(scene)) { return NAN_FLT; } int sound_scene_playing(struct Scene *UNUSED(scene)) { return -1; } -int sound_read_sound_buffer(struct bSound *UNUSED(sound), float *UNUSED(buffer), int UNUSED(length), float UNUSED(start), float UNUSED(end)) { return 0; } void sound_read_waveform(struct bSound *sound) { (void)sound; } void sound_init_main(struct Main *bmain) { (void)bmain; } void sound_set_cfra(int cfra) { (void)cfra; } diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index 555ed5890c8..8a669b89907 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -513,10 +513,14 @@ static float *get_ss_weights(WeightTable *wtable, int gridCuts, int faceLen) w2 = (1.0f - fx + fac2 * fx * -fac) * (fy); w4 = (fx) * (1.0f - fy + -fac2 * fy * fac); - fac2 = 1.0f - (w1 + w2 + w4); - fac2 = fac2 / (float)(faceLen - 3); - for (j = 0; j < faceLen; j++) - w[j] = fac2; + /* these values aren't used for tri's and cause divide by zero */ + if (faceLen > 3) { + fac2 = 1.0f - (w1 + w2 + w4); + fac2 = fac2 / (float)(faceLen - 3); + for (j = 0; j < faceLen; j++) { + w[j] = fac2; + } + } w[i] = w1; w[(i - 1 + faceLen) % faceLen] = w2; @@ -598,7 +602,7 @@ static void ss_sync_from_derivedmesh(CCGSubSurf *ss, DerivedMesh *dm, } mp = mpoly; - index = DM_get_poly_data_layer(dm, CD_ORIGINDEX); + index = (int *)dm->getPolyDataArray(dm, CD_ORIGINDEX); for (i = 0; i < dm->numPolyData; i++, mp++) { CCGFace *f; @@ -2699,6 +2703,30 @@ static void *ccgDM_get_edge_data_layer(DerivedMesh *dm, int type) } static void *ccgDM_get_tessface_data_layer(DerivedMesh *dm, int type) +{ + if (type == CD_ORIGINDEX) { + /* create origindex on demand to save memory */ + int *origindex; + + /* Avoid re-creation if the layer exists already */ + origindex = DM_get_tessface_data_layer(dm, CD_ORIGINDEX); + if (origindex) { + return origindex; + } + + DM_add_tessface_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL); + origindex = DM_get_tessface_data_layer(dm, CD_ORIGINDEX); + + /* silly loop counting up */ + range_vn_i(origindex, dm->getNumTessFaces(dm), 0); + + return origindex; + } + + return DM_get_tessface_data_layer(dm, type); +} + +static void *ccgDM_get_poly_data_layer(DerivedMesh *dm, int type) { if (type == CD_ORIGINDEX) { /* create origindex on demand to save memory */ @@ -2709,13 +2737,13 @@ static void *ccgDM_get_tessface_data_layer(DerivedMesh *dm, int type) int gridFaces = ccgSubSurf_getGridSize(ss) - 1; /* Avoid re-creation if the layer exists already */ - origindex = DM_get_tessface_data_layer(dm, CD_ORIGINDEX); + origindex = DM_get_poly_data_layer(dm, CD_ORIGINDEX); if (origindex) { return origindex; } - DM_add_tessface_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL); - origindex = DM_get_tessface_data_layer(dm, CD_ORIGINDEX); + DM_add_poly_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL); + origindex = DM_get_poly_data_layer(dm, CD_ORIGINDEX); totface = ccgSubSurf_getNumFaces(ss); @@ -2731,7 +2759,7 @@ static void *ccgDM_get_tessface_data_layer(DerivedMesh *dm, int type) return origindex; } - return DM_get_tessface_data_layer(dm, type); + return DM_get_poly_data_layer(dm, type); } static void *ccgDM_get_vert_data(DerivedMesh *dm, int index, int type) @@ -2764,6 +2792,16 @@ static void *ccgDM_get_tessface_data(DerivedMesh *dm, int index, int type) return DM_get_tessface_data(dm, index, type); } +static void *ccgDM_get_poly_data(DerivedMesh *dm, int index, int type) +{ + if (type == CD_ORIGINDEX) { + /* ensure creation of CD_ORIGINDEX layer */ + ccgDM_get_tessface_data_layer(dm, type); + } + + return DM_get_poly_data(dm, index, type); +} + static int ccgDM_getNumGrids(DerivedMesh *dm) { CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm; @@ -3016,6 +3054,9 @@ static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm) me->totface, me->totvert, &me->vdata); } + if (ccgdm->pbvh) + pbvh_show_diffuse_color_set(ccgdm->pbvh, ob->sculpt->show_diffuse_color); + return ccgdm->pbvh; } @@ -3091,7 +3132,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, } /* We absolutely need that layer, else it's no valid tessellated data! */ - polyidx = CustomData_add_layer(&ccgdm->dm.faceData, CD_POLYINDEX, CD_CALLOC, + polyidx = CustomData_add_layer(&ccgdm->dm.faceData, CD_ORIGINDEX, CD_CALLOC, NULL, ccgSubSurf_getNumFinalFaces(ss)); ccgdm->dm.getMinMax = ccgDM_getMinMax; @@ -3119,9 +3160,11 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, ccgdm->dm.getVertData = ccgDM_get_vert_data; ccgdm->dm.getEdgeData = ccgDM_get_edge_data; ccgdm->dm.getTessFaceData = ccgDM_get_tessface_data; + ccgdm->dm.getPolyData = ccgDM_get_poly_data; ccgdm->dm.getVertDataArray = ccgDM_get_vert_data_layer; ccgdm->dm.getEdgeDataArray = ccgDM_get_edge_data_layer; ccgdm->dm.getTessFaceDataArray = ccgDM_get_tessface_data_layer; + ccgdm->dm.getPolyDataArray = ccgDM_get_poly_data_layer; ccgdm->dm.getNumGrids = ccgDM_getNumGrids; ccgdm->dm.getGridSize = ccgDM_getGridSize; ccgdm->dm.getGridData = ccgDM_getGridData; @@ -3220,8 +3263,8 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, vertOrigIndex = DM_get_vert_data_layer(&ccgdm->dm, CD_ORIGINDEX); /*edgeOrigIndex = DM_get_edge_data_layer(&ccgdm->dm, CD_ORIGINDEX);*/ - faceOrigIndex = DM_get_tessface_data_layer(&ccgdm->dm, CD_ORIGINDEX); + faceOrigIndex = DM_get_tessface_data_layer(&ccgdm->dm, CD_ORIGINDEX); polyOrigIndex = DM_get_poly_data_layer(&ccgdm->dm, CD_ORIGINDEX); #if 0 @@ -3359,7 +3402,8 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, /*set original index data*/ if (faceOrigIndex) { - *faceOrigIndex = origIndex; + /* reference the index in 'polyOrigIndex' */ + *faceOrigIndex = faceNum; faceOrigIndex++; } if (polyOrigIndex) { diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c index 3c89fdba13a..b3497b9932f 100644 --- a/source/blender/blenkernel/intern/text.c +++ b/source/blender/blenkernel/intern/text.c @@ -48,18 +48,22 @@ #include "DNA_constraint_types.h" #include "DNA_controller_types.h" +#include "DNA_actuator_types.h" #include "DNA_scene_types.h" #include "DNA_screen_types.h" #include "DNA_space_types.h" #include "DNA_text_types.h" #include "DNA_userdef_types.h" #include "DNA_object_types.h" +#include "DNA_node_types.h" +#include "DNA_material_types.h" #include "BKE_depsgraph.h" #include "BKE_global.h" #include "BKE_library.h" #include "BKE_main.h" #include "BKE_text.h" +#include "BKE_node.h" #ifdef WITH_PYTHON @@ -313,7 +317,7 @@ int BKE_text_reload(Text *text) fseek(fp, 0L, SEEK_END); len = ftell(fp); - fseek(fp, 0L, SEEK_SET); + fseek(fp, 0L, SEEK_SET); text->undo_pos = -1; @@ -369,7 +373,7 @@ int BKE_text_reload(Text *text) text->curl = text->sell = text->lines.first; text->curc = text->selc = 0; - MEM_freeN(buffer); + MEM_freeN(buffer); return 1; } @@ -403,7 +407,7 @@ Text *BKE_text_load(const char *file, const char *relpath) fseek(fp, 0L, SEEK_END); len = ftell(fp); - fseek(fp, 0L, SEEK_SET); + fseek(fp, 0L, SEEK_SET); ta->name = MEM_mallocN(strlen(file) + 1, "text_name"); strcpy(ta->name, file); @@ -468,7 +472,7 @@ Text *BKE_text_load(const char *file, const char *relpath) ta->curl = ta->sell = ta->lines.first; ta->curc = ta->selc = 0; - MEM_freeN(buffer); + MEM_freeN(buffer); return ta; } @@ -528,7 +532,11 @@ void BKE_text_unlink(Main *bmain, Text *text) SpaceLink *sl; Object *ob; bController *cont; + bActuator *act; bConstraint *con; + bNodeTree *ntree; + bNode *node; + Material *mat; short update; for (ob = bmain->object.first; ob; ob = ob->id.next) { @@ -541,6 +549,15 @@ void BKE_text_unlink(Main *bmain, Text *text) if (pc->text == text) pc->text = NULL; } } + /* game actuators */ + for (act = ob->actuators.first; act; act = act->next) { + if (act->type == ACT_2DFILTER) { + bTwoDFilterActuator *tfa; + + tfa = act->data; + if (tfa->text == text) tfa->text = NULL; + } + } /* pyconstraints */ update = 0; @@ -571,6 +588,28 @@ void BKE_text_unlink(Main *bmain, Text *text) DAG_id_tag_update(&ob->id, OB_RECALC_DATA); } + /* nodes */ + for (mat = bmain->mat.first; mat; mat = mat->id.next) { + ntree = mat->nodetree; + if (!ntree) + continue; + for (node = ntree->nodes.first; node; node = node->next) { + if (node->type == SH_NODE_SCRIPT) { + Text *ntext = (Text *)node->id; + if (ntext == text) node->id = NULL; + } + } + } + + for (ntree = bmain->nodetree.first; ntree; ntree = ntree->id.next) { + for (node = ntree->nodes.first; node; node = node->next) { + if (node->type == SH_NODE_SCRIPT) { + Text *ntext = (Text *)node->id; + if (ntext == text) node->id = NULL; + } + } + } + /* text space */ for (scr = bmain->screen.first; scr; scr = scr->id.next) { for (area = scr->areabase.first; area; area = area->next) { @@ -672,7 +711,7 @@ void txt_clean_text(Text *text) if (!text->lines.first) { if (text->lines.last) text->lines.first = text->lines.last; else text->lines.first = text->lines.last = txt_new_line(NULL); - } + } if (!text->lines.last) text->lines.last = text->lines.first; @@ -721,7 +760,7 @@ int txt_get_span(TextLine *from, TextLine *to) if (!tmp) ret = 0; } - return ret; + return ret; } static void txt_make_dirty(Text *text) @@ -923,7 +962,7 @@ void txt_move_right(Text *text, short sel) txt_move_down(text, sel); *charp = 0; } - } + } else { // do nice right only if there are only spaces // spaces hardcoded in DNA_text_types.h @@ -1365,7 +1404,7 @@ int txt_find_string(Text *text, const char *findstr, int wrap, int match_case) int newc = (int)(s - tl->line); txt_move_to(text, newl, newc, 0); txt_move_to(text, newl, newc + strlen(findstr), 1); - return 1; + return 1; } else return 0; @@ -1447,7 +1486,7 @@ char *txt_sel_to_buf(Text *text) length += charl; buf[length] = 0; - } + } return buf; } @@ -1919,6 +1958,7 @@ static unsigned int txt_undo_read_unicode(const char *undo_buf, int *undo_pos, s break; case 4: /* 32-bit unicode symbol */ unicode = txt_undo_read_uint32(undo_buf, undo_pos); + break; default: /* should never happen */ BLI_assert(0); @@ -1970,6 +2010,7 @@ static unsigned int txt_redo_read_unicode(const char *undo_buf, int *undo_pos, s break; case 4: /* 32-bit unicode symbol */ unicode = txt_undo_read_uint32(undo_buf, undo_pos); + break; default: /* should never happen */ BLI_assert(0); @@ -2065,7 +2106,7 @@ void txt_do_undo(Text *text) charp = op - UNDO_BS_1 + 1; txt_add_char(text, txt_undo_read_unicode(text->undo_buf, &text->undo_pos, charp)); text->undo_pos--; - break; + break; case UNDO_DEL_1: case UNDO_DEL_2: case UNDO_DEL_3: case UNDO_DEL_4: charp = op - UNDO_DEL_1 + 1; @@ -2091,7 +2132,7 @@ void txt_do_undo(Text *text) txt_curs_first(text, &holdl, &holdc); holdln = txt_get_span(text->lines.first, holdl); - txt_insert_buf(text, buf); + txt_insert_buf(text, buf); MEM_freeN(buf); text->curl = text->lines.first; @@ -2222,7 +2263,7 @@ void txt_do_redo(Text *text) unsigned short charp; char *buf; - text->undo_pos++; + text->undo_pos++; op = text->undo_buf[text->undo_pos]; if (!op) { @@ -2338,7 +2379,7 @@ void txt_do_redo(Text *text) text->undo_pos += linep; buf[linep] = 0; - txt_insert_buf(text, buf); + txt_insert_buf(text, buf); MEM_freeN(buf); text->undo_pos++; @@ -2356,7 +2397,7 @@ void txt_do_redo(Text *text) //charp is the first char selected or 0 linep = txt_redo_read_uint32(text->undo_buf, &text->undo_pos); - //linep is now the first line of the selection + //linep is now the first line of the selection //set the selcetion for this now text->curc = charp; text->curl = text->lines.first; @@ -2463,7 +2504,7 @@ void txt_split_curline(Text *text) text->curl->format = NULL; text->curl->len = text->curl->len - text->curc; - BLI_insertlinkbefore(&text->lines, text->curl, ins); + BLI_insertlinkbefore(&text->lines, text->curl, ins); text->curc = 0; diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c index bdd9b424f3b..6d0313f6334 100644 --- a/source/blender/blenkernel/intern/texture.c +++ b/source/blender/blenkernel/intern/texture.c @@ -571,7 +571,7 @@ void default_mtex(MTex *mtex) mtex->size[1] = 1.0; mtex->size[2] = 1.0; mtex->tex = NULL; - mtex->texflag = MTEX_3TAP_BUMP | MTEX_BUMP_OBJECTSPACE; + mtex->texflag = MTEX_3TAP_BUMP | MTEX_BUMP_OBJECTSPACE | MTEX_MAPTO_BOUNDS; mtex->colormodel = 0; mtex->r = 1.0; mtex->g = 0.0; @@ -646,7 +646,7 @@ MTex *add_mtex_id(ID *id, int slot) if (slot == -1) { /* find first free */ - int i; + int i; for (i = 0; i < MAX_MTEX; i++) { if (!mtex_ar[i]) { slot = i; @@ -909,8 +909,7 @@ void autotexname(Tex *tex) if (tex->use_nodes) { new_id(&bmain->tex, (ID *)tex, "Noddy"); } - else - if (tex->type == TEX_IMAGE) { + else if (tex->type == TEX_IMAGE) { ima = tex->ima; if (ima) { BLI_strncpy(di, ima->name, sizeof(di)); @@ -1073,19 +1072,21 @@ void set_current_material_texture(Material *ma, Tex *newtex) { Tex *tex = NULL; bNode *node; - - if (ma && ma->use_nodes && ma->nodetree) { - node = nodeGetActiveID(ma->nodetree, ID_TE); - if (node) { - tex = (Tex *)node->id; - id_us_min(&tex->id); + if ((ma->use_nodes && ma->nodetree) && + (node = nodeGetActiveID(ma->nodetree, ID_TE))) + { + tex = (Tex *)node->id; + id_us_min(&tex->id); + if (newtex) { node->id = &newtex->id; id_us_plus(&newtex->id); - ma = NULL; + } + else { + node->id = NULL; } } - if (ma) { + else { int act = (int)ma->texact; tex = (ma->mtex[act]) ? ma->mtex[act]->tex : NULL; diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index 97ebc3a90ba..89446a1856f 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -51,6 +51,8 @@ #include "BLI_string.h" #include "BLI_threads.h" +#include "BLF_translation.h" + #include "BKE_global.h" #include "BKE_tracking.h" #include "BKE_movieclip.h" @@ -169,10 +171,9 @@ void BKE_tracking_settings_init(MovieTracking *tracking) tracking->settings.default_minimum_correlation = 0.75; tracking->settings.default_pattern_size = 11; tracking->settings.default_search_size = 61; - tracking->settings.keyframe1 = 1; - tracking->settings.keyframe2 = 30; tracking->settings.dist = 1; tracking->settings.object_distance = 1; + tracking->settings.reconstruction_success_threshold = 1e-3; tracking->stabilization.scaleinf = 1.0f; tracking->stabilization.locinf = 1.0f; @@ -223,7 +224,7 @@ void BKE_tracking_get_projection_matrix(MovieTracking *tracking, MovieTrackingOb float viewfac, pixsize, left, right, bottom, top, clipsta, clipend; float winmat[4][4]; float ycor = 1.0f / tracking->camera.pixel_aspect; - float shiftx, shifty, winside = MAX2(winx, winy); + float shiftx, shifty, winside = (float)min_ii(winx, winy); BKE_tracking_camera_shift_get(tracking, winx, winy, &shiftx, &shifty); @@ -335,7 +336,7 @@ static void search_pixel_to_marker_unified(int frame_width, int frame_height, } /* Each marker has 5 coordinates associated with it that get warped with - * tracking: the four corners ("pattern_corners"), and the cernter ("pos"). + * tracking: the four corners ("pattern_corners"), and the center ("pos"). * This function puts those 5 points into the appropriate frame for tracking * (the "search" coordinate frame). */ @@ -455,7 +456,7 @@ void BKE_tracking_clipboard_paste_tracks(MovieTracking *tracking, MovieTrackingO /*********************** Tracks *************************/ -static void tracking_marker_insert_disabled(MovieTrackingTrack *track, MovieTrackingMarker *ref_marker, +static void tracking_marker_insert_disabled(MovieTrackingTrack *track, const MovieTrackingMarker *ref_marker, int before, int overwrite) { MovieTrackingMarker marker_new; @@ -633,7 +634,7 @@ void BKE_tracking_track_path_clear(MovieTrackingTrack *track, int ref_frame, int } } -void BKE_tracking_tracks_join(MovieTrackingTrack *dst_track, MovieTrackingTrack *src_track) +void BKE_tracking_tracks_join(MovieTracking *tracking, MovieTrackingTrack *dst_track, MovieTrackingTrack *src_track) { int i = 0, a = 0, b = 0, tot; MovieTrackingMarker *markers; @@ -736,6 +737,8 @@ void BKE_tracking_tracks_join(MovieTrackingTrack *dst_track, MovieTrackingTrack dst_track->markersnr = i; MEM_freeN(markers); + + BKE_tracking_dopesheet_tag_update(tracking); } MovieTrackingTrack *BKE_tracking_track_get_named(MovieTracking *tracking, MovieTrackingObject *object, const char *name) @@ -856,7 +859,7 @@ static void track_mask_gpencil_layer_rasterize(int frame_width, int frame_height } /* TODO: add an option to control whether AA is enabled or not */ - PLX_raskterize((float (*)[2])mask_points, stroke->totpoints, mask, mask_width, mask_height, FALSE); + PLX_raskterize((float (*)[2])mask_points, stroke->totpoints, mask, mask_width, mask_height); MEM_freeN(mask_points); } @@ -997,8 +1000,8 @@ void BKE_tracking_marker_clamp(MovieTrackingMarker *marker, int event) if (event == CLAMP_PAT_DIM) { for (a = 0; a < 2; a++) { /* search shouldn't be resized smaller than pattern */ - marker->search_min[a] = minf(pat_min[a], marker->search_min[a]); - marker->search_max[a] = maxf(pat_max[a], marker->search_max[a]); + marker->search_min[a] = min_ff(pat_min[a], marker->search_min[a]); + marker->search_max[a] = max_ff(pat_max[a], marker->search_max[a]); } } else if (event == CLAMP_PAT_POS) { @@ -1022,8 +1025,8 @@ void BKE_tracking_marker_clamp(MovieTrackingMarker *marker, int event) else if (event == CLAMP_SEARCH_DIM) { for (a = 0; a < 2; a++) { /* search shouldn't be resized smaller than pattern */ - marker->search_min[a] = minf(pat_min[a], marker->search_min[a]); - marker->search_max[a] = maxf(pat_max[a], marker->search_max[a]); + marker->search_min[a] = min_ff(pat_min[a], marker->search_min[a]); + marker->search_max[a] = max_ff(pat_max[a], marker->search_max[a]); } } else if (event == CLAMP_SEARCH_POS) { @@ -1043,14 +1046,6 @@ void BKE_tracking_marker_clamp(MovieTrackingMarker *marker, int event) } } } - else if (event == CLAMP_SEARCH_DIM) { - float dim[2]; - sub_v2_v2v2(dim, pat_max, pat_min); - for (a = 0; a < 2; a++) { - marker->search_min[a] = pat_min[a]; - marker->search_max[a] = pat_max[a]; - } - } } MovieTrackingMarker *BKE_tracking_marker_get(MovieTrackingTrack *track, int framenr) @@ -1187,23 +1182,25 @@ MovieTrackingObject *BKE_tracking_object_add(MovieTracking *tracking, const char tracking->objectnr = BLI_countlist(&tracking->objects) - 1; object->scale = 1.0f; + object->keyframe1 = 1; + object->keyframe2 = 30; BKE_tracking_object_unique_name(tracking, object); return object; } -void BKE_tracking_object_delete(MovieTracking *tracking, MovieTrackingObject *object) +int BKE_tracking_object_delete(MovieTracking *tracking, MovieTrackingObject *object) { MovieTrackingTrack *track; int index = BLI_findindex(&tracking->objects, object); - if (index < 0) - return; + if (index == -1) + return FALSE; if (object->flag & TRACKING_OBJECT_CAMERA) { /* object used for camera solving can't be deleted */ - return; + return FALSE; } track = object->tracks.first; @@ -1219,10 +1216,11 @@ void BKE_tracking_object_delete(MovieTracking *tracking, MovieTrackingObject *ob tracking->tot_object--; - if (index > 0) + if (index != 0) tracking->objectnr = index - 1; else tracking->objectnr = 0; + return TRUE; } void BKE_tracking_object_unique_name(MovieTracking *tracking, MovieTrackingObject *object) @@ -1502,7 +1500,8 @@ ImBuf *BKE_tracking_distortion_exec(MovieDistortion *distortion, MovieTracking * ibuf->x, ibuf->y, overscan, ibuf->channels); } - resibuf->userflags |= IB_RECT_INVALID; + if (ibuf->rect) + imb_freerectImBuf(ibuf); } else { if (undistort) { @@ -1520,9 +1519,8 @@ ImBuf *BKE_tracking_distortion_exec(MovieDistortion *distortion, MovieTracking * (void) overscan; (void) undistort; - if (ibuf->rect_float) { - resibuf->userflags |= IB_RECT_INVALID; - } + if (ibuf->rect_float && ibuf->rect) + imb_freerectImBuf(ibuf); #endif return resibuf; @@ -2029,7 +2027,7 @@ static void track_context_free(void *customdata) { TrackContext *track_context = (TrackContext *)customdata; -#if WITH_LIBMV +#ifdef WITH_LIBMV if (track_context->search_area) MEM_freeN(track_context->search_area); @@ -2144,7 +2142,7 @@ void BKE_tracking_context_sync(MovieTrackingContext *context) context->sync_frame = newframe; - tracking->dopesheet.ok = FALSE; + BKE_tracking_dopesheet_tag_update(tracking); } void BKE_tracking_context_sync_user(const MovieTrackingContext *context, MovieClipUser *user) @@ -2289,9 +2287,9 @@ static ImBuf *tracking_context_get_reference_ibuf(MovieTrackingContext *context, return ibuf; } -static void track_context_update_reference(MovieTrackingContext *context, TrackContext *track_context, - MovieTrackingTrack *track, MovieTrackingMarker *marker, int curfra, - int frame_width, int frame_height) +static int track_context_update_reference(MovieTrackingContext *context, TrackContext *track_context, + MovieTrackingTrack *track, MovieTrackingMarker *marker, int curfra, + int frame_width, int frame_height) { MovieTrackingMarker *marker_keyed = NULL; ImBuf *reference_ibuf = NULL; @@ -2299,6 +2297,10 @@ static void track_context_update_reference(MovieTrackingContext *context, TrackC /* calculate patch for keyframed position */ reference_ibuf = tracking_context_get_reference_ibuf(context, track, marker, curfra, &marker_keyed); + + if (!reference_ibuf) + return FALSE; + track_context->marker = *marker_keyed; if (track_context->search_area) { @@ -2317,6 +2319,8 @@ static void track_context_update_reference(MovieTrackingContext *context, TrackC } IMB_freeImBuf(reference_ibuf); + + return TRUE; } static void tracking_configure_tracker(TrackContext *track_context, MovieTrackingTrack *track, @@ -2345,10 +2349,10 @@ static int tracking_check_marker_margin(MovieTrackingTrack *track, MovieTracking /* margin from frame boundaries */ BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max); sub_v2_v2v2(dim, pat_max, pat_min); - margin[0] = margin[1] = maxf(dim[0], dim[1]) / 2.0f; + margin[0] = margin[1] = max_ff(dim[0], dim[1]) / 2.0f; - margin[0] = maxf(margin[0], (float)track->margin / frame_width); - margin[1] = maxf(margin[1], (float)track->margin / frame_height); + margin[0] = max_ff(margin[0], (float)track->margin / frame_width); + margin[1] = max_ff(margin[1], (float)track->margin / frame_height); /* do not track markers which are too close to boundary */ if (marker->pos[0] < margin[0] || marker->pos[0] > 1.0f - margin[0] || @@ -2402,7 +2406,7 @@ static void tracking_insert_new_marker(MovieTrackingContext *context, MovieTrack * if so -- create disabled marker before currently tracking "segment" */ - tracking_marker_insert_disabled(track, &new_marker, !context->backwards, FALSE); + tracking_marker_insert_disabled(track, old_marker, !context->backwards, FALSE); } /* insert currently tracked marker */ @@ -2481,8 +2485,12 @@ int BKE_tracking_context_step(MovieTrackingContext *context) float *patch_new; if (need_readjust) { - track_context_update_reference(context, track_context, track, marker, - curfra, frame_width, frame_height); + if (track_context_update_reference(context, track_context, track, marker, + curfra, frame_width, frame_height) == FALSE) + { + /* happens when reference frame fails to be loaded */ + continue; + } } /* for now track to the same search area dimension as marker has got for current frame @@ -2554,6 +2562,9 @@ typedef struct MovieReconstructContext { TracksMap *tracks_map; + float success_threshold; + int use_fallback_reconstruction; + int sfra, efra; } MovieReconstructContext; @@ -2753,10 +2764,11 @@ static int reconstruct_refine_intrinsics_get_flags(MovieTracking *tracking, Movi return flags; } -static int reconstruct_count_tracks_on_both_keyframes(MovieTracking *tracking, ListBase *tracksbase) +static int reconstruct_count_tracks_on_both_keyframes(MovieTracking *tracking, MovieTrackingObject *object) { + ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object); int tot = 0; - int frame1 = tracking->settings.keyframe1, frame2 = tracking->settings.keyframe2; + int frame1 = object->keyframe1, frame2 = object->keyframe2; MovieTrackingTrack *track; track = tracksbase->first; @@ -2776,15 +2788,13 @@ static int reconstruct_count_tracks_on_both_keyframes(MovieTracking *tracking, L int BKE_tracking_reconstruction_check(MovieTracking *tracking, MovieTrackingObject *object, char *error_msg, int error_size) { -#if WITH_LIBMV - ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object); - +#ifdef WITH_LIBMV if (tracking->settings.motion_flag & TRACKING_MOTION_MODAL) { /* TODO: check for number of tracks? */ return TRUE; } - else if (reconstruct_count_tracks_on_both_keyframes(tracking, tracksbase) < 8) { - BLI_strncpy(error_msg, "At least 8 common tracks on both of keyframes are needed for reconstruction", + else if (reconstruct_count_tracks_on_both_keyframes(tracking, object) < 8) { + BLI_strncpy(error_msg, N_("At least 8 common tracks on both of keyframes are needed for reconstruction"), error_size); return FALSE; @@ -2792,7 +2802,7 @@ int BKE_tracking_reconstruction_check(MovieTracking *tracking, MovieTrackingObje return TRUE; #else - BLI_strncpy(error_msg, "Blender is compiled without motion tracking library", error_size); + BLI_strncpy(error_msg, N_("Blender is compiled without motion tracking library"), error_size); (void) tracking; (void) object; @@ -2824,6 +2834,9 @@ MovieReconstructContext *BKE_tracking_reconstruction_context_new(MovieTracking * context->k2 = camera->k2; context->k3 = camera->k3; + context->success_threshold = tracking->settings.reconstruction_success_threshold; + context->use_fallback_reconstruction = tracking->settings.reconstruction_flag & TRACKING_USE_FALLBACK_RECONSTRUCTION; + context->tracks_map = tracks_map_new(context->object_name, context->is_camera, num_tracks, 0); track = tracksbase->first; @@ -2845,10 +2858,10 @@ MovieReconstructContext *BKE_tracking_reconstruction_context_new(MovieTracking * } if (first < track->markersnr - 1) - sfra = MIN2(sfra, first_marker->framenr); + sfra = min_ii(sfra, first_marker->framenr); if (last >= 0) - efra = MAX2(efra, last_marker->framenr); + efra = max_ii(efra, last_marker->framenr); tracks_map_insert(context->tracks_map, track, NULL); @@ -2923,12 +2936,18 @@ void BKE_tracking_reconstruction_solve(MovieReconstructContext *context, short * reconstruct_update_solve_cb, &progressdata); } else { + struct libmv_reconstructionOptions options; + + options.success_threshold = context->success_threshold; + options.use_fallback_reconstruction = context->use_fallback_reconstruction; + context->reconstruction = libmv_solveReconstruction(context->tracks, context->keyframe1, context->keyframe2, context->refine_flags, context->focal_length, context->principal_point[0], context->principal_point[1], context->k1, context->k2, context->k3, + &options, reconstruct_update_solve_cb, &progressdata); } @@ -2950,6 +2969,7 @@ int BKE_tracking_reconstruction_finish(MovieReconstructContext *context, MovieTr MovieTrackingReconstruction *reconstruction; tracks_map_merge(context->tracks_map, tracking); + BKE_tracking_dopesheet_tag_update(tracking); if (context->is_camera) { reconstruction = &tracking->reconstruction; @@ -3195,8 +3215,8 @@ static float stabilization_calculate_autoscale_factor(MovieTracking *tracking, i if (track->flag & TRACK_USE_2D_STAB || ((stab->flag & TRACKING_STABILIZE_ROTATION) && track == stab->rot_track)) { - sfra = MIN2(sfra, track->markers[0].framenr); - efra = MAX2(efra, track->markers[track->markersnr - 1].framenr); + sfra = min_ii(sfra, track->markers[0].framenr); + efra = max_ii(efra, track->markers[track->markersnr - 1].framenr); } track = track->next; @@ -3272,7 +3292,7 @@ static float stabilization_calculate_autoscale_factor(MovieTracking *tracking, i S = (-w * I - h * J) / (dx * I + dy * J + K); - scale = maxf(scale, S); + scale = max_ff(scale, S); } } } @@ -3281,7 +3301,7 @@ static float stabilization_calculate_autoscale_factor(MovieTracking *tracking, i stab->scale = scale; if (stab->maxscale > 0.0f) - stab->scale = minf(stab->scale, stab->maxscale); + stab->scale = min_ff(stab->scale, stab->maxscale); } else { stab->scale = 1.0f; @@ -3640,7 +3660,7 @@ static void channels_segments_calc(MovieTrackingDopesheetChannel *channel) channel->segments[2 * segment] = start_marker->framenr; channel->segments[2 * segment + 1] = start_marker->framenr + len; - channel->max_segment = MAX2(channel->max_segment, len); + channel->max_segment = max_ii(channel->max_segment, len); segment++; } @@ -3648,7 +3668,7 @@ static void channels_segments_calc(MovieTrackingDopesheetChannel *channel) } } -static void tracking_dopesheet_sort(MovieTracking *tracking, int sort_method, int inverse) +static void tracking_dopesheet_sort(MovieTracking *tracking, int sort_method, int inverse) { MovieTrackingDopesheet *dopesheet = &tracking->dopesheet; diff --git a/source/blender/blenkernel/intern/unit.c b/source/blender/blenkernel/intern/unit.c index da5e7ff3db7..84e1f29f6c0 100644 --- a/source/blender/blenkernel/intern/unit.c +++ b/source/blender/blenkernel/intern/unit.c @@ -259,7 +259,7 @@ static struct bUnitCollection buNaturalTimeCollecton = {buNaturalTimeDef, 3, 0, static struct bUnitDef buNaturalRotDef[] = { - {"degree", "degrees", "°", NULL, "Degrees", M_PI/180.0, 0.0, B_UNIT_DEF_NONE}, + {"degree", "degrees", "°", NULL, "Degrees", M_PI / 180.0, 0.0, B_UNIT_DEF_NONE}, // {"radian", "radians", "r", NULL, "Radians", 1.0, 0.0, B_UNIT_DEF_NONE}, // {"turn", "turns", "t", NULL, "Turns", 1.0/(M_PI*2.0), 0.0,B_UNIT_DEF_NONE}, {NULL, NULL, NULL, NULL, NULL, 0.0, 0.0} @@ -350,7 +350,7 @@ static int unit_as_string(char *str, int len_max, double value, int prec, bUnitC /* Add unit prefix and strip zeros */ /* replace trailing zero's with spaces - * so the number is less complicated but allignment in a button wont + * so the number is less complicated but alignment in a button wont * jump about while dragging */ i = len - 1; diff --git a/source/blender/blenkernel/intern/world.c b/source/blender/blenkernel/intern/world.c index 434bfe19c1f..4bde895cf7d 100644 --- a/source/blender/blenkernel/intern/world.c +++ b/source/blender/blenkernel/intern/world.c @@ -107,7 +107,7 @@ World *add_world(const char *name) wrld->ao_indirect_energy = 1.0f; wrld->ao_indirect_bounces = 1; wrld->aobias = 0.05f; - wrld->ao_samp_method = WO_AOSAMP_HAMMERSLEY; + wrld->ao_samp_method = WO_AOSAMP_HAMMERSLEY; wrld->ao_approx_error = 0.25f; wrld->preview = NULL; diff --git a/source/blender/blenkernel/intern/writeavi.c b/source/blender/blenkernel/intern/writeavi.c index dab44b5463c..d4428be3faf 100644 --- a/source/blender/blenkernel/intern/writeavi.c +++ b/source/blender/blenkernel/intern/writeavi.c @@ -47,7 +47,11 @@ #include "BKE_report.h" #include "BKE_writeavi.h" -#include "AVI_avi.h" + +/* ********************** general blender movie support ***************************** */ + +#ifdef WITH_AVI +# include "AVI_avi.h" /* callbacks */ static int start_avi(Scene *scene, RenderData *rd, int rectx, int recty, ReportList *reports); @@ -55,30 +59,31 @@ static void end_avi(void); static int append_avi(RenderData *rd, int start_frame, int frame, int *pixels, int rectx, int recty, ReportList *reports); static void filepath_avi(char *string, RenderData *rd); - -/* ********************** general blender movie support ***************************** */ +#endif /* WITH_AVI */ #ifdef WITH_QUICKTIME -#include "quicktime_export.h" +# include "quicktime_export.h" #endif #ifdef WITH_FFMPEG -#include "BKE_writeffmpeg.h" +# include "BKE_writeffmpeg.h" #endif #include "BKE_writeframeserver.h" bMovieHandle *BKE_movie_handle_get(const char imtype) { - static bMovieHandle mh; + static bMovieHandle mh = {0}; /* set the default handle, as builtin */ +#ifdef WITH_AVI mh.start_movie = start_avi; mh.append_movie = append_avi; mh.end_movie = end_avi; mh.get_next_frame = NULL; mh.get_movie_path = filepath_avi; - +#endif + /* do the platform specific handles */ #ifdef WITH_QUICKTIME if (imtype == R_IMF_IMTYPE_QUICKTIME) { @@ -114,6 +119,8 @@ bMovieHandle *BKE_movie_handle_get(const char imtype) /* ****************************************************************** */ +#ifdef WITH_AVI + static AviMovie *avi = NULL; static void filepath_avi(char *string, RenderData *rd) @@ -155,7 +162,7 @@ static int start_avi(Scene *scene, RenderData *rd, int rectx, int recty, ReportL else format = AVI_FORMAT_MJPEG; if (AVI_open_compress(name, avi, 1, format) != AVI_ERROR_NONE) { - BKE_report(reports, RPT_ERROR, "Cannot open or start AVI movie file."); + BKE_report(reports, RPT_ERROR, "Cannot open or start AVI movie file"); MEM_freeN(avi); avi = NULL; return 0; @@ -168,8 +175,8 @@ static int start_avi(Scene *scene, RenderData *rd, int rectx, int recty, ReportL avi->interlace = 0; avi->odd_fields = 0; -/* avi->interlace= rd->mode & R_FIELDS; */ -/* avi->odd_fields= (rd->mode & R_ODDFIELD)?1:0; */ +/* avi->interlace = rd->mode & R_FIELDS; */ +/* avi->odd_fields = (rd->mode & R_ODDFIELD) ? 1 : 0; */ printf("Created avi: %s\n", name); return 1; @@ -219,6 +226,7 @@ static void end_avi(void) MEM_freeN(avi); avi = NULL; } +#endif /* WITH_AVI */ /* similar to BKE_makepicstring() */ void BKE_movie_filepath_get(char *string, RenderData *rd) diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c index 4019eba5177..3a8a14290dc 100644 --- a/source/blender/blenkernel/intern/writeffmpeg.c +++ b/source/blender/blenkernel/intern/writeffmpeg.c @@ -289,7 +289,7 @@ static int write_video_frame(RenderData *rd, int cfra, AVFrame *frame, ReportLis } if (!success) - BKE_report(reports, RPT_ERROR, "Error writing frame."); + BKE_report(reports, RPT_ERROR, "Error writing frame"); return success; } @@ -307,7 +307,7 @@ static AVFrame *generate_video_frame(uint8_t *pixels, ReportList *reports) if (c->pix_fmt != PIX_FMT_BGR32) { rgb_frame = alloc_picture(PIX_FMT_BGR32, width, height); if (!rgb_frame) { - BKE_report(reports, RPT_ERROR, "Couldn't allocate temporary frame."); + BKE_report(reports, RPT_ERROR, "Could not allocate temporary frame"); return NULL; } } @@ -695,12 +695,12 @@ static int start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty, Report exts = get_file_extensions(ffmpeg_type); if (!exts) { - BKE_report(reports, RPT_ERROR, "No valid formats found."); + BKE_report(reports, RPT_ERROR, "No valid formats found"); return 0; } fmt = av_guess_format(NULL, exts[0], NULL); if (!fmt) { - BKE_report(reports, RPT_ERROR, "No valid formats found."); + BKE_report(reports, RPT_ERROR, "No valid formats found"); return 0; } @@ -795,7 +795,7 @@ static int start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty, Report if (error[0]) BKE_report(reports, RPT_ERROR, error); else - BKE_report(reports, RPT_ERROR, "Error initializing video stream."); + BKE_report(reports, RPT_ERROR, "Error initializing video stream"); av_dict_free(&opts); return 0; @@ -805,20 +805,20 @@ static int start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty, Report if (ffmpeg_audio_codec != CODEC_ID_NONE) { audio_stream = alloc_audio_stream(rd, fmt->audio_codec, of); if (!audio_stream) { - BKE_report(reports, RPT_ERROR, "Error initializing audio stream."); + BKE_report(reports, RPT_ERROR, "Error initializing audio stream"); av_dict_free(&opts); return 0; } } if (!(fmt->flags & AVFMT_NOFILE)) { if (avio_open(&of->pb, name, AVIO_FLAG_WRITE) < 0) { - BKE_report(reports, RPT_ERROR, "Could not open file for writing."); + BKE_report(reports, RPT_ERROR, "Could not open file for writing"); av_dict_free(&opts); return 0; } } if (avformat_write_header(of, NULL) < 0) { - BKE_report(reports, RPT_ERROR, "Could not initialize streams. Probably unsupported codec combination."); + BKE_report(reports, RPT_ERROR, "Could not initialize streams, probably unsupported codec combination"); av_dict_free(&opts); return 0; } @@ -839,7 +839,7 @@ static int start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty, Report * inter-frames (H.264 B-frames, for example), it can output the frames * in a different order from the one it was given. * For example, when sending frames 1, 2, 3, 4 to the encoder, it may write - * them in the order 1, 4, 2, 3 - first the two frames used for predition, + * them in the order 1, 4, 2, 3 - first the two frames used for prediction, * and then the bidirectionally-predicted frames. What this means in practice * is that the encoder may not immediately produce one output frame for each * input frame. These delayed frames must be flushed before we close the @@ -914,8 +914,7 @@ void BKE_ffmpeg_filepath_get(char *string, RenderData *rd) } while (*fe) { - if (BLI_strcasecmp(string + strlen(string) - strlen(*fe), *fe) == 0) - { + if (BLI_strcasecmp(string + strlen(string) - strlen(*fe), *fe) == 0) { break; } fe++; @@ -983,7 +982,7 @@ int BKE_ffmpeg_append(RenderData *rd, int start_frame, int frame, int *pixels, i PRINT("Writing frame %i, render width=%d, render height=%d\n", frame, rectx, recty); -// why is this done before writing the video frame and again at end_ffmpeg? +/* why is this done before writing the video frame and again at end_ffmpeg? */ // write_audio_frames(frame / (((double)rd->frs_sec) / rd->frs_sec_base)); if (video_stream) { @@ -1226,7 +1225,7 @@ int BKE_ffmpeg_property_add_string(RenderData *rd, const char *type, const char while (*param == ' ') param++; } - o = my_av_find_opt(&c, name, NULL, 0, 0); + o = my_av_find_opt(&c, name, NULL, 0, 0); if (!o) { return 0; } @@ -1234,7 +1233,7 @@ int BKE_ffmpeg_property_add_string(RenderData *rd, const char *type, const char return 0; } if (param && o->type != FF_OPT_TYPE_CONST && o->unit) { - p = my_av_find_opt(&c, param, o->unit, 0, 0); + p = my_av_find_opt(&c, param, o->unit, 0, 0); if (p) { prop = BKE_ffmpeg_property_add(rd, (char *) type, p - c.av_class->option, o - c.av_class->option); } diff --git a/source/blender/blenkernel/intern/writeframeserver.c b/source/blender/blenkernel/intern/writeframeserver.c index d8fddb9851a..acbbcb0b043 100644 --- a/source/blender/blenkernel/intern/writeframeserver.c +++ b/source/blender/blenkernel/intern/writeframeserver.c @@ -118,13 +118,13 @@ int BKE_frameserver_start(struct Scene *scene, RenderData *UNUSED(rd), int rectx (void)scene; /* unused */ if (!startup_socket_system()) { - BKE_report(reports, RPT_ERROR, "Can't startup socket system"); + BKE_report(reports, RPT_ERROR, "Cannot startup socket system"); return 0; } if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { shutdown_socket_system(); - BKE_report(reports, RPT_ERROR, "Can't open socket"); + BKE_report(reports, RPT_ERROR, "Cannot open socket"); return 0; } @@ -136,13 +136,13 @@ int BKE_frameserver_start(struct Scene *scene, RenderData *UNUSED(rd), int rectx if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) { shutdown_socket_system(); - BKE_report(reports, RPT_ERROR, "Can't bind to socket"); + BKE_report(reports, RPT_ERROR, "Cannot bind to socket"); return 0; } if (listen(sock, SOMAXCONN) < 0) { shutdown_socket_system(); - BKE_report(reports, RPT_ERROR, "Can't establish listen backlog"); + BKE_report(reports, RPT_ERROR, "Cannot establish listen backlog"); return 0; } connsock = -1; -- cgit v1.2.3 From da24aa8d109a08b40b5547aacf3586026de78af2 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 5 Nov 2012 19:57:59 +0000 Subject: Merging r51897 through r51922 from trunk into soc-2011-tomato --- source/blender/blenkernel/intern/sequencer.c | 38 ++++++++++++++++++++-------- source/blender/blenkernel/intern/text.c | 28 ++++++++++++-------- 2 files changed, 46 insertions(+), 20 deletions(-) (limited to 'source/blender/blenkernel/intern') diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index 80ea00fc703..af0cab98fe0 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -676,8 +676,8 @@ void BKE_sequence_reload_new_file(Scene *scene, Sequence *seq, int lock_range) if (seq->anim) IMB_free_anim(seq->anim); - /* OCIO_TODO: support configurable input space for strips */ - seq->anim = openanim(str, IB_rect | ((seq->flag & SEQ_FILTERY) ? IB_animdeinterlace : 0), seq->streamindex, NULL); + seq->anim = openanim(str, IB_rect | ((seq->flag & SEQ_FILTERY) ? IB_animdeinterlace : 0), + seq->streamindex, seq->strip->colorspace_settings.name); if (!seq->anim) { return; @@ -1174,8 +1174,8 @@ static void seq_open_anim_file(Sequence *seq) seq->strip->dir, seq->strip->stripdata->name); BLI_path_abs(name, G.main->name); - /* OCIO_TODO: support configurable input space for strips */ - seq->anim = openanim(name, IB_rect | ((seq->flag & SEQ_FILTERY) ? IB_animdeinterlace : 0), seq->streamindex, NULL); + seq->anim = openanim(name, IB_rect | ((seq->flag & SEQ_FILTERY) ? IB_animdeinterlace : 0), + seq->streamindex, seq->strip->colorspace_settings.name); if (seq->anim == NULL) { return; @@ -1301,7 +1301,6 @@ static ImBuf *seq_proxy_fetch(SeqRenderData context, Sequence *seq, int cfra) } if (BLI_exists(name)) { - /* OCIO_TODO: support configurable spaces for strips */ ImBuf *ibuf = IMB_loadiffname(name, IB_rect, NULL); if (ibuf) @@ -1346,7 +1345,6 @@ static void seq_proxy_build_frame(SeqRenderData context, Sequence *seq, int cfra BLI_make_existing_file(name); - /* OCIO_TODO: support per-strip color space settings */ ok = IMB_saveiff(ibuf, name, IB_rect | IB_zbuf | IB_zbuffloat); if (ok == 0) { perror(name); @@ -2529,8 +2527,7 @@ static ImBuf *do_render_strip_uncached(SeqRenderData context, Sequence *seq, flo BLI_path_abs(name, G.main->name); } - /* OCIO_TODO: support configurable space for image strips */ - if (s_elem && (ibuf = IMB_loadiffname(name, IB_rect, NULL))) { + if (s_elem && (ibuf = IMB_loadiffname(name, IB_rect, seq->strip->colorspace_settings.name))) { /* we don't need both (speed reasons)! */ if (ibuf->rect_float && ibuf->rect) imb_freerectImBuf(ibuf); @@ -3940,6 +3937,25 @@ Sequence *BKE_sequence_alloc(ListBase *lb, int cfra, int machine) return seq; } +void BKE_sequence_init_colorspace(Sequence *seq) +{ + if (seq->strip && seq->strip->stripdata) { + char name[FILE_MAX]; + ImBuf *ibuf; + + BLI_join_dirfile(name, sizeof(name), seq->strip->dir, seq->strip->stripdata->name); + BLI_path_abs(name, G.main->name); + + /* initialize input color space */ + if (seq->type == SEQ_TYPE_IMAGE) { + ibuf = IMB_loadiffname(name, IB_rect, seq->strip->colorspace_settings.name); + + if (ibuf) + IMB_freeImBuf(ibuf); + } + } +} + /* NOTE: this function doesn't fill in image names */ Sequence *BKE_sequencer_add_image_strip(bContext *C, ListBase *seqbasep, SeqLoadInfo *seq_load) { @@ -4046,14 +4062,14 @@ Sequence *BKE_sequencer_add_movie_strip(bContext *C, ListBase *seqbasep, SeqLoad Sequence *seq; /* generic strip vars */ Strip *strip; StripElem *se; + char colorspace[64] = "\0"; /* MAX_COLORSPACE_NAME */ struct anim *an; BLI_strncpy(path, seq_load->path, sizeof(path)); BLI_path_abs(path, G.main->name); - /* OCIO_TODO: support configurable input space for strips */ - an = openanim(path, IB_rect, 0, NULL); + an = openanim(path, IB_rect, 0, colorspace); if (an == NULL) return NULL; @@ -4072,6 +4088,8 @@ Sequence *BKE_sequencer_add_movie_strip(bContext *C, ListBase *seqbasep, SeqLoad seq->len = IMB_anim_get_duration(an, IMB_TC_RECORD_RUN); strip->us = 1; + BLI_strncpy(seq->strip->colorspace_settings.name, colorspace, sizeof(seq->strip->colorspace_settings.name)); + /* we only need 1 element for MOVIE strips */ strip->stripdata = se = MEM_callocN(sizeof(StripElem), "stripelem"); diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c index b3497b9932f..d230cf8f1fe 100644 --- a/source/blender/blenkernel/intern/text.c +++ b/source/blender/blenkernel/intern/text.c @@ -2862,7 +2862,7 @@ int txt_replace_char(Text *text, unsigned int add) void txt_indent(Text *text) { - int len, num; + int len, num, curc_old; char *tmp; const char *add = "\t"; @@ -2885,6 +2885,8 @@ void txt_indent(Text *text) indentlen = spaceslen; } + curc_old = text->curc; + num = 0; while (TRUE) { tmp = MEM_mallocN(text->curl->len + indentlen + 1, "textline_string"); @@ -2905,7 +2907,7 @@ void txt_indent(Text *text) txt_clean_text(text); if (text->curl == text->sell) { - text->selc = text->sell->len; + text->selc += indentlen; break; } else { @@ -2913,7 +2915,9 @@ void txt_indent(Text *text) num++; } } - text->curc = 0; + if (!curc_old) text->curc = 0; + else text->curc = curc_old + indentlen; + while (num > 0) { text->curl = text->curl->prev; num--; @@ -2928,7 +2932,8 @@ void txt_unindent(Text *text) { int num = 0; const char *remove = "\t"; - int indent = 1; + int indentlen = 1; + int unindented_first = FALSE; /* hardcoded: TXT_TABSIZE = 4 spaces: */ int spaceslen = TXT_TABSIZE; @@ -2940,25 +2945,26 @@ void txt_unindent(Text *text) /* insert spaces rather than tabs */ if (text->flags & TXT_TABSTOSPACES) { remove = tab_to_spaces; - indent = spaceslen; + indentlen = spaceslen; } while (TRUE) { int i = 0; - if (BLI_strncasecmp(text->curl->line, remove, indent) == 0) { + if (BLI_strncasecmp(text->curl->line, remove, indentlen) == 0) { + if (num == 0) unindented_first = TRUE; while (i < text->curl->len) { - text->curl->line[i] = text->curl->line[i + indent]; + text->curl->line[i] = text->curl->line[i + indentlen]; i++; } - text->curl->len -= indent; + text->curl->len -= indentlen; } txt_make_dirty(text); txt_clean_text(text); if (text->curl == text->sell) { - text->selc = text->sell->len; + if (i > 0) text->selc = MAX2(text->selc - indentlen, 0); break; } else { @@ -2967,7 +2973,9 @@ void txt_unindent(Text *text) } } - text->curc = 0; + + if (unindented_first) text->curc = MAX2(text->curc - indentlen, 0); + while (num > 0) { text->curl = text->curl->prev; num--; -- cgit v1.2.3 From b1afaa8312cf2dcb601f0e91cef66efd62f0682a Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 10 Dec 2012 15:18:00 +0000 Subject: Merging r51923 through r52851 from trunk into soc-2011-tomato --- source/blender/blenkernel/intern/DerivedMesh.c | 145 +-- source/blender/blenkernel/intern/action.c | 4 +- source/blender/blenkernel/intern/anim.c | 123 ++- source/blender/blenkernel/intern/anim_sys.c | 17 +- source/blender/blenkernel/intern/armature.c | 9 +- source/blender/blenkernel/intern/blender.c | 10 +- source/blender/blenkernel/intern/bmfont.c | 13 +- source/blender/blenkernel/intern/brush.c | 2 - source/blender/blenkernel/intern/camera.c | 1 + source/blender/blenkernel/intern/cdderivedmesh.c | 104 +- source/blender/blenkernel/intern/collision.c | 10 +- source/blender/blenkernel/intern/colortools.c | 39 +- source/blender/blenkernel/intern/constraint.c | 8 +- source/blender/blenkernel/intern/context.c | 10 + source/blender/blenkernel/intern/curve.c | 16 +- source/blender/blenkernel/intern/customdata.c | 4 +- source/blender/blenkernel/intern/depsgraph.c | 72 +- source/blender/blenkernel/intern/displist.c | 111 ++- source/blender/blenkernel/intern/dynamicpaint.c | 10 +- source/blender/blenkernel/intern/editderivedmesh.c | 2 +- source/blender/blenkernel/intern/idcode.c | 65 +- source/blender/blenkernel/intern/image.c | 305 +++--- source/blender/blenkernel/intern/lamp.c | 40 +- source/blender/blenkernel/intern/library.c | 5 +- source/blender/blenkernel/intern/mask.c | 12 +- source/blender/blenkernel/intern/mask_evaluate.c | 8 +- source/blender/blenkernel/intern/mask_rasterize.c | 2 +- source/blender/blenkernel/intern/mesh.c | 6 +- source/blender/blenkernel/intern/modifier.c | 4 +- source/blender/blenkernel/intern/modifiers_bmesh.c | 6 +- source/blender/blenkernel/intern/movieclip.c | 11 +- source/blender/blenkernel/intern/multires.c | 2 +- source/blender/blenkernel/intern/node.c | 32 +- source/blender/blenkernel/intern/object.c | 20 +- source/blender/blenkernel/intern/ocean.c | 20 +- source/blender/blenkernel/intern/particle.c | 32 +- source/blender/blenkernel/intern/particle_system.c | 25 +- source/blender/blenkernel/intern/pointcache.c | 9 +- source/blender/blenkernel/intern/scene.c | 33 +- source/blender/blenkernel/intern/seqeffects.c | 3 + source/blender/blenkernel/intern/seqmodifier.c | 12 +- source/blender/blenkernel/intern/sequencer.c | 44 +- source/blender/blenkernel/intern/shrinkwrap.c | 49 +- source/blender/blenkernel/intern/smoke.c | 33 +- source/blender/blenkernel/intern/sound.c | 20 +- source/blender/blenkernel/intern/subsurf_ccg.c | 3 +- source/blender/blenkernel/intern/suggestions.c | 10 +- source/blender/blenkernel/intern/text.c | 1012 ++++++-------------- source/blender/blenkernel/intern/tracking.c | 36 +- source/blender/blenkernel/intern/writeffmpeg.c | 41 +- 50 files changed, 1268 insertions(+), 1342 deletions(-) (limited to 'source/blender/blenkernel/intern') diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index fd92b7b5d69..d09bea0f662 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -392,7 +392,7 @@ void DM_ensure_tessface(DerivedMesh *dm) } else if (dm->dirty & DM_DIRTY_TESS_CDLAYERS) { - BLI_assert(CustomData_has_layer(&dm->faceData, CD_ORIGINDEX)); + BLI_assert(CustomData_has_layer(&dm->faceData, CD_ORIGINDEX) || numTessFaces == 0); DM_update_tessface_data(dm); } @@ -1159,119 +1159,64 @@ void DM_update_weight_mcol(Object *ob, DerivedMesh *dm, int const draw_flag, ColorBand *coba = stored_cb; /* warning, not a local var */ unsigned char *wtcol_v; -#if 0 /* See coment below. */ - unsigned char *wtcol_f = dm->getTessFaceDataArray(dm, CD_PREVIEW_MCOL); -#endif unsigned char(*wtcol_l)[4] = CustomData_get_layer(dm->getLoopDataLayout(dm), CD_PREVIEW_MLOOPCOL); -#if 0 /* See coment below. */ - MFace *mf = dm->getTessFaceArray(dm); -#endif MLoop *mloop = dm->getLoopArray(dm), *ml; MPoly *mp = dm->getPolyArray(dm); -#if 0 - int numFaces = dm->getNumTessFaces(dm); -#endif int numVerts = dm->getNumVerts(dm); int totloop; int i, j; -#if 0 /* See comment below */ - /* If no CD_PREVIEW_MCOL existed yet, add a new one! */ - if (!wtcol_f) - wtcol_f = CustomData_add_layer(&dm->faceData, CD_PREVIEW_MCOL, CD_CALLOC, NULL, numFaces); - - if (wtcol_f) { - unsigned char *wtcol_f_step = wtcol_f; -# else -#if 0 - /* XXX We have to create a CD_PREVIEW_MCOL, else it might sigsev (after a SubSurf mod, eg)... */ - if (!dm->getTessFaceDataArray(dm, CD_PREVIEW_MCOL)) - CustomData_add_layer(&dm->faceData, CD_PREVIEW_MCOL, CD_CALLOC, NULL, numFaces); -#endif - - { -#endif - - /* Weights are given by caller. */ - if (weights) { - float *w = weights; - /* If indices is not NULL, it means we do not have weights for all vertices, - * so we must create them (and set them to zero)... */ - if (indices) { - w = MEM_callocN(sizeof(float) * numVerts, "Temp weight array DM_update_weight_mcol"); - i = num; - while (i--) - w[indices[i]] = weights[i]; - } - - /* Convert float weights to colors. */ - wtcol_v = calc_colors_from_weights_array(numVerts, w); - - if (indices) - MEM_freeN(w); + /* Weights are given by caller. */ + if (weights) { + float *w = weights; + /* If indices is not NULL, it means we do not have weights for all vertices, + * so we must create them (and set them to zero)... */ + if (indices) { + w = MEM_callocN(sizeof(float) * numVerts, "Temp weight array DM_update_weight_mcol"); + i = num; + while (i--) + w[indices[i]] = weights[i]; } - /* No weights given, take them from active vgroup(s). */ - else - wtcol_v = calc_weightpaint_vert_array(ob, dm, draw_flag, coba); - - /* Now copy colors in all face verts. */ - /* first add colors to the tessellation faces */ - /* XXX Why update that layer? We have to update WEIGHT_MLOOPCOL anyway, - * and tessellation recreates mface layers from mloop/mpoly ones, so no - * need to fill WEIGHT_MCOL here. */ -#if 0 - for (i = 0; i < numFaces; i++, mf++, wtcol_f_step += (4 * 4)) { - /*origindex being NULL means we're operating on original mesh data*/ -#if 0 - unsigned int fidx = mf->v4 ? 3 : 2; + /* Convert float weights to colors. */ + wtcol_v = calc_colors_from_weights_array(numVerts, w); -#else /* better zero out triangles 4th component. else valgrind complains when the buffer's copied */ - unsigned int fidx; - if (mf->v4) { - fidx = 3; - } - else { - fidx = 2; - *(int *)(&wtcol_f_step[3 * 4]) = 0; - } -#endif + if (indices) + MEM_freeN(w); + } - do { - copy_v4_v4_char((char *)&wtcol_f_step[fidx * 4], - (char *)&wtcol_v[4 * (*(&mf->v1 + fidx))]); - } while (fidx--); - } -#endif - /*now add to loops, so the data can be passed through the modifier stack*/ - /* If no CD_PREVIEW_MLOOPCOL existed yet, we have to add a new one! */ - if (!wtcol_l) { - BLI_array_declare(wtcol_l); - totloop = 0; - for (i = 0; i < dm->numPolyData; i++, mp++) { - ml = mloop + mp->loopstart; - - BLI_array_grow_items(wtcol_l, mp->totloop); - for (j = 0; j < mp->totloop; j++, ml++, totloop++) { - copy_v4_v4_char((char *)&wtcol_l[totloop], - (char *)&wtcol_v[4 * ml->v]); - } + /* No weights given, take them from active vgroup(s). */ + else + wtcol_v = calc_weightpaint_vert_array(ob, dm, draw_flag, coba); + + /* now add to loops, so the data can be passed through the modifier stack */ + /* If no CD_PREVIEW_MLOOPCOL existed yet, we have to add a new one! */ + if (!wtcol_l) { + BLI_array_declare(wtcol_l); + totloop = 0; + for (i = 0; i < dm->numPolyData; i++, mp++) { + ml = mloop + mp->loopstart; + + BLI_array_grow_items(wtcol_l, mp->totloop); + for (j = 0; j < mp->totloop; j++, ml++, totloop++) { + copy_v4_v4_char((char *)&wtcol_l[totloop], + (char *)&wtcol_v[4 * ml->v]); } - CustomData_add_layer(&dm->loopData, CD_PREVIEW_MLOOPCOL, CD_ASSIGN, wtcol_l, totloop); } - else { - totloop = 0; - for (i = 0; i < dm->numPolyData; i++, mp++) { - ml = mloop + mp->loopstart; + CustomData_add_layer(&dm->loopData, CD_PREVIEW_MLOOPCOL, CD_ASSIGN, wtcol_l, totloop); + } + else { + totloop = 0; + for (i = 0; i < dm->numPolyData; i++, mp++) { + ml = mloop + mp->loopstart; - for (j = 0; j < mp->totloop; j++, ml++, totloop++) { - copy_v4_v4_char((char *)&wtcol_l[totloop], - (char *)&wtcol_v[4 * ml->v]); - } + for (j = 0; j < mp->totloop; j++, ml++, totloop++) { + copy_v4_v4_char((char *)&wtcol_l[totloop], + (char *)&wtcol_v[4 * ml->v]); } } - MEM_freeN(wtcol_v); } + MEM_freeN(wtcol_v); dm->dirty |= DM_DIRTY_TESS_CDLAYERS; } @@ -1680,8 +1625,8 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos nextmask &= ~CD_MASK_ORCO; DM_set_only_copy(orcodm, nextmask | CD_MASK_ORIGINDEX | - (mti->requiredDataMask ? - mti->requiredDataMask(ob, md) : 0)); + (mti->requiredDataMask ? + mti->requiredDataMask(ob, md) : 0)); ndm = mti->applyModifier(md, ob, orcodm, app_flags & ~MOD_APPLY_USECACHE); if (ndm) { @@ -2167,6 +2112,8 @@ static void mesh_build_data(Scene *scene, Object *ob, CustomDataMask dataMask, /* weight paint and face select need original indices because of selection buffer drawing */ int needMapping = (ob == obact) && (editing || (ob->mode & (OB_MODE_WEIGHT_PAINT | OB_MODE_VERTEX_PAINT | OB_MODE_TEXTURE_PAINT))); + BLI_assert(ob->type == OB_MESH); + clear_mesh_caches(ob); mesh_calc_modifiers(scene, ob, NULL, &ob->derivedDeform, diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index e95451252d0..dd27cc70ba3 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -512,7 +512,7 @@ const char *BKE_pose_ikparam_get_name(bPose *pose) { if (pose) { switch (pose->iksolver) { - case IKSOLVER_LEGACY: + case IKSOLVER_STANDARD: return NULL; case IKSOLVER_ITASC: return "bItasc"; @@ -587,7 +587,7 @@ void BKE_pose_ikparam_init(bPose *pose) BKE_pose_itasc_init(itasc); pose->ikparam = itasc; break; - case IKSOLVER_LEGACY: + case IKSOLVER_STANDARD: default: pose->ikparam = NULL; break; diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index dffe26bd782..9a2462e9724 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -76,8 +76,8 @@ /* --------------------- */ /* forward declarations */ -static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBase *duplilist, float par_space_mat[][4], int par_index, - int level, short flag); +static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBase *duplilist, float par_space_mat[][4], + int persistent_id[MAX_DUPLI_RECUR], int level, int index, short flag); /* ******************************************************************** */ /* Animation Visualization */ @@ -706,31 +706,45 @@ int where_on_path(Object *ob, float ctime, float vec[4], float dir[3], float qua #define DUPLILIST_FOR_RENDER 2 #define DUPLILIST_ANIMATED 4 -static DupliObject *new_dupli_object(ListBase *lb, Object *ob, float mat[][4], int lay, int index, int par_index, int type, short flag) +static DupliObject *new_dupli_object(ListBase *lb, Object *ob, float mat[][4], int lay, + int persistent_id[MAX_DUPLI_RECUR], int level, int index, int type, short flag) { DupliObject *dob = MEM_callocN(sizeof(DupliObject), "dupliobject"); - + int i; + BLI_addtail(lb, dob); dob->ob = ob; copy_m4_m4(dob->mat, mat); copy_m4_m4(dob->omat, ob->obmat); dob->origlay = ob->lay; - dob->index = index; - dob->particle_index = par_index; dob->type = type; dob->animated = (type == OB_DUPLIGROUP) && (flag & DUPLILIST_ANIMATED); ob->lay = lay; + + /* set persistent id, which is an array with a persistent index for each level + * (particle number, vertex number, ..). by comparing this we can find the same + * dupli object between frames, which is needed for motion blur. last level + * goes first in the array. */ + dob->persistent_id[0] = index; + for (i = 1; i < level; i++) + dob->persistent_id[i] = persistent_id[level - 1 - i]; + + /* metaballs never draw in duplis, they are instead merged into one by the basis + * mball outside of the group. this does mean that if that mball is not in the + * scene, they will not show up at all, limitation that should be solved once. */ + if (ob->type == OB_MBALL) + dob->no_draw = TRUE; return dob; } -static void group_duplilist(ListBase *lb, Scene *scene, Object *ob, int par_index, +static void group_duplilist(ListBase *lb, Scene *scene, Object *ob, int persistent_id[MAX_DUPLI_RECUR], int level, short flag) { DupliObject *dob; Group *group; GroupObject *go; - float mat[4][4], tmat[4][4]; + float mat[4][4], tmat[4][4], id; if (ob->dup_group == NULL) return; group = ob->dup_group; @@ -750,7 +764,7 @@ static void group_duplilist(ListBase *lb, Scene *scene, Object *ob, int par_inde if (group_is_animated(ob, group)) flag |= DUPLILIST_ANIMATED; - for (go = group->gobject.first; go; go = go->next) { + for (go = group->gobject.first, id = 0; go; go = go->next, id++) { /* note, if you check on layer here, render goes wrong... it still deforms verts and uses parent imat */ if (go->ob != ob) { @@ -764,7 +778,7 @@ static void group_duplilist(ListBase *lb, Scene *scene, Object *ob, int par_inde mult_m4_m4m4(mat, ob->obmat, go->ob->obmat); } - dob = new_dupli_object(lb, go->ob, mat, ob->lay, 0, par_index, OB_DUPLIGROUP, flag); + dob = new_dupli_object(lb, go->ob, mat, ob->lay, persistent_id, level, id, OB_DUPLIGROUP, flag); /* check the group instance and object layers match, also that the object visible flags are ok. */ if ((dob->origlay & group->layer) == 0 || @@ -773,20 +787,17 @@ static void group_duplilist(ListBase *lb, Scene *scene, Object *ob, int par_inde { dob->no_draw = TRUE; } - else { - dob->no_draw = FALSE; - } if (go->ob->transflag & OB_DUPLI) { copy_m4_m4(dob->ob->obmat, dob->mat); - object_duplilist_recursive(&group->id, scene, go->ob, lb, ob->obmat, par_index, level + 1, flag); + object_duplilist_recursive(&group->id, scene, go->ob, lb, ob->obmat, persistent_id, level + 1, id, flag); copy_m4_m4(dob->ob->obmat, dob->omat); } } } } -static void frames_duplilist(ListBase *lb, Scene *scene, Object *ob, int par_index, int level, short flag) +static void frames_duplilist(ListBase *lb, Scene *scene, Object *ob, int persistent_id[MAX_DUPLI_RECUR], int level, short flag) { extern int enable_cu_speed; /* object.c */ Object copyob; @@ -834,7 +845,7 @@ static void frames_duplilist(ListBase *lb, Scene *scene, Object *ob, int par_ind BKE_animsys_evaluate_animdata(scene, &ob->id, ob->adt, (float)scene->r.cfra, ADT_RECALC_ANIM); /* ob-eval will do drivers, so we don't need to do them */ BKE_object_where_is_calc_time(scene, ob, (float)scene->r.cfra); - dob = new_dupli_object(lb, ob, ob->obmat, ob->lay, scene->r.cfra, par_index, OB_DUPLIFRAMES, flag); + dob = new_dupli_object(lb, ob, ob->obmat, ob->lay, persistent_id, level, scene->r.cfra, OB_DUPLIFRAMES, flag); copy_m4_m4(dob->omat, copyob.obmat); } } @@ -865,7 +876,7 @@ typedef struct VertexDupliData { Scene *scene; Object *ob, *par; float (*orco)[3]; - int par_index; + int *persistent_id; } VertexDupliData; /* ------------- */ @@ -902,7 +913,7 @@ static void vertex_dupli__mapFunc(void *userData, int index, const float co[3], origlay = vdd->ob->lay; - dob = new_dupli_object(vdd->lb, vdd->ob, obmat, vdd->par->lay, index, vdd->par_index, OB_DUPLIVERTS, vdd->flag); + dob = new_dupli_object(vdd->lb, vdd->ob, obmat, vdd->par->lay, vdd->persistent_id, vdd->level, index, OB_DUPLIVERTS, vdd->flag); /* restore the original layer so that each dupli will have proper dob->origlay */ vdd->ob->lay = origlay; @@ -914,12 +925,12 @@ static void vertex_dupli__mapFunc(void *userData, int index, const float co[3], float tmpmat[4][4]; copy_m4_m4(tmpmat, vdd->ob->obmat); copy_m4_m4(vdd->ob->obmat, obmat); /* pretend we are really this mat */ - object_duplilist_recursive((ID *)vdd->id, vdd->scene, vdd->ob, vdd->lb, obmat, vdd->par_index, vdd->level + 1, vdd->flag); + object_duplilist_recursive((ID *)vdd->id, vdd->scene, vdd->ob, vdd->lb, obmat, vdd->persistent_id, vdd->level + 1, index, vdd->flag); copy_m4_m4(vdd->ob->obmat, tmpmat); } } -static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[][4], int par_index, +static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[][4], int persistent_id[MAX_DUPLI_RECUR], int level, short flag) { Object *ob, *ob_iter; @@ -1004,7 +1015,7 @@ static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, fl vdd.scene = scene; vdd.par = par; copy_m4_m4(vdd.pmat, pmat); - vdd.par_index = par_index; + vdd.persistent_id = persistent_id; /* mballs have a different dupli handling */ if (ob->type != OB_MBALL) ob->flag |= OB_DONE; /* doesnt render */ @@ -1043,7 +1054,7 @@ static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, fl dm->release(dm); } -static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[][4], int par_index, +static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[][4], int persistent_id[MAX_DUPLI_RECUR], int level, short flag) { Object *ob, *ob_iter; @@ -1186,7 +1197,7 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa copy_m4_m4(tmat, obmat); mul_m4_m4m3(obmat, tmat, mat); - dob = new_dupli_object(lb, ob, obmat, par->lay, a, par_index, OB_DUPLIFACES, (flag & DUPLILIST_ANIMATED)); + dob = new_dupli_object(lb, ob, obmat, par->lay, persistent_id, level, a, OB_DUPLIFACES, (flag & DUPLILIST_ANIMATED)); if (flag & DUPLILIST_FOR_RENDER) { w = 1.0f / (float)mp->totloop; @@ -1209,7 +1220,7 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa float tmpmat[4][4]; copy_m4_m4(tmpmat, ob->obmat); copy_m4_m4(ob->obmat, obmat); /* pretend we are really this mat */ - object_duplilist_recursive((ID *)id, scene, ob, lb, ob->obmat, par_index, level + 1, flag); + object_duplilist_recursive((ID *)id, scene, ob, lb, ob->obmat, persistent_id, level + 1, a, flag); copy_m4_m4(ob->obmat, tmpmat); } } @@ -1229,7 +1240,7 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa dm->release(dm); } -static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[][4], int UNUSED(par_index), ParticleSystem *psys, +static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[][4], int persistent_id[MAX_DUPLI_RECUR], ParticleSystem *psys, int level, short flag) { GroupObject *go; @@ -1244,8 +1255,9 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p float ctime, pa_time, scale = 1.0f; float tmat[4][4], mat[4][4], pamat[4][4], vec[3], size = 0.0; float (*obmat)[4], (*oldobmat)[4]; - int a, b, counter, index, hair = 0; + int a, b, hair = 0; int totpart, totchild, totgroup = 0 /*, pa_num */; + int dupli_type_hack = !BKE_scene_use_new_shading_nodes(scene); int no_draw_flag = PARS_UNEXIST; @@ -1360,8 +1372,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p else a = totpart; - index = 0; - for (pa = psys->particles, counter = 0; a < totpart + totchild; a++, pa++, counter++) { + for (pa = psys->particles; a < totpart + totchild; a++, pa++) { if (a < totpart) { /* handle parent particle */ if (pa->flag & no_draw_flag) @@ -1456,13 +1467,21 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p else copy_m4_m4(mat, tmat); - dob = new_dupli_object(lb, go->ob, mat, par->lay, counter, index, OB_DUPLIPARTS, (flag & DUPLILIST_ANIMATED)); + dob = new_dupli_object(lb, go->ob, mat, par->lay, persistent_id, level, a, OB_DUPLIPARTS, (flag & DUPLILIST_ANIMATED)); + dob->particle_system = psys; copy_m4_m4(dob->omat, obcopylist[b].obmat); if (flag & DUPLILIST_FOR_RENDER) psys_get_dupli_texture(psys, part, sim.psmd, pa, cpa, dob->uv, dob->orco); } } else { + int dupli_type = OB_DUPLIPARTS; + + /* blender internal needs this to be set to dupligroup to render + * groups correctly, but we don't want this hack for cycles */ + if(dupli_type_hack && GS(id->name) == ID_GR) + dupli_type = OB_DUPLIGROUP; + /* to give ipos in object correct offset */ BKE_object_where_is_calc_time(scene, ob, ctime - pa_time); @@ -1516,14 +1535,12 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p if (part->draw & PART_DRAW_GLOBAL_OB) add_v3_v3v3(mat[3], mat[3], vec); - dob = new_dupli_object(lb, ob, mat, ob->lay, counter, index, GS(id->name) == ID_GR ? OB_DUPLIGROUP : OB_DUPLIPARTS, (flag & DUPLILIST_ANIMATED)); + dob = new_dupli_object(lb, ob, mat, ob->lay, persistent_id, level, a, dupli_type, (flag & DUPLILIST_ANIMATED)); + dob->particle_system = psys; copy_m4_m4(dob->omat, oldobmat); if (flag & DUPLILIST_FOR_RENDER) psys_get_dupli_texture(psys, part, sim.psmd, pa, cpa, dob->uv, dob->orco); } - - /* only counts visible particles */ - index++; } /* restore objects since they were changed in BKE_object_where_is_calc_time */ @@ -1570,7 +1587,7 @@ static Object *find_family_object(Object **obar, char *family, char ch) } -static void font_duplilist(ListBase *lb, Scene *scene, Object *par, int par_index, int level, short flag) +static void font_duplilist(ListBase *lb, Scene *scene, Object *par, int persistent_id[MAX_DUPLI_RECUR], int level, short flag) { Object *ob, *obar[256] = {NULL}; Curve *cu; @@ -1609,7 +1626,7 @@ static void font_duplilist(ListBase *lb, Scene *scene, Object *par, int par_inde copy_m4_m4(obmat, par->obmat); copy_v3_v3(obmat[3], vec); - new_dupli_object(lb, ob, obmat, par->lay, a, par_index, OB_DUPLIVERTS, flag); + new_dupli_object(lb, ob, obmat, par->lay, persistent_id, level, a, OB_DUPLIVERTS, flag); } } @@ -1618,8 +1635,8 @@ static void font_duplilist(ListBase *lb, Scene *scene, Object *par, int par_inde /* ------------- */ -static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBase *duplilist, float par_space_mat[][4], int par_index, - int level, short flag) +static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBase *duplilist, float par_space_mat[][4], + int persistent_id[MAX_DUPLI_RECUR], int level, int index, short flag) { if ((ob->transflag & OB_DUPLI) == 0) return; @@ -1636,34 +1653,45 @@ static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBas } } + /* keep track of persistent id */ + if (level > 0) + persistent_id[level - 1] = index; + if (ob->transflag & OB_DUPLIPARTS) { ParticleSystem *psys = ob->particlesystem.first; - for (; psys; psys = psys->next) - new_particle_duplilist(duplilist, id, scene, ob, par_space_mat, par_index, psys, level + 1, flag); + int psysid = 0; + + /* particle system take up one level in id, the particles another */ + for (; psys; psys = psys->next, psysid++) { + persistent_id[level] = psysid; + new_particle_duplilist(duplilist, id, scene, ob, par_space_mat, persistent_id, psys, level + 2, flag); + } + + persistent_id[level] = 0; } else if (ob->transflag & OB_DUPLIVERTS) { if (ob->type == OB_MESH) { - vertex_duplilist(duplilist, id, scene, ob, par_space_mat, par_index, level + 1, flag); + vertex_duplilist(duplilist, id, scene, ob, par_space_mat, persistent_id, level + 1, flag); } else if (ob->type == OB_FONT) { if (GS(id->name) == ID_SCE) { /* TODO - support dupligroups */ - font_duplilist(duplilist, scene, ob, par_index, level + 1, flag); + font_duplilist(duplilist, scene, ob, persistent_id, level + 1, flag); } } } else if (ob->transflag & OB_DUPLIFACES) { if (ob->type == OB_MESH) - face_duplilist(duplilist, id, scene, ob, par_space_mat, par_index, level + 1, flag); + face_duplilist(duplilist, id, scene, ob, par_space_mat, persistent_id, level + 1, flag); } else if (ob->transflag & OB_DUPLIFRAMES) { if (GS(id->name) == ID_SCE) { /* TODO - support dupligroups */ - frames_duplilist(duplilist, scene, ob, par_index, level + 1, flag); + frames_duplilist(duplilist, scene, ob, persistent_id, level + 1, flag); } } else if (ob->transflag & OB_DUPLIGROUP) { DupliObject *dob; - group_duplilist(duplilist, scene, ob, par_index, level + 1, flag); /* now recursive */ + group_duplilist(duplilist, scene, ob, persistent_id, level + 1, flag); /* now recursive */ if (level == 0) { for (dob = duplilist->first; dob; dob = dob->next) @@ -1671,6 +1699,10 @@ static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBas copy_m4_m4(dob->ob->obmat, dob->mat); } } + + /* clear persistent id */ + if (level > 0) + persistent_id[level - 1] = 0; } /* Returns a list of DupliObject @@ -1678,13 +1710,14 @@ static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBas ListBase *object_duplilist_ex(Scene *sce, Object *ob, int update, int for_render) { ListBase *duplilist = MEM_mallocN(sizeof(ListBase), "duplilist"); + int persistent_id[MAX_DUPLI_RECUR] = {0}; int flag = 0; if (update) flag |= DUPLILIST_DO_UPDATE; if (for_render) flag |= DUPLILIST_FOR_RENDER; duplilist->first = duplilist->last = NULL; - object_duplilist_recursive((ID *)sce, sce, ob, duplilist, NULL, 0, 0, flag); + object_duplilist_recursive((ID *)sce, sce, ob, duplilist, NULL, persistent_id, 0, 0, flag); return duplilist; } diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c index 66ed31c5b72..40b883e3f4e 100644 --- a/source/blender/blenkernel/intern/anim_sys.c +++ b/source/blender/blenkernel/intern/anim_sys.c @@ -781,7 +781,7 @@ void BKE_animdata_main_cb(Main *mainptr, ID_AnimData_Edit_Callback func, void *u ANIMDATA_NODETREE_IDS_CB(mainptr->tex.first, Tex); /* lamps */ - ANIMDATA_IDS_CB(mainptr->lamp.first); + ANIMDATA_NODETREE_IDS_CB(mainptr->lamp.first, Lamp); /* materials */ ANIMDATA_NODETREE_IDS_CB(mainptr->mat.first, Material); @@ -823,7 +823,7 @@ void BKE_animdata_main_cb(Main *mainptr, ID_AnimData_Edit_Callback func, void *u ANIMDATA_IDS_CB(mainptr->mask.first); /* worlds */ - ANIMDATA_IDS_CB(mainptr->world.first); + ANIMDATA_NODETREE_IDS_CB(mainptr->world.first, World); /* scenes */ ANIMDATA_NODETREE_IDS_CB(mainptr->scene.first, Scene); @@ -868,7 +868,7 @@ void BKE_all_animdata_fix_paths_rename(ID *ref_id, const char *prefix, const cha RENAMEFIX_ANIM_NODETREE_IDS(mainptr->tex.first, Tex); /* lamps */ - RENAMEFIX_ANIM_IDS(mainptr->lamp.first); + RENAMEFIX_ANIM_NODETREE_IDS(mainptr->lamp.first, Lamp); /* materials */ RENAMEFIX_ANIM_NODETREE_IDS(mainptr->mat.first, Material); @@ -910,7 +910,7 @@ void BKE_all_animdata_fix_paths_rename(ID *ref_id, const char *prefix, const cha RENAMEFIX_ANIM_IDS(mainptr->mask.first); /* worlds */ - RENAMEFIX_ANIM_IDS(mainptr->world.first); + RENAMEFIX_ANIM_NODETREE_IDS(mainptr->world.first, World); /* scenes */ RENAMEFIX_ANIM_NODETREE_IDS(mainptr->scene.first, Scene); @@ -973,9 +973,8 @@ KeyingSet *BKE_keyingset_add(ListBase *list, const char idname[], const char nam /* allocate new KeyingSet */ ks = MEM_callocN(sizeof(KeyingSet), "KeyingSet"); - BLI_strncpy(ks->idname, idname ? idname : name ? name : "KeyingSet", sizeof(ks->idname)); - - BLI_strncpy(ks->name, name ? name : idname ? idname : "Keying Set", sizeof(ks->name)); + BLI_strncpy(ks->idname, (idname) ? idname : (name) ? name : "KeyingSet", sizeof(ks->idname)); + BLI_strncpy(ks->name, (name) ? name : (idname) ? idname : "Keying Set", sizeof(ks->name)); ks->flag = flag; ks->keyingflag = keyingflag; @@ -983,10 +982,10 @@ KeyingSet *BKE_keyingset_add(ListBase *list, const char idname[], const char nam /* add KeyingSet to list */ BLI_addtail(list, ks); - /* Make sure KeyingSet has a unique idname. */ + /* Make sure KeyingSet has a unique idname */ BLI_uniquename(list, ks, "KeyingSet", '.', offsetof(KeyingSet, idname), sizeof(ks->idname)); - /* Make sure KeyingSet has a unique label (this helps with identification). */ + /* Make sure KeyingSet has a unique label (this helps with identification) */ BLI_uniquename(list, ks, "Keying Set", '.', offsetof(KeyingSet, name), sizeof(ks->name)); /* return new KeyingSet for further editing */ diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index b3cbc1f2b16..1970df54339 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -1822,8 +1822,15 @@ static void splineik_init_tree_from_pchan(Scene *scene, Object *UNUSED(ob), bPos */ /* only happens on reload file, but violates depsgraph still... fix! */ - if ((cu->path == NULL) || (cu->path->data == NULL)) + if (ELEM(NULL, cu->path, cu->path->data)) { BKE_displist_make_curveTypes(scene, ikData->tar, 0); + + /* path building may fail in EditMode after removing verts [#33268]*/ + if (ELEM(NULL, cu->path, cu->path->data)) { + /* BLI_assert(cu->path != NULL); */ + return; + } + } } /* find the root bone and the chain of bones from the root to the tip diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index e1e868b234e..f0d201ea3f7 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -70,6 +70,7 @@ #include "BKE_displist.h" #include "BKE_global.h" #include "BKE_idprop.h" +#include "BKE_image.h" #include "BKE_ipo.h" #include "BKE_library.h" #include "BKE_main.h" @@ -113,6 +114,7 @@ void free_blender(void) BKE_spacetypes_free(); /* after free main, it uses space callbacks */ IMB_exit(); + BKE_images_exit(); BLI_callback_global_finalize(); @@ -266,7 +268,7 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath G.winpos = bfd->winpos; G.displaymode = bfd->displaymode; G.fileflags = bfd->fileflags; - CTX_wm_manager_set(C, bfd->main->wm.first); + CTX_wm_manager_set(C, G.main->wm.first); CTX_wm_screen_set(C, bfd->curscreen); CTX_data_scene_set(C, bfd->curscreen->scene); CTX_wm_area_set(C, NULL); @@ -276,7 +278,11 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath /* this can happen when active scene was lib-linked, and doesn't exist anymore */ if (CTX_data_scene(C) == NULL) { - CTX_data_scene_set(C, bfd->main->scene.first); + /* in case we don't even have a local scene, add one */ + if (!G.main->scene.first) + BKE_scene_add("Scene"); + + CTX_data_scene_set(C, G.main->scene.first); CTX_wm_screen(C)->scene = CTX_data_scene(C); curscene = CTX_data_scene(C); } diff --git a/source/blender/blenkernel/intern/bmfont.c b/source/blender/blenkernel/intern/bmfont.c index df7fb2c1807..0495e729937 100644 --- a/source/blender/blenkernel/intern/bmfont.c +++ b/source/blender/blenkernel/intern/bmfont.c @@ -247,12 +247,13 @@ int locateGlyph(bmFont *bmfont, unsigned short unicode) return(current); } -void matrixGlyph(ImBuf * ibuf, unsigned short unicode, - float *centerx, float *centery, - float *sizex, float *sizey, - float *transx, float *transy, - float *movex, float *movey, - float *advance) +void matrixGlyph( + ImBuf * ibuf, unsigned short unicode, + float *centerx, float *centery, + float *sizex, float *sizey, + float *transx, float *transy, + float *movex, float *movey, + float *advance) { int index; bmFont *bmfont; diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index 98b206712d6..f310895f590 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -1287,8 +1287,6 @@ unsigned int *BKE_brush_gen_texture_cache(Brush *br, int half_side) texcache = MEM_callocN(sizeof(int) * side * side, "Brush texture cache"); - BKE_image_get_ibuf(mtex->tex->ima, NULL); - /*do normalized cannonical view coords for texture*/ for (y = -1.0, iy = 0; iy < side; iy++, y += step) { for (x = -1.0, ix = 0; ix < side; ix++, x += step) { diff --git a/source/blender/blenkernel/intern/camera.c b/source/blender/blenkernel/intern/camera.c index 9118baeae6f..57c88919021 100644 --- a/source/blender/blenkernel/intern/camera.c +++ b/source/blender/blenkernel/intern/camera.c @@ -267,6 +267,7 @@ void BKE_camera_params_from_view3d(CameraParams *params, View3D *v3d, RegionView params->clipsta = -params->clipend; params->is_ortho = TRUE; + /* make sure any changes to this match ED_view3d_radius_to_ortho_dist() */ params->ortho_scale = rv3d->dist * sensor_size / v3d->lens; params->zoom = 2.0f; } diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index 2e0b3a3c64a..54bbe4bf495 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -623,8 +623,8 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm, /* double lookup */ const int *index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX); const int *index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX); - if ((index_mf_to_mpoly && index_mp_to_orig) == FALSE) { - index_mf_to_mpoly = index_mp_to_orig = NULL; + if (index_mf_to_mpoly == NULL) { + index_mp_to_orig = NULL; } colType = CD_TEXTURE_MCOL; @@ -653,12 +653,29 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm, else { if (index_mf_to_mpoly) { orig = DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, i); - if (orig == ORIGINDEX_NONE) { if (nors) nors += 3; continue; } - if (drawParamsMapped) { draw_option = drawParamsMapped(userData, orig); } - else { if (nors) nors += 3; continue; } + if (orig == ORIGINDEX_NONE) { + /* XXX, this is not really correct + * it will draw the previous faces context for this one when we don't know its settings. + * but better then skipping it altogether. - campbell */ + draw_option = DM_DRAW_OPTION_NORMAL; + } + else if (drawParamsMapped) { + draw_option = drawParamsMapped(userData, orig); + } + else { + if (nors) { + nors += 3; continue; + } + } + } + else if (drawParamsMapped) { + draw_option = drawParamsMapped(userData, i); + } + else { + if (nors) { + nors += 3; continue; + } } - else if (drawParamsMapped) { draw_option = drawParamsMapped(userData, i); } - else { if (nors) nors += 3; continue; } } if (draw_option != DM_DRAW_OPTION_SKIP) { @@ -742,9 +759,12 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm, if (index_mf_to_mpoly) { orig = DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, actualFace); if (orig == ORIGINDEX_NONE) { - continue; + /* XXX, this is not really correct + * it will draw the previous faces context for this one when we don't know its settings. + * but better then skipping it altogether. - campbell */ + draw_option = DM_DRAW_OPTION_NORMAL; } - if (drawParamsMapped) { + else if (drawParamsMapped) { draw_option = drawParamsMapped(userData, orig); } } @@ -812,8 +832,8 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm, /* double lookup */ const int *index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX); const int *index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX); - if ((index_mf_to_mpoly && index_mp_to_orig) == FALSE) { - index_mf_to_mpoly = index_mp_to_orig = NULL; + if (index_mf_to_mpoly == NULL) { + index_mp_to_orig = NULL; } @@ -828,8 +848,6 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm, mcol = DM_get_tessface_data_layer(dm, colType); } - printf("%s: %p(%d/%d)\n", __func__, mcol, CD_ID_MCOL, colType); - cdDM_update_normals_from_pbvh(dm); /* back-buffer always uses legacy since VBO's would need the @@ -1050,8 +1068,8 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, /* double lookup */ const int *index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX); const int *index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX); - if ((index_mf_to_mpoly && index_mp_to_orig) == FALSE) { - index_mf_to_mpoly = index_mp_to_orig = NULL; + if (index_mf_to_mpoly == NULL) { + index_mp_to_orig = NULL; } cdDM_update_normals_from_pbvh(dm); @@ -1351,8 +1369,8 @@ static void cdDM_drawMappedFacesMat(DerivedMesh *dm, /* double lookup */ const int *index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX); const int *index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX); - if ((index_mf_to_mpoly && index_mp_to_orig) == FALSE) { - index_mf_to_mpoly = index_mp_to_orig = NULL; + if (index_mf_to_mpoly == NULL) { + index_mp_to_orig = NULL; } cdDM_update_normals_from_pbvh(dm); @@ -1956,12 +1974,11 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, int use_mdisps, /* avoid this where possiblem, takes extra memory */ if (use_tessface) { - int *polyindex; BM_mesh_elem_index_ensure(bm, BM_FACE); index = dm->getTessFaceDataArray(dm, CD_ORIGINDEX); - for (i = 0; i < dm->numTessFaceData; i++, index++, polyindex++) { + for (i = 0; i < dm->numTessFaceData; i++, index++) { MFace *mf = &mface[i]; const BMLoop **l = em_looptris[i]; efa = l[0]->f; @@ -2257,6 +2274,11 @@ void CDDM_calc_normals_tessface(DerivedMesh *dm) * this is a really horribly written function. ger. - joeedh * * note, CDDM_recalc_tessellation has to run on the returned DM if you want to access tessfaces. + * + * Note: This function is currently only used by the Mirror modifier, so it + * skips any faces that have all vertices merged (to avoid creating pairs + * of faces sharing the same set of vertices). If used elsewhere, it may + * be necessary to make this functionality optional. */ DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, const int *vtargetmap) { @@ -2300,14 +2322,11 @@ DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, const int *vtargetmap) newv[i] = newv[vtargetmap[i]]; } } - - /* find-replace merged vertices with target vertices */ - ml = cddm->mloop; - for (i = 0; i < totloop; i++, ml++) { - if (vtargetmap[ml->v] != -1) { - ml->v = vtargetmap[ml->v]; - } - } + + /* Don't remap vertices in cddm->mloop, because we need to know the original + * indices in order to skip faces with all vertices merged. + * The "update loop indices..." section further down remaps vertices in mloop. + */ /* now go through and fix edges and faces */ med = cddm->medge; @@ -2341,6 +2360,24 @@ DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, const int *vtargetmap) ml = cddm->mloop + mp->loopstart; + /* skip faces with all vertices merged */ + { + int all_vertices_merged = TRUE; + + for (j = 0; j < mp->totloop; j++, ml++) { + if (vtargetmap[ml->v] == -1) { + all_vertices_merged = FALSE; + break; + } + } + + if (UNLIKELY(all_vertices_merged)) { + continue; + } + } + + ml = cddm->mloop + mp->loopstart; + c = 0; for (j = 0; j < mp->totloop; j++, ml++) { med = cddm->medge + ml->e; @@ -2499,7 +2536,7 @@ void CDDM_calc_edges(DerivedMesh *dm) EdgeHashIterator *ehi; MPoly *mp = cddm->mpoly; MLoop *ml; - MEdge *med; + MEdge *med, *origmed; EdgeHash *eh = BLI_edgehash_new(); int v1, v2; int *eindex; @@ -2532,6 +2569,7 @@ void CDDM_calc_edges(DerivedMesh *dm) CustomData_add_layer(&edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges); CustomData_add_layer(&edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges); + origmed = cddm->medge; med = CustomData_get_layer(&edgeData, CD_MEDGE); index = CustomData_get_layer(&edgeData, CD_ORIGINDEX); @@ -2542,8 +2580,14 @@ void CDDM_calc_edges(DerivedMesh *dm) BLI_edgehashIterator_getKey(ehi, &med->v1, &med->v2); j = GET_INT_FROM_POINTER(BLI_edgehashIterator_getValue(ehi)); - med->flag = ME_EDGEDRAW | ME_EDGERENDER; - *index = j == 0 ? ORIGINDEX_NONE : eindex[j - 1]; + if (j == 0) { + med->flag = ME_EDGEDRAW | ME_EDGERENDER; + *index = ORIGINDEX_NONE; + } + else { + med->flag = ME_EDGEDRAW | ME_EDGERENDER | origmed[j - 1].flag; + *index = eindex[j - 1]; + } BLI_edgehashIterator_setValue(ehi, SET_INT_IN_POINTER(i)); } diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index b488e683947..4641a02265a 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -198,8 +198,10 @@ static void collision_compute_barycentric ( float pv[3], float p1[3], float p2[3 w3[0] = 1.0f - w1[0] - w2[0]; } -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdouble-promotion" +#ifdef __GNUC__ +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wdouble-promotion" +#endif DO_INLINE void collision_interpolateOnTriangle ( float to[3], float v1[3], float v2[3], float v3[3], double w1, double w2, double w3 ) { @@ -371,7 +373,9 @@ static int cloth_collision_response_static ( ClothModifierData *clmd, CollisionM return result; } -#pragma GCC diagnostic pop +#ifdef __GNUC__ +# pragma GCC diagnostic pop +#endif //Determines collisions on overlap, collisions are written to collpair[i] and collision+number_collision_found is returned static CollPair* cloth_collision(ModifierData *md1, ModifierData *md2, diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c index 75276adf518..529fe07cab3 100644 --- a/source/blender/blenkernel/intern/colortools.c +++ b/source/blender/blenkernel/intern/colortools.c @@ -1008,8 +1008,8 @@ void scopes_update(Scopes *scopes, ImBuf *ibuf, const ColorManagedViewSettings * const ColorManagedDisplaySettings *display_settings) { int x, y, c; - unsigned int n, nl; - double div, divl; + unsigned int nl, na, nr, ng, nb; + double divl, diva, divr, divg, divb; float *rf = NULL; unsigned char *rc = NULL; unsigned int *bin_lum, *bin_r, *bin_g, *bin_b, *bin_a; @@ -1149,24 +1149,37 @@ void scopes_update(Scopes *scopes, ImBuf *ibuf, const ColorManagedViewSettings * savedlines += 1; } + /* test for nicer distribution even - non standard, leave it out for a while */ +#if 0 + for (x = 0; x < 256; x++) { + bin_lum[x] = sqrt (bin_lum[x]); + bin_r[x] = sqrt(bin_r[x]); + bin_g[x] = sqrt(bin_g[x]); + bin_b[x] = sqrt(bin_b[x]); + bin_a[x] = sqrt(bin_a[x]); + } +#endif + /* convert hist data to float (proportional to max count) */ - n = 0; - nl = 0; + nl = na = nr = nb = ng = 0; for (x = 0; x < 256; x++) { if (bin_lum[x] > nl) nl = bin_lum[x]; - if (bin_r[x] > n) n = bin_r[x]; - if (bin_g[x] > n) n = bin_g[x]; - if (bin_b[x] > n) n = bin_b[x]; - if (bin_a[x] > n) n = bin_a[x]; + if (bin_r[x] > nr) nr = bin_r[x]; + if (bin_g[x] > ng) ng = bin_g[x]; + if (bin_b[x] > nb) nb = bin_b[x]; + if (bin_a[x] > na) na = bin_a[x]; } - div = 1.0 / (double)n; divl = 1.0 / (double)nl; + diva = 1.0 / (double)na; + divr = 1.0 / (double)nr; + divg = 1.0 / (double)ng; + divb = 1.0 / (double)nb; for (x = 0; x < 256; x++) { scopes->hist.data_luma[x] = bin_lum[x] * divl; - scopes->hist.data_r[x] = bin_r[x] * div; - scopes->hist.data_g[x] = bin_g[x] * div; - scopes->hist.data_b[x] = bin_b[x] * div; - scopes->hist.data_a[x] = bin_a[x] * div; + scopes->hist.data_r[x] = bin_r[x] * divr; + scopes->hist.data_g[x] = bin_g[x] * divg; + scopes->hist.data_b[x] = bin_b[x] * divb; + scopes->hist.data_a[x] = bin_a[x] * diva; } MEM_freeN(bin_lum); MEM_freeN(bin_r); diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index e300b5e0f19..97d750854f4 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -84,15 +84,9 @@ #include "BKE_movieclip.h" #ifdef WITH_PYTHON -#include "BPY_extern.h" +# include "BPY_extern.h" #endif -#ifndef M_PI -#define M_PI 3.14159265358979323846 -#endif - - - /* ************************ Constraints - General Utilities *************************** */ /* These functions here don't act on any specific constraints, and are therefore should/will * not require any of the special function-pointers afforded by the relevant constraint diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c index 719ae7357b4..ffb93139358 100644 --- a/source/blender/blenkernel/intern/context.c +++ b/source/blender/blenkernel/intern/context.c @@ -44,6 +44,7 @@ #include "BLI_listbase.h" #include "BLI_string.h" +#include "BLI_threads.h" #include "BLI_utildefines.h" #include "BKE_context.h" @@ -245,6 +246,10 @@ static void *ctx_wm_python_context_get(const bContext *C, const char *member, vo (void)C, (void)member; #endif + /* don't allow UI context access from non-main threads */ + if (!BLI_thread_is_main()) + return NULL; + return fall_through; } @@ -264,6 +269,11 @@ static int ctx_data_get(bContext *C, const char *member, bContextDataResult *res // return 1; } #endif + + /* don't allow UI context access from non-main threads */ + if (!BLI_thread_is_main()) + return done; + /* we check recursion to ensure that we do not get infinite * loops requesting data from ourselfs in a context callback */ diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index 67aaaceaa38..754a4fbc0c8 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -1116,13 +1116,13 @@ void BKE_nurb_makeCurve(Nurb *nu, float *coord_array, float *tilt_array, float * *fp = basisu[i] * bp->vec[3]; sumdiv += *fp; } - if (sumdiv != 0.0f) if (sumdiv < 0.999f || sumdiv > 1.001f) { - /* is normalizing needed? */ - fp = sum; - for (i = istart; i <= iend; i++, fp++) { - *fp /= sumdiv; - } + if ((sumdiv != 0.0f) && (sumdiv < 0.999f || sumdiv > 1.001f)) { + /* is normalizing needed? */ + fp = sum; + for (i = istart; i <= iend; i++, fp++) { + *fp /= sumdiv; } + } /* one! (1.0) real point */ fp = sum; @@ -2481,8 +2481,8 @@ void BKE_curve_bevelList_make(Object *ob) else bevp2 = bevp1 + 1; - inp = (bevp1->vec[0] - bevp0->vec[0]) * (bevp0->vec[1] - bevp2->vec[1]) + - (bevp0->vec[1] - bevp1->vec[1]) * (bevp0->vec[0] - bevp2->vec[0]); + inp = ((bevp1->vec[0] - bevp0->vec[0]) * (bevp0->vec[1] - bevp2->vec[1]) + + (bevp0->vec[1] - bevp1->vec[1]) * (bevp0->vec[0] - bevp2->vec[0])); if (inp > 0.0f) sd->dir = 1; diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index 93c776ae30e..b2f8db0dcce 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -761,7 +761,7 @@ static void layerDoMinMax_mloopuv(void *data, void *vmin, void *vmax) { MLoopUV *min = vmin, *max = vmax, *luv = data; - DO_MINMAX2(luv->uv, min->uv, max->uv); + minmax_v2v2_v2(min->uv, max->uv, luv->uv); } static void layerAdd_mloopuv(void *data1, void *data2) @@ -833,7 +833,7 @@ static void layerDoMinMax_mloop_origspace(void *data, void *vmin, void *vmax) { OrigSpaceLoop *min = vmin, *max = vmax, *luv = data; - DO_MINMAX2(luv->uv, min->uv, max->uv); + minmax_v2v2_v2(min->uv, max->uv, luv->uv); } static void layerAdd_mloop_origspace(void *data1, void *data2) diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index 950a0ca3d60..3ed759392b6 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -45,6 +45,7 @@ #include "DNA_anim_types.h" #include "DNA_camera_types.h" #include "DNA_group_types.h" +#include "DNA_lamp_types.h" #include "DNA_lattice_types.h" #include "DNA_key_types.h" #include "DNA_material_types.h" @@ -350,8 +351,8 @@ static void dag_add_driver_relation(AnimData *adt, DagForest *dag, DagNode *node /* XXX: forward def for material driver handling... */ static void dag_add_material_driver_relations(DagForest *dag, DagNode *node, Material *ma); -/* recursive handling for material nodetree drivers */ -static void dag_add_material_nodetree_driver_relations(DagForest *dag, DagNode *node, bNodeTree *ntree) +/* recursive handling for shader nodetree drivers */ +static void dag_add_shader_nodetree_driver_relations(DagForest *dag, DagNode *node, bNodeTree *ntree) { bNode *n; @@ -367,7 +368,7 @@ static void dag_add_material_nodetree_driver_relations(DagForest *dag, DagNode * dag_add_material_driver_relations(dag, node, (Material *)n->id); } else if (n->type == NODE_GROUP) { - dag_add_material_nodetree_driver_relations(dag, node, (bNodeTree *)n->id); + dag_add_shader_nodetree_driver_relations(dag, node, (bNodeTree *)n->id); } } } @@ -386,21 +387,45 @@ static void dag_add_material_driver_relations(DagForest *dag, DagNode *node, Mat ma->id.flag |= LIB_DOIT; /* material itself */ - if (ma->adt) { + if (ma->adt) dag_add_driver_relation(ma->adt, dag, node, 1); - } /* textures */ // TODO... //dag_add_texture_driver_relations(DagForest *dag, DagNode *node, ID *id); /* material's nodetree */ - if (ma->nodetree) { - dag_add_material_nodetree_driver_relations(dag, node, ma->nodetree); - } + if (ma->nodetree) + dag_add_shader_nodetree_driver_relations(dag, node, ma->nodetree); +} + +/* recursive handling for lamp drivers */ +static void dag_add_lamp_driver_relations(DagForest *dag, DagNode *node, Lamp *la) +{ + /* Prevent infinite recursion by checking (and tagging the lamp) as having been visited + * already (see build_dag()). This assumes la->id.flag & LIB_DOIT isn't set by anything else + * in the meantime... [#32017] + */ + if (la->id.flag & LIB_DOIT) + return; + else + la->id.flag |= LIB_DOIT; + + /* lamp itself */ + if (la->adt) + dag_add_driver_relation(la->adt, dag, node, 1); + + /* textures */ + // TODO... + //dag_add_texture_driver_relations(DagForest *dag, DagNode *node, ID *id); + + /* lamp's nodetree */ + if (la->nodetree) + dag_add_shader_nodetree_driver_relations(dag, node, la->nodetree); } -static void dag_add_collision_field_relation(DagForest *dag, Scene *scene, Object *ob, DagNode *node, int skip_forcefield){ +static void dag_add_collision_field_relation(DagForest *dag, Scene *scene, Object *ob, DagNode *node, int skip_forcefield) +{ Base *base; DagNode *node2; @@ -646,6 +671,9 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O } } } + else if (ob->type == OB_LAMP) { + dag_add_lamp_driver_relations(dag, node, ob->data); + } /* particles */ psys = ob->particlesystem.first; @@ -816,6 +844,7 @@ DagForest *build_dag(Main *bmain, Scene *sce, short mask) /* clear "LIB_DOIT" flag from all materials, to prevent infinite recursion problems later [#32017] */ tag_main_idcode(bmain, ID_MA, FALSE); + tag_main_idcode(bmain, ID_LA, FALSE); /* add base node for scene. scene is always the first node in DAG */ scenenode = dag_add_node(dag, sce); @@ -1911,13 +1940,13 @@ void DAG_scene_sort(Main *bmain, Scene *sce) static void lib_id_recalc_tag(Main *bmain, ID *id) { id->flag |= LIB_ID_RECALC; - bmain->id_tag_update[id->name[0]] = 1; + DAG_id_type_tag(bmain, GS(id->name)); } static void lib_id_recalc_data_tag(Main *bmain, ID *id) { id->flag |= LIB_ID_RECALC_DATA; - bmain->id_tag_update[id->name[0]] = 1; + DAG_id_type_tag(bmain, GS(id->name)); } /* node was checked to have lasttime != curtime and is if type ID_OB */ @@ -2789,6 +2818,7 @@ void DAG_ids_check_recalc(Main *bmain, Scene *scene, int time) void DAG_ids_clear_recalc(Main *bmain) { ListBase *lbarray[MAX_LIBARRAY]; + bNodeTree *ntree; int a; /* loop over all ID types */ @@ -2801,9 +2831,15 @@ void DAG_ids_clear_recalc(Main *bmain) /* we tag based on first ID type character to avoid * looping over all ID's in case there are no tags */ if (id && bmain->id_tag_update[id->name[0]]) { - for (; id; id = id->next) + for (; id; id = id->next) { if (id->flag & (LIB_ID_RECALC | LIB_ID_RECALC_DATA)) id->flag &= ~(LIB_ID_RECALC | LIB_ID_RECALC_DATA); + + /* some ID's contain semi-datablock nodetree */ + ntree = ntreeFromID(id); + if (ntree && (ntree->id.flag & (LIB_ID_RECALC | LIB_ID_RECALC_DATA))) + ntree->id.flag &= ~(LIB_ID_RECALC | LIB_ID_RECALC_DATA); + } } } @@ -2870,8 +2906,18 @@ void DAG_id_tag_update(ID *id, short flag) } } -void DAG_id_type_tag(struct Main *bmain, short idtype) +void DAG_id_type_tag(Main *bmain, short idtype) { + if (idtype == ID_NT) { + /* stupid workaround so parent datablocks of nested nodetree get looped + * over when we loop over tagged datablock types */ + DAG_id_type_tag(bmain, ID_MA); + DAG_id_type_tag(bmain, ID_TE); + DAG_id_type_tag(bmain, ID_LA); + DAG_id_type_tag(bmain, ID_WO); + DAG_id_type_tag(bmain, ID_SCE); + } + bmain->id_tag_update[((char *)&idtype)[0]] = 1; } diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index e13d05d0a2f..083cb02fd3d 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -487,7 +487,7 @@ void BKE_displist_fill(ListBase *dispbase, ListBase *to, int flipnormal) } /* XXX (obedit && obedit->actcol)?(obedit->actcol-1):0)) { */ - if (totvert && (tot = BLI_scanfill_calc(&sf_ctx, FALSE))) { + if (totvert && (tot = BLI_scanfill_calc(&sf_ctx, BLI_SCANFILL_CALC_REMOVE_DOUBLES))) { if (tot) { dlnew = MEM_callocN(sizeof(DispList), "filldisplist"); dlnew->type = DL_INDEX3; @@ -630,7 +630,7 @@ static void curve_to_filledpoly(Curve *cu, ListBase *UNUSED(nurb), ListBase *dis * - first point left, last point right * - based on subdivided points in original curve, not on points in taper curve (still) */ -float BKE_displist_calc_taper(Scene *scene, Object *taperobj, int cur, int tot) +static float displist_calc_taper(Scene *scene, Object *taperobj, float fac) { DispList *dl; @@ -643,7 +643,6 @@ float BKE_displist_calc_taper(Scene *scene, Object *taperobj, int cur, int tot) dl = taperobj->disp.first; } if (dl) { - float fac = ((float)cur) / (float)(tot - 1); float minx, dx, *fp; int a; @@ -671,6 +670,13 @@ float BKE_displist_calc_taper(Scene *scene, Object *taperobj, int cur, int tot) return 1.0; } +float BKE_displist_calc_taper(Scene *scene, Object *taperobj, int cur, int tot) +{ + float fac = ((float)cur) / (float)(tot - 1); + + return displist_calc_taper(scene, taperobj, fac); +} + void BKE_displist_make_mball(Scene *scene, Object *ob) { if (!ob || ob->type != OB_MBALL) @@ -1240,7 +1246,7 @@ void BKE_displist_make_surf(Scene *scene, Object *ob, ListBase *dispbase, } } -static void rotateBevelPiece(Curve *cu, BevPoint *bevp, DispList *dlb, float widfac, float fac, float **data_r) +static void rotateBevelPiece(Curve *cu, BevPoint *bevp, BevPoint *nbevp, DispList *dlb, float bev_blend, float widfac, float fac, float **data_r) { float *fp, *data = *data_r; int b; @@ -1248,22 +1254,48 @@ static void rotateBevelPiece(Curve *cu, BevPoint *bevp, DispList *dlb, float wid fp = dlb->verts; for (b = 0; b < dlb->nr; b++, fp += 3, data += 3) { if (cu->flag & CU_3D) { - float vec[3]; + float vec[3], quat[4]; vec[0] = fp[1] + widfac; vec[1] = fp[2]; vec[2] = 0.0; - mul_qt_v3(bevp->quat, vec); + if (nbevp == NULL) { + copy_v3_v3(data, bevp->vec); + copy_qt_qt(quat, bevp->quat); + } + else { + interp_v3_v3v3(data, bevp->vec, nbevp->vec, bev_blend); + interp_qt_qtqt(quat, bevp->quat, nbevp->quat, bev_blend); + } + + mul_qt_v3(quat, vec); - data[0] = bevp->vec[0] + fac * vec[0]; - data[1] = bevp->vec[1] + fac * vec[1]; - data[2] = bevp->vec[2] + fac * vec[2]; + data[0] += fac * vec[0]; + data[1] += fac * vec[1]; + data[2] += fac * vec[2]; } else { - data[0] = bevp->vec[0] + fac * (widfac + fp[1]) * bevp->sina; - data[1] = bevp->vec[1] + fac * (widfac + fp[1]) * bevp->cosa; - data[2] = bevp->vec[2] + fac * fp[2]; + float sina, cosa; + + if (nbevp == NULL) { + copy_v3_v3(data, bevp->vec); + sina = bevp->sina; + cosa = bevp->cosa; + } + else { + interp_v3_v3v3(data, bevp->vec, nbevp->vec, bev_blend); + + /* perhaps we need to interpolate angles instead. but the thing is + * cosa and sina are not actually sine and cosine + */ + sina = nbevp->sina * bev_blend + bevp->sina * (1.0f - bev_blend); + cosa = nbevp->cosa * bev_blend + bevp->cosa * (1.0f - bev_blend); + } + + data[0] += fac * (widfac + fp[1]) * sina; + data[1] += fac * (widfac + fp[1]) * cosa; + data[2] += fac * fp[2]; } } @@ -1399,8 +1431,8 @@ static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispba firstblend = 1.0f - (bevfac1 * (bl->nr - 1) - (int)(bevfac1 * (bl->nr - 1))); lastblend = bevfac2 * (bl->nr - 1) - (int)(bevfac2 * (bl->nr - 1)); - if (steps > bl->nr) { - steps = bl->nr; + if (start + steps > bl->nr) { + steps = bl->nr - start; lastblend = 1.0f; } @@ -1438,7 +1470,29 @@ static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispba fac = bevp->radius; } else { - fac = BKE_displist_calc_taper(scene, cu->taperobj, i, bl->nr); + float len, taper_fac; + + if (cu->flag & CU_MAP_TAPER) { + len = (steps - 3) + firstblend + lastblend; + + if (a == 0) + taper_fac = 0.0f; + else if (a == steps - 1) + taper_fac = 1.0f; + else + taper_fac = ((float) a - (1.0f - firstblend)) / len; + } + else { + len = bl->nr - 1; + taper_fac = (float) i / len; + + if (a == 0) + taper_fac += (1.0f - firstblend) / len; + else if (a == steps - 1) + taper_fac -= (1.0f - lastblend) / len; + } + + fac = displist_calc_taper(scene, cu->taperobj, taper_fac); } if (bevp->split_tag) { @@ -1446,27 +1500,12 @@ static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispba } /* rotate bevel piece and write in data */ - rotateBevelPiece(cu, bevp, dlb, widfac, fac, &data); - - if (a == 1 || a == steps - 1) { - float *cur_fp = cur_data, *prev_fp = cur_data - 3 * dlb->nr; - int b; - - for (b = 0; b < dlb->nr; b++, prev_fp += 3, cur_fp += 3) { - float cur[3], prev[3]; - - copy_v3_v3(cur, cur_fp); - copy_v3_v3(prev, prev_fp); - - if (a == 1) - interp_v3_v3v3(prev, cur_fp, prev_fp, firstblend); - if (a == steps - 1) - interp_v3_v3v3(cur, prev_fp, cur_fp, lastblend); - - copy_v3_v3(cur_fp, cur); - copy_v3_v3(prev_fp, prev); - } - } + if (a == 0) + rotateBevelPiece(cu, bevp, bevp + 1, dlb, 1.0f - firstblend, widfac, fac, &data); + else if (a == steps - 1) + rotateBevelPiece(cu, bevp, bevp - 1, dlb, 1.0f - lastblend, widfac, fac, &data); + else + rotateBevelPiece(cu, bevp, NULL, dlb, 0.0f, widfac, fac, &data); if (cu->bevobj && (cu->flag & CU_FILL_CAPS)) { if (a == 1) diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c index 89d728c0419..ed85e5b627b 100644 --- a/source/blender/blenkernel/intern/dynamicpaint.c +++ b/source/blender/blenkernel/intern/dynamicpaint.c @@ -86,11 +86,13 @@ #include "RE_shader_ext.h" #ifdef _OPENMP -#include +# include #endif /* could enable at some point but for now there are far too many conversions */ -#pragma GCC diagnostic ignored "-Wdouble-promotion" +#ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wdouble-promotion" +#endif /* precalculated gaussian factors for 5x super sampling */ static float gaussianFactors[5] = {0.996849f, @@ -3364,7 +3366,7 @@ static int dynamicPaint_paintMesh(DynamicPaintSurface *surface, (!hit_found || (brush->flags & MOD_DPAINT_INVERSE_PROX))) { float proxDist = -1.0f; - float hitCo[3]; + float hitCo[3] = {0.0f, 0.0f, 0.0f}; short hQuad; int face; @@ -3721,6 +3723,8 @@ static int dynamicPaint_paintParticles(DynamicPaintSurface *surface, float smooth_range = smooth * (1.0f - strength), dist; /* calculate max range that can have particles with higher influence than the nearest one */ float max_range = smooth - strength * smooth + solidradius; + /* Make gcc happy! */ + dist = max_range; particles = BLI_kdtree_range_search(tree, max_range, bData->realCoord[bData->s_pos[index]].v, NULL, &nearest); diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c index 8d430eb58b5..321a61ce238 100644 --- a/source/blender/blenkernel/intern/editderivedmesh.c +++ b/source/blender/blenkernel/intern/editderivedmesh.c @@ -215,7 +215,7 @@ static void BMEdit_RecalcTessellation_intern(BMEditMesh *tm) /* complete the loop */ BLI_scanfill_edge_add(&sf_ctx, sf_vert_first, sf_vert); - totfilltri = BLI_scanfill_calc_ex(&sf_ctx, FALSE, efa->no); + totfilltri = BLI_scanfill_calc_ex(&sf_ctx, 0, efa->no); BLI_array_grow_items(looptris, totfilltri); for (sf_tri = sf_ctx.fillfacebase.first; sf_tri; sf_tri = sf_tri->next) { diff --git a/source/blender/blenkernel/intern/idcode.c b/source/blender/blenkernel/intern/idcode.c index 30427a81c4b..c3008d17bd1 100644 --- a/source/blender/blenkernel/intern/idcode.c +++ b/source/blender/blenkernel/intern/idcode.c @@ -47,39 +47,40 @@ typedef struct { } IDType; /* plural need to match rna_main.c's MainCollectionDef */ +/* WARNING! Keep it in sync with i18n contexts in BLF_translation.h */ static IDType idtypes[] = { - { ID_AC, "Action", "actions", IDTYPE_FLAGS_ISLINKABLE}, - { ID_AR, "Armature", "armatures", IDTYPE_FLAGS_ISLINKABLE}, - { ID_BR, "Brush", "brushes", IDTYPE_FLAGS_ISLINKABLE}, - { ID_CA, "Camera", "cameras", IDTYPE_FLAGS_ISLINKABLE}, - { ID_CU, "Curve", "curves", IDTYPE_FLAGS_ISLINKABLE}, - { ID_GD, "GPencil", "grease_pencil", IDTYPE_FLAGS_ISLINKABLE}, /* rename gpencil */ - { ID_GR, "Group", "groups", IDTYPE_FLAGS_ISLINKABLE}, - { ID_ID, "ID", "ids", 0}, /* plural is fake */ - { ID_IM, "Image", "images", IDTYPE_FLAGS_ISLINKABLE}, - { ID_IP, "Ipo", "ipos", IDTYPE_FLAGS_ISLINKABLE}, /* deprecated */ - { ID_KE, "Key", "shape_keys", 0}, - { ID_LA, "Lamp", "lamps", IDTYPE_FLAGS_ISLINKABLE}, - { ID_LI, "Library", "libraries", 0}, - { ID_LT, "Lattice", "lattices", IDTYPE_FLAGS_ISLINKABLE}, - { ID_MA, "Material", "materials", IDTYPE_FLAGS_ISLINKABLE}, - { ID_MB, "Metaball", "metaballs", IDTYPE_FLAGS_ISLINKABLE}, - { ID_ME, "Mesh", "meshes", IDTYPE_FLAGS_ISLINKABLE}, - { ID_NT, "NodeTree", "node_groups", IDTYPE_FLAGS_ISLINKABLE}, - { ID_OB, "Object", "objects", IDTYPE_FLAGS_ISLINKABLE}, - { ID_PA, "ParticleSettings", "particles", 0}, - { ID_SCE, "Scene", "scenes", IDTYPE_FLAGS_ISLINKABLE}, - { ID_SCR, "Screen", "screens", 0}, - { ID_SEQ, "Sequence", "sequences", 0}, /* not actually ID data */ - { ID_SPK, "Speaker", "speakers", IDTYPE_FLAGS_ISLINKABLE}, - { ID_SO, "Sound", "sounds", IDTYPE_FLAGS_ISLINKABLE}, - { ID_TE, "Texture", "textures", IDTYPE_FLAGS_ISLINKABLE}, - { ID_TXT, "Text", "texts", IDTYPE_FLAGS_ISLINKABLE}, - { ID_VF, "VFont", "fonts", IDTYPE_FLAGS_ISLINKABLE}, - { ID_WO, "World", "worlds", IDTYPE_FLAGS_ISLINKABLE}, - { ID_WM, "WindowManager", "window_managers", 0}, - { ID_MC, "MovieClip", "movieclips", IDTYPE_FLAGS_ISLINKABLE}, - { ID_MSK, "Mask", "masks", IDTYPE_FLAGS_ISLINKABLE}, + { ID_AC, "Action", "actions", IDTYPE_FLAGS_ISLINKABLE }, + { ID_AR, "Armature", "armatures", IDTYPE_FLAGS_ISLINKABLE }, + { ID_BR, "Brush", "brushes", IDTYPE_FLAGS_ISLINKABLE }, + { ID_CA, "Camera", "cameras", IDTYPE_FLAGS_ISLINKABLE }, + { ID_CU, "Curve", "curves", IDTYPE_FLAGS_ISLINKABLE }, + { ID_GD, "GPencil", "grease_pencil", IDTYPE_FLAGS_ISLINKABLE }, /* rename gpencil */ + { ID_GR, "Group", "groups", IDTYPE_FLAGS_ISLINKABLE }, + { ID_ID, "ID", "ids", 0 }, /* plural is fake */ + { ID_IM, "Image", "images", IDTYPE_FLAGS_ISLINKABLE }, + { ID_IP, "Ipo", "ipos", IDTYPE_FLAGS_ISLINKABLE }, /* deprecated */ + { ID_KE, "Key", "shape_keys", 0 }, + { ID_LA, "Lamp", "lamps", IDTYPE_FLAGS_ISLINKABLE }, + { ID_LI, "Library", "libraries", 0 }, + { ID_LT, "Lattice", "lattices", IDTYPE_FLAGS_ISLINKABLE }, + { ID_MA, "Material", "materials", IDTYPE_FLAGS_ISLINKABLE }, + { ID_MB, "Metaball", "metaballs", IDTYPE_FLAGS_ISLINKABLE }, + { ID_MC, "MovieClip", "movieclips", IDTYPE_FLAGS_ISLINKABLE }, + { ID_ME, "Mesh", "meshes", IDTYPE_FLAGS_ISLINKABLE }, + { ID_MSK, "Mask", "masks", IDTYPE_FLAGS_ISLINKABLE }, + { ID_NT, "NodeTree", "node_groups", IDTYPE_FLAGS_ISLINKABLE }, + { ID_OB, "Object", "objects", IDTYPE_FLAGS_ISLINKABLE }, + { ID_PA, "ParticleSettings", "particles", 0 }, + { ID_SCE, "Scene", "scenes", IDTYPE_FLAGS_ISLINKABLE }, + { ID_SCR, "Screen", "screens", 0 }, + { ID_SEQ, "Sequence", "sequences", 0 }, /* not actually ID data */ + { ID_SPK, "Speaker", "speakers", IDTYPE_FLAGS_ISLINKABLE }, + { ID_SO, "Sound", "sounds", IDTYPE_FLAGS_ISLINKABLE }, + { ID_TE, "Texture", "textures", IDTYPE_FLAGS_ISLINKABLE }, + { ID_TXT, "Text", "texts", IDTYPE_FLAGS_ISLINKABLE }, + { ID_VF, "VFont", "fonts", IDTYPE_FLAGS_ISLINKABLE }, + { ID_WO, "World", "worlds", IDTYPE_FLAGS_ISLINKABLE }, + { ID_WM, "WindowManager", "window_managers", 0 }, }; static int nidtypes = sizeof(idtypes) / sizeof(idtypes[0]); diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index ef751ce3493..f09f128e874 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -100,6 +100,8 @@ #include "WM_api.h" +static SpinLock image_spin; + /* max int, to indicate we don't store sequences in ibuf */ #define IMA_NO_INDEX 0x7FEFEFEF @@ -108,6 +110,16 @@ #define IMA_INDEX_FRAME(index) (index >> 10) #define IMA_INDEX_PASS(index) (index & ~1023) +void BKE_images_init(void) +{ + BLI_spin_init(&image_spin); +} + +void BKE_images_exit(void) +{ + BLI_spin_end(&image_spin); +} + /* ******** IMAGE PROCESSING ************* */ static void de_interlace_ng(struct ImBuf *ibuf) /* neogeo fields */ @@ -168,13 +180,14 @@ static void de_interlace_st(struct ImBuf *ibuf) /* standard fields */ void BKE_image_de_interlace(Image *ima, int odd) { - ImBuf *ibuf = BKE_image_get_ibuf(ima, NULL); + ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL); if (ibuf) { if (odd) de_interlace_st(ibuf); else de_interlace_ng(ibuf); } + BKE_image_release_ibuf(ima, ibuf, NULL); } /* ***************** ALLOC & FREE, DATA MANAGING *************** */ @@ -260,8 +273,9 @@ static ImBuf *image_get_ibuf(Image *ima, int index, int frame) /* this function is intended to be thread safe. with IMA_NO_INDEX this * should be OK, but when iterating over the list this is more tricky * */ - if (index == IMA_NO_INDEX) + if (index == IMA_NO_INDEX) { return ima->ibufs.first; + } else { ImBuf *ibuf; @@ -269,9 +283,9 @@ static ImBuf *image_get_ibuf(Image *ima, int index, int frame) for (ibuf = ima->ibufs.first; ibuf; ibuf = ibuf->next) if (ibuf->index == index) return ibuf; - - return NULL; } + + return NULL; } /* no ima->ibuf anymore, but listbase */ @@ -534,7 +548,7 @@ int BKE_image_scale(Image *image, int width, int height) ibuf->userflags |= IB_BITMAPDIRTY; } - BKE_image_release_ibuf(image, lock); + BKE_image_release_ibuf(image, ibuf, lock); return (ibuf != NULL); } @@ -649,6 +663,13 @@ static ImBuf *add_ibuf_size(unsigned int width, unsigned int height, const char BKE_image_buf_fill_color(rect, rect_float, width, height, color); } + if (rect_float) { + /* both byte and float buffers are filling in sRGB space, need to linearize float buffer after BKE_image_buf_fill* functions */ + + IMB_buffer_float_from_float(rect_float, rect_float, ibuf->channels, IB_PROFILE_LINEAR_RGB, IB_PROFILE_SRGB, + ibuf->flags & IB_cm_predivide, ibuf->x, ibuf->y, ibuf->x, ibuf->x); + } + return ibuf; } @@ -1561,7 +1582,7 @@ void BKE_stamp_buf(Scene *scene, Object *camera, unsigned char *rect, float *rec /* also a little of space to the background. */ buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, display, - x - BUFF_MARGIN_X, y - BUFF_MARGIN_Y, w + BUFF_MARGIN_X, y + h + BUFF_MARGIN_Y); + x - BUFF_MARGIN_X, y - BUFF_MARGIN_Y, w + BUFF_MARGIN_X, y + h + BUFF_MARGIN_Y); /* and draw the text. */ BLF_position(mono, x, y + y_ofs, 0.0); @@ -1578,7 +1599,7 @@ void BKE_stamp_buf(Scene *scene, Object *camera, unsigned char *rect, float *rec /* and space for background. */ buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, display, - 0, y - BUFF_MARGIN_Y, w + BUFF_MARGIN_X, y + h + BUFF_MARGIN_Y); + 0, y - BUFF_MARGIN_Y, w + BUFF_MARGIN_X, y + h + BUFF_MARGIN_Y); BLF_position(mono, x, y + y_ofs, 0.0); BLF_draw_buffer(mono, stamp_data.note); @@ -1594,7 +1615,7 @@ void BKE_stamp_buf(Scene *scene, Object *camera, unsigned char *rect, float *rec /* and space for background. */ buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, display, - 0, y - BUFF_MARGIN_Y, w + BUFF_MARGIN_X, y + h + BUFF_MARGIN_Y); + 0, y - BUFF_MARGIN_Y, w + BUFF_MARGIN_X, y + h + BUFF_MARGIN_Y); BLF_position(mono, x, y + y_ofs, 0.0); BLF_draw_buffer(mono, stamp_data.date); @@ -1610,7 +1631,7 @@ void BKE_stamp_buf(Scene *scene, Object *camera, unsigned char *rect, float *rec /* and space for background. */ buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, display, - 0, y - BUFF_MARGIN_Y, w + BUFF_MARGIN_X, y + h + BUFF_MARGIN_Y); + 0, y - BUFF_MARGIN_Y, w + BUFF_MARGIN_X, y + h + BUFF_MARGIN_Y); BLF_position(mono, x, y + y_ofs, 0.0); BLF_draw_buffer(mono, stamp_data.rendertime); @@ -1625,7 +1646,7 @@ void BKE_stamp_buf(Scene *scene, Object *camera, unsigned char *rect, float *rec /* extra space for background. */ buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, display, - x - BUFF_MARGIN_X, y - BUFF_MARGIN_Y, w + BUFF_MARGIN_X, y + h + BUFF_MARGIN_Y); + x - BUFF_MARGIN_X, y - BUFF_MARGIN_Y, w + BUFF_MARGIN_X, y + h + BUFF_MARGIN_Y); /* and pad the text. */ BLF_position(mono, x, y + y_ofs, 0.0); @@ -1641,7 +1662,7 @@ void BKE_stamp_buf(Scene *scene, Object *camera, unsigned char *rect, float *rec /* extra space for background */ buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, display, - x - BUFF_MARGIN_X, y, x + w + BUFF_MARGIN_X, y + h + BUFF_MARGIN_Y); + x - BUFF_MARGIN_X, y, x + w + BUFF_MARGIN_X, y + h + BUFF_MARGIN_Y); /* and pad the text. */ BLF_position(mono, x, y + y_ofs, 0.0); @@ -1656,7 +1677,7 @@ void BKE_stamp_buf(Scene *scene, Object *camera, unsigned char *rect, float *rec /* extra space for background. */ buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, display, - x - BUFF_MARGIN_X, y - BUFF_MARGIN_Y, x + w + BUFF_MARGIN_X, y + h + BUFF_MARGIN_Y); + x - BUFF_MARGIN_X, y - BUFF_MARGIN_Y, x + w + BUFF_MARGIN_X, y + h + BUFF_MARGIN_Y); /* and pad the text. */ BLF_position(mono, x, y + y_ofs, 0.0); @@ -1671,7 +1692,7 @@ void BKE_stamp_buf(Scene *scene, Object *camera, unsigned char *rect, float *rec /* extra space for background. */ buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, display, - x - BUFF_MARGIN_X, y - BUFF_MARGIN_Y, x + w + BUFF_MARGIN_X, y + h + BUFF_MARGIN_Y); + x - BUFF_MARGIN_X, y - BUFF_MARGIN_Y, x + w + BUFF_MARGIN_X, y + h + BUFF_MARGIN_Y); BLF_position(mono, x, y + y_ofs, 0.0); BLF_draw_buffer(mono, stamp_data.camera); @@ -1684,7 +1705,7 @@ void BKE_stamp_buf(Scene *scene, Object *camera, unsigned char *rect, float *rec /* extra space for background. */ buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, display, - x - BUFF_MARGIN_X, y - BUFF_MARGIN_Y, x + w + BUFF_MARGIN_X, y + h + BUFF_MARGIN_Y); + x - BUFF_MARGIN_X, y - BUFF_MARGIN_Y, x + w + BUFF_MARGIN_X, y + h + BUFF_MARGIN_Y); BLF_position(mono, x, y + y_ofs, 0.0); BLF_draw_buffer(mono, stamp_data.cameralens); } @@ -1697,7 +1718,7 @@ void BKE_stamp_buf(Scene *scene, Object *camera, unsigned char *rect, float *rec /* extra space for background. */ buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, display, - x - BUFF_MARGIN_X, y - BUFF_MARGIN_Y, x + w + BUFF_MARGIN_X, y + h + BUFF_MARGIN_Y); + x - BUFF_MARGIN_X, y - BUFF_MARGIN_Y, x + w + BUFF_MARGIN_X, y + h + BUFF_MARGIN_Y); /* and pad the text. */ BLF_position(mono, x, y + y_ofs, 0.0); @@ -1713,7 +1734,7 @@ void BKE_stamp_buf(Scene *scene, Object *camera, unsigned char *rect, float *rec /* extra space for background. */ buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, display, - x - BUFF_MARGIN_X, y - BUFF_MARGIN_Y, x + w + BUFF_MARGIN_X, y + h + BUFF_MARGIN_Y); + x - BUFF_MARGIN_X, y - BUFF_MARGIN_Y, x + w + BUFF_MARGIN_X, y + h + BUFF_MARGIN_Y); BLF_position(mono, x, y + y_ofs, 0.0); BLF_draw_buffer(mono, stamp_data.strip); @@ -2081,6 +2102,8 @@ void BKE_image_signal(Image *ima, ImageUser *iuser, int signal) if (ima == NULL) return; + BLI_spin_lock(&image_spin); + switch (signal) { case IMA_SIGNAL_FREE: image_free_buffers(ima); @@ -2157,6 +2180,8 @@ void BKE_image_signal(Image *ima, ImageUser *iuser, int signal) break; } + BLI_spin_unlock(&image_spin); + /* don't use notifiers because they are not 100% sure to succeeded * this also makes sure all scenes are accounted for. */ { @@ -2320,7 +2345,7 @@ static ImBuf *image_load_sequence_file(Image *ima, ImageUser *iuser, int frame) if (ibuf) { #ifdef WITH_OPENEXR - /* handle multilayer case, don't assign ibuf. will be handled in BKE_image_get_ibuf */ + /* handle multilayer case, don't assign ibuf. will be handled in BKE_image_acquire_ibuf */ if (ibuf->ftype == OPENEXR && ibuf->userdata) { image_create_multilayer(ima, ibuf, frame); ima->type = IMA_TYPE_MULTILAYER; @@ -2482,7 +2507,7 @@ static ImBuf *image_load_image_file(Image *ima, ImageUser *iuser, int cfra) } if (ibuf) { - /* handle multilayer case, don't assign ibuf. will be handled in BKE_image_get_ibuf */ + /* handle multilayer case, don't assign ibuf. will be handled in BKE_image_acquire_ibuf */ if (ibuf->ftype == OPENEXR && ibuf->userdata) { image_create_multilayer(ima, ibuf, cfra); ima->type = IMA_TYPE_MULTILAYER; @@ -2751,38 +2776,32 @@ static ImBuf *image_get_ibuf_threadsafe(Image *ima, ImageUser *iuser, int *frame * a big bottleneck */ } - *frame_r = frame; - *index_r = index; + if (frame_r) + *frame_r = frame; + + if (index_r) + *index_r = index; return ibuf; } -/* Checks optional ImageUser and verifies/creates ImBuf. */ -/* use this one if you want to get a render result in progress, - * if not, use BKE_image_get_ibuf which doesn't require a release */ -ImBuf *BKE_image_acquire_ibuf(Image *ima, ImageUser *iuser, void **lock_r) +/* Checks optional ImageUser and verifies/creates ImBuf. + * + * not thread-safe, so callee should worry about thread locks + */ +static ImBuf *image_acquire_ibuf(Image *ima, ImageUser *iuser, void **lock_r) { ImBuf *ibuf = NULL; float color[] = {0, 0, 0, 1}; int frame = 0, index = 0; - /* This function is intended to be thread-safe. It postpones the mutex lock - * until it needs to load the image, if the image is already there it - * should just get the pointer and return. The reason is that a lot of mutex - * locks appears to be very slow on certain multicore macs, causing a render - * with image textures to actually slow down as more threads are used. - * - * Note that all the image loading functions should also make sure they do - * things in a threadsafe way for image_get_ibuf_threadsafe to work correct. - * That means, the last two steps must be, 1) add the ibuf to the list and - * 2) set ima/iuser->ok to 0 to IMA_OK_LOADED */ - if (lock_r) *lock_r = NULL; /* quick reject tests */ if (ima == NULL) return NULL; + if (iuser) { if (iuser->ok == 0) return NULL; @@ -2790,95 +2809,71 @@ ImBuf *BKE_image_acquire_ibuf(Image *ima, ImageUser *iuser, void **lock_r) else if (ima->ok == 0) return NULL; - /* try to get the ibuf without locking */ ibuf = image_get_ibuf_threadsafe(ima, iuser, &frame, &index); if (ibuf == NULL) { - /* couldn't get ibuf and image is not ok, so let's lock and try to - * load the image */ - BLI_lock_thread(LOCK_IMAGE); - - /* need to check ok flag and loading ibuf again, because the situation - * might have changed in the meantime */ - if (iuser) { - if (iuser->ok == 0) { - BLI_unlock_thread(LOCK_IMAGE); - return NULL; - } - } - else if (ima->ok == 0) { - BLI_unlock_thread(LOCK_IMAGE); - return NULL; - } - - ibuf = image_get_ibuf_threadsafe(ima, iuser, &frame, &index); - - if (ibuf == NULL) { - /* we are sure we have to load the ibuf, using source and type */ - if (ima->source == IMA_SRC_MOVIE) { - /* source is from single file, use flipbook to store ibuf */ - ibuf = image_load_movie_file(ima, iuser, frame); + /* we are sure we have to load the ibuf, using source and type */ + if (ima->source == IMA_SRC_MOVIE) { + /* source is from single file, use flipbook to store ibuf */ + ibuf = image_load_movie_file(ima, iuser, frame); + } + else if (ima->source == IMA_SRC_SEQUENCE) { + if (ima->type == IMA_TYPE_IMAGE) { + /* regular files, ibufs in flipbook, allows saving */ + ibuf = image_load_sequence_file(ima, iuser, frame); } - else if (ima->source == IMA_SRC_SEQUENCE) { - if (ima->type == IMA_TYPE_IMAGE) { - /* regular files, ibufs in flipbook, allows saving */ - ibuf = image_load_sequence_file(ima, iuser, frame); - } - /* no else; on load the ima type can change */ - if (ima->type == IMA_TYPE_MULTILAYER) { - /* only 1 layer/pass stored in imbufs, no exrhandle anim storage, no saving */ - ibuf = image_load_sequence_multilayer(ima, iuser, frame); - } - } - else if (ima->source == IMA_SRC_FILE) { - - if (ima->type == IMA_TYPE_IMAGE) - ibuf = image_load_image_file(ima, iuser, frame); /* cfra only for '#', this global is OK */ - /* no else; on load the ima type can change */ - if (ima->type == IMA_TYPE_MULTILAYER) - /* keeps render result, stores ibufs in listbase, allows saving */ - ibuf = image_get_ibuf_multilayer(ima, iuser); - + /* no else; on load the ima type can change */ + if (ima->type == IMA_TYPE_MULTILAYER) { + /* only 1 layer/pass stored in imbufs, no exrhandle anim storage, no saving */ + ibuf = image_load_sequence_multilayer(ima, iuser, frame); } - else if (ima->source == IMA_SRC_GENERATED) { - /* generated is: ibuf is allocated dynamically */ - /* 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, - color, &ima->colorspace_settings); - image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0); - ima->ok = IMA_OK_LOADED; + } + else if (ima->source == IMA_SRC_FILE) { + + if (ima->type == IMA_TYPE_IMAGE) + ibuf = image_load_image_file(ima, iuser, frame); /* cfra only for '#', this global is OK */ + /* no else; on load the ima type can change */ + if (ima->type == IMA_TYPE_MULTILAYER) + /* keeps render result, stores ibufs in listbase, allows saving */ + ibuf = image_get_ibuf_multilayer(ima, iuser); + + } + else if (ima->source == IMA_SRC_GENERATED) { + /* generated is: ibuf is allocated dynamically */ + /* 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, + color, &ima->colorspace_settings); + image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0); + ima->ok = IMA_OK_LOADED; + } + else if (ima->source == IMA_SRC_VIEWER) { + if (ima->type == IMA_TYPE_R_RESULT) { + /* always verify entirely, and potentially + * returns pointer to release later */ + ibuf = image_get_render_result(ima, iuser, lock_r); } - else if (ima->source == IMA_SRC_VIEWER) { - if (ima->type == IMA_TYPE_R_RESULT) { - /* always verify entirely, and potentially - * returns pointer to release later */ - ibuf = image_get_render_result(ima, iuser, lock_r); - } - else if (ima->type == IMA_TYPE_COMPOSITE) { - /* requires lock/unlock, otherwise don't return image */ - if (lock_r) { - /* unlock in BKE_image_release_ibuf */ - BLI_lock_thread(LOCK_VIEWER); - *lock_r = ima; - - /* XXX anim play for viewer nodes not yet supported */ - frame = 0; // XXX iuser?iuser->framenr:0; - ibuf = image_get_ibuf(ima, 0, frame); - - if (!ibuf) { - /* Composite Viewer, all handled in compositor */ - /* fake ibuf, will be filled in compositor */ - ibuf = IMB_allocImBuf(256, 256, 32, IB_rect); - image_assign_ibuf(ima, ibuf, 0, frame); - } + else if (ima->type == IMA_TYPE_COMPOSITE) { + /* requires lock/unlock, otherwise don't return image */ + if (lock_r) { + /* unlock in BKE_image_release_ibuf */ + BLI_lock_thread(LOCK_VIEWER); + *lock_r = ima; + + /* XXX anim play for viewer nodes not yet supported */ + frame = 0; // XXX iuser?iuser->framenr:0; + ibuf = image_get_ibuf(ima, 0, frame); + + if (!ibuf) { + /* Composite Viewer, all handled in compositor */ + /* fake ibuf, will be filled in compositor */ + ibuf = IMB_allocImBuf(256, 256, 32, IB_rect); + image_assign_ibuf(ima, ibuf, 0, frame); } } } } - - BLI_unlock_thread(LOCK_IMAGE); } BKE_image_tag_time(ima); @@ -2886,23 +2881,79 @@ ImBuf *BKE_image_acquire_ibuf(Image *ima, ImageUser *iuser, void **lock_r) return ibuf; } -void BKE_image_release_ibuf(Image *ima, void *lock) +/* return image buffer for given image and user + * + * - will lock render result if image type is render result and lock is not NULL + * - will return NULL if image type if render or composite result and lock is NULL + * + * references the result, BKE_image_release_ibuf should be used to de-reference + */ +ImBuf *BKE_image_acquire_ibuf(Image *ima, ImageUser *iuser, void **lock_r) { - /* for getting image during threaded render / compositing, need to release */ - if (lock == ima) { - BLI_unlock_thread(LOCK_VIEWER); /* viewer image */ + ImBuf *ibuf; + + BLI_spin_lock(&image_spin); + + ibuf = image_acquire_ibuf(ima, iuser, lock_r); + + if (ibuf) + IMB_refImBuf(ibuf); + + BLI_spin_unlock(&image_spin); + + return ibuf; +} + +void BKE_image_release_ibuf(Image *ima, ImBuf *ibuf, void *lock) +{ + if (lock) { + /* for getting image during threaded render / compositing, need to release */ + if (lock == ima) { + BLI_unlock_thread(LOCK_VIEWER); /* viewer image */ + } + else if (lock) { + RE_ReleaseResultImage(lock); /* render result */ + BLI_unlock_thread(LOCK_VIEWER); /* view image imbuf */ + } } - else if (lock) { - RE_ReleaseResultImage(lock); /* render result */ - BLI_unlock_thread(LOCK_VIEWER); /* view image imbuf */ + + if (ibuf) { + BLI_spin_lock(&image_spin); + IMB_freeImBuf(ibuf); + BLI_spin_unlock(&image_spin); } } -/* warning, this can allocate generated images */ -ImBuf *BKE_image_get_ibuf(Image *ima, ImageUser *iuser) +/* checks whether there's an image buffer for given image and user */ +int BKE_image_has_ibuf(Image *ima, ImageUser *iuser) { - /* here (+fie_ima/2-1) makes sure that division happens correctly */ - return BKE_image_acquire_ibuf(ima, iuser, NULL); + ImBuf *ibuf; + + /* quick reject tests */ + if (ima == NULL) + return FALSE; + + if (iuser) { + if (iuser->ok == 0) + return FALSE; + } + else if (ima->ok == 0) + return FALSE; + + ibuf = image_get_ibuf_threadsafe(ima, iuser, NULL, NULL); + + if (!ibuf) { + BLI_spin_lock(&image_spin); + + ibuf = image_get_ibuf_threadsafe(ima, iuser, NULL, NULL); + + if (!ibuf) + ibuf = image_acquire_ibuf(ima, iuser, NULL); + + BLI_spin_unlock(&image_spin); + } + + return ibuf != NULL; } int BKE_image_user_frame_get(const ImageUser *iuser, int cfra, int fieldnr, short *r_is_in_range) @@ -3020,7 +3071,7 @@ int BKE_image_has_alpha(struct Image *image) ibuf = BKE_image_acquire_ibuf(image, NULL, &lock); planes = (ibuf ? ibuf->planes : 0); - BKE_image_release_ibuf(image, lock); + BKE_image_release_ibuf(image, ibuf, lock); if (planes == 32) return 1; @@ -3044,7 +3095,7 @@ void BKE_image_get_size(Image *image, ImageUser *iuser, int *width, int *height) *height = IMG_SIZE_FALLBACK; } - BKE_image_release_ibuf(image, lock); + BKE_image_release_ibuf(image, ibuf, lock); } void BKE_image_get_size_fl(Image *image, ImageUser *iuser, float size[2]) diff --git a/source/blender/blenkernel/intern/lamp.c b/source/blender/blenkernel/intern/lamp.c index 4782d09a7c8..2f37db846f3 100644 --- a/source/blender/blenkernel/intern/lamp.c +++ b/source/blender/blenkernel/intern/lamp.c @@ -33,9 +33,12 @@ #include "MEM_guardedalloc.h" +#include "DNA_anim_types.h" #include "DNA_lamp_types.h" #include "DNA_material_types.h" +#include "DNA_node_types.h" #include "DNA_object_types.h" +#include "DNA_scene_types.h" #include "DNA_texture_types.h" #include "BLI_listbase.h" @@ -73,7 +76,7 @@ Lamp *BKE_lamp_add(const char *name) la->soft = 3.0f; la->compressthresh = 0.05f; la->ray_samp = la->ray_sampy = la->ray_sampz = 1; - la->area_size = la->area_sizey = la->area_sizez = 1.0f; + la->area_size = la->area_sizey = la->area_sizez = 0.1f; la->buffers = 1; la->buftype = LA_SHADBUF_HALFWAY; la->ray_samp_method = LA_SAMP_HALTON; @@ -232,3 +235,38 @@ void BKE_lamp_free(Lamp *la) la->id.icon_id = 0; } +/* Calculate all drivers for lamps, see material_drivers_update for why this is a bad hack */ + +static void lamp_node_drivers_update(Scene *scene, bNodeTree *ntree, float ctime) +{ + bNode *node; + + /* nodetree itself */ + if (ntree->adt && ntree->adt->drivers.first) + BKE_animsys_evaluate_animdata(scene, &ntree->id, ntree->adt, ctime, ADT_RECALC_DRIVERS); + + /* nodes */ + for (node = ntree->nodes.first; node; node = node->next) + if (node->id && node->type == NODE_GROUP) + lamp_node_drivers_update(scene, (bNodeTree *)node->id, ctime); +} + +void lamp_drivers_update(Scene *scene, Lamp *la, float ctime) +{ + /* Prevent infinite recursion by checking (and tagging the lamp) as having been visited already + * (see BKE_scene_update_tagged()). This assumes la->id.flag & LIB_DOIT isn't set by anything else + * in the meantime... [#32017] */ + if (la->id.flag & LIB_DOIT) + return; + else + la->id.flag |= LIB_DOIT; + + /* lamp itself */ + if (la->adt && la->adt->drivers.first) + BKE_animsys_evaluate_animdata(scene, &la->id, la->adt, ctime, ADT_RECALC_DRIVERS); + + /* nodes */ + if (la->nodetree) + lamp_node_drivers_update(scene, la->nodetree, ctime); +} + diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index 942e71b5052..eb0612a75bd 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -998,7 +998,6 @@ void free_main(Main *mainvar) #endif } } - a = set_listbasepointers(mainvar, lbarray); MEM_freeN(mainvar); } @@ -1521,7 +1520,9 @@ void test_idbutton(char *name) /* search for id */ idtest = BLI_findstring(lb, name, offsetof(ID, name) + 2); - if (idtest) if (new_id(lb, idtest, name) == 0) id_sort_by_name(lb, idtest); + if (idtest && (new_id(lb, idtest, name) == 0)) { + id_sort_by_name(lb, idtest); + } } void text_idbutton(struct ID *id, char *text) diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index b7f4c4bd61e..bda924060d5 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -1416,7 +1416,7 @@ void BKE_mask_layer_evaluate(MaskLayer *masklay, const float ctime, const int do for (spline = masklay->splines.first; spline; spline = spline->next) { int i; - int has_auto = FALSE; + int need_handle_recalc = FALSE; BKE_mask_spline_ensure_deform(spline); @@ -1436,16 +1436,16 @@ void BKE_mask_layer_evaluate(MaskLayer *masklay, const float ctime, const int do add_v2_v2(point_deform->bezt.vec[2], delta); } - if (point->bezt.h1 == HD_AUTO) { - has_auto = TRUE; + if (ELEM(point->bezt.h1, HD_AUTO, HD_VECT)) { + need_handle_recalc = TRUE; } } - /* if the spline has auto handles, these need to be recalculated after deformation */ - if (has_auto) { + /* if the spline has auto or vector handles, these need to be recalculated after deformation */ + if (need_handle_recalc) { for (i = 0; i < spline->tot_point; i++) { MaskSplinePoint *point_deform = &spline->points_deform[i]; - if (point_deform->bezt.h1 == HD_AUTO) { + if (ELEM(point_deform->bezt.h1, HD_AUTO, HD_VECT)) { BKE_mask_calc_handle_point(spline, point_deform); } } diff --git a/source/blender/blenkernel/intern/mask_evaluate.c b/source/blender/blenkernel/intern/mask_evaluate.c index e67df9c6419..a2f6b3c1929 100644 --- a/source/blender/blenkernel/intern/mask_evaluate.c +++ b/source/blender/blenkernel/intern/mask_evaluate.c @@ -245,7 +245,7 @@ static void feather_bucket_add_edge(FeatherEdgesBucket *bucket, int start, int e } else { bucket->segments = MEM_reallocN(bucket->segments, - (alloc_delta + bucket->tot_segment) * sizeof(*bucket->segments)); + (alloc_delta + bucket->tot_segment) * sizeof(*bucket->segments)); } bucket->alloc_segment += alloc_delta; @@ -289,10 +289,10 @@ static void feather_bucket_check_intersect(float (*feather_points)[2], int tot_f /* collapse loop with smaller AABB */ for (k = 0; k < tot_feather_point; k++) { if (k >= check_b && k <= cur_a) { - DO_MINMAX2(feather_points[k], min_a, max_a); + minmax_v2v2_v2(min_a, max_a, feather_points[k]); } else { - DO_MINMAX2(feather_points[k], min_b, max_b); + minmax_v2v2_v2(min_b, max_b, feather_points[k]); } } @@ -379,7 +379,7 @@ void BKE_mask_spline_feather_collapse_inner_loops(MaskSpline *spline, float (*fe int next = i + 1; float delta; - DO_MINMAX2(feather_points[i], min, max); + minmax_v2v2_v2(min, max, feather_points[i]); if (next == tot_feather_point) { if (spline->flag & MASK_SPLINE_CYCLIC) diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c index 88393fab79c..2fa928e7c07 100644 --- a/source/blender/blenkernel/intern/mask_rasterize.c +++ b/source/blender/blenkernel/intern/mask_rasterize.c @@ -933,7 +933,7 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas } /* main scan-fill */ - sf_tri_tot = BLI_scanfill_calc_ex(&sf_ctx, FALSE, zvec); + sf_tri_tot = BLI_scanfill_calc_ex(&sf_ctx, 0, zvec); face_array = MEM_mallocN(sizeof(*face_array) * (sf_tri_tot + tot_feather_quads), "maskrast_face_index"); face_index = 0; diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index 6d44473583f..036f8f5e673 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -2388,7 +2388,7 @@ void create_vert_poly_map(MeshElemMap **map, int **mem, * of edges that use that vertex as an endpoint. The lists are allocated * from one memory pool. */ void create_vert_edge_map(MeshElemMap **map, int **mem, - const MEdge *medge, int totvert, int totedge) + const MEdge *medge, int totvert, int totedge) { int i, *indices; @@ -2607,7 +2607,7 @@ int BKE_mesh_recalc_tessellation(CustomData *fdata, } BLI_scanfill_edge_add(&sf_ctx, sf_vert_last, sf_vert_first); - totfilltri = BLI_scanfill_calc(&sf_ctx, FALSE); + totfilltri = BLI_scanfill_calc(&sf_ctx, 0); if (totfilltri) { BLI_array_grow_items(mface_to_poly_map, totfilltri); BLI_array_grow_items(mface, totfilltri); @@ -3011,7 +3011,7 @@ float BKE_mesh_calc_poly_area(MPoly *mpoly, MLoop *loopstart, MLoop *l_iter = loopstart; float area, polynorm_local[3], (*vertexcos)[3]; const float *no = polynormal ? polynormal : polynorm_local; - BLI_array_fixedstack_declare(vertexcos, BM_NGON_STACK_SIZE, mpoly->totloop, __func__); + BLI_array_fixedstack_declare(vertexcos, BM_DEFAULT_NGON_STACK_SIZE, mpoly->totloop, __func__); /* pack vertex cos into an array for area_poly_v3 */ for (i = 0; i < mpoly->totloop; i++, l_iter++) { diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 9c7cbc42bdd..25b70ce1793 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -249,13 +249,13 @@ int modifier_couldBeCage(struct Scene *scene, ModifierData *md) modifier_supportsMapping(md)); } -int modifier_sameTopology(ModifierData *md) +int modifier_isSameTopology(ModifierData *md) { ModifierTypeInfo *mti = modifierType_getInfo(md->type); return ELEM(mti->type, eModifierTypeType_OnlyDeform, eModifierTypeType_NonGeometrical); } -int modifier_nonGeometrical(ModifierData *md) +int modifier_isNonGeometrical(ModifierData *md) { ModifierTypeInfo *mti = modifierType_getInfo(md->type); return (mti->type == eModifierTypeType_NonGeometrical); diff --git a/source/blender/blenkernel/intern/modifiers_bmesh.c b/source/blender/blenkernel/intern/modifiers_bmesh.c index 98eac9b95af..381e4350391 100644 --- a/source/blender/blenkernel/intern/modifiers_bmesh.c +++ b/source/blender/blenkernel/intern/modifiers_bmesh.c @@ -79,7 +79,7 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) /*do verts*/ mv = mvert = dm->dupVertArray(dm); for (i = 0; i < totvert; i++, mv++) { - v = BM_vert_create(bm, mv->co, NULL); + v = BM_vert_create(bm, mv->co, NULL, BM_CREATE_SKIP_CD); normal_short_to_float_v3(v->no, mv->no); v->head.hflag = BM_vert_flag_from_mflag(mv->flag); BM_elem_index_set(v, i); /* set_inline */ @@ -97,7 +97,7 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) me = medge = dm->dupEdgeArray(dm); for (i = 0; i < totedge; i++, me++) { //BLI_assert(BM_edge_exists(vtable[me->v1], vtable[me->v2]) == NULL); - e = BM_edge_create(bm, vtable[me->v1], vtable[me->v2], NULL, FALSE); + e = BM_edge_create(bm, vtable[me->v1], vtable[me->v2], NULL, BM_CREATE_SKIP_CD); e->head.hflag = BM_edge_flag_from_mflag(me->flag); BM_elem_index_set(e, i); /* set_inline */ @@ -134,7 +134,7 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) edges[j] = etable[ml->e]; } - f = BM_face_create_ngon(bm, verts[0], verts[1], edges, mp->totloop, FALSE); + f = BM_face_create_ngon(bm, verts[0], verts[1], edges, mp->totloop, BM_CREATE_SKIP_CD); if (UNLIKELY(f == NULL)) { continue; diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c index 6e8f2697ee1..4156b5b4367 100644 --- a/source/blender/blenkernel/intern/movieclip.c +++ b/source/blender/blenkernel/intern/movieclip.c @@ -1176,13 +1176,16 @@ void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClip search_ibuf = BKE_tracking_get_search_imbuf(ibuf, track, &undist_marker, TRUE, TRUE); - if (!search_ibuf->rect_float) { - /* sampling happens in float buffer */ - IMB_float_from_rect(search_ibuf); + if (search_ibuf) { + if (!search_ibuf->rect_float) { + /* sampling happens in float buffer */ + IMB_float_from_rect(search_ibuf); + } + + scopes->track_search = search_ibuf; } scopes->undist_marker = undist_marker; - scopes->track_search = search_ibuf; scopes->frame_width = ibuf->x; scopes->frame_height = ibuf->y; diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c index 66f2ff12258..c737dccc5d2 100644 --- a/source/blender/blenkernel/intern/multires.c +++ b/source/blender/blenkernel/intern/multires.c @@ -984,7 +984,7 @@ static void grid_tangent(const CCGKey *key, int x, int y, int axis, CCGElem *gri /* Construct 3x3 tangent-space matrix in 'mat' */ static void grid_tangent_matrix(float mat[3][3], const CCGKey *key, - int x, int y, CCGElem *grid) + int x, int y, CCGElem *grid) { grid_tangent(key, x, y, 0, grid, mat[0]); normalize_v3(mat[0]); diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 153eb5271c5..17dcf34b71f 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -38,9 +38,13 @@ #include "DNA_action_types.h" #include "DNA_anim_types.h" +#include "DNA_lamp_types.h" +#include "DNA_material_types.h" #include "DNA_node_types.h" #include "DNA_node_types.h" #include "DNA_scene_types.h" +#include "DNA_texture_types.h" +#include "DNA_world_types.h" #include "BLI_string.h" #include "BLI_math.h" @@ -406,13 +410,14 @@ bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node) /* only shader nodes get pleasant preview updating this way, compo uses own system */ if (node->preview) { - if (ntree->type == NTREE_SHADER) { + if (ntree && (ntree->type == NTREE_SHADER)) { nnode->preview = MEM_dupallocN(node->preview); if (node->preview->rect) nnode->preview->rect = MEM_dupallocN(node->preview->rect); } - else + else { nnode->preview = NULL; + } } if (ntree) @@ -1153,6 +1158,18 @@ void ntreeSetOutput(bNodeTree *ntree) * might be different for editor or for "real" use... */ } +bNodeTree *ntreeFromID(ID *id) +{ + switch (GS(id->name)) { + case ID_MA: return ((Material*)id)->nodetree; + case ID_LA: return ((Lamp*)id)->nodetree; + case ID_WO: return ((World*)id)->nodetree; + case ID_TE: return ((Tex*)id)->nodetree; + case ID_SCE: return ((Scene*)id)->nodetree; + default: return NULL; + } +} + typedef struct MakeLocalCallData { ID *group_id; ID *new_id; @@ -2153,8 +2170,6 @@ static void registerCompositNodes(bNodeTreeType *ttype) register_node_type_reroute(ttype); register_node_type_cmp_group(ttype); -// register_node_type_cmp_forloop(ttype); -// register_node_type_cmp_whileloop(ttype); register_node_type_cmp_rlayers(ttype); register_node_type_cmp_image(ttype); @@ -2184,6 +2199,7 @@ static void registerCompositNodes(bNodeTreeType *ttype) register_node_type_cmp_normal(ttype); register_node_type_cmp_curve_vec(ttype); register_node_type_cmp_map_value(ttype); + register_node_type_cmp_map_range(ttype); register_node_type_cmp_normalize(ttype); register_node_type_cmp_filter(ttype); @@ -2254,8 +2270,6 @@ static void registerShaderNodes(bNodeTreeType *ttype) register_node_type_reroute(ttype); register_node_type_sh_group(ttype); - //register_node_type_sh_forloop(ttype); - //register_node_type_sh_whileloop(ttype); register_node_type_sh_output(ttype); register_node_type_sh_material(ttype); @@ -2293,17 +2307,21 @@ static void registerShaderNodes(bNodeTreeType *ttype) register_node_type_sh_particle_info(ttype); register_node_type_sh_bump(ttype); register_node_type_sh_script(ttype); + register_node_type_sh_tangent(ttype); + register_node_type_sh_normal_map(ttype); register_node_type_sh_background(ttype); register_node_type_sh_bsdf_anisotropic(ttype); register_node_type_sh_bsdf_diffuse(ttype); register_node_type_sh_bsdf_glossy(ttype); register_node_type_sh_bsdf_glass(ttype); + register_node_type_sh_bsdf_refraction(ttype); register_node_type_sh_bsdf_translucent(ttype); register_node_type_sh_bsdf_transparent(ttype); register_node_type_sh_bsdf_velvet(ttype); register_node_type_sh_emission(ttype); register_node_type_sh_holdout(ttype); + register_node_type_sh_ambient_occlusion(ttype); //register_node_type_sh_volume_transparent(ttype); //register_node_type_sh_volume_isotropic(ttype); register_node_type_sh_mix_shader(ttype); @@ -2332,8 +2350,6 @@ static void registerTextureNodes(bNodeTreeType *ttype) register_node_type_reroute(ttype); register_node_type_tex_group(ttype); -// register_node_type_tex_forloop(ttype); -// register_node_type_tex_whileloop(ttype); register_node_type_tex_math(ttype); register_node_type_tex_mix_rgb(ttype); diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 0611e84bdf3..47ca502d247 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -196,18 +196,18 @@ int BKE_object_support_modifier_type_check(Object *ob, int modifier_type) return TRUE; } -void BKE_object_link_modifiers(struct Object *ob, struct Object *from) +void BKE_object_link_modifiers(struct Object *ob_dst, struct Object *ob_src) { ModifierData *md; - BKE_object_free_modifiers(ob); + BKE_object_free_modifiers(ob_dst); - if (!ELEM5(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_LATTICE)) { + if (!ELEM5(ob_dst->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_LATTICE)) { /* only objects listed above can have modifiers and linking them to objects * which doesn't have modifiers stack is quite silly */ return; } - for (md = from->modifiers.first; md; md = md->next) { + for (md = ob_src->modifiers.first; md; md = md->next) { ModifierData *nmd = NULL; if (ELEM4(md->type, @@ -219,16 +219,18 @@ void BKE_object_link_modifiers(struct Object *ob, struct Object *from) continue; } - if (!BKE_object_support_modifier_type_check(ob, md->type)) + if (!BKE_object_support_modifier_type_check(ob_dst, md->type)) continue; nmd = modifier_new(md->type); + BLI_strncpy(nmd->name, md->name, sizeof(nmd->name)); modifier_copyData(md, nmd); - BLI_addtail(&ob->modifiers, nmd); + BLI_addtail(&ob_dst->modifiers, nmd); + modifier_unique_name(&ob_dst->modifiers, nmd); } - BKE_object_copy_particlesystems(ob, from); - BKE_object_copy_softbody(ob, from); + BKE_object_copy_particlesystems(ob_dst, ob_src); + BKE_object_copy_softbody(ob_dst, ob_src); /* TODO: smoke?, cloth? */ } @@ -2654,6 +2656,8 @@ void BKE_object_handle_update(Scene *scene, Object *ob) } } } + else if (ob->type == OB_LAMP) + lamp_drivers_update(scene, ob->data, ctime); /* particles */ if (ob->particlesystem.first) { diff --git a/source/blender/blenkernel/intern/ocean.c b/source/blender/blenkernel/intern/ocean.c index 7bc736d394e..e694a7e7eb3 100644 --- a/source/blender/blenkernel/intern/ocean.c +++ b/source/blender/blenkernel/intern/ocean.c @@ -183,7 +183,7 @@ MINLINE float catrom(float p0, float p1, float p2, float p3, float f) MINLINE float omega(float k, float depth) { - return sqrt(GRAVITY * k * tanh(k * depth)); + return sqrtf(GRAVITY * k * tanhf(k * depth)); } // modified Phillips spectrum @@ -256,8 +256,8 @@ static void add_comlex_c(fftw_complex res, fftw_complex cmpl1, fftw_complex cmpl static void mul_complex_f(fftw_complex res, fftw_complex cmpl, float f) { - res[0] = cmpl[0] * f; - res[1] = cmpl[1] * f; + res[0] = cmpl[0] * (double)f; + res[1] = cmpl[1] * (double)f; } static void mul_complex_c(fftw_complex res, fftw_complex cmpl1, fftw_complex cmpl2) @@ -289,8 +289,8 @@ static void exp_complex(fftw_complex res, fftw_complex cmpl) { float r = expf(cmpl[0]); - res[0] = cos(cmpl[1]) * r; - res[1] = sin(cmpl[1]) * r; + res[0] = cosf(cmpl[1]) * r; + res[1] = sinf(cmpl[1]) * r; } float BKE_ocean_jminus_to_foam(float jminus, float coverage) @@ -462,7 +462,7 @@ void BKE_ocean_eval_ij(struct Ocean *oc, struct OceanResult *ocr, int i, int j) i = abs(i) % oc->_M; j = abs(j) % oc->_N; - ocr->disp[1] = oc->_do_disp_y ? oc->_disp_y[i * oc->_N + j] : 0.0f; + ocr->disp[1] = oc->_do_disp_y ? (float)oc->_disp_y[i * oc->_N + j] : 0.0f; if (oc->_do_chop) { ocr->disp[0] = oc->_disp_x[i * oc->_N + j]; @@ -546,7 +546,7 @@ void BKE_simulate_ocean(struct Ocean *o, float t, float scale, float chop_amount mul_complex_f(mul_param, mul_param, chop_amount); mul_complex_c(mul_param, mul_param, minus_i); mul_complex_c(mul_param, mul_param, o->_htilda[i * (1 + o->_N / 2) + j]); - mul_complex_f(mul_param, mul_param, (o->_k[i * (1 + o->_N / 2) + j] == 0.0 ? 0.0 : o->_kx[i] / o->_k[i * (1 + o->_N / 2) + j])); + mul_complex_f(mul_param, mul_param, (o->_k[i * (1 + o->_N / 2) + j] == 0.0f ? 0.0f : o->_kx[i] / o->_k[i * (1 + o->_N / 2) + j])); init_complex(o->_fft_in_x[i * (1 + o->_N / 2) + j], real_c(mul_param), image_c(mul_param)); } } @@ -568,7 +568,7 @@ void BKE_simulate_ocean(struct Ocean *o, float t, float scale, float chop_amount mul_complex_f(mul_param, mul_param, chop_amount); mul_complex_c(mul_param, mul_param, minus_i); mul_complex_c(mul_param, mul_param, o->_htilda[i * (1 + o->_N / 2) + j]); - mul_complex_f(mul_param, mul_param, (o->_k[i * (1 + o->_N / 2) + j] == 0.0 ? 0.0 : o->_kz[j] / o->_k[i * (1 + o->_N / 2) + j])); + mul_complex_f(mul_param, mul_param, (o->_k[i * (1 + o->_N / 2) + j] == 0.0f ? 0.0f : o->_kz[j] / o->_k[i * (1 + o->_N / 2) + j])); init_complex(o->_fft_in_z[i * (1 + o->_N / 2) + j], real_c(mul_param), image_c(mul_param)); } } @@ -589,7 +589,7 @@ void BKE_simulate_ocean(struct Ocean *o, float t, float scale, float chop_amount mul_complex_f(mul_param, mul_param, chop_amount); mul_complex_c(mul_param, mul_param, o->_htilda[i * (1 + o->_N / 2) + j]); - mul_complex_f(mul_param, mul_param, (o->_k[i * (1 + o->_N / 2) + j] == 0.0 ? 0.0 : o->_kx[i] * o->_kx[i] / o->_k[i * (1 + o->_N / 2) + j])); + mul_complex_f(mul_param, mul_param, (o->_k[i * (1 + o->_N / 2) + j] == 0.0f ? 0.0f : o->_kx[i] * o->_kx[i] / o->_k[i * (1 + o->_N / 2) + j])); init_complex(o->_fft_in_jxx[i * (1 + o->_N / 2) + j], real_c(mul_param), image_c(mul_param)); } } @@ -616,7 +616,7 @@ void BKE_simulate_ocean(struct Ocean *o, float t, float scale, float chop_amount mul_complex_f(mul_param, mul_param, chop_amount); mul_complex_c(mul_param, mul_param, o->_htilda[i * (1 + o->_N / 2) + j]); - mul_complex_f(mul_param, mul_param, (o->_k[i * (1 + o->_N / 2) + j] == 0.0 ? 0.0 : o->_kz[j] * o->_kz[j] / o->_k[i * (1 + o->_N / 2) + j])); + mul_complex_f(mul_param, mul_param, (o->_k[i * (1 + o->_N / 2) + j] == 0.0f ? 0.0f : o->_kz[j] * o->_kz[j] / o->_k[i * (1 + o->_N / 2) + j])); init_complex(o->_fft_in_jzz[i * (1 + o->_N / 2) + j], real_c(mul_param), image_c(mul_param)); } } diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index d645204d29c..5f5a713064d 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -822,8 +822,8 @@ int psys_render_simplify_distribution(ParticleThreadContext *ctx, int tot) index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX); index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX); - if ((index_mf_to_mpoly && index_mp_to_orig) == FALSE) { - index_mf_to_mpoly = index_mp_to_orig = NULL; + if (index_mf_to_mpoly == NULL) { + index_mp_to_orig = NULL; } facearea = MEM_callocN(sizeof(float) * totorigface, "SimplifyFaceArea"); @@ -1645,8 +1645,8 @@ int psys_particle_dm_face_lookup(Object *ob, DerivedMesh *dm, int index, const f /* double lookup */ const int *index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX); const int *index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX); - if ((index_mf_to_mpoly && index_mp_to_orig) == FALSE) { - index_mf_to_mpoly = index_mp_to_orig = NULL; + if (index_mf_to_mpoly == NULL) { + index_mp_to_orig = NULL; } mpoly = dm->getPolyArray(dm); @@ -3786,14 +3786,22 @@ static int get_particle_uv(DerivedMesh *dm, ParticleData *pa, int face_index, co return 1; } -#define SET_PARTICLE_TEXTURE(type, pvalue, texfac) \ - if ((event & mtex->mapto) & type) { pvalue = texture_value_blend(def, pvalue, value, texfac, blend); } (void)0 +#define SET_PARTICLE_TEXTURE(type, pvalue, texfac) \ + if ((event & mtex->mapto) & type) { \ + pvalue = texture_value_blend(def, pvalue, value, texfac, blend); \ + } (void)0 -#define CLAMP_PARTICLE_TEXTURE_POS(type, pvalue) \ - if (event & type) { if (pvalue < 0.0f) pvalue = 1.0f + pvalue; CLAMP(pvalue, 0.0f, 1.0f); } (void)0 +#define CLAMP_PARTICLE_TEXTURE_POS(type, pvalue) \ + if (event & type) { \ + if (pvalue < 0.0f) \ + pvalue = 1.0f + pvalue; \ + CLAMP(pvalue, 0.0f, 1.0f); \ + } (void)0 -#define CLAMP_PARTICLE_TEXTURE_POSNEG(type, pvalue) \ - if (event & type) { CLAMP(pvalue, -1.0f, 1.0f); } (void)0 +#define CLAMP_PARTICLE_TEXTURE_POSNEG(type, pvalue) \ + if (event & type) { \ + CLAMP(pvalue, -1.0f, 1.0f); \ + } (void)0 static void get_cpa_texture(DerivedMesh *dm, ParticleSystem *psys, ParticleSettings *part, ParticleData *par, int child_index, int face_index, const float fw[4], float *orco, ParticleTexture *ptex, int event, float cfra) { @@ -3802,8 +3810,8 @@ static void get_cpa_texture(DerivedMesh *dm, ParticleSystem *psys, ParticleSetti float value, rgba[4], texvec[3]; ptex->ivel = ptex->life = ptex->exist = ptex->size = ptex->damp = - ptex->gravity = ptex->field = ptex->time = ptex->clump = ptex->kink = - ptex->effector = ptex->rough1 = ptex->rough2 = ptex->roughe = 1.f; + ptex->gravity = ptex->field = ptex->time = ptex->clump = ptex->kink = + ptex->effector = ptex->rough1 = ptex->rough2 = ptex->roughe = 1.0f; ptex->length = 1.0f - part->randlength * PSYS_FRAND(child_index + 26); ptex->length *= part->clength_thres < PSYS_FRAND(child_index + 27) ? part->clength : 1.0f; diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 2b95946f571..90889d7c09e 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -367,11 +367,12 @@ void psys_calc_dmcache(Object *ob, DerivedMesh *dm, ParticleSystem *psys) nodedmelem= MEM_callocN(sizeof(LinkNode)*totdmelem, "psys node elems"); nodearray= MEM_callocN(sizeof(LinkNode *)*totelem, "psys node array"); - for (i=0, node=nodedmelem; ilink = SET_INT_IN_POINTER(i); - origindex_final = *origindex; + /* may be vertex or face origindex */ + origindex_final = origindex ? origindex[i] : ORIGINDEX_NONE; /* if we have a poly source, do an index lookup */ if (origindex_poly && origindex_final != ORIGINDEX_NONE) { @@ -466,13 +467,7 @@ static void distribute_grid(DerivedMesh *dm, ParticleSystem *psys) mv++; for (i=1; ico[0]); - min[1]=MIN2(min[1],mv->co[1]); - min[2]=MIN2(min[2],mv->co[2]); - - max[0]=MAX2(max[0],mv->co[0]); - max[1]=MAX2(max[1],mv->co[1]); - max[2]=MAX2(max[2],mv->co[2]); + minmax_v3v3_v3(min, max, mv->co); } sub_v3_v3v3(delta, max, min); @@ -2145,16 +2140,22 @@ static void psys_update_effectors(ParticleSimulationData *sim) precalc_guides(sim, sim->psys->effectors); } -static void integrate_particle(ParticleSettings *part, ParticleData *pa, float dtime, float *external_acceleration, void (*force_func)(void *forcedata, ParticleKey *state, float *force, float *impulse), void *forcedata) +static void integrate_particle(ParticleSettings *part, ParticleData *pa, float dtime, float *external_acceleration, + void (*force_func)(void *forcedata, ParticleKey *state, float *force, float *impulse), + void *forcedata) { +#define ZERO_F43 {{0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}} + ParticleKey states[5]; - float force[3],acceleration[3],impulse[3],dx[4][3],dv[4][3],oldpos[3]; + float force[3], acceleration[3], impulse[3], dx[4][3] = ZERO_F43, dv[4][3] = ZERO_F43, oldpos[3]; float pa_mass= (part->flag & PART_SIZEMASS ? part->mass * pa->size : part->mass); int i, steps=1; int integrator = part->integrator; +#undef ZERO_F43 + copy_v3_v3(oldpos, pa->state.co); - + /* Verlet integration behaves strangely with moving emitters, so do first step with euler. */ if (pa->prev_state.time < 0.f && integrator == PART_INT_VERLET) integrator = PART_INT_EULER; diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index f195b3d71b0..965a1e2b4a6 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -686,7 +686,7 @@ static int ptcache_smoke_read(PTCacheFile *pf, void *smoke_v) /* reallocate fluid if needed*/ if (reallocate) { - sds->active_fields = active_fields; + sds->active_fields = active_fields | cache_fields; smoke_reallocate_fluid(sds, ch_dx, ch_res, 1); sds->dx = ch_dx; VECCOPY(sds->res, ch_res); @@ -755,6 +755,7 @@ static int ptcache_smoke_read(PTCacheFile *pf, void *smoke_v) if (cache_fields & SM_ACTIVE_FIRE) { ptcache_file_compressed_read(pf, (unsigned char *)flame, out_len_big); ptcache_file_compressed_read(pf, (unsigned char *)fuel, out_len_big); + ptcache_file_compressed_read(pf, (unsigned char *)react, out_len_big); } if (cache_fields & SM_ACTIVE_COLORS) { ptcache_file_compressed_read(pf, (unsigned char *)r, out_len_big); @@ -2568,10 +2569,12 @@ int BKE_ptcache_id_reset(Scene *scene, PTCacheID *pid, int mode) sbFreeSimulation(pid->calldata); else if (pid->type == PTCACHE_TYPE_PARTICLES) psys_reset(pid->calldata, PSYS_RESET_DEPSGRAPH); - /*else if (pid->type == PTCACHE_TYPE_SMOKE_DOMAIN) +#if 0 + else if (pid->type == PTCACHE_TYPE_SMOKE_DOMAIN) smokeModifier_reset(pid->calldata); else if (pid->type == PTCACHE_TYPE_SMOKE_HIGHRES) - smokeModifier_reset_turbulence(pid->calldata);*/ + smokeModifier_reset_turbulence(pid->calldata); +#endif else if (pid->type == PTCACHE_TYPE_DYNAMICPAINT) dynamicPaint_clearSurface((DynamicPaintSurface*)pid->calldata); } diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index a1918b77a1e..9bb2fb2de52 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -58,8 +58,10 @@ #include "BKE_anim.h" #include "BKE_animsys.h" +#include "BKE_action.h" #include "BKE_colortools.h" #include "BKE_depsgraph.h" +#include "BKE_fcurve.h" #include "BKE_global.h" #include "BKE_group.h" #include "BKE_idprop.h" @@ -115,6 +117,24 @@ void free_qtcodecdata(QuicktimeCodecData *qcd) } } +static void remove_sequencer_fcurves(Scene *sce) +{ + AnimData *adt = BKE_animdata_from_id(&sce->id); + + if (adt && adt->action) { + FCurve *fcu, *nextfcu; + + for (fcu = adt->action->curves.first; fcu; fcu = nextfcu) { + nextfcu = fcu->next; + + if ((fcu->rna_path) && strstr(fcu->rna_path, "sequences_all")) { + action_groups_remove_channel(adt->action, fcu); + free_fcurve(fcu); + } + } + } +} + Scene *BKE_scene_copy(Scene *sce, int type) { Scene *scen; @@ -179,6 +199,10 @@ Scene *BKE_scene_copy(Scene *sce, int type) BLI_strncpy(scen->sequencer_colorspace_settings.name, sce->sequencer_colorspace_settings.name, sizeof(scen->sequencer_colorspace_settings.name)); + + /* remove animation used by sequencer */ + if (type != SCE_COPY_FULL) + remove_sequencer_fcurves(scen); } /* tool settings */ @@ -377,6 +401,7 @@ Scene *BKE_scene_add(const char *name) sce->r.im_format.planes = R_IMF_PLANES_RGB; sce->r.im_format.imtype = R_IMF_IMTYPE_PNG; sce->r.im_format.quality = 90; + sce->r.im_format.compress = 90; sce->r.displaymode = R_OUTPUT_AREA; sce->r.framapto = 100; @@ -1019,8 +1044,10 @@ static void scene_update_tagged_recursive(Main *bmain, Scene *scene, Scene *scen if (ob->dup_group && (ob->transflag & OB_DUPLIGROUP)) group_handle_recalc_and_update(scene_parent, ob, ob->dup_group); - /* always update layer, so that animating layers works */ - base->lay = ob->lay; + /* always update layer, so that animating layers works (joshua july 2010) */ + /* XXX commented out, this has depsgraph issues anyway - and this breaks setting scenes + * (on scene-set, the base-lay is copied to ob-lay (ton nov 2012) */ + // base->lay = ob->lay; } /* scene drivers... */ @@ -1048,6 +1075,7 @@ void BKE_scene_update_tagged(Main *bmain, Scene *scene) * when trying to find materials with drivers that need evaluating [#32017] */ tag_main_idcode(bmain, ID_MA, FALSE); + tag_main_idcode(bmain, ID_LA, FALSE); /* update all objects: drivers, matrices, displists, etc. flags set * by depgraph or manual, no layer check here, gets correct flushed @@ -1117,6 +1145,7 @@ void BKE_scene_update_for_newframe(Main *bmain, Scene *sce, unsigned int lay) * when trying to find materials with drivers that need evaluating [#32017] */ tag_main_idcode(bmain, ID_MA, FALSE); + tag_main_idcode(bmain, ID_LA, FALSE); /* BKE_object_handle_update() on all objects, groups and sets */ scene_update_tagged_recursive(bmain, sce, sce); diff --git a/source/blender/blenkernel/intern/seqeffects.c b/source/blender/blenkernel/intern/seqeffects.c index 469881020c1..0b7fdaa7c1d 100644 --- a/source/blender/blenkernel/intern/seqeffects.c +++ b/source/blender/blenkernel/intern/seqeffects.c @@ -139,6 +139,9 @@ static ImBuf *prepare_effect_imbufs(SeqRenderData context, ImBuf *ibuf1, ImBuf * IMB_rect_from_float(ibuf3); } + if (out->rect_float) + IMB_colormanagement_assign_float_colorspace(out, context.scene->sequencer_colorspace_settings.name); + return out; } diff --git a/source/blender/blenkernel/intern/seqmodifier.c b/source/blender/blenkernel/intern/seqmodifier.c index b0dcad64722..5b2e9f2bf23 100644 --- a/source/blender/blenkernel/intern/seqmodifier.c +++ b/source/blender/blenkernel/intern/seqmodifier.c @@ -349,9 +349,9 @@ static void hue_correct_apply_threaded(int width, int height, unsigned char *rec hsv_to_rgb(hsv[0], hsv[1], hsv[2], result, result + 1, result + 2); if (mask_rect_float) - copy_v3_v3(mask, mask_rect_float + pixel_index); + copy_v3_v3(mask, mask_rect_float + pixel_index); else if (mask_rect) - rgb_uchar_to_float(mask, mask_rect + pixel_index); + rgb_uchar_to_float(mask, mask_rect + pixel_index); result[0] = pixel[0] * (1.0f - mask[0]) + result[0] * mask[0]; result[1] = pixel[1] * (1.0f - mask[1]) + result[1] * mask[1]; @@ -427,17 +427,17 @@ static void brightcontrast_apply_threaded(int width, int height, unsigned char * unsigned char *pixel = rect + pixel_index; for (c = 0; c < 3; c++) { - i = pixel[c]; + i = (float) pixel[c] / 255.0f; v = a * i + b; if (mask_rect) { unsigned char *m = mask_rect + pixel_index; float t = (float) m[c] / 255.0f; - pixel[c] = pixel[c] * (1.0f - t) + v * t; + v = (float) pixel[c] * (1.0f - t) + v * t; } - else - pixel[c] = v; + + pixel[c] = FTOCHAR(v); } } else if (rect_float) { diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index af0cab98fe0..acce3740c98 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -1835,6 +1835,8 @@ static ImBuf *input_preprocess(SeqRenderData context, Sequence *seq, float cfra, StripCrop c = {0}; StripTransform t = {0}; int sx, sy, dx, dy; + double xscale = 1.0; + double yscale = 1.0; if (is_proxy_image) { double f = seq_rendersize_to_scale_factor(context.preview_render_size); @@ -1851,6 +1853,17 @@ static ImBuf *input_preprocess(SeqRenderData context, Sequence *seq, float cfra, t = *seq->strip->transform; } + xscale = context.scene->r.xsch ? ((double)context.rectx / (double)context.scene->r.xsch) : 1.0; + yscale = context.scene->r.ysch ? ((double)context.recty / (double)context.scene->r.ysch) : 1.0; + + xscale /= (double)context.rectx / (double)ibuf->x; + yscale /= (double)context.recty / (double)ibuf->y; + + c.left *= xscale; c.right *= xscale; + c.top *= yscale; c.bottom *= yscale; + + t.xofs *= xscale; t.yofs *= yscale; + sx = ibuf->x - c.left - c.right; sy = ibuf->y - c.top - c.bottom; dx = sx; @@ -2338,12 +2351,15 @@ static ImBuf *seq_render_scene_strip(SeqRenderData context, Sequence *seq, float */ const short is_rendering = G.is_rendering; + const short is_background = G.background; const int do_seq_gl = G.is_rendering ? 0 /* (context.scene->r.seq_flag & R_SEQ_GL_REND) */ : (context.scene->r.seq_flag & R_SEQ_GL_PREV); int do_seq; - int have_seq = FALSE; + // int have_seq = FALSE; /* UNUSED */ + int have_comp = FALSE; Scene *scene; + int is_thread_main = BLI_thread_is_main(); /* don't refer to seq->scene above this point!, it can be NULL */ if (seq->scene == NULL) { @@ -2353,7 +2369,8 @@ static ImBuf *seq_render_scene_strip(SeqRenderData context, Sequence *seq, float scene = seq->scene; frame = scene->r.sfra + nr + seq->anim_startofs; - have_seq = (scene->r.scemode & R_DOSEQ) && scene->ed && scene->ed->seqbase.first; + // have_seq = (scene->r.scemode & R_DOSEQ) && scene->ed && scene->ed->seqbase.first; /* UNUSED */ + have_comp = (scene->r.scemode & R_DOCOMP) && scene->use_nodes && scene->nodetree; oldcfra = scene->r.cfra; scene->r.cfra = frame; @@ -2366,14 +2383,14 @@ static ImBuf *seq_render_scene_strip(SeqRenderData context, Sequence *seq, float camera = scene->camera; } - if (have_seq == FALSE && camera == NULL) { + if (have_comp == FALSE && camera == NULL) { scene->r.cfra = oldcfra; return NULL; } /* prevent eternal loop */ do_seq = context.scene->r.scemode & R_DOSEQ; - context.scene->r.scemode &= ~R_DOSEQ; + scene->r.scemode &= ~R_DOSEQ; #ifdef DURIAN_CAMERA_SWITCH /* stooping to new low's in hackyness :( */ @@ -2383,10 +2400,7 @@ static ImBuf *seq_render_scene_strip(SeqRenderData context, Sequence *seq, float (void)oldmarkers; #endif - if ((sequencer_view3d_cb && do_seq_gl && camera) && - (BLI_thread_is_main() == TRUE) && - ((have_seq == FALSE) || (scene == context.scene))) - { + if ((sequencer_view3d_cb && do_seq_gl && camera) && is_thread_main) { char err_out[256] = "unknown"; /* for old scened this can be uninitialized, * should probably be added to do_versions at some point if the functionality stays */ @@ -2405,11 +2419,19 @@ static ImBuf *seq_render_scene_strip(SeqRenderData context, Sequence *seq, float Render *re = RE_GetRender(scene->id.name); RenderResult rres; - /* XXX: this if can be removed when sequence preview rendering uses the job system */ - if (is_rendering || context.scene != scene) { + /* XXX: this if can be removed when sequence preview rendering uses the job system + * + * disable rendered preview for sequencer while rendering -- it's very much possible + * that preview render will went into conflict with final render + * + * When rendering from command line renderer is called from main thread, in this + * case it's always safe to render scene here + */ + if (!is_thread_main || is_rendering == FALSE || is_background) { if (re == NULL) re = RE_NewRender(scene->id.name); + BKE_scene_update_for_newframe(context.bmain, scene, scene->lay); RE_BlenderFrame(re, context.bmain, scene, NULL, camera, scene->lay, frame, FALSE); /* restore previous state after it was toggled on & off by RE_BlenderFrame */ @@ -2440,7 +2462,7 @@ static ImBuf *seq_render_scene_strip(SeqRenderData context, Sequence *seq, float } /* restore */ - context.scene->r.scemode |= do_seq; + scene->r.scemode |= do_seq; scene->r.cfra = oldcfra; diff --git a/source/blender/blenkernel/intern/shrinkwrap.c b/source/blender/blenkernel/intern/shrinkwrap.c index 96faec389df..72db34d339c 100644 --- a/source/blender/blenkernel/intern/shrinkwrap.c +++ b/source/blender/blenkernel/intern/shrinkwrap.c @@ -56,33 +56,16 @@ #include "BKE_mesh.h" #include "BKE_tessmesh.h" -/* Util macros */ -#define OUT_OF_MEMORY() ((void)printf("Shrinkwrap: Out of memory\n")) - -/* Benchmark macros */ -#if !defined(_WIN32) && 0 - -#include - -#define BENCH(a) \ - do { \ - double _t1, _t2; \ - struct timeval _tstart, _tend; \ - clock_t _clock_init = clock(); \ - gettimeofday ( &_tstart, NULL); \ - (a); \ - gettimeofday ( &_tend, NULL); \ - _t1 = ( double ) _tstart.tv_sec + ( double ) _tstart.tv_usec/ ( 1000*1000 ); \ - _t2 = ( double ) _tend.tv_sec + ( double ) _tend.tv_usec/ ( 1000*1000 ); \ - printf("%s: %fs (real) %fs (cpu)\n", #a, _t2-_t1, (float)(clock()-_clock_init)/CLOCKS_PER_SEC);\ - } while (0) - +/* for timing... */ +#if 0 +# include "PIL_time.h" #else - -#define BENCH(a) (a) - +# define TIMEIT_BENCH(expr, id) (expr) #endif +/* Util macros */ +#define OUT_OF_MEMORY() ((void)printf("Shrinkwrap: Out of memory\n")) + /* get derived mesh */ /* TODO is anyfunction that does this? returning the derivedFinal without we caring if its in edit mode or not? */ DerivedMesh *object_get_derived_final(Object *ob) @@ -143,7 +126,7 @@ static void shrinkwrap_calc_nearest_vertex(ShrinkwrapCalcData *calc) BVHTreeNearest nearest = NULL_BVHTreeNearest; - BENCH(bvhtree_from_mesh_verts(&treeData, calc->target, 0.0, 2, 6)); + TIMEIT_BENCH(bvhtree_from_mesh_verts(&treeData, calc->target, 0.0, 2, 6), bvhtree_verts); if (treeData.tree == NULL) { OUT_OF_MEMORY(); return; @@ -294,6 +277,7 @@ static void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc) /* Options about projection direction */ const char use_normal = calc->smd->shrinkOpts; + const float proj_limit_squared = calc->smd->projLimit * calc->smd->projLimit; float proj_axis[3] = {0.0f, 0.0f, 0.0f}; /* Raycast and tree stuff */ @@ -410,6 +394,13 @@ static void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc) treeData.raycast_callback, &treeData); } + /* don't set the initial dist (which is more efficient), + * because its calculated in the targets space, we want the dist in our own space */ + if (proj_limit_squared != 0.0f) { + if (len_squared_v3v3(hit.co, co) > proj_limit_squared) { + hit.index = -1; + } + } if (hit.index != -1) { madd_v3_v3v3fl(hit.co, hit.co, tmp_no, calc->keepDist); @@ -437,7 +428,7 @@ static void shrinkwrap_calc_nearest_surface_point(ShrinkwrapCalcData *calc) BVHTreeNearest nearest = NULL_BVHTreeNearest; /* Create a bvh-tree of the given target */ - BENCH(bvhtree_from_mesh_faces(&treeData, calc->target, 0.0, 2, 6)); + TIMEIT_BENCH(bvhtree_from_mesh_faces(&treeData, calc->target, 0.0, 2, 6), bvhtree_faces); if (treeData.tree == NULL) { OUT_OF_MEMORY(); return; @@ -584,15 +575,15 @@ void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd, Object *ob, DerivedM if (calc.target) { switch (smd->shrinkType) { case MOD_SHRINKWRAP_NEAREST_SURFACE: - BENCH(shrinkwrap_calc_nearest_surface_point(&calc)); + TIMEIT_BENCH(shrinkwrap_calc_nearest_surface_point(&calc), deform_surface); break; case MOD_SHRINKWRAP_PROJECT: - BENCH(shrinkwrap_calc_normal_projection(&calc)); + TIMEIT_BENCH(shrinkwrap_calc_normal_projection(&calc), deform_project); break; case MOD_SHRINKWRAP_NEAREST_VERTEX: - BENCH(shrinkwrap_calc_nearest_vertex(&calc)); + TIMEIT_BENCH(shrinkwrap_calc_nearest_vertex(&calc), deform_vertex); break; } } diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c index 443aed1fc41..53dfbdcfb85 100644 --- a/source/blender/blenkernel/intern/smoke.c +++ b/source/blender/blenkernel/intern/smoke.c @@ -165,7 +165,7 @@ void flame_get_spectrum(unsigned char *UNUSED(spec), int UNUSED(width), float UN void smoke_reallocate_fluid(SmokeDomainSettings *sds, float dx, int res[3], int free_old) { int use_heat = (sds->active_fields & SM_ACTIVE_HEAT); - int use_fire = (sds->active_fields & (SM_ACTIVE_HEAT | SM_ACTIVE_FIRE)); + int use_fire = (sds->active_fields & SM_ACTIVE_FIRE); int use_colors = (sds->active_fields & SM_ACTIVE_COLORS); if (free_old && sds->fluid) @@ -262,21 +262,21 @@ static void smoke_set_domain_from_derivedmesh(SmokeDomainSettings *sds, Object * scale = res / size[0]; sds->scale = size[0] / ob->size[0]; sds->base_res[0] = res; - sds->base_res[1] = (int)(size[1] * scale + 0.5); - sds->base_res[2] = (int)(size[2] * scale + 0.5); + 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->base_res[0] = (int)(size[0] * scale + 0.5); + sds->base_res[0] = (int)(size[0] * scale + 0.5f); sds->base_res[1] = res; - sds->base_res[2] = (int)(size[2] * scale + 0.5); + sds->base_res[2] = (int)(size[2] * scale + 0.5f); } else { scale = res / size[2]; sds->scale = size[2] / ob->size[2]; - sds->base_res[0] = (int)(size[0] * scale + 0.5); - sds->base_res[1] = (int)(size[1] * scale + 0.5); + 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; } @@ -1581,7 +1581,7 @@ BLI_INLINE void apply_inflow_fields(SmokeFlowSettings *sfs, float emission_value if (fuel && fuel[index]) { /* instead of using 1.0 for all new fuel add slight falloff * to reduce flow blockiness */ - float value = 1.0f - pow(1.0f - emission_value, 2.0f); + float value = 1.0f - powf(1.0f - emission_value, 2.0f); if (value > react[index]) { float f = fuel_flow / fuel[index]; @@ -1944,9 +1944,9 @@ static void update_effectors(Scene *scene, Object *ob, SmokeDomainSettings *sds, mul_v3_fl(retvel, mag); // TODO dg - do in force! - force_x[index] = MIN2(MAX2(-1.0, retvel[0] * 0.2), 1.0); - force_y[index] = MIN2(MAX2(-1.0, retvel[1] * 0.2), 1.0); - force_z[index] = MIN2(MAX2(-1.0, retvel[2] * 0.2), 1.0); + force_x[index] = min_ff(max_ff(-1.0f, retvel[0] * 0.2f), 1.0f); + force_y[index] = min_ff(max_ff(-1.0f, retvel[1] * 0.2f), 1.0f); + force_z[index] = min_ff(max_ff(-1.0f, retvel[2] * 0.2f), 1.0f); } } } @@ -1999,7 +1999,7 @@ static void step(Scene *scene, Object *ob, SmokeModifierData *smd, DerivedMesh * /* adapt timestep for different framerates, dt = 0.1 is at 25fps */ dt = DT_DEFAULT * (25.0f / fps); // maximum timestep/"CFL" constraint: dt < 5.0 *dx / maxVel - maxVel = (sds->dx * 5.0); + maxVel = (sds->dx * 5.0f); #if 0 for (i = 0; i < size; i++) { @@ -2009,7 +2009,7 @@ static void step(Scene *scene, Object *ob, SmokeModifierData *smd, DerivedMesh * } #endif - maxVelMag = sqrt(maxVelMag) * dt * sds->time_scale; + maxVelMag = sqrtf(maxVelMag) * dt * sds->time_scale; totalSubsteps = (int)((maxVelMag / maxVel) + 1.0f); /* always round up */ totalSubsteps = (totalSubsteps < 1) ? 1 : totalSubsteps; totalSubsteps = (totalSubsteps > maxSubSteps) ? maxSubSteps : totalSubsteps; @@ -2267,7 +2267,8 @@ static void smokeModifier_process(SmokeModifierData *smd, Scene *scene, Object * } } -struct DerivedMesh *smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedMesh *dm){ +struct DerivedMesh *smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedMesh *dm) +{ smokeModifier_process(smd, scene, ob, dm); /* return generated geometry for adaptive domain */ @@ -2285,7 +2286,7 @@ static float calc_voxel_transp(float *result, float *input, int res[3], int *pix const size_t index = smoke_get_index(pixel[0], res[0], pixel[1], res[1], pixel[2]); // T_ray *= T_vox - *tRay *= exp(input[index] * correct); + *tRay *= expf(input[index] * correct); if (result[index] < 0.0f) { @@ -2385,7 +2386,7 @@ static void smoke_calc_transparency(SmokeDomainSettings *sds, Scene *scene) float light[3]; int a, z, slabsize = sds->res[0] * sds->res[1], size = sds->res[0] * sds->res[1] * sds->res[2]; float *density = smoke_get_density(sds->fluid); - float correct = -7.0 * sds->dx; + float correct = -7.0f * sds->dx; if (!get_lamp(scene, light)) return; diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c index aad205bb5bf..af9d21d8cbc 100644 --- a/source/blender/blenkernel/intern/sound.c +++ b/source/blender/blenkernel/intern/sound.c @@ -353,17 +353,17 @@ void sound_load(struct Main *bmain, bSound *sound) } // XXX unused currently #if 0 - break; + break; + } + case SOUND_TYPE_BUFFER: + if (sound->child_sound && sound->child_sound->handle) + sound->handle = AUD_bufferSound(sound->child_sound->handle); + break; + case SOUND_TYPE_LIMITER: + if (sound->child_sound && sound->child_sound->handle) + sound->handle = AUD_limitSound(sound->child_sound, sound->start, sound->end); + break; } - case SOUND_TYPE_BUFFER: - if (sound->child_sound && sound->child_sound->handle) - sound->handle = AUD_bufferSound(sound->child_sound->handle); - break; - case SOUND_TYPE_LIMITER: - if (sound->child_sound && sound->child_sound->handle) - sound->handle = AUD_limitSound(sound->child_sound, sound->start, sound->end); - break; -} #endif if (sound->flags & SOUND_FLAGS_MONO) { void *handle = AUD_monoSound(sound->handle); diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index 8a669b89907..be8b572417e 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -3025,7 +3025,8 @@ static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm) * when the ccgdm gets remade, the assumption is that the topology * does not change. */ ccgdm_create_grids(dm); - BLI_pbvh_grids_update(ob->sculpt->pbvh, ccgdm->gridData, ccgdm->gridAdjacency, (void **)ccgdm->gridFaces); + BLI_pbvh_grids_update(ob->sculpt->pbvh, ccgdm->gridData, ccgdm->gridAdjacency, (void **)ccgdm->gridFaces, + ccgdm->gridFlagMats, ccgdm->gridHidden); } ccgdm->pbvh = ob->sculpt->pbvh; diff --git a/source/blender/blenkernel/intern/suggestions.c b/source/blender/blenkernel/intern/suggestions.c index 99e33594a3e..ff9774f85af 100644 --- a/source/blender/blenkernel/intern/suggestions.c +++ b/source/blender/blenkernel/intern/suggestions.c @@ -47,6 +47,7 @@ static SuggList suggestions = {NULL, NULL, NULL, NULL, NULL}; static char *documentation = NULL; //static int doc_lines = 0; +/* TODO, replace with BLI_strncasecmp() */ static int txttl_cmp(const char *first, const char *second, int len) { int cmp, i; @@ -113,19 +114,18 @@ short texttool_text_is_active(Text *text) void texttool_suggest_add(const char *name, char type) { + const int len = strlen(name); + int cmp; SuggItem *newitem, *item; - int len, cmp; - newitem = MEM_mallocN(sizeof(SuggItem) + strlen(name) + 1, "SuggestionItem"); + newitem = MEM_mallocN(sizeof(SuggItem) + len + 1, "SuggItem"); if (!newitem) { printf("Failed to allocate memory for suggestion.\n"); return; } newitem->name = (char *) (newitem + 1); - len = strlen(name); - strncpy(newitem->name, name, len); - newitem->name[len] = '\0'; + memcpy(newitem->name, name, len + 1); newitem->type = type; newitem->prev = newitem->next = NULL; diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c index d230cf8f1fe..322b77e0462 100644 --- a/source/blender/blenkernel/intern/text.c +++ b/source/blender/blenkernel/intern/text.c @@ -96,17 +96,6 @@ * If the user moves the cursor the st containing that cursor should * be popped ... other st's retain their own top location. * - * Markers - * -- - * The mrk->flags define the behavior and relationships between markers. The - * upper two bytes are used to hold a group ID, the lower two are normal flags. If - * TMARK_EDITALL is set the group ID defines which other markers should be edited. - * - * The mrk->clr field is used to visually group markers where the flags may not - * match. A template system, for example, may allow editing of repeating tokens - * (in one group) but include other marked positions (in another group) all in the - * same template with the same color. - * * Undo * -- * Undo/Redo works by storing @@ -136,8 +125,7 @@ static void txt_pop_first(Text *text); static void txt_pop_last(Text *text); -static void txt_undo_add_op(Text *text, int op); -static void txt_undo_add_block(Text *text, int op, const char *buf); +static void txt_undo_add_blockop(Text *text, int op, const char *buf); static void txt_delete_line(Text *text, TextLine *line); static void txt_delete_sel(Text *text); static void txt_make_dirty(Text *text); @@ -175,7 +163,6 @@ void BKE_text_free(Text *text) } BLI_freelistN(&text->lines); - BLI_freelistN(&text->markers); if (text->name) MEM_freeN(text->name); MEM_freeN(text->undo_buf); @@ -203,7 +190,6 @@ Text *BKE_text_add(const char *name) ta->flags |= TXT_TABSTOSPACES; ta->lines.first = ta->lines.last = NULL; - ta->markers.first = ta->markers.last = NULL; tmp = (TextLine *) MEM_mallocN(sizeof(TextLine), "textline"); tmp->line = (char *) MEM_mallocN(1, "textline_string"); @@ -399,7 +385,6 @@ Text *BKE_text_load(const char *file, const char *relpath) ta->id.us = 1; ta->lines.first = ta->lines.last = NULL; - ta->markers.first = ta->markers.last = NULL; ta->curl = ta->sell = NULL; if ((U.flag & USER_TXT_TABSTOSPACES_DISABLE) == 0) @@ -496,7 +481,6 @@ Text *BKE_text_copy(Text *ta) tan->flags = ta->flags | TXT_ISDIRTY; tan->lines.first = tan->lines.last = NULL; - tan->markers.first = tan->markers.last = NULL; tan->curl = tan->sell = NULL; tan->nlines = ta->nlines; @@ -785,23 +769,6 @@ static void txt_curs_sel(Text *text, TextLine ***linep, int **charp) *linep = &text->sell; *charp = &text->selc; } -static void txt_curs_first(Text *text, TextLine **linep, int *charp) -{ - if (text->curl == text->sell) { - *linep = text->curl; - if (text->curc < text->selc) *charp = text->curc; - else *charp = text->selc; - } - else if (txt_get_span(text->lines.first, text->curl) < txt_get_span(text->lines.first, text->sell)) { - *linep = text->curl; - *charp = text->curc; - } - else { - *linep = text->sell; - *charp = text->selc; - } -} - /*****************************/ /* Cursor movement functions */ /*****************************/ @@ -843,13 +810,11 @@ void txt_move_up(Text *text, short sel) { TextLine **linep; int *charp; - /* int old; */ /* UNUSED */ if (!text) return; if (sel) txt_curs_sel(text, &linep, &charp); else { txt_pop_first(text); txt_curs_cur(text, &linep, &charp); } if (!*linep) return; - /* old = *charp; */ /* UNUSED */ if ((*linep)->prev) { int index = txt_utf8_offset_to_index((*linep)->line, *charp); @@ -857,8 +822,6 @@ void txt_move_up(Text *text, short sel) if (index > txt_utf8_len((*linep)->line)) *charp = (*linep)->len; else *charp = txt_utf8_index_to_offset((*linep)->line, index); - if (!undoing) - txt_undo_add_op(text, sel ? UNDO_SUP : UNDO_CUP); } else { txt_move_bol(text, sel); @@ -871,22 +834,17 @@ void txt_move_down(Text *text, short sel) { TextLine **linep; int *charp; - /* int old; */ /* UNUSED */ if (!text) return; if (sel) txt_curs_sel(text, &linep, &charp); else { txt_pop_last(text); txt_curs_cur(text, &linep, &charp); } if (!*linep) return; - /* old = *charp; */ /* UNUSED */ if ((*linep)->next) { int index = txt_utf8_offset_to_index((*linep)->line, *charp); *linep = (*linep)->next; if (index > txt_utf8_len((*linep)->line)) *charp = (*linep)->len; else *charp = txt_utf8_index_to_offset((*linep)->line, index); - - if (!undoing) - txt_undo_add_op(text, sel ? UNDO_SDOWN : UNDO_CDOWN); } else { txt_move_eol(text, sel); @@ -898,7 +856,7 @@ void txt_move_down(Text *text, short sel) void txt_move_left(Text *text, short sel) { TextLine **linep; - int *charp, oundoing = undoing; + int *charp; int tabsize = 0, i = 0; if (!text) return; @@ -906,8 +864,6 @@ void txt_move_left(Text *text, short sel) else { txt_pop_first(text); txt_curs_cur(text, &linep, &charp); } if (!*linep) return; - undoing = 1; - if (*charp == 0) { if ((*linep)->prev) { txt_move_up(text, sel); @@ -939,24 +895,19 @@ void txt_move_left(Text *text, short sel) } } - undoing = oundoing; - if (!undoing) txt_undo_add_op(text, sel ? UNDO_SLEFT : UNDO_CLEFT); - if (!sel) txt_pop_sel(text); } void txt_move_right(Text *text, short sel) { TextLine **linep; - int *charp, oundoing = undoing, do_tab = FALSE, i; + int *charp, do_tab = FALSE, i; if (!text) return; if (sel) txt_curs_sel(text, &linep, &charp); else { txt_pop_last(text); txt_curs_cur(text, &linep, &charp); } if (!*linep) return; - undoing = 1; - if (*charp == (*linep)->len) { if ((*linep)->next) { txt_move_down(text, sel); @@ -984,124 +935,103 @@ void txt_move_right(Text *text, short sel) else (*charp) += BLI_str_utf8_size((*linep)->line + *charp); } - undoing = oundoing; - if (!undoing) txt_undo_add_op(text, sel ? UNDO_SRIGHT : UNDO_CRIGHT); - if (!sel) txt_pop_sel(text); } void txt_jump_left(Text *text, short sel) { TextLine **linep; - int *charp, oldc; + int *charp; if (!text) return; if (sel) txt_curs_sel(text, &linep, &charp); else { txt_pop_first(text); txt_curs_cur(text, &linep, &charp); } if (!*linep) return; - oldc = *charp; BLI_str_cursor_step_utf8((*linep)->line, (*linep)->len, charp, STRCUR_DIR_PREV, STRCUR_JUMP_DELIM); if (!sel) txt_pop_sel(text); - if (!undoing) { - int span = txt_get_span(text->lines.first, *linep); - txt_undo_add_toop(text, sel ? UNDO_STO : UNDO_CTO, span, oldc, span, (unsigned short)*charp); - } } void txt_jump_right(Text *text, short sel) { TextLine **linep; - int *charp, oldc; + int *charp; if (!text) return; if (sel) txt_curs_sel(text, &linep, &charp); else { txt_pop_last(text); txt_curs_cur(text, &linep, &charp); } if (!*linep) return; - oldc = *charp; BLI_str_cursor_step_utf8((*linep)->line, (*linep)->len, charp, STRCUR_DIR_NEXT, STRCUR_JUMP_DELIM); if (!sel) txt_pop_sel(text); - if (!undoing) { - int span = txt_get_span(text->lines.first, *linep); - txt_undo_add_toop(text, sel ? UNDO_STO : UNDO_CTO, span, oldc, span, (unsigned short)*charp); - } } void txt_move_bol(Text *text, short sel) { TextLine **linep; - int *charp, old; + int *charp; if (!text) return; if (sel) txt_curs_sel(text, &linep, &charp); else txt_curs_cur(text, &linep, &charp); if (!*linep) return; - old = *charp; *charp = 0; if (!sel) txt_pop_sel(text); - if (!undoing) txt_undo_add_toop(text, sel ? UNDO_STO : UNDO_CTO, txt_get_span(text->lines.first, *linep), old, txt_get_span(text->lines.first, *linep), (unsigned short)*charp); } void txt_move_eol(Text *text, short sel) { TextLine **linep; - int *charp, old; + int *charp; if (!text) return; if (sel) txt_curs_sel(text, &linep, &charp); else txt_curs_cur(text, &linep, &charp); if (!*linep) return; - old = *charp; - + *charp = (*linep)->len; if (!sel) txt_pop_sel(text); - if (!undoing) txt_undo_add_toop(text, sel ? UNDO_STO : UNDO_CTO, txt_get_span(text->lines.first, *linep), old, txt_get_span(text->lines.first, *linep), (unsigned short)*charp); } void txt_move_bof(Text *text, short sel) { TextLine **linep; - int *charp, old; + int *charp; if (!text) return; if (sel) txt_curs_sel(text, &linep, &charp); else txt_curs_cur(text, &linep, &charp); if (!*linep) return; - old = *charp; *linep = text->lines.first; *charp = 0; if (!sel) txt_pop_sel(text); - if (!undoing) txt_undo_add_toop(text, sel ? UNDO_STO : UNDO_CTO, txt_get_span(text->lines.first, *linep), old, txt_get_span(text->lines.first, *linep), (unsigned short)*charp); } void txt_move_eof(Text *text, short sel) { TextLine **linep; - int *charp, old; + int *charp; if (!text) return; if (sel) txt_curs_sel(text, &linep, &charp); else txt_curs_cur(text, &linep, &charp); if (!*linep) return; - old = *charp; *linep = text->lines.last; *charp = (*linep)->len; if (!sel) txt_pop_sel(text); - if (!undoing) txt_undo_add_toop(text, sel ? UNDO_STO : UNDO_CTO, txt_get_span(text->lines.first, *linep), old, txt_get_span(text->lines.first, *linep), (unsigned short)*charp); } void txt_move_toline(Text *text, unsigned int line, short sel) @@ -1112,16 +1042,14 @@ void txt_move_toline(Text *text, unsigned int line, short sel) /* Moves to a certain byte in a line, not a certain utf8-character! */ void txt_move_to(Text *text, unsigned int line, unsigned int ch, short sel) { - TextLine **linep, *oldl; - int *charp, oldc; + TextLine **linep; + int *charp; unsigned int i; if (!text) return; if (sel) txt_curs_sel(text, &linep, &charp); else txt_curs_cur(text, &linep, &charp); if (!*linep) return; - oldc = *charp; - oldl = *linep; *linep = text->lines.first; for (i = 0; i < line; i++) { @@ -1133,7 +1061,6 @@ void txt_move_to(Text *text, unsigned int line, unsigned int ch, short sel) *charp = ch; if (!sel) txt_pop_sel(text); - if (!undoing) txt_undo_add_toop(text, sel ? UNDO_STO : UNDO_CTO, txt_get_span(text->lines.first, oldl), oldc, txt_get_span(text->lines.first, *linep), (unsigned short)*charp); } /****************************/ @@ -1152,8 +1079,6 @@ static void txt_curs_swap(Text *text) tmpc = text->curc; text->curc = text->selc; text->selc = tmpc; - - if (!undoing) txt_undo_add_op(text, UNDO_SWAP); } static void txt_pop_first(Text *text) @@ -1164,12 +1089,6 @@ static void txt_pop_first(Text *text) { txt_curs_swap(text); } - - if (!undoing) txt_undo_add_toop(text, UNDO_STO, - txt_get_span(text->lines.first, text->sell), - text->selc, - txt_get_span(text->lines.first, text->curl), - text->curc); txt_pop_sel(text); } @@ -1181,12 +1100,6 @@ static void txt_pop_last(Text *text) { txt_curs_swap(text); } - - if (!undoing) txt_undo_add_toop(text, UNDO_STO, - txt_get_span(text->lines.first, text->sell), - text->selc, - txt_get_span(text->lines.first, text->curl), - text->curc); txt_pop_sel(text); } @@ -1222,9 +1135,7 @@ int txt_has_sel(Text *text) static void txt_delete_sel(Text *text) { TextLine *tmpl; - TextMarker *mrk; char *buf; - int move, lineno; if (!text) return; if (!text->curl) return; @@ -1236,33 +1147,11 @@ static void txt_delete_sel(Text *text) if (!undoing) { buf = txt_sel_to_buf(text); - txt_undo_add_block(text, UNDO_DBLOCK, buf); + txt_undo_add_blockop(text, UNDO_DBLOCK, buf); MEM_freeN(buf); } buf = MEM_mallocN(text->curc + (text->sell->len - text->selc) + 1, "textline_string"); - - if (text->curl != text->sell) { - txt_clear_marker_region(text, text->curl, text->curc, text->curl->len, 0, 0); - move = txt_get_span(text->curl, text->sell); - } - else { - mrk = txt_find_marker_region(text, text->curl, text->curc, text->selc, 0, 0); - if (mrk && (mrk->start > text->curc || mrk->end < text->selc)) - txt_clear_marker_region(text, text->curl, text->curc, text->selc, 0, 0); - move = 0; - } - - mrk = txt_find_marker_region(text, text->sell, text->selc - 1, text->sell->len, 0, 0); - if (mrk) { - lineno = mrk->lineno; - do { - mrk->lineno -= move; - if (mrk->start > text->curc) mrk->start -= text->selc - text->curc; - mrk->end -= text->selc - text->curc; - mrk = mrk->next; - } while (mrk && mrk->lineno == lineno); - } strncpy(buf, text->curl->line, text->curc); strcpy(buf + text->curc, text->sell->line + text->selc); @@ -1491,19 +1380,9 @@ char *txt_sel_to_buf(Text *text) return buf; } -static void txt_shift_markers(Text *text, int lineno, int count) -{ - TextMarker *marker; - - for (marker = text->markers.first; marker; marker = marker->next) - if (marker->lineno >= lineno) { - marker->lineno += count; - } -} - void txt_insert_buf(Text *text, const char *in_buffer) { - int l = 0, u, len, lineno = -1, count = 0; + int l = 0, u, len; size_t i = 0, j; TextLine *add; char *buffer; @@ -1517,7 +1396,7 @@ void txt_insert_buf(Text *text, const char *in_buffer) buffer = BLI_strdupn(in_buffer, len); len += txt_extended_ascii_as_utf8(&buffer); - if (!undoing) txt_undo_add_block(text, UNDO_IBLOCK, buffer); + if (!undoing) txt_undo_add_blockop(text, UNDO_IBLOCK, buffer); u = undoing; undoing = 1; @@ -1530,9 +1409,6 @@ void txt_insert_buf(Text *text, const char *in_buffer) else { undoing = u; MEM_freeN(buffer); return; } i++; - /* Read as many full lines as we can */ - lineno = txt_get_span(text->lines.first, text->curl); - while (i < len) { l = 0; @@ -1544,14 +1420,8 @@ void txt_insert_buf(Text *text, const char *in_buffer) add = txt_new_linen(buffer + (i - l), l); BLI_insertlinkbefore(&text->lines, text->curl, add); i++; - count++; } else { - if (count) { - txt_shift_markers(text, lineno, count); - count = 0; - } - for (j = i - l; j < i && j < len; ) txt_add_raw_char(text, BLI_str_utf8_as_unicode_step(buffer, &j)); break; @@ -1560,10 +1430,6 @@ void txt_insert_buf(Text *text, const char *in_buffer) MEM_freeN(buffer); - if (count) { - txt_shift_markers(text, lineno, count); - } - undoing = u; } @@ -1599,6 +1465,7 @@ static void dump_buffer(Text *text) while (i++ < text->undo_pos) printf("%d: %d %c\n", i, text->undo_buf[i], text->undo_buf[i]); } +/* Note: this function is outdated and must be updated if needed for future use */ void txt_print_undo(Text *text) { int i = 0; @@ -1615,37 +1482,7 @@ void txt_print_undo(Text *text) while (i <= text->undo_pos) { op = text->undo_buf[i]; - if (op == UNDO_CLEFT) { - ops = "Cursor left"; - } - else if (op == UNDO_CRIGHT) { - ops = "Cursor right"; - } - else if (op == UNDO_CUP) { - ops = "Cursor up"; - } - else if (op == UNDO_CDOWN) { - ops = "Cursor down"; - } - else if (op == UNDO_SLEFT) { - ops = "Selection left"; - } - else if (op == UNDO_SRIGHT) { - ops = "Selection right"; - } - else if (op == UNDO_SUP) { - ops = "Selection up"; - } - else if (op == UNDO_SDOWN) { - ops = "Selection down"; - } - else if (op == UNDO_STO) { - ops = "Selection "; - } - else if (op == UNDO_CTO) { - ops = "Cursor "; - } - else if (op == UNDO_INSERT_1) { + if (op == UNDO_INSERT_1) { ops = "Insert ascii "; } else if (op == UNDO_INSERT_2) { @@ -1681,9 +1518,6 @@ void txt_print_undo(Text *text) else if (op == UNDO_DEL_4) { ops = "Delete unicode "; } - else if (op == UNDO_SWAP) { - ops = "Cursor swap"; - } else if (op == UNDO_DBLOCK) { ops = "Delete text block"; } @@ -1738,29 +1572,6 @@ void txt_print_undo(Text *text) } } } - else if (op == UNDO_STO || op == UNDO_CTO) { - i++; - - charp = text->undo_buf[i]; i++; - charp = charp + (text->undo_buf[i] << 8); i++; - - linep = text->undo_buf[i]; i++; - linep = linep + (text->undo_buf[i] << 8); i++; - linep = linep + (text->undo_buf[i] << 16); i++; - linep = linep + (text->undo_buf[i] << 24); i++; - - printf("to <%d, %d> ", linep, charp); - - charp = text->undo_buf[i]; i++; - charp = charp + (text->undo_buf[i] << 8); i++; - - linep = text->undo_buf[i]; i++; - linep = linep + (text->undo_buf[i] << 8); i++; - linep = linep + (text->undo_buf[i] << 16); i++; - linep = linep + (text->undo_buf[i] << 24); i++; - - printf("from <%d, %d>", linep, charp); - } else if (op == UNDO_DBLOCK || op == UNDO_IBLOCK) { i++; @@ -1811,16 +1622,6 @@ void txt_print_undo(Text *text) } } -static void txt_undo_add_op(Text *text, int op) -{ - if (!max_undo_test(text, 2)) - return; - - text->undo_pos++; - text->undo_buf[text->undo_pos] = op; - text->undo_buf[text->undo_pos + 1] = 0; -} - static void txt_undo_store_uint16(char *undo_buf, int *undo_pos, unsigned short value) { undo_buf[*undo_pos] = (value) & 0xff; @@ -1841,17 +1642,41 @@ static void txt_undo_store_uint32(char *undo_buf, int *undo_pos, unsigned int va (*undo_pos)++; } -static void txt_undo_add_block(Text *text, int op, const char *buf) +/* store the cur cursor to the undo buffer */ +static void txt_undo_store_cur(Text *text) +{ + txt_undo_store_uint16(text->undo_buf, &text->undo_pos, text->curc); + txt_undo_store_uint32(text->undo_buf, &text->undo_pos, txt_get_span(text->lines.first, text->curl)); +} + +/* store the sel cursor to the undo buffer */ +static void txt_undo_store_sel(Text *text) +{ + txt_undo_store_uint16(text->undo_buf, &text->undo_pos, text->selc); + txt_undo_store_uint32(text->undo_buf, &text->undo_pos, txt_get_span(text->lines.first, text->sell)); +} + +/* store both cursors to the undo buffer */ +static void txt_undo_store_cursors(Text *text) +{ + txt_undo_store_cur(text); + txt_undo_store_sel(text); +} + +/* store an operator along with a block of data */ +static void txt_undo_add_blockop(Text *text, int op, const char *buf) { unsigned int length = strlen(buf); - if (!max_undo_test(text, length + 11)) + if (!max_undo_test(text, length + 11 + 12)) return; text->undo_pos++; text->undo_buf[text->undo_pos] = op; text->undo_pos++; + txt_undo_store_cursors(text); + txt_undo_store_uint32(text->undo_buf, &text->undo_pos, length); strncpy(text->undo_buf + text->undo_pos, buf, length); @@ -1863,34 +1688,30 @@ static void txt_undo_add_block(Text *text, int op, const char *buf) text->undo_buf[text->undo_pos + 1] = 0; } -void txt_undo_add_toop(Text *text, int op, unsigned int froml, unsigned short fromc, unsigned int tol, unsigned short toc) +/* store a regular operator */ +void txt_undo_add_op(Text *text, int op) { if (!max_undo_test(text, 15)) return; - if (froml == tol && fromc == toc) return; - text->undo_pos++; text->undo_buf[text->undo_pos] = op; text->undo_pos++; - txt_undo_store_uint16(text->undo_buf, &text->undo_pos, fromc); - txt_undo_store_uint32(text->undo_buf, &text->undo_pos, froml); - txt_undo_store_uint16(text->undo_buf, &text->undo_pos, toc); - txt_undo_store_uint32(text->undo_buf, &text->undo_pos, tol); + txt_undo_store_cursors(text); text->undo_buf[text->undo_pos] = op; - text->undo_buf[text->undo_pos + 1] = 0; } +/* store an operator for a single character */ static void txt_undo_add_charop(Text *text, int op_start, unsigned int c) { char utf8[BLI_UTF8_MAX]; size_t i, utf8_size = BLI_str_utf8_from_unicode(c, utf8); - if (!max_undo_test(text, 3 + utf8_size)) + if (!max_undo_test(text, 3 + utf8_size + 12)) return; text->undo_pos++; @@ -1899,6 +1720,8 @@ static void txt_undo_add_charop(Text *text, int op_start, unsigned int c) text->undo_buf[text->undo_pos] = op_start + utf8_size - 1; text->undo_pos++; + txt_undo_store_cur(text); + for (i = 0; i < utf8_size; i++) { text->undo_buf[text->undo_pos] = utf8[i]; text->undo_pos++; @@ -1909,6 +1732,9 @@ static void txt_undo_add_charop(Text *text, int op_start, unsigned int c) else { text->undo_buf[text->undo_pos] = op_start + 3; text->undo_pos++; + + txt_undo_store_cursors(text); + txt_undo_store_uint32(text->undo_buf, &text->undo_pos, c); text->undo_buf[text->undo_pos] = op_start + 3; } @@ -1934,6 +1760,29 @@ static unsigned int txt_undo_read_uint32(const char *undo_buf, int *undo_pos) return val; } +/* read the cur cursor from the undo buffer */ +static void txt_undo_read_cur(const char *undo_buf, int *undo_pos, unsigned int *curln, unsigned short *curc) +{ + *curln = txt_undo_read_uint32(undo_buf, undo_pos); + *curc = txt_undo_read_uint16(undo_buf, undo_pos); +} + +/* read the sel cursor from the undo buffer */ +static void txt_undo_read_sel(const char *undo_buf, int *undo_pos, unsigned int *selln, unsigned short *selc) +{ + *selln = txt_undo_read_uint32(undo_buf, undo_pos); + *selc = txt_undo_read_uint16(undo_buf, undo_pos); +} + +/* read both cursors from the undo buffer */ +static void txt_undo_read_cursors(const char *undo_buf, int *undo_pos, + unsigned int *curln, unsigned short *curc, + unsigned int *selln, unsigned short *selc) +{ + txt_undo_read_sel(undo_buf, undo_pos, selln, selc); + txt_undo_read_cur(undo_buf, undo_pos, curln, curc); +} + static unsigned int txt_undo_read_unicode(const char *undo_buf, int *undo_pos, short bytes) { unsigned int unicode; @@ -1986,6 +1835,29 @@ static unsigned int txt_redo_read_uint32(const char *undo_buf, int *undo_pos) return val; } +/* redo read cur cursor from the undo buffer */ +static void txt_redo_read_cur(const char *undo_buf, int *undo_pos, unsigned int *curln, unsigned short *curc) +{ + *curc = txt_redo_read_uint16(undo_buf, undo_pos); + *curln = txt_redo_read_uint32(undo_buf, undo_pos); +} + +/* redo read sel cursor from the undo buffer */ +static void txt_redo_read_sel(const char *undo_buf, int *undo_pos, unsigned int *selln, unsigned short *selc) +{ + *selc = txt_redo_read_uint16(undo_buf, undo_pos); + *selln = txt_redo_read_uint32(undo_buf, undo_pos); +} + +/* redo read both cursors from the undo buffer */ +static void txt_redo_read_cursors(const char *undo_buf, int *undo_pos, + unsigned int *curln, unsigned short *curc, + unsigned int *selln, unsigned short *selc) +{ + txt_redo_read_cur(undo_buf, undo_pos, curln, curc); + txt_redo_read_sel(undo_buf, undo_pos, selln, selc); +} + static unsigned int txt_redo_read_unicode(const char *undo_buf, int *undo_pos, short bytes) { unsigned int unicode; @@ -2024,9 +1896,10 @@ void txt_do_undo(Text *text) { int op = text->undo_buf[text->undo_pos]; unsigned int linep, i; + unsigned int uchar; + unsigned int curln, selln; + unsigned short curc, selc; unsigned short charp; - TextLine *holdl; - int holdc, holdln; char *buf; if (text->undo_pos < 0) { @@ -2038,88 +1911,60 @@ void txt_do_undo(Text *text) undoing = 1; switch (op) { - case UNDO_CLEFT: - txt_move_right(text, 0); - break; + case UNDO_INSERT_1: + case UNDO_INSERT_2: + case UNDO_INSERT_3: + case UNDO_INSERT_4: + text->undo_pos -= op - UNDO_INSERT_1 + 1; - case UNDO_CRIGHT: - txt_move_left(text, 0); - break; + /* get and restore the cursors */ + txt_undo_read_cur(text->undo_buf, &text->undo_pos, &curln, &curc); + txt_move_to(text, curln, curc, 0); + txt_move_to(text, curln, curc, 1); - case UNDO_CUP: - txt_move_down(text, 0); - break; + txt_delete_char(text); - case UNDO_CDOWN: - txt_move_up(text, 0); - break; - - case UNDO_SLEFT: - txt_move_right(text, 1); - break; - - case UNDO_SRIGHT: - txt_move_left(text, 1); - break; - - case UNDO_SUP: - txt_move_down(text, 1); + text->undo_pos--; break; - case UNDO_SDOWN: - txt_move_up(text, 1); - break; - - case UNDO_CTO: - case UNDO_STO: - text->undo_pos--; - text->undo_pos--; - text->undo_pos--; - text->undo_pos--; - - text->undo_pos--; - text->undo_pos--; - - linep = txt_undo_read_uint32(text->undo_buf, &text->undo_pos); - charp = txt_undo_read_uint16(text->undo_buf, &text->undo_pos); - - if (op == UNDO_CTO) { - txt_move_toline(text, linep, 0); - text->curc = charp; - txt_pop_sel(text); - } - else { - txt_move_toline(text, linep, 1); - text->selc = charp; - } + case UNDO_BS_1: + case UNDO_BS_2: + case UNDO_BS_3: + case UNDO_BS_4: + charp = op - UNDO_BS_1 + 1; + uchar = txt_undo_read_unicode(text->undo_buf, &text->undo_pos, charp); - text->undo_pos--; - break; + /* get and restore the cursors */ + txt_undo_read_cur(text->undo_buf, &text->undo_pos, &curln, &curc); + txt_move_to(text, curln, curc, 0); + txt_move_to(text, curln, curc, 1); - case UNDO_INSERT_1: case UNDO_INSERT_2: case UNDO_INSERT_3: case UNDO_INSERT_4: - txt_backspace_char(text); - text->undo_pos -= op - UNDO_INSERT_1 + 1; - text->undo_pos--; - break; + txt_add_char(text, uchar); - case UNDO_BS_1: case UNDO_BS_2: case UNDO_BS_3: case UNDO_BS_4: - charp = op - UNDO_BS_1 + 1; - txt_add_char(text, txt_undo_read_unicode(text->undo_buf, &text->undo_pos, charp)); text->undo_pos--; break; - - case UNDO_DEL_1: case UNDO_DEL_2: case UNDO_DEL_3: case UNDO_DEL_4: + + case UNDO_DEL_1: + case UNDO_DEL_2: + case UNDO_DEL_3: + case UNDO_DEL_4: charp = op - UNDO_DEL_1 + 1; - txt_add_char(text, txt_undo_read_unicode(text->undo_buf, &text->undo_pos, charp)); + uchar = txt_undo_read_unicode(text->undo_buf, &text->undo_pos, charp); + + /* get and restore the cursors */ + txt_undo_read_cur(text->undo_buf, &text->undo_pos, &curln, &curc); + txt_move_to(text, curln, curc, 0); + txt_move_to(text, curln, curc, 1); + + txt_add_char(text, uchar); + txt_move_left(text, 0); - text->undo_pos--; - break; - case UNDO_SWAP: - txt_curs_swap(text); + text->undo_pos--; break; case UNDO_DBLOCK: + /* length of the string in the buffer */ linep = txt_undo_read_uint32(text->undo_buf, &text->undo_pos); buf = MEM_mallocN(linep + 1, "dblock buffer"); @@ -2128,34 +1973,33 @@ void txt_do_undo(Text *text) text->undo_pos--; } buf[i] = 0; - - txt_curs_first(text, &holdl, &holdc); - holdln = txt_get_span(text->lines.first, holdl); - - txt_insert_buf(text, buf); - MEM_freeN(buf); - - text->curl = text->lines.first; - while (holdln > 0) { - if (text->curl->next) - text->curl = text->curl->next; - - holdln--; - } - text->curc = holdc; + /* skip over the length that was stored again */ text->undo_pos--; text->undo_pos--; text->undo_pos--; text->undo_pos--; + /* Get the cursor positions */ + txt_undo_read_cursors(text->undo_buf, &text->undo_pos, &curln, &curc, &selln, &selc); + + /* move cur to location that needs buff inserted */ + txt_move_to(text, curln, curc, 0); + + txt_insert_buf(text, buf); + MEM_freeN(buf); + + /* restore the cursors */ + txt_move_to(text, curln, curc, 0); + txt_move_to(text, selln, selc, 1); + text->undo_pos--; break; case UNDO_IBLOCK: + /* length of the string in the buffer */ linep = txt_undo_read_uint32(text->undo_buf, &text->undo_pos); - txt_delete_sel(text); /* txt_backspace_char removes utf8-characters, not bytes */ buf = MEM_mallocN(linep + 1, "iblock buffer"); @@ -2167,47 +2011,38 @@ void txt_do_undo(Text *text) linep = txt_utf8_len(buf); MEM_freeN(buf); - while (linep > 0) { - txt_backspace_char(text); - linep--; - } - + /* skip over the length that was stored again */ text->undo_pos--; text->undo_pos--; - text->undo_pos--; text->undo_pos--; - text->undo_pos--; + + /* get and restore the cursors */ + txt_undo_read_cursors(text->undo_buf, &text->undo_pos, &curln, &curc, &selln, &selc); + + txt_move_to(text, curln, curc, 0); + txt_move_to(text, selln, selc, 1); + + if ((curln == selln) && (curc == selc)) { + for (i = 0; i < linep; i++) + txt_move_right(text, 1); + } + + txt_delete_selected(text); + text->undo_pos--; break; case UNDO_INDENT: case UNDO_UNINDENT: case UNDO_COMMENT: case UNDO_UNCOMMENT: - linep = txt_undo_read_uint32(text->undo_buf, &text->undo_pos); - //linep is now the end line of the selection - - charp = txt_undo_read_uint16(text->undo_buf, &text->undo_pos); - //charp is the last char selected or text->line->len - - //set the selection for this now - text->selc = charp; - text->sell = text->lines.first; - for (i = 0; i < linep; i++) { - text->sell = text->sell->next; - } - - linep = txt_undo_read_uint32(text->undo_buf, &text->undo_pos); - //first line to be selected - - charp = txt_undo_read_uint16(text->undo_buf, &text->undo_pos); - //first postion to be selected - text->curc = charp; - text->curl = text->lines.first; - for (i = 0; i < linep; i++) { - text->curl = text->curl->next; - } - + case UNDO_DUPLICATE: + case UNDO_MOVE_LINES_UP: + case UNDO_MOVE_LINES_DOWN: + /* get and restore the cursors */ + txt_undo_read_cursors(text->undo_buf, &text->undo_pos, &curln, &curc, &selln, &selc); + txt_move_to(text, curln, curc, 0); + txt_move_to(text, selln, selc, 1); if (op == UNDO_INDENT) { txt_unindent(text); @@ -2221,37 +2056,24 @@ void txt_do_undo(Text *text) else if (op == UNDO_UNCOMMENT) { txt_comment(text); } + else if (op == UNDO_DUPLICATE) { + txt_delete_line(text, text->curl->next); + } + else if (op == UNDO_MOVE_LINES_UP) { + txt_move_lines(text, TXT_MOVE_LINE_DOWN); + } + else if (op == UNDO_MOVE_LINES_DOWN) { + txt_move_lines(text, TXT_MOVE_LINE_UP); + } text->undo_pos--; break; - case UNDO_DUPLICATE: - txt_delete_line(text, text->curl->next); - break; - case UNDO_MOVE_LINES_UP: - txt_move_lines(text, TXT_MOVE_LINE_DOWN); - break; - case UNDO_MOVE_LINES_DOWN: - txt_move_lines(text, TXT_MOVE_LINE_UP); - break; default: //XXX error("Undo buffer error - resetting"); text->undo_pos = -1; break; } - - /* next undo step may need evaluating */ - if (text->undo_pos >= 0) { - switch (text->undo_buf[text->undo_pos]) { - case UNDO_STO: - txt_do_undo(text); - txt_do_redo(text); /* selections need restoring */ - break; - case UNDO_SWAP: - txt_do_undo(text); /* swaps should appear transparent */ - break; - } - } undoing = 0; } @@ -2259,9 +2081,12 @@ void txt_do_undo(Text *text) void txt_do_redo(Text *text) { char op; - unsigned int linep, i; - unsigned short charp; char *buf; + unsigned int linep; + unsigned short charp; + unsigned int uchar; + unsigned int curln, selln; + unsigned short curc, selc; text->undo_pos++; op = text->undo_buf[text->undo_pos]; @@ -2274,104 +2099,91 @@ void txt_do_redo(Text *text) undoing = 1; switch (op) { - case UNDO_CLEFT: - txt_move_left(text, 0); - break; - - case UNDO_CRIGHT: - txt_move_right(text, 0); - break; + case UNDO_INSERT_1: + case UNDO_INSERT_2: + case UNDO_INSERT_3: + case UNDO_INSERT_4: + text->undo_pos++; - case UNDO_CUP: - txt_move_up(text, 0); - break; + /* get and restore the cursors */ + txt_redo_read_cur(text->undo_buf, &text->undo_pos, &curln, &curc); + txt_move_to(text, curln, curc, 0); + txt_move_to(text, curln, curc, 1); - case UNDO_CDOWN: - txt_move_down(text, 0); - break; - - case UNDO_SLEFT: - txt_move_left(text, 1); - break; - - case UNDO_SRIGHT: - txt_move_right(text, 1); - break; - - case UNDO_SUP: - txt_move_up(text, 1); - break; - - case UNDO_SDOWN: - txt_move_down(text, 1); - break; - - case UNDO_INSERT_1: case UNDO_INSERT_2: case UNDO_INSERT_3: case UNDO_INSERT_4: - text->undo_pos++; charp = op - UNDO_INSERT_1 + 1; - txt_add_char(text, txt_redo_read_unicode(text->undo_buf, &text->undo_pos, charp)); - break; + uchar = txt_redo_read_unicode(text->undo_buf, &text->undo_pos, charp); - case UNDO_BS_1: case UNDO_BS_2: case UNDO_BS_3: case UNDO_BS_4: - text->undo_pos++; - txt_backspace_char(text); - text->undo_pos += op - UNDO_BS_1 + 1; + txt_add_char(text, uchar); break; - case UNDO_DEL_1: case UNDO_DEL_2: case UNDO_DEL_3: case UNDO_DEL_4: + case UNDO_BS_1: + case UNDO_BS_2: + case UNDO_BS_3: + case UNDO_BS_4: text->undo_pos++; - txt_delete_char(text); - text->undo_pos += op - UNDO_DEL_1 + 1; - break; - case UNDO_SWAP: - txt_curs_swap(text); - txt_do_redo(text); /* swaps should appear transparent a*/ - break; + /* get and restore the cursors */ + txt_redo_read_cur(text->undo_buf, &text->undo_pos, &curln, &curc); + txt_move_to(text, curln, curc, 0); + txt_move_to(text, curln, curc, 1); + + text->undo_pos += op - UNDO_BS_1 + 1; - case UNDO_CTO: - case UNDO_STO: - text->undo_pos++; - text->undo_pos++; + /* move right so we backspace the correct char */ + txt_move_right(text, 0); + txt_backspace_char(text); - text->undo_pos++; - text->undo_pos++; - text->undo_pos++; - text->undo_pos++; + break; + case UNDO_DEL_1: + case UNDO_DEL_2: + case UNDO_DEL_3: + case UNDO_DEL_4: text->undo_pos++; - charp = txt_redo_read_uint16(text->undo_buf, &text->undo_pos); - linep = txt_redo_read_uint32(text->undo_buf, &text->undo_pos); + /* get and restore the cursors */ + txt_redo_read_cur(text->undo_buf, &text->undo_pos, &curln, &curc); + txt_move_to(text, curln, curc, 0); + txt_move_to(text, curln, curc, 1); - if (op == UNDO_CTO) { - txt_move_toline(text, linep, 0); - text->curc = charp; - txt_pop_sel(text); - } - else { - txt_move_toline(text, linep, 1); - text->selc = charp; - } + text->undo_pos += op - UNDO_DEL_1 + 1; + + txt_delete_char(text); break; case UNDO_DBLOCK: text->undo_pos++; + + /* get and restore the cursors */ + txt_redo_read_cursors(text->undo_buf, &text->undo_pos, &curln, &curc, &selln, &selc); + txt_move_to(text, curln, curc, 0); + txt_move_to(text, selln, selc, 1); + + /* length of the block */ linep = txt_redo_read_uint32(text->undo_buf, &text->undo_pos); - txt_delete_sel(text); text->undo_pos += linep; + /* skip over the length that was stored again */ text->undo_pos++; text->undo_pos++; text->undo_pos++; text->undo_pos++; + txt_delete_sel(text); + break; case UNDO_IBLOCK: text->undo_pos++; + + /* get and restore the cursors */ + txt_redo_read_cursors(text->undo_buf, &text->undo_pos, &curln, &curc, &selln, &selc); + txt_move_to(text, curln, curc, 0); + txt_move_to(text, curln, curc, 1); + + /* length of the block */ linep = txt_redo_read_uint32(text->undo_buf, &text->undo_pos); buf = MEM_mallocN(linep + 1, "iblock buffer"); @@ -2382,40 +2194,27 @@ void txt_do_redo(Text *text) txt_insert_buf(text, buf); MEM_freeN(buf); + /* skip over the length that was stored again */ text->undo_pos++; text->undo_pos++; text->undo_pos++; text->undo_pos++; + break; case UNDO_INDENT: case UNDO_UNINDENT: case UNDO_COMMENT: case UNDO_UNCOMMENT: + case UNDO_DUPLICATE: + case UNDO_MOVE_LINES_UP: + case UNDO_MOVE_LINES_DOWN: text->undo_pos++; - charp = txt_redo_read_uint16(text->undo_buf, &text->undo_pos); - //charp is the first char selected or 0 - - linep = txt_redo_read_uint32(text->undo_buf, &text->undo_pos); - //linep is now the first line of the selection - //set the selcetion for this now - text->curc = charp; - text->curl = text->lines.first; - for (i = 0; i < linep; i++) { - text->curl = text->curl->next; - } - - charp = txt_redo_read_uint16(text->undo_buf, &text->undo_pos); - //last postion to be selected - - linep = txt_redo_read_uint32(text->undo_buf, &text->undo_pos); - //Last line to be selected - - text->selc = charp; - text->sell = text->lines.first; - for (i = 0; i < linep; i++) { - text->sell = text->sell->next; - } + + /* get and restore the cursors */ + txt_redo_read_cursors(text->undo_buf, &text->undo_pos, &curln, &curc, &selln, &selc); + txt_move_to(text, curln, curc, 0); + txt_move_to(text, selln, selc, 1); if (op == UNDO_INDENT) { txt_indent(text); @@ -2429,15 +2228,28 @@ void txt_do_redo(Text *text) else if (op == UNDO_UNCOMMENT) { txt_uncomment(text); } - break; - case UNDO_DUPLICATE: - txt_duplicate_line(text); - break; - case UNDO_MOVE_LINES_UP: - txt_move_lines(text, TXT_MOVE_LINE_UP); - break; - case UNDO_MOVE_LINES_DOWN: - txt_move_lines(text, TXT_MOVE_LINE_DOWN); + else if (op == UNDO_DUPLICATE) { + txt_duplicate_line(text); + } + else if (op == UNDO_MOVE_LINES_UP) { + /* offset the cursor by + 1 */ + txt_move_to(text, curln + 1, curc, 0); + txt_move_to(text, selln + 1, selc, 1); + + txt_move_lines(text, TXT_MOVE_LINE_UP); + } + else if (op == UNDO_MOVE_LINES_DOWN) { + /* offset the cursor by - 1 */ + txt_move_to(text, curln - 1, curc, 0); + txt_move_to(text, selln - 1, selc, 1); + + txt_move_lines(text, TXT_MOVE_LINE_DOWN); + } + + /* re-restore the cursors since they got moved when redoing */ + txt_move_to(text, curln, curc, 0); + txt_move_to(text, selln, selc, 1); + break; default: //XXX error("Undo buffer error - resetting"); @@ -2456,31 +2268,15 @@ void txt_do_redo(Text *text) void txt_split_curline(Text *text) { TextLine *ins; - TextMarker *mrk; char *left, *right; - int lineno = -1; if (!text) return; if (!text->curl) return; txt_delete_sel(text); - /* Move markers */ - - lineno = txt_get_span(text->lines.first, text->curl); - mrk = text->markers.first; - while (mrk) { - if (mrk->lineno == lineno && mrk->start > text->curc) { - mrk->lineno++; - mrk->start -= text->curc; - mrk->end -= text->curc; - } - else if (mrk->lineno > lineno) { - mrk->lineno++; - } - mrk = mrk->next; - } - + if (!undoing) txt_undo_add_charop(text, UNDO_INSERT_1, '\n'); + /* Make the two half strings */ left = MEM_mallocN(text->curc + 1, "textline_string"); @@ -2512,28 +2308,13 @@ void txt_split_curline(Text *text) txt_clean_text(text); txt_pop_sel(text); - if (!undoing) txt_undo_add_charop(text, UNDO_INSERT_1, '\n'); } static void txt_delete_line(Text *text, TextLine *line) { - TextMarker *mrk = NULL, *nxt; - int lineno = -1; - if (!text) return; if (!text->curl) return; - lineno = txt_get_span(text->lines.first, line); - mrk = text->markers.first; - while (mrk) { - nxt = mrk->next; - if (mrk->lineno == lineno) - BLI_freelinkN(&text->markers, mrk); - else if (mrk->lineno > lineno) - mrk->lineno--; - mrk = nxt; - } - BLI_remlink(&text->lines, line); if (line->line) MEM_freeN(line->line); @@ -2548,25 +2329,12 @@ static void txt_delete_line(Text *text, TextLine *line) static void txt_combine_lines(Text *text, TextLine *linea, TextLine *lineb) { char *tmp; - TextMarker *mrk = NULL; - int lineno = -1; - + if (!text) return; if (!linea || !lineb) return; - mrk = txt_find_marker_region(text, lineb, 0, lineb->len, 0, 0); - if (mrk) { - lineno = mrk->lineno; - do { - mrk->lineno--; - mrk->start += linea->len; - mrk->end += linea->len; - mrk = mrk->next; - } while (mrk && mrk->lineno == lineno); - } - if (lineno == -1) lineno = txt_get_span(text->lines.first, lineb); - + tmp = MEM_mallocN(linea->len + lineb->len + 1, "textline_string"); strcpy(tmp, linea->line); @@ -2619,27 +2387,7 @@ void txt_delete_char(Text *text) } else { /* Just deleting a char */ size_t c_len = 0; - TextMarker *mrk; c = BLI_str_utf8_as_unicode_and_size(text->curl->line + text->curc, &c_len); - - mrk = txt_find_marker_region(text, text->curl, text->curc - c_len, text->curl->len, 0, 0); - if (mrk) { - int lineno = mrk->lineno; - if (mrk->end == text->curc) { - if ((mrk->flags & TMARK_TEMP) && !(mrk->flags & TMARK_EDITALL)) { - txt_clear_markers(text, mrk->group, TMARK_TEMP); - } - else { - BLI_freelinkN(&text->markers, mrk); - } - return; - } - do { - if (mrk->start > text->curc) mrk->start -= c_len; - mrk->end -= c_len; - mrk = mrk->next; - } while (mrk && mrk->lineno == lineno); - } memmove(text->curl->line + text->curc, text->curl->line + text->curc + c_len, text->curl->len - text->curc - c_len + 1); @@ -2683,28 +2431,8 @@ void txt_backspace_char(Text *text) } else { /* Just backspacing a char */ size_t c_len = 0; - TextMarker *mrk; char *prev = BLI_str_prev_char_utf8(text->curl->line + text->curc); c = BLI_str_utf8_as_unicode_and_size(prev, &c_len); - - mrk = txt_find_marker_region(text, text->curl, text->curc - c_len, text->curl->len, 0, 0); - if (mrk) { - int lineno = mrk->lineno; - if (mrk->start == text->curc) { - if ((mrk->flags & TMARK_TEMP) && !(mrk->flags & TMARK_EDITALL)) { - txt_clear_markers(text, mrk->group, TMARK_TEMP); - } - else { - BLI_freelinkN(&text->markers, mrk); - } - return; - } - do { - if (mrk->start > text->curc - c_len) mrk->start -= c_len; - mrk->end -= c_len; - mrk = mrk->next; - } while (mrk && mrk->lineno == lineno); - } /* source and destination overlap, don't use memcpy() */ memmove(text->curl->line + text->curc - c_len, @@ -2746,9 +2474,7 @@ static void txt_convert_tab_to_spaces(Text *text) static int txt_add_char_intern(Text *text, unsigned int add, int replace_tabs) { - int lineno; char *tmp, ch[BLI_UTF8_MAX]; - TextMarker *mrk; size_t add_len; if (!text) return 0; @@ -2767,16 +2493,9 @@ static int txt_add_char_intern(Text *text, unsigned int add, int replace_tabs) txt_delete_sel(text); + if (!undoing) txt_undo_add_charop(text, UNDO_INSERT_1, add); + add_len = BLI_str_utf8_from_unicode(add, ch); - mrk = txt_find_marker_region(text, text->curl, text->curc - 1, text->curl->len, 0, 0); - if (mrk) { - lineno = mrk->lineno; - do { - if (mrk->start > text->curc) mrk->start += add_len; - mrk->end += add_len; - mrk = mrk->next; - } while (mrk && mrk->lineno == lineno); - } tmp = MEM_mallocN(text->curl->len + add_len + 1, "textline_string"); @@ -2793,7 +2512,6 @@ static int txt_add_char_intern(Text *text, unsigned int add, int replace_tabs) txt_make_dirty(text); txt_clean_text(text); - if (!undoing) txt_undo_add_charop(text, UNDO_INSERT_1, add); return 1; } @@ -2824,10 +2542,7 @@ int txt_replace_char(Text *text, unsigned int add) /* If text is selected or we're at the end of the line just use txt_add_char */ if (text->curc == text->curl->len || txt_has_sel(text) || add == '\n') { - int i = txt_add_char(text, add); - TextMarker *mrk = txt_find_marker(text, text->curl, text->curc, 0, 0); - if (mrk) BLI_freelinkN(&text->markers, mrk); - return i; + return txt_add_char(text, add); } del = BLI_str_utf8_as_unicode_and_size(text->curl->line + text->curc, &del_size); @@ -2854,8 +2569,8 @@ int txt_replace_char(Text *text, unsigned int add) /* Should probably create a new op for this */ if (!undoing) { - txt_undo_add_charop(text, UNDO_DEL_1, del); txt_undo_add_charop(text, UNDO_INSERT_1, add); + txt_undo_add_charop(text, UNDO_DEL_1, del); } return 1; } @@ -2924,7 +2639,7 @@ void txt_indent(Text *text) } if (!undoing) { - txt_undo_add_toop(text, UNDO_INDENT, txt_get_span(text->lines.first, text->curl), text->curc, txt_get_span(text->lines.first, text->sell), text->selc); + txt_undo_add_op(text, UNDO_INDENT); } } @@ -2982,7 +2697,7 @@ void txt_unindent(Text *text) } if (!undoing) { - txt_undo_add_toop(text, UNDO_UNINDENT, txt_get_span(text->lines.first, text->curl), text->curc, txt_get_span(text->lines.first, text->sell), text->selc); + txt_undo_add_op(text, UNDO_UNINDENT); } } @@ -3031,7 +2746,7 @@ void txt_comment(Text *text) } if (!undoing) { - txt_undo_add_toop(text, UNDO_COMMENT, txt_get_span(text->lines.first, text->curl), text->curc, txt_get_span(text->lines.first, text->sell), text->selc); + txt_undo_add_op(text, UNDO_COMMENT); } } @@ -3076,7 +2791,7 @@ void txt_uncomment(Text *text) } if (!undoing) { - txt_undo_add_toop(text, UNDO_UNCOMMENT, txt_get_span(text->lines.first, text->curl), text->curc, txt_get_span(text->lines.first, text->sell), text->selc); + txt_undo_add_op(text, UNDO_UNCOMMENT); } } @@ -3165,157 +2880,6 @@ int setcurr_tab_spaces(Text *text, int space) return i; } -/*********************************/ -/* Text marker utility functions */ -/*********************************/ - -/* Creates and adds a marker to the list maintaining sorted order */ -void txt_add_marker(Text *text, TextLine *line, int start, int end, const unsigned char color[4], int group, int flags) -{ - TextMarker *tmp, *marker; - - marker = MEM_mallocN(sizeof(TextMarker), "text_marker"); - - marker->lineno = txt_get_span(text->lines.first, line); - marker->start = MIN2(start, end); - marker->end = MAX2(start, end); - marker->group = group; - marker->flags = flags; - - marker->color[0] = color[0]; - marker->color[1] = color[1]; - marker->color[2] = color[2]; - marker->color[3] = color[3]; - - for (tmp = text->markers.last; tmp; tmp = tmp->prev) - if (tmp->lineno < marker->lineno || (tmp->lineno == marker->lineno && tmp->start < marker->start)) - break; - - if (tmp) BLI_insertlinkafter(&text->markers, tmp, marker); - else BLI_addhead(&text->markers, marker); -} - -/* Returns the first matching marker on the specified line between two points. - * If the group or flags fields are non-zero the returned flag must be in the - * specified group and have at least the specified flags set. */ -TextMarker *txt_find_marker_region(Text *text, TextLine *line, int start, int end, int group, int flags) -{ - TextMarker *marker, *next; - int lineno = txt_get_span(text->lines.first, line); - - for (marker = text->markers.first; marker; marker = next) { - next = marker->next; - - if (group && marker->group != group) continue; - else if ((marker->flags & flags) != flags) continue; - else if (marker->lineno < lineno) continue; - else if (marker->lineno > lineno) break; - - if ((marker->start == marker->end && start <= marker->start && marker->start <= end) || - (marker->start < end && marker->end > start)) - { - return marker; - } - } - return NULL; -} - -/* Clears all markers on the specified line between two points. If the group or - * flags fields are non-zero the returned flag must be in the specified group - * and have at least the specified flags set. */ -short txt_clear_marker_region(Text *text, TextLine *line, int start, int end, int group, int flags) -{ - TextMarker *marker, *next; - int lineno = txt_get_span(text->lines.first, line); - short cleared = 0; - - for (marker = text->markers.first; marker; marker = next) { - next = marker->next; - - if (group && marker->group != group) continue; - else if ((marker->flags & flags) != flags) continue; - else if (marker->lineno < lineno) continue; - else if (marker->lineno > lineno) break; - - if ((marker->start == marker->end && start <= marker->start && marker->start <= end) || - (marker->start < end && marker->end > start)) - { - BLI_freelinkN(&text->markers, marker); - cleared = 1; - } - } - return cleared; -} - -/* Clears all markers in the specified group (if given) with at least the - * specified flags set. Useful for clearing temporary markers (group = 0, - * flags = TMARK_TEMP) */ -short txt_clear_markers(Text *text, int group, int flags) -{ - TextMarker *marker, *next; - short cleared = 0; - - for (marker = text->markers.first; marker; marker = next) { - next = marker->next; - - if ((!group || marker->group == group) && - (marker->flags & flags) == flags) - { - BLI_freelinkN(&text->markers, marker); - cleared = 1; - } - } - return cleared; -} - -/* Finds the marker at the specified line and cursor position with at least the - * specified flags set in the given group (if non-zero). */ -TextMarker *txt_find_marker(Text *text, TextLine *line, int curs, int group, int flags) -{ - TextMarker *marker; - int lineno = txt_get_span(text->lines.first, line); - - for (marker = text->markers.first; marker; marker = marker->next) { - if (group && marker->group != group) continue; - else if ((marker->flags & flags) != flags) continue; - else if (marker->lineno < lineno) continue; - else if (marker->lineno > lineno) break; - - if (marker->start <= curs && curs <= marker->end) - return marker; - } - return NULL; -} - -/* Finds the previous marker in the same group. If no other is found, the same - * marker will be returned */ -TextMarker *txt_prev_marker(Text *text, TextMarker *marker) -{ - TextMarker *tmp = marker; - while (tmp) { - if (tmp->prev) tmp = tmp->prev; - else tmp = text->markers.last; - if (tmp->group == marker->group) - return tmp; - } - return NULL; /* Only if (marker == NULL) */ -} - -/* Finds the next marker in the same group. If no other is found, the same - * marker will be returned */ -TextMarker *txt_next_marker(Text *text, TextMarker *marker) -{ - TextMarker *tmp = marker; - while (tmp) { - if (tmp->next) tmp = tmp->next; - else tmp = text->markers.first; - if (tmp->group == marker->group) - return tmp; - } - return NULL; /* Only if (marker == NULL) */ -} - - /*******************************/ /* Character utility functions */ /*******************************/ diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index 89446a1856f..30b48401046 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -1124,10 +1124,10 @@ void BKE_tracking_marker_pattern_minmax(const MovieTrackingMarker *marker, float { INIT_MINMAX2(min, max); - DO_MINMAX2(marker->pattern_corners[0], min, max); - DO_MINMAX2(marker->pattern_corners[1], min, max); - DO_MINMAX2(marker->pattern_corners[2], min, max); - DO_MINMAX2(marker->pattern_corners[3], min, max); + minmax_v2v2_v2(min, max, marker->pattern_corners[0]); + minmax_v2v2_v2(min, max, marker->pattern_corners[1]); + minmax_v2v2_v2(min, max, marker->pattern_corners[2]); + minmax_v2v2_v2(min, max, marker->pattern_corners[3]); } void BKE_tracking_marker_get_subframe_position(MovieTrackingTrack *track, float framenr, float pos[2]) @@ -1624,6 +1624,9 @@ ImBuf *BKE_tracking_sample_pattern(int frame_width, int frame_height, ImBuf *sea double warped_position_x, warped_position_y; float *mask = NULL; + if (num_samples_x <= 0 || num_samples_y <= 0) + return NULL; + pattern_ibuf = IMB_allocImBuf(num_samples_x, num_samples_y, 32, IB_rectfloat); if (!search_ibuf->rect_float) { @@ -1690,10 +1693,15 @@ ImBuf *BKE_tracking_get_pattern_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, Mo search_ibuf = BKE_tracking_get_search_imbuf(ibuf, track, marker, anchored, disable_channels); - pattern_ibuf = BKE_tracking_sample_pattern(ibuf->x, ibuf->y, search_ibuf, track, marker, - FALSE, num_samples_x, num_samples_y, NULL); + if (search_ibuf) { + pattern_ibuf = BKE_tracking_sample_pattern(ibuf->x, ibuf->y, search_ibuf, track, marker, + FALSE, num_samples_x, num_samples_y, NULL); - IMB_freeImBuf(search_ibuf); + IMB_freeImBuf(search_ibuf); + } + else { + pattern_ibuf = NULL; + } return pattern_ibuf; } @@ -1718,6 +1726,9 @@ ImBuf *BKE_tracking_get_search_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, Mov w = (marker->search_max[0] - marker->search_min[0]) * ibuf->x; h = (marker->search_max[1] - marker->search_min[1]) * ibuf->y; + if (w <= 0 || h <= 0) + return NULL; + searchibuf = IMB_allocImBuf(w, h, 32, ibuf->rect_float ? IB_rectfloat : IB_rect); IMB_rectcpy(searchibuf, ibuf, 0, 0, x, y, w, h); @@ -2187,6 +2198,12 @@ static float *track_get_search_floatbuf(ImBuf *ibuf, MovieTrackingTrack *track, searchibuf = BKE_tracking_get_search_imbuf(ibuf, track, marker, FALSE, TRUE); + if (!searchibuf) { + *width_r = 0; + *height_r = 0; + return NULL; + } + width = searchibuf->x; height = searchibuf->y; @@ -2506,6 +2523,9 @@ int BKE_tracking_context_step(MovieTrackingContext *context) get_marker_coords_for_tracking(frame_width, frame_height, &track_context->marker, src_pixel_x, src_pixel_y); get_marker_coords_for_tracking(frame_width, frame_height, marker, dst_pixel_x, dst_pixel_y); + if (!patch_new || !track_context->search_area) + continue; + /* run the tracker! */ tracked = libmv_trackRegion(&options, track_context->search_area, @@ -3141,7 +3161,7 @@ static int stabilization_median_point_get(MovieTracking *tracking, int framenr, if (track->flag & TRACK_USE_2D_STAB) { MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr); - DO_MINMAX2(marker->pos, min, max); + minmax_v2v2_v2(min, max, marker->pos); ok = TRUE; } diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c index 3a8a14290dc..0f861a7ed37 100644 --- a/source/blender/blenkernel/intern/writeffmpeg.c +++ b/source/blender/blenkernel/intern/writeffmpeg.c @@ -111,6 +111,11 @@ static void delete_picture(AVFrame *f) } } +static int use_float_audio_buffer(int codec_id) +{ + return codec_id == CODEC_ID_AAC || codec_id == CODEC_ID_AC3 || codec_id == CODEC_ID_VORBIS; +} + #ifdef WITH_AUDASPACE static int write_audio_frame(void) { @@ -478,9 +483,7 @@ static AVStream *alloc_video_stream(RenderData *rd, int codec_id, AVFormatContex c->time_base.den = 2997; c->time_base.num = 100; } - else if ((double) ((int) rd->frs_sec_base) == - rd->frs_sec_base) - { + else if ((float) ((int) rd->frs_sec_base) == rd->frs_sec_base) { c->time_base.den = rd->frs_sec; c->time_base.num = (int) rd->frs_sec_base; } @@ -601,12 +604,14 @@ static AVStream *alloc_video_stream(RenderData *rd, int codec_id, AVFormatContex /* Prepare an audio stream for the output file */ -static AVStream *alloc_audio_stream(RenderData *rd, int codec_id, AVFormatContext *of) +static AVStream *alloc_audio_stream(RenderData *rd, int codec_id, AVFormatContext *of, char *error, int error_size) { AVStream *st; AVCodecContext *c; AVCodec *codec; + error[0] = '\0'; + st = av_new_stream(of, 1); if (!st) return NULL; @@ -618,6 +623,10 @@ static AVStream *alloc_audio_stream(RenderData *rd, int codec_id, AVFormatContex c->bit_rate = ffmpeg_audio_bitrate * 1000; c->sample_fmt = AV_SAMPLE_FMT_S16; c->channels = rd->ffcodecdata.audio_channels; + if (use_float_audio_buffer(codec_id)) { + c->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL; + c->sample_fmt = AV_SAMPLE_FMT_FLT; + } codec = avcodec_find_encoder(c->codec_id); if (!codec) { //XXX error("Couldn't find a valid audio codec"); @@ -628,6 +637,7 @@ static AVStream *alloc_audio_stream(RenderData *rd, int codec_id, AVFormatContex if (avcodec_open(c, codec) < 0) { //XXX error("Couldn't initialize audio codec"); + BLI_strncpy(error, IMB_ffmpeg_last_error(), error_size); return NULL; } @@ -648,7 +658,12 @@ static AVStream *alloc_audio_stream(RenderData *rd, int codec_id, AVFormatContex audio_output_buffer = (uint8_t *) av_malloc(audio_outbuf_size); - audio_input_buffer = (uint8_t *) av_malloc(audio_input_samples * c->channels * sizeof(int16_t)); + if (use_float_audio_buffer(codec_id)) { + audio_input_buffer = (uint8_t *) av_malloc(audio_input_samples * c->channels * sizeof(float)); + } + else { + audio_input_buffer = (uint8_t *) av_malloc(audio_input_samples * c->channels * sizeof(int16_t)); + } audio_time = 0.0f; @@ -803,9 +818,12 @@ static int start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty, Report } if (ffmpeg_audio_codec != CODEC_ID_NONE) { - audio_stream = alloc_audio_stream(rd, fmt->audio_codec, of); + audio_stream = alloc_audio_stream(rd, fmt->audio_codec, of, error, sizeof(error)); if (!audio_stream) { - BKE_report(reports, RPT_ERROR, "Error initializing audio stream"); + if (error[0]) + BKE_report(reports, RPT_ERROR, error); + else + BKE_report(reports, RPT_ERROR, "Error initializing audio stream"); av_dict_free(&opts); return 0; } @@ -945,7 +963,12 @@ int BKE_ffmpeg_start(struct Scene *scene, RenderData *rd, int rectx, int recty, AVCodecContext *c = audio_stream->codec; AUD_DeviceSpecs specs; specs.channels = c->channels; - specs.format = AUD_FORMAT_S16; + if (use_float_audio_buffer(c->codec_id)) { + specs.format = AUD_FORMAT_FLOAT32; + } + else { + specs.format = AUD_FORMAT_S16; + } specs.rate = rd->ffcodecdata.audio_mixrate; audio_mixdown_device = sound_mixdown(scene, specs, rd->sfra, rd->ffcodecdata.audio_volume); #ifdef FFMPEG_CODEC_TIME_BASE @@ -999,7 +1022,7 @@ int BKE_ffmpeg_append(RenderData *rd, int start_frame, int frame, int *pixels, i } #ifdef WITH_AUDASPACE - write_audio_frames((frame - rd->sfra) / (((double)rd->frs_sec) / rd->frs_sec_base)); + write_audio_frames((frame - rd->sfra) / (((double)rd->frs_sec) / (double)rd->frs_sec_base)); #endif return success; } -- cgit v1.2.3 From ec870eb2144391dbf0aed9d23b4e79c9dd982003 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 10 Dec 2012 16:38:13 +0000 Subject: code cleanup: camera tracking - Moved keyframes and refirement flags into reconstruction options structure - Moved distortion coefficients and other camera intrinsics into own structure - Cleaned up reconstruction functions in libmv c-api --- source/blender/blenkernel/intern/tracking.c | 48 ++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 14 deletions(-) (limited to 'source/blender/blenkernel/intern') diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index 30b48401046..16415258eb5 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -2932,6 +2932,31 @@ static void reconstruct_update_solve_cb(void *customdata, double progress, const BLI_snprintf(progressdata->stats_message, progressdata->message_size, "Solving camera | %s", message); } + +static void camraIntrincicsOptionsFromContext(libmv_cameraIntrinsicsOptions *camera_intrinsics_options, + MovieReconstructContext *context) +{ + camera_intrinsics_options->focal_length = context->focal_length; + + camera_intrinsics_options->principal_point_x = context->principal_point[0]; + camera_intrinsics_options->principal_point_y = context->principal_point[1]; + + camera_intrinsics_options->k1 = context->k1; + camera_intrinsics_options->k2 = context->k2; + camera_intrinsics_options->k3 = context->k3; +} + +static void reconstructionOptionsFromContext(libmv_reconstructionOptions *reconstruction_options, + MovieReconstructContext *context) +{ + reconstruction_options->keyframe1 = context->keyframe1; + reconstruction_options->keyframe2 = context->keyframe2; + + reconstruction_options->refine_intrinsics = context->refine_flags; + + reconstruction_options->success_threshold = context->success_threshold; + reconstruction_options->use_fallback_reconstruction = context->use_fallback_reconstruction; +} #endif void BKE_tracking_reconstruction_solve(MovieReconstructContext *context, short *stop, short *do_update, @@ -2942,32 +2967,27 @@ void BKE_tracking_reconstruction_solve(MovieReconstructContext *context, short * ReconstructProgressData progressdata; + libmv_cameraIntrinsicsOptions camera_intrinsics_options; + libmv_reconstructionOptions reconstruction_options; + progressdata.stop = stop; progressdata.do_update = do_update; progressdata.progress = progress; progressdata.stats_message = stats_message; progressdata.message_size = message_size; + camraIntrincicsOptionsFromContext(&camera_intrinsics_options, context); + reconstructionOptionsFromContext(&reconstruction_options, context); + if (context->motion_flag & TRACKING_MOTION_MODAL) { context->reconstruction = libmv_solveModal(context->tracks, - context->focal_length, - context->principal_point[0], context->principal_point[1], - context->k1, context->k2, context->k3, + &camera_intrinsics_options, reconstruct_update_solve_cb, &progressdata); } else { - struct libmv_reconstructionOptions options; - - options.success_threshold = context->success_threshold; - options.use_fallback_reconstruction = context->use_fallback_reconstruction; - context->reconstruction = libmv_solveReconstruction(context->tracks, - context->keyframe1, context->keyframe2, - context->refine_flags, - context->focal_length, - context->principal_point[0], context->principal_point[1], - context->k1, context->k2, context->k3, - &options, + &camera_intrinsics_options, + &reconstruction_options, reconstruct_update_solve_cb, &progressdata); } -- cgit v1.2.3 From 5137b5a146e9ed701f2b41bcd7cb08a6251e9601 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 10 Dec 2012 16:38:28 +0000 Subject: Camera tracking: libmv distortion API now also uses camera intrinsics structure instead of passing all the parameters to every function. Makes it much easier to tweak distortion model. --- source/blender/blenkernel/intern/tracking.c | 54 +++++++++++++++++++++-------- 1 file changed, 39 insertions(+), 15 deletions(-) (limited to 'source/blender/blenkernel/intern') diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index 16415258eb5..5e8ef23e000 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -1426,6 +1426,27 @@ void BKE_tracking_camera_get_reconstructed_interpolate(MovieTracking *tracking, /*********************** Distortion/Undistortion *************************/ +#ifdef WITH_LIBMV +static void cameraIntrinscisOptionsFromTracking(libmv_cameraIntrinsicsOptions *camera_intrinsics_options, + MovieTracking *tracking, int calibration_width, int calibration_height) +{ + MovieTrackingCamera *camera = &tracking->camera; + float aspy = 1.0f / tracking->camera.pixel_aspect; + + camera_intrinsics_options->focal_length = camera->focal; + + camera_intrinsics_options->principal_point_x = camera->principal[0]; + camera_intrinsics_options->principal_point_y = camera->principal[1] * aspy; + + camera_intrinsics_options->k1 = camera->k1; + camera_intrinsics_options->k2 = camera->k2; + camera_intrinsics_options->k3 = camera->k3; + + camera_intrinsics_options->image_width = calibration_width; + camera_intrinsics_options->image_height = (double) calibration_height * aspy; +} +#endif + MovieDistortion *BKE_tracking_distortion_new(void) { MovieDistortion *distortion; @@ -1438,21 +1459,17 @@ MovieDistortion *BKE_tracking_distortion_new(void) void BKE_tracking_distortion_update(MovieDistortion *distortion, MovieTracking *tracking, int calibration_width, int calibration_height) { - MovieTrackingCamera *camera = &tracking->camera; - float aspy = 1.0f / tracking->camera.pixel_aspect; - #ifdef WITH_LIBMV + libmv_cameraIntrinsicsOptions camera_intrinsics_options; + + cameraIntrinscisOptionsFromTracking(&camera_intrinsics_options, tracking, + calibration_width, calibration_height); + if (!distortion->intrinsics) { - distortion->intrinsics = libmv_CameraIntrinsicsNew(camera->focal, - camera->principal[0], camera->principal[1] * aspy, - camera->k1, camera->k2, camera->k3, - calibration_width, calibration_height * aspy); + distortion->intrinsics = libmv_CameraIntrinsicsNew(&camera_intrinsics_options); } else { - libmv_CameraIntrinsicsUpdate(distortion->intrinsics, camera->focal, - camera->principal[0], camera->principal[1] * aspy, - camera->k1, camera->k2, camera->k3, - calibration_width, calibration_height * aspy); + libmv_CameraIntrinsicsUpdate(distortion->intrinsics, &camera_intrinsics_options); } #else (void) distortion; @@ -1540,15 +1557,17 @@ void BKE_tracking_distort_v2(MovieTracking *tracking, const float co[2], float r MovieTrackingCamera *camera = &tracking->camera; #ifdef WITH_LIBMV + libmv_cameraIntrinsicsOptions camera_intrinsics_options; double x, y; float aspy = 1.0f / tracking->camera.pixel_aspect; + cameraIntrinscisOptionsFromTracking(&camera_intrinsics_options, tracking, 0, 0); + /* normalize coords */ x = (co[0] - camera->principal[0]) / camera->focal; y = (co[1] - camera->principal[1] * aspy) / camera->focal; - libmv_applyCameraIntrinsics(camera->focal, camera->principal[0], camera->principal[1] * aspy, - camera->k1, camera->k2, camera->k3, x, y, &x, &y); + libmv_applyCameraIntrinsics(&camera_intrinsics_options, x, y, &x, &y); /* result is in image coords already */ r_co[0] = x; @@ -1565,11 +1584,13 @@ void BKE_tracking_undistort_v2(MovieTracking *tracking, const float co[2], float MovieTrackingCamera *camera = &tracking->camera; #ifdef WITH_LIBMV + libmv_cameraIntrinsicsOptions camera_intrinsics_options; double x = co[0], y = co[1]; float aspy = 1.0f / tracking->camera.pixel_aspect; - libmv_InvertIntrinsics(camera->focal, camera->principal[0], camera->principal[1] * aspy, - camera->k1, camera->k2, camera->k3, x, y, &x, &y); + cameraIntrinscisOptionsFromTracking(&camera_intrinsics_options, tracking, 0, 0); + + libmv_InvertIntrinsics(&camera_intrinsics_options, x, y, &x, &y); r_co[0] = x * camera->focal + camera->principal[0]; r_co[1] = y * camera->focal + camera->principal[1] * aspy; @@ -2944,6 +2965,9 @@ static void camraIntrincicsOptionsFromContext(libmv_cameraIntrinsicsOptions *cam camera_intrinsics_options->k1 = context->k1; camera_intrinsics_options->k2 = context->k2; camera_intrinsics_options->k3 = context->k3; + + camera_intrinsics_options->image_width = 0; + camera_intrinsics_options->image_height = 0; } static void reconstructionOptionsFromContext(libmv_reconstructionOptions *reconstruction_options, -- cgit v1.2.3