From 2372e67dd6a2231869ec50d7bf382006be7141de Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 23 Sep 2016 12:43:23 +0200 Subject: Cycles: Don't sum up memory usage of all devices together for the stats --- intern/cycles/device/device_multi.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/intern/cycles/device/device_multi.cpp b/intern/cycles/device/device_multi.cpp index c4f8d9e16e0..ef257358b22 100644 --- a/intern/cycles/device/device_multi.cpp +++ b/intern/cycles/device/device_multi.cpp @@ -51,7 +51,7 @@ public: Device *device; foreach(DeviceInfo& subinfo, info.multi_devices) { - device = Device::create(subinfo, stats, background); + device = Device::create(subinfo, sub_stats_, background); devices.push_back(SubDevice(device)); } @@ -107,6 +107,7 @@ public: } mem.device_pointer = unique_ptr++; + stats.mem_alloc(mem.device_size); } void mem_copy_to(device_memory& mem) @@ -161,6 +162,7 @@ public: } mem.device_pointer = 0; + stats.mem_free(mem.device_size); } void const_copy_to(const char *name, void *host, size_t size) @@ -186,6 +188,7 @@ public: } mem.device_pointer = unique_ptr++; + stats.mem_alloc(mem.device_size); } void tex_free(device_memory& mem) @@ -199,6 +202,7 @@ public: } mem.device_pointer = 0; + stats.mem_free(mem.device_size); } void pixels_alloc(device_memory& mem) @@ -336,6 +340,9 @@ public: foreach(SubDevice& sub, devices) sub.device->task_cancel(); } + +protected: + Stats sub_stats_; }; Device *device_multi_create(DeviceInfo& info, Stats &stats, bool background) -- cgit v1.2.3 From 776a8548f03a049d56f19943e6bc4590ecd53028 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Fri, 23 Sep 2016 13:05:11 +0200 Subject: Fix T49430: append scene with gamelogic broken. In fact, it was the whole remapping process that was broken in logic bricks area, due to terrible design of links between those bricks... Object copying was also broken in that case, fixed as well. To be backported to 2.78. Note that issue was actually probably there since ages, hidden behind dirty hacks used in previous append code (though likely visible in some corner cases). Listen kids: do not, never, ever, do what has been done for links between logic bricks. Never. Ever. Even as pure runtime data it would have been bad, but as stored data... --- source/blender/blenkernel/BKE_sca.h | 6 +- source/blender/blenkernel/intern/library_remap.c | 5 + source/blender/blenkernel/intern/object.c | 8 +- source/blender/blenkernel/intern/sca.c | 156 +++++++++++++++++++++++ 4 files changed, 169 insertions(+), 6 deletions(-) diff --git a/source/blender/blenkernel/BKE_sca.h b/source/blender/blenkernel/BKE_sca.h index 1743a4431fd..a504f1bac3d 100644 --- a/source/blender/blenkernel/BKE_sca.h +++ b/source/blender/blenkernel/BKE_sca.h @@ -31,8 +31,9 @@ * \ingroup bke */ -struct bSensor; +struct Main; struct Object; +struct bSensor; struct bController; struct bActuator; @@ -68,6 +69,9 @@ void clear_sca_new_poins(void); void set_sca_new_poins_ob(struct Object *ob); void set_sca_new_poins(void); +void BKE_sca_logic_links_remap(struct Main *bmain, struct Object *ob_old, struct Object *ob_new); +void BKE_sca_logic_copy(struct Object *ob_new, struct Object *ob); + void sca_move_sensor(struct bSensor *sens_to_move, struct Object *ob, int move_up); void sca_move_controller(struct bController *cont_to_move, struct Object *ob, int move_up); void sca_move_actuator(struct bActuator *act_to_move, struct Object *ob, int move_up); diff --git a/source/blender/blenkernel/intern/library_remap.c b/source/blender/blenkernel/intern/library_remap.c index f4563649302..b468e6436c8 100644 --- a/source/blender/blenkernel/intern/library_remap.c +++ b/source/blender/blenkernel/intern/library_remap.c @@ -99,6 +99,7 @@ #include "BKE_object.h" #include "BKE_paint.h" #include "BKE_particle.h" +#include "BKE_sca.h" #include "BKE_speaker.h" #include "BKE_sound.h" #include "BKE_screen.h" @@ -448,6 +449,10 @@ ATTR_NONNULL(1) static void libblock_remap_data( } } + if (old_id && GS(old_id->name) == ID_OB) { + BKE_sca_logic_links_remap(bmain, (Object *)old_id, (Object *)new_id); + } + /* XXX We may not want to always 'transfer' fakeuser from old to new id... Think for now it's desired behavior * though, we can always add an option (flag) to control this later if needed. */ if (old_id && (old_id->flag & LIB_FAKEUSER)) { diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index cdd7560e3c4..d87c257d555 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -1118,11 +1118,9 @@ Object *BKE_object_copy_ex(Main *bmain, Object *ob, bool copy_caches) BLI_listbase_clear(&obn->prop); BKE_bproperty_copy_list(&obn->prop, &ob->prop); - - copy_sensors(&obn->sensors, &ob->sensors); - copy_controllers(&obn->controllers, &ob->controllers); - copy_actuators(&obn->actuators, &ob->actuators); - + + BKE_sca_logic_copy(obn, ob); + if (ob->pose) { copy_object_pose(obn, ob); /* backwards compat... non-armatures can get poses in older files? */ diff --git a/source/blender/blenkernel/intern/sca.c b/source/blender/blenkernel/intern/sca.c index a468420f87d..c357b2ef9f7 100644 --- a/source/blender/blenkernel/intern/sca.c +++ b/source/blender/blenkernel/intern/sca.c @@ -44,7 +44,9 @@ #include "DNA_object_types.h" #include "BLI_blenlib.h" +#include "BLI_ghash.h" #include "BLI_math.h" + #include "BKE_global.h" #include "BKE_main.h" #include "BKE_library.h" @@ -653,6 +655,160 @@ void set_sca_new_poins(void) } } +/** + * Try to remap logic links to new object... Very, *very* weak. + */ +/* XXX Logick bricks... I don't have words to say what I think about this behavior. + * They have silent hidden ugly inter-objects dependencies (a sensor can link into any other + * object's controllers, and same between controllers and actuators, without *any* explicit reference + * to data-block involved). + * This is bad, bad, bad!!! + * ...and forces us to add yet another very ugly hack to get remapping with logic bricks working. */ +void BKE_sca_logic_links_remap(Main *bmain, Object *ob_old, Object *ob_new) +{ + GHash *controllers_map = ob_old->controllers.first ? + BLI_ghash_ptr_new_ex(__func__, BLI_listbase_count(&ob_old->controllers)) : NULL; + GHash *actuators_map = ob_old->actuators.first ? + BLI_ghash_ptr_new_ex(__func__, BLI_listbase_count(&ob_old->actuators)) : NULL; + + if (!(controllers_map || actuators_map)) { + return; + } + + /* We try to remap old controllers/actuators to new ones - in a very basic way. */ + for (bController *cont_old = ob_old->controllers.first, *cont_new = ob_new->controllers.first; + cont_old; + cont_old = cont_old->next) + { + bController *cont_new2 = cont_new; + + if (cont_old->mynew != NULL) { + cont_new2 = cont_old->mynew; + if (!(cont_new2 == cont_new || BLI_findindex(&ob_new->controllers, cont_new2) >= 0)) { + cont_new2 = NULL; + } + } + else if (cont_new && cont_old->type != cont_new->type) { + cont_new2 = NULL; + } + + BLI_ghash_insert(controllers_map, cont_old, cont_new2); + + if (cont_new) { + cont_new = cont_new->next; + } + } + + for (bActuator *act_old = ob_old->actuators.first, *act_new = ob_new->actuators.first; + act_old; + act_old = act_old->next) + { + bActuator *act_new2 = act_new; + + if (act_old->mynew != NULL) { + act_new2 = act_old->mynew; + if (!(act_new2 == act_new || BLI_findindex(&ob_new->actuators, act_new2) >= 0)) { + act_new2 = NULL; + } + } + else if (act_new && act_old->type != act_new->type) { + act_new2 = NULL; + } + + BLI_ghash_insert(actuators_map, act_old, act_new2); + + if (act_new) { + act_new = act_new->next; + } + } + + for (Object *ob = bmain->object.first; ob; ob = ob->id.next) { + if (controllers_map != NULL) { + for (bSensor *sens = ob->sensors.first; sens; sens = sens->next) { + for (int a = 0; a < sens->totlinks; a++) { + if (sens->links[a]) { + bController *old_link = sens->links[a]; + bController **new_link_p = (bController **)BLI_ghash_lookup_p(controllers_map, old_link); + + if (new_link_p == NULL) { + /* old_link is *not* in map's keys (i.e. not to any ob_old->controllers), + * which means we ignore it totally here. */ + } + else if (*new_link_p == NULL) { + unlink_logicbricks((void **)&old_link, (void ***)&(sens->links), &sens->totlinks); + a--; + } + else { + sens->links[a] = *new_link_p; + } + } + } + } + } + + if (actuators_map != NULL) { + for (bController *cont = ob->controllers.first; cont; cont = cont->next) { + for (int a = 0; a < cont->totlinks; a++) { + if (cont->links[a]) { + bActuator *old_link = cont->links[a]; + bActuator **new_link_p = (bActuator **)BLI_ghash_lookup_p(actuators_map, old_link); + + if (new_link_p == NULL) { + /* old_link is *not* in map's keys (i.e. not to any ob_old->actuators), + * which means we ignore it totally here. */ + } + else if (*new_link_p == NULL) { + unlink_logicbricks((void **)&old_link, (void ***)&(cont->links), &cont->totlinks); + a--; + } + else { + cont->links[a] = *new_link_p; + } + } + } + } + } + } + + if (controllers_map) { + BLI_ghash_free(controllers_map, NULL, NULL); + } + if (actuators_map) { + BLI_ghash_free(actuators_map, NULL, NULL); + } +} + +/** + * Handle the copying of logic data into a new object, including internal logic links update. + * External links (links between logic bricks of different objects) must be handled separately. + */ +void BKE_sca_logic_copy(Object *ob_new, Object *ob) +{ + copy_sensors(&ob_new->sensors, &ob->sensors); + copy_controllers(&ob_new->controllers, &ob->controllers); + copy_actuators(&ob_new->actuators, &ob->actuators); + + for (bSensor *sens = ob->sensors.first; sens; sens = sens->next) { + if (sens->flag & SENS_NEW) { + for (int a = 0; a < sens->totlinks; a++) { + if (sens->links[a] && sens->links[a]->mynew) { + sens->links[a] = sens->links[a]->mynew; + } + } + } + } + + for (bController *cont = ob->controllers.first; cont; cont = cont->next) { + if (cont->flag & CONT_NEW) { + for (int a = 0; a < cont->totlinks; a++) { + if (cont->links[a] && cont->links[a]->mynew) { + cont->links[a] = cont->links[a]->mynew; + } + } + } + } +} + /* ******************** INTERFACE ******************* */ void sca_move_sensor(bSensor *sens_to_move, Object *ob, int move_up) { -- cgit v1.2.3 From 1d03bc73cea8b24ad1b90f7df5a3124a91370524 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 23 Sep 2016 14:32:14 +0200 Subject: Particles: Add operator to quicly duplicate active particle system to the same object --- .../scripts/startup/bl_ui/properties_particle.py | 2 ++ source/blender/editors/physics/particle_object.c | 34 ++++++++++++++++++++++ source/blender/editors/physics/physics_intern.h | 1 + source/blender/editors/physics/physics_ops.c | 1 + 4 files changed, 38 insertions(+) diff --git a/release/scripts/startup/bl_ui/properties_particle.py b/release/scripts/startup/bl_ui/properties_particle.py index 89ea9dff69b..4e2666d7e40 100644 --- a/release/scripts/startup/bl_ui/properties_particle.py +++ b/release/scripts/startup/bl_ui/properties_particle.py @@ -79,6 +79,8 @@ class PARTICLE_MT_specials(Menu): props.use_active = False props.remove_target_particles = True + layout.operator("particle.duplicate_particle_system") + class PARTICLE_MT_hair_dynamics_presets(Menu): bl_label = "Hair Dynamics Presets" diff --git a/source/blender/editors/physics/particle_object.c b/source/blender/editors/physics/particle_object.c index 0dd00df6182..2462061c331 100644 --- a/source/blender/editors/physics/particle_object.c +++ b/source/blender/editors/physics/particle_object.c @@ -1187,3 +1187,37 @@ void PARTICLE_OT_copy_particle_systems(wmOperatorType *ot) RNA_def_boolean(ot->srna, "remove_target_particles", true, "Remove Target Particles", "Remove particle systems on the target objects"); RNA_def_boolean(ot->srna, "use_active", false, "Use Active", "Use the active particle system from the context"); } + +static int duplicate_particle_systems_poll(bContext *C) +{ + if (!ED_operator_object_active_editable(C)) { + return false; + } + Object *ob = ED_object_active_context(C); + if (BLI_listbase_is_empty(&ob->particlesystem)) { + return false; + } + return true; +} + +static int duplicate_particle_systems_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Scene *scene = CTX_data_scene(C); + Object *ob = ED_object_active_context(C); + ParticleSystem *psys = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem).data; + copy_particle_systems_to_object(scene, ob, psys, ob, PAR_COPY_SPACE_OBJECT); + return OPERATOR_FINISHED; +} + +void PARTICLE_OT_duplicate_particle_system(wmOperatorType *ot) +{ + ot->name = "Duplicate Particle Systems"; + ot->description = "Duplicate particle system within the active object"; + ot->idname = "PARTICLE_OT_duplicate_particle_system"; + + ot->poll = duplicate_particle_systems_poll; + ot->exec = duplicate_particle_systems_exec; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} diff --git a/source/blender/editors/physics/physics_intern.h b/source/blender/editors/physics/physics_intern.h index 361c058647a..6b6df15e987 100644 --- a/source/blender/editors/physics/physics_intern.h +++ b/source/blender/editors/physics/physics_intern.h @@ -75,6 +75,7 @@ void PARTICLE_OT_target_move_down(struct wmOperatorType *ot); void PARTICLE_OT_connect_hair(struct wmOperatorType *ot); void PARTICLE_OT_disconnect_hair(struct wmOperatorType *ot); void PARTICLE_OT_copy_particle_systems(struct wmOperatorType *ot); +void PARTICLE_OT_duplicate_particle_system(struct wmOperatorType *ot); void PARTICLE_OT_dupliob_copy(struct wmOperatorType *ot); void PARTICLE_OT_dupliob_remove(struct wmOperatorType *ot); diff --git a/source/blender/editors/physics/physics_ops.c b/source/blender/editors/physics/physics_ops.c index 5074a41ad20..7ba4b2be43b 100644 --- a/source/blender/editors/physics/physics_ops.c +++ b/source/blender/editors/physics/physics_ops.c @@ -83,6 +83,7 @@ static void operatortypes_particle(void) WM_operatortype_append(PARTICLE_OT_connect_hair); WM_operatortype_append(PARTICLE_OT_disconnect_hair); WM_operatortype_append(PARTICLE_OT_copy_particle_systems); + WM_operatortype_append(PARTICLE_OT_duplicate_particle_system); WM_operatortype_append(PARTICLE_OT_dupliob_copy); WM_operatortype_append(PARTICLE_OT_dupliob_remove); -- cgit v1.2.3 From 1e89a261b2482bdc1579fa730b3a00beda5fffad Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 23 Sep 2016 14:49:55 +0200 Subject: Outliner: Fix assert failure with palette ID --- source/blender/editors/space_outliner/outliner_intern.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h index ca037cb20cc..a1663dd641d 100644 --- a/source/blender/editors/space_outliner/outliner_intern.h +++ b/source/blender/editors/space_outliner/outliner_intern.h @@ -62,7 +62,7 @@ typedef struct TreeElement { #define TREESTORE_ID_TYPE(_id) \ (ELEM(GS((_id)->name), ID_SCE, ID_LI, ID_OB, ID_ME, ID_CU, ID_MB, ID_NT, ID_MA, ID_TE, ID_IM, ID_LT, ID_LA, ID_CA) || \ ELEM(GS((_id)->name), ID_KE, ID_WO, ID_SPK, ID_GR, ID_AR, ID_AC, ID_BR, ID_PA, ID_GD, ID_LS) || \ - ELEM(GS((_id)->name), ID_SCR, ID_WM, ID_TXT, ID_VF, ID_SO, ID_CF)) /* Only in 'blendfile' mode ... :/ */ + ELEM(GS((_id)->name), ID_SCR, ID_WM, ID_TXT, ID_VF, ID_SO, ID_CF, ID_PAL)) /* Only in 'blendfile' mode ... :/ */ /* TreeElement->flag */ #define TE_ACTIVE 1 -- cgit v1.2.3 From c61cb0e0765915d7ad2d9e91f6f72dfcea662744 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 23 Sep 2016 14:51:42 +0200 Subject: Particle: Prevent crash duplicating hair on objects with modifiers --- source/blender/editors/physics/particle_object.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/physics/particle_object.c b/source/blender/editors/physics/particle_object.c index 2462061c331..545042e1d84 100644 --- a/source/blender/editors/physics/particle_object.c +++ b/source/blender/editors/physics/particle_object.c @@ -1097,8 +1097,9 @@ static bool copy_particle_systems_to_object(Scene *scene, Object *ob_from, Parti BLI_assert(false); break; } - - remap_hair_emitter(scene, ob_from, psys_from, ob_to, psys, psys->edit, from_mat, to_mat, psys_from->flag & PSYS_GLOBAL_HAIR, psys->flag & PSYS_GLOBAL_HAIR); + if (ob_from != ob_to) { + remap_hair_emitter(scene, ob_from, psys_from, ob_to, psys, psys->edit, from_mat, to_mat, psys_from->flag & PSYS_GLOBAL_HAIR, psys->flag & PSYS_GLOBAL_HAIR); + } /* tag for recalc */ // psys->recalc |= PSYS_RECALC_RESET; -- cgit v1.2.3 From 1925b9b2fac4e637cc2e0e2053e25059c5098664 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 23 Sep 2016 15:33:07 +0200 Subject: Particle: Add option to duplicate settings together with particle system itself This way it's possible to copy combed hair, use it as a basis for another particle system to do some awesome artistic stuff. --- source/blender/editors/physics/particle_object.c | 25 ++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/source/blender/editors/physics/particle_object.c b/source/blender/editors/physics/particle_object.c index 545042e1d84..895d791b8e2 100644 --- a/source/blender/editors/physics/particle_object.c +++ b/source/blender/editors/physics/particle_object.c @@ -993,7 +993,13 @@ static void remove_particle_systems_from_object(Object *ob_to) } /* single_psys_from is optional, if NULL all psys of ob_from are copied */ -static bool copy_particle_systems_to_object(Scene *scene, Object *ob_from, ParticleSystem *single_psys_from, Object *ob_to, int space) +static bool copy_particle_systems_to_object(Main *bmain, + Scene *scene, + Object *ob_from, + ParticleSystem *single_psys_from, + Object *ob_to, + int space, + bool duplicate_settings) { ModifierData *md; ParticleSystem *psys_start = NULL, *psys, *psys_from; @@ -1070,6 +1076,11 @@ static bool copy_particle_systems_to_object(Scene *scene, Object *ob_from, Parti if (psys_from->edit) copy_particle_edit(scene, ob_to, psys, psys_from); + + if (duplicate_settings) { + id_us_min(psys->part); + psys->part = BKE_particlesettings_copy(bmain, psys->part); + } } MEM_freeN(tmp_psys); @@ -1131,6 +1142,7 @@ static int copy_particle_systems_exec(bContext *C, wmOperator *op) const int space = RNA_enum_get(op->ptr, "space"); const bool remove_target_particles = RNA_boolean_get(op->ptr, "remove_target_particles"); const bool use_active = RNA_boolean_get(op->ptr, "use_active"); + Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); Object *ob_from = ED_object_active_context(C); ParticleSystem *psys_from = use_active ? CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem).data : NULL; @@ -1146,7 +1158,7 @@ static int copy_particle_systems_exec(bContext *C, wmOperator *op) remove_particle_systems_from_object(ob_to); changed = true; } - if (copy_particle_systems_to_object(scene, ob_from, psys_from, ob_to, space)) + if (copy_particle_systems_to_object(bmain, scene, ob_from, psys_from, ob_to, space, false)) changed = true; else fail++; @@ -1201,12 +1213,14 @@ static int duplicate_particle_systems_poll(bContext *C) return true; } -static int duplicate_particle_systems_exec(bContext *C, wmOperator *UNUSED(op)) +static int duplicate_particle_systems_exec(bContext *C, wmOperator *op) { + const bool duplicate_settings = RNA_boolean_get(op->ptr, "use_duplicate_settings"); Scene *scene = CTX_data_scene(C); Object *ob = ED_object_active_context(C); ParticleSystem *psys = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem).data; - copy_particle_systems_to_object(scene, ob, psys, ob, PAR_COPY_SPACE_OBJECT); + copy_particle_systems_to_object(CTX_data_main(C), scene, ob, psys, ob, + PAR_COPY_SPACE_OBJECT, duplicate_settings); return OPERATOR_FINISHED; } @@ -1221,4 +1235,7 @@ void PARTICLE_OT_duplicate_particle_system(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + RNA_def_boolean(ot->srna, "use_duplicate_settings", false, "Duplicate Settings", + "Duplicate settings as well, so new particle system uses own settings"); } -- cgit v1.2.3 From 06b51c64ad7cbf73dc0bc9c31060ffff0b778898 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 23 Sep 2016 15:39:33 +0200 Subject: Particles: Prevent crash when copying to an object with subsurf modifier Probably something will be remapped wrongly, but better than crash. --- source/blender/editors/physics/particle_object.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/physics/particle_object.c b/source/blender/editors/physics/particle_object.c index 895d791b8e2..4a4474868a2 100644 --- a/source/blender/editors/physics/particle_object.c +++ b/source/blender/editors/physics/particle_object.c @@ -697,6 +697,9 @@ static bool remap_hair_emitter(Scene *scene, Object *ob, ParticleSystem *psys, dm = target_psmd->dm_deformed; } target_dm = target_psmd->dm_final; + if (dm == NULL) { + return false; + } /* don't modify the original vertices */ dm = CDDM_copy(dm); @@ -1078,7 +1081,7 @@ static bool copy_particle_systems_to_object(Main *bmain, copy_particle_edit(scene, ob_to, psys, psys_from); if (duplicate_settings) { - id_us_min(psys->part); + id_us_min(&psys->part->id); psys->part = BKE_particlesettings_copy(bmain, psys->part); } } -- cgit v1.2.3 From 4e3578f47082c3b28be4b0065fc97e4916046d8f Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 23 Sep 2016 15:57:39 +0200 Subject: Cycles: Prevent crash in special cases when object has less slots than mesh This is something what was guaranteed in give_current_material(), just copied some range checking logic from there. Not sure what would be a proper fix here tho. --- source/blender/blenkernel/intern/mesh.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index 7714c71681a..1cc8d8c381c 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -2368,8 +2368,12 @@ Mesh *BKE_mesh_new_from_object( if (tmpcu->mat) { for (i = tmpcu->totcol; i-- > 0; ) { /* are we an object material or data based? */ - - tmpmesh->mat[i] = ob->matbits[i] ? ob->mat[i] : tmpcu->mat[i]; + if (ob->matbits[i] && i >= ob->totcol) { + tmpmesh->mat[i] = NULL; + } + else { + tmpmesh->mat[i] = ob->matbits[i] ? ob->mat[i] : tmpcu->mat[i]; + } if (do_mat_id_us && tmpmesh->mat[i]) { id_us_plus(&tmpmesh->mat[i]->id); @@ -2388,7 +2392,12 @@ Mesh *BKE_mesh_new_from_object( if (tmpmb->mat) { for (i = tmpmb->totcol; i-- > 0; ) { /* are we an object material or data based? */ - tmpmesh->mat[i] = ob->matbits[i] ? ob->mat[i] : tmpmb->mat[i]; + if (ob->matbits[i] && i >= ob->totcol) { + tmpmesh->mat[i] = NULL; + } + else { + tmpmesh->mat[i] = ob->matbits[i] ? ob->mat[i] : tmpmb->mat[i]; + } if (do_mat_id_us && tmpmesh->mat[i]) { id_us_plus(&tmpmesh->mat[i]->id); @@ -2408,7 +2417,12 @@ Mesh *BKE_mesh_new_from_object( if (origmesh->mat) { for (i = origmesh->totcol; i-- > 0; ) { /* are we an object material or data based? */ - tmpmesh->mat[i] = ob->matbits[i] ? ob->mat[i] : origmesh->mat[i]; + if (ob->matbits[i] && i >= ob->totcol) { + tmpmesh->mat[i] = NULL; + } + else { + tmpmesh->mat[i] = ob->matbits[i] ? ob->mat[i] : origmesh->mat[i]; + } if (do_mat_id_us && tmpmesh->mat[i]) { id_us_plus(&tmpmesh->mat[i]->id); -- cgit v1.2.3 From c3b754f9bdd379acee1a5d6042b8d46cde4b18ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dietrich?= Date: Fri, 23 Sep 2016 19:44:51 +0200 Subject: Alembic: only export face sets when required by the user. Also remove deprecated face set code. --- source/blender/alembic/intern/abc_mesh.cc | 24 +++++------------------- source/blender/alembic/intern/abc_mesh.h | 4 +--- 2 files changed, 6 insertions(+), 22 deletions(-) diff --git a/source/blender/alembic/intern/abc_mesh.cc b/source/blender/alembic/intern/abc_mesh.cc index 5a6058771c2..00c86779960 100644 --- a/source/blender/alembic/intern/abc_mesh.cc +++ b/source/blender/alembic/intern/abc_mesh.cc @@ -309,7 +309,6 @@ AbcMeshWriter::AbcMeshWriter(Scene *scene, { m_is_animated = isAnimated(); m_subsurf_mod = NULL; - m_has_per_face_materials = false; m_is_subd = false; /* If the object is static, use the default static time sampling. */ @@ -406,8 +405,8 @@ void AbcMeshWriter::writeMesh(DerivedMesh *dm) get_vertices(dm, points); get_topology(dm, poly_verts, loop_counts, smooth_normal); - if (m_first_frame) { - writeCommonData(dm, m_mesh_schema); + if (m_first_frame && m_settings.export_face_sets) { + writeFaceSets(dm, m_mesh_schema); } m_mesh_sample = OPolyMeshSchema::Sample(V3fArraySample(points), @@ -475,9 +474,8 @@ void AbcMeshWriter::writeSubD(DerivedMesh *dm) get_topology(dm, poly_verts, loop_counts, smooth_normal); get_creases(dm, crease_indices, crease_lengths, crease_sharpness); - if (m_first_frame) { - /* create materials' face_sets */ - writeCommonData(dm, m_subdiv_schema); + if (m_first_frame && m_settings.export_face_sets) { + writeFaceSets(dm, m_subdiv_schema); } m_subdiv_sample = OSubDSchema::Sample(V3fArraySample(points), @@ -514,7 +512,7 @@ void AbcMeshWriter::writeSubD(DerivedMesh *dm) } template -void AbcMeshWriter::writeCommonData(DerivedMesh *dm, Schema &schema) +void AbcMeshWriter::writeFaceSets(DerivedMesh *dm, Schema &schema) { std::map< std::string, std::vector > geo_groups; getGeoGroups(dm, geo_groups); @@ -588,18 +586,6 @@ void AbcMeshWriter::writeArbGeoParams(DerivedMesh *dm) write_custom_data(m_mesh_schema.getArbGeomParams(), m_custom_data_config, &dm->loopData, CD_MLOOPCOL); } } - - if (m_first_frame && m_has_per_face_materials) { - std::vector material_indices; - - if (m_settings.export_face_sets) { - get_material_indices(dm, material_indices); - - OFaceSetSchema::Sample samp; - samp.setFaces(Int32ArraySample(material_indices)); - m_face_set.getSchema().set(samp); - } - } } void AbcMeshWriter::getVelocities(DerivedMesh *dm, std::vector &vels) diff --git a/source/blender/alembic/intern/abc_mesh.h b/source/blender/alembic/intern/abc_mesh.h index 9dc222e5206..41abe78f75f 100644 --- a/source/blender/alembic/intern/abc_mesh.h +++ b/source/blender/alembic/intern/abc_mesh.h @@ -39,8 +39,6 @@ class AbcMeshWriter : public AbcObjectWriter { Alembic::AbcGeom::OSubDSchema m_subdiv_schema; Alembic::AbcGeom::OSubDSchema::Sample m_subdiv_sample; - bool m_has_per_face_materials; - Alembic::AbcGeom::OFaceSet m_face_set; Alembic::Abc::OArrayProperty m_mat_indices; bool m_is_animated; @@ -87,7 +85,7 @@ private: void getVelocities(DerivedMesh *dm, std::vector &vels); template - void writeCommonData(DerivedMesh *dm, Schema &schema); + void writeFaceSets(DerivedMesh *dm, Schema &schema); }; /* ************************************************************************** */ -- cgit v1.2.3 From 25b61662f5b4c9d04a43611927e7748a046f35db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dietrich?= Date: Fri, 23 Sep 2016 19:45:06 +0200 Subject: Quiet warning. --- source/blender/alembic/intern/abc_exporter.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/alembic/intern/abc_exporter.cc b/source/blender/alembic/intern/abc_exporter.cc index a31122b7cd0..d259721e192 100644 --- a/source/blender/alembic/intern/abc_exporter.cc +++ b/source/blender/alembic/intern/abc_exporter.cc @@ -87,10 +87,10 @@ ExportSettings::ExportSettings() , export_child_hairs(true) , export_ogawa(true) , pack_uv(false) - , do_convert_axis(false) , triangulate(false) , quad_method(0) , ngon_method(0) + , do_convert_axis(false) {} static bool object_is_smoke_sim(Object *ob) -- cgit v1.2.3 From 4b891b40c218ef5f45706cbc4636a5333469dd1c Mon Sep 17 00:00:00 2001 From: Gaia Clary Date: Fri, 23 Sep 2016 12:56:04 +0200 Subject: Fix: Collada Importer did not import the Blender Profile information correctly when multiple objects are bound to same armature. This caused Bone tails to be placed wrong. --- source/blender/collada/ArmatureImporter.cpp | 105 ++++++++++++++-------------- source/blender/collada/ArmatureImporter.h | 12 ++-- source/blender/collada/collada_utils.cpp | 32 +++++++++ source/blender/collada/collada_utils.h | 19 +++++ 4 files changed, 110 insertions(+), 58 deletions(-) diff --git a/source/blender/collada/ArmatureImporter.cpp b/source/blender/collada/ArmatureImporter.cpp index d97fb55af9c..0d5c482aef5 100644 --- a/source/blender/collada/ArmatureImporter.cpp +++ b/source/blender/collada/ArmatureImporter.cpp @@ -60,15 +60,6 @@ ArmatureImporter::ArmatureImporter(UnitConverter *conv, MeshImporterBase *mesh, mesh_importer(mesh) { } -void ArmatureImporter::clear_extended_boneset() -{ - for (std::map::iterator it = extended_bones.begin(); it != extended_bones.end(); ++it) { - if (it->second != NULL) - delete it->second; - } - extended_bones.clear(); -} - ArmatureImporter::~ArmatureImporter() { // free skin controller data if we forget to do this earlier @@ -76,7 +67,6 @@ ArmatureImporter::~ArmatureImporter() for (it = skin_by_data_uid.begin(); it != skin_by_data_uid.end(); it++) { it->second.free(); } - clear_extended_boneset(); } #if 0 @@ -156,8 +146,8 @@ int ArmatureImporter::create_bone(SkinInfo *skin, COLLADAFW::Node *node, EditBon if (parent) bone->parent = parent; float loc[3], size[3], rot[3][3]; - - BoneExtended &be = add_bone_extended(bone, node, totchild, layer_labels); + BoneExtensionMap &extended_bones = bone_extension_manager.getExtensionMap(arm); + BoneExtended &be = add_bone_extended(bone, node, totchild, layer_labels, extended_bones); int layer = be.get_bone_layers(); if (layer) bone->layer = layer; arm->layer |= layer; // ensure that all populated bone layers are visible after import @@ -205,7 +195,6 @@ int ArmatureImporter::create_bone(SkinInfo *skin, COLLADAFW::Node *node, EditBon chain_length = cl; } - bone->length = len_v3v3(bone->head, bone->tail); joint_by_uid[node->getUniqueId()] = node; finished_joints.push_back(node); @@ -221,43 +210,49 @@ int ArmatureImporter::create_bone(SkinInfo *skin, COLLADAFW::Node *node, EditBon * tail locations for the affected bones (nodes which don't have any connected child) * Hint: The extended_bones set gets populated in ArmatureImporter::create_bone **/ -void ArmatureImporter::fix_leaf_bones(bArmature *armature, Bone *bone, bool fix_orientation) +void ArmatureImporter::fix_leaf_bone_hierarchy(bArmature *armature, Bone *bone, bool fix_orientation) { if (bone == NULL) return; if (bc_is_leaf_bone(bone)) { - + BoneExtensionMap &extended_bones = bone_extension_manager.getExtensionMap(armature); BoneExtended *be = extended_bones[bone->name]; - if (be == NULL || !be->has_tail()) { + EditBone *ebone = bc_get_edit_bone(armature, bone->name); + fix_leaf_bone(armature, ebone, be, fix_orientation); + } + + for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) { + fix_leaf_bone_hierarchy(armature, child, fix_orientation); + } +} - /* Collada only knows Joints, Here we guess a reasonable leaf bone length */ - float leaf_length = (leaf_bone_length == FLT_MAX) ? 1.0 : leaf_bone_length; +void ArmatureImporter::fix_leaf_bone(bArmature *armature, EditBone *ebone, BoneExtended *be , bool fix_orientation) +{ + if (be == NULL || !be->has_tail()) { - EditBone *ebone = bc_get_edit_bone(armature, bone->name); - float vec[3]; + /* Collada only knows Joints, Here we guess a reasonable leaf bone length */ + float leaf_length = (leaf_bone_length == FLT_MAX) ? 1.0 : leaf_bone_length; - if (ebone->parent != NULL && fix_orientation) { - EditBone *parent = ebone->parent; - sub_v3_v3v3(vec, ebone->head, parent->head); - if (len_squared_v3(vec) < MINIMUM_BONE_LENGTH) - { - sub_v3_v3v3(vec, parent->tail, parent->head); - } - } - else { - vec[2] = 0.1f; - sub_v3_v3v3(vec, ebone->tail, ebone->head); - } - normalize_v3_v3(vec, vec); - mul_v3_fl(vec, leaf_length); - add_v3_v3v3(ebone->tail, ebone->head, vec); + float vec[3]; + + if (fix_orientation && ebone->parent != NULL) { + EditBone *parent = ebone->parent; + sub_v3_v3v3(vec, ebone->head, parent->head); + if (len_squared_v3(vec) < MINIMUM_BONE_LENGTH) + { + sub_v3_v3v3(vec, parent->tail, parent->head); + } + } + else { + vec[2] = 0.1f; + sub_v3_v3v3(vec, ebone->tail, ebone->head); } - } - for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) { - fix_leaf_bones(armature, child, fix_orientation); + normalize_v3_v3(vec, vec); + mul_v3_fl(vec, leaf_length); + add_v3_v3v3(ebone->tail, ebone->head, vec); } } @@ -280,6 +275,7 @@ void ArmatureImporter::fix_parent_connect(bArmature *armature, Bone *bone) void ArmatureImporter::connect_bone_chains(bArmature *armature, Bone *parentbone, int clip) { + BoneExtensionMap &extended_bones = bone_extension_manager.getExtensionMap(armature); BoneExtended *dominant_child = NULL; int maxlen = 0; Bone *child; @@ -445,11 +441,10 @@ ArmatureJoints& ArmatureImporter::get_armature_joints(Object *ob_arm) return armature_joints.back(); } #endif -Object *ArmatureImporter::create_armature_bones(std::vector &ob_arms) +void ArmatureImporter::create_armature_bones(std::vector &ob_arms) { std::vector::iterator ri; std::vector layer_labels; - Object *ob_arm = NULL; //if there is an armature created for root_joint next root_joint for (ri = root_joints.begin(); ri != root_joints.end(); ri++) { @@ -470,15 +465,23 @@ Object *ArmatureImporter::create_armature_bones(std::vector &ob_arms) continue; } - clear_extended_boneset(); - ED_armature_to_edit(armature); armature->layer = 0; // layer is set according to imported bone set in create_bone() create_bone(NULL, *ri , NULL, (*ri)->getChildNodes().getCount(), NULL, armature, layer_labels); + if (this->import_settings->find_chains) { + connect_bone_chains(armature, (Bone *)armature->bonebase.first, UNLIMITED_CHAIN_MAX); + } /* exit armature edit mode to populate the Armature object */ + ED_armature_from_edit(armature); + ED_armature_edit_free(armature); + + ED_armature_to_edit(armature); + + fix_leaf_bone_hierarchy(armature, (Bone *)armature->bonebase.first, this->import_settings->fix_orientation); unskinned_armature_map[(*ri)->getUniqueId()] = ob_arm; + ED_armature_from_edit(armature); ED_armature_edit_free(armature); @@ -489,7 +492,6 @@ Object *ArmatureImporter::create_armature_bones(std::vector &ob_arms) DAG_id_tag_update(&ob_arm->id, OB_RECALC_OB | OB_RECALC_DATA); } - return ob_arm; } Object *ArmatureImporter::create_armature_bones(SkinInfo& skin) @@ -584,8 +586,6 @@ Object *ArmatureImporter::create_armature_bones(SkinInfo& skin) bArmature * armature = (bArmature *)ob_arm->data; ED_armature_to_edit(armature); - clear_extended_boneset(); - totbone = 0; // bone_direction_row = 1; // TODO: don't default to Y but use asset and based on it decide on default row @@ -615,6 +615,14 @@ Object *ArmatureImporter::create_armature_bones(SkinInfo& skin) ED_armature_from_edit(armature); ED_armature_edit_free(armature); + ED_armature_to_edit(armature); + if (this->import_settings->find_chains) { + connect_bone_chains(armature, (Bone *)armature->bonebase.first, UNLIMITED_CHAIN_MAX); + } + fix_leaf_bone_hierarchy(armature, (Bone *)armature->bonebase.first, this->import_settings->fix_orientation); + ED_armature_from_edit(armature); + ED_armature_edit_free(armature); + DAG_id_tag_update(&ob_arm->id, OB_RECALC_OB | OB_RECALC_DATA); return ob_arm; @@ -756,11 +764,6 @@ void ArmatureImporter::make_armatures(bContext *C, std::vector &object /* and step back to edit mode to fix the leaf nodes */ ED_armature_to_edit(armature); - if (this->import_settings->find_chains) - connect_bone_chains(armature, (Bone *)armature->bonebase.first, UNLIMITED_CHAIN_MAX); - - fix_leaf_bones(armature, (Bone *)armature->bonebase.first, this->import_settings->fix_orientation); - fix_parent_connect(armature, (Bone *)armature->bonebase.first); ED_armature_from_edit(armature); @@ -952,7 +955,7 @@ bool ArmatureImporter::get_joint_bind_mat(float m[4][4], COLLADAFW::Node *joint) return found; } -BoneExtended &ArmatureImporter::add_bone_extended(EditBone *bone, COLLADAFW::Node *node, int sibcount, std::vector &layer_labels) +BoneExtended &ArmatureImporter::add_bone_extended(EditBone *bone, COLLADAFW::Node *node, int sibcount, std::vector &layer_labels, BoneExtensionMap &extended_bones) { BoneExtended *be = new BoneExtended(bone); extended_bones[bone->name] = be; diff --git a/source/blender/collada/ArmatureImporter.h b/source/blender/collada/ArmatureImporter.h index 524c524c9c9..17173f157e5 100644 --- a/source/blender/collada/ArmatureImporter.h +++ b/source/blender/collada/ArmatureImporter.h @@ -68,8 +68,7 @@ private: // std::map joint_index_to_joint_info_map; // std::map joint_id_to_joint_index_map; - - std::map extended_bones; + BoneExtensionManager bone_extension_manager; // int bone_direction_row; // XXX not used float leaf_bone_length; int totbone; @@ -108,16 +107,15 @@ private: int create_bone(SkinInfo* skin, COLLADAFW::Node *node, EditBone *parent, int totchild, float parent_mat[4][4], bArmature *arm, std::vector &layer_labels); - BoneExtended &add_bone_extended(EditBone *bone, COLLADAFW::Node * node, int sibcount, std::vector &layer_labels); - void clear_extended_boneset(); + BoneExtended &add_bone_extended(EditBone *bone, COLLADAFW::Node * node, int sibcount, std::vector &layer_labels, BoneExtensionMap &extended_bones); - void fix_leaf_bones(bArmature *armature, Bone *bone, bool fix_orientation); + void fix_leaf_bone_hierarchy(bArmature *armature, Bone *bone, bool fix_orientation); + void fix_leaf_bone(bArmature *armature, EditBone *ebone, BoneExtended *be, bool fix_orientation); void fix_parent_connect(bArmature *armature, Bone *bone); void connect_bone_chains(bArmature *armature, Bone *bone, const int max_chain_length); void set_pose( Object *ob_arm, COLLADAFW::Node *root_node, const char *parentname, float parent_mat[4][4]); - #if 0 void set_leaf_bone_shapes(Object *ob_arm); void set_euler_rotmode(); @@ -132,7 +130,7 @@ private: #endif Object *create_armature_bones(SkinInfo& skin); - Object *create_armature_bones(std::vector &arm_objs); + void create_armature_bones(std::vector &arm_objs); /** TagsMap typedef for uid_tags_map. */ typedef std::map TagsMap; diff --git a/source/blender/collada/collada_utils.cpp b/source/blender/collada/collada_utils.cpp index abe5130b9c1..2efa8b21d81 100644 --- a/source/blender/collada/collada_utils.cpp +++ b/source/blender/collada/collada_utils.cpp @@ -412,6 +412,38 @@ int bc_set_layer(int bitfield, int layer, bool enable) return bitfield; } +/* + | This method creates a new extension map when needed. + | Note: The ~BoneExtensionManager destructor takes care + | to delete the created maps when the manager is removed. +*/ +BoneExtensionMap &BoneExtensionManager::getExtensionMap(bArmature *armature) +{ + std::string key = armature->id.name; + BoneExtensionMap *result = extended_bone_maps[key]; + if (result == NULL) + { + result = new BoneExtensionMap(); + extended_bone_maps[key] = result; + } + return *result; +} + +BoneExtensionManager::~BoneExtensionManager() +{ + std::map::iterator map_it; + for (map_it = extended_bone_maps.begin(); map_it != extended_bone_maps.end(); ++map_it) + { + BoneExtensionMap *extended_bones = map_it->second; + for (BoneExtensionMap::iterator ext_it = extended_bones->begin(); ext_it != extended_bones->end(); ++ext_it) { + if (ext_it->second != NULL) + delete ext_it->second; + } + extended_bones->clear(); + delete extended_bones; + } +} + /** * BoneExtended is a helper class needed for the Bone chain finder * See ArmatureImporter::fix_leaf_bones() diff --git a/source/blender/collada/collada_utils.h b/source/blender/collada/collada_utils.h index ee371f7959e..7fdbef3b6cb 100644 --- a/source/blender/collada/collada_utils.h +++ b/source/blender/collada/collada_utils.h @@ -153,5 +153,24 @@ public: int get_use_connect(); }; +/* a map to store bone extension maps +| std:string : an armature name +| BoneExtended * : a map that contains extra data for bones +*/ +typedef std::map BoneExtensionMap; + +/* +| A class to organise bone extendion data for multiple Armatures. +| this is needed for the case where a Collada file contains 2 or more +| separate armatures. +*/ +class BoneExtensionManager { +private: + std::map extended_bone_maps; + +public: + BoneExtensionMap &getExtensionMap(bArmature *armature); + ~BoneExtensionManager(); +}; #endif -- cgit v1.2.3 From 7a259d8422b9fd29fb9990269821fa64fc146a01 Mon Sep 17 00:00:00 2001 From: Gaia Clary Date: Sat, 24 Sep 2016 01:27:37 +0200 Subject: Collada: Trying to get rif of some warning messages on linux --- source/blender/collada/ArmatureImporter.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/collada/ArmatureImporter.cpp b/source/blender/collada/ArmatureImporter.cpp index 0d5c482aef5..4a5775cabe0 100644 --- a/source/blender/collada/ArmatureImporter.cpp +++ b/source/blender/collada/ArmatureImporter.cpp @@ -52,10 +52,10 @@ static const char *bc_get_joint_name(T *node) ArmatureImporter::ArmatureImporter(UnitConverter *conv, MeshImporterBase *mesh, Scene *sce, const ImportSettings *import_settings) : - import_settings(import_settings), + scene(sce), unit_converter(conv), + import_settings(import_settings), TransformReader(conv), - scene(sce), empty(NULL), mesh_importer(mesh) { } -- cgit v1.2.3 From 36d0ea3123743e675333e90c712c69d666fe5710 Mon Sep 17 00:00:00 2001 From: Gaia Clary Date: Sat, 24 Sep 2016 01:47:55 +0200 Subject: Collada: Trying to get rid of some warning messages on linux --- source/blender/collada/ArmatureImporter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/collada/ArmatureImporter.cpp b/source/blender/collada/ArmatureImporter.cpp index 4a5775cabe0..ae43c0a69d2 100644 --- a/source/blender/collada/ArmatureImporter.cpp +++ b/source/blender/collada/ArmatureImporter.cpp @@ -52,10 +52,10 @@ static const char *bc_get_joint_name(T *node) ArmatureImporter::ArmatureImporter(UnitConverter *conv, MeshImporterBase *mesh, Scene *sce, const ImportSettings *import_settings) : + TransformReader(conv), scene(sce), unit_converter(conv), import_settings(import_settings), - TransformReader(conv), empty(NULL), mesh_importer(mesh) { } -- cgit v1.2.3 From bf2c2d43ef3ff955560a6b22be04c8860d0beabe Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Sat, 24 Sep 2016 12:49:43 +1200 Subject: Fix T49441: Grease Pencil - pie menu - brush name field crashes blender Using context.active_gpencil_brush to access the active Grease Pencil brush would result in a crash if trying to rename the brush, because the "ID" pointer was not set. To be backported to 2.78 --- source/blender/editors/screen/screen_context.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/screen/screen_context.c b/source/blender/editors/screen/screen_context.c index 34c51914027..c165bbfd301 100644 --- a/source/blender/editors/screen/screen_context.c +++ b/source/blender/editors/screen/screen_context.c @@ -509,7 +509,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult bGPDbrush *brush = BKE_gpencil_brush_getactive(scene->toolsettings); if (brush) { - CTX_data_pointer_set(result, NULL, &RNA_GPencilBrush, brush); + CTX_data_pointer_set(result, &scene->id, &RNA_GPencilBrush, brush); return 1; } } -- cgit v1.2.3 From a070a5befa1110120547333d84c6e67cae53d648 Mon Sep 17 00:00:00 2001 From: Peter Lu <> Date: Sat, 24 Sep 2016 16:08:10 +0200 Subject: Mesh: added default UVs for Monkey, improved UVs for UV Sphere and Icosphere. Fixes T47488 and T47478. Reviewed By: brecht Differential Revision: https://developer.blender.org/D2224 --- source/blender/bmesh/intern/bmesh_opdefines.c | 3 +- source/blender/bmesh/operators/bmo_primitive.c | 666 +++++++++++++++++++++++-- source/blender/editors/mesh/editmesh_add.c | 9 +- 3 files changed, 639 insertions(+), 39 deletions(-) diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c index 79c2f80d6aa..0d0fdda2c4c 100644 --- a/source/blender/bmesh/intern/bmesh_opdefines.c +++ b/source/blender/bmesh/intern/bmesh_opdefines.c @@ -1635,7 +1635,8 @@ static BMOpDefine bmo_create_icosphere_def = { static BMOpDefine bmo_create_monkey_def = { "create_monkey", /* slots_in */ - {{"matrix", BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */ + {{"matrix", BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */ + {"calc_uvs", BMO_OP_SLOT_BOOL}, /* calculate default UVs */ {{'\0'}}, }, /* slots_out */ diff --git a/source/blender/bmesh/operators/bmo_primitive.c b/source/blender/bmesh/operators/bmo_primitive.c index d2b9fa9efa3..992e89fe127 100644 --- a/source/blender/bmesh/operators/bmo_primitive.c +++ b/source/blender/bmesh/operators/bmo_primitive.c @@ -78,6 +78,31 @@ static const short icoface[20][3] = { {10, 9, 11} }; +static const float icouvs[60][2] = +{ + {0.818181f, 0.000000f}, {0.727272f, 0.157461f}, {0.909090f, 0.157461f}, + {0.727272f, 0.157461f}, {0.636363f, 0.000000f}, {0.545454f, 0.157461f}, + {0.090909f, 0.000000f}, {0.000000f, 0.157461f}, {0.181818f, 0.157461f}, + {0.272727f, 0.000000f}, {0.181818f, 0.157461f}, {0.363636f, 0.157461f}, + {0.454545f, 0.000000f}, {0.363636f, 0.157461f}, {0.545454f, 0.157461f}, + {0.727272f, 0.157461f}, {0.545454f, 0.157461f}, {0.636363f, 0.314921f}, + {0.909090f, 0.157461f}, {0.727272f, 0.157461f}, {0.818181f, 0.314921f}, + {0.181818f, 0.157461f}, {0.000000f, 0.157461f}, {0.090909f, 0.314921f}, + {0.363636f, 0.157461f}, {0.181818f, 0.157461f}, {0.272727f, 0.314921f}, + {0.545454f, 0.157461f}, {0.363636f, 0.157461f}, {0.454545f, 0.314921f}, + {0.727272f, 0.157461f}, {0.636363f, 0.314921f}, {0.818181f, 0.314921f}, + {0.909090f, 0.157461f}, {0.818181f, 0.314921f}, {1.000000f, 0.314921f}, + {0.181818f, 0.157461f}, {0.090909f, 0.314921f}, {0.272727f, 0.314921f}, + {0.363636f, 0.157461f}, {0.272727f, 0.314921f}, {0.454545f, 0.314921f}, + {0.545454f, 0.157461f}, {0.454545f, 0.314921f}, {0.636363f, 0.314921f}, + {0.818181f, 0.314921f}, {0.636363f, 0.314921f}, {0.727272f, 0.472382f}, + {1.000000f, 0.314921f}, {0.818181f, 0.314921f}, {0.909090f, 0.472382f}, + {0.272727f, 0.314921f}, {0.090909f, 0.314921f}, {0.181818f, 0.472382f}, + {0.454545f, 0.314921f}, {0.272727f, 0.314921f}, {0.363636f, 0.472382f}, + {0.636363f, 0.314921f}, {0.454545f, 0.314921f}, {0.545454f, 0.472382f} +}; + + static const int monkeyo = 4; static const int monkeynv = 271; static const int monkeynf = 250; @@ -218,6 +243,510 @@ static signed char monkeyf[250][4] = { {-68, -67, 24, -33}, }; +static const float monkeyuvs[] = +{ + 0.890955f, 0.590063f, 0.870622f, 0.589649f, 0.860081f, 0.560115f, 0.904571f, 0.559404f, + 0.856226f, 0.850547f, 0.868067f, 0.821510f, 0.888398f, 0.821999f, 0.900640f, 0.853232f, + 0.904571f, 0.559404f, 0.860081f, 0.560115f, 0.853018f, 0.521562f, 0.920166f, 0.524546f, + 0.847458f, 0.888748f, 0.856226f, 0.850547f, 0.900640f, 0.853232f, 0.914672f, 0.888748f, + 0.860081f, 0.560115f, 0.828900f, 0.590771f, 0.798481f, 0.569535f, 0.853018f, 0.521562f, + 0.795104f, 0.838402f, 0.826436f, 0.818537f, 0.856226f, 0.850547f, 0.847458f, 0.888748f, + 0.870622f, 0.589649f, 0.854402f, 0.604754f, 0.828900f, 0.590771f, 0.860081f, 0.560115f, + 0.826436f, 0.818537f, 0.852534f, 0.805700f, 0.868067f, 0.821510f, 0.856226f, 0.850547f, + 0.854402f, 0.604754f, 0.854107f, 0.625459f, 0.828171f, 0.633354f, 0.828900f, 0.590771f, + 0.827598f, 0.775964f, 0.853157f, 0.785002f, 0.852534f, 0.805700f, 0.826436f, 0.818537f, + 0.828900f, 0.590771f, 0.828171f, 0.633354f, 0.791018f, 0.645443f, 0.798481f, 0.569535f, + 0.791018f, 0.762238f, 0.827598f, 0.775964f, 0.826436f, 0.818537f, 0.795104f, 0.838402f, + 0.828171f, 0.633354f, 0.855181f, 0.668527f, 0.842358f, 0.702491f, 0.791018f, 0.645443f, + 0.844839f, 0.707525f, 0.856142f, 0.742025f, 0.827598f, 0.775964f, 0.791018f, 0.762238f, + 0.854107f, 0.625459f, 0.867508f, 0.642291f, 0.855181f, 0.668527f, 0.828171f, 0.633354f, + 0.856142f, 0.742025f, 0.867293f, 0.768782f, 0.853157f, 0.785002f, 0.827598f, 0.775964f, + 0.867508f, 0.642291f, 0.890474f, 0.641909f, 0.900375f, 0.666964f, 0.855181f, 0.668527f, + 0.901223f, 0.745592f, 0.890219f, 0.770183f, 0.867293f, 0.768782f, 0.856142f, 0.742025f, + 0.855181f, 0.668527f, 0.900375f, 0.666964f, 0.918898f, 0.699697f, 0.842358f, 0.702491f, + 0.921180f, 0.713713f, 0.901223f, 0.745592f, 0.856142f, 0.742025f, 0.844839f, 0.707525f, + 0.900375f, 0.666964f, 0.931889f, 0.636832f, 0.968392f, 0.645333f, 0.918898f, 0.699697f, + 0.968213f, 0.770220f, 0.931368f, 0.777093f, 0.901223f, 0.745592f, 0.921180f, 0.713713f, + 0.890474f, 0.641909f, 0.905882f, 0.627902f, 0.931889f, 0.636832f, 0.900375f, 0.666964f, + 0.931368f, 0.777093f, 0.904990f, 0.784860f, 0.890219f, 0.770183f, 0.901223f, 0.745592f, + 0.905882f, 0.627902f, 0.906232f, 0.605742f, 0.933717f, 0.593037f, 0.931889f, 0.636832f, + 0.931250f, 0.820926f, 0.904357f, 0.807013f, 0.904990f, 0.784860f, 0.931368f, 0.777093f, + 0.931889f, 0.636832f, 0.933717f, 0.593037f, 0.968392f, 0.573812f, 0.968392f, 0.645333f, + 0.965038f, 0.841671f, 0.931250f, 0.820926f, 0.931368f, 0.777093f, 0.968213f, 0.770220f, + 0.933717f, 0.593037f, 0.904571f, 0.559404f, 0.920166f, 0.524546f, 0.968392f, 0.573812f, + 0.914672f, 0.888748f, 0.900640f, 0.853232f, 0.931250f, 0.820926f, 0.965038f, 0.841671f, + 0.906232f, 0.605742f, 0.890955f, 0.590063f, 0.904571f, 0.559404f, 0.933717f, 0.593037f, + 0.900640f, 0.853232f, 0.888398f, 0.821999f, 0.904357f, 0.807013f, 0.931250f, 0.820926f, + 0.890955f, 0.590063f, 0.906232f, 0.605742f, 0.902359f, 0.607909f, 0.889591f, 0.593275f, + 0.900583f, 0.804677f, 0.904357f, 0.807013f, 0.888398f, 0.821999f, 0.887178f, 0.818729f, + 0.906232f, 0.605742f, 0.905882f, 0.627902f, 0.899781f, 0.626257f, 0.902359f, 0.607909f, + 0.898822f, 0.786233f, 0.904990f, 0.784860f, 0.904357f, 0.807013f, 0.900583f, 0.804677f, + 0.905882f, 0.627902f, 0.890474f, 0.641909f, 0.887842f, 0.636527f, 0.899781f, 0.626257f, + 0.887351f, 0.775442f, 0.890219f, 0.770183f, 0.904990f, 0.784860f, 0.898822f, 0.786233f, + 0.890474f, 0.641909f, 0.867508f, 0.642291f, 0.870908f, 0.635245f, 0.887842f, 0.636527f, + 0.870376f, 0.775972f, 0.867293f, 0.768782f, 0.890219f, 0.770183f, 0.887351f, 0.775442f, + 0.867508f, 0.642291f, 0.854107f, 0.625459f, 0.859881f, 0.623942f, 0.870908f, 0.635245f, + 0.858859f, 0.786774f, 0.853157f, 0.785002f, 0.867293f, 0.768782f, 0.870376f, 0.775972f, + 0.854107f, 0.625459f, 0.854402f, 0.604754f, 0.859664f, 0.608186f, 0.859881f, 0.623942f, + 0.857942f, 0.802505f, 0.852534f, 0.805700f, 0.853157f, 0.785002f, 0.858859f, 0.786774f, + 0.854402f, 0.604754f, 0.870622f, 0.589649f, 0.871664f, 0.593961f, 0.859664f, 0.608186f, + 0.869299f, 0.817249f, 0.868067f, 0.821510f, 0.852534f, 0.805700f, 0.857942f, 0.802505f, + 0.870622f, 0.589649f, 0.890955f, 0.590063f, 0.889591f, 0.593275f, 0.871664f, 0.593961f, + 0.887178f, 0.818729f, 0.888398f, 0.821999f, 0.868067f, 0.821510f, 0.869299f, 0.817249f, + 0.879400f, 0.616512f, 0.871664f, 0.593961f, 0.889591f, 0.593275f, + 0.887178f, 0.818729f, 0.869299f, 0.817249f, 0.878029f, 0.795063f, + 0.859664f, 0.608186f, 0.871664f, 0.593961f, 0.879400f, 0.616512f, + 0.878029f, 0.795063f, 0.869299f, 0.817249f, 0.857942f, 0.802505f, + 0.879400f, 0.616512f, 0.859881f, 0.623942f, 0.859664f, 0.608186f, + 0.857942f, 0.802505f, 0.858859f, 0.786774f, 0.878029f, 0.795063f, + 0.879400f, 0.616512f, 0.870908f, 0.635245f, 0.859881f, 0.623942f, + 0.858859f, 0.786774f, 0.870376f, 0.775972f, 0.878029f, 0.795063f, + 0.879400f, 0.616512f, 0.887842f, 0.636527f, 0.870908f, 0.635245f, + 0.870376f, 0.775972f, 0.887351f, 0.775442f, 0.878029f, 0.795063f, + 0.879400f, 0.616512f, 0.899781f, 0.626257f, 0.887842f, 0.636527f, + 0.887351f, 0.775442f, 0.898822f, 0.786233f, 0.878029f, 0.795063f, + 0.879400f, 0.616512f, 0.902359f, 0.607909f, 0.899781f, 0.626257f, + 0.898822f, 0.786233f, 0.900583f, 0.804677f, 0.878029f, 0.795063f, + 0.879400f, 0.616512f, 0.889591f, 0.593275f, 0.902359f, 0.607909f, + 0.900583f, 0.804677f, 0.887178f, 0.818729f, 0.878029f, 0.795063f, + 0.540260f, 0.053805f, 0.536419f, 0.062072f, 0.518925f, 0.059681f, 0.518916f, 0.050294f, + 0.518925f, 0.059681f, 0.501452f, 0.062043f, 0.497626f, 0.053770f, 0.518916f, 0.050294f, + 0.551930f, 0.058338f, 0.542788f, 0.064089f, 0.536419f, 0.062072f, 0.540260f, 0.053805f, + 0.501452f, 0.062043f, 0.495083f, 0.064047f, 0.485955f, 0.058273f, 0.497626f, 0.053770f, + 0.555073f, 0.061900f, 0.546290f, 0.072669f, 0.542788f, 0.064089f, 0.551930f, 0.058338f, + 0.495083f, 0.064047f, 0.491565f, 0.072625f, 0.482805f, 0.061829f, 0.485955f, 0.058273f, + 0.563812f, 0.076586f, 0.548333f, 0.084893f, 0.546290f, 0.072669f, 0.555073f, 0.061900f, + 0.491565f, 0.072625f, 0.489507f, 0.084858f, 0.474014f, 0.076511f, 0.482805f, 0.061829f, + 0.583135f, 0.108495f, 0.555621f, 0.121749f, 0.548333f, 0.084893f, 0.563812f, 0.076586f, + 0.489507f, 0.084858f, 0.482177f, 0.121781f, 0.454527f, 0.108481f, 0.474014f, 0.076511f, + 0.605512f, 0.165134f, 0.647395f, 0.200502f, 0.621513f, 0.227818f, 0.553118f, 0.209599f, + 0.416514f, 0.229490f, 0.389677f, 0.201890f, 0.432024f, 0.165644f, 0.485339f, 0.210053f, + 0.647395f, 0.200502f, 0.676379f, 0.233241f, 0.664761f, 0.253225f, 0.621513f, 0.227818f, + 0.372747f, 0.256357f, 0.360308f, 0.235899f, 0.389677f, 0.201890f, 0.416514f, 0.229490f, + 0.676379f, 0.233241f, 0.715342f, 0.265392f, 0.683908f, 0.279995f, 0.664761f, 0.253225f, + 0.353696f, 0.284606f, 0.320452f, 0.270303f, 0.360308f, 0.235899f, 0.372747f, 0.256357f, + 0.715342f, 0.265392f, 0.707254f, 0.310054f, 0.687515f, 0.311539f, 0.683908f, 0.279995f, + 0.351187f, 0.317440f, 0.330721f, 0.316853f, 0.320452f, 0.270303f, 0.353696f, 0.284606f, + 0.707254f, 0.310054f, 0.697446f, 0.332673f, 0.676824f, 0.323937f, 0.687515f, 0.311539f, + 0.362723f, 0.329722f, 0.341964f, 0.339667f, 0.330721f, 0.316853f, 0.351187f, 0.317440f, + 0.697446f, 0.332673f, 0.662817f, 0.372521f, 0.639050f, 0.357330f, 0.676824f, 0.323937f, + 0.402772f, 0.362131f, 0.379297f, 0.378686f, 0.341964f, 0.339667f, 0.362723f, 0.329722f, + 0.662817f, 0.372521f, 0.626842f, 0.395792f, 0.618316f, 0.375151f, 0.639050f, 0.357330f, + 0.424583f, 0.379267f, 0.416915f, 0.400552f, 0.379297f, 0.378686f, 0.402772f, 0.362131f, + 0.626842f, 0.395792f, 0.604826f, 0.397804f, 0.600808f, 0.377857f, 0.618316f, 0.375151f, + 0.442396f, 0.381222f, 0.439252f, 0.401540f, 0.416915f, 0.400552f, 0.424583f, 0.379267f, + 0.604826f, 0.397804f, 0.553095f, 0.390512f, 0.559674f, 0.357011f, 0.600808f, 0.377857f, + 0.482938f, 0.358497f, 0.490934f, 0.391862f, 0.439252f, 0.401540f, 0.442396f, 0.381222f, + 0.553095f, 0.390512f, 0.521923f, 0.386009f, 0.521086f, 0.343868f, 0.559674f, 0.357011f, + 0.521086f, 0.343868f, 0.521923f, 0.386009f, 0.490934f, 0.391862f, 0.482938f, 0.358497f, + 0.577279f, 0.340156f, 0.599845f, 0.344815f, 0.600808f, 0.377857f, 0.559674f, 0.357011f, + 0.442396f, 0.381222f, 0.441977f, 0.347815f, 0.464579f, 0.342230f, 0.482938f, 0.358497f, + 0.599845f, 0.344815f, 0.615546f, 0.342005f, 0.618316f, 0.375151f, 0.600808f, 0.377857f, + 0.424583f, 0.379267f, 0.425972f, 0.345582f, 0.441977f, 0.347815f, 0.442396f, 0.381222f, + 0.634472f, 0.332311f, 0.639050f, 0.357330f, 0.618316f, 0.375151f, 0.615546f, 0.342005f, + 0.424583f, 0.379267f, 0.402772f, 0.362131f, 0.406362f, 0.336480f, 0.425972f, 0.345582f, + 0.662406f, 0.312804f, 0.676824f, 0.323937f, 0.639050f, 0.357330f, 0.634472f, 0.332311f, + 0.402772f, 0.362131f, 0.362723f, 0.329722f, 0.377061f, 0.317685f, 0.406362f, 0.336480f, + 0.668440f, 0.297958f, 0.687515f, 0.311539f, 0.676824f, 0.323937f, 0.662406f, 0.312804f, + 0.362723f, 0.329722f, 0.351187f, 0.317440f, 0.370304f, 0.302644f, 0.377061f, 0.317685f, + 0.664101f, 0.277872f, 0.683908f, 0.279995f, 0.687515f, 0.311539f, 0.668440f, 0.297958f, + 0.351187f, 0.317440f, 0.353696f, 0.284606f, 0.374100f, 0.281778f, 0.370304f, 0.302644f, + 0.639236f, 0.253047f, 0.664761f, 0.253225f, 0.683908f, 0.279995f, 0.664101f, 0.277872f, + 0.353696f, 0.284606f, 0.372747f, 0.256357f, 0.398938f, 0.255633f, 0.374100f, 0.281778f, + 0.613992f, 0.242662f, 0.621513f, 0.227818f, 0.664761f, 0.253225f, 0.639236f, 0.253047f, + 0.372747f, 0.256357f, 0.416514f, 0.229490f, 0.424464f, 0.244473f, 0.398938f, 0.255633f, + 0.572941f, 0.258564f, 0.553118f, 0.209599f, 0.621513f, 0.227818f, 0.613992f, 0.242662f, + 0.416514f, 0.229490f, 0.485339f, 0.210053f, 0.466409f, 0.259709f, 0.424464f, 0.244473f, + 0.572941f, 0.258564f, 0.563905f, 0.272007f, 0.519760f, 0.248864f, 0.553118f, 0.209599f, + 0.519760f, 0.248864f, 0.475886f, 0.273078f, 0.466409f, 0.259709f, 0.485339f, 0.210053f, + 0.577279f, 0.340156f, 0.559674f, 0.357011f, 0.521086f, 0.343868f, 0.558527f, 0.316594f, + 0.521086f, 0.343868f, 0.482938f, 0.358497f, 0.464579f, 0.342230f, 0.482619f, 0.317843f, + 0.558527f, 0.316594f, 0.521086f, 0.343868f, 0.520277f, 0.294764f, 0.556923f, 0.291214f, + 0.520277f, 0.294764f, 0.521086f, 0.343868f, 0.482619f, 0.317843f, 0.483433f, 0.292249f, + 0.519760f, 0.248864f, 0.563905f, 0.272007f, 0.556923f, 0.291214f, 0.520277f, 0.294764f, + 0.483433f, 0.292249f, 0.475886f, 0.273078f, 0.519760f, 0.248864f, 0.520277f, 0.294764f, + 0.525483f, 0.068967f, 0.518928f, 0.067899f, 0.518925f, 0.059681f, 0.536419f, 0.062072f, + 0.518925f, 0.059681f, 0.518928f, 0.067899f, 0.512375f, 0.068956f, 0.501452f, 0.062043f, + 0.531231f, 0.073829f, 0.525483f, 0.068967f, 0.536419f, 0.062072f, 0.542788f, 0.064089f, + 0.501452f, 0.062043f, 0.512375f, 0.068956f, 0.506626f, 0.073811f, 0.495083f, 0.064047f, + 0.531019f, 0.087431f, 0.531231f, 0.073829f, 0.542788f, 0.064089f, 0.546290f, 0.072669f, + 0.495083f, 0.064047f, 0.506626f, 0.073811f, 0.506827f, 0.087416f, 0.491565f, 0.072625f, + 0.555621f, 0.121749f, 0.532042f, 0.127713f, 0.532669f, 0.090920f, 0.548333f, 0.084893f, + 0.505177f, 0.090908f, 0.505828f, 0.127728f, 0.482177f, 0.121781f, 0.489507f, 0.084858f, + 0.531019f, 0.087431f, 0.546290f, 0.072669f, 0.548333f, 0.084893f, 0.532669f, 0.090920f, + 0.489507f, 0.084858f, 0.491565f, 0.072625f, 0.506827f, 0.087416f, 0.505177f, 0.090908f, + 0.538112f, 0.158382f, 0.518981f, 0.151749f, 0.518941f, 0.128358f, 0.532042f, 0.127713f, + 0.518941f, 0.128358f, 0.518981f, 0.151749f, 0.499851f, 0.158434f, 0.505828f, 0.127728f, + 0.532669f, 0.090920f, 0.532042f, 0.127713f, 0.518941f, 0.128358f, 0.518925f, 0.093952f, + 0.518941f, 0.128358f, 0.505828f, 0.127728f, 0.505177f, 0.090908f, 0.518925f, 0.093952f, + 0.518927f, 0.085180f, 0.531019f, 0.087431f, 0.532669f, 0.090920f, 0.518925f, 0.093952f, + 0.505177f, 0.090908f, 0.506827f, 0.087416f, 0.518927f, 0.085180f, 0.518925f, 0.093952f, + 0.548362f, 0.173560f, 0.537959f, 0.175966f, 0.535214f, 0.166808f, 0.538112f, 0.158382f, + 0.502799f, 0.166857f, 0.500100f, 0.176033f, 0.489683f, 0.173693f, 0.499851f, 0.158434f, + 0.544281f, 0.193366f, 0.537248f, 0.187577f, 0.537959f, 0.175966f, 0.548362f, 0.173560f, + 0.500100f, 0.176033f, 0.500890f, 0.187571f, 0.493996f, 0.193428f, 0.489683f, 0.173693f, + 0.519841f, 0.200843f, 0.528757f, 0.191785f, 0.537248f, 0.187577f, 0.544281f, 0.193366f, + 0.500890f, 0.187571f, 0.509219f, 0.191626f, 0.519841f, 0.200843f, 0.493996f, 0.193428f, + 0.517577f, 0.190607f, 0.519132f, 0.185382f, 0.528757f, 0.191785f, 0.519841f, 0.200843f, + 0.509219f, 0.191626f, 0.519132f, 0.185382f, 0.517577f, 0.190607f, 0.519841f, 0.200843f, + 0.518981f, 0.151749f, 0.538112f, 0.158382f, 0.535214f, 0.166808f, 0.518998f, 0.159028f, + 0.502799f, 0.166857f, 0.499851f, 0.158434f, 0.518981f, 0.151749f, 0.518998f, 0.159028f, + 0.518998f, 0.159028f, 0.535214f, 0.166808f, 0.531131f, 0.171631f, 0.519016f, 0.165599f, + 0.506910f, 0.171667f, 0.502799f, 0.166857f, 0.518998f, 0.159028f, 0.519016f, 0.165599f, + 0.519132f, 0.185382f, 0.519099f, 0.179457f, 0.528222f, 0.186316f, 0.528757f, 0.191785f, + 0.509787f, 0.186260f, 0.519099f, 0.179457f, 0.519132f, 0.185382f, 0.509219f, 0.191626f, + 0.528757f, 0.191785f, 0.528222f, 0.186316f, 0.533528f, 0.184215f, 0.537248f, 0.187577f, + 0.504547f, 0.184206f, 0.509787f, 0.186260f, 0.509219f, 0.191626f, 0.500890f, 0.187571f, + 0.537248f, 0.187577f, 0.533528f, 0.184215f, 0.533449f, 0.176739f, 0.537959f, 0.175966f, + 0.504604f, 0.176791f, 0.504547f, 0.184206f, 0.500890f, 0.187571f, 0.500100f, 0.176033f, + 0.537959f, 0.175966f, 0.533449f, 0.176739f, 0.531131f, 0.171631f, 0.535214f, 0.166808f, + 0.506910f, 0.171667f, 0.504604f, 0.176791f, 0.500100f, 0.176033f, 0.502799f, 0.166857f, + 0.519099f, 0.179457f, 0.533449f, 0.176739f, 0.533528f, 0.184215f, 0.528222f, 0.186316f, + 0.504547f, 0.184206f, 0.504604f, 0.176791f, 0.519099f, 0.179457f, 0.509787f, 0.186260f, + 0.519099f, 0.179457f, 0.519016f, 0.165599f, 0.531131f, 0.171631f, 0.533449f, 0.176739f, + 0.506910f, 0.171667f, 0.519016f, 0.165599f, 0.519099f, 0.179457f, 0.504604f, 0.176791f, + 0.519841f, 0.200843f, 0.544281f, 0.193366f, 0.553118f, 0.209599f, 0.519760f, 0.248864f, + 0.485339f, 0.210053f, 0.493996f, 0.193428f, 0.519841f, 0.200843f, 0.519760f, 0.248864f, + 0.544281f, 0.193366f, 0.548362f, 0.173560f, 0.561572f, 0.167779f, 0.553118f, 0.209599f, + 0.476363f, 0.167996f, 0.489683f, 0.173693f, 0.493996f, 0.193428f, 0.485339f, 0.210053f, + 0.548362f, 0.173560f, 0.538112f, 0.158382f, 0.559475f, 0.149319f, 0.561572f, 0.167779f, + 0.478371f, 0.149447f, 0.499851f, 0.158434f, 0.489683f, 0.173693f, 0.476363f, 0.167996f, + 0.538112f, 0.158382f, 0.532042f, 0.127713f, 0.555621f, 0.121749f, 0.559475f, 0.149319f, + 0.482177f, 0.121781f, 0.505828f, 0.127728f, 0.499851f, 0.158434f, 0.478371f, 0.149447f, + 0.583135f, 0.108495f, 0.596138f, 0.133426f, 0.559475f, 0.149319f, 0.555621f, 0.121749f, + 0.478371f, 0.149447f, 0.441395f, 0.133592f, 0.454527f, 0.108481f, 0.482177f, 0.121781f, + 0.596138f, 0.133426f, 0.601169f, 0.147885f, 0.561572f, 0.167779f, 0.559475f, 0.149319f, + 0.476363f, 0.167996f, 0.436337f, 0.148194f, 0.441395f, 0.133592f, 0.478371f, 0.149447f, + 0.605512f, 0.165134f, 0.553118f, 0.209599f, 0.561572f, 0.167779f, 0.601169f, 0.147885f, + 0.476363f, 0.167996f, 0.485339f, 0.210053f, 0.432024f, 0.165644f, 0.436337f, 0.148194f, + 0.531019f, 0.087431f, 0.518927f, 0.085180f, 0.518925f, 0.083865f, 0.528933f, 0.084957f, + 0.518925f, 0.083865f, 0.518927f, 0.085180f, 0.506827f, 0.087416f, 0.508915f, 0.084945f, + 0.531231f, 0.073829f, 0.531019f, 0.087431f, 0.528933f, 0.084957f, 0.529036f, 0.075429f, + 0.508915f, 0.084945f, 0.506827f, 0.087416f, 0.506626f, 0.073811f, 0.508820f, 0.075415f, + 0.525483f, 0.068967f, 0.531231f, 0.073829f, 0.529036f, 0.075429f, 0.523751f, 0.070508f, + 0.508820f, 0.075415f, 0.506626f, 0.073811f, 0.512375f, 0.068956f, 0.514106f, 0.070501f, + 0.518928f, 0.067899f, 0.525483f, 0.068967f, 0.523751f, 0.070508f, 0.518929f, 0.069468f, + 0.514106f, 0.070501f, 0.512375f, 0.068956f, 0.518928f, 0.067899f, 0.518929f, 0.069468f, + 0.518929f, 0.069468f, 0.523751f, 0.070508f, 0.521560f, 0.074970f, 0.518928f, 0.074259f, + 0.516297f, 0.074966f, 0.514106f, 0.070501f, 0.518929f, 0.069468f, 0.518928f, 0.074259f, + 0.523751f, 0.070508f, 0.529036f, 0.075429f, 0.524236f, 0.076691f, 0.521560f, 0.074970f, + 0.513619f, 0.076684f, 0.508820f, 0.075415f, 0.514106f, 0.070501f, 0.516297f, 0.074966f, + 0.529036f, 0.075429f, 0.528933f, 0.084957f, 0.524601f, 0.079886f, 0.524236f, 0.076691f, + 0.513252f, 0.079879f, 0.508915f, 0.084945f, 0.508820f, 0.075415f, 0.513619f, 0.076684f, + 0.528933f, 0.084957f, 0.518925f, 0.083865f, 0.518926f, 0.079331f, 0.524601f, 0.079886f, + 0.518926f, 0.079331f, 0.518925f, 0.083865f, 0.508915f, 0.084945f, 0.513252f, 0.079879f, + 0.518926f, 0.079331f, 0.518928f, 0.074259f, 0.521560f, 0.074970f, 0.524601f, 0.079886f, + 0.516297f, 0.074966f, 0.518928f, 0.074259f, 0.518926f, 0.079331f, 0.513252f, 0.079879f, + 0.524601f, 0.079886f, 0.521560f, 0.074970f, 0.524236f, 0.076691f, + 0.513619f, 0.076684f, 0.516297f, 0.074966f, 0.513252f, 0.079879f, + 0.556923f, 0.291214f, 0.563905f, 0.272007f, 0.571787f, 0.277295f, 0.568351f, 0.292904f, + 0.468070f, 0.278617f, 0.475886f, 0.273078f, 0.483433f, 0.292249f, 0.471978f, 0.294282f, + 0.558527f, 0.316594f, 0.556923f, 0.291214f, 0.568351f, 0.292904f, 0.573085f, 0.311386f, + 0.471978f, 0.294282f, 0.483433f, 0.292249f, 0.482619f, 0.317843f, 0.467790f, 0.313081f, + 0.577279f, 0.340156f, 0.558527f, 0.316594f, 0.573085f, 0.311386f, 0.584855f, 0.327708f, + 0.467790f, 0.313081f, 0.482619f, 0.317843f, 0.464579f, 0.342230f, 0.456477f, 0.329961f, + 0.563905f, 0.272007f, 0.572941f, 0.258564f, 0.580734f, 0.266620f, 0.571787f, 0.277295f, + 0.458737f, 0.268049f, 0.466409f, 0.259709f, 0.475886f, 0.273078f, 0.468070f, 0.278617f, + 0.572941f, 0.258564f, 0.613992f, 0.242662f, 0.611720f, 0.255725f, 0.580734f, 0.266620f, + 0.427062f, 0.257728f, 0.424464f, 0.244473f, 0.466409f, 0.259709f, 0.458737f, 0.268049f, + 0.613992f, 0.242662f, 0.639236f, 0.253047f, 0.632494f, 0.262853f, 0.611720f, 0.255725f, + 0.406068f, 0.265508f, 0.398938f, 0.255633f, 0.424464f, 0.244473f, 0.427062f, 0.257728f, + 0.639236f, 0.253047f, 0.664101f, 0.277872f, 0.653658f, 0.279971f, 0.632494f, 0.262853f, + 0.384904f, 0.283634f, 0.374100f, 0.281778f, 0.398938f, 0.255633f, 0.406068f, 0.265508f, + 0.664101f, 0.277872f, 0.668440f, 0.297958f, 0.656064f, 0.297636f, 0.653658f, 0.279971f, + 0.383015f, 0.301864f, 0.370304f, 0.302644f, 0.374100f, 0.281778f, 0.384904f, 0.283634f, + 0.668440f, 0.297958f, 0.662406f, 0.312804f, 0.652752f, 0.310186f, 0.656064f, 0.297636f, + 0.386858f, 0.314615f, 0.377061f, 0.317685f, 0.370304f, 0.302644f, 0.383015f, 0.301864f, + 0.662406f, 0.312804f, 0.634472f, 0.332311f, 0.629040f, 0.323864f, 0.652752f, 0.310186f, + 0.411556f, 0.327673f, 0.406362f, 0.336480f, 0.377061f, 0.317685f, 0.386858f, 0.314615f, + 0.634472f, 0.332311f, 0.615546f, 0.342005f, 0.614408f, 0.331972f, 0.629040f, 0.323864f, + 0.426727f, 0.335361f, 0.425972f, 0.345582f, 0.406362f, 0.336480f, 0.411556f, 0.327673f, + 0.615546f, 0.342005f, 0.599845f, 0.344815f, 0.601033f, 0.333624f, 0.614408f, 0.331972f, + 0.440344f, 0.336537f, 0.441977f, 0.347815f, 0.425972f, 0.345582f, 0.426727f, 0.335361f, + 0.599845f, 0.344815f, 0.577279f, 0.340156f, 0.584855f, 0.327708f, 0.601033f, 0.333624f, + 0.456477f, 0.329961f, 0.464579f, 0.342230f, 0.441977f, 0.347815f, 0.440344f, 0.336537f, + 0.601033f, 0.333624f, 0.584855f, 0.327708f, 0.590644f, 0.321516f, 0.601799f, 0.328453f, + 0.450408f, 0.323919f, 0.456477f, 0.329961f, 0.440344f, 0.336537f, 0.439372f, 0.331331f, + 0.614408f, 0.331972f, 0.601033f, 0.333624f, 0.601799f, 0.328453f, 0.613335f, 0.327083f, + 0.439372f, 0.331331f, 0.440344f, 0.336537f, 0.426727f, 0.335361f, 0.427623f, 0.330358f, + 0.629040f, 0.323864f, 0.614408f, 0.331972f, 0.613335f, 0.327083f, 0.626851f, 0.320513f, + 0.427623f, 0.330358f, 0.426727f, 0.335361f, 0.411556f, 0.327673f, 0.413648f, 0.324175f, + 0.652752f, 0.310186f, 0.629040f, 0.323864f, 0.626851f, 0.320513f, 0.646248f, 0.306421f, + 0.413648f, 0.324175f, 0.411556f, 0.327673f, 0.386858f, 0.314615f, 0.393381f, 0.310510f, + 0.656064f, 0.297636f, 0.652752f, 0.310186f, 0.646248f, 0.306421f, 0.649541f, 0.296225f, + 0.393381f, 0.310510f, 0.386858f, 0.314615f, 0.383015f, 0.301864f, 0.389662f, 0.300183f, + 0.653658f, 0.279971f, 0.656064f, 0.297636f, 0.649541f, 0.296225f, 0.647785f, 0.283486f, + 0.389662f, 0.300183f, 0.383015f, 0.301864f, 0.384904f, 0.283634f, 0.391040f, 0.287071f, + 0.632494f, 0.262853f, 0.653658f, 0.279971f, 0.647785f, 0.283486f, 0.629829f, 0.267263f, + 0.391040f, 0.287071f, 0.384904f, 0.283634f, 0.406068f, 0.265508f, 0.408893f, 0.269959f, + 0.611720f, 0.255725f, 0.632494f, 0.262853f, 0.629829f, 0.267263f, 0.612641f, 0.261560f, + 0.408893f, 0.269959f, 0.406068f, 0.265508f, 0.427062f, 0.257728f, 0.426254f, 0.263693f, + 0.580734f, 0.266620f, 0.611720f, 0.255725f, 0.612641f, 0.261560f, 0.585166f, 0.270991f, + 0.426254f, 0.263693f, 0.427062f, 0.257728f, 0.458737f, 0.268049f, 0.454369f, 0.272583f, + 0.571787f, 0.277295f, 0.580734f, 0.266620f, 0.585166f, 0.270991f, 0.578124f, 0.281900f, + 0.454369f, 0.272583f, 0.458737f, 0.268049f, 0.468070f, 0.278617f, 0.461798f, 0.283441f, + 0.584855f, 0.327708f, 0.573085f, 0.311386f, 0.579548f, 0.309340f, 0.590644f, 0.321516f, + 0.461204f, 0.311233f, 0.467790f, 0.313081f, 0.456477f, 0.329961f, 0.450408f, 0.323919f, + 0.573085f, 0.311386f, 0.568351f, 0.292904f, 0.577524f, 0.293776f, 0.579548f, 0.309340f, + 0.462754f, 0.295432f, 0.471978f, 0.294282f, 0.467790f, 0.313081f, 0.461204f, 0.311233f, + 0.568351f, 0.292904f, 0.571787f, 0.277295f, 0.578124f, 0.281900f, 0.577524f, 0.293776f, + 0.461798f, 0.283441f, 0.468070f, 0.278617f, 0.471978f, 0.294282f, 0.462754f, 0.295432f, + 0.521923f, 0.386009f, 0.553095f, 0.390512f, 0.553209f, 0.433063f, 0.523031f, 0.433628f, + 0.492809f, 0.434538f, 0.490934f, 0.391862f, 0.521923f, 0.386009f, 0.523031f, 0.433628f, + 0.553095f, 0.390512f, 0.604826f, 0.397804f, 0.609819f, 0.431516f, 0.553209f, 0.433063f, + 0.435860f, 0.435740f, 0.439252f, 0.401540f, 0.490934f, 0.391862f, 0.492809f, 0.434538f, + 0.604826f, 0.397804f, 0.626842f, 0.395792f, 0.648174f, 0.419316f, 0.609819f, 0.431516f, + 0.396518f, 0.425416f, 0.416915f, 0.400552f, 0.439252f, 0.401540f, 0.435860f, 0.435740f, + 0.626842f, 0.395792f, 0.662817f, 0.372521f, 0.692106f, 0.388274f, 0.648174f, 0.419316f, + 0.350292f, 0.396229f, 0.379297f, 0.378686f, 0.416915f, 0.400552f, 0.396518f, 0.425416f, + 0.662817f, 0.372521f, 0.697446f, 0.332673f, 0.726332f, 0.341754f, 0.692106f, 0.388274f, + 0.312756f, 0.350588f, 0.341964f, 0.339667f, 0.379297f, 0.378686f, 0.350292f, 0.396229f, + 0.697446f, 0.332673f, 0.707254f, 0.310054f, 0.735879f, 0.312112f, 0.726332f, 0.341754f, + 0.301067f, 0.320593f, 0.330721f, 0.316853f, 0.341964f, 0.339667f, 0.312756f, 0.350588f, + 0.707254f, 0.310054f, 0.715342f, 0.265392f, 0.729900f, 0.256393f, 0.735879f, 0.312112f, + 0.304876f, 0.261087f, 0.320452f, 0.270303f, 0.330721f, 0.316853f, 0.301067f, 0.320593f, + 0.715342f, 0.265392f, 0.676379f, 0.233241f, 0.698172f, 0.216906f, 0.729900f, 0.256393f, + 0.337414f, 0.219179f, 0.360308f, 0.235899f, 0.320452f, 0.270303f, 0.304876f, 0.261087f, + 0.676379f, 0.233241f, 0.647395f, 0.200502f, 0.663103f, 0.190671f, 0.698172f, 0.216906f, + 0.373474f, 0.191872f, 0.389677f, 0.201890f, 0.360308f, 0.235899f, 0.337414f, 0.219179f, + 0.626908f, 0.015608f, 0.649444f, 0.022378f, 0.660451f, 0.076084f, 0.621440f, 0.048089f, + 0.376796f, 0.075296f, 0.388827f, 0.021586f, 0.411318f, 0.015131f, 0.416419f, 0.047631f, + 0.567460f, 0.000144f, 0.626908f, 0.015608f, 0.621440f, 0.048089f, 0.577206f, 0.032801f, + 0.416419f, 0.047631f, 0.411318f, 0.015131f, 0.470636f, 0.000144f, 0.460782f, 0.032656f, + 0.518922f, 0.024886f, 0.567460f, 0.000144f, 0.577206f, 0.032801f, 0.547413f, 0.041724f, + 0.460782f, 0.032656f, 0.470636f, 0.000144f, 0.518922f, 0.024886f, 0.490511f, 0.041669f, + 0.540260f, 0.053805f, 0.518916f, 0.050294f, 0.518922f, 0.024886f, 0.547413f, 0.041724f, + 0.518922f, 0.024886f, 0.518916f, 0.050294f, 0.497626f, 0.053770f, 0.490511f, 0.041669f, + 0.551930f, 0.058338f, 0.540260f, 0.053805f, 0.547413f, 0.041724f, 0.558059f, 0.053871f, + 0.490511f, 0.041669f, 0.497626f, 0.053770f, 0.485955f, 0.058273f, 0.479842f, 0.053785f, + 0.555073f, 0.061900f, 0.551930f, 0.058338f, 0.558059f, 0.053871f, 0.576951f, 0.057998f, + 0.479842f, 0.053785f, 0.485955f, 0.058273f, 0.482805f, 0.061829f, 0.460920f, 0.057845f, + 0.563812f, 0.076586f, 0.555073f, 0.061900f, 0.576951f, 0.057998f, 0.611687f, 0.078268f, + 0.460920f, 0.057845f, 0.482805f, 0.061829f, 0.474014f, 0.076511f, 0.425932f, 0.077985f, + 0.576951f, 0.057998f, 0.577206f, 0.032801f, 0.621440f, 0.048089f, 0.611687f, 0.078268f, + 0.416419f, 0.047631f, 0.460782f, 0.032656f, 0.460920f, 0.057845f, 0.425932f, 0.077985f, + 0.576951f, 0.057998f, 0.558059f, 0.053871f, 0.547413f, 0.041724f, 0.577206f, 0.032801f, + 0.490511f, 0.041669f, 0.479842f, 0.053785f, 0.460920f, 0.057845f, 0.460782f, 0.032656f, + 0.626663f, 0.111357f, 0.611687f, 0.078268f, 0.621440f, 0.048089f, 0.660451f, 0.076084f, + 0.416419f, 0.047631f, 0.425932f, 0.077985f, 0.410618f, 0.111244f, 0.376796f, 0.075296f, + 0.583135f, 0.108495f, 0.563812f, 0.076586f, 0.611687f, 0.078268f, 0.626663f, 0.111357f, + 0.425932f, 0.077985f, 0.474014f, 0.076511f, 0.454527f, 0.108481f, 0.410618f, 0.111244f, + 0.596138f, 0.133426f, 0.629482f, 0.130456f, 0.623495f, 0.146796f, 0.601169f, 0.147885f, + 0.413741f, 0.147158f, 0.407648f, 0.130594f, 0.441395f, 0.133592f, 0.436337f, 0.148194f, + 0.583135f, 0.108495f, 0.626663f, 0.111357f, 0.629482f, 0.130456f, 0.596138f, 0.133426f, + 0.407648f, 0.130594f, 0.410618f, 0.111244f, 0.454527f, 0.108481f, 0.441395f, 0.133592f, + 0.605512f, 0.165134f, 0.601169f, 0.147885f, 0.623495f, 0.146796f, 0.619303f, 0.159841f, + 0.413741f, 0.147158f, 0.436337f, 0.148194f, 0.432024f, 0.165644f, 0.418035f, 0.160361f, + 0.605512f, 0.165134f, 0.619303f, 0.159841f, 0.663103f, 0.190671f, 0.647395f, 0.200502f, + 0.373474f, 0.191872f, 0.418035f, 0.160361f, 0.432024f, 0.165644f, 0.389677f, 0.201890f, + 0.945900f, 0.079569f, 0.886245f, 0.121777f, 0.849114f, 0.099732f, 0.891780f, 0.036916f, + 0.183115f, 0.092127f, 0.141314f, 0.112482f, 0.078961f, 0.060719f, 0.142277f, 0.021467f, + 0.891780f, 0.036916f, 0.849114f, 0.099732f, 0.788458f, 0.080826f, 0.805584f, 0.010786f, + 0.246353f, 0.076510f, 0.183115f, 0.092127f, 0.142277f, 0.021467f, 0.232648f, 0.003484f, + 0.805584f, 0.010786f, 0.788458f, 0.080826f, 0.687018f, 0.077204f, 0.672384f, 0.022201f, + 0.349875f, 0.075955f, 0.246353f, 0.076510f, 0.232648f, 0.003484f, 0.365979f, 0.020991f, + 0.672384f, 0.022201f, 0.687018f, 0.077204f, 0.660451f, 0.076084f, 0.649444f, 0.022378f, + 0.376796f, 0.075296f, 0.349875f, 0.075955f, 0.365979f, 0.020991f, 0.388827f, 0.021586f, + 0.626663f, 0.111357f, 0.660451f, 0.076084f, 0.687018f, 0.077204f, 0.629482f, 0.130456f, + 0.349875f, 0.075955f, 0.376796f, 0.075296f, 0.410618f, 0.111244f, 0.407648f, 0.130594f, + 0.729900f, 0.256393f, 0.698172f, 0.216906f, 0.760215f, 0.193244f, 0.789046f, 0.233323f, + 0.271553f, 0.193871f, 0.337414f, 0.219179f, 0.304876f, 0.261087f, 0.241255f, 0.236977f, + 0.994525f, 0.167705f, 0.909112f, 0.183261f, 0.886245f, 0.121777f, 0.945900f, 0.079569f, + 0.141314f, 0.112482f, 0.107928f, 0.179083f, 0.011829f, 0.155367f, 0.078961f, 0.060719f, + 0.911671f, 0.402429f, 0.862868f, 0.338556f, 0.894128f, 0.301884f, 0.962901f, 0.344752f, + 0.123776f, 0.315519f, 0.160557f, 0.356821f, 0.106400f, 0.432652f, 0.043968f, 0.367038f, + 0.962901f, 0.344752f, 0.894128f, 0.301884f, 0.915360f, 0.259804f, 0.999856f, 0.254640f, + 0.098965f, 0.266968f, 0.123776f, 0.315519f, 0.043968f, 0.367038f, 0.000144f, 0.259113f, + 0.999856f, 0.254640f, 0.915360f, 0.259804f, 0.909112f, 0.183261f, 0.994525f, 0.167705f, + 0.107928f, 0.179083f, 0.098965f, 0.266968f, 0.000144f, 0.259113f, 0.011829f, 0.155367f, + 0.749542f, 0.334683f, 0.735879f, 0.312112f, 0.766337f, 0.300809f, 0.789162f, 0.313727f, + 0.267408f, 0.310142f, 0.301067f, 0.320593f, 0.288183f, 0.346496f, 0.242992f, 0.325552f, + 0.789162f, 0.313727f, 0.766337f, 0.300809f, 0.815314f, 0.276388f, 0.846174f, 0.293397f, + 0.213065f, 0.285164f, 0.267408f, 0.310142f, 0.242992f, 0.325552f, 0.178537f, 0.304983f, + 0.846174f, 0.293397f, 0.815314f, 0.276388f, 0.845007f, 0.256352f, 0.873517f, 0.265922f, + 0.179662f, 0.263312f, 0.213065f, 0.285164f, 0.178537f, 0.304983f, 0.147089f, 0.274284f, + 0.873517f, 0.265922f, 0.845007f, 0.256352f, 0.859075f, 0.228168f, 0.886999f, 0.233769f, + 0.162803f, 0.231720f, 0.179662f, 0.263312f, 0.147089f, 0.274284f, 0.131514f, 0.237587f, + 0.842355f, 0.195160f, 0.875030f, 0.184705f, 0.886999f, 0.233769f, 0.859075f, 0.228168f, + 0.131514f, 0.237587f, 0.145224f, 0.182749f, 0.176788f, 0.196179f, 0.162803f, 0.231720f, + 0.909112f, 0.183261f, 0.915360f, 0.259804f, 0.886999f, 0.233769f, 0.875030f, 0.184705f, + 0.131514f, 0.237587f, 0.098965f, 0.266968f, 0.107928f, 0.179083f, 0.145224f, 0.182749f, + 0.915360f, 0.259804f, 0.894128f, 0.301884f, 0.873517f, 0.265922f, 0.886999f, 0.233769f, + 0.147089f, 0.274284f, 0.123776f, 0.315519f, 0.098965f, 0.266968f, 0.131514f, 0.237587f, + 0.894128f, 0.301884f, 0.862868f, 0.338556f, 0.846174f, 0.293397f, 0.873517f, 0.265922f, + 0.178537f, 0.304983f, 0.160557f, 0.356821f, 0.123776f, 0.315519f, 0.147089f, 0.274284f, + 0.862868f, 0.338556f, 0.794286f, 0.364062f, 0.789162f, 0.313727f, 0.846174f, 0.293397f, + 0.242992f, 0.325552f, 0.239776f, 0.382592f, 0.160557f, 0.356821f, 0.178537f, 0.304983f, + 0.770185f, 0.379538f, 0.749542f, 0.334683f, 0.789162f, 0.313727f, 0.794286f, 0.364062f, + 0.242992f, 0.325552f, 0.288183f, 0.346496f, 0.268122f, 0.398737f, 0.239776f, 0.382592f, + 0.845499f, 0.449967f, 0.794286f, 0.364062f, 0.862868f, 0.338556f, 0.911671f, 0.402429f, + 0.160557f, 0.356821f, 0.239776f, 0.382592f, 0.185281f, 0.484099f, 0.106400f, 0.432652f, + 0.815858f, 0.445381f, 0.770572f, 0.444261f, 0.755700f, 0.418603f, 0.770185f, 0.379538f, + 0.287033f, 0.442912f, 0.271364f, 0.473316f, 0.219260f, 0.477186f, 0.268122f, 0.398737f, + 0.815858f, 0.445381f, 0.770185f, 0.379538f, 0.794286f, 0.364062f, 0.845499f, 0.449967f, + 0.239776f, 0.382592f, 0.268122f, 0.398737f, 0.219260f, 0.477186f, 0.185281f, 0.484099f, + 0.819845f, 0.468071f, 0.815858f, 0.445381f, 0.845499f, 0.449967f, + 0.185281f, 0.484099f, 0.219260f, 0.477186f, 0.215894f, 0.503605f, + 0.735879f, 0.312112f, 0.729900f, 0.256393f, 0.789046f, 0.233323f, 0.766337f, 0.300809f, + 0.241255f, 0.236977f, 0.304876f, 0.261087f, 0.301067f, 0.320593f, 0.267408f, 0.310142f, + 0.789046f, 0.233323f, 0.809631f, 0.233887f, 0.815314f, 0.276388f, 0.766337f, 0.300809f, + 0.213065f, 0.285164f, 0.219168f, 0.237388f, 0.241255f, 0.236977f, 0.267408f, 0.310142f, + 0.809631f, 0.233887f, 0.829287f, 0.219562f, 0.845007f, 0.256352f, 0.815314f, 0.276388f, + 0.179662f, 0.263312f, 0.199067f, 0.222464f, 0.219168f, 0.237388f, 0.213065f, 0.285164f, + 0.842355f, 0.195160f, 0.859075f, 0.228168f, 0.845007f, 0.256352f, 0.829287f, 0.219562f, + 0.179662f, 0.263312f, 0.162803f, 0.231720f, 0.176788f, 0.196179f, 0.199067f, 0.222464f, + 0.687018f, 0.077204f, 0.788458f, 0.080826f, 0.786480f, 0.117591f, 0.715482f, 0.139727f, + 0.246666f, 0.114850f, 0.246353f, 0.076510f, 0.349875f, 0.075955f, 0.319538f, 0.139409f, + 0.760215f, 0.193244f, 0.715482f, 0.139727f, 0.786480f, 0.117591f, 0.785486f, 0.152330f, + 0.246666f, 0.114850f, 0.319538f, 0.139409f, 0.271553f, 0.193871f, 0.245969f, 0.151002f, + 0.698172f, 0.216906f, 0.663103f, 0.190671f, 0.715482f, 0.139727f, 0.760215f, 0.193244f, + 0.319538f, 0.139409f, 0.373474f, 0.191872f, 0.337414f, 0.219179f, 0.271553f, 0.193871f, + 0.663103f, 0.190671f, 0.623495f, 0.146796f, 0.629482f, 0.130456f, 0.715482f, 0.139727f, + 0.407648f, 0.130594f, 0.413741f, 0.147158f, 0.373474f, 0.191872f, 0.319538f, 0.139409f, + 0.629482f, 0.130456f, 0.687018f, 0.077204f, 0.715482f, 0.139727f, + 0.319538f, 0.139409f, 0.349875f, 0.075955f, 0.407648f, 0.130594f, + 0.663103f, 0.190671f, 0.619303f, 0.159841f, 0.623495f, 0.146796f, + 0.413741f, 0.147158f, 0.418035f, 0.160361f, 0.373474f, 0.191872f, + 0.842355f, 0.195160f, 0.837382f, 0.156361f, 0.858171f, 0.137775f, 0.875030f, 0.184705f, + 0.171653f, 0.132294f, 0.196622f, 0.155241f, 0.176788f, 0.196179f, 0.145224f, 0.182749f, + 0.909112f, 0.183261f, 0.875030f, 0.184705f, 0.858171f, 0.137775f, 0.886245f, 0.121777f, + 0.171653f, 0.132294f, 0.145224f, 0.182749f, 0.107928f, 0.179083f, 0.141314f, 0.112482f, + 0.785486f, 0.152330f, 0.786480f, 0.117591f, 0.858171f, 0.137775f, 0.837382f, 0.156361f, + 0.171653f, 0.132294f, 0.246666f, 0.114850f, 0.245969f, 0.151002f, 0.196622f, 0.155241f, + 0.788458f, 0.080826f, 0.849114f, 0.099732f, 0.858171f, 0.137775f, 0.786480f, 0.117591f, + 0.171653f, 0.132294f, 0.183115f, 0.092127f, 0.246353f, 0.076510f, 0.246666f, 0.114850f, + 0.886245f, 0.121777f, 0.858171f, 0.137775f, 0.849114f, 0.099732f, + 0.183115f, 0.092127f, 0.171653f, 0.132294f, 0.141314f, 0.112482f, + 0.506166f, 0.904851f, 0.432388f, 0.894943f, 0.438797f, 0.870229f, 0.491058f, 0.881714f, + 0.315867f, 0.868209f, 0.321637f, 0.893225f, 0.247207f, 0.901159f, 0.263032f, 0.878321f, + 0.506166f, 0.904851f, 0.491058f, 0.881714f, 0.572792f, 0.860484f, 0.604825f, 0.879946f, + 0.181486f, 0.854693f, 0.263032f, 0.878321f, 0.247207f, 0.901159f, 0.148729f, 0.873349f, + 0.604825f, 0.879946f, 0.572792f, 0.860484f, 0.586396f, 0.793977f, 0.619962f, 0.791615f, + 0.169745f, 0.787474f, 0.181486f, 0.854693f, 0.148729f, 0.873349f, 0.136063f, 0.784093f, + 0.619962f, 0.791615f, 0.586396f, 0.793977f, 0.549027f, 0.746412f, 0.563786f, 0.739211f, + 0.208656f, 0.740879f, 0.169745f, 0.787474f, 0.136063f, 0.784093f, 0.194086f, 0.733241f, + 0.563786f, 0.739211f, 0.549027f, 0.746412f, 0.500314f, 0.711729f, 0.508270f, 0.697693f, + 0.258399f, 0.707497f, 0.208656f, 0.740879f, 0.194086f, 0.733241f, 0.250811f, 0.693249f, + 0.508270f, 0.697693f, 0.500314f, 0.711729f, 0.438641f, 0.680683f, 0.434803f, 0.658882f, + 0.320962f, 0.677959f, 0.258399f, 0.707497f, 0.250811f, 0.693249f, 0.325318f, 0.656224f, + 0.500314f, 0.711729f, 0.505666f, 0.730944f, 0.452955f, 0.700023f, 0.438641f, 0.680683f, + 0.306136f, 0.696976f, 0.252524f, 0.726592f, 0.258399f, 0.707497f, 0.320962f, 0.677959f, + 0.549027f, 0.746412f, 0.542850f, 0.755753f, 0.505666f, 0.730944f, 0.500314f, 0.711729f, + 0.252524f, 0.726592f, 0.214575f, 0.750414f, 0.208656f, 0.740879f, 0.258399f, 0.707497f, + 0.586396f, 0.793977f, 0.568148f, 0.787367f, 0.542850f, 0.755753f, 0.549027f, 0.746412f, + 0.214575f, 0.750414f, 0.188269f, 0.781375f, 0.169745f, 0.787474f, 0.208656f, 0.740879f, + 0.572792f, 0.860484f, 0.555495f, 0.826352f, 0.568148f, 0.787367f, 0.586396f, 0.793977f, + 0.188269f, 0.781375f, 0.199850f, 0.820889f, 0.181486f, 0.854693f, 0.169745f, 0.787474f, + 0.491058f, 0.881714f, 0.501231f, 0.844356f, 0.555495f, 0.826352f, 0.572792f, 0.860484f, + 0.199850f, 0.820889f, 0.253846f, 0.840502f, 0.263032f, 0.878321f, 0.181486f, 0.854693f, + 0.491058f, 0.881714f, 0.438797f, 0.870229f, 0.457832f, 0.840040f, 0.501231f, 0.844356f, + 0.297562f, 0.837358f, 0.315867f, 0.868209f, 0.263032f, 0.878321f, 0.253846f, 0.840502f, + 0.760215f, 0.193244f, 0.785486f, 0.152330f, 0.796021f, 0.176969f, 0.783193f, 0.187449f, + 0.233625f, 0.175620f, 0.245969f, 0.151002f, 0.271553f, 0.193871f, 0.246955f, 0.187075f, + 0.391039f, 0.611891f, 0.434803f, 0.658882f, 0.438641f, 0.680683f, 0.394766f, 0.686125f, + 0.320962f, 0.677959f, 0.325318f, 0.656224f, 0.369913f, 0.610196f, 0.364838f, 0.684445f, + 0.789046f, 0.233323f, 0.760215f, 0.193244f, 0.783193f, 0.187449f, 0.809631f, 0.233887f, + 0.246955f, 0.187075f, 0.271553f, 0.193871f, 0.241255f, 0.236977f, 0.219168f, 0.237388f, + 0.391747f, 0.862097f, 0.401605f, 0.841460f, 0.438797f, 0.870229f, 0.432388f, 0.894943f, + 0.315867f, 0.868209f, 0.354026f, 0.840297f, 0.363377f, 0.861308f, 0.321637f, 0.893225f, + 0.438641f, 0.680683f, 0.452955f, 0.700023f, 0.435018f, 0.718280f, 0.394766f, 0.686125f, + 0.323658f, 0.715731f, 0.306136f, 0.696976f, 0.320962f, 0.677959f, 0.364838f, 0.684445f, + 0.433669f, 0.729661f, 0.384658f, 0.710299f, 0.394766f, 0.686125f, 0.435018f, 0.718280f, + 0.364838f, 0.684445f, 0.374400f, 0.708969f, 0.324726f, 0.727177f, 0.323658f, 0.715731f, + 0.410995f, 0.747662f, 0.384658f, 0.710299f, 0.433669f, 0.729661f, 0.427812f, 0.742828f, + 0.324726f, 0.727177f, 0.374400f, 0.708969f, 0.347028f, 0.745816f, 0.330270f, 0.740536f, + 0.418086f, 0.784946f, 0.384657f, 0.795423f, 0.384658f, 0.710299f, 0.410995f, 0.747662f, + 0.374400f, 0.708969f, 0.372270f, 0.794472f, 0.338952f, 0.783073f, 0.347028f, 0.745816f, + 0.401605f, 0.841460f, 0.384657f, 0.795423f, 0.418086f, 0.784946f, 0.431333f, 0.817535f, + 0.338952f, 0.783073f, 0.372270f, 0.794472f, 0.354026f, 0.840297f, 0.324790f, 0.815460f, + 0.438797f, 0.870229f, 0.401605f, 0.841460f, 0.431333f, 0.817535f, 0.457832f, 0.840040f, + 0.324790f, 0.815460f, 0.354026f, 0.840297f, 0.315867f, 0.868209f, 0.297562f, 0.837358f, + 0.809631f, 0.233887f, 0.816266f, 0.203086f, 0.825107f, 0.209762f, 0.829287f, 0.219562f, + 0.199767f, 0.214827f, 0.209828f, 0.206161f, 0.219168f, 0.237388f, 0.199067f, 0.222464f, + 0.809631f, 0.233887f, 0.783193f, 0.187449f, 0.802192f, 0.184609f, 0.816266f, 0.203086f, + 0.226485f, 0.183086f, 0.246955f, 0.187075f, 0.219168f, 0.237388f, 0.209828f, 0.206161f, + 0.783193f, 0.187449f, 0.796021f, 0.176969f, 0.802192f, 0.184609f, + 0.226485f, 0.183086f, 0.233625f, 0.175620f, 0.246955f, 0.187075f, + 0.457832f, 0.840040f, 0.431333f, 0.817535f, 0.448505f, 0.804621f, 0.473386f, 0.824700f, + 0.307886f, 0.802031f, 0.324790f, 0.815460f, 0.297562f, 0.837358f, 0.282357f, 0.821525f, + 0.431333f, 0.817535f, 0.418086f, 0.784946f, 0.435868f, 0.779569f, 0.448505f, 0.804621f, + 0.321237f, 0.777208f, 0.338952f, 0.783073f, 0.324790f, 0.815460f, 0.307886f, 0.802031f, + 0.418086f, 0.784946f, 0.410995f, 0.747662f, 0.423718f, 0.754191f, 0.435868f, 0.779569f, + 0.334089f, 0.752045f, 0.347028f, 0.745816f, 0.338952f, 0.783073f, 0.321237f, 0.777208f, + 0.410995f, 0.747662f, 0.427812f, 0.742828f, 0.437950f, 0.749777f, 0.423718f, 0.754191f, + 0.319919f, 0.747250f, 0.330270f, 0.740536f, 0.347028f, 0.745816f, 0.334089f, 0.752045f, + 0.427812f, 0.742828f, 0.433669f, 0.729661f, 0.445392f, 0.731997f, 0.437950f, 0.749777f, + 0.312907f, 0.729222f, 0.324726f, 0.727177f, 0.330270f, 0.740536f, 0.319919f, 0.747250f, + 0.433669f, 0.729661f, 0.435018f, 0.718280f, 0.440995f, 0.724383f, 0.445392f, 0.731997f, + 0.317510f, 0.721697f, 0.323658f, 0.715731f, 0.324726f, 0.727177f, 0.312907f, 0.729222f, + 0.435018f, 0.718280f, 0.452955f, 0.700023f, 0.455277f, 0.713731f, 0.440995f, 0.724383f, + 0.303460f, 0.710657f, 0.306136f, 0.696976f, 0.323658f, 0.715731f, 0.317510f, 0.721697f, + 0.501231f, 0.844356f, 0.457832f, 0.840040f, 0.473386f, 0.824700f, 0.512485f, 0.828811f, + 0.282357f, 0.821525f, 0.297562f, 0.837358f, 0.253846f, 0.840502f, 0.242975f, 0.824574f, + 0.555495f, 0.826352f, 0.501231f, 0.844356f, 0.512485f, 0.828811f, 0.550942f, 0.811814f, + 0.242975f, 0.824574f, 0.253846f, 0.840502f, 0.199850f, 0.820889f, 0.204839f, 0.806417f, + 0.568148f, 0.787367f, 0.555495f, 0.826352f, 0.550942f, 0.811814f, 0.552139f, 0.787682f, + 0.204839f, 0.806417f, 0.199850f, 0.820889f, 0.188269f, 0.781375f, 0.204331f, 0.782156f, + 0.542850f, 0.755753f, 0.568148f, 0.787367f, 0.552139f, 0.787682f, 0.539407f, 0.764539f, + 0.204331f, 0.782156f, 0.188269f, 0.781375f, 0.214575f, 0.750414f, 0.217774f, 0.759319f, + 0.505666f, 0.730944f, 0.542850f, 0.755753f, 0.539407f, 0.764539f, 0.508439f, 0.743135f, + 0.217774f, 0.759319f, 0.214575f, 0.750414f, 0.252524f, 0.726592f, 0.249419f, 0.738732f, + 0.452955f, 0.700023f, 0.505666f, 0.730944f, 0.508439f, 0.743135f, 0.455277f, 0.713731f, + 0.249419f, 0.738732f, 0.252524f, 0.726592f, 0.306136f, 0.696976f, 0.303460f, 0.710657f, + 0.437950f, 0.749777f, 0.445392f, 0.731997f, 0.470841f, 0.748408f, 0.454776f, 0.761665f, + 0.286960f, 0.745020f, 0.312907f, 0.729222f, 0.319919f, 0.747250f, 0.302729f, 0.758742f, + 0.454776f, 0.761665f, 0.470841f, 0.748408f, 0.488870f, 0.770464f, 0.475403f, 0.783904f, + 0.268291f, 0.766661f, 0.286960f, 0.745020f, 0.302729f, 0.758742f, 0.281439f, 0.780511f, + 0.475403f, 0.783904f, 0.488870f, 0.770464f, 0.503673f, 0.787562f, 0.494476f, 0.802470f, + 0.252972f, 0.783410f, 0.268291f, 0.766661f, 0.281439f, 0.780511f, 0.261790f, 0.798626f, + 0.494476f, 0.802470f, 0.503673f, 0.787562f, 0.518562f, 0.791602f, 0.516802f, 0.807339f, + 0.237920f, 0.787045f, 0.252972f, 0.783410f, 0.261790f, 0.798626f, 0.239243f, 0.802891f, + 0.512485f, 0.828811f, 0.473386f, 0.824700f, 0.494476f, 0.802470f, 0.516802f, 0.807339f, + 0.261790f, 0.798626f, 0.282357f, 0.821525f, 0.242975f, 0.824574f, 0.239243f, 0.802891f, + 0.448505f, 0.804621f, 0.475403f, 0.783904f, 0.494476f, 0.802470f, 0.473386f, 0.824700f, + 0.261790f, 0.798626f, 0.281439f, 0.780511f, 0.307886f, 0.802031f, 0.282357f, 0.821525f, + 0.448505f, 0.804621f, 0.435868f, 0.779569f, 0.454776f, 0.761665f, 0.475403f, 0.783904f, + 0.302729f, 0.758742f, 0.321237f, 0.777208f, 0.307886f, 0.802031f, 0.281439f, 0.780511f, + 0.437950f, 0.749777f, 0.454776f, 0.761665f, 0.435868f, 0.779569f, 0.423718f, 0.754191f, + 0.321237f, 0.777208f, 0.302729f, 0.758742f, 0.319919f, 0.747250f, 0.334089f, 0.752045f, + 0.440995f, 0.724383f, 0.455277f, 0.713731f, 0.470841f, 0.748408f, 0.445392f, 0.731997f, + 0.286960f, 0.745020f, 0.303460f, 0.710657f, 0.317510f, 0.721697f, 0.312907f, 0.729222f, + 0.508439f, 0.743135f, 0.488870f, 0.770464f, 0.470841f, 0.748408f, 0.455277f, 0.713731f, + 0.286960f, 0.745020f, 0.268291f, 0.766661f, 0.249419f, 0.738732f, 0.303460f, 0.710657f, + 0.539407f, 0.764539f, 0.503673f, 0.787562f, 0.488870f, 0.770464f, 0.508439f, 0.743135f, + 0.268291f, 0.766661f, 0.252972f, 0.783410f, 0.217774f, 0.759319f, 0.249419f, 0.738732f, + 0.552139f, 0.787682f, 0.518562f, 0.791602f, 0.503673f, 0.787562f, 0.539407f, 0.764539f, + 0.252972f, 0.783410f, 0.237920f, 0.787045f, 0.204331f, 0.782156f, 0.217774f, 0.759319f, + 0.550942f, 0.811814f, 0.516802f, 0.807339f, 0.518562f, 0.791602f, 0.552139f, 0.787682f, + 0.237920f, 0.787045f, 0.239243f, 0.802891f, 0.204839f, 0.806417f, 0.204331f, 0.782156f, + 0.512485f, 0.828811f, 0.516802f, 0.807339f, 0.550942f, 0.811814f, + 0.204839f, 0.806417f, 0.239243f, 0.802891f, 0.242975f, 0.824574f, + 0.508270f, 0.697693f, 0.434803f, 0.658882f, 0.484068f, 0.628776f, 0.543385f, 0.683538f, + 0.276936f, 0.625067f, 0.325318f, 0.656224f, 0.250811f, 0.693249f, 0.216123f, 0.678120f, + 0.563786f, 0.739211f, 0.508270f, 0.697693f, 0.543385f, 0.683538f, 0.581052f, 0.726933f, + 0.216123f, 0.678120f, 0.250811f, 0.693249f, 0.194086f, 0.733241f, 0.177176f, 0.720426f, + 0.619962f, 0.791615f, 0.563786f, 0.739211f, 0.581052f, 0.726933f, 0.616701f, 0.759965f, + 0.177176f, 0.720426f, 0.194086f, 0.733241f, 0.136063f, 0.784093f, 0.140379f, 0.752377f, + 0.707492f, 0.759884f, 0.619962f, 0.791615f, 0.616701f, 0.759965f, 0.660647f, 0.741167f, + 0.140379f, 0.752377f, 0.136063f, 0.784093f, 0.049526f, 0.748824f, 0.097038f, 0.732052f, + 0.745511f, 0.652100f, 0.707492f, 0.759884f, 0.660647f, 0.741167f, 0.677256f, 0.670436f, + 0.097038f, 0.732052f, 0.049526f, 0.748824f, 0.019409f, 0.639749f, 0.083564f, 0.662038f, + 0.740843f, 0.572428f, 0.745511f, 0.652100f, 0.677256f, 0.670436f, 0.671403f, 0.592656f, + 0.083564f, 0.662038f, 0.019409f, 0.639749f, 0.033664f, 0.564403f, 0.092820f, 0.589862f, + 0.677256f, 0.670436f, 0.543385f, 0.683538f, 0.484068f, 0.628776f, 0.671403f, 0.592656f, + 0.276936f, 0.625067f, 0.216123f, 0.678120f, 0.083564f, 0.662038f, 0.092820f, 0.589862f, + 0.677256f, 0.670436f, 0.660647f, 0.741167f, 0.581052f, 0.726933f, 0.543385f, 0.683538f, + 0.177176f, 0.720426f, 0.097038f, 0.732052f, 0.083564f, 0.662038f, 0.216123f, 0.678120f, + 0.660647f, 0.741167f, 0.616701f, 0.759965f, 0.581052f, 0.726933f, + 0.177176f, 0.720426f, 0.140379f, 0.752377f, 0.097038f, 0.732052f, + 0.842355f, 0.195160f, 0.829287f, 0.219562f, 0.834578f, 0.206879f, 0.834705f, 0.206959f, + 0.033664f, 0.564403f, 0.051216f, 0.522659f, 0.145041f, 0.562595f, 0.092820f, 0.589862f, + 0.620420f, 0.565675f, 0.671403f, 0.592656f, 0.484068f, 0.628776f, 0.498072f, 0.552315f, + 0.276936f, 0.625067f, 0.092820f, 0.589862f, 0.145041f, 0.562595f, 0.264218f, 0.550140f, + 0.391039f, 0.611891f, 0.498072f, 0.552315f, 0.484068f, 0.628776f, 0.434803f, 0.658882f, + 0.276936f, 0.625067f, 0.264218f, 0.550140f, 0.369913f, 0.610196f, 0.325318f, 0.656224f +}; + #define VERT_MARK 1 #define EDGE_ORIG 1 @@ -496,6 +1025,8 @@ void bmo_create_icosphere_exec(BMesh *bm, BMOperator *op) BMO_vert_flag_enable(bm, eva[a], VERT_MARK); } + int uvi = 0; + const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); for (a = 0; a < 20; a++) { BMFace *eftemp; BMVert *v1, *v2, *v3; @@ -510,7 +1041,19 @@ void bmo_create_icosphere_exec(BMesh *bm, BMOperator *op) BMO_edge_flag_enable(bm, l->e, EDGE_MARK); } - BMO_face_flag_enable(bm, eftemp, FACE_MARK); + /* Set the UVs here, the iteration order of the faces is not guaranteed, + * so it's best to set the UVs right after the face is created. */ + if(calc_uvs) { + BMLoop* l; + BMIter liter2; + int loop_index; + BM_ITER_ELEM_INDEX (l, &liter2, eftemp, BM_LOOPS_OF_FACE, loop_index) { + MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); + luv->uv[0] = icouvs[uvi][0]; + luv->uv[1] = icouvs[uvi][1]; + uvi++; + } + } } if (subdiv > 1) { @@ -530,29 +1073,7 @@ void bmo_create_icosphere_exec(BMesh *bm, BMOperator *op) BMO_op_finish(bm, &bmop); } - if (calc_uvs) { - BMFace *f; - BMIter fiter; - - /* We cannot tag faces for UVs computing above, so we have to do it now, based on all its vertices - * being tagged. */ - BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) { - bool valid = true; - - BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) { - if (!BMO_vert_flag_test(bm, l->v, VERT_MARK)) { - valid = false; - break; - } - } - if (valid) { - BMO_face_flag_enable(bm, f, FACE_MARK); - } - } - - BM_mesh_calc_uvs_sphere(bm, FACE_MARK); - } /* must transform after because of sphere subdivision */ BM_ITER_MESH (v, &viter, bm, BM_VERTS_OF_MESH) { @@ -564,7 +1085,7 @@ void bmo_create_icosphere_exec(BMesh *bm, BMOperator *op) BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "verts.out", BM_VERT, VERT_MARK); } -static void bm_mesh_calc_uvs_sphere_face(BMFace *f, float mat_rot[3][3], const int cd_loop_uv_offset) +static void bm_mesh_calc_uvs_sphere_face(BMFace *f, const int cd_loop_uv_offset) { float *uvs[4]; BMLoop *l; @@ -574,12 +1095,42 @@ static void bm_mesh_calc_uvs_sphere_face(BMFace *f, float mat_rot[3][3], const i BLI_assert(f->len <= 4); + /* If face has 3 vertices, it's a polar face, in which case we need to + * compute a nearbye to determine its latitude. */ + float avgx = 0.0f, avgy = 0.0f; + BM_ITER_ELEM_INDEX (l, &iter, f, BM_LOOPS_OF_FACE, loop_index) { + if (f->len == 3) { + avgx += l->v->co[0]; + avgy += l->v->co[1]; + } + } + avgx /= 3.0f; + avgy /= 3.0f; + BM_ITER_ELEM_INDEX (l, &iter, f, BM_LOOPS_OF_FACE, loop_index) { MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - float vco[3]; + float x = l->v->co[0]; + float y = l->v->co[1]; + float z = l->v->co[2]; + float len = len_v3(l->v->co); + + /* Use neigboring point to compute angle for poles. */ + float theta; + if (f->len == 3 && fabsf(x) < 0.0001f && fabsf(y) < 0.0001f) { + theta = atan2f(avgy, avgx); + } + else { + theta = atan2f(y, x); + } - mul_v3_m3v3(vco, mat_rot, l->v->co); - map_to_sphere(&luv->uv[0], &luv->uv[1], vco[0], vco[1], vco[2]); + /* Shift borderline coordinates to the left. */ + if (fabsf(theta - M_PI) < 0.0001f) { + theta = -M_PI; + } + + float phi = saacos(z / len); + luv->uv[0] = 0.5f + theta / ((float)M_PI * 2); + luv->uv[1] = 1.0f - phi / (float)M_PI; uvs[loop_index] = luv->uv; } @@ -615,21 +1166,38 @@ void BM_mesh_calc_uvs_sphere(BMesh *bm, const short oflag) const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); - /* We apply a 'magic' rotationto vcos before mapping them to sphere, - * those values seem to give best results for both ico and uv sphere projections. */ - float mat_rot[3][3]; - const float axis[3] = {0.806f, 0.329f, 0.491f}; - const float angle = DEG2RADF(120.0f); + BLI_assert(cd_loop_uv_offset != -1); /* caller is responsible for giving us UVs */ - axis_angle_to_mat3(mat_rot, axis, angle); + BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) { + if (!BMO_face_flag_test(bm, f, oflag)) + continue; - BLI_assert(cd_loop_uv_offset != -1); /* caller is responsible for giving us UVs */ + bm_mesh_calc_uvs_sphere_face(f, cd_loop_uv_offset); + } + + BMIter iter2; + BMLoop* l; + int loop_index; + float minx = 1.0f; BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) { if (!BMO_face_flag_test(bm, f, oflag)) continue; + BM_ITER_ELEM_INDEX (l, &iter2, f, BM_LOOPS_OF_FACE, loop_index) { + MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); + if (luv->uv[0] < minx) { + minx = luv->uv[0]; + } + } + } - bm_mesh_calc_uvs_sphere_face(f, mat_rot, cd_loop_uv_offset); + BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) { + if (!BMO_face_flag_test(bm, f, oflag)) + continue; + BM_ITER_ELEM_INDEX (l, &iter2, f, BM_LOOPS_OF_FACE, loop_index) { + MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); + luv->uv[0] -= minx; + } } } @@ -640,6 +1208,7 @@ void bmo_create_monkey_exec(BMesh *bm, BMOperator *op) int i; BMO_slot_mat4_get(op->slots_in, "matrix", mat); + const bool calc_uvs = BMO_slot_bool_get(op->slots_in, "calc_uvs"); for (i = 0; i < monkeynv; i++) { float v[3]; @@ -666,20 +1235,43 @@ void bmo_create_monkey_exec(BMesh *bm, BMOperator *op) mul_m4_v3(mat, tv[i]->co); } + int uvi = 0; + const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); for (i = 0; i < monkeynf; i++) { - BM_face_create_quad_tri(bm, + BMFace* temp1 = BM_face_create_quad_tri(bm, tv[monkeyf[i][0] + i - monkeyo], tv[monkeyf[i][1] + i - monkeyo], tv[monkeyf[i][2] + i - monkeyo], (monkeyf[i][3] != monkeyf[i][2]) ? tv[monkeyf[i][3] + i - monkeyo] : NULL, NULL, BM_CREATE_NOP); - BM_face_create_quad_tri(bm, + BMFace* temp2 = BM_face_create_quad_tri(bm, tv[monkeynv + monkeyf[i][2] + i - monkeyo], tv[monkeynv + monkeyf[i][1] + i - monkeyo], tv[monkeynv + monkeyf[i][0] + i - monkeyo], (monkeyf[i][3] != monkeyf[i][2]) ? tv[monkeynv + monkeyf[i][3] + i - monkeyo] : NULL, NULL, BM_CREATE_NOP); + + /* Set the UVs here, the iteration order of the faces is not guaranteed, + * so it's best to set the UVs right after the face is created. */ + if(calc_uvs) { + BMLoop* l; + BMIter liter; + int loop_index; + BM_ITER_ELEM_INDEX (l, &liter, temp1, BM_LOOPS_OF_FACE, loop_index) { + MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); + luv->uv[0] = monkeyuvs[uvi*2 + 0]; + luv->uv[1] = monkeyuvs[uvi*2 + 1]; + uvi++; + } + BM_ITER_ELEM_INDEX (l, &liter, temp2, BM_LOOPS_OF_FACE, loop_index) { + MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); + luv->uv[0] = monkeyuvs[uvi*2 + 0]; + luv->uv[1] = monkeyuvs[uvi*2 + 1]; + uvi++; + } + + } } MEM_freeN(tv); diff --git a/source/blender/editors/mesh/editmesh_add.c b/source/blender/editors/mesh/editmesh_add.c index 2a9f9c830f4..3725590c188 100644 --- a/source/blender/editors/mesh/editmesh_add.c +++ b/source/blender/editors/mesh/editmesh_add.c @@ -461,6 +461,7 @@ static int add_primitive_monkey_exec(bContext *C, wmOperator *op) bool enter_editmode; unsigned int layer; bool was_editmode; + const bool calc_uvs = RNA_boolean_get(op->ptr, "calc_uvs"); WM_operator_view3d_unit_defaults(C, op); ED_object_add_generic_get_opts(C, op, 'Y', loc, rot, &enter_editmode, &layer, NULL); @@ -471,9 +472,13 @@ static int add_primitive_monkey_exec(bContext *C, wmOperator *op) em = BKE_editmesh_from_object(obedit); + if (calc_uvs) { + ED_mesh_uv_texture_ensure(obedit->data, NULL); + } + if (!EDBM_op_call_and_selectf( em, op, "verts.out", false, - "create_monkey matrix=%m4", mat)) + "create_monkey matrix=%m4 calc_uvs=%b", mat, calc_uvs)) { return OPERATOR_CANCELLED; } @@ -498,6 +503,8 @@ void MESH_OT_primitive_monkey_add(wmOperatorType *ot) ED_object_add_unit_props(ot); ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + /* props */ + ED_object_add_mesh_props(ot); ED_object_add_generic_props(ot, true); } -- cgit v1.2.3 From 4446acbf17748f30b163016cfc4b88bba8653517 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dietrich?= Date: Sat, 24 Sep 2016 21:41:16 +0200 Subject: Viewport smoke: add support for axis aligned slicing. Current approach uses view aligned slicing to generate polygons for GL texturing such that the generated polygons are always facing the view plane. Now it is also possible to use object aligned slicing, which creates polygons by slicing the object perpendicular to whichever axis is facing the most the view plane. It is also possible to create a single slice for inspecting the volume, or for 2D rendering effects. Settings for this, along with a density multiplier setting, are to be found in a newly added "Smoke Display Settings" panel in the smoke domain properties tab. Reviewers: plasmasolutions, gottfried Differential Revision: https://developer.blender.org/D1733 --- .../startup/bl_ui/properties_physics_smoke.py | 35 ++++++++ source/blender/blenkernel/intern/smoke.c | 13 +++ source/blender/blenloader/intern/versioning_270.c | 19 +++++ source/blender/editors/space_view3d/drawvolume.c | 95 +++++++++++++++++++++- source/blender/makesdna/DNA_smoke_types.h | 27 ++++++ source/blender/makesrna/intern/rna_smoke.c | 62 ++++++++++++++ 6 files changed, 248 insertions(+), 3 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_physics_smoke.py b/release/scripts/startup/bl_ui/properties_physics_smoke.py index 99aa54a958a..829850e4f2f 100644 --- a/release/scripts/startup/bl_ui/properties_physics_smoke.py +++ b/release/scripts/startup/bl_ui/properties_physics_smoke.py @@ -349,5 +349,40 @@ class PHYSICS_PT_smoke_field_weights(PhysicButtonsPanel, Panel): domain = context.smoke.domain_settings effector_weights_ui(self, context, domain.effector_weights, 'SMOKE') + +class PHYSICS_PT_smoke_display_settings(PhysicButtonsPanel, Panel): + bl_label = "Smoke Display Settings" + bl_options = {'DEFAULT_CLOSED'} + + @classmethod + def poll(cls, context): + md = context.smoke + rd = context.scene.render + return md and (md.smoke_type == 'DOMAIN') and (not rd.use_game_engine) + + def draw(self, context): + domain = context.smoke.domain_settings + layout = self.layout + + layout.prop(domain, "display_thickness") + + layout.separator() + layout.label(text="Slicing:") + layout.prop(domain, "slice_method") + + slice_method = domain.slice_method + axis_slice_method = domain.axis_slice_method + + if slice_method == 'AXIS_ALIGNED': + layout.prop(domain, "axis_slice_method") + + if axis_slice_method == 'SINGLE': + layout.prop(domain, "slice_axis") + layout.prop(domain, "slice_depth") + + if axis_slice_method == 'FULL': + layout.prop(domain, "slice_per_voxel") + + if __name__ == "__main__": # only for live edit. bpy.utils.register_module(__name__) diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c index f622d541f3a..d0f546e9bef 100644 --- a/source/blender/blenkernel/intern/smoke.c +++ b/source/blender/blenkernel/intern/smoke.c @@ -536,6 +536,13 @@ void smokeModifier_createType(struct SmokeModifierData *smd) #endif smd->domain->data_depth = 0; smd->domain->cache_file_format = PTCACHE_FILE_PTCACHE; + + smd->domain->display_thickness = 1.0f; + smd->domain->slice_method = MOD_SMOKE_SLICE_VIEW_ALIGNED; + smd->domain->axis_slice_method = AXIS_SLICE_FULL; + smd->domain->slice_per_voxel = 5.0f; + smd->domain->slice_depth = 0.5f; + smd->domain->slice_axis = 0; } else if (smd->type & MOD_SMOKE_TYPE_FLOW) { @@ -629,6 +636,12 @@ void smokeModifier_copy(struct SmokeModifierData *smd, struct SmokeModifierData tsmd->domain->openvdb_comp = smd->domain->openvdb_comp; tsmd->domain->data_depth = smd->domain->data_depth; tsmd->domain->cache_file_format = smd->domain->cache_file_format; + + tsmd->domain->slice_method = smd->domain->slice_method; + tsmd->domain->axis_slice_method = smd->domain->axis_slice_method; + tsmd->domain->slice_per_voxel = smd->domain->slice_per_voxel; + tsmd->domain->slice_depth = smd->domain->slice_depth; + tsmd->domain->slice_axis = smd->domain->slice_axis; } else if (tsmd->flow) { tsmd->flow->psys = smd->flow->psys; diff --git a/source/blender/blenloader/intern/versioning_270.c b/source/blender/blenloader/intern/versioning_270.c index aa5ef1c98cf..0d4ff00b775 100644 --- a/source/blender/blenloader/intern/versioning_270.c +++ b/source/blender/blenloader/intern/versioning_270.c @@ -52,6 +52,7 @@ #include "DNA_linestyle_types.h" #include "DNA_actuator_types.h" #include "DNA_view3d_types.h" +#include "DNA_smoke_types.h" #include "DNA_genfile.h" @@ -1405,5 +1406,23 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main) scene->r.ffcodecdata.constant_rate_factor = FFM_CRF_NONE; } } + + if (!DNA_struct_elem_find(fd->filesdna, "SmokeModifierData", "float", "slice_per_voxel")) { + Object *ob; + ModifierData *md; + + for (ob = main->object.first; ob; ob = ob->id.next) { + for (md = ob->modifiers.first; md; md = md->next) { + if (md->type == eModifierType_Smoke) { + SmokeModifierData *smd = (SmokeModifierData *)md; + if (smd->domain) { + smd->domain->slice_per_voxel = 5.0f; + smd->domain->slice_depth = 0.5f; + smd->domain->display_thickness = 1.0f; + } + } + } + } + } } } diff --git a/source/blender/editors/space_view3d/drawvolume.c b/source/blender/editors/space_view3d/drawvolume.c index 06677ef4476..d743e7c09e7 100644 --- a/source/blender/editors/space_view3d/drawvolume.c +++ b/source/blender/editors/space_view3d/drawvolume.c @@ -113,6 +113,63 @@ typedef struct VolumeSlicer { float (*verts)[3]; } VolumeSlicer; +/* *************************** Axis Aligned Slicing ************************** */ + +static void create_single_slice(VolumeSlicer *slicer, const float depth, + const int axis, const int idx) +{ + const float vertices[3][4][3] = { + { + { depth, slicer->min[1], slicer->min[2] }, + { depth, slicer->max[1], slicer->min[2] }, + { depth, slicer->max[1], slicer->max[2] }, + { depth, slicer->min[1], slicer->max[2] } + }, + { + { slicer->min[0], depth, slicer->min[2] }, + { slicer->min[0], depth, slicer->max[2] }, + { slicer->max[0], depth, slicer->max[2] }, + { slicer->max[0], depth, slicer->min[2] } + }, + { + { slicer->min[0], slicer->min[1], depth }, + { slicer->min[0], slicer->max[1], depth }, + { slicer->max[0], slicer->max[1], depth }, + { slicer->max[0], slicer->min[1], depth } + } + }; + + copy_v3_v3(slicer->verts[idx + 0], vertices[axis][0]); + copy_v3_v3(slicer->verts[idx + 1], vertices[axis][1]); + copy_v3_v3(slicer->verts[idx + 2], vertices[axis][2]); + copy_v3_v3(slicer->verts[idx + 3], vertices[axis][0]); + copy_v3_v3(slicer->verts[idx + 4], vertices[axis][2]); + copy_v3_v3(slicer->verts[idx + 5], vertices[axis][3]); +} + +static void create_axis_aligned_slices(VolumeSlicer *slicer, const int num_slices, + const float view_dir[3], const int axis) +{ + float depth, slice_size = slicer->size[axis] / num_slices; + + /* always process slices in back to front order! */ + if (view_dir[axis] > 0.0f) { + depth = slicer->min[axis]; + } + else { + depth = slicer->max[axis]; + slice_size = -slice_size; + } + + int count = 0; + for (int slice = 0; slice < num_slices; slice++) { + create_single_slice(slicer, depth, axis, count); + + count += 6; + depth += slice_size; + } +} + /* *************************** View Aligned Slicing ************************** */ /* Code adapted from: @@ -433,8 +490,25 @@ void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob, /* setup slicing information */ - const int max_slices = 256; - const int max_points = max_slices * 12; + const bool view_aligned = (sds->slice_method == MOD_SMOKE_SLICE_VIEW_ALIGNED); + int max_slices, max_points, axis = 0; + + if (view_aligned) { + max_slices = max_iii(sds->res[0], sds->res[1], sds->res[2]) * sds->slice_per_voxel; + max_points = max_slices * 12; + } + else { + if (sds->axis_slice_method == AXIS_SLICE_FULL) { + axis = axis_dominant_v3_single(viewnormal); + max_slices = sds->res[axis] * sds->slice_per_voxel; + } + else { + axis = (sds->slice_axis == SLICE_AXIS_AUTO) ? axis_dominant_v3_single(viewnormal) : sds->slice_axis - 1; + max_slices = 1; + } + + max_points = max_slices * 6; + } VolumeSlicer slicer; copy_v3_v3(slicer.min, min); @@ -442,7 +516,22 @@ void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob, copy_v3_v3(slicer.size, size); slicer.verts = MEM_mallocN(sizeof(float) * 3 * max_points, "smoke_slice_vertices"); - const int num_points = create_view_aligned_slices(&slicer, max_slices, viewnormal); + int num_points; + + if (view_aligned) { + num_points = create_view_aligned_slices(&slicer, max_slices, viewnormal); + } + else { + num_points = max_points; + + if (sds->axis_slice_method == AXIS_SLICE_FULL) { + create_axis_aligned_slices(&slicer, max_slices, viewnormal, axis); + } + else { + const float depth = (sds->slice_depth - 0.5f) * size[axis]; + create_single_slice(&slicer, depth, axis, 0); + } + } /* setup buffer and draw */ diff --git a/source/blender/makesdna/DNA_smoke_types.h b/source/blender/makesdna/DNA_smoke_types.h index 76de8443faa..5526c18f656 100644 --- a/source/blender/makesdna/DNA_smoke_types.h +++ b/source/blender/makesdna/DNA_smoke_types.h @@ -52,6 +52,26 @@ enum { /* viewsettings */ #define MOD_SMOKE_VIEW_SHOWBIG (1<<0) +/* slice method */ +enum { + MOD_SMOKE_SLICE_VIEW_ALIGNED = 0, + MOD_SMOKE_SLICE_AXIS_ALIGNED = 1, +}; + +/* axis aligned method */ +enum { + AXIS_SLICE_FULL = 0, + AXIS_SLICE_SINGLE = 1, +}; + +/* single slice direction */ +enum { + SLICE_AXIS_AUTO = 0, + SLICE_AXIS_X = 1, + SLICE_AXIS_Y = 2, + SLICE_AXIS_Z = 3, +}; + /* cache compression */ #define SM_CACHE_LIGHT 0 #define SM_CACHE_HEAVY 1 @@ -161,6 +181,13 @@ typedef struct SmokeDomainSettings { float burning_rate, flame_smoke, flame_vorticity; float flame_ignition, flame_max_temp; float flame_smoke_color[3]; + + /* Display settings */ + char slice_method, axis_slice_method; + char slice_axis, pad2; + float slice_per_voxel; + float slice_depth; + float display_thickness; } SmokeDomainSettings; diff --git a/source/blender/makesrna/intern/rna_smoke.c b/source/blender/makesrna/intern/rna_smoke.c index dad5577dc12..22c1a115a15 100644 --- a/source/blender/makesrna/intern/rna_smoke.c +++ b/source/blender/makesrna/intern/rna_smoke.c @@ -443,6 +443,26 @@ static void rna_def_smoke_domain_settings(BlenderRNA *brna) {0, NULL, 0, NULL, NULL} }; + static EnumPropertyItem smoke_view_items[] = { + {MOD_SMOKE_SLICE_VIEW_ALIGNED, "VIEW_ALIGNED", 0, "View", "Slice volume parallel to the view plane"}, + {MOD_SMOKE_SLICE_AXIS_ALIGNED, "AXIS_ALIGNED", 0, "Axis", "Slice volume parallel to the major axis"}, + {0, NULL, 0, NULL, NULL} + }; + + static EnumPropertyItem axis_slice_method_items[] = { + {AXIS_SLICE_FULL, "FULL", 0, "Full", "Slice the whole domain object"}, + {AXIS_SLICE_SINGLE, "SINGLE", 0, "Single", "Perform a single slice of the domain object"}, + {0, NULL, 0, NULL, NULL} + }; + + static EnumPropertyItem axis_slice_position_items[] = { + {SLICE_AXIS_AUTO, "AUTO", 0, "Auto", "Adjust slice direction according to the view direction"}, + {SLICE_AXIS_X, "X", 0, "X", "Slice along the X axis"}, + {SLICE_AXIS_Y, "Y", 0, "Y", "Slice along the Y axis"}, + {SLICE_AXIS_Z, "Z", 0, "Z", "Slice along the Z axis"}, + {0, NULL, 0, NULL, NULL} + }; + srna = RNA_def_struct(brna, "SmokeDomainSettings", NULL); RNA_def_struct_ui_text(srna, "Domain Settings", "Smoke domain settings"); RNA_def_struct_sdna(srna, "SmokeDomainSettings"); @@ -719,6 +739,48 @@ static void rna_def_smoke_domain_settings(BlenderRNA *brna) RNA_def_property_enum_funcs(prop, NULL, "rna_Smoke_cachetype_set", NULL); RNA_def_property_ui_text(prop, "File Format", "Select the file format to be used for caching"); RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_resetCache"); + + /* display settings */ + + prop = RNA_def_property(srna, "slice_method", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "slice_method"); + RNA_def_property_enum_items(prop, smoke_view_items); + RNA_def_property_ui_text(prop, "View Method", "How to slice the volume for viewport rendering"); + RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL); + + prop = RNA_def_property(srna, "axis_slice_method", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "axis_slice_method"); + RNA_def_property_enum_items(prop, axis_slice_method_items); + RNA_def_property_ui_text(prop, "Method", ""); + RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL); + + prop = RNA_def_property(srna, "slice_axis", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "slice_axis"); + RNA_def_property_enum_items(prop, axis_slice_position_items); + RNA_def_property_ui_text(prop, "Axis", ""); + RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL); + + prop = RNA_def_property(srna, "slice_per_voxel", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "slice_per_voxel"); + RNA_def_property_range(prop, 0.0, 100.0); + RNA_def_property_ui_range(prop, 0.0, 5.0, 0.1, 1); + RNA_def_property_ui_text(prop, "Slice Per Voxel", + "How many slices per voxel should be generated"); + RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL); + + prop = RNA_def_property(srna, "slice_depth", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "slice_depth"); + RNA_def_property_range(prop, 0.0, 1.0); + RNA_def_property_ui_range(prop, 0.0, 1.0, 0.1, 3); + RNA_def_property_ui_text(prop, "Position", "Position of the slice"); + RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL); + + prop = RNA_def_property(srna, "display_thickness", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "display_thickness"); + RNA_def_property_range(prop, 0.001, 1000.0); + RNA_def_property_ui_range(prop, 0.1, 100.0, 0.1, 3); + RNA_def_property_ui_text(prop, "Thickness", "Thickness of smoke drawing in the viewport"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, NULL); } static void rna_def_smoke_flow_settings(BlenderRNA *brna) -- cgit v1.2.3 From 14e825aa1fb57db85cecfda0cd69843b57cefd12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dietrich?= Date: Sat, 24 Sep 2016 22:36:54 +0200 Subject: Viewport smoke: add options to draw velocity vectors. This basically exposes to the UI a function that was only available through a debug macro ; the purpose is obviously to help debugging simulations. It adds ways to draw the vectors either as colored needles or as arrows showing the direction of the vectors. The colors are based on the magnitude of the underlying vectors. Reviewers: plasmasolutions, gottfried Differential Revision: https://developer.blender.org/D1733 --- .../startup/bl_ui/properties_physics_smoke.py | 8 + source/blender/blenkernel/intern/smoke.c | 4 + source/blender/editors/space_view3d/drawobject.c | 7 +- source/blender/editors/space_view3d/drawvolume.c | 204 ++++++++++++++++----- .../blender/editors/space_view3d/view3d_intern.h | 6 +- source/blender/makesdna/DNA_smoke_types.h | 10 +- source/blender/makesrna/intern/rna_smoke.c | 24 +++ 7 files changed, 213 insertions(+), 50 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_physics_smoke.py b/release/scripts/startup/bl_ui/properties_physics_smoke.py index 829850e4f2f..3cf77135622 100644 --- a/release/scripts/startup/bl_ui/properties_physics_smoke.py +++ b/release/scripts/startup/bl_ui/properties_physics_smoke.py @@ -383,6 +383,14 @@ class PHYSICS_PT_smoke_display_settings(PhysicButtonsPanel, Panel): if axis_slice_method == 'FULL': layout.prop(domain, "slice_per_voxel") + layout.separator() + layout.label(text="Debug:") + layout.prop(domain, "draw_velocity") + col = layout.column(); + col.enabled = domain.draw_velocity + col.prop(domain, "vector_draw_type") + col.prop(domain, "vector_scale") + if __name__ == "__main__": # only for live edit. bpy.utils.register_module(__name__) diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c index d0f546e9bef..05540f51588 100644 --- a/source/blender/blenkernel/intern/smoke.c +++ b/source/blender/blenkernel/intern/smoke.c @@ -543,6 +543,7 @@ void smokeModifier_createType(struct SmokeModifierData *smd) smd->domain->slice_per_voxel = 5.0f; smd->domain->slice_depth = 0.5f; smd->domain->slice_axis = 0; + smd->domain->vector_scale = 1.0f; } else if (smd->type & MOD_SMOKE_TYPE_FLOW) { @@ -642,6 +643,9 @@ void smokeModifier_copy(struct SmokeModifierData *smd, struct SmokeModifierData tsmd->domain->slice_per_voxel = smd->domain->slice_per_voxel; tsmd->domain->slice_depth = smd->domain->slice_depth; tsmd->domain->slice_axis = smd->domain->slice_axis; + tsmd->domain->draw_velocity = smd->domain->draw_velocity; + tsmd->domain->vector_draw_type = smd->domain->vector_draw_type; + tsmd->domain->vector_scale = smd->domain->vector_scale; } else if (tsmd->flow) { tsmd->flow->psys = smd->flow->psys; diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index a74c0f0f467..ea40d4eb5e1 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -7912,9 +7912,10 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short } /* smoke debug render */ -#ifdef SMOKE_DEBUG_VELOCITY - draw_smoke_velocity(smd->domain, ob); -#endif + if (!render_override && sds->draw_velocity) { + draw_smoke_velocity(sds, viewnormal); + } + #ifdef SMOKE_DEBUG_HEAT draw_smoke_heat(smd->domain, ob); #endif diff --git a/source/blender/editors/space_view3d/drawvolume.c b/source/blender/editors/space_view3d/drawvolume.c index d743e7c09e7..ef4db7ed6b8 100644 --- a/source/blender/editors/space_view3d/drawvolume.c +++ b/source/blender/editors/space_view3d/drawvolume.c @@ -40,6 +40,7 @@ #include "BLI_utildefines.h" #include "BLI_math.h" +#include "BKE_DerivedMesh.h" #include "BKE_particle.h" #include "smoke_API.h" @@ -571,61 +572,180 @@ void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob, } } -#ifdef SMOKE_DEBUG_VELOCITY -void draw_smoke_velocity(SmokeDomainSettings *domain, Object *ob) +static void add_tri(float (*verts)[3], float(*colors)[3], int *offset, + float p1[3], float p2[3], float p3[3], float rgb[3]) { - float x, y, z; - float x0, y0, z0; - int *base_res = domain->base_res; - int *res = domain->res; - int *res_min = domain->res_min; - int *res_max = domain->res_max; - float *vel_x = smoke_get_velocity_x(domain->fluid); - float *vel_y = smoke_get_velocity_y(domain->fluid); - float *vel_z = smoke_get_velocity_z(domain->fluid); + copy_v3_v3(verts[*offset + 0], p1); + copy_v3_v3(verts[*offset + 1], p2); + copy_v3_v3(verts[*offset + 2], p3); - float min[3]; - float *cell_size = domain->cell_size; - float step_size = ((float)max_iii(base_res[0], base_res[1], base_res[2])) / 16.f; - float vf = domain->scale / 16.f * 2.f; /* velocity factor */ + copy_v3_v3(colors[*offset + 0], rgb); + copy_v3_v3(colors[*offset + 1], rgb); + copy_v3_v3(colors[*offset + 2], rgb); - glLineWidth(1.0f); + *offset += 3; +} + +static void add_needle(float (*verts)[3], float (*colors)[3], float center[3], + float dir[3], float scale, float voxel_size, int *offset) +{ + float len = len_v3(dir); + + float rgb[3]; + weight_to_rgb(rgb, len); + + if (len != 0.0f) { + mul_v3_fl(dir, 1.0f / len); + len *= scale; + } + + len *= voxel_size; + + float corners[4][3] = { + { 0.0f, 0.2f, -0.5f }, + { -0.2f * 0.866f, -0.2f * 0.5f, -0.5f }, + { 0.2f * 0.866f, -0.2f * 0.5f, -0.5f }, + { 0.0f, 0.0f, 0.5f } + }; + + const float up[3] = { 0.0f, 0.0f, 1.0f }; + float rot[3][3]; + + rotation_between_vecs_to_mat3(rot, up, dir); + transpose_m3(rot); + + for (int i = 0; i < 4; i++) { + mul_m3_v3(rot, corners[i]); + mul_v3_fl(corners[i], len); + add_v3_v3(corners[i], center); + } + + add_tri(verts, colors, offset, corners[0], corners[1], corners[2], rgb); + add_tri(verts, colors, offset, corners[0], corners[1], corners[3], rgb); + add_tri(verts, colors, offset, corners[1], corners[2], corners[3], rgb); + add_tri(verts, colors, offset, corners[2], corners[0], corners[3], rgb); +} + +static void add_streamline(float (*verts)[3], float(*colors)[3], float center[3], + float dir[3], float scale, float voxel_size, int *offset) +{ + const float len = len_v3(dir); + + float rgb[3]; + weight_to_rgb(rgb, len); + + copy_v3_v3(colors[(*offset)], rgb); + copy_v3_v3(verts[(*offset)++], center); + + mul_v3_fl(dir, scale * voxel_size); + add_v3_v3(center, dir); + + copy_v3_v3(colors[(*offset)], rgb); + copy_v3_v3(verts[(*offset)++], center); +} + +typedef void (*vector_draw_func)(float(*)[3], float(*)[3], float*, float*, float, float, int*); + +void draw_smoke_velocity(SmokeDomainSettings *domain, float viewnormal[3]) +{ + const int *base_res = domain->base_res; + const int *res = domain->res; + const int *res_min = domain->res_min; + + int res_max[3]; + copy_v3_v3_int(res_max, domain->res_max); + + const float *vel_x = smoke_get_velocity_x(domain->fluid); + const float *vel_y = smoke_get_velocity_y(domain->fluid); + const float *vel_z = smoke_get_velocity_z(domain->fluid); + + const float *cell_size = domain->cell_size; + const float step_size = ((float)max_iii(base_res[0], base_res[1], base_res[2])) / 16.0f; /* set first position so that it doesn't jump when domain moves */ - x0 = res_min[0] + fmod(-(float)domain->shift[0] + res_min[0], step_size); - y0 = res_min[1] + fmod(-(float)domain->shift[1] + res_min[1], step_size); - z0 = res_min[2] + fmod(-(float)domain->shift[2] + res_min[2], step_size); - if (x0 < res_min[0]) x0 += step_size; - if (y0 < res_min[1]) y0 += step_size; - if (z0 < res_min[2]) z0 += step_size; + float xyz[3] = { + res_min[0] + fmod(-(float)domain->shift[0] + res_min[0], step_size), + res_min[1] + fmod(-(float)domain->shift[1] + res_min[1], step_size), + res_min[2] + fmod(-(float)domain->shift[2] + res_min[2], step_size) + }; + + if (xyz[0] < res_min[0]) xyz[0] += step_size; + if (xyz[1] < res_min[1]) xyz[1] += step_size; + if (xyz[2] < res_min[2]) xyz[2] += step_size; + + float min[3]; add_v3_v3v3(min, domain->p0, domain->obj_shift_f); - for (x = floor(x0); x < res_max[0]; x += step_size) - for (y = floor(y0); y < res_max[1]; y += step_size) - for (z = floor(z0); z < res_max[2]; z += step_size) { + int num_points_v[3] = { + ((float)(res_max[0] - floor(xyz[0])) / step_size) + 0.5f, + ((float)(res_max[1] - floor(xyz[1])) / step_size) + 0.5f, + ((float)(res_max[2] - floor(xyz[2])) / step_size) + 0.5f + }; + + if (domain->slice_method == MOD_SMOKE_SLICE_AXIS_ALIGNED && + domain->axis_slice_method == AXIS_SLICE_SINGLE) + { + const int axis = (domain->slice_axis == SLICE_AXIS_AUTO) ? + axis_dominant_v3_single(viewnormal) : domain->slice_axis - 1; + + xyz[axis] = (float)res[axis] * domain->slice_depth; + num_points_v[axis] = 1; + res_max[axis] = xyz[axis] + 1; + } + + vector_draw_func func; + int max_points; + + if (domain->vector_draw_type == VECTOR_DRAW_NEEDLE) { + func = add_needle; + max_points = (num_points_v[0] * num_points_v[1] * num_points_v[2]) * 4 * 3; + } + else { + func = add_streamline; + max_points = (num_points_v[0] * num_points_v[1] * num_points_v[2]) * 2; + } + + float (*verts)[3] = MEM_mallocN(sizeof(float) * 3 * max_points, ""); + float (*colors)[3] = MEM_mallocN(sizeof(float) * 3 * max_points, ""); + + int num_points = 0; + + for (float x = floor(xyz[0]); x < res_max[0]; x += step_size) { + for (float y = floor(xyz[1]); y < res_max[1]; y += step_size) { + for (float z = floor(xyz[2]); z < res_max[2]; z += step_size) { int index = (floor(x) - res_min[0]) + (floor(y) - res_min[1]) * res[0] + (floor(z) - res_min[2]) * res[0] * res[1]; - float pos[3] = {min[0] + ((float)x + 0.5f) * cell_size[0], min[1] + ((float)y + 0.5f) * cell_size[1], min[2] + ((float)z + 0.5f) * cell_size[2]}; - float vel = sqrtf(vel_x[index] * vel_x[index] + vel_y[index] * vel_y[index] + vel_z[index] * vel_z[index]); + float pos[3] = { + min[0] + ((float)x + 0.5f) * cell_size[0], + min[1] + ((float)y + 0.5f) * cell_size[1], + min[2] + ((float)z + 0.5f) * cell_size[2] + }; - /* draw heat as scaled "arrows" */ - if (vel >= 0.01f) { - float col_g = 1.0f - vel; - CLAMP(col_g, 0.0f, 1.0f); - glColor3f(1.0f, col_g, 0.0f); - glPointSize(10.0f * vel); + float vel[3] = { + vel_x[index], vel_y[index], vel_z[index] + }; - glBegin(GL_LINES); - glVertex3f(pos[0], pos[1], pos[2]); - glVertex3f(pos[0] + vel_x[index] * vf, pos[1] + vel_y[index] * vf, pos[2] + vel_z[index] * vf); - glEnd(); - glBegin(GL_POINTS); - glVertex3f(pos[0] + vel_x[index] * vf, pos[1] + vel_y[index] * vf, pos[2] + vel_z[index] * vf); - glEnd(); - } + func(verts, colors, pos, vel, domain->vector_scale, cell_size[0], &num_points); } + } + } + + glLineWidth(1.0f); + + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, 0, verts); + + glEnableClientState(GL_COLOR_ARRAY); + glColorPointer(3, GL_FLOAT, 0, colors); + + glDrawArrays(GL_LINES, 0, num_points); + + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + + MEM_freeN(verts); + MEM_freeN(colors); } -#endif #ifdef SMOKE_DEBUG_HEAT void draw_smoke_heat(SmokeDomainSettings *domain, Object *ob) diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h index 314dadbaa52..0e2cb95dd89 100644 --- a/source/blender/editors/space_view3d/view3d_intern.h +++ b/source/blender/editors/space_view3d/view3d_intern.h @@ -296,12 +296,10 @@ void draw_smoke_volume(struct SmokeDomainSettings *sds, struct Object *ob, const float min[3], const float max[3], const float viewnormal[3]); -//#define SMOKE_DEBUG_VELOCITY //#define SMOKE_DEBUG_HEAT -#ifdef SMOKE_DEBUG_VELOCITY -void draw_smoke_velocity(struct SmokeDomainSettings *domain, struct Object *ob); -#endif +void draw_smoke_velocity(struct SmokeDomainSettings *domain, float viewnormal[3]); + #ifdef SMOKE_DEBUG_HEAT void draw_smoke_heat(struct SmokeDomainSettings *domain, struct Object *ob); #endif diff --git a/source/blender/makesdna/DNA_smoke_types.h b/source/blender/makesdna/DNA_smoke_types.h index 5526c18f656..ba7f73c2f63 100644 --- a/source/blender/makesdna/DNA_smoke_types.h +++ b/source/blender/makesdna/DNA_smoke_types.h @@ -72,6 +72,11 @@ enum { SLICE_AXIS_Z = 3, }; +enum { + VECTOR_DRAW_NEEDLE = 0, + VECTOR_DRAW_STREAMLINE = 1, +}; + /* cache compression */ #define SM_CACHE_LIGHT 0 #define SM_CACHE_HEAVY 1 @@ -184,10 +189,13 @@ typedef struct SmokeDomainSettings { /* Display settings */ char slice_method, axis_slice_method; - char slice_axis, pad2; + char slice_axis, draw_velocity; float slice_per_voxel; float slice_depth; float display_thickness; + float vector_scale; + char vector_draw_type; + char pad2[3]; } SmokeDomainSettings; diff --git a/source/blender/makesrna/intern/rna_smoke.c b/source/blender/makesrna/intern/rna_smoke.c index 22c1a115a15..40a45416aca 100644 --- a/source/blender/makesrna/intern/rna_smoke.c +++ b/source/blender/makesrna/intern/rna_smoke.c @@ -463,6 +463,12 @@ static void rna_def_smoke_domain_settings(BlenderRNA *brna) {0, NULL, 0, NULL, NULL} }; + static EnumPropertyItem vector_draw_items[] = { + {VECTOR_DRAW_NEEDLE, "NEEDLE", 0, "Needle", "Draw vectors as needles"}, + {VECTOR_DRAW_STREAMLINE, "STREAMLINE", 0, "Streamlines", "Draw vectors as streamlines"}, + {0, NULL, 0, NULL, NULL} + }; + srna = RNA_def_struct(brna, "SmokeDomainSettings", NULL); RNA_def_struct_ui_text(srna, "Domain Settings", "Smoke domain settings"); RNA_def_struct_sdna(srna, "SmokeDomainSettings"); @@ -781,6 +787,24 @@ static void rna_def_smoke_domain_settings(BlenderRNA *brna) RNA_def_property_ui_range(prop, 0.1, 100.0, 0.1, 3); RNA_def_property_ui_text(prop, "Thickness", "Thickness of smoke drawing in the viewport"); RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, NULL); + + prop = RNA_def_property(srna, "draw_velocity", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "draw_velocity", 0); + RNA_def_property_ui_text(prop, "Draw Velocity", "Toggle visualation of the velocity field as needles"); + RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL); + + prop = RNA_def_property(srna, "vector_draw_type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "vector_draw_type"); + RNA_def_property_enum_items(prop, vector_draw_items); + RNA_def_property_ui_text(prop, "Draw Type", ""); + RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL); + + prop = RNA_def_property(srna, "vector_scale", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "vector_scale"); + RNA_def_property_range(prop, 0.0, 1000.0); + RNA_def_property_ui_range(prop, 0.0, 100.0, 0.1, 3); + RNA_def_property_ui_text(prop, "Scale", "Multiplier for scaling the vectors"); + RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL); } static void rna_def_smoke_flow_settings(BlenderRNA *brna) -- cgit v1.2.3 From d35bf3f421fe4166f5275067cc71e92465f1b954 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dietrich?= Date: Sun, 25 Sep 2016 00:26:21 +0200 Subject: Fix compile error when building without smoke support. Also fixes possible NULL pointer dereference. Fixes T49445. --- source/blender/editors/space_view3d/drawvolume.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/source/blender/editors/space_view3d/drawvolume.c b/source/blender/editors/space_view3d/drawvolume.c index ef4db7ed6b8..79d51093734 100644 --- a/source/blender/editors/space_view3d/drawvolume.c +++ b/source/blender/editors/space_view3d/drawvolume.c @@ -648,6 +648,20 @@ typedef void (*vector_draw_func)(float(*)[3], float(*)[3], float*, float*, float void draw_smoke_velocity(SmokeDomainSettings *domain, float viewnormal[3]) { +#ifdef WITH_SMOKE + const float *vel_x = smoke_get_velocity_x(domain->fluid); + const float *vel_y = smoke_get_velocity_y(domain->fluid); + const float *vel_z = smoke_get_velocity_z(domain->fluid); +#else + const float *vel_x = NULL; + const float *vel_y = NULL; + const float *vel_z = NULL; +#endif + + if (ELEM(NULL, vel_x, vel_y, vel_z)) { + return; + } + const int *base_res = domain->base_res; const int *res = domain->res; const int *res_min = domain->res_min; @@ -655,10 +669,6 @@ void draw_smoke_velocity(SmokeDomainSettings *domain, float viewnormal[3]) int res_max[3]; copy_v3_v3_int(res_max, domain->res_max); - const float *vel_x = smoke_get_velocity_x(domain->fluid); - const float *vel_y = smoke_get_velocity_y(domain->fluid); - const float *vel_z = smoke_get_velocity_z(domain->fluid); - const float *cell_size = domain->cell_size; const float step_size = ((float)max_iii(base_res[0], base_res[1], base_res[2])) / 16.0f; -- cgit v1.2.3 From 5bdff9ea80068f5d921d818e314d6677b425c2b5 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 25 Sep 2016 12:15:14 +1000 Subject: Quiet shadow warning No need to declare new iterator for second loop. --- source/blender/bmesh/operators/bmo_primitive.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/source/blender/bmesh/operators/bmo_primitive.c b/source/blender/bmesh/operators/bmo_primitive.c index 992e89fe127..7b32921f8cf 100644 --- a/source/blender/bmesh/operators/bmo_primitive.c +++ b/source/blender/bmesh/operators/bmo_primitive.c @@ -1028,26 +1028,24 @@ void bmo_create_icosphere_exec(BMesh *bm, BMOperator *op) int uvi = 0; const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); for (a = 0; a < 20; a++) { - BMFace *eftemp; + BMFace *f; BMVert *v1, *v2, *v3; v1 = eva[icoface[a][0]]; v2 = eva[icoface[a][1]]; v3 = eva[icoface[a][2]]; - eftemp = BM_face_create_quad_tri(bm, v1, v2, v3, NULL, NULL, BM_CREATE_NOP); + f = BM_face_create_quad_tri(bm, v1, v2, v3, NULL, NULL, BM_CREATE_NOP); - BM_ITER_ELEM (l, &liter, eftemp, BM_LOOPS_OF_FACE) { + BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) { BMO_edge_flag_enable(bm, l->e, EDGE_MARK); } /* Set the UVs here, the iteration order of the faces is not guaranteed, * so it's best to set the UVs right after the face is created. */ - if(calc_uvs) { - BMLoop* l; - BMIter liter2; + if (calc_uvs) { int loop_index; - BM_ITER_ELEM_INDEX (l, &liter2, eftemp, BM_LOOPS_OF_FACE, loop_index) { + BM_ITER_ELEM_INDEX (l, &liter, f, BM_LOOPS_OF_FACE, loop_index) { MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); luv->uv[0] = icouvs[uvi][0]; luv->uv[1] = icouvs[uvi][1]; -- cgit v1.2.3 From d9b242f5fbd1c7cdd3a59663250ac603dfa9ad84 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 25 Sep 2016 11:34:31 +1000 Subject: Curve Fitting: de-duplicate cubic evaluation --- extern/curve_fit_nd/intern/curve_fit_cubic.c | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/extern/curve_fit_nd/intern/curve_fit_cubic.c b/extern/curve_fit_nd/intern/curve_fit_cubic.c index 9b4f1869c02..1ca38505e19 100644 --- a/extern/curve_fit_nd/intern/curve_fit_cubic.c +++ b/extern/curve_fit_nd/intern/curve_fit_cubic.c @@ -255,7 +255,7 @@ static void cubic_list_clear(CubicList *clist) /** \name Cubic Evaluation * \{ */ -static void cubic_evaluate( +static void cubic_calc_point( const Cubic *cubic, const double t, const uint dims, double r_v[]) { @@ -271,18 +271,6 @@ static void cubic_evaluate( } } -static void cubic_calc_point( - const Cubic *cubic, const double t, const uint dims, - double r_v[]) -{ - CUBIC_VARS_CONST(cubic, dims, p0, p1, p2, p3); - const double s = 1.0 - t; - for (uint j = 0; j < dims; j++) { - r_v[j] = p0[j] * s * s * s + - 3.0 * t * s * (s * p1[j] + t * p2[j]) + t * t * t * p3[j]; - } -} - static void cubic_calc_speed( const Cubic *cubic, const double t, const uint dims, double r_v[]) @@ -332,7 +320,7 @@ static double cubic_calc_error( #endif for (uint i = 1; i < points_offset_len - 1; i++, pt_real += dims) { - cubic_evaluate(cubic, u[i], dims, pt_eval); + cubic_calc_point(cubic, u[i], dims, pt_eval); const double err_sq = len_squared_vnvn(pt_real, pt_eval, dims); if (err_sq >= error_max_sq) { @@ -368,7 +356,7 @@ static double cubic_calc_error_simple( #endif for (uint i = 1; i < points_offset_len - 1; i++, pt_real += dims) { - cubic_evaluate(cubic, u[i], dims, pt_eval); + cubic_calc_point(cubic, u[i], dims, pt_eval); const double err_sq = len_squared_vnvn(pt_real, pt_eval, dims); if (err_sq >= error_threshold_sq) { @@ -501,7 +489,7 @@ static double points_calc_circle_tangent_factor( return (1.0 / 3.0) * 0.75; } else if (tan_dot < -1.0 + eps) { - /* parallele tangents (half-circle) */ + /* parallel tangents (half-circle) */ return (1.0 / 2.0); } else { -- cgit v1.2.3 From 05dbd650986717e9c131b06943b38f6d96a4903b Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 25 Sep 2016 11:40:18 +1000 Subject: Curve Fitting: inline dot-product (avoid temp vector) --- extern/curve_fit_nd/intern/curve_fit_cubic.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/extern/curve_fit_nd/intern/curve_fit_cubic.c b/extern/curve_fit_nd/intern/curve_fit_cubic.c index 1ca38505e19..ea482a1a012 100644 --- a/extern/curve_fit_nd/intern/curve_fit_cubic.c +++ b/extern/curve_fit_nd/intern/curve_fit_cubic.c @@ -665,13 +665,11 @@ static void cubic_from_points( double alpha_l, alpha_r; #ifdef USE_VLA double a[2][dims]; - double tmp[dims]; #else double *a[2] = { alloca(sizeof(double) * dims), alloca(sizeof(double) * dims), }; - double *tmp = alloca(sizeof(double) * dims); #endif { @@ -682,22 +680,22 @@ static void cubic_from_points( mul_vnvn_fl(a[0], tan_l, B1(u_prime[i]), dims); mul_vnvn_fl(a[1], tan_r, B2(u_prime[i]), dims); - c[0][0] += dot_vnvn(a[0], a[0], dims); - c[0][1] += dot_vnvn(a[0], a[1], dims); - c[1][1] += dot_vnvn(a[1], a[1], dims); + const double b0_plus_b1 = B0plusB1(u_prime[i]); + const double b2_plus_b3 = B2plusB3(u_prime[i]); - c[1][0] = c[0][1]; + /* inline dot product */ + for (uint j = 0; j < dims; j++) { + const double tmp = (pt[j] - (p0[j] * b0_plus_b1)) + (p3[j] * b2_plus_b3); - { - const double b0_plus_b1 = B0plusB1(u_prime[i]); - const double b2_plus_b3 = B2plusB3(u_prime[i]); - for (uint j = 0; j < dims; j++) { - tmp[j] = (pt[j] - (p0[j] * b0_plus_b1)) + (p3[j] * b2_plus_b3); - } + x[0] += a[0][j] * tmp; + x[1] += a[1][j] * tmp; - x[0] += dot_vnvn(a[0], tmp, dims); - x[1] += dot_vnvn(a[1], tmp, dims); + c[0][0] += a[0][j] * a[0][j]; + c[0][1] += a[0][j] * a[1][j]; + c[1][1] += a[1][j] * a[1][j]; } + + c[1][0] = c[0][1]; } double det_C0_C1 = c[0][0] * c[1][1] - c[0][1] * c[1][0]; -- cgit v1.2.3 From 6b5ad4a4d7039a78c4d7dc0315e855787b4dd10b Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 25 Sep 2016 12:03:10 +1000 Subject: Curve Fitting: 'offset' method used sign when it shouldn't --- extern/curve_fit_nd/intern/curve_fit_cubic.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extern/curve_fit_nd/intern/curve_fit_cubic.c b/extern/curve_fit_nd/intern/curve_fit_cubic.c index ea482a1a012..0a32f1e796a 100644 --- a/extern/curve_fit_nd/intern/curve_fit_cubic.c +++ b/extern/curve_fit_nd/intern/curve_fit_cubic.c @@ -611,8 +611,8 @@ static void cubic_from_points_offset_fallback( } } - double alpha_l = (dists[0] / 0.75) / dot_vnvn(tan_l, a[0], dims); - double alpha_r = (dists[1] / 0.75) / -dot_vnvn(tan_r, a[1], dims); + double alpha_l = (dists[0] / 0.75) / fabs(dot_vnvn(tan_l, a[0], dims)); + double alpha_r = (dists[1] / 0.75) / fabs(dot_vnvn(tan_r, a[1], dims)); if (!(alpha_l > 0.0)) { alpha_l = dir_dist / 3.0; -- cgit v1.2.3 From 6dd87f2abb5a15ec0712d3b202723386248eb672 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 25 Sep 2016 12:11:46 +1000 Subject: Curve Fitting: re-fitting heap pre-allocated too much --- extern/curve_fit_nd/intern/curve_fit_cubic_refit.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/extern/curve_fit_nd/intern/curve_fit_cubic_refit.c b/extern/curve_fit_nd/intern/curve_fit_cubic_refit.c index d22d042bff5..bf1ab99995f 100644 --- a/extern/curve_fit_nd/intern/curve_fit_cubic_refit.c +++ b/extern/curve_fit_nd/intern/curve_fit_cubic_refit.c @@ -463,7 +463,7 @@ static uint curve_incremental_simplify( rstate_pool_create(&epool, 0); #endif - Heap *heap = HEAP_new(knots_len); + Heap *heap = HEAP_new(knots_len_remaining); struct KnotRemove_Params params = { .pd = pd, @@ -698,7 +698,7 @@ static uint curve_incremental_simplify_refit( refit_pool_create(&epool, 0); #endif - Heap *heap = HEAP_new(knots_len); + Heap *heap = HEAP_new(knots_len_remaining); struct KnotRefit_Params params = { .pd = pd, @@ -890,7 +890,7 @@ static void knot_corner_error_recalculate( static uint curve_incremental_simplify_corners( const struct PointData *pd, struct Knot *knots, const uint knots_len, uint knots_len_remaining, - const double error_sq_max, const double error_sq_2x_max, + const double error_sq_max, const double error_sq_collapse_max, const double corner_angle, const uint dims, uint *r_corner_index_len) @@ -954,12 +954,12 @@ static uint curve_incremental_simplify_corners( project_vn_vnvn_normalized(k_proj_ref, co_prev, k_prev->tan[1], dims); project_vn_vnvn_normalized(k_proj_split, co_split, k_prev->tan[1], dims); - if (len_squared_vnvn(k_proj_ref, k_proj_split, dims) < error_sq_2x_max) { + if (len_squared_vnvn(k_proj_ref, k_proj_split, dims) < error_sq_collapse_max) { project_vn_vnvn_normalized(k_proj_ref, co_next, k_next->tan[0], dims); project_vn_vnvn_normalized(k_proj_split, co_split, k_next->tan[0], dims); - if (len_squared_vnvn(k_proj_ref, k_proj_split, dims) < error_sq_2x_max) { + if (len_squared_vnvn(k_proj_ref, k_proj_split, dims) < error_sq_collapse_max) { struct Knot *k_split = &knots[split_index]; @@ -1260,9 +1260,12 @@ int curve_fit_cubic_to_points_refit_db( #ifdef USE_CORNER_DETECT if (use_corner) { + +#ifdef DEBUG for (uint i = 0; i < knots_len; i++) { assert(knots[i].heap_node == NULL); } +#endif knots_len_remaining = curve_incremental_simplify_corners( &pd, knots, knots_len, knots_len_remaining, -- cgit v1.2.3 From 335ee5ce5aee3a92415d1608cc66acf3da995598 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Sun, 25 Sep 2016 05:07:38 +0200 Subject: Fix T49310: incorrect Cycles standalone normals with negative scale. --- intern/cycles/render/mesh.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp index 3eff35bae9e..039bb49d82f 100644 --- a/intern/cycles/render/mesh.cpp +++ b/intern/cycles/render/mesh.cpp @@ -471,16 +471,12 @@ void Mesh::add_face_normals() /* compute face normals */ size_t triangles_size = num_triangles(); - bool flip = transform_negative_scaled; if(triangles_size) { float3 *verts_ptr = verts.data(); for(size_t i = 0; i < triangles_size; i++) { fN[i] = compute_face_normal(get_triangle(i), verts_ptr); - - if(flip) - fN[i] = -fN[i]; } } -- cgit v1.2.3 From ae69986b70611f358491759f39fd91efd015dab9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dietrich?= Date: Sun, 25 Sep 2016 17:02:46 +0200 Subject: Viewport smoke: fix a couple of issues in the new display settings. - WITH_SMOKE macro was not defined so some code was not compiled, though it was still accessible from the UI - some UI elements were disappearing due to bad indentation, also rework the UI code to not hide but rather disable/grey out button in the UI - Display thickness was not used due to bad manual merge of the code from the patch. --- .../startup/bl_ui/properties_physics_smoke.py | 37 ++++++++++++---------- source/blender/editors/space_view3d/CMakeLists.txt | 4 +++ source/blender/editors/space_view3d/drawvolume.c | 12 +++---- 3 files changed, 30 insertions(+), 23 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_physics_smoke.py b/release/scripts/startup/bl_ui/properties_physics_smoke.py index 3cf77135622..41a0194e31b 100644 --- a/release/scripts/startup/bl_ui/properties_physics_smoke.py +++ b/release/scripts/startup/bl_ui/properties_physics_smoke.py @@ -373,23 +373,26 @@ class PHYSICS_PT_smoke_display_settings(PhysicButtonsPanel, Panel): slice_method = domain.slice_method axis_slice_method = domain.axis_slice_method - if slice_method == 'AXIS_ALIGNED': - layout.prop(domain, "axis_slice_method") - - if axis_slice_method == 'SINGLE': - layout.prop(domain, "slice_axis") - layout.prop(domain, "slice_depth") - - if axis_slice_method == 'FULL': - layout.prop(domain, "slice_per_voxel") - - layout.separator() - layout.label(text="Debug:") - layout.prop(domain, "draw_velocity") - col = layout.column(); - col.enabled = domain.draw_velocity - col.prop(domain, "vector_draw_type") - col.prop(domain, "vector_scale") + row = layout.row(); + row.enabled = (slice_method == 'AXIS_ALIGNED') + row.prop(domain, "axis_slice_method") + + col = layout.column(); + col.enabled = (axis_slice_method == 'SINGLE') + col.prop(domain, "slice_axis") + col.prop(domain, "slice_depth") + + row = layout.row(); + row.enabled = (axis_slice_method == 'FULL') + row.prop(domain, "slice_per_voxel") + + layout.separator() + layout.label(text="Debug:") + layout.prop(domain, "draw_velocity") + col = layout.column(); + col.enabled = domain.draw_velocity + col.prop(domain, "vector_draw_type") + col.prop(domain, "vector_scale") if __name__ == "__main__": # only for live edit. diff --git a/source/blender/editors/space_view3d/CMakeLists.txt b/source/blender/editors/space_view3d/CMakeLists.txt index 059b384a9e2..a5c60248bf1 100644 --- a/source/blender/editors/space_view3d/CMakeLists.txt +++ b/source/blender/editors/space_view3d/CMakeLists.txt @@ -90,6 +90,10 @@ if(WITH_FREESTYLE) add_definitions(-DWITH_FREESTYLE) endif() +if(WITH_MOD_SMOKE) + add_definitions(-DWITH_SMOKE) +endif() + if(WITH_LEGACY_DEPSGRAPH) add_definitions(-DWITH_LEGACY_DEPSGRAPH) endif() diff --git a/source/blender/editors/space_view3d/drawvolume.c b/source/blender/editors/space_view3d/drawvolume.c index 79d51093734..d743ff9239a 100644 --- a/source/blender/editors/space_view3d/drawvolume.c +++ b/source/blender/editors/space_view3d/drawvolume.c @@ -382,7 +382,7 @@ static void bind_shader(SmokeDomainSettings *sds, GPUShader *shader, GPUTexture GPU_shader_uniform_texture(shader, spec_location, tex_spec); } else { - float density_scale = 10.0f; + float density_scale = 10.0f * sds->display_thickness; GPU_shader_uniform_vector(shader, stepsize_location, 1, 1, &sds->dx); GPU_shader_uniform_vector(shader, densityscale_location, 1, 1, &density_scale); @@ -572,6 +572,7 @@ void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob, } } +#ifdef WITH_SMOKE static void add_tri(float (*verts)[3], float(*colors)[3], int *offset, float p1[3], float p2[3], float p3[3], float rgb[3]) { @@ -645,6 +646,7 @@ static void add_streamline(float (*verts)[3], float(*colors)[3], float center[3] } typedef void (*vector_draw_func)(float(*)[3], float(*)[3], float*, float*, float, float, int*); +#endif /* WITH_SMOKE */ void draw_smoke_velocity(SmokeDomainSettings *domain, float viewnormal[3]) { @@ -652,11 +654,6 @@ void draw_smoke_velocity(SmokeDomainSettings *domain, float viewnormal[3]) const float *vel_x = smoke_get_velocity_x(domain->fluid); const float *vel_y = smoke_get_velocity_y(domain->fluid); const float *vel_z = smoke_get_velocity_z(domain->fluid); -#else - const float *vel_x = NULL; - const float *vel_y = NULL; - const float *vel_z = NULL; -#endif if (ELEM(NULL, vel_x, vel_y, vel_z)) { return; @@ -755,6 +752,9 @@ void draw_smoke_velocity(SmokeDomainSettings *domain, float viewnormal[3]) MEM_freeN(verts); MEM_freeN(colors); +#else + UNUSED_VARS(domain, viewnormal); +#endif } #ifdef SMOKE_DEBUG_HEAT -- cgit v1.2.3 From 584288a97c2b1f28dc0e29b2bd986830df233947 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dietrich?= Date: Sun, 25 Sep 2016 21:45:09 +0200 Subject: Smoke debug draw: take adaptive domain position into account. Eventually the various functions that deals with adaptive domain bounding box shall de-duplicated. --- source/blender/editors/space_view3d/drawvolume.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/source/blender/editors/space_view3d/drawvolume.c b/source/blender/editors/space_view3d/drawvolume.c index d743ff9239a..b0e21601b9c 100644 --- a/source/blender/editors/space_view3d/drawvolume.c +++ b/source/blender/editors/space_view3d/drawvolume.c @@ -680,8 +680,11 @@ void draw_smoke_velocity(SmokeDomainSettings *domain, float viewnormal[3]) if (xyz[1] < res_min[1]) xyz[1] += step_size; if (xyz[2] < res_min[2]) xyz[2] += step_size; - float min[3]; - add_v3_v3v3(min, domain->p0, domain->obj_shift_f); + float min[3] = { + domain->p0[0] - domain->cell_size[0] * domain->adapt_res, + domain->p0[1] - domain->cell_size[1] * domain->adapt_res, + domain->p0[2] - domain->cell_size[2] * domain->adapt_res, + }; int num_points_v[3] = { ((float)(res_max[0] - floor(xyz[0])) / step_size) + 0.5f, @@ -695,7 +698,7 @@ void draw_smoke_velocity(SmokeDomainSettings *domain, float viewnormal[3]) const int axis = (domain->slice_axis == SLICE_AXIS_AUTO) ? axis_dominant_v3_single(viewnormal) : domain->slice_axis - 1; - xyz[axis] = (float)res[axis] * domain->slice_depth; + xyz[axis] = (float)base_res[axis] * domain->slice_depth; num_points_v[axis] = 1; res_max[axis] = xyz[axis] + 1; } -- cgit v1.2.3 From 448ee227be612ca4627c4ddc5e2650ebe2a3a28e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dietrich?= Date: Sun, 25 Sep 2016 21:55:29 +0200 Subject: Volume slice settings: tweak/fix UI enabling conditions. It was still possible to have some properties enabled when it does not make sense to have them so. --- release/scripts/startup/bl_ui/properties_physics_smoke.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_physics_smoke.py b/release/scripts/startup/bl_ui/properties_physics_smoke.py index 41a0194e31b..df03f23a4b5 100644 --- a/release/scripts/startup/bl_ui/properties_physics_smoke.py +++ b/release/scripts/startup/bl_ui/properties_physics_smoke.py @@ -373,17 +373,20 @@ class PHYSICS_PT_smoke_display_settings(PhysicButtonsPanel, Panel): slice_method = domain.slice_method axis_slice_method = domain.axis_slice_method + do_axis_slicing = (slice_method == 'AXIS_ALIGNED') + do_full_slicing = (axis_slice_method == 'FULL') + row = layout.row(); - row.enabled = (slice_method == 'AXIS_ALIGNED') + row.enabled = do_axis_slicing row.prop(domain, "axis_slice_method") col = layout.column(); - col.enabled = (axis_slice_method == 'SINGLE') + col.enabled = not do_full_slicing and do_axis_slicing col.prop(domain, "slice_axis") col.prop(domain, "slice_depth") row = layout.row(); - row.enabled = (axis_slice_method == 'FULL') + row.enabled = do_full_slicing or not do_axis_slicing row.prop(domain, "slice_per_voxel") layout.separator() -- cgit v1.2.3 From 0b89b31a1842edba162e3ca01b556906c8adee52 Mon Sep 17 00:00:00 2001 From: Lukas Stockner Date: Sun, 25 Sep 2016 22:08:08 +0200 Subject: Cycles: Fix T49411: Multiscatter GGX with zero roughness when Filter Glossy is enabled --- .../cycles/kernel/closure/bsdf_microfacet_multi.h | 60 +++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/intern/cycles/kernel/closure/bsdf_microfacet_multi.h b/intern/cycles/kernel/closure/bsdf_microfacet_multi.h index df848c3d179..0a6dd4dcbdf 100644 --- a/intern/cycles/kernel/closure/bsdf_microfacet_multi.h +++ b/intern/cycles/kernel/closure/bsdf_microfacet_multi.h @@ -373,6 +373,11 @@ ccl_device float3 bsdf_microfacet_multi_ggx_eval_transmit(const ShaderClosure *s ccl_device float3 bsdf_microfacet_multi_ggx_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf, ccl_addr_space uint *lcg_state) { const MicrofacetBsdf *bsdf = (const MicrofacetBsdf*)sc; + + if(bsdf->alpha_x*bsdf->alpha_y < 1e-7f) { + return make_float3(0.0f, 0.0f, 0.0f); + } + bool is_aniso = (bsdf->alpha_x != bsdf->alpha_y); float3 X, Y, Z; Z = bsdf->N; @@ -394,9 +399,18 @@ ccl_device float3 bsdf_microfacet_multi_ggx_eval_reflect(const ShaderClosure *sc ccl_device int bsdf_microfacet_multi_ggx_sample(KernelGlobals *kg, const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf, ccl_addr_space uint *lcg_state) { const MicrofacetBsdf *bsdf = (const MicrofacetBsdf*)sc; - bool is_aniso = (bsdf->alpha_x != bsdf->alpha_y); + float3 X, Y, Z; Z = bsdf->N; + + if(bsdf->alpha_x*bsdf->alpha_y < 1e-7f) { + *omega_in = 2*dot(Z, I)*Z - I; + *pdf = 1e6f; + *eval = make_float3(1e6f, 1e6f, 1e6f); + return LABEL_REFLECT|LABEL_SINGULAR; + } + + bool is_aniso = (bsdf->alpha_x != bsdf->alpha_y); if(is_aniso) make_orthonormals_tangent(Z, bsdf->T, &X, &Y); else @@ -438,6 +452,11 @@ ccl_device int bsdf_microfacet_multi_ggx_glass_setup(MicrofacetBsdf *bsdf) ccl_device float3 bsdf_microfacet_multi_ggx_glass_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf, ccl_addr_space uint *lcg_state) { const MicrofacetBsdf *bsdf = (const MicrofacetBsdf*)sc; + + if(bsdf->alpha_x*bsdf->alpha_y < 1e-7f) { + return make_float3(0.0f, 0.0f, 0.0f); + } + float3 X, Y, Z; Z = bsdf->N; make_orthonormals(Z, &X, &Y); @@ -451,6 +470,11 @@ ccl_device float3 bsdf_microfacet_multi_ggx_glass_eval_transmit(const ShaderClos ccl_device float3 bsdf_microfacet_multi_ggx_glass_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf, ccl_addr_space uint *lcg_state) { const MicrofacetBsdf *bsdf = (const MicrofacetBsdf*)sc; + + if(bsdf->alpha_x*bsdf->alpha_y < 1e-7f) { + return make_float3(0.0f, 0.0f, 0.0f); + } + float3 X, Y, Z; Z = bsdf->N; make_orthonormals(Z, &X, &Y); @@ -465,8 +489,42 @@ ccl_device float3 bsdf_microfacet_multi_ggx_glass_eval_reflect(const ShaderClosu ccl_device int bsdf_microfacet_multi_ggx_glass_sample(KernelGlobals *kg, const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf, ccl_addr_space uint *lcg_state) { const MicrofacetBsdf *bsdf = (const MicrofacetBsdf*)sc; + float3 X, Y, Z; Z = bsdf->N; + + if(bsdf->alpha_x*bsdf->alpha_y < 1e-7f) { + float3 R, T; +#ifdef __RAY_DIFFERENTIALS__ + float3 dRdx, dRdy, dTdx, dTdy; +#endif + bool inside; + float fresnel = fresnel_dielectric(bsdf->ior, Z, I, &R, &T, +#ifdef __RAY_DIFFERENTIALS__ + dIdx, dIdy, &dRdx, &dRdy, &dTdx, &dTdy, +#endif + &inside); + + *pdf = 1e6f; + *eval = make_float3(1e6f, 1e6f, 1e6f); + if(randu < fresnel) { + *omega_in = R; +#ifdef __RAY_DIFFERENTIALS__ + *domega_in_dx = dRdx; + *domega_in_dy = dRdy; +#endif + return LABEL_REFLECT|LABEL_SINGULAR; + } + else { + *omega_in = T; +#ifdef __RAY_DIFFERENTIALS__ + *domega_in_dx = dTdx; + *domega_in_dy = dTdy; +#endif + return LABEL_TRANSMIT|LABEL_SINGULAR; + } + } + make_orthonormals(Z, &X, &Y); float3 localI = make_float3(dot(I, X), dot(I, Y), dot(I, Z)); -- cgit v1.2.3 From 04230e80d12a7187887a927f16a0ccdac9b50e9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dietrich?= Date: Sun, 25 Sep 2016 22:09:05 +0200 Subject: Alembic: only interpolate vertices when their number don't differ between samples. This could cause some crashes. --- source/blender/alembic/intern/abc_mesh.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/source/blender/alembic/intern/abc_mesh.cc b/source/blender/alembic/intern/abc_mesh.cc index 00c86779960..8e640b36c27 100644 --- a/source/blender/alembic/intern/abc_mesh.cc +++ b/source/blender/alembic/intern/abc_mesh.cc @@ -859,7 +859,10 @@ static void read_mverts(CDStreamConfig &config, const AbcMeshData &mesh_data) const P3fArraySamplePtr &positions = mesh_data.positions; const N3fArraySamplePtr &normals = mesh_data.vertex_normals; - if (config.weight != 0.0f && mesh_data.ceil_positions) { + if ( config.weight != 0.0f + && mesh_data.ceil_positions != NULL + && mesh_data.ceil_positions->size() == positions->size()) + { read_mverts_interp(mverts, positions, mesh_data.ceil_positions, config.weight); return; } -- cgit v1.2.3 From 18b0738303b27d827d3f4d4e32a22785817a818e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dietrich?= Date: Sun, 25 Sep 2016 22:11:09 +0200 Subject: Cleanup: remove unused function. --- source/blender/alembic/intern/abc_mesh.cc | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/source/blender/alembic/intern/abc_mesh.cc b/source/blender/alembic/intern/abc_mesh.cc index 8e640b36c27..84b89d9ab9e 100644 --- a/source/blender/alembic/intern/abc_mesh.cc +++ b/source/blender/alembic/intern/abc_mesh.cc @@ -146,19 +146,6 @@ static void get_topology(DerivedMesh *dm, } } -static void get_material_indices(DerivedMesh *dm, std::vector &indices) -{ - indices.clear(); - indices.reserve(dm->getNumTessFaces(dm)); - - MPoly *mpolys = dm->getPolyArray(dm); - - for (int i = 1, e = dm->getNumPolys(dm); i < e; ++i) { - MPoly *mpoly = &mpolys[i]; - indices.push_back(mpoly->mat_nr); - } -} - static void get_creases(DerivedMesh *dm, std::vector &indices, std::vector &lengths, -- cgit v1.2.3 From 07de832e22f5052d042605fdf3f8161a213c4f80 Mon Sep 17 00:00:00 2001 From: Lukas Stockner Date: Sun, 25 Sep 2016 22:11:50 +0200 Subject: Cycles: Use correct light sampling PDF for MIS calculation with Branched Path Tracing The light sampling functions calculate light sampling PDF for the case that the light has been randomly selected out of all lights. However, since BPT handles lamps and meshlights separately, this isn't the case. So, to avoid a wrong result, the code just included the 0.5 factor in the throughput. In theory, however, the correction should be made to the sampling probability, which needs to be doubled. Now, for the regular calculation, that's no real difference since the throughput is divided by the pdf. However, it does matter for the MIS calculation - it's unbiased both ways, but including the factor in the PDF instead of the throughput should give slightly better results. Reviewers: sergey, brecht, dingto, juicyfruit Differential Revision: https://developer.blender.org/D2258 --- intern/cycles/kernel/kernel_path_surface.h | 15 +++++++++------ intern/cycles/kernel/kernel_path_volume.h | 12 ++++++------ 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/intern/cycles/kernel/kernel_path_surface.h b/intern/cycles/kernel/kernel_path_surface.h index 27acf8166b3..45f0f1cbfaa 100644 --- a/intern/cycles/kernel/kernel_path_surface.h +++ b/intern/cycles/kernel/kernel_path_surface.h @@ -46,15 +46,17 @@ ccl_device_noinline void kernel_branched_path_surface_connect_light(KernelGlobal float num_samples_inv = num_samples_adjust/(num_samples*kernel_data.integrator.num_all_lights); RNG lamp_rng = cmj_hash(*rng, i); - if(kernel_data.integrator.pdf_triangles != 0.0f) - num_samples_inv *= 0.5f; - for(int j = 0; j < num_samples; j++) { float light_u, light_v; path_branched_rng_2D(kg, &lamp_rng, state, j, num_samples, PRNG_LIGHT_U, &light_u, &light_v); LightSample ls; if(lamp_light_sample(kg, i, light_u, light_v, ccl_fetch(sd, P), &ls)) { + /* The sampling probability returned by lamp_light_sample assumes that all lights were sampled. + * However, this code only samples lamps, so if the scene also had mesh lights, the real probability is twice as high. */ + if(kernel_data.integrator.pdf_triangles != 0.0f) + ls.pdf *= 2.0f; + if(direct_emission(kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp)) { /* trace shadow ray */ float3 shadow; @@ -73,9 +75,6 @@ ccl_device_noinline void kernel_branched_path_surface_connect_light(KernelGlobal int num_samples = ceil_to_int(num_samples_adjust*kernel_data.integrator.mesh_light_samples); float num_samples_inv = num_samples_adjust/num_samples; - if(kernel_data.integrator.num_all_lights) - num_samples_inv *= 0.5f; - for(int j = 0; j < num_samples; j++) { float light_t = path_branched_rng_1D(kg, rng, state, j, num_samples, PRNG_LIGHT); float light_u, light_v; @@ -87,6 +86,10 @@ ccl_device_noinline void kernel_branched_path_surface_connect_light(KernelGlobal LightSample ls; if(light_sample(kg, light_t, light_u, light_v, ccl_fetch(sd, time), ccl_fetch(sd, P), state->bounce, &ls)) { + /* Same as above, probability needs to be corrected since the sampling was forced to select a mesh light. */ + if(kernel_data.integrator.num_all_lights) + ls.pdf *= 2.0f; + if(direct_emission(kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp)) { /* trace shadow ray */ float3 shadow; diff --git a/intern/cycles/kernel/kernel_path_volume.h b/intern/cycles/kernel/kernel_path_volume.h index 0bb8f1c517f..5ee1912c913 100644 --- a/intern/cycles/kernel/kernel_path_volume.h +++ b/intern/cycles/kernel/kernel_path_volume.h @@ -136,9 +136,6 @@ ccl_device void kernel_branched_path_volume_connect_light(KernelGlobals *kg, RNG float num_samples_inv = 1.0f/(num_samples*kernel_data.integrator.num_all_lights); RNG lamp_rng = cmj_hash(*rng, i); - if(kernel_data.integrator.pdf_triangles != 0.0f) - num_samples_inv *= 0.5f; - for(int j = 0; j < num_samples; j++) { /* sample random position on given light */ float light_u, light_v; @@ -161,6 +158,9 @@ ccl_device void kernel_branched_path_volume_connect_light(KernelGlobals *kg, RNG /* todo: split up light_sample so we don't have to call it again with new position */ if(lamp_light_sample(kg, i, light_u, light_v, sd->P, &ls)) { + if(kernel_data.integrator.pdf_triangles != 0.0f) + ls.pdf *= 2.0f; + if(direct_emission(kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp)) { /* trace shadow ray */ float3 shadow; @@ -179,9 +179,6 @@ ccl_device void kernel_branched_path_volume_connect_light(KernelGlobals *kg, RNG int num_samples = kernel_data.integrator.mesh_light_samples; float num_samples_inv = 1.0f/num_samples; - if(kernel_data.integrator.num_all_lights) - num_samples_inv *= 0.5f; - for(int j = 0; j < num_samples; j++) { /* sample random position on random triangle */ float light_t = path_branched_rng_1D_for_decision(kg, rng, state, j, num_samples, PRNG_LIGHT); @@ -209,6 +206,9 @@ ccl_device void kernel_branched_path_volume_connect_light(KernelGlobals *kg, RNG /* todo: split up light_sample so we don't have to call it again with new position */ if(light_sample(kg, light_t, light_u, light_v, sd->time, sd->P, state->bounce, &ls)) { + if(kernel_data.integrator.num_all_lights) + ls.pdf *= 2.0f; + if(direct_emission(kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp)) { /* trace shadow ray */ float3 shadow; -- cgit v1.2.3 From 7c532601090c6e5a09484a0f8a39467856a8d6f4 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Mon, 26 Sep 2016 09:49:34 +0200 Subject: Fix crash in own recent rB776a8548f03a049. New ID may be null, have to check this too! Reported by @panzergame over IRC, thanks. To be ported to 2.78 as well. --- source/blender/blenkernel/intern/sca.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/source/blender/blenkernel/intern/sca.c b/source/blender/blenkernel/intern/sca.c index c357b2ef9f7..61aa8c7589f 100644 --- a/source/blender/blenkernel/intern/sca.c +++ b/source/blender/blenkernel/intern/sca.c @@ -666,15 +666,16 @@ void set_sca_new_poins(void) * ...and forces us to add yet another very ugly hack to get remapping with logic bricks working. */ void BKE_sca_logic_links_remap(Main *bmain, Object *ob_old, Object *ob_new) { + if (ob_new == NULL || (ob_old->controllers.first == NULL && ob_old->actuators.first == NULL)) { + /* Nothing to do here... */ + return; + } + GHash *controllers_map = ob_old->controllers.first ? BLI_ghash_ptr_new_ex(__func__, BLI_listbase_count(&ob_old->controllers)) : NULL; GHash *actuators_map = ob_old->actuators.first ? BLI_ghash_ptr_new_ex(__func__, BLI_listbase_count(&ob_old->actuators)) : NULL; - if (!(controllers_map || actuators_map)) { - return; - } - /* We try to remap old controllers/actuators to new ones - in a very basic way. */ for (bController *cont_old = ob_old->controllers.first, *cont_new = ob_new->controllers.first; cont_old; -- cgit v1.2.3 From eab3e0af1c50d9aafdb57fbfb269eed631f3ecc1 Mon Sep 17 00:00:00 2001 From: Dalai Felinto Date: Mon, 26 Sep 2016 13:56:45 +0000 Subject: Cleanup: stereo windowmanager code This will make the changes in blender2.8 branch simpler --- source/blender/windowmanager/intern/wm_stereo.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/source/blender/windowmanager/intern/wm_stereo.c b/source/blender/windowmanager/intern/wm_stereo.c index 5576a104123..1c1c2ad35af 100644 --- a/source/blender/windowmanager/intern/wm_stereo.c +++ b/source/blender/windowmanager/intern/wm_stereo.c @@ -168,7 +168,6 @@ static void wm_method_draw_stereo3d_sidebyside(wmWindow *win) wmDrawData *drawdata; wmDrawTriple *triple; float halfx, halfy, ratiox, ratioy; - float alpha = 1.0f; int view; int soffx; bool cross_eyed = (win->stereo3d_format->flag & S3D_SIDEBYSIDE_CROSSEYED) != 0; @@ -187,8 +186,6 @@ static void wm_method_draw_stereo3d_sidebyside(wmWindow *win) soffx = 0; } - glEnable(triple->target); - const int sizex = triple->x; const int sizey = triple->y; @@ -206,9 +203,10 @@ static void wm_method_draw_stereo3d_sidebyside(wmWindow *win) halfy /= triple->y; } + glEnable(triple->target); glBindTexture(triple->target, triple->bind); - glColor4f(1.0f, 1.0f, 1.0f, alpha); + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); glBegin(GL_QUADS); glTexCoord2f(halfx, halfy); glVertex2f(soffx, 0); @@ -225,7 +223,6 @@ static void wm_method_draw_stereo3d_sidebyside(wmWindow *win) glBindTexture(triple->target, 0); glDisable(triple->target); - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); } } @@ -234,7 +231,6 @@ static void wm_method_draw_stereo3d_topbottom(wmWindow *win) wmDrawData *drawdata; wmDrawTriple *triple; float halfx, halfy, ratiox, ratioy; - float alpha = 1.0f; int view; int soffy; @@ -249,8 +245,6 @@ static void wm_method_draw_stereo3d_topbottom(wmWindow *win) soffy = 0; } - glEnable(triple->target); - const int sizex = triple->x; const int sizey = triple->y; @@ -268,9 +262,10 @@ static void wm_method_draw_stereo3d_topbottom(wmWindow *win) halfy /= triple->y; } + glEnable(triple->target); glBindTexture(triple->target, triple->bind); - glColor4f(1.0f, 1.0f, 1.0f, alpha); + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); glBegin(GL_QUADS); glTexCoord2f(halfx, halfy); glVertex2f(0, soffy); @@ -287,7 +282,6 @@ static void wm_method_draw_stereo3d_topbottom(wmWindow *win) glBindTexture(triple->target, 0); glDisable(triple->target); - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); } } -- cgit v1.2.3 From b23ffded0866b5b24cb50fca669efde4ec1e3ffd Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Mon, 26 Sep 2016 16:35:52 +0200 Subject: Fix Scene datablocks being created with a real user while never having any real datablock user. Now using new system dedicated to that kind of cases, id_ensure_real_user(), instead. That way, usercount of Scenes is handled correctly at deletion time. Reported by @sergey over IRC, thanks. --- source/blender/blenkernel/intern/scene.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index acf6a313989..0d204461d16 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -819,6 +819,8 @@ Scene *BKE_scene_add(Main *bmain, const char *name) Scene *sce; sce = BKE_libblock_alloc(bmain, ID_SCE, name); + id_us_min(&sce->id); + id_us_ensure_real(&sce->id); BKE_scene_init(sce); -- cgit v1.2.3