From 5520331215ffec52cd518f30bdf6e6276840e290 Mon Sep 17 00:00:00 2001 From: Tamito Kajiyama Date: Tue, 11 Jun 2013 02:32:01 +0000 Subject: [PATCH 01/37] Fix #35561: freestyle + read full sample layers = crash. Now add_freestyle() in pipeline.c takes a second argument to enable/disable stroke rendering. When stroke rendering is disabled, the function allocates data structures but does not perform stroke rendering. The allocated data structures (mostly left unpopulated with data elements) are intended to allow for the Read Full Sample Layers (Shift-R) command in the compositor. --- source/blender/freestyle/FRS_freestyle.h | 2 +- .../intern/application/Controller.cpp | 7 +++-- .../freestyle/intern/application/Controller.h | 2 +- .../BlenderStrokeRenderer.cpp | 4 +-- .../blender_interface/BlenderStrokeRenderer.h | 2 +- .../blender_interface/FRS_freestyle.cpp | 7 +++-- .../render/extern/include/RE_pipeline.h | 2 +- .../blender/render/intern/source/pipeline.c | 29 ++++++++++++++----- 8 files changed, 37 insertions(+), 18 deletions(-) diff --git a/source/blender/freestyle/FRS_freestyle.h b/source/blender/freestyle/FRS_freestyle.h index b10a73277bf..7be51b37f7a 100644 --- a/source/blender/freestyle/FRS_freestyle.h +++ b/source/blender/freestyle/FRS_freestyle.h @@ -45,7 +45,7 @@ void FRS_set_context(struct bContext *C); void FRS_read_file(struct bContext *C); int FRS_is_freestyle_enabled(struct SceneRenderLayer *srl); void FRS_init_stroke_rendering(struct Render *re); -struct Render *FRS_do_stroke_rendering(struct Render *re, struct SceneRenderLayer *srl); +struct Render *FRS_do_stroke_rendering(struct Render *re, struct SceneRenderLayer *srl, int render); void FRS_finish_stroke_rendering(struct Render *re); void FRS_composite_result(struct Render *re, struct SceneRenderLayer *srl, struct Render *freestyle_render); void FRS_exit(void); diff --git a/source/blender/freestyle/intern/application/Controller.cpp b/source/blender/freestyle/intern/application/Controller.cpp index 436cdbfe6b5..dbf3fa8349e 100644 --- a/source/blender/freestyle/intern/application/Controller.cpp +++ b/source/blender/freestyle/intern/application/Controller.cpp @@ -833,17 +833,18 @@ void Controller::ResetRenderCount() _render_count = 0; } -Render *Controller::RenderStrokes(Render *re) +Render *Controller::RenderStrokes(Render *re, bool render) { _Chrono.start(); BlenderStrokeRenderer *blenderRenderer = new BlenderStrokeRenderer(re, ++_render_count); - _Canvas->Render(blenderRenderer); + if (render) + _Canvas->Render(blenderRenderer); real d = _Chrono.stop(); if (G.debug & G_DEBUG_FREESTYLE) { cout << "Temporary scene generation: " << d << endl; } _Chrono.start(); - Render *freestyle_render = blenderRenderer->RenderScene(re); + Render *freestyle_render = blenderRenderer->RenderScene(re, render); d = _Chrono.stop(); if (G.debug & G_DEBUG_FREESTYLE) { cout << "Stroke rendering : " << d << endl; diff --git a/source/blender/freestyle/intern/application/Controller.h b/source/blender/freestyle/intern/application/Controller.h index 3315fe7e20b..c8eaaf5486b 100644 --- a/source/blender/freestyle/intern/application/Controller.h +++ b/source/blender/freestyle/intern/application/Controller.h @@ -86,7 +86,7 @@ public: void toggleEdgeTesselationNature(Nature::EdgeNature iNature); void DrawStrokes(); void ResetRenderCount(); - Render *RenderStrokes(Render *re); + Render *RenderStrokes(Render *re, bool render); void SwapStyleModules(unsigned i1, unsigned i2); void InsertStyleModule(unsigned index, const char *iFileName); void InsertStyleModule(unsigned index, const char *iName, struct Text *iText); diff --git a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp index 294da904497..096447de214 100644 --- a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp +++ b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp @@ -476,7 +476,7 @@ Object *BlenderStrokeRenderer::NewMesh() const return ob; } -Render *BlenderStrokeRenderer::RenderScene(Render *re) +Render *BlenderStrokeRenderer::RenderScene(Render *re, bool render) { Camera *camera = (Camera *)freestyle_scene->camera->data; if (camera->clipend < _z) @@ -489,7 +489,7 @@ Render *BlenderStrokeRenderer::RenderScene(Render *re) Render *freestyle_render = RE_NewRender(freestyle_scene->id.name); - RE_RenderFreestyleStrokes(freestyle_render, freestyle_bmain, freestyle_scene); + RE_RenderFreestyleStrokes(freestyle_render, freestyle_bmain, freestyle_scene, render); return freestyle_render; } diff --git a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.h b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.h index 4d34f70f689..ae0e6bed3b2 100644 --- a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.h +++ b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.h @@ -51,7 +51,7 @@ public: Object *NewMesh() const; - Render *RenderScene(Render *re); + Render *RenderScene(Render *re, bool render); protected: Main *freestyle_bmain; diff --git a/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp b/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp index d5002d6fa39..8cb44d05b84 100644 --- a/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp +++ b/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp @@ -580,12 +580,15 @@ void FRS_init_stroke_rendering(Render *re) controller->ResetRenderCount(); } -Render *FRS_do_stroke_rendering(Render *re, SceneRenderLayer *srl) +Render *FRS_do_stroke_rendering(Render *re, SceneRenderLayer *srl, int render) { Main bmain = {0}; Render *freestyle_render = NULL; Text *text, *next_text; + if (!render) + return controller->RenderStrokes(re, false); + RenderMonitor monitor(re); controller->setRenderMonitor(&monitor); @@ -619,7 +622,7 @@ Render *FRS_do_stroke_rendering(Render *re, SceneRenderLayer *srl) re->i.infostr = NULL; freestyle_scene = re->scene; controller->DrawStrokes(); - freestyle_render = controller->RenderStrokes(re); + freestyle_render = controller->RenderStrokes(re, true); controller->CloseFile(); freestyle_scene = NULL; diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h index 52d42cd20a4..118d0036464 100644 --- a/source/blender/render/extern/include/RE_pipeline.h +++ b/source/blender/render/extern/include/RE_pipeline.h @@ -226,7 +226,7 @@ void RE_TileProcessor(struct Render *re); void RE_BlenderFrame(struct Render *re, struct Main *bmain, struct Scene *scene, struct SceneRenderLayer *srl, struct Object *camera_override, unsigned int lay, int frame, const short write_still); void RE_BlenderAnim(struct Render *re, struct Main *bmain, struct Scene *scene, struct Object *camera_override, unsigned int lay, int sfra, int efra, int tfra); #ifdef WITH_FREESTYLE -void RE_RenderFreestyleStrokes(struct Render *re, struct Main *bmain, struct Scene *scene); +void RE_RenderFreestyleStrokes(struct Render *re, struct Main *bmain, struct Scene *scene, int render); #endif /* error reporting */ diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index c8f8f844e5f..068df215edb 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -1081,7 +1081,7 @@ static void threaded_tile_processor(Render *re) } #ifdef WITH_FREESTYLE -static void add_freestyle(Render *re); +static void add_freestyle(Render *re, int render); static void free_all_freestyle_renders(void); #endif @@ -1097,7 +1097,7 @@ void RE_TileProcessor(Render *re) /* Freestyle */ if (re->r.mode & R_EDGE_FRS) { if (!re->test_break(re->tbh)) { - add_freestyle(re); + add_freestyle(re, 1); free_all_freestyle_renders(); @@ -1150,7 +1150,7 @@ static void do_render_3d(Render *re) /* Freestyle */ if (re->r.mode & R_EDGE_FRS) if (!re->test_break(re->tbh)) - add_freestyle(re); + add_freestyle(re, 1); #endif /* do left-over 3d post effects (flares) */ @@ -1633,7 +1633,7 @@ static void render_composit_stats(void *UNUSED(arg), char *str) #ifdef WITH_FREESTYLE /* invokes Freestyle stroke rendering */ -static void add_freestyle(Render *re) +static void add_freestyle(Render *re, int render) { SceneRenderLayer *srl, *actsrl; LinkData *link; @@ -1659,7 +1659,7 @@ static void add_freestyle(Render *re) if ((re->r.scemode & R_SINGLE_LAYER) && srl != actsrl) continue; if (FRS_is_freestyle_enabled(srl)) { - link->data = (void *)FRS_do_stroke_rendering(re, srl); + link->data = (void *)FRS_do_stroke_rendering(re, srl, render); } } @@ -1853,6 +1853,11 @@ void RE_MergeFullSample(Render *re, Main *bmain, Scene *sce, bNodeTree *ntree) for (scene = re->main->scene.first; scene; scene = scene->id.next) scene->id.flag |= LIB_DOIT; +#ifdef WITH_FREESTYLE + for (scene = re->freestyle_bmain.scene.first; scene; scene = scene->id.next) + scene->id.flag &= ~LIB_DOIT; +#endif + for (node = ntree->nodes.first; node; node = node->next) { if (node->type == CMP_NODE_R_LAYERS) { Scene *nodescene = (Scene *)node->id; @@ -1876,7 +1881,16 @@ void RE_MergeFullSample(Render *re, Main *bmain, Scene *sce, bNodeTree *ntree) re->display_init(re->dih, re->result); re->display_clear(re->dch, re->result); +#ifdef WITH_FREESTYLE + if (re->r.mode & R_EDGE_FRS) + add_freestyle(re, 0); +#endif + do_merge_fullsample(re, ntree); + +#ifdef WITH_FREESTYLE + free_all_freestyle_renders(); +#endif } /* returns fully composited render-result on given time step (in RenderData) */ @@ -2445,11 +2459,12 @@ void RE_BlenderFrame(Render *re, Main *bmain, Scene *scene, SceneRenderLayer *sr } #ifdef WITH_FREESTYLE -void RE_RenderFreestyleStrokes(Render *re, Main *bmain, Scene *scene) +void RE_RenderFreestyleStrokes(Render *re, Main *bmain, Scene *scene, int render) { re->result_ok= 0; if (render_initialize_from_main(re, bmain, scene, NULL, NULL, scene->lay, 0, 0)) { - do_render_fields_blur_3d(re); + if (render) + do_render_fields_blur_3d(re); } re->result_ok = 1; } From 5e892def15a571e7d83b9edbc108f54f8a9e810e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 11 Jun 2013 05:09:12 +0000 Subject: [PATCH 02/37] fix [#35656] Crash on File Browser --- source/blender/editors/screen/area.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index 69c1d2cf169..429156ea6a7 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -1339,6 +1339,7 @@ void area_copy_data(ScrArea *sa1, ScrArea *sa2, int swap_space) sa1->headertype = sa2->headertype; sa1->spacetype = sa2->spacetype; + sa1->type = sa2->type; sa1->butspacetype = sa2->butspacetype; if (swap_space == 1) { From f0e6e60f65f2e7b55df15a9aad37a40e23785df3 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 11 Jun 2013 05:21:36 +0000 Subject: [PATCH 03/37] fix for problem where curve handles in editmode could be obscured by other selected objects (referred to in [#35669]) --- source/blender/editors/space_view3d/drawobject.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index db10c1c5957..86e3560786c 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -5460,7 +5460,7 @@ static void drawnurb(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, drawDispList(scene, v3d, rv3d, base, dt, dflag, ob_wire_col); - if (v3d->zbuf) glDisable(GL_DEPTH_TEST); + if (v3d->zbuf) glDepthFunc(GL_ALWAYS); /* first non-selected and active handles */ index = 0; @@ -5481,7 +5481,7 @@ static void drawnurb(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, drawvertsN(nu, 0, hide_handles, NULL); } - if (v3d->zbuf) glEnable(GL_DEPTH_TEST); + if (v3d->zbuf) glDepthFunc(GL_LEQUAL); /* direction vectors for 3d curve paths * when at its lowest, don't render normals */ From c730ae0921b6948e17a751e285536320e5ac0967 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 11 Jun 2013 05:56:02 +0000 Subject: [PATCH 04/37] another case that should have been in r57371, also reduce type conversions in compassion. --- .../blender/editors/space_view3d/drawobject.c | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 86e3560786c..4793c9af068 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -105,8 +105,8 @@ typedef enum eWireDrawMode { typedef struct drawDMVerts_userData { BMEditMesh *em; - int sel; BMVert *eve_act; + char sel; /* cached theme values */ unsigned char th_editmesh_active[4]; @@ -2038,13 +2038,13 @@ static void draw_dm_face_normals(BMEditMesh *em, Scene *scene, Object *ob, Deriv static void draw_dm_face_centers__mapFunc(void *userData, int index, const float cent[3], const float UNUSED(no[3])) { BMFace *efa = EDBM_face_at_index(((void **)userData)[0], index); - int sel = *(((int **)userData)[1]); + const char sel = *(((char **)userData)[1]); if (efa && !BM_elem_flag_test(efa, BM_ELEM_HIDDEN) && BM_elem_flag_test(efa, BM_ELEM_SELECT) == sel) { bglVertex3fv(cent); } } -static void draw_dm_face_centers(BMEditMesh *em, DerivedMesh *dm, int sel) +static void draw_dm_face_centers(BMEditMesh *em, DerivedMesh *dm, char sel) { void *ptrs[2] = {em, &sel}; @@ -2065,9 +2065,7 @@ static void draw_dm_vert_normals__mapFunc(void *userData, int index, const float copy_v3_v3(no, no_f); } else { - no[0] = no_s[0] / 32767.0f; - no[1] = no_s[1] / 32767.0f; - no[2] = no_s[2] / 32767.0f; + normal_short_to_float_v3(no, no_s); } if (!data->uniform_scale) { @@ -2147,7 +2145,7 @@ static void draw_dm_verts__mapFunc(void *userData, int index, const float co[3], } } -static void draw_dm_verts(BMEditMesh *em, DerivedMesh *dm, int sel, BMVert *eve_act, +static void draw_dm_verts(BMEditMesh *em, DerivedMesh *dm, const char sel, BMVert *eve_act, RegionView3D *rv3d) { drawDMVerts_userData data; @@ -5092,7 +5090,7 @@ static void ob_draw_RE_motion(float com[3], float rotscale[3][3], float itw, flo /* place to add drawers */ -static void drawhandlesN(Nurb *nu, short sel, short hide_handles) +static void drawhandlesN(Nurb *nu, const char sel, const bool hide_handles) { BezTriple *bezt; float *fp; @@ -5187,7 +5185,7 @@ static void drawhandlesN_active(Nurb *nu) glLineWidth(1); } -static void drawvertsN(Nurb *nu, short sel, short hide_handles, void *lastsel) +static void drawvertsN(Nurb *nu, const char sel, const bool hide_handles, void *lastsel) { BezTriple *bezt; BPoint *bp; @@ -5450,7 +5448,7 @@ static void drawnurb(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, Curve *cu = ob->data; Nurb *nu; BevList *bl; - short hide_handles = (cu->drawflag & CU_HIDE_HANDLES); + const bool hide_handles = (cu->drawflag & CU_HIDE_HANDLES) != 0; int index; unsigned char wire_col[3]; @@ -5526,13 +5524,13 @@ static void drawnurb(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, } } - if (v3d->zbuf) glDisable(GL_DEPTH_TEST); + if (v3d->zbuf) glDepthFunc(GL_ALWAYS); for (nu = nurb; nu; nu = nu->next) { drawvertsN(nu, 1, hide_handles, cu->lastsel); } - if (v3d->zbuf) glEnable(GL_DEPTH_TEST); + if (v3d->zbuf) glDepthFunc(GL_LEQUAL); } /* draw a sphere for use as an empty drawtype */ From 401eaa448b7437c55aeec46b26f8c0e751f421ac Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 11 Jun 2013 08:06:59 +0000 Subject: [PATCH 05/37] Fix for distortion happens when flipping mesh normals Issue was caused by missing X/Y displacement components flip when flipping the normals (flipping the normals changes the tangent space apparently and displacement vectors need to be modified to correspond to new space). Reported by Jonathan Williamson in IRC. --- source/blender/bmesh/intern/bmesh_core.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c index 56ac6c379c2..b7eeceae494 100644 --- a/source/blender/bmesh/intern/bmesh_core.c +++ b/source/blender/bmesh/intern/bmesh_core.c @@ -791,7 +791,10 @@ static bool bm_loop_reverse_loop(BMesh *bm, BMFace *f for (x = 0; x < sides; x++) { for (y = 0; y < x; y++) { swap_v3_v3(co[y * sides + x], co[sides * x + y]); + SWAP(float, co[y * sides + x][0], co[y * sides + x][1]); + SWAP(float, co[x * sides + y][0], co[x * sides + y][1]); } + SWAP(float, co[x * sides + x][0], co[x * sides + x][1]); } } } From e969bb207d125e4641ea91a7b8d3e9a6fe131deb Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 11 Jun 2013 08:07:05 +0000 Subject: [PATCH 06/37] Fix compilation error caused by recent wavelength node commit Apparently, it's bad idea to rely on compiler to cast NULL which is (void*)0 to int -- and in fact if i was a compiler would also generate an error. Further, couldn't see why we need to pass NULL or 0 th add_node, argument value is defautl to 0 already. --- intern/cycles/render/nodes.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index bec45e23f7a..74033d5c2fa 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -2969,7 +2969,7 @@ void WavelengthNode::compile(SVMCompiler& compiler) compiler.stack_assign(wavelength_in); compiler.stack_assign(color_out); - compiler.add_node(NODE_WAVELENGTH, wavelength_in->stack_offset, color_out->stack_offset, NULL); + compiler.add_node(NODE_WAVELENGTH, wavelength_in->stack_offset, color_out->stack_offset); } void WavelengthNode::compile(OSLCompiler& compiler) From e895c8302ea0f89a8a2040157d0f36e6ea978864 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 11 Jun 2013 09:14:39 +0000 Subject: [PATCH 07/37] Use OpenMP threads in bm_loop_interp_mdisps Gives approx 2x speedup on my laptop on such operations as mesh subdivision in edit mode. Desktops with fancier CPUs could benefit even more. Thanks Campbell for review! --- source/blender/bmesh/intern/bmesh_interp.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/source/blender/bmesh/intern/bmesh_interp.c b/source/blender/bmesh/intern/bmesh_interp.c index bf7bfc1123c..9c85a4fc4e5 100644 --- a/source/blender/bmesh/intern/bmesh_interp.c +++ b/source/blender/bmesh/intern/bmesh_interp.c @@ -432,10 +432,8 @@ static void bm_loop_flip_disp(float source_axis_x[3], float source_axis_y[3], static void bm_loop_interp_mdisps(BMesh *bm, BMLoop *target, BMFace *source) { MDisps *mdisps; - BMLoop *l_iter; - BMLoop *l_first; - float x, y, d, v1[3], v2[3], v3[3], v4[3] = {0.0f, 0.0f, 0.0f}, e1[3], e2[3]; - int ix, iy, res; + float d, v1[3], v2[3], v3[3], v4[3] = {0.0f, 0.0f, 0.0f}, e1[3], e2[3]; + int ix, res; float axis_x[3], axis_y[3]; /* ignore 2-edged faces */ @@ -467,10 +465,15 @@ static void bm_loop_interp_mdisps(BMesh *bm, BMLoop *target, BMFace *source) res = (int)sqrt(mdisps->totdisp); d = 1.0f / (float)(res - 1); - for (x = 0.0f, ix = 0; ix < res; x += d, ix++) { + #pragma omp parallel for if(res > 3) + for (ix = 0; ix < res; ix++) { + float x = d * ix, y; + int iy; for (y = 0.0f, iy = 0; iy < res; y += d, iy++) { + BMLoop *l_iter; + BMLoop *l_first; float co1[3], co2[3], co[3]; - + copy_v3_v3(co1, e1); mul_v3_fl(co1, y); From 568f0c70c13ed8aca358b9b50606c7cd671ce2e2 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 11 Jun 2013 11:21:16 +0000 Subject: [PATCH 08/37] Fix #35704: Simplify on scene with dupli recursion crashes Couple of issues here: - User shouldn't be able to run into dupligroup recursion. It was checking already when setting a group for dupli. Added check to operator which adds object to group. - It's still possible files with recursion are hanging around, so made simplify function robust to such kind of crap. --- source/blender/editors/object/object_group.c | 62 ++++++++++++++++++++ source/blender/makesrna/intern/rna_scene.c | 7 +++ 2 files changed, 69 insertions(+) diff --git a/source/blender/editors/object/object_group.c b/source/blender/editors/object/object_group.c index 8afd3049b84..f48e4ff5056 100644 --- a/source/blender/editors/object/object_group.c +++ b/source/blender/editors/object/object_group.c @@ -42,6 +42,7 @@ #include "BKE_context.h" #include "BKE_depsgraph.h" #include "BKE_group.h" +#include "BKE_library.h" #include "BKE_main.h" #include "BKE_report.h" #include "BKE_object.h" @@ -377,8 +378,50 @@ void OBJECT_OT_group_add(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } +static bool group_link_early_exit_check(Group *group, Object *object) +{ + GroupObject *group_object; + + for (group_object = group->gobject.first; group_object; group_object = group_object->next) { + if (group_object->ob == object) { + return true; + } + } + + return false; +} + +static bool check_group_contains_object_recursive(Group *group, Object *object) +{ + GroupObject *group_object; + + if ((group->id.flag & LIB_DOIT) == 0) { + /* Cycle already exists in groups, let's prevent further crappyness */ + return true; + } + + group->id.flag &= ~LIB_DOIT; + + for (group_object = group->gobject.first; group_object; group_object = group_object->next) { + Object *current_object = group_object->ob; + + if (current_object == object) { + return true; + } + + if (current_object->dup_group) { + if (check_group_contains_object_recursive(current_object->dup_group, object)) { + return true; + } + } + } + + return false; +} + static int group_link_exec(bContext *C, wmOperator *op) { + Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); Object *ob = ED_object_context(C); Group *group = BLI_findlink(&CTX_data_main(C)->group, RNA_enum_get(op->ptr, "group")); @@ -386,6 +429,25 @@ static int group_link_exec(bContext *C, wmOperator *op) if (ELEM(NULL, ob, group)) return OPERATOR_CANCELLED; + /* Early return check, if the object is already in group + * we could sckip all the dependency check and just consider + * operator is finished. + */ + if (group_link_early_exit_check(group, ob)) { + return OPERATOR_FINISHED; + } + + /* Adding object to group which is used as dupligroup for self is bad idea. + * + * It is also bad idea to add object to group which is in group which + * contains our current object. + */ + tag_main_lb(&bmain->group, TRUE); + if (ob->dup_group == group || check_group_contains_object_recursive(group, ob)) { + BKE_report(op->reports, RPT_ERROR, "Could not add the group because of dependency cycle detected"); + return OPERATOR_CANCELLED; + } + BKE_group_object_add(group, ob, scene, NULL); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index ec672522a76..0218c188062 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -1255,6 +1255,12 @@ static void object_simplify_update(Object *ob) ModifierData *md; ParticleSystem *psys; + if ((ob->id.flag & LIB_DOIT) == 0) { + return; + } + + ob->id.flag &= ~LIB_DOIT; + for (md = ob->modifiers.first; md; md = md->next) { if (ELEM3(md->type, eModifierType_Subsurf, eModifierType_Multires, eModifierType_ParticleSystem)) { ob->recalc |= PSYS_RECALC_CHILD; @@ -1279,6 +1285,7 @@ static void rna_Scene_use_simplify_update(Main *bmain, Scene *UNUSED(scene), Poi Scene *sce_iter; Base *base; + tag_main_lb(&bmain->object, TRUE); for (SETLOOPER(sce, sce_iter, base)) object_simplify_update(base->object); From 789fabba4187e253c48defdc4fe5546e551de965 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 11 Jun 2013 12:37:56 +0000 Subject: [PATCH 09/37] Fix #35405: properties editor preview render restarted unnecessarily after F12 render. --- source/blender/editors/render/render_internal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c index da2f8bd2f9d..4e94e534c4d 100644 --- a/source/blender/editors/render/render_internal.c +++ b/source/blender/editors/render/render_internal.c @@ -442,7 +442,7 @@ static void render_endjob(void *rjv) /* XXX render stability hack */ G.is_rendering = FALSE; - WM_main_add_notifier(NC_WINDOW, NULL); + WM_main_add_notifier(NC_SCENE|ND_RENDER_RESULT, NULL); /* Partial render result will always update display buffer * for first render layer only. This is nice because you'll From de83a4f13c1a6b4d31f3db7db696be3362b21199 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 11 Jun 2013 12:52:02 +0000 Subject: [PATCH 10/37] Fix #35251: cycles crash rendering with a particular user preferences configuration. --- intern/cycles/blender/blender_python.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/intern/cycles/blender/blender_python.cpp b/intern/cycles/blender/blender_python.cpp index 9600340a1f3..9a86cee6546 100644 --- a/intern/cycles/blender/blender_python.cpp +++ b/intern/cycles/blender/blender_python.cpp @@ -63,7 +63,7 @@ static PyObject *create_func(PyObject *self, PyObject *args) BL::RenderEngine engine(engineptr); PointerRNA userprefptr; - RNA_id_pointer_create((ID*)PyLong_AsVoidPtr(pyuserpref), &userprefptr); + RNA_pointer_create(NULL, &RNA_UserPreferences, (void*)PyLong_AsVoidPtr(pyuserpref), &userprefptr); BL::UserPreferences userpref(userprefptr); PointerRNA dataptr; From e895e2e0d125d393ca81850d551e139a7070429f Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 11 Jun 2013 14:15:46 +0000 Subject: [PATCH 11/37] Fix #35711: cycles border render issue after recent changes. --- intern/cycles/blender/blender_session.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp index fdce4b16b57..c981e379333 100644 --- a/intern/cycles/blender/blender_session.cpp +++ b/intern/cycles/blender/blender_session.cpp @@ -102,11 +102,14 @@ void BlenderSession::create_session() /* create sync */ sync = new BlenderSync(b_engine, b_data, b_scene, scene, !background, session->progress, session_params.device.type == DEVICE_CPU); - /* for final render we will do sync per render layer */ + /* for final render we will do data sync per render layer */ if(b_v3d) { sync->sync_data(b_v3d, b_engine.camera_override()); sync->sync_view(b_v3d, b_rv3d, width, height); } + else { + sync->sync_camera(b_render, b_engine.camera_override(), width, height); + } /* set buffer parameters */ BufferParams buffer_params = BlenderSync::get_buffer_params(b_render, b_scene, b_v3d, b_rv3d, scene->camera, width, height); From c8f30bc7f09ae0b2df947c18972601f8e3c821e7 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 11 Jun 2013 15:11:55 +0000 Subject: [PATCH 12/37] fix [#35574] Export Key Map issue problem was the keymap failed to import but didnt give any feedback, now it displays error message. --- release/scripts/modules/bpy/utils.py | 40 ++++++++++++++-------- release/scripts/startup/bl_operators/wm.py | 14 ++++---- 2 files changed, 34 insertions(+), 20 deletions(-) diff --git a/release/scripts/modules/bpy/utils.py b/release/scripts/modules/bpy/utils.py index b78105dedb5..ec3891e8d76 100644 --- a/release/scripts/modules/bpy/utils.py +++ b/release/scripts/modules/bpy/utils.py @@ -482,8 +482,9 @@ def preset_find(name, preset_path, display_name=False, ext=".py"): return filepath -def keyconfig_set(filepath): +def keyconfig_set(filepath, report=None): from os.path import basename, splitext + from itertools import chain if _bpy.app.debug_python: print("loading preset:", filepath) @@ -496,25 +497,36 @@ def keyconfig_set(filepath): keyfile = open(filepath) exec(compile(keyfile.read(), filepath, "exec"), {"__file__": filepath}) keyfile.close() + error_msg = "" except: import traceback - traceback.print_exc() + error_msg = traceback.format_exc() - kc_new = [kc for kc in keyconfigs if kc not in keyconfigs_old][0] + if error_msg: + if report is not None: + report({'ERROR'}, error_msg) + print(error_msg) - kc_new.name = "" + kc_new = next(chain(iter(kc for kc in keyconfigs if kc not in keyconfigs_old), (None,))) + if kc_new is None: + if report is not None: + report({'ERROR'}, "Failed to load keymap %r" % filepath) + return False + else: + kc_new.name = "" - # remove duplicates - name = splitext(basename(filepath))[0] - while True: - kc_dupe = keyconfigs.get(name) - if kc_dupe: - keyconfigs.remove(kc_dupe) - else: - break + # remove duplicates + name = splitext(basename(filepath))[0] + while True: + kc_dupe = keyconfigs.get(name) + if kc_dupe: + keyconfigs.remove(kc_dupe) + else: + break - kc_new.name = name - keyconfigs.active = kc_new + kc_new.name = name + keyconfigs.active = kc_new + return True def user_resource(resource_type, path="", create=False): diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py index a2a8c991259..9cd9131ec4b 100644 --- a/release/scripts/startup/bl_operators/wm.py +++ b/release/scripts/startup/bl_operators/wm.py @@ -1199,9 +1199,10 @@ class WM_OT_keyconfig_activate(Operator): ) def execute(self, context): - bpy.utils.keyconfig_set(self.filepath) - return {'FINISHED'} - + if bpy.utils.keyconfig_set(self.filepath, report=self.report): + return {'FINISHED'} + else: + return {'CANCELLED'} class WM_OT_appconfig_default(Operator): bl_idname = "wm.appconfig_default" @@ -1386,9 +1387,10 @@ class WM_OT_keyconfig_import(Operator): return {'CANCELLED'} # sneaky way to check we're actually running the code. - bpy.utils.keyconfig_set(path) - - return {'FINISHED'} + if bpy.utils.keyconfig_set(path, report=self.report): + return {'FINISHED'} + else: + return {'CANCELLED'} def invoke(self, context, event): wm = context.window_manager From 3d21bf96887cf0f936d9f280516c94a814b9fbf2 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 11 Jun 2013 21:58:43 +0000 Subject: [PATCH 13/37] Fix lamp size allowing negative values. --- source/blender/makesrna/intern/rna_lamp.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/blender/makesrna/intern/rna_lamp.c b/source/blender/makesrna/intern/rna_lamp.c index 6be1933f12f..d733d9b4cb6 100644 --- a/source/blender/makesrna/intern/rna_lamp.c +++ b/source/blender/makesrna/intern/rna_lamp.c @@ -675,6 +675,7 @@ static void rna_def_lamp_shadow(StructRNA *srna, int spot, int area) prop = RNA_def_property(srna, "shadow_soft_size", PROP_FLOAT, PROP_DISTANCE); RNA_def_property_float_sdna(prop, NULL, "area_size"); + RNA_def_property_range(prop, 0.0f, FLT_MAX); RNA_def_property_ui_range(prop, 0, 100, 0.1, 3); RNA_def_property_ui_text(prop, "Shadow Soft Size", "Light size for ray shadow sampling (Raytraced shadows)"); RNA_def_property_update(prop, 0, "rna_Lamp_update"); @@ -739,11 +740,13 @@ static void rna_def_area_lamp(BlenderRNA *brna) prop = RNA_def_property(srna, "size", PROP_FLOAT, PROP_DISTANCE); RNA_def_property_float_sdna(prop, NULL, "area_size"); + RNA_def_property_range(prop, 0.0f, FLT_MAX); RNA_def_property_ui_range(prop, 0, 100, 0.1, 3); RNA_def_property_ui_text(prop, "Size", "Size of the area of the area Lamp, X direction size for Rectangle shapes"); RNA_def_property_update(prop, 0, "rna_Lamp_draw_update"); prop = RNA_def_property(srna, "size_y", PROP_FLOAT, PROP_DISTANCE); + RNA_def_property_range(prop, 0.0f, FLT_MAX); RNA_def_property_float_sdna(prop, NULL, "area_sizey"); RNA_def_property_ui_range(prop, 0, 100, 0.1, 3); RNA_def_property_ui_text(prop, "Size Y", From 37f92119e449a56116bc7a78aaafeaa67ee4c493 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 11 Jun 2013 21:58:48 +0000 Subject: [PATCH 14/37] Fix #35665: more CUDA issues with recent kernel changes, tested on sm_20, sm_21 and sm_30 cards, so hopefully it should all work now. Also includes some warnings fixes related to nvcc compiler arguments, should make no difference otherwise. --- intern/cycles/kernel/CMakeLists.txt | 13 +++++- intern/cycles/kernel/kernel_jitter.h | 5 ++- intern/cycles/kernel/kernel_path.h | 59 ++++++++++----------------- intern/cycles/kernel/kernel_random.h | 61 +++++++++++----------------- 4 files changed, 61 insertions(+), 77 deletions(-) diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt index f87f5dec741..8b4466863e0 100644 --- a/intern/cycles/kernel/CMakeLists.txt +++ b/intern/cycles/kernel/CMakeLists.txt @@ -129,9 +129,20 @@ if(WITH_CYCLES_CUDA_BINARIES) foreach(arch ${CYCLES_CUDA_BINARIES_ARCH}) set(cuda_cubin kernel_${arch}.cubin) + if(${arch} MATCHES "sm_1[0-9]") + # sm_1x + set(cuda_arch_flags "--maxrregcount=24 --opencc-options -OPT:Olimit=0") + elseif(${arch} MATCHES "sm_2[0-9]") + # sm_2x + set(cuda_arch_flags "--maxrregcount=24") + else() + # sm_3x + set(cuda_arch_flags "--maxrregcount=32") + endif() + add_custom_command( OUTPUT ${cuda_cubin} - COMMAND ${CUDA_NVCC_EXECUTABLE} -arch=${arch} -m${CUDA_BITS} --cubin ${CMAKE_CURRENT_SOURCE_DIR}/kernel.cu -o ${CMAKE_CURRENT_BINARY_DIR}/${cuda_cubin} --ptxas-options="-v" --maxrregcount=24 --opencc-options -OPT:Olimit=0 -I${CMAKE_CURRENT_SOURCE_DIR}/../util -I${CMAKE_CURRENT_SOURCE_DIR}/svm -DCCL_NAMESPACE_BEGIN= -DCCL_NAMESPACE_END= -DNVCC + COMMAND ${CUDA_NVCC_EXECUTABLE} -arch=${arch} -m${CUDA_BITS} --cubin ${CMAKE_CURRENT_SOURCE_DIR}/kernel.cu -o ${CMAKE_CURRENT_BINARY_DIR}/${cuda_cubin} --ptxas-options="-v" ${cuda_arch_flags} -I${CMAKE_CURRENT_SOURCE_DIR}/../util -I${CMAKE_CURRENT_SOURCE_DIR}/svm -DCCL_NAMESPACE_BEGIN= -DCCL_NAMESPACE_END= -DNVCC DEPENDS ${cuda_sources}) delayed_install("${CMAKE_CURRENT_BINARY_DIR}" "${cuda_cubin}" ${CYCLES_INSTALL_PATH}/lib) diff --git a/intern/cycles/kernel/kernel_jitter.h b/intern/cycles/kernel/kernel_jitter.h index 5ea44cd0cad..15d2151228f 100644 --- a/intern/cycles/kernel/kernel_jitter.h +++ b/intern/cycles/kernel/kernel_jitter.h @@ -146,7 +146,7 @@ __device_noinline float cmj_sample_1D(int s, int N, int p) return (x + jx)*invN; } -__device_noinline float2 cmj_sample_2D(int s, int N, int p) +__device_noinline void cmj_sample_2D(int s, int N, int p, float *fx, float *fy) { int m = float_to_int(sqrtf(N)); int n = (N + m - 1)/m; @@ -173,7 +173,8 @@ __device_noinline float2 cmj_sample_2D(int s, int N, int p) float jx = cmj_randfloat(s, p * 0x967a889b); float jy = cmj_randfloat(s, p * 0x368cc8b7); - return make_float2((sx + (sy + jx)*invn)*invm, (s + jy)*invN); + *fx = (sx + (sy + jx)*invn)*invm; + *fy = (s + jy)*invN; } #endif diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h index f58f83e2f82..b895d1fcf52 100644 --- a/intern/cycles/kernel/kernel_path.h +++ b/intern/cycles/kernel/kernel_path.h @@ -409,9 +409,8 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample, /* ambient occlusion */ if(kernel_data.integrator.use_ambient_occlusion || (sd.flag & SD_AO)) { /* todo: solve correlation */ - float2 bsdf_uv = path_rng_2D(kg, rng, sample, num_samples, rng_offset + PRNG_BSDF_U); - float bsdf_u = bsdf_uv.x; - float bsdf_v = bsdf_uv.y; + float bsdf_u, bsdf_v; + path_rng_2D(kg, rng, sample, num_samples, rng_offset + PRNG_BSDF_U, &bsdf_u, &bsdf_v); float ao_factor = kernel_data.background.ao_factor; float3 ao_N; @@ -450,9 +449,8 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample, #else float light_o = path_rng_1D(kg, rng, sample, num_samples, rng_offset + PRNG_LIGHT_F); #endif - float2 light_uv = path_rng_2D(kg, rng, sample, num_samples, rng_offset + PRNG_LIGHT_U); - float light_u = light_uv.x; - float light_v = light_uv.y; + float light_u, light_v; + path_rng_2D(kg, rng, sample, num_samples, rng_offset + PRNG_LIGHT_U, &light_u, &light_v); Ray light_ray; BsdfEval L_light; @@ -484,9 +482,8 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample, BsdfEval bsdf_eval; float3 bsdf_omega_in; differential3 bsdf_domega_in; - float2 bsdf_uv = path_rng_2D(kg, rng, sample, num_samples, rng_offset + PRNG_BSDF_U); - float bsdf_u = bsdf_uv.x; - float bsdf_v = bsdf_uv.y; + float bsdf_u, bsdf_v; + path_rng_2D(kg, rng, sample, num_samples, rng_offset + PRNG_BSDF_U, &bsdf_u, &bsdf_v); int label; label = shader_bsdf_sample(kg, &sd, bsdf_u, bsdf_v, &bsdf_eval, @@ -653,10 +650,8 @@ __device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, int sample, Ray #ifdef __AO__ /* ambient occlusion */ if(kernel_data.integrator.use_ambient_occlusion || (sd.flag & SD_AO)) { - /* todo: solve correlation */ - float2 bsdf_uv = path_rng_2D(kg, rng, sample, num_total_samples, rng_offset + PRNG_BSDF_U); - float bsdf_u = bsdf_uv.x; - float bsdf_v = bsdf_uv.y; + float bsdf_u, bsdf_v; + path_rng_2D(kg, rng, sample, num_total_samples, rng_offset + PRNG_BSDF_U, &bsdf_u, &bsdf_v); float ao_factor = kernel_data.background.ao_factor; float3 ao_N; @@ -695,9 +690,8 @@ __device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, int sample, Ray #else float light_o = path_rng_1D(kg, rng, sample, num_total_samples, rng_offset + PRNG_LIGHT_F); #endif - float2 light_uv = path_rng_2D(kg, rng, sample, num_total_samples, rng_offset + PRNG_LIGHT_U); - float light_u = light_uv.x; - float light_v = light_uv.y; + float light_u, light_v; + path_rng_2D(kg, rng, sample, num_total_samples, rng_offset + PRNG_LIGHT_U, &light_u, &light_v); Ray light_ray; BsdfEval L_light; @@ -730,9 +724,8 @@ __device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, int sample, Ray BsdfEval bsdf_eval; float3 bsdf_omega_in; differential3 bsdf_domega_in; - float2 bsdf_uv = path_rng_2D(kg, rng, sample, num_total_samples, rng_offset + PRNG_BSDF_U); - float bsdf_u = bsdf_uv.x; - float bsdf_v = bsdf_uv.y; + float bsdf_u, bsdf_v; + path_rng_2D(kg, rng, sample, num_total_samples, rng_offset + PRNG_BSDF_U, &bsdf_u, &bsdf_v); int label; label = shader_bsdf_sample(kg, &sd, bsdf_u, bsdf_v, &bsdf_eval, @@ -784,10 +777,8 @@ __device_noinline void kernel_path_non_progressive_lighting(KernelGlobals *kg, R float3 ao_bsdf = shader_bsdf_ao(kg, sd, ao_factor, &ao_N); for(int j = 0; j < num_samples; j++) { - /* todo: solve correlation */ - float2 bsdf_uv = path_rng_2D(kg, rng, sample*num_samples + j, aa_samples*num_samples, rng_offset + PRNG_BSDF_U); - float bsdf_u = bsdf_uv.x; - float bsdf_v = bsdf_uv.y; + float bsdf_u, bsdf_v; + path_rng_2D(kg, rng, sample*num_samples + j, aa_samples*num_samples, rng_offset + PRNG_BSDF_U, &bsdf_u, &bsdf_v); float3 ao_D; float ao_pdf; @@ -836,9 +827,8 @@ __device_noinline void kernel_path_non_progressive_lighting(KernelGlobals *kg, R num_samples_inv *= 0.5f; for(int j = 0; j < num_samples; j++) { - float2 light_uv = path_rng_2D(kg, &lamp_rng, sample*num_samples + j, aa_samples*num_samples, rng_offset + PRNG_LIGHT_U); - float light_u = light_uv.x; - float light_v = light_uv.y; + float light_u, light_v; + path_rng_2D(kg, &lamp_rng, sample*num_samples + j, aa_samples*num_samples, rng_offset + PRNG_LIGHT_U, &light_u, &light_v); if(direct_emission(kg, sd, i, 0.0f, 0.0f, light_u, light_v, &light_ray, &L_light, &is_lamp)) { /* trace shadow ray */ @@ -862,9 +852,8 @@ __device_noinline void kernel_path_non_progressive_lighting(KernelGlobals *kg, R for(int j = 0; j < num_samples; j++) { float light_t = path_rng_1D(kg, rng, sample*num_samples + j, aa_samples*num_samples, rng_offset + PRNG_LIGHT); - float2 light_uv = path_rng_2D(kg, rng, sample*num_samples + j, aa_samples*num_samples, rng_offset + PRNG_LIGHT_U); - float light_u = light_uv.x; - float light_v = light_uv.y; + float light_u, light_v; + path_rng_2D(kg, rng, sample*num_samples + j, aa_samples*num_samples, rng_offset + PRNG_LIGHT_U, &light_u, &light_v); /* only sample triangle lights */ if(kernel_data.integrator.num_all_lights) @@ -913,9 +902,8 @@ __device_noinline void kernel_path_non_progressive_lighting(KernelGlobals *kg, R BsdfEval bsdf_eval; float3 bsdf_omega_in; differential3 bsdf_domega_in; - float2 bsdf_uv = path_rng_2D(kg, &bsdf_rng, sample*num_samples + j, aa_samples*num_samples, rng_offset + PRNG_BSDF_U); - float bsdf_u = bsdf_uv.x; - float bsdf_v = bsdf_uv.y; + float bsdf_u, bsdf_v; + path_rng_2D(kg, &bsdf_rng, sample*num_samples + j, aa_samples*num_samples, rng_offset + PRNG_BSDF_U, &bsdf_u, &bsdf_v); int label; label = shader_bsdf_sample_closure(kg, sd, sc, bsdf_u, bsdf_v, &bsdf_eval, @@ -1162,11 +1150,8 @@ __device void kernel_path_trace(KernelGlobals *kg, float lens_u = 0.0f, lens_v = 0.0f; - if(kernel_data.cam.aperturesize > 0.0f) { - float2 lens_uv = path_rng_2D(kg, &rng, sample, num_samples, PRNG_LENS_U); - lens_u = lens_uv.x; - lens_v = lens_uv.y; - } + if(kernel_data.cam.aperturesize > 0.0f) + path_rng_2D(kg, &rng, sample, num_samples, PRNG_LENS_U, &lens_u, &lens_v); float time = 0.0f; diff --git a/intern/cycles/kernel/kernel_random.h b/intern/cycles/kernel/kernel_random.h index b5f824d5cce..20fc1fe2253 100644 --- a/intern/cycles/kernel/kernel_random.h +++ b/intern/cycles/kernel/kernel_random.h @@ -102,8 +102,16 @@ __device uint sobol_lookup(const uint m, const uint frame, const uint ex, const return index; } -__device_inline float path_rng(KernelGlobals *kg, RNG *rng, int sample, int dimension) +__device_inline float path_rng_1D(KernelGlobals *kg, RNG *rng, int sample, int num_samples, int dimension) { +#ifdef __CMJ__ + if(kernel_data.integrator.sampling_pattern == SAMPLING_PATTERN_CMJ) { + /* correlated multi-jittered */ + int p = *rng + dimension; + return cmj_sample_1D(sample, num_samples, p); + } +#endif + #ifdef __SOBOL_FULL_SCREEN__ uint result = sobol_dimension(kg, *rng, dimension); float r = (float)result * (1.0f/(float)0xFFFFFFFF); @@ -117,41 +125,27 @@ __device_inline float path_rng(KernelGlobals *kg, RNG *rng, int sample, int dime float shift; if(dimension & 1) - shift = (*rng >> 16)*(1.0f/(float)0xFFFF); + shift = (*rng >> 16)/((float)0xFFFF); else - shift = (*rng & 0xFFFF)*(1.0f/(float)0xFFFF); + shift = (*rng & 0xFFFF)/((float)0xFFFF); return r + shift - floorf(r + shift); #endif } -__device_inline float path_rng_1D(KernelGlobals *kg, RNG *rng, int sample, int num_samples, int dimension) +__device_inline void path_rng_2D(KernelGlobals *kg, RNG *rng, int sample, int num_samples, int dimension, float *fx, float *fy) { #ifdef __CMJ__ if(kernel_data.integrator.sampling_pattern == SAMPLING_PATTERN_CMJ) { /* correlated multi-jittered */ int p = *rng + dimension; - return cmj_sample_1D(sample, num_samples, p); + cmj_sample_2D(sample, num_samples, p, fx, fy); } #endif /* sobol */ - return path_rng(kg, rng, sample, dimension); -} - -__device_inline float2 path_rng_2D(KernelGlobals *kg, RNG *rng, int sample, int num_samples, int dimension) -{ -#ifdef __CMJ__ - if(kernel_data.integrator.sampling_pattern == SAMPLING_PATTERN_CMJ) { - /* correlated multi-jittered */ - int p = *rng + dimension; - return cmj_sample_2D(sample, num_samples, p); - } -#endif - - /* sobol */ - return make_float2(path_rng(kg, rng, sample, dimension), - path_rng(kg, rng, sample, dimension + 1)); + *fx = path_rng_1D(kg, rng, sample, num_samples, dimension); + *fy = path_rng_1D(kg, rng, sample, num_samples, dimension + 1); } __device_inline void path_rng_init(KernelGlobals *kg, __global uint *rng_state, int sample, int num_samples, RNG *rng, int x, int y, float *fx, float *fy) @@ -184,10 +178,7 @@ __device_inline void path_rng_init(KernelGlobals *kg, __global uint *rng_state, *fy = 0.5f; } else { - float2 fxy = path_rng_2D(kg, rng, sample, num_samples, PRNG_FILTER_U); - - *fx = fxy.x; - *fy = fxy.y; + path_rng_2D(kg, rng, sample, num_samples, PRNG_FILTER_U, fx, fy); } #endif } @@ -202,21 +193,20 @@ __device void path_rng_end(KernelGlobals *kg, __global uint *rng_state, RNG rng) /* Linear Congruential Generator */ __device float path_rng(KernelGlobals *kg, RNG& rng, int sample, int dimension) +{ +} + +__device_inline float path_rng_1D(KernelGlobals *kg, RNG& rng, int sample, int num_samples, int dimension) { /* implicit mod 2^32 */ rng = (1103515245*(rng) + 12345); return (float)rng * (1.0f/(float)0xFFFFFFFF); } -__device_inline float path_rng_1D(KernelGlobals *kg, RNG& rng, int sample, int num_samples, int dimension) +__device_inline void path_rng_2D(KernelGlobals *kg, RNG& rng, int sample, int num_samples, int dimension, float *fx, float *fy) { - return path_rng(kg, rng, sample, dimension); -} - -__device_inline float2 path_rng_2D(KernelGlobals *kg, RNG& rng, int sample, int num_samples, int dimension) -{ - return make_float2(path_rng(kg, rng, sample, dimension), - path_rng(kg, rng, sample, dimension + 1)); + *fx = path_rng_1D(kg, rng, sample, num_samples, dimension); + *fy = path_rng_1D(kg, rng, sample, num_samples, dimension + 1); } __device void path_rng_init(KernelGlobals *kg, __global uint *rng_state, int sample, int num_samples, RNG *rng, int x, int y, float *fx, float *fy) @@ -231,10 +221,7 @@ __device void path_rng_init(KernelGlobals *kg, __global uint *rng_state, int sam *fy = 0.5f; } else { - float2 fxy = path_rng_2D(kg, rng, sample, num_samples, PRNG_FILTER_U); - - *fx = fxy.x; - *fy = fxy.y; + path_rng_2D(kg, rng, sample, num_samples, PRNG_FILTER_U, fx, fy); } } From fa51f02be3254db81bcf004d9e50e5ce86da16c6 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 12 Jun 2013 00:10:56 +0000 Subject: [PATCH 15/37] minor changes to the script auto-execution based on Brecht's suggestions. --- release/scripts/startup/bl_ui/space_info.py | 5 ++--- source/blender/python/intern/bpy_driver.c | 6 +++--- source/blender/python/intern/bpy_interface.c | 2 +- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_info.py b/release/scripts/startup/bl_ui/space_info.py index 7487aaf420d..5d476c01b08 100644 --- a/release/scripts/startup/bl_ui/space_info.py +++ b/release/scripts/startup/bl_ui/space_info.py @@ -67,14 +67,13 @@ class INFO_HT_header(Header): if bpy.app.autoexec_fail is True and bpy.app.autoexec_fail_quiet is False: layout.operator_context = 'EXEC_DEFAULT' - row.label("Script failed to auto-run", icon='ERROR') + row.label("Auto-run disabled: %s" % bpy.app.autoexec_fail_message, icon='ERROR') if bpy.data.is_saved: props = row.operator("wm.open_mainfile", icon='SCREEN_BACK', text="Reload Trusted") props.filepath = bpy.data.filepath props.use_scripts = True - row.operator("script.autoexec_warn_clear", icon='CANCEL') - row.label("Skipping: (%s)" % bpy.app.autoexec_fail_message) + row.operator("script.autoexec_warn_clear", text="Ignore") return row.operator("wm.splash", text="", icon='BLENDER', emboss=False) diff --git a/source/blender/python/intern/bpy_driver.c b/source/blender/python/intern/bpy_driver.c index e7c0b7b8811..481758db252 100644 --- a/source/blender/python/intern/bpy_driver.c +++ b/source/blender/python/intern/bpy_driver.c @@ -180,7 +180,7 @@ float BPY_driver_exec(ChannelDriver *driver, const float evaltime) DriverVar *dvar; double result = 0.0; /* default return */ - char *expr = NULL; + const char *expr; short targets_ok = 1; int i; @@ -192,9 +192,9 @@ float BPY_driver_exec(ChannelDriver *driver, const float evaltime) if (!(G.f & G_SCRIPT_AUTOEXEC)) { if (!(G.f & G_SCRIPT_AUTOEXEC_FAIL_QUIET)) { G.f |= G_SCRIPT_AUTOEXEC_FAIL; - BLI_snprintf(G.autoexec_fail, sizeof(G.autoexec_fail), "Driver '%s'", driver->expression); + BLI_snprintf(G.autoexec_fail, sizeof(G.autoexec_fail), "Driver '%s'", expr); - printf("skipping driver '%s', automatic scripts are disabled\n", driver->expression); + printf("skipping driver '%s', automatic scripts are disabled\n", expr); } return 0.0f; } diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c index 79f856344d3..feffea20553 100644 --- a/source/blender/python/intern/bpy_interface.c +++ b/source/blender/python/intern/bpy_interface.c @@ -731,7 +731,7 @@ void BPY_modules_load_user(bContext *C) if (!(G.f & G_SCRIPT_AUTOEXEC)) { if (!(G.f & G_SCRIPT_AUTOEXEC_FAIL_QUIET)) { G.f |= G_SCRIPT_AUTOEXEC_FAIL; - BLI_snprintf(G.autoexec_fail, sizeof(G.autoexec_fail), "Register Text '%s'", text->id.name + 2); + BLI_snprintf(G.autoexec_fail, sizeof(G.autoexec_fail), "Text '%s'", text->id.name + 2); printf("scripts disabled for \"%s\", skipping '%s'\n", bmain->name, text->id.name + 2); } From da733a25a553caddfeb96d10c45b99526dbcb895 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 12 Jun 2013 06:06:19 +0000 Subject: [PATCH 16/37] correct solidify normal calculation logic - always calculate vertex normals since they are used as fallbacks. - only calculate rim normals if the normals are not already flagged as dirty. --- .../blender/modifiers/intern/MOD_solidify.c | 90 ++++++++++--------- 1 file changed, 48 insertions(+), 42 deletions(-) diff --git a/source/blender/modifiers/intern/MOD_solidify.c b/source/blender/modifiers/intern/MOD_solidify.c index 4ef5f11c91f..1b04984a302 100644 --- a/source/blender/modifiers/intern/MOD_solidify.c +++ b/source/blender/modifiers/intern/MOD_solidify.c @@ -65,7 +65,7 @@ static void dm_calc_normal(DerivedMesh *dm, float (*temp_nors)[3]) float (*face_nors)[3]; float *f_no; - int calc_face_nors = 0; + bool calc_face_nors = false; numVerts = dm->getNumVerts(dm); numEdges = dm->getNumEdges(dm); @@ -84,7 +84,7 @@ static void dm_calc_normal(DerivedMesh *dm, float (*temp_nors)[3]) face_nors = CustomData_get_layer(&dm->polyData, CD_NORMAL); if (!face_nors) { - calc_face_nors = 1; + calc_face_nors = true; face_nors = CustomData_add_layer(&dm->polyData, CD_NORMAL, CD_CALLOC, NULL, numFaces); } @@ -504,7 +504,7 @@ static DerivedMesh *applyModifier( else { /* make a face normal layer if not present */ float (*face_nors)[3]; - int face_nors_calc = 0; + bool face_nors_calc = false; /* same as EM_solidify() in editmesh_lib.c */ float *vert_angles = MEM_callocN(sizeof(float) * numVerts * 2, "mod_solid_pair"); /* 2 in 1 */ @@ -514,7 +514,7 @@ static DerivedMesh *applyModifier( face_nors = CustomData_get_layer(&dm->polyData, CD_NORMAL); if (!face_nors) { face_nors = CustomData_add_layer(&dm->polyData, CD_NORMAL, CD_CALLOC, NULL, dm->numPolyData); - face_nors_calc = 1; + face_nors_calc = true; } if (vert_nors == NULL) { @@ -633,10 +633,16 @@ static DerivedMesh *applyModifier( if (vert_nors) MEM_freeN(vert_nors); - /* flip vertex normals for copied verts */ - mv = mvert + numVerts; - for (i = 0; i < numVerts; i++, mv++) { - negate_v3_short(mv->no); + /* must recalculate normals with vgroups since they can displace unevenly [#26888] */ + if ((dm->dirty & DM_DIRTY_NORMALS) || (smd->flag & MOD_SOLIDIFY_RIM) || dvert) { + result->dirty |= DM_DIRTY_NORMALS; + } + else { + /* flip vertex normals for copied verts */ + mv = mvert + numVerts; + for (i = 0; i < numVerts; i++, mv++) { + negate_v3_short(mv->no); + } } if (smd->flag & MOD_SOLIDIFY_RIM) { @@ -653,8 +659,9 @@ static DerivedMesh *applyModifier( #define SOLIDIFY_SIDE_NORMALS #ifdef SOLIDIFY_SIDE_NORMALS + const bool do_side_normals = !(result->dirty & DM_DIRTY_NORMALS); /* annoying to allocate these since we only need the edge verts, */ - float (*edge_vert_nos)[3] = MEM_callocN(sizeof(float) * numVerts * 3, "solidify_edge_nos"); + float (*edge_vert_nos)[3] = do_side_normals ? MEM_callocN(sizeof(float) * numVerts * 3, __func__) : NULL; float nor[3]; #endif const unsigned char crease_rim = smd->crease_rim * 255.0f; @@ -772,41 +779,45 @@ static DerivedMesh *applyModifier( } #ifdef SOLIDIFY_SIDE_NORMALS - normal_quad_v3(nor, - mvert[ml[j - 4].v].co, - mvert[ml[j - 3].v].co, - mvert[ml[j - 2].v].co, - mvert[ml[j - 1].v].co); + if (do_side_normals) { + normal_quad_v3(nor, + mvert[ml[j - 4].v].co, + mvert[ml[j - 3].v].co, + mvert[ml[j - 2].v].co, + mvert[ml[j - 1].v].co); - add_v3_v3(edge_vert_nos[ed->v1], nor); - add_v3_v3(edge_vert_nos[ed->v2], nor); + add_v3_v3(edge_vert_nos[ed->v1], nor); + add_v3_v3(edge_vert_nos[ed->v2], nor); - if (face_nors_result) { - copy_v3_v3(face_nors_result[(numFaces * 2) + i], nor); + if (face_nors_result) { + copy_v3_v3(face_nors_result[(numFaces * 2) + i], nor); + } } #endif } #ifdef SOLIDIFY_SIDE_NORMALS - ed = medge + (numEdges * 2); - for (i = 0; i < newEdges; i++, ed++) { - float nor_cpy[3]; - short *nor_short; - int k; + if (do_side_normals) { + ed = medge + (numEdges * 2); + for (i = 0; i < newEdges; i++, ed++) { + float nor_cpy[3]; + short *nor_short; + int k; - /* note, only the first vertex (lower half of the index) is calculated */ - normalize_v3_v3(nor_cpy, edge_vert_nos[ed->v1]); + /* note, only the first vertex (lower half of the index) is calculated */ + normalize_v3_v3(nor_cpy, edge_vert_nos[ed->v1]); - for (k = 0; k < 2; k++) { /* loop over both verts of the edge */ - nor_short = mvert[*(&ed->v1 + k)].no; - normal_short_to_float_v3(nor, nor_short); - add_v3_v3(nor, nor_cpy); - normalize_v3(nor); - normal_float_to_short_v3(nor_short, nor); + for (k = 0; k < 2; k++) { /* loop over both verts of the edge */ + nor_short = mvert[*(&ed->v1 + k)].no; + normal_short_to_float_v3(nor, nor_short); + add_v3_v3(nor, nor_cpy); + normalize_v3(nor); + normal_float_to_short_v3(nor_short, nor); + } } - } - MEM_freeN(edge_vert_nos); + MEM_freeN(edge_vert_nos); + } #endif BLI_array_free(new_vert_arr); @@ -818,11 +829,6 @@ static DerivedMesh *applyModifier( if (old_vert_arr) MEM_freeN(old_vert_arr); - /* must recalculate normals with vgroups since they can displace unevenly [#26888] */ - if ((dm->dirty & DM_DIRTY_NORMALS) || dvert) { - result->dirty |= DM_DIRTY_NORMALS; - } - if (numFaces == 0 && numEdges != 0) { modifier_setError(md, "Faces needed for useful output"); } @@ -832,11 +838,11 @@ static DerivedMesh *applyModifier( #undef SOLIDIFY_SIDE_NORMALS -static bool dependsOnNormals(ModifierData *md) +static bool dependsOnNormals(ModifierData *UNUSED(md)) { - SolidifyModifierData *smd = (SolidifyModifierData *) md; - - return (smd->flag & MOD_SOLIDIFY_NORMAL_CALC) == 0; + /* even when we calculate our own normals, + * the vertex normals are used as a fallback */ + return true; } ModifierTypeInfo modifierType_Solidify = { From 3994ad8cedccb6a09afeac80c987f17bdad3d2db Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 12 Jun 2013 06:20:24 +0000 Subject: [PATCH 17/37] solidify: remove BLI_array realloc's. --- .../blender/modifiers/intern/MOD_solidify.c | 28 ++++++++++++------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/source/blender/modifiers/intern/MOD_solidify.c b/source/blender/modifiers/intern/MOD_solidify.c index 1b04984a302..67713cbd1e7 100644 --- a/source/blender/modifiers/intern/MOD_solidify.c +++ b/source/blender/modifiers/intern/MOD_solidify.c @@ -37,7 +37,6 @@ #include "BLI_utildefines.h" #include "BLI_math.h" #include "BLI_edgehash.h" -#include "BLI_array.h" #include "BLI_string.h" #include "BKE_cdderivedmesh.h" @@ -241,10 +240,13 @@ static DerivedMesh *applyModifier( const short mat_ofs_rim = mat_nr_max ? smd->mat_ofs_rim : 0; /* use for edges */ + /* over-alloc new_vert_arr, old_vert_arr */ int *new_vert_arr = NULL; - BLI_array_declare(new_vert_arr); + STACK_DECLARE(new_vert_arr); + int *new_edge_arr = NULL; - BLI_array_declare(new_edge_arr); + STACK_DECLARE(new_edge_arr); + int *old_vert_arr = MEM_callocN(sizeof(int) * numVerts, "old_vert_arr in solidify"); int *edge_users = NULL; @@ -276,6 +278,9 @@ static DerivedMesh *applyModifier( orig_mloop = dm->getLoopArray(dm); orig_mpoly = dm->getPolyArray(dm); + STACK_INIT(new_vert_arr); + STACK_INIT(new_edge_arr); + if (smd->flag & MOD_SOLIDIFY_RIM) { EdgeHash *edgehash = BLI_edgehash_new(); EdgeHashIterator *ehi; @@ -285,8 +290,11 @@ static DerivedMesh *applyModifier( #define INVALID_UNUSED -1 #define INVALID_PAIR -2 - edge_users = MEM_mallocN(sizeof(int) * numEdges, "solid_mod edges"); - edge_order = MEM_mallocN(sizeof(char) * numEdges, "solid_mod eorder"); + new_vert_arr = MEM_mallocN(sizeof(*new_vert_arr) * (numVerts * 2), __func__); + new_edge_arr = MEM_mallocN(sizeof(*new_edge_arr) * ((numEdges * 2) + numVerts), __func__); + + edge_users = MEM_mallocN(sizeof(*edge_users) * numEdges, "solid_mod edges"); + edge_order = MEM_mallocN(sizeof(*edge_order) * numEdges, "solid_mod eorder"); for (i = 0, mv = orig_mvert; i < numVerts; i++, mv++) { mv->flag &= ~ME_VERT_TMP_TAG; @@ -337,7 +345,7 @@ static DerivedMesh *applyModifier( BLI_edgehashIterator_getKey(ehi, &v1, &v2); orig_mvert[v1].flag |= ME_VERT_TMP_TAG; orig_mvert[v2].flag |= ME_VERT_TMP_TAG; - BLI_array_append(new_edge_arr, eidx); + STACK_PUSH(new_edge_arr, eidx); newFaces++; newLoops += 4; } @@ -346,8 +354,8 @@ static DerivedMesh *applyModifier( for (i = 0, mv = orig_mvert; i < numVerts; i++, mv++) { if (mv->flag & ME_VERT_TMP_TAG) { - old_vert_arr[i] = BLI_array_count(new_vert_arr); - BLI_array_append(new_vert_arr, i); + old_vert_arr[i] = STACK_SIZE(new_vert_arr); + STACK_PUSH(new_vert_arr, i); newEdges++; mv->flag &= ~ME_VERT_TMP_TAG; @@ -820,8 +828,8 @@ static DerivedMesh *applyModifier( } #endif - BLI_array_free(new_vert_arr); - BLI_array_free(new_edge_arr); + MEM_freeN(new_vert_arr); + MEM_freeN(new_edge_arr); MEM_freeN(edge_users); MEM_freeN(edge_order); } From d00ca6eb2c4f9598bfbf9419f36937a16f81fc62 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 12 Jun 2013 06:51:02 +0000 Subject: [PATCH 18/37] solidify: reduce sign conversions. --- .../blender/modifiers/intern/MOD_solidify.c | 118 ++++++++++-------- 1 file changed, 65 insertions(+), 53 deletions(-) diff --git a/source/blender/modifiers/intern/MOD_solidify.c b/source/blender/modifiers/intern/MOD_solidify.c index 67713cbd1e7..89deeefbfaf 100644 --- a/source/blender/modifiers/intern/MOD_solidify.c +++ b/source/blender/modifiers/intern/MOD_solidify.c @@ -47,6 +47,10 @@ #include "MOD_modifiertypes.h" #include "MOD_util.h" +#ifdef __GNUC__ +# pragma GCC diagnostic error "-Wsign-conversion" +#endif + /* *** derived mesh high quality normal calculation function *** */ /* could be exposed for other functions to use */ @@ -95,7 +99,7 @@ static void dm_calc_normal(DerivedMesh *dm, float (*temp_nors)[3]) EdgeHashIterator *edge_iter; int edge_ref_count = 0; unsigned int ed_v1, ed_v2; /* use when getting the key */ - EdgeFaceRef *edge_ref_array = MEM_callocN(numEdges * sizeof(EdgeFaceRef), "Edge Connectivity"); + EdgeFaceRef *edge_ref_array = MEM_callocN(sizeof(EdgeFaceRef) * (size_t)numEdges, "Edge Connectivity"); EdgeFaceRef *edge_ref; float edge_normal[3]; @@ -221,7 +225,7 @@ static DerivedMesh *applyModifier( DerivedMesh *dm, ModifierApplyFlag UNUSED(flag)) { - int i; + unsigned int i; DerivedMesh *result; const SolidifyModifierData *smd = (SolidifyModifierData *) md; @@ -229,10 +233,10 @@ static DerivedMesh *applyModifier( MEdge *ed, *medge, *orig_medge; MLoop *ml, *mloop, *orig_mloop; MPoly *mp, *mpoly, *orig_mpoly; - const int numVerts = dm->getNumVerts(dm); - const int numEdges = dm->getNumEdges(dm); - const int numFaces = dm->getNumPolys(dm); - int numLoops = 0, newLoops = 0, newFaces = 0, newEdges = 0; + const unsigned int numVerts = (unsigned int)dm->getNumVerts(dm); + const unsigned int numEdges = (unsigned int)dm->getNumEdges(dm); + const unsigned int numFaces = (unsigned int)dm->getNumPolys(dm); + unsigned int numLoops = 0, newLoops = 0, newFaces = 0, newEdges = 0; /* only use material offsets if we have 2 or more materials */ const short mat_nr_max = ob->totcol > 1 ? ob->totcol - 1 : 0; @@ -241,15 +245,15 @@ static DerivedMesh *applyModifier( /* use for edges */ /* over-alloc new_vert_arr, old_vert_arr */ - int *new_vert_arr = NULL; + unsigned int *new_vert_arr = NULL; STACK_DECLARE(new_vert_arr); - int *new_edge_arr = NULL; + unsigned int *new_edge_arr = NULL; STACK_DECLARE(new_edge_arr); - int *old_vert_arr = MEM_callocN(sizeof(int) * numVerts, "old_vert_arr in solidify"); + unsigned int *old_vert_arr = MEM_callocN(sizeof(old_vert_arr) * (size_t)numVerts, "old_vert_arr in solidify"); - int *edge_users = NULL; + unsigned int *edge_users = NULL; char *edge_order = NULL; float (*vert_nors)[3] = NULL; @@ -270,7 +274,7 @@ static DerivedMesh *applyModifier( modifier_get_vgroup(ob, dm, smd->defgrp_name, &dvert, &defgrp_index); - numLoops = dm->numLoopData; + numLoops = (unsigned int)dm->numLoopData; newLoops = 0; orig_mvert = dm->getVertArray(dm); @@ -285,16 +289,16 @@ static DerivedMesh *applyModifier( EdgeHash *edgehash = BLI_edgehash_new(); EdgeHashIterator *ehi; unsigned int v1, v2; - int eidx; + unsigned int eidx; -#define INVALID_UNUSED -1 -#define INVALID_PAIR -2 +#define INVALID_UNUSED ((unsigned int)-1) +#define INVALID_PAIR ((unsigned int)-2) - new_vert_arr = MEM_mallocN(sizeof(*new_vert_arr) * (numVerts * 2), __func__); - new_edge_arr = MEM_mallocN(sizeof(*new_edge_arr) * ((numEdges * 2) + numVerts), __func__); + new_vert_arr = MEM_mallocN(sizeof(*new_vert_arr) * (size_t)(numVerts * 2), __func__); + new_edge_arr = MEM_mallocN(sizeof(*new_edge_arr) * (size_t)((numEdges * 2) + numVerts), __func__); - edge_users = MEM_mallocN(sizeof(*edge_users) * numEdges, "solid_mod edges"); - edge_order = MEM_mallocN(sizeof(*edge_order) * numEdges, "solid_mod eorder"); + edge_users = MEM_mallocN(sizeof(*edge_users) * (size_t)numEdges, "solid_mod edges"); + edge_order = MEM_mallocN(sizeof(*edge_order) * (size_t)numEdges, "solid_mod eorder"); for (i = 0, mv = orig_mvert; i < numVerts; i++, mv++) { mv->flag &= ~ME_VERT_TMP_TAG; @@ -306,7 +310,7 @@ static DerivedMesh *applyModifier( #endif for (i = 0, ed = orig_medge; i < numEdges; i++, ed++) { - BLI_edgehash_insert(edgehash, ed->v1, ed->v2, SET_INT_IN_POINTER(i)); + BLI_edgehash_insert(edgehash, ed->v1, ed->v2, SET_UINT_IN_POINTER(i)); edge_users[i] = INVALID_UNUSED; } @@ -323,7 +327,7 @@ static DerivedMesh *applyModifier( { ml_v1 = ml->v; /* add edge user */ - eidx = GET_INT_FROM_POINTER(BLI_edgehash_lookup(edgehash, ml_v1, ml_v2)); + eidx = GET_UINT_FROM_POINTER(BLI_edgehash_lookup(edgehash, ml_v1, ml_v2)); if (edge_users[eidx] == INVALID_UNUSED) { ed = orig_medge + eidx; edge_users[eidx] = (ml_v1 < ml_v2) == (ed->v1 < ed->v2) ? i : (i + numFaces); @@ -335,13 +339,10 @@ static DerivedMesh *applyModifier( } } -#undef INVALID_UNUSED -#undef INVALID_PAIR - ehi = BLI_edgehashIterator_new(edgehash); for (; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) { - eidx = GET_INT_FROM_POINTER(BLI_edgehashIterator_getValue(ehi)); - if (edge_users[eidx] >= 0) { + eidx = GET_UINT_FROM_POINTER(BLI_edgehashIterator_getValue(ehi)); + if (!ELEM(edge_users[eidx], INVALID_UNUSED, INVALID_PAIR)) { BLI_edgehashIterator_getKey(ehi, &v1, &v2); orig_mvert[v1].flag |= ME_VERT_TMP_TAG; orig_mvert[v2].flag |= ME_VERT_TMP_TAG; @@ -352,6 +353,9 @@ static DerivedMesh *applyModifier( } BLI_edgehashIterator_free(ehi); +#undef INVALID_UNUSED +#undef INVALID_PAIR + for (i = 0, mv = orig_mvert; i < numVerts; i++, mv++) { if (mv->flag & ME_VERT_TMP_TAG) { old_vert_arr[i] = STACK_SIZE(new_vert_arr); @@ -366,29 +370,32 @@ static DerivedMesh *applyModifier( } if (smd->flag & MOD_SOLIDIFY_NORMAL_CALC) { - vert_nors = MEM_callocN(sizeof(float) * numVerts * 3, "mod_solid_vno_hq"); + vert_nors = MEM_callocN(sizeof(float) * (size_t)numVerts * 3, "mod_solid_vno_hq"); dm_calc_normal(dm, vert_nors); } - result = CDDM_from_template(dm, numVerts * 2, (numEdges * 2) + newEdges, 0, - (numLoops * 2) + newLoops, (numFaces * 2) + newFaces); + result = CDDM_from_template(dm, + (int)(numVerts * 2), + (int)((numEdges * 2) + newEdges), 0, + (int)((numLoops * 2) + newLoops), + (int)((numFaces * 2) + newFaces)); mpoly = CDDM_get_polys(result); mloop = CDDM_get_loops(result); medge = CDDM_get_edges(result); mvert = CDDM_get_verts(result); - DM_copy_edge_data(dm, result, 0, 0, numEdges); - DM_copy_edge_data(dm, result, 0, numEdges, numEdges); + DM_copy_edge_data(dm, result, 0, 0, (int)numEdges); + DM_copy_edge_data(dm, result, 0, (int)numEdges, (int)numEdges); - DM_copy_vert_data(dm, result, 0, 0, numVerts); - DM_copy_vert_data(dm, result, 0, numVerts, numVerts); + DM_copy_vert_data(dm, result, 0, 0, (int)numVerts); + DM_copy_vert_data(dm, result, 0, (int)numVerts, (int)numVerts); - DM_copy_loop_data(dm, result, 0, 0, numLoops); - DM_copy_loop_data(dm, result, 0, numLoops, numLoops); + DM_copy_loop_data(dm, result, 0, 0, (int)numLoops); + DM_copy_loop_data(dm, result, 0, (int)numLoops, (int)numLoops); - DM_copy_poly_data(dm, result, 0, 0, numFaces); - DM_copy_poly_data(dm, result, 0, numFaces, numFaces); + DM_copy_poly_data(dm, result, 0, 0, (int)numFaces); + DM_copy_poly_data(dm, result, 0, (int)numFaces, (int)numFaces); /* if the original has it, get the result so we can update it */ face_nors_result = CustomData_get_layer(&result->polyData, CD_NORMAL); @@ -397,7 +404,7 @@ static DerivedMesh *applyModifier( mp = mpoly + numFaces; for (i = 0; i < dm->numPolyData; i++, mp++) { MLoop *ml2; - int e; + unsigned int e; int j; ml2 = mloop + mp->loopstart + dm->numLoopData; @@ -447,7 +454,7 @@ static DerivedMesh *applyModifier( if (do_clamp) { vert_lens = MEM_callocN(sizeof(float) * numVerts, "vert_lens"); - fill_vn_fl(vert_lens, numVerts, FLT_MAX); + fill_vn_fl(vert_lens, (int)numVerts, FLT_MAX); for (i = 0; i < numEdges; i++) { const float ed_len = len_squared_v3v3(mvert[medge[i].v1].co, mvert[medge[i].v2].co); vert_lens[medge[i].v1] = min_ff(vert_lens[medge[i].v1], ed_len); @@ -517,7 +524,7 @@ static DerivedMesh *applyModifier( /* same as EM_solidify() in editmesh_lib.c */ float *vert_angles = MEM_callocN(sizeof(float) * numVerts * 2, "mod_solid_pair"); /* 2 in 1 */ float *vert_accum = vert_angles + numVerts; - int vidx; + unsigned int vidx; face_nors = CustomData_get_layer(&dm->polyData, CD_NORMAL); if (!face_nors) { @@ -599,7 +606,7 @@ static DerivedMesh *applyModifier( float *vert_lens = MEM_callocN(sizeof(float) * numVerts, "vert_lens"); const float offset = fabsf(smd->offset) * smd->offset_clamp; const float offset_sq = offset * offset; - fill_vn_fl(vert_lens, numVerts, FLT_MAX); + fill_vn_fl(vert_lens, (int)numVerts, FLT_MAX); for (i = 0; i < numEdges; i++) { const float ed_len = len_squared_v3v3(mvert[medge[i].v1].co, mvert[medge[i].v2].co); vert_lens[medge[i].v1] = min_ff(vert_lens[medge[i].v1], ed_len); @@ -678,7 +685,7 @@ static DerivedMesh *applyModifier( int *origindex_edge; int *orig_ed; - int j; + unsigned int j; if (crease_rim || crease_outer || crease_inner) { result->cd_flag |= ME_CDFLAG_EDGE_CREASE; @@ -705,37 +712,38 @@ static DerivedMesh *applyModifier( ml = mloop + (numLoops * 2); j = 0; for (i = 0; i < newFaces; i++, mp++) { - int eidx = new_edge_arr[i]; - int fidx = edge_users[eidx]; - int flip, k1, k2; + unsigned int eidx = new_edge_arr[i]; + unsigned int fidx = edge_users[eidx]; + int k1, k2; + bool flip; if (fidx >= numFaces) { fidx -= numFaces; - flip = TRUE; + flip = true; } else { - flip = FALSE; + flip = false; } ed = medge + eidx; /* copy most of the face settings */ - DM_copy_poly_data(dm, result, fidx, (numFaces * 2) + i, 1); - mp->loopstart = j + numLoops * 2; + DM_copy_poly_data(dm, result, (int)fidx, (int)((numFaces * 2) + i), 1); + mp->loopstart = (int)(j + numLoops * 2); mp->flag = mpoly[fidx].flag; /* notice we use 'mp->totloop' which is later overwritten, * we could lookup the original face but theres no point since this is a copy * and will have the same value, just take care when changing order of assignment */ k1 = mpoly[fidx].loopstart + (((edge_order[eidx] - 1) + mp->totloop) % mp->totloop); /* prev loop */ - k2 = mpoly[fidx].loopstart + (edge_order[eidx]); + k2 = mpoly[fidx].loopstart + (edge_order[eidx]); mp->totloop = 4; - CustomData_copy_data(&dm->loopData, &result->loopData, k2, numLoops * 2 + j + 0, 1); - CustomData_copy_data(&dm->loopData, &result->loopData, k1, numLoops * 2 + j + 1, 1); - CustomData_copy_data(&dm->loopData, &result->loopData, k1, numLoops * 2 + j + 2, 1); - CustomData_copy_data(&dm->loopData, &result->loopData, k2, numLoops * 2 + j + 3, 1); + CustomData_copy_data(&dm->loopData, &result->loopData, k2, (int)(numLoops * 2 + j + 0), 1); + CustomData_copy_data(&dm->loopData, &result->loopData, k1, (int)(numLoops * 2 + j + 1), 1); + CustomData_copy_data(&dm->loopData, &result->loopData, k1, (int)(numLoops * 2 + j + 2), 1); + CustomData_copy_data(&dm->loopData, &result->loopData, k2, (int)(numLoops * 2 + j + 3), 1); if (flip == FALSE) { ml[j].v = ed->v1; @@ -830,10 +838,14 @@ static DerivedMesh *applyModifier( MEM_freeN(new_vert_arr); MEM_freeN(new_edge_arr); + MEM_freeN(edge_users); MEM_freeN(edge_order); } + STACK_FREE(new_vert_arr); + STACK_FREE(new_edge_arr); + if (old_vert_arr) MEM_freeN(old_vert_arr); From f0b991c944e8a4af383619f620eb2115595abb04 Mon Sep 17 00:00:00 2001 From: Lukas Toenne Date: Wed, 12 Jun 2013 07:02:52 +0000 Subject: [PATCH 19/37] Supplementary fix for #35640, internal node group trees (inside material, lamp, world, texture and scene) still keep their original library pointer when appending, making them uneditable. Clearing the lib pointer now has been moved inside the id_clear_lib_data function, with an ugly switch statement to handle integrated node trees. --- source/blender/blenkernel/intern/lamp.c | 6 ------ source/blender/blenkernel/intern/library.c | 15 +++++++++++++++ source/blender/blenkernel/intern/material.c | 6 ------ source/blender/blenkernel/intern/texture.c | 6 ------ source/blender/blenkernel/intern/world.c | 6 ------ 5 files changed, 15 insertions(+), 24 deletions(-) diff --git a/source/blender/blenkernel/intern/lamp.c b/source/blender/blenkernel/intern/lamp.c index 1f381a1a2c2..903b032e080 100644 --- a/source/blender/blenkernel/intern/lamp.c +++ b/source/blender/blenkernel/intern/lamp.c @@ -172,9 +172,6 @@ void BKE_lamp_make_local(Lamp *la) if (la->id.lib == NULL) return; if (la->id.us == 1) { id_clear_lib_data(bmain, &la->id); - /* nodetree uses same lib */ - if (la->nodetree) - la->nodetree->id.lib = NULL; return; } @@ -189,9 +186,6 @@ void BKE_lamp_make_local(Lamp *la) if (is_local && is_lib == FALSE) { id_clear_lib_data(bmain, &la->id); - /* nodetree uses same lib */ - if (la->nodetree) - la->nodetree->id.lib = NULL; } else if (is_local && is_lib) { Lamp *la_new = BKE_lamp_copy(la); diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index db4706e3c6c..c1715ada7bd 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -1428,11 +1428,26 @@ bool new_id(ListBase *lb, ID *id, const char *tname) * don't have other library users. */ void id_clear_lib_data(Main *bmain, ID *id) { + bNodeTree *ntree = NULL; + BKE_id_lib_local_paths(bmain, id->lib, id); id->lib = NULL; id->flag = LIB_LOCAL; new_id(which_libbase(bmain, GS(id->name)), id, NULL); + + /* internal bNodeTree blocks inside ID types below + * also stores id->lib, make sure this stays in sync. + */ + switch (GS(id->name)) { + case ID_SCE: ntree = ((Scene *)id)->nodetree; break; + case ID_MA: ntree = ((Material *)id)->nodetree; break; + case ID_LA: ntree = ((Lamp *)id)->nodetree; break; + case ID_WO: ntree = ((World *)id)->nodetree; break; + case ID_TE: ntree = ((Tex *)id)->nodetree; break; + } + if (ntree) + ntree->id.lib = NULL; } /* next to indirect usage in read/writefile also in editobject.c scene.c */ diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index 87fb64c0761..c8cd65e9477 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -308,9 +308,6 @@ void BKE_material_make_local(Material *ma) if (ma->id.us == 1) { id_clear_lib_data(bmain, &ma->id); extern_local_material(ma); - /* nodetree uses same lib */ - if (ma->nodetree) - ma->nodetree->id.lib = NULL; return; } @@ -373,9 +370,6 @@ void BKE_material_make_local(Material *ma) if (is_local && is_lib == FALSE) { id_clear_lib_data(bmain, &ma->id); extern_local_material(ma); - /* nodetree uses same lib */ - if (ma->nodetree) - ma->nodetree->id.lib = NULL; } /* Both user and local, so copy. */ else if (is_local && is_lib) { diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c index be48c7cf12a..1d0b0deae7e 100644 --- a/source/blender/blenkernel/intern/texture.c +++ b/source/blender/blenkernel/intern/texture.c @@ -765,9 +765,6 @@ void BKE_texture_make_local(Tex *tex) if (tex->id.us == 1) { id_clear_lib_data(bmain, &tex->id); extern_local_texture(tex); - /* nodetree uses same lib */ - if (tex->nodetree) - tex->nodetree->id.lib = NULL; return; } @@ -827,9 +824,6 @@ void BKE_texture_make_local(Tex *tex) if (is_local && is_lib == FALSE) { id_clear_lib_data(bmain, &tex->id); extern_local_texture(tex); - /* nodetree uses same lib */ - if (tex->nodetree) - tex->nodetree->id.lib = NULL; } else if (is_local && is_lib) { Tex *tex_new = BKE_texture_copy(tex); diff --git a/source/blender/blenkernel/intern/world.c b/source/blender/blenkernel/intern/world.c index 050fcd2600b..206f829eaa8 100644 --- a/source/blender/blenkernel/intern/world.c +++ b/source/blender/blenkernel/intern/world.c @@ -179,9 +179,6 @@ void BKE_world_make_local(World *wrld) if (wrld->id.lib == NULL) return; if (wrld->id.us == 1) { id_clear_lib_data(bmain, &wrld->id); - /* nodetree uses same lib */ - if (wrld->nodetree) - wrld->nodetree->id.lib = NULL; return; } @@ -194,9 +191,6 @@ void BKE_world_make_local(World *wrld) if (is_local && is_lib == FALSE) { id_clear_lib_data(bmain, &wrld->id); - /* nodetree uses same lib */ - if (wrld->nodetree) - wrld->nodetree->id.lib = NULL; } else if (is_local && is_lib) { World *wrld_new = BKE_world_copy(wrld); From 293b3f0bdff8ca5368ee4625ae9fb8470973e28b Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 12 Jun 2013 07:16:13 +0000 Subject: [PATCH 20/37] optimize solidify, no need to do edgehash lookups, the edges are known. --- .../blender/modifiers/intern/MOD_solidify.c | 65 ++++++------------- 1 file changed, 21 insertions(+), 44 deletions(-) diff --git a/source/blender/modifiers/intern/MOD_solidify.c b/source/blender/modifiers/intern/MOD_solidify.c index 89deeefbfaf..7ca187aa039 100644 --- a/source/blender/modifiers/intern/MOD_solidify.c +++ b/source/blender/modifiers/intern/MOD_solidify.c @@ -36,7 +36,6 @@ #include "BLI_utildefines.h" #include "BLI_math.h" -#include "BLI_edgehash.h" #include "BLI_string.h" #include "BKE_cdderivedmesh.h" @@ -59,11 +58,17 @@ typedef struct EdgeFaceRef { int f2; } EdgeFaceRef; +BLI_INLINE bool edgeref_is_init(const EdgeFaceRef *edge_ref) +{ + return (edge_ref->f1 != 0) && (edge_ref->f2 != 0); +} + static void dm_calc_normal(DerivedMesh *dm, float (*temp_nors)[3]) { int i, numVerts, numEdges, numFaces; MPoly *mpoly, *mp; MLoop *mloop, *ml; + MEdge *medge, *ed; MVert *mvert, *mv; float (*face_nors)[3]; @@ -74,6 +79,7 @@ static void dm_calc_normal(DerivedMesh *dm, float (*temp_nors)[3]) numEdges = dm->getNumEdges(dm); numFaces = dm->getNumPolys(dm); mpoly = dm->getPolyArray(dm); + medge = dm->getEdgeArray(dm); mvert = dm->getVertArray(dm); mloop = dm->getLoopArray(dm); @@ -95,18 +101,12 @@ static void dm_calc_normal(DerivedMesh *dm, float (*temp_nors)[3]) mp = mpoly; { - EdgeHash *edge_hash = BLI_edgehash_new(); - EdgeHashIterator *edge_iter; - int edge_ref_count = 0; - unsigned int ed_v1, ed_v2; /* use when getting the key */ EdgeFaceRef *edge_ref_array = MEM_callocN(sizeof(EdgeFaceRef) * (size_t)numEdges, "Edge Connectivity"); EdgeFaceRef *edge_ref; float edge_normal[3]; /* This loop adds an edge hash if its not there, and adds the face index */ for (i = 0; i < numFaces; i++, mp++) { - unsigned int ml_v1; - unsigned int ml_v2; int j; f_no = face_nors[i]; @@ -115,18 +115,12 @@ static void dm_calc_normal(DerivedMesh *dm, float (*temp_nors)[3]) ml = mloop + mp->loopstart; - for (j = 0, ml_v2 = ml[mp->totloop - 1].v; - j < mp->totloop; - j++, ml++, ml_v2 = ml_v1) - { - ml_v1 = ml->v; + for (j = 0; j < mp->totloop; j++, ml++) { /* --- add edge ref to face --- */ - edge_ref = (EdgeFaceRef *)BLI_edgehash_lookup(edge_hash, ml_v1, ml_v2); - if (!edge_ref) { - edge_ref = &edge_ref_array[edge_ref_count++]; + edge_ref = &edge_ref_array[ml->e]; + if (!edgeref_is_init(edge_ref)) { edge_ref->f1 = i; edge_ref->f2 = -1; - BLI_edgehash_insert(edge_hash, ml_v1, ml_v2, edge_ref); } else { edge_ref->f2 = i; @@ -135,15 +129,10 @@ static void dm_calc_normal(DerivedMesh *dm, float (*temp_nors)[3]) } } - for (edge_iter = BLI_edgehashIterator_new(edge_hash); - !BLI_edgehashIterator_isDone(edge_iter); - BLI_edgehashIterator_step(edge_iter)) - { - /* Get the edge vert indices, and edge value (the face indices that use it)*/ - BLI_edgehashIterator_getKey(edge_iter, &ed_v1, &ed_v2); - edge_ref = BLI_edgehashIterator_getValue(edge_iter); + for (i = 0, ed = medge, edge_ref = edge_ref_array; i < numEdges; i++, ed++, edge_ref++) { + /* Get the edge vert indices, and edge value (the face indices that use it) */ - if (edge_ref->f2 != -1) { + if (edgeref_is_init(edge_ref) && (edge_ref->f2 != -1)) { /* We have 2 faces using this edge, calculate the edges normal * using the angle between the 2 faces as a weighting */ #if 0 @@ -160,11 +149,9 @@ static void dm_calc_normal(DerivedMesh *dm, float (*temp_nors)[3]) /* an edge without another attached- the weight on this is undefined */ copy_v3_v3(edge_normal, face_nors[edge_ref->f1]); } - add_v3_v3(temp_nors[ed_v1], edge_normal); - add_v3_v3(temp_nors[ed_v2], edge_normal); + add_v3_v3(temp_nors[ed->v1], edge_normal); + add_v3_v3(temp_nors[ed->v2], edge_normal); } - BLI_edgehashIterator_free(edge_iter); - BLI_edgehash_free(edge_hash, NULL); MEM_freeN(edge_ref_array); } @@ -286,9 +273,6 @@ static DerivedMesh *applyModifier( STACK_INIT(new_edge_arr); if (smd->flag & MOD_SOLIDIFY_RIM) { - EdgeHash *edgehash = BLI_edgehash_new(); - EdgeHashIterator *ehi; - unsigned int v1, v2; unsigned int eidx; #define INVALID_UNUSED ((unsigned int)-1) @@ -309,9 +293,8 @@ static DerivedMesh *applyModifier( fill_vn_i(edge_users, numEdges, INVALID_UNUSED); #endif - for (i = 0, ed = orig_medge; i < numEdges; i++, ed++) { - BLI_edgehash_insert(edgehash, ed->v1, ed->v2, SET_UINT_IN_POINTER(i)); - edge_users[i] = INVALID_UNUSED; + for (eidx = 0, ed = orig_medge; eidx < numEdges; eidx++, ed++) { + edge_users[eidx] = INVALID_UNUSED; } for (i = 0, mp = orig_mpoly; i < numFaces; i++, mp++) { @@ -327,7 +310,7 @@ static DerivedMesh *applyModifier( { ml_v1 = ml->v; /* add edge user */ - eidx = GET_UINT_FROM_POINTER(BLI_edgehash_lookup(edgehash, ml_v1, ml_v2)); + eidx = ml->e; if (edge_users[eidx] == INVALID_UNUSED) { ed = orig_medge + eidx; edge_users[eidx] = (ml_v1 < ml_v2) == (ed->v1 < ed->v2) ? i : (i + numFaces); @@ -339,19 +322,15 @@ static DerivedMesh *applyModifier( } } - ehi = BLI_edgehashIterator_new(edgehash); - for (; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) { - eidx = GET_UINT_FROM_POINTER(BLI_edgehashIterator_getValue(ehi)); + for (eidx = 0, ed = orig_medge; eidx < numEdges; eidx++, ed++) { if (!ELEM(edge_users[eidx], INVALID_UNUSED, INVALID_PAIR)) { - BLI_edgehashIterator_getKey(ehi, &v1, &v2); - orig_mvert[v1].flag |= ME_VERT_TMP_TAG; - orig_mvert[v2].flag |= ME_VERT_TMP_TAG; + orig_mvert[ed->v1].flag |= ME_VERT_TMP_TAG; + orig_mvert[ed->v2].flag |= ME_VERT_TMP_TAG; STACK_PUSH(new_edge_arr, eidx); newFaces++; newLoops += 4; } } - BLI_edgehashIterator_free(ehi); #undef INVALID_UNUSED #undef INVALID_PAIR @@ -365,8 +344,6 @@ static DerivedMesh *applyModifier( mv->flag &= ~ME_VERT_TMP_TAG; } } - - BLI_edgehash_free(edgehash, NULL); } if (smd->flag & MOD_SOLIDIFY_NORMAL_CALC) { From 0b316d72cabb0d604587f98c37c394b4cac35189 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 12 Jun 2013 07:53:54 +0000 Subject: [PATCH 21/37] change to solidify modifiers own normal calculation function, dont attempt to calculate normals for edges with 3+ face users. --- .../blender/modifiers/intern/MOD_solidify.c | 36 +++++++++++-------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/source/blender/modifiers/intern/MOD_solidify.c b/source/blender/modifiers/intern/MOD_solidify.c index 7ca187aa039..6d5dda61f23 100644 --- a/source/blender/modifiers/intern/MOD_solidify.c +++ b/source/blender/modifiers/intern/MOD_solidify.c @@ -122,9 +122,13 @@ static void dm_calc_normal(DerivedMesh *dm, float (*temp_nors)[3]) edge_ref->f1 = i; edge_ref->f2 = -1; } - else { + else if ((edge_ref->f1 != -1) && (edge_ref->f2 == -1)) { edge_ref->f2 = i; } + else { + /* 3+ faces using an edge, we can't handle this usefully */ + edge_ref->f1 = edge_ref->f2 = -1; + } /* --- done --- */ } } @@ -132,25 +136,27 @@ static void dm_calc_normal(DerivedMesh *dm, float (*temp_nors)[3]) for (i = 0, ed = medge, edge_ref = edge_ref_array; i < numEdges; i++, ed++, edge_ref++) { /* Get the edge vert indices, and edge value (the face indices that use it) */ - if (edgeref_is_init(edge_ref) && (edge_ref->f2 != -1)) { - /* We have 2 faces using this edge, calculate the edges normal - * using the angle between the 2 faces as a weighting */ + if (edgeref_is_init(edge_ref) && (edge_ref->f1 != -1)) { + if (edge_ref->f2 != -1) { + /* We have 2 faces using this edge, calculate the edges normal + * using the angle between the 2 faces as a weighting */ #if 0 - add_v3_v3v3(edge_normal, face_nors[edge_ref->f1], face_nors[edge_ref->f2]); - normalize_v3(edge_normal); + add_v3_v3v3(edge_normal, face_nors[edge_ref->f1], face_nors[edge_ref->f2]); + normalize_v3(edge_normal); - mul_v3_fl(edge_normal, angle_normalized_v3v3(face_nors[edge_ref->f1], face_nors[edge_ref->f2])); + mul_v3_fl(edge_normal, angle_normalized_v3v3(face_nors[edge_ref->f1], face_nors[edge_ref->f2])); #else - mid_v3_v3v3_angle_weighted(edge_normal, face_nors[edge_ref->f1], face_nors[edge_ref->f2]); + mid_v3_v3v3_angle_weighted(edge_normal, face_nors[edge_ref->f1], face_nors[edge_ref->f2]); #endif + } + else { + /* only one face attached to that edge */ + /* an edge without another attached- the weight on this is undefined */ + copy_v3_v3(edge_normal, face_nors[edge_ref->f1]); + } + add_v3_v3(temp_nors[ed->v1], edge_normal); + add_v3_v3(temp_nors[ed->v2], edge_normal); } - else { - /* only one face attached to that edge */ - /* an edge without another attached- the weight on this is undefined */ - copy_v3_v3(edge_normal, face_nors[edge_ref->f1]); - } - add_v3_v3(temp_nors[ed->v1], edge_normal); - add_v3_v3(temp_nors[ed->v2], edge_normal); } MEM_freeN(edge_ref_array); } From 8e2e590484dbdb2da433649fac8521b91f384ca2 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 12 Jun 2013 08:24:31 +0000 Subject: [PATCH 22/37] fix [#35710] Mesh explodes while using solidify modifier with tubular non-manifold base mesh. --- source/blender/makesdna/DNA_meshdata_types.h | 2 +- source/blender/modifiers/intern/MOD_solidify.c | 17 +++++++++++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/source/blender/makesdna/DNA_meshdata_types.h b/source/blender/makesdna/DNA_meshdata_types.h index d1e123cb826..9f9bc25a61c 100644 --- a/source/blender/makesdna/DNA_meshdata_types.h +++ b/source/blender/makesdna/DNA_meshdata_types.h @@ -309,7 +309,7 @@ typedef struct FreestyleFace { /* reserve 16 for ME_HIDE */ #define ME_EDGERENDER (1<<5) #define ME_LOOSEEDGE (1<<7) -/* #define ME_SEAM_LAST (1<<8) */ /* UNUSED */ +#define ME_EDGE_TMP_TAG (1 << 8) #define ME_SHARP (1<<9) /* only reason this flag remains a 'short' */ /* puno = vertexnormal (mface) */ diff --git a/source/blender/modifiers/intern/MOD_solidify.c b/source/blender/modifiers/intern/MOD_solidify.c index 6d5dda61f23..2c9170522d5 100644 --- a/source/blender/modifiers/intern/MOD_solidify.c +++ b/source/blender/modifiers/intern/MOD_solidify.c @@ -60,7 +60,7 @@ typedef struct EdgeFaceRef { BLI_INLINE bool edgeref_is_init(const EdgeFaceRef *edge_ref) { - return (edge_ref->f1 != 0) && (edge_ref->f2 != 0); + return !((edge_ref->f1 == 0) && (edge_ref->f2 == 0)); } static void dm_calc_normal(DerivedMesh *dm, float (*temp_nors)[3]) @@ -128,6 +128,7 @@ static void dm_calc_normal(DerivedMesh *dm, float (*temp_nors)[3]) else { /* 3+ faces using an edge, we can't handle this usefully */ edge_ref->f1 = edge_ref->f2 = -1; + medge[ml->e].flag |= ME_EDGE_TMP_TAG; } /* --- done --- */ } @@ -501,6 +502,7 @@ static DerivedMesh *applyModifier( } else { /* make a face normal layer if not present */ + const bool check_non_manifold = (smd->flag & MOD_SOLIDIFY_NORMAL_CALC) != 0; float (*face_nors)[3]; bool face_nors_calc = false; @@ -551,9 +553,20 @@ static DerivedMesh *applyModifier( if (angle < FLT_EPSILON) { angle = FLT_EPSILON; } + vidx = ml[i_this].v; vert_accum[vidx] += angle; - vert_angles[vidx] += shell_angle_to_dist(angle_normalized_v3v3(vert_nors[vidx], face_nors[i])) * angle; + + /* skip 3+ face user edges */ + if ((check_non_manifold == false) || + LIKELY(((orig_medge[ml[i_this].e].flag & ME_EDGE_TMP_TAG) == 0) && + ((orig_medge[ml[i_next].e].flag & ME_EDGE_TMP_TAG) == 0))) + { + vert_angles[vidx] += shell_angle_to_dist(angle_normalized_v3v3(vert_nors[vidx], face_nors[i])) * angle; + } + else { + vert_angles[vidx] += angle; + } /* --- end non-angle-calc section --- */ From 31e667c10eec08aadf1a8fc156ffefcaf63a24ec Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 12 Jun 2013 09:35:02 +0000 Subject: [PATCH 23/37] solidify: dont add poly-normal layer to the derived mesh, since this is no longer a convention. --- source/blender/blenkernel/BKE_mesh.h | 3 +- .../blender/blenkernel/intern/cdderivedmesh.c | 4 +- source/blender/blenkernel/intern/mesh.c | 17 +++- .../blender/modifiers/intern/MOD_solidify.c | 89 +++++++------------ 4 files changed, 52 insertions(+), 61 deletions(-) diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index 7bb188d5ff6..3054849999c 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -221,7 +221,8 @@ void BKE_mesh_calc_normals_mapping_ex( void BKE_mesh_calc_normals_poly( struct MVert *mverts, int numVerts, struct MLoop *mloop, struct MPoly *mpolys, - int numLoops, int numPolys, float (*polyNors_r)[3]); + int numLoops, int numPolys, float (*polyNors_r)[3], + const bool only_face_normals); void BKE_mesh_calc_normals(struct Mesh *me); diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index af0dadeccab..64d6ca6666e 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -2291,7 +2291,7 @@ void CDDM_calc_normals(DerivedMesh *dm) } BKE_mesh_calc_normals_poly(cddm->mvert, dm->numVertData, CDDM_get_loops(dm), CDDM_get_polys(dm), - dm->numLoopData, dm->numPolyData, poly_nors); + dm->numLoopData, dm->numPolyData, poly_nors, false); cddm->dm.dirty &= ~DM_DIRTY_NORMALS; } @@ -2306,7 +2306,7 @@ void CDDM_calc_normals(DerivedMesh *dm) cddm->mvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData); BKE_mesh_calc_normals_poly(cddm->mvert, dm->numVertData, CDDM_get_loops(dm), CDDM_get_polys(dm), - dm->numLoopData, dm->numPolyData, NULL); + dm->numLoopData, dm->numPolyData, NULL, false); cddm->dm.dirty &= ~DM_DIRTY_NORMALS; } diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index 2eb318c316f..d02884f1a7b 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -1907,7 +1907,7 @@ void BKE_mesh_calc_normals_mapping_ex(MVert *mverts, int numVerts, if (only_face_normals == FALSE) { /* vertex normals are optional, they require some extra calculations, * so make them optional */ - BKE_mesh_calc_normals_poly(mverts, numVerts, mloop, mpolys, numLoops, numPolys, pnors); + BKE_mesh_calc_normals_poly(mverts, numVerts, mloop, mpolys, numLoops, numPolys, pnors, false); } else { /* only calc poly normals */ @@ -1994,13 +1994,24 @@ static void mesh_calc_normals_poly_accum(MPoly *mp, MLoop *ml, } void BKE_mesh_calc_normals_poly(MVert *mverts, int numVerts, MLoop *mloop, MPoly *mpolys, - int UNUSED(numLoops), int numPolys, float (*r_polynors)[3]) + int UNUSED(numLoops), int numPolys, float (*r_polynors)[3], + const bool only_face_normals) { float (*pnors)[3] = r_polynors; float (*tnorms)[3]; int i; MPoly *mp; + if (only_face_normals) { + BLI_assert(pnors != NULL); + +#pragma omp parallel for if (numPolys > BM_OMP_LIMIT) + for (i = 0; i < numPolys; i++) { + BKE_mesh_calc_poly_normal(&mpolys[i], mloop + mpolys[i].loopstart, mverts, pnors[i]); + } + return; + } + /* first go through and calculate normals for all the polys */ tnorms = MEM_callocN(sizeof(*tnorms) * numVerts, __func__); @@ -2037,7 +2048,7 @@ void BKE_mesh_calc_normals(Mesh *mesh) { BKE_mesh_calc_normals_poly(mesh->mvert, mesh->totvert, mesh->mloop, mesh->mpoly, mesh->totloop, mesh->totpoly, - NULL); + NULL, false); } void BKE_mesh_calc_normals_tessface(MVert *mverts, int numVerts, MFace *mfaces, int numFaces, float (*faceNors_r)[3]) diff --git a/source/blender/modifiers/intern/MOD_solidify.c b/source/blender/modifiers/intern/MOD_solidify.c index 2c9170522d5..ce1896fc971 100644 --- a/source/blender/modifiers/intern/MOD_solidify.c +++ b/source/blender/modifiers/intern/MOD_solidify.c @@ -63,7 +63,12 @@ BLI_INLINE bool edgeref_is_init(const EdgeFaceRef *edge_ref) return !((edge_ref->f1 == 0) && (edge_ref->f2 == 0)); } -static void dm_calc_normal(DerivedMesh *dm, float (*temp_nors)[3]) +/** + * \param dm Mesh to calculate normals for. + * \param face_nors Precalculated face normals. + * \param r_vert_nors Return vert normals. + */ +static void dm_calc_normal(DerivedMesh *dm, float (*face_nors)[3], float (*r_vert_nors)[3]) { int i, numVerts, numEdges, numFaces; MPoly *mpoly, *mp; @@ -71,10 +76,6 @@ static void dm_calc_normal(DerivedMesh *dm, float (*temp_nors)[3]) MEdge *medge, *ed; MVert *mvert, *mv; - float (*face_nors)[3]; - float *f_no; - bool calc_face_nors = false; - numVerts = dm->getNumVerts(dm); numEdges = dm->getNumEdges(dm); numFaces = dm->getNumPolys(dm); @@ -91,12 +92,6 @@ static void dm_calc_normal(DerivedMesh *dm, float (*temp_nors)[3]) cddm->mvert = mv; #endif - face_nors = CustomData_get_layer(&dm->polyData, CD_NORMAL); - if (!face_nors) { - calc_face_nors = true; - face_nors = CustomData_add_layer(&dm->polyData, CD_NORMAL, CD_CALLOC, NULL, numFaces); - } - mv = mvert; mp = mpoly; @@ -109,10 +104,6 @@ static void dm_calc_normal(DerivedMesh *dm, float (*temp_nors)[3]) for (i = 0; i < numFaces; i++, mp++) { int j; - f_no = face_nors[i]; - if (calc_face_nors) - BKE_mesh_calc_poly_normal(mp, mloop + mp->loopstart, mvert, f_no); - ml = mloop + mp->loopstart; for (j = 0; j < mp->totloop; j++, ml++) { @@ -155,8 +146,8 @@ static void dm_calc_normal(DerivedMesh *dm, float (*temp_nors)[3]) /* an edge without another attached- the weight on this is undefined */ copy_v3_v3(edge_normal, face_nors[edge_ref->f1]); } - add_v3_v3(temp_nors[ed->v1], edge_normal); - add_v3_v3(temp_nors[ed->v2], edge_normal); + add_v3_v3(r_vert_nors[ed->v1], edge_normal); + add_v3_v3(r_vert_nors[ed->v2], edge_normal); } } MEM_freeN(edge_ref_array); @@ -164,8 +155,8 @@ static void dm_calc_normal(DerivedMesh *dm, float (*temp_nors)[3]) /* normalize vertex normals and assign */ for (i = 0; i < numVerts; i++, mv++) { - if (normalize_v3(temp_nors[i]) == 0.0f) { - normal_short_to_float_v3(temp_nors[i], mv->no); + if (normalize_v3(r_vert_nors[i]) == 0.0f) { + normal_short_to_float_v3(r_vert_nors[i], mv->no); } } } @@ -230,7 +221,8 @@ static DerivedMesh *applyModifier( const unsigned int numVerts = (unsigned int)dm->getNumVerts(dm); const unsigned int numEdges = (unsigned int)dm->getNumEdges(dm); const unsigned int numFaces = (unsigned int)dm->getNumPolys(dm); - unsigned int numLoops = 0, newLoops = 0, newFaces = 0, newEdges = 0; + const unsigned int numLoops = (unsigned int)dm->getNumLoops(dm); + unsigned int newLoops = 0, newFaces = 0, newEdges = 0; /* only use material offsets if we have 2 or more materials */ const short mat_nr_max = ob->totcol > 1 ? ob->totcol - 1 : 0; @@ -251,8 +243,9 @@ static DerivedMesh *applyModifier( char *edge_order = NULL; float (*vert_nors)[3] = NULL; + float (*face_nors)[3] = NULL; - float (*face_nors_result)[3] = NULL; + const bool need_face_normals = (smd->flag & MOD_SOLIDIFY_NORMAL_CALC) || (smd->flag & MOD_SOLIDIFY_EVEN); const float ofs_orig = -(((-smd->offset_fac + 1.0f) * 0.5f) * smd->offset); const float ofs_new = smd->offset + ofs_orig; @@ -268,14 +261,21 @@ static DerivedMesh *applyModifier( modifier_get_vgroup(ob, dm, smd->defgrp_name, &dvert, &defgrp_index); - numLoops = (unsigned int)dm->numLoopData; - newLoops = 0; - orig_mvert = dm->getVertArray(dm); orig_medge = dm->getEdgeArray(dm); orig_mloop = dm->getLoopArray(dm); orig_mpoly = dm->getPolyArray(dm); + if (need_face_normals) { + /* calculate only face normals */ + face_nors = MEM_mallocN(sizeof(*face_nors) * (size_t)numFaces, __func__); + BKE_mesh_calc_normals_poly( + orig_mvert, (int)numVerts, + orig_mloop, orig_mpoly, + (int)numLoops, (int)numFaces, + face_nors, true); + } + STACK_INIT(new_vert_arr); STACK_INIT(new_edge_arr); @@ -355,7 +355,7 @@ static DerivedMesh *applyModifier( if (smd->flag & MOD_SOLIDIFY_NORMAL_CALC) { vert_nors = MEM_callocN(sizeof(float) * (size_t)numVerts * 3, "mod_solid_vno_hq"); - dm_calc_normal(dm, vert_nors); + dm_calc_normal(dm, face_nors, vert_nors); } result = CDDM_from_template(dm, @@ -381,9 +381,6 @@ static DerivedMesh *applyModifier( DM_copy_poly_data(dm, result, 0, 0, (int)numFaces); DM_copy_poly_data(dm, result, 0, (int)numFaces, (int)numFaces); - /* if the original has it, get the result so we can update it */ - face_nors_result = CustomData_get_layer(&result->polyData, CD_NORMAL); - /* flip normals */ mp = mpoly + numFaces; for (i = 0; i < dm->numPolyData; i++, mp++) { @@ -414,10 +411,6 @@ static DerivedMesh *applyModifier( ml2[j].e += numEdges; ml2[j].v += numVerts; } - - if (face_nors_result) { - negate_v3_v3(face_nors_result[numFaces + i], face_nors_result[i]); - } } for (i = 0, ed = medge + numEdges; i < numEdges; i++, ed++) { @@ -503,20 +496,12 @@ static DerivedMesh *applyModifier( else { /* make a face normal layer if not present */ const bool check_non_manifold = (smd->flag & MOD_SOLIDIFY_NORMAL_CALC) != 0; - float (*face_nors)[3]; - bool face_nors_calc = false; /* same as EM_solidify() in editmesh_lib.c */ float *vert_angles = MEM_callocN(sizeof(float) * numVerts * 2, "mod_solid_pair"); /* 2 in 1 */ float *vert_accum = vert_angles + numVerts; unsigned int vidx; - face_nors = CustomData_get_layer(&dm->polyData, CD_NORMAL); - if (!face_nors) { - face_nors = CustomData_add_layer(&dm->polyData, CD_NORMAL, CD_CALLOC, NULL, dm->numPolyData); - face_nors_calc = true; - } - if (vert_nors == NULL) { vert_nors = MEM_mallocN(sizeof(float) * numVerts * 3, "mod_solid_vno"); for (i = 0, mv = mvert; i < numVerts; i++, mv++) { @@ -529,22 +514,17 @@ static DerivedMesh *applyModifier( float nor_prev[3]; float nor_next[3]; - int i_this = mp->totloop - 1; + int i_curr = mp->totloop - 1; int i_next = 0; ml = &mloop[mp->loopstart]; - /* --- not related to angle calc --- */ - if (face_nors_calc) - BKE_mesh_calc_poly_normal(mp, ml, mvert, face_nors[i]); - /* --- end non-angle-calc section --- */ - - sub_v3_v3v3(nor_prev, mvert[ml[i_this - 1].v].co, mvert[ml[i_this].v].co); + sub_v3_v3v3(nor_prev, mvert[ml[i_curr - 1].v].co, mvert[ml[i_curr].v].co); normalize_v3(nor_prev); while (i_next < mp->totloop) { float angle; - sub_v3_v3v3(nor_next, mvert[ml[i_this].v].co, mvert[ml[i_next].v].co); + sub_v3_v3v3(nor_next, mvert[ml[i_curr].v].co, mvert[ml[i_next].v].co); normalize_v3(nor_next); angle = angle_normalized_v3v3(nor_prev, nor_next); @@ -554,12 +534,12 @@ static DerivedMesh *applyModifier( angle = FLT_EPSILON; } - vidx = ml[i_this].v; + vidx = ml[i_curr].v; vert_accum[vidx] += angle; /* skip 3+ face user edges */ if ((check_non_manifold == false) || - LIKELY(((orig_medge[ml[i_this].e].flag & ME_EDGE_TMP_TAG) == 0) && + LIKELY(((orig_medge[ml[i_curr].e].flag & ME_EDGE_TMP_TAG) == 0) && ((orig_medge[ml[i_next].e].flag & ME_EDGE_TMP_TAG) == 0))) { vert_angles[vidx] += shell_angle_to_dist(angle_normalized_v3v3(vert_nors[vidx], face_nors[i])) * angle; @@ -572,7 +552,7 @@ static DerivedMesh *applyModifier( /* step */ copy_v3_v3(nor_prev, nor_next); - i_this = i_next; + i_curr = i_next; i_next++; } } @@ -800,10 +780,6 @@ static DerivedMesh *applyModifier( add_v3_v3(edge_vert_nos[ed->v1], nor); add_v3_v3(edge_vert_nos[ed->v2], nor); - - if (face_nors_result) { - copy_v3_v3(face_nors_result[(numFaces * 2) + i], nor); - } } #endif } @@ -845,6 +821,9 @@ static DerivedMesh *applyModifier( if (old_vert_arr) MEM_freeN(old_vert_arr); + if (face_nors) + MEM_freeN(face_nors); + if (numFaces == 0 && numEdges != 0) { modifier_setError(md, "Faces needed for useful output"); } From 1d1bf3b2babd885a94422d6430af1b211109d7ae Mon Sep 17 00:00:00 2001 From: Gaia Clary Date: Wed, 12 Jun 2013 09:52:37 +0000 Subject: [PATCH 24/37] prepared local vgroup selection function for more general usage --- source/blender/editors/include/ED_object.h | 16 ++++++++++ source/blender/editors/object/object_vgroup.c | 31 ++++++------------- 2 files changed, 25 insertions(+), 22 deletions(-) diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h index 00b8fc4535d..b2810031474 100644 --- a/source/blender/editors/include/ED_object.h +++ b/source/blender/editors/include/ED_object.h @@ -200,6 +200,22 @@ int ED_object_multires_update_totlevels_cb(struct Object *ob, void *totlevel_v); /* object_select.c */ void ED_object_select_linked_by_id(struct bContext *C, struct ID *id); +/* object_vgroup.c */ +typedef enum eVGroupSelect { + WT_VGROUP_ACTIVE = 1, + WT_VGROUP_BONE_SELECT = 2, + WT_VGROUP_BONE_DEFORM = 3, + WT_VGROUP_ALL = 4, +} eVGroupSelect; + +#define WT_VGROUP_MASK_ALL \ + ((1 << WT_VGROUP_ACTIVE) | \ + (1 << WT_VGROUP_BONE_SELECT) | \ + (1 << WT_VGROUP_BONE_DEFORM) | \ + (1 << WT_VGROUP_ALL)) + +bool *ED_vgroup_subset_from_select_type(struct Object *ob, eVGroupSelect subset_type, int *r_vgroup_tot, int *r_subset_count); + #ifdef __cplusplus } #endif diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 1089df2e00d..74f1515fe74 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -430,19 +430,6 @@ typedef enum WT_ReplaceMode { WT_REPLACE_EMPTY_WEIGHTS = 2 } WT_ReplaceMode; -typedef enum WT_VertexGroupSelect { - WT_VGROUP_ACTIVE = 1, - WT_VGROUP_BONE_SELECT = 2, - WT_VGROUP_BONE_DEFORM = 3, - WT_VGROUP_ALL = 4, -} WT_VertexGroupSelect; - -#define WT_VGROUP_MASK_ALL \ - ((1 << WT_VGROUP_ACTIVE) | \ - (1 << WT_VGROUP_BONE_SELECT) | \ - (1 << WT_VGROUP_BONE_DEFORM) | \ - (1 << WT_VGROUP_ALL)) - static EnumPropertyItem WT_vertex_group_mode_item[] = { {WT_REPLACE_ACTIVE_VERTEX_GROUP, "WT_REPLACE_ACTIVE_VERTEX_GROUP", 0, "Active", "Transfer active vertex group from selected to active mesh"}, @@ -1179,7 +1166,7 @@ static void vgroup_duplicate(Object *ob) /** * Return the subset type of the Vertex Group Selection */ -static bool *vgroup_subset_from_select_type(Object *ob, WT_VertexGroupSelect subset_type, int *r_vgroup_tot, int *r_subset_count) +bool *ED_vgroup_subset_from_select_type(Object *ob, eVGroupSelect subset_type, int *r_vgroup_tot, int *r_subset_count) { bool *vgroup_validmap = NULL; *r_vgroup_tot = BLI_countlist(&ob->defbase); @@ -3010,11 +2997,11 @@ static int vertex_group_levels_exec(bContext *C, wmOperator *op) float offset = RNA_float_get(op->ptr, "offset"); float gain = RNA_float_get(op->ptr, "gain"); - WT_VertexGroupSelect subset_type = RNA_enum_get(op->ptr, "group_select_mode"); + eVGroupSelect subset_type = RNA_enum_get(op->ptr, "group_select_mode"); int subset_count, vgroup_tot; - bool *vgroup_validmap = vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count); + bool *vgroup_validmap = ED_vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count); vgroup_levels_subset(ob, vgroup_validmap, vgroup_tot, subset_count, offset, gain); MEM_freeN(vgroup_validmap); @@ -3192,11 +3179,11 @@ static int vertex_group_invert_exec(bContext *C, wmOperator *op) bool auto_assign = RNA_boolean_get(op->ptr, "auto_assign"); bool auto_remove = RNA_boolean_get(op->ptr, "auto_remove"); - WT_VertexGroupSelect subset_type = RNA_enum_get(op->ptr, "group_select_mode"); + eVGroupSelect subset_type = RNA_enum_get(op->ptr, "group_select_mode"); int subset_count, vgroup_tot; - bool *vgroup_validmap = vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count); + bool *vgroup_validmap = ED_vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count); vgroup_invert_subset(ob, vgroup_validmap, vgroup_tot, subset_count, auto_assign, auto_remove); MEM_freeN(vgroup_validmap); @@ -3300,11 +3287,11 @@ static int vertex_group_clean_exec(bContext *C, wmOperator *op) float limit = RNA_float_get(op->ptr, "limit"); bool keep_single = RNA_boolean_get(op->ptr, "keep_single"); - WT_VertexGroupSelect subset_type = RNA_enum_get(op->ptr, "group_select_mode"); + eVGroupSelect subset_type = RNA_enum_get(op->ptr, "group_select_mode"); int subset_count, vgroup_tot; - bool *vgroup_validmap = vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count); + bool *vgroup_validmap = ED_vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count); vgroup_clean_subset(ob, vgroup_validmap, vgroup_tot, subset_count, limit, keep_single); MEM_freeN(vgroup_validmap); @@ -3341,11 +3328,11 @@ static int vertex_group_limit_total_exec(bContext *C, wmOperator *op) Object *ob = ED_object_context(C); const int limit = RNA_int_get(op->ptr, "limit"); - WT_VertexGroupSelect subset_type = RNA_enum_get(op->ptr, "group_select_mode"); + eVGroupSelect subset_type = RNA_enum_get(op->ptr, "group_select_mode"); int subset_count, vgroup_tot; - bool *vgroup_validmap = vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count); + bool *vgroup_validmap = ED_vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count); int remove_tot = vgroup_limit_total_subset(ob, vgroup_validmap, vgroup_tot, subset_count, limit); MEM_freeN(vgroup_validmap); From 69153c7089e8af5a2539bd314caca11010952cff Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 12 Jun 2013 10:03:13 +0000 Subject: [PATCH 25/37] ifdef bugfix since its a little strange. --- source/blender/modifiers/intern/MOD_solidify.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/source/blender/modifiers/intern/MOD_solidify.c b/source/blender/modifiers/intern/MOD_solidify.c index ce1896fc971..97f229439e6 100644 --- a/source/blender/modifiers/intern/MOD_solidify.c +++ b/source/blender/modifiers/intern/MOD_solidify.c @@ -50,6 +50,9 @@ # pragma GCC diagnostic error "-Wsign-conversion" #endif +/* skip shell thickness for non-manifold edges, see [#35710] */ +#define USE_NONMANIFOLD_WORKAROUND + /* *** derived mesh high quality normal calculation function *** */ /* could be exposed for other functions to use */ @@ -119,7 +122,9 @@ static void dm_calc_normal(DerivedMesh *dm, float (*face_nors)[3], float (*r_ver else { /* 3+ faces using an edge, we can't handle this usefully */ edge_ref->f1 = edge_ref->f2 = -1; +#ifdef USE_NONMANIFOLD_WORKAROUND medge[ml->e].flag |= ME_EDGE_TMP_TAG; +#endif } /* --- done --- */ } @@ -494,9 +499,9 @@ static DerivedMesh *applyModifier( } } else { - /* make a face normal layer if not present */ +#ifdef USE_NONMANIFOLD_WORKAROUND const bool check_non_manifold = (smd->flag & MOD_SOLIDIFY_NORMAL_CALC) != 0; - +#endif /* same as EM_solidify() in editmesh_lib.c */ float *vert_angles = MEM_callocN(sizeof(float) * numVerts * 2, "mod_solid_pair"); /* 2 in 1 */ float *vert_accum = vert_angles + numVerts; @@ -537,6 +542,7 @@ static DerivedMesh *applyModifier( vidx = ml[i_curr].v; vert_accum[vidx] += angle; +#ifdef USE_NONMANIFOLD_WORKAROUND /* skip 3+ face user edges */ if ((check_non_manifold == false) || LIKELY(((orig_medge[ml[i_curr].e].flag & ME_EDGE_TMP_TAG) == 0) && @@ -547,6 +553,9 @@ static DerivedMesh *applyModifier( else { vert_angles[vidx] += angle; } +#else + vert_angles[vidx] += shell_angle_to_dist(angle_normalized_v3v3(vert_nors[vidx], face_nors[i])) * angle; +#endif /* --- end non-angle-calc section --- */ From 793e582d1a65bf2fbe285ae624916a569a8fdc17 Mon Sep 17 00:00:00 2001 From: Gaia Clary Date: Wed, 12 Jun 2013 10:39:27 +0000 Subject: [PATCH 26/37] Vertex weight panel now uses same sort order as Vertex Group list --- .../editors/space_view3d/view3d_buttons.c | 26 ++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c index 9d4da4c7e13..f7edb2949bc 100644 --- a/source/blender/editors/space_view3d/view3d_buttons.c +++ b/source/blender/editors/space_view3d/view3d_buttons.c @@ -70,6 +70,7 @@ #include "ED_armature.h" #include "ED_gpencil.h" +#include "ED_object.h" #include "ED_mesh.h" #include "ED_screen.h" #include "ED_transform.h" @@ -1005,8 +1006,10 @@ static void view3d_panel_vgroup(const bContext *C, Panel *pa) if (dv && dv->totweight) { uiLayout *col; bDeformGroup *dg; - MDeformWeight *dw = dv->dw; unsigned int i; + int subset_count, vgroup_tot; + bool *vgroup_validmap; + eVGroupSelect subset_type = WT_VGROUP_ALL; int yco = 0; uiBlockSetHandleFunc(block, do_view3d_vgroup_buttons, NULL); @@ -1016,16 +1019,21 @@ static void view3d_panel_vgroup(const bContext *C, Panel *pa) uiBlockBeginAlign(block); - for (i = dv->totweight; i != 0; i--, dw++) { - dg = BLI_findlink(&ob->defbase, dw->def_nr); - if (dg) { - uiDefButF(block, NUM, B_VGRP_PNL_EDIT_SINGLE + dw->def_nr, dg->name, 0, yco, 180, 20, - &dw->weight, 0.0, 1.0, 1, 3, ""); - uiDefBut(block, BUT, B_VGRP_PNL_COPY_SINGLE + dw->def_nr, "C", 180, yco, 20, 20, - NULL, 0, 0, 0, 0, TIP_("Copy this group's weight to other selected verts")); - yco -= 20; + vgroup_validmap = ED_vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count); + for (i = 0, dg = ob->defbase.first; dg; i++, dg = dg->next) { + if (vgroup_validmap[i]) { + MDeformWeight *dw = defvert_find_index(dv, i); + if (dw) { + uiDefButF(block, NUM, B_VGRP_PNL_EDIT_SINGLE + i, dg->name, 0, yco, 180, 20, + &dw->weight, 0.0, 1.0, 1, 3, ""); + uiDefBut(block, BUT, B_VGRP_PNL_COPY_SINGLE + i, "C", 180, yco, 20, 20, + NULL, 0, 0, 0, 0, TIP_("Copy this group's weight to other selected verts")); + yco -= 20; + } } } + MEM_freeN(vgroup_validmap); + yco -= 2; uiBlockEndAlign(block); From 0c91ebfeee94500ebd76d15119261c6d0f72b41f Mon Sep 17 00:00:00 2001 From: Lukas Toenne Date: Wed, 12 Jun 2013 11:26:44 +0000 Subject: [PATCH 27/37] Fix #35703, Viewer node doesn't updates image sometimes. The viewer node was not getting correctly initialized node->id pointer to the Viewer image (thanks to Sergey for figuring that out). The original proposal was to add another special init hack for the viewer node->id, but rather would do it right and so moved all the special init hacks for constant ID backpointers (Scene for RenderLayer, Composite, Defocus, FileOutput and MovieClip for MovieClip, MovieDistortion and Stabilization nodes). These are now part of the local init callbacks functions of the appropriate nodes, using the new initfunc_api callback which takes a Context pointer, so they have access to Scene. --- source/blender/blenkernel/BKE_node.h | 2 +- source/blender/blenkernel/intern/node.c | 3 + source/blender/editors/space_node/node_add.c | 16 ---- source/blender/makesrna/intern/rna_nodetree.c | 18 +---- source/blender/makesrna/intern/rna_scene.c | 2 +- source/blender/nodes/NOD_composite.h | 2 + .../nodes/composite/node_composite_tree.c | 62 ++------------- .../nodes/node_composite_composite.c | 13 +++ .../composite/nodes/node_composite_defocus.c | 12 ++- .../composite/nodes/node_composite_image.c | 79 +++++++++++++++++++ .../nodes/node_composite_movieclip.c | 11 ++- .../nodes/node_composite_moviedistortion.c | 13 +++ .../nodes/node_composite_outputFile.c | 2 + .../nodes/node_composite_splitViewer.c | 4 + .../nodes/node_composite_stabilize2d.c | 13 ++- .../composite/nodes/node_composite_viewer.c | 4 + 16 files changed, 158 insertions(+), 98 deletions(-) diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index 55f68fcb8bd..ec0dd11392d 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -925,7 +925,7 @@ void ntreeCompositExecTree(struct bNodeTree *ntree, struct RenderData *rd, int r void ntreeCompositTagRender(struct Scene *sce); int ntreeCompositTagAnimated(struct bNodeTree *ntree); void ntreeCompositTagGenerators(struct bNodeTree *ntree); -void ntreeCompositForceHidden(struct bNodeTree *ntree, struct Scene *scene); +void ntreeCompositForceHidden(struct bNodeTree *ntree); void ntreeCompositClearTags(struct bNodeTree *ntree); struct bNodeSocket *ntreeCompositOutputFileAddSocket(struct bNodeTree *ntree, struct bNode *node, diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index f805005e911..d40e0daf247 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -150,6 +150,9 @@ static void node_init(const struct bContext *C, bNodeTree *ntree, bNode *node) ntype->initfunc_api(C, &ptr); } + if (node->id) + id_us_plus(node->id); + node->flag |= NODE_INIT; } diff --git a/source/blender/editors/space_node/node_add.c b/source/blender/editors/space_node/node_add.c index 509339dd3d4..d5224a37358 100644 --- a/source/blender/editors/space_node/node_add.c +++ b/source/blender/editors/space_node/node_add.c @@ -64,13 +64,11 @@ /* XXX Does some additional initialization on top of nodeAddNode * Can be used with both custom and static nodes, if idname==NULL the static int type will be used instead. - * Can be called from menus too, but they should do own undopush and redraws. */ bNode *node_add_node(const bContext *C, const char *idname, int type, float locx, float locy) { SpaceNode *snode = CTX_wm_space_node(C); Main *bmain = CTX_data_main(C); - Scene *scene = CTX_data_scene(C); bNode *node = NULL; node_deselect_all(snode); @@ -96,20 +94,6 @@ bNode *node_add_node(const bContext *C, const char *idname, int type, float locx ntreeUpdateTree(bmain, snode->edittree); ED_node_set_active(bmain, snode->edittree, node); - if (snode->nodetree->type == NTREE_COMPOSIT) { - if (ELEM4(node->type, CMP_NODE_R_LAYERS, CMP_NODE_COMPOSITE, CMP_NODE_DEFOCUS, CMP_NODE_OUTPUT_FILE)) { - node->id = &scene->id; - } - else if (ELEM3(node->type, CMP_NODE_MOVIECLIP, CMP_NODE_MOVIEDISTORTION, CMP_NODE_STABILIZE2D)) { - node->id = (ID *)scene->clip; - } - - ntreeCompositForceHidden(snode->edittree, scene); - } - - if (node->id) - id_us_plus(node->id); - if (snode->flag & SNODE_USE_HIDDEN_PREVIEW) node->flag &= ~NODE_PREVIEW; diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 4433dc45601..04051cf3418 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -724,23 +724,7 @@ static bNode *rna_NodeTree_node_new(bNodeTree *ntree, bContext *C, ReportList *r node = nodeAddNode(C, ntree, type); BLI_assert(node && node->typeinfo); - /* XXX ugly stuff, should be done with specialized operators (after actual node creation)! */ - if (ntree->type == NTREE_COMPOSIT) { - if (ELEM4(node->type, CMP_NODE_COMPOSITE, CMP_NODE_DEFOCUS, CMP_NODE_OUTPUT_FILE, CMP_NODE_R_LAYERS)) { - /* annoying, find the node tree we are in, scene can be NULL */ - Scene *scene; - for (scene = CTX_data_main(C)->scene.first; scene; scene = scene->id.next) { - if (scene->nodetree == ntree) { - break; - } - } - node->id = (ID *)scene; - id_us_plus(node->id); - } - - ntreeCompositForceHidden(ntree, CTX_data_scene(C)); - } - else if (ntree->type == NTREE_TEXTURE) { + if (ntree->type == NTREE_TEXTURE) { ntreeTexCheckCyclics(ntree); } diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 0218c188062..44eee642081 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -1195,7 +1195,7 @@ static void rna_SceneRenderLayer_pass_update(Main *bmain, Scene *activescene, Po Scene *scene = (Scene *)ptr->id.data; if (scene->nodetree) - ntreeCompositForceHidden(scene->nodetree, scene); + ntreeCompositForceHidden(scene->nodetree); rna_Scene_glsl_update(bmain, activescene, ptr); } diff --git a/source/blender/nodes/NOD_composite.h b/source/blender/nodes/NOD_composite.h index 896714338e5..626e7955b08 100644 --- a/source/blender/nodes/NOD_composite.h +++ b/source/blender/nodes/NOD_composite.h @@ -138,4 +138,6 @@ void register_node_type_cmp_switch(void); void register_node_type_cmp_pixelate(void); void register_node_type_cmp_trackpos(void); +void node_cmp_rlayers_force_hidden_passes(struct bNode *node); + #endif diff --git a/source/blender/nodes/composite/node_composite_tree.c b/source/blender/nodes/composite/node_composite_tree.c index a00ddf3d5e0..0b62481b2f7 100644 --- a/source/blender/nodes/composite/node_composite_tree.c +++ b/source/blender/nodes/composite/node_composite_tree.c @@ -74,7 +74,7 @@ static void composite_get_from_context(const bContext *C, bNodeTreeType *UNUSED( *r_ntree = scene->nodetree; /* update output sockets based on available layers */ - ntreeCompositForceHidden(scene->nodetree, scene); + ntreeCompositForceHidden(scene->nodetree); } @@ -262,69 +262,17 @@ void ntreeCompositExecTree(bNodeTree *ntree, RenderData *rd, int rendering, int /* *********************************************** */ -static void set_output_visible(bNode *node, int passflag, int index, int pass) -{ - bNodeSocket *sock = BLI_findlink(&node->outputs, index); - /* clear the SOCK_HIDDEN flag as well, in case a socket was hidden before */ - if (passflag & pass) - sock->flag &= ~(SOCK_HIDDEN | SOCK_UNAVAIL); - else - sock->flag |= SOCK_UNAVAIL; -} - -/* clumsy checking... should do dynamic outputs once */ -static void force_hidden_passes(bNode *node, int passflag) -{ - bNodeSocket *sock; - - for (sock = node->outputs.first; sock; sock = sock->next) - sock->flag &= ~SOCK_UNAVAIL; - - set_output_visible(node, passflag, RRES_OUT_IMAGE, SCE_PASS_COMBINED); - set_output_visible(node, passflag, RRES_OUT_ALPHA, SCE_PASS_COMBINED); - - set_output_visible(node, passflag, RRES_OUT_Z, SCE_PASS_Z); - set_output_visible(node, passflag, RRES_OUT_NORMAL, SCE_PASS_NORMAL); - set_output_visible(node, passflag, RRES_OUT_VEC, SCE_PASS_VECTOR); - set_output_visible(node, passflag, RRES_OUT_UV, SCE_PASS_UV); - set_output_visible(node, passflag, RRES_OUT_RGBA, SCE_PASS_RGBA); - set_output_visible(node, passflag, RRES_OUT_DIFF, SCE_PASS_DIFFUSE); - set_output_visible(node, passflag, RRES_OUT_SPEC, SCE_PASS_SPEC); - set_output_visible(node, passflag, RRES_OUT_SHADOW, SCE_PASS_SHADOW); - set_output_visible(node, passflag, RRES_OUT_AO, SCE_PASS_AO); - set_output_visible(node, passflag, RRES_OUT_REFLECT, SCE_PASS_REFLECT); - set_output_visible(node, passflag, RRES_OUT_REFRACT, SCE_PASS_REFRACT); - set_output_visible(node, passflag, RRES_OUT_INDIRECT, SCE_PASS_INDIRECT); - set_output_visible(node, passflag, RRES_OUT_INDEXOB, SCE_PASS_INDEXOB); - set_output_visible(node, passflag, RRES_OUT_INDEXMA, SCE_PASS_INDEXMA); - set_output_visible(node, passflag, RRES_OUT_MIST, SCE_PASS_MIST); - set_output_visible(node, passflag, RRES_OUT_EMIT, SCE_PASS_EMIT); - set_output_visible(node, passflag, RRES_OUT_ENV, SCE_PASS_ENVIRONMENT); - set_output_visible(node, passflag, RRES_OUT_DIFF_DIRECT, SCE_PASS_DIFFUSE_DIRECT); - set_output_visible(node, passflag, RRES_OUT_DIFF_INDIRECT, SCE_PASS_DIFFUSE_INDIRECT); - set_output_visible(node, passflag, RRES_OUT_DIFF_COLOR, SCE_PASS_DIFFUSE_COLOR); - set_output_visible(node, passflag, RRES_OUT_GLOSSY_DIRECT, SCE_PASS_GLOSSY_DIRECT); - set_output_visible(node, passflag, RRES_OUT_GLOSSY_INDIRECT, SCE_PASS_GLOSSY_INDIRECT); - set_output_visible(node, passflag, RRES_OUT_GLOSSY_COLOR, SCE_PASS_GLOSSY_COLOR); - set_output_visible(node, passflag, RRES_OUT_TRANSM_DIRECT, SCE_PASS_TRANSM_DIRECT); - set_output_visible(node, passflag, RRES_OUT_TRANSM_INDIRECT, SCE_PASS_TRANSM_INDIRECT); - set_output_visible(node, passflag, RRES_OUT_TRANSM_COLOR, SCE_PASS_TRANSM_COLOR); -} - /* based on rules, force sockets hidden always */ -void ntreeCompositForceHidden(bNodeTree *ntree, Scene *curscene) +void ntreeCompositForceHidden(bNodeTree *ntree) { bNode *node; if (ntree == NULL) return; for (node = ntree->nodes.first; node; node = node->next) { - if (node->type == CMP_NODE_R_LAYERS) { - Scene *sce = node->id ? (Scene *)node->id : curscene; - SceneRenderLayer *srl = BLI_findlink(&sce->r.layers, node->custom1); - if (srl) - force_hidden_passes(node, srl->passflag); - } + if (node->type == CMP_NODE_R_LAYERS) + node_cmp_rlayers_force_hidden_passes(node); + /* XXX this stuff is called all the time, don't want that. * Updates should only happen when actually necessary. */ diff --git a/source/blender/nodes/composite/nodes/node_composite_composite.c b/source/blender/nodes/composite/nodes/node_composite_composite.c index be9ed457150..c6c6a612bc4 100644 --- a/source/blender/nodes/composite/nodes/node_composite_composite.c +++ b/source/blender/nodes/composite/nodes/node_composite_composite.c @@ -31,6 +31,10 @@ #include "node_composite_util.h" +#include "BKE_context.h" + +#include "RNA_access.h" + /* **************** COMPOSITE ******************** */ static bNodeSocketTemplate cmp_node_composite_in[] = { { SOCK_RGBA, 1, N_("Image"), 0.0f, 0.0f, 0.0f, 1.0f}, @@ -39,12 +43,21 @@ static bNodeSocketTemplate cmp_node_composite_in[] = { { -1, 0, "" } }; +static void init(const bContext *C, PointerRNA *ptr) +{ + Scene *scene = CTX_data_scene(C); + bNode *node = ptr->data; + + node->id = &scene->id; +} + void register_node_type_cmp_composite(void) { static bNodeType ntype; cmp_node_type_base(&ntype, CMP_NODE_COMPOSITE, "Composite", NODE_CLASS_OUTPUT, NODE_PREVIEW); node_type_socket_templates(&ntype, cmp_node_composite_in, NULL); + ntype.initfunc_api = init; /* Do not allow muting for this node. */ node_type_internal_links(&ntype, NULL); diff --git a/source/blender/nodes/composite/nodes/node_composite_defocus.c b/source/blender/nodes/composite/nodes/node_composite_defocus.c index a3311755717..c057ba904ba 100644 --- a/source/blender/nodes/composite/nodes/node_composite_defocus.c +++ b/source/blender/nodes/composite/nodes/node_composite_defocus.c @@ -33,6 +33,10 @@ #include +#include "BKE_context.h" + +#include "RNA_access.h" + /* ************ qdn: Defocus node ****************** */ static bNodeSocketTemplate cmp_node_defocus_in[] = { { SOCK_RGBA, 1, N_("Image"), 1.0f, 1.0f, 1.0f, 1.0f}, @@ -44,8 +48,10 @@ static bNodeSocketTemplate cmp_node_defocus_out[] = { { -1, 0, "" } }; -static void node_composit_init_defocus(bNodeTree *UNUSED(ntree), bNode *node) +static void node_composit_init_defocus(const bContext *C, PointerRNA *ptr) { + Scene *scene = CTX_data_scene(C); + bNode *node = ptr->data; /* qdn: defocus node */ NodeDefocus *nbd = MEM_callocN(sizeof(NodeDefocus), "node defocus data"); nbd->bktype = 0; @@ -59,6 +65,8 @@ static void node_composit_init_defocus(bNodeTree *UNUSED(ntree), bNode *node) nbd->scale = 1.f; nbd->no_zbuf = 1; node->storage = nbd; + + node->id = &scene->id; } void register_node_type_cmp_defocus(void) @@ -67,7 +75,7 @@ void register_node_type_cmp_defocus(void) cmp_node_type_base(&ntype, CMP_NODE_DEFOCUS, "Defocus", NODE_CLASS_OP_FILTER, 0); node_type_socket_templates(&ntype, cmp_node_defocus_in, cmp_node_defocus_out); - node_type_init(&ntype, node_composit_init_defocus); + ntype.initfunc_api = node_composit_init_defocus; node_type_storage(&ntype, "NodeDefocus", node_free_standard_storage, node_copy_standard_storage); nodeRegisterType(&ntype); diff --git a/source/blender/nodes/composite/nodes/node_composite_image.c b/source/blender/nodes/composite/nodes/node_composite_image.c index b02bf6f438a..41f1f81e048 100644 --- a/source/blender/nodes/composite/nodes/node_composite_image.c +++ b/source/blender/nodes/composite/nodes/node_composite_image.c @@ -31,9 +31,16 @@ #include "node_composite_util.h" +#include "BLI_utildefines.h" + +#include "DNA_scene_types.h" + +#include "BKE_context.h" #include "BKE_global.h" #include "BKE_main.h" +#include "RNA_access.h" + /* **************** IMAGE (and RenderResult, multilayer image) ******************** */ static bNodeSocketTemplate cmp_node_rlayers_out[] = { @@ -347,6 +354,77 @@ void register_node_type_cmp_image(void) /* **************** RENDER RESULT ******************** */ +static void set_output_visible(bNode *node, int passflag, int index, int pass) +{ + bNodeSocket *sock = BLI_findlink(&node->outputs, index); + /* clear the SOCK_HIDDEN flag as well, in case a socket was hidden before */ + if (passflag & pass) + sock->flag &= ~(SOCK_HIDDEN | SOCK_UNAVAIL); + else + sock->flag |= SOCK_UNAVAIL; +} + +/* clumsy checking... should do dynamic outputs once */ +void node_cmp_rlayers_force_hidden_passes(bNode *node) +{ + Scene *scene = (Scene *)node->id; + SceneRenderLayer *srl; + int passflag; + bNodeSocket *sock; + + /* must always have valid scene pointer */ + BLI_assert(scene != NULL); + + srl = BLI_findlink(&scene->r.layers, node->custom1); + if (!srl) + return; + + passflag = srl->passflag; + + for (sock = node->outputs.first; sock; sock = sock->next) + sock->flag &= ~SOCK_UNAVAIL; + + set_output_visible(node, passflag, RRES_OUT_IMAGE, SCE_PASS_COMBINED); + set_output_visible(node, passflag, RRES_OUT_ALPHA, SCE_PASS_COMBINED); + + set_output_visible(node, passflag, RRES_OUT_Z, SCE_PASS_Z); + set_output_visible(node, passflag, RRES_OUT_NORMAL, SCE_PASS_NORMAL); + set_output_visible(node, passflag, RRES_OUT_VEC, SCE_PASS_VECTOR); + set_output_visible(node, passflag, RRES_OUT_UV, SCE_PASS_UV); + set_output_visible(node, passflag, RRES_OUT_RGBA, SCE_PASS_RGBA); + set_output_visible(node, passflag, RRES_OUT_DIFF, SCE_PASS_DIFFUSE); + set_output_visible(node, passflag, RRES_OUT_SPEC, SCE_PASS_SPEC); + set_output_visible(node, passflag, RRES_OUT_SHADOW, SCE_PASS_SHADOW); + set_output_visible(node, passflag, RRES_OUT_AO, SCE_PASS_AO); + set_output_visible(node, passflag, RRES_OUT_REFLECT, SCE_PASS_REFLECT); + set_output_visible(node, passflag, RRES_OUT_REFRACT, SCE_PASS_REFRACT); + set_output_visible(node, passflag, RRES_OUT_INDIRECT, SCE_PASS_INDIRECT); + set_output_visible(node, passflag, RRES_OUT_INDEXOB, SCE_PASS_INDEXOB); + set_output_visible(node, passflag, RRES_OUT_INDEXMA, SCE_PASS_INDEXMA); + set_output_visible(node, passflag, RRES_OUT_MIST, SCE_PASS_MIST); + set_output_visible(node, passflag, RRES_OUT_EMIT, SCE_PASS_EMIT); + set_output_visible(node, passflag, RRES_OUT_ENV, SCE_PASS_ENVIRONMENT); + set_output_visible(node, passflag, RRES_OUT_DIFF_DIRECT, SCE_PASS_DIFFUSE_DIRECT); + set_output_visible(node, passflag, RRES_OUT_DIFF_INDIRECT, SCE_PASS_DIFFUSE_INDIRECT); + set_output_visible(node, passflag, RRES_OUT_DIFF_COLOR, SCE_PASS_DIFFUSE_COLOR); + set_output_visible(node, passflag, RRES_OUT_GLOSSY_DIRECT, SCE_PASS_GLOSSY_DIRECT); + set_output_visible(node, passflag, RRES_OUT_GLOSSY_INDIRECT, SCE_PASS_GLOSSY_INDIRECT); + set_output_visible(node, passflag, RRES_OUT_GLOSSY_COLOR, SCE_PASS_GLOSSY_COLOR); + set_output_visible(node, passflag, RRES_OUT_TRANSM_DIRECT, SCE_PASS_TRANSM_DIRECT); + set_output_visible(node, passflag, RRES_OUT_TRANSM_INDIRECT, SCE_PASS_TRANSM_INDIRECT); + set_output_visible(node, passflag, RRES_OUT_TRANSM_COLOR, SCE_PASS_TRANSM_COLOR); +} + +static void node_composit_init_rlayers(const bContext *C, PointerRNA *ptr) +{ + Scene *scene = CTX_data_scene(C); + bNode *node = ptr->data; + + node->id = &scene->id; + + node_cmp_rlayers_force_hidden_passes(node); +} + static int node_composit_poll_rlayers(bNodeType *UNUSED(ntype), bNodeTree *ntree) { if (strcmp(ntree->idname, "CompositorNodeTree") == 0) { @@ -371,6 +449,7 @@ void register_node_type_cmp_rlayers(void) cmp_node_type_base(&ntype, CMP_NODE_R_LAYERS, "Render Layers", NODE_CLASS_INPUT, NODE_PREVIEW); node_type_socket_templates(&ntype, NULL, cmp_node_rlayers_out); + ntype.initfunc_api = node_composit_init_rlayers; ntype.poll = node_composit_poll_rlayers; nodeRegisterType(&ntype); diff --git a/source/blender/nodes/composite/nodes/node_composite_movieclip.c b/source/blender/nodes/composite/nodes/node_composite_movieclip.c index b42b8d36c0c..fc0d8060644 100644 --- a/source/blender/nodes/composite/nodes/node_composite_movieclip.c +++ b/source/blender/nodes/composite/nodes/node_composite_movieclip.c @@ -33,6 +33,10 @@ #include "node_composite_util.h" +#include "BKE_context.h" + +#include "RNA_access.h" + static bNodeSocketTemplate cmp_node_movieclip_out[] = { { SOCK_RGBA, 0, N_("Image")}, { SOCK_FLOAT, 0, N_("Alpha")}, @@ -43,10 +47,13 @@ static bNodeSocketTemplate cmp_node_movieclip_out[] = { { -1, 0, "" } }; -static void init(bNodeTree *UNUSED(ntree), bNode *node) +static void init(const bContext *C, PointerRNA *ptr) { + bNode *node = ptr->data; + Scene *scene = CTX_data_scene(C); MovieClipUser *user = MEM_callocN(sizeof(MovieClipUser), "node movie clip user"); + node->id = (ID *)scene->clip; node->storage = user; user->framenr = 1; } @@ -57,7 +64,7 @@ void register_node_type_cmp_movieclip(void) cmp_node_type_base(&ntype, CMP_NODE_MOVIECLIP, "Movie Clip", NODE_CLASS_INPUT, NODE_PREVIEW); node_type_socket_templates(&ntype, NULL, cmp_node_movieclip_out); - node_type_init(&ntype, init); + ntype.initfunc_api = init; node_type_storage(&ntype, "MovieClipUser", node_free_standard_storage, node_copy_standard_storage); nodeRegisterType(&ntype); diff --git a/source/blender/nodes/composite/nodes/node_composite_moviedistortion.c b/source/blender/nodes/composite/nodes/node_composite_moviedistortion.c index 103a05f900e..b110cffd080 100644 --- a/source/blender/nodes/composite/nodes/node_composite_moviedistortion.c +++ b/source/blender/nodes/composite/nodes/node_composite_moviedistortion.c @@ -32,6 +32,10 @@ #include "node_composite_util.h" +#include "BKE_context.h" + +#include "RNA_access.h" + /* **************** Translate ******************** */ static bNodeSocketTemplate cmp_node_moviedistortion_in[] = { @@ -52,6 +56,14 @@ static const char *label(bNode *node) return IFACE_("Distortion"); } +static void init(const bContext *C, PointerRNA *ptr) +{ + bNode *node = ptr->data; + Scene *scene = CTX_data_scene(C); + + node->id = (ID *)scene->clip; +} + static void storage_free(bNode *node) { if (node->storage) @@ -74,6 +86,7 @@ void register_node_type_cmp_moviedistortion(void) node_type_socket_templates(&ntype, cmp_node_moviedistortion_in, cmp_node_moviedistortion_out); node_type_label(&ntype, label); + ntype.initfunc_api = init; node_type_storage(&ntype, NULL, storage_free, storage_copy); nodeRegisterType(&ntype); diff --git a/source/blender/nodes/composite/nodes/node_composite_outputFile.c b/source/blender/nodes/composite/nodes/node_composite_outputFile.c index a6c59c1bc91..90b21f1bab0 100644 --- a/source/blender/nodes/composite/nodes/node_composite_outputFile.c +++ b/source/blender/nodes/composite/nodes/node_composite_outputFile.c @@ -179,6 +179,8 @@ static void init_output_file(const bContext *C, PointerRNA *ptr) ImageFormatData *format = NULL; node->storage = nimf; + node->id = &scene->id; + if (scene) { RenderData *rd = &scene->r; diff --git a/source/blender/nodes/composite/nodes/node_composite_splitViewer.c b/source/blender/nodes/composite/nodes/node_composite_splitViewer.c index 6d1cd56fa4a..c3eb44281f5 100644 --- a/source/blender/nodes/composite/nodes/node_composite_splitViewer.c +++ b/source/blender/nodes/composite/nodes/node_composite_splitViewer.c @@ -32,6 +32,8 @@ #include "node_composite_util.h" +#include "BKE_image.h" + /* **************** SPLIT VIEWER ******************** */ static bNodeSocketTemplate cmp_node_splitviewer_in[] = { { SOCK_RGBA, 1, N_("Image"), 0.0f, 0.0f, 0.0f, 1.0f}, @@ -47,6 +49,8 @@ static void node_composit_init_splitviewer(bNodeTree *UNUSED(ntree), bNode *node iuser->fie_ima = 2; iuser->ok = 1; node->custom1 = 50; /* default 50% split */ + + node->id = (ID *)BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node"); } void register_node_type_cmp_splitviewer(void) diff --git a/source/blender/nodes/composite/nodes/node_composite_stabilize2d.c b/source/blender/nodes/composite/nodes/node_composite_stabilize2d.c index 2daf240ab18..28e2a2a205b 100644 --- a/source/blender/nodes/composite/nodes/node_composite_stabilize2d.c +++ b/source/blender/nodes/composite/nodes/node_composite_stabilize2d.c @@ -33,6 +33,10 @@ #include "node_composite_util.h" +#include "BKE_context.h" + +#include "RNA_access.h" + /* **************** Translate ******************** */ static bNodeSocketTemplate cmp_node_stabilize2d_in[] = { @@ -45,8 +49,13 @@ static bNodeSocketTemplate cmp_node_stabilize2d_out[] = { { -1, 0, "" } }; -static void init(bNodeTree *UNUSED(ntree), bNode *node) +static void init(const bContext *C, PointerRNA *ptr) { + bNode *node = ptr->data; + Scene *scene = CTX_data_scene(C); + + node->id = (ID *)scene->clip; + /* default to bilinear, see node_sampler_type_items in rna_nodetree.c */ node->custom1 = 1; } @@ -57,7 +66,7 @@ void register_node_type_cmp_stabilize2d(void) cmp_node_type_base(&ntype, CMP_NODE_STABILIZE2D, "Stabilize 2D", NODE_CLASS_DISTORT, 0); node_type_socket_templates(&ntype, cmp_node_stabilize2d_in, cmp_node_stabilize2d_out); - node_type_init(&ntype, init); + ntype.initfunc_api = init; nodeRegisterType(&ntype); } diff --git a/source/blender/nodes/composite/nodes/node_composite_viewer.c b/source/blender/nodes/composite/nodes/node_composite_viewer.c index 54d3f372c50..4b96270d36c 100644 --- a/source/blender/nodes/composite/nodes/node_composite_viewer.c +++ b/source/blender/nodes/composite/nodes/node_composite_viewer.c @@ -32,6 +32,8 @@ #include "node_composite_util.h" +#include "BKE_image.h" + /* **************** VIEWER ******************** */ static bNodeSocketTemplate cmp_node_viewer_in[] = { @@ -50,6 +52,8 @@ static void node_composit_init_viewer(bNodeTree *UNUSED(ntree), bNode *node) iuser->ok = 1; node->custom3 = 0.5f; node->custom4 = 0.5f; + + node->id = (ID *)BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node"); } void register_node_type_cmp_viewer(void) From 2aab2d97de00e39c1c623e544df2c285131e6e2d Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Wed, 12 Jun 2013 12:32:07 +0000 Subject: [PATCH 28/37] Bugfix [#35668] Tooltip for Euler Discontinuity Filter was misleading The tooltip seemed to hint that this tool is able to resolve all manner of gimble-lock situations by untangling the curves (i.e. performing some kind of equivalent-angles resolution, keeping in mind the nearest situations nearby). However, this tool currently only performs corrections for the most basic case when large jump+flip discontinuity artifacts appear in euler rotation curves as a result of rotation values getting clipped to +/- 180 degrees, which arises when these rotation curves are the result of baking some physics sim or so. (Also, fixed an unrelated "replace-all" typo in a comment) --- source/blender/blenkernel/intern/nla.c | 2 +- source/blender/editors/space_graph/graph_edit.c | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/source/blender/blenkernel/intern/nla.c b/source/blender/blenkernel/intern/nla.c index 7b5b6a28421..1fbc2432595 100644 --- a/source/blender/blenkernel/intern/nla.c +++ b/source/blender/blenkernel/intern/nla.c @@ -503,7 +503,7 @@ float nlastrip_get_frame(NlaStrip *strip, float cframe, short mode) /* Non clipped mapping for strip-time <-> global time - * mode = eNlaTime_ConvertModesp[] -> NLATIME_CONVERT_* + * mode = eNlaTime_ConvertModes -> NLATIME_CONVERT_* * * Public API method - perform this mapping using the given AnimData block * and perform any necessary sanity checks on the value diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c index a51fef6c692..9d22d6fcc95 100644 --- a/source/blender/editors/space_graph/graph_edit.c +++ b/source/blender/editors/space_graph/graph_edit.c @@ -1745,7 +1745,9 @@ void GRAPH_OT_euler_filter(wmOperatorType *ot) /* identifiers */ ot->name = "Euler Discontinuity Filter"; ot->idname = "GRAPH_OT_euler_filter"; - ot->description = "Fixes the most common causes of gimbal lock in the selected Euler Rotation F-Curves"; + ot->description = "Fix large jumps and flips in the selected " + "Euler Rotation F-Curves arising from rotation " + "values being clipped when baking physics"; /* api callbacks */ ot->exec = graphkeys_euler_filter_exec; From 22d2faccefb3b44f5f4b6372e4d114c44f27e194 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 12 Jun 2013 12:34:10 +0000 Subject: [PATCH 29/37] Cleaned code a bit around 2D stabilization Hopefully it's more readable now. Took me a while to remmeber all the stuff going on here while was looking into possibility of implementing some feature here. --- source/blender/blenkernel/BKE_tracking.h | 6 +- source/blender/blenkernel/intern/tracking.c | 98 +++++++++++-------- source/blender/editors/space_clip/clip_draw.c | 9 +- 3 files changed, 63 insertions(+), 50 deletions(-) diff --git a/source/blender/blenkernel/BKE_tracking.h b/source/blender/blenkernel/BKE_tracking.h index d8c761cd1b4..84bca0bd3ba 100644 --- a/source/blender/blenkernel/BKE_tracking.h +++ b/source/blender/blenkernel/BKE_tracking.h @@ -204,10 +204,10 @@ void BKE_tracking_detect_fast(struct MovieTracking *tracking, struct ListBase *t /* **** 2D stabilization **** */ void BKE_tracking_stabilization_data_get(struct MovieTracking *tracking, int framenr, int width, int height, - float loc[2], float *scale, float *angle); + float translation[2], float *scale, float *angle); struct ImBuf *BKE_tracking_stabilize_frame(struct MovieTracking *tracking, int framenr, struct ImBuf *ibuf, - float loc[2], float *scale, float *angle); -void BKE_tracking_stabilization_data_to_mat4(int width, int height, float aspect, float loc[2], + float translation[2], float *scale, float *angle); +void BKE_tracking_stabilization_data_to_mat4(int width, int height, float aspect, float translation[2], float scale, float angle, float mat[4][4]); /* Dopesheet */ diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index d556c75259b..9ae3c5cdfe1 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -3602,18 +3602,18 @@ static bool stabilization_median_point_get(MovieTracking *tracking, int framenr, * NOTE: frame number should be in clip space, not scene space */ static void stabilization_calculate_data(MovieTracking *tracking, int framenr, float width, float height, - float firstmedian[2], float median[2], float loc[2], - float *scale, float *angle) + float firstmedian[2], float median[2], + float translation[2], float *scale, float *angle) { MovieTrackingStabilization *stab = &tracking->stabilization; *scale = (stab->scale - 1.0f) * stab->scaleinf + 1.0f; *angle = 0.0f; - loc[0] = (firstmedian[0] - median[0]) * width * (*scale); - loc[1] = (firstmedian[1] - median[1]) * height * (*scale); + translation[0] = (firstmedian[0] - median[0]) * width * (*scale); + translation[1] = (firstmedian[1] - median[1]) * height * (*scale); - mul_v2_fl(loc, stab->locinf); + mul_v2_fl(translation, stab->locinf); if ((stab->flag & TRACKING_STABILIZE_ROTATION) && stab->rot_track && stab->rotinf) { MovieTrackingMarker *marker; @@ -3635,8 +3635,8 @@ static void stabilization_calculate_data(MovieTracking *tracking, int framenr, f *angle *= stab->rotinf; /* convert to rotation around image center */ - loc[0] -= (x0 + (x - x0) * cosf(*angle) - (y - y0) * sinf(*angle) - x) * (*scale); - loc[1] -= (y0 + (x - x0) * sinf(*angle) + (y - y0) * cosf(*angle) - y) * (*scale); + translation[0] -= (x0 + (x - x0) * cosf(*angle) - (y - y0) * sinf(*angle) - x) * (*scale); + translation[1] -= (y0 + (x - x0) * sinf(*angle) + (y - y0) * cosf(*angle) - y) * (*scale); } } @@ -3679,7 +3679,7 @@ static float stabilization_calculate_autoscale_factor(MovieTracking *tracking, i */ for (cfra = sfra; cfra <= efra; cfra++) { float median[2]; - float loc[2], angle, tmp_scale; + float translation[2], angle, tmp_scale; int i; float mat[4][4]; float points[4][2] = {{0.0f, 0.0f}, {0.0f, height}, {width, height}, {width, 0.0f}}; @@ -3687,9 +3687,9 @@ static float stabilization_calculate_autoscale_factor(MovieTracking *tracking, i stabilization_median_point_get(tracking, cfra, median); - stabilization_calculate_data(tracking, cfra, width, height, firstmedian, median, loc, &tmp_scale, &angle); + stabilization_calculate_data(tracking, cfra, width, height, firstmedian, median, translation, &tmp_scale, &angle); - BKE_tracking_stabilization_data_to_mat4(width, height, aspect, loc, 1.0f, angle, mat); + BKE_tracking_stabilization_data_to_mat4(width, height, aspect, translation, 1.0f, angle, mat); si = sin(angle); co = cos(angle); @@ -3715,8 +3715,8 @@ static float stabilization_calculate_autoscale_factor(MovieTracking *tracking, i const float rotDx[4][2] = {{1.0f, 0.0f}, {0.0f, -1.0f}, {-1.0f, 0.0f}, {0.0f, 1.0f}}; const float rotDy[4][2] = {{0.0f, 1.0f}, {1.0f, 0.0f}, {0.0f, -1.0f}, {-1.0f, 0.0f}}; - float dx = loc[0] * rotDx[j][0] + loc[1] * rotDx[j][1], - dy = loc[0] * rotDy[j][0] + loc[1] * rotDy[j][1]; + float dx = translation[0] * rotDx[j][0] + translation[1] * rotDx[j][1], + dy = translation[0] * rotDy[j][0] + translation[1] * rotDy[j][1]; float w, h, E, F, G, H, I, J, K, S; @@ -3772,14 +3772,14 @@ static float stabilization_calculate_autoscale_factor(MovieTracking *tracking, i * NOTE: frame number should be in clip space, not scene space */ void BKE_tracking_stabilization_data_get(MovieTracking *tracking, int framenr, int width, int height, - float loc[2], float *scale, float *angle) + float translation[2], float *scale, float *angle) { float firstmedian[2], median[2]; MovieTrackingStabilization *stab = &tracking->stabilization; /* Early output if stabilization is disabled. */ if ((stab->flag & TRACKING_2D_STABILIZATION) == 0) { - zero_v2(loc); + zero_v2(translation); *scale = 1.0f; *angle = 0.0f; @@ -3803,16 +3803,18 @@ void BKE_tracking_stabilization_data_get(MovieTracking *tracking, int framenr, i if (stab->flag & TRACKING_AUTOSCALE) stabilization_calculate_autoscale_factor(tracking, width, height); - stabilization_calculate_data(tracking, framenr, width, height, firstmedian, median, loc, scale, angle); + stabilization_calculate_data(tracking, framenr, width, height, firstmedian, median, + translation, scale, angle); stab->ok = TRUE; } else { - stabilization_calculate_data(tracking, framenr, width, height, firstmedian, median, loc, scale, angle); + stabilization_calculate_data(tracking, framenr, width, height, firstmedian, median, + translation, scale, angle); } } else { - zero_v2(loc); + zero_v2(translation); *scale = 1.0f; *angle = 0.0f; } @@ -3824,7 +3826,7 @@ void BKE_tracking_stabilization_data_get(MovieTracking *tracking, int framenr, i * NOTE: frame number should be in clip space, not scene space */ ImBuf *BKE_tracking_stabilize_frame(MovieTracking *tracking, int framenr, ImBuf *ibuf, - float loc[2], float *scale, float *angle) + float translation[2], float *scale, float *angle) { float tloc[2], tscale, tangle; MovieTrackingStabilization *stab = &tracking->stabilization; @@ -3836,16 +3838,16 @@ ImBuf *BKE_tracking_stabilize_frame(MovieTracking *tracking, int framenr, ImBuf void (*interpolation)(struct ImBuf *, struct ImBuf *, float, float, int, int) = NULL; int ibuf_flags; - if (loc) - copy_v2_v2(tloc, loc); + if (translation) + copy_v2_v2(tloc, translation); if (scale) tscale = *scale; /* Perform early output if no stabilization is used. */ if ((stab->flag & TRACKING_2D_STABILIZATION) == 0) { - if (loc) - zero_v2(loc); + if (translation) + zero_v2(translation); if (scale) *scale = 1.0f; @@ -3902,8 +3904,8 @@ ImBuf *BKE_tracking_stabilize_frame(MovieTracking *tracking, int framenr, ImBuf if (tmpibuf->rect_float) tmpibuf->userflags |= IB_RECT_INVALID; - if (loc) - copy_v2_v2(loc, tloc); + if (translation) + copy_v2_v2(translation, tloc); if (scale) *scale = tscale; @@ -3921,33 +3923,43 @@ ImBuf *BKE_tracking_stabilize_frame(MovieTracking *tracking, int framenr, ImBuf * NOTE: The reaosn it is 4x4 matrix is because it's * used for OpenGL drawing directly. */ -void BKE_tracking_stabilization_data_to_mat4(int width, int height, float aspect, float loc[2], - float scale, float angle, float mat[4][4]) +void BKE_tracking_stabilization_data_to_mat4(int width, int height, float aspect, + float translation[2], float scale, float angle, + float mat[4][4]) { - float lmat[4][4], rmat[4][4], smat[4][4], cmat[4][4], icmat[4][4], amat[4][4], iamat[4][4]; - float svec[3] = {scale, scale, scale}; + float translation_mat[4][4], rotation_mat[4][4], scale_mat[4][4], + center_mat[4][4], inv_center_mat[4][4], + aspect_mat[4][4], inv_aspect_mat[4][4]; + float scale_vector[3] = {scale, scale, scale}; - unit_m4(rmat); - unit_m4(lmat); - unit_m4(smat); - unit_m4(cmat); - unit_m4(amat); + unit_m4(translation_mat); + unit_m4(rotation_mat); + unit_m4(scale_mat); + unit_m4(center_mat); + unit_m4(aspect_mat); /* aspect ratio correction matrix */ - amat[0][0] = 1.0f / aspect; - invert_m4_m4(iamat, amat); + aspect_mat[0][0] = 1.0f / aspect; + invert_m4_m4(inv_aspect_mat, aspect_mat); - /* image center as rotation center */ - cmat[3][0] = (float)width / 2.0f; - cmat[3][1] = (float)height / 2.0f; - invert_m4_m4(icmat, cmat); + /* image center as rotation center + * + * Rotation matrix is constructing in a way rotaion happens around image center, + * and it's matter of calculating trasnlation in a way, that applying translation + * after rotation would make it so rotation happens around median point of tracks + * used for translation stabilization. + */ + center_mat[3][0] = (float)width / 2.0f; + center_mat[3][1] = (float)height / 2.0f; + invert_m4_m4(inv_center_mat, center_mat); - size_to_mat4(smat, svec); /* scale matrix */ - add_v2_v2(lmat[3], loc); /* translation matrix */ - rotate_m4(rmat, 'Z', angle); /* rotation matrix */ + size_to_mat4(scale_mat, scale_vector); /* scale matrix */ + add_v2_v2(translation_mat[3], translation); /* translation matrix */ + rotate_m4(rotation_mat, 'Z', angle); /* rotation matrix */ /* compose transformation matrix */ - mul_serie_m4(mat, lmat, cmat, amat, rmat, iamat, smat, icmat, NULL); + mul_serie_m4(mat, translation_mat, center_mat, aspect_mat, rotation_mat, inv_aspect_mat, + scale_mat, inv_center_mat, NULL); } /*********************** Dopesheet functions *************************/ diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c index 8fd2c4420f7..d1fd5093974 100644 --- a/source/blender/editors/space_clip/clip_draw.c +++ b/source/blender/editors/space_clip/clip_draw.c @@ -1428,15 +1428,16 @@ void clip_draw_main(const bContext *C, SpaceClip *sc, ARegion *ar) ibuf = ED_space_clip_get_stable_buffer(sc, sc->loc, &sc->scale, &sc->angle); if (ibuf) { - float loc[2]; + float translation[2]; float aspect = clip->tracking.camera.pixel_aspect; if (width != ibuf->x) - mul_v2_v2fl(loc, sc->loc, (float)width / ibuf->x); + mul_v2_v2fl(translation, sc->loc, (float)width / ibuf->x); else - copy_v2_v2(loc, sc->loc); + copy_v2_v2(translation, sc->loc); - BKE_tracking_stabilization_data_to_mat4(width, height, aspect, loc, sc->scale, sc->angle, sc->stabmat); + BKE_tracking_stabilization_data_to_mat4(width, height, aspect, + translation, sc->scale, sc->angle, sc->stabmat); unit_m4(smat); smat[0][0] = 1.0f / width; From ba3a1067fa831d8fa7812049a1c3ee08a6b27bd9 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 12 Jun 2013 12:55:44 +0000 Subject: [PATCH 30/37] Remove magic constants from Track Position node RNA code. --- source/blender/blenkernel/BKE_node.h | 4 ++++ .../compositor/operations/COM_TrackPositionOperation.cpp | 7 ++++--- .../compositor/operations/COM_TrackPositionOperation.h | 6 ------ source/blender/makesrna/intern/rna_nodetree.c | 9 ++++++--- 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index ec0dd11392d..587acb8f0d7 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -917,6 +917,10 @@ void ntreeGPUMaterialNodes(struct bNodeTree *ntree, struct GPUMateria #define CMP_SCALE_RENDERSIZE_FRAME_ASPECT (1 << 0) #define CMP_SCALE_RENDERSIZE_FRAME_CROP (1 << 1) +/* track position node, in custom1 */ +#define CMP_TRACKPOS_ABSOLUTE 0 +#define CMP_TRACKPOS_RELATIVE_START 1 +#define CMP_TRACKPOS_RELATIVE_FRAME 2 /* API */ struct CompBuf; diff --git a/source/blender/compositor/operations/COM_TrackPositionOperation.cpp b/source/blender/compositor/operations/COM_TrackPositionOperation.cpp index e647ae975ff..4f00358633a 100644 --- a/source/blender/compositor/operations/COM_TrackPositionOperation.cpp +++ b/source/blender/compositor/operations/COM_TrackPositionOperation.cpp @@ -31,6 +31,7 @@ extern "C" { #include "BKE_movieclip.h" + #include "BKE_node.h" #include "BKE_tracking.h" } @@ -42,7 +43,7 @@ TrackPositionOperation::TrackPositionOperation() : NodeOperation() this->m_trackingObjectName[0] = 0; this->m_trackName[0] = 0; this->m_axis = 0; - this->m_position = POSITION_ABSOLUTE; + this->m_position = CMP_TRACKPOS_ABSOLUTE; this->m_relativeFrame = 0; } @@ -77,7 +78,7 @@ void TrackPositionOperation::initExecution() copy_v2_v2(this->m_markerPos, marker->pos); - if (this->m_position == POSITION_RELATIVE_START) { + if (this->m_position == CMP_TRACKPOS_RELATIVE_START) { int i; for (i = 0; i < track->markersnr; i++) { @@ -90,7 +91,7 @@ void TrackPositionOperation::initExecution() } } } - else if (this->m_position == POSITION_RELATIVE_FRAME) { + else if (this->m_position == CMP_TRACKPOS_RELATIVE_FRAME) { int relative_clip_framenr = BKE_movieclip_remap_scene_to_clip_frame(this->m_movieClip, this->m_relativeFrame); diff --git a/source/blender/compositor/operations/COM_TrackPositionOperation.h b/source/blender/compositor/operations/COM_TrackPositionOperation.h index b934719a92b..3f05b907ea0 100644 --- a/source/blender/compositor/operations/COM_TrackPositionOperation.h +++ b/source/blender/compositor/operations/COM_TrackPositionOperation.h @@ -39,12 +39,6 @@ */ class TrackPositionOperation : public NodeOperation { protected: - enum { - POSITION_ABSOLUTE = 0, - POSITION_RELATIVE_START, - POSITION_RELATIVE_FRAME - }; - MovieClip *m_movieClip; int m_framenumber; char m_trackingObjectName[64]; diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 04051cf3418..5230390bf00 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -5714,9 +5714,12 @@ static void def_cmp_trackpos(StructRNA *srna) PropertyRNA *prop; static EnumPropertyItem position_items[] = { - {0, "ABSOLUTE", 0, "Absolute", "Output absolute position of a marker"}, - {1, "RELATIVE_START", 0, "Relative Start", "Output position of a marker relative to first marker of a track"}, - {2, "RELATIVE_FRAME", 0, "Relative Frame", "Output position of a marker relative to marker at given frame number"}, + {CMP_TRACKPOS_ABSOLUTE, "ABSOLUTE", 0, + "Absolute", "Output absolute position of a marker"}, + {CMP_TRACKPOS_RELATIVE_START, "RELATIVE_START", 0, + "Relative Start", "Output position of a marker relative to first marker of a track"}, + {CMP_TRACKPOS_RELATIVE_FRAME, "RELATIVE_FRAME", 0, + "Relative Frame", "Output position of a marker relative to marker at given frame number"}, {0, NULL, 0, NULL, NULL} }; From 9aa088bab68adb1488ae42c14813babbab594117 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 12 Jun 2013 14:28:36 +0000 Subject: [PATCH 31/37] Track Position node now could output absolute position of track at a given frame --- source/blender/blenkernel/BKE_node.h | 1 + .../compositor/nodes/COM_TrackPositionNode.cpp | 14 ++++++++++++-- source/blender/editors/space_node/drawnode.c | 2 +- source/blender/makesrna/intern/rna_nodetree.c | 2 ++ 4 files changed, 16 insertions(+), 3 deletions(-) diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index 587acb8f0d7..b43747ab33a 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -921,6 +921,7 @@ void ntreeGPUMaterialNodes(struct bNodeTree *ntree, struct GPUMateria #define CMP_TRACKPOS_ABSOLUTE 0 #define CMP_TRACKPOS_RELATIVE_START 1 #define CMP_TRACKPOS_RELATIVE_FRAME 2 +#define CMP_TRACKPOS_ABSOLUTE_FRAME 3 /* API */ struct CompBuf; diff --git a/source/blender/compositor/nodes/COM_TrackPositionNode.cpp b/source/blender/compositor/nodes/COM_TrackPositionNode.cpp index f4efcfe27f0..c5474e0ce70 100644 --- a/source/blender/compositor/nodes/COM_TrackPositionNode.cpp +++ b/source/blender/compositor/nodes/COM_TrackPositionNode.cpp @@ -27,6 +27,8 @@ extern "C" { #include "DNA_movieclip_types.h" + + #include "BKE_node.h" } TrackPositionNode::TrackPositionNode(bNode *editorNode) : Node(editorNode) @@ -44,13 +46,21 @@ void TrackPositionNode::convertToOperations(ExecutionSystem *graph, CompositorCo NodeTrackPosData *trackpos_data = (NodeTrackPosData *) editorNode->storage; + int frame_number; + if (editorNode->custom1 == CMP_TRACKPOS_ABSOLUTE_FRAME) { + frame_number = editorNode->custom2; + } + else { + frame_number = context->getFramenumber(); + } + TrackPositionOperation *operationX = new TrackPositionOperation(); TrackPositionOperation *operationY = new TrackPositionOperation(); operationX->setMovieClip(clip); operationX->setTrackingObject(trackpos_data->tracking_object); operationX->setTrackName(trackpos_data->track_name); - operationX->setFramenumber(context->getFramenumber()); + operationX->setFramenumber(frame_number); operationX->setAxis(0); operationX->setPosition(editorNode->custom1); operationX->setRelativeFrame(editorNode->custom2); @@ -58,7 +68,7 @@ void TrackPositionNode::convertToOperations(ExecutionSystem *graph, CompositorCo operationY->setMovieClip(clip); operationY->setTrackingObject(trackpos_data->tracking_object); operationY->setTrackName(trackpos_data->track_name); - operationY->setFramenumber(context->getFramenumber()); + operationY->setFramenumber(frame_number); operationY->setAxis(1); operationY->setPosition(editorNode->custom1); operationY->setRelativeFrame(editorNode->custom2); diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index e6b4f3cbefb..6ba736b75f3 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -2216,7 +2216,7 @@ static void node_composit_buts_trackpos(uiLayout *layout, bContext *C, PointerRN uiItemR(layout, ptr, "position", 0, NULL, ICON_NONE); - if (node->custom1 == 2) { + if (ELEM(node->custom1, CMP_TRACKPOS_RELATIVE_FRAME, CMP_TRACKPOS_ABSOLUTE_FRAME)) { uiItemR(layout, ptr, "frame_relative", 0, NULL, ICON_NONE); } } diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 5230390bf00..a2bb1aff3b9 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -5720,6 +5720,8 @@ static void def_cmp_trackpos(StructRNA *srna) "Relative Start", "Output position of a marker relative to first marker of a track"}, {CMP_TRACKPOS_RELATIVE_FRAME, "RELATIVE_FRAME", 0, "Relative Frame", "Output position of a marker relative to marker at given frame number"}, + {CMP_TRACKPOS_ABSOLUTE_FRAME, "ABSOLUTE_FRAME", 0, + "Absolute Frame", "Output absolute position of a marker at given frame number"}, {0, NULL, 0, NULL, NULL} }; From f4dc0fa6c9709168afaaafbb21e54b8e476a9717 Mon Sep 17 00:00:00 2001 From: Tamito Kajiyama Date: Wed, 12 Jun 2013 17:59:03 +0000 Subject: [PATCH 32/37] Fix #35353: Freestyle + Compositor + Auto-render renders freestyle lines in the wrong place. --- .../intern/blender_interface/BlenderStrokeRenderer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp index 096447de214..d665a0630ac 100644 --- a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp +++ b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp @@ -85,7 +85,7 @@ BlenderStrokeRenderer::BlenderStrokeRenderer(Render *re, int render_count) : Str //freestyle_scene->r.maximsize = old_scene->r.maximsize; /* DEPRECATED */ freestyle_scene->r.ocres = old_scene->r.ocres; freestyle_scene->r.color_mgt_flag = 0; // old_scene->r.color_mgt_flag; - freestyle_scene->r.scemode = old_scene->r.scemode & ~(R_SINGLE_LAYER); + freestyle_scene->r.scemode = old_scene->r.scemode & ~(R_SINGLE_LAYER | R_NO_FRAME_UPDATE); freestyle_scene->r.flag = old_scene->r.flag; freestyle_scene->r.threads = old_scene->r.threads; freestyle_scene->r.border.xmin = old_scene->r.border.xmin; From 69e7fb6091207e38bec4f51c11e6fcdbd71f736e Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 12 Jun 2013 20:47:46 +0000 Subject: [PATCH 33/37] Fix #35715: incorrect shortcut shown for some menus after recent code refactoring. --- source/blender/editors/interface/interface_layout.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index 89d481eac45..b6575f4eca0 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -1752,7 +1752,7 @@ void uiItemMenuEnumO(uiLayout *layout, bContext *C, const char *opname, const ch if (ot->prop && WM_key_event_operator_string(C, ot->idname, layout->root->opcontext, NULL, false, keybuf, sizeof(keybuf))) { - namestr += BLI_snprintf(namestr, sizeof(namestr_buf) - (namestr - namestr_buf), "|%s", name); + namestr += BLI_snprintf(namestr, sizeof(namestr_buf) - (namestr - namestr_buf), "|%s", keybuf); } } From a5f60e933755357bb54f821c5011ebc108de772c Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 12 Jun 2013 20:47:48 +0000 Subject: [PATCH 34/37] Fix #35723: cycles motion blur rendering issue after recent optimizations to skip some unneeded object syncing. --- intern/cycles/blender/blender_session.cpp | 8 ++++++-- intern/cycles/blender/blender_sync.h | 4 ++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp index c981e379333..ecdc631e39a 100644 --- a/intern/cycles/blender/blender_session.cpp +++ b/intern/cycles/blender/blender_session.cpp @@ -102,12 +102,16 @@ void BlenderSession::create_session() /* create sync */ sync = new BlenderSync(b_engine, b_data, b_scene, scene, !background, session->progress, session_params.device.type == DEVICE_CPU); - /* for final render we will do data sync per render layer */ if(b_v3d) { + /* full data sync */ sync->sync_data(b_v3d, b_engine.camera_override()); sync->sync_view(b_v3d, b_rv3d, width, height); } else { + /* for final render we will do full data sync per render layer, only + * do some basic syncing here, no objects or materials for speed */ + sync->sync_render_layers(b_v3d, NULL); + sync->sync_integrator(); sync->sync_camera(b_render, b_engine.camera_override(), width, height); } @@ -373,8 +377,8 @@ void BlenderSession::render() scene->integrator->tag_update(scene); /* update scene */ - sync->sync_data(b_v3d, b_engine.camera_override(), b_rlay_name.c_str()); sync->sync_camera(b_render, b_engine.camera_override(), width, height); + sync->sync_data(b_v3d, b_engine.camera_override(), b_rlay_name.c_str()); /* update number of samples per layer */ int samples = sync->get_layer_samples(); diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h index 5b63042a682..ed1f2b9d70f 100644 --- a/intern/cycles/blender/blender_sync.h +++ b/intern/cycles/blender/blender_sync.h @@ -56,6 +56,8 @@ public: /* sync */ bool sync_recalc(); void sync_data(BL::SpaceView3D b_v3d, BL::Object b_override, const char *layer = 0); + void sync_render_layers(BL::SpaceView3D b_v3d, const char *layer); + void sync_integrator(); void sync_camera(BL::RenderSettings b_render, BL::Object b_override, int width, int height); void sync_view(BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, int width, int height); int get_layer_samples() { return render_layer.samples; } @@ -74,10 +76,8 @@ private: void sync_objects(BL::SpaceView3D b_v3d, int motion = 0); void sync_motion(BL::SpaceView3D b_v3d, BL::Object b_override); void sync_film(); - void sync_integrator(); void sync_view(); void sync_world(bool update_all); - void sync_render_layers(BL::SpaceView3D b_v3d, const char *layer); void sync_shaders(); void sync_curve_settings(); From 532503e0cb4fb76b8ef67f3b93ec3bd29d199089 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 13 Jun 2013 00:33:48 +0000 Subject: [PATCH 35/37] fix for problem with creating weight-paint preview. In the case where the modifier stack didnt need deform-verts to calculate, they would not be available for the preview either. This fixes a bug caused by r57206 which set mirror to preview so the mirrored weights would be displayed, but it only worked when there was an armature after it, see [#35545]. --- source/blender/blenkernel/BKE_modifier.h | 5 +++-- source/blender/blenkernel/intern/DerivedMesh.c | 17 ++++++++++++----- source/blender/blenkernel/intern/modifier.c | 11 +++++++++-- 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h index e466964c73f..6b9392a4169 100644 --- a/source/blender/blenkernel/BKE_modifier.h +++ b/source/blender/blenkernel/BKE_modifier.h @@ -371,11 +371,12 @@ typedef struct CDMaskLink { * evaluation, assuming the data indicated by dataMask is required at the * end of the stack. */ -struct CDMaskLink *modifiers_calcDataMasks(struct Scene *scene, +struct CDMaskLink *modifiers_calcDataMasks(struct Scene *scene, struct Object *ob, struct ModifierData *md, CustomDataMask dataMask, - int required_mode); + int required_mode, + ModifierData *previewmd, CustomDataMask previewmask); struct ModifierData *modifiers_getLastPreview(struct Scene *scene, struct ModifierData *md, int required_mode); diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index fc226288f04..6a21f33ac15 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -1482,7 +1482,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_ORIGINDEX; + CustomDataMask mask, nextmask, previewmask = 0, append_mask = CD_MASK_ORIGINDEX; float (*deformedVerts)[3] = NULL; DerivedMesh *dm = NULL, *orcodm, *clothorcodm, *finaldm; int numVerts = me->totvert; @@ -1532,17 +1532,24 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos if (useRenderParams) required_mode = eModifierMode_Render; else required_mode = eModifierMode_Realtime; - datamasks = modifiers_calcDataMasks(scene, ob, md, dataMask, required_mode); - curr = datamasks; - if (do_mod_wmcol || do_mod_mcol) { /* Find the last active modifier generating a preview, or NULL if none. */ /* XXX Currently, DPaint modifier just ignores this. * Needs a stupid hack... * The whole "modifier preview" thing has to be (re?)designed, anyway! */ previewmd = modifiers_getLastPreview(scene, md, required_mode); + + /* even if the modifier doesn't need the data, to make a preview it may */ + if (previewmd) { + if (do_mod_wmcol) { + previewmask = CD_MASK_MDEFORMVERT; + } + } } + datamasks = modifiers_calcDataMasks(scene, ob, md, dataMask, required_mode, previewmd, previewmask); + curr = datamasks; + if (deform_r) *deform_r = NULL; *final_r = NULL; @@ -2028,7 +2035,7 @@ static void editbmesh_calc_modifiers(Scene *scene, Object *ob, BMEditMesh *em, D dm = NULL; md = modifiers_getVirtualModifierList(ob); - datamasks = modifiers_calcDataMasks(scene, ob, md, dataMask, required_mode); + datamasks = modifiers_calcDataMasks(scene, ob, md, dataMask, required_mode, NULL, 0); curr = datamasks; for (i = 0; md; i++, md = md->next, curr = curr->next) { diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 1ebe99eb660..c17830639e4 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -363,7 +363,9 @@ bool modifier_isEnabled(struct Scene *scene, ModifierData *md, int required_mode return 1; } -CDMaskLink *modifiers_calcDataMasks(struct Scene *scene, Object *ob, ModifierData *md, CustomDataMask dataMask, int required_mode) +CDMaskLink *modifiers_calcDataMasks(struct Scene *scene, Object *ob, ModifierData *md, + CustomDataMask dataMask, int required_mode, + ModifierData *previewmd, CustomDataMask previewmask) { CDMaskLink *dataMasks = NULL; CDMaskLink *curr, *prev; @@ -374,10 +376,15 @@ CDMaskLink *modifiers_calcDataMasks(struct Scene *scene, Object *ob, ModifierDat curr = MEM_callocN(sizeof(CDMaskLink), "CDMaskLink"); - if (modifier_isEnabled(scene, md, required_mode)) + if (modifier_isEnabled(scene, md, required_mode)) { if (mti->requiredDataMask) curr->mask = mti->requiredDataMask(ob, md); + if (previewmd == md) { + curr->mask |= previewmask; + } + } + /* prepend new datamask */ curr->next = dataMasks; dataMasks = curr; From 8eb6b954fd0a70d7b7e48c4f7b41b995702fe0d3 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 13 Jun 2013 01:13:26 +0000 Subject: [PATCH 36/37] internal change to searchbox: store the active search index rather then index + 1, simplifies checks. --- .../editors/interface/interface_regions.c | 72 +++++++++---------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index 8621a61a2d1..b764c70b111 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -835,25 +835,27 @@ static void ui_searchbox_select(bContext *C, ARegion *ar, uiBut *but, int step) /* apply step */ data->active += step; - if (data->items.totitem == 0) - data->active = 0; - else if (data->active > data->items.totitem) { + if (data->items.totitem == 0) { + data->active = -1; + } + else if (data->active >= data->items.totitem) { if (data->items.more) { data->items.offset++; - data->active = data->items.totitem; + data->active = data->items.totitem - 1; ui_searchbox_update(C, ar, but, false); } - else - data->active = data->items.totitem; + else { + data->active = data->items.totitem - 1; + } } - else if (data->active < 1) { + else if (data->active < 0) { if (data->items.offset) { data->items.offset--; - data->active = 1; + data->active = 0; ui_searchbox_update(C, ar, but, false); } - else if (data->active < 0) - data->active = 0; + else if (data->active < -1) + data->active = -1; } ED_region_tag_redraw(ar); @@ -913,15 +915,13 @@ bool ui_searchbox_apply(uiBut *but, ARegion *ar) but->func_arg2 = NULL; - if (data->active) { - char *name = data->items.names[data->active - 1]; - char *cpoin = strchr(name, '|'); + if (data->active != -1) { + const char *name = data->items.names[data->active]; + const char *name_sep = strchr(name, '|'); + + BLI_strncpy(but->editstr, name, name_sep ? (name_sep - name) : data->items.maxstrlen); - if (cpoin) cpoin[0] = 0; - BLI_strncpy(but->editstr, name, data->items.maxstrlen); - if (cpoin) cpoin[0] = '|'; - - but->func_arg2 = data->items.pointers[data->active - 1]; + but->func_arg2 = data->items.pointers[data->active]; return true; } @@ -955,8 +955,8 @@ void ui_searchbox_event(bContext *C, ARegion *ar, uiBut *but, const wmEvent *eve for (a = 0; a < data->items.totitem; a++) { ui_searchbox_butrect(&rect, data, a); if (BLI_rcti_isect_pt(&rect, event->x - ar->winrct.xmin, event->y - ar->winrct.ymin)) { - if (data->active != a + 1) { - data->active = a + 1; + if (data->active != a) { + data->active = a; ui_searchbox_select(C, ar, but, 0); break; } @@ -980,7 +980,7 @@ void ui_searchbox_update(bContext *C, ARegion *ar, uiBut *but, const bool reset) } else { data->items.offset_i = data->items.offset = 0; - data->active = 0; + data->active = -1; /* handle active */ if (but->search_func && but->func_arg2) { @@ -992,19 +992,19 @@ void ui_searchbox_update(bContext *C, ARegion *ar, uiBut *but, const bool reset) if (data->items.totitem) { /* first case, begin of list */ if (data->items.offset_i < data->items.maxitem) { - data->active = data->items.offset_i + 1; + data->active = data->items.offset_i; data->items.offset_i = 0; } else { /* second case, end of list */ if (data->items.totitem - data->items.offset_i <= data->items.maxitem) { - data->active = 1 + data->items.offset_i - data->items.totitem + data->items.maxitem; + data->active = data->items.offset_i - data->items.totitem + data->items.maxitem; data->items.offset_i = data->items.totitem - data->items.maxitem; } else { /* center active item */ data->items.offset_i -= data->items.maxitem / 2; - data->active = 1 + data->items.maxitem / 2; + data->active = data->items.maxitem / 2; } } } @@ -1018,19 +1018,19 @@ void ui_searchbox_update(bContext *C, ARegion *ar, uiBut *but, const bool reset) but->search_func(C, but->search_arg, but->editstr, &data->items); /* handle case where editstr is equal to one of items */ - if (reset && data->active == 0) { + if (reset && data->active == -1) { int a; for (a = 0; a < data->items.totitem; a++) { - char *cpoin = strchr(data->items.names[a], '|'); - - if (cpoin) cpoin[0] = 0; - if (0 == strcmp(but->editstr, data->items.names[a])) - data->active = a + 1; - if (cpoin) cpoin[0] = '|'; + const char *name = data->items.names[a]; + const char *name_sep = strchr(name, '|'); + if (STREQLEN(but->editstr, name, name_sep ? (name_sep - name) : data->items.maxstrlen)) { + data->active = a; + break; + } } if (data->items.totitem == 1 && but->editstr[0]) - data->active = 1; + data->active = 0; } /* validate selected item */ @@ -1075,9 +1075,9 @@ static void ui_searchbox_region_draw_cb(const bContext *UNUSED(C), ARegion *ar) /* widget itself */ if (data->preview) - ui_draw_preview_item(&data->fstyle, &rect, data->items.names[a], data->items.icons[a], (a + 1) == data->active ? UI_ACTIVE : 0); + ui_draw_preview_item(&data->fstyle, &rect, data->items.names[a], data->items.icons[a], (a == data->active) ? UI_ACTIVE : 0); else - ui_draw_menu_item(&data->fstyle, &rect, data->items.names[a], data->items.icons[a], (a + 1) == data->active ? UI_ACTIVE : 0); + ui_draw_menu_item(&data->fstyle, &rect, data->items.names[a], data->items.icons[a], (a == data->active) ? UI_ACTIVE : 0); } /* indicate more */ @@ -1101,7 +1101,7 @@ static void ui_searchbox_region_draw_cb(const bContext *UNUSED(C), ARegion *ar) ui_searchbox_butrect(&rect, data, a); /* widget itself */ - ui_draw_menu_item(&data->fstyle, &rect, data->items.names[a], data->items.icons[a], (a + 1) == data->active ? UI_ACTIVE : 0); + ui_draw_menu_item(&data->fstyle, &rect, data->items.names[a], data->items.icons[a], (a == data->active) ? UI_ACTIVE : 0); } /* indicate more */ @@ -2090,7 +2090,7 @@ static void square_picker(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, in /* a HS circle, V slider, rgb/hsv/hex sliders */ -static void uiBlockPicker(uiBlock *block, float rgba[4], PointerRNA *ptr, PropertyRNA *prop, int show_picker) +static void uiBlockPicker(uiBlock *block, float rgba[4], PointerRNA *ptr, PropertyRNA *prop, bool show_picker) { static short colormode = 0; /* temp? 0=rgb, 1=hsv, 2=hex */ uiBut *bt; From 8b4bca6cf056e81b0ae0e4854d2bd93d08d3a932 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 13 Jun 2013 01:39:07 +0000 Subject: [PATCH 37/37] fix [#35713] Set Origin not waiting for user input. Only activate search-box items on mouse-release, Otherwise this gives odd behavior when using the operator-search popup since some tools expect the mouse buttons not to be held when activating which includes operators that have their own popup menus. --- source/blender/editors/interface/interface_handlers.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index d431115d84e..875789c5758 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -2128,8 +2128,11 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle changed = true; } else if (inbox) { - button_activate_state(C, but, BUTTON_STATE_EXIT); - retval = WM_UI_HANDLER_BREAK; + /* if we allow activation on key press, it gives problems launching operators [#35713] */ + if (event->val == KM_RELEASE) { + button_activate_state(C, but, BUTTON_STATE_EXIT); + retval = WM_UI_HANDLER_BREAK; + } } break; }