From 94a2775a14865ef699901afd41294b688e7211a5 Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Wed, 29 Feb 2012 19:46:31 +0000 Subject: [PATCH 001/347] M source/blender/editors/object/object_vgroup.c M source/blender/editors/object/object_ops.c M source/blender/editors/object/object_intern.h --- source/blender/editors/object/object_intern.h | 1 + source/blender/editors/object/object_ops.c | 1 + source/blender/editors/object/object_vgroup.c | 29 +++++++++++++++++++ 3 files changed, 31 insertions(+) diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index 526706b566d..b1c071ea2a0 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -200,6 +200,7 @@ void OBJECT_OT_vertex_group_copy_to_selected(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_copy(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_normalize(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_normalize_all(struct wmOperatorType *ot); +void OBJECT_OT_vertex_group_transfer_weight(struct wmOperatorType *ot); /*cyborgmuppets experimental test */ void OBJECT_OT_vertex_group_levels(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_lock(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_fix(struct wmOperatorType *ot); diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index 542b75e1f19..550082d7554 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -173,6 +173,7 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_vertex_group_copy); WM_operatortype_append(OBJECT_OT_vertex_group_normalize); WM_operatortype_append(OBJECT_OT_vertex_group_normalize_all); + WM_operatortype_append(OBJECT_OT_vertex_group_transfer_weight); /*cyborgmuppets experimental test*/ WM_operatortype_append(OBJECT_OT_vertex_group_lock); WM_operatortype_append(OBJECT_OT_vertex_group_fix); WM_operatortype_append(OBJECT_OT_vertex_group_invert); diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index c60041fe67b..f14177ae3a3 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -1176,6 +1176,8 @@ static void vgroup_normalize_all(Object *ob, int lock_active) } } +static void vgroup_transfer_weight() +{} static void vgroup_lock_all(Object *ob, int action) { @@ -2367,6 +2369,33 @@ void OBJECT_OT_vertex_group_normalize_all(wmOperatorType *ot) "Keep the values of the active group while normalizing others"); } +static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) +{ + Object *ob= ED_object_context(C); + + vgroup_transfer_weight(); + + DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, ob->data); + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_vertex_group_transfer_weight(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Transfer Weight"; + ot->idname= "OBJECT_OT_vertex_group_transfer_weight"; + + /* api callbacks */ + ot->poll= vertex_group_poll; + ot->exec= vertex_group_transfer_weight_exec; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + static int vertex_group_fix_exec(bContext *C, wmOperator *op) { Object *ob= CTX_data_active_object(C); From 42dfd8292821bdf079eb4cde97dc396aca59fb32 Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Wed, 29 Feb 2012 19:55:54 +0000 Subject: [PATCH 002/347] M source/blender/editors/object/object_ops.c M source/blender/editors/object/object_intern.h --- source/blender/editors/object/object_intern.h | 2 +- source/blender/editors/object/object_ops.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index b1c071ea2a0..29f46f93315 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -200,7 +200,7 @@ void OBJECT_OT_vertex_group_copy_to_selected(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_copy(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_normalize(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_normalize_all(struct wmOperatorType *ot); -void OBJECT_OT_vertex_group_transfer_weight(struct wmOperatorType *ot); /*cyborgmuppets experimental test */ +void OBJECT_OT_vertex_group_transfer_weight(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_levels(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_lock(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_fix(struct wmOperatorType *ot); diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index 550082d7554..d6b5861fa66 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -173,7 +173,7 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_vertex_group_copy); WM_operatortype_append(OBJECT_OT_vertex_group_normalize); WM_operatortype_append(OBJECT_OT_vertex_group_normalize_all); - WM_operatortype_append(OBJECT_OT_vertex_group_transfer_weight); /*cyborgmuppets experimental test*/ + WM_operatortype_append(OBJECT_OT_vertex_group_transfer_weight); WM_operatortype_append(OBJECT_OT_vertex_group_lock); WM_operatortype_append(OBJECT_OT_vertex_group_fix); WM_operatortype_append(OBJECT_OT_vertex_group_invert); From 5b29a7bd2f9e3503c06e0e97a1fc75bca106dc6c Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Fri, 2 Mar 2012 13:33:14 +0000 Subject: [PATCH 003/347] from first change up until including this: added two buttons to gui, transfer weight and trtransfer weight all, made the basic structure, redy to implement the contents of the functions in object_vgroup.c --- source/blender/editors/object/object_intern.h | 1 + source/blender/editors/object/object_ops.c | 1 + source/blender/editors/object/object_vgroup.c | 42 +++++++++++++++++-- 3 files changed, 41 insertions(+), 3 deletions(-) diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index 29f46f93315..bb87bd5de2e 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -200,6 +200,7 @@ void OBJECT_OT_vertex_group_copy_to_selected(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_copy(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_normalize(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_normalize_all(struct wmOperatorType *ot); +void OBJECT_OT_vertex_group_transfer_weight_all(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_transfer_weight(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_levels(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_lock(struct wmOperatorType *ot); diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index d6b5861fa66..08df069fbf1 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -173,6 +173,7 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_vertex_group_copy); WM_operatortype_append(OBJECT_OT_vertex_group_normalize); WM_operatortype_append(OBJECT_OT_vertex_group_normalize_all); + WM_operatortype_append(OBJECT_OT_vertex_group_transfer_weight_all); WM_operatortype_append(OBJECT_OT_vertex_group_transfer_weight); WM_operatortype_append(OBJECT_OT_vertex_group_lock); WM_operatortype_append(OBJECT_OT_vertex_group_fix); diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index f14177ae3a3..d8aead9fdc9 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -20,7 +20,7 @@ * * The Original Code is: all of this file. * - * Contributor(s): none yet. + * Contributor(s): Ove M Henriksen * * ***** END GPL LICENSE BLOCK ***** */ @@ -75,6 +75,7 @@ #include "UI_resources.h" #include "object_intern.h" +#include /************************ Exported Functions **********************/ static void vgroup_remap_update_users(Object *ob, int *map); @@ -1176,8 +1177,16 @@ static void vgroup_normalize_all(Object *ob, int lock_active) } } -static void vgroup_transfer_weight() -{} +static void vgroup_transfer_weight_all(Object *ob_act, Object *ob_other) +{ + /* for each vertex group {vgroup_transfer_weight()} */ + printf("Not implemented yet!"); +} + +static void vgroup_transfer_weight(Object *ob_act, Object *ob_other) +{ + printf("not implemented yet!"); +} static void vgroup_lock_all(Object *ob, int action) { @@ -2369,6 +2378,33 @@ void OBJECT_OT_vertex_group_normalize_all(wmOperatorType *ot) "Keep the values of the active group while normalizing others"); } +static int vertex_group_transfer_weight_all_exec(bContext *C, wmOperator *op) +{ + Object *ob= ED_object_context(C); + + vgroup_transfer_weight_all(); + + DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, ob->data); + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_vertex_group_transfer_weight_all(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Transfer Weight"; + ot->idname= "OBJECT_OT_vertex_group_transfer_weight"; + + /* api callbacks */ + ot->poll= vertex_group_poll; + ot->exec= vertex_group_transfer_weight_all_exec; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) { Object *ob= ED_object_context(C); From fd9ea43c47cf11f05bdcb25053b4d3a5f0586dc0 Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Sun, 4 Mar 2012 15:03:59 +0000 Subject: [PATCH 004/347] Requested commit. two wight paint buttons added, code calling functions and empty functions in place. --- source/blender/editors/object/object_vgroup.c | 29 ++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index d8aead9fdc9..53b2bd96e87 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -1177,15 +1177,18 @@ static void vgroup_normalize_all(Object *ob, int lock_active) } } -static void vgroup_transfer_weight_all(Object *ob_act, Object *ob_other) +static void vgroup_transfer_weight_all(bContext *C) { /* for each vertex group {vgroup_transfer_weight()} */ printf("Not implemented yet!"); } -static void vgroup_transfer_weight(Object *ob_act, Object *ob_other) +static void vgroup_transfer_weight(bContext *C) { - printf("not implemented yet!"); + printf("Not implemented yet!"); + + + } static void vgroup_lock_all(Object *ob, int action) @@ -2378,11 +2381,10 @@ void OBJECT_OT_vertex_group_normalize_all(wmOperatorType *ot) "Keep the values of the active group while normalizing others"); } -static int vertex_group_transfer_weight_all_exec(bContext *C, wmOperator *op) +static int vertex_group_transfer_weight_all_exec(const bContext *C, wmOperator *op) { - Object *ob= ED_object_context(C); - - vgroup_transfer_weight_all(); + Object *ob= CTX_data_active_object(C); + vgroup_transfer_weight_all(C); DAG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); @@ -2391,11 +2393,12 @@ static int vertex_group_transfer_weight_all_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } +/* Transfers all vertex groups and weight from active object to targets*/ void OBJECT_OT_vertex_group_transfer_weight_all(wmOperatorType *ot) { /* identifiers */ - ot->name= "Transfer Weight"; - ot->idname= "OBJECT_OT_vertex_group_transfer_weight"; + ot->name= "Transfer Weight All"; + ot->idname= "OBJECT_OT_vertex_group_transfer_weight_all"; /* api callbacks */ ot->poll= vertex_group_poll; @@ -2405,11 +2408,10 @@ void OBJECT_OT_vertex_group_transfer_weight_all(wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } -static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) +static int vertex_group_transfer_weight_exec(const bContext *C, wmOperator *op) { - Object *ob= ED_object_context(C); - - vgroup_transfer_weight(); + Object *ob= CTX_data_active_object(C); + vgroup_transfer_weight(C); DAG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); @@ -2418,6 +2420,7 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } +/* Transfers one vertex group with weight from active object to target*/ void OBJECT_OT_vertex_group_transfer_weight(wmOperatorType *ot) { /* identifiers */ From 5087c5a6184522f6f25848a367b29374e471c7d9 Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Sat, 10 Mar 2012 00:09:57 +0000 Subject: [PATCH 005/347] Adjusted line number of funtions and implemented vertex group copy into them. --- source/blender/editors/object/object_vgroup.c | 137 +++++++++--------- 1 file changed, 68 insertions(+), 69 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 53b2bd96e87..8855b7c08c1 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -1177,20 +1177,6 @@ static void vgroup_normalize_all(Object *ob, int lock_active) } } -static void vgroup_transfer_weight_all(bContext *C) -{ - /* for each vertex group {vgroup_transfer_weight()} */ - printf("Not implemented yet!"); -} - -static void vgroup_transfer_weight(bContext *C) -{ - printf("Not implemented yet!"); - - - -} - static void vgroup_lock_all(Object *ob, int action) { bDeformGroup *dg; @@ -2264,6 +2250,7 @@ void OBJECT_OT_vertex_group_deselect(wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } +/*Adds a copy of selected vertex group on source object to source object*/ static int vertex_group_copy_exec(bContext *C, wmOperator *UNUSED(op)) { Object *ob= ED_object_context(C); @@ -2381,60 +2368,6 @@ void OBJECT_OT_vertex_group_normalize_all(wmOperatorType *ot) "Keep the values of the active group while normalizing others"); } -static int vertex_group_transfer_weight_all_exec(const bContext *C, wmOperator *op) -{ - Object *ob= CTX_data_active_object(C); - vgroup_transfer_weight_all(C); - - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); - WM_event_add_notifier(C, NC_GEOM|ND_DATA, ob->data); - - return OPERATOR_FINISHED; -} - -/* Transfers all vertex groups and weight from active object to targets*/ -void OBJECT_OT_vertex_group_transfer_weight_all(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Transfer Weight All"; - ot->idname= "OBJECT_OT_vertex_group_transfer_weight_all"; - - /* api callbacks */ - ot->poll= vertex_group_poll; - ot->exec= vertex_group_transfer_weight_all_exec; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; -} - -static int vertex_group_transfer_weight_exec(const bContext *C, wmOperator *op) -{ - Object *ob= CTX_data_active_object(C); - vgroup_transfer_weight(C); - - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); - WM_event_add_notifier(C, NC_GEOM|ND_DATA, ob->data); - - return OPERATOR_FINISHED; -} - -/* Transfers one vertex group with weight from active object to target*/ -void OBJECT_OT_vertex_group_transfer_weight(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Transfer Weight"; - ot->idname= "OBJECT_OT_vertex_group_transfer_weight"; - - /* api callbacks */ - ot->poll= vertex_group_poll; - ot->exec= vertex_group_transfer_weight_exec; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; -} - static int vertex_group_fix_exec(bContext *C, wmOperator *op) { Object *ob= CTX_data_active_object(C); @@ -2719,7 +2652,6 @@ static int vertex_group_copy_to_selected_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } - void OBJECT_OT_vertex_group_copy_to_selected(wmOperatorType *ot) { /* identifiers */ @@ -2735,6 +2667,73 @@ void OBJECT_OT_vertex_group_copy_to_selected(wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } +/* Transfers all vertex groups and weight from active object to targets*/ +static void vgroup_copy_weight_all(const bContext *C, wmOperator *op) +{ + /* for each vertex group {vgroup_copy_weight(sourceGroup, targetGroup)} */ + printf("Not implemented yet! \n"); +} + +static int vertex_group_transfer_weight_all_exec(const bContext *C, wmOperator *op) +{ + Object *ob= CTX_data_active_object(C); + vertex_group_copy_to_selected_exec(C, op); + vgroup_copy_weight_all(C, op); + + DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, ob->data); + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_vertex_group_transfer_weight_all(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Transfer Weight All"; + ot->idname= "OBJECT_OT_vertex_group_transfer_weight_all"; + + /* api callbacks */ + ot->poll= vertex_group_poll; + ot->exec= vertex_group_transfer_weight_all_exec; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +/* Transfers one vertex group with weight from active object to target*/ +static void vgroup_copy_weight(/*source vertex group*/ /*target vertex group*/) +{ + printf("Not implemented yet! \n"); +} + +static int vertex_group_transfer_weight_exec(const bContext *C, wmOperator *op) +{ + Object *ob= CTX_data_active_object(C); + /*vertex_group_copy_to_selected_exec(C,op); ----- must be implemented!*/ + vgroup_copy_weight(); + + DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, ob->data); + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_vertex_group_transfer_weight(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Transfer Weight"; + ot->idname= "OBJECT_OT_vertex_group_transfer_weight"; + + /* api callbacks */ + ot->poll= vertex_group_poll; + ot->exec= vertex_group_transfer_weight_exec; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + static EnumPropertyItem vgroup_items[]= { {0, NULL, 0, NULL, NULL}}; From 0b8ae86e591955214bb78b684be57430d119f9ab Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Thu, 15 Mar 2012 21:49:40 +0000 Subject: [PATCH 006/347] Added functionality: copy vertex group from source to targets. Changed some comments to represent the code more accuratly. --- source/blender/editors/object/object_intern.h | 1 + source/blender/editors/object/object_ops.c | 1 + source/blender/editors/object/object_vgroup.c | 77 +++++++++++++++---- 3 files changed, 66 insertions(+), 13 deletions(-) diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index bb87bd5de2e..8f24a9638ab 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -197,6 +197,7 @@ void OBJECT_OT_vertex_group_select(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_deselect(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_copy_to_linked(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_copy_to_selected(struct wmOperatorType *ot); +void OBJECT_OT_vertex_group_copy_to_selected_single(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_copy(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_normalize(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_normalize_all(struct wmOperatorType *ot); diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index 08df069fbf1..c704e165ca2 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -170,6 +170,7 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_vertex_group_deselect); WM_operatortype_append(OBJECT_OT_vertex_group_copy_to_linked); WM_operatortype_append(OBJECT_OT_vertex_group_copy_to_selected); + WM_operatortype_append(OBJECT_OT_vertex_group_copy_to_selected_single); WM_operatortype_append(OBJECT_OT_vertex_group_copy); WM_operatortype_append(OBJECT_OT_vertex_group_normalize); WM_operatortype_append(OBJECT_OT_vertex_group_normalize_all); diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 8855b7c08c1..2983ea6c65f 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -75,7 +75,7 @@ #include "UI_resources.h" #include "object_intern.h" -#include +#include /*only for development purposes, remove*/ /************************ Exported Functions **********************/ static void vgroup_remap_update_users(Object *ob, int *map); @@ -2250,7 +2250,7 @@ void OBJECT_OT_vertex_group_deselect(wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } -/*Adds a copy of selected vertex group on source object to source object*/ +/*Adds a copy of selected vertex group from source object to source object*/ static int vertex_group_copy_exec(bContext *C, wmOperator *UNUSED(op)) { Object *ob= ED_object_context(C); @@ -2628,6 +2628,7 @@ void OBJECT_OT_vertex_group_copy_to_linked(wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } +/*Copy vertex groups from source to target*/ /*warning! overwrites list*/ static int vertex_group_copy_to_selected_exec(bContext *C, wmOperator *op) { Object *obact= ED_object_context(C); @@ -2652,6 +2653,7 @@ static int vertex_group_copy_to_selected_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } +/*Copy vertex groups from source to target*/ /*warning! overwrites list*/ void OBJECT_OT_vertex_group_copy_to_selected(wmOperatorType *ot) { /* identifiers */ @@ -2667,31 +2669,77 @@ void OBJECT_OT_vertex_group_copy_to_selected(wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } -/* Transfers all vertex groups and weight from active object to targets*/ +static int vertex_group_copy_to_selected_single_exec(bContext *C, wmOperator *op) +{ + Object *obact= CTX_data_active_object(C); + int change= 0; + int fail= 0; + + bDeformGroup *dg; + dg = BLI_findlink(&obact->defbase, (obact->actdef-1)); + + CTX_DATA_BEGIN(C, Object*, obslc, selected_editable_objects) + { + if(obact != obslc) { + if(ED_vgroup_add_name(obslc, dg->name)) change++; + else fail++; + } + } + CTX_DATA_END; + + if((change == 0 && fail == 0) || fail) { + BKE_reportf(op->reports, RPT_ERROR, + "Copy to VGroups to Selected warning done %d, failed %d, object data must have matching indicies", + change, fail); + } + + return OPERATOR_FINISHED; +} + +/*Copy a vertex group from source to targets*/ +void OBJECT_OT_vertex_group_copy_to_selected_single(wmOperatorType *ot) /*Todo: add gui in python*/ +{ + /* identifiers */ + ot->name= "Copy a Vertex Group to Selected"; + ot->idname= "OBJECT_OT_vertex_group_copy_to_selected_single"; + ot->description= "Copy a vertex group to other selected objects with matching indices"; + + /* api callbacks */ + ot->poll= vertex_group_poll; + ot->exec= vertex_group_copy_to_selected_exec; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + static void vgroup_copy_weight_all(const bContext *C, wmOperator *op) { - /* for each vertex group {vgroup_copy_weight(sourceGroup, targetGroup)} */ + /* for each vertex group {defvert_copy(sourceGroup, targetGroup)} */ printf("Not implemented yet! \n"); } static int vertex_group_transfer_weight_all_exec(const bContext *C, wmOperator *op) { - Object *ob= CTX_data_active_object(C); - vertex_group_copy_to_selected_exec(C, op); + Object *ob = CTX_data_active_object(C); + + vertex_group_copy_to_selected_exec(C, op); /*!!!This causes all vertex groups to be copied, weight or not.*/ vgroup_copy_weight_all(C, op); + /*is the right stuff being updated?*/ DAG_id_tag_update(&ob->id, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); WM_event_add_notifier(C, NC_GEOM|ND_DATA, ob->data); + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); return OPERATOR_FINISHED; } +/* Transfers all vertex groups with weight from source to targets*/ void OBJECT_OT_vertex_group_transfer_weight_all(wmOperatorType *ot) { /* identifiers */ ot->name= "Transfer Weight All"; ot->idname= "OBJECT_OT_vertex_group_transfer_weight_all"; + ot->description= "Copy all vertex groups including weights to targets"; /* api callbacks */ ot->poll= vertex_group_poll; @@ -2701,30 +2749,33 @@ void OBJECT_OT_vertex_group_transfer_weight_all(wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } -/* Transfers one vertex group with weight from active object to target*/ -static void vgroup_copy_weight(/*source vertex group*/ /*target vertex group*/) +static void vgroup_copy_weight(const bContext *C, wmOperator *op) { printf("Not implemented yet! \n"); } static int vertex_group_transfer_weight_exec(const bContext *C, wmOperator *op) { - Object *ob= CTX_data_active_object(C); - /*vertex_group_copy_to_selected_exec(C,op); ----- must be implemented!*/ - vgroup_copy_weight(); + Object *ob = CTX_data_active_object(C); + vertex_group_copy_to_selected_single_exec(C,op); /*!!!This will copy vertex grop, weight or not.*/ + vgroup_copy_weight(C, op); + + /*is the right stuff being updated?*/ DAG_id_tag_update(&ob->id, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); WM_event_add_notifier(C, NC_GEOM|ND_DATA, ob->data); + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); return OPERATOR_FINISHED; } +/* Transfers one vertex group with weight from source to targets*/ void OBJECT_OT_vertex_group_transfer_weight(wmOperatorType *ot) { /* identifiers */ ot->name= "Transfer Weight"; ot->idname= "OBJECT_OT_vertex_group_transfer_weight"; + ot->description= "Copy a vertex group including weights to targets"; /* api callbacks */ ot->poll= vertex_group_poll; From 4fb535070ecaae57dc3f6521e447d42c6cc57193 Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Tue, 3 Apr 2012 08:23:00 +0000 Subject: [PATCH 007/347] Removed: The uneccecary previously added code and added functions for "copy_to_selected_single. Reason: less code and consistensy with existing code. Added fuction "ED_vgroup_copy_single" that forms the basis for the above. --- source/blender/editors/object/object_intern.h | 2 - source/blender/editors/object/object_ops.c | 2 - source/blender/editors/object/object_vgroup.c | 131 +++++++----------- 3 files changed, 48 insertions(+), 87 deletions(-) diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index 8f24a9638ab..651272323f3 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -201,8 +201,6 @@ void OBJECT_OT_vertex_group_copy_to_selected_single(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_copy(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_normalize(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_normalize_all(struct wmOperatorType *ot); -void OBJECT_OT_vertex_group_transfer_weight_all(struct wmOperatorType *ot); -void OBJECT_OT_vertex_group_transfer_weight(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_levels(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_lock(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_fix(struct wmOperatorType *ot); diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index c704e165ca2..4307bd71c1b 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -174,8 +174,6 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_vertex_group_copy); WM_operatortype_append(OBJECT_OT_vertex_group_normalize); WM_operatortype_append(OBJECT_OT_vertex_group_normalize_all); - WM_operatortype_append(OBJECT_OT_vertex_group_transfer_weight_all); - WM_operatortype_append(OBJECT_OT_vertex_group_transfer_weight); WM_operatortype_append(OBJECT_OT_vertex_group_lock); WM_operatortype_append(OBJECT_OT_vertex_group_fix); WM_operatortype_append(OBJECT_OT_vertex_group_invert); diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 2983ea6c65f..dcf3a400470 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -312,7 +312,7 @@ int ED_vgroup_give_array(ID *id, MDeformVert **dvert_arr, int *dvert_tot) return FALSE; } -/* matching index only */ +/*Copy all vertex groups to target, overwriting existing. matching index only*/ int ED_vgroup_copy_array(Object *ob, Object *ob_from) { MDeformVert **dvert_array_from, **dvf; @@ -377,6 +377,43 @@ int ED_vgroup_copy_array(Object *ob, Object *ob_from) return 1; } +/*Copy a single vertex group from source to destination with weights*/ +int ED_vgroup_copy_single(Object *ob_dst, const Object *ob_src) +{ + MDeformVert **dv_array_src; + MDeformVert **dv_array_dst; + MDeformWeight *dw_dst, *dw_src; + int dv_tot_src, dv_tot_dst; + int i, index_src, index_dst; + bDeformGroup *dg_src, *dg_dst; + + /*get source deform group*/ + dg_src = BLI_findlink(&ob_src->defbase, (ob_src->actdef-1)); + + /*Create new and overwrite vertex group on destination without data*/ + ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_src->name)); + ED_vgroup_add_name(ob_dst, dg_src->name); + + /*get destination deformgroup*/ + dg_dst= defgroup_find_name(ob_dst, dg_src->name); + + /*get vertex group arrays*/ + ED_vgroup_give_parray(ob_src->data, &dv_array_src, &dv_tot_src, FALSE); + ED_vgroup_give_parray(ob_dst->data, &dv_array_dst, &dv_tot_dst, FALSE); + + /*get indexes of vertex groups*/ + index_src= BLI_findindex(&ob_src->defbase, dg_src); + index_dst= BLI_findindex(&ob_dst->defbase, dg_dst); + + /* Loop through the vertices and copy weight*/ + for(i=0; iweight = dw_src->weight; + } + + return 1; +} /* for Mesh in Object mode */ /* allows editmode for Lattice */ @@ -2653,7 +2690,7 @@ static int vertex_group_copy_to_selected_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -/*Copy vertex groups from source to target*/ /*warning! overwrites list*/ +/* Transfer all vertex groups with weight to selected*/ void OBJECT_OT_vertex_group_copy_to_selected(wmOperatorType *ot) { /* identifiers */ @@ -2675,18 +2712,19 @@ static int vertex_group_copy_to_selected_single_exec(bContext *C, wmOperator *op int change= 0; int fail= 0; - bDeformGroup *dg; - dg = BLI_findlink(&obact->defbase, (obact->actdef-1)); - + /*Macro to loop through selected objects and perform operation*/ CTX_DATA_BEGIN(C, Object*, obslc, selected_editable_objects) { if(obact != obslc) { - if(ED_vgroup_add_name(obslc, dg->name)) change++; + if(ED_vgroup_copy_single(obslc, obact)) change++; else fail++; + /*event notifiers for correct display of data*/ + DAG_id_tag_update(&obslc->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, obslc); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obslc->data); } } CTX_DATA_END; - if((change == 0 && fail == 0) || fail) { BKE_reportf(op->reports, RPT_ERROR, "Copy to VGroups to Selected warning done %d, failed %d, object data must have matching indicies", @@ -2696,8 +2734,8 @@ static int vertex_group_copy_to_selected_single_exec(bContext *C, wmOperator *op return OPERATOR_FINISHED; } -/*Copy a vertex group from source to targets*/ -void OBJECT_OT_vertex_group_copy_to_selected_single(wmOperatorType *ot) /*Todo: add gui in python*/ +/*Transfer vertex group with weight to selected*/ +void OBJECT_OT_vertex_group_copy_to_selected_single(wmOperatorType *ot) { /* identifiers */ ot->name= "Copy a Vertex Group to Selected"; @@ -2706,80 +2744,7 @@ void OBJECT_OT_vertex_group_copy_to_selected_single(wmOperatorType *ot) /*Todo: /* api callbacks */ ot->poll= vertex_group_poll; - ot->exec= vertex_group_copy_to_selected_exec; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; -} - -static void vgroup_copy_weight_all(const bContext *C, wmOperator *op) -{ - /* for each vertex group {defvert_copy(sourceGroup, targetGroup)} */ - printf("Not implemented yet! \n"); -} - -static int vertex_group_transfer_weight_all_exec(const bContext *C, wmOperator *op) -{ - Object *ob = CTX_data_active_object(C); - - vertex_group_copy_to_selected_exec(C, op); /*!!!This causes all vertex groups to be copied, weight or not.*/ - vgroup_copy_weight_all(C, op); - - /*is the right stuff being updated?*/ - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_GEOM|ND_DATA, ob->data); - WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); - - return OPERATOR_FINISHED; -} - -/* Transfers all vertex groups with weight from source to targets*/ -void OBJECT_OT_vertex_group_transfer_weight_all(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Transfer Weight All"; - ot->idname= "OBJECT_OT_vertex_group_transfer_weight_all"; - ot->description= "Copy all vertex groups including weights to targets"; - - /* api callbacks */ - ot->poll= vertex_group_poll; - ot->exec= vertex_group_transfer_weight_all_exec; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; -} - -static void vgroup_copy_weight(const bContext *C, wmOperator *op) -{ - printf("Not implemented yet! \n"); -} - -static int vertex_group_transfer_weight_exec(const bContext *C, wmOperator *op) -{ - Object *ob = CTX_data_active_object(C); - - vertex_group_copy_to_selected_single_exec(C,op); /*!!!This will copy vertex grop, weight or not.*/ - vgroup_copy_weight(C, op); - - /*is the right stuff being updated?*/ - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_GEOM|ND_DATA, ob->data); - WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); - - return OPERATOR_FINISHED; -} - -/* Transfers one vertex group with weight from source to targets*/ -void OBJECT_OT_vertex_group_transfer_weight(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Transfer Weight"; - ot->idname= "OBJECT_OT_vertex_group_transfer_weight"; - ot->description= "Copy a vertex group including weights to targets"; - - /* api callbacks */ - ot->poll= vertex_group_poll; - ot->exec= vertex_group_transfer_weight_exec; + ot->exec= vertex_group_copy_to_selected_single_exec; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; From 0563ec03f53d81132359e3dd4da86c43d40320fa Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Tue, 17 Apr 2012 19:10:57 +0000 Subject: [PATCH 008/347] Added mechanics for detecting and reacting on uneven indices. --- source/blender/editors/object/object_vgroup.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index aab05e022c0..31b314b374b 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -405,6 +405,12 @@ int ED_vgroup_copy_single(Object *ob_dst, const Object *ob_src) index_src= BLI_findindex(&ob_src->defbase, dg_src); index_dst= BLI_findindex(&ob_dst->defbase, dg_dst); + /*Check if indices are matching, delete and return if not*/ + if (ob_dst==ob_src || dv_tot_dst==0 || (dv_tot_dst != dv_tot_src) || dv_array_src==NULL || dv_array_dst==NULL) { + ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_dst->name)); + return 0; + } + /* Loop through the vertices and copy weight*/ for(i=0; ireports, RPT_ERROR, + "Copy to VGroups to Selected warning done %d, failed %d, object data must have matching indices", + change, fail); + } + return OPERATOR_FINISHED; } From c88c6886aad117c62a7786f135cf0cb313605a5d Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Thu, 19 Apr 2012 00:09:20 +0000 Subject: [PATCH 009/347] added function for copying weight to target vertex from closest source vertex --- source/blender/editors/object/object_vgroup.c | 97 +++++++++++++++++-- 1 file changed, 89 insertions(+), 8 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 31b314b374b..edaa1158db0 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -421,6 +421,87 @@ int ED_vgroup_copy_single(Object *ob_dst, const Object *ob_src) return 1; } +/*return distance between coordinates that are comparable to other instances but not right*/ +float comparable_distance_between_coordinates(const float co_1[3], const float co_2[3]){ + float x_dist, y_dist, z_dist, dist_XY_square, distance; + x_dist= co_1[0] - co_2[0]; + y_dist= co_1[1] - co_2[1]; + z_dist= co_1[2] - co_2[2]; + dist_XY_square= x_dist * x_dist + y_dist * y_dist; + distance= dist_XY_square + z_dist * z_dist; + return distance; +} + +/*return the closest weight*/ +MDeformWeight *dweight_get_nearest(MVert *mv_dst, MDeformVert **dv_array_src, MVert *mv_src, int mv_tot_src, int index) +{ + MDeformWeight *dw; + float min_dist, dist; + int i; + /*initiate*/ + dw= (*dv_array_src)->dw; + min_dist= comparable_distance_between_coordinates(mv_dst->co, mv_src->co); + /*get closest*/ + for(i=0; ico, mv_src->co); + if(min_dist > dist){ + min_dist= dist; + dw= defvert_verify_index((*dv_array_src), index); + } + } + return dw; +} + +/*Copy a single vertex group from source to destination with weights, get the closest weight on source*/ +int ED_vgroup_copy_by_closest_single(Object *ob_dst, const Object *ob_src) +{ + MDeformVert **dv_array_src; + MDeformVert **dv_array_dst; + MDeformWeight *dw_dst, *dw_src; + int dv_tot_src, dv_tot_dst; + int i, index_dst, index_src; + bDeformGroup *dg_src, *dg_dst; + Mesh *me_src, *me_dst; + MVert *mv_src, *mv_dst; + + /*get source deform group*/ + dg_src = BLI_findlink(&ob_src->defbase, (ob_src->actdef-1)); + + /*Create new and overwrite vertex group on destination without data*/ + ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_src->name)); + ED_vgroup_add_name(ob_dst, dg_src->name); + + /*get destination deformgroup*/ + dg_dst= defgroup_find_name(ob_dst, dg_src->name); + + /*get meshes*/ + me_dst= ob_dst->data; + me_src= ob_src->data; + + /*get vertex group arrays*/ + ED_vgroup_give_parray(ob_src->data, &dv_array_src, &dv_tot_src, FALSE); + ED_vgroup_give_parray(ob_dst->data, &dv_array_dst, &dv_tot_dst, FALSE); + + /*get indexes of vertex groups*/ + index_src= BLI_findindex(&ob_src->defbase, dg_src); + index_dst= BLI_findindex(&ob_dst->defbase, dg_dst); + + /*get vertices*/ + mv_dst= me_dst->mvert; + mv_src= me_src->mvert; + + /*TODO: Check if it should be used and return 0 if not*/ + + /* Loop through the vertices and copy weight from closest to destination*/ + for(i=0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++) { + dw_dst= defvert_verify_index(*dv_array_dst, index_dst); + dw_src= dweight_get_nearest(mv_dst, dv_array_src, mv_src, me_src->totvert, index_src); + dw_dst->weight = dw_src->weight; + } + + return 1; +} + /* for Mesh in Object mode */ /* allows editmode for Lattice */ static void ED_vgroup_nr_vert_add(Object *ob, @@ -2800,8 +2881,12 @@ static int vertex_group_copy_to_selected_single_exec(bContext *C, wmOperator *op CTX_DATA_BEGIN(C, Object*, obslc, selected_editable_objects) { if(obact != obslc) { + /*Trying function for matching number of vertices*/ if(ED_vgroup_copy_single(obslc, obact)) change++; - else fail++; + /*Trying function for get weight from closest vertex*/ + else if(ED_vgroup_copy_by_closest_single(obslc, obact)) change++; + /*Triggers error message*/ + else fail++; /*event notifiers for correct display of data*/ DAG_id_tag_update(&obslc->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, obslc); @@ -2809,15 +2894,11 @@ static int vertex_group_copy_to_selected_single_exec(bContext *C, wmOperator *op } } CTX_DATA_END; + + /*reports error when: 1: indices are not matching. 2: smart functions fails.*/ if((change == 0 && fail == 0) || fail) { BKE_reportf(op->reports, RPT_ERROR, - "Copy to VGroups to Selected warning done %d, failed %d, object data must have matching indicies", - change, fail); - } - - if ((change == 0 && fail == 0) || fail) { - BKE_reportf(op->reports, RPT_ERROR, - "Copy to VGroups to Selected warning done %d, failed %d, object data must have matching indices", + "Copy to VGroups to Selected warning done %d, failed %d, Noob coder is noob!", change, fail); } From 12ce42e76f5e3a33b0bf148762513dc94d296616 Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Tue, 24 Apr 2012 15:00:38 +0000 Subject: [PATCH 010/347] BVHTree accellerated: ED_vgroup_copy_by_closest_single --- source/blender/editors/object/object_vgroup.c | 82 ++++++++++--------- 1 file changed, 44 insertions(+), 38 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index edaa1158db0..4ac948792a2 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -432,37 +432,31 @@ float comparable_distance_between_coordinates(const float co_1[3], const float c return distance; } -/*return the closest weight*/ -MDeformWeight *dweight_get_nearest(MVert *mv_dst, MDeformVert **dv_array_src, MVert *mv_src, int mv_tot_src, int index) -{ - MDeformWeight *dw; - float min_dist, dist; - int i; - /*initiate*/ - dw= (*dv_array_src)->dw; - min_dist= comparable_distance_between_coordinates(mv_dst->co, mv_src->co); - /*get closest*/ - for(i=0; ico, mv_src->co); - if(min_dist > dist){ - min_dist= dist; - dw= defvert_verify_index((*dv_array_src), index); - } - } - return dw; -} - /*Copy a single vertex group from source to destination with weights, get the closest weight on source*/ int ED_vgroup_copy_by_closest_single(Object *ob_dst, const Object *ob_src) { - MDeformVert **dv_array_src; - MDeformVert **dv_array_dst; - MDeformWeight *dw_dst, *dw_src; - int dv_tot_src, dv_tot_dst; - int i, index_dst, index_src; bDeformGroup *dg_src, *dg_dst; - Mesh *me_src, *me_dst; - MVert *mv_src, *mv_dst; + MDeformVert **dv_array_src, **dv_array_dst; + MDeformWeight *dw_dst, *dw_src; + MVert *mv_dst; + Mesh *me_dst; + BVHTreeFromMesh tree_mesh_src; + BVHTreeNearest nearest; + DerivedMesh *dmesh_src; + int dv_tot_src, dv_tot_dst, i, index_dst, index_src; + + /*TODO: Check if it should be used and return 0 if not*/ + /*TODO: Bugfix, if position of object center is not similar, the copy will fail*/ + /*suggested sollution: temporarily set object center to geometry center on both source and target*/ + /*suggested sollution: temporarily manipulate destination object center to align with source*/ + /*suggested solution: user choise*/ + /*TODO: take scale into account*/ + /*memory safety TODO make this work. + if (tree_mesh_src.tree == NULL) + { + OUT_OF_MEMORY(); + return; + }*/ /*get source deform group*/ dg_src = BLI_findlink(&ob_src->defbase, (ob_src->actdef-1)); @@ -476,7 +470,12 @@ int ED_vgroup_copy_by_closest_single(Object *ob_dst, const Object *ob_src) /*get meshes*/ me_dst= ob_dst->data; - me_src= ob_src->data; + + /*get derived mesh*/ + dmesh_src= ob_src->derivedDeform; + + /*make node tree*/ + bvhtree_from_mesh_verts(&tree_mesh_src, dmesh_src, 0.0, 2, 6); /*get vertex group arrays*/ ED_vgroup_give_parray(ob_src->data, &dv_array_src, &dv_tot_src, FALSE); @@ -488,17 +487,24 @@ int ED_vgroup_copy_by_closest_single(Object *ob_dst, const Object *ob_src) /*get vertices*/ mv_dst= me_dst->mvert; - mv_src= me_src->mvert; - - /*TODO: Check if it should be used and return 0 if not*/ /* Loop through the vertices and copy weight from closest to destination*/ for(i=0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++) { + /*Reset nearest*/ + nearest.index= -1; + nearest.dist= FLT_MAX; + + /*Node tree accelerated search for closest vetex*/ + BLI_bvhtree_find_nearest(tree_mesh_src.tree, mv_dst->co, &nearest, tree_mesh_src.nearest_callback, &tree_mesh_src); + + /*copy weight*/ + dw_src= defvert_verify_index(dv_array_src[nearest.index], index_src); dw_dst= defvert_verify_index(*dv_array_dst, index_dst); - dw_src= dweight_get_nearest(mv_dst, dv_array_src, mv_src, me_src->totvert, index_src); dw_dst->weight = dw_src->weight; } + free_bvhtree_from_mesh(&tree_mesh_src); + return 1; } @@ -2881,13 +2887,13 @@ static int vertex_group_copy_to_selected_single_exec(bContext *C, wmOperator *op CTX_DATA_BEGIN(C, Object*, obslc, selected_editable_objects) { if(obact != obslc) { - /*Trying function for matching number of vertices*/ + /*Try function for matching number of vertices*/ if(ED_vgroup_copy_single(obslc, obact)) change++; - /*Trying function for get weight from closest vertex*/ + /*Try function for get weight from closest vertex*/ else if(ED_vgroup_copy_by_closest_single(obslc, obact)) change++; - /*Triggers error message*/ + /*Trigger error message*/ else fail++; - /*event notifiers for correct display of data*/ + /*Event notifiers for correct display of data*/ DAG_id_tag_update(&obslc->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, obslc); WM_event_add_notifier(C, NC_GEOM|ND_DATA, obslc->data); @@ -2895,10 +2901,10 @@ static int vertex_group_copy_to_selected_single_exec(bContext *C, wmOperator *op } CTX_DATA_END; - /*reports error when: 1: indices are not matching. 2: smart functions fails.*/ + /*Report error when task could not be completed.*/ if((change == 0 && fail == 0) || fail) { BKE_reportf(op->reports, RPT_ERROR, - "Copy to VGroups to Selected warning done %d, failed %d, Noob coder is noob!", + "Copy to VGroups to Selected warning done %d, failed %d, All functions failed!", change, fail); } From 01a62964d9a95af2067b2c9ed9c645f104b5de21 Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Tue, 24 Apr 2012 16:31:40 +0000 Subject: [PATCH 011/347] Cleanup only: Comments clarified, whitespaces adjusted for consistency, unneccesary code removed. --- source/blender/editors/object/object_vgroup.c | 61 ++++++++----------- 1 file changed, 24 insertions(+), 37 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index cdec2e96b82..673345961e9 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -317,13 +317,12 @@ int ED_vgroup_copy_array(Object *ob, Object *ob_from) { MDeformVert **dvert_array_from, **dvf; MDeformVert **dvert_array, **dv; - int dvert_tot_from; - int dvert_tot; - int i; + int dvert_tot_from, dvert_tot, i; int defbase_tot_from= BLI_countlist(&ob_from->defbase); int defbase_tot= BLI_countlist(&ob->defbase); short new_vgroup= FALSE; + /*get vertex groups arrays*/ ED_vgroup_give_parray(ob_from->data, &dvert_array_from, &dvert_tot_from, FALSE); ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot, FALSE); @@ -351,8 +350,8 @@ int ED_vgroup_copy_array(Object *ob, Object *ob_from) if (defbase_tot_from < defbase_tot) { /* correct vgroup indices because the number of vgroups is being reduced. */ int *remap= MEM_mallocN(sizeof(int) * (defbase_tot + 1), __func__); - for (i=0; i<=defbase_tot_from; i++) remap[i]= i; - for (; i<=defbase_tot; i++) remap[i]= 0; /* can't use these, so disable */ + for (i=0; i <= defbase_tot_from; i++) remap[i]= i; + for (; i <= defbase_tot; i++) remap[i]= 0; /* can't use these, so disable */ vgroup_remap_update_users(ob, remap); MEM_freeN(remap); @@ -388,7 +387,7 @@ int ED_vgroup_copy_single(Object *ob_dst, const Object *ob_src) bDeformGroup *dg_src, *dg_dst; /*get source deform group*/ - dg_src = BLI_findlink(&ob_src->defbase, (ob_src->actdef-1)); + dg_src= BLI_findlink(&ob_src->defbase, (ob_src->actdef-1)); /*Create new and overwrite vertex group on destination without data*/ ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_src->name)); @@ -406,34 +405,23 @@ int ED_vgroup_copy_single(Object *ob_dst, const Object *ob_src) index_dst= BLI_findindex(&ob_dst->defbase, dg_dst); /*Check if indices are matching, delete and return if not*/ - if (ob_dst==ob_src || dv_tot_dst==0 || (dv_tot_dst != dv_tot_src) || dv_array_src==NULL || dv_array_dst==NULL) { + if (ob_dst == ob_src || dv_tot_dst == 0 || (dv_tot_dst != dv_tot_src) || dv_array_src == NULL || dv_array_dst == NULL) { ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_dst->name)); return 0; } /* Loop through the vertices and copy weight*/ for(i=0; iweight = dw_src->weight; + dw_src= defvert_verify_index(*dv_array_src, index_src); + dw_dst= defvert_verify_index(*dv_array_dst, index_dst); + dw_dst->weight= dw_src->weight; } return 1; } -/*return distance between coordinates that are comparable to other instances but not right*/ -float comparable_distance_between_coordinates(const float co_1[3], const float co_2[3]){ - float x_dist, y_dist, z_dist, dist_XY_square, distance; - x_dist= co_1[0] - co_2[0]; - y_dist= co_1[1] - co_2[1]; - z_dist= co_1[2] - co_2[2]; - dist_XY_square= x_dist * x_dist + y_dist * y_dist; - distance= dist_XY_square + z_dist * z_dist; - return distance; -} - -/*Copy a single vertex group from source to destination with weights, get the closest weight on source*/ -int ED_vgroup_copy_by_closest_single(Object *ob_dst, const Object *ob_src) +/*Copy a single vertex group from source to destination with weights by nearest weight*/ +int ED_vgroup_copy_by_nearest_single(Object *ob_dst, const Object *ob_src) { bDeformGroup *dg_src, *dg_dst; MDeformVert **dv_array_src, **dv_array_dst; @@ -459,7 +447,7 @@ int ED_vgroup_copy_by_closest_single(Object *ob_dst, const Object *ob_src) }*/ /*get source deform group*/ - dg_src = BLI_findlink(&ob_src->defbase, (ob_src->actdef-1)); + dg_src= BLI_findlink(&ob_src->defbase, (ob_src->actdef-1)); /*Create new and overwrite vertex group on destination without data*/ ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_src->name)); @@ -470,8 +458,6 @@ int ED_vgroup_copy_by_closest_single(Object *ob_dst, const Object *ob_src) /*get meshes*/ me_dst= ob_dst->data; - - /*get derived mesh*/ dmesh_src= ob_src->derivedDeform; /*make node tree*/ @@ -488,8 +474,9 @@ int ED_vgroup_copy_by_closest_single(Object *ob_dst, const Object *ob_src) /*get vertices*/ mv_dst= me_dst->mvert; - /* Loop through the vertices and copy weight from closest to destination*/ + /* Loop through the vertices and copy weight from nearest weight*/ for(i=0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++) { + /*Reset nearest*/ nearest.index= -1; nearest.dist= FLT_MAX; @@ -500,11 +487,11 @@ int ED_vgroup_copy_by_closest_single(Object *ob_dst, const Object *ob_src) /*copy weight*/ dw_src= defvert_verify_index(dv_array_src[nearest.index], index_src); dw_dst= defvert_verify_index(*dv_array_dst, index_dst); - dw_dst->weight = dw_src->weight; + dw_dst->weight= dw_src->weight; } + /*free memory and return*/ free_bvhtree_from_mesh(&tree_mesh_src); - return 1; } @@ -2866,16 +2853,16 @@ static int vertex_group_copy_to_selected_exec(bContext *C, wmOperator *op) void OBJECT_OT_vertex_group_copy_to_selected(wmOperatorType *ot) { /* identifiers */ - ot->name = "Copy Vertex Group to Selected"; - ot->idname = "OBJECT_OT_vertex_group_copy_to_selected"; - ot->description = "Copy Vertex Groups to other selected objects with matching indices"; + ot->name= "Copy Vertex Group to Selected"; + ot->idname= "OBJECT_OT_vertex_group_copy_to_selected"; + ot->description= "Copy Vertex Groups to other selected objects with matching indices"; /* api callbacks */ - ot->poll = vertex_group_poll; - ot->exec = vertex_group_copy_to_selected_exec; + ot->poll= vertex_group_poll; + ot->exec= vertex_group_copy_to_selected_exec; /* flags */ - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } static int vertex_group_copy_to_selected_single_exec(bContext *C, wmOperator *op) @@ -2891,7 +2878,7 @@ static int vertex_group_copy_to_selected_single_exec(bContext *C, wmOperator *op /*Try function for matching number of vertices*/ if(ED_vgroup_copy_single(obslc, obact)) change++; /*Try function for get weight from closest vertex*/ - else if(ED_vgroup_copy_by_closest_single(obslc, obact)) change++; + else if(ED_vgroup_copy_by_nearest_single(obslc, obact)) change++; /*Trigger error message*/ else fail++; /*Event notifiers for correct display of data*/ @@ -2902,7 +2889,7 @@ static int vertex_group_copy_to_selected_single_exec(bContext *C, wmOperator *op } CTX_DATA_END; - /*Report error when task could not be completed.*/ + /*Report error when task can not be completed with available functions.*/ if((change == 0 && fail == 0) || fail) { BKE_reportf(op->reports, RPT_ERROR, "Copy to VGroups to Selected warning done %d, failed %d, All functions failed!", From 0e9c52047be538fbf95759fa8b73bf0536d73de7 Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Fri, 4 May 2012 21:28:21 +0000 Subject: [PATCH 012/347] Added incomplete function ED_vgroup_copy_by_nearest_face_single It does not work but is a starting point. --- source/blender/editors/object/object_vgroup.c | 91 +++++++++++++++---- 1 file changed, 75 insertions(+), 16 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 673345961e9..93eef06f402 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -421,7 +421,7 @@ int ED_vgroup_copy_single(Object *ob_dst, const Object *ob_src) } /*Copy a single vertex group from source to destination with weights by nearest weight*/ -int ED_vgroup_copy_by_nearest_single(Object *ob_dst, const Object *ob_src) +int ED_vgroup_copy_by_nearest_vertex_single(Object *ob_dst, const Object *ob_src) { bDeformGroup *dg_src, *dg_dst; MDeformVert **dv_array_src, **dv_array_dst; @@ -433,19 +433,6 @@ int ED_vgroup_copy_by_nearest_single(Object *ob_dst, const Object *ob_src) DerivedMesh *dmesh_src; int dv_tot_src, dv_tot_dst, i, index_dst, index_src; - /*TODO: Check if it should be used and return 0 if not*/ - /*TODO: Bugfix, if position of object center is not similar, the copy will fail*/ - /*suggested sollution: temporarily set object center to geometry center on both source and target*/ - /*suggested sollution: temporarily manipulate destination object center to align with source*/ - /*suggested solution: user choise*/ - /*TODO: take scale into account*/ - /*memory safety TODO make this work. - if (tree_mesh_src.tree == NULL) - { - OUT_OF_MEMORY(); - return; - }*/ - /*get source deform group*/ dg_src= BLI_findlink(&ob_src->defbase, (ob_src->actdef-1)); @@ -475,7 +462,7 @@ int ED_vgroup_copy_by_nearest_single(Object *ob_dst, const Object *ob_src) mv_dst= me_dst->mvert; /* Loop through the vertices and copy weight from nearest weight*/ - for(i=0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++) { + for(i=0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ /*Reset nearest*/ nearest.index= -1; @@ -495,6 +482,76 @@ int ED_vgroup_copy_by_nearest_single(Object *ob_dst, const Object *ob_src) return 1; } +/*Copy a single vertex group from source to destination with weights by nearest weight*/ +int ED_vgroup_copy_by_nearest_face_single(Object *ob_dst, Object *ob_src) +{ + bDeformGroup *dg_src, *dg_dst; + MDeformVert **dv_array_src, **dv_array_dst; + MDeformWeight *dw_dst, *dw_src; + MVert *mv_dst; + MFace *mface_src; + Mesh *me_dst, *me_src; + BVHTreeFromMesh tree_mesh_faces_src; + BVHTreeNearest nearest; + DerivedMesh *dmesh_src; + int dv_tot_src, dv_tot_dst, i, index_dst, index_src; + float weight; + + /*get source deform group*/ + dg_src= BLI_findlink(&ob_src->defbase, (ob_src->actdef-1)); + + /*Create new and overwrite vertex group on destination without data*/ + ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_src->name)); + ED_vgroup_add_name(ob_dst, dg_src->name); + + /*get destination deformgroup*/ + dg_dst= defgroup_find_name(ob_dst, dg_src->name); + + /*get meshes*/ + me_dst= ob_dst->data; + me_src= ob_src->data; + dmesh_src= ob_src->derivedDeform; + + /*make node tree*/ + DM_ensure_tessface(dmesh_src); + bvhtree_from_mesh_faces(&tree_mesh_faces_src, dmesh_src, 0.0, 2, 6); + + /*get vertex group arrays*/ + ED_vgroup_give_parray(ob_src->data, &dv_array_src, &dv_tot_src, FALSE); + ED_vgroup_give_parray(ob_dst->data, &dv_array_dst, &dv_tot_dst, FALSE); + + /*get indexes of vertex groups*/ + index_src= BLI_findindex(&ob_src->defbase, dg_src); + index_dst= BLI_findindex(&ob_dst->defbase, dg_dst); + + /*get vertices*/ + mv_dst= me_dst->mvert; + + /* Loop through the vertices and copy weight from nearest weight*/ + for(i=0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ + /*Reset nearest*/ + nearest.index= -1; + nearest.dist= FLT_MAX; + + /*Node tree accelerated search for closest face*/ + BLI_bvhtree_find_nearest(tree_mesh_faces_src.tree, mv_dst->co, &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src); + + /*get*/ + mface_src= me_src->mface + nearest.index; + dw_src= defvert_verify_index(dv_array_src[mface_src->v1], index_src); + weight= dw_src->weight; + weight= 0; + + /*copy weight*/ + dw_dst= defvert_verify_index(*dv_array_dst, index_dst); + dw_dst->weight= weight; + } + + /*free memory and return*/ + free_bvhtree_from_mesh(&tree_mesh_faces_src); + return 1; +} + /* for Mesh in Object mode */ /* allows editmode for Lattice */ static void ED_vgroup_nr_vert_add(Object *ob, @@ -2878,7 +2935,9 @@ static int vertex_group_copy_to_selected_single_exec(bContext *C, wmOperator *op /*Try function for matching number of vertices*/ if(ED_vgroup_copy_single(obslc, obact)) change++; /*Try function for get weight from closest vertex*/ - else if(ED_vgroup_copy_by_nearest_single(obslc, obact)) change++; + /*TODO: try this function*/ + /*Try function for get weight from closest face*/ + else if(ED_vgroup_copy_by_nearest_face_single(obslc, obact)) change++; /*Trigger error message*/ else fail++; /*Event notifiers for correct display of data*/ From 2624c871bdb12ea08891d20b64b10524f66c0382 Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Sun, 6 May 2012 17:19:16 +0000 Subject: [PATCH 013/347] ED_vgroup_copy_by_nearest_vertex_single: Added transformation into target space ED_vgroup_copy_by_nearest_face_single: Is incomplete. BVHTree fails. --- source/blender/editors/object/object_vgroup.c | 40 ++++++++++++++++--- 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 93eef06f402..ea0b7542886 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -421,7 +421,7 @@ int ED_vgroup_copy_single(Object *ob_dst, const Object *ob_src) } /*Copy a single vertex group from source to destination with weights by nearest weight*/ -int ED_vgroup_copy_by_nearest_vertex_single(Object *ob_dst, const Object *ob_src) +int ED_vgroup_copy_by_nearest_vertex_single(Object *ob_dst, Object *ob_src) { bDeformGroup *dg_src, *dg_dst; MDeformVert **dv_array_src, **dv_array_dst; @@ -432,6 +432,7 @@ int ED_vgroup_copy_by_nearest_vertex_single(Object *ob_dst, const Object *ob_src BVHTreeNearest nearest; DerivedMesh *dmesh_src; int dv_tot_src, dv_tot_dst, i, index_dst, index_src; + float tmp_co[3], tmp_mat[4][4]; /*get source deform group*/ dg_src= BLI_findlink(&ob_src->defbase, (ob_src->actdef-1)); @@ -461,6 +462,11 @@ int ED_vgroup_copy_by_nearest_vertex_single(Object *ob_dst, const Object *ob_src /*get vertices*/ mv_dst= me_dst->mvert; + /*Prepearing transformation matrix*/ + /*This can be excluded to make a lazy feature that works better when object centers relative to mesh is the same*/ + invert_m4_m4(ob_src->imat, ob_src->obmat); + mult_m4_m4m4(tmp_mat, ob_src->imat, ob_dst->obmat); + /* Loop through the vertices and copy weight from nearest weight*/ for(i=0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ @@ -468,8 +474,11 @@ int ED_vgroup_copy_by_nearest_vertex_single(Object *ob_dst, const Object *ob_src nearest.index= -1; nearest.dist= FLT_MAX; + /*Transforming into target space*/ + mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); + /*Node tree accelerated search for closest vetex*/ - BLI_bvhtree_find_nearest(tree_mesh_src.tree, mv_dst->co, &nearest, tree_mesh_src.nearest_callback, &tree_mesh_src); + BLI_bvhtree_find_nearest(tree_mesh_src.tree, tmp_co, &nearest, tree_mesh_src.nearest_callback, &tree_mesh_src); /*copy weight*/ dw_src= defvert_verify_index(dv_array_src[nearest.index], index_src); @@ -483,6 +492,7 @@ int ED_vgroup_copy_by_nearest_vertex_single(Object *ob_dst, const Object *ob_src } /*Copy a single vertex group from source to destination with weights by nearest weight*/ +/*TODO: transform into target space as in by_vertex function. postphoned due to easier testing during development*/ int ED_vgroup_copy_by_nearest_face_single(Object *ob_dst, Object *ob_src) { bDeformGroup *dg_src, *dg_dst; @@ -495,7 +505,7 @@ int ED_vgroup_copy_by_nearest_face_single(Object *ob_dst, Object *ob_src) BVHTreeNearest nearest; DerivedMesh *dmesh_src; int dv_tot_src, dv_tot_dst, i, index_dst, index_src; - float weight; + float weight/*, tot_dist*/; /*get source deform group*/ dg_src= BLI_findlink(&ob_src->defbase, (ob_src->actdef-1)); @@ -510,12 +520,13 @@ int ED_vgroup_copy_by_nearest_face_single(Object *ob_dst, Object *ob_src) /*get meshes*/ me_dst= ob_dst->data; me_src= ob_src->data; - dmesh_src= ob_src->derivedDeform; + dmesh_src= ob_src->derivedDeform; /*sergey- : this might easily be null?? (using ob_src.deriveddeform*/ /*make node tree*/ DM_ensure_tessface(dmesh_src); bvhtree_from_mesh_faces(&tree_mesh_faces_src, dmesh_src, 0.0, 2, 6); + /*get vertex group arrays*/ ED_vgroup_give_parray(ob_src->data, &dv_array_src, &dv_tot_src, FALSE); ED_vgroup_give_parray(ob_dst->data, &dv_array_dst, &dv_tot_dst, FALSE); @@ -529,6 +540,7 @@ int ED_vgroup_copy_by_nearest_face_single(Object *ob_dst, Object *ob_src) /* Loop through the vertices and copy weight from nearest weight*/ for(i=0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ + /*Reset nearest*/ nearest.index= -1; nearest.dist= FLT_MAX; @@ -536,11 +548,27 @@ int ED_vgroup_copy_by_nearest_face_single(Object *ob_dst, Object *ob_src) /*Node tree accelerated search for closest face*/ BLI_bvhtree_find_nearest(tree_mesh_faces_src.tree, mv_dst->co, &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src); - /*get*/ + /*get weight*/ mface_src= me_src->mface + nearest.index; + /*tot_dist= ()+()+(); use a comparable distance + if(mface_src->v4){ + tot_dist+= (); + }*/ dw_src= defvert_verify_index(dv_array_src[mface_src->v1], index_src); weight= dw_src->weight; - weight= 0; + dw_src= defvert_verify_index(dv_array_src[mface_src->v2], index_src); + weight+= dw_src->weight; + dw_src= defvert_verify_index(dv_array_src[mface_src->v3], index_src); + weight+= dw_src->weight; + if(mface_src->v4){ + dw_src= defvert_verify_index(dv_array_src[mface_src->v4], index_src); + weight+= dw_src->weight; + weight/=4; + } + else{ + weight/=3; + } + /*copy weight*/ dw_dst= defvert_verify_index(*dv_array_dst, index_dst); From f61e50aa4ea462b3e369764843e868c4692143bd Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Wed, 9 May 2012 16:24:46 +0000 Subject: [PATCH 014/347] it works! Even it compiles some code might still not be implemented. (I know the gui lacks). --- source/blender/editors/object/object_vgroup.c | 256 ++++++++++++++++++ 1 file changed, 256 insertions(+) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 0c0611d3d33..5e575c890b4 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -376,6 +376,210 @@ int ED_vgroup_copy_array(Object *ob, Object *ob_from) return 1; } +/*Copy a single vertex group from source to destination with weights*/ +int ED_vgroup_copy_single(Object *ob_dst, const Object *ob_src) +{ + MDeformVert **dv_array_src; + MDeformVert **dv_array_dst; + MDeformWeight *dw_dst, *dw_src; + int dv_tot_src, dv_tot_dst; + int i, index_src, index_dst; + bDeformGroup *dg_src, *dg_dst; + + /*get source deform group*/ + dg_src= BLI_findlink(&ob_src->defbase, (ob_src->actdef-1)); + + /*Create new and overwrite vertex group on destination without data*/ + ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_src->name)); + ED_vgroup_add_name(ob_dst, dg_src->name); + + /*get destination deformgroup*/ + dg_dst= defgroup_find_name(ob_dst, dg_src->name); + + /*get vertex group arrays*/ + ED_vgroup_give_parray(ob_src->data, &dv_array_src, &dv_tot_src, FALSE); + ED_vgroup_give_parray(ob_dst->data, &dv_array_dst, &dv_tot_dst, FALSE); + + /*get indexes of vertex groups*/ + index_src= BLI_findindex(&ob_src->defbase, dg_src); + index_dst= BLI_findindex(&ob_dst->defbase, dg_dst); + + /*Check if indices are matching, delete and return if not*/ + if (ob_dst == ob_src || dv_tot_dst == 0 || (dv_tot_dst != dv_tot_src) || dv_array_src == NULL || dv_array_dst == NULL) { + ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_dst->name)); + return 0; + } + + /* Loop through the vertices and copy weight*/ + for(i=0; iweight= dw_src->weight; + } + + return 1; +} + +/*Copy a single vertex group from source to destination with weights by nearest weight*/ +int ED_vgroup_copy_by_nearest_vertex_single(Object *ob_dst, Object *ob_src) +{ + bDeformGroup *dg_src, *dg_dst; + MDeformVert **dv_array_src, **dv_array_dst; + MDeformWeight *dw_dst, *dw_src; + MVert *mv_dst; + Mesh *me_dst; + BVHTreeFromMesh tree_mesh_src; + BVHTreeNearest nearest; + DerivedMesh *dmesh_src; + int dv_tot_src, dv_tot_dst, i, index_dst, index_src; + float tmp_co[3], tmp_mat[4][4]; + + /*get source deform group*/ + dg_src= BLI_findlink(&ob_src->defbase, (ob_src->actdef-1)); + + /*Create new and overwrite vertex group on destination without data*/ + ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_src->name)); + ED_vgroup_add_name(ob_dst, dg_src->name); + + /*get destination deformgroup*/ + dg_dst= defgroup_find_name(ob_dst, dg_src->name); + + /*get meshes*/ + me_dst= ob_dst->data; + dmesh_src= ob_src->derivedDeform; + + /*make node tree*/ + bvhtree_from_mesh_verts(&tree_mesh_src, dmesh_src, 0.0, 2, 6); + + /*get vertex group arrays*/ + ED_vgroup_give_parray(ob_src->data, &dv_array_src, &dv_tot_src, FALSE); + ED_vgroup_give_parray(ob_dst->data, &dv_array_dst, &dv_tot_dst, FALSE); + + /*get indexes of vertex groups*/ + index_src= BLI_findindex(&ob_src->defbase, dg_src); + index_dst= BLI_findindex(&ob_dst->defbase, dg_dst); + + /*get vertices*/ + mv_dst= me_dst->mvert; + + /*Prepearing transformation matrix*/ + /*This can be excluded to make a lazy feature that works better when object centers relative to mesh is the same*/ + invert_m4_m4(ob_src->imat, ob_src->obmat); + mult_m4_m4m4(tmp_mat, ob_src->imat, ob_dst->obmat); + + /* Loop through the vertices and copy weight from nearest weight*/ + for(i=0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ + + /*Reset nearest*/ + nearest.index= -1; + nearest.dist= FLT_MAX; + + /*Transforming into target space*/ + mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); + + /*Node tree accelerated search for closest vetex*/ + BLI_bvhtree_find_nearest(tree_mesh_src.tree, tmp_co, &nearest, tree_mesh_src.nearest_callback, &tree_mesh_src); + + /*copy weight*/ + dw_src= defvert_verify_index(dv_array_src[nearest.index], index_src); + dw_dst= defvert_verify_index(*dv_array_dst, index_dst); + dw_dst->weight= dw_src->weight; + } + + /*free memory and return*/ + free_bvhtree_from_mesh(&tree_mesh_src); + return 1; +} + +/*Copy a single vertex group from source to destination with weights by nearest weight*/ +/*TODO: transform into target space as in by_vertex function. postphoned due to easier testing during development*/ +int ED_vgroup_copy_by_nearest_face_single(Object *ob_dst, Object *ob_src) +{ + bDeformGroup *dg_src, *dg_dst; + MDeformVert **dv_array_src, **dv_array_dst; + MDeformWeight *dw_dst, *dw_src; + MVert *mv_dst; + MFace *mface_src; + Mesh *me_dst, *me_src; + BVHTreeFromMesh tree_mesh_faces_src; + BVHTreeNearest nearest; + DerivedMesh *dmesh_src; + int dv_tot_src, dv_tot_dst, i, index_dst, index_src; + float weight/*, tot_dist*/; + + /*get source deform group*/ + dg_src= BLI_findlink(&ob_src->defbase, (ob_src->actdef-1)); + + /*Create new and overwrite vertex group on destination without data*/ + ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_src->name)); + ED_vgroup_add_name(ob_dst, dg_src->name); + + /*get destination deformgroup*/ + dg_dst= defgroup_find_name(ob_dst, dg_src->name); + + /*get meshes*/ + me_dst= ob_dst->data; + me_src= ob_src->data; + dmesh_src= ob_src->derivedDeform; /*sergey- : this might easily be null?? (using ob_src.deriveddeform*/ + + /*make node tree*/ + DM_ensure_tessface(dmesh_src); + bvhtree_from_mesh_faces(&tree_mesh_faces_src, dmesh_src, 0.0, 2, 6); + + + /*get vertex group arrays*/ + ED_vgroup_give_parray(ob_src->data, &dv_array_src, &dv_tot_src, FALSE); + ED_vgroup_give_parray(ob_dst->data, &dv_array_dst, &dv_tot_dst, FALSE); + + /*get indexes of vertex groups*/ + index_src= BLI_findindex(&ob_src->defbase, dg_src); + index_dst= BLI_findindex(&ob_dst->defbase, dg_dst); + + /*get vertices*/ + mv_dst= me_dst->mvert; + + /* Loop through the vertices and copy weight from nearest weight*/ + for(i=0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ + + /*Reset nearest*/ + nearest.index= -1; + nearest.dist= FLT_MAX; + + /*Node tree accelerated search for closest face*/ + BLI_bvhtree_find_nearest(tree_mesh_faces_src.tree, mv_dst->co, &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src); + + /*get weight*/ + mface_src= me_src->mface + nearest.index; + /*tot_dist= ()+()+(); use a comparable distance + if(mface_src->v4){ + tot_dist+= (); + }*/ + dw_src= defvert_verify_index(dv_array_src[mface_src->v1], index_src); + weight= dw_src->weight; + dw_src= defvert_verify_index(dv_array_src[mface_src->v2], index_src); + weight+= dw_src->weight; + dw_src= defvert_verify_index(dv_array_src[mface_src->v3], index_src); + weight+= dw_src->weight; + if(mface_src->v4){ + dw_src= defvert_verify_index(dv_array_src[mface_src->v4], index_src); + weight+= dw_src->weight; + weight/=4; + } + else{ + weight/=3; + } + + + /*copy weight*/ + dw_dst= defvert_verify_index(*dv_array_dst, index_dst); + dw_dst->weight= weight; + } + + /*free memory and return*/ + free_bvhtree_from_mesh(&tree_mesh_faces_src); + return 1; +} + /* for Mesh in Object mode */ /* allows editmode for Lattice */ @@ -2760,6 +2964,58 @@ void OBJECT_OT_vertex_group_copy_to_selected(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } +static int vertex_group_copy_to_selected_single_exec(bContext *C, wmOperator *op) +{ + Object *obact= CTX_data_active_object(C); + int change= 0; + int fail= 0; + + /*Macro to loop through selected objects and perform operation*/ + CTX_DATA_BEGIN(C, Object*, obslc, selected_editable_objects) + { + if(obact != obslc) { + /*Try function for matching number of vertices*/ + if(ED_vgroup_copy_single(obslc, obact)) change++; + /*Try function for get weight from closest vertex*/ + /*TODO: try this function*/ + /*Try function for get weight from closest face*/ + else if(ED_vgroup_copy_by_nearest_face_single(obslc, obact)) change++; + /*Trigger error message*/ + else fail++; + /*Event notifiers for correct display of data*/ + DAG_id_tag_update(&obslc->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, obslc); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obslc->data); + } + } + CTX_DATA_END; + + /*Report error when task can not be completed with available functions.*/ + if((change == 0 && fail == 0) || fail) { + BKE_reportf(op->reports, RPT_ERROR, + "Copy to VGroups to Selected warning done %d, failed %d, All functions failed!", + change, fail); + } + + return OPERATOR_FINISHED; +} + +/*Transfer vertex group with weight to selected*/ +void OBJECT_OT_vertex_group_copy_to_selected_single(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Copy a Vertex Group to Selected"; + ot->idname= "OBJECT_OT_vertex_group_copy_to_selected_single"; + ot->description= "Copy a vertex group to other selected objects with matching indices"; + + /* api callbacks */ + ot->poll= vertex_group_poll; + ot->exec= vertex_group_copy_to_selected_single_exec; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + static EnumPropertyItem vgroup_items[] = { {0, NULL, 0, NULL, NULL} }; From 8776458e74f329e61977f4539be00bed9e2f0d10 Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Wed, 9 May 2012 16:38:49 +0000 Subject: [PATCH 015/347] gui fixed --- release/scripts/startup/bl_ui/space_view3d_toolbar.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py index f220ec19bfe..f33c9051989 100644 --- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py +++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py @@ -983,6 +983,8 @@ class VIEW3D_PT_tools_weightpaint(View3DPanel, Panel): col = layout.column() col.active = ob.vertex_groups.active is not None + col.operator("object.vertex_group_copy_to_selected", text="Transfer weight All") + col.operator("object.vertex_group_copy_to_selected_single", text="Transfer weight") col.operator("object.vertex_group_normalize_all", text="Normalize All") col.operator("object.vertex_group_normalize", text="Normalize") col.operator("object.vertex_group_mirror", text="Mirror") From f95f3d96976e24f7fbf8e268e853ef1d0106e624 Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Fri, 11 May 2012 21:33:24 +0000 Subject: [PATCH 016/347] Incomplete ED_vgroup_copy_by_nearest_face_single() compiles. --- source/blender/editors/object/object_vgroup.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 33a9d9b00f0..ee690b16229 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -538,6 +538,11 @@ int ED_vgroup_copy_by_nearest_face_single(Object *ob_dst, Object *ob_src) /*get vertices*/ mv_dst= me_dst->mvert; + /*get faces*/ + mface_src= dmesh_src->getTessFaceArray(dmesh_src); + + /*printf("test % \n", *mface_src);*/ + /* Loop through the vertices and copy weight from nearest weight*/ for(i=0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ @@ -549,15 +554,11 @@ int ED_vgroup_copy_by_nearest_face_single(Object *ob_dst, Object *ob_src) BLI_bvhtree_find_nearest(tree_mesh_faces_src.tree, mv_dst->co, &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src); /*get weight*/ - printf("test %d %d \n", me_src->mface->v1, (*me_src->mface).v1); - mface_src= me_src->mface + nearest.index; /*tot_dist= ()+()+(); use a comparable distance if(mface_src->v4){ tot_dist+= (); }*/ - printf("test %d \n", (*mface_src).v1); - dv_array_src+= mface_src->v1; - dw_src= defvert_verify_index(*dv_array_src, index_src); + dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v1], index_src); weight= dw_src->weight; dw_src= defvert_verify_index(dv_array_src[mface_src->v2], index_src); weight+= dw_src->weight; From c40d445ef7fe462b26ac5303215c23495f2c77c5 Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Sat, 12 May 2012 00:37:45 +0000 Subject: [PATCH 017/347] ED_vgroup_copy_by_nearest_face_single() Is supposed to work, but something funny is going on. (logick error) Function also needs optimization. --- source/blender/editors/object/object_vgroup.c | 99 +++++++++++++------ 1 file changed, 68 insertions(+), 31 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index ee690b16229..dff7dc6636c 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -491,21 +491,30 @@ int ED_vgroup_copy_by_nearest_vertex_single(Object *ob_dst, Object *ob_src) return 1; } +float sqr_dist_v3v3(float v1[3], float v2[3]) +{ + float d[3]; + d[0]= v2[0]-v1[0]; + d[1]= v2[1]-v1[1]; + d[2]= v2[2]-v1[2]; + return dot_v3v3(d, d); +} + /*Copy a single vertex group from source to destination with weights by nearest weight*/ /*TODO: transform into target space as in by_vertex function. postphoned due to easier testing during development*/ int ED_vgroup_copy_by_nearest_face_single(Object *ob_dst, Object *ob_src) { bDeformGroup *dg_src, *dg_dst; - MDeformVert **dv_array_src, **dv_array_dst; - MDeformWeight *dw_dst, *dw_src; - MVert *mv_dst; - MFace *mface_src; - Mesh *me_dst, *me_src; - BVHTreeFromMesh tree_mesh_faces_src = {NULL}; - BVHTreeNearest nearest; + Mesh *me_dst; DerivedMesh *dmesh_src; + BVHTreeFromMesh tree_mesh_faces_src = {NULL}; + MDeformVert **dv_array_src, **dv_array_dst; + MVert *mv_dst, *mv_src; + MFace *mface_src; + BVHTreeNearest nearest; + MDeformWeight *dw_dst, *dw_src; int dv_tot_src, dv_tot_dst, i, index_dst, index_src; - float weight/*, tot_dist*/; + float weight, tot_dist, dist_v1, dist_v2, dist_v3, dist_v4; /*get source deform group*/ dg_src= BLI_findlink(&ob_src->defbase, (ob_src->actdef-1)); @@ -519,14 +528,12 @@ int ED_vgroup_copy_by_nearest_face_single(Object *ob_dst, Object *ob_src) /*get meshes*/ me_dst= ob_dst->data; - me_src= ob_src->data; /*mfaces does not exist*/ dmesh_src= ob_src->derivedDeform; /*sergey- : this might easily be null?? (using ob_src.deriveddeform*/ /*make node tree*/ DM_ensure_tessface(dmesh_src); bvhtree_from_mesh_faces(&tree_mesh_faces_src, dmesh_src, 0.0, 2, 6); - /*get vertex group arrays*/ ED_vgroup_give_parray(ob_src->data, &dv_array_src, &dv_tot_src, FALSE); ED_vgroup_give_parray(ob_dst->data, &dv_array_dst, &dv_tot_dst, FALSE); @@ -537,16 +544,15 @@ int ED_vgroup_copy_by_nearest_face_single(Object *ob_dst, Object *ob_src) /*get vertices*/ mv_dst= me_dst->mvert; + mv_src= dmesh_src->getVertArray(dmesh_src); /*get faces*/ mface_src= dmesh_src->getTessFaceArray(dmesh_src); - /*printf("test % \n", *mface_src);*/ - /* Loop through the vertices and copy weight from nearest weight*/ for(i=0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ - /*Reset nearest*/ + /*Reset nearest*//*can I accellerate further with tweaking this=*/ nearest.index= -1; nearest.dist= FLT_MAX; @@ -554,25 +560,56 @@ int ED_vgroup_copy_by_nearest_face_single(Object *ob_dst, Object *ob_src) BLI_bvhtree_find_nearest(tree_mesh_faces_src.tree, mv_dst->co, &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src); /*get weight*/ - /*tot_dist= ()+()+(); use a comparable distance - if(mface_src->v4){ - tot_dist+= (); - }*/ - dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v1], index_src); - weight= dw_src->weight; - dw_src= defvert_verify_index(dv_array_src[mface_src->v2], index_src); - weight+= dw_src->weight; - dw_src= defvert_verify_index(dv_array_src[mface_src->v3], index_src); - weight+= dw_src->weight; - if(mface_src->v4){ - dw_src= defvert_verify_index(dv_array_src[mface_src->v4], index_src); - weight+= dw_src->weight; - weight/=4; - } - else{ - weight/=3; - } + dist_v1= sqr_dist_v3v3(mv_dst->co, mv_src[mface_src[nearest.index].v1].co); + dist_v2= sqr_dist_v3v3(mv_dst->co, mv_src[mface_src[nearest.index].v2].co); + dist_v3= sqr_dist_v3v3(mv_dst->co, mv_src[mface_src[nearest.index].v3].co); + /*get weight from overlapping vert if any*/ + if(dist_v1 == 0)weight= defvert_verify_index(dv_array_src[mface_src[nearest.index].v1], index_src)->weight; + if(dist_v2 == 0)weight= defvert_verify_index(dv_array_src[mface_src[nearest.index].v2], index_src)->weight; + if(dist_v3 == 0)weight= defvert_verify_index(dv_array_src[mface_src[nearest.index].v3], index_src)->weight; + + /*interpolate weight*/ + else{ + + /*check for quad*/ + if(mface_src[nearest.index].v4){ + dist_v4= sqr_dist_v3v3(mv_dst->co, mv_src[mface_src->v4].co); + + /*check if vert 4 is overlapping*/ + if(dist_v4 == 0)weight= defvert_verify_index(dv_array_src[mface_src[nearest.index].v4], index_src)->weight; + + /*get weight from quad*/ + else{ + tot_dist= dist_v1 + dist_v2 + dist_v3 + dist_v4; + + dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v1], index_src); + weight= dw_src->weight * dist_v1; + dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v2], index_src); + weight+= dw_src->weight * dist_v2; + dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v3], index_src); + weight+= dw_src->weight * dist_v3; + dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v4], index_src); + weight+= dw_src->weight * dist_v4; + + weight/=tot_dist; + } + } + + /*get weight from triangle*/ + else{ + tot_dist= dist_v1 + dist_v2 + dist_v3; + + dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v1], index_src); + weight= dw_src->weight * dist_v1; + dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v2], index_src); + weight+= dw_src->weight * dist_v2; + dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v3], index_src); + weight+= dw_src->weight * dist_v3; + + weight/=tot_dist; + } + } /*copy weight*/ dw_dst= defvert_verify_index(*dv_array_dst, index_dst); From 8d7de250f3b990ecfb507615aac32acf9a332259 Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Sat, 12 May 2012 01:04:12 +0000 Subject: [PATCH 018/347] Tiny bit of cleaning. --- source/blender/editors/object/object_vgroup.c | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index dff7dc6636c..7d0adaa587e 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -528,7 +528,7 @@ int ED_vgroup_copy_by_nearest_face_single(Object *ob_dst, Object *ob_src) /*get meshes*/ me_dst= ob_dst->data; - dmesh_src= ob_src->derivedDeform; /*sergey- : this might easily be null?? (using ob_src.deriveddeform*/ + dmesh_src= ob_src->derivedDeform; /*make node tree*/ DM_ensure_tessface(dmesh_src); @@ -552,7 +552,7 @@ int ED_vgroup_copy_by_nearest_face_single(Object *ob_dst, Object *ob_src) /* Loop through the vertices and copy weight from nearest weight*/ for(i=0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ - /*Reset nearest*//*can I accellerate further with tweaking this=*/ + /*Reset nearest*/ nearest.index= -1; nearest.dist= FLT_MAX; @@ -560,14 +560,18 @@ int ED_vgroup_copy_by_nearest_face_single(Object *ob_dst, Object *ob_src) BLI_bvhtree_find_nearest(tree_mesh_faces_src.tree, mv_dst->co, &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src); /*get weight*/ + + /*TODO: Have to project onto face to get a decent result*/ + + /*get distances*/ dist_v1= sqr_dist_v3v3(mv_dst->co, mv_src[mface_src[nearest.index].v1].co); dist_v2= sqr_dist_v3v3(mv_dst->co, mv_src[mface_src[nearest.index].v2].co); dist_v3= sqr_dist_v3v3(mv_dst->co, mv_src[mface_src[nearest.index].v3].co); /*get weight from overlapping vert if any*/ - if(dist_v1 == 0)weight= defvert_verify_index(dv_array_src[mface_src[nearest.index].v1], index_src)->weight; - if(dist_v2 == 0)weight= defvert_verify_index(dv_array_src[mface_src[nearest.index].v2], index_src)->weight; - if(dist_v3 == 0)weight= defvert_verify_index(dv_array_src[mface_src[nearest.index].v3], index_src)->weight; + if(dist_v1 == 0) weight= defvert_verify_index(dv_array_src[mface_src[nearest.index].v1], index_src)->weight; + if(dist_v2 == 0) weight= defvert_verify_index(dv_array_src[mface_src[nearest.index].v2], index_src)->weight; + if(dist_v3 == 0) weight= defvert_verify_index(dv_array_src[mface_src[nearest.index].v3], index_src)->weight; /*interpolate weight*/ else{ @@ -577,7 +581,7 @@ int ED_vgroup_copy_by_nearest_face_single(Object *ob_dst, Object *ob_src) dist_v4= sqr_dist_v3v3(mv_dst->co, mv_src[mface_src->v4].co); /*check if vert 4 is overlapping*/ - if(dist_v4 == 0)weight= defvert_verify_index(dv_array_src[mface_src[nearest.index].v4], index_src)->weight; + if(dist_v4 == 0) weight= defvert_verify_index(dv_array_src[mface_src[nearest.index].v4], index_src)->weight; /*get weight from quad*/ else{ @@ -592,7 +596,7 @@ int ED_vgroup_copy_by_nearest_face_single(Object *ob_dst, Object *ob_src) dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v4], index_src); weight+= dw_src->weight * dist_v4; - weight/=tot_dist; + weight/= tot_dist; } } @@ -607,7 +611,7 @@ int ED_vgroup_copy_by_nearest_face_single(Object *ob_dst, Object *ob_src) dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v3], index_src); weight+= dw_src->weight * dist_v3; - weight/=tot_dist; + weight/= tot_dist; } } From 097ebb0a6366741d6addbd81e0f6953dfa878067 Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Sat, 12 May 2012 02:13:26 +0000 Subject: [PATCH 019/347] ED_vgroup_copy_by_nearest_face_single() excluded 4th vertex in faces for better result. --- source/blender/editors/object/object_vgroup.c | 76 ++++++++++++++----- 1 file changed, 55 insertions(+), 21 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 7d0adaa587e..1b67fe146ab 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -514,7 +514,7 @@ int ED_vgroup_copy_by_nearest_face_single(Object *ob_dst, Object *ob_src) BVHTreeNearest nearest; MDeformWeight *dw_dst, *dw_src; int dv_tot_src, dv_tot_dst, i, index_dst, index_src; - float weight, tot_dist, dist_v1, dist_v2, dist_v3, dist_v4; + float weight, tot_dist, dist_v1, dist_v2, dist_v3, dist_v4, tmp_co[3]; /*get source deform group*/ dg_src= BLI_findlink(&ob_src->defbase, (ob_src->actdef-1)); @@ -556,17 +556,21 @@ int ED_vgroup_copy_by_nearest_face_single(Object *ob_dst, Object *ob_src) nearest.index= -1; nearest.dist= FLT_MAX; + /*set destination coordinate*/ + copy_v3_v3(tmp_co, mv_dst->co); + /*Node tree accelerated search for closest face*/ - BLI_bvhtree_find_nearest(tree_mesh_faces_src.tree, mv_dst->co, &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src); + BLI_bvhtree_find_nearest(tree_mesh_faces_src.tree, tmp_co, &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src); /*get weight*/ /*TODO: Have to project onto face to get a decent result*/ + /*Smart solution might be to just substract the distance difference to plane instead.*/ /*get distances*/ - dist_v1= sqr_dist_v3v3(mv_dst->co, mv_src[mface_src[nearest.index].v1].co); - dist_v2= sqr_dist_v3v3(mv_dst->co, mv_src[mface_src[nearest.index].v2].co); - dist_v3= sqr_dist_v3v3(mv_dst->co, mv_src[mface_src[nearest.index].v3].co); + dist_v1= sqr_dist_v3v3(tmp_co, mv_src[mface_src[nearest.index].v1].co); + dist_v2= sqr_dist_v3v3(tmp_co, mv_src[mface_src[nearest.index].v2].co); + dist_v3= sqr_dist_v3v3(tmp_co, mv_src[mface_src[nearest.index].v3].co); /*get weight from overlapping vert if any*/ if(dist_v1 == 0) weight= defvert_verify_index(dv_array_src[mface_src[nearest.index].v1], index_src)->weight; @@ -578,25 +582,57 @@ int ED_vgroup_copy_by_nearest_face_single(Object *ob_dst, Object *ob_src) /*check for quad*/ if(mface_src[nearest.index].v4){ - dist_v4= sqr_dist_v3v3(mv_dst->co, mv_src[mface_src->v4].co); + dist_v4= sqr_dist_v3v3(tmp_co, mv_src[mface_src->v4].co); /*check if vert 4 is overlapping*/ if(dist_v4 == 0) weight= defvert_verify_index(dv_array_src[mface_src[nearest.index].v4], index_src)->weight; /*get weight from quad*/ else{ - tot_dist= dist_v1 + dist_v2 + dist_v3 + dist_v4; + if(dist_v1 > dist_v2||dist_v1 > dist_v3||dist_v1 > dist_v4){ + /*exclude v1 and get weight from the 3 closest*/ + tot_dist= dist_v4 + dist_v2 + dist_v3; - dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v1], index_src); - weight= dw_src->weight * dist_v1; - dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v2], index_src); - weight+= dw_src->weight * dist_v2; - dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v3], index_src); - weight+= dw_src->weight * dist_v3; - dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v4], index_src); - weight+= dw_src->weight * dist_v4; + dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v4], index_src); + weight= dw_src->weight * (1-dist_v4/tot_dist); + dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v2], index_src); + weight+= dw_src->weight * (1-dist_v2/tot_dist); + dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v3], index_src); + weight+= dw_src->weight * (1-dist_v3/tot_dist); + } + else if(dist_v2 > dist_v3||dist_v2 > dist_v4){ + /*exclude v2 and get weight from the 3 closest*/ + tot_dist= dist_v1 + dist_v4 + dist_v3; - weight/= tot_dist; + dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v1], index_src); + weight= dw_src->weight * (1-dist_v1/tot_dist); + dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v4], index_src); + weight+= dw_src->weight * (1-dist_v4/tot_dist); + dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v3], index_src); + weight+= dw_src->weight * (1-dist_v3/tot_dist); + } + else if(dist_v3 > dist_v4){ + /*exclude v3 and get weight from the 3 closest*/ + tot_dist= dist_v1 + dist_v2 + dist_v4; + + dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v1], index_src); + weight= dw_src->weight * (1-dist_v1/tot_dist); + dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v2], index_src); + weight+= dw_src->weight * (1-dist_v2/tot_dist); + dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v4], index_src); + weight+= dw_src->weight * (1-dist_v4/tot_dist); + } + else{ + /*exclude v4 and get weight from the 3 closest*/ + tot_dist= dist_v1 + dist_v2 + dist_v3; + + dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v1], index_src); + weight= dw_src->weight * (1-dist_v1/tot_dist); + dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v2], index_src); + weight+= dw_src->weight * (1-dist_v2/tot_dist); + dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v3], index_src); + weight+= dw_src->weight * (1-dist_v3/tot_dist); + } } } @@ -605,13 +641,11 @@ int ED_vgroup_copy_by_nearest_face_single(Object *ob_dst, Object *ob_src) tot_dist= dist_v1 + dist_v2 + dist_v3; dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v1], index_src); - weight= dw_src->weight * dist_v1; + weight= dw_src->weight * (1-dist_v1/tot_dist); dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v2], index_src); - weight+= dw_src->weight * dist_v2; + weight+= dw_src->weight * (1-dist_v2/tot_dist); dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v3], index_src); - weight+= dw_src->weight * dist_v3; - - weight/= tot_dist; + weight+= dw_src->weight * (1-dist_v3/tot_dist); } } From 66f4f3a9f5bacbb661b87a0463b0875fad00d8be Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Sat, 12 May 2012 03:32:13 +0000 Subject: [PATCH 020/347] some more cleanup --- source/blender/editors/object/object_vgroup.c | 54 +++++++++---------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 1b67fe146ab..580124d480d 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -589,49 +589,49 @@ int ED_vgroup_copy_by_nearest_face_single(Object *ob_dst, Object *ob_src) /*get weight from quad*/ else{ - if(dist_v1 > dist_v2||dist_v1 > dist_v3||dist_v1 > dist_v4){ - /*exclude v1 and get weight from the 3 closest*/ + + /*exclude v1 and get weight from the 3 closest*/ + if(dist_v1 >= dist_v2 && dist_v1 >= dist_v3 && dist_v1 >= dist_v4){ tot_dist= dist_v4 + dist_v2 + dist_v3; - dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v4], index_src); - weight= dw_src->weight * (1-dist_v4/tot_dist); + weight= dw_src->weight / tot_dist * dist_v4; dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v2], index_src); - weight+= dw_src->weight * (1-dist_v2/tot_dist); + weight+= dw_src->weight / tot_dist * dist_v2; dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v3], index_src); - weight+= dw_src->weight * (1-dist_v3/tot_dist); + weight+= dw_src->weight / tot_dist * dist_v3; } - else if(dist_v2 > dist_v3||dist_v2 > dist_v4){ - /*exclude v2 and get weight from the 3 closest*/ + + /*exclude v2 and get weight from the 3 closest*/ + else if(dist_v2 >= dist_v3 && dist_v2 >= dist_v4){ tot_dist= dist_v1 + dist_v4 + dist_v3; - dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v1], index_src); - weight= dw_src->weight * (1-dist_v1/tot_dist); + weight= dw_src->weight / tot_dist * dist_v1; dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v4], index_src); - weight+= dw_src->weight * (1-dist_v4/tot_dist); + weight+= dw_src->weight / tot_dist * dist_v4; dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v3], index_src); - weight+= dw_src->weight * (1-dist_v3/tot_dist); + weight+= dw_src->weight / tot_dist * dist_v3; } - else if(dist_v3 > dist_v4){ - /*exclude v3 and get weight from the 3 closest*/ + + /*exclude v3 and get weight from the 3 closest*/ + else if(dist_v3 >= dist_v4){ tot_dist= dist_v1 + dist_v2 + dist_v4; - dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v1], index_src); - weight= dw_src->weight * (1-dist_v1/tot_dist); + weight= dw_src->weight / tot_dist * dist_v1; dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v2], index_src); - weight+= dw_src->weight * (1-dist_v2/tot_dist); + weight+= dw_src->weight / tot_dist * dist_v2; dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v4], index_src); - weight+= dw_src->weight * (1-dist_v4/tot_dist); + weight+= dw_src->weight / tot_dist * dist_v4; } - else{ - /*exclude v4 and get weight from the 3 closest*/ - tot_dist= dist_v1 + dist_v2 + dist_v3; + /*exclude v4 and get weight from the 3 closest*/ + else{ + tot_dist= dist_v1 + dist_v2 + dist_v3; dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v1], index_src); - weight= dw_src->weight * (1-dist_v1/tot_dist); + weight= dw_src->weight / tot_dist * dist_v1; dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v2], index_src); - weight+= dw_src->weight * (1-dist_v2/tot_dist); + weight+= dw_src->weight / tot_dist * dist_v2; dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v3], index_src); - weight+= dw_src->weight * (1-dist_v3/tot_dist); + weight+= dw_src->weight / tot_dist * dist_v3; } } } @@ -641,11 +641,11 @@ int ED_vgroup_copy_by_nearest_face_single(Object *ob_dst, Object *ob_src) tot_dist= dist_v1 + dist_v2 + dist_v3; dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v1], index_src); - weight= dw_src->weight * (1-dist_v1/tot_dist); + weight= dw_src->weight / tot_dist * dist_v1; dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v2], index_src); - weight+= dw_src->weight * (1-dist_v2/tot_dist); + weight+= dw_src->weight / tot_dist * dist_v2; dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v3], index_src); - weight+= dw_src->weight * (1-dist_v3/tot_dist); + weight+= dw_src->weight / tot_dist * dist_v3; } } From b7f4ea118c4daad48283362bc454d62a9cfea832 Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Sat, 12 May 2012 03:50:44 +0000 Subject: [PATCH 021/347] obs! not thinking straight. Reverting bug from cleanup. --- source/blender/editors/object/object_vgroup.c | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 580124d480d..256d8f3f3d9 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -594,44 +594,44 @@ int ED_vgroup_copy_by_nearest_face_single(Object *ob_dst, Object *ob_src) if(dist_v1 >= dist_v2 && dist_v1 >= dist_v3 && dist_v1 >= dist_v4){ tot_dist= dist_v4 + dist_v2 + dist_v3; dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v4], index_src); - weight= dw_src->weight / tot_dist * dist_v4; + weight= dw_src->weight * (1-dist_v4/tot_dist); dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v2], index_src); - weight+= dw_src->weight / tot_dist * dist_v2; + weight+= dw_src->weight * (1-dist_v2/tot_dist); dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v3], index_src); - weight+= dw_src->weight / tot_dist * dist_v3; + weight+= dw_src->weight * (1-dist_v3/tot_dist); } /*exclude v2 and get weight from the 3 closest*/ else if(dist_v2 >= dist_v3 && dist_v2 >= dist_v4){ tot_dist= dist_v1 + dist_v4 + dist_v3; dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v1], index_src); - weight= dw_src->weight / tot_dist * dist_v1; + weight= dw_src->weight * (1-dist_v1/tot_dist); dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v4], index_src); - weight+= dw_src->weight / tot_dist * dist_v4; + weight+= dw_src->weight * (1-dist_v4/tot_dist); dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v3], index_src); - weight+= dw_src->weight / tot_dist * dist_v3; + weight+= dw_src->weight * (1-dist_v3/tot_dist); } /*exclude v3 and get weight from the 3 closest*/ else if(dist_v3 >= dist_v4){ tot_dist= dist_v1 + dist_v2 + dist_v4; dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v1], index_src); - weight= dw_src->weight / tot_dist * dist_v1; + weight= dw_src->weight * (1-dist_v1/tot_dist); dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v2], index_src); - weight+= dw_src->weight / tot_dist * dist_v2; + weight+= dw_src->weight * (1-dist_v2/tot_dist); dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v4], index_src); - weight+= dw_src->weight / tot_dist * dist_v4; + weight+= dw_src->weight * (1-dist_v4/tot_dist); } /*exclude v4 and get weight from the 3 closest*/ else{ tot_dist= dist_v1 + dist_v2 + dist_v3; dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v1], index_src); - weight= dw_src->weight / tot_dist * dist_v1; + weight= dw_src->weight * (1-dist_v1/tot_dist); dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v2], index_src); - weight+= dw_src->weight / tot_dist * dist_v2; + weight+= dw_src->weight * (1-dist_v2/tot_dist); dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v3], index_src); - weight+= dw_src->weight / tot_dist * dist_v3; + weight+= dw_src->weight * (1-dist_v3/tot_dist); } } } @@ -641,11 +641,11 @@ int ED_vgroup_copy_by_nearest_face_single(Object *ob_dst, Object *ob_src) tot_dist= dist_v1 + dist_v2 + dist_v3; dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v1], index_src); - weight= dw_src->weight / tot_dist * dist_v1; + weight= dw_src->weight * (1-dist_v1/tot_dist); dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v2], index_src); - weight+= dw_src->weight / tot_dist * dist_v2; + weight+= dw_src->weight * (1-dist_v2/tot_dist); dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v3], index_src); - weight+= dw_src->weight / tot_dist * dist_v3; + weight+= dw_src->weight * (1-dist_v3/tot_dist); } } From 7adeedfecc19d5acc94463bdffa0e6e4524259ee Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Sat, 12 May 2012 17:43:56 +0000 Subject: [PATCH 022/347] ED_vgroup_copy_by_nearest_face_single() Math for interpolation of weights fixed to be consistent with reality... Still there is probably some indexing errors. Some vertices that should have blue weight, gets red. (on border faces) --- source/blender/editors/object/object_vgroup.c | 83 +++++++++++-------- 1 file changed, 50 insertions(+), 33 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 256d8f3f3d9..b96130716a5 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -514,7 +514,7 @@ int ED_vgroup_copy_by_nearest_face_single(Object *ob_dst, Object *ob_src) BVHTreeNearest nearest; MDeformWeight *dw_dst, *dw_src; int dv_tot_src, dv_tot_dst, i, index_dst, index_src; - float weight, tot_dist, dist_v1, dist_v2, dist_v3, dist_v4, tmp_co[3]; + float weight, tot_distribution, distribution_v1, distribution_v2, distribution_v3, distribution_v4, tmp_co[3]; /*get source deform group*/ dg_src= BLI_findlink(&ob_src->defbase, (ob_src->actdef-1)); @@ -544,6 +544,7 @@ int ED_vgroup_copy_by_nearest_face_single(Object *ob_dst, Object *ob_src) /*get vertices*/ mv_dst= me_dst->mvert; + mv_src= dmesh_src->getVertArray(dmesh_src); /*get faces*/ @@ -568,84 +569,100 @@ int ED_vgroup_copy_by_nearest_face_single(Object *ob_dst, Object *ob_src) /*Smart solution might be to just substract the distance difference to plane instead.*/ /*get distances*/ - dist_v1= sqr_dist_v3v3(tmp_co, mv_src[mface_src[nearest.index].v1].co); - dist_v2= sqr_dist_v3v3(tmp_co, mv_src[mface_src[nearest.index].v2].co); - dist_v3= sqr_dist_v3v3(tmp_co, mv_src[mface_src[nearest.index].v3].co); + distribution_v1= sqr_dist_v3v3(tmp_co, mv_src[mface_src[nearest.index].v1].co); + distribution_v2= sqr_dist_v3v3(tmp_co, mv_src[mface_src[nearest.index].v2].co); + distribution_v3= sqr_dist_v3v3(tmp_co, mv_src[mface_src[nearest.index].v3].co); + + /*test + printf("dist_v1 %f index v1%d \n", dist_v1, mface_src[nearest.index].v1); + printf("dist_v2 %f index v2%d \n", dist_v2, mface_src[nearest.index].v2); + printf("dist_v3 %f index v3%d \n", dist_v3, mface_src[nearest.index].v3);*/ /*get weight from overlapping vert if any*/ - if(dist_v1 == 0) weight= defvert_verify_index(dv_array_src[mface_src[nearest.index].v1], index_src)->weight; - if(dist_v2 == 0) weight= defvert_verify_index(dv_array_src[mface_src[nearest.index].v2], index_src)->weight; - if(dist_v3 == 0) weight= defvert_verify_index(dv_array_src[mface_src[nearest.index].v3], index_src)->weight; + if(distribution_v1 == 0) weight= defvert_verify_index(dv_array_src[mface_src[nearest.index].v1], index_src)->weight; + if(distribution_v2 == 0) weight= defvert_verify_index(dv_array_src[mface_src[nearest.index].v2], index_src)->weight; + if(distribution_v3 == 0) weight= defvert_verify_index(dv_array_src[mface_src[nearest.index].v3], index_src)->weight; /*interpolate weight*/ else{ /*check for quad*/ if(mface_src[nearest.index].v4){ - dist_v4= sqr_dist_v3v3(tmp_co, mv_src[mface_src->v4].co); + distribution_v4= sqr_dist_v3v3(tmp_co, mv_src[mface_src->v4].co); /*check if vert 4 is overlapping*/ - if(dist_v4 == 0) weight= defvert_verify_index(dv_array_src[mface_src[nearest.index].v4], index_src)->weight; + if(distribution_v4 == 0) weight= defvert_verify_index(dv_array_src[mface_src[nearest.index].v4], index_src)->weight; /*get weight from quad*/ else{ + /*invert distribution*/ + distribution_v1= 1 / distribution_v1; + distribution_v2= 1 / distribution_v2; + distribution_v3= 1 / distribution_v3; + distribution_v4= 1 / distribution_v4; + /*exclude v1 and get weight from the 3 closest*/ - if(dist_v1 >= dist_v2 && dist_v1 >= dist_v3 && dist_v1 >= dist_v4){ - tot_dist= dist_v4 + dist_v2 + dist_v3; + if(distribution_v1 > distribution_v2 && distribution_v1 > distribution_v3 && distribution_v1 > distribution_v4){ + tot_distribution= distribution_v4 + distribution_v2 + distribution_v3; dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v4], index_src); - weight= dw_src->weight * (1-dist_v4/tot_dist); + weight= dw_src->weight * distribution_v4 / tot_distribution; dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v2], index_src); - weight+= dw_src->weight * (1-dist_v2/tot_dist); + weight+= dw_src->weight * distribution_v2 / tot_distribution; dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v3], index_src); - weight+= dw_src->weight * (1-dist_v3/tot_dist); + weight+= dw_src->weight * distribution_v3 / tot_distribution; } /*exclude v2 and get weight from the 3 closest*/ - else if(dist_v2 >= dist_v3 && dist_v2 >= dist_v4){ - tot_dist= dist_v1 + dist_v4 + dist_v3; + else if(distribution_v2 > distribution_v3 && distribution_v2 > distribution_v4){ + tot_distribution= distribution_v1 + distribution_v4 + distribution_v3; dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v1], index_src); - weight= dw_src->weight * (1-dist_v1/tot_dist); + weight= dw_src->weight * distribution_v1 / tot_distribution; dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v4], index_src); - weight+= dw_src->weight * (1-dist_v4/tot_dist); + weight+= dw_src->weight * distribution_v4 / tot_distribution; dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v3], index_src); - weight+= dw_src->weight * (1-dist_v3/tot_dist); + weight+= dw_src->weight * distribution_v3 / tot_distribution; } /*exclude v3 and get weight from the 3 closest*/ - else if(dist_v3 >= dist_v4){ - tot_dist= dist_v1 + dist_v2 + dist_v4; + else if(distribution_v3 > distribution_v4){ + tot_distribution= distribution_v1 + distribution_v2 + distribution_v4; dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v1], index_src); - weight= dw_src->weight * (1-dist_v1/tot_dist); + weight= dw_src->weight * distribution_v1 / tot_distribution; dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v2], index_src); - weight+= dw_src->weight * (1-dist_v2/tot_dist); + weight+= dw_src->weight * distribution_v2 / tot_distribution; dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v4], index_src); - weight+= dw_src->weight * (1-dist_v4/tot_dist); + weight+= dw_src->weight * distribution_v4 / tot_distribution; } - /*exclude v4 and get weight from the 3 closest*/ + /*exclude v4 and get weight from the 3 closest. Also when some distances are the same*/ else{ - tot_dist= dist_v1 + dist_v2 + dist_v3; + tot_distribution= distribution_v1 + distribution_v2 + distribution_v3; dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v1], index_src); - weight= dw_src->weight * (1-dist_v1/tot_dist); + weight= dw_src->weight * distribution_v1 / tot_distribution; dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v2], index_src); - weight+= dw_src->weight * (1-dist_v2/tot_dist); + weight+= dw_src->weight * distribution_v2 / tot_distribution; dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v3], index_src); - weight+= dw_src->weight * (1-dist_v3/tot_dist); + weight+= dw_src->weight * distribution_v3 / tot_distribution; } } } /*get weight from triangle*/ else{ - tot_dist= dist_v1 + dist_v2 + dist_v3; + /*invert distribution*/ + distribution_v1= 1 / distribution_v1; + distribution_v2= 1 / distribution_v2; + distribution_v3= 1 / distribution_v3; + + tot_distribution= distribution_v1 + distribution_v2 + distribution_v3; dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v1], index_src); - weight= dw_src->weight * (1-dist_v1/tot_dist); + weight= dw_src->weight * distribution_v1 / tot_distribution; dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v2], index_src); - weight+= dw_src->weight * (1-dist_v2/tot_dist); + weight+= dw_src->weight * distribution_v2 / tot_distribution; dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v3], index_src); - weight+= dw_src->weight * (1-dist_v3/tot_dist); + weight+= dw_src->weight * distribution_v3 / tot_distribution; } } From 4215071ace4e6d9ea7a3e8aa2719e382761b5427 Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Sun, 13 May 2012 03:46:46 +0000 Subject: [PATCH 023/347] Complete working function added: ED_vgroup_copy_by_nearest_vertex_in_face_single() --- source/blender/editors/object/object_vgroup.c | 101 +++++++++++++++++- 1 file changed, 100 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index b96130716a5..b1824e90dde 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -500,6 +500,105 @@ float sqr_dist_v3v3(float v1[3], float v2[3]) return dot_v3v3(d, d); } +/*Copy a single vertex group from source to destination with weights by nearest weight in face*/ +int ED_vgroup_copy_by_nearest_vertex_in_face_single(Object *ob_dst, Object *ob_src) +{ + bDeformGroup *dg_src, *dg_dst; + Mesh *me_dst; + DerivedMesh *dmesh_src; + BVHTreeFromMesh tree_mesh_faces_src = {NULL}; + MDeformVert **dv_array_src, **dv_array_dst; + MVert *mv_dst, *mv_src; + MFace *mface_src; + BVHTreeNearest nearest; + MDeformWeight *dw_dst, *dw_src; + int dv_tot_src, dv_tot_dst, i, index_dst, index_src; + float dist_v1, dist_v2, dist_v3, dist_v4, tmp_co[3], tmp_mat[4][4]; + + /*get source deform group*/ + dg_src= BLI_findlink(&ob_src->defbase, (ob_src->actdef-1)); + + /*Create new and overwrite vertex group on destination without data*/ + ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_src->name)); + ED_vgroup_add_name(ob_dst, dg_src->name); + + /*get destination deformgroup*/ + dg_dst= defgroup_find_name(ob_dst, dg_src->name); + + /*get meshes*/ + me_dst= ob_dst->data; + dmesh_src= ob_src->derivedDeform; + + /*make node tree*/ + DM_ensure_tessface(dmesh_src); + bvhtree_from_mesh_faces(&tree_mesh_faces_src, dmesh_src, 0.0, 2, 6); + + /*get vertex group arrays*/ + ED_vgroup_give_parray(ob_src->data, &dv_array_src, &dv_tot_src, FALSE); + ED_vgroup_give_parray(ob_dst->data, &dv_array_dst, &dv_tot_dst, FALSE); + + /*get indexes of vertex groups*/ + index_src= BLI_findindex(&ob_src->defbase, dg_src); + index_dst= BLI_findindex(&ob_dst->defbase, dg_dst); + + /*get vertices*/ + mv_dst= me_dst->mvert; + + mv_src= dmesh_src->getVertArray(dmesh_src); + + /*get faces*/ + mface_src= dmesh_src->getTessFaceArray(dmesh_src); + + /*Prepearing transformation matrix*/ + invert_m4_m4(ob_src->imat, ob_src->obmat); + mult_m4_m4m4(tmp_mat, ob_src->imat, ob_dst->obmat); + + /* Loop through the vertices and copy weight from nearest weight*/ + for(i=0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ + + /*Reset nearest*/ + nearest.index= -1; + nearest.dist= FLT_MAX; + + /*Transforming into target space*/ + mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); + + /*Node tree accelerated search for closest face*/ + BLI_bvhtree_find_nearest(tree_mesh_faces_src.tree, tmp_co, &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src); + + /*get distances*/ + dist_v1= sqr_dist_v3v3(tmp_co, mv_src[mface_src[nearest.index].v1].co); + dist_v2= sqr_dist_v3v3(tmp_co, mv_src[mface_src[nearest.index].v2].co); + dist_v3= sqr_dist_v3v3(tmp_co, mv_src[mface_src[nearest.index].v3].co); + + /*get weight from triangle*/ + if(dist_v1weight= dw_src->weight; + } + + /*free memory and return*/ + free_bvhtree_from_mesh(&tree_mesh_faces_src); + return 1; +} + /*Copy a single vertex group from source to destination with weights by nearest weight*/ /*TODO: transform into target space as in by_vertex function. postphoned due to easier testing during development*/ int ED_vgroup_copy_by_nearest_face_single(Object *ob_dst, Object *ob_src) @@ -3075,7 +3174,7 @@ static int vertex_group_copy_to_selected_single_exec(bContext *C, wmOperator *op /*Try function for get weight from closest vertex*/ /*TODO: try this function*/ /*Try function for get weight from closest face*/ - else if(ED_vgroup_copy_by_nearest_face_single(obslc, obact)) change++; + else if(ED_vgroup_copy_by_nearest_vertex_in_face_single(obslc, obact)) change++; /*Trigger error message*/ else fail++; /*Event notifiers for correct display of data*/ From 4bee0a42dd8f41abf6d9bcf72b484f05cba8f955 Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Sun, 13 May 2012 05:33:25 +0000 Subject: [PATCH 024/347] Cleanup. Basis changed/added for: ED_vgroup_copy_by_nearest_face_single() Interpolation is still not working 100% --- source/blender/editors/object/object_vgroup.c | 148 ++++++------------ 1 file changed, 51 insertions(+), 97 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index b1824e90dde..f40bdde8aa2 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -376,7 +376,7 @@ int ED_vgroup_copy_array(Object *ob, Object *ob_from) return 1; } -/*Copy a single vertex group from source to destination with weights*/ +/*Copy a single vertex group from source to destination with weights by identical meshes*/ int ED_vgroup_copy_single(Object *ob_dst, const Object *ob_src) { MDeformVert **dv_array_src; @@ -389,7 +389,7 @@ int ED_vgroup_copy_single(Object *ob_dst, const Object *ob_src) /*get source deform group*/ dg_src= BLI_findlink(&ob_src->defbase, (ob_src->actdef-1)); - /*Create new and overwrite vertex group on destination without data*/ + /*create new and overwrite vertex group on destination without data*/ ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_src->name)); ED_vgroup_add_name(ob_dst, dg_src->name); @@ -404,13 +404,13 @@ int ED_vgroup_copy_single(Object *ob_dst, const Object *ob_src) index_src= BLI_findindex(&ob_src->defbase, dg_src); index_dst= BLI_findindex(&ob_dst->defbase, dg_dst); - /*Check if indices are matching, delete and return if not*/ + /*check if indices are matching, delete and return if not*/ if (ob_dst == ob_src || dv_tot_dst == 0 || (dv_tot_dst != dv_tot_src) || dv_array_src == NULL || dv_array_dst == NULL) { ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_dst->name)); return 0; } - /* Loop through the vertices and copy weight*/ + /* loop through the vertices and copy weight*/ for(i=0; idefbase, (ob_src->actdef-1)); - /*Create new and overwrite vertex group on destination without data*/ + /*create new and overwrite vertex group on destination without data*/ ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_src->name)); ED_vgroup_add_name(ob_dst, dg_src->name); @@ -462,22 +462,22 @@ int ED_vgroup_copy_by_nearest_vertex_single(Object *ob_dst, Object *ob_src) /*get vertices*/ mv_dst= me_dst->mvert; - /*Prepearing transformation matrix*/ - /*This can be excluded to make a lazy feature that works better when object centers relative to mesh is the same*/ + /*prepare transformation matrix*/ + /*this can be excluded to make a lazy feature that works better when object centers relative to mesh is the same*/ invert_m4_m4(ob_src->imat, ob_src->obmat); mult_m4_m4m4(tmp_mat, ob_src->imat, ob_dst->obmat); - /* Loop through the vertices and copy weight from nearest weight*/ + /* loop through the vertices and copy weight from nearest weight*/ for(i=0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ - /*Reset nearest*/ + /*reset nearest*/ nearest.index= -1; nearest.dist= FLT_MAX; - /*Transforming into target space*/ + /*transform into target space*/ mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); - /*Node tree accelerated search for closest vetex*/ + /*node tree accelerated search for closest vetex*/ BLI_bvhtree_find_nearest(tree_mesh_src.tree, tmp_co, &nearest, tree_mesh_src.nearest_callback, &tree_mesh_src); /*copy weight*/ @@ -491,6 +491,7 @@ int ED_vgroup_copy_by_nearest_vertex_single(Object *ob_dst, Object *ob_src) return 1; } +/*Return the squared distance between two points in 3d space*/ float sqr_dist_v3v3(float v1[3], float v2[3]) { float d[3]; @@ -518,7 +519,7 @@ int ED_vgroup_copy_by_nearest_vertex_in_face_single(Object *ob_dst, Object *ob_s /*get source deform group*/ dg_src= BLI_findlink(&ob_src->defbase, (ob_src->actdef-1)); - /*Create new and overwrite vertex group on destination without data*/ + /*create new and overwrite vertex group on destination without data*/ ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_src->name)); ED_vgroup_add_name(ob_dst, dg_src->name); @@ -543,27 +544,26 @@ int ED_vgroup_copy_by_nearest_vertex_in_face_single(Object *ob_dst, Object *ob_s /*get vertices*/ mv_dst= me_dst->mvert; - mv_src= dmesh_src->getVertArray(dmesh_src); /*get faces*/ mface_src= dmesh_src->getTessFaceArray(dmesh_src); - /*Prepearing transformation matrix*/ + /*prepare transformation matrix*/ invert_m4_m4(ob_src->imat, ob_src->obmat); mult_m4_m4m4(tmp_mat, ob_src->imat, ob_dst->obmat); - /* Loop through the vertices and copy weight from nearest weight*/ + /* loop through the vertices and copy weight from nearest weight*/ for(i=0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ - /*Reset nearest*/ + /*reset nearest*/ nearest.index= -1; nearest.dist= FLT_MAX; - /*Transforming into target space*/ + /*transform into target space*/ mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); - /*Node tree accelerated search for closest face*/ + /*node tree accelerated search for closest face*/ BLI_bvhtree_find_nearest(tree_mesh_faces_src.tree, tmp_co, &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src); /*get distances*/ @@ -581,7 +581,7 @@ int ED_vgroup_copy_by_nearest_vertex_in_face_single(Object *ob_dst, Object *ob_s else{ dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v3], index_src); } - /*Check for and get weight from quad*/ + /*check for and get weight from quad*/ if(mface_src[nearest.index].v4){ dist_v4= sqr_dist_v3v3(tmp_co, mv_src[mface_src[nearest.index].v4].co); if(dist_v4defbase, (ob_src->actdef-1)); - /*Create new and overwrite vertex group on destination without data*/ + /*create new and overwrite vertex group on destination without data*/ ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_src->name)); ED_vgroup_add_name(ob_dst, dg_src->name); @@ -643,27 +643,24 @@ int ED_vgroup_copy_by_nearest_face_single(Object *ob_dst, Object *ob_src) /*get vertices*/ mv_dst= me_dst->mvert; - mv_src= dmesh_src->getVertArray(dmesh_src); /*get faces*/ mface_src= dmesh_src->getTessFaceArray(dmesh_src); - /* Loop through the vertices and copy weight from nearest weight*/ + /* loop through the vertices and copy weight from nearest weight*/ for(i=0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ - /*Reset nearest*/ + /*reset nearest*/ nearest.index= -1; nearest.dist= FLT_MAX; /*set destination coordinate*/ copy_v3_v3(tmp_co, mv_dst->co); - /*Node tree accelerated search for closest face*/ + /*node tree accelerated search for closest face*/ BLI_bvhtree_find_nearest(tree_mesh_faces_src.tree, tmp_co, &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src); - /*get weight*/ - /*TODO: Have to project onto face to get a decent result*/ /*Smart solution might be to just substract the distance difference to plane instead.*/ @@ -672,90 +669,40 @@ int ED_vgroup_copy_by_nearest_face_single(Object *ob_dst, Object *ob_src) distribution_v2= sqr_dist_v3v3(tmp_co, mv_src[mface_src[nearest.index].v2].co); distribution_v3= sqr_dist_v3v3(tmp_co, mv_src[mface_src[nearest.index].v3].co); - /*test - printf("dist_v1 %f index v1%d \n", dist_v1, mface_src[nearest.index].v1); - printf("dist_v2 %f index v2%d \n", dist_v2, mface_src[nearest.index].v2); - printf("dist_v3 %f index v3%d \n", dist_v3, mface_src[nearest.index].v3);*/ - /*get weight from overlapping vert if any*/ if(distribution_v1 == 0) weight= defvert_verify_index(dv_array_src[mface_src[nearest.index].v1], index_src)->weight; if(distribution_v2 == 0) weight= defvert_verify_index(dv_array_src[mface_src[nearest.index].v2], index_src)->weight; if(distribution_v3 == 0) weight= defvert_verify_index(dv_array_src[mface_src[nearest.index].v3], index_src)->weight; - - /*interpolate weight*/ else{ + /*invert distribution*/ + distribution_v1= 1/distribution_v1; + distribution_v2= 1/distribution_v2; + distribution_v3= 1/distribution_v3; + + /*set total distribution*/ + tot_distribution= distribution_v1 + distribution_v2 + distribution_v3; /*check for quad*/ if(mface_src[nearest.index].v4){ distribution_v4= sqr_dist_v3v3(tmp_co, mv_src[mface_src->v4].co); - - /*check if vert 4 is overlapping*/ if(distribution_v4 == 0) weight= defvert_verify_index(dv_array_src[mface_src[nearest.index].v4], index_src)->weight; - - /*get weight from quad*/ else{ + distribution_v4= 1/distribution_v4; + tot_distribution+= distribution_v4; - /*invert distribution*/ - distribution_v1= 1 / distribution_v1; - distribution_v2= 1 / distribution_v2; - distribution_v3= 1 / distribution_v3; - distribution_v4= 1 / distribution_v4; - - /*exclude v1 and get weight from the 3 closest*/ - if(distribution_v1 > distribution_v2 && distribution_v1 > distribution_v3 && distribution_v1 > distribution_v4){ - tot_distribution= distribution_v4 + distribution_v2 + distribution_v3; - dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v4], index_src); - weight= dw_src->weight * distribution_v4 / tot_distribution; - dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v2], index_src); - weight+= dw_src->weight * distribution_v2 / tot_distribution; - dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v3], index_src); - weight+= dw_src->weight * distribution_v3 / tot_distribution; - } - - /*exclude v2 and get weight from the 3 closest*/ - else if(distribution_v2 > distribution_v3 && distribution_v2 > distribution_v4){ - tot_distribution= distribution_v1 + distribution_v4 + distribution_v3; - dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v1], index_src); - weight= dw_src->weight * distribution_v1 / tot_distribution; - dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v4], index_src); - weight+= dw_src->weight * distribution_v4 / tot_distribution; - dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v3], index_src); - weight+= dw_src->weight * distribution_v3 / tot_distribution; - } - - /*exclude v3 and get weight from the 3 closest*/ - else if(distribution_v3 > distribution_v4){ - tot_distribution= distribution_v1 + distribution_v2 + distribution_v4; - dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v1], index_src); - weight= dw_src->weight * distribution_v1 / tot_distribution; - dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v2], index_src); - weight+= dw_src->weight * distribution_v2 / tot_distribution; - dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v4], index_src); - weight+= dw_src->weight * distribution_v4 / tot_distribution; - } - - /*exclude v4 and get weight from the 3 closest. Also when some distances are the same*/ - else{ - tot_distribution= distribution_v1 + distribution_v2 + distribution_v3; - dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v1], index_src); - weight= dw_src->weight * distribution_v1 / tot_distribution; - dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v2], index_src); - weight+= dw_src->weight * distribution_v2 / tot_distribution; - dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v3], index_src); - weight+= dw_src->weight * distribution_v3 / tot_distribution; - } + /*get weight from quad*/ + dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v1], index_src); + weight= dw_src->weight * distribution_v1 / tot_distribution; + dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v2], index_src); + weight+= dw_src->weight * distribution_v2 / tot_distribution; + dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v3], index_src); + weight+= dw_src->weight * distribution_v3 / tot_distribution; + dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v4], index_src); + weight+= dw_src->weight * distribution_v4 / tot_distribution; } } - - /*get weight from triangle*/ else{ - - /*invert distribution*/ - distribution_v1= 1 / distribution_v1; - distribution_v2= 1 / distribution_v2; - distribution_v3= 1 / distribution_v3; - - tot_distribution= distribution_v1 + distribution_v2 + distribution_v3; + /*get weight from triangle*/ dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v1], index_src); weight= dw_src->weight * distribution_v1 / tot_distribution; dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v2], index_src); @@ -765,6 +712,13 @@ int ED_vgroup_copy_by_nearest_face_single(Object *ob_dst, Object *ob_src) } } + /*snap to valid number*/ + weight*= 1000; + weight+= 0.5; + weight= (int)weight; + weight/=1000; + if(weight>1)weight= 1; + /*copy weight*/ dw_dst= defvert_verify_index(*dv_array_dst, index_dst); dw_dst->weight= weight; @@ -3174,7 +3128,7 @@ static int vertex_group_copy_to_selected_single_exec(bContext *C, wmOperator *op /*Try function for get weight from closest vertex*/ /*TODO: try this function*/ /*Try function for get weight from closest face*/ - else if(ED_vgroup_copy_by_nearest_vertex_in_face_single(obslc, obact)) change++; + else if(ED_vgroup_copy_by_nearest_face_single(obslc, obact)) change++; /*Trigger error message*/ else fail++; /*Event notifiers for correct display of data*/ From 55e627d01eb8f2eeea190f53ce4a014052ed0cf2 Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Sun, 13 May 2012 05:57:32 +0000 Subject: [PATCH 025/347] Removed sqr_dist_v3v3() Now using existing: len_squared_v3v3() --- source/blender/editors/object/object_vgroup.c | 26 ++++++------------- 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index f40bdde8aa2..a81fb87e9b1 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -491,16 +491,6 @@ int ED_vgroup_copy_by_nearest_vertex_single(Object *ob_dst, Object *ob_src) return 1; } -/*Return the squared distance between two points in 3d space*/ -float sqr_dist_v3v3(float v1[3], float v2[3]) -{ - float d[3]; - d[0]= v2[0]-v1[0]; - d[1]= v2[1]-v1[1]; - d[2]= v2[2]-v1[2]; - return dot_v3v3(d, d); -} - /*Copy a single vertex group from source to destination with weights by nearest weight in face*/ int ED_vgroup_copy_by_nearest_vertex_in_face_single(Object *ob_dst, Object *ob_src) { @@ -567,9 +557,9 @@ int ED_vgroup_copy_by_nearest_vertex_in_face_single(Object *ob_dst, Object *ob_s BLI_bvhtree_find_nearest(tree_mesh_faces_src.tree, tmp_co, &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src); /*get distances*/ - dist_v1= sqr_dist_v3v3(tmp_co, mv_src[mface_src[nearest.index].v1].co); - dist_v2= sqr_dist_v3v3(tmp_co, mv_src[mface_src[nearest.index].v2].co); - dist_v3= sqr_dist_v3v3(tmp_co, mv_src[mface_src[nearest.index].v3].co); + dist_v1= len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v1].co); + dist_v2= len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v2].co); + dist_v3= len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v3].co); /*get weight from triangle*/ if(dist_v1weight; @@ -684,7 +674,7 @@ int ED_vgroup_copy_by_nearest_face_single(Object *ob_dst, Object *ob_src) /*check for quad*/ if(mface_src[nearest.index].v4){ - distribution_v4= sqr_dist_v3v3(tmp_co, mv_src[mface_src->v4].co); + distribution_v4= len_squared_v3v3(tmp_co, mv_src[mface_src->v4].co); if(distribution_v4 == 0) weight= defvert_verify_index(dv_array_src[mface_src[nearest.index].v4], index_src)->weight; else{ distribution_v4= 1/distribution_v4; From 9331b5e92fc847841b04d8303132ac5779d9860c Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Sun, 13 May 2012 08:16:41 +0000 Subject: [PATCH 026/347] Projection onto face added for: ED_vgroup_copy_by_nearest_face_single() --- source/blender/editors/object/object_vgroup.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index a81fb87e9b1..392f56a6c5f 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -603,7 +603,7 @@ int ED_vgroup_copy_by_nearest_face_single(Object *ob_dst, Object *ob_src) BVHTreeNearest nearest; MDeformWeight *dw_dst, *dw_src; int dv_tot_src, dv_tot_dst, i, index_dst, index_src; - float weight, tot_distribution, distribution_v1, distribution_v2, distribution_v3, distribution_v4, tmp_co[3]; + float weight, tot_distribution, distribution_v1, distribution_v2, distribution_v3, distribution_v4, tmp_co[3], tmp_co_v4[3], normal[3]; /*get source deform group*/ dg_src= BLI_findlink(&ob_src->defbase, (ob_src->actdef-1)); @@ -651,8 +651,9 @@ int ED_vgroup_copy_by_nearest_face_single(Object *ob_dst, Object *ob_src) /*node tree accelerated search for closest face*/ BLI_bvhtree_find_nearest(tree_mesh_faces_src.tree, tmp_co, &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src); - /*TODO: Have to project onto face to get a decent result*/ - /*Smart solution might be to just substract the distance difference to plane instead.*/ + /*project destination coordinate onto face*/ + normal_tri_v3(normal, mv_src[mface_src[nearest.index].v1].co, mv_src[mface_src[nearest.index].v2].co, mv_src[mface_src[nearest.index].v3].co); + project_v3_plane(tmp_co, normal, mv_src[mface_src[nearest.index].v1].co); /*get distances*/ distribution_v1= len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v1].co); @@ -674,7 +675,10 @@ int ED_vgroup_copy_by_nearest_face_single(Object *ob_dst, Object *ob_src) /*check for quad*/ if(mface_src[nearest.index].v4){ - distribution_v4= len_squared_v3v3(tmp_co, mv_src[mface_src->v4].co); + /*project vertex nr4 coordinate onto face and distribute*/ + copy_v3_v3(tmp_co_v4, mv_src[mface_src[nearest.index].v4].co); + project_v3_plane(tmp_co_v4, normal, mv_src[mface_src[nearest.index].v1].co); + distribution_v4= len_squared_v3v3(tmp_co, tmp_co_v4); if(distribution_v4 == 0) weight= defvert_verify_index(dv_array_src[mface_src[nearest.index].v4], index_src)->weight; else{ distribution_v4= 1/distribution_v4; @@ -702,12 +706,12 @@ int ED_vgroup_copy_by_nearest_face_single(Object *ob_dst, Object *ob_src) } } - /*snap to valid number*/ + /*snap to valid number, for testing. This should not be nessecary if interpolation works as its supposed to! or is my logick wrong???*//* weight*= 1000; weight+= 0.5; weight= (int)weight; weight/=1000; - if(weight>1)weight= 1; + if(weight>1)weight= 1;*/ /*copy weight*/ dw_dst= defvert_verify_index(*dv_array_dst, index_dst); From 9af6397b2d7043de46926e23376717232576041a Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Tue, 15 May 2012 02:47:23 +0000 Subject: [PATCH 027/347] Function for copying weights interpolated from faces complete! ED_vgroup_copy_by_nearest_face_single() --- source/blender/editors/object/object_vgroup.c | 88 ++++--------------- 1 file changed, 18 insertions(+), 70 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 855230c54f3..15b49feed0a 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -590,7 +590,6 @@ int ED_vgroup_copy_by_nearest_vertex_in_face_single(Object *ob_dst, Object *ob_s } /*Copy a single vertex group from source to destination with weights interpolated over nearest face*/ -/*TODO: transform into target space as in by_vertex function. postphoned due to easier testing during development*/ int ED_vgroup_copy_by_nearest_face_single(Object *ob_dst, Object *ob_src) { bDeformGroup *dg_src, *dg_dst; @@ -601,9 +600,9 @@ int ED_vgroup_copy_by_nearest_face_single(Object *ob_dst, Object *ob_src) MVert *mv_dst, *mv_src; MFace *mface_src; BVHTreeNearest nearest; - MDeformWeight *dw_dst, *dw_src; + MDeformWeight *dw_dst; int dv_tot_src, dv_tot_dst, i, index_dst, index_src; - float weight, tot_distribution, distribution_v1, distribution_v2, distribution_v3, distribution_v4, tmp_co[3], tmp_co_v4[3], normal[3]; + float weight, tmp_weight[4], tmp_co[3], normal[3], tmp_mat[4][4]; /*get source deform group*/ dg_src= BLI_findlink(&ob_src->defbase, (ob_src->actdef-1)); @@ -638,6 +637,10 @@ int ED_vgroup_copy_by_nearest_face_single(Object *ob_dst, Object *ob_src) /*get faces*/ mface_src= dmesh_src->getTessFaceArray(dmesh_src); + /*prepare transformation matrix*/ + invert_m4_m4(ob_src->imat, ob_src->obmat); + mult_m4_m4m4(tmp_mat, ob_src->imat, ob_dst->obmat); + /* loop through the vertices and copy weight from nearest weight*/ for(i=0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ @@ -645,80 +648,25 @@ int ED_vgroup_copy_by_nearest_face_single(Object *ob_dst, Object *ob_src) nearest.index= -1; nearest.dist= FLT_MAX; - /*set destination coordinate*/ - copy_v3_v3(tmp_co, mv_dst->co); - /*node tree accelerated search for closest face*/ BLI_bvhtree_find_nearest(tree_mesh_faces_src.tree, tmp_co, &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src); - /*project destination coordinate onto face*/ + /*transform into target space onto face*/ + mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); normal_tri_v3(normal, mv_src[mface_src[nearest.index].v1].co, mv_src[mface_src[nearest.index].v2].co, mv_src[mface_src[nearest.index].v3].co); project_v3_plane(tmp_co, normal, mv_src[mface_src[nearest.index].v1].co); - /*get distances*/ - distribution_v1= len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v1].co); - distribution_v2= len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v2].co); - distribution_v3= len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v3].co); + /*interpolate weights*/ + interp_weights_face_v3(tmp_weight, mv_src[mface_src[nearest.index].v1].co, + mv_src[mface_src[nearest.index].v2].co, + mv_src[mface_src[nearest.index].v3].co, + mv_src[mface_src[nearest.index].v4].co, tmp_co); - /*get weight from overlapping vert if any*/ - if(distribution_v1 == 0) weight= defvert_verify_index(dv_array_src[mface_src[nearest.index].v1], index_src)->weight; - if(distribution_v2 == 0) weight= defvert_verify_index(dv_array_src[mface_src[nearest.index].v2], index_src)->weight; - if(distribution_v3 == 0) weight= defvert_verify_index(dv_array_src[mface_src[nearest.index].v3], index_src)->weight; - else{ - /*invert distribution*/ - distribution_v1= 1/distribution_v1; - distribution_v2= 1/distribution_v2; - distribution_v3= 1/distribution_v3; - - /*set total distribution*/ - tot_distribution= distribution_v1 + distribution_v2 + distribution_v3; - - /*check for quad*/ - if(mface_src[nearest.index].v4){ - /*project vertex nr4 coordinate onto face and distribute*/ - copy_v3_v3(tmp_co_v4, mv_src[mface_src[nearest.index].v4].co); - project_v3_plane(tmp_co_v4, normal, mv_src[mface_src[nearest.index].v1].co); - distribution_v4= len_squared_v3v3(tmp_co, tmp_co_v4); - if(distribution_v4 == 0) weight= defvert_verify_index(dv_array_src[mface_src[nearest.index].v4], index_src)->weight; - else{ - distribution_v4= 1/distribution_v4; - tot_distribution+= distribution_v4; - - /*get weight from quad*/ - dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v1], index_src); - weight= dw_src->weight * distribution_v1 / tot_distribution; - dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v2], index_src); - weight+= dw_src->weight * distribution_v2 / tot_distribution; - dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v3], index_src); - weight+= dw_src->weight * distribution_v3 / tot_distribution; - dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v4], index_src); - weight+= dw_src->weight * distribution_v4 / tot_distribution; - } - } - else{ - /*get weight from triangle*/ - dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v1], index_src); - weight= dw_src->weight * distribution_v1 / tot_distribution; - dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v2], index_src); - weight+= dw_src->weight * distribution_v2 / tot_distribution; - dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v3], index_src); - weight+= dw_src->weight * distribution_v3 / tot_distribution; - } - } - - /*dist_to_line_segment_v3()*/ - /*There is probably something fundamentaly wrong about the interpolation. - When a vertex is on an edge, it should get no weight from the vertex not connected to the edge... - Projected onto edge it should get linar interpolation from two vertices. - so it should get the interpolated weight from the third vertex based on the inverted distance from edge along normal to edge! - if I got this right! :P - */ - /*snap to valid number, for testing. This should not be nessecary if interpolation works as its supposed to! or is my logick wrong???*//* - weight*= 1000; - weight+= 0.5; - weight= (int)weight; - weight/=1000; - if(weight>1)weight= 1;*/ + /*get weights*/ + weight= tmp_weight[0] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v1], index_src)->weight; + weight+= tmp_weight[1] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v2], index_src)->weight; + weight+= tmp_weight[2] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v3], index_src)->weight; + weight+= tmp_weight[3] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v4], index_src)->weight; /*copy weight*/ dw_dst= defvert_verify_index(*dv_array_dst, index_dst); From f386587e27b53599b25011f6398edb56ba8b4131 Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Wed, 16 May 2012 05:16:34 +0000 Subject: [PATCH 028/347] Bugfix --- source/blender/editors/object/object_vgroup.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 15b49feed0a..de1161a771e 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -648,12 +648,14 @@ int ED_vgroup_copy_by_nearest_face_single(Object *ob_dst, Object *ob_src) nearest.index= -1; nearest.dist= FLT_MAX; + /*transform into target space*/ + mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); + normal_tri_v3(normal, mv_src[mface_src[nearest.index].v1].co, mv_src[mface_src[nearest.index].v2].co, mv_src[mface_src[nearest.index].v3].co); + /*node tree accelerated search for closest face*/ BLI_bvhtree_find_nearest(tree_mesh_faces_src.tree, tmp_co, &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src); - /*transform into target space onto face*/ - mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); - normal_tri_v3(normal, mv_src[mface_src[nearest.index].v1].co, mv_src[mface_src[nearest.index].v2].co, mv_src[mface_src[nearest.index].v3].co); + /*project onto face*/ project_v3_plane(tmp_co, normal, mv_src[mface_src[nearest.index].v1].co); /*interpolate weights*/ From 0978d1eb9df6cb27bc98627e9688c3eeac5508a5 Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Thu, 17 May 2012 01:42:06 +0000 Subject: [PATCH 029/347] Added framework for transfer weight options. vertex_group_transfer_weight_exec() governs all. Functions renamed/added with _transfer_weight_ as opposed to _copy_by_ This is to reflect changes in parameters and usage as the internal code will change. --- .../startup/bl_ui/space_view3d_toolbar.py | 3 +- source/blender/editors/object/object_intern.h | 1 + source/blender/editors/object/object_ops.c | 1 + source/blender/editors/object/object_vgroup.c | 208 ++++++++++++++++-- 4 files changed, 198 insertions(+), 15 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py index 729380a0433..50f26c33e15 100644 --- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py +++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py @@ -986,8 +986,7 @@ class VIEW3D_PT_tools_weightpaint(View3DPanel, Panel): col = layout.column() col.active = ob.vertex_groups.active is not None - col.operator("object.vertex_group_copy_to_selected", text="Transfer weight All") - col.operator("object.vertex_group_copy_to_selected_single", text="Transfer weight") + col.operator("object.vertex_group_transfer_weight", text="Transfer weight") col.operator("object.vertex_group_normalize_all", text="Normalize All") col.operator("object.vertex_group_normalize", text="Normalize") col.operator("object.vertex_group_mirror", text="Mirror") diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index e29ab687fff..5269caab426 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -196,6 +196,7 @@ void OBJECT_OT_vertex_group_remove_from(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_select(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_deselect(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_copy_to_linked(struct wmOperatorType *ot); +void OBJECT_OT_vertex_group_transfer_weight(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_copy_to_selected(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_copy_to_selected_single(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_copy(struct wmOperatorType *ot); diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index 9f5ae7e255f..7e535eed29d 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -170,6 +170,7 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_vertex_group_select); WM_operatortype_append(OBJECT_OT_vertex_group_deselect); WM_operatortype_append(OBJECT_OT_vertex_group_copy_to_linked); + WM_operatortype_append(OBJECT_OT_vertex_group_transfer_weight); WM_operatortype_append(OBJECT_OT_vertex_group_copy_to_selected); WM_operatortype_append(OBJECT_OT_vertex_group_copy_to_selected_single); WM_operatortype_append(OBJECT_OT_vertex_group_copy); diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index de1161a771e..7cbf0e2145c 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -420,8 +420,57 @@ int ED_vgroup_copy_single(Object *ob_dst, const Object *ob_src) return 1; } -/*Copy a single vertex group from source to destination with weights by nearest weight*/ -int ED_vgroup_copy_by_nearest_vertex_single(Object *ob_dst, Object *ob_src) +/********************** Start transfer weight functions *********************/ + +int ED_vgroup_transfer_weight_by_index_all(Object *ob_dst, Object *ob_src, short mode) +{ + /* mode 1 == replace all weights*/ + if(mode == 1){ + return ED_vgroup_copy_array(ob_dst, ob_src); + } + + /* mode 2 == apply to null/0 weights*/ + else if(mode == 2){ + return 0; + } + + /* mode 3 == apply to selected weights*/ + else if(mode == 3){ + return 0; + } + else return 0; +} + +int ED_vgroup_transfer_weight_by_index_single(Object *ob_dst, Object *ob_src, short mode) +{ + /* mode 1 == replace all weights*/ + if(mode == 1){ + return ED_vgroup_copy_single(ob_dst, ob_src); + } + + /* mode 2 == apply to null/0 weights*/ + else if(mode == 2){ + return 0; + } + + /* mode 3 == apply to selected weights*/ + else if(mode == 3){ + return 0; + } + else return 0; +} + +int ED_vgroup_transfer_weight_by_nearest_vertex_all(Object *ob_dst, Object *ob_src, short mode) +{ + ob_dst= ob_dst; + ob_src= ob_src; + /* mode 1 == replace all weights*/ + /* mode 2 == apply to null/0 weights*/ + /* mode 3 == apply to selected weights*/ + return mode; +} + +int ED_vgroup_transfer_weight_by_nearest_vertex_single(Object *ob_dst, Object *ob_src, short mode) { bDeformGroup *dg_src, *dg_dst; MDeformVert **dv_array_src, **dv_array_dst; @@ -434,6 +483,11 @@ int ED_vgroup_copy_by_nearest_vertex_single(Object *ob_dst, Object *ob_src) int dv_tot_src, dv_tot_dst, i, index_dst, index_src; float tmp_co[3], tmp_mat[4][4]; + /* mode 1 == replace all weights*/ + /* mode 2 == apply to null/0 weights*/ + /* mode 3 == apply to selected weights*/ + return mode; + /*get source deform group*/ dg_src= BLI_findlink(&ob_src->defbase, (ob_src->actdef-1)); @@ -491,8 +545,17 @@ int ED_vgroup_copy_by_nearest_vertex_single(Object *ob_dst, Object *ob_src) return 1; } -/*Copy a single vertex group from source to destination with weights by nearest weight in face*/ -int ED_vgroup_copy_by_nearest_vertex_in_face_single(Object *ob_dst, Object *ob_src) +int ED_vgroup_transfer_weight_by_nearest_vertex_in_face_all(Object *ob_dst, Object *ob_src, short mode) +{ + ob_dst= ob_dst; + ob_src= ob_src; + /* mode 1 == replace all weights*/ + /* mode 2 == apply to null/0 weights*/ + /* mode 3 == apply to selected weights*/ + return mode; +} + +int ED_vgroup_transfer_weight_by_nearest_vertex_in_face_single(Object *ob_dst, Object *ob_src, short mode) { bDeformGroup *dg_src, *dg_dst; Mesh *me_dst; @@ -506,6 +569,11 @@ int ED_vgroup_copy_by_nearest_vertex_in_face_single(Object *ob_dst, Object *ob_s int dv_tot_src, dv_tot_dst, i, index_dst, index_src; float dist_v1, dist_v2, dist_v3, dist_v4, tmp_co[3], tmp_mat[4][4]; + /* mode 1 == replace all weights*/ + /* mode 2 == apply to null/0 weights*/ + /* mode 3 == apply to selected weights*/ + return mode; + /*get source deform group*/ dg_src= BLI_findlink(&ob_src->defbase, (ob_src->actdef-1)); @@ -589,8 +657,17 @@ int ED_vgroup_copy_by_nearest_vertex_in_face_single(Object *ob_dst, Object *ob_s return 1; } -/*Copy a single vertex group from source to destination with weights interpolated over nearest face*/ -int ED_vgroup_copy_by_nearest_face_single(Object *ob_dst, Object *ob_src) +int ED_vgroup_transfer_weight_by_nearest_face_all(Object *ob_dst, Object *ob_src, short mode) +{ + ob_dst= ob_dst; + ob_src= ob_src; + /* mode 1 == replace all weights*/ + /* mode 2 == apply to null/0 weights*/ + /* mode 3 == apply to selected weights*/ + return mode; +} + +int ED_vgroup_transfer_weight_by_nearest_face_single(Object *ob_dst, Object *ob_src, short mode) { bDeformGroup *dg_src, *dg_dst; Mesh *me_dst; @@ -604,6 +681,11 @@ int ED_vgroup_copy_by_nearest_face_single(Object *ob_dst, Object *ob_src) int dv_tot_src, dv_tot_dst, i, index_dst, index_src; float weight, tmp_weight[4], tmp_co[3], normal[3], tmp_mat[4][4]; + /* mode 1 == replace all weights*/ + /* mode 2 == apply to null/0 weights*/ + /* mode 3 == apply to selected weights*/ + return mode; + /*get source deform group*/ dg_src= BLI_findlink(&ob_src->defbase, (ob_src->actdef-1)); @@ -680,6 +762,7 @@ int ED_vgroup_copy_by_nearest_face_single(Object *ob_dst, Object *ob_src) return 1; } +/********************** End transfer weight functions *********************/ /* for Mesh in Object mode */ /* allows editmode for Lattice */ @@ -3048,7 +3131,6 @@ static int vertex_group_copy_to_selected_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } - void OBJECT_OT_vertex_group_copy_to_selected(wmOperatorType *ot) { /* identifiers */ @@ -3074,12 +3156,8 @@ static int vertex_group_copy_to_selected_single_exec(bContext *C, wmOperator *op CTX_DATA_BEGIN(C, Object*, obslc, selected_editable_objects) { if(obact != obslc) { - /*Try function for matching number of vertices*/ + /*Try function for matching indices*/ if(ED_vgroup_copy_single(obslc, obact)) change++; - /*Try function for get weight from closest vertex*/ - /*TODO: try this function*/ - /*Try function for get weight from closest face*/ - else if(ED_vgroup_copy_by_nearest_face_single(obslc, obact)) change++; /*Trigger error message*/ else fail++; /*Event notifiers for correct display of data*/ @@ -3093,7 +3171,7 @@ static int vertex_group_copy_to_selected_single_exec(bContext *C, wmOperator *op /*Report error when task can not be completed with available functions.*/ if((change == 0 && fail == 0) || fail) { BKE_reportf(op->reports, RPT_ERROR, - "Copy to VGroups to Selected warning done %d, failed %d, All functions failed!", + "Copy to VGroups to Selected single warning done %d, failed %d, object data must have matching indices", change, fail); } @@ -3116,6 +3194,110 @@ void OBJECT_OT_vertex_group_copy_to_selected_single(wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } +static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) +{ + Object *obact= CTX_data_active_object(C); + int change= 0; + int fail= 0; + + /*TODO: get this parameter*/ + short option= 2; + /* option 1 == single*/ + /* option 2 == all*/ + + /*TODO: get this parameter*/ + short method= 1; + /*method 1 == by matching indices*/ + /*method 2 == by nearest vertex*/ + /*method 3 == by nearest vertex in face*/ + /*method 4 == by nearest face*/ + + /*TODO: get this parameter*/ + short mode= 1; + /* mode is passed on to lower funtions*/ + + /*Macro to loop through selected objects and perform operation*/ + CTX_DATA_BEGIN(C, Object*, obslc, selected_editable_objects) + { + /*check if object is the same*/ + if(obact != obslc) { + /*apply option*/ + if(option == 1){ + /*apply method*/ + if(method == 1){ + /*Try function with mode*/ + if(ED_vgroup_transfer_weight_by_index_single(obslc, obact, mode)) change++; /*(tmp dev info remove) tested and working*/ + else fail++; + } + else if(method == 2){ + if(ED_vgroup_transfer_weight_by_nearest_vertex_single(obslc, obact, mode)) change++; + else fail++; + } + else if(method == 3){ + if(ED_vgroup_transfer_weight_by_nearest_vertex_in_face_single(obslc, obact, mode)) change++; + else fail++; + } + else if(method == 4){ + if(ED_vgroup_transfer_weight_by_nearest_face_single(obslc, obact, mode)) change++; + else fail++; + } + else fail++; + } + else if(option == 2){ + if(method == 1){ + if(ED_vgroup_transfer_weight_by_index_all(obslc, obact, mode)) change++; /*(tmp dev info remove) tested and working*/ + else fail++; + } + else if(method == 2){ + if(ED_vgroup_transfer_weight_by_nearest_vertex_all(obslc, obact, mode)) change++; + else fail++; + } + else if(method == 3){ + if(ED_vgroup_transfer_weight_by_nearest_vertex_in_face_all(obslc, obact, mode)) change++; + else fail++; + } + else if(method == 4){ + if(ED_vgroup_transfer_weight_by_nearest_face_all(obslc, obact, mode)) change++; + else fail++; /*Trigger error message on function failed, includes unknown mode)*/ + } + else fail++; /*Trigger error message on unknown method*/ + } + else fail++; /*Trigger error message on unknown option*/ + + /*Event notifiers for correct display of data*/ + DAG_id_tag_update(&obslc->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, obslc); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obslc->data); + } + } + CTX_DATA_END; + + /*Report error when task can not be completed with available functions.*/ + if((change == 0 && fail == 0) || fail) { + BKE_reportf(op->reports, RPT_ERROR, + "Copy to VGroups to Selected warning done %d, failed %d, unknown option/method or All functions failed!", + change, fail); + } + + return OPERATOR_FINISHED; +} + +/*transfers weight from active to selected*/ +void OBJECT_OT_vertex_group_transfer_weight(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Transfer weight to selected"; + ot->idname= "OBJECT_OT_vertex_group_transfer_weight"; + ot->description= "Transfers weight from active to selected depending on options"; + + /* api callbacks */ + ot->poll= vertex_group_poll; + ot->exec= vertex_group_transfer_weight_exec; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + static EnumPropertyItem vgroup_items[] = { {0, NULL, 0, NULL, NULL} }; From 506057c83b2925bd17477a12a5e3fc26a3a9cd6a Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Thu, 17 May 2012 03:15:39 +0000 Subject: [PATCH 030/347] Fixed readabillity of options framework by adding enums. --- source/blender/editors/object/object_vgroup.c | 90 ++++++++++--------- 1 file changed, 47 insertions(+), 43 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 7cbf0e2145c..c1338ceabe5 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -3201,68 +3201,72 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) int fail= 0; /*TODO: get this parameter*/ - short option= 2; - /* option 1 == single*/ - /* option 2 == all*/ + enum option {single =1, all =2}; + enum option option_choise= 1; /*TODO: get this parameter*/ - short method= 1; - /*method 1 == by matching indices*/ - /*method 2 == by nearest vertex*/ - /*method 3 == by nearest vertex in face*/ - /*method 4 == by nearest face*/ + enum method {by_index = 1, by_nearest_vertex = 2, by_nearest_vertex_in_face = 3, by_nearest_face = 4}; + enum method method_choise= 1; /*TODO: get this parameter*/ short mode= 1; /* mode is passed on to lower funtions*/ - /*Macro to loop through selected objects and perform operation*/ + /*Macro to loop through selected objects and perform operation depending on option and method*/ CTX_DATA_BEGIN(C, Object*, obslc, selected_editable_objects) { - /*check if object is the same*/ if(obact != obslc) { - /*apply option*/ - if(option == 1){ - /*apply method*/ - if(method == 1){ - /*Try function with mode*/ - if(ED_vgroup_transfer_weight_by_index_single(obslc, obact, mode)) change++; /*(tmp dev info remove) tested and working*/ + switch(option_choise){ + + /*single*/ + case(single): + switch(method_choise){ + + case(by_index): + if(ED_vgroup_transfer_weight_by_index_single(obslc, obact, mode)) change++; else fail++; - } - else if(method == 2){ + break; + + case(by_nearest_vertex): if(ED_vgroup_transfer_weight_by_nearest_vertex_single(obslc, obact, mode)) change++; else fail++; - } - else if(method == 3){ + break; + + case(by_nearest_vertex_in_face): if(ED_vgroup_transfer_weight_by_nearest_vertex_in_face_single(obslc, obact, mode)) change++; else fail++; - } - else if(method == 4){ + break; + + case(by_nearest_face): if(ED_vgroup_transfer_weight_by_nearest_face_single(obslc, obact, mode)) change++; else fail++; + break; + } + + /*all*/ + case(all): + switch(method_choise){ + case(by_index): + if(ED_vgroup_transfer_weight_by_index_all(obslc, obact, mode)) change++; + else fail++; + break; + + case(by_nearest_vertex): + if(ED_vgroup_transfer_weight_by_nearest_vertex_single(obslc, obact, mode)) change++; + else fail++; + break; + + case(by_nearest_vertex_in_face): + if(ED_vgroup_transfer_weight_by_nearest_vertex_in_face_single(obslc, obact, mode)) change++; + else fail++; + break; + + case(by_nearest_face): + if(ED_vgroup_transfer_weight_by_nearest_face_single(obslc, obact, mode)) change++; + else fail++; + break; } - else fail++; } - else if(option == 2){ - if(method == 1){ - if(ED_vgroup_transfer_weight_by_index_all(obslc, obact, mode)) change++; /*(tmp dev info remove) tested and working*/ - else fail++; - } - else if(method == 2){ - if(ED_vgroup_transfer_weight_by_nearest_vertex_all(obslc, obact, mode)) change++; - else fail++; - } - else if(method == 3){ - if(ED_vgroup_transfer_weight_by_nearest_vertex_in_face_all(obslc, obact, mode)) change++; - else fail++; - } - else if(method == 4){ - if(ED_vgroup_transfer_weight_by_nearest_face_all(obslc, obact, mode)) change++; - else fail++; /*Trigger error message on function failed, includes unknown mode)*/ - } - else fail++; /*Trigger error message on unknown method*/ - } - else fail++; /*Trigger error message on unknown option*/ /*Event notifiers for correct display of data*/ DAG_id_tag_update(&obslc->id, OB_RECALC_DATA); From e7970575efe4a9efbf83917d85bb60db7364ee9f Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Thu, 17 May 2012 03:18:47 +0000 Subject: [PATCH 031/347] bugfix (using _all not _single as postfix for functions); --- source/blender/editors/object/object_vgroup.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index c1338ceabe5..0c53399c532 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -3252,17 +3252,17 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) break; case(by_nearest_vertex): - if(ED_vgroup_transfer_weight_by_nearest_vertex_single(obslc, obact, mode)) change++; + if(ED_vgroup_transfer_weight_by_nearest_vertex_all(obslc, obact, mode)) change++; else fail++; break; case(by_nearest_vertex_in_face): - if(ED_vgroup_transfer_weight_by_nearest_vertex_in_face_single(obslc, obact, mode)) change++; + if(ED_vgroup_transfer_weight_by_nearest_vertex_in_face_all(obslc, obact, mode)) change++; else fail++; break; case(by_nearest_face): - if(ED_vgroup_transfer_weight_by_nearest_face_single(obslc, obact, mode)) change++; + if(ED_vgroup_transfer_weight_by_nearest_face_all(obslc, obact, mode)) change++; else fail++; break; } From daa4b41fb2fd3f154e4f582fbab1f8c2179cafa1 Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Thu, 17 May 2012 08:10:19 +0000 Subject: [PATCH 032/347] Fucntions adjusted to support options. (still lacking feature for selected and option for all) --- source/blender/editors/object/object_vgroup.c | 554 ++++++++++++------ 1 file changed, 390 insertions(+), 164 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 0c53399c532..1c30c0b2510 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -424,17 +424,17 @@ int ED_vgroup_copy_single(Object *ob_dst, const Object *ob_src) int ED_vgroup_transfer_weight_by_index_all(Object *ob_dst, Object *ob_src, short mode) { - /* mode 1 == replace all weights*/ + if(mode == 1){ return ED_vgroup_copy_array(ob_dst, ob_src); } - /* mode 2 == apply to null/0 weights*/ + else if(mode == 2){ return 0; } - /* mode 3 == apply to selected weights*/ + else if(mode == 3){ return 0; } @@ -443,19 +443,72 @@ int ED_vgroup_transfer_weight_by_index_all(Object *ob_dst, Object *ob_src, short int ED_vgroup_transfer_weight_by_index_single(Object *ob_dst, Object *ob_src, short mode) { + MDeformVert **dv_array_src; + MDeformVert **dv_array_dst; + MDeformWeight *dw_dst, *dw_src; + int dv_tot_src, dv_tot_dst; + int i, index_src, index_dst; + bDeformGroup *dg_src, *dg_dst; + + /*get source deform group*/ + dg_src= BLI_findlink(&ob_src->defbase, (ob_src->actdef-1)); + + /*create new and overwrite vertex group on destination without data*/ + if(!defgroup_find_name(ob_dst, dg_src->name) || mode == 1){ + ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_src->name)); + ED_vgroup_add_name(ob_dst, dg_src->name); + } + + /*get destination deformgroup*/ + dg_dst= defgroup_find_name(ob_dst, dg_src->name); + + /*get vertex group arrays*/ + ED_vgroup_give_parray(ob_src->data, &dv_array_src, &dv_tot_src, FALSE); + ED_vgroup_give_parray(ob_dst->data, &dv_array_dst, &dv_tot_dst, FALSE); + + /*get indexes of vertex groups*/ + index_src= BLI_findindex(&ob_src->defbase, dg_src); + index_dst= BLI_findindex(&ob_dst->defbase, dg_dst); + + /*check if indices are matching, delete and return if not*/ + if (ob_dst == ob_src || dv_tot_dst == 0 || (dv_tot_dst != dv_tot_src) || dv_array_src == NULL || dv_array_dst == NULL) { + ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_dst->name)); + return 0; + } + /* mode 1 == replace all weights*/ if(mode == 1){ - return ED_vgroup_copy_single(ob_dst, ob_src); + /* loop through the vertices and copy weight*/ + for(i=0; iweight= dw_src->weight; + } + return 1; } - /* mode 2 == apply to null/0 weights*/ + /* mode 2 == replace null weights*/ else if(mode == 2){ - return 0; + /* loop through the vertices and copy weight*/ + for(i=0; iweight || dw_dst->weight == 0) dw_dst->weight= dw_src->weight; + } + return 1; } - /* mode 3 == apply to selected weights*/ + /* mode 3 == replace selected weights*/ else if(mode == 3){ - return 0; + /* loop through the vertices and copy weight*/ + for(i=0; iflag == 1) dw_dst->weight= dw_src->weight; /*this does not work*/ + } + return 1; } else return 0; } @@ -464,9 +517,6 @@ int ED_vgroup_transfer_weight_by_nearest_vertex_all(Object *ob_dst, Object *ob_s { ob_dst= ob_dst; ob_src= ob_src; - /* mode 1 == replace all weights*/ - /* mode 2 == apply to null/0 weights*/ - /* mode 3 == apply to selected weights*/ return mode; } @@ -483,17 +533,14 @@ int ED_vgroup_transfer_weight_by_nearest_vertex_single(Object *ob_dst, Object *o int dv_tot_src, dv_tot_dst, i, index_dst, index_src; float tmp_co[3], tmp_mat[4][4]; - /* mode 1 == replace all weights*/ - /* mode 2 == apply to null/0 weights*/ - /* mode 3 == apply to selected weights*/ - return mode; - /*get source deform group*/ dg_src= BLI_findlink(&ob_src->defbase, (ob_src->actdef-1)); /*create new and overwrite vertex group on destination without data*/ - ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_src->name)); - ED_vgroup_add_name(ob_dst, dg_src->name); + if(!defgroup_find_name(ob_dst, dg_src->name) || mode == 1){ + ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_src->name)); + ED_vgroup_add_name(ob_dst, dg_src->name); + } /*get destination deformgroup*/ dg_dst= defgroup_find_name(ob_dst, dg_src->name); @@ -521,37 +568,74 @@ int ED_vgroup_transfer_weight_by_nearest_vertex_single(Object *ob_dst, Object *o invert_m4_m4(ob_src->imat, ob_src->obmat); mult_m4_m4m4(tmp_mat, ob_src->imat, ob_dst->obmat); - /* loop through the vertices and copy weight from nearest weight*/ - for(i=0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ - - /*reset nearest*/ - nearest.index= -1; - nearest.dist= FLT_MAX; - - /*transform into target space*/ - mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); - - /*node tree accelerated search for closest vetex*/ - BLI_bvhtree_find_nearest(tree_mesh_src.tree, tmp_co, &nearest, tree_mesh_src.nearest_callback, &tree_mesh_src); - - /*copy weight*/ - dw_src= defvert_verify_index(dv_array_src[nearest.index], index_src); - dw_dst= defvert_verify_index(*dv_array_dst, index_dst); - dw_dst->weight= dw_src->weight; + /* mode 1 == replace all weights*/ + if(mode == 1){ + /* loop through the vertices and copy weight*/ + for(i=0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ + /*reset nearest*/ + nearest.index= -1; + nearest.dist= FLT_MAX; + /*transform into target space*/ + mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); + /*node tree accelerated search for closest vetex*/ + BLI_bvhtree_find_nearest(tree_mesh_src.tree, tmp_co, &nearest, tree_mesh_src.nearest_callback, &tree_mesh_src); + dw_src= defvert_verify_index(dv_array_src[nearest.index], index_src); + dw_dst= defvert_verify_index(*dv_array_dst, index_dst); + dw_dst->weight= dw_src->weight; + } + /*free memory and return*/ + free_bvhtree_from_mesh(&tree_mesh_src); + return 1; } - /*free memory and return*/ - free_bvhtree_from_mesh(&tree_mesh_src); - return 1; + /* mode 2 == replace null weights*/ + else if(mode == 2){ + /* loop through the vertices and copy weight weight*/ + for(i=0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ + /*reset nearest*/ + nearest.index= -1; + nearest.dist= FLT_MAX; + /*transform into target space*/ + mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); + /*node tree accelerated search for closest vetex*/ + BLI_bvhtree_find_nearest(tree_mesh_src.tree, tmp_co, &nearest, tree_mesh_src.nearest_callback, &tree_mesh_src); + dw_src= defvert_verify_index(dv_array_src[nearest.index], index_src); + dw_dst= defvert_verify_index(*dv_array_dst, index_dst); + /*check if destination weight is null or zero*/ + if(!dw_dst->weight || dw_dst->weight == 0) dw_dst->weight= dw_src->weight; + } + /*free memory and return*/ + free_bvhtree_from_mesh(&tree_mesh_src); + return 1; + } + + /* mode 3 == replace selected weights*/ + else if(mode == 3){ + /* loop through the vertices and copy weight*/ + for(i=0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ + /*reset nearest*/ + nearest.index= -1; + nearest.dist= FLT_MAX; + /*transform into target space*/ + mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); + /*node tree accelerated search for closest vetex*/ + BLI_bvhtree_find_nearest(tree_mesh_src.tree, tmp_co, &nearest, tree_mesh_src.nearest_callback, &tree_mesh_src); + dw_src= defvert_verify_index(dv_array_src[nearest.index], index_src); + dw_dst= defvert_verify_index(*dv_array_dst, index_dst); + /*dw_dst->weight= dw_src->weight;*//*TODO fix this*/ + } + + /*free memory and return*/ + free_bvhtree_from_mesh(&tree_mesh_src); + return 1; + } + else return 0; } int ED_vgroup_transfer_weight_by_nearest_vertex_in_face_all(Object *ob_dst, Object *ob_src, short mode) { ob_dst= ob_dst; ob_src= ob_src; - /* mode 1 == replace all weights*/ - /* mode 2 == apply to null/0 weights*/ - /* mode 3 == apply to selected weights*/ return mode; } @@ -569,17 +653,14 @@ int ED_vgroup_transfer_weight_by_nearest_vertex_in_face_single(Object *ob_dst, O int dv_tot_src, dv_tot_dst, i, index_dst, index_src; float dist_v1, dist_v2, dist_v3, dist_v4, tmp_co[3], tmp_mat[4][4]; - /* mode 1 == replace all weights*/ - /* mode 2 == apply to null/0 weights*/ - /* mode 3 == apply to selected weights*/ - return mode; - /*get source deform group*/ dg_src= BLI_findlink(&ob_src->defbase, (ob_src->actdef-1)); /*create new and overwrite vertex group on destination without data*/ - ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_src->name)); - ED_vgroup_add_name(ob_dst, dg_src->name); + if(!defgroup_find_name(ob_dst, dg_src->name) || mode == 1){ + ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_src->name)); + ED_vgroup_add_name(ob_dst, dg_src->name); + } /*get destination deformgroup*/ dg_dst= defgroup_find_name(ob_dst, dg_src->name); @@ -611,59 +692,136 @@ int ED_vgroup_transfer_weight_by_nearest_vertex_in_face_single(Object *ob_dst, O invert_m4_m4(ob_src->imat, ob_src->obmat); mult_m4_m4m4(tmp_mat, ob_src->imat, ob_dst->obmat); - /* loop through the vertices and copy weight from nearest weight*/ - for(i=0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ - - /*reset nearest*/ - nearest.index= -1; - nearest.dist= FLT_MAX; - - /*transform into target space*/ - mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); - - /*node tree accelerated search for closest face*/ - BLI_bvhtree_find_nearest(tree_mesh_faces_src.tree, tmp_co, &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src); - - /*get distances*/ - dist_v1= len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v1].co); - dist_v2= len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v2].co); - dist_v3= len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v3].co); - - /*get weight from triangle*/ - if(dist_v1totvert; i++, mv_dst++, dv_array_dst++){ + /*reset nearest*/ + nearest.index= -1; + nearest.dist= FLT_MAX; + /*transform into target space*/ + mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); + /*node tree accelerated search for closest face*/ + BLI_bvhtree_find_nearest(tree_mesh_faces_src.tree, tmp_co, &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src); + /*get distances*/ + dist_v1= len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v1].co); + dist_v2= len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v2].co); + dist_v3= len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v3].co); + /*get weight from triangle*/ + if(dist_v1weight= dw_src->weight; } - - /*copy weight*/ - dw_dst= defvert_verify_index(*dv_array_dst, index_dst); - dw_dst->weight= dw_src->weight; + /*free memory and return*/ + free_bvhtree_from_mesh(&tree_mesh_faces_src); + return 1; } - /*free memory and return*/ - free_bvhtree_from_mesh(&tree_mesh_faces_src); - return 1; + /* mode 2 == replace null weights*/ + else if(mode == 2){ + /* loop through the vertices and copy weight from nearest weight*/ + for(i=0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ + /*reset nearest*/ + nearest.index= -1; + nearest.dist= FLT_MAX; + /*transform into target space*/ + mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); + /*node tree accelerated search for closest face*/ + BLI_bvhtree_find_nearest(tree_mesh_faces_src.tree, tmp_co, &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src); + /*get distances*/ + dist_v1= len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v1].co); + dist_v2= len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v2].co); + dist_v3= len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v3].co); + /*get weight from triangle*/ + if(dist_v1weight || dw_dst->weight == 0) dw_dst->weight= dw_src->weight; + } + /*free memory and return*/ + free_bvhtree_from_mesh(&tree_mesh_faces_src); + return 1; + } + + /* mode 3 == replace selected weights*/ + else if(mode == 3){ + /* loop through the vertices and copy weight from nearest weight*/ + for(i=0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ + /*reset nearest*/ + nearest.index= -1; + nearest.dist= FLT_MAX; + /*transform into target space*/ + mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); + /*node tree accelerated search for closest face*/ + BLI_bvhtree_find_nearest(tree_mesh_faces_src.tree, tmp_co, &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src); + /*get distances*/ + dist_v1= len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v1].co); + dist_v2= len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v2].co); + dist_v3= len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v3].co); + /*get weight from triangle*/ + if(dist_v1weight= dw_src->weight;*/ /*TODO: fix this!*/ + } + /*free memory and return*/ + free_bvhtree_from_mesh(&tree_mesh_faces_src); + return 1; + } + else return 0; } int ED_vgroup_transfer_weight_by_nearest_face_all(Object *ob_dst, Object *ob_src, short mode) { ob_dst= ob_dst; ob_src= ob_src; - /* mode 1 == replace all weights*/ - /* mode 2 == apply to null/0 weights*/ - /* mode 3 == apply to selected weights*/ return mode; } @@ -681,17 +839,14 @@ int ED_vgroup_transfer_weight_by_nearest_face_single(Object *ob_dst, Object *ob_ int dv_tot_src, dv_tot_dst, i, index_dst, index_src; float weight, tmp_weight[4], tmp_co[3], normal[3], tmp_mat[4][4]; - /* mode 1 == replace all weights*/ - /* mode 2 == apply to null/0 weights*/ - /* mode 3 == apply to selected weights*/ - return mode; - /*get source deform group*/ dg_src= BLI_findlink(&ob_src->defbase, (ob_src->actdef-1)); /*create new and overwrite vertex group on destination without data*/ - ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_src->name)); - ED_vgroup_add_name(ob_dst, dg_src->name); + if(!defgroup_find_name(ob_dst, dg_src->name) || mode == 1){ + ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_src->name)); + ED_vgroup_add_name(ob_dst, dg_src->name); + } /*get destination deformgroup*/ dg_dst= defgroup_find_name(ob_dst, dg_src->name); @@ -723,43 +878,106 @@ int ED_vgroup_transfer_weight_by_nearest_face_single(Object *ob_dst, Object *ob_ invert_m4_m4(ob_src->imat, ob_src->obmat); mult_m4_m4m4(tmp_mat, ob_src->imat, ob_dst->obmat); - /* loop through the vertices and copy weight from nearest weight*/ - for(i=0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ - - /*reset nearest*/ - nearest.index= -1; - nearest.dist= FLT_MAX; - - /*transform into target space*/ - mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); - normal_tri_v3(normal, mv_src[mface_src[nearest.index].v1].co, mv_src[mface_src[nearest.index].v2].co, mv_src[mface_src[nearest.index].v3].co); - - /*node tree accelerated search for closest face*/ - BLI_bvhtree_find_nearest(tree_mesh_faces_src.tree, tmp_co, &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src); - - /*project onto face*/ - project_v3_plane(tmp_co, normal, mv_src[mface_src[nearest.index].v1].co); - - /*interpolate weights*/ - interp_weights_face_v3(tmp_weight, mv_src[mface_src[nearest.index].v1].co, - mv_src[mface_src[nearest.index].v2].co, - mv_src[mface_src[nearest.index].v3].co, - mv_src[mface_src[nearest.index].v4].co, tmp_co); - - /*get weights*/ - weight= tmp_weight[0] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v1], index_src)->weight; - weight+= tmp_weight[1] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v2], index_src)->weight; - weight+= tmp_weight[2] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v3], index_src)->weight; - weight+= tmp_weight[3] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v4], index_src)->weight; - - /*copy weight*/ - dw_dst= defvert_verify_index(*dv_array_dst, index_dst); - dw_dst->weight= weight; + /* mode 1 == replace all weights*/ + if(mode == 1){ + /* loop through the vertices and copy weight from nearest weight*/ + for(i=0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ + /*reset nearest*/ + nearest.index= -1; + nearest.dist= FLT_MAX; + /*transform into target space*/ + mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); + normal_tri_v3(normal, mv_src[mface_src[nearest.index].v1].co, mv_src[mface_src[nearest.index].v2].co, mv_src[mface_src[nearest.index].v3].co); + /*node tree accelerated search for closest face*/ + BLI_bvhtree_find_nearest(tree_mesh_faces_src.tree, tmp_co, &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src); + /*project onto face*/ + project_v3_plane(tmp_co, normal, mv_src[mface_src[nearest.index].v1].co); + /*interpolate weights*/ + interp_weights_face_v3(tmp_weight, mv_src[mface_src[nearest.index].v1].co, + mv_src[mface_src[nearest.index].v2].co, + mv_src[mface_src[nearest.index].v3].co, + mv_src[mface_src[nearest.index].v4].co, tmp_co); + /*get weights*/ + weight= tmp_weight[0] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v1], index_src)->weight; + weight+= tmp_weight[1] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v2], index_src)->weight; + weight+= tmp_weight[2] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v3], index_src)->weight; + weight+= tmp_weight[3] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v4], index_src)->weight; + /*copy weight*/ + dw_dst= defvert_verify_index(*dv_array_dst, index_dst); + dw_dst->weight= weight; + } + /*free memory and return*/ + free_bvhtree_from_mesh(&tree_mesh_faces_src); + return 1; } - /*free memory and return*/ - free_bvhtree_from_mesh(&tree_mesh_faces_src); - return 1; + /* mode 2 == replace null weights*/ + else if(mode == 2){ + /* loop through the vertices and copy weight from nearest weight*/ + for(i=0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ + /*reset nearest*/ + nearest.index= -1; + nearest.dist= FLT_MAX; + /*transform into target space*/ + mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); + normal_tri_v3(normal, mv_src[mface_src[nearest.index].v1].co, mv_src[mface_src[nearest.index].v2].co, mv_src[mface_src[nearest.index].v3].co); + /*node tree accelerated search for closest face*/ + BLI_bvhtree_find_nearest(tree_mesh_faces_src.tree, tmp_co, &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src); + /*project onto face*/ + project_v3_plane(tmp_co, normal, mv_src[mface_src[nearest.index].v1].co); + /*interpolate weights*/ + interp_weights_face_v3(tmp_weight, mv_src[mface_src[nearest.index].v1].co, + mv_src[mface_src[nearest.index].v2].co, + mv_src[mface_src[nearest.index].v3].co, + mv_src[mface_src[nearest.index].v4].co, tmp_co); + /*get weights*/ + weight= tmp_weight[0] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v1], index_src)->weight; + weight+= tmp_weight[1] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v2], index_src)->weight; + weight+= tmp_weight[2] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v3], index_src)->weight; + weight+= tmp_weight[3] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v4], index_src)->weight; + /*copy weight*/ + dw_dst= defvert_verify_index(*dv_array_dst, index_dst); + /*check if destination weight is null or zero and copy weight*/ + if(!dw_dst->weight || dw_dst->weight == 0) dw_dst->weight= weight; + } + /*free memory and return*/ + free_bvhtree_from_mesh(&tree_mesh_faces_src); + return 1; + } + + /* mode 3 == replace selected weights*/ + else if(mode == 3){ + /* loop through the vertices and copy weight from nearest weight*/ + for(i=0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ + /*reset nearest*/ + nearest.index= -1; + nearest.dist= FLT_MAX; + /*transform into target space*/ + mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); + normal_tri_v3(normal, mv_src[mface_src[nearest.index].v1].co, mv_src[mface_src[nearest.index].v2].co, mv_src[mface_src[nearest.index].v3].co); + /*node tree accelerated search for closest face*/ + BLI_bvhtree_find_nearest(tree_mesh_faces_src.tree, tmp_co, &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src); + /*project onto face*/ + project_v3_plane(tmp_co, normal, mv_src[mface_src[nearest.index].v1].co); + /*interpolate weights*/ + interp_weights_face_v3(tmp_weight, mv_src[mface_src[nearest.index].v1].co, + mv_src[mface_src[nearest.index].v2].co, + mv_src[mface_src[nearest.index].v3].co, + mv_src[mface_src[nearest.index].v4].co, tmp_co); + /*get weights*/ + weight= tmp_weight[0] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v1], index_src)->weight; + weight+= tmp_weight[1] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v2], index_src)->weight; + weight+= tmp_weight[2] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v3], index_src)->weight; + weight+= tmp_weight[3] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v4], index_src)->weight; + /*copy weight*/ + dw_dst= defvert_verify_index(*dv_array_dst, index_dst); + /*dw_dst->weight= weight;*//*TODO: fix this!*/ + } + /*free memory and return*/ + free_bvhtree_from_mesh(&tree_mesh_faces_src); + return 1; + } + else return 0; } /********************** End transfer weight functions *********************/ @@ -3201,70 +3419,78 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) int fail= 0; /*TODO: get this parameter*/ - enum option {single =1, all =2}; - enum option option_choise= 1; + enum option {single =1, all =2} option= 1; /*TODO: get this parameter*/ - enum method {by_index = 1, by_nearest_vertex = 2, by_nearest_vertex_in_face = 3, by_nearest_face = 4}; - enum method method_choise= 1; + enum method {by_index = 1, by_nearest_vertex = 2, by_nearest_face = 3, by_nearest_vertex_in_face = 4} method= 4; /*TODO: get this parameter*/ - short mode= 1; /* mode is passed on to lower funtions*/ + short mode= 2; + + /* mode 1 == replace all weights*/ + /* mode 2 == replace null weights*/ + /* mode 3 == replace selected weights*/ + + /*Truth table for testing:----*/ + /*1,1,1 Tested and working.*/ + /*1,1,2 Tested and working.*/ + /*1,1,3 Tested and NOT working.*/ + /*1,2,1 Tested and working.*/ + /*1,2,2 Tested and working.*/ + /*1,2,3 Tested and NOT working.*/ + /*1,3,1 Tested and working.*/ + /*1,3,2 Tested and working.*/ + /*1,3,3 Tested and NOT working.*/ + /*1,4,1 Tested and working.*/ + /*1,4,2 Tested and working.*/ + /*1,4,3 Tested and NOT working.*/ /*Macro to loop through selected objects and perform operation depending on option and method*/ CTX_DATA_BEGIN(C, Object*, obslc, selected_editable_objects) { if(obact != obslc) { - switch(option_choise){ + switch(option){ /*single*/ case(single): - switch(method_choise){ + switch(method){ case(by_index): if(ED_vgroup_transfer_weight_by_index_single(obslc, obact, mode)) change++; - else fail++; - break; + else fail++; break; case(by_nearest_vertex): if(ED_vgroup_transfer_weight_by_nearest_vertex_single(obslc, obact, mode)) change++; - else fail++; - break; - - case(by_nearest_vertex_in_face): - if(ED_vgroup_transfer_weight_by_nearest_vertex_in_face_single(obslc, obact, mode)) change++; - else fail++; - break; + else fail++; break; case(by_nearest_face): + if(ED_vgroup_transfer_weight_by_nearest_vertex_in_face_single(obslc, obact, mode)) change++; + else fail++; break; + + case(by_nearest_vertex_in_face): if(ED_vgroup_transfer_weight_by_nearest_face_single(obslc, obact, mode)) change++; - else fail++; - break; + else fail++; break; } /*all*/ case(all): - switch(method_choise){ + switch(method){ case(by_index): - if(ED_vgroup_transfer_weight_by_index_all(obslc, obact, mode)) change++; - else fail++; - break; + /*if(ED_vgroup_transfer_weight_by_index_all(obslc, obact, mode)) change++; + else fail++;*/ break; case(by_nearest_vertex): - if(ED_vgroup_transfer_weight_by_nearest_vertex_all(obslc, obact, mode)) change++; - else fail++; - break; + /*if(ED_vgroup_transfer_weight_by_nearest_vertex_all(obslc, obact, mode)) change++; + else fail++;*/ break; case(by_nearest_vertex_in_face): - if(ED_vgroup_transfer_weight_by_nearest_vertex_in_face_all(obslc, obact, mode)) change++; - else fail++; - break; + /*if(ED_vgroup_transfer_weight_by_nearest_vertex_in_face_all(obslc, obact, mode)) change++; + else fail++;*/ break; case(by_nearest_face): - if(ED_vgroup_transfer_weight_by_nearest_face_all(obslc, obact, mode)) change++; - else fail++; - break; + /*if(ED_vgroup_transfer_weight_by_nearest_face_all(obslc, obact, mode)) change++; + else fail++;*/ break; } } From f4f5254100c16f7e9906dffcdc9695295e27c7e2 Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Thu, 17 May 2012 09:47:11 +0000 Subject: [PATCH 033/347] cleanup: Style = adding spaces around operators. --- source/blender/editors/object/object_vgroup.c | 326 +++++++++--------- 1 file changed, 163 insertions(+), 163 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 1c30c0b2510..fd98f7aaa3c 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -387,22 +387,22 @@ int ED_vgroup_copy_single(Object *ob_dst, const Object *ob_src) bDeformGroup *dg_src, *dg_dst; /*get source deform group*/ - dg_src= BLI_findlink(&ob_src->defbase, (ob_src->actdef-1)); + dg_src = BLI_findlink(&ob_src->defbase, (ob_src->actdef-1)); /*create new and overwrite vertex group on destination without data*/ ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_src->name)); ED_vgroup_add_name(ob_dst, dg_src->name); /*get destination deformgroup*/ - dg_dst= defgroup_find_name(ob_dst, dg_src->name); + dg_dst = defgroup_find_name(ob_dst, dg_src->name); /*get vertex group arrays*/ ED_vgroup_give_parray(ob_src->data, &dv_array_src, &dv_tot_src, FALSE); ED_vgroup_give_parray(ob_dst->data, &dv_array_dst, &dv_tot_dst, FALSE); /*get indexes of vertex groups*/ - index_src= BLI_findindex(&ob_src->defbase, dg_src); - index_dst= BLI_findindex(&ob_dst->defbase, dg_dst); + index_src = BLI_findindex(&ob_src->defbase, dg_src); + index_dst = BLI_findindex(&ob_dst->defbase, dg_dst); /*check if indices are matching, delete and return if not*/ if (ob_dst == ob_src || dv_tot_dst == 0 || (dv_tot_dst != dv_tot_src) || dv_array_src == NULL || dv_array_dst == NULL) { @@ -411,10 +411,10 @@ int ED_vgroup_copy_single(Object *ob_dst, const Object *ob_src) } /* loop through the vertices and copy weight*/ - for(i=0; iweight= dw_src->weight; + for(i = 0; i < dv_tot_dst; i++, dv_array_src++, dv_array_dst++) { + dw_src = defvert_verify_index(*dv_array_src, index_src); + dw_dst = defvert_verify_index(*dv_array_dst, index_dst); + dw_dst->weight = dw_src->weight; } return 1; @@ -451,7 +451,7 @@ int ED_vgroup_transfer_weight_by_index_single(Object *ob_dst, Object *ob_src, sh bDeformGroup *dg_src, *dg_dst; /*get source deform group*/ - dg_src= BLI_findlink(&ob_src->defbase, (ob_src->actdef-1)); + dg_src = BLI_findlink(&ob_src->defbase, (ob_src->actdef-1)); /*create new and overwrite vertex group on destination without data*/ if(!defgroup_find_name(ob_dst, dg_src->name) || mode == 1){ @@ -460,15 +460,15 @@ int ED_vgroup_transfer_weight_by_index_single(Object *ob_dst, Object *ob_src, sh } /*get destination deformgroup*/ - dg_dst= defgroup_find_name(ob_dst, dg_src->name); + dg_dst = defgroup_find_name(ob_dst, dg_src->name); /*get vertex group arrays*/ ED_vgroup_give_parray(ob_src->data, &dv_array_src, &dv_tot_src, FALSE); ED_vgroup_give_parray(ob_dst->data, &dv_array_dst, &dv_tot_dst, FALSE); /*get indexes of vertex groups*/ - index_src= BLI_findindex(&ob_src->defbase, dg_src); - index_dst= BLI_findindex(&ob_dst->defbase, dg_dst); + index_src = BLI_findindex(&ob_src->defbase, dg_src); + index_dst = BLI_findindex(&ob_dst->defbase, dg_dst); /*check if indices are matching, delete and return if not*/ if (ob_dst == ob_src || dv_tot_dst == 0 || (dv_tot_dst != dv_tot_src) || dv_array_src == NULL || dv_array_dst == NULL) { @@ -479,10 +479,10 @@ int ED_vgroup_transfer_weight_by_index_single(Object *ob_dst, Object *ob_src, sh /* mode 1 == replace all weights*/ if(mode == 1){ /* loop through the vertices and copy weight*/ - for(i=0; iweight= dw_src->weight; + for(i = 0; i < dv_tot_dst; i++, dv_array_src++, dv_array_dst++){ + dw_src = defvert_verify_index(*dv_array_src, index_src); + dw_dst = defvert_verify_index(*dv_array_dst, index_dst); + dw_dst->weight = dw_src->weight; } return 1; } @@ -490,11 +490,11 @@ int ED_vgroup_transfer_weight_by_index_single(Object *ob_dst, Object *ob_src, sh /* mode 2 == replace null weights*/ else if(mode == 2){ /* loop through the vertices and copy weight*/ - for(i=0; iweight || dw_dst->weight == 0) dw_dst->weight= dw_src->weight; + if(!dw_dst->weight || dw_dst->weight == 0) dw_dst->weight = dw_src->weight; } return 1; } @@ -502,11 +502,11 @@ int ED_vgroup_transfer_weight_by_index_single(Object *ob_dst, Object *ob_src, sh /* mode 3 == replace selected weights*/ else if(mode == 3){ /* loop through the vertices and copy weight*/ - for(i=0; iflag == 1) dw_dst->weight= dw_src->weight; /*this does not work*/ + if((*dv_array_src)->flag == 1) dw_dst->weight = dw_src->weight; /*This does not work*/ } return 1; } @@ -515,8 +515,8 @@ int ED_vgroup_transfer_weight_by_index_single(Object *ob_dst, Object *ob_src, sh int ED_vgroup_transfer_weight_by_nearest_vertex_all(Object *ob_dst, Object *ob_src, short mode) { - ob_dst= ob_dst; - ob_src= ob_src; + ob_dst = ob_dst; + ob_src = ob_src; return mode; } @@ -534,7 +534,7 @@ int ED_vgroup_transfer_weight_by_nearest_vertex_single(Object *ob_dst, Object *o float tmp_co[3], tmp_mat[4][4]; /*get source deform group*/ - dg_src= BLI_findlink(&ob_src->defbase, (ob_src->actdef-1)); + dg_src = BLI_findlink(&ob_src->defbase, (ob_src->actdef-1)); /*create new and overwrite vertex group on destination without data*/ if(!defgroup_find_name(ob_dst, dg_src->name) || mode == 1){ @@ -543,11 +543,11 @@ int ED_vgroup_transfer_weight_by_nearest_vertex_single(Object *ob_dst, Object *o } /*get destination deformgroup*/ - dg_dst= defgroup_find_name(ob_dst, dg_src->name); + dg_dst = defgroup_find_name(ob_dst, dg_src->name); /*get meshes*/ - me_dst= ob_dst->data; - dmesh_src= ob_src->derivedDeform; + me_dst = ob_dst->data; + dmesh_src = ob_src->derivedDeform; /*make node tree*/ bvhtree_from_mesh_verts(&tree_mesh_src, dmesh_src, 0.0, 2, 6); @@ -557,11 +557,11 @@ int ED_vgroup_transfer_weight_by_nearest_vertex_single(Object *ob_dst, Object *o ED_vgroup_give_parray(ob_dst->data, &dv_array_dst, &dv_tot_dst, FALSE); /*get indexes of vertex groups*/ - index_src= BLI_findindex(&ob_src->defbase, dg_src); - index_dst= BLI_findindex(&ob_dst->defbase, dg_dst); + index_src = BLI_findindex(&ob_src->defbase, dg_src); + index_dst = BLI_findindex(&ob_dst->defbase, dg_dst); /*get vertices*/ - mv_dst= me_dst->mvert; + mv_dst = me_dst->mvert; /*prepare transformation matrix*/ /*this can be excluded to make a lazy feature that works better when object centers relative to mesh is the same*/ @@ -571,17 +571,17 @@ int ED_vgroup_transfer_weight_by_nearest_vertex_single(Object *ob_dst, Object *o /* mode 1 == replace all weights*/ if(mode == 1){ /* loop through the vertices and copy weight*/ - for(i=0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ + for(i = 0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ /*reset nearest*/ - nearest.index= -1; - nearest.dist= FLT_MAX; + nearest.index = -1; + nearest.dist = FLT_MAX; /*transform into target space*/ mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); /*node tree accelerated search for closest vetex*/ BLI_bvhtree_find_nearest(tree_mesh_src.tree, tmp_co, &nearest, tree_mesh_src.nearest_callback, &tree_mesh_src); - dw_src= defvert_verify_index(dv_array_src[nearest.index], index_src); - dw_dst= defvert_verify_index(*dv_array_dst, index_dst); - dw_dst->weight= dw_src->weight; + dw_src = defvert_verify_index(dv_array_src[nearest.index], index_src); + dw_dst = defvert_verify_index(*dv_array_dst, index_dst); + dw_dst->weight = dw_src->weight; } /*free memory and return*/ free_bvhtree_from_mesh(&tree_mesh_src); @@ -591,18 +591,18 @@ int ED_vgroup_transfer_weight_by_nearest_vertex_single(Object *ob_dst, Object *o /* mode 2 == replace null weights*/ else if(mode == 2){ /* loop through the vertices and copy weight weight*/ - for(i=0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ + for(i = 0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ /*reset nearest*/ - nearest.index= -1; - nearest.dist= FLT_MAX; + nearest.index = -1; + nearest.dist = FLT_MAX; /*transform into target space*/ mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); /*node tree accelerated search for closest vetex*/ BLI_bvhtree_find_nearest(tree_mesh_src.tree, tmp_co, &nearest, tree_mesh_src.nearest_callback, &tree_mesh_src); - dw_src= defvert_verify_index(dv_array_src[nearest.index], index_src); - dw_dst= defvert_verify_index(*dv_array_dst, index_dst); + dw_src = defvert_verify_index(dv_array_src[nearest.index], index_src); + dw_dst = defvert_verify_index(*dv_array_dst, index_dst); /*check if destination weight is null or zero*/ - if(!dw_dst->weight || dw_dst->weight == 0) dw_dst->weight= dw_src->weight; + if(!dw_dst->weight || dw_dst->weight == 0) dw_dst->weight = dw_src->weight; } /*free memory and return*/ free_bvhtree_from_mesh(&tree_mesh_src); @@ -612,16 +612,16 @@ int ED_vgroup_transfer_weight_by_nearest_vertex_single(Object *ob_dst, Object *o /* mode 3 == replace selected weights*/ else if(mode == 3){ /* loop through the vertices and copy weight*/ - for(i=0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ + for(i = 0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ /*reset nearest*/ - nearest.index= -1; - nearest.dist= FLT_MAX; + nearest.index = -1; + nearest.dist = FLT_MAX; /*transform into target space*/ mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); /*node tree accelerated search for closest vetex*/ BLI_bvhtree_find_nearest(tree_mesh_src.tree, tmp_co, &nearest, tree_mesh_src.nearest_callback, &tree_mesh_src); - dw_src= defvert_verify_index(dv_array_src[nearest.index], index_src); - dw_dst= defvert_verify_index(*dv_array_dst, index_dst); + dw_src = defvert_verify_index(dv_array_src[nearest.index], index_src); + dw_dst = defvert_verify_index(*dv_array_dst, index_dst); /*dw_dst->weight= dw_src->weight;*//*TODO fix this*/ } @@ -634,8 +634,8 @@ int ED_vgroup_transfer_weight_by_nearest_vertex_single(Object *ob_dst, Object *o int ED_vgroup_transfer_weight_by_nearest_vertex_in_face_all(Object *ob_dst, Object *ob_src, short mode) { - ob_dst= ob_dst; - ob_src= ob_src; + ob_dst = ob_dst; + ob_src = ob_src; return mode; } @@ -654,7 +654,7 @@ int ED_vgroup_transfer_weight_by_nearest_vertex_in_face_single(Object *ob_dst, O float dist_v1, dist_v2, dist_v3, dist_v4, tmp_co[3], tmp_mat[4][4]; /*get source deform group*/ - dg_src= BLI_findlink(&ob_src->defbase, (ob_src->actdef-1)); + dg_src = BLI_findlink(&ob_src->defbase, (ob_src->actdef-1)); /*create new and overwrite vertex group on destination without data*/ if(!defgroup_find_name(ob_dst, dg_src->name) || mode == 1){ @@ -663,11 +663,11 @@ int ED_vgroup_transfer_weight_by_nearest_vertex_in_face_single(Object *ob_dst, O } /*get destination deformgroup*/ - dg_dst= defgroup_find_name(ob_dst, dg_src->name); + dg_dst = defgroup_find_name(ob_dst, dg_src->name); /*get meshes*/ - me_dst= ob_dst->data; - dmesh_src= ob_src->derivedDeform; + me_dst = ob_dst->data; + dmesh_src = ob_src->derivedDeform; /*make node tree*/ DM_ensure_tessface(dmesh_src); @@ -678,15 +678,15 @@ int ED_vgroup_transfer_weight_by_nearest_vertex_in_face_single(Object *ob_dst, O ED_vgroup_give_parray(ob_dst->data, &dv_array_dst, &dv_tot_dst, FALSE); /*get indexes of vertex groups*/ - index_src= BLI_findindex(&ob_src->defbase, dg_src); - index_dst= BLI_findindex(&ob_dst->defbase, dg_dst); + index_src = BLI_findindex(&ob_src->defbase, dg_src); + index_dst = BLI_findindex(&ob_dst->defbase, dg_dst); /*get vertices*/ - mv_dst= me_dst->mvert; - mv_src= dmesh_src->getVertArray(dmesh_src); + mv_dst = me_dst->mvert; + mv_src = dmesh_src->getVertArray(dmesh_src); /*get faces*/ - mface_src= dmesh_src->getTessFaceArray(dmesh_src); + mface_src = dmesh_src->getTessFaceArray(dmesh_src); /*prepare transformation matrix*/ invert_m4_m4(ob_src->imat, ob_src->obmat); @@ -695,38 +695,38 @@ int ED_vgroup_transfer_weight_by_nearest_vertex_in_face_single(Object *ob_dst, O /* mode 1 == replace all weights*/ if(mode == 1){ /* loop through the vertices and copy weight from nearest weight*/ - for(i=0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ + for(i = 0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ /*reset nearest*/ - nearest.index= -1; - nearest.dist= FLT_MAX; + nearest.index = -1; + nearest.dist = FLT_MAX; /*transform into target space*/ mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); /*node tree accelerated search for closest face*/ BLI_bvhtree_find_nearest(tree_mesh_faces_src.tree, tmp_co, &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src); /*get distances*/ - dist_v1= len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v1].co); - dist_v2= len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v2].co); - dist_v3= len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v3].co); + dist_v1 = len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v1].co); + dist_v2 = len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v2].co); + dist_v3 = len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v3].co); /*get weight from triangle*/ - if(dist_v1weight= dw_src->weight; + dw_dst = defvert_verify_index(*dv_array_dst, index_dst); + dw_dst->weight = dw_src->weight; } /*free memory and return*/ free_bvhtree_from_mesh(&tree_mesh_faces_src); @@ -738,37 +738,37 @@ int ED_vgroup_transfer_weight_by_nearest_vertex_in_face_single(Object *ob_dst, O /* loop through the vertices and copy weight from nearest weight*/ for(i=0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ /*reset nearest*/ - nearest.index= -1; - nearest.dist= FLT_MAX; + nearest.index = -1; + nearest.dist = FLT_MAX; /*transform into target space*/ mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); /*node tree accelerated search for closest face*/ BLI_bvhtree_find_nearest(tree_mesh_faces_src.tree, tmp_co, &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src); /*get distances*/ - dist_v1= len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v1].co); - dist_v2= len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v2].co); - dist_v3= len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v3].co); + dist_v1 = len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v1].co); + dist_v2 = len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v2].co); + dist_v3 = len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v3].co); /*get weight from triangle*/ - if(dist_v1weight || dw_dst->weight == 0) dw_dst->weight= dw_src->weight; + if(!dw_dst->weight || dw_dst->weight == 0) dw_dst->weight = dw_src->weight; } /*free memory and return*/ free_bvhtree_from_mesh(&tree_mesh_faces_src); @@ -778,37 +778,37 @@ int ED_vgroup_transfer_weight_by_nearest_vertex_in_face_single(Object *ob_dst, O /* mode 3 == replace selected weights*/ else if(mode == 3){ /* loop through the vertices and copy weight from nearest weight*/ - for(i=0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ + for(i = 0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ /*reset nearest*/ - nearest.index= -1; - nearest.dist= FLT_MAX; + nearest.index = -1; + nearest.dist = FLT_MAX; /*transform into target space*/ mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); /*node tree accelerated search for closest face*/ BLI_bvhtree_find_nearest(tree_mesh_faces_src.tree, tmp_co, &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src); /*get distances*/ - dist_v1= len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v1].co); - dist_v2= len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v2].co); - dist_v3= len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v3].co); + dist_v1 = len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v1].co); + dist_v2 = len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v2].co); + dist_v3 = len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v3].co); /*get weight from triangle*/ - if(dist_v1weight= dw_src->weight;*/ /*TODO: fix this!*/ } /*free memory and return*/ @@ -820,8 +820,8 @@ int ED_vgroup_transfer_weight_by_nearest_vertex_in_face_single(Object *ob_dst, O int ED_vgroup_transfer_weight_by_nearest_face_all(Object *ob_dst, Object *ob_src, short mode) { - ob_dst= ob_dst; - ob_src= ob_src; + ob_dst = ob_dst; + ob_src = ob_src; return mode; } @@ -840,7 +840,7 @@ int ED_vgroup_transfer_weight_by_nearest_face_single(Object *ob_dst, Object *ob_ float weight, tmp_weight[4], tmp_co[3], normal[3], tmp_mat[4][4]; /*get source deform group*/ - dg_src= BLI_findlink(&ob_src->defbase, (ob_src->actdef-1)); + dg_src = BLI_findlink(&ob_src->defbase, (ob_src->actdef-1)); /*create new and overwrite vertex group on destination without data*/ if(!defgroup_find_name(ob_dst, dg_src->name) || mode == 1){ @@ -849,11 +849,11 @@ int ED_vgroup_transfer_weight_by_nearest_face_single(Object *ob_dst, Object *ob_ } /*get destination deformgroup*/ - dg_dst= defgroup_find_name(ob_dst, dg_src->name); + dg_dst = defgroup_find_name(ob_dst, dg_src->name); /*get meshes*/ - me_dst= ob_dst->data; - dmesh_src= ob_src->derivedDeform; + me_dst = ob_dst->data; + dmesh_src = ob_src->derivedDeform; /*make node tree*/ DM_ensure_tessface(dmesh_src); @@ -864,15 +864,15 @@ int ED_vgroup_transfer_weight_by_nearest_face_single(Object *ob_dst, Object *ob_ ED_vgroup_give_parray(ob_dst->data, &dv_array_dst, &dv_tot_dst, FALSE); /*get indexes of vertex groups*/ - index_src= BLI_findindex(&ob_src->defbase, dg_src); - index_dst= BLI_findindex(&ob_dst->defbase, dg_dst); + index_src = BLI_findindex(&ob_src->defbase, dg_src); + index_dst = BLI_findindex(&ob_dst->defbase, dg_dst); /*get vertices*/ - mv_dst= me_dst->mvert; - mv_src= dmesh_src->getVertArray(dmesh_src); + mv_dst = me_dst->mvert; + mv_src = dmesh_src->getVertArray(dmesh_src); /*get faces*/ - mface_src= dmesh_src->getTessFaceArray(dmesh_src); + mface_src = dmesh_src->getTessFaceArray(dmesh_src); /*prepare transformation matrix*/ invert_m4_m4(ob_src->imat, ob_src->obmat); @@ -881,10 +881,10 @@ int ED_vgroup_transfer_weight_by_nearest_face_single(Object *ob_dst, Object *ob_ /* mode 1 == replace all weights*/ if(mode == 1){ /* loop through the vertices and copy weight from nearest weight*/ - for(i=0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ + for(i = 0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ /*reset nearest*/ - nearest.index= -1; - nearest.dist= FLT_MAX; + nearest.index = -1; + nearest.dist = FLT_MAX; /*transform into target space*/ mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); normal_tri_v3(normal, mv_src[mface_src[nearest.index].v1].co, mv_src[mface_src[nearest.index].v2].co, mv_src[mface_src[nearest.index].v3].co); @@ -898,13 +898,13 @@ int ED_vgroup_transfer_weight_by_nearest_face_single(Object *ob_dst, Object *ob_ mv_src[mface_src[nearest.index].v3].co, mv_src[mface_src[nearest.index].v4].co, tmp_co); /*get weights*/ - weight= tmp_weight[0] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v1], index_src)->weight; - weight+= tmp_weight[1] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v2], index_src)->weight; - weight+= tmp_weight[2] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v3], index_src)->weight; - weight+= tmp_weight[3] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v4], index_src)->weight; + weight = tmp_weight[0] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v1], index_src)->weight; + weight += tmp_weight[1] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v2], index_src)->weight; + weight += tmp_weight[2] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v3], index_src)->weight; + weight += tmp_weight[3] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v4], index_src)->weight; /*copy weight*/ - dw_dst= defvert_verify_index(*dv_array_dst, index_dst); - dw_dst->weight= weight; + dw_dst = defvert_verify_index(*dv_array_dst, index_dst); + dw_dst->weight = weight; } /*free memory and return*/ free_bvhtree_from_mesh(&tree_mesh_faces_src); @@ -914,10 +914,10 @@ int ED_vgroup_transfer_weight_by_nearest_face_single(Object *ob_dst, Object *ob_ /* mode 2 == replace null weights*/ else if(mode == 2){ /* loop through the vertices and copy weight from nearest weight*/ - for(i=0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ + for(i = 0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ /*reset nearest*/ - nearest.index= -1; - nearest.dist= FLT_MAX; + nearest.index = -1; + nearest.dist = FLT_MAX; /*transform into target space*/ mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); normal_tri_v3(normal, mv_src[mface_src[nearest.index].v1].co, mv_src[mface_src[nearest.index].v2].co, mv_src[mface_src[nearest.index].v3].co); @@ -931,14 +931,14 @@ int ED_vgroup_transfer_weight_by_nearest_face_single(Object *ob_dst, Object *ob_ mv_src[mface_src[nearest.index].v3].co, mv_src[mface_src[nearest.index].v4].co, tmp_co); /*get weights*/ - weight= tmp_weight[0] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v1], index_src)->weight; - weight+= tmp_weight[1] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v2], index_src)->weight; - weight+= tmp_weight[2] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v3], index_src)->weight; - weight+= tmp_weight[3] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v4], index_src)->weight; + weight = tmp_weight[0] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v1], index_src)->weight; + weight += tmp_weight[1] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v2], index_src)->weight; + weight += tmp_weight[2] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v3], index_src)->weight; + weight += tmp_weight[3] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v4], index_src)->weight; /*copy weight*/ - dw_dst= defvert_verify_index(*dv_array_dst, index_dst); + dw_dst = defvert_verify_index(*dv_array_dst, index_dst); /*check if destination weight is null or zero and copy weight*/ - if(!dw_dst->weight || dw_dst->weight == 0) dw_dst->weight= weight; + if(!dw_dst->weight || dw_dst->weight == 0) dw_dst->weight = weight; } /*free memory and return*/ free_bvhtree_from_mesh(&tree_mesh_faces_src); @@ -948,10 +948,10 @@ int ED_vgroup_transfer_weight_by_nearest_face_single(Object *ob_dst, Object *ob_ /* mode 3 == replace selected weights*/ else if(mode == 3){ /* loop through the vertices and copy weight from nearest weight*/ - for(i=0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ + for(i = 0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ /*reset nearest*/ - nearest.index= -1; - nearest.dist= FLT_MAX; + nearest.index = -1; + nearest.dist = FLT_MAX; /*transform into target space*/ mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); normal_tri_v3(normal, mv_src[mface_src[nearest.index].v1].co, mv_src[mface_src[nearest.index].v2].co, mv_src[mface_src[nearest.index].v3].co); @@ -965,12 +965,12 @@ int ED_vgroup_transfer_weight_by_nearest_face_single(Object *ob_dst, Object *ob_ mv_src[mface_src[nearest.index].v3].co, mv_src[mface_src[nearest.index].v4].co, tmp_co); /*get weights*/ - weight= tmp_weight[0] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v1], index_src)->weight; - weight+= tmp_weight[1] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v2], index_src)->weight; - weight+= tmp_weight[2] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v3], index_src)->weight; - weight+= tmp_weight[3] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v4], index_src)->weight; + weight = tmp_weight[0] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v1], index_src)->weight; + weight += tmp_weight[1] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v2], index_src)->weight; + weight += tmp_weight[2] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v3], index_src)->weight; + weight += tmp_weight[3] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v4], index_src)->weight; /*copy weight*/ - dw_dst= defvert_verify_index(*dv_array_dst, index_dst); + dw_dst = defvert_verify_index(*dv_array_dst, index_dst); /*dw_dst->weight= weight;*//*TODO: fix this!*/ } /*free memory and return*/ @@ -3366,9 +3366,9 @@ void OBJECT_OT_vertex_group_copy_to_selected(wmOperatorType *ot) static int vertex_group_copy_to_selected_single_exec(bContext *C, wmOperator *op) { - Object *obact= CTX_data_active_object(C); - int change= 0; - int fail= 0; + Object *obact = CTX_data_active_object(C); + int change = 0; + int fail = 0; /*Macro to loop through selected objects and perform operation*/ CTX_DATA_BEGIN(C, Object*, obslc, selected_editable_objects) @@ -3400,33 +3400,33 @@ static int vertex_group_copy_to_selected_single_exec(bContext *C, wmOperator *op void OBJECT_OT_vertex_group_copy_to_selected_single(wmOperatorType *ot) { /* identifiers */ - ot->name= "Copy a Vertex Group to Selected"; - ot->idname= "OBJECT_OT_vertex_group_copy_to_selected_single"; - ot->description= "Copy a vertex group to other selected objects with matching indices"; + ot->name = "Copy a Vertex Group to Selected"; + ot->idname = "OBJECT_OT_vertex_group_copy_to_selected_single"; + ot->description = "Copy a vertex group to other selected objects with matching indices"; /* api callbacks */ - ot->poll= vertex_group_poll; - ot->exec= vertex_group_copy_to_selected_single_exec; + ot->poll = vertex_group_poll; + ot->exec = vertex_group_copy_to_selected_single_exec; /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; } static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) { - Object *obact= CTX_data_active_object(C); - int change= 0; - int fail= 0; + Object *obact = CTX_data_active_object(C); + int change = 0; + int fail = 0; /*TODO: get this parameter*/ enum option {single =1, all =2} option= 1; /*TODO: get this parameter*/ - enum method {by_index = 1, by_nearest_vertex = 2, by_nearest_face = 3, by_nearest_vertex_in_face = 4} method= 4; + enum method {by_index = 1, by_nearest_vertex = 2, by_nearest_face = 3, by_nearest_vertex_in_face = 4} method = 4; /*TODO: get this parameter*/ /* mode is passed on to lower funtions*/ - short mode= 2; + short mode = 2; /* mode 1 == replace all weights*/ /* mode 2 == replace null weights*/ @@ -3516,16 +3516,16 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) void OBJECT_OT_vertex_group_transfer_weight(wmOperatorType *ot) { /* identifiers */ - ot->name= "Transfer weight to selected"; - ot->idname= "OBJECT_OT_vertex_group_transfer_weight"; - ot->description= "Transfers weight from active to selected depending on options"; + ot->name = "Transfer weight to selected"; + ot->idname = "OBJECT_OT_vertex_group_transfer_weight"; + ot->description = "Transfers weight from active to selected depending on options"; /* api callbacks */ - ot->poll= vertex_group_poll; - ot->exec= vertex_group_transfer_weight_exec; + ot->poll = vertex_group_poll; + ot->exec = vertex_group_transfer_weight_exec; /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; } static EnumPropertyItem vgroup_items[] = { From 044fd86a15b358a5e250896b88d493c17c3d5e21 Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Thu, 17 May 2012 12:15:39 +0000 Subject: [PATCH 034/347] Some changes to structure as a response to review. (I still havent adressed all issues.) --- source/blender/editors/object/object_vgroup.c | 569 +++++------------- 1 file changed, 146 insertions(+), 423 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index fd98f7aaa3c..d1622e507d0 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -20,7 +20,7 @@ * * The Original Code is: all of this file. * - * Contributor(s): none yet. + * Contributor(s): Ove M Henriksen. * * ***** END GPL LICENSE BLOCK ***** */ @@ -376,6 +376,10 @@ int ED_vgroup_copy_array(Object *ob, Object *ob_from) return 1; } +/*ideasman42 2012/05/17 09:04:35 +the single vgroup to copy could be an argument - +allows to be more flexible later even if for now, the arg is "ob_src->actdef-1" for all callers. +*/ /*Copy a single vertex group from source to destination with weights by identical meshes*/ int ED_vgroup_copy_single(Object *ob_dst, const Object *ob_src) { @@ -422,26 +426,7 @@ int ED_vgroup_copy_single(Object *ob_dst, const Object *ob_src) /********************** Start transfer weight functions *********************/ -int ED_vgroup_transfer_weight_by_index_all(Object *ob_dst, Object *ob_src, short mode) -{ - - if(mode == 1){ - return ED_vgroup_copy_array(ob_dst, ob_src); - } - - - else if(mode == 2){ - return 0; - } - - - else if(mode == 3){ - return 0; - } - else return 0; -} - -int ED_vgroup_transfer_weight_by_index_single(Object *ob_dst, Object *ob_src, short mode) +int ED_vgroup_transfer_weight_by_index(Object *ob_dst, Object *ob_src, short mode, short option) { MDeformVert **dv_array_src; MDeformVert **dv_array_dst; @@ -450,6 +435,9 @@ int ED_vgroup_transfer_weight_by_index_single(Object *ob_dst, Object *ob_src, sh int i, index_src, index_dst; bDeformGroup *dg_src, *dg_dst; + /*remove this:*/ + option=option; + /*get source deform group*/ dg_src = BLI_findlink(&ob_src->defbase, (ob_src->actdef-1)); @@ -476,51 +464,19 @@ int ED_vgroup_transfer_weight_by_index_single(Object *ob_dst, Object *ob_src, sh return 0; } - /* mode 1 == replace all weights*/ - if(mode == 1){ - /* loop through the vertices and copy weight*/ - for(i = 0; i < dv_tot_dst; i++, dv_array_src++, dv_array_dst++){ - dw_src = defvert_verify_index(*dv_array_src, index_src); - dw_dst = defvert_verify_index(*dv_array_dst, index_dst); - dw_dst->weight = dw_src->weight; - } - return 1; + /* loop through the vertices and copy weight*/ + for(i = 0; i < dv_tot_dst; i++, dv_array_src++, dv_array_dst++){ + dw_src = defvert_verify_index(*dv_array_src, index_src); + dw_dst = defvert_verify_index(*dv_array_dst, index_dst); + if(mode == 1) dw_dst->weight = dw_src->weight; + else if(mode == 2) {if(!dw_dst->weight || dw_dst->weight == 0) dw_dst->weight = dw_src->weight;} + else if(mode == 3) {if((*dv_array_src)->flag == 1) dw_dst->weight = dw_src->weight;}/*This does not work*/ + else return 0; } - - /* mode 2 == replace null weights*/ - else if(mode == 2){ - /* loop through the vertices and copy weight*/ - for(i = 0; i < dv_tot_dst; i++, dv_array_src++, dv_array_dst++) { - dw_src = defvert_verify_index(*dv_array_src, index_src); - dw_dst = defvert_verify_index(*dv_array_dst, index_dst); - /*check if destination weight is null or zero*/ - if(!dw_dst->weight || dw_dst->weight == 0) dw_dst->weight = dw_src->weight; - } - return 1; - } - - /* mode 3 == replace selected weights*/ - else if(mode == 3){ - /* loop through the vertices and copy weight*/ - for(i = 0; i < dv_tot_dst; i++, dv_array_src++, dv_array_dst++) { - dw_src = defvert_verify_index(*dv_array_src, index_src); - dw_dst = defvert_verify_index(*dv_array_dst, index_dst); - /*check if source vertex is selected*/ - if((*dv_array_src)->flag == 1) dw_dst->weight = dw_src->weight; /*This does not work*/ - } - return 1; - } - else return 0; + return 1; } -int ED_vgroup_transfer_weight_by_nearest_vertex_all(Object *ob_dst, Object *ob_src, short mode) -{ - ob_dst = ob_dst; - ob_src = ob_src; - return mode; -} - -int ED_vgroup_transfer_weight_by_nearest_vertex_single(Object *ob_dst, Object *ob_src, short mode) +int ED_vgroup_transfer_weight_by_nearest_vertex(Object *ob_dst, Object *ob_src, short mode, short option) { bDeformGroup *dg_src, *dg_dst; MDeformVert **dv_array_src, **dv_array_dst; @@ -533,6 +489,9 @@ int ED_vgroup_transfer_weight_by_nearest_vertex_single(Object *ob_dst, Object *o int dv_tot_src, dv_tot_dst, i, index_dst, index_src; float tmp_co[3], tmp_mat[4][4]; + /*remove this:*/ + option=option; + /*get source deform group*/ dg_src = BLI_findlink(&ob_src->defbase, (ob_src->actdef-1)); @@ -568,78 +527,28 @@ int ED_vgroup_transfer_weight_by_nearest_vertex_single(Object *ob_dst, Object *o invert_m4_m4(ob_src->imat, ob_src->obmat); mult_m4_m4m4(tmp_mat, ob_src->imat, ob_dst->obmat); - /* mode 1 == replace all weights*/ - if(mode == 1){ - /* loop through the vertices and copy weight*/ - for(i = 0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ - /*reset nearest*/ - nearest.index = -1; - nearest.dist = FLT_MAX; - /*transform into target space*/ - mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); - /*node tree accelerated search for closest vetex*/ - BLI_bvhtree_find_nearest(tree_mesh_src.tree, tmp_co, &nearest, tree_mesh_src.nearest_callback, &tree_mesh_src); - dw_src = defvert_verify_index(dv_array_src[nearest.index], index_src); - dw_dst = defvert_verify_index(*dv_array_dst, index_dst); - dw_dst->weight = dw_src->weight; - } - /*free memory and return*/ - free_bvhtree_from_mesh(&tree_mesh_src); - return 1; + /* loop through the vertices and copy weight*/ + for(i = 0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ + /*reset nearest*/ + nearest.index = -1; + nearest.dist = FLT_MAX; + /*transform into target space*/ + mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); + /*node tree accelerated search for closest vetex*/ + BLI_bvhtree_find_nearest(tree_mesh_src.tree, tmp_co, &nearest, tree_mesh_src.nearest_callback, &tree_mesh_src); + dw_src = defvert_verify_index(dv_array_src[nearest.index], index_src); + dw_dst = defvert_verify_index(*dv_array_dst, index_dst); + if(mode == 1) dw_dst->weight = dw_src->weight; + else if(mode == 2) {if(!dw_dst->weight || dw_dst->weight == 0) dw_dst->weight = dw_src->weight;} + else if(mode == 3) {dw_dst->weight= dw_src->weight;}/*TODO fix this*/ + else return 0; } - - /* mode 2 == replace null weights*/ - else if(mode == 2){ - /* loop through the vertices and copy weight weight*/ - for(i = 0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ - /*reset nearest*/ - nearest.index = -1; - nearest.dist = FLT_MAX; - /*transform into target space*/ - mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); - /*node tree accelerated search for closest vetex*/ - BLI_bvhtree_find_nearest(tree_mesh_src.tree, tmp_co, &nearest, tree_mesh_src.nearest_callback, &tree_mesh_src); - dw_src = defvert_verify_index(dv_array_src[nearest.index], index_src); - dw_dst = defvert_verify_index(*dv_array_dst, index_dst); - /*check if destination weight is null or zero*/ - if(!dw_dst->weight || dw_dst->weight == 0) dw_dst->weight = dw_src->weight; - } - /*free memory and return*/ - free_bvhtree_from_mesh(&tree_mesh_src); - return 1; - } - - /* mode 3 == replace selected weights*/ - else if(mode == 3){ - /* loop through the vertices and copy weight*/ - for(i = 0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ - /*reset nearest*/ - nearest.index = -1; - nearest.dist = FLT_MAX; - /*transform into target space*/ - mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); - /*node tree accelerated search for closest vetex*/ - BLI_bvhtree_find_nearest(tree_mesh_src.tree, tmp_co, &nearest, tree_mesh_src.nearest_callback, &tree_mesh_src); - dw_src = defvert_verify_index(dv_array_src[nearest.index], index_src); - dw_dst = defvert_verify_index(*dv_array_dst, index_dst); - /*dw_dst->weight= dw_src->weight;*//*TODO fix this*/ - } - - /*free memory and return*/ - free_bvhtree_from_mesh(&tree_mesh_src); - return 1; - } - else return 0; + /*free memory and return*/ + free_bvhtree_from_mesh(&tree_mesh_src); + return 1; } -int ED_vgroup_transfer_weight_by_nearest_vertex_in_face_all(Object *ob_dst, Object *ob_src, short mode) -{ - ob_dst = ob_dst; - ob_src = ob_src; - return mode; -} - -int ED_vgroup_transfer_weight_by_nearest_vertex_in_face_single(Object *ob_dst, Object *ob_src, short mode) +int ED_vgroup_transfer_weight_by_nearest_vertex_in_face(Object *ob_dst, Object *ob_src, short mode, short option) { bDeformGroup *dg_src, *dg_dst; Mesh *me_dst; @@ -653,6 +562,9 @@ int ED_vgroup_transfer_weight_by_nearest_vertex_in_face_single(Object *ob_dst, O int dv_tot_src, dv_tot_dst, i, index_dst, index_src; float dist_v1, dist_v2, dist_v3, dist_v4, tmp_co[3], tmp_mat[4][4]; + /*remove this:*/ + option=option; + /*get source deform group*/ dg_src = BLI_findlink(&ob_src->defbase, (ob_src->actdef-1)); @@ -692,140 +604,54 @@ int ED_vgroup_transfer_weight_by_nearest_vertex_in_face_single(Object *ob_dst, O invert_m4_m4(ob_src->imat, ob_src->obmat); mult_m4_m4m4(tmp_mat, ob_src->imat, ob_dst->obmat); - /* mode 1 == replace all weights*/ - if(mode == 1){ - /* loop through the vertices and copy weight from nearest weight*/ - for(i = 0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ - /*reset nearest*/ - nearest.index = -1; - nearest.dist = FLT_MAX; - /*transform into target space*/ - mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); - /*node tree accelerated search for closest face*/ - BLI_bvhtree_find_nearest(tree_mesh_faces_src.tree, tmp_co, &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src); - /*get distances*/ - dist_v1 = len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v1].co); - dist_v2 = len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v2].co); - dist_v3 = len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v3].co); - /*get weight from triangle*/ - if(dist_v1 < dist_v2 && dist_v1 < dist_v3){ - dw_src = defvert_verify_index(dv_array_src[mface_src[nearest.index].v1], index_src); - } - else if(dist_v2 < dist_v3){ - dw_src = defvert_verify_index(dv_array_src[mface_src[nearest.index].v2], index_src); - } - else{ - dw_src = defvert_verify_index(dv_array_src[mface_src[nearest.index].v3], index_src); - } - /*check for and get weight from quad*/ - if(mface_src[nearest.index].v4){ - dist_v4 = len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v4].co); - if(dist_v4 < dist_v1 && dist_v4 < dist_v2 && dist_v4 < dist_v3){ - dw_src = defvert_verify_index(dv_array_src[mface_src[nearest.index].v4], index_src); - } - } - /*copy weight*/ - dw_dst = defvert_verify_index(*dv_array_dst, index_dst); - dw_dst->weight = dw_src->weight; - } - /*free memory and return*/ - free_bvhtree_from_mesh(&tree_mesh_faces_src); - return 1; - } + /* +ideasman42 2012/05/17 09:04:35 +also mode == 1 isnt so readable, better define an enum. +*/ - /* mode 2 == replace null weights*/ - else if(mode == 2){ - /* loop through the vertices and copy weight from nearest weight*/ - for(i=0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ - /*reset nearest*/ - nearest.index = -1; - nearest.dist = FLT_MAX; - /*transform into target space*/ - mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); - /*node tree accelerated search for closest face*/ - BLI_bvhtree_find_nearest(tree_mesh_faces_src.tree, tmp_co, &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src); - /*get distances*/ - dist_v1 = len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v1].co); - dist_v2 = len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v2].co); - dist_v3 = len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v3].co); - /*get weight from triangle*/ - if(dist_v1 < dist_v2 && dist_v1 < dist_v3){ - dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v1], index_src); - } - else if(dist_v2 < dist_v3){ - dw_src = defvert_verify_index(dv_array_src[mface_src[nearest.index].v2], index_src); - } - else{ - dw_src = defvert_verify_index(dv_array_src[mface_src[nearest.index].v3], index_src); - } - /*check for and get weight from quad*/ - if(mface_src[nearest.index].v4){ - dist_v4 = len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v4].co); - if(dist_v4 < dist_v1 && dist_v4 < dist_v2 && dist_v4 < dist_v3){ - dw_src = defvert_verify_index(dv_array_src[mface_src[nearest.index].v4], index_src); - } - } - /*copy weight*/ - dw_dst = defvert_verify_index(*dv_array_dst, index_dst); - /*check if destination weight is null or zero*/ - if(!dw_dst->weight || dw_dst->weight == 0) dw_dst->weight = dw_src->weight; + /* loop through the vertices and copy weight from nearest weight*/ + for(i = 0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ + /*reset nearest*/ + nearest.index = -1; + nearest.dist = FLT_MAX; + /*transform into target space*/ + mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); + /*node tree accelerated search for closest face*/ + BLI_bvhtree_find_nearest(tree_mesh_faces_src.tree, tmp_co, &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src); + /*get distances*/ + dist_v1 = len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v1].co); + dist_v2 = len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v2].co); + dist_v3 = len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v3].co); + /*get weight from triangle*/ + if(dist_v1 < dist_v2 && dist_v1 < dist_v3){ + dw_src = defvert_verify_index(dv_array_src[mface_src[nearest.index].v1], index_src); } - /*free memory and return*/ - free_bvhtree_from_mesh(&tree_mesh_faces_src); - return 1; - } - - /* mode 3 == replace selected weights*/ - else if(mode == 3){ - /* loop through the vertices and copy weight from nearest weight*/ - for(i = 0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ - /*reset nearest*/ - nearest.index = -1; - nearest.dist = FLT_MAX; - /*transform into target space*/ - mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); - /*node tree accelerated search for closest face*/ - BLI_bvhtree_find_nearest(tree_mesh_faces_src.tree, tmp_co, &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src); - /*get distances*/ - dist_v1 = len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v1].co); - dist_v2 = len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v2].co); - dist_v3 = len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v3].co); - /*get weight from triangle*/ - if(dist_v1 < dist_v2 && dist_v1 < dist_v3){ - dw_src = defvert_verify_index(dv_array_src[mface_src[nearest.index].v1], index_src); - } - else if(dist_v2 < dist_v3){ - dw_src = defvert_verify_index(dv_array_src[mface_src[nearest.index].v2], index_src); - } - else{ - dw_src = defvert_verify_index(dv_array_src[mface_src[nearest.index].v3], index_src); - } - /*check for and get weight from quad*/ - if(mface_src[nearest.index].v4){ - dist_v4 = len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v4].co); - if(dist_v4 < dist_v1 && dist_v4 < dist_v2 && dist_v4 < dist_v3){ - dw_src = defvert_verify_index(dv_array_src[mface_src[nearest.index].v4], index_src); - } - } - /*copy weight*/ - dw_dst = defvert_verify_index(*dv_array_dst, index_dst); - /*dw_dst->weight= dw_src->weight;*/ /*TODO: fix this!*/ + else if(dist_v2 < dist_v3){ + dw_src = defvert_verify_index(dv_array_src[mface_src[nearest.index].v2], index_src); } - /*free memory and return*/ - free_bvhtree_from_mesh(&tree_mesh_faces_src); - return 1; + else{ + dw_src = defvert_verify_index(dv_array_src[mface_src[nearest.index].v3], index_src); + } + /*check for and get weight from quad*/ + if(mface_src[nearest.index].v4){ + dist_v4 = len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v4].co); + if(dist_v4 < dist_v1 && dist_v4 < dist_v2 && dist_v4 < dist_v3){ + dw_src = defvert_verify_index(dv_array_src[mface_src[nearest.index].v4], index_src); + } + } + /*copy weight*/ + dw_dst = defvert_verify_index(*dv_array_dst, index_dst); + if(mode == 1) dw_dst->weight = dw_src->weight; + else if(mode == 2) {if(!dw_dst->weight || dw_dst->weight == 0) dw_dst->weight = dw_src->weight;} + else if(mode == 3) {dw_dst->weight= dw_src->weight;}/*TODO: fix this!*/ + else return 0; } - else return 0; + /*free memory and return*/ + free_bvhtree_from_mesh(&tree_mesh_faces_src); + return 1; } -int ED_vgroup_transfer_weight_by_nearest_face_all(Object *ob_dst, Object *ob_src, short mode) -{ - ob_dst = ob_dst; - ob_src = ob_src; - return mode; -} - -int ED_vgroup_transfer_weight_by_nearest_face_single(Object *ob_dst, Object *ob_src, short mode) +int ED_vgroup_transfer_weight_by_nearest_face(Object *ob_dst, Object *ob_src, short mode, short option) { bDeformGroup *dg_src, *dg_dst; Mesh *me_dst; @@ -839,6 +665,9 @@ int ED_vgroup_transfer_weight_by_nearest_face_single(Object *ob_dst, Object *ob_ int dv_tot_src, dv_tot_dst, i, index_dst, index_src; float weight, tmp_weight[4], tmp_co[3], normal[3], tmp_mat[4][4]; + /*remove this:*/ + option=option; + /*get source deform group*/ dg_src = BLI_findlink(&ob_src->defbase, (ob_src->actdef-1)); @@ -878,106 +707,38 @@ int ED_vgroup_transfer_weight_by_nearest_face_single(Object *ob_dst, Object *ob_ invert_m4_m4(ob_src->imat, ob_src->obmat); mult_m4_m4m4(tmp_mat, ob_src->imat, ob_dst->obmat); - /* mode 1 == replace all weights*/ - if(mode == 1){ - /* loop through the vertices and copy weight from nearest weight*/ - for(i = 0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ - /*reset nearest*/ - nearest.index = -1; - nearest.dist = FLT_MAX; - /*transform into target space*/ - mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); - normal_tri_v3(normal, mv_src[mface_src[nearest.index].v1].co, mv_src[mface_src[nearest.index].v2].co, mv_src[mface_src[nearest.index].v3].co); - /*node tree accelerated search for closest face*/ - BLI_bvhtree_find_nearest(tree_mesh_faces_src.tree, tmp_co, &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src); - /*project onto face*/ - project_v3_plane(tmp_co, normal, mv_src[mface_src[nearest.index].v1].co); - /*interpolate weights*/ - interp_weights_face_v3(tmp_weight, mv_src[mface_src[nearest.index].v1].co, - mv_src[mface_src[nearest.index].v2].co, - mv_src[mface_src[nearest.index].v3].co, - mv_src[mface_src[nearest.index].v4].co, tmp_co); - /*get weights*/ - weight = tmp_weight[0] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v1], index_src)->weight; - weight += tmp_weight[1] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v2], index_src)->weight; - weight += tmp_weight[2] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v3], index_src)->weight; - weight += tmp_weight[3] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v4], index_src)->weight; - /*copy weight*/ - dw_dst = defvert_verify_index(*dv_array_dst, index_dst); - dw_dst->weight = weight; - } - /*free memory and return*/ - free_bvhtree_from_mesh(&tree_mesh_faces_src); - return 1; + /* loop through the vertices and copy weight from nearest weight*/ + for(i = 0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ + /*reset nearest*/ + nearest.index = -1; + nearest.dist = FLT_MAX; + /*transform into target space*/ + mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); + normal_tri_v3(normal, mv_src[mface_src[nearest.index].v1].co, mv_src[mface_src[nearest.index].v2].co, mv_src[mface_src[nearest.index].v3].co); + /*node tree accelerated search for closest face*/ + BLI_bvhtree_find_nearest(tree_mesh_faces_src.tree, tmp_co, &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src); + /*project onto face*/ + project_v3_plane(tmp_co, normal, mv_src[mface_src[nearest.index].v1].co); + /*interpolate weights*/ + interp_weights_face_v3(tmp_weight, mv_src[mface_src[nearest.index].v1].co, + mv_src[mface_src[nearest.index].v2].co, + mv_src[mface_src[nearest.index].v3].co, + mv_src[mface_src[nearest.index].v4].co, tmp_co); + /*get weights*/ + weight = tmp_weight[0] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v1], index_src)->weight; + weight += tmp_weight[1] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v2], index_src)->weight; + weight += tmp_weight[2] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v3], index_src)->weight; + weight += tmp_weight[3] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v4], index_src)->weight; + /*copy weight*/ + dw_dst = defvert_verify_index(*dv_array_dst, index_dst); + if(mode == 1) dw_dst->weight = weight; + else if(mode == 2) {if(!dw_dst->weight || dw_dst->weight == 0) dw_dst->weight = weight;} + else if(mode == 3) {dw_dst->weight= weight;}/*TODO: fix this!*/ + else return 0; } - - /* mode 2 == replace null weights*/ - else if(mode == 2){ - /* loop through the vertices and copy weight from nearest weight*/ - for(i = 0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ - /*reset nearest*/ - nearest.index = -1; - nearest.dist = FLT_MAX; - /*transform into target space*/ - mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); - normal_tri_v3(normal, mv_src[mface_src[nearest.index].v1].co, mv_src[mface_src[nearest.index].v2].co, mv_src[mface_src[nearest.index].v3].co); - /*node tree accelerated search for closest face*/ - BLI_bvhtree_find_nearest(tree_mesh_faces_src.tree, tmp_co, &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src); - /*project onto face*/ - project_v3_plane(tmp_co, normal, mv_src[mface_src[nearest.index].v1].co); - /*interpolate weights*/ - interp_weights_face_v3(tmp_weight, mv_src[mface_src[nearest.index].v1].co, - mv_src[mface_src[nearest.index].v2].co, - mv_src[mface_src[nearest.index].v3].co, - mv_src[mface_src[nearest.index].v4].co, tmp_co); - /*get weights*/ - weight = tmp_weight[0] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v1], index_src)->weight; - weight += tmp_weight[1] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v2], index_src)->weight; - weight += tmp_weight[2] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v3], index_src)->weight; - weight += tmp_weight[3] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v4], index_src)->weight; - /*copy weight*/ - dw_dst = defvert_verify_index(*dv_array_dst, index_dst); - /*check if destination weight is null or zero and copy weight*/ - if(!dw_dst->weight || dw_dst->weight == 0) dw_dst->weight = weight; - } - /*free memory and return*/ - free_bvhtree_from_mesh(&tree_mesh_faces_src); - return 1; - } - - /* mode 3 == replace selected weights*/ - else if(mode == 3){ - /* loop through the vertices and copy weight from nearest weight*/ - for(i = 0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ - /*reset nearest*/ - nearest.index = -1; - nearest.dist = FLT_MAX; - /*transform into target space*/ - mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); - normal_tri_v3(normal, mv_src[mface_src[nearest.index].v1].co, mv_src[mface_src[nearest.index].v2].co, mv_src[mface_src[nearest.index].v3].co); - /*node tree accelerated search for closest face*/ - BLI_bvhtree_find_nearest(tree_mesh_faces_src.tree, tmp_co, &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src); - /*project onto face*/ - project_v3_plane(tmp_co, normal, mv_src[mface_src[nearest.index].v1].co); - /*interpolate weights*/ - interp_weights_face_v3(tmp_weight, mv_src[mface_src[nearest.index].v1].co, - mv_src[mface_src[nearest.index].v2].co, - mv_src[mface_src[nearest.index].v3].co, - mv_src[mface_src[nearest.index].v4].co, tmp_co); - /*get weights*/ - weight = tmp_weight[0] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v1], index_src)->weight; - weight += tmp_weight[1] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v2], index_src)->weight; - weight += tmp_weight[2] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v3], index_src)->weight; - weight += tmp_weight[3] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v4], index_src)->weight; - /*copy weight*/ - dw_dst = defvert_verify_index(*dv_array_dst, index_dst); - /*dw_dst->weight= weight;*//*TODO: fix this!*/ - } - /*free memory and return*/ - free_bvhtree_from_mesh(&tree_mesh_faces_src); - return 1; - } - else return 0; + /*free memory and return*/ + free_bvhtree_from_mesh(&tree_mesh_faces_src); + return 1; } /********************** End transfer weight functions *********************/ @@ -3396,6 +3157,16 @@ static int vertex_group_copy_to_selected_single_exec(bContext *C, wmOperator *op return OPERATOR_FINISHED; } +/* +ideasman42 2012/05/17 09:04:35 +suggest to have one operator with single vgroup as an option, if this is a hassle, it can be done later. + +example properties?: + * properties * + prop = RNA_def_enum(ot->srna, "group", vgroup_items, 0, "Group", "Vertex group to set as active"); + RNA_def_enum_funcs(prop, vgroup_itemf); + ot->prop = prop; +*/ /*Transfer vertex group with weight to selected*/ void OBJECT_OT_vertex_group_copy_to_selected_single(wmOperatorType *ot) { @@ -3418,87 +3189,39 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) int change = 0; int fail = 0; - /*TODO: get this parameter*/ - enum option {single =1, all =2} option= 1; + /*TODO: get these parameters*/ + enum Function {by_index = 1, by_nearest_vertex = 2, by_nearest_face = 3, by_nearest_vertex_in_face = 4} function = 4; + /*TODO: pass these on to functions*/ + enum Mode {replace_all_weights = 1, replace_empty_weights = 2, replace_selected_weights = 3} mode= 1; + enum Option {single = 1, all = 2} option = 1; - /*TODO: get this parameter*/ - enum method {by_index = 1, by_nearest_vertex = 2, by_nearest_face = 3, by_nearest_vertex_in_face = 4} method = 4; - - /*TODO: get this parameter*/ - /* mode is passed on to lower funtions*/ - short mode = 2; - - /* mode 1 == replace all weights*/ - /* mode 2 == replace null weights*/ - /* mode 3 == replace selected weights*/ - - /*Truth table for testing:----*/ - /*1,1,1 Tested and working.*/ - /*1,1,2 Tested and working.*/ - /*1,1,3 Tested and NOT working.*/ - /*1,2,1 Tested and working.*/ - /*1,2,2 Tested and working.*/ - /*1,2,3 Tested and NOT working.*/ - /*1,3,1 Tested and working.*/ - /*1,3,2 Tested and working.*/ - /*1,3,3 Tested and NOT working.*/ - /*1,4,1 Tested and working.*/ - /*1,4,2 Tested and working.*/ - /*1,4,3 Tested and NOT working.*/ - - /*Macro to loop through selected objects and perform operation depending on option and method*/ + /*Macro to loop through selected objects and perform operation depending on function, option and method*/ CTX_DATA_BEGIN(C, Object*, obslc, selected_editable_objects) { - if(obact != obslc) { - switch(option){ - - /*single*/ - case(single): - switch(method){ + if(obact != obslc){ + switch(function){ case(by_index): - if(ED_vgroup_transfer_weight_by_index_single(obslc, obact, mode)) change++; + if(ED_vgroup_transfer_weight_by_index(obslc, obact, mode, option)) change++; else fail++; break; case(by_nearest_vertex): - if(ED_vgroup_transfer_weight_by_nearest_vertex_single(obslc, obact, mode)) change++; + if(ED_vgroup_transfer_weight_by_nearest_vertex(obslc, obact, mode, option)) change++; else fail++; break; case(by_nearest_face): - if(ED_vgroup_transfer_weight_by_nearest_vertex_in_face_single(obslc, obact, mode)) change++; + if(ED_vgroup_transfer_weight_by_nearest_face(obslc, obact, mode, option)) change++; else fail++; break; case(by_nearest_vertex_in_face): - if(ED_vgroup_transfer_weight_by_nearest_face_single(obslc, obact, mode)) change++; + if(ED_vgroup_transfer_weight_by_nearest_vertex_in_face(obslc, obact, mode, option)) change++; else fail++; break; - } - - /*all*/ - case(all): - switch(method){ - case(by_index): - /*if(ED_vgroup_transfer_weight_by_index_all(obslc, obact, mode)) change++; - else fail++;*/ break; - - case(by_nearest_vertex): - /*if(ED_vgroup_transfer_weight_by_nearest_vertex_all(obslc, obact, mode)) change++; - else fail++;*/ break; - - case(by_nearest_vertex_in_face): - /*if(ED_vgroup_transfer_weight_by_nearest_vertex_in_face_all(obslc, obact, mode)) change++; - else fail++;*/ break; - - case(by_nearest_face): - /*if(ED_vgroup_transfer_weight_by_nearest_face_all(obslc, obact, mode)) change++; - else fail++;*/ break; - } } - - /*Event notifiers for correct display of data*/ - DAG_id_tag_update(&obslc->id, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, obslc); - WM_event_add_notifier(C, NC_GEOM|ND_DATA, obslc->data); } + /*Event notifiers for correct display of data*/ + DAG_id_tag_update(&obslc->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, obslc); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obslc->data); } CTX_DATA_END; From 8521ca69fac26ebfa14910566f2271562e1ff0b5 Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Thu, 17 May 2012 12:36:07 +0000 Subject: [PATCH 035/347] removed: OBJECT_OT_vertex_group_copy_to_selected_single() plan for future to implement option as an argument in: OBJECT_OT_vertex_group_copy_to_selected() --- source/blender/editors/object/object_intern.h | 1 - source/blender/editors/object/object_ops.c | 1 - source/blender/editors/object/object_vgroup.c | 71 ++++--------------- 3 files changed, 13 insertions(+), 60 deletions(-) diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index 5269caab426..4d67a620939 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -198,7 +198,6 @@ void OBJECT_OT_vertex_group_deselect(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_copy_to_linked(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_transfer_weight(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_copy_to_selected(struct wmOperatorType *ot); -void OBJECT_OT_vertex_group_copy_to_selected_single(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_copy(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_normalize(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_normalize_all(struct wmOperatorType *ot); diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index 7e535eed29d..986a294d065 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -172,7 +172,6 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_vertex_group_copy_to_linked); WM_operatortype_append(OBJECT_OT_vertex_group_transfer_weight); WM_operatortype_append(OBJECT_OT_vertex_group_copy_to_selected); - WM_operatortype_append(OBJECT_OT_vertex_group_copy_to_selected_single); WM_operatortype_append(OBJECT_OT_vertex_group_copy); WM_operatortype_append(OBJECT_OT_vertex_group_normalize); WM_operatortype_append(OBJECT_OT_vertex_group_normalize_all); diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index d1622e507d0..41fbbfdac14 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -437,6 +437,7 @@ int ED_vgroup_transfer_weight_by_index(Object *ob_dst, Object *ob_src, short mod /*remove this:*/ option=option; + /*TODO: for option all, loop through all vertex groups*/ /*get source deform group*/ dg_src = BLI_findlink(&ob_src->defbase, (ob_src->actdef-1)); @@ -3110,6 +3111,10 @@ static int vertex_group_copy_to_selected_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } +/* +ideasman42 2012/05/17 09:04:35 +suggest to have one operator with single vgroup as an option, if this is a hassle, it can be done later. +*/ void OBJECT_OT_vertex_group_copy_to_selected(wmOperatorType *ot) { /* identifiers */ @@ -3125,64 +3130,6 @@ void OBJECT_OT_vertex_group_copy_to_selected(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } -static int vertex_group_copy_to_selected_single_exec(bContext *C, wmOperator *op) -{ - Object *obact = CTX_data_active_object(C); - int change = 0; - int fail = 0; - - /*Macro to loop through selected objects and perform operation*/ - CTX_DATA_BEGIN(C, Object*, obslc, selected_editable_objects) - { - if(obact != obslc) { - /*Try function for matching indices*/ - if(ED_vgroup_copy_single(obslc, obact)) change++; - /*Trigger error message*/ - else fail++; - /*Event notifiers for correct display of data*/ - DAG_id_tag_update(&obslc->id, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, obslc); - WM_event_add_notifier(C, NC_GEOM|ND_DATA, obslc->data); - } - } - CTX_DATA_END; - - /*Report error when task can not be completed with available functions.*/ - if((change == 0 && fail == 0) || fail) { - BKE_reportf(op->reports, RPT_ERROR, - "Copy to VGroups to Selected single warning done %d, failed %d, object data must have matching indices", - change, fail); - } - - return OPERATOR_FINISHED; -} - -/* -ideasman42 2012/05/17 09:04:35 -suggest to have one operator with single vgroup as an option, if this is a hassle, it can be done later. - -example properties?: - * properties * - prop = RNA_def_enum(ot->srna, "group", vgroup_items, 0, "Group", "Vertex group to set as active"); - RNA_def_enum_funcs(prop, vgroup_itemf); - ot->prop = prop; -*/ -/*Transfer vertex group with weight to selected*/ -void OBJECT_OT_vertex_group_copy_to_selected_single(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Copy a Vertex Group to Selected"; - ot->idname = "OBJECT_OT_vertex_group_copy_to_selected_single"; - ot->description = "Copy a vertex group to other selected objects with matching indices"; - - /* api callbacks */ - ot->poll = vertex_group_poll; - ot->exec = vertex_group_copy_to_selected_single_exec; - - /* flags */ - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; -} - static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) { Object *obact = CTX_data_active_object(C); @@ -3249,6 +3196,14 @@ void OBJECT_OT_vertex_group_transfer_weight(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + + /* + example properties?: + * properties * + prop = RNA_def_enum(ot->srna, "group", vgroup_items, 0, "Group", "Vertex group to set as active"); + RNA_def_enum_funcs(prop, vgroup_itemf); + ot->prop = prop; + */ } static EnumPropertyItem vgroup_items[] = { From 79031d35f1a180bed1212c15649bd2593c7de580 Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Mon, 21 May 2012 17:00:08 +0000 Subject: [PATCH 036/347] Added support for replace_selected_weights in all weight transfer fucntions. --- source/blender/editors/object/object_vgroup.c | 58 +++++++++++-------- 1 file changed, 34 insertions(+), 24 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 41fbbfdac14..8a82f2ae107 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -431,6 +431,8 @@ int ED_vgroup_transfer_weight_by_index(Object *ob_dst, Object *ob_src, short mod MDeformVert **dv_array_src; MDeformVert **dv_array_dst; MDeformWeight *dw_dst, *dw_src; + MVert *mv_src; + Mesh *me_src; int dv_tot_src, dv_tot_dst; int i, index_src, index_dst; bDeformGroup *dg_src, *dg_dst; @@ -448,6 +450,12 @@ int ED_vgroup_transfer_weight_by_index(Object *ob_dst, Object *ob_src, short mod ED_vgroup_add_name(ob_dst, dg_src->name); } + /*get meshes*/ + me_src = ob_src->data; + + /*get vertices*/ + mv_src = me_src->mvert; + /*get destination deformgroup*/ dg_dst = defgroup_find_name(ob_dst, dg_src->name); @@ -460,18 +468,18 @@ int ED_vgroup_transfer_weight_by_index(Object *ob_dst, Object *ob_src, short mod index_dst = BLI_findindex(&ob_dst->defbase, dg_dst); /*check if indices are matching, delete and return if not*/ - if (ob_dst == ob_src || dv_tot_dst == 0 || (dv_tot_dst != dv_tot_src) || dv_array_src == NULL || dv_array_dst == NULL) { + if(ob_dst == ob_src || dv_tot_dst == 0 || (dv_tot_dst != dv_tot_src) || dv_array_src == NULL || dv_array_dst == NULL) { ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_dst->name)); return 0; } /* loop through the vertices and copy weight*/ - for(i = 0; i < dv_tot_dst; i++, dv_array_src++, dv_array_dst++){ + for(i = 0; i < dv_tot_dst; i++, dv_array_src++, dv_array_dst++, mv_src++){ dw_src = defvert_verify_index(*dv_array_src, index_src); dw_dst = defvert_verify_index(*dv_array_dst, index_dst); if(mode == 1) dw_dst->weight = dw_src->weight; else if(mode == 2) {if(!dw_dst->weight || dw_dst->weight == 0) dw_dst->weight = dw_src->weight;} - else if(mode == 3) {if((*dv_array_src)->flag == 1) dw_dst->weight = dw_src->weight;}/*This does not work*/ + else if(mode == 3) {if(mv_src->flag == 1) dw_dst->weight = dw_src->weight;} else return 0; } return 1; @@ -482,8 +490,8 @@ int ED_vgroup_transfer_weight_by_nearest_vertex(Object *ob_dst, Object *ob_src, bDeformGroup *dg_src, *dg_dst; MDeformVert **dv_array_src, **dv_array_dst; MDeformWeight *dw_dst, *dw_src; - MVert *mv_dst; - Mesh *me_dst; + MVert *mv_dst, *mv_src; + Mesh *me_dst, *me_src; BVHTreeFromMesh tree_mesh_src; BVHTreeNearest nearest; DerivedMesh *dmesh_src; @@ -507,6 +515,7 @@ int ED_vgroup_transfer_weight_by_nearest_vertex(Object *ob_dst, Object *ob_src, /*get meshes*/ me_dst = ob_dst->data; + me_src = ob_src->data; dmesh_src = ob_src->derivedDeform; /*make node tree*/ @@ -522,6 +531,7 @@ int ED_vgroup_transfer_weight_by_nearest_vertex(Object *ob_dst, Object *ob_src, /*get vertices*/ mv_dst = me_dst->mvert; + mv_src = me_src->mvert; /*prepare transformation matrix*/ /*this can be excluded to make a lazy feature that works better when object centers relative to mesh is the same*/ @@ -541,7 +551,7 @@ int ED_vgroup_transfer_weight_by_nearest_vertex(Object *ob_dst, Object *ob_src, dw_dst = defvert_verify_index(*dv_array_dst, index_dst); if(mode == 1) dw_dst->weight = dw_src->weight; else if(mode == 2) {if(!dw_dst->weight || dw_dst->weight == 0) dw_dst->weight = dw_src->weight;} - else if(mode == 3) {dw_dst->weight= dw_src->weight;}/*TODO fix this*/ + else if(mode == 3) {if(mv_src[nearest.index].flag == 1) dw_dst->weight = dw_src->weight;} else return 0; } /*free memory and return*/ @@ -560,7 +570,7 @@ int ED_vgroup_transfer_weight_by_nearest_vertex_in_face(Object *ob_dst, Object * MFace *mface_src; BVHTreeNearest nearest; MDeformWeight *dw_dst, *dw_src; - int dv_tot_src, dv_tot_dst, i, index_dst, index_src; + int dv_tot_src, dv_tot_dst, i, index_dst, index_src, index_nearest_vertex; float dist_v1, dist_v2, dist_v3, dist_v4, tmp_co[3], tmp_mat[4][4]; /*remove this:*/ @@ -623,28 +633,21 @@ also mode == 1 isnt so readable, better define an enum. dist_v1 = len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v1].co); dist_v2 = len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v2].co); dist_v3 = len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v3].co); - /*get weight from triangle*/ - if(dist_v1 < dist_v2 && dist_v1 < dist_v3){ - dw_src = defvert_verify_index(dv_array_src[mface_src[nearest.index].v1], index_src); - } - else if(dist_v2 < dist_v3){ - dw_src = defvert_verify_index(dv_array_src[mface_src[nearest.index].v2], index_src); - } - else{ - dw_src = defvert_verify_index(dv_array_src[mface_src[nearest.index].v3], index_src); - } - /*check for and get weight from quad*/ + /*get closest vertex*/ + if(dist_v1 < dist_v2 && dist_v1 < dist_v3) index_nearest_vertex = mface_src[nearest.index].v1; + else if(dist_v2 < dist_v3) index_nearest_vertex = mface_src[nearest.index].v2; + else index_nearest_vertex = mface_src[nearest.index].v3; if(mface_src[nearest.index].v4){ dist_v4 = len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v4].co); - if(dist_v4 < dist_v1 && dist_v4 < dist_v2 && dist_v4 < dist_v3){ - dw_src = defvert_verify_index(dv_array_src[mface_src[nearest.index].v4], index_src); - } + if(dist_v4 < dist_v1 && dist_v4 < dist_v2 && dist_v4 < dist_v3) index_nearest_vertex = mface_src[nearest.index].v1; } /*copy weight*/ + dw_src = defvert_verify_index(dv_array_src[index_nearest_vertex], index_src); dw_dst = defvert_verify_index(*dv_array_dst, index_dst); if(mode == 1) dw_dst->weight = dw_src->weight; else if(mode == 2) {if(!dw_dst->weight || dw_dst->weight == 0) dw_dst->weight = dw_src->weight;} - else if(mode == 3) {dw_dst->weight= dw_src->weight;}/*TODO: fix this!*/ + /*ATTENTION: face select in weightpaint mode seems reversed. Might create bug when fixed*/ + else if(mode == 3) {if(mface_src[nearest.index].flag != SELECT) dw_dst->weight = dw_src->weight;} else return 0; } /*free memory and return*/ @@ -734,7 +737,8 @@ int ED_vgroup_transfer_weight_by_nearest_face(Object *ob_dst, Object *ob_src, sh dw_dst = defvert_verify_index(*dv_array_dst, index_dst); if(mode == 1) dw_dst->weight = weight; else if(mode == 2) {if(!dw_dst->weight || dw_dst->weight == 0) dw_dst->weight = weight;} - else if(mode == 3) {dw_dst->weight= weight;}/*TODO: fix this!*/ + /*ATTENTION: face select in weightpaint mode seems reversed. Might create bug when fixed*/ + else if(mode == 3) {if(mface_src[nearest.index].flag != SELECT) dw_dst->weight = weight;} else return 0; } /*free memory and return*/ @@ -3139,9 +3143,15 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) /*TODO: get these parameters*/ enum Function {by_index = 1, by_nearest_vertex = 2, by_nearest_face = 3, by_nearest_vertex_in_face = 4} function = 4; /*TODO: pass these on to functions*/ - enum Mode {replace_all_weights = 1, replace_empty_weights = 2, replace_selected_weights = 3} mode= 1; + enum Mode {replace_all_weights = 1, replace_empty_weights = 2, replace_selected_weights = 3} mode= 3; enum Option {single = 1, all = 2} option = 1; + /*Truth table for testing:*/ + /*1,3,1 working*/ + /*2,3,1 working*/ + /*3,3,1 working*/ + /*4,3,1 working*/ + /*Macro to loop through selected objects and perform operation depending on function, option and method*/ CTX_DATA_BEGIN(C, Object*, obslc, selected_editable_objects) { From cc5582decbbe1c548cfb6d12958680025617e787 Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Mon, 21 May 2012 17:39:56 +0000 Subject: [PATCH 037/347] Fixed SELECT comparisons --- source/blender/editors/object/object_vgroup.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 8a82f2ae107..648f83c9c48 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -479,7 +479,7 @@ int ED_vgroup_transfer_weight_by_index(Object *ob_dst, Object *ob_src, short mod dw_dst = defvert_verify_index(*dv_array_dst, index_dst); if(mode == 1) dw_dst->weight = dw_src->weight; else if(mode == 2) {if(!dw_dst->weight || dw_dst->weight == 0) dw_dst->weight = dw_src->weight;} - else if(mode == 3) {if(mv_src->flag == 1) dw_dst->weight = dw_src->weight;} + else if(mode == 3) {if(mv_src->flag & SELECT) dw_dst->weight = dw_src->weight;} else return 0; } return 1; @@ -551,7 +551,7 @@ int ED_vgroup_transfer_weight_by_nearest_vertex(Object *ob_dst, Object *ob_src, dw_dst = defvert_verify_index(*dv_array_dst, index_dst); if(mode == 1) dw_dst->weight = dw_src->weight; else if(mode == 2) {if(!dw_dst->weight || dw_dst->weight == 0) dw_dst->weight = dw_src->weight;} - else if(mode == 3) {if(mv_src[nearest.index].flag == 1) dw_dst->weight = dw_src->weight;} + else if(mode == 3) {if(mv_src[nearest.index].flag & SELECT) dw_dst->weight = dw_src->weight;} else return 0; } /*free memory and return*/ @@ -646,8 +646,7 @@ also mode == 1 isnt so readable, better define an enum. dw_dst = defvert_verify_index(*dv_array_dst, index_dst); if(mode == 1) dw_dst->weight = dw_src->weight; else if(mode == 2) {if(!dw_dst->weight || dw_dst->weight == 0) dw_dst->weight = dw_src->weight;} - /*ATTENTION: face select in weightpaint mode seems reversed. Might create bug when fixed*/ - else if(mode == 3) {if(mface_src[nearest.index].flag != SELECT) dw_dst->weight = dw_src->weight;} + else if(mode == 3) {if(mface_src[nearest.index].flag & ME_FACE_SEL) dw_dst->weight = dw_src->weight;} else return 0; } /*free memory and return*/ @@ -737,8 +736,7 @@ int ED_vgroup_transfer_weight_by_nearest_face(Object *ob_dst, Object *ob_src, sh dw_dst = defvert_verify_index(*dv_array_dst, index_dst); if(mode == 1) dw_dst->weight = weight; else if(mode == 2) {if(!dw_dst->weight || dw_dst->weight == 0) dw_dst->weight = weight;} - /*ATTENTION: face select in weightpaint mode seems reversed. Might create bug when fixed*/ - else if(mode == 3) {if(mface_src[nearest.index].flag != SELECT) dw_dst->weight = weight;} + else if(mode == 3) {if(mface_src[nearest.index].flag & ME_FACE_SEL) dw_dst->weight = weight;} else return 0; } /*free memory and return*/ From 6913e6dd54a5f819838adef6374bb6a9996d0d81 Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Mon, 21 May 2012 18:15:12 +0000 Subject: [PATCH 038/347] Changed functions to check for select on destination instead of source --- source/blender/editors/object/object_vgroup.c | 24 +++++++++---------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 648f83c9c48..3fac2a7c98f 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -431,8 +431,8 @@ int ED_vgroup_transfer_weight_by_index(Object *ob_dst, Object *ob_src, short mod MDeformVert **dv_array_src; MDeformVert **dv_array_dst; MDeformWeight *dw_dst, *dw_src; - MVert *mv_src; - Mesh *me_src; + MVert *mv_dst; + Mesh *me_dst; int dv_tot_src, dv_tot_dst; int i, index_src, index_dst; bDeformGroup *dg_src, *dg_dst; @@ -451,10 +451,10 @@ int ED_vgroup_transfer_weight_by_index(Object *ob_dst, Object *ob_src, short mod } /*get meshes*/ - me_src = ob_src->data; + me_dst = ob_dst->data; /*get vertices*/ - mv_src = me_src->mvert; + mv_dst = me_dst->mvert; /*get destination deformgroup*/ dg_dst = defgroup_find_name(ob_dst, dg_src->name); @@ -474,12 +474,12 @@ int ED_vgroup_transfer_weight_by_index(Object *ob_dst, Object *ob_src, short mod } /* loop through the vertices and copy weight*/ - for(i = 0; i < dv_tot_dst; i++, dv_array_src++, dv_array_dst++, mv_src++){ + for(i = 0; i < dv_tot_dst; i++, dv_array_src++, dv_array_dst++, mv_dst++){ dw_src = defvert_verify_index(*dv_array_src, index_src); dw_dst = defvert_verify_index(*dv_array_dst, index_dst); if(mode == 1) dw_dst->weight = dw_src->weight; else if(mode == 2) {if(!dw_dst->weight || dw_dst->weight == 0) dw_dst->weight = dw_src->weight;} - else if(mode == 3) {if(mv_src->flag & SELECT) dw_dst->weight = dw_src->weight;} + else if(mode == 3) {if(mv_dst->flag & SELECT) dw_dst->weight = dw_src->weight;} else return 0; } return 1; @@ -490,8 +490,8 @@ int ED_vgroup_transfer_weight_by_nearest_vertex(Object *ob_dst, Object *ob_src, bDeformGroup *dg_src, *dg_dst; MDeformVert **dv_array_src, **dv_array_dst; MDeformWeight *dw_dst, *dw_src; - MVert *mv_dst, *mv_src; - Mesh *me_dst, *me_src; + MVert *mv_dst; + Mesh *me_dst; BVHTreeFromMesh tree_mesh_src; BVHTreeNearest nearest; DerivedMesh *dmesh_src; @@ -515,7 +515,6 @@ int ED_vgroup_transfer_weight_by_nearest_vertex(Object *ob_dst, Object *ob_src, /*get meshes*/ me_dst = ob_dst->data; - me_src = ob_src->data; dmesh_src = ob_src->derivedDeform; /*make node tree*/ @@ -531,7 +530,6 @@ int ED_vgroup_transfer_weight_by_nearest_vertex(Object *ob_dst, Object *ob_src, /*get vertices*/ mv_dst = me_dst->mvert; - mv_src = me_src->mvert; /*prepare transformation matrix*/ /*this can be excluded to make a lazy feature that works better when object centers relative to mesh is the same*/ @@ -551,7 +549,7 @@ int ED_vgroup_transfer_weight_by_nearest_vertex(Object *ob_dst, Object *ob_src, dw_dst = defvert_verify_index(*dv_array_dst, index_dst); if(mode == 1) dw_dst->weight = dw_src->weight; else if(mode == 2) {if(!dw_dst->weight || dw_dst->weight == 0) dw_dst->weight = dw_src->weight;} - else if(mode == 3) {if(mv_src[nearest.index].flag & SELECT) dw_dst->weight = dw_src->weight;} + else if(mode == 3) {if(mv_dst->flag & SELECT) dw_dst->weight = dw_src->weight;} else return 0; } /*free memory and return*/ @@ -646,7 +644,7 @@ also mode == 1 isnt so readable, better define an enum. dw_dst = defvert_verify_index(*dv_array_dst, index_dst); if(mode == 1) dw_dst->weight = dw_src->weight; else if(mode == 2) {if(!dw_dst->weight || dw_dst->weight == 0) dw_dst->weight = dw_src->weight;} - else if(mode == 3) {if(mface_src[nearest.index].flag & ME_FACE_SEL) dw_dst->weight = dw_src->weight;} + else if(mode == 3) {if(mv_dst->flag & SELECT) dw_dst->weight = dw_src->weight;} else return 0; } /*free memory and return*/ @@ -736,7 +734,7 @@ int ED_vgroup_transfer_weight_by_nearest_face(Object *ob_dst, Object *ob_src, sh dw_dst = defvert_verify_index(*dv_array_dst, index_dst); if(mode == 1) dw_dst->weight = weight; else if(mode == 2) {if(!dw_dst->weight || dw_dst->weight == 0) dw_dst->weight = weight;} - else if(mode == 3) {if(mface_src[nearest.index].flag & ME_FACE_SEL) dw_dst->weight = weight;} + else if(mode == 3) {if(mv_dst->flag & SELECT) dw_dst->weight = weight;} else return 0; } /*free memory and return*/ From c4c75c33d0dd3222285b6799da3656316776592a Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Wed, 23 May 2012 10:21:57 +0000 Subject: [PATCH 039/347] Changed structure of the entire feature/code. It should now work in 24 different ways depending on options. Its not tested in depth yet... --- source/blender/editors/object/object_vgroup.c | 410 ++++++++---------- 1 file changed, 183 insertions(+), 227 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 3fac2a7c98f..6dc954b88ad 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -376,57 +376,9 @@ int ED_vgroup_copy_array(Object *ob, Object *ob_from) return 1; } -/*ideasman42 2012/05/17 09:04:35 -the single vgroup to copy could be an argument - -allows to be more flexible later even if for now, the arg is "ob_src->actdef-1" for all callers. -*/ -/*Copy a single vertex group from source to destination with weights by identical meshes*/ -int ED_vgroup_copy_single(Object *ob_dst, const Object *ob_src) -{ - MDeformVert **dv_array_src; - MDeformVert **dv_array_dst; - MDeformWeight *dw_dst, *dw_src; - int dv_tot_src, dv_tot_dst; - int i, index_src, index_dst; - bDeformGroup *dg_src, *dg_dst; - - /*get source deform group*/ - dg_src = BLI_findlink(&ob_src->defbase, (ob_src->actdef-1)); - - /*create new and overwrite vertex group on destination without data*/ - ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_src->name)); - ED_vgroup_add_name(ob_dst, dg_src->name); - - /*get destination deformgroup*/ - dg_dst = defgroup_find_name(ob_dst, dg_src->name); - - /*get vertex group arrays*/ - ED_vgroup_give_parray(ob_src->data, &dv_array_src, &dv_tot_src, FALSE); - ED_vgroup_give_parray(ob_dst->data, &dv_array_dst, &dv_tot_dst, FALSE); - - /*get indexes of vertex groups*/ - index_src = BLI_findindex(&ob_src->defbase, dg_src); - index_dst = BLI_findindex(&ob_dst->defbase, dg_dst); - - /*check if indices are matching, delete and return if not*/ - if (ob_dst == ob_src || dv_tot_dst == 0 || (dv_tot_dst != dv_tot_src) || dv_array_src == NULL || dv_array_dst == NULL) { - ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_dst->name)); - return 0; - } - - /* loop through the vertices and copy weight*/ - for(i = 0; i < dv_tot_dst; i++, dv_array_src++, dv_array_dst++) { - dw_src = defvert_verify_index(*dv_array_src, index_src); - dw_dst = defvert_verify_index(*dv_array_dst, index_dst); - dw_dst->weight = dw_src->weight; - } - - return 1; -} - /********************** Start transfer weight functions *********************/ -int ED_vgroup_transfer_weight_by_index(Object *ob_dst, Object *ob_src, short mode, short option) +int ED_vgroup_transfer_weight_by_index(Object *ob_dst, Object *ob_src, short dw_replace_options, bDeformGroup *dg_src) { MDeformVert **dv_array_src; MDeformVert **dv_array_dst; @@ -435,17 +387,12 @@ int ED_vgroup_transfer_weight_by_index(Object *ob_dst, Object *ob_src, short mod Mesh *me_dst; int dv_tot_src, dv_tot_dst; int i, index_src, index_dst; - bDeformGroup *dg_src, *dg_dst; + bDeformGroup *dg_dst; - /*remove this:*/ - option=option; - /*TODO: for option all, loop through all vertex groups*/ - - /*get source deform group*/ - dg_src = BLI_findlink(&ob_src->defbase, (ob_src->actdef-1)); + enum dw_options {REPLACE_ALL_WEIGHTS = 1, REPLACE_EMPTY_WEIGHTS = 2, REPLACE_SELECTED_WEIGHTS = 3} dw_options = dw_replace_options; /*create new and overwrite vertex group on destination without data*/ - if(!defgroup_find_name(ob_dst, dg_src->name) || mode == 1){ + if (!defgroup_find_name(ob_dst, dg_src->name) || dw_options == 1){ ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_src->name)); ED_vgroup_add_name(ob_dst, dg_src->name); } @@ -468,26 +415,26 @@ int ED_vgroup_transfer_weight_by_index(Object *ob_dst, Object *ob_src, short mod index_dst = BLI_findindex(&ob_dst->defbase, dg_dst); /*check if indices are matching, delete and return if not*/ - if(ob_dst == ob_src || dv_tot_dst == 0 || (dv_tot_dst != dv_tot_src) || dv_array_src == NULL || dv_array_dst == NULL) { + if (ob_dst == ob_src || dv_tot_dst == 0 || (dv_tot_dst != dv_tot_src) || dv_array_src == NULL || dv_array_dst == NULL) { ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_dst->name)); return 0; } /* loop through the vertices and copy weight*/ - for(i = 0; i < dv_tot_dst; i++, dv_array_src++, dv_array_dst++, mv_dst++){ + for (i = 0; i < dv_tot_dst; i++, dv_array_src++, dv_array_dst++, mv_dst++){ dw_src = defvert_verify_index(*dv_array_src, index_src); dw_dst = defvert_verify_index(*dv_array_dst, index_dst); - if(mode == 1) dw_dst->weight = dw_src->weight; - else if(mode == 2) {if(!dw_dst->weight || dw_dst->weight == 0) dw_dst->weight = dw_src->weight;} - else if(mode == 3) {if(mv_dst->flag & SELECT) dw_dst->weight = dw_src->weight;} + if (dw_options == REPLACE_ALL_WEIGHTS) dw_dst->weight = dw_src->weight; + else if (dw_options == REPLACE_EMPTY_WEIGHTS) {if (!dw_dst->weight || dw_dst->weight == 0) dw_dst->weight = dw_src->weight;} + else if (dw_options == REPLACE_SELECTED_WEIGHTS) {if (mv_dst->flag & SELECT) dw_dst->weight = dw_src->weight;} else return 0; } return 1; } -int ED_vgroup_transfer_weight_by_nearest_vertex(Object *ob_dst, Object *ob_src, short mode, short option) +int ED_vgroup_transfer_weight_by_nearest_vertex(Object *ob_dst, Object *ob_src, short dw_replace_options, bDeformGroup *dg_src) { - bDeformGroup *dg_src, *dg_dst; + bDeformGroup *dg_dst; MDeformVert **dv_array_src, **dv_array_dst; MDeformWeight *dw_dst, *dw_src; MVert *mv_dst; @@ -498,14 +445,10 @@ int ED_vgroup_transfer_weight_by_nearest_vertex(Object *ob_dst, Object *ob_src, int dv_tot_src, dv_tot_dst, i, index_dst, index_src; float tmp_co[3], tmp_mat[4][4]; - /*remove this:*/ - option=option; - - /*get source deform group*/ - dg_src = BLI_findlink(&ob_src->defbase, (ob_src->actdef-1)); + enum dw_options {REPLACE_ALL_WEIGHTS = 1, REPLACE_EMPTY_WEIGHTS = 2, REPLACE_SELECTED_WEIGHTS = 3} dw_options = dw_replace_options; /*create new and overwrite vertex group on destination without data*/ - if(!defgroup_find_name(ob_dst, dg_src->name) || mode == 1){ + if (!defgroup_find_name(ob_dst, dg_src->name) || dw_replace_options == 1){ ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_src->name)); ED_vgroup_add_name(ob_dst, dg_src->name); } @@ -532,129 +475,37 @@ int ED_vgroup_transfer_weight_by_nearest_vertex(Object *ob_dst, Object *ob_src, mv_dst = me_dst->mvert; /*prepare transformation matrix*/ - /*this can be excluded to make a lazy feature that works better when object centers relative to mesh is the same*/ invert_m4_m4(ob_src->imat, ob_src->obmat); mult_m4_m4m4(tmp_mat, ob_src->imat, ob_dst->obmat); /* loop through the vertices and copy weight*/ - for(i = 0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ + for (i = 0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ + /*reset nearest*/ nearest.index = -1; nearest.dist = FLT_MAX; + /*transform into target space*/ mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); + /*node tree accelerated search for closest vetex*/ BLI_bvhtree_find_nearest(tree_mesh_src.tree, tmp_co, &nearest, tree_mesh_src.nearest_callback, &tree_mesh_src); dw_src = defvert_verify_index(dv_array_src[nearest.index], index_src); dw_dst = defvert_verify_index(*dv_array_dst, index_dst); - if(mode == 1) dw_dst->weight = dw_src->weight; - else if(mode == 2) {if(!dw_dst->weight || dw_dst->weight == 0) dw_dst->weight = dw_src->weight;} - else if(mode == 3) {if(mv_dst->flag & SELECT) dw_dst->weight = dw_src->weight;} + if (dw_options == REPLACE_ALL_WEIGHTS) dw_dst->weight = dw_src->weight; + else if (dw_options == REPLACE_EMPTY_WEIGHTS) {if (!dw_dst->weight || dw_dst->weight == 0) dw_dst->weight = dw_src->weight;} + else if(dw_options == REPLACE_SELECTED_WEIGHTS) {if (mv_dst->flag & SELECT) dw_dst->weight = dw_src->weight;} else return 0; } + /*free memory and return*/ free_bvhtree_from_mesh(&tree_mesh_src); return 1; } -int ED_vgroup_transfer_weight_by_nearest_vertex_in_face(Object *ob_dst, Object *ob_src, short mode, short option) +int ED_vgroup_transfer_weight_by_nearest_face(Object *ob_dst, Object *ob_src, short dw_replace_options, bDeformGroup *dg_src) { - bDeformGroup *dg_src, *dg_dst; - Mesh *me_dst; - DerivedMesh *dmesh_src; - BVHTreeFromMesh tree_mesh_faces_src = {NULL}; - MDeformVert **dv_array_src, **dv_array_dst; - MVert *mv_dst, *mv_src; - MFace *mface_src; - BVHTreeNearest nearest; - MDeformWeight *dw_dst, *dw_src; - int dv_tot_src, dv_tot_dst, i, index_dst, index_src, index_nearest_vertex; - float dist_v1, dist_v2, dist_v3, dist_v4, tmp_co[3], tmp_mat[4][4]; - - /*remove this:*/ - option=option; - - /*get source deform group*/ - dg_src = BLI_findlink(&ob_src->defbase, (ob_src->actdef-1)); - - /*create new and overwrite vertex group on destination without data*/ - if(!defgroup_find_name(ob_dst, dg_src->name) || mode == 1){ - ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_src->name)); - ED_vgroup_add_name(ob_dst, dg_src->name); - } - - /*get destination deformgroup*/ - dg_dst = defgroup_find_name(ob_dst, dg_src->name); - - /*get meshes*/ - me_dst = ob_dst->data; - dmesh_src = ob_src->derivedDeform; - - /*make node tree*/ - DM_ensure_tessface(dmesh_src); - bvhtree_from_mesh_faces(&tree_mesh_faces_src, dmesh_src, 0.0, 2, 6); - - /*get vertex group arrays*/ - ED_vgroup_give_parray(ob_src->data, &dv_array_src, &dv_tot_src, FALSE); - ED_vgroup_give_parray(ob_dst->data, &dv_array_dst, &dv_tot_dst, FALSE); - - /*get indexes of vertex groups*/ - index_src = BLI_findindex(&ob_src->defbase, dg_src); - index_dst = BLI_findindex(&ob_dst->defbase, dg_dst); - - /*get vertices*/ - mv_dst = me_dst->mvert; - mv_src = dmesh_src->getVertArray(dmesh_src); - - /*get faces*/ - mface_src = dmesh_src->getTessFaceArray(dmesh_src); - - /*prepare transformation matrix*/ - invert_m4_m4(ob_src->imat, ob_src->obmat); - mult_m4_m4m4(tmp_mat, ob_src->imat, ob_dst->obmat); - - /* -ideasman42 2012/05/17 09:04:35 -also mode == 1 isnt so readable, better define an enum. -*/ - - /* loop through the vertices and copy weight from nearest weight*/ - for(i = 0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ - /*reset nearest*/ - nearest.index = -1; - nearest.dist = FLT_MAX; - /*transform into target space*/ - mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); - /*node tree accelerated search for closest face*/ - BLI_bvhtree_find_nearest(tree_mesh_faces_src.tree, tmp_co, &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src); - /*get distances*/ - dist_v1 = len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v1].co); - dist_v2 = len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v2].co); - dist_v3 = len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v3].co); - /*get closest vertex*/ - if(dist_v1 < dist_v2 && dist_v1 < dist_v3) index_nearest_vertex = mface_src[nearest.index].v1; - else if(dist_v2 < dist_v3) index_nearest_vertex = mface_src[nearest.index].v2; - else index_nearest_vertex = mface_src[nearest.index].v3; - if(mface_src[nearest.index].v4){ - dist_v4 = len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v4].co); - if(dist_v4 < dist_v1 && dist_v4 < dist_v2 && dist_v4 < dist_v3) index_nearest_vertex = mface_src[nearest.index].v1; - } - /*copy weight*/ - dw_src = defvert_verify_index(dv_array_src[index_nearest_vertex], index_src); - dw_dst = defvert_verify_index(*dv_array_dst, index_dst); - if(mode == 1) dw_dst->weight = dw_src->weight; - else if(mode == 2) {if(!dw_dst->weight || dw_dst->weight == 0) dw_dst->weight = dw_src->weight;} - else if(mode == 3) {if(mv_dst->flag & SELECT) dw_dst->weight = dw_src->weight;} - else return 0; - } - /*free memory and return*/ - free_bvhtree_from_mesh(&tree_mesh_faces_src); - return 1; -} - -int ED_vgroup_transfer_weight_by_nearest_face(Object *ob_dst, Object *ob_src, short mode, short option) -{ - bDeformGroup *dg_src, *dg_dst; + bDeformGroup *dg_dst; Mesh *me_dst; DerivedMesh *dmesh_src; BVHTreeFromMesh tree_mesh_faces_src = {NULL}; @@ -666,14 +517,10 @@ int ED_vgroup_transfer_weight_by_nearest_face(Object *ob_dst, Object *ob_src, sh int dv_tot_src, dv_tot_dst, i, index_dst, index_src; float weight, tmp_weight[4], tmp_co[3], normal[3], tmp_mat[4][4]; - /*remove this:*/ - option=option; - - /*get source deform group*/ - dg_src = BLI_findlink(&ob_src->defbase, (ob_src->actdef-1)); + enum dw_options {REPLACE_ALL_WEIGHTS = 1, REPLACE_EMPTY_WEIGHTS = 2, REPLACE_SELECTED_WEIGHTS = 3} dw_options = dw_replace_options; /*create new and overwrite vertex group on destination without data*/ - if(!defgroup_find_name(ob_dst, dg_src->name) || mode == 1){ + if (!defgroup_find_name(ob_dst, dg_src->name) || dw_options == 1){ ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_src->name)); ED_vgroup_add_name(ob_dst, dg_src->name); } @@ -709,34 +556,135 @@ int ED_vgroup_transfer_weight_by_nearest_face(Object *ob_dst, Object *ob_src, sh mult_m4_m4m4(tmp_mat, ob_src->imat, ob_dst->obmat); /* loop through the vertices and copy weight from nearest weight*/ - for(i = 0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ + for (i = 0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ + /*reset nearest*/ nearest.index = -1; nearest.dist = FLT_MAX; + /*transform into target space*/ mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); normal_tri_v3(normal, mv_src[mface_src[nearest.index].v1].co, mv_src[mface_src[nearest.index].v2].co, mv_src[mface_src[nearest.index].v3].co); + /*node tree accelerated search for closest face*/ BLI_bvhtree_find_nearest(tree_mesh_faces_src.tree, tmp_co, &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src); + /*project onto face*/ project_v3_plane(tmp_co, normal, mv_src[mface_src[nearest.index].v1].co); + /*interpolate weights*/ interp_weights_face_v3(tmp_weight, mv_src[mface_src[nearest.index].v1].co, mv_src[mface_src[nearest.index].v2].co, mv_src[mface_src[nearest.index].v3].co, mv_src[mface_src[nearest.index].v4].co, tmp_co); + /*get weights*/ weight = tmp_weight[0] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v1], index_src)->weight; weight += tmp_weight[1] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v2], index_src)->weight; weight += tmp_weight[2] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v3], index_src)->weight; weight += tmp_weight[3] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v4], index_src)->weight; + /*copy weight*/ dw_dst = defvert_verify_index(*dv_array_dst, index_dst); - if(mode == 1) dw_dst->weight = weight; - else if(mode == 2) {if(!dw_dst->weight || dw_dst->weight == 0) dw_dst->weight = weight;} - else if(mode == 3) {if(mv_dst->flag & SELECT) dw_dst->weight = weight;} + if (dw_options == REPLACE_ALL_WEIGHTS) dw_dst->weight = weight; + else if (dw_options == REPLACE_EMPTY_WEIGHTS) {if (!dw_dst->weight || dw_dst->weight == 0) dw_dst->weight = weight;} + else if (dw_options == REPLACE_SELECTED_WEIGHTS) {if (mv_dst->flag & SELECT) dw_dst->weight = weight;} else return 0; } + + /*free memory and return*/ + free_bvhtree_from_mesh(&tree_mesh_faces_src); + return 1; +} + +int ED_vgroup_transfer_weight_by_nearest_vertex_in_face(Object *ob_dst, Object *ob_src, short dw_replace_options, bDeformGroup *dg_src) +{ + bDeformGroup *dg_dst; + Mesh *me_dst; + DerivedMesh *dmesh_src; + BVHTreeFromMesh tree_mesh_faces_src = {NULL}; + MDeformVert **dv_array_src, **dv_array_dst; + MVert *mv_dst, *mv_src; + MFace *mface_src; + BVHTreeNearest nearest; + MDeformWeight *dw_dst, *dw_src; + int dv_tot_src, dv_tot_dst, i, index_dst, index_src, index_nearest_vertex; + float dist_v1, dist_v2, dist_v3, dist_v4, tmp_co[3], tmp_mat[4][4]; + + enum dw_options {REPLACE_ALL_WEIGHTS = 1, REPLACE_EMPTY_WEIGHTS = 2, REPLACE_SELECTED_WEIGHTS = 3} dw_options = dw_replace_options; + + /*create new and overwrite vertex group on destination without data*/ + if (!defgroup_find_name(ob_dst, dg_src->name) || dw_replace_options == 1){ + ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_src->name)); + ED_vgroup_add_name(ob_dst, dg_src->name); + } + + /*get destination deformgroup*/ + dg_dst = defgroup_find_name(ob_dst, dg_src->name); + + /*get meshes*/ + me_dst = ob_dst->data; + dmesh_src = ob_src->derivedDeform; + + /*make node tree*/ + DM_ensure_tessface(dmesh_src); + bvhtree_from_mesh_faces(&tree_mesh_faces_src, dmesh_src, 0.0, 2, 6); + + /*get vertex group arrays*/ + ED_vgroup_give_parray(ob_src->data, &dv_array_src, &dv_tot_src, FALSE); + ED_vgroup_give_parray(ob_dst->data, &dv_array_dst, &dv_tot_dst, FALSE); + + /*get indexes of vertex groups*/ + index_src = BLI_findindex(&ob_src->defbase, dg_src); + index_dst = BLI_findindex(&ob_dst->defbase, dg_dst); + + /*get vertices*/ + mv_dst = me_dst->mvert; + mv_src = dmesh_src->getVertArray(dmesh_src); + + /*get faces*/ + mface_src = dmesh_src->getTessFaceArray(dmesh_src); + + /*prepare transformation matrix*/ + invert_m4_m4(ob_src->imat, ob_src->obmat); + mult_m4_m4m4(tmp_mat, ob_src->imat, ob_dst->obmat); + + /* loop through the vertices and copy weight from nearest weight*/ + for (i = 0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ + + /*reset nearest*/ + nearest.index = -1; + nearest.dist = FLT_MAX; + + /*transform into target space*/ + mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); + + /*node tree accelerated search for closest face*/ + BLI_bvhtree_find_nearest(tree_mesh_faces_src.tree, tmp_co, &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src); + + /*get distances*/ + dist_v1 = len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v1].co); + dist_v2 = len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v2].co); + dist_v3 = len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v3].co); + + /*get closest vertex*/ + if (dist_v1 < dist_v2 && dist_v1 < dist_v3) index_nearest_vertex = mface_src[nearest.index].v1; + else if (dist_v2 < dist_v3) index_nearest_vertex = mface_src[nearest.index].v2; + else index_nearest_vertex = mface_src[nearest.index].v3; + if (mface_src[nearest.index].v4){ + dist_v4 = len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v4].co); + if (dist_v4 < dist_v1 && dist_v4 < dist_v2 && dist_v4 < dist_v3) index_nearest_vertex = mface_src[nearest.index].v4; + } + + /*copy weight*/ + dw_src = defvert_verify_index(dv_array_src[index_nearest_vertex], index_src); + dw_dst = defvert_verify_index(*dv_array_dst, index_dst); + if (dw_options == REPLACE_ALL_WEIGHTS) dw_dst->weight = dw_src->weight; + else if (dw_options == REPLACE_EMPTY_WEIGHTS) {if (!dw_dst->weight || dw_dst->weight == 0) dw_dst->weight = dw_src->weight;} + else if (dw_options == REPLACE_SELECTED_WEIGHTS) {if (mv_dst->flag & SELECT) dw_dst->weight = dw_src->weight;} + else return 0; + } + /*free memory and return*/ free_bvhtree_from_mesh(&tree_mesh_faces_src); return 1; @@ -3111,10 +3059,6 @@ static int vertex_group_copy_to_selected_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -/* -ideasman42 2012/05/17 09:04:35 -suggest to have one operator with single vgroup as an option, if this is a hassle, it can be done later. -*/ void OBJECT_OT_vertex_group_copy_to_selected(wmOperatorType *ot) { /* identifiers */ @@ -3132,59 +3076,79 @@ void OBJECT_OT_vertex_group_copy_to_selected(wmOperatorType *ot) static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) { - Object *obact = CTX_data_active_object(C); + Object *ob_act = CTX_data_active_object(C); int change = 0; int fail = 0; + short dw_replace_options; + bDeformGroup *dg_src; /*TODO: get these parameters*/ - enum Function {by_index = 1, by_nearest_vertex = 2, by_nearest_face = 3, by_nearest_vertex_in_face = 4} function = 4; - /*TODO: pass these on to functions*/ - enum Mode {replace_all_weights = 1, replace_empty_weights = 2, replace_selected_weights = 3} mode= 3; - enum Option {single = 1, all = 2} option = 1; - - /*Truth table for testing:*/ - /*1,3,1 working*/ - /*2,3,1 working*/ - /*3,3,1 working*/ - /*4,3,1 working*/ + enum dg_options {REPLACE_SINGLE_VERTEX_GROUP = 1, REPLACE_ALL_VERTEX_GROUPS = 2} dg_options = 2; + enum function_options {BY_INDEX = 1, BY_NEAREST_VERTEX = 2, BY_NEAREST_FACE = 3, BY_NEAREST_VERTEX_IN_FACE = 4} function_options = 4; + dw_replace_options = 1; /*REPLACE_ALL_WEIGHTS = 1, REPLACE_EMPTY_WEIGHTS = 2, REPLACE_SELECTED_WEIGHTS = 3*/ /*Macro to loop through selected objects and perform operation depending on function, option and method*/ - CTX_DATA_BEGIN(C, Object*, obslc, selected_editable_objects) - { - if(obact != obslc){ - switch(function){ + CTX_DATA_BEGIN(C, Object*, ob_slc, selected_editable_objects){ + if (ob_act != ob_slc){ + switch(dg_options){ - case(by_index): - if(ED_vgroup_transfer_weight_by_index(obslc, obact, mode, option)) change++; - else fail++; break; + case(REPLACE_SINGLE_VERTEX_GROUP): + dg_src = BLI_findlink(&ob_act->defbase, ob_act->actdef -1); + switch(function_options){ - case(by_nearest_vertex): - if(ED_vgroup_transfer_weight_by_nearest_vertex(obslc, obact, mode, option)) change++; - else fail++; break; + case(BY_INDEX): + if (ED_vgroup_transfer_weight_by_index(ob_slc, ob_act, dw_replace_options, dg_src)) change++; + else fail++; break; - case(by_nearest_face): - if(ED_vgroup_transfer_weight_by_nearest_face(obslc, obact, mode, option)) change++; - else fail++; break; + case(BY_NEAREST_VERTEX): + if (ED_vgroup_transfer_weight_by_nearest_vertex(ob_slc, ob_act, dw_replace_options, dg_src)) change++; + else fail++; break; - case(by_nearest_vertex_in_face): - if(ED_vgroup_transfer_weight_by_nearest_vertex_in_face(obslc, obact, mode, option)) change++; - else fail++; break; + case(BY_NEAREST_FACE): + if (ED_vgroup_transfer_weight_by_nearest_face(ob_slc, ob_act, dw_replace_options, dg_src)) change++; + else fail++; break; + + case(BY_NEAREST_VERTEX_IN_FACE): + if (ED_vgroup_transfer_weight_by_nearest_vertex_in_face(ob_slc, ob_act, dw_replace_options, dg_src)) change++; + else fail++; break; + } + + case(REPLACE_ALL_VERTEX_GROUPS): + for (dg_src = ob_act->defbase.first; dg_src; dg_src = dg_src->next){ + switch(function_options){ + + case(BY_INDEX): + if (ED_vgroup_transfer_weight_by_index(ob_slc, ob_act, dw_replace_options, dg_src)) change++; + else fail++; break; + + case(BY_NEAREST_VERTEX): + if (ED_vgroup_transfer_weight_by_nearest_vertex(ob_slc, ob_act, dw_replace_options, dg_src)) change++; + else fail++; break; + + case(BY_NEAREST_FACE): + if (ED_vgroup_transfer_weight_by_nearest_face(ob_slc, ob_act, dw_replace_options, dg_src)) change++; + else fail++; break; + + case(BY_NEAREST_VERTEX_IN_FACE): + if (ED_vgroup_transfer_weight_by_nearest_vertex_in_face(ob_slc, ob_act, dw_replace_options, dg_src)) change++; + else fail++; break; + } + } + } } - } /*Event notifiers for correct display of data*/ - DAG_id_tag_update(&obslc->id, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, obslc); - WM_event_add_notifier(C, NC_GEOM|ND_DATA, obslc->data); + DAG_id_tag_update(&ob_slc->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob_slc); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, ob_slc->data); } CTX_DATA_END; /*Report error when task can not be completed with available functions.*/ - if((change == 0 && fail == 0) || fail) { + if ((change == 0 && fail == 0) || fail) { BKE_reportf(op->reports, RPT_ERROR, "Copy to VGroups to Selected warning done %d, failed %d, unknown option/method or All functions failed!", change, fail); } - return OPERATOR_FINISHED; } @@ -3202,14 +3166,6 @@ void OBJECT_OT_vertex_group_transfer_weight(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; - - /* - example properties?: - * properties * - prop = RNA_def_enum(ot->srna, "group", vgroup_items, 0, "Group", "Vertex group to set as active"); - RNA_def_enum_funcs(prop, vgroup_itemf); - ot->prop = prop; - */ } static EnumPropertyItem vgroup_items[] = { From c2c2611faa26cb7ebd1126ebe30520164a183184 Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Thu, 24 May 2012 20:03:09 +0000 Subject: [PATCH 040/347] Restructuring code. All functions merged into ED_vgroup_transfer_weight() to avoid duplicate code. --- source/blender/editors/object/object_vgroup.c | 594 ++++++++---------- 1 file changed, 277 insertions(+), 317 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 6dc954b88ad..c0fe8c1f342 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -376,151 +376,34 @@ int ED_vgroup_copy_array(Object *ob, Object *ob_from) return 1; } -/********************** Start transfer weight functions *********************/ +/***********************Start transfer weight function************************/ -int ED_vgroup_transfer_weight_by_index(Object *ob_dst, Object *ob_src, short dw_replace_options, bDeformGroup *dg_src) -{ - MDeformVert **dv_array_src; - MDeformVert **dv_array_dst; - MDeformWeight *dw_dst, *dw_src; - MVert *mv_dst; - Mesh *me_dst; - int dv_tot_src, dv_tot_dst; - int i, index_src, index_dst; - bDeformGroup *dg_dst; - - enum dw_options {REPLACE_ALL_WEIGHTS = 1, REPLACE_EMPTY_WEIGHTS = 2, REPLACE_SELECTED_WEIGHTS = 3} dw_options = dw_replace_options; - - /*create new and overwrite vertex group on destination without data*/ - if (!defgroup_find_name(ob_dst, dg_src->name) || dw_options == 1){ - ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_src->name)); - ED_vgroup_add_name(ob_dst, dg_src->name); - } - - /*get meshes*/ - me_dst = ob_dst->data; - - /*get vertices*/ - mv_dst = me_dst->mvert; - - /*get destination deformgroup*/ - dg_dst = defgroup_find_name(ob_dst, dg_src->name); - - /*get vertex group arrays*/ - ED_vgroup_give_parray(ob_src->data, &dv_array_src, &dv_tot_src, FALSE); - ED_vgroup_give_parray(ob_dst->data, &dv_array_dst, &dv_tot_dst, FALSE); - - /*get indexes of vertex groups*/ - index_src = BLI_findindex(&ob_src->defbase, dg_src); - index_dst = BLI_findindex(&ob_dst->defbase, dg_dst); - - /*check if indices are matching, delete and return if not*/ - if (ob_dst == ob_src || dv_tot_dst == 0 || (dv_tot_dst != dv_tot_src) || dv_array_src == NULL || dv_array_dst == NULL) { - ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_dst->name)); - return 0; - } - - /* loop through the vertices and copy weight*/ - for (i = 0; i < dv_tot_dst; i++, dv_array_src++, dv_array_dst++, mv_dst++){ - dw_src = defvert_verify_index(*dv_array_src, index_src); - dw_dst = defvert_verify_index(*dv_array_dst, index_dst); - if (dw_options == REPLACE_ALL_WEIGHTS) dw_dst->weight = dw_src->weight; - else if (dw_options == REPLACE_EMPTY_WEIGHTS) {if (!dw_dst->weight || dw_dst->weight == 0) dw_dst->weight = dw_src->weight;} - else if (dw_options == REPLACE_SELECTED_WEIGHTS) {if (mv_dst->flag & SELECT) dw_dst->weight = dw_src->weight;} - else return 0; - } - return 1; -} - -int ED_vgroup_transfer_weight_by_nearest_vertex(Object *ob_dst, Object *ob_src, short dw_replace_options, bDeformGroup *dg_src) -{ - bDeformGroup *dg_dst; - MDeformVert **dv_array_src, **dv_array_dst; - MDeformWeight *dw_dst, *dw_src; - MVert *mv_dst; - Mesh *me_dst; - BVHTreeFromMesh tree_mesh_src; - BVHTreeNearest nearest; - DerivedMesh *dmesh_src; - int dv_tot_src, dv_tot_dst, i, index_dst, index_src; - float tmp_co[3], tmp_mat[4][4]; - - enum dw_options {REPLACE_ALL_WEIGHTS = 1, REPLACE_EMPTY_WEIGHTS = 2, REPLACE_SELECTED_WEIGHTS = 3} dw_options = dw_replace_options; - - /*create new and overwrite vertex group on destination without data*/ - if (!defgroup_find_name(ob_dst, dg_src->name) || dw_replace_options == 1){ - ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_src->name)); - ED_vgroup_add_name(ob_dst, dg_src->name); - } - - /*get destination deformgroup*/ - dg_dst = defgroup_find_name(ob_dst, dg_src->name); - - /*get meshes*/ - me_dst = ob_dst->data; - dmesh_src = ob_src->derivedDeform; - - /*make node tree*/ - bvhtree_from_mesh_verts(&tree_mesh_src, dmesh_src, 0.0, 2, 6); - - /*get vertex group arrays*/ - ED_vgroup_give_parray(ob_src->data, &dv_array_src, &dv_tot_src, FALSE); - ED_vgroup_give_parray(ob_dst->data, &dv_array_dst, &dv_tot_dst, FALSE); - - /*get indexes of vertex groups*/ - index_src = BLI_findindex(&ob_src->defbase, dg_src); - index_dst = BLI_findindex(&ob_dst->defbase, dg_dst); - - /*get vertices*/ - mv_dst = me_dst->mvert; - - /*prepare transformation matrix*/ - invert_m4_m4(ob_src->imat, ob_src->obmat); - mult_m4_m4m4(tmp_mat, ob_src->imat, ob_dst->obmat); - - /* loop through the vertices and copy weight*/ - for (i = 0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ - - /*reset nearest*/ - nearest.index = -1; - nearest.dist = FLT_MAX; - - /*transform into target space*/ - mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); - - /*node tree accelerated search for closest vetex*/ - BLI_bvhtree_find_nearest(tree_mesh_src.tree, tmp_co, &nearest, tree_mesh_src.nearest_callback, &tree_mesh_src); - dw_src = defvert_verify_index(dv_array_src[nearest.index], index_src); - dw_dst = defvert_verify_index(*dv_array_dst, index_dst); - if (dw_options == REPLACE_ALL_WEIGHTS) dw_dst->weight = dw_src->weight; - else if (dw_options == REPLACE_EMPTY_WEIGHTS) {if (!dw_dst->weight || dw_dst->weight == 0) dw_dst->weight = dw_src->weight;} - else if(dw_options == REPLACE_SELECTED_WEIGHTS) {if (mv_dst->flag & SELECT) dw_dst->weight = dw_src->weight;} - else return 0; - } - - /*free memory and return*/ - free_bvhtree_from_mesh(&tree_mesh_src); - return 1; -} - -int ED_vgroup_transfer_weight_by_nearest_face(Object *ob_dst, Object *ob_src, short dw_replace_options, bDeformGroup *dg_src) +int ED_vgroup_transfer_weight( + Object *ob_dst, Object *ob_src, bDeformGroup *dg_src, short replace_options, short method_options) { bDeformGroup *dg_dst; Mesh *me_dst; DerivedMesh *dmesh_src; - BVHTreeFromMesh tree_mesh_faces_src = {NULL}; + BVHTreeFromMesh tree_mesh_vertices_src, tree_mesh_faces_src = {NULL}; MDeformVert **dv_array_src, **dv_array_dst; MVert *mv_dst, *mv_src; MFace *mface_src; BVHTreeNearest nearest; - MDeformWeight *dw_dst; - int dv_tot_src, dv_tot_dst, i, index_dst, index_src; - float weight, tmp_weight[4], tmp_co[3], normal[3], tmp_mat[4][4]; + MDeformWeight *dw_dst, *dw_src; + int dv_tot_src, dv_tot_dst, i, index_dst, index_src, index_nearest, index_nearest_vertex; + float weight, tmp_weight[4], tmp_co[3], normal[3], tmp_mat[4][4], dist_v1, dist_v2, dist_v3, dist_v4; - enum dw_options {REPLACE_ALL_WEIGHTS = 1, REPLACE_EMPTY_WEIGHTS = 2, REPLACE_SELECTED_WEIGHTS = 3} dw_options = dw_replace_options; + enum replace_option {REPLACE_ALL_WEIGHTS = 1, + REPLACE_EMPTY_WEIGHTS = 2, + REPLACE_SELECTED_WEIGHTS = 3} replace_option = replace_options; + + enum method_option {BY_INDEX = 1, + BY_NEAREST_VERTEX = 2, + BY_NEAREST_FACE = 3, + BY_NEAREST_VERTEX_IN_FACE = 4} method_option = method_options; /*create new and overwrite vertex group on destination without data*/ - if (!defgroup_find_name(ob_dst, dg_src->name) || dw_options == 1){ + if (!defgroup_find_name(ob_dst, dg_src->name) || replace_option == 1){ ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_src->name)); ED_vgroup_add_name(ob_dst, dg_src->name); } @@ -532,10 +415,6 @@ int ED_vgroup_transfer_weight_by_nearest_face(Object *ob_dst, Object *ob_src, sh me_dst = ob_dst->data; dmesh_src = ob_src->derivedDeform; - /*make node tree*/ - DM_ensure_tessface(dmesh_src); - bvhtree_from_mesh_faces(&tree_mesh_faces_src, dmesh_src, 0.0, 2, 6); - /*get vertex group arrays*/ ED_vgroup_give_parray(ob_src->data, &dv_array_src, &dv_tot_src, FALSE); ED_vgroup_give_parray(ob_dst->data, &dv_array_dst, &dv_tot_dst, FALSE); @@ -548,149 +427,222 @@ int ED_vgroup_transfer_weight_by_nearest_face(Object *ob_dst, Object *ob_src, sh mv_dst = me_dst->mvert; mv_src = dmesh_src->getVertArray(dmesh_src); - /*get faces*/ - mface_src = dmesh_src->getTessFaceArray(dmesh_src); - /*prepare transformation matrix*/ invert_m4_m4(ob_src->imat, ob_src->obmat); mult_m4_m4m4(tmp_mat, ob_src->imat, ob_dst->obmat); - /* loop through the vertices and copy weight from nearest weight*/ - for (i = 0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ + switch (method_option) { - /*reset nearest*/ - nearest.index = -1; - nearest.dist = FLT_MAX; - - /*transform into target space*/ - mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); - normal_tri_v3(normal, mv_src[mface_src[nearest.index].v1].co, mv_src[mface_src[nearest.index].v2].co, mv_src[mface_src[nearest.index].v3].co); - - /*node tree accelerated search for closest face*/ - BLI_bvhtree_find_nearest(tree_mesh_faces_src.tree, tmp_co, &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src); - - /*project onto face*/ - project_v3_plane(tmp_co, normal, mv_src[mface_src[nearest.index].v1].co); - - /*interpolate weights*/ - interp_weights_face_v3(tmp_weight, mv_src[mface_src[nearest.index].v1].co, - mv_src[mface_src[nearest.index].v2].co, - mv_src[mface_src[nearest.index].v3].co, - mv_src[mface_src[nearest.index].v4].co, tmp_co); - - /*get weights*/ - weight = tmp_weight[0] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v1], index_src)->weight; - weight += tmp_weight[1] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v2], index_src)->weight; - weight += tmp_weight[2] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v3], index_src)->weight; - weight += tmp_weight[3] * defvert_verify_index(dv_array_src[mface_src[nearest.index].v4], index_src)->weight; - - /*copy weight*/ - dw_dst = defvert_verify_index(*dv_array_dst, index_dst); - if (dw_options == REPLACE_ALL_WEIGHTS) dw_dst->weight = weight; - else if (dw_options == REPLACE_EMPTY_WEIGHTS) {if (!dw_dst->weight || dw_dst->weight == 0) dw_dst->weight = weight;} - else if (dw_options == REPLACE_SELECTED_WEIGHTS) {if (mv_dst->flag & SELECT) dw_dst->weight = weight;} - else return 0; - } - - /*free memory and return*/ - free_bvhtree_from_mesh(&tree_mesh_faces_src); - return 1; -} - -int ED_vgroup_transfer_weight_by_nearest_vertex_in_face(Object *ob_dst, Object *ob_src, short dw_replace_options, bDeformGroup *dg_src) -{ - bDeformGroup *dg_dst; - Mesh *me_dst; - DerivedMesh *dmesh_src; - BVHTreeFromMesh tree_mesh_faces_src = {NULL}; - MDeformVert **dv_array_src, **dv_array_dst; - MVert *mv_dst, *mv_src; - MFace *mface_src; - BVHTreeNearest nearest; - MDeformWeight *dw_dst, *dw_src; - int dv_tot_src, dv_tot_dst, i, index_dst, index_src, index_nearest_vertex; - float dist_v1, dist_v2, dist_v3, dist_v4, tmp_co[3], tmp_mat[4][4]; - - enum dw_options {REPLACE_ALL_WEIGHTS = 1, REPLACE_EMPTY_WEIGHTS = 2, REPLACE_SELECTED_WEIGHTS = 3} dw_options = dw_replace_options; - - /*create new and overwrite vertex group on destination without data*/ - if (!defgroup_find_name(ob_dst, dg_src->name) || dw_replace_options == 1){ - ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_src->name)); - ED_vgroup_add_name(ob_dst, dg_src->name); - } - - /*get destination deformgroup*/ - dg_dst = defgroup_find_name(ob_dst, dg_src->name); - - /*get meshes*/ - me_dst = ob_dst->data; - dmesh_src = ob_src->derivedDeform; - - /*make node tree*/ - DM_ensure_tessface(dmesh_src); - bvhtree_from_mesh_faces(&tree_mesh_faces_src, dmesh_src, 0.0, 2, 6); - - /*get vertex group arrays*/ - ED_vgroup_give_parray(ob_src->data, &dv_array_src, &dv_tot_src, FALSE); - ED_vgroup_give_parray(ob_dst->data, &dv_array_dst, &dv_tot_dst, FALSE); - - /*get indexes of vertex groups*/ - index_src = BLI_findindex(&ob_src->defbase, dg_src); - index_dst = BLI_findindex(&ob_dst->defbase, dg_dst); - - /*get vertices*/ - mv_dst = me_dst->mvert; - mv_src = dmesh_src->getVertArray(dmesh_src); - - /*get faces*/ - mface_src = dmesh_src->getTessFaceArray(dmesh_src); - - /*prepare transformation matrix*/ - invert_m4_m4(ob_src->imat, ob_src->obmat); - mult_m4_m4m4(tmp_mat, ob_src->imat, ob_dst->obmat); - - /* loop through the vertices and copy weight from nearest weight*/ - for (i = 0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ - - /*reset nearest*/ - nearest.index = -1; - nearest.dist = FLT_MAX; - - /*transform into target space*/ - mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); - - /*node tree accelerated search for closest face*/ - BLI_bvhtree_find_nearest(tree_mesh_faces_src.tree, tmp_co, &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src); - - /*get distances*/ - dist_v1 = len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v1].co); - dist_v2 = len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v2].co); - dist_v3 = len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v3].co); - - /*get closest vertex*/ - if (dist_v1 < dist_v2 && dist_v1 < dist_v3) index_nearest_vertex = mface_src[nearest.index].v1; - else if (dist_v2 < dist_v3) index_nearest_vertex = mface_src[nearest.index].v2; - else index_nearest_vertex = mface_src[nearest.index].v3; - if (mface_src[nearest.index].v4){ - dist_v4 = len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v4].co); - if (dist_v4 < dist_v1 && dist_v4 < dist_v2 && dist_v4 < dist_v3) index_nearest_vertex = mface_src[nearest.index].v4; + case (BY_INDEX): + /*check if indices are matching, delete and return if not*/ + if (ob_dst == ob_src || dv_tot_dst == 0 || (dv_tot_dst != dv_tot_src) + || dv_array_src == NULL || dv_array_dst == NULL) { + ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_dst->name)); + return 0; } - /*copy weight*/ - dw_src = defvert_verify_index(dv_array_src[index_nearest_vertex], index_src); - dw_dst = defvert_verify_index(*dv_array_dst, index_dst); - if (dw_options == REPLACE_ALL_WEIGHTS) dw_dst->weight = dw_src->weight; - else if (dw_options == REPLACE_EMPTY_WEIGHTS) {if (!dw_dst->weight || dw_dst->weight == 0) dw_dst->weight = dw_src->weight;} - else if (dw_options == REPLACE_SELECTED_WEIGHTS) {if (mv_dst->flag & SELECT) dw_dst->weight = dw_src->weight;} - else return 0; + /* loop through the vertices*/ + for (i = 0; i < dv_tot_dst; i++, dv_array_src++, dv_array_dst++, mv_dst++){ + + /*copy weight*/ + dw_src = defvert_verify_index(*dv_array_src, index_src); + dw_dst = defvert_verify_index(*dv_array_dst, index_dst); + + switch (replace_option) { + + case (REPLACE_ALL_WEIGHTS): + dw_dst->weight = dw_src->weight; + break; + + case(REPLACE_EMPTY_WEIGHTS): + if (!dw_dst->weight || dw_dst->weight == 0) dw_dst->weight = dw_src->weight; + break; + + case(REPLACE_SELECTED_WEIGHTS): + if (mv_dst->flag & SELECT) dw_dst->weight = dw_src->weight; + break; + } + } + break; + + case (BY_NEAREST_VERTEX): + /*make node tree*/ + bvhtree_from_mesh_verts(&tree_mesh_vertices_src, dmesh_src, 0.0, 2, 6); + + /* loop through the vertices*/ + for (i = 0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ + + /*reset nearest*/ + nearest.index = -1; + nearest.dist = FLT_MAX; + + /*transform into target space*/ + mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); + + /*node tree accelerated search for closest vetex*/ + BLI_bvhtree_find_nearest(tree_mesh_vertices_src.tree, tmp_co, &nearest, tree_mesh_vertices_src.nearest_callback, &tree_mesh_vertices_src); + + /*copy weight*/ + dw_src = defvert_verify_index(dv_array_src[nearest.index], index_src); + dw_dst = defvert_verify_index(*dv_array_dst, index_dst); + + switch (replace_option) { + + case (REPLACE_ALL_WEIGHTS): + dw_dst->weight = dw_src->weight; + break; + + case(REPLACE_EMPTY_WEIGHTS): + if (!dw_dst->weight || dw_dst->weight == 0) dw_dst->weight = dw_src->weight; + break; + + case(REPLACE_SELECTED_WEIGHTS): + if (mv_dst->flag & SELECT) dw_dst->weight = dw_src->weight; + break; + } + } + break; + + case (BY_NEAREST_FACE): + /*get faces*/ + DM_ensure_tessface(dmesh_src); + mface_src = dmesh_src->getTessFaceArray(dmesh_src); + + /*make node tree*/ + bvhtree_from_mesh_faces(&tree_mesh_faces_src, dmesh_src, 0.0, 2, 6); + + /* loop through the vertices*/ + for (i = 0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ + + /*reset nearest*/ + nearest.index = -1; + nearest.dist = FLT_MAX; + + /*transform into target space*/ + mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); + + /*node tree accelerated search for closest face*/ + BLI_bvhtree_find_nearest(tree_mesh_faces_src.tree, + tmp_co, + &nearest, tree_mesh_faces_src.nearest_callback, + &tree_mesh_faces_src); + index_nearest = nearest.index; + + /*project onto face*/ + normal_tri_v3(normal, + mv_src[mface_src[nearest.index].v1].co, + mv_src[mface_src[nearest.index].v2].co, + mv_src[mface_src[nearest.index].v3].co); + project_v3_plane(tmp_co, normal, mv_src[mface_src[index_nearest].v1].co); + + /*interpolate weights*/ + interp_weights_face_v3(tmp_weight, + mv_src[mface_src[index_nearest].v1].co, + mv_src[mface_src[index_nearest].v2].co, + mv_src[mface_src[index_nearest].v3].co, + mv_src[mface_src[index_nearest].v4].co, + tmp_co); + + /*get weights*/ + weight = + tmp_weight[0] * defvert_verify_index(dv_array_src[mface_src[index_nearest].v1], index_src)->weight; + weight += + tmp_weight[1] * defvert_verify_index(dv_array_src[mface_src[index_nearest].v2], index_src)->weight; + weight += + tmp_weight[2] * defvert_verify_index(dv_array_src[mface_src[index_nearest].v3], index_src)->weight; + weight += + tmp_weight[3] * defvert_verify_index(dv_array_src[mface_src[index_nearest].v4], index_src)->weight; + + /*copy weight*/ + dw_dst = defvert_verify_index(*dv_array_dst, index_dst); + + switch (replace_option) { + + case (REPLACE_ALL_WEIGHTS): + dw_dst->weight = weight; + break; + + case(REPLACE_EMPTY_WEIGHTS): + if (!dw_dst->weight || dw_dst->weight == 0) dw_dst->weight = weight; + break; + + case(REPLACE_SELECTED_WEIGHTS): + if (mv_dst->flag & SELECT) dw_dst->weight = weight; + break; + } + } + break; + + case (BY_NEAREST_VERTEX_IN_FACE): + /*get faces*/ + DM_ensure_tessface(dmesh_src); + mface_src = dmesh_src->getTessFaceArray(dmesh_src); + + /*make node tree*/ + bvhtree_from_mesh_faces(&tree_mesh_faces_src, dmesh_src, 0.0, 2, 6); + + /*loop through the vertices*/ + for (i = 0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ + + /*reset nearest*/ + nearest.index = -1; + nearest.dist = FLT_MAX; + + /*transform into target space*/ + mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); + + /*node tree accelerated search for closest face*/ + BLI_bvhtree_find_nearest(tree_mesh_faces_src.tree, + tmp_co, + &nearest, tree_mesh_faces_src.nearest_callback, + &tree_mesh_faces_src); + index_nearest = nearest.index; + + /*get distances*/ + dist_v1 = len_squared_v3v3(tmp_co, mv_src[mface_src[index_nearest].v1].co); + dist_v2 = len_squared_v3v3(tmp_co, mv_src[mface_src[index_nearest].v2].co); + dist_v3 = len_squared_v3v3(tmp_co, mv_src[mface_src[index_nearest].v3].co); + + /*get closest vertex*/ + if (dist_v1 < dist_v2 && dist_v1 < dist_v3) index_nearest_vertex = mface_src[index_nearest].v1; + else if (dist_v2 < dist_v3) index_nearest_vertex = mface_src[index_nearest].v2; + else index_nearest_vertex = mface_src[index_nearest].v3; + if (mface_src[index_nearest].v4){ + dist_v4 = len_squared_v3v3(tmp_co, mv_src[mface_src[index_nearest].v4].co); + if (dist_v4 < dist_v1 && dist_v4 < dist_v2 && dist_v4 < dist_v3) { + index_nearest_vertex = mface_src[index_nearest].v4; + } + } + + /*copy weight*/ + dw_src = defvert_verify_index(dv_array_src[index_nearest_vertex], index_src); + dw_dst = defvert_verify_index(*dv_array_dst, index_dst); + + switch (replace_option) { + + case (REPLACE_ALL_WEIGHTS): + dw_dst->weight = dw_src->weight; + break; + + case(REPLACE_EMPTY_WEIGHTS): + if (!dw_dst->weight || dw_dst->weight == 0) dw_dst->weight = dw_src->weight; + break; + + case(REPLACE_SELECTED_WEIGHTS): + if (mv_dst->flag & SELECT) dw_dst->weight = dw_src->weight; + break; + } + } + break; } /*free memory and return*/ + free_bvhtree_from_mesh(&tree_mesh_vertices_src); free_bvhtree_from_mesh(&tree_mesh_faces_src); return 1; } -/********************** End transfer weight functions *********************/ +/***********************End transfer weight function**************************/ /* for Mesh in Object mode */ /* allows editmode for Lattice */ @@ -3079,68 +3031,76 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) Object *ob_act = CTX_data_active_object(C); int change = 0; int fail = 0; - short dw_replace_options; bDeformGroup *dg_src; - /*TODO: get these parameters*/ - enum dg_options {REPLACE_SINGLE_VERTEX_GROUP = 1, REPLACE_ALL_VERTEX_GROUPS = 2} dg_options = 2; - enum function_options {BY_INDEX = 1, BY_NEAREST_VERTEX = 2, BY_NEAREST_FACE = 3, BY_NEAREST_VERTEX_IN_FACE = 4} function_options = 4; - dw_replace_options = 1; /*REPLACE_ALL_WEIGHTS = 1, REPLACE_EMPTY_WEIGHTS = 2, REPLACE_SELECTED_WEIGHTS = 3*/ + enum vertex_group_option {REPLACE_SINGLE_VERTEX_GROUP = 1, + REPLACE_ALL_VERTEX_GROUPS = 2} vertex_group_option; + + short replace_option; /*REPLACE_ALL_WEIGHTS = 1, + * REPLACE_EMPTY_WEIGHTS = 2, + * REPLACE_SELECTED_WEIGHTS = 3*/ + + short method_option; /*BY_INDEX = 1, + * BY_NEAREST_VERTEX = 2, + * BY_NEAREST_FACE = 3, + * BY_NEAREST_VERTEX_IN_FACE = 4*/ + + vertex_group_option = 1; + replace_option = 1; + method_option = 3; + + /*Truth table for testing*/ + /*1,1,1 working*/ + /*1,1,2 working*/ + /*1,1,3 working*/ + /*1,1,4 working*/ + /*1,2,1 working*/ + /*1,2,2 working*/ + /*1,2,3 working*/ + /*1,2,4 working*/ + /*1,3,1 working*/ + /*1,3,2 working*/ + /*1,3,3 working*/ + /*1,3,4 working*/ + /*2,1,1 */ + /*2,1,2*/ + /*2,1,3*/ + /*2,1,4*/ + /*2,2,1*/ + /*2,2,2*/ + /*2,2,3*/ + /*2,2,4*/ + /*2,3,1*/ + /*2,3,2*/ + /*2,3,3*/ + /*2,3,4*/ /*Macro to loop through selected objects and perform operation depending on function, option and method*/ CTX_DATA_BEGIN(C, Object*, ob_slc, selected_editable_objects){ + if (ob_act != ob_slc){ - switch(dg_options){ + switch(vertex_group_option){ - case(REPLACE_SINGLE_VERTEX_GROUP): - dg_src = BLI_findlink(&ob_act->defbase, ob_act->actdef -1); - switch(function_options){ + case(REPLACE_SINGLE_VERTEX_GROUP): + if (ED_vgroup_transfer_weight(ob_slc, ob_act, BLI_findlink(&ob_act->defbase, ob_act->actdef - 1), replace_option, method_option)) + change++; + else fail++; break; - case(BY_INDEX): - if (ED_vgroup_transfer_weight_by_index(ob_slc, ob_act, dw_replace_options, dg_src)) change++; - else fail++; break; - - case(BY_NEAREST_VERTEX): - if (ED_vgroup_transfer_weight_by_nearest_vertex(ob_slc, ob_act, dw_replace_options, dg_src)) change++; - else fail++; break; - - case(BY_NEAREST_FACE): - if (ED_vgroup_transfer_weight_by_nearest_face(ob_slc, ob_act, dw_replace_options, dg_src)) change++; - else fail++; break; - - case(BY_NEAREST_VERTEX_IN_FACE): - if (ED_vgroup_transfer_weight_by_nearest_vertex_in_face(ob_slc, ob_act, dw_replace_options, dg_src)) change++; - else fail++; break; - } - - case(REPLACE_ALL_VERTEX_GROUPS): - for (dg_src = ob_act->defbase.first; dg_src; dg_src = dg_src->next){ - switch(function_options){ - - case(BY_INDEX): - if (ED_vgroup_transfer_weight_by_index(ob_slc, ob_act, dw_replace_options, dg_src)) change++; - else fail++; break; - - case(BY_NEAREST_VERTEX): - if (ED_vgroup_transfer_weight_by_nearest_vertex(ob_slc, ob_act, dw_replace_options, dg_src)) change++; - else fail++; break; - - case(BY_NEAREST_FACE): - if (ED_vgroup_transfer_weight_by_nearest_face(ob_slc, ob_act, dw_replace_options, dg_src)) change++; - else fail++; break; - - case(BY_NEAREST_VERTEX_IN_FACE): - if (ED_vgroup_transfer_weight_by_nearest_vertex_in_face(ob_slc, ob_act, dw_replace_options, dg_src)) change++; - else fail++; break; - } - } + case(REPLACE_ALL_VERTEX_GROUPS): + for (dg_src = ob_act->defbase.first; dg_src; dg_src = dg_src->next){ + if (ED_vgroup_transfer_weight(ob_slc, ob_act, dg_src, replace_option, method_option)) change++; + else fail++; break; } + } - /*Event notifiers for correct display of data*/ - DAG_id_tag_update(&ob_slc->id, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob_slc); - WM_event_add_notifier(C, NC_GEOM|ND_DATA, ob_slc->data); + } } + + /*Event notifiers for correct display of data*/ + DAG_id_tag_update(&ob_slc->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob_slc); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, ob_slc->data); + CTX_DATA_END; /*Report error when task can not be completed with available functions.*/ From b4a229c43afdefa7cca3462a9d14f1a3bcef9bd2 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 26 May 2012 14:31:34 +0000 Subject: [PATCH 041/347] style edits --- source/blender/editors/object/object_vgroup.c | 52 ++++++++++--------- 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 81119c8292e..cc60cf9881d 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -29,7 +29,6 @@ * \ingroup edobj */ - #include #include #include @@ -458,9 +457,10 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s switch (method_option) { case BY_INDEX: - /*check if indices are matching, delete and return if not*/ - if (ob_dst == ob_src || dv_tot_dst == 0 || dv_tot_dst != dv_tot_src - || dv_array_src == NULL || dv_array_dst == NULL) { + /* check if indices are matching, delete and return if not */ + if (ob_dst == ob_src || dv_tot_dst == 0 || dv_tot_dst != dv_tot_src || + dv_array_src == NULL || dv_array_dst == NULL) + { ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_dst->name)); return 0; } @@ -491,7 +491,7 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s /*node tree accelerated search for closest vetex*/ BLI_bvhtree_find_nearest(tree_mesh_vertices_src.tree, tmp_co, - &nearest, tree_mesh_vertices_src.nearest_callback, &tree_mesh_vertices_src); + &nearest, tree_mesh_vertices_src.nearest_callback, &tree_mesh_vertices_src); /*copy weight*/ dw_src = defvert_verify_index(dv_array_src[nearest.index], index_src); @@ -523,20 +523,21 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s /*node tree accelerated search for closest face*/ BLI_bvhtree_find_nearest(tree_mesh_faces_src.tree, tmp_co, - &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src); + &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src); index_nearest = nearest.index; /*project onto face*/ normal_tri_v3(normal, mv_src[mface_src[nearest.index].v1].co, - mv_src[mface_src[nearest.index].v2].co, - mv_src[mface_src[nearest.index].v3].co); + mv_src[mface_src[nearest.index].v2].co, + mv_src[mface_src[nearest.index].v3].co); + project_v3_plane(tmp_co, normal, mv_src[mface_src[index_nearest].v1].co); /*interpolate weights*/ interp_weights_face_v3(tmp_weight, mv_src[mface_src[index_nearest].v1].co, - mv_src[mface_src[index_nearest].v2].co, - mv_src[mface_src[index_nearest].v3].co, - mv_src[mface_src[index_nearest].v4].co, tmp_co); + mv_src[mface_src[index_nearest].v2].co, + mv_src[mface_src[index_nearest].v3].co, + mv_src[mface_src[index_nearest].v4].co, tmp_co); /*get weights*/ weight = tmp_weight[0] * defvert_verify_index(dv_array_src[mface_src[index_nearest].v1], index_src)->weight; @@ -573,7 +574,7 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s /*node tree accelerated search for closest face*/ BLI_bvhtree_find_nearest(tree_mesh_faces_src.tree, tmp_co, - &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src); + &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src); index_nearest = nearest.index; /*get distances*/ @@ -2996,30 +2997,31 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) int fail = 0; bDeformGroup *dg_src; - /*TODO: get these parameters from gui. - *For now 1,3,1 is default because GUI doesnt contain more than one button yet: - *Replace all weights in single vertexgroup based on interpolation of nearest face*/ + /* TODO: get these parameters from gui. + * For now 1,3,1 is default because GUI doesnt contain more than one button yet: + * Replace all weights in single vertexgroup based on interpolation of nearest face*/ VertexGroupOption vertex_group_option = 1; MethodOption method_option = 3; ReplaceOption replace_option = 1; /*Macro to loop through selected objects and perform operation depending on function, option and method*/ - CTX_DATA_BEGIN(C, Object*, ob_slc, selected_editable_objects){ + CTX_DATA_BEGIN(C, Object*, ob_slc, selected_editable_objects) { if (ob_act != ob_slc){ switch(vertex_group_option){ - case REPLACE_SINGLE_VERTEX_GROUP: - if (ED_vgroup_transfer_weight(ob_slc, ob_act, BLI_findlink(&ob_act->defbase, ob_act->actdef - 1), method_option, replace_option)) - change++; - else fail++; break; + case REPLACE_SINGLE_VERTEX_GROUP: + if (ED_vgroup_transfer_weight(ob_slc, ob_act, BLI_findlink(&ob_act->defbase, ob_act->actdef - 1), method_option, replace_option)) + change++; + else fail++; + break; - case REPLACE_ALL_VERTEX_GROUPS: - for (dg_src = ob_act->defbase.first; dg_src; dg_src = dg_src->next){ - if (ED_vgroup_transfer_weight(ob_slc, ob_act, dg_src, method_option, replace_option)) change++; - else fail++; break; - } + case REPLACE_ALL_VERTEX_GROUPS: + for (dg_src = ob_act->defbase.first; dg_src; dg_src = dg_src->next){ + if (ED_vgroup_transfer_weight(ob_slc, ob_act, dg_src, method_option, replace_option)) change++; + else fail++;break; + } } } } From 25c7e8e1283c2ebc741bdd42dd0abc89eecd0486 Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Sat, 26 May 2012 15:27:21 +0000 Subject: [PATCH 042/347] bug fixes, review issue 6256058. --- source/blender/editors/object/object_vgroup.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index cc60cf9881d..83ef066f71f 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -402,12 +402,15 @@ void vgroup_transfer_weight(MVert *mv_dst, float *weight_dst, float weight_src, case REPLACE_ALL_WEIGHTS: *weight_dst = weight_src; + break; case REPLACE_EMPTY_WEIGHTS: if (!weight_dst || weight_dst == 0) *weight_dst = weight_src; + break; case REPLACE_SELECTED_WEIGHTS: if (mv_dst->flag & SELECT) *weight_dst = weight_src; + break; } } @@ -426,7 +429,7 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s float weight, tmp_weight[4], tmp_co[3], normal[3], tmp_mat[4][4], dist_v1, dist_v2, dist_v3, dist_v4; /*create new and overwrite vertex group on destination without data*/ - if (!defgroup_find_name(ob_dst, dg_src->name) || replace_option == (ReplaceOption)REPLACE_ALL_WEIGHTS){ + if (!defgroup_find_name(ob_dst, dg_src->name) || replace_option == REPLACE_ALL_WEIGHTS){ ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_src->name)); ED_vgroup_add_name(ob_dst, dg_src->name); } @@ -543,7 +546,9 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s weight = tmp_weight[0] * defvert_verify_index(dv_array_src[mface_src[index_nearest].v1], index_src)->weight; weight += tmp_weight[1] * defvert_verify_index(dv_array_src[mface_src[index_nearest].v2], index_src)->weight; weight += tmp_weight[2] * defvert_verify_index(dv_array_src[mface_src[index_nearest].v3], index_src)->weight; - weight += tmp_weight[3] * defvert_verify_index(dv_array_src[mface_src[index_nearest].v4], index_src)->weight; + if (mface_src[index_nearest].v4 || mface_src[index_nearest].v4 == 0){ + weight += tmp_weight[3] * defvert_verify_index(dv_array_src[mface_src[index_nearest].v4], index_src)->weight; + } /*copy weight*/ dw_dst = defvert_verify_index(*dv_array_dst, index_dst); @@ -3020,8 +3025,9 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) case REPLACE_ALL_VERTEX_GROUPS: for (dg_src = ob_act->defbase.first; dg_src; dg_src = dg_src->next){ if (ED_vgroup_transfer_weight(ob_slc, ob_act, dg_src, method_option, replace_option)) change++; - else fail++;break; + else fail++; } + break; } } } From 6c41b326fee8dd919e6b5e1e93501364613ecd17 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 26 May 2012 15:48:55 +0000 Subject: [PATCH 043/347] style cleanup --- source/blender/editors/object/object_vgroup.c | 37 ++++++++++--------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 83ef066f71f..81adb1c41ff 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -429,7 +429,7 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s float weight, tmp_weight[4], tmp_co[3], normal[3], tmp_mat[4][4], dist_v1, dist_v2, dist_v3, dist_v4; /*create new and overwrite vertex group on destination without data*/ - if (!defgroup_find_name(ob_dst, dg_src->name) || replace_option == REPLACE_ALL_WEIGHTS){ + if (!defgroup_find_name(ob_dst, dg_src->name) || replace_option == REPLACE_ALL_WEIGHTS) { ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_src->name)); ED_vgroup_add_name(ob_dst, dg_src->name); } @@ -469,7 +469,7 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s } /* loop through the vertices*/ - for (i = 0; i < dv_tot_dst; i++, dv_array_src++, dv_array_dst++, mv_dst++){ + for (i = 0; i < dv_tot_dst; i++, dv_array_src++, dv_array_dst++, mv_dst++) { /*copy weight*/ dw_src = defvert_verify_index(*dv_array_src, index_src); @@ -483,7 +483,7 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s bvhtree_from_mesh_verts(&tree_mesh_vertices_src, dmesh_src, 0.0, 2, 6); /* loop through the vertices*/ - for (i = 0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ + for (i = 0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++) { /*reset nearest*/ /*nearest.index = -1; It is asumed using index of previous search as starting point result in speedup. It will be tested later*/ @@ -515,7 +515,7 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s bvhtree_from_mesh_faces(&tree_mesh_faces_src, dmesh_src, 0.0, 2, 6); /* loop through the vertices*/ - for (i = 0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ + for (i = 0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++) { /*reset nearest*/ /*nearest.index = -1; It is asumed using index of previous search as starting point result in speedup. It will be tested later*/ @@ -531,8 +531,8 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s /*project onto face*/ normal_tri_v3(normal, mv_src[mface_src[nearest.index].v1].co, - mv_src[mface_src[nearest.index].v2].co, - mv_src[mface_src[nearest.index].v3].co); + mv_src[mface_src[nearest.index].v2].co, + mv_src[mface_src[nearest.index].v3].co); project_v3_plane(tmp_co, normal, mv_src[mface_src[index_nearest].v1].co); @@ -546,7 +546,7 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s weight = tmp_weight[0] * defvert_verify_index(dv_array_src[mface_src[index_nearest].v1], index_src)->weight; weight += tmp_weight[1] * defvert_verify_index(dv_array_src[mface_src[index_nearest].v2], index_src)->weight; weight += tmp_weight[2] * defvert_verify_index(dv_array_src[mface_src[index_nearest].v3], index_src)->weight; - if (mface_src[index_nearest].v4 || mface_src[index_nearest].v4 == 0){ + if (mface_src[index_nearest].v4 || mface_src[index_nearest].v4 == 0) { weight += tmp_weight[3] * defvert_verify_index(dv_array_src[mface_src[index_nearest].v4], index_src)->weight; } @@ -568,7 +568,7 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s bvhtree_from_mesh_faces(&tree_mesh_faces_src, dmesh_src, 0.0, 2, 6); /*loop through the vertices*/ - for (i = 0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){ + for (i = 0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++) { /*reset nearest*/ /*nearest.index = -1; It is asumed using index of previous search as starting point result in speedup. It will be tested later*/ @@ -591,9 +591,9 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s if (dist_v1 < dist_v2 && dist_v1 < dist_v3) index_nearest_vertex = mface_src[index_nearest].v1; else if (dist_v2 < dist_v3) index_nearest_vertex = mface_src[index_nearest].v2; else index_nearest_vertex = mface_src[index_nearest].v3; - if (mface_src[index_nearest].v4 || mface_src[index_nearest].v4 == 0){ + if (mface_src[index_nearest].v4 || mface_src[index_nearest].v4 == 0) { dist_v4 = len_squared_v3v3(tmp_co, mv_src[mface_src[index_nearest].v4].co); - if (dist_v4 < dist_v1 && dist_v4 < dist_v2 && dist_v4 < dist_v3){ + if (dist_v4 < dist_v1 && dist_v4 < dist_v2 && dist_v4 < dist_v3) { index_nearest_vertex = mface_src[index_nearest].v4; } } @@ -2962,7 +2962,7 @@ static int vertex_group_copy_to_selected_exec(bContext *C, wmOperator *op) int change = 0; int fail = 0; - CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) + CTX_DATA_BEGIN(C, Object *, ob, selected_editable_objects) { if (obact != ob) { if (ED_vgroup_copy_array(ob, obact)) change++; @@ -3011,10 +3011,11 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) ReplaceOption replace_option = 1; /*Macro to loop through selected objects and perform operation depending on function, option and method*/ - CTX_DATA_BEGIN(C, Object*, ob_slc, selected_editable_objects) { + CTX_DATA_BEGIN(C, Object *, ob_slc, selected_editable_objects) + { - if (ob_act != ob_slc){ - switch(vertex_group_option){ + if (ob_act != ob_slc) { + switch (vertex_group_option) { case REPLACE_SINGLE_VERTEX_GROUP: if (ED_vgroup_transfer_weight(ob_slc, ob_act, BLI_findlink(&ob_act->defbase, ob_act->actdef - 1), method_option, replace_option)) @@ -3023,7 +3024,7 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) break; case REPLACE_ALL_VERTEX_GROUPS: - for (dg_src = ob_act->defbase.first; dg_src; dg_src = dg_src->next){ + for (dg_src = ob_act->defbase.first; dg_src; dg_src = dg_src->next) { if (ED_vgroup_transfer_weight(ob_slc, ob_act, dg_src, method_option, replace_option)) change++; else fail++; } @@ -3034,8 +3035,8 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) /*Event notifiers for correct display of data*/ DAG_id_tag_update(&ob_slc->id, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob_slc); - WM_event_add_notifier(C, NC_GEOM|ND_DATA, ob_slc->data); + WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob_slc); + WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob_slc->data); CTX_DATA_END; @@ -3061,7 +3062,7 @@ void OBJECT_OT_vertex_group_transfer_weight(wmOperatorType *ot) ot->exec = vertex_group_transfer_weight_exec; /* flags */ - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } static EnumPropertyItem vgroup_items[] = { From 89cc1b2e50787de180fd2fc7c6cc03274b4491ad Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Sun, 27 May 2012 14:17:01 +0000 Subject: [PATCH 044/347] GUI added, but crashes becasuse: ob_act / ob_src ->DerivedDeform == 0x0 --- source/blender/editors/object/object_vgroup.c | 42 +++++++++++++++---- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 81adb1c41ff..c88fa164fdc 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -395,6 +395,27 @@ typedef enum ReplaceOption { REPLACE_SELECTED_WEIGHTS = 3 } ReplaceOption; +static EnumPropertyItem vertex_group_option_item[] = { + {REPLACE_SINGLE_VERTEX_GROUP, "REPLACE_SINGLE_VERTEX_GROUP", 1, "Single", "Transfer single vertex group."}, + {REPLACE_ALL_VERTEX_GROUPS, "REPLACE_ALL_VERTEX_GROUPS", 1, "All", "Transfer all vertex groups."}, + {0, NULL, 0, NULL, NULL} +}; + +static EnumPropertyItem method_option_item[] = { + {BY_INDEX, "BY_INDEX", 1, "Vertex index", "Copy for identical meshes."}, + {BY_NEAREST_VERTEX, "BY_NEAREST_VERTEX", 1, "Nearest vertex", "Copy weight from closest vertex."}, + {BY_NEAREST_FACE, "BY_NEAREST_FACE", 1, "Nearest face", "Barycentric interpolation from nearest face."}, + {BY_NEAREST_VERTEX_IN_FACE, "BY_NEAREST_VERTEX_IN_FACE", 1, "Nearest vertex in face", "Copy weight from closest vertex in nearest face."}, + {0, NULL, 0, NULL, NULL} +}; + +static EnumPropertyItem replace_option_item[] = { + {REPLACE_ALL_WEIGHTS, "REPLACE_ALL_WEIGHTS", 1, "All", "Overwrites all weights."}, + {REPLACE_EMPTY_WEIGHTS, "REPLACE_EMPTY_WEIGHTS", 1, "Empty", "Adds weights to vertices with no weight."}, + {REPLACE_SELECTED_WEIGHTS, "REPLACE_SELECTED_WEIGHTS", 1, "Selected", "Replace selected weights."}, + {0, NULL, 0, NULL, NULL} +}; + /*copy weight*/ void vgroup_transfer_weight(MVert *mv_dst, float *weight_dst, float weight_src, ReplaceOption replace_option) { @@ -608,6 +629,12 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s free_bvhtree_from_mesh(&tree_mesh_faces_src); break; } + + /*free memory*/ + if (mface_src) MEM_freeN(mface_src); + if (dv_array_src) MEM_freeN(dv_array_src); + if (dv_array_dst) MEM_freeN(dv_array_dst); + return 1; } @@ -3002,13 +3029,9 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) int fail = 0; bDeformGroup *dg_src; - /* TODO: get these parameters from gui. - * For now 1,3,1 is default because GUI doesnt contain more than one button yet: - * Replace all weights in single vertexgroup based on interpolation of nearest face*/ - - VertexGroupOption vertex_group_option = 1; - MethodOption method_option = 3; - ReplaceOption replace_option = 1; + VertexGroupOption vertex_group_option = RNA_enum_get(op->ptr, "VertexGroupOption"); + MethodOption method_option = RNA_enum_get(op->ptr, "MethodOption"); + ReplaceOption replace_option = RNA_enum_get(op->ptr, "ReplaceOption"); /*Macro to loop through selected objects and perform operation depending on function, option and method*/ CTX_DATA_BEGIN(C, Object *, ob_slc, selected_editable_objects) @@ -3063,6 +3086,11 @@ void OBJECT_OT_vertex_group_transfer_weight(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + ot->prop = RNA_def_enum(ot->srna, "VertexGroupOption", vertex_group_option_item, 1, "Group", "What groups to transfer."); + ot->prop = RNA_def_enum(ot->srna, "MethodOption", method_option_item, 3, "Method", "How to calculate weight."); + ot->prop = RNA_def_enum(ot->srna, "ReplaceOption", replace_option_item, 1, "Replace", "What weights to overwrite"); } static EnumPropertyItem vgroup_items[] = { From bfd894b267b9753b36db60ed45ab512665519a95 Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Sun, 27 May 2012 15:57:43 +0000 Subject: [PATCH 045/347] added mesh_get_derived_deform(scene, ob_act, CD_MASK_BAREMESH | CD_MASK_ORIGINDEX) but now it crashes on: a: @0x9bc692c8 math_vector_inline.c 296 --- source/blender/editors/object/object_vgroup.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index c88fa164fdc..b9e185423d3 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -435,7 +435,7 @@ void vgroup_transfer_weight(MVert *mv_dst, float *weight_dst, float weight_src, } } -int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_src, MethodOption method_option, ReplaceOption replace_option) +int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_src, Scene *scene, MethodOption method_option, ReplaceOption replace_option) { bDeformGroup *dg_dst; Mesh *me_dst; @@ -460,7 +460,7 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s /*get meshes*/ me_dst = ob_dst->data; - dmesh_src = ob_src->derivedDeform; + dmesh_src = mesh_get_derived_deform(scene, ob_src, CD_MASK_BAREMESH | CD_MASK_ORIGINDEX); /*get vertex group arrays*/ ED_vgroup_give_parray(ob_src->data, &dv_array_src, &dv_tot_src, FALSE); @@ -3024,6 +3024,7 @@ void OBJECT_OT_vertex_group_copy_to_selected(wmOperatorType *ot) static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) { + Scene *scene = CTX_data_scene(C); Object *ob_act = CTX_data_active_object(C); int change = 0; int fail = 0; @@ -3041,14 +3042,14 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) switch (vertex_group_option) { case REPLACE_SINGLE_VERTEX_GROUP: - if (ED_vgroup_transfer_weight(ob_slc, ob_act, BLI_findlink(&ob_act->defbase, ob_act->actdef - 1), method_option, replace_option)) + if (ED_vgroup_transfer_weight(ob_slc, ob_act, BLI_findlink(&ob_act->defbase, ob_act->actdef - 1), scene, method_option, replace_option)) change++; else fail++; break; case REPLACE_ALL_VERTEX_GROUPS: for (dg_src = ob_act->defbase.first; dg_src; dg_src = dg_src->next) { - if (ED_vgroup_transfer_weight(ob_slc, ob_act, dg_src, method_option, replace_option)) change++; + if (ED_vgroup_transfer_weight(ob_slc, ob_act, dg_src, scene, method_option, replace_option)) change++; else fail++; } break; From ea9655ce14982f8d3bfed3edf8159c99e694197b Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Sun, 27 May 2012 17:34:10 +0000 Subject: [PATCH 046/347] Fixed iterators. Memory bugs persist... --- source/blender/editors/object/object_vgroup.c | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index b9e185423d3..c6345aff227 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -441,7 +441,7 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s Mesh *me_dst; DerivedMesh *dmesh_src; BVHTreeFromMesh tree_mesh_vertices_src, tree_mesh_faces_src = {NULL}; - MDeformVert **dv_array_src, **dv_array_dst; + MDeformVert **dv_array_src, **dv_array_dst, **dv_src, **dv_dst; MVert *mv_dst, *mv_src; MFace *mface_src; BVHTreeNearest nearest; @@ -490,7 +490,7 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s } /* loop through the vertices*/ - for (i = 0; i < dv_tot_dst; i++, dv_array_src++, dv_array_dst++, mv_dst++) { + for(i = 0, dv_src = dv_array_src, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++, dv_src++, mv_src++) { /*copy weight*/ dw_src = defvert_verify_index(*dv_array_src, index_src); @@ -503,8 +503,8 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s /*make node tree*/ bvhtree_from_mesh_verts(&tree_mesh_vertices_src, dmesh_src, 0.0, 2, 6); - /* loop through the vertices*/ - for (i = 0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++) { + /* loop trough vertices*/ + for(i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++, mv_src++){ /*reset nearest*/ /*nearest.index = -1; It is asumed using index of previous search as starting point result in speedup. It will be tested later*/ @@ -536,7 +536,7 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s bvhtree_from_mesh_faces(&tree_mesh_faces_src, dmesh_src, 0.0, 2, 6); /* loop through the vertices*/ - for (i = 0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++) { + for(i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++, mv_src++) { /*reset nearest*/ /*nearest.index = -1; It is asumed using index of previous search as starting point result in speedup. It will be tested later*/ @@ -552,8 +552,8 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s /*project onto face*/ normal_tri_v3(normal, mv_src[mface_src[nearest.index].v1].co, - mv_src[mface_src[nearest.index].v2].co, - mv_src[mface_src[nearest.index].v3].co); + mv_src[mface_src[index_nearest].v2].co, + mv_src[mface_src[index_nearest].v3].co); project_v3_plane(tmp_co, normal, mv_src[mface_src[index_nearest].v1].co); @@ -589,7 +589,7 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s bvhtree_from_mesh_faces(&tree_mesh_faces_src, dmesh_src, 0.0, 2, 6); /*loop through the vertices*/ - for (i = 0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++) { + for(i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_src++, mv_src++){ /*reset nearest*/ /*nearest.index = -1; It is asumed using index of previous search as starting point result in speedup. It will be tested later*/ @@ -630,10 +630,12 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s break; } - /*free memory*/ + /*free memory*//*TODO must free wehn function breaks on return 0 as well, right?*/ if (mface_src) MEM_freeN(mface_src); if (dv_array_src) MEM_freeN(dv_array_src); if (dv_array_dst) MEM_freeN(dv_array_dst); + if (dv_src) MEM_freeN(dv_src); + if (dv_dst) MEM_freeN(dv_dst); return 1; } From 1dce081e2ba094158ce062e439d613127c756821 Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Sun, 27 May 2012 17:47:21 +0000 Subject: [PATCH 047/347] small cleaning --- source/blender/editors/object/object_vgroup.c | 94 +++++++++---------- 1 file changed, 46 insertions(+), 48 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index c6345aff227..15fca1548e0 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -449,32 +449,32 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s int dv_tot_src, dv_tot_dst, i, index_dst, index_src, index_nearest, index_nearest_vertex; float weight, tmp_weight[4], tmp_co[3], normal[3], tmp_mat[4][4], dist_v1, dist_v2, dist_v3, dist_v4; - /*create new and overwrite vertex group on destination without data*/ + /* create new and overwrite vertex group on destination without data */ if (!defgroup_find_name(ob_dst, dg_src->name) || replace_option == REPLACE_ALL_WEIGHTS) { ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_src->name)); ED_vgroup_add_name(ob_dst, dg_src->name); } - /*get destination deformgroup*/ + /* get destination deformgroup */ dg_dst = defgroup_find_name(ob_dst, dg_src->name); - /*get meshes*/ + /* get meshes */ me_dst = ob_dst->data; dmesh_src = mesh_get_derived_deform(scene, ob_src, CD_MASK_BAREMESH | CD_MASK_ORIGINDEX); - /*get vertex group arrays*/ + /* get vertex group arrays */ ED_vgroup_give_parray(ob_src->data, &dv_array_src, &dv_tot_src, FALSE); ED_vgroup_give_parray(ob_dst->data, &dv_array_dst, &dv_tot_dst, FALSE); - /*get indexes of vertex groups*/ + /* get indexes of vertex groups */ index_src = BLI_findindex(&ob_src->defbase, dg_src); index_dst = BLI_findindex(&ob_dst->defbase, dg_dst); - /*get vertices*/ + /* get vertices */ mv_dst = me_dst->mvert; mv_src = dmesh_src->getVertArray(dmesh_src); - /*prepare transformation matrix*/ + /* prepare transformation matrix */ invert_m4_m4(ob_src->imat, ob_src->obmat); mult_m4_m4m4(tmp_mat, ob_src->imat, ob_dst->obmat); @@ -492,7 +492,7 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s /* loop through the vertices*/ for(i = 0, dv_src = dv_array_src, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++, dv_src++, mv_src++) { - /*copy weight*/ + /* copy weight */ dw_src = defvert_verify_index(*dv_array_src, index_src); dw_dst = defvert_verify_index(*dv_array_dst, index_dst); vgroup_transfer_weight(mv_dst, &dw_dst->weight, dw_src->weight, replace_option); @@ -500,70 +500,70 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s break; case BY_NEAREST_VERTEX: - /*make node tree*/ + /* make node tree */ bvhtree_from_mesh_verts(&tree_mesh_vertices_src, dmesh_src, 0.0, 2, 6); - /* loop trough vertices*/ + /* loop trough vertices */ for(i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++, mv_src++){ - /*reset nearest*/ - /*nearest.index = -1; It is asumed using index of previous search as starting point result in speedup. It will be tested later*/ + /* reset nearest */ + /* nearest.index = -1; It is asumed using index of previous search as starting point result in speedup. It will be tested later */ nearest.dist = FLT_MAX; - /*transform into target space*/ + /* transform into target space */ mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); - /*node tree accelerated search for closest vetex*/ + /* node tree accelerated search for closest vetex */ BLI_bvhtree_find_nearest(tree_mesh_vertices_src.tree, tmp_co, &nearest, tree_mesh_vertices_src.nearest_callback, &tree_mesh_vertices_src); - /*copy weight*/ + /* copy weight */ dw_src = defvert_verify_index(dv_array_src[nearest.index], index_src); dw_dst = defvert_verify_index(*dv_array_dst, index_dst); vgroup_transfer_weight(mv_dst, &dw_dst->weight, dw_src->weight, replace_option); } - /*free memory*/ + /* free memory */ free_bvhtree_from_mesh(&tree_mesh_vertices_src); break; case BY_NEAREST_FACE: - /*get faces*/ + /* get faces */ DM_ensure_tessface(dmesh_src); mface_src = dmesh_src->getTessFaceArray(dmesh_src); - /*make node tree*/ + /* make node tree */ bvhtree_from_mesh_faces(&tree_mesh_faces_src, dmesh_src, 0.0, 2, 6); - /* loop through the vertices*/ + /* loop through the vertices */ for(i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++, mv_src++) { - /*reset nearest*/ - /*nearest.index = -1; It is asumed using index of previous search as starting point result in speedup. It will be tested later*/ + /* reset nearest */ + /* nearest.index = -1; It is asumed using index of previous search as starting point result in speedup. It will be tested later */ nearest.dist = FLT_MAX; - /*transform into target space*/ + /* transform into target space */ mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); - /*node tree accelerated search for closest face*/ + /* node tree accelerated search for closest face */ BLI_bvhtree_find_nearest(tree_mesh_faces_src.tree, tmp_co, &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src); index_nearest = nearest.index; - /*project onto face*/ + /* project onto face */ normal_tri_v3(normal, mv_src[mface_src[nearest.index].v1].co, mv_src[mface_src[index_nearest].v2].co, mv_src[mface_src[index_nearest].v3].co); project_v3_plane(tmp_co, normal, mv_src[mface_src[index_nearest].v1].co); - /*interpolate weights*/ + /* interpolate weights */ interp_weights_face_v3(tmp_weight, mv_src[mface_src[index_nearest].v1].co, mv_src[mface_src[index_nearest].v2].co, mv_src[mface_src[index_nearest].v3].co, mv_src[mface_src[index_nearest].v4].co, tmp_co); - /*get weights*/ + /* get weights */ weight = tmp_weight[0] * defvert_verify_index(dv_array_src[mface_src[index_nearest].v1], index_src)->weight; weight += tmp_weight[1] * defvert_verify_index(dv_array_src[mface_src[index_nearest].v2], index_src)->weight; weight += tmp_weight[2] * defvert_verify_index(dv_array_src[mface_src[index_nearest].v3], index_src)->weight; @@ -571,44 +571,44 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s weight += tmp_weight[3] * defvert_verify_index(dv_array_src[mface_src[index_nearest].v4], index_src)->weight; } - /*copy weight*/ + /* copy weight */ dw_dst = defvert_verify_index(*dv_array_dst, index_dst); vgroup_transfer_weight(mv_dst, &dw_dst->weight, weight, replace_option); } - /*free memory*/ + /* free memory */ free_bvhtree_from_mesh(&tree_mesh_faces_src); break; case BY_NEAREST_VERTEX_IN_FACE: - /*get faces*/ + /* get faces */ DM_ensure_tessface(dmesh_src); mface_src = dmesh_src->getTessFaceArray(dmesh_src); - /*make node tree*/ + /* make node tree */ bvhtree_from_mesh_faces(&tree_mesh_faces_src, dmesh_src, 0.0, 2, 6); - /*loop through the vertices*/ + /* loop through the vertices */ for(i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_src++, mv_src++){ - /*reset nearest*/ - /*nearest.index = -1; It is asumed using index of previous search as starting point result in speedup. It will be tested later*/ + /* reset nearest */ + /* nearest.index = -1; It is asumed using index of previous search as starting point result in speedup. It will be tested later */ nearest.dist = FLT_MAX; - /*transform into target space*/ + /* transform into target space */ mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); - /*node tree accelerated search for closest face*/ + /* node tree accelerated search for closest face */ BLI_bvhtree_find_nearest(tree_mesh_faces_src.tree, tmp_co, &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src); index_nearest = nearest.index; - /*get distances*/ + /* get distances */ dist_v1 = len_squared_v3v3(tmp_co, mv_src[mface_src[index_nearest].v1].co); dist_v2 = len_squared_v3v3(tmp_co, mv_src[mface_src[index_nearest].v2].co); dist_v3 = len_squared_v3v3(tmp_co, mv_src[mface_src[index_nearest].v3].co); - /*get closest vertex*/ + /* get closest vertex */ if (dist_v1 < dist_v2 && dist_v1 < dist_v3) index_nearest_vertex = mface_src[index_nearest].v1; else if (dist_v2 < dist_v3) index_nearest_vertex = mface_src[index_nearest].v2; else index_nearest_vertex = mface_src[index_nearest].v3; @@ -619,23 +619,21 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s } } - /*copy weight*/ + /* copy weight */ dw_src = defvert_verify_index(dv_array_src[index_nearest_vertex], index_src); dw_dst = defvert_verify_index(*dv_array_dst, index_dst); vgroup_transfer_weight(mv_dst, &dw_dst->weight, dw_src->weight, replace_option); } - /*free memory*/ + /* free memory */ free_bvhtree_from_mesh(&tree_mesh_faces_src); break; } - /*free memory*//*TODO must free wehn function breaks on return 0 as well, right?*/ + /*free memory*//*TODO must free when function breaks on return 0 as well, right?*/ if (mface_src) MEM_freeN(mface_src); if (dv_array_src) MEM_freeN(dv_array_src); if (dv_array_dst) MEM_freeN(dv_array_dst); - if (dv_src) MEM_freeN(dv_src); - if (dv_dst) MEM_freeN(dv_dst); return 1; } @@ -3036,7 +3034,7 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) MethodOption method_option = RNA_enum_get(op->ptr, "MethodOption"); ReplaceOption replace_option = RNA_enum_get(op->ptr, "ReplaceOption"); - /*Macro to loop through selected objects and perform operation depending on function, option and method*/ + /* Macro to loop through selected objects and perform operation depending on function, option and method */ CTX_DATA_BEGIN(C, Object *, ob_slc, selected_editable_objects) { @@ -3059,14 +3057,14 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) } } - /*Event notifiers for correct display of data*/ + /* Event notifiers for correct display of data */ DAG_id_tag_update(&ob_slc->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob_slc); WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob_slc->data); CTX_DATA_END; - /*Report error when task can not be completed with available functions.*/ + /* Report error when task can not be completed with available functions. */ if ((change == 0 && fail == 0) || fail) { BKE_reportf(op->reports, RPT_ERROR, "Copy to VGroups to Selected warning done %d, failed %d, object data must have matching indices", @@ -3075,7 +3073,7 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -/*transfers weight from active to selected*/ +/* transfers weight from active to selected */ void OBJECT_OT_vertex_group_transfer_weight(wmOperatorType *ot) { /* identifiers */ @@ -3091,8 +3089,8 @@ void OBJECT_OT_vertex_group_transfer_weight(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ - ot->prop = RNA_def_enum(ot->srna, "VertexGroupOption", vertex_group_option_item, 1, "Group", "What groups to transfer."); - ot->prop = RNA_def_enum(ot->srna, "MethodOption", method_option_item, 3, "Method", "How to calculate weight."); + ot->prop = RNA_def_enum(ot->srna, "VertexGroupOption", vertex_group_option_item, 1, "Group", "What groups to transfer"); + ot->prop = RNA_def_enum(ot->srna, "MethodOption", method_option_item, 3, "Method", "How to calculate weight"); ot->prop = RNA_def_enum(ot->srna, "ReplaceOption", replace_option_item, 1, "Replace", "What weights to overwrite"); } From be4d30bf8e03f878522b4422d30bb172e17bffc5 Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Sun, 27 May 2012 18:05:10 +0000 Subject: [PATCH 048/347] Bogus MEM_freeN removed and cleaned descriptions. --- source/blender/editors/object/object_vgroup.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 15fca1548e0..e2dda936b19 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -631,7 +631,6 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s } /*free memory*//*TODO must free when function breaks on return 0 as well, right?*/ - if (mface_src) MEM_freeN(mface_src); if (dv_array_src) MEM_freeN(dv_array_src); if (dv_array_dst) MEM_freeN(dv_array_dst); @@ -3089,9 +3088,9 @@ void OBJECT_OT_vertex_group_transfer_weight(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ - ot->prop = RNA_def_enum(ot->srna, "VertexGroupOption", vertex_group_option_item, 1, "Group", "What groups to transfer"); - ot->prop = RNA_def_enum(ot->srna, "MethodOption", method_option_item, 3, "Method", "How to calculate weight"); - ot->prop = RNA_def_enum(ot->srna, "ReplaceOption", replace_option_item, 1, "Replace", "What weights to overwrite"); + ot->prop = RNA_def_enum(ot->srna, "VertexGroupOption", vertex_group_option_item, 1, "Group", ""); + ot->prop = RNA_def_enum(ot->srna, "MethodOption", method_option_item, 3, "Method", ""); + ot->prop = RNA_def_enum(ot->srna, "ReplaceOption", replace_option_item, 1, "Replace", ""); } static EnumPropertyItem vgroup_items[] = { From 0d42015671b3f835742c023178f040b898276a79 Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Thu, 31 May 2012 19:09:23 +0000 Subject: [PATCH 049/347] Fixes to bugs that appeared during restructure. --- source/blender/editors/object/object_vgroup.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index e2dda936b19..e74c16741d8 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -426,7 +426,7 @@ void vgroup_transfer_weight(MVert *mv_dst, float *weight_dst, float weight_src, break; case REPLACE_EMPTY_WEIGHTS: - if (!weight_dst || weight_dst == 0) *weight_dst = weight_src; + if (*weight_dst == 0) *weight_dst = weight_src; break; case REPLACE_SELECTED_WEIGHTS: @@ -493,8 +493,8 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s for(i = 0, dv_src = dv_array_src, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++, dv_src++, mv_src++) { /* copy weight */ - dw_src = defvert_verify_index(*dv_array_src, index_src); - dw_dst = defvert_verify_index(*dv_array_dst, index_dst); + dw_src = defvert_verify_index(*dv_src, index_src); + dw_dst = defvert_verify_index(*dv_dst, index_dst); vgroup_transfer_weight(mv_dst, &dw_dst->weight, dw_src->weight, replace_option); } break; @@ -504,7 +504,7 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s bvhtree_from_mesh_verts(&tree_mesh_vertices_src, dmesh_src, 0.0, 2, 6); /* loop trough vertices */ - for(i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++, mv_src++){ + for(i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++, mv_dst++){ /* reset nearest */ /* nearest.index = -1; It is asumed using index of previous search as starting point result in speedup. It will be tested later */ @@ -519,7 +519,7 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s /* copy weight */ dw_src = defvert_verify_index(dv_array_src[nearest.index], index_src); - dw_dst = defvert_verify_index(*dv_array_dst, index_dst); + dw_dst = defvert_verify_index(*dv_dst, index_dst); vgroup_transfer_weight(mv_dst, &dw_dst->weight, dw_src->weight, replace_option); } @@ -536,7 +536,7 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s bvhtree_from_mesh_faces(&tree_mesh_faces_src, dmesh_src, 0.0, 2, 6); /* loop through the vertices */ - for(i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++, mv_src++) { + for(i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++, mv_dst++) { /* reset nearest */ /* nearest.index = -1; It is asumed using index of previous search as starting point result in speedup. It will be tested later */ @@ -572,7 +572,7 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s } /* copy weight */ - dw_dst = defvert_verify_index(*dv_array_dst, index_dst); + dw_dst = defvert_verify_index(*dv_dst, index_dst); vgroup_transfer_weight(mv_dst, &dw_dst->weight, weight, replace_option); } @@ -589,7 +589,7 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s bvhtree_from_mesh_faces(&tree_mesh_faces_src, dmesh_src, 0.0, 2, 6); /* loop through the vertices */ - for(i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_src++, mv_src++){ + for(i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++, mv_dst++){ /* reset nearest */ /* nearest.index = -1; It is asumed using index of previous search as starting point result in speedup. It will be tested later */ @@ -621,7 +621,7 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s /* copy weight */ dw_src = defvert_verify_index(dv_array_src[index_nearest_vertex], index_src); - dw_dst = defvert_verify_index(*dv_array_dst, index_dst); + dw_dst = defvert_verify_index(*dv_dst, index_dst); vgroup_transfer_weight(mv_dst, &dw_dst->weight, dw_src->weight, replace_option); } From 7b294890167dbc8850fc98e9d101c46359c27adb Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Sun, 3 Jun 2012 16:44:48 +0000 Subject: [PATCH 050/347] BVHTree usage optimized for transferring between meshes of 300k faces. Mesh were the shape of a human. Optimizing for anything less would not make sense because it happens ~instant moving to 10 tree from binary tree increased speed by ~30% initiating additional searches with the first increased speed by ~99% Now function completes in less than two seconds on my amd 2,6ghz --- source/blender/editors/object/object_vgroup.c | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index e74c16741d8..03147818360 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -501,15 +501,15 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s case BY_NEAREST_VERTEX: /* make node tree */ - bvhtree_from_mesh_verts(&tree_mesh_vertices_src, dmesh_src, 0.0, 2, 6); + bvhtree_from_mesh_verts(&tree_mesh_vertices_src, dmesh_src, FLT_EPSILON, 10, 6); + + /* reset nearest */ + nearest.dist = FLT_MAX; + nearest.index = -1; /* loop trough vertices */ for(i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++, mv_dst++){ - /* reset nearest */ - /* nearest.index = -1; It is asumed using index of previous search as starting point result in speedup. It will be tested later */ - nearest.dist = FLT_MAX; - /* transform into target space */ mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); @@ -533,15 +533,15 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s mface_src = dmesh_src->getTessFaceArray(dmesh_src); /* make node tree */ - bvhtree_from_mesh_faces(&tree_mesh_faces_src, dmesh_src, 0.0, 2, 6); + bvhtree_from_mesh_faces(&tree_mesh_faces_src, dmesh_src, FLT_EPSILON, 10, 6); + + /* reset nearest */ + nearest.dist = FLT_MAX; + nearest.index = -1; /* loop through the vertices */ for(i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++, mv_dst++) { - /* reset nearest */ - /* nearest.index = -1; It is asumed using index of previous search as starting point result in speedup. It will be tested later */ - nearest.dist = FLT_MAX; - /* transform into target space */ mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); @@ -586,15 +586,15 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s mface_src = dmesh_src->getTessFaceArray(dmesh_src); /* make node tree */ - bvhtree_from_mesh_faces(&tree_mesh_faces_src, dmesh_src, 0.0, 2, 6); + bvhtree_from_mesh_faces(&tree_mesh_faces_src, dmesh_src, FLT_EPSILON, 10, 6); + + /* reset nearest */ + nearest.dist = FLT_MAX; + nearest.index = -1; /* loop through the vertices */ for(i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++, mv_dst++){ - /* reset nearest */ - /* nearest.index = -1; It is asumed using index of previous search as starting point result in speedup. It will be tested later */ - nearest.dist = FLT_MAX; - /* transform into target space */ mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); From 512b35754e81c8b5fc4fe93fc26b995f5083dc60 Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Sun, 3 Jun 2012 17:16:50 +0000 Subject: [PATCH 051/347] Bugfix to bug from optimizing... --- source/blender/editors/object/object_vgroup.c | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 03147818360..b389b0b66b7 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -503,13 +503,12 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s /* make node tree */ bvhtree_from_mesh_verts(&tree_mesh_vertices_src, dmesh_src, FLT_EPSILON, 10, 6); - /* reset nearest */ - nearest.dist = FLT_MAX; - nearest.index = -1; - /* loop trough vertices */ for(i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++, mv_dst++){ + /* reset nearest */ + nearest.dist = FLT_MAX; + /* transform into target space */ mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); @@ -535,13 +534,12 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s /* make node tree */ bvhtree_from_mesh_faces(&tree_mesh_faces_src, dmesh_src, FLT_EPSILON, 10, 6); - /* reset nearest */ - nearest.dist = FLT_MAX; - nearest.index = -1; - /* loop through the vertices */ for(i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++, mv_dst++) { + /* reset nearest */ + nearest.dist = FLT_MAX; + /* transform into target space */ mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); @@ -588,13 +586,12 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s /* make node tree */ bvhtree_from_mesh_faces(&tree_mesh_faces_src, dmesh_src, FLT_EPSILON, 10, 6); - /* reset nearest */ - nearest.dist = FLT_MAX; - nearest.index = -1; - /* loop through the vertices */ for(i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++, mv_dst++){ + /* reset nearest */ + nearest.dist = FLT_MAX; + /* transform into target space */ mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); From c63dcaee07d86a23652bb4fce6f3ecde94bbee38 Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Sun, 3 Jun 2012 18:44:17 +0000 Subject: [PATCH 052/347] small fix to mem release when using index method --- source/blender/editors/object/object_vgroup.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index b389b0b66b7..8347480ecda 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -486,6 +486,8 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s dv_array_src == NULL || dv_array_dst == NULL) { ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_dst->name)); + if (dv_array_src) MEM_freeN(dv_array_src); + if (dv_array_dst) MEM_freeN(dv_array_dst); return 0; } @@ -627,7 +629,7 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s break; } - /*free memory*//*TODO must free when function breaks on return 0 as well, right?*/ + /*free memory*/ if (dv_array_src) MEM_freeN(dv_array_src); if (dv_array_dst) MEM_freeN(dv_array_dst); From 87c585c1ba120d92a42add7ffe3c2aff12f93b30 Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Sun, 3 Jun 2012 20:23:41 +0000 Subject: [PATCH 053/347] Reverting to binary tree because related optimization with type 10 tree were bugged. Now feature completes in ~5 sec for a mesh with 300k vertices. but it works as intended. --- source/blender/editors/object/object_vgroup.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 8347480ecda..d4d81501f9a 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -503,13 +503,14 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s case BY_NEAREST_VERTEX: /* make node tree */ - bvhtree_from_mesh_verts(&tree_mesh_vertices_src, dmesh_src, FLT_EPSILON, 10, 6); + bvhtree_from_mesh_verts(&tree_mesh_vertices_src, dmesh_src, FLT_EPSILON, 2, 6); /* loop trough vertices */ for(i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++, mv_dst++){ /* reset nearest */ nearest.dist = FLT_MAX; + /* nearest.index = -1; when this is commented out, the next search is initiated by the index of the previous. */ /* transform into target space */ mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); @@ -534,13 +535,14 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s mface_src = dmesh_src->getTessFaceArray(dmesh_src); /* make node tree */ - bvhtree_from_mesh_faces(&tree_mesh_faces_src, dmesh_src, FLT_EPSILON, 10, 6); + bvhtree_from_mesh_faces(&tree_mesh_faces_src, dmesh_src, FLT_EPSILON, 2, 6); /* loop through the vertices */ for(i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++, mv_dst++) { /* reset nearest */ nearest.dist = FLT_MAX; + /* nearest.index = -1; when this is commented out, the next search is initiated by the index of the previous. */ /* transform into target space */ mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); @@ -586,13 +588,14 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s mface_src = dmesh_src->getTessFaceArray(dmesh_src); /* make node tree */ - bvhtree_from_mesh_faces(&tree_mesh_faces_src, dmesh_src, FLT_EPSILON, 10, 6); + bvhtree_from_mesh_faces(&tree_mesh_faces_src, dmesh_src, FLT_EPSILON, 2, 6); /* loop through the vertices */ for(i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++, mv_dst++){ /* reset nearest */ nearest.dist = FLT_MAX; + /* nearest.index = -1; when this is commented out, the next search is initiated by the index of the previous. */ /* transform into target space */ mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); From cd346252d720307c4943699f62f82289683fd9d1 Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Sun, 3 Jun 2012 21:34:17 +0000 Subject: [PATCH 054/347] After reverting to binary tree, starting search at the top by reseting nearest is marginally faster than using previous search. --- source/blender/editors/object/object_vgroup.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index d4d81501f9a..52d5bcaffa7 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -510,7 +510,8 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s /* reset nearest */ nearest.dist = FLT_MAX; - /* nearest.index = -1; when this is commented out, the next search is initiated by the index of the previous. */ + /* With current binary tree its marginally faster to start searching at the top, as opposed to previous search. */ + nearest.index = -1; /* transform into target space */ mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); @@ -542,7 +543,8 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s /* reset nearest */ nearest.dist = FLT_MAX; - /* nearest.index = -1; when this is commented out, the next search is initiated by the index of the previous. */ + /* With current binary tree its marginally faster to start searching at the top, as opposed to previous search. */ + nearest.index = -1; /* transform into target space */ mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); @@ -595,7 +597,8 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s /* reset nearest */ nearest.dist = FLT_MAX; - /* nearest.index = -1; when this is commented out, the next search is initiated by the index of the previous. */ + /* With current binary tree its marginally faster to start searching at the top, as opposed to previous search. */ + nearest.index = -1; /* transform into target space */ mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); From 51cbfba3067fcd2e2d5c3966f563f8911f147d17 Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Mon, 4 Jun 2012 22:17:40 +0000 Subject: [PATCH 055/347] Now the feature is more intuitive. copying from selected to active. --- source/blender/editors/object/object_vgroup.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 52d5bcaffa7..d58720d5293 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -3046,14 +3046,14 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) switch (vertex_group_option) { case REPLACE_SINGLE_VERTEX_GROUP: - if (ED_vgroup_transfer_weight(ob_slc, ob_act, BLI_findlink(&ob_act->defbase, ob_act->actdef - 1), scene, method_option, replace_option)) + if (ED_vgroup_transfer_weight(ob_act, ob_slc, BLI_findlink(&ob_slc->defbase, ob_slc->actdef - 1), scene, method_option, replace_option)) change++; else fail++; break; case REPLACE_ALL_VERTEX_GROUPS: - for (dg_src = ob_act->defbase.first; dg_src; dg_src = dg_src->next) { - if (ED_vgroup_transfer_weight(ob_slc, ob_act, dg_src, scene, method_option, replace_option)) change++; + for (dg_src = ob_slc->defbase.first; dg_src; dg_src = dg_src->next) { + if (ED_vgroup_transfer_weight(ob_act, ob_slc, dg_src, scene, method_option, replace_option)) change++; else fail++; } break; From 59d699805c460f4f68e52f4005b6c43d6f4f7ea2 Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Tue, 5 Jun 2012 20:48:01 +0000 Subject: [PATCH 056/347] Bugfix, no longer crashing wehn no source vertex group. --- source/blender/editors/object/object_vgroup.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index d58720d5293..32433caee5a 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -396,8 +396,8 @@ typedef enum ReplaceOption { } ReplaceOption; static EnumPropertyItem vertex_group_option_item[] = { - {REPLACE_SINGLE_VERTEX_GROUP, "REPLACE_SINGLE_VERTEX_GROUP", 1, "Single", "Transfer single vertex group."}, - {REPLACE_ALL_VERTEX_GROUPS, "REPLACE_ALL_VERTEX_GROUPS", 1, "All", "Transfer all vertex groups."}, + {REPLACE_SINGLE_VERTEX_GROUP, "REPLACE_SINGLE_VERTEX_GROUP", 1, "Single", "Transfer single vertex group from selected to active mesh."}, + {REPLACE_ALL_VERTEX_GROUPS, "REPLACE_ALL_VERTEX_GROUPS", 1, "All", "Transfer all vertex groups from selected to active mesh."}, {0, NULL, 0, NULL, NULL} }; @@ -3042,12 +3042,12 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) CTX_DATA_BEGIN(C, Object *, ob_slc, selected_editable_objects) { - if (ob_act != ob_slc) { + if (ob_act != ob_slc && ob_slc->defbase.first) { switch (vertex_group_option) { case REPLACE_SINGLE_VERTEX_GROUP: - if (ED_vgroup_transfer_weight(ob_act, ob_slc, BLI_findlink(&ob_slc->defbase, ob_slc->actdef - 1), scene, method_option, replace_option)) - change++; + if (ED_vgroup_transfer_weight(ob_act, ob_slc, + BLI_findlink(&ob_slc->defbase, ob_slc->actdef - 1), scene, method_option, replace_option)) change++; else fail++; break; @@ -3059,6 +3059,7 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) break; } } + else change++; } /* Event notifiers for correct display of data */ @@ -3081,9 +3082,9 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) void OBJECT_OT_vertex_group_transfer_weight(wmOperatorType *ot) { /* identifiers */ - ot->name = "Transfer weight to selected"; + ot->name = "Transfer weight"; ot->idname = "OBJECT_OT_vertex_group_transfer_weight"; - ot->description = "Transfers weight from active to selected depending on options"; + ot->description = "Transfer weight paint to active from selected mesh"; /* api callbacks */ ot->poll = vertex_group_poll; From 2548494bc19d1ade390050ef5af68c04047bb6e8 Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Tue, 5 Jun 2012 21:10:15 +0000 Subject: [PATCH 057/347] Removed confusing error reporting code. The confusing part was inconsitent reporting. It reported un eaven indices when only one source and a fail, but not when several sources and some success and some fail. --- source/blender/editors/object/object_vgroup.c | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 32433caee5a..af5d61cac9d 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -3030,8 +3030,6 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); Object *ob_act = CTX_data_active_object(C); - int change = 0; - int fail = 0; bDeformGroup *dg_src; VertexGroupOption vertex_group_option = RNA_enum_get(op->ptr, "VertexGroupOption"); @@ -3046,20 +3044,16 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) switch (vertex_group_option) { case REPLACE_SINGLE_VERTEX_GROUP: - if (ED_vgroup_transfer_weight(ob_act, ob_slc, - BLI_findlink(&ob_slc->defbase, ob_slc->actdef - 1), scene, method_option, replace_option)) change++; - else fail++; + ED_vgroup_transfer_weight(ob_act, ob_slc, BLI_findlink(&ob_slc->defbase, ob_slc->actdef - 1), scene, method_option, replace_option); break; case REPLACE_ALL_VERTEX_GROUPS: for (dg_src = ob_slc->defbase.first; dg_src; dg_src = dg_src->next) { - if (ED_vgroup_transfer_weight(ob_act, ob_slc, dg_src, scene, method_option, replace_option)) change++; - else fail++; + ED_vgroup_transfer_weight(ob_act, ob_slc, dg_src, scene, method_option, replace_option); } break; } } - else change++; } /* Event notifiers for correct display of data */ @@ -3069,12 +3063,6 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) CTX_DATA_END; - /* Report error when task can not be completed with available functions. */ - if ((change == 0 && fail == 0) || fail) { - BKE_reportf(op->reports, RPT_ERROR, - "Copy to VGroups to Selected warning done %d, failed %d, object data must have matching indices", - change, fail); - } return OPERATOR_FINISHED; } From 5414ea4701c2e90cbef59bc8eef1f7a028a6738a Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Wed, 6 Jun 2012 23:21:45 +0000 Subject: [PATCH 058/347] Fixed naming from "single vertex group" to "active vertex group" --- source/blender/editors/object/object_vgroup.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index af5d61cac9d..f93867f4695 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -378,7 +378,7 @@ int ED_vgroup_copy_array(Object *ob, Object *ob_from) /***********************Start transfer weight*********************************/ typedef enum VertexGroupOption { - REPLACE_SINGLE_VERTEX_GROUP = 1, + REPLACE_ACTIVE_VERTEX_GROUP = 1, REPLACE_ALL_VERTEX_GROUPS = 2 } VertexGroupOption; @@ -396,7 +396,7 @@ typedef enum ReplaceOption { } ReplaceOption; static EnumPropertyItem vertex_group_option_item[] = { - {REPLACE_SINGLE_VERTEX_GROUP, "REPLACE_SINGLE_VERTEX_GROUP", 1, "Single", "Transfer single vertex group from selected to active mesh."}, + {REPLACE_ACTIVE_VERTEX_GROUP, "REPLACE_ACTIVE_VERTEX_GROUP", 1, "Active", "Transfer active vertex group from selected to active mesh."}, {REPLACE_ALL_VERTEX_GROUPS, "REPLACE_ALL_VERTEX_GROUPS", 1, "All", "Transfer all vertex groups from selected to active mesh."}, {0, NULL, 0, NULL, NULL} }; @@ -3043,7 +3043,7 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) if (ob_act != ob_slc && ob_slc->defbase.first) { switch (vertex_group_option) { - case REPLACE_SINGLE_VERTEX_GROUP: + case REPLACE_ACTIVE_VERTEX_GROUP: ED_vgroup_transfer_weight(ob_act, ob_slc, BLI_findlink(&ob_slc->defbase, ob_slc->actdef - 1), scene, method_option, replace_option); break; From 340e156a2f8fd58e1ad4cba4464d347a2a5aeb6e Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Mon, 11 Jun 2012 19:31:22 +0000 Subject: [PATCH 059/347] Bugfix: No longer crashes when there is no dverts on target mesh from before. --- source/blender/editors/object/object_vgroup.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index f93867f4695..7f5c8d14f49 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -459,8 +459,11 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s dg_dst = defgroup_find_name(ob_dst, dg_src->name); /* get meshes */ - me_dst = ob_dst->data; dmesh_src = mesh_get_derived_deform(scene, ob_src, CD_MASK_BAREMESH | CD_MASK_ORIGINDEX); + me_dst = ob_dst->data; + + /* create data in memory when nothing there */ + if (!me_dst->dvert) ED_vgroup_data_create(ob_dst->data); /* get vertex group arrays */ ED_vgroup_give_parray(ob_src->data, &dv_array_src, &dv_tot_src, FALSE); From 995b9d5e8de4a69f96c5017a6ee859ab89785939 Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Mon, 11 Jun 2012 20:32:34 +0000 Subject: [PATCH 060/347] style cleanup fixed naming --- source/blender/editors/object/object_vgroup.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 7f5c8d14f49..7873fa16ea3 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -3035,9 +3035,9 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) Object *ob_act = CTX_data_active_object(C); bDeformGroup *dg_src; - VertexGroupOption vertex_group_option = RNA_enum_get(op->ptr, "VertexGroupOption"); - MethodOption method_option = RNA_enum_get(op->ptr, "MethodOption"); - ReplaceOption replace_option = RNA_enum_get(op->ptr, "ReplaceOption"); + VertexGroupOption vertex_group_option = RNA_enum_get(op->ptr, "vertex_group_option"); + MethodOption method_option = RNA_enum_get(op->ptr, "method_option"); + ReplaceOption replace_option = RNA_enum_get(op->ptr, "replace_option"); /* Macro to loop through selected objects and perform operation depending on function, option and method */ CTX_DATA_BEGIN(C, Object *, ob_slc, selected_editable_objects) @@ -3085,9 +3085,9 @@ void OBJECT_OT_vertex_group_transfer_weight(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ - ot->prop = RNA_def_enum(ot->srna, "VertexGroupOption", vertex_group_option_item, 1, "Group", ""); - ot->prop = RNA_def_enum(ot->srna, "MethodOption", method_option_item, 3, "Method", ""); - ot->prop = RNA_def_enum(ot->srna, "ReplaceOption", replace_option_item, 1, "Replace", ""); + ot->prop = RNA_def_enum(ot->srna, "vertex_group_option", vertex_group_option_item, 1, "Group", ""); + ot->prop = RNA_def_enum(ot->srna, "method_option", method_option_item, 3, "Method", ""); + ot->prop = RNA_def_enum(ot->srna, "replace_option", replace_option_item, 1, "Replace", ""); } static EnumPropertyItem vgroup_items[] = { From 9d32423f3e695f8bdd5a0d1b032b5e822613977a Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Mon, 11 Jun 2012 22:58:49 +0000 Subject: [PATCH 061/347] Bugfix: no longer crashes when dverts does not exist on source. Added release for derivedmesh. --- source/blender/editors/object/object_vgroup.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 7873fa16ea3..5a2a9a06e39 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -438,7 +438,7 @@ void vgroup_transfer_weight(MVert *mv_dst, float *weight_dst, float weight_src, int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_src, Scene *scene, MethodOption method_option, ReplaceOption replace_option) { bDeformGroup *dg_dst; - Mesh *me_dst; + Mesh *me_dst, *me_src; DerivedMesh *dmesh_src; BVHTreeFromMesh tree_mesh_vertices_src, tree_mesh_faces_src = {NULL}; MDeformVert **dv_array_src, **dv_array_dst, **dv_src, **dv_dst; @@ -461,6 +461,10 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s /* get meshes */ dmesh_src = mesh_get_derived_deform(scene, ob_src, CD_MASK_BAREMESH | CD_MASK_ORIGINDEX); me_dst = ob_dst->data; + me_src = ob_src->data; + + /* sanity check */ + if (!me_src->dvert) return 0; /* create data in memory when nothing there */ if (!me_dst->dvert) ED_vgroup_data_create(ob_dst->data); @@ -491,6 +495,7 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_dst->name)); if (dv_array_src) MEM_freeN(dv_array_src); if (dv_array_dst) MEM_freeN(dv_array_dst); + dmesh_src->release(dmesh_src); return 0; } @@ -641,6 +646,7 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s /*free memory*/ if (dv_array_src) MEM_freeN(dv_array_src); if (dv_array_dst) MEM_freeN(dv_array_dst); + dmesh_src->release(dmesh_src); return 1; } From 108d157254f4e00aee11002020b899279d28d1f9 Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Mon, 18 Jun 2012 17:11:53 +0000 Subject: [PATCH 062/347] Changed naming of "option" to "mode". No longer using defvert_verify_index() but defvert_find_index(). Changing function created error wehn not found. Must be adressed. --- source/blender/editors/object/object_vgroup.c | 125 +++++++++++------- 1 file changed, 74 insertions(+), 51 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index f56f9f657bc..188e1c2efca 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -377,31 +377,31 @@ int ED_vgroup_copy_array(Object *ob, Object *ob_from) /***********************Start transfer weight*********************************/ -typedef enum VertexGroupOption { +typedef enum VertexGroupMode { REPLACE_ACTIVE_VERTEX_GROUP = 1, REPLACE_ALL_VERTEX_GROUPS = 2 -} VertexGroupOption; +} VertexGroupMode; -typedef enum MethodOption { +typedef enum MethodMode { BY_INDEX = 1, BY_NEAREST_VERTEX = 2, BY_NEAREST_FACE = 3, BY_NEAREST_VERTEX_IN_FACE = 4 -} MethodOption; +} MethodMode; -typedef enum ReplaceOption { +typedef enum ReplaceMode { REPLACE_ALL_WEIGHTS = 1, REPLACE_EMPTY_WEIGHTS = 2, REPLACE_SELECTED_WEIGHTS = 3 -} ReplaceOption; +} ReplaceMode; -static EnumPropertyItem vertex_group_option_item[] = { +static EnumPropertyItem vertex_group_mode_item[] = { {REPLACE_ACTIVE_VERTEX_GROUP, "REPLACE_ACTIVE_VERTEX_GROUP", 1, "Active", "Transfer active vertex group from selected to active mesh."}, {REPLACE_ALL_VERTEX_GROUPS, "REPLACE_ALL_VERTEX_GROUPS", 1, "All", "Transfer all vertex groups from selected to active mesh."}, {0, NULL, 0, NULL, NULL} }; -static EnumPropertyItem method_option_item[] = { +static EnumPropertyItem method_mode_item[] = { {BY_INDEX, "BY_INDEX", 1, "Vertex index", "Copy for identical meshes."}, {BY_NEAREST_VERTEX, "BY_NEAREST_VERTEX", 1, "Nearest vertex", "Copy weight from closest vertex."}, {BY_NEAREST_FACE, "BY_NEAREST_FACE", 1, "Nearest face", "Barycentric interpolation from nearest face."}, @@ -409,7 +409,7 @@ static EnumPropertyItem method_option_item[] = { {0, NULL, 0, NULL, NULL} }; -static EnumPropertyItem replace_option_item[] = { +static EnumPropertyItem replace_mode_item[] = { {REPLACE_ALL_WEIGHTS, "REPLACE_ALL_WEIGHTS", 1, "All", "Overwrites all weights."}, {REPLACE_EMPTY_WEIGHTS, "REPLACE_EMPTY_WEIGHTS", 1, "Empty", "Adds weights to vertices with no weight."}, {REPLACE_SELECTED_WEIGHTS, "REPLACE_SELECTED_WEIGHTS", 1, "Selected", "Replace selected weights."}, @@ -417,9 +417,9 @@ static EnumPropertyItem replace_option_item[] = { }; /*copy weight*/ -void vgroup_transfer_weight(MVert *mv_dst, float *weight_dst, float weight_src, ReplaceOption replace_option) +void vgroup_transfer_weight(MVert *mv_dst, float *weight_dst, float weight_src, ReplaceMode replace_mode) { - switch (replace_option) { + switch (replace_mode) { case REPLACE_ALL_WEIGHTS: *weight_dst = weight_src; @@ -435,7 +435,8 @@ void vgroup_transfer_weight(MVert *mv_dst, float *weight_dst, float weight_src, } } -int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_src, Scene *scene, MethodOption method_option, ReplaceOption replace_option) +int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_src, Scene *scene, + MethodMode method_mode, ReplaceMode replace_mode) { bDeformGroup *dg_dst; Mesh *me_dst, *me_src; @@ -450,7 +451,7 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s float weight, tmp_weight[4], tmp_co[3], normal[3], tmp_mat[4][4], dist_v1, dist_v2, dist_v3, dist_v4; /* create new and overwrite vertex group on destination without data */ - if (!defgroup_find_name(ob_dst, dg_src->name) || replace_option == REPLACE_ALL_WEIGHTS) { + if (!defgroup_find_name(ob_dst, dg_src->name) || replace_mode == REPLACE_ALL_WEIGHTS) { ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_src->name)); ED_vgroup_add_name(ob_dst, dg_src->name); } @@ -464,7 +465,10 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s me_src = ob_src->data; /* sanity check */ - if (!me_src->dvert) return 0; + if (!me_src->dvert) { + /*todo fix!*/ + return 0; + } /* create data in memory when nothing there */ if (!me_dst->dvert) ED_vgroup_data_create(ob_dst->data); @@ -485,7 +489,7 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s invert_m4_m4(ob_src->imat, ob_src->obmat); mult_m4_m4m4(tmp_mat, ob_src->imat, ob_dst->obmat); - switch (method_option) { + switch (method_mode) { case BY_INDEX: /* check if indices are matching, delete and return if not */ @@ -496,6 +500,7 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s if (dv_array_src) MEM_freeN(dv_array_src); if (dv_array_dst) MEM_freeN(dv_array_dst); dmesh_src->release(dmesh_src); + /*todo: fix*/ return 0; } @@ -503,9 +508,9 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s for(i = 0, dv_src = dv_array_src, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++, dv_src++, mv_src++) { /* copy weight */ - dw_src = defvert_verify_index(*dv_src, index_src); - dw_dst = defvert_verify_index(*dv_dst, index_dst); - vgroup_transfer_weight(mv_dst, &dw_dst->weight, dw_src->weight, replace_option); + dw_src = defvert_find_index(*dv_src, index_src); + dw_dst = defvert_find_index(*dv_dst, index_dst); + vgroup_transfer_weight(mv_dst, &dw_dst->weight, dw_src->weight, replace_mode); } break; @@ -526,12 +531,18 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s /* node tree accelerated search for closest vetex */ BLI_bvhtree_find_nearest(tree_mesh_vertices_src.tree, tmp_co, - &nearest, tree_mesh_vertices_src.nearest_callback, &tree_mesh_vertices_src); + &nearest, tree_mesh_vertices_src.nearest_callback, &tree_mesh_vertices_src); /* copy weight */ - dw_src = defvert_verify_index(dv_array_src[nearest.index], index_src); - dw_dst = defvert_verify_index(*dv_dst, index_dst); - vgroup_transfer_weight(mv_dst, &dw_dst->weight, dw_src->weight, replace_option); + /* + ideasman42 2012/06/17 21:32:15 + this is very bad - this function will add a vertex weight if not found, thereby modifying the source which should never happen. +use defvert_find_index() instead. You will need to do something sane when the vgroup is not found - +it should not add any vgroups or act as if all vgroups are 0 weight. + */ + dw_src = defvert_find_index(dv_array_src[nearest.index], index_src); + dw_dst = defvert_find_index(*dv_dst, index_dst); + vgroup_transfer_weight(mv_dst, &dw_dst->weight, dw_src->weight, replace_mode); } /* free memory */ @@ -559,33 +570,45 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s /* node tree accelerated search for closest face */ BLI_bvhtree_find_nearest(tree_mesh_faces_src.tree, tmp_co, - &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src); + &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src); index_nearest = nearest.index; /* project onto face */ - normal_tri_v3(normal, mv_src[mface_src[nearest.index].v1].co, - mv_src[mface_src[index_nearest].v2].co, - mv_src[mface_src[index_nearest].v3].co); + normal_tri_v3(normal, + mv_src[mface_src[nearest.index].v1].co, + mv_src[mface_src[index_nearest].v2].co, + mv_src[mface_src[index_nearest].v3].co); project_v3_plane(tmp_co, normal, mv_src[mface_src[index_nearest].v1].co); /* interpolate weights */ - interp_weights_face_v3(tmp_weight, mv_src[mface_src[index_nearest].v1].co, - mv_src[mface_src[index_nearest].v2].co, - mv_src[mface_src[index_nearest].v3].co, - mv_src[mface_src[index_nearest].v4].co, tmp_co); + if (mface_src[index_nearest].v4) { + interp_weights_face_v3(tmp_weight, + mv_src[mface_src[index_nearest].v1].co, + mv_src[mface_src[index_nearest].v2].co, + mv_src[mface_src[index_nearest].v3].co, + mv_src[mface_src[index_nearest].v4].co, tmp_co); + } + else { + interp_weights_face_v3(tmp_weight, + mv_src[mface_src[index_nearest].v1].co, + mv_src[mface_src[index_nearest].v2].co, + mv_src[mface_src[index_nearest].v3].co, NULL, tmp_co); + } /* get weights */ - weight = tmp_weight[0] * defvert_verify_index(dv_array_src[mface_src[index_nearest].v1], index_src)->weight; - weight += tmp_weight[1] * defvert_verify_index(dv_array_src[mface_src[index_nearest].v2], index_src)->weight; - weight += tmp_weight[2] * defvert_verify_index(dv_array_src[mface_src[index_nearest].v3], index_src)->weight; + /* ideasman42 2012/06/17 21:32:15*/ + /* you can loop over 3-4 items here, ratrher then inline all 4 calls. paint_vertex.c has examples of this. */ + weight = tmp_weight[0] * defvert_find_index(dv_array_src[mface_src[index_nearest].v1], index_src)->weight; + weight += tmp_weight[1] * defvert_find_index(dv_array_src[mface_src[index_nearest].v2], index_src)->weight; + weight += tmp_weight[2] * defvert_find_index(dv_array_src[mface_src[index_nearest].v3], index_src)->weight; if (mface_src[index_nearest].v4 || mface_src[index_nearest].v4 == 0) { - weight += tmp_weight[3] * defvert_verify_index(dv_array_src[mface_src[index_nearest].v4], index_src)->weight; + weight += tmp_weight[3] * defvert_find_index(dv_array_src[mface_src[index_nearest].v4], index_src)->weight; } /* copy weight */ - dw_dst = defvert_verify_index(*dv_dst, index_dst); - vgroup_transfer_weight(mv_dst, &dw_dst->weight, weight, replace_option); + dw_dst = defvert_find_index(*dv_dst, index_dst); + vgroup_transfer_weight(mv_dst, &dw_dst->weight, weight, replace_mode); } /* free memory */ @@ -613,7 +636,7 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s /* node tree accelerated search for closest face */ BLI_bvhtree_find_nearest(tree_mesh_faces_src.tree, tmp_co, - &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src); + &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src); index_nearest = nearest.index; /* get distances */ @@ -633,9 +656,9 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s } /* copy weight */ - dw_src = defvert_verify_index(dv_array_src[index_nearest_vertex], index_src); - dw_dst = defvert_verify_index(*dv_dst, index_dst); - vgroup_transfer_weight(mv_dst, &dw_dst->weight, dw_src->weight, replace_option); + dw_src = defvert_find_index(dv_array_src[index_nearest_vertex], index_src); + dw_dst = defvert_find_index(*dv_dst, index_dst); + vgroup_transfer_weight(mv_dst, &dw_dst->weight, dw_src->weight, replace_mode); } /* free memory */ @@ -3001,7 +3024,7 @@ static int vertex_group_copy_to_selected_exec(bContext *C, wmOperator *op) int change = 0; int fail = 0; - CTX_DATA_BEGIN(C, Object *, ob, selected_editable_objects) + CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) { if (obact != ob) { if (ED_vgroup_copy_array(ob, obact)) change++; @@ -3040,24 +3063,24 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) Object *ob_act = CTX_data_active_object(C); bDeformGroup *dg_src; - VertexGroupOption vertex_group_option = RNA_enum_get(op->ptr, "vertex_group_option"); - MethodOption method_option = RNA_enum_get(op->ptr, "method_option"); - ReplaceOption replace_option = RNA_enum_get(op->ptr, "replace_option"); + VertexGroupMode vertex_group_mode = RNA_enum_get(op->ptr, "vertex_group_mode"); + MethodMode method_mode = RNA_enum_get(op->ptr, "method_mode"); + ReplaceMode replace_mode = RNA_enum_get(op->ptr, "replace_mode"); /* Macro to loop through selected objects and perform operation depending on function, option and method */ - CTX_DATA_BEGIN(C, Object *, ob_slc, selected_editable_objects) + CTX_DATA_BEGIN (C, Object *, ob_slc, selected_editable_objects) { if (ob_act != ob_slc && ob_slc->defbase.first) { - switch (vertex_group_option) { + switch (vertex_group_mode) { case REPLACE_ACTIVE_VERTEX_GROUP: - ED_vgroup_transfer_weight(ob_act, ob_slc, BLI_findlink(&ob_slc->defbase, ob_slc->actdef - 1), scene, method_option, replace_option); + ED_vgroup_transfer_weight(ob_act, ob_slc, BLI_findlink(&ob_slc->defbase, ob_slc->actdef - 1), scene, method_mode, replace_mode); break; case REPLACE_ALL_VERTEX_GROUPS: for (dg_src = ob_slc->defbase.first; dg_src; dg_src = dg_src->next) { - ED_vgroup_transfer_weight(ob_act, ob_slc, dg_src, scene, method_option, replace_option); + ED_vgroup_transfer_weight(ob_act, ob_slc, dg_src, scene, method_mode, replace_mode); } break; } @@ -3090,9 +3113,9 @@ void OBJECT_OT_vertex_group_transfer_weight(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ - ot->prop = RNA_def_enum(ot->srna, "vertex_group_option", vertex_group_option_item, 1, "Group", ""); - ot->prop = RNA_def_enum(ot->srna, "method_option", method_option_item, 3, "Method", ""); - ot->prop = RNA_def_enum(ot->srna, "replace_option", replace_option_item, 1, "Replace", ""); + ot->prop = RNA_def_enum(ot->srna, "vertex_group_mode", vertex_group_mode_item, 1, "Group", ""); + ot->prop = RNA_def_enum(ot->srna, "method_mode", method_mode_item, 3, "Method", ""); + ot->prop = RNA_def_enum(ot->srna, "replace_mode", replace_mode_item, 1, "Replace", ""); } static EnumPropertyItem vgroup_items[] = { From 3253716183383781904684629b1edc1f6d2cf4ea Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Mon, 18 Jun 2012 19:32:45 +0000 Subject: [PATCH 063/347] Bugfix: no longer crashes when MDefomWeight is not fond on source. --- source/blender/editors/object/object_vgroup.c | 30 ++++++++++--------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 188e1c2efca..47c0b26218c 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -509,8 +509,10 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s /* copy weight */ dw_src = defvert_find_index(*dv_src, index_src); - dw_dst = defvert_find_index(*dv_dst, index_dst); - vgroup_transfer_weight(mv_dst, &dw_dst->weight, dw_src->weight, replace_mode); + if(dw_src && dw_src->weight) { + dw_dst = defvert_verify_index(*dv_dst, index_dst); + vgroup_transfer_weight(mv_dst, &dw_dst->weight, dw_src->weight, replace_mode); + } } break; @@ -534,15 +536,11 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s &nearest, tree_mesh_vertices_src.nearest_callback, &tree_mesh_vertices_src); /* copy weight */ - /* - ideasman42 2012/06/17 21:32:15 - this is very bad - this function will add a vertex weight if not found, thereby modifying the source which should never happen. -use defvert_find_index() instead. You will need to do something sane when the vgroup is not found - -it should not add any vgroups or act as if all vgroups are 0 weight. - */ dw_src = defvert_find_index(dv_array_src[nearest.index], index_src); - dw_dst = defvert_find_index(*dv_dst, index_dst); - vgroup_transfer_weight(mv_dst, &dw_dst->weight, dw_src->weight, replace_mode); + if(dw_src && dw_src->weight) { + dw_dst = defvert_verify_index(*dv_dst, index_dst); + vgroup_transfer_weight(mv_dst, &dw_dst->weight, dw_src->weight, replace_mode); + } } /* free memory */ @@ -607,8 +605,10 @@ it should not add any vgroups or act as if all vgroups are 0 weight. } /* copy weight */ - dw_dst = defvert_find_index(*dv_dst, index_dst); - vgroup_transfer_weight(mv_dst, &dw_dst->weight, weight, replace_mode); + if(weight > 0) { + dw_dst = defvert_verify_index(*dv_dst, index_dst); + vgroup_transfer_weight(mv_dst, &dw_dst->weight, weight, replace_mode); + } } /* free memory */ @@ -657,8 +657,10 @@ it should not add any vgroups or act as if all vgroups are 0 weight. /* copy weight */ dw_src = defvert_find_index(dv_array_src[index_nearest_vertex], index_src); - dw_dst = defvert_find_index(*dv_dst, index_dst); - vgroup_transfer_weight(mv_dst, &dw_dst->weight, dw_src->weight, replace_mode); + if(dw_src && dw_src->weight) { + dw_dst = defvert_verify_index(*dv_dst, index_dst); + vgroup_transfer_weight(mv_dst, &dw_dst->weight, dw_src->weight, replace_mode); + } } /* free memory */ From 56ebb0b4a825af75ea6db03f1dc55c8933b0cc50 Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Mon, 18 Jun 2012 19:59:15 +0000 Subject: [PATCH 064/347] style cleanup fixed indents (I belive!?!) --- source/blender/editors/object/object_vgroup.c | 54 +++++++++---------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 47c0b26218c..a9ff41b8046 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -396,24 +396,24 @@ typedef enum ReplaceMode { } ReplaceMode; static EnumPropertyItem vertex_group_mode_item[] = { - {REPLACE_ACTIVE_VERTEX_GROUP, "REPLACE_ACTIVE_VERTEX_GROUP", 1, "Active", "Transfer active vertex group from selected to active mesh."}, - {REPLACE_ALL_VERTEX_GROUPS, "REPLACE_ALL_VERTEX_GROUPS", 1, "All", "Transfer all vertex groups from selected to active mesh."}, - {0, NULL, 0, NULL, NULL} + {REPLACE_ACTIVE_VERTEX_GROUP, "REPLACE_ACTIVE_VERTEX_GROUP", 1, "Active", "Transfer active vertex group from selected to active mesh."}, + {REPLACE_ALL_VERTEX_GROUPS, "REPLACE_ALL_VERTEX_GROUPS", 1, "All", "Transfer all vertex groups from selected to active mesh."}, + {0, NULL, 0, NULL, NULL} }; static EnumPropertyItem method_mode_item[] = { - {BY_INDEX, "BY_INDEX", 1, "Vertex index", "Copy for identical meshes."}, - {BY_NEAREST_VERTEX, "BY_NEAREST_VERTEX", 1, "Nearest vertex", "Copy weight from closest vertex."}, - {BY_NEAREST_FACE, "BY_NEAREST_FACE", 1, "Nearest face", "Barycentric interpolation from nearest face."}, - {BY_NEAREST_VERTEX_IN_FACE, "BY_NEAREST_VERTEX_IN_FACE", 1, "Nearest vertex in face", "Copy weight from closest vertex in nearest face."}, - {0, NULL, 0, NULL, NULL} + {BY_INDEX, "BY_INDEX", 1, "Vertex index", "Copy for identical meshes."}, + {BY_NEAREST_VERTEX, "BY_NEAREST_VERTEX", 1, "Nearest vertex", "Copy weight from closest vertex."}, + {BY_NEAREST_FACE, "BY_NEAREST_FACE", 1, "Nearest face", "Barycentric interpolation from nearest face."}, + {BY_NEAREST_VERTEX_IN_FACE, "BY_NEAREST_VERTEX_IN_FACE", 1, "Nearest vertex in face", "Copy weight from closest vertex in nearest face."}, + {0, NULL, 0, NULL, NULL} }; static EnumPropertyItem replace_mode_item[] = { - {REPLACE_ALL_WEIGHTS, "REPLACE_ALL_WEIGHTS", 1, "All", "Overwrites all weights."}, - {REPLACE_EMPTY_WEIGHTS, "REPLACE_EMPTY_WEIGHTS", 1, "Empty", "Adds weights to vertices with no weight."}, - {REPLACE_SELECTED_WEIGHTS, "REPLACE_SELECTED_WEIGHTS", 1, "Selected", "Replace selected weights."}, - {0, NULL, 0, NULL, NULL} + {REPLACE_ALL_WEIGHTS, "REPLACE_ALL_WEIGHTS", 1, "All", "Overwrites all weights."}, + {REPLACE_EMPTY_WEIGHTS, "REPLACE_EMPTY_WEIGHTS", 1, "Empty", "Adds weights to vertices with no weight."}, + {REPLACE_SELECTED_WEIGHTS, "REPLACE_SELECTED_WEIGHTS", 1, "Selected", "Replace selected weights."}, + {0, NULL, 0, NULL, NULL} }; /*copy weight*/ @@ -436,7 +436,7 @@ void vgroup_transfer_weight(MVert *mv_dst, float *weight_dst, float weight_src, } int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_src, Scene *scene, - MethodMode method_mode, ReplaceMode replace_mode) + MethodMode method_mode, ReplaceMode replace_mode) { bDeformGroup *dg_dst; Mesh *me_dst, *me_src; @@ -533,7 +533,7 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s /* node tree accelerated search for closest vetex */ BLI_bvhtree_find_nearest(tree_mesh_vertices_src.tree, tmp_co, - &nearest, tree_mesh_vertices_src.nearest_callback, &tree_mesh_vertices_src); + &nearest, tree_mesh_vertices_src.nearest_callback, &tree_mesh_vertices_src); /* copy weight */ dw_src = defvert_find_index(dv_array_src[nearest.index], index_src); @@ -568,30 +568,30 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s /* node tree accelerated search for closest face */ BLI_bvhtree_find_nearest(tree_mesh_faces_src.tree, tmp_co, - &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src); + &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src); index_nearest = nearest.index; /* project onto face */ normal_tri_v3(normal, - mv_src[mface_src[nearest.index].v1].co, - mv_src[mface_src[index_nearest].v2].co, - mv_src[mface_src[index_nearest].v3].co); + mv_src[mface_src[nearest.index].v1].co, + mv_src[mface_src[index_nearest].v2].co, + mv_src[mface_src[index_nearest].v3].co); project_v3_plane(tmp_co, normal, mv_src[mface_src[index_nearest].v1].co); /* interpolate weights */ if (mface_src[index_nearest].v4) { interp_weights_face_v3(tmp_weight, - mv_src[mface_src[index_nearest].v1].co, - mv_src[mface_src[index_nearest].v2].co, - mv_src[mface_src[index_nearest].v3].co, - mv_src[mface_src[index_nearest].v4].co, tmp_co); + mv_src[mface_src[index_nearest].v1].co, + mv_src[mface_src[index_nearest].v2].co, + mv_src[mface_src[index_nearest].v3].co, + mv_src[mface_src[index_nearest].v4].co, tmp_co); } else { interp_weights_face_v3(tmp_weight, - mv_src[mface_src[index_nearest].v1].co, - mv_src[mface_src[index_nearest].v2].co, - mv_src[mface_src[index_nearest].v3].co, NULL, tmp_co); + mv_src[mface_src[index_nearest].v1].co, + mv_src[mface_src[index_nearest].v2].co, + mv_src[mface_src[index_nearest].v3].co, NULL, tmp_co); } /* get weights */ @@ -605,7 +605,7 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s } /* copy weight */ - if(weight > 0) { + if(weight > 0) {/*todo: handle NULL source properly*/ dw_dst = defvert_verify_index(*dv_dst, index_dst); vgroup_transfer_weight(mv_dst, &dw_dst->weight, weight, replace_mode); } @@ -636,7 +636,7 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s /* node tree accelerated search for closest face */ BLI_bvhtree_find_nearest(tree_mesh_faces_src.tree, tmp_co, - &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src); + &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src); index_nearest = nearest.index; /* get distances */ From fcb650a1545e7ad4ece61c69b83259349cde8231 Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Tue, 19 Jun 2012 00:35:39 +0000 Subject: [PATCH 065/347] Fixed loop instead of one liners for interpolate over face method mode. --- source/blender/editors/object/object_vgroup.c | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index a9ff41b8046..6f126ce3a91 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -447,7 +447,7 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s MFace *mface_src; BVHTreeNearest nearest; MDeformWeight *dw_dst, *dw_src; - int dv_tot_src, dv_tot_dst, i, index_dst, index_src, index_nearest, index_nearest_vertex; + int dv_tot_src, dv_tot_dst, i, j, v, index_dst, index_src, index_nearest, index_nearest_vertex; float weight, tmp_weight[4], tmp_co[3], normal[3], tmp_mat[4][4], dist_v1, dist_v2, dist_v3, dist_v4; /* create new and overwrite vertex group on destination without data */ @@ -579,7 +579,7 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s project_v3_plane(tmp_co, normal, mv_src[mface_src[index_nearest].v1].co); - /* interpolate weights */ + /* interpolate weights over face*/ if (mface_src[index_nearest].v4) { interp_weights_face_v3(tmp_weight, mv_src[mface_src[index_nearest].v1].co, @@ -594,18 +594,16 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s mv_src[mface_src[index_nearest].v3].co, NULL, tmp_co); } - /* get weights */ - /* ideasman42 2012/06/17 21:32:15*/ - /* you can loop over 3-4 items here, ratrher then inline all 4 calls. paint_vertex.c has examples of this. */ - weight = tmp_weight[0] * defvert_find_index(dv_array_src[mface_src[index_nearest].v1], index_src)->weight; - weight += tmp_weight[1] * defvert_find_index(dv_array_src[mface_src[index_nearest].v2], index_src)->weight; - weight += tmp_weight[2] * defvert_find_index(dv_array_src[mface_src[index_nearest].v3], index_src)->weight; - if (mface_src[index_nearest].v4 || mface_src[index_nearest].v4 == 0) { - weight += tmp_weight[3] * defvert_find_index(dv_array_src[mface_src[index_nearest].v4], index_src)->weight; + /* get weights from face*/ + weight = 0; + if (mface_src[index_nearest].v4 || mface_src[index_nearest].v4 == 0) v = 4; + else v = 3; + for (j = 0; j < v; j++) { + weight += tmp_weight[j] * defvert_find_index(dv_array_src[(&mface_src[index_nearest].v1)[j]], index_src)->weight; } /* copy weight */ - if(weight > 0) {/*todo: handle NULL source properly*/ + if(weight > 0) { dw_dst = defvert_verify_index(*dv_dst, index_dst); vgroup_transfer_weight(mv_dst, &dw_dst->weight, weight, replace_mode); } From 32992cabe795638ba4d5c44ab51637d6dc5b743c Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Tue, 19 Jun 2012 01:19:44 +0000 Subject: [PATCH 066/347] Bugfix to if statement always reporting true --- source/blender/editors/object/object_vgroup.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 6f126ce3a91..ca6dfe08c4d 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -466,7 +466,7 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s /* sanity check */ if (!me_src->dvert) { - /*todo fix!*/ + /*todo fix!***********************************************************************************************/ return 0; } @@ -500,7 +500,7 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s if (dv_array_src) MEM_freeN(dv_array_src); if (dv_array_dst) MEM_freeN(dv_array_dst); dmesh_src->release(dmesh_src); - /*todo: fix*/ + /*todo: fix********************************************************************************************/ return 0; } @@ -580,7 +580,7 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s project_v3_plane(tmp_co, normal, mv_src[mface_src[index_nearest].v1].co); /* interpolate weights over face*/ - if (mface_src[index_nearest].v4) { + if (&mface_src[index_nearest].v4 != NULL) { interp_weights_face_v3(tmp_weight, mv_src[mface_src[index_nearest].v1].co, mv_src[mface_src[index_nearest].v2].co, @@ -596,7 +596,7 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s /* get weights from face*/ weight = 0; - if (mface_src[index_nearest].v4 || mface_src[index_nearest].v4 == 0) v = 4; + if (&mface_src[index_nearest].v4 != NULL) v = 4; else v = 3; for (j = 0; j < v; j++) { weight += tmp_weight[j] * defvert_find_index(dv_array_src[(&mface_src[index_nearest].v1)[j]], index_src)->weight; @@ -646,7 +646,7 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s if (dist_v1 < dist_v2 && dist_v1 < dist_v3) index_nearest_vertex = mface_src[index_nearest].v1; else if (dist_v2 < dist_v3) index_nearest_vertex = mface_src[index_nearest].v2; else index_nearest_vertex = mface_src[index_nearest].v3; - if (mface_src[index_nearest].v4 || mface_src[index_nearest].v4 == 0) { + if (&mface_src[index_nearest].v4 != NULL) { dist_v4 = len_squared_v3v3(tmp_co, mv_src[mface_src[index_nearest].v4].co); if (dist_v4 < dist_v1 && dist_v4 < dist_v2 && dist_v4 < dist_v3) { index_nearest_vertex = mface_src[index_nearest].v4; From 07aaf356f7c24f1ac2bcd2d01583de2df06894a6 Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Tue, 19 Jun 2012 02:23:31 +0000 Subject: [PATCH 067/347] Error reporting added. Note that when changing to optional methods that fails, it fails silently still. Might have to adress this. --- source/blender/editors/object/object_vgroup.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index ca6dfe08c4d..87d735da1e9 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -436,7 +436,7 @@ void vgroup_transfer_weight(MVert *mv_dst, float *weight_dst, float weight_src, } int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_src, Scene *scene, - MethodMode method_mode, ReplaceMode replace_mode) + MethodMode method_mode, ReplaceMode replace_mode, wmOperator *op) { bDeformGroup *dg_dst; Mesh *me_dst, *me_src; @@ -466,7 +466,7 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s /* sanity check */ if (!me_src->dvert) { - /*todo fix!***********************************************************************************************/ + BKE_reportf(op->reports, RPT_ERROR, "Transfer failed. Source mesh does not have vertices"); return 0; } @@ -500,7 +500,7 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s if (dv_array_src) MEM_freeN(dv_array_src); if (dv_array_dst) MEM_freeN(dv_array_dst); dmesh_src->release(dmesh_src); - /*todo: fix********************************************************************************************/ + BKE_reportf(op->reports, RPT_ERROR, "Transfer failed. Indices are not matching"); return 0; } @@ -3062,6 +3062,7 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) Scene *scene = CTX_data_scene(C); Object *ob_act = CTX_data_active_object(C); bDeformGroup *dg_src; + int fail = 0; VertexGroupMode vertex_group_mode = RNA_enum_get(op->ptr, "vertex_group_mode"); MethodMode method_mode = RNA_enum_get(op->ptr, "method_mode"); @@ -3075,12 +3076,14 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) switch (vertex_group_mode) { case REPLACE_ACTIVE_VERTEX_GROUP: - ED_vgroup_transfer_weight(ob_act, ob_slc, BLI_findlink(&ob_slc->defbase, ob_slc->actdef - 1), scene, method_mode, replace_mode); + if (!ED_vgroup_transfer_weight( + ob_act, ob_slc, BLI_findlink(&ob_slc->defbase, ob_slc->actdef - 1), scene, method_mode, replace_mode, op)) fail++; break; case REPLACE_ALL_VERTEX_GROUPS: for (dg_src = ob_slc->defbase.first; dg_src; dg_src = dg_src->next) { - ED_vgroup_transfer_weight(ob_act, ob_slc, dg_src, scene, method_mode, replace_mode); + if (!ED_vgroup_transfer_weight( + ob_act, ob_slc, dg_src, scene, method_mode, replace_mode, op)) fail++; } break; } @@ -3094,6 +3097,7 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) CTX_DATA_END; + if (fail != 0) return OPERATOR_CANCELLED; return OPERATOR_FINISHED; } From 873b26702937ec27d31de0efcec00e4997e81bf0 Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Tue, 19 Jun 2012 09:52:16 +0000 Subject: [PATCH 068/347] cleanup for bwetter naming --- source/blender/editors/object/object_vgroup.c | 45 ++++++++++++++----- 1 file changed, 35 insertions(+), 10 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 87d735da1e9..700534ba897 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -382,12 +382,12 @@ typedef enum VertexGroupMode { REPLACE_ALL_VERTEX_GROUPS = 2 } VertexGroupMode; -typedef enum MethodMode { +typedef enum Method { BY_INDEX = 1, BY_NEAREST_VERTEX = 2, BY_NEAREST_FACE = 3, BY_NEAREST_VERTEX_IN_FACE = 4 -} MethodMode; +} Method; typedef enum ReplaceMode { REPLACE_ALL_WEIGHTS = 1, @@ -401,7 +401,7 @@ static EnumPropertyItem vertex_group_mode_item[] = { {0, NULL, 0, NULL, NULL} }; -static EnumPropertyItem method_mode_item[] = { +static EnumPropertyItem method_item[] = { {BY_INDEX, "BY_INDEX", 1, "Vertex index", "Copy for identical meshes."}, {BY_NEAREST_VERTEX, "BY_NEAREST_VERTEX", 1, "Nearest vertex", "Copy weight from closest vertex."}, {BY_NEAREST_FACE, "BY_NEAREST_FACE", 1, "Nearest face", "Barycentric interpolation from nearest face."}, @@ -436,7 +436,7 @@ void vgroup_transfer_weight(MVert *mv_dst, float *weight_dst, float weight_src, } int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_src, Scene *scene, - MethodMode method_mode, ReplaceMode replace_mode, wmOperator *op) + Method method, ReplaceMode replace_mode, wmOperator *op) { bDeformGroup *dg_dst; Mesh *me_dst, *me_src; @@ -466,7 +466,7 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s /* sanity check */ if (!me_src->dvert) { - BKE_reportf(op->reports, RPT_ERROR, "Transfer failed. Source mesh does not have vertices"); + BKE_reportf(op->reports, RPT_ERROR, "Transfer failed. Source mesh does not have any vertex groups"); return 0; } @@ -489,7 +489,7 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s invert_m4_m4(ob_src->imat, ob_src->obmat); mult_m4_m4m4(tmp_mat, ob_src->imat, ob_dst->obmat); - switch (method_mode) { + switch (method) { case BY_INDEX: /* check if indices are matching, delete and return if not */ @@ -513,6 +513,10 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s dw_dst = defvert_verify_index(*dv_dst, index_dst); vgroup_transfer_weight(mv_dst, &dw_dst->weight, dw_src->weight, replace_mode); } + /* why? + ideasman42 2012/06/19 07:27:34 + there should be an 'else {' ... here, which checks if 'dv_dst' has any weights and clears them (at least when overwrite is enabled). This will depend on the options selected, but you see the issue I hope. + */ } break; @@ -540,6 +544,10 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s if(dw_src && dw_src->weight) { dw_dst = defvert_verify_index(*dv_dst, index_dst); vgroup_transfer_weight(mv_dst, &dw_dst->weight, dw_src->weight, replace_mode); + /* why? + ideasman42 2012/06/19 07:27:34 + there should be an 'else {' ... here, which checks if 'dv_dst' has any weights and clears them (at least when overwrite is enabled). This will depend on the options selected, but you see the issue I hope. + */ } } @@ -597,9 +605,18 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s /* get weights from face*/ weight = 0; if (&mface_src[index_nearest].v4 != NULL) v = 4; + /* + ideasman42 2012/06/19 07:27:34 + comparing v4 with NULL is misleading, since its not a pointer. suggest to use this: +mf = &mface_src[index_nearest]; fidx = mf->v4 ? 3 : 2; do { unsigned int vidx = (&mf->v1)[fidx]; ... operate on vidx ... } while (fidx--); + */ else v = 3; for (j = 0; j < v; j++) { weight += tmp_weight[j] * defvert_find_index(dv_array_src[(&mface_src[index_nearest].v1)[j]], index_src)->weight; + /* +ideasman42 2012/06/19 07:27:34 +defvert_find_index may be a NULL pointer, so getting ->weight from it may crash. better use defvert_find_weight() here which falls back to 0.0 when not found. + */ } /* copy weight */ @@ -647,6 +664,10 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s else if (dist_v2 < dist_v3) index_nearest_vertex = mface_src[index_nearest].v2; else index_nearest_vertex = mface_src[index_nearest].v3; if (&mface_src[index_nearest].v4 != NULL) { + /* +ideasman42 2012/06/19 07:27:34 +comparing v4 with NULL is misleading... see above. + */ dist_v4 = len_squared_v3v3(tmp_co, mv_src[mface_src[index_nearest].v4].co); if (dist_v4 < dist_v1 && dist_v4 < dist_v2 && dist_v4 < dist_v3) { index_nearest_vertex = mface_src[index_nearest].v4; @@ -659,6 +680,10 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s dw_dst = defvert_verify_index(*dv_dst, index_dst); vgroup_transfer_weight(mv_dst, &dw_dst->weight, dw_src->weight, replace_mode); } + /* +ideasman42 2012/06/19 07:27:34 why? +there should be an 'else {' ... here, which checks if 'dv_dst' has any weights and clears them (at least when overwrite is enabled). This will depend on the options selected, but you see the issue I hope. + */ } /* free memory */ @@ -3065,7 +3090,7 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) int fail = 0; VertexGroupMode vertex_group_mode = RNA_enum_get(op->ptr, "vertex_group_mode"); - MethodMode method_mode = RNA_enum_get(op->ptr, "method_mode"); + Method method = RNA_enum_get(op->ptr, "method"); ReplaceMode replace_mode = RNA_enum_get(op->ptr, "replace_mode"); /* Macro to loop through selected objects and perform operation depending on function, option and method */ @@ -3077,13 +3102,13 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) case REPLACE_ACTIVE_VERTEX_GROUP: if (!ED_vgroup_transfer_weight( - ob_act, ob_slc, BLI_findlink(&ob_slc->defbase, ob_slc->actdef - 1), scene, method_mode, replace_mode, op)) fail++; + ob_act, ob_slc, BLI_findlink(&ob_slc->defbase, ob_slc->actdef - 1), scene, method, replace_mode, op)) fail++; break; case REPLACE_ALL_VERTEX_GROUPS: for (dg_src = ob_slc->defbase.first; dg_src; dg_src = dg_src->next) { if (!ED_vgroup_transfer_weight( - ob_act, ob_slc, dg_src, scene, method_mode, replace_mode, op)) fail++; + ob_act, ob_slc, dg_src, scene, method, replace_mode, op)) fail++; } break; } @@ -3118,7 +3143,7 @@ void OBJECT_OT_vertex_group_transfer_weight(wmOperatorType *ot) /* properties */ ot->prop = RNA_def_enum(ot->srna, "vertex_group_mode", vertex_group_mode_item, 1, "Group", ""); - ot->prop = RNA_def_enum(ot->srna, "method_mode", method_mode_item, 3, "Method", ""); + ot->prop = RNA_def_enum(ot->srna, "method", method_item, 3, "Method", ""); ot->prop = RNA_def_enum(ot->srna, "replace_mode", replace_mode_item, 1, "Replace", ""); } From 51036b31860a8ed4bffac8260aacaa8d972d6bc7 Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Tue, 19 Jun 2012 16:23:52 +0000 Subject: [PATCH 069/347] Fixed better check for Mface.v4 --- source/blender/editors/object/object_vgroup.c | 37 +++++++------------ 1 file changed, 14 insertions(+), 23 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 700534ba897..a90e3182923 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -444,10 +444,11 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s BVHTreeFromMesh tree_mesh_vertices_src, tree_mesh_faces_src = {NULL}; MDeformVert **dv_array_src, **dv_array_dst, **dv_src, **dv_dst; MVert *mv_dst, *mv_src; - MFace *mface_src; + MFace *mface_src, *mf; BVHTreeNearest nearest; MDeformWeight *dw_dst, *dw_src; - int dv_tot_src, dv_tot_dst, i, j, v, index_dst, index_src, index_nearest, index_nearest_vertex; + int dv_tot_src, dv_tot_dst, i, v_index, index_dst, index_src, index_nearest, index_nearest_vertex; + unsigned int f_index; float weight, tmp_weight[4], tmp_co[3], normal[3], tmp_mat[4][4], dist_v1, dist_v2, dist_v3, dist_v4; /* create new and overwrite vertex group on destination without data */ @@ -604,20 +605,12 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s /* get weights from face*/ weight = 0; - if (&mface_src[index_nearest].v4 != NULL) v = 4; - /* - ideasman42 2012/06/19 07:27:34 - comparing v4 with NULL is misleading, since its not a pointer. suggest to use this: -mf = &mface_src[index_nearest]; fidx = mf->v4 ? 3 : 2; do { unsigned int vidx = (&mf->v1)[fidx]; ... operate on vidx ... } while (fidx--); - */ - else v = 3; - for (j = 0; j < v; j++) { - weight += tmp_weight[j] * defvert_find_index(dv_array_src[(&mface_src[index_nearest].v1)[j]], index_src)->weight; - /* -ideasman42 2012/06/19 07:27:34 -defvert_find_index may be a NULL pointer, so getting ->weight from it may crash. better use defvert_find_weight() here which falls back to 0.0 when not found. - */ - } + mf = &mface_src[index_nearest]; + f_index = mf->v4 ? 3 : 2; + do { + v_index = (&mf->v1)[f_index]; + weight += tmp_weight[f_index] * defvert_find_weight(dv_array_src[v_index], index_src); + } while (f_index--); /* copy weight */ if(weight > 0) { @@ -663,14 +656,12 @@ defvert_find_index may be a NULL pointer, so getting ->weight from it may crash. if (dist_v1 < dist_v2 && dist_v1 < dist_v3) index_nearest_vertex = mface_src[index_nearest].v1; else if (dist_v2 < dist_v3) index_nearest_vertex = mface_src[index_nearest].v2; else index_nearest_vertex = mface_src[index_nearest].v3; - if (&mface_src[index_nearest].v4 != NULL) { - /* -ideasman42 2012/06/19 07:27:34 -comparing v4 with NULL is misleading... see above. - */ - dist_v4 = len_squared_v3v3(tmp_co, mv_src[mface_src[index_nearest].v4].co); + mf = &mface_src[index_nearest]; + f_index = mf->v4 ? 3 : 2; + if (f_index == 3) { + dist_v4 = len_squared_v3v3(tmp_co, mv_src[mf->v4].co); if (dist_v4 < dist_v1 && dist_v4 < dist_v2 && dist_v4 < dist_v3) { - index_nearest_vertex = mface_src[index_nearest].v4; + index_nearest_vertex = mf->v4; } } From 622ae0a1ca9ff9dae0670d4bc8fcd134110a8572 Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Tue, 19 Jun 2012 18:26:55 +0000 Subject: [PATCH 070/347] clenaup. --- source/blender/editors/object/object_vgroup.c | 39 +++++++------------ 1 file changed, 14 insertions(+), 25 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index a90e3182923..7ca9e697229 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -581,32 +581,21 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s index_nearest = nearest.index; /* project onto face */ - normal_tri_v3(normal, - mv_src[mface_src[nearest.index].v1].co, - mv_src[mface_src[index_nearest].v2].co, - mv_src[mface_src[index_nearest].v3].co); - - project_v3_plane(tmp_co, normal, mv_src[mface_src[index_nearest].v1].co); + mf = &mface_src[index_nearest]; + normal_tri_v3(normal, mv_src[mf->v1].co, mv_src[mf->v2].co, mv_src[mf->v3].co); + project_v3_plane(tmp_co, normal, mv_src[mf->v1].co); /* interpolate weights over face*/ - if (&mface_src[index_nearest].v4 != NULL) { - interp_weights_face_v3(tmp_weight, - mv_src[mface_src[index_nearest].v1].co, - mv_src[mface_src[index_nearest].v2].co, - mv_src[mface_src[index_nearest].v3].co, - mv_src[mface_src[index_nearest].v4].co, tmp_co); + f_index = mf->v4 ? 3 : 2; + if (f_index == 3) { + interp_weights_face_v3(tmp_weight, mv_src[mf->v1].co, mv_src[mf->v2].co, mv_src[mf->v3].co, mv_src[mf->v4].co, tmp_co); } else { - interp_weights_face_v3(tmp_weight, - mv_src[mface_src[index_nearest].v1].co, - mv_src[mface_src[index_nearest].v2].co, - mv_src[mface_src[index_nearest].v3].co, NULL, tmp_co); + interp_weights_face_v3(tmp_weight, mv_src[mf->v1].co, mv_src[mf->v2].co, mv_src[mf->v3].co, NULL, tmp_co); } /* get weights from face*/ weight = 0; - mf = &mface_src[index_nearest]; - f_index = mf->v4 ? 3 : 2; do { v_index = (&mf->v1)[f_index]; weight += tmp_weight[f_index] * defvert_find_weight(dv_array_src[v_index], index_src); @@ -648,16 +637,16 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s index_nearest = nearest.index; /* get distances */ - dist_v1 = len_squared_v3v3(tmp_co, mv_src[mface_src[index_nearest].v1].co); - dist_v2 = len_squared_v3v3(tmp_co, mv_src[mface_src[index_nearest].v2].co); - dist_v3 = len_squared_v3v3(tmp_co, mv_src[mface_src[index_nearest].v3].co); + mf = &mface_src[index_nearest]; + dist_v1 = len_squared_v3v3(tmp_co, mv_src[mf->v1].co); + dist_v2 = len_squared_v3v3(tmp_co, mv_src[mf->v2].co); + dist_v3 = len_squared_v3v3(tmp_co, mv_src[mf->v3].co); /* get closest vertex */ - if (dist_v1 < dist_v2 && dist_v1 < dist_v3) index_nearest_vertex = mface_src[index_nearest].v1; - else if (dist_v2 < dist_v3) index_nearest_vertex = mface_src[index_nearest].v2; - else index_nearest_vertex = mface_src[index_nearest].v3; - mf = &mface_src[index_nearest]; f_index = mf->v4 ? 3 : 2; + if (dist_v1 < dist_v2 && dist_v1 < dist_v3) index_nearest_vertex = mf->v1; + else if (dist_v2 < dist_v3) index_nearest_vertex = mf->v2; + else index_nearest_vertex = mf->v3; if (f_index == 3) { dist_v4 = len_squared_v3v3(tmp_co, mv_src[mf->v4].co); if (dist_v4 < dist_v1 && dist_v4 < dist_v2 && dist_v4 < dist_v3) { From 370901890ac1177a4619b18613096391914204f8 Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Tue, 19 Jun 2012 19:15:59 +0000 Subject: [PATCH 071/347] Its now overwriting properly by clearing weights when using replace_mode all. Reason for not going for suggested "else" on copy in each case is that it would present a paradox. (it would delete weights that got created in some instances) --- source/blender/editors/object/object_vgroup.c | 20 ++++++++----------- 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 7ca9e697229..5648a06f540 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -490,6 +490,14 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s invert_m4_m4(ob_src->imat, ob_src->obmat); mult_m4_m4m4(tmp_mat, ob_src->imat, ob_dst->obmat); + /* clear weights */ + if (replace_mode == REPLACE_ALL_WEIGHTS) { + for(i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++) { + dw_dst = defvert_verify_index(*dv_dst, index_dst); + if (dw_dst) (*dw_dst).weight = 0; + } + } + switch (method) { case BY_INDEX: @@ -514,10 +522,6 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s dw_dst = defvert_verify_index(*dv_dst, index_dst); vgroup_transfer_weight(mv_dst, &dw_dst->weight, dw_src->weight, replace_mode); } - /* why? - ideasman42 2012/06/19 07:27:34 - there should be an 'else {' ... here, which checks if 'dv_dst' has any weights and clears them (at least when overwrite is enabled). This will depend on the options selected, but you see the issue I hope. - */ } break; @@ -545,10 +549,6 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s if(dw_src && dw_src->weight) { dw_dst = defvert_verify_index(*dv_dst, index_dst); vgroup_transfer_weight(mv_dst, &dw_dst->weight, dw_src->weight, replace_mode); - /* why? - ideasman42 2012/06/19 07:27:34 - there should be an 'else {' ... here, which checks if 'dv_dst' has any weights and clears them (at least when overwrite is enabled). This will depend on the options selected, but you see the issue I hope. - */ } } @@ -660,10 +660,6 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s dw_dst = defvert_verify_index(*dv_dst, index_dst); vgroup_transfer_weight(mv_dst, &dw_dst->weight, dw_src->weight, replace_mode); } - /* -ideasman42 2012/06/19 07:27:34 why? -there should be an 'else {' ... here, which checks if 'dv_dst' has any weights and clears them (at least when overwrite is enabled). This will depend on the options selected, but you see the issue I hope. - */ } /* free memory */ From 30085e5ea96dcec5ef0afd239fbd33760cee83ce Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Wed, 4 Jul 2012 16:30:12 +0000 Subject: [PATCH 072/347] response to code review: http://codereview.appspot.com/6301100/diff/1/source/blender/editors/object/object_vgroup.c --- source/blender/editors/object/object_vgroup.c | 114 ++++++++++-------- 1 file changed, 63 insertions(+), 51 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 5648a06f540..c5296d0f7a7 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -375,68 +375,72 @@ int ED_vgroup_copy_array(Object *ob, Object *ob_from) return 1; } -/***********************Start transfer weight*********************************/ +/***********************Start weight transfer (WT)*********************************/ -typedef enum VertexGroupMode { - REPLACE_ACTIVE_VERTEX_GROUP = 1, - REPLACE_ALL_VERTEX_GROUPS = 2 -} VertexGroupMode; +typedef enum WT_VertexGroupMode { + WT_REPLACE_ACTIVE_VERTEX_GROUP = 1, + WT_REPLACE_ALL_VERTEX_GROUPS = 2 +} WT_VertexGroupMode; -typedef enum Method { - BY_INDEX = 1, - BY_NEAREST_VERTEX = 2, - BY_NEAREST_FACE = 3, - BY_NEAREST_VERTEX_IN_FACE = 4 -} Method; +typedef enum WT_Method { + WT_BY_INDEX = 1, + WT_BY_NEAREST_VERTEX = 2, + WT_BY_NEAREST_FACE = 3, + WT_BY_NEAREST_VERTEX_IN_FACE = 4 +} WT_Method; -typedef enum ReplaceMode { - REPLACE_ALL_WEIGHTS = 1, - REPLACE_EMPTY_WEIGHTS = 2, - REPLACE_SELECTED_WEIGHTS = 3 -} ReplaceMode; +typedef enum WT_ReplaceMode { + WT_REPLACE_ALL_WEIGHTS = 1, + WT_REPLACE_EMPTY_WEIGHTS = 2, + WT_REPLACE_SELECTED_WEIGHTS = 3 +} WT_ReplaceMode; -static EnumPropertyItem vertex_group_mode_item[] = { - {REPLACE_ACTIVE_VERTEX_GROUP, "REPLACE_ACTIVE_VERTEX_GROUP", 1, "Active", "Transfer active vertex group from selected to active mesh."}, - {REPLACE_ALL_VERTEX_GROUPS, "REPLACE_ALL_VERTEX_GROUPS", 1, "All", "Transfer all vertex groups from selected to active mesh."}, +static EnumPropertyItem WT_vertex_group_mode_item[] = { + {WT_REPLACE_ACTIVE_VERTEX_GROUP, "WT_REPLACE_ACTIVE_VERTEX_GROUP", 1, "Active", "Transfer active vertex group from selected to active mesh."}, + {WT_REPLACE_ALL_VERTEX_GROUPS, "WT_REPLACE_ALL_VERTEX_GROUPS", 1, "All", "Transfer all vertex groups from selected to active mesh."}, {0, NULL, 0, NULL, NULL} }; -static EnumPropertyItem method_item[] = { - {BY_INDEX, "BY_INDEX", 1, "Vertex index", "Copy for identical meshes."}, - {BY_NEAREST_VERTEX, "BY_NEAREST_VERTEX", 1, "Nearest vertex", "Copy weight from closest vertex."}, - {BY_NEAREST_FACE, "BY_NEAREST_FACE", 1, "Nearest face", "Barycentric interpolation from nearest face."}, - {BY_NEAREST_VERTEX_IN_FACE, "BY_NEAREST_VERTEX_IN_FACE", 1, "Nearest vertex in face", "Copy weight from closest vertex in nearest face."}, +static EnumPropertyItem WT_method_item[] = { + {WT_BY_INDEX, "WT_BY_INDEX", 1, "Vertex index", "Copy for identical meshes."}, + {WT_BY_NEAREST_VERTEX, "WT_BY_NEAREST_VERTEX", 1, "Nearest vertex", "Copy weight from closest vertex."}, + {WT_BY_NEAREST_FACE, "WT_BY_NEAREST_FACE", 1, "Nearest face", "Barycentric interpolation from nearest face."}, + {WT_BY_NEAREST_VERTEX_IN_FACE, "WT_BY_NEAREST_VERTEX_IN_FACE", 1, "Nearest vertex in face", "Copy weight from closest vertex in nearest face."}, {0, NULL, 0, NULL, NULL} }; -static EnumPropertyItem replace_mode_item[] = { - {REPLACE_ALL_WEIGHTS, "REPLACE_ALL_WEIGHTS", 1, "All", "Overwrites all weights."}, - {REPLACE_EMPTY_WEIGHTS, "REPLACE_EMPTY_WEIGHTS", 1, "Empty", "Adds weights to vertices with no weight."}, - {REPLACE_SELECTED_WEIGHTS, "REPLACE_SELECTED_WEIGHTS", 1, "Selected", "Replace selected weights."}, +static EnumPropertyItem WT_replace_mode_item[] = { + {WT_REPLACE_ALL_WEIGHTS, "WT_REPLACE_ALL_WEIGHTS", 1, "All", "Overwrites all weights."}, + {WT_REPLACE_EMPTY_WEIGHTS, "WT_REPLACE_EMPTY_WEIGHTS", 1, "Empty", "Adds weights to vertices with no weight."}, + {WT_REPLACE_SELECTED_WEIGHTS, "WT_REPLACE_SELECTED_WEIGHTS", 1, "Selected", "Replace selected weights."}, {0, NULL, 0, NULL, NULL} }; /*copy weight*/ -void vgroup_transfer_weight(MVert *mv_dst, float *weight_dst, float weight_src, ReplaceMode replace_mode) +void vgroup_transfer_weight(MVert *mv_dst, float *weight_dst, float weight_src, WT_ReplaceMode replace_mode) { switch (replace_mode) { - case REPLACE_ALL_WEIGHTS: + case WT_REPLACE_ALL_WEIGHTS: *weight_dst = weight_src; break; - case REPLACE_EMPTY_WEIGHTS: + case WT_REPLACE_EMPTY_WEIGHTS: if (*weight_dst == 0) *weight_dst = weight_src; break; - case REPLACE_SELECTED_WEIGHTS: + case WT_REPLACE_SELECTED_WEIGHTS: if (mv_dst->flag & SELECT) *weight_dst = weight_src; break; + + default: + BLI_assert(0); + break; } } int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_src, Scene *scene, - Method method, ReplaceMode replace_mode, wmOperator *op) + WT_Method method, WT_ReplaceMode replace_mode, wmOperator *op) { bDeformGroup *dg_dst; Mesh *me_dst, *me_src; @@ -452,7 +456,7 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s float weight, tmp_weight[4], tmp_co[3], normal[3], tmp_mat[4][4], dist_v1, dist_v2, dist_v3, dist_v4; /* create new and overwrite vertex group on destination without data */ - if (!defgroup_find_name(ob_dst, dg_src->name) || replace_mode == REPLACE_ALL_WEIGHTS) { + if (!defgroup_find_name(ob_dst, dg_src->name) || replace_mode == WT_REPLACE_ALL_WEIGHTS) { ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_src->name)); ED_vgroup_add_name(ob_dst, dg_src->name); } @@ -491,7 +495,7 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s mult_m4_m4m4(tmp_mat, ob_src->imat, ob_dst->obmat); /* clear weights */ - if (replace_mode == REPLACE_ALL_WEIGHTS) { + if (replace_mode == WT_REPLACE_ALL_WEIGHTS) { for(i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++) { dw_dst = defvert_verify_index(*dv_dst, index_dst); if (dw_dst) (*dw_dst).weight = 0; @@ -500,7 +504,7 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s switch (method) { - case BY_INDEX: + case WT_BY_INDEX: /* check if indices are matching, delete and return if not */ if (ob_dst == ob_src || dv_tot_dst == 0 || dv_tot_dst != dv_tot_src || dv_array_src == NULL || dv_array_dst == NULL) @@ -525,7 +529,7 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s } break; - case BY_NEAREST_VERTEX: + case WT_BY_NEAREST_VERTEX: /* make node tree */ bvhtree_from_mesh_verts(&tree_mesh_vertices_src, dmesh_src, FLT_EPSILON, 2, 6); @@ -544,7 +548,7 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s BLI_bvhtree_find_nearest(tree_mesh_vertices_src.tree, tmp_co, &nearest, tree_mesh_vertices_src.nearest_callback, &tree_mesh_vertices_src); - /* copy weight */ + /* copy weight that are not NULL including weight value 0. Existing target weights are overwritten prior to this in relevant cases. */ dw_src = defvert_find_index(dv_array_src[nearest.index], index_src); if(dw_src && dw_src->weight) { dw_dst = defvert_verify_index(*dv_dst, index_dst); @@ -556,7 +560,7 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s free_bvhtree_from_mesh(&tree_mesh_vertices_src); break; - case BY_NEAREST_FACE: + case WT_BY_NEAREST_FACE: /* get faces */ DM_ensure_tessface(dmesh_src); mface_src = dmesh_src->getTessFaceArray(dmesh_src); @@ -601,7 +605,7 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s weight += tmp_weight[f_index] * defvert_find_weight(dv_array_src[v_index], index_src); } while (f_index--); - /* copy weight */ + /* copy weight that are not NULL including weight value 0. Existing target weights are overwritten prior to this in relevant cases. */ if(weight > 0) { dw_dst = defvert_verify_index(*dv_dst, index_dst); vgroup_transfer_weight(mv_dst, &dw_dst->weight, weight, replace_mode); @@ -612,7 +616,7 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s free_bvhtree_from_mesh(&tree_mesh_faces_src); break; - case BY_NEAREST_VERTEX_IN_FACE: + case WT_BY_NEAREST_VERTEX_IN_FACE: /* get faces */ DM_ensure_tessface(dmesh_src); mface_src = dmesh_src->getTessFaceArray(dmesh_src); @@ -654,7 +658,7 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s } } - /* copy weight */ + /* copy weight that are not NULL including weight value 0. Existing target weights are overwritten prior to this in relevant cases. */ dw_src = defvert_find_index(dv_array_src[index_nearest_vertex], index_src); if(dw_src && dw_src->weight) { dw_dst = defvert_verify_index(*dv_dst, index_dst); @@ -665,6 +669,10 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s /* free memory */ free_bvhtree_from_mesh(&tree_mesh_faces_src); break; + + default: + BLI_assert(0); + break; } /*free memory*/ @@ -675,7 +683,7 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s return 1; } -/***********************End transfer weight***********************************/ +/***********************End weight transfer (WT)***********************************/ /* for Mesh in Object mode */ /* allows editmode for Lattice */ @@ -3065,9 +3073,9 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) bDeformGroup *dg_src; int fail = 0; - VertexGroupMode vertex_group_mode = RNA_enum_get(op->ptr, "vertex_group_mode"); - Method method = RNA_enum_get(op->ptr, "method"); - ReplaceMode replace_mode = RNA_enum_get(op->ptr, "replace_mode"); + WT_VertexGroupMode vertex_group_mode = RNA_enum_get(op->ptr, "WT_vertex_group_mode"); + WT_Method method = RNA_enum_get(op->ptr, "WT_method"); + WT_ReplaceMode replace_mode = RNA_enum_get(op->ptr, "WT_replace_mode"); /* Macro to loop through selected objects and perform operation depending on function, option and method */ CTX_DATA_BEGIN (C, Object *, ob_slc, selected_editable_objects) @@ -3076,17 +3084,21 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) if (ob_act != ob_slc && ob_slc->defbase.first) { switch (vertex_group_mode) { - case REPLACE_ACTIVE_VERTEX_GROUP: + case WT_REPLACE_ACTIVE_VERTEX_GROUP: if (!ED_vgroup_transfer_weight( ob_act, ob_slc, BLI_findlink(&ob_slc->defbase, ob_slc->actdef - 1), scene, method, replace_mode, op)) fail++; break; - case REPLACE_ALL_VERTEX_GROUPS: + case WT_REPLACE_ALL_VERTEX_GROUPS: for (dg_src = ob_slc->defbase.first; dg_src; dg_src = dg_src->next) { if (!ED_vgroup_transfer_weight( ob_act, ob_slc, dg_src, scene, method, replace_mode, op)) fail++; } break; + + default: + BLI_assert(0); + break; } } } @@ -3118,9 +3130,9 @@ void OBJECT_OT_vertex_group_transfer_weight(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ - ot->prop = RNA_def_enum(ot->srna, "vertex_group_mode", vertex_group_mode_item, 1, "Group", ""); - ot->prop = RNA_def_enum(ot->srna, "method", method_item, 3, "Method", ""); - ot->prop = RNA_def_enum(ot->srna, "replace_mode", replace_mode_item, 1, "Replace", ""); + ot->prop = RNA_def_enum(ot->srna, "WT_vertex_group_mode", WT_vertex_group_mode_item, 1, "Group", ""); + ot->prop = RNA_def_enum(ot->srna, "WT_method", WT_method_item, 3, "Method", ""); + ot->prop = RNA_def_enum(ot->srna, "WT_replace_mode", WT_replace_mode_item, 1, "Replace", ""); } static EnumPropertyItem vgroup_items[] = { From 7beff06950a9811a9689ab2d04f8ca4d573d1436 Mon Sep 17 00:00:00 2001 From: Mitchell Stokes Date: Sun, 7 Oct 2012 00:09:02 +0000 Subject: [PATCH 073/347] BGE: Committing patch [#31442] "API improvements: Group references python api, for better control over groups and instances" by Martin Sell (moerdn). This patch adds a member and a group property to KX_GameObject: * KX_GameObject.member returns the list of group members if the object is a group object, otherwise None is returned * KX_GameObject.group returns the group object that the object belongs to or None if the object is not part of a group --- doc/python_api/rst/bge.types.rst | 12 ++++ source/gameengine/Ketsji/KX_GameObject.cpp | 76 +++++++++++++++++++++- source/gameengine/Ketsji/KX_GameObject.h | 32 +++++++++ source/gameengine/Ketsji/KX_Scene.cpp | 21 ++++++ 4 files changed, 140 insertions(+), 1 deletion(-) diff --git a/doc/python_api/rst/bge.types.rst b/doc/python_api/rst/bge.types.rst index f4374f7f355..6599cfeb2b2 100644 --- a/doc/python_api/rst/bge.types.rst +++ b/doc/python_api/rst/bge.types.rst @@ -986,6 +986,18 @@ Types The object's parent object. (read-only). :type: :class:`KX_GameObject` or None + + .. attribute:: members + + Returns the list of group members if the object is a group object, otherwise None is returned. + + :type: :class:`CListValue` of :class:`KX_GameObject` or None + + .. attribute:: group + + Returns the group object that the object belongs to or None if the object is not part of a group. + + :type: :class:`KX_GameObject` or None .. attribute:: visible diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index fe8419d5343..80634c3d8fc 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -110,7 +110,9 @@ KX_GameObject::KX_GameObject( m_pHitObject(NULL), m_pObstacleSimulation(NULL), m_actionManager(NULL), - m_isDeformable(false) + m_isDeformable(false), + m_pDupliGroupObject(NULL), + m_pInstanceObjects(NULL) #ifdef WITH_PYTHON , m_attr_dict(NULL) #endif @@ -168,6 +170,16 @@ KX_GameObject::~KX_GameObject() KX_GetActiveScene()->RemoveAnimatedObject(this); delete m_actionManager; } + + if (m_pDupliGroupObject) + { + m_pDupliGroupObject->Release(); + } + + if (m_pInstanceObjects) + { + m_pInstanceObjects->Release(); + } #ifdef WITH_PYTHON if (m_attr_dict) { PyDict_Clear(m_attr_dict); /* in case of circular refs or other weird cases */ @@ -229,6 +241,46 @@ KX_IPhysicsController* KX_GameObject::GetPhysicsController() return m_pPhysicsController1; } +KX_GameObject* KX_GameObject::GetDupliGroupObject() +{ + return m_pDupliGroupObject; +} + +CListValue* KX_GameObject::GetInstanceObjects() +{ + return m_pInstanceObjects; +} + +void KX_GameObject::AddInstanceObjects(KX_GameObject* obj) +{ + if(!m_pInstanceObjects) + m_pInstanceObjects = new CListValue(); + + obj->AddRef(); + m_pInstanceObjects->Add(obj); +} + +void KX_GameObject::RemoveInstanceObject(KX_GameObject* obj) +{ + assert(m_pInstanceObjects); + m_pInstanceObjects->RemoveValue(obj); + obj->Release(); +} + +void KX_GameObject::RemoveDupliGroupObject() +{ + if(m_pDupliGroupObject) { + m_pDupliGroupObject->Release(); + m_pDupliGroupObject = NULL; + } +} + +void KX_GameObject::SetDupliGroupObject(KX_GameObject* obj) +{ + obj->AddRef(); + m_pDupliGroupObject = obj; +} + KX_GameObject* KX_GameObject::GetParent() { KX_GameObject* result = NULL; @@ -1629,6 +1681,8 @@ PyMethodDef KX_GameObject::Methods[] = { PyAttributeDef KX_GameObject::Attributes[] = { KX_PYATTRIBUTE_RO_FUNCTION("name", KX_GameObject, pyattr_get_name), KX_PYATTRIBUTE_RO_FUNCTION("parent", KX_GameObject, pyattr_get_parent), + KX_PYATTRIBUTE_RO_FUNCTION("members", KX_GameObject, pyattr_get_instance_objects), + KX_PYATTRIBUTE_RO_FUNCTION("group", KX_GameObject, pyattr_get_dupli_group_object), KX_PYATTRIBUTE_RO_FUNCTION("life", KX_GameObject, pyattr_get_life), KX_PYATTRIBUTE_RW_FUNCTION("mass", KX_GameObject, pyattr_get_mass, pyattr_set_mass), KX_PYATTRIBUTE_RW_FUNCTION("linVelocityMin", KX_GameObject, pyattr_get_lin_vel_min, pyattr_set_lin_vel_min), @@ -1924,6 +1978,26 @@ PyObject *KX_GameObject::pyattr_get_parent(void *self_v, const KX_PYATTRIBUTE_DE Py_RETURN_NONE; } +PyObject *KX_GameObject::pyattr_get_instance_objects(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + KX_GameObject* self= static_cast(self_v); + CListValue* instances = self->GetInstanceObjects(); + if (instances) { + return instances->GetProxy(); + } + Py_RETURN_NONE; +} + +PyObject *KX_GameObject::pyattr_get_dupli_group_object(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + KX_GameObject* self= static_cast(self_v); + KX_GameObject* pivot = self->GetDupliGroupObject(); + if (pivot) { + return pivot->GetProxy(); + } + Py_RETURN_NONE; +} + PyObject *KX_GameObject::pyattr_get_life(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { KX_GameObject* self= static_cast(self_v); diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h index ea75ca4a917..4fde0752a13 100644 --- a/source/gameengine/Ketsji/KX_GameObject.h +++ b/source/gameengine/Ketsji/KX_GameObject.h @@ -116,6 +116,8 @@ protected: KX_ObstacleSimulation* m_pObstacleSimulation; + CListValue* m_pInstanceObjects; + KX_GameObject* m_pDupliGroupObject; // The action manager is used to play/stop/update actions BL_ActionManager* m_actionManager; @@ -207,6 +209,33 @@ public: */ void RemoveParent(KX_Scene *scene); + /********************************* + * group reference API + *********************************/ + + KX_GameObject* + GetDupliGroupObject( + ); + + CListValue* + GetInstanceObjects( + ); + + void + SetDupliGroupObject(KX_GameObject* + ); + + void + AddInstanceObjects(KX_GameObject* + ); + + void + RemoveDupliGroupObject( + ); + + void + RemoveInstanceObject(KX_GameObject* + ); /********************************* * Animation API *********************************/ @@ -949,6 +978,9 @@ public: static PyObject* pyattr_get_name(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef); static PyObject* pyattr_get_parent(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); + static PyObject* pyattr_get_dupli_group_object(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); + static PyObject* pyattr_get_instance_objects(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); + static PyObject* pyattr_get_life(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); static PyObject* pyattr_get_mass(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); static int pyattr_set_mass(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp index 652ed2ab2dd..a4237f9fabe 100644 --- a/source/gameengine/Ketsji/KX_Scene.cpp +++ b/source/gameengine/Ketsji/KX_Scene.cpp @@ -769,6 +769,13 @@ void KX_Scene::DupliGroupRecurse(CValue* obj, int level) // we can now add the graphic controller to the physic engine replica->ActivateGraphicController(true); + // set references for dupli-group + // groupobj holds a list of all objects, that belongs to this group + groupobj->AddInstanceObjects(replica); + + // every object gets the reference to its dupli-group object + replica->SetDupliGroupObject(groupobj); + // done with replica replica->Release(); } @@ -1017,6 +1024,20 @@ int KX_Scene::NewRemoveObject(class CValue* gameobj) m_timemgr->RemoveTimeProperty(propval); } } + + // if the object is the dupligroup proxy, you have to cleanup all m_pDupliGroupObject's in all + // instances refering to this group + if(newobj->GetInstanceObjects()) { + for (int i = 0; i < newobj->GetInstanceObjects()->GetCount(); i++) { + KX_GameObject* instance = (KX_GameObject*)newobj->GetInstanceObjects()->GetValue(i); + instance->RemoveDupliGroupObject(); + } + } + + // if this object was part of a group, make sure to remove it from that group's instance list + KX_GameObject* group = newobj->GetDupliGroupObject(); + if (group) + group->RemoveInstanceObject(newobj); newobj->RemoveMeshes(); ret = 1; From 397d316ab1cb2ef5ee42eae6ce18d154479aa6b8 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Sun, 7 Oct 2012 00:30:31 +0000 Subject: [PATCH 074/347] Fix render engine API compatibility breakage in end_result, this parameter should have been optional. --- source/blender/makesrna/intern/rna_render.c | 1 - 1 file changed, 1 deletion(-) diff --git a/source/blender/makesrna/intern/rna_render.c b/source/blender/makesrna/intern/rna_render.c index d2e4e8edbfb..039d50e4ee8 100644 --- a/source/blender/makesrna/intern/rna_render.c +++ b/source/blender/makesrna/intern/rna_render.c @@ -329,7 +329,6 @@ static void rna_def_render_engine(BlenderRNA *brna) prop = RNA_def_pointer(func, "result", "RenderResult", "Result", ""); RNA_def_property_flag(prop, PROP_REQUIRED); prop = RNA_def_boolean(func, "cancel", 0, "Cancel", "Don't merge back results"); - RNA_def_property_flag(prop, PROP_REQUIRED); func = RNA_def_function(srna, "test_break", "RE_engine_test_break"); prop = RNA_def_boolean(func, "do_break", 0, "Break", ""); From d5de816a150501c0041c6315a3dd8dc572c5887e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 7 Oct 2012 03:26:30 +0000 Subject: [PATCH 075/347] patch [#32791] Spelling mistakes corrected. from Sunny Gogoi (darkowlzz) --- doc/guides/interface_API.txt | 16 ++++++++-------- .../blender/editors/interface/interface_layout.c | 3 ++- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/doc/guides/interface_API.txt b/doc/guides/interface_API.txt index 5f601dd3ebc..5f0fbc85ff8 100644 --- a/doc/guides/interface_API.txt +++ b/doc/guides/interface_API.txt @@ -50,7 +50,7 @@ Contents - It works with only OpenGL calls, for the full 100%. This means that it has some quirks built-in to work with all OS's and OpenGL versions. Especially frontbuffer drawing is a continuous point of attention. Buttons can be drawn with any window matrix. However, - errors can still occor when buttons are created in windows with non-standard glViewports. + errors can still occur when buttons are created in windows with non-standard glViewports. - The code was written to replace the old 1.8 button system, but under high pressure. Quite some button methods from the old system were copied for that reason. @@ -95,7 +95,7 @@ blender/source/blender/src/toolbox.c (extra GUI elements built on top of this AP All GUI elements are collected in uiBlocks, which in turn are linked together in a list that's part of a Blender Area-window. - uiBlock *block= uiNewBlock(&curarea->uiblocks, "stuff", UI_EMBOSSX, UI_HELV, curarea->win); + uiBlock *block = uiNewBlock(&curarea->uiblocks, "stuff", UI_EMBOSSX, UI_HELV, curarea->win); The next code example makes a new block, and puts it in the list of blocks of the current active Area: @@ -221,7 +221,7 @@ void uiBlockSetButmFunc(uiBlock *block, void (*menufunc)(void *arg, int event), void uiAutoBlock(uiBlock *block, float minx, float miny, float sizex, float sizey, UI_BLOCK_ROWS) Sets the buttons in this block to automatically align, and fit within boundaries. - Internally it allows multiple collums or rows as well. Only 'row order' has been implemented. + Internally it allows multiple colums or rows as well. Only 'row order' has been implemented. The uiDefBut definitions don't need coordinates as input here, but instead: - first value (x1) to indicate row number - width and height values (if filled in) will be used to define a relative width/height. @@ -346,7 +346,7 @@ type: without returnvalues, the first item gets value 0 (incl. title!) Example: "Do something %t| turn left %2| turn right %1| nothing %0" -11. COL +11. COLOR A special button that only visualizes a RGB value In 'retval' you can put a code, which is used to identify for sliders if it needs redraws while using the sliders. Check button '5'. @@ -363,7 +363,7 @@ uiBut *uiDefIconBut(uiBlock *block, int type, int retval, int icon, float min, float max, float a1, float a2, char *tip) Same syntax and types available as previous uiDefBut, but now with an icon code - instead of a name. THe icons are numbered in resources.c + instead of a name. The icons are numbered in resources.c uiBut *uiDefIconTextButF(uiBlock *block, int type, int retval, int icon, char *str, short x1, short y1, short x2, short y2, float *poin, @@ -397,9 +397,9 @@ void uiDefBlockBut(uiBlock *block, uiBlockFuncFP func, void *arg, char *str, static uiBlock *info_file_importmenu(void *arg_unused) { uiBlock *block; - short yco= 0, xco = 20; + short yco = 0, xco = 20; - block= uiNewBlock(&curarea->uiblocks, "importmenu", UI_EMBOSSW, UI_HELV, G.curscreen->mainwin); + block = uiNewBlock(&curarea->uiblocks, "importmenu", UI_EMBOSSW, UI_HELV, G.curscreen->mainwin); uiBlockSetXOfs(block, -40); // offset to parent button /* flags are defines */ @@ -409,7 +409,7 @@ void uiDefBlockBut(uiBlock *block, uiBlockFuncFP func, void *arg, char *str, uiDefButS(block, TOG|BIT|2, 0, "Two Sided", xco, yco-=20, 75, 19, &U.vrmlflag, 0.0, 0.0, 0, 0, ""); uiBlockSetDirection(block, UI_RIGHT); - uiTextBoundsBlock(block, 50); // checks for fontsize + uiTextBoundsBlock(block, 50); /* checks for fontsize */ return block; } diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index 7a369019ac4..d692bf8e492 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -835,8 +835,9 @@ void uiItemsFullEnumO(uiLayout *layout, const char *opname, const char *propname bt = block->buttons.last; bt->flag = UI_TEXT_LEFT; } - else /* XXX bug here, collums draw bottom item badly */ + else { /* XXX bug here, colums draw bottom item badly */ uiItemS(column); + } } } From a17e39476cf3d7bc7724e5d259d0c3572cdb08dc Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 7 Oct 2012 04:21:37 +0000 Subject: [PATCH 076/347] Optimization for endian switching, but shifting is a lot faster then using a temp char (approx 18x speedup on my system). --- .../blenlib/BLI_endian_switch_inline.h | 80 +++++++------------ 1 file changed, 29 insertions(+), 51 deletions(-) diff --git a/source/blender/blenlib/BLI_endian_switch_inline.h b/source/blender/blenlib/BLI_endian_switch_inline.h index b747da3b738..6694276a995 100644 --- a/source/blender/blenlib/BLI_endian_switch_inline.h +++ b/source/blender/blenlib/BLI_endian_switch_inline.h @@ -32,85 +32,63 @@ * \ingroup bli */ +/* note: using a temp char to switch endian is a lot slower, + * use bit shifting instead. */ +/* *** 16 *** */ BLI_INLINE void BLI_endian_switch_int16(short *val) { - char *p_i = (char *)val; - char s_i; + short tval = *val; + *val = (tval >> 8) | + (tval << 8); - s_i = p_i[0]; - p_i[0] = p_i[1]; - p_i[1] = s_i; } - BLI_INLINE void BLI_endian_switch_uint16(unsigned short *val) { - char *p_i = (char *)val; - char s_i; - - s_i = p_i[0]; - p_i[0] = p_i[1]; - p_i[1] = s_i; + BLI_endian_switch_int16((short *)val); } + +/* *** 32 *** */ BLI_INLINE void BLI_endian_switch_int32(int *val) { - char *p_i = (char *)val; - char s_i; + int tval = *val; + *val = ((tval >> 24)) | + ((tval << 8) & 0x00ff0000) | + ((tval >> 8) & 0x0000ff00) | + ((tval << 24)); - s_i = p_i[0]; p_i[0] = p_i[3]; p_i[3] = s_i; - s_i = p_i[1]; p_i[1] = p_i[2]; p_i[2] = s_i; } - BLI_INLINE void BLI_endian_switch_uint32(unsigned int *val) { - char *p_i = (char *)val; - char s_i; - - s_i = p_i[0]; p_i[0] = p_i[3]; p_i[3] = s_i; - s_i = p_i[1]; p_i[1] = p_i[2]; p_i[2] = s_i; + BLI_endian_switch_int32((int *)val); } - BLI_INLINE void BLI_endian_switch_float(float *val) { - char *p_i = (char *)val; - char s_i; - - s_i = p_i[0]; p_i[0] = p_i[3]; p_i[3] = s_i; - s_i = p_i[1]; p_i[1] = p_i[2]; p_i[2] = s_i; + BLI_endian_switch_int32((int *)val); } + +/* *** 64 *** */ BLI_INLINE void BLI_endian_switch_int64(int64_t *val) { - char *p_i = (char *)val; - char s_i; - - s_i = p_i[0]; p_i[0] = p_i[7]; p_i[7] = s_i; - s_i = p_i[1]; p_i[1] = p_i[6]; p_i[6] = s_i; - s_i = p_i[2]; p_i[2] = p_i[5]; p_i[5] = s_i; - s_i = p_i[3]; p_i[3] = p_i[4]; p_i[4] = s_i; + int64_t tval = *val; + *val = ((tval >> 56)) | + ((tval << 40) & 0x00ff000000000000) | + ((tval << 24) & 0x0000ff0000000000) | + ((tval << 8) & 0x000000ff00000000) | + ((tval >> 8) & 0x00000000ff000000) | + ((tval >> 24) & 0x0000000000ff0000) | + ((tval >> 40) & 0x000000000000ff00) | + ((tval << 56)); } - BLI_INLINE void BLI_endian_switch_uint64(uint64_t *val) { - char *p_i = (char *)val; - char s_i; - - s_i = p_i[0]; p_i[0] = p_i[7]; p_i[7] = s_i; - s_i = p_i[1]; p_i[1] = p_i[6]; p_i[6] = s_i; - s_i = p_i[2]; p_i[2] = p_i[5]; p_i[5] = s_i; - s_i = p_i[3]; p_i[3] = p_i[4]; p_i[4] = s_i; + BLI_endian_switch_int64((int64_t *)val); } - BLI_INLINE void BLI_endian_switch_double(double *val) { - char *p_i = (char *)val; - char s_i; - - s_i = p_i[0]; p_i[0] = p_i[7]; p_i[7] = s_i; - s_i = p_i[1]; p_i[1] = p_i[6]; p_i[6] = s_i; - s_i = p_i[2]; p_i[2] = p_i[5]; p_i[5] = s_i; - s_i = p_i[3]; p_i[3] = p_i[4]; p_i[4] = s_i; + BLI_endian_switch_int64((int64_t *)val); } #endif /* __BLI_ENDIAN_SWITCH_INLINE_H__ */ From c530661db21ce882d4b5ef16d64ed5fc8f469761 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 7 Oct 2012 06:06:28 +0000 Subject: [PATCH 077/347] patch [#32556] Stupid endian conversion in avi format from Andreas Schwab (schwab) modified to use code from BLI_endian_switch. --- source/blender/avi/intern/endian.c | 31 +++++++------------ .../blenlib/BLI_endian_switch_inline.h | 2 +- 2 files changed, 12 insertions(+), 21 deletions(-) diff --git a/source/blender/avi/intern/endian.c b/source/blender/avi/intern/endian.c index c9b95d25810..8e5ed80f5a0 100644 --- a/source/blender/avi/intern/endian.c +++ b/source/blender/avi/intern/endian.c @@ -46,31 +46,22 @@ #endif #ifdef __BIG_ENDIAN__ + +/* copied from BLI_endian_switch_inline.h */ static void invert(int *num) { - int new = 0, i, j; - - for (j = 0; j < 4; j++) { - for (i = 0; i < 8; i++) { - new |= ((*num >> (j * 8 + i)) & 1) << ((3 - j) * 8 + i); - } - } - - *num = new; + int tval = *val; + *val = ((tval >> 24)) | + ((tval << 8) & 0x00ff0000) | + ((tval >> 8) & 0x0000ff00) | + ((tval << 24)); } -static void sinvert(short int *num) +static void sinvert(short int *val) { - short int new = 0; - int i, j; - - for (j = 0; j < 2; j++) { - for (i = 0; i < 8; i++) { - new |= ((*num >> (j * 8 + i)) & 1) << ((1 - j) * 8 + i); - } - } - - *num = new; + short tval = *val; + *val = (tval >> 8) | + (tval << 8); } static void Ichunk(AviChunk *chunk) diff --git a/source/blender/blenlib/BLI_endian_switch_inline.h b/source/blender/blenlib/BLI_endian_switch_inline.h index 6694276a995..948d462fde4 100644 --- a/source/blender/blenlib/BLI_endian_switch_inline.h +++ b/source/blender/blenlib/BLI_endian_switch_inline.h @@ -40,7 +40,7 @@ BLI_INLINE void BLI_endian_switch_int16(short *val) { short tval = *val; *val = (tval >> 8) | - (tval << 8); + (tval << 8); } BLI_INLINE void BLI_endian_switch_uint16(unsigned short *val) From 89a415a49d0e96bd6bf63b5e6e9d5bfe2f87bc49 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 7 Oct 2012 06:27:31 +0000 Subject: [PATCH 078/347] rename avi files (endian.h is common linux include). --- source/blender/avi/AVI_avi.h | 2 +- source/blender/avi/CMakeLists.txt | 20 +++++++++---------- source/blender/avi/intern/avi.c | 3 +-- .../avi/intern/{codecs.c => avi_codecs.c} | 8 ++++---- .../avi/intern/{endian.c => avi_endian.c} | 7 ++++--- .../avi/intern/{endian.h => avi_endian.h} | 12 ++++------- .../avi/intern/{mjpeg.c => avi_mjpeg.c} | 14 +++++++------ .../avi/intern/{mjpeg.h => avi_mjpeg.h} | 5 ++++- .../avi/intern/{options.c => avi_options.c} | 4 ++-- .../avi/intern/{avirgb.c => avi_rgb.c} | 8 ++++---- .../avi/intern/{avirgb.h => avi_rgb.h} | 9 ++++++--- .../avi/intern/{rgb32.c => avi_rgb32.c} | 9 +++++---- .../avi/intern/{rgb32.h => avi_rgb32.h} | 9 ++++++--- 13 files changed, 59 insertions(+), 51 deletions(-) rename source/blender/avi/intern/{codecs.c => avi_codecs.c} (96%) rename source/blender/avi/intern/{endian.c => avi_endian.c} (98%) rename source/blender/avi/intern/{endian.h => avi_endian.h} (90%) rename source/blender/avi/intern/{mjpeg.c => avi_mjpeg.c} (99%) rename source/blender/avi/intern/{mjpeg.h => avi_mjpeg.h} (91%) rename source/blender/avi/intern/{options.c => avi_options.c} (98%) rename source/blender/avi/intern/{avirgb.c => avi_rgb.c} (98%) rename source/blender/avi/intern/{avirgb.h => avi_rgb.h} (76%) rename source/blender/avi/intern/{rgb32.c => avi_rgb32.c} (97%) rename source/blender/avi/intern/{rgb32.h => avi_rgb32.h} (76%) diff --git a/source/blender/avi/AVI_avi.h b/source/blender/avi/AVI_avi.h index bdfdbc117ed..4dc52970119 100644 --- a/source/blender/avi/AVI_avi.h +++ b/source/blender/avi/AVI_avi.h @@ -178,7 +178,7 @@ typedef struct _AviStreamRec { } AviStreamRec; typedef struct _AviMovie { - FILE *fp; + FILE *fp; int type; #define AVI_MOVIE_READ 0 diff --git a/source/blender/avi/CMakeLists.txt b/source/blender/avi/CMakeLists.txt index 79422dff917..292206d8cb9 100644 --- a/source/blender/avi/CMakeLists.txt +++ b/source/blender/avi/CMakeLists.txt @@ -35,19 +35,19 @@ set(INC_SYS set(SRC intern/avi.c - intern/avirgb.c - intern/codecs.c - intern/endian.c - intern/mjpeg.c - intern/options.c - intern/rgb32.c + intern/avi_rgb.c + intern/avi_codecs.c + intern/avi_endian.c + intern/avi_mjpeg.c + intern/avi_options.c + intern/avi_rgb32.c AVI_avi.h intern/avi_intern.h - intern/avirgb.h - intern/endian.h - intern/mjpeg.h - intern/rgb32.h + intern/avi_rgb.h + intern/avi_endian.h + intern/avi_mjpeg.h + intern/avi_rgb32.h ) blender_add_lib(bf_avi "${SRC}" "${INC}" "${INC_SYS}") diff --git a/source/blender/avi/intern/avi.c b/source/blender/avi/intern/avi.c index 2845b2f95c9..15d8702a5ec 100644 --- a/source/blender/avi/intern/avi.c +++ b/source/blender/avi/intern/avi.c @@ -32,7 +32,6 @@ * This is external code. */ - #include #include #include @@ -49,7 +48,7 @@ #include "AVI_avi.h" #include "avi_intern.h" -#include "endian.h" +#include "avi_endian.h" static int AVI_DEBUG = 0; static char DEBUG_FCC[4]; diff --git a/source/blender/avi/intern/codecs.c b/source/blender/avi/intern/avi_codecs.c similarity index 96% rename from source/blender/avi/intern/codecs.c rename to source/blender/avi/intern/avi_codecs.c index 01e228d570e..e43826064a6 100644 --- a/source/blender/avi/intern/codecs.c +++ b/source/blender/avi/intern/avi_codecs.c @@ -25,7 +25,7 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/avi/intern/codecs.c +/** \file blender/avi/intern/avi_codecs.c * \ingroup avi * * This is external code. Identify and convert different avi-files. @@ -35,9 +35,9 @@ #include "AVI_avi.h" #include "avi_intern.h" -#include "avirgb.h" -#include "mjpeg.h" -#include "rgb32.h" +#include "avi_rgb.h" +#include "avi_mjpeg.h" +#include "avi_rgb32.h" void *avi_format_convert(AviMovie *movie, int stream, void *buffer, AviFormat from, AviFormat to, int *size) { diff --git a/source/blender/avi/intern/endian.c b/source/blender/avi/intern/avi_endian.c similarity index 98% rename from source/blender/avi/intern/endian.c rename to source/blender/avi/intern/avi_endian.c index 8e5ed80f5a0..70add8bd90f 100644 --- a/source/blender/avi/intern/endian.c +++ b/source/blender/avi/intern/avi_endian.c @@ -26,7 +26,7 @@ * */ -/** \file blender/avi/intern/endian.c +/** \file blender/avi/intern/avi_endian.c * \ingroup avi * * This is external code. Streams bytes to output depending on the @@ -36,9 +36,10 @@ #include #include -#include +#include + #include "AVI_avi.h" -#include "endian.h" +#include "avi_endian.h" #include "avi_intern.h" #ifdef __BIG_ENDIAN__ diff --git a/source/blender/avi/intern/endian.h b/source/blender/avi/intern/avi_endian.h similarity index 90% rename from source/blender/avi/intern/endian.h rename to source/blender/avi/intern/avi_endian.h index 7ef49cb1699..8cea283a553 100644 --- a/source/blender/avi/intern/endian.h +++ b/source/blender/avi/intern/avi_endian.h @@ -25,17 +25,14 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/avi/intern/endian.h +/** \file blender/avi/intern/avi_endian.h * \ingroup avi * * This is external code. */ -#ifndef __ENDIAN_H__ -#define __ENDIAN_H__ - -#include -#include "AVI_avi.h" +#ifndef __AVI_ENDIAN_H__ +#define __AVI_ENDIAN_H__ #define AVI_RAW 0 #define AVI_CHUNK 1 @@ -48,5 +45,4 @@ void awrite(AviMovie *movie, void *datain, int block, int size, FILE *fp, int type); -#endif - +#endif /* __AVI_ENDIAN_H__ */ diff --git a/source/blender/avi/intern/mjpeg.c b/source/blender/avi/intern/avi_mjpeg.c similarity index 99% rename from source/blender/avi/intern/mjpeg.c rename to source/blender/avi/intern/avi_mjpeg.c index a700284bf68..b98e03d6a19 100644 --- a/source/blender/avi/intern/mjpeg.c +++ b/source/blender/avi/intern/avi_mjpeg.c @@ -26,21 +26,23 @@ * */ -/** \file blender/avi/intern/mjpeg.c +/** \file blender/avi/intern/avi_mjpeg.c * \ingroup avi * * This is external code. Converts between avi and mpeg/jpeg. */ - -#include "AVI_avi.h" #include #include -#include "jpeglib.h" -#include "jerror.h" + +#include "AVI_avi.h" + #include "MEM_guardedalloc.h" -#include "mjpeg.h" +#include "jpeglib.h" +#include "jerror.h" + +#include "avi_mjpeg.h" #define PADUP(num, amt) ((num + (amt - 1)) & ~(amt - 1)) diff --git a/source/blender/avi/intern/mjpeg.h b/source/blender/avi/intern/avi_mjpeg.h similarity index 91% rename from source/blender/avi/intern/mjpeg.h rename to source/blender/avi/intern/avi_mjpeg.h index 75649891f2b..6ae0e56ffa4 100644 --- a/source/blender/avi/intern/mjpeg.h +++ b/source/blender/avi/intern/avi_mjpeg.h @@ -25,11 +25,14 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/avi/intern/mjpeg.h +/** \file blender/avi/intern/avi_mjpeg.h * \ingroup avi */ +#ifndef __AVI_MJPEG_H__ +#define __AVI_MJPEG_H__ void *avi_converter_from_mjpeg (AviMovie *movie, int stream, unsigned char *buffer, int *size); void *avi_converter_to_mjpeg (AviMovie *movie, int stream, unsigned char *buffer, int *size); +#endif /* __AVI_MJPEG_H__ */ diff --git a/source/blender/avi/intern/options.c b/source/blender/avi/intern/avi_options.c similarity index 98% rename from source/blender/avi/intern/options.c rename to source/blender/avi/intern/avi_options.c index 7de91318ecf..f7759a1099f 100644 --- a/source/blender/avi/intern/options.c +++ b/source/blender/avi/intern/avi_options.c @@ -26,7 +26,7 @@ * */ -/** \file blender/avi/intern/options.c +/** \file blender/avi/intern/avi_options.c * \ingroup avi * * This is external code. Sets some compression related options @@ -35,7 +35,7 @@ #include "AVI_avi.h" #include "avi_intern.h" -#include "endian.h" +#include "avi_endian.h" #ifdef WIN32 # include "BLI_winstuff.h" diff --git a/source/blender/avi/intern/avirgb.c b/source/blender/avi/intern/avi_rgb.c similarity index 98% rename from source/blender/avi/intern/avirgb.c rename to source/blender/avi/intern/avi_rgb.c index 7a95972845a..61587e15e61 100644 --- a/source/blender/avi/intern/avirgb.c +++ b/source/blender/avi/intern/avi_rgb.c @@ -26,19 +26,19 @@ * */ -/** \file blender/avi/intern/avirgb.c +/** \file blender/avi/intern/avi_rgb.c * \ingroup avi * * This is external code. Converts rgb-type avi-s. */ - -#include "AVI_avi.h" #include #include #include "MEM_guardedalloc.h" -#include "avirgb.h" + +#include "AVI_avi.h" +#include "avi_rgb.h" /* implementation */ diff --git a/source/blender/avi/intern/avirgb.h b/source/blender/avi/intern/avi_rgb.h similarity index 76% rename from source/blender/avi/intern/avirgb.h rename to source/blender/avi/intern/avi_rgb.h index 20211d6ab2d..773166e9fab 100644 --- a/source/blender/avi/intern/avirgb.h +++ b/source/blender/avi/intern/avi_rgb.h @@ -25,11 +25,14 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/avi/intern/avirgb.h +/** \file blender/avi/intern/avi_rgb.h * \ingroup avi */ +#ifndef __AVI_RGB_H__ +#define __AVI_RGB_H__ -void *avi_converter_from_avi_rgb (AviMovie *movie, int stream, unsigned char *buffer, int *size); -void *avi_converter_to_avi_rgb (AviMovie *movie, int stream, unsigned char *buffer, int *size); +void *avi_converter_from_avi_rgb(AviMovie *movie, int stream, unsigned char *buffer, int *size); +void *avi_converter_to_avi_rgb(AviMovie *movie, int stream, unsigned char *buffer, int *size); +#endif /* __AVI_RGB_H__ */ diff --git a/source/blender/avi/intern/rgb32.c b/source/blender/avi/intern/avi_rgb32.c similarity index 97% rename from source/blender/avi/intern/rgb32.c rename to source/blender/avi/intern/avi_rgb32.c index 84630f09fe5..5c7a4889d97 100644 --- a/source/blender/avi/intern/rgb32.c +++ b/source/blender/avi/intern/avi_rgb32.c @@ -26,18 +26,19 @@ * */ -/** \file blender/avi/intern/rgb32.c +/** \file blender/avi/intern/avi_rgb32.c * \ingroup avi * * This is external code. Converts between rgb32 and avi. */ - -#include "AVI_avi.h" #include #include + #include "MEM_guardedalloc.h" -#include "rgb32.h" + +#include "AVI_avi.h" +#include "avi_rgb32.h" void *avi_converter_from_rgb32(AviMovie *movie, int stream, unsigned char *buffer, int *size) { diff --git a/source/blender/avi/intern/rgb32.h b/source/blender/avi/intern/avi_rgb32.h similarity index 76% rename from source/blender/avi/intern/rgb32.h rename to source/blender/avi/intern/avi_rgb32.h index 55f9771a4df..523f9e795fd 100644 --- a/source/blender/avi/intern/rgb32.h +++ b/source/blender/avi/intern/avi_rgb32.h @@ -25,11 +25,14 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/avi/intern/rgb32.h +/** \file blender/avi/intern/avi_rgb32.h * \ingroup avi */ +#ifndef __AVI_RGB32_H__ +#define __AVI_RGB32_H__ -void *avi_converter_from_rgb32 (AviMovie *movie, int stream, unsigned char *buffer, int *size); -void *avi_converter_to_rgb32 (AviMovie *movie, int stream, unsigned char *buffer, int *size); +void *avi_converter_from_rgb32(AviMovie *movie, int stream, unsigned char *buffer, int *size); +void *avi_converter_to_rgb32(AviMovie *movie, int stream, unsigned char *buffer, int *size); +#endif /* __AVI_RGB32_H__ */ From 1a9f930514719eee65609d7499bd184147580b55 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 7 Oct 2012 07:27:09 +0000 Subject: [PATCH 079/347] add type checking for more error prone macros. --- source/blender/blenkernel/BKE_armature.h | 10 ++++-- source/blender/blenkernel/BKE_sequencer.h | 8 +++-- source/blender/blenlib/BLI_utildefines.h | 4 +++ source/blender/editors/include/ED_anim_api.h | 36 ++++++++++---------- source/blender/editors/include/ED_armature.h | 13 +++++-- 5 files changed, 46 insertions(+), 25 deletions(-) diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h index a3f3beefbaf..6b9de47836e 100644 --- a/source/blender/blenkernel/BKE_armature.h +++ b/source/blender/blenkernel/BKE_armature.h @@ -131,8 +131,14 @@ typedef struct Mat4 { Mat4 *b_bone_spline_setup(struct bPoseChannel *pchan, int rest); /* like EBONE_VISIBLE */ -#define PBONE_VISIBLE(arm, bone) (((bone)->layer & (arm)->layer) && !((bone)->flag & BONE_HIDDEN_P)) -#define PBONE_SELECTABLE(arm, bone) (PBONE_VISIBLE(arm, bone) && !((bone)->flag & BONE_UNSELECTABLE)) +#define PBONE_VISIBLE(arm, bone) ( \ + CHECK_TYPE_INLINE(arm, bArmature), \ + CHECK_TYPE_INLINE(bone, Bone), \ + (((bone)->layer & (arm)->layer) && !((bone)->flag & BONE_HIDDEN_P)) \ + ) + +#define PBONE_SELECTABLE(arm, bone) \ + (PBONE_VISIBLE(arm, bone) && !((bone)->flag & BONE_UNSELECTABLE)) #ifdef __cplusplus } diff --git a/source/blender/blenkernel/BKE_sequencer.h b/source/blender/blenkernel/BKE_sequencer.h index cecff2d9516..80431682d6f 100644 --- a/source/blender/blenkernel/BKE_sequencer.h +++ b/source/blender/blenkernel/BKE_sequencer.h @@ -73,15 +73,17 @@ void BKE_sequence_iterator_end(SeqIterator *iter); SeqIterator iter; \ for (BKE_sequence_iterator_begin(ed, &iter, 1); \ iter.valid; \ - BKE_sequence_iterator_next(&iter)) { \ + BKE_sequence_iterator_next(&iter)) \ + { \ _seq = iter.seq; - + #define SEQ_BEGIN(ed, _seq) \ { \ SeqIterator iter; \ for (BKE_sequence_iterator_begin(ed, &iter, 0); \ iter.valid; \ - BKE_sequence_iterator_next(&iter)) { \ + BKE_sequence_iterator_next(&iter)) \ + { \ _seq = iter.seq; #define SEQ_END \ diff --git a/source/blender/blenlib/BLI_utildefines.h b/source/blender/blenlib/BLI_utildefines.h index 29097a4c6c3..ebb40c18c21 100644 --- a/source/blender/blenlib/BLI_utildefines.h +++ b/source/blender/blenlib/BLI_utildefines.h @@ -128,6 +128,10 @@ #endif #endif +/* can be used in simple macros */ +#define CHECK_TYPE_INLINE(val, type) \ + ((void)(((type *)0) == (val))) + #ifndef SWAP # define SWAP(type, a, b) { \ type sw_ap; \ diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h index e1401a8ff88..8d7ae3aad6a 100644 --- a/source/blender/editors/include/ED_anim_api.h +++ b/source/blender/editors/include/ED_anim_api.h @@ -232,28 +232,28 @@ typedef enum eAnimFilter_Flags { /* Dopesheet only */ /* 'Scene' channels */ -#define SEL_SCEC(sce) ((sce->flag & SCE_DS_SELECTED)) -#define EXPANDED_SCEC(sce) ((sce->flag & SCE_DS_COLLAPSED) == 0) +#define SEL_SCEC(sce) (CHECK_TYPE_INLINE(sce, Scene), ((sce->flag & SCE_DS_SELECTED))) +#define EXPANDED_SCEC(sce) (CHECK_TYPE_INLINE(sce, Scene), ((sce->flag & SCE_DS_COLLAPSED) == 0)) /* 'Sub-Scene' channels (flags stored in Data block) */ -#define FILTER_WOR_SCED(wo) ((wo->flag & WO_DS_EXPAND)) +#define FILTER_WOR_SCED(wo) (CHECK_TYPE_INLINE(wo, World), (wo->flag & WO_DS_EXPAND)) /* 'Object' channels */ -#define SEL_OBJC(base) ((base->flag & SELECT)) -#define EXPANDED_OBJC(ob) ((ob->nlaflag & OB_ADS_COLLAPSED) == 0) +#define SEL_OBJC(base) (CHECK_TYPE_INLINE(base, Base), ((base->flag & SELECT))) +#define EXPANDED_OBJC(ob) (CHECK_TYPE_INLINE(ob, Object), ((ob->nlaflag & OB_ADS_COLLAPSED) == 0)) /* 'Sub-object' channels (flags stored in Data block) */ -#define FILTER_SKE_OBJD(key) ((key->flag & KEY_DS_EXPAND)) -#define FILTER_MAT_OBJD(ma) ((ma->flag & MA_DS_EXPAND)) -#define FILTER_LAM_OBJD(la) ((la->flag & LA_DS_EXPAND)) -#define FILTER_CAM_OBJD(ca) ((ca->flag & CAM_DS_EXPAND)) -#define FILTER_CUR_OBJD(cu) ((cu->flag & CU_DS_EXPAND)) -#define FILTER_PART_OBJD(part) ((part->flag & PART_DS_EXPAND)) -#define FILTER_MBALL_OBJD(mb) ((mb->flag2 & MB_DS_EXPAND)) -#define FILTER_ARM_OBJD(arm) ((arm->flag & ARM_DS_EXPAND)) -#define FILTER_MESH_OBJD(me) ((me->flag & ME_DS_EXPAND)) -#define FILTER_LATTICE_OBJD(lt) ((lt->flag & LT_DS_EXPAND)) -#define FILTER_SPK_OBJD(spk) ((spk->flag & SPK_DS_EXPAND)) +#define FILTER_SKE_OBJD(key) (CHECK_TYPE_INLINE(key, Key), ((key->flag & KEY_DS_EXPAND))) +#define FILTER_MAT_OBJD(ma) (CHECK_TYPE_INLINE(ma, Material), ((ma->flag & MA_DS_EXPAND))) +#define FILTER_LAM_OBJD(la) (CHECK_TYPE_INLINE(la, Lamp), ((la->flag & LA_DS_EXPAND))) +#define FILTER_CAM_OBJD(ca) (CHECK_TYPE_INLINE(ca, Camera), ((ca->flag & CAM_DS_EXPAND))) +#define FILTER_CUR_OBJD(cu) (CHECK_TYPE_INLINE(cu, Curve), ((cu->flag & CU_DS_EXPAND))) +#define FILTER_PART_OBJD(part) (CHECK_TYPE_INLINE(part, ParticleSettings), ((part->flag & PART_DS_EXPAND))) +#define FILTER_MBALL_OBJD(mb) (CHECK_TYPE_INLINE(mb, MetaBall), ((mb->flag2 & MB_DS_EXPAND))) +#define FILTER_ARM_OBJD(arm) (CHECK_TYPE_INLINE(arm, bArmature), ((arm->flag & ARM_DS_EXPAND))) +#define FILTER_MESH_OBJD(me) (CHECK_TYPE_INLINE(me, Mesh), ((me->flag & ME_DS_EXPAND))) +#define FILTER_LATTICE_OBJD(lt) (CHECK_TYPE_INLINE(lt, Lattice), ((lt->flag & LT_DS_EXPAND))) +#define FILTER_SPK_OBJD(spk) (CHECK_TYPE_INLINE(spk, Speaker), ((spk->flag & SPK_DS_EXPAND))) /* Variable use expanders */ -#define FILTER_NTREE_DATA(ntree) ((ntree->flag & NTREE_DS_EXPAND)) -#define FILTER_TEX_DATA(tex) ((tex->flag & TEX_DS_EXPAND)) +#define FILTER_NTREE_DATA(ntree) (CHECK_TYPE_INLINE(ntree, bNodeTree), ((ntree->flag & NTREE_DS_EXPAND))) +#define FILTER_TEX_DATA(tex) (CHECK_TYPE_INLINE(tex, Tex), ((tex->flag & TEX_DS_EXPAND))) /* 'Sub-object/Action' channels (flags stored in Action) */ #define SEL_ACTC(actc) ((actc->flag & ACT_SELECTED)) diff --git a/source/blender/editors/include/ED_armature.h b/source/blender/editors/include/ED_armature.h index b9996c87194..efd10f3cb6b 100644 --- a/source/blender/editors/include/ED_armature.h +++ b/source/blender/editors/include/ED_armature.h @@ -93,9 +93,18 @@ typedef struct EditBone { #define BONESEL_NOSEL (1 << 31) /* Indicates a negative number */ /* useful macros */ -#define EBONE_VISIBLE(arm, ebone) (((arm)->layer & (ebone)->layer) && !((ebone)->flag & BONE_HIDDEN_A)) +#define EBONE_VISIBLE(arm, ebone) ( \ + CHECK_TYPE_INLINE(arm, bArmature), \ + CHECK_TYPE_INLINE(ebone, EditBone), \ + (((arm)->layer & (ebone)->layer) && !((ebone)->flag & BONE_HIDDEN_A)) \ + ) + #define EBONE_SELECTABLE(arm, ebone) (EBONE_VISIBLE(arm, ebone) && !(ebone->flag & BONE_UNSELECTABLE)) -#define EBONE_EDITABLE(ebone) (((ebone)->flag & BONE_SELECTED) && !((ebone)->flag & BONE_EDITMODE_LOCKED)) + +#define EBONE_EDITABLE(ebone) ( \ + CHECK_TYPE_INLINE(ebone, EditBone), \ + (((ebone)->flag & BONE_SELECTED) && !((ebone)->flag & BONE_EDITMODE_LOCKED)) \ + ) /* used in bone_select_hierachy() */ #define BONE_SELECT_PARENT 0 From 7748133bf2d0a99f37b2a0b0ce438b6726db36fa Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 7 Oct 2012 07:38:22 +0000 Subject: [PATCH 080/347] code cleanup: glare stream operation was setting alpha array twice. --- .../compositor/operations/COM_GlareStreaksOperation.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/source/blender/compositor/operations/COM_GlareStreaksOperation.cpp b/source/blender/compositor/operations/COM_GlareStreaksOperation.cpp index 9125783c222..60d37fb8145 100644 --- a/source/blender/compositor/operations/COM_GlareStreaksOperation.cpp +++ b/source/blender/compositor/operations/COM_GlareStreaksOperation.cpp @@ -81,11 +81,9 @@ void GlareStreaksOperation::generateGlare(float *data, MemoryBuffer *inputTile, float *sourcebuffer = tsrc->getBuffer(); float factor = 1.f / (float)(6 - settings->iter); - for (int i = 0; i < size4; i++) { - data[i] += sourcebuffer[i] * factor; - } - for (int i = 0; i < size; i++) { - data[i * 4 + 3] = 1.0f; + for (int i = 0; i < size4; i += 4) { + madd_v3_v3fl(&data[i], &sourcebuffer[i], factor); + data[i + 3] = 1.0f; } tdst->clear(); From e8872a8ea259c856aab188cda8eb4502d6a02cfc Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 7 Oct 2012 09:48:59 +0000 Subject: [PATCH 081/347] style cleanup: if(); --- .../cmake/cmake_static_check_clang_array.py | 1 + .../cmake/cmake_static_check_cppcheck.py | 1 + .../cmake/cmake_static_check_smatch.py | 1 + .../cmake/cmake_static_check_sparse.py | 1 + .../cmake/cmake_static_check_splint.py | 1 + source/blender/blenkernel/intern/blender.c | 8 +- source/blender/blenkernel/intern/customdata.c | 49 ++++++--- source/blender/blenkernel/intern/displist.c | 4 +- source/blender/blenkernel/intern/font.c | 8 +- source/blender/blenkernel/intern/lattice.c | 5 +- source/blender/blenkernel/intern/modifier.c | 8 +- source/blender/blenkernel/intern/particle.c | 8 +- .../blenlib/BLI_endian_switch_inline.h | 12 +-- .../blender/editors/armature/editarmature.c | 11 +- source/blender/editors/curve/editcurve.c | 101 +++++++++++++----- source/blender/editors/interface/interface.c | 12 ++- .../editors/interface/interface_handlers.c | 20 +++- .../editors/interface/interface_layout.c | 8 +- .../editors/interface/interface_widgets.c | 4 +- source/blender/editors/mesh/editface.c | 8 +- .../blender/editors/physics/particle_edit.c | 8 +- source/blender/editors/render/render_update.c | 44 ++++++-- source/blender/editors/screen/area.c | 29 +++-- .../blender/editors/sculpt_paint/paint_undo.c | 12 ++- source/blender/editors/space_file/filelist.c | 4 +- .../blender/editors/space_image/space_image.c | 5 +- .../editors/space_outliner/outliner_draw.c | 14 ++- .../editors/space_outliner/outliner_tree.c | 24 +++-- .../editors/space_sequencer/sequencer_edit.c | 4 +- .../editors/space_view3d/drawarmature.c | 13 ++- .../editors/space_view3d/view3d_draw.c | 4 +- .../editors/transform/transform_conversions.c | 8 +- source/blender/makesdna/intern/makesdna.c | 18 ++-- .../nodes/texture/nodes/node_texture_output.c | 2 +- .../render/intern/source/convertblender.c | 8 +- .../render/intern/source/imagetexture.c | 33 ++++-- .../blender/render/intern/source/occlusion.c | 7 +- .../blender/render/intern/source/pipeline.c | 12 ++- .../render/intern/source/pointdensity.c | 6 +- .../render/intern/source/render_texture.c | 41 ++++--- .../blender/render/intern/source/rendercore.c | 49 ++++++--- .../render/intern/source/renderdatabase.c | 9 +- .../render/intern/source/shadeoutput.c | 47 +++++--- source/blender/render/intern/source/sss.c | 4 +- source/blender/render/intern/source/zbuf.c | 4 +- .../windowmanager/intern/wm_event_system.c | 8 +- .../blender/windowmanager/intern/wm_files.c | 7 +- 47 files changed, 495 insertions(+), 200 deletions(-) diff --git a/build_files/cmake/cmake_static_check_clang_array.py b/build_files/cmake/cmake_static_check_clang_array.py index ff15a130ee0..8afaf0805f2 100644 --- a/build_files/cmake/cmake_static_check_clang_array.py +++ b/build_files/cmake/cmake_static_check_clang_array.py @@ -30,6 +30,7 @@ import os CHECKER_IGNORE_PREFIX = [ "extern", "intern/moto", + "blender/intern/opennl", ] CHECKER_BIN = "python2" diff --git a/build_files/cmake/cmake_static_check_cppcheck.py b/build_files/cmake/cmake_static_check_cppcheck.py index c340ca5c458..4ea357162ca 100644 --- a/build_files/cmake/cmake_static_check_cppcheck.py +++ b/build_files/cmake/cmake_static_check_cppcheck.py @@ -30,6 +30,7 @@ import os CHECKER_IGNORE_PREFIX = [ "extern", "intern/moto", + "blender/intern/opennl", ] CHECKER_BIN = "cppcheck" diff --git a/build_files/cmake/cmake_static_check_smatch.py b/build_files/cmake/cmake_static_check_smatch.py index 779945b030a..eebb2e94f93 100644 --- a/build_files/cmake/cmake_static_check_smatch.py +++ b/build_files/cmake/cmake_static_check_smatch.py @@ -25,6 +25,7 @@ CHECKER_IGNORE_PREFIX = [ "extern", "intern/moto", + "blender/intern/opennl", ] CHECKER_BIN = "smatch" diff --git a/build_files/cmake/cmake_static_check_sparse.py b/build_files/cmake/cmake_static_check_sparse.py index db1b14e7acb..8862fc78bb5 100644 --- a/build_files/cmake/cmake_static_check_sparse.py +++ b/build_files/cmake/cmake_static_check_sparse.py @@ -25,6 +25,7 @@ CHECKER_IGNORE_PREFIX = [ "extern", "intern/moto", + "blender/intern/opennl", ] CHECKER_BIN = "sparse" diff --git a/build_files/cmake/cmake_static_check_splint.py b/build_files/cmake/cmake_static_check_splint.py index f538fa612d0..b753a6122cd 100644 --- a/build_files/cmake/cmake_static_check_splint.py +++ b/build_files/cmake/cmake_static_check_splint.py @@ -25,6 +25,7 @@ CHECKER_IGNORE_PREFIX = [ "extern", "intern/moto", + "blender/intern/opennl", ] CHECKER_BIN = "splint" diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index 99b788e80ce..197e38ac778 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -621,7 +621,9 @@ void BKE_undo_step(bContext *C, int step) } else if (step == 1) { /* curundo should never be NULL, after restart or load file it should call undo_save */ - if (curundo == NULL || curundo->prev == NULL) ; // XXX error("No undo available"); + if (curundo == NULL || curundo->prev == NULL) { + // XXX error("No undo available"); + } else { if (G.debug & G_DEBUG) printf("undo %s\n", curundo->name); curundo = curundo->prev; @@ -631,7 +633,9 @@ void BKE_undo_step(bContext *C, int step) else { /* curundo has to remain current situation! */ - if (curundo == NULL || curundo->next == NULL) ; // XXX error("No redo available"); + if (curundo == NULL || curundo->next == NULL) { + // XXX error("No redo available"); + } else { read_undosave(C, curundo->next); curundo = curundo->next; diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index de55751f2ec..efcc00c401d 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -2866,7 +2866,9 @@ void CustomData_external_reload(CustomData *data, ID *UNUSED(id), CustomDataMask layer = &data->layers[i]; typeInfo = layerType_getInfo(layer->type); - if (!(mask & CD_TYPE_AS_MASK(layer->type))) ; + if (!(mask & CD_TYPE_AS_MASK(layer->type))) { + /* pass */ + } else if ((layer->flag & CD_FLAG_EXTERNAL) && (layer->flag & CD_FLAG_IN_MEMORY)) { if (typeInfo->free) typeInfo->free(layer->data, totelem, typeInfo->size); @@ -2892,10 +2894,15 @@ void CustomData_external_read(CustomData *data, ID *id, CustomDataMask mask, int layer = &data->layers[i]; typeInfo = layerType_getInfo(layer->type); - if (!(mask & CD_TYPE_AS_MASK(layer->type))) ; - else if (layer->flag & CD_FLAG_IN_MEMORY) ; - else if ((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->read) + if (!(mask & CD_TYPE_AS_MASK(layer->type))) { + /* pass */ + } + else if (layer->flag & CD_FLAG_IN_MEMORY) { + /* pass */ + } + else if ((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->read) { update = 1; + } } if (!update) @@ -2913,15 +2920,23 @@ void CustomData_external_read(CustomData *data, ID *id, CustomDataMask mask, int layer = &data->layers[i]; typeInfo = layerType_getInfo(layer->type); - if (!(mask & CD_TYPE_AS_MASK(layer->type))) ; - else if (layer->flag & CD_FLAG_IN_MEMORY) ; + if (!(mask & CD_TYPE_AS_MASK(layer->type))) { + /* pass */ + } + else if (layer->flag & CD_FLAG_IN_MEMORY) { + /* pass */ + } else if ((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->read) { blay = cdf_layer_find(cdf, layer->type, layer->name); if (blay) { if (cdf_read_layer(cdf, blay)) { - if (typeInfo->read(cdf, layer->data, totelem)) ; - else break; + if (typeInfo->read(cdf, layer->data, totelem)) { + /* pass */ + } + else { + break; + } layer->flag |= CD_FLAG_IN_MEMORY; } else @@ -2952,9 +2967,12 @@ void CustomData_external_write(CustomData *data, ID *id, CustomDataMask mask, in layer = &data->layers[i]; typeInfo = layerType_getInfo(layer->type); - if (!(mask & CD_TYPE_AS_MASK(layer->type))) ; - else if ((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->write) + if (!(mask & CD_TYPE_AS_MASK(layer->type))) { + /* pass */ + } + else if ((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->write) { update = 1; + } } if (!update) @@ -2995,11 +3013,16 @@ void CustomData_external_write(CustomData *data, ID *id, CustomDataMask mask, in blay = cdf_layer_find(cdf, layer->type, layer->name); if (cdf_write_layer(cdf, blay)) { - if (typeInfo->write(cdf, layer->data, totelem)) ; - else break; + if (typeInfo->write(cdf, layer->data, totelem)) { + /* pass */ + } + else { + break; + } } - else + else { break; + } } } diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index 64959fd3aa1..10c9f30f5ee 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -299,7 +299,9 @@ static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase, i else resolu = nu->resolu; - if (!BKE_nurb_check_valid_u(nu)) ; + if (!BKE_nurb_check_valid_u(nu)) { + /* pass */ + } else if (nu->type == CU_BEZIER) { /* count */ len = 0; diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c index 8b35974ea62..06b21fbbd29 100644 --- a/source/blender/blenkernel/intern/font.c +++ b/source/blender/blenkernel/intern/font.c @@ -928,8 +928,12 @@ makebreak: * 3: curs down */ ct = chartransdata + cu->pos; - if ((mode == FO_CURSUP || mode == FO_PAGEUP) && ct->linenr == 0) ; - else if ((mode == FO_CURSDOWN || mode == FO_PAGEDOWN) && ct->linenr == lnr) ; + if ((mode == FO_CURSUP || mode == FO_PAGEUP) && ct->linenr == 0) { + /* pass */ + } + else if ((mode == FO_CURSDOWN || mode == FO_PAGEDOWN) && ct->linenr == lnr) { + /* pass */ + } else { switch (mode) { case FO_CURSUP: lnr = ct->linenr - 1; break; diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c index 17e4103c7d3..bb871f0cfd4 100644 --- a/source/blender/blenkernel/intern/lattice.c +++ b/source/blender/blenkernel/intern/lattice.c @@ -879,9 +879,10 @@ void outside_lattice(Lattice *lt) for (v = 0; v < lt->pntsv; v++) { for (u = 0; u < lt->pntsu; u++, bp++) { - if (u == 0 || v == 0 || w == 0 || u == lt->pntsu - 1 || v == lt->pntsv - 1 || w == lt->pntsw - 1) ; + if (u == 0 || v == 0 || w == 0 || u == lt->pntsu - 1 || v == lt->pntsv - 1 || w == lt->pntsw - 1) { + /* pass */ + } else { - bp->hide = 1; bp->f1 &= ~SELECT; diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 28de80a7157..f072ed4009e 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -574,10 +574,12 @@ int modifiers_isCorrectableDeformed(Object *ob) ModifierData *md = modifiers_getVirtualModifierList(ob); for (; md; md = md->next) { - if (ob->mode == OB_MODE_EDIT && (md->mode & eModifierMode_Editmode) == 0) ; - else - if (modifier_isCorrectableDeformed(md)) + if (ob->mode == OB_MODE_EDIT && (md->mode & eModifierMode_Editmode) == 0) { + /* pass */ + } + else if (modifier_isCorrectableDeformed(md)) { return 1; + } } return 0; } diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index e8af794eaea..89dadcd8dd5 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -97,8 +97,8 @@ int count_particles(ParticleSystem *psys) int tot = 0; LOOP_SHOWN_PARTICLES { - if (pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN) == 0) ; - else if (pa->alive == PARS_DEAD && (part->flag & PART_DIED) == 0) ; + if (pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN) == 0) {} + else if (pa->alive == PARS_DEAD && (part->flag & PART_DIED) == 0) {} else tot++; } return tot; @@ -110,8 +110,8 @@ int count_particles_mod(ParticleSystem *psys, int totgr, int cur) int tot = 0; LOOP_SHOWN_PARTICLES { - if (pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN) == 0) ; - else if (pa->alive == PARS_DEAD && (part->flag & PART_DIED) == 0) ; + if (pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN) == 0) {} + else if (pa->alive == PARS_DEAD && (part->flag & PART_DIED) == 0) {} else if (p % totgr == cur) tot++; } return tot; diff --git a/source/blender/blenlib/BLI_endian_switch_inline.h b/source/blender/blenlib/BLI_endian_switch_inline.h index 948d462fde4..6aa0405861e 100644 --- a/source/blender/blenlib/BLI_endian_switch_inline.h +++ b/source/blender/blenlib/BLI_endian_switch_inline.h @@ -74,12 +74,12 @@ BLI_INLINE void BLI_endian_switch_int64(int64_t *val) { int64_t tval = *val; *val = ((tval >> 56)) | - ((tval << 40) & 0x00ff000000000000) | - ((tval << 24) & 0x0000ff0000000000) | - ((tval << 8) & 0x000000ff00000000) | - ((tval >> 8) & 0x00000000ff000000) | - ((tval >> 24) & 0x0000000000ff0000) | - ((tval >> 40) & 0x000000000000ff00) | + ((tval << 40) & 0x00ff000000000000l) | + ((tval << 24) & 0x0000ff0000000000l) | + ((tval << 8) & 0x000000ff00000000l) | + ((tval >> 8) & 0x00000000ff000000l) | + ((tval >> 24) & 0x0000000000ff0000l) | + ((tval >> 40) & 0x000000000000ff00l) | ((tval << 56)); } BLI_INLINE void BLI_endian_switch_uint64(uint64_t *val) diff --git a/source/blender/editors/armature/editarmature.c b/source/blender/editors/armature/editarmature.c index 707594ff590..46bbf6f0683 100644 --- a/source/blender/editors/armature/editarmature.c +++ b/source/blender/editors/armature/editarmature.c @@ -3357,12 +3357,17 @@ static int armature_extrude_exec(bContext *C, wmOperator *op) if (EBONE_VISIBLE(arm, ebone)) { /* we extrude per definition the tip */ do_extrude = FALSE; - if (ebone->flag & (BONE_TIPSEL | BONE_SELECTED)) + if (ebone->flag & (BONE_TIPSEL | BONE_SELECTED)) { do_extrude = TRUE; + } else if (ebone->flag & BONE_ROOTSEL) { /* but, a bone with parent deselected we do the root... */ - if (ebone->parent && (ebone->parent->flag & BONE_TIPSEL)) ; - else do_extrude = 2; + if (ebone->parent && (ebone->parent->flag & BONE_TIPSEL)) { + /* pass */ + } + else { + do_extrude = 2; + } } if (do_extrude) { diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index afd6bc4c4b5..d22b9f2abfb 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -1579,8 +1579,9 @@ static int deleteflagNurb(bContext *C, wmOperator *UNUSED(op), int flag) BPoint *bp, *bpn, *newbp; int a, b, newu, newv, sel; - if (obedit->type == OB_SURF) ; - else return OPERATOR_CANCELLED; + if (obedit->type != OB_SURF) { + return OPERATOR_CANCELLED; + } cu->lastsel = NULL; @@ -1593,8 +1594,12 @@ static int deleteflagNurb(bContext *C, wmOperator *UNUSED(op), int flag) a = nu->pntsu * nu->pntsv; while (a) { a--; - if (bp->f1 & flag) ; - else break; + if (bp->f1 & flag) { + /* pass */ + } + else { + break; + } bp++; } if (a == 0) { @@ -1715,8 +1720,12 @@ static short extrudeflagNurb(EditNurb *editnurb, int flag) bp = nu->bp; a = nu->pntsu; while (a) { - if (bp->f1 & flag) ; - else break; + if (bp->f1 & flag) { + /* pass */ + } + else { + break; + } bp++; a--; } @@ -3762,20 +3771,28 @@ static void merge_2_nurb(wmOperator *op, ListBase *editnurb, Nurb *nu1, Nurb *nu /* first nurbs: u = resolu-1 selected */ - if (is_u_selected(nu1, nu1->pntsu - 1) ) ; + if (is_u_selected(nu1, nu1->pntsu - 1) ) { + /* pass */ + } else { /* For 2D curves blender uses (orderv = 0). It doesn't make any sense mathematically. */ /* but after rotating (orderu = 0) will be confusing. */ if (nu1->orderv == 0) nu1->orderv = 1; rotate_direction_nurb(nu1); - if (is_u_selected(nu1, nu1->pntsu - 1)) ; + if (is_u_selected(nu1, nu1->pntsu - 1)) { + /* pass */ + } else { rotate_direction_nurb(nu1); - if (is_u_selected(nu1, nu1->pntsu - 1)) ; + if (is_u_selected(nu1, nu1->pntsu - 1)) { + /* pass */ + } else { rotate_direction_nurb(nu1); - if (is_u_selected(nu1, nu1->pntsu - 1)) ; + if (is_u_selected(nu1, nu1->pntsu - 1)) { + /* pass */ + } else { /* rotate again, now its OK! */ if (nu1->pntsv != 1) rotate_direction_nurb(nu1); @@ -3786,17 +3803,25 @@ static void merge_2_nurb(wmOperator *op, ListBase *editnurb, Nurb *nu1, Nurb *nu } /* 2nd nurbs: u = 0 selected */ - if (is_u_selected(nu2, 0) ) ; + if (is_u_selected(nu2, 0) ) { + /* pass */ + } else { if (nu2->orderv == 0) nu2->orderv = 1; rotate_direction_nurb(nu2); - if (is_u_selected(nu2, 0)) ; + if (is_u_selected(nu2, 0)) { + /* pass */ + } else { rotate_direction_nurb(nu2); - if (is_u_selected(nu2, 0)) ; + if (is_u_selected(nu2, 0)) { + /* pass */ + } else { rotate_direction_nurb(nu2); - if (is_u_selected(nu2, 0)) ; + if (is_u_selected(nu2, 0)) { + /* pass */ + } else { /* rotate again, now its OK! */ if (nu1->pntsu == 1) rotate_direction_nurb(nu1); @@ -3892,15 +3917,27 @@ static int merge_nurb(bContext *C, wmOperator *op) /* resolution match, to avoid uv rotations */ if (nus1->nu->pntsv == 1) { - if (nus1->nu->pntsu == nus2->nu->pntsu || nus1->nu->pntsu == nus2->nu->pntsv) ; - else ok = 0; + if (nus1->nu->pntsu == nus2->nu->pntsu || nus1->nu->pntsu == nus2->nu->pntsv) { + /* pass */ + } + else { + ok = 0; + } } else if (nus2->nu->pntsv == 1) { - if (nus2->nu->pntsu == nus1->nu->pntsu || nus2->nu->pntsu == nus1->nu->pntsv) ; - else ok = 0; + if (nus2->nu->pntsu == nus1->nu->pntsu || nus2->nu->pntsu == nus1->nu->pntsv) { + /* pass */ + } + else { + ok = 0; + } + } + else if (nus1->nu->pntsu == nus2->nu->pntsu || nus1->nu->pntsv == nus2->nu->pntsv) { + /* pass */ + } + else if (nus1->nu->pntsu == nus2->nu->pntsv || nus1->nu->pntsv == nus2->nu->pntsu) { + /* pass */ } - else if (nus1->nu->pntsu == nus2->nu->pntsu || nus1->nu->pntsv == nus2->nu->pntsv) ; - else if (nus1->nu->pntsu == nus2->nu->pntsv || nus1->nu->pntsv == nus2->nu->pntsu) ; else { ok = 0; } @@ -3949,8 +3986,12 @@ static int make_segment_exec(bContext *C, wmOperator *op) if (isNurbsel_count(cu, nu) == 1) { /* only 1 selected, not first or last, a little complex, but intuitive */ if (nu->pntsv == 1) { - if ( (nu->bp->f1 & SELECT) || (nu->bp[nu->pntsu - 1].f1 & SELECT)) ; - else break; + if ( (nu->bp->f1 & SELECT) || (nu->bp[nu->pntsu - 1].f1 & SELECT)) { + /* pass */ + } + else { + break; + } } } } @@ -5684,8 +5725,12 @@ static int delete_exec(bContext *C, wmOperator *op) a = nu->pntsu; if (a) { while (a) { - if (BEZSELECTED_HIDDENHANDLES(cu, bezt) ) ; - else break; + if (BEZSELECTED_HIDDENHANDLES(cu, bezt)) { + /* pass */ + } + else { + break; + } a--; bezt++; } @@ -5704,8 +5749,12 @@ static int delete_exec(bContext *C, wmOperator *op) a = nu->pntsu * nu->pntsv; if (a) { while (a) { - if (bp->f1 & SELECT) ; - else break; + if (bp->f1 & SELECT) { + /* pass */ + } + else { + break; + } a--; bp++; } diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 2c00e39766c..df18498559e 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -1152,9 +1152,15 @@ static void ui_is_but_sel(uiBut *but, double *value) } } - if (is_push == 2) ; - else if (is_push == 1) but->flag |= UI_SELECT; - else but->flag &= ~UI_SELECT; + if (is_push == 2) { + /* pass */ + } + else if (is_push == 1) { + but->flag |= UI_SELECT; + } + else { + but->flag &= ~UI_SELECT; + } } static uiBut *ui_find_inlink(uiBlock *block, void *poin) diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 60e4c2aa90f..f798f0b399b 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -704,7 +704,9 @@ static int ui_but_mouse_inside_icon(uiBut *but, ARegion *ar, wmEvent *event) BLI_rcti_rctf_copy(&rect, &but->rect); - if (but->imb) ; /* use button size itself */ + if (but->imb) { + /* use button size itself */ + } else if (but->flag & UI_ICON_LEFT) { rect.xmax = rect.xmin + (BLI_rcti_size_y(&rect)); } @@ -1184,7 +1186,9 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data, /* numeric value */ if (ELEM4(but->type, NUM, NUMABS, NUMSLI, HSVSLI)) { - if (but->poin == NULL && but->rnapoin.data == NULL) ; + if (but->poin == NULL && but->rnapoin.data == NULL) { + /* pass */ + } else if (mode == 'c') { ui_get_but_string(but, buf, sizeof(buf)); WM_clipboard_text_set(buf, 0); @@ -1205,7 +1209,9 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data, else if (but->type == COLOR) { float rgb[3]; - if (but->poin == NULL && but->rnapoin.data == NULL) ; + if (but->poin == NULL && but->rnapoin.data == NULL) { + /* pass */ + } else if (mode == 'c') { ui_get_but_vectorf(but, rgb); @@ -1234,7 +1240,9 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data, else if (ELEM3(but->type, TEX, IDPOIN, SEARCH_MENU)) { uiHandleButtonData *active_data = but->active; - if (but->poin == NULL && but->rnapoin.data == NULL) ; + if (but->poin == NULL && but->rnapoin.data == NULL) { + /* pass */ + } else if (mode == 'c') { button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING); BLI_strncpy(buf, active_data->str, UI_MAX_DRAW_STR); @@ -2297,7 +2305,9 @@ static int ui_do_but_TEX(bContext *C, uiBlock *block, uiBut *but, uiHandleButton { if (data->state == BUTTON_STATE_HIGHLIGHT) { if (ELEM(event->type, LEFTMOUSE, EVT_BUT_OPEN) && event->val == KM_PRESS) { - if (but->dt == UI_EMBOSSN && !event->ctrl) ; + if (but->dt == UI_EMBOSSN && !event->ctrl) { + /* pass */ + } else { button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING); return WM_UI_HANDLER_BREAK; diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index d692bf8e492..8e30b31f3fe 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -2516,8 +2516,12 @@ static void ui_item_align(uiLayout *litem, short nr) if (!bitem->but->alignnr) bitem->but->alignnr = nr; } - else if (item->type == ITEM_LAYOUT_ABSOLUTE) ; - else if (item->type == ITEM_LAYOUT_OVERLAP) ; + else if (item->type == ITEM_LAYOUT_ABSOLUTE) { + /* pass */ + } + else if (item->type == ITEM_LAYOUT_OVERLAP) { + /* pass */ + } else if (item->type == ITEM_LAYOUT_BOX) { box = (uiLayoutItemBx *)item; box->roundbox->alignnr = nr; diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index 3fc20309264..0e1fd87c985 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -891,8 +891,8 @@ static void widget_draw_icon(uiBut *but, BIFIconID icon, float alpha, rcti *rect /* calculate blend color */ if (ELEM4(but->type, TOG, ROW, TOGN, LISTROW)) { - if (but->flag & UI_SELECT) ; - else if (but->flag & UI_ACTIVE) ; + if (but->flag & UI_SELECT) {} + else if (but->flag & UI_ACTIVE) {} else alpha = 0.5f; } diff --git a/source/blender/editors/mesh/editface.c b/source/blender/editors/mesh/editface.c index 5fd848ccb13..429b2148894 100644 --- a/source/blender/editors/mesh/editface.c +++ b/source/blender/editors/mesh/editface.c @@ -214,7 +214,9 @@ static void select_linked_tfaces_with_seams(int mode, Mesh *me, unsigned int ind /* fill array by selection */ mp = me->mpoly; for (a = 0; a < me->totpoly; a++, mp++) { - if (mp->flag & ME_HIDE) ; + if (mp->flag & ME_HIDE) { + /* pass */ + } else if (mp->flag & ME_FACE_SEL) { hash_add_face(ehash, mp, me->mloop + mp->loopstart); linkflag[a] = 1; @@ -572,7 +574,9 @@ int do_paintface_box_select(ViewContext *vc, rcti *rect, int select, int extend) mpoly = me->mpoly; for (a = 1; a <= me->totpoly; a++, mpoly++) { if (selar[a]) { - if (mpoly->flag & ME_HIDE) ; + if (mpoly->flag & ME_HIDE) { + /* pass */ + } else { if (select) mpoly->flag |= ME_FACE_SEL; else mpoly->flag &= ~ME_FACE_SEL; diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c index ee2b5e08520..dc490c94b38 100644 --- a/source/blender/editors/physics/particle_edit.c +++ b/source/blender/editors/physics/particle_edit.c @@ -3989,7 +3989,9 @@ void PE_undo_step(Scene *scene, int step) } else if (step==1) { - if (edit->curundo==NULL || edit->curundo->prev==NULL); + if (edit->curundo==NULL || edit->curundo->prev==NULL) { + /* pass */ + } else { if (G.debug & G_DEBUG) printf("undo %s\n", edit->curundo->name); edit->curundo= edit->curundo->prev; @@ -3999,7 +4001,9 @@ void PE_undo_step(Scene *scene, int step) else { /* curundo has to remain current situation! */ - if (edit->curundo==NULL || edit->curundo->next==NULL); + if (edit->curundo==NULL || edit->curundo->next==NULL) { + /* pass */ + } else { get_PTCacheUndo(edit, edit->curundo->next); edit->curundo= edit->curundo->next; diff --git a/source/blender/editors/render/render_update.c b/source/blender/editors/render/render_update.c index 08ccf37265b..cd55b91cb6b 100644 --- a/source/blender/editors/render/render_update.c +++ b/source/blender/editors/render/render_update.c @@ -224,8 +224,12 @@ static void material_changed(Main *bmain, Material *ma) /* find node materials using this */ for (parent = bmain->mat.first; parent; parent = parent->id.next) { - if (parent->use_nodes && parent->nodetree && nodes_use_material(parent->nodetree, ma)) ; - else continue; + if (parent->use_nodes && parent->nodetree && nodes_use_material(parent->nodetree, ma)) { + /* pass */ + } + else { + continue; + } BKE_icon_changed(BKE_icon_getid(&parent->id)); @@ -247,9 +251,15 @@ static void texture_changed(Main *bmain, Tex *tex) /* find materials */ for (ma = bmain->mat.first; ma; ma = ma->id.next) { - if (mtex_use_tex(ma->mtex, MAX_MTEX, tex)) ; - else if (ma->use_nodes && ma->nodetree && nodes_use_tex(ma->nodetree, tex)) ; - else continue; + if (mtex_use_tex(ma->mtex, MAX_MTEX, tex)) { + /* pass */ + } + else if (ma->use_nodes && ma->nodetree && nodes_use_tex(ma->nodetree, tex)) { + /* pass */ + } + else { + continue; + } BKE_icon_changed(BKE_icon_getid(&ma->id)); @@ -259,18 +269,30 @@ static void texture_changed(Main *bmain, Tex *tex) /* find lamps */ for (la = bmain->lamp.first; la; la = la->id.next) { - if (mtex_use_tex(la->mtex, MAX_MTEX, tex)) ; - else if (la->nodetree && nodes_use_tex(la->nodetree, tex)) ; - else continue; + if (mtex_use_tex(la->mtex, MAX_MTEX, tex)) { + /* pass */ + } + else if (la->nodetree && nodes_use_tex(la->nodetree, tex)) { + /* pass */ + } + else { + continue; + } BKE_icon_changed(BKE_icon_getid(&la->id)); } /* find worlds */ for (wo = bmain->world.first; wo; wo = wo->id.next) { - if (mtex_use_tex(wo->mtex, MAX_MTEX, tex)) ; - else if (wo->nodetree && nodes_use_tex(wo->nodetree, tex)) ; - else continue; + if (mtex_use_tex(wo->mtex, MAX_MTEX, tex)) { + /* pass */ + } + else if (wo->nodetree && nodes_use_tex(wo->nodetree, tex)) { + /* pass */ + } + else { + continue; + } BKE_icon_changed(BKE_icon_getid(&wo->id)); } diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index 01a5304451a..7c377a041e7 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -407,8 +407,12 @@ void region_scissor_winrct(ARegion *ar, rcti *winrct) ar = ar->prev; if (BLI_rcti_isect(winrct, &ar->winrct, NULL)) { - if (ar->flag & RGN_FLAG_HIDDEN) ; - else if (ar->alignment & RGN_SPLIT_PREV) ; + if (ar->flag & RGN_FLAG_HIDDEN) { + /* pass */ + } + else if (ar->alignment & RGN_SPLIT_PREV) { + /* pass */ + } else if (ar->alignment == RGN_OVERLAP_LEFT) { winrct->xmin = ar->winrct.xmax + 1; } @@ -935,20 +939,25 @@ static void region_rect_recursive(ScrArea *sa, ARegion *ar, rcti *remainder, int /* prefsize, for header we stick to exception */ prefsizex = ar->sizex ? ar->sizex : ar->type->prefsizex; - if (ar->regiontype == RGN_TYPE_HEADER) + if (ar->regiontype == RGN_TYPE_HEADER) { prefsizey = ar->type->prefsizey; + } else if (ar->regiontype == RGN_TYPE_UI && sa->spacetype == SPACE_FILE) { prefsizey = UI_UNIT_Y * 2 + (UI_UNIT_Y / 2); } - else + else { prefsizey = ar->sizey ? ar->sizey : ar->type->prefsizey; - - /* hidden is user flag */ - if (ar->flag & RGN_FLAG_HIDDEN) ; - /* XXX floating area region, not handled yet here */ - else if (alignment == RGN_ALIGN_FLOAT) ; - /* remainder is too small for any usage */ + } + + + if (ar->flag & RGN_FLAG_HIDDEN) { + /* hidden is user flag */ + } + else if (alignment == RGN_ALIGN_FLOAT) { + /* XXX floating area region, not handled yet here */ + } else if (rct_fits(remainder, 'v', 1) < 0 || rct_fits(remainder, 'h', 1) < 0) { + /* remainder is too small for any usage */ ar->flag |= RGN_FLAG_TOO_SMALL; } else if (alignment == RGN_ALIGN_NONE) { diff --git a/source/blender/editors/sculpt_paint/paint_undo.c b/source/blender/editors/sculpt_paint/paint_undo.c index f5b9aa742c6..e406d4f5c3b 100644 --- a/source/blender/editors/sculpt_paint/paint_undo.c +++ b/source/blender/editors/sculpt_paint/paint_undo.c @@ -152,7 +152,9 @@ static int undo_stack_step(bContext *C, UndoStack *stack, int step, const char * UndoElem *undo; if (step == 1) { - if (stack->current == NULL) ; + if (stack->current == NULL) { + /* pass */ + } else { if (!name || strcmp(stack->current->name, name) == 0) { if (G.debug & G_DEBUG_WM) { @@ -165,7 +167,9 @@ static int undo_stack_step(bContext *C, UndoStack *stack, int step, const char * } } else if (step == -1) { - if ((stack->current != NULL && stack->current->next == NULL) || stack->elems.first == NULL) ; + if ((stack->current != NULL && stack->current->next == NULL) || stack->elems.first == NULL) { + /* pass */ + } else { if (!name || strcmp(stack->current->name, name) == 0) { undo = (stack->current && stack->current->next) ? stack->current->next : stack->elems.first; @@ -254,7 +258,9 @@ int ED_undo_paint_valid(int type, const char *name) else return 0; - if (stack->current == NULL) ; + if (stack->current == NULL) { + /* pass */ + } else { if (name && strcmp(stack->current->name, name) == 0) return 1; diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c index d3b4df05aa9..ce522ec7e3f 100644 --- a/source/blender/editors/space_file/filelist.c +++ b/source/blender/editors/space_file/filelist.c @@ -748,7 +748,9 @@ static int file_is_blend_backup(const char *str) a = strlen(str); b = 7; - if (a == 0 || b >= a) ; + if (a == 0 || b >= a) { + /* pass */ + } else { char *loc; diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c index 31cb6d91889..7f53f378042 100644 --- a/source/blender/editors/space_image/space_image.c +++ b/source/blender/editors/space_image/space_image.c @@ -414,8 +414,9 @@ static void image_refresh(const bContext *C, ScrArea *sa) /* don't need to check for pin here, see above */ sima->image = tf->tpage; - if (sima->flag & SI_EDITTILE) ; - else sima->curtile = tf->tile; + if ((sima->flag & SI_EDITTILE) == 0) { + sima->curtile = tf->tile; + } } } } diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c index a05588495e9..e8aa01af6b2 100644 --- a/source/blender/editors/space_outliner/outliner_draw.c +++ b/source/blender/editors/space_outliner/outliner_draw.c @@ -783,7 +783,9 @@ static void outliner_draw_keymapbuts(uiBlock *block, ARegion *ar, SpaceOops *soo wmKeyMapItem *kmi = te->directdata; /* modal map? */ - if (kmi->propvalue) ; + if (kmi->propvalue) { + /* pass */ + } else { uiDefBlockBut(block, operator_search_menu, kmi, "", xstart, (int)te->ys + 1, butw1, UI_UNIT_Y - 1, "Assign new Operator"); } @@ -1409,11 +1411,15 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene /* closed item, we draw the icons, not when it's a scene, or master-server list though */ if (!TSELEM_OPEN(tselem, soops)) { if (te->subtree.first) { - if (tselem->type == 0 && te->idcode == ID_SCE) ; - else if (tselem->type != TSE_R_LAYER) { /* this tree element always has same amount of branches, so don't draw */ + if (tselem->type == 0 && te->idcode == ID_SCE) { + /* pass */ + } + else if (tselem->type != TSE_R_LAYER) { + /* this tree element always has same amount of branches, so don't draw */ + int tempx = startx + offsx; - // divider + /* divider */ UI_ThemeColorShade(TH_BACK, -40); glRecti(tempx - 10, *starty + 4, tempx - 8, *starty + UI_UNIT_Y - 4); diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c index 3e1ce1fea6e..ef0542130ea 100644 --- a/source/blender/editors/space_outliner/outliner_tree.c +++ b/source/blender/editors/space_outliner/outliner_tree.c @@ -769,7 +769,9 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor else { /* do not extend Armature when we have posemode */ tselem = TREESTORE(te->parent); - if (GS(tselem->id->name) == ID_OB && ((Object *)tselem->id)->mode & OB_MODE_POSE) ; + if (GS(tselem->id->name) == ID_OB && ((Object *)tselem->id)->mode & OB_MODE_POSE) { + /* pass */ + } else { Bone *curBone; for (curBone = arm->bonebase.first; curBone; curBone = curBone->next) { @@ -811,9 +813,15 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i te->parent = parent; te->index = index; // for data arays - if (ELEM3(type, TSE_SEQUENCE, TSE_SEQ_STRIP, TSE_SEQUENCE_DUP)) ; - else if (ELEM3(type, TSE_RNA_STRUCT, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM)) ; - else if (type == TSE_ANIM_DATA) ; + if (ELEM3(type, TSE_SEQUENCE, TSE_SEQ_STRIP, TSE_SEQUENCE_DUP)) { + /* pass */ + } + else if (ELEM3(type, TSE_RNA_STRUCT, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM)) { + /* pass */ + } + else if (type == TSE_ANIM_DATA) { + /* pass */ + } else { te->name = id->name + 2; // default, can be overridden by Library or non-ID data te->idcode = GS(id->name); @@ -1055,8 +1063,12 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i if (key[0]) { wmOperatorType *ot = NULL; - if (kmi->propvalue) ; - else ot = WM_operatortype_find(kmi->idname, 0); + if (kmi->propvalue) { + /* pass */ + } + else { + ot = WM_operatortype_find(kmi->idname, 0); + } if (ot || kmi->propvalue) { TreeElement *ten = outliner_add_element(soops, &te->subtree, kmi, te, TSE_KEYMAP_ITEM, a); diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index 204930e82a6..459a8d54d12 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -579,7 +579,9 @@ static Sequence *del_seq_find_replace_recurs(Scene *scene, Sequence *seq) seq2 = del_seq_find_replace_recurs(scene, seq->seq2); seq3 = del_seq_find_replace_recurs(scene, seq->seq3); - if (seq1 == seq->seq1 && seq2 == seq->seq2 && seq3 == seq->seq3) ; + if (seq1 == seq->seq1 && seq2 == seq->seq2 && seq3 == seq->seq3) { + /* pass */ + } else if (seq1 || seq2 || seq3) { seq->seq1 = (seq1) ? seq1 : (seq2) ? seq2 : seq3; seq->seq2 = (seq2) ? seq2 : (seq1) ? seq1 : seq3; diff --git a/source/blender/editors/space_view3d/drawarmature.c b/source/blender/editors/space_view3d/drawarmature.c index ecce12b8cba..31df13343ce 100644 --- a/source/blender/editors/space_view3d/drawarmature.c +++ b/source/blender/editors/space_view3d/drawarmature.c @@ -2226,9 +2226,16 @@ static void draw_ebones(View3D *v3d, ARegion *ar, Object *ob, const short dt) } /* restore */ - if (index != -1) glLoadName(-1); - if (ELEM(arm->drawtype, ARM_LINE, ARM_WIRE)) ; - else if (dt > OB_WIRE) bglPolygonOffset(rv3d->dist, 0.0f); + if (index != -1) { + glLoadName(-1); + } + + if (ELEM(arm->drawtype, ARM_LINE, ARM_WIRE)) { + /* pass */ + } + else if (dt > OB_WIRE) { + bglPolygonOffset(rv3d->dist, 0.0f); + } /* finally names and axes */ if (arm->flag & (ARM_DRAWNAMES | ARM_DRAWAXES)) { diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index ca768f2ef17..00d35a5d2e1 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -355,7 +355,9 @@ static void drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, const char ** if (dx < GRID_MIN_PX_D) { rv3d->gridview *= sublines; dx *= sublines; - if (dx < GRID_MIN_PX_D) ; + if (dx < GRID_MIN_PX_D) { + /* pass */ + } else { UI_ThemeColor(TH_GRID); drawgrid_draw(ar, wx, wy, x, y, dx); diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 39a5da94798..2e9d1ee670f 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -3986,13 +3986,13 @@ static void SeqTransInfo(TransInfo *t, Sequence *seq, int *recursive, int *count *flag = (seq->flag | SELECT) & ~(SEQ_LEFTSEL | SEQ_RIGHTSEL); if (t->frame_side == 'R') { - if (right <= cfra) *count = *flag = 0; /* ignore */ - else if (left > cfra) ; /* keep the selection */ + if (right <= cfra) { *count = *flag = 0; } /* ignore */ + else if (left > cfra) { } /* keep the selection */ else *flag |= SEQ_RIGHTSEL; } else { - if (left >= cfra) *count = *flag = 0; /* ignore */ - else if (right < cfra) ; /* keep the selection */ + if (left >= cfra) { *count = *flag = 0; } /* ignore */ + else if (right < cfra) { } /* keep the selection */ else *flag |= SEQ_LEFTSEL; } } diff --git a/source/blender/makesdna/intern/makesdna.c b/source/blender/makesdna/intern/makesdna.c index 494cb875169..079f2768352 100644 --- a/source/blender/makesdna/intern/makesdna.c +++ b/source/blender/makesdna/intern/makesdna.c @@ -485,11 +485,15 @@ static int preprocess_include(char *maindata, int len) } /* do not copy when: */ - if (comment) ; - else if (cp[0] == ' ' && cp[1] == ' ') ; - else if (cp[-1] == '*' && cp[0] == ' ') ; /* pointers with a space */ - - /* skip special keywords */ + if (comment) { + /* pass */ + } + else if (cp[0] == ' ' && cp[1] == ' ') { + /* pass */ + } + else if (cp[-1] == '*' && cp[0] == ' ') { + /* pointers with a space */ + } /* skip special keywords */ else if (strncmp("DNA_DEPRECATED", cp, 14) == 0) { /* single values are skipped already, so decrement 1 less */ a -= 13; @@ -1028,7 +1032,9 @@ static int make_structDNA(char *baseDirectory, FILE *file) if (debugSDNA > -1) printf("Writing file ... "); - if (nr_names == 0 || nr_structs == 0) ; + if (nr_names == 0 || nr_structs == 0) { + /* pass */ + } else { strcpy(str, "SDNA"); dna_write(file, str, 4); diff --git a/source/blender/nodes/texture/nodes/node_texture_output.c b/source/blender/nodes/texture/nodes/node_texture_output.c index ce22bc00a55..fdd3b97ad59 100644 --- a/source/blender/nodes/texture/nodes/node_texture_output.c +++ b/source/blender/nodes/texture/nodes/node_texture_output.c @@ -65,7 +65,7 @@ static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **UNUSED(o tex_input_rgba(&target->tr, in[0], ¶ms, cdata->thread); target->tin = (target->tr + target->tg + target->tb) / 3.0f; - target->talpha = 1; + target->talpha = TRUE; if (target->nor) { if (in[1] && in[1]->hasinput) diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index b3948563a87..46ab3aeb21f 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -4106,8 +4106,12 @@ static void set_fullsample_trace_flag(Render *re, ObjectRen *obr) vlr->flag |= R_FULL_OSA; } else if (trace) { - if (mode & MA_SHLESS); - else if (vlr->mat->material_type == MA_TYPE_VOLUME); + if (mode & MA_SHLESS) { + /* pass */ + } + else if (vlr->mat->material_type == MA_TYPE_VOLUME) { + /* pass */ + } else if ((mode & MA_RAYMIRROR) || ((mode & MA_TRANSP) && (mode & MA_RAYTRANSP))) { /* for blurry reflect/refract, better to take more samples * inside the raytrace than as OSA samples */ diff --git a/source/blender/render/intern/source/imagetexture.c b/source/blender/render/intern/source/imagetexture.c index 6c86f2a2999..154292a3065 100644 --- a/source/blender/render/intern/source/imagetexture.c +++ b/source/blender/render/intern/source/imagetexture.c @@ -150,8 +150,13 @@ int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], TexResul fx-= xs; fy-= ys; - if ( (tex->flag & TEX_CHECKER_ODD)==0) { - if ((xs+ys) & 1);else return retval; + if ( (tex->flag & TEX_CHECKER_ODD) == 0) { + if ((xs + ys) & 1) { + /* pass */ + } + else { + return retval; + } } if ( (tex->flag & TEX_CHECKER_EVEN)==0) { if ((xs+ys) & 1) return retval; @@ -474,7 +479,9 @@ static void boxsampleclip(struct ImBuf *ibuf, rctf *rf, TexResult *texres) muly= 1.0; - if (starty==endy); + if (starty==endy) { + /* pass */ + } else { if (y==starty) muly= 1.0f-(rf->ymin - y); if (y==endy) muly= (rf->ymax - y); @@ -1453,8 +1460,12 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const image_mipmap_test(tex, ibuf); if (tex->imaflag & TEX_USEALPHA) { - if (tex->imaflag & TEX_CALCALPHA); - else texres->talpha= 1; + if (tex->imaflag & TEX_CALCALPHA) { + /* pass */ + } + else { + texres->talpha = TRUE; + } } texr.talpha= texres->talpha; @@ -1550,11 +1561,17 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const if (boundary==0) { if ( (tex->flag & TEX_CHECKER_ODD)==0) { - if ((xs+ys) & 1); - else return retval; + if ((xs + ys) & 1) { + /* pass */ + } + else { + return retval; + } } if ( (tex->flag & TEX_CHECKER_EVEN)==0) { - if ((xs+ys) & 1) return retval; + if ((xs + ys) & 1) { + return retval; + } } fx-= xs; fy-= ys; diff --git a/source/blender/render/intern/source/occlusion.c b/source/blender/render/intern/source/occlusion.c index af774c5be73..895c5d6c8fb 100644 --- a/source/blender/render/intern/source/occlusion.c +++ b/source/blender/render/intern/source/occlusion.c @@ -625,9 +625,12 @@ static void occ_build_sh_normalize(OccNode *node) sh_mul(node->sh, 1.0f / node->area); for (b = 0; b < TOTCHILD; b++) { - if (node->childflag & (1 << b)) ; - else if (node->child[b].node) + if (node->childflag & (1 << b)) { + /* pass */ + } + else if (node->child[b].node) { occ_build_sh_normalize(node->child[b].node); + } } } diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index b1b88fc9fd5..b64a6b85ef7 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -505,7 +505,9 @@ void RE_InitState(Render *re, Render *source, RenderData *rd, SceneRenderLayer * BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); if (re->r.scemode & R_PREVIEWBUTS) { - if (re->result && re->result->rectx == re->rectx && re->result->recty == re->recty) ; + if (re->result && re->result->rectx == re->rectx && re->result->recty == re->recty) { + /* pass */ + } else { render_result_free(re->result); re->result = NULL; @@ -654,8 +656,12 @@ static void *do_part_thread(void *pa_v) } else if (render_display_draw_enabled(&R)) { /* on break, don't merge in result for preview renders, looks nicer */ - if (R.test_break(R.tbh) && (R.r.scemode & R_PREVIEWBUTS)) ; - else render_result_merge(R.result, pa->result); + if (R.test_break(R.tbh) && (R.r.scemode & R_PREVIEWBUTS)) { + /* pass */ + } + else { + render_result_merge(R.result, pa->result); + } } } diff --git a/source/blender/render/intern/source/pointdensity.c b/source/blender/render/intern/source/pointdensity.c index 49c2bf1d053..a93dde7e813 100644 --- a/source/blender/render/intern/source/pointdensity.c +++ b/source/blender/render/intern/source/pointdensity.c @@ -481,7 +481,7 @@ int pointdensitytex(Tex *tex, float *texvec, TexResult *texres) case TEX_PD_COLOR_PARTAGE: if (pd->coba) { if (do_colorband(pd->coba, age, col)) { - texres->talpha= 1; + texres->talpha = TRUE; copy_v3_v3(&texres->tr, col); texres->tin *= col[3]; texres->ta = texres->tin; @@ -494,7 +494,7 @@ int pointdensitytex(Tex *tex, float *texvec, TexResult *texres) if (pd->coba) { if (do_colorband(pd->coba, speed, col)) { - texres->talpha= 1; + texres->talpha = TRUE; copy_v3_v3(&texres->tr, col); texres->tin *= col[3]; texres->ta = texres->tin; @@ -503,7 +503,7 @@ int pointdensitytex(Tex *tex, float *texvec, TexResult *texres) break; } case TEX_PD_COLOR_PARTVEL: - texres->talpha= 1; + texres->talpha = TRUE; mul_v3_fl(vec, pd->speed_scale); copy_v3_v3(&texres->tr, vec); texres->ta = texres->tin; diff --git a/source/blender/render/intern/source/render_texture.c b/source/blender/render/intern/source/render_texture.c index 982f7e7d824..0511b03b42d 100644 --- a/source/blender/render/intern/source/render_texture.c +++ b/source/blender/render/intern/source/render_texture.c @@ -887,12 +887,12 @@ static void do_2d_mapping(MTex *mtex, float *t, VlakRen *vlr, const float n[3], fx = (t[0] + 1.0f) / 2.0f; fy = (t[1] + 1.0f) / 2.0f; } - else if (wrap==MTEX_TUBE) map_to_tube( &fx, &fy, t[0], t[1], t[2]); - else if (wrap==MTEX_SPHERE) map_to_sphere(&fx, &fy, t[0], t[1], t[2]); + else if (wrap == MTEX_TUBE) map_to_tube( &fx, &fy, t[0], t[1], t[2]); + else if (wrap == MTEX_SPHERE) map_to_sphere(&fx, &fy, t[0], t[1], t[2]); else { - if (texco==TEXCO_OBJECT) cubemap_ob(ob, n, t[0], t[1], t[2], &fx, &fy); - else if (texco==TEXCO_GLOB) cubemap_glob(n, t[0], t[1], t[2], &fx, &fy); - else cubemap(mtex, vlr, n, t[0], t[1], t[2], &fx, &fy); + if (texco == TEXCO_OBJECT) cubemap_ob(ob, n, t[0], t[1], t[2], &fx, &fy); + else if (texco == TEXCO_GLOB) cubemap_glob(n, t[0], t[1], t[2], &fx, &fy); + else cubemap(mtex, vlr, n, t[0], t[1], t[2], &fx, &fy); } /* repeat */ @@ -953,10 +953,17 @@ static void do_2d_mapping(MTex *mtex, float *t, VlakRen *vlr, const float n[3], if (t[1]<=0.0f) { fx= t[0]+dxt[0]; fy= t[0]+dyt[0]; - if (fx>=0.0f && fy>=0.0f && t[0]>=0.0f); - else if (fx<=0.0f && fy<=0.0f && t[0]<=0.0f); - else ok= 0; + if (fx>=0.0f && fy>=0.0f && t[0]>=0.0f) { + /* pass */ + } + else if (fx<=0.0f && fy<=0.0f && t[0]<=0.0f) { + /* pass */ + } + else { + ok = 0; + } } + if (ok) { if (wrap==MTEX_TUBE) { map_to_tube(area, area+1, t[0], t[1], t[2]); @@ -1096,7 +1103,7 @@ static int multitex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, float tmpvec[3]; int retval=0; /* return value, int:0, col:1, nor:2, everything:3 */ - texres->talpha= 0; /* is set when image texture returns alpha (considered premul) */ + texres->talpha = FALSE; /* is set when image texture returns alpha (considered premul) */ if (tex->use_nodes && tex->nodetree) { retval = ntreeTexExecTree(tex->nodetree, texres, texvec, dxt, dyt, osatex, thread, @@ -1193,7 +1200,7 @@ static int multitex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, if (tex->flag & TEX_COLORBAND) { float col[4]; if (do_colorband(tex->coba, texres->tin, col)) { - texres->talpha= 1; + texres->talpha = TRUE; texres->tr= col[0]; texres->tg= col[1]; texres->tb= col[2]; @@ -2445,7 +2452,9 @@ void do_material_tex(ShadeInput *shi, Render *re) copy_v3_v3(nor, texres.nor); - if (mtex->normapspace == MTEX_NSPACE_CAMERA); + if (mtex->normapspace == MTEX_NSPACE_CAMERA) { + /* pass */ + } else if (mtex->normapspace == MTEX_NSPACE_WORLD) { mul_mat3_m4_v3(re->viewmat, nor); } @@ -2922,10 +2931,14 @@ void do_halo_tex(HaloRen *har, float xn, float yn, float col_r[4]) } if (mtex->mapto & MAP_ALPHA) { if (rgb) { - if (texres.talpha) texres.tin= texres.ta; - else texres.tin = rgb_to_bw(&texres.tr); + if (texres.talpha) { + texres.tin = texres.ta; + } + else { + texres.tin = rgb_to_bw(&texres.tr); + } } - + col_r[3]*= texres.tin; } } diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c index 0d894073cee..285cd02c4ff 100644 --- a/source/blender/render/intern/source/rendercore.c +++ b/source/blender/render/intern/source/rendercore.c @@ -271,16 +271,26 @@ static void halo_tile(RenderPart *pa, RenderLayer *rl) har= R.sortedhalos[a]; /* layer test, clip halo with y */ - if ((har->lay & lay)==0); - else if (testrect.ymin > har->maxy); - else if (testrect.ymax < har->miny); + if ((har->lay & lay) == 0) { + /* pass */ + } + else if (testrect.ymin > har->maxy) { + /* pass */ + } + else if (testrect.ymax < har->miny) { + /* pass */ + } else { minx= floor(har->xs-har->rad); maxx= ceil(har->xs+har->rad); - if (testrect.xmin > maxx); - else if (testrect.xmax < minx); + if (testrect.xmin > maxx) { + /* pass */ + } + else if (testrect.xmax < minx) { + /* pass */ + } else { minx= MAX2(minx, testrect.xmin); @@ -980,7 +990,9 @@ static void convert_to_key_alpha(RenderPart *pa, RenderLayer *rl) float *rectf= rlpp[sample]->rectf; for (y= pa->rectx*pa->recty; y>0; y--, rectf+=4) { - if (rectf[3] >= 1.0f); + if (rectf[3] >= 1.0f) { + /* pass */ + } else if (rectf[3] > 0.0f) { rectf[0] /= rectf[3]; rectf[1] /= rectf[3]; @@ -1833,16 +1845,23 @@ static void renderhalo_post(RenderResult *rr, float *rectf, HaloRen *har) /* pos har->miny= miny= haloys - har->rad/R.ycor; har->maxy= maxy= haloys + har->rad/R.ycor; - if (maxy<0); - else if (rr->rectyrecty < miny) { + /* pass */ + } else { - minx= floor(haloxs-har->rad); - maxx= ceil(haloxs+har->rad); + minx = floor(haloxs - har->rad); + maxx = ceil(haloxs + har->rad); - if (maxx<0); - else if (rr->rectxrectx < minx) { + /* pass */ + } else { - if (minx<0) minx= 0; if (maxx>=rr->rectx) maxx= rr->rectx-1; if (miny<0) miny= 0; @@ -2099,7 +2118,9 @@ static void bake_shade(void *handle, Object *ob, ShadeInput *shi, int UNUSED(qua copy_v3_v3(nor, shi->vn); - if (R.r.bake_normal_space == R_BAKE_SPACE_CAMERA); + if (R.r.bake_normal_space == R_BAKE_SPACE_CAMERA) { + /* pass */ + } else if (R.r.bake_normal_space == R_BAKE_SPACE_TANGENT) { float mat[3][3], imat[3][3]; diff --git a/source/blender/render/intern/source/renderdatabase.c b/source/blender/render/intern/source/renderdatabase.c index 6395a04b534..172af3a6c6f 100644 --- a/source/blender/render/intern/source/renderdatabase.c +++ b/source/blender/render/intern/source/renderdatabase.c @@ -976,10 +976,13 @@ HaloRen *RE_inithalo(Render *re, ObjectRen *obr, Material *ma, if (ma->mtex[0]) { - if ( (ma->mode & MA_HALOTEX) ) har->tex= 1; - else if (har->mat->septex & (1<<0)); /* only 1 level textures */ + if (ma->mode & MA_HALOTEX) { + har->tex = 1; + } + else if (har->mat->septex & (1 << 0)) { + /* only 1 level textures */ + } else { - mtex= ma->mtex[0]; copy_v3_v3(texvec, vec); diff --git a/source/blender/render/intern/source/shadeoutput.c b/source/blender/render/intern/source/shadeoutput.c index 6883710d1be..873657ec6ba 100644 --- a/source/blender/render/intern/source/shadeoutput.c +++ b/source/blender/render/intern/source/shadeoutput.c @@ -123,30 +123,45 @@ float mistfactor(float zcor, float const co[3]) { float fac, hi; - fac= zcor - R.wrld.miststa; /* zcor is calculated per pixel */ + fac = zcor - R.wrld.miststa; /* zcor is calculated per pixel */ /* fac= -co[2]-R.wrld.miststa; */ - if (fac>0.0f) { - if (fac< R.wrld.mistdist) { + if (fac > 0.0f) { + if (fac < R.wrld.mistdist) { - fac= (fac/(R.wrld.mistdist)); + fac = (fac / R.wrld.mistdist); - if (R.wrld.mistype==0) fac*= fac; - else if (R.wrld.mistype==1); - else fac= sqrt(fac); + if (R.wrld.mistype == 0) { + fac *= fac; + } + else if (R.wrld.mistype == 1) { + /* pass */ + } + else { + fac = sqrt(fac); + } + } + else { + fac = 1.0f; } - else fac= 1.0f; } - else fac= 0.0f; + else { + fac = 0.0f; + } /* height switched off mist */ if (R.wrld.misthi!=0.0f && fac!=0.0f) { /* at height misthi the mist is completely gone */ - hi= R.viewinv[0][2]*co[0]+R.viewinv[1][2]*co[1]+R.viewinv[2][2]*co[2]+R.viewinv[3][2]; + hi = R.viewinv[0][2] * co[0] + + R.viewinv[1][2] * co[1] + + R.viewinv[2][2] * co[2] + + R.viewinv[3][2]; - if (hi>R.wrld.misthi) fac= 0.0f; + if (hi > R.wrld.misthi) { + fac = 0.0f; + } else if (hi>0.0f) { hi= (R.wrld.misthi-hi)/R.wrld.misthi; fac*= hi*hi; @@ -1351,7 +1366,9 @@ static void shade_one_light(LampRen *lar, ShadeInput *shi, ShadeResult *shr, int /* this complex construction screams for a nicer implementation! (ton) */ if (R.r.mode & R_SHADOW) { if (ma->mode & MA_SHADOW) { - if (lar->type==LA_HEMI || lar->type==LA_AREA); + if (lar->type == LA_HEMI || lar->type == LA_AREA) { + /* pass */ + } else if ((ma->mode & MA_RAYBIAS) && (lar->mode & LA_SHAD_RAY) && (vlr->flag & R_SMOOTH)) { float thresh= shi->obr->ob->smoothresh; if (inp>thresh) @@ -1466,8 +1483,10 @@ static void shade_one_light(LampRen *lar, ShadeInput *shi, ShadeResult *shr, int if (shadfac[3]>0.0f && shi->spec!=0.0f && !(lar->mode & LA_NO_SPEC) && !(lar->mode & LA_ONLYSHADOW)) { - if (!(passflag & (SCE_PASS_COMBINED|SCE_PASS_SPEC))); - else if (lar->type==LA_HEMI) { + if (!(passflag & (SCE_PASS_COMBINED | SCE_PASS_SPEC))) { + /* pass */ + } + else if (lar->type == LA_HEMI) { float t; /* hemi uses no spec shaders (yet) */ diff --git a/source/blender/render/intern/source/sss.c b/source/blender/render/intern/source/sss.c index 69e738e840d..9b7a521db41 100644 --- a/source/blender/render/intern/source/sss.c +++ b/source/blender/render/intern/source/sss.c @@ -238,7 +238,9 @@ static void approximate_Rd_rgb(ScatterSettings **ss, float rr, float *rd) float indexf, t, idxf; int index; - if (rr > (RD_TABLE_RANGE_2*RD_TABLE_RANGE_2)); + if (rr > (RD_TABLE_RANGE_2 * RD_TABLE_RANGE_2)) { + /* pass */ + } else if (rr > RD_TABLE_RANGE) { rr= sqrt(rr); indexf= rr*(RD_TABLE_SIZE/RD_TABLE_RANGE_2); diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c index bf6962d0087..ba62baae897 100644 --- a/source/blender/render/intern/source/zbuf.c +++ b/source/blender/render/intern/source/zbuf.c @@ -2038,7 +2038,9 @@ static void zmask_rect(int *rectz, int *rectp, int xs, int ys, int neg) MEM_freeN(temprectp); - if (neg); /* z values for negative are already correct */ + if (neg) { + /* z values for negative are already correct */ + } else { /* clear not filled z values */ for (len= xs*ys -1; len>=0; len--) { diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 2f238cd22e7..ef9e25e0fef 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -255,8 +255,12 @@ void wm_event_do_notifiers(bContext *C) for (win = wm->windows.first; win; win = win->next) { /* filter out notifiers */ - if (note->category == NC_SCREEN && note->reference && note->reference != win->screen) ; - else if (note->category == NC_SCENE && note->reference && note->reference != win->screen->scene) ; + if (note->category == NC_SCREEN && note->reference && note->reference != win->screen) { + /* pass */ + } + else if (note->category == NC_SCENE && note->reference && note->reference != win->screen->scene) { + /* pass */ + } else { ScrArea *sa; ARegion *ar; diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index 7b78dbedb31..c6bd912e89b 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -190,9 +190,12 @@ static void wm_window_match_do(bContext *C, ListBase *oldwmlist) /* cases 1 and 2 */ if (oldwmlist->first == NULL) { - if (G.main->wm.first) ; /* nothing todo */ - else + if (G.main->wm.first) { + /* nothing todo */ + } + else { wm_add_default(C); + } } else { /* cases 3 and 4 */ From 35f0ded3776bc08fb52e8068a8a91374192d5b2f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 7 Oct 2012 10:01:54 +0000 Subject: [PATCH 082/347] fix for logical errors - range check on hair_velocity_smoothing() was off by one. - cloth sim parm's are used before NULL check in readfile.c --- source/blender/blenkernel/intern/implicit.c | 2 +- source/blender/blenloader/intern/readfile.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index ebb95a6561e..2b23e8450ae 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -1450,7 +1450,7 @@ static void hair_velocity_smoothing(ClothModifierData *clmd, lfVector *lF, lfVec i = HAIR_GRID_INDEX(lX[v], gmin, gmax, 0); j = HAIR_GRID_INDEX(lX[v], gmin, gmax, 1); k = HAIR_GRID_INDEX(lX[v], gmin, gmax, 2); - if (i < 0 || j < 0 || k < 0 || i > 10 || j >= 10 || k >= 10) + if (i < 0 || j < 0 || k < 0 || i >= 10 || j >= 10 || k >= 10) continue; grid[i][j][k].velocity[0] += lV[v][0]; diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 26d9fb9e829..fdb68d4cc17 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -3567,10 +3567,10 @@ static void direct_link_particlesystems(FileData *fd, ListBase *particles) psys->clmd->clothObject = NULL; psys->clmd->sim_parms= newdataadr(fd, psys->clmd->sim_parms); - psys->clmd->sim_parms->effector_weights = NULL; psys->clmd->coll_parms= newdataadr(fd, psys->clmd->coll_parms); if (psys->clmd->sim_parms) { + psys->clmd->sim_parms->effector_weights = NULL; if (psys->clmd->sim_parms->presets > 10) psys->clmd->sim_parms->presets = 0; } From aedf450746f1373beb82b9844e66b7ea1c828814 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 7 Oct 2012 12:28:19 +0000 Subject: [PATCH 083/347] code cleanup: use checks for empty rather then size in the BGE --- source/gameengine/Rasterizer/RAS_MaterialBucket.cpp | 6 +++--- .../RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp b/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp index 183da9d252e..c890f0c3dc5 100644 --- a/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp +++ b/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp @@ -147,7 +147,7 @@ void RAS_MeshSlot::begin(RAS_MeshSlot::iterator& it) int startvertex, endvertex; int startindex, endindex; - it.array = (m_displayArrays.size() > 0)? m_displayArrays[m_startarray]: NULL; + it.array = m_displayArrays.empty() ? NULL : m_displayArrays[m_startarray]; if (it.array == NULL || it.array->m_index.size() == 0 || it.array->m_vertex.size() == 0) { it.array = NULL; @@ -368,7 +368,7 @@ bool RAS_MeshSlot::Join(RAS_MeshSlot *target, MT_Scalar distance) size_t i; // verify if we can join - if (m_joinSlot || m_joinedSlots.size() || target->m_joinSlot) + if (m_joinSlot || (m_joinedSlots.empty() == false) || target->m_joinSlot) return false; if (!Equals(target)) @@ -461,7 +461,7 @@ bool RAS_MeshSlot::Split(bool force) abort(); } - if (target->m_displayArrays.size()) { + if (target->m_displayArrays.empty() == false) { target->m_endvertex = target->m_displayArrays.back()->m_vertex.size(); target->m_endindex = target->m_displayArrays.back()->m_index.size(); } diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp index 67423123a7a..a0da1c79baa 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp @@ -359,7 +359,7 @@ void RAS_OpenGLRasterizer::ClearCachingInfo(void) void RAS_OpenGLRasterizer::FlushDebugShapes() { - if (!m_debugShapes.size()) + if (m_debugShapes.empty()) return; // DrawDebugLines From c0a9f3f6a1bea9abec2b5e2efe6eb18b01972489 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 7 Oct 2012 12:31:56 +0000 Subject: [PATCH 084/347] code cleanup: grease pencil eraser had duplicated logic for getting screen coords of a point, move into a static function. --- .../blender/editors/gpencil/gpencil_paint.c | 107 +++++++----------- 1 file changed, 40 insertions(+), 67 deletions(-) diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index de7c2c41a6d..b6857249abf 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -792,6 +792,37 @@ static short gp_stroke_eraser_strokeinside(const int mval[], const int UNUSED(mv return 0; } +static void gp_point_to_xy(ARegion *ar, View2D *v2d, rctf *subrect, bGPDstroke *gps, bGPDspoint *pt, + int *r_x, int *r_y) +{ + int xyval[2]; + + if (gps->flag & GP_STROKE_3DSPACE) { + if (ED_view3d_project_int_global(ar, &pt->x, xyval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + *r_x = xyval[0]; + *r_y = xyval[1]; + } + else { + *r_x = V2D_IS_CLIPPED; + *r_y = V2D_IS_CLIPPED; + } + } + else if (gps->flag & GP_STROKE_2DSPACE) { + UI_view2d_view_to_region(v2d, pt->x, pt->y, r_x, r_y); + } + else { + if (subrect == NULL) { /* normal 3D view */ + *r_x = (int)(pt->x / 100 * ar->winx); + *r_y = (int)(pt->y / 100 * ar->winy); + } + else { /* camera view, use subrect */ + *r_x = (int)((pt->x / 100) * BLI_rctf_size_x(subrect)) + subrect->xmin; + *r_y = (int)((pt->y / 100) * BLI_rctf_size_y(subrect)) + subrect->ymin; + } + } +} + + /* eraser tool - evaluation per stroke */ // TODO: this could really do with some optimization (KD-Tree/BVH?) static void gp_stroke_eraser_dostroke(tGPsdata *p, @@ -800,7 +831,6 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p, { bGPDspoint *pt1, *pt2; int x0 = 0, y0 = 0, x1 = 0, y1 = 0; - int xyval[2]; int i; if (gps->totpoints == 0) { @@ -810,33 +840,11 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p, BLI_freelinkN(&gpf->strokes, gps); } else if (gps->totpoints == 1) { - /* get coordinates */ - if (gps->flag & GP_STROKE_3DSPACE) { - if (ED_view3d_project_int_global(p->ar, &gps->points->x, xyval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { - x0 = xyval[0]; - y0 = xyval[1]; - } - else { - x0 = V2D_IS_CLIPPED; - y0 = V2D_IS_CLIPPED; - } - } - else if (gps->flag & GP_STROKE_2DSPACE) { - UI_view2d_view_to_region(p->v2d, gps->points->x, gps->points->y, &x0, &y0); - } - else { - if (p->subrect == NULL) { /* normal 3D view */ - x0 = (int)(gps->points->x / 100 * p->ar->winx); - y0 = (int)(gps->points->y / 100 * p->ar->winy); - } - else { /* camera view, use subrect */ - x0 = (int)((gps->points->x / 100) * BLI_rctf_size_x(p->subrect)) + p->subrect->xmin; - y0 = (int)((gps->points->y / 100) * BLI_rctf_size_y(p->subrect)) + p->subrect->ymin; - } - } + gp_point_to_xy(p->ar, p->v2d, p->subrect, gps, gps->points, &x0, &y0); /* do boundbox check first */ - if (BLI_rcti_isect_pt(rect, x0, y0)) { + + if ((!ELEM(V2D_IS_CLIPPED, x0, y0)) && BLI_rcti_isect_pt(rect, x0, y0)) { /* only check if point is inside */ if (((x0 - mval[0]) * (x0 - mval[0]) + (y0 - mval[1]) * (y0 - mval[1])) <= rad * rad) { /* free stroke */ @@ -853,48 +861,13 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p, /* get points to work with */ pt1 = gps->points + i; pt2 = gps->points + i + 1; - - /* get coordinates */ - if (gps->flag & GP_STROKE_3DSPACE) { - if (ED_view3d_project_int_global(p->ar, &pt1->x, xyval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { - x0 = xyval[0]; - y0 = xyval[1]; - } - else { - x0 = V2D_IS_CLIPPED; - y0 = V2D_IS_CLIPPED; - } - if (ED_view3d_project_int_global(p->ar, &pt2->x, xyval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { - x1 = xyval[0]; - y1 = xyval[1]; - } - else { - x1 = V2D_IS_CLIPPED; - y1 = V2D_IS_CLIPPED; - } - } - else if (gps->flag & GP_STROKE_2DSPACE) { - UI_view2d_view_to_region(p->v2d, pt1->x, pt1->y, &x0, &y0); - - UI_view2d_view_to_region(p->v2d, pt2->x, pt2->y, &x1, &y1); - } - else { - if (p->subrect == NULL) { /* normal 3D view */ - x0 = (int)(pt1->x / 100 * p->ar->winx); - y0 = (int)(pt1->y / 100 * p->ar->winy); - x1 = (int)(pt2->x / 100 * p->ar->winx); - y1 = (int)(pt2->y / 100 * p->ar->winy); - } - else { /* camera view, use subrect */ - x0 = (int)((pt1->x / 100) * BLI_rctf_size_x(p->subrect)) + p->subrect->xmin; - y0 = (int)((pt1->y / 100) * BLI_rctf_size_y(p->subrect)) + p->subrect->ymin; - x1 = (int)((pt2->x / 100) * BLI_rctf_size_x(p->subrect)) + p->subrect->xmin; - y1 = (int)((pt2->y / 100) * BLI_rctf_size_y(p->subrect)) + p->subrect->ymin; - } - } - + + gp_point_to_xy(p->ar, p->v2d, p->subrect, gps, pt1, &x0, &y0); + gp_point_to_xy(p->ar, p->v2d, p->subrect, gps, pt2, &x1, &y1); + /* check that point segment of the boundbox of the eraser stroke */ - if (BLI_rcti_isect_pt(rect, x0, y0) || BLI_rcti_isect_pt(rect, x1, y1)) { + if (((!ELEM(V2D_IS_CLIPPED, x0, y0)) && BLI_rcti_isect_pt(rect, x0, y0)) || + ((!ELEM(V2D_IS_CLIPPED, x1, y1)) && BLI_rcti_isect_pt(rect, x1, y1))) { /* check if point segment of stroke had anything to do with * eraser region (either within stroke painted, or on its lines) * - this assumes that linewidth is irrelevant From ccd9f1491a137754aabf214d27f4785a04d10841 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 7 Oct 2012 14:00:18 +0000 Subject: [PATCH 085/347] style cleanup: line length, rename V3D_PROJ_RET_SUCCESS -> V3D_PROJ_RET_OK --- .../blender/editors/armature/editarmature.c | 23 +++++++++---- .../editors/armature/editarmature_sketch.c | 12 +++---- .../blender/editors/armature/meshlaplacian.c | 4 ++- source/blender/editors/curve/editfont.c | 5 +-- source/blender/editors/gpencil/drawgpencil.c | 21 ++++++------ .../blender/editors/gpencil/gpencil_paint.c | 28 ++++++++++------ source/blender/editors/include/ED_view3d.h | 2 +- source/blender/editors/mesh/editmesh_select.c | 6 ++-- source/blender/editors/mesh/editmesh_slide.c | 8 ++--- source/blender/editors/mesh/editmesh_tools.c | 8 ++--- source/blender/editors/mesh/meshtools.c | 2 +- .../blender/editors/physics/particle_edit.c | 14 ++++---- .../editors/sculpt_paint/paint_cursor.c | 4 +-- .../editors/sculpt_paint/paint_vertex.c | 2 +- .../blender/editors/space_view3d/drawobject.c | 32 +++++++++---------- .../editors/space_view3d/view3d_draw.c | 2 +- .../editors/space_view3d/view3d_edit.c | 2 +- .../editors/space_view3d/view3d_select.c | 7 ++-- .../editors/space_view3d/view3d_view.c | 10 +++--- source/blender/editors/transform/transform.c | 6 ++-- .../editors/transform/transform_snap.c | 8 ++--- 21 files changed, 116 insertions(+), 90 deletions(-) diff --git a/source/blender/editors/armature/editarmature.c b/source/blender/editors/armature/editarmature.c index 46bbf6f0683..ffdced3262f 100644 --- a/source/blender/editors/armature/editarmature.c +++ b/source/blender/editors/armature/editarmature.c @@ -661,7 +661,9 @@ static int apply_armature_pose2bones_exec(bContext *C, wmOperator *op) /* helpful warnings... */ /* TODO: add warnings to be careful about actions, applying deforms first, etc. */ if (ob->adt && ob->adt->action) - BKE_report(op->reports, RPT_WARNING, "Actions on this armature will be destroyed by this new rest pose as the transforms stored are relative to the old rest pose"); + BKE_report(op->reports, RPT_WARNING, + "Actions on this armature will be destroyed by this new rest pose as the " + "transforms stored are relative to the old rest pose"); /* Get editbones of active armature to alter */ ED_armature_to_edit(ob); @@ -1591,7 +1593,8 @@ void ARMATURE_OT_select_linked(wmOperatorType *ot) /* does bones and points */ /* note that BONE ROOT only gets drawn for root bones (or without IK) */ -static EditBone *get_nearest_editbonepoint(ViewContext *vc, const int mval[2], ListBase *edbo, int findunsel, int *selmask) +static EditBone *get_nearest_editbonepoint(ViewContext *vc, const int mval[2], + ListBase *edbo, int findunsel, int *selmask) { EditBone *ebone; rcti rect; @@ -2556,7 +2559,8 @@ void updateDuplicateSubtarget(EditBone *dupBone, ListBase *editbones, Object *ob } -EditBone *duplicateEditBoneObjects(EditBone *curBone, const char *name, ListBase *editbones, Object *src_ob, Object *dst_ob) +EditBone *duplicateEditBoneObjects(EditBone *curBone, const char *name, ListBase *editbones, + Object *src_ob, Object *dst_ob) { EditBone *eBone = MEM_mallocN(sizeof(EditBone), "addup_editbone"); @@ -3036,7 +3040,8 @@ static void bones_merge(Object *obedit, EditBone *start, EditBone *end, EditBone newbone->parent = start->parent; /* TODO, copy more things to the new bone */ - newbone->flag = start->flag & (BONE_HINGE | BONE_NO_DEFORM | BONE_NO_SCALE | BONE_NO_CYCLICOFFSET | BONE_NO_LOCAL_LOCATION | BONE_DONE); + newbone->flag = start->flag & (BONE_HINGE | BONE_NO_DEFORM | BONE_NO_SCALE | + BONE_NO_CYCLICOFFSET | BONE_NO_LOCAL_LOCATION | BONE_DONE); /* step 2a: reparent any side chains which may be parented to any bone in the chain of bones to merge * - potentially several tips for side chains leading to some tree exist... @@ -4481,7 +4486,8 @@ void ARMATURE_OT_align(wmOperatorType *ot) /* ***************** Pose tools ********************* */ -// XXX bone_looper is only to be used when we want to access settings (i.e. editability/visibility/selected) that context doesn't offer +/* XXX bone_looper is only to be used when we want to access settings + * (i.e. editability/visibility/selected) that context doesn't offer */ static int bone_looper(Object *ob, Bone *bone, void *data, int (*bone_func)(Object *, Bone *, void *)) { @@ -4511,7 +4517,8 @@ static int bone_looper(Object *ob, Bone *bone, void *data, /* called from editview.c, for mode-less pose selection */ /* assumes scene obact and basact is still on old situation */ -int ED_do_pose_selectbuffer(Scene *scene, Base *base, unsigned int *buffer, short hits, short extend, short deselect, short toggle) +int ED_do_pose_selectbuffer(Scene *scene, Base *base, unsigned int *buffer, short hits, + short extend, short deselect, short toggle) { Object *ob = base->object; Bone *nearBone; @@ -4757,7 +4764,9 @@ static void add_vgroups__mapFunc(void *userData, int index, const float co[3], copy_v3_v3(verts[index], co); } -static void envelope_bone_weighting(Object *ob, Mesh *mesh, float (*verts)[3], int numbones, Bone **bonelist, bDeformGroup **dgrouplist, bDeformGroup **dgroupflip, float (*root)[3], float (*tip)[3], int *selected, float scale) +static void envelope_bone_weighting(Object *ob, Mesh *mesh, float (*verts)[3], int numbones, Bone **bonelist, + bDeformGroup **dgrouplist, bDeformGroup **dgroupflip, + float (*root)[3], float (*tip)[3], int *selected, float scale) { /* Create vertex group weights from envelopes */ diff --git a/source/blender/editors/armature/editarmature_sketch.c b/source/blender/editors/armature/editarmature_sketch.c index 5ba4a232250..68d8a8d721e 100644 --- a/source/blender/editors/armature/editarmature_sketch.c +++ b/source/blender/editors/armature/editarmature_sketch.c @@ -646,7 +646,7 @@ static SK_Point *sk_snapPointStroke(bContext *C, SK_Stroke *stk, int mval[2], in short pval[2]; int pdist; - if (ED_view3d_project_short_global(ar, stk->points[i].p, pval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_short_global(ar, stk->points[i].p, pval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { pdist = ABS(pval[0] - mval[0]) + ABS(pval[1] - mval[1]); @@ -682,7 +682,7 @@ static SK_Point *sk_snapPointArmature(bContext *C, Object *ob, ListBase *ebones, { copy_v3_v3(vec, bone->head); mul_m4_v3(ob->obmat, vec); - if (ED_view3d_project_short_noclip(ar, vec, pval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_short_noclip(ar, vec, pval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { pdist = ABS(pval[0] - mval[0]) + ABS(pval[1] - mval[1]); @@ -699,7 +699,7 @@ static SK_Point *sk_snapPointArmature(bContext *C, Object *ob, ListBase *ebones, copy_v3_v3(vec, bone->tail); mul_m4_v3(ob->obmat, vec); - if (ED_view3d_project_short_noclip(ar, vec, pval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_short_noclip(ar, vec, pval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { pdist = ABS(pval[0] - mval[0]) + ABS(pval[1] - mval[1]); @@ -939,7 +939,7 @@ static void sk_projectDrawPoint(bContext *C, float vec[3], SK_Stroke *stk, SK_Dr initgrabz(ar->regiondata, fp[0], fp[1], fp[2]); /* method taken from editview.c - mouse_cursor() */ - if (ED_view3d_project_short_global(ar, fp, cval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_short_global(ar, fp, cval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { VECSUB2D(mval_f, cval, dd->mval); ED_view3d_win_to_delta(ar, mval_f, dvec); sub_v3_v3v3(vec, fp, dvec); @@ -1793,8 +1793,8 @@ int sk_detectMergeGesture(bContext *C, SK_Gesture *gest, SK_Sketch *UNUSED(sketc short start_val[2], end_val[2]; short dist; - if ((ED_view3d_project_short_global(ar, gest->stk->points[0].p, start_val, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) && - (ED_view3d_project_short_global(ar, sk_lastStrokePoint(gest->stk)->p, end_val, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS)) + if ((ED_view3d_project_short_global(ar, gest->stk->points[0].p, start_val, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) && + (ED_view3d_project_short_global(ar, sk_lastStrokePoint(gest->stk)->p, end_val, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK)) { dist = MAX2(ABS(start_val[0] - end_val[0]), ABS(start_val[1] - end_val[1])); diff --git a/source/blender/editors/armature/meshlaplacian.c b/source/blender/editors/armature/meshlaplacian.c index 522622ec5c4..e7efd7936c0 100644 --- a/source/blender/editors/armature/meshlaplacian.c +++ b/source/blender/editors/armature/meshlaplacian.c @@ -1254,7 +1254,9 @@ static MDefBoundIsect *meshdeform_ray_tree_intersect(MeshDeformBind *mdb, float hit.index = -1; hit.dist = FLT_MAX; - if (BLI_bvhtree_ray_cast(mdb->bvhtree, isect_mdef.start, isect_mdef.vec, 0.0, &hit, harmonic_ray_callback, data) != -1) { + if (BLI_bvhtree_ray_cast(mdb->bvhtree, isect_mdef.start, isect_mdef.vec, + 0.0, &hit, harmonic_ray_callback, data) != -1) + { len= isect_mdef.labda; isect_mdef.face = mface = mface1 + hit.index; diff --git a/source/blender/editors/curve/editfont.c b/source/blender/editors/curve/editfont.c index b11d640256c..b379ce6e5cf 100644 --- a/source/blender/editors/curve/editfont.c +++ b/source/blender/editors/curve/editfont.c @@ -441,8 +441,9 @@ static void txt_add_object(bContext *C, TextLine *firstline, int totline, float obedit = BKE_object_add(scene, OB_FONT); base = scene->basact; - - ED_object_base_init_transform(C, base, NULL, rot); /* seems to assume view align ? TODO - look into this, could be an operator option */ + /* seems to assume view align ? TODO - look into this, could be an operator option */ + ED_object_base_init_transform(C, base, NULL, rot); + BKE_object_where_is_calc(scene, obedit); obedit->loc[0] += offset[0]; diff --git a/source/blender/editors/gpencil/drawgpencil.c b/source/blender/editors/gpencil/drawgpencil.c index 5ff4ccbd126..3b26c46a410 100644 --- a/source/blender/editors/gpencil/drawgpencil.c +++ b/source/blender/editors/gpencil/drawgpencil.c @@ -149,7 +149,8 @@ static void gp_draw_stroke_buffer(tGPspoint *points, int totpoints, short thickn /* ----- Existing Strokes Drawing (3D and Point) ------ */ /* draw a given stroke - just a single dot (only one point) */ -static void gp_draw_stroke_point(bGPDspoint *points, short thickness, short dflag, short sflag, int offsx, int offsy, int winx, int winy) +static void gp_draw_stroke_point(bGPDspoint *points, short thickness, short dflag, short sflag, + int offsx, int offsy, int winx, int winy) { /* draw point */ if (sflag & GP_STROKE_3DSPACE) { @@ -508,7 +509,8 @@ static void gp_draw_strokes(bGPDframe *gpf, int offsx, int offsy, int winx, int glDepthMask(0); glEnable(GL_DEPTH_TEST); - /* first arg is normally rv3d->dist, but this isn't available here and seems to work quite well without */ + /* first arg is normally rv3d->dist, but this isn't + * available here and seems to work quite well without */ bglPolygonOffset(1.0f, 1.0f); #if 0 glEnable(GL_POLYGON_OFFSET_LINE); @@ -579,7 +581,8 @@ static void gp_draw_data(bGPdata *gpd, int offsx, int offsy, int winx, int winy, /* draw 'onionskins' (frame left + right) */ if (gpl->flag & GP_LAYER_ONIONSKIN) { - /* drawing method - only immediately surrounding (gstep = 0), or within a frame range on either side (gstep > 0)*/ + /* drawing method - only immediately surrounding (gstep = 0), + * or within a frame range on either side (gstep > 0)*/ if (gpl->gstep) { bGPDframe *gf; float fac; @@ -640,7 +643,8 @@ static void gp_draw_data(bGPdata *gpd, int offsx, int offsy, int winx, int winy, if (ED_gpencil_session_active() && (gpl->flag & GP_LAYER_ACTIVE) && (gpf->flag & GP_FRAME_PAINT)) { - /* Buffer stroke needs to be drawn with a different linestyle to help differentiate them from normal strokes. */ + /* Buffer stroke needs to be drawn with a different linestyle + * to help differentiate them from normal strokes. */ gp_draw_stroke_buffer(gpd->sbuffer, gpd->sbuffer_size, lthick, dflag, gpd->sbuffer_sflag); } } @@ -724,8 +728,8 @@ void draw_gpencil_2dimage(const bContext *C) } /* draw grease-pencil sketches to specified 2d-view assuming that matrices are already set correctly - * Note: this gets called twice - first time with onlyv2d=1 to draw 'canvas' strokes, second time with onlyv2d=0 for screen-aligned strokes - */ + * Note: this gets called twice - first time with onlyv2d=1 to draw 'canvas' strokes, + * second time with onlyv2d=0 for screen-aligned strokes */ void draw_gpencil_view2d(const bContext *C, short onlyv2d) { ScrArea *sa = CTX_wm_area(C); @@ -750,9 +754,8 @@ void draw_gpencil_view2d(const bContext *C, short onlyv2d) } /* draw grease-pencil sketches to specified 3d-view assuming that matrices are already set correctly - * Note: this gets called twice - first time with only3d=1 to draw 3d-strokes, second time with only3d=0 for screen-aligned strokes - */ - + * Note: this gets called twice - first time with only3d=1 to draw 3d-strokes, + * second time with only3d=0 for screen-aligned strokes */ void draw_gpencil_view3d(Scene *scene, View3D *v3d, ARegion *ar, short only3d) { bGPdata *gpd; diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index b6857249abf..c07f0db7114 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -279,7 +279,7 @@ static void gp_stroke_convertcoords(tGPsdata *p, const int mval[2], float out[3] /* method taken from editview.c - mouse_cursor() */ /* TODO, use ED_view3d_project_float_global */ - if (ED_view3d_project_int_global(p->ar, rvec, mval_prj, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_int_global(p->ar, rvec, mval_prj, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { VECSUB2D(mval_f, mval_prj, mval); ED_view3d_win_to_delta(p->ar, mval_f, dvec); sub_v3_v3v3(out, rvec, dvec); @@ -395,8 +395,10 @@ static short gp_stroke_addpoint(tGPsdata *p, const int mval[2], float pressure) pts = &gps->points[gps->totpoints - 1]; - /* special case for poly lines: normally, depth is needed only when creating new stroke from buffer, - * but poly lines are converting to stroke instantly, so initialize depth buffer before converting coordinates + /* special case for poly lines: normally, + * depth is needed only when creating new stroke from buffer, + * but poly lines are converting to stroke instantly, + * so initialize depth buffer before converting coordinates */ if (gpencil_project_check(p)) { View3D *v3d = p->sa->spacedata.first; @@ -798,7 +800,7 @@ static void gp_point_to_xy(ARegion *ar, View2D *v2d, rctf *subrect, bGPDstroke * int xyval[2]; if (gps->flag & GP_STROKE_3DSPACE) { - if (ED_view3d_project_int_global(ar, &pt->x, xyval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_int_global(ar, &pt->x, xyval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { *r_x = xyval[0]; *r_y = xyval[1]; } @@ -1396,13 +1398,17 @@ static void gpencil_draw_status_indicators(tGPsdata *p) /* print status info */ switch (p->paintmode) { case GP_PAINTMODE_ERASER: - ED_area_headerprint(p->sa, "Grease Pencil Erase Session: Hold and drag LMB or RMB to erase | ESC/Enter to end"); + ED_area_headerprint(p->sa, + "Grease Pencil Erase Session: Hold and drag LMB or RMB to erase |" + " ESC/Enter to end"); break; case GP_PAINTMODE_DRAW_STRAIGHT: - ED_area_headerprint(p->sa, "Grease Pencil Line Session: Hold and drag LMB to draw | ESC/Enter to end"); + ED_area_headerprint(p->sa, "Grease Pencil Line Session: Hold and drag LMB to draw | " + "ESC/Enter to end"); break; case GP_PAINTMODE_DRAW: - ED_area_headerprint(p->sa, "Grease Pencil Freehand Session: Hold and drag LMB to draw | ESC/Enter to end"); + ED_area_headerprint(p->sa, "Grease Pencil Freehand Session: Hold and drag LMB to draw | " + "ESC/Enter to end"); break; default: /* unhandled future cases */ @@ -1678,7 +1684,8 @@ static tGPsdata *gpencil_stroke_begin(bContext *C, wmOperator *op) //printf("\t\tGP - start stroke\n"); /* we may need to set up paint env again if we're resuming */ - /* XXX: watch it with the paintmode! in future, it'd be nice to allow changing paint-mode when in sketching-sessions */ + /* XXX: watch it with the paintmode! in future, + * it'd be nice to allow changing paint-mode when in sketching-sessions */ /* XXX: with tablet events, we may event want to check for eraser here, for nicer tablet support */ if (gp_session_initdata(C, p)) @@ -1862,7 +1869,10 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, wmEvent *event) case OPERATOR_RUNNING_MODAL | OPERATOR_PASS_THROUGH: /* event doesn't need to be handled */ - //printf("unhandled event -> %d (mmb? = %d | mmv? = %d)\n", event->type, event->type == MIDDLEMOUSE, event->type==MOUSEMOVE); +#if 0 + printf("unhandled event -> %d (mmb? = %d | mmv? = %d)\n", + event->type, event->type == MIDDLEMOUSE, event->type==MOUSEMOVE); +#endif break; } diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index b81e08ed7ef..f71133d3118 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -119,7 +119,7 @@ void ED_view3d_depth_tag_update(struct RegionView3D *rv3d); /* return values for ED_view3d_project_...() */ typedef enum { - V3D_PROJ_RET_SUCCESS = 0, + V3D_PROJ_RET_OK = 0, V3D_PROJ_RET_CLIP_NEAR = 1, /* can't avoid this when in perspective mode, (can't avoid) */ V3D_PROJ_RET_CLIP_BB = 2, /* bounding box clip - RV3D_CLIPPING */ V3D_PROJ_RET_CLIP_WIN = 3, /* outside window bounds */ diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index da87767e492..680d15ec51e 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -1059,11 +1059,11 @@ static void mouse_mesh_loop(bContext *C, int mval[2], short extend, short ring) /* We can't be sure this has already been set... */ ED_view3d_init_mats_rv3d(vc.obedit, vc.rv3d); - if (ED_view3d_project_float_object(vc.ar, eed->v1->co, v1_co, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_float_object(vc.ar, eed->v1->co, v1_co, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { length_1 = len_squared_v2v2(mvalf, v1_co); } - if (ED_view3d_project_float_object(vc.ar, eed->v2->co, v2_co, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_float_object(vc.ar, eed->v2->co, v2_co, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { length_2 = len_squared_v2v2(mvalf, v2_co); } #if 0 @@ -1090,7 +1090,7 @@ static void mouse_mesh_loop(bContext *C, int mval[2], short extend, short ring) float co[2], tdist; BM_face_calc_center_mean(f, cent); - if (ED_view3d_project_float_object(vc.ar, cent, co, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_float_object(vc.ar, cent, co, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { tdist = len_squared_v2v2(mvalf, co); if (tdist < best_dist) { /* printf("Best face: %p (%f)\n", f, tdist);*/ diff --git a/source/blender/editors/mesh/editmesh_slide.c b/source/blender/editors/mesh/editmesh_slide.c index e42b95c6013..eaf0c14a0a8 100644 --- a/source/blender/editors/mesh/editmesh_slide.c +++ b/source/blender/editors/mesh/editmesh_slide.c @@ -390,8 +390,8 @@ static BMEdge *vtx_slide_nrst_in_frame(VertexSlideOp *vso, const float mval[2]) mul_v3_m4v3(v2_proj, vso->obj->obmat, edge->v2->co); /* we could use ED_view3d_project_float_object here, but for now dont since we dont have the context */ - if ((ED_view3d_project_float_global(vso->active_region, v1_proj, v1_proj, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) && - (ED_view3d_project_float_global(vso->active_region, v2_proj, v2_proj, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS)) + if ((ED_view3d_project_float_global(vso->active_region, v1_proj, v1_proj, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) && + (ED_view3d_project_float_global(vso->active_region, v2_proj, v2_proj, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK)) { const float dist = dist_to_line_segment_v2(mval, v1_proj, v2_proj); if (dist < min_dist) { @@ -458,8 +458,8 @@ static void vtx_slide_update(VertexSlideOp *vso, wmEvent *event) mul_v3_m4v3(start_vtx_proj, vso->obj->obmat, vso->start_vtx->co); mul_v3_m4v3(edge_other_proj, vso->obj->obmat, other->co); - if ((ED_view3d_project_float_global(vso->active_region, edge_other_proj, edge_other_proj, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_SUCCESS) || - (ED_view3d_project_float_global(vso->active_region, start_vtx_proj, start_vtx_proj, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_SUCCESS)) + if ((ED_view3d_project_float_global(vso->active_region, edge_other_proj, edge_other_proj, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_OK) || + (ED_view3d_project_float_global(vso->active_region, start_vtx_proj, start_vtx_proj, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_OK)) { /* not much we can do here */ return; diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 879e20fcf8b..0d78d850e74 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -165,7 +165,7 @@ void EMBM_project_snap_verts(bContext *C, ARegion *ar, BMEditMesh *em) if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { float mval[2], co_proj[3], no_dummy[3]; int dist_dummy; - if (ED_view3d_project_float_object(ar, eve->co, mval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_float_object(ar, eve->co, mval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { if (snapObjectsContext(C, mval, &dist_dummy, co_proj, no_dummy, SNAP_NOT_OBEDIT)) { mul_v3_m4v3(eve->co, obedit->imat, co_proj); } @@ -767,8 +767,8 @@ static int edbm_dupli_extrude_cursor_invoke(bContext *C, wmOperator *op, wmEvent if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) { float co1[3], co2[3]; - if ((ED_view3d_project_float_object(vc.ar, eed->v1->co, co1, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) && - (ED_view3d_project_float_object(vc.ar, eed->v2->co, co2, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS)) + if ((ED_view3d_project_float_object(vc.ar, eed->v1->co, co1, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) && + (ED_view3d_project_float_object(vc.ar, eed->v2->co, co2, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK)) { /* 2D rotate by 90d while adding. * (x, y) = (y, -x) @@ -2772,7 +2772,7 @@ static int edbm_knife_cut_exec(bContext *C, wmOperator *op) screen_vert_coords = sco = MEM_mallocN(bm->totvert * sizeof(float) * 2, __func__); BM_ITER_MESH_INDEX (bv, &iter, bm, BM_VERTS_OF_MESH, i) { - if (ED_view3d_project_float_object(ar, bv->co, *sco, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_float_object(ar, bv->co, *sco, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_OK) { copy_v2_fl(*sco, FLT_MAX); /* set error value */ } BM_elem_index_set(bv, i); /* set_ok */ diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c index 42d82fff38e..f265113708a 100644 --- a/source/blender/editors/mesh/meshtools.c +++ b/source/blender/editors/mesh/meshtools.c @@ -1237,7 +1237,7 @@ int ED_mesh_pick_face_vert(bContext *C, Mesh *me, Object *ob, const int mval[2], const int v_idx = me->mloop[mp->loopstart + fidx].v; dm->getVertCo(dm, v_idx, co); mul_m4_v3(ob->obmat, co); - if (ED_view3d_project_float_global(ar, co, sco, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_float_global(ar, co, sco, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { len = len_squared_v2v2(mval_f, sco); if (len < len_best) { len_best = len; diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c index dc490c94b38..1010c0efce4 100644 --- a/source/blender/editors/physics/particle_edit.c +++ b/source/blender/editors/physics/particle_edit.c @@ -411,7 +411,7 @@ static int key_test_depth(PEData *data, const float co[3], const int screen_co[2 /* used to calculate here but all callers have the screen_co already, so pass as arg */ #if 0 if (ED_view3d_project_int_global(data->vc.ar, co, screen_co, - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) != V3D_PROJ_RET_SUCCESS) + V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) != V3D_PROJ_RET_OK) { return 0; } @@ -448,7 +448,7 @@ static int key_inside_circle(PEData *data, float rad, const float co[3], float * int screen_co[2]; /* TODO, should this check V3D_PROJ_TEST_CLIP_BB too? */ - if (ED_view3d_project_int_global(data->vc.ar, co, screen_co, V3D_PROJ_TEST_CLIP_WIN) != V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_int_global(data->vc.ar, co, screen_co, V3D_PROJ_TEST_CLIP_WIN) != V3D_PROJ_RET_OK) { return 0; } @@ -473,7 +473,7 @@ static int key_inside_rect(PEData *data, const float co[3]) { int screen_co[2]; - if (ED_view3d_project_int_global(data->vc.ar, co, screen_co, V3D_PROJ_TEST_CLIP_WIN) != V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_int_global(data->vc.ar, co, screen_co, V3D_PROJ_TEST_CLIP_WIN) != V3D_PROJ_RET_OK) { return 0; } @@ -1665,7 +1665,7 @@ int PE_lasso_select(bContext *C, const int mcords[][2], const short moves, short LOOP_KEYS { copy_v3_v3(co, key->co); mul_m4_v3(mat, co); - if ((ED_view3d_project_int_global(ar, co, screen_co, V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_SUCCESS) && + if ((ED_view3d_project_int_global(ar, co, screen_co, V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) && BLI_lasso_is_point_inside(mcords, moves, screen_co[0], screen_co[1], IS_CLIPPED) && key_test_depth(&data, co, screen_co)) { @@ -1685,7 +1685,7 @@ int PE_lasso_select(bContext *C, const int mcords[][2], const short moves, short copy_v3_v3(co, key->co); mul_m4_v3(mat, co); - if ((ED_view3d_project_int_global(ar, co, screen_co, V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_SUCCESS) && + if ((ED_view3d_project_int_global(ar, co, screen_co, V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) && BLI_lasso_is_point_inside(mcords, moves, screen_co[0], screen_co[1], IS_CLIPPED) && key_test_depth(&data, co, screen_co)) { @@ -2797,7 +2797,7 @@ static void brush_cut(PEData *data, int pa_index) if (edit->points[pa_index].flag & PEP_HIDE) return; - if (ED_view3d_project_int_global(ar, key->co, screen_co, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_SUCCESS) + if (ED_view3d_project_int_global(ar, key->co, screen_co, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_OK) return; rad2= data->rad * data->rad; @@ -2822,7 +2822,7 @@ static void brush_cut(PEData *data, int pa_index) /* calculate path time closest to root that was inside the circle */ for (k=1, key++; k<=keys; k++, key++) { - if ((ED_view3d_project_int_global(ar, key->co, screen_co, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_SUCCESS) || + if ((ED_view3d_project_int_global(ar, key->co, screen_co, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_OK) || key_test_depth(data, key->co, screen_co) == 0) { x0 = (float)screen_co[0]; diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c index 6120229190d..e3d714b1917 100644 --- a/source/blender/editors/sculpt_paint/paint_cursor.c +++ b/source/blender/editors/sculpt_paint/paint_cursor.c @@ -322,8 +322,8 @@ static int project_brush_radius(ViewContext *vc, add_v3_v3v3(offset, location, ortho); /* project the center of the brush, and the tangent point to the view onto the screen */ - if ((ED_view3d_project_float_global(vc->ar, location, p1, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) && - (ED_view3d_project_float_global(vc->ar, offset, p2, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS)) + if ((ED_view3d_project_float_global(vc->ar, location, p1, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) && + (ED_view3d_project_float_global(vc->ar, offset, p2, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK)) { /* the distance between these points is the size of the projected brush in pixels */ return len_v2v2(p1, p2); diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c index 5a79368ac49..6b3017b8638 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.c @@ -848,7 +848,7 @@ static float calc_vp_strength_dl(VPaint *vp, ViewContext *vc, const float vert_n { float vertco[2]; - if (ED_view3d_project_float_global(vc->ar, vert_nor, vertco, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_float_global(vc->ar, vert_nor, vertco, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { float delta[2]; float dist_squared; diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 84a69b811ca..1b008c27fc0 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -787,7 +787,7 @@ void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, int depth_write, floa (vos->flag & V3D_CACHE_TEXT_GLOBALSPACE) ? rv3d->persmat : rv3d->persmatob, (vos->flag & V3D_CACHE_TEXT_LOCALCLIP) != 0, vos->vec, vos->sco, - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_SUCCESS) + V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) { tot++; } @@ -1885,7 +1885,7 @@ void lattice_foreachScreenVert(ViewContext *vc, void (*func)(void *userData, BPo if (bp->hide == 0) { int screen_co[2]; if (ED_view3d_project_int_object(vc->ar, dl ? co : bp->vec, screen_co, - V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_SUCCESS) + V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_OK) { func(userData, bp, screen_co[0], screen_co[1]); } @@ -1995,7 +1995,7 @@ static void mesh_foreachScreenVert__mapFunc(void *userData, int index, const flo V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN; int screen_co[2]; - if (ED_view3d_project_int_object(data->vc.ar, co, screen_co, flag) != V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_int_object(data->vc.ar, co, screen_co, flag) != V3D_PROJ_RET_OK) { return; } @@ -2067,10 +2067,10 @@ static void mesh_foreachScreenEdge__mapFunc(void *userData, int index, const flo V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN : V3D_PROJ_TEST_NOP; - if (ED_view3d_project_int_object(data->vc.ar, v0co, screen_co_a, flag) != V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_int_object(data->vc.ar, v0co, screen_co_a, flag) != V3D_PROJ_RET_OK) { return; } - if (ED_view3d_project_int_object(data->vc.ar, v1co, screen_co_b, flag) != V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_int_object(data->vc.ar, v1co, screen_co_b, flag) != V3D_PROJ_RET_OK) { return; } @@ -2128,7 +2128,7 @@ static void mesh_foreachScreenFace__mapFunc(void *userData, int index, const flo if (efa && !BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { int screen_co[2]; if (ED_view3d_project_int_object(data->vc.ar, cent, screen_co, - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_SUCCESS) + V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) { data->func(data->userData, efa, screen_co[0], screen_co[1], index); } @@ -2178,24 +2178,24 @@ void nurbs_foreachScreenVert( if (cu->drawflag & CU_HIDE_HANDLES) { if (ED_view3d_project_int_object(vc->ar, bezt->vec[1], screen_co, - V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_SUCCESS) + V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_OK) { func(userData, nu, NULL, bezt, 1, screen_co[0], screen_co[1]); } } else { if (ED_view3d_project_int_object(vc->ar, bezt->vec[0], screen_co, - V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_SUCCESS) + V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_OK) { func(userData, nu, NULL, bezt, 0, screen_co[0], screen_co[1]); } if (ED_view3d_project_int_object(vc->ar, bezt->vec[1], screen_co, - V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_SUCCESS) + V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_OK) { func(userData, nu, NULL, bezt, 1, screen_co[0], screen_co[1]); } if (ED_view3d_project_int_object(vc->ar, bezt->vec[2], screen_co, - V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_SUCCESS) + V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_OK) { func(userData, nu, NULL, bezt, 2, screen_co[0], screen_co[1]); } @@ -2210,7 +2210,7 @@ void nurbs_foreachScreenVert( if (bp->hide == 0) { int screen_co[2]; if (ED_view3d_project_int_object(vc->ar, bp->vec, screen_co, - V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_SUCCESS) + V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_OK) { func(userData, nu, bp, NULL, -1, screen_co[0], screen_co[1]); } @@ -2232,7 +2232,7 @@ void mball_foreachScreenElem( for (ml = mb->editelems->first; ml; ml = ml->next) { int screen_co[2]; if (ED_view3d_project_int_object(vc->ar, &ml->x, screen_co, - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_SUCCESS) + V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) { func(userData, ml, screen_co[0], screen_co[1]); } @@ -2255,7 +2255,7 @@ void armature_foreachScreenBone( /* project head location to screenspace */ if (ED_view3d_project_int_object(vc->ar, ebone->head, screen_co_a, - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_SUCCESS) + V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) { points_proj_tot++; } @@ -2266,7 +2266,7 @@ void armature_foreachScreenBone( /* project tail location to screenspace */ if (ED_view3d_project_int_object(vc->ar, ebone->tail, screen_co_b, - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_SUCCESS) + V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) { points_proj_tot++; } @@ -2302,7 +2302,7 @@ void pose_foreachScreenBone( /* project head location to screenspace */ if (ED_view3d_project_int_object(vc->ar, pchan->pose_head, screen_co_a, - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_SUCCESS) + V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) { points_proj_tot++; } @@ -2313,7 +2313,7 @@ void pose_foreachScreenBone( /* project tail location to screenspace */ if (ED_view3d_project_int_object(vc->ar, pchan->pose_tail, screen_co_b, - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_SUCCESS) + V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) { points_proj_tot++; } diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 00d35a5d2e1..c6bcbfbf50d 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -558,7 +558,7 @@ static void drawcursor(Scene *scene, ARegion *ar, View3D *v3d) int co[2]; /* we don't want the clipping for cursor */ - if (ED_view3d_project_int_global(ar, give_cursor(scene, v3d), co, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_int_global(ar, give_cursor(scene, v3d), co, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { setlinestyle(0); cpack(0xFF); circ((float)co[0], (float)co[1], 10.0); diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 735f7b5ea4a..504f746637e 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -3534,7 +3534,7 @@ static int view3d_cursor3d_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent * /* flip = */ initgrabz(rv3d, fp[0], fp[1], fp[2]); } - if (ED_view3d_project_float_global(ar, fp, mval_fl, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_float_global(ar, fp, mval_fl, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { short depth_used = FALSE; if (U.uiflag & USER_ZBUF_CURSOR) { /* maybe this should be accessed some other way */ diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index 53f2c2e9f5e..5f0bb180711 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -120,7 +120,7 @@ int view3d_get_view_aligned_coordinate(ViewContext *vc, float fp[3], const int m initgrabz(vc->rv3d, fp[0], fp[1], fp[2]); - if (ret == V3D_PROJ_RET_SUCCESS) { + if (ret == V3D_PROJ_RET_OK) { const float mval_f[2] = {(float)(mval_cpy[0] - mval[0]), (float)(mval_cpy[1] - mval[1])}; ED_view3d_win_to_delta(vc->ar, mval_f, dvec); @@ -1506,7 +1506,8 @@ static int mouse_select(bContext *C, const int mval[2], short extend, short dese } } } - else if (ED_do_pose_selectbuffer(scene, basact, buffer, hits, extend, deselect, toggle) ) { /* then bone is found */ + else if (ED_do_pose_selectbuffer(scene, basact, buffer, hits, extend, deselect, toggle) ) { + /* then bone is found */ /* we make the armature selected: * not-selected active object in posemode won't work well for tools */ @@ -2639,7 +2640,7 @@ static int object_circle_select(ViewContext *vc, int select, const int mval[2], if (((base->flag & SELECT) == 0) && BASE_SELECTABLE(vc->v3d, base)) { float screen_co[2]; if (ED_view3d_project_float_global(vc->ar, base->object->obmat[3], screen_co, - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_SUCCESS) + V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) { if (len_squared_v2v2(mval_fl, screen_co) <= radius_squared) { ED_base_object_select(base, select); diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index f138a95b0ef..84b1505c900 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -863,7 +863,7 @@ eV3DProjStatus ED_view3d_project_base(struct ARegion *ar, struct Base *base) eV3DProjStatus ret = ED_view3d_project_short_global(ar, base->object->obmat[3], &base->sx, V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN); - if (ret != V3D_PROJ_RET_SUCCESS) { + if (ret != V3D_PROJ_RET_OK) { base->sx = IS_CLIPPED; base->sy = 0; } @@ -949,7 +949,7 @@ static eV3DProjStatus ed_view3d_project__internal(ARegion *ar, return V3D_PROJ_RET_CLIP_NEAR; } - return V3D_PROJ_RET_SUCCESS; + return V3D_PROJ_RET_OK; } eV3DProjStatus ED_view3d_project_short_ex(ARegion *ar, float perspmat[4][4], const int is_local, @@ -957,7 +957,7 @@ eV3DProjStatus ED_view3d_project_short_ex(ARegion *ar, float perspmat[4][4], con { float tvec[2]; eV3DProjStatus ret = ed_view3d_project__internal(ar, perspmat, is_local, co, tvec, flag); - if (ret == V3D_PROJ_RET_SUCCESS) { + if (ret == V3D_PROJ_RET_OK) { if ((tvec[0] > -32700.0 && tvec[0] < 32700.0f) && (tvec[1] > -32700.0 && tvec[1] < 32700.0f)) { @@ -976,7 +976,7 @@ eV3DProjStatus ED_view3d_project_int_ex(ARegion *ar, float perspmat[4][4], const { float tvec[2]; eV3DProjStatus ret = ed_view3d_project__internal(ar, perspmat, is_local, co, tvec, flag); - if (ret == V3D_PROJ_RET_SUCCESS) { + if (ret == V3D_PROJ_RET_OK) { if ((tvec[0] > -2140000000.0 && tvec[0] < 2140000000.0f) && (tvec[1] > -2140000000.0 && tvec[1] < 2140000000.0f)) { @@ -995,7 +995,7 @@ eV3DProjStatus ED_view3d_project_float_ex(ARegion *ar, float perspmat[4][4], con { float tvec[2]; eV3DProjStatus ret = ed_view3d_project__internal(ar, perspmat, is_local, co, tvec, flag); - if (ret == V3D_PROJ_RET_SUCCESS) { + if (ret == V3D_PROJ_RET_OK) { if (finite(tvec[0]) && finite(tvec[1])) { diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index be568fcb9d8..be4e580de01 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -230,7 +230,7 @@ void projectIntView(TransInfo *t, const float vec[3], int adr[2]) { if (t->spacetype == SPACE_VIEW3D) { if (t->ar->regiontype == RGN_TYPE_WINDOW) { - if (ED_view3d_project_int_global(t->ar, vec, adr, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_int_global(t->ar, vec, adr, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_OK) { adr[0] = (int)2140000000.0f; /* this is what was done in 2.64, perhaps we can be smarter? */ adr[1] = (int)2140000000.0f; } @@ -355,7 +355,7 @@ void projectFloatView(TransInfo *t, const float vec[3], float adr[2]) case SPACE_VIEW3D: { if (t->ar->regiontype == RGN_TYPE_WINDOW) { - if (ED_view3d_project_float_global(t->ar, vec, adr, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_float_global(t->ar, vec, adr, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_OK) { /* XXX, 2.64 and prior did this, weak! */ adr[0] = t->ar->winx / 2.0f; adr[1] = t->ar->winy / 2.0f; @@ -4853,7 +4853,7 @@ static void calcNonProportionalEdgeSlide(TransInfo *t, SlideData *sld, const flo sv->edge_len = len_v3v3(dw_p, up_p); mul_v3_m4v3(v_proj, t->obedit->obmat, sv->v->co); - if (ED_view3d_project_float_global(t->ar, v_proj, v_proj, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_float_global(t->ar, v_proj, v_proj, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { dist = len_squared_v2v2(mval, v_proj); if (dist < min_dist) { min_dist = dist; diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index 2f2b31de89d..94b8abb8850 100644 --- a/source/blender/editors/transform/transform_snap.c +++ b/source/blender/editors/transform/transform_snap.c @@ -317,7 +317,7 @@ void applyProject(TransInfo *t) copy_v3_v3(iloc, td->ob->obmat[3]); } - if (ED_view3d_project_float_global(t->ar, iloc, mval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_float_global(t->ar, iloc, mval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { if (snapObjectsTransform(t, mval, &dist, loc, no, t->tsnap.modeSelect)) { // if (t->flag & (T_EDIT|T_POSE)) { // mul_m4_v3(imat, loc); @@ -603,7 +603,7 @@ int updateSelectedSnapPoint(TransInfo *t) int dx, dy; int dist; - if (ED_view3d_project_int_global(t->ar, p->co, screen_loc, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_int_global(t->ar, p->co, screen_loc, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_OK) { continue; } @@ -1236,7 +1236,7 @@ static int snapEdge(ARegion *ar, float v1co[3], short v1no[3], float v2co[3], sh new_depth = len_v3v3(location, ray_start); - if (ED_view3d_project_int_global(ar, location, screen_loc, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_int_global(ar, location, screen_loc, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { new_dist = abs(screen_loc[0] - (int)mval[0]) + abs(screen_loc[1] - (int)mval[1]); } else { @@ -1297,7 +1297,7 @@ static int snapVertex(ARegion *ar, float vco[3], short vno[3], float obmat[][4], new_depth = len_v3v3(location, ray_start); - if (ED_view3d_project_int_global(ar, location, screen_loc, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_int_global(ar, location, screen_loc, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { new_dist = abs(screen_loc[0] - (int)mval[0]) + abs(screen_loc[1] - (int)mval[1]); } else { From e3ab85a3f589fd6d649caf8fbe71ea70e0a217de Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Sun, 7 Oct 2012 14:15:50 +0000 Subject: [PATCH 086/347] Revert fix for #31806, needs a better solution, can hang compiling some shaders. --- intern/cycles/render/svm.cpp | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/intern/cycles/render/svm.cpp b/intern/cycles/render/svm.cpp index da287a10199..844ce01569f 100644 --- a/intern/cycles/render/svm.cpp +++ b/intern/cycles/render/svm.cpp @@ -274,17 +274,6 @@ void SVMCompiler::stack_clear_users(ShaderNode *node, set& done) foreach(ShaderInput *in, output->links) in->stack_offset = SVM_STACK_INVALID; - - /* unmark any nodes that have no more valid outputs, see [#31806] */ - if(done.find(output->parent) != done.end()) { - all_done = true; - foreach(ShaderOutput *pout, output->parent->outputs) - if(pout->stack_offset != SVM_STACK_INVALID) - all_done = false; - - if(all_done) - done.erase(output->parent); - } } } } From c80c4c896aedae7c711d10e6f133d3bdca460de3 Mon Sep 17 00:00:00 2001 From: "Sv. Lockal" Date: Sun, 7 Oct 2012 15:39:47 +0000 Subject: [PATCH 087/347] Fix file descriptor leak in BLI_file_ungzip_to_mem and small memleak in wm_window_title. --- source/blender/blenlib/intern/fileops.c | 2 ++ source/blender/windowmanager/intern/wm_window.c | 6 ++---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/source/blender/blenlib/intern/fileops.c b/source/blender/blenlib/intern/fileops.c index 1df904f617a..883cdfde426 100644 --- a/source/blender/blenlib/intern/fileops.c +++ b/source/blender/blenlib/intern/fileops.c @@ -140,6 +140,8 @@ char *BLI_file_ungzip_to_mem(const char *from_file, int *size_r) } else break; } + + gzclose(gzfile); if (size == 0) { MEM_freeN(mem); diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index d0bed4e5965..44827302d7d 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -300,11 +300,9 @@ void wm_window_close(bContext *C, wmWindowManager *wm, wmWindow *win) void wm_window_title(wmWindowManager *wm, wmWindow *win) { - /* handle the 'temp' window, only set title when not set before */ if (win->screen && win->screen->temp) { - char *title = GHOST_GetTitle(win->ghostwin); - if (title == NULL || title[0] == 0) - GHOST_SetTitle(win->ghostwin, "Blender"); + /* nothing to do for 'temp' windows, + * because WM_window_open_temp always sets window title */ } else { From 9fcb7cd520dd5b1befcff9115a707a2b4cfa718a Mon Sep 17 00:00:00 2001 From: Mitchell Stokes Date: Sun, 7 Oct 2012 19:10:03 +0000 Subject: [PATCH 088/347] BGE: When applying movement to an object with the Character physics type, use the btKinematicCharacterController's setWalkDirection() instead of moving the physics object ourselves. This reduces issues with tunneling (the character going through other objects). --- .../Physics/Bullet/CcdPhysicsController.cpp | 16 ++++++++++------ .../Physics/Bullet/CcdPhysicsEnvironment.h | 5 +++++ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp index 81bf66d9536..240bda811f0 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp +++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp @@ -895,18 +895,22 @@ void CcdPhysicsController::RelativeTranslate(float dlocX,float dlocY,float dloc return; } - // btRigidBody* body = GetRigidBody(); // not used anymore - btVector3 dloc(dlocX,dlocY,dlocZ); btTransform xform = m_object->getWorldTransform(); if (local) - { dloc = xform.getBasis()*dloc; - } - xform.setOrigin(xform.getOrigin() + dloc); - SetCenterOfMassTransform(xform); + if (m_characterController) + { + m_characterController->setWalkDirection(dloc/GetPhysicsEnvironment()->getNumTimeSubSteps()); + } + else + { + + xform.setOrigin(xform.getOrigin() + dloc); + SetCenterOfMassTransform(xform); + } } } diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h index c499a1ef75c..59e40a6f91a 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h +++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h @@ -115,6 +115,11 @@ protected: virtual void setLinearAirDamping(float damping); virtual void setUseEpa(bool epa); + int getNumTimeSubSteps() + { + return m_numTimeSubSteps; + } + virtual void beginFrame(); virtual void endFrame() {} /// Perform an integration step of duration 'timeStep'. From 7b37e78c91d2a7a9c95c7a0f5bbe74fbca18c07c Mon Sep 17 00:00:00 2001 From: Dan Eicher Date: Sun, 7 Oct 2012 20:07:30 +0000 Subject: [PATCH 089/347] Grease Pencil py-api * new/remove for GPencil frames/strokes/ * add/pop for points * clear for frame/layer & grease_pencil * copy for frame + fix for free_gpencil_frames() not clearing the active frame --- source/blender/blenkernel/intern/gpencil.c | 1 + source/blender/makesrna/intern/rna_gpencil.c | 259 ++++++++++++++++-- source/blender/makesrna/intern/rna_main_api.c | 29 ++ 3 files changed, 271 insertions(+), 18 deletions(-) diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c index 84871375788..76b00ffdb1c 100644 --- a/source/blender/blenkernel/intern/gpencil.c +++ b/source/blender/blenkernel/intern/gpencil.c @@ -87,6 +87,7 @@ void free_gpencil_frames(bGPDlayer *gpl) free_gpencil_strokes(gpf); BLI_freelinkN(&gpl->frames, gpf); } + gpl->actframe = NULL; } /* Free all of the gp-layers for a viewport (list should be &gpd->layers or so) */ diff --git a/source/blender/makesrna/intern/rna_gpencil.c b/source/blender/makesrna/intern/rna_gpencil.c index bf7f4984ea1..ae1c7fd2d5b 100644 --- a/source/blender/makesrna/intern/rna_gpencil.c +++ b/source/blender/makesrna/intern/rna_gpencil.c @@ -111,6 +111,108 @@ static void rna_GPencilLayer_info_set(PointerRNA *ptr, const char *value) BLI_uniquename(&gpd->layers, gpl, "GP_Layer", '.', offsetof(bGPDlayer, info), sizeof(gpl->info)); } +static void rna_GPencil_stroke_point_add(bGPDstroke *stroke, int count) +{ + if (stroke->points == NULL) + stroke->points = MEM_callocN(sizeof(bGPDspoint) * count, "gp_stroke_points"); + else + stroke->points = MEM_reallocN(stroke->points, sizeof(bGPDspoint) * (stroke->totpoints + count)); + + stroke->totpoints += count; +} + +static void rna_GPencil_stroke_point_pop(bGPDstroke *stroke, ReportList *reports, int index) +{ + bGPDspoint *pt_tmp = stroke->points; + + /* python style negative indexing */ + if (index < 0) { + index += stroke->totpoints; + } + + if (stroke->totpoints <= index || index < 0) { + BKE_report(reports, RPT_ERROR, "GPencilStrokePoints.pop: index out of range"); + return; + } + + stroke->totpoints--; + + stroke->points = MEM_callocN(sizeof(bGPDspoint) * stroke->totpoints, "gp_stroke_points"); + + if (index > 0) + memcpy(stroke->points, pt_tmp, sizeof(bGPDspoint) * index); + + if (index < stroke->totpoints) + memcpy(&stroke->points[index], &pt_tmp[index + 1], sizeof(bGPDspoint) * (stroke->totpoints - index)); + + /* free temp buffer */ + MEM_freeN(pt_tmp); + + WM_main_add_notifier(NC_GPENCIL | NA_EDITED, NULL); +} + +static bGPDstroke *rna_GPencil_stroke_new(bGPDframe *frame) +{ + bGPDstroke *stroke = MEM_callocN(sizeof(bGPDstroke), "gp_stroke"); + + BLI_addtail(&frame->strokes, stroke); + + return stroke; +} + +static void rna_GPencil_stroke_remove(bGPDframe *frame, ReportList *reports, bGPDstroke *stroke) +{ + if (BLI_findindex(&frame->strokes, stroke) == -1) { + BKE_reportf(reports, RPT_ERROR, "Stroke not found in grease pencil frame"); + return; + } + + BLI_freelinkN(&frame->strokes, stroke); + + WM_main_add_notifier(NC_GPENCIL | NA_EDITED, NULL); +} + +static bGPDframe *rna_GPencil_frame_new(bGPDlayer *layer, ReportList *reports, int frame_number) +{ + if (BKE_gpencil_layer_find_frame(layer, frame_number)) { + BKE_reportf(reports, RPT_ERROR, "Frame already exists on this frame number"); + return NULL; + } + + bGPDframe *frame = gpencil_frame_addnew(layer, frame_number); + + WM_main_add_notifier(NC_GPENCIL | NA_EDITED, NULL); + + return frame; +} + +static void rna_GPencil_frame_remove(bGPDlayer *layer, ReportList *reports, bGPDframe *frame) +{ + if (BLI_findindex(&layer->frames, frame) == -1) { + BKE_reportf(reports, RPT_ERROR, "Frame not found in grease pencil layer"); + return; + } + + gpencil_layer_delframe(layer, frame); + + WM_main_add_notifier(NC_GPENCIL | NA_EDITED, NULL); +} + +static bGPDframe *rna_GPencil_frame_copy(bGPDlayer *layer, bGPDframe *src) +{ + bGPDframe *frame = gpencil_frame_duplicate(src); + + while (BKE_gpencil_layer_find_frame(layer, frame->framenum)) { + frame->framenum++; + } + + BLI_addtail(&layer->frames, frame); + + WM_main_add_notifier(NC_GPENCIL | NA_EDITED, NULL); + + return frame; +} + static bGPDlayer *rna_GPencil_layer_new(bGPdata *gpd, const char *name, int setactive) { bGPDlayer *gl = gpencil_layer_addnew(gpd, name, setactive); @@ -122,14 +224,7 @@ static bGPDlayer *rna_GPencil_layer_new(bGPdata *gpd, const char *name, int seta static void rna_GPencil_layer_remove(bGPdata *gpd, ReportList *reports, bGPDlayer *layer) { - bGPDlayer *gl; - - for (gl = gpd->layers.first; gl; gl = gl->next) { - if (gl == layer) - break; - } - - if (gl == NULL) { + if (BLI_findindex(&gpd->layers, layer) == -1) { BKE_reportf(reports, RPT_ERROR, "Layer not found in grease pencil data"); return; } @@ -139,6 +234,27 @@ static void rna_GPencil_layer_remove(bGPdata *gpd, ReportList *reports, bGPDlaye WM_main_add_notifier(NC_GPENCIL | ND_DATA | NA_EDITED, NULL); } +static void rna_GPencil_frame_clear(bGPDframe *frame) +{ + free_gpencil_strokes(frame); + + WM_main_add_notifier(NC_GPENCIL | ND_DATA | NA_EDITED, NULL); +} + +static void rna_GPencil_layer_clear(bGPDlayer *layer) +{ + free_gpencil_frames(layer); + + WM_main_add_notifier(NC_GPENCIL | ND_DATA | NA_EDITED, NULL); +} + +static void rna_GPencil_clear(bGPdata *gpd) +{ + free_gpencil_layers(&gpd->layers); + + WM_main_add_notifier(NC_GPENCIL | ND_DATA | NA_EDITED, NULL); +} + #else static void rna_def_gpencil_stroke_point(BlenderRNA *brna) @@ -154,19 +270,49 @@ static void rna_def_gpencil_stroke_point(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "x"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Coordinates", ""); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); prop = RNA_def_property(srna, "pressure", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "pressure"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Pressure", "Pressure of tablet at point when drawing it"); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); +} + +static void rna_def_gpencil_stroke_points_api(BlenderRNA *brna, PropertyRNA *cprop) +{ + StructRNA *srna; + + FunctionRNA *func; + /* PropertyRNA *parm; */ + + RNA_def_property_srna(cprop, "GPencilStrokePoints"); + srna = RNA_def_struct(brna, "GPencilStrokePoints", NULL); + RNA_def_struct_sdna(srna, "bGPDstroke"); + RNA_def_struct_ui_text(srna, "Grease Pencil Stroke Points", "Collection of grease pencil stroke points"); + + func = RNA_def_function(srna, "add", "rna_GPencil_stroke_point_add"); + RNA_def_function_ui_description(func, "Add a new grease pencil stroke point"); + RNA_def_int(func, "count", 1, 1, INT_MAX, "Number", "Number of points to add to the stroke", 1, INT_MAX); + + func = RNA_def_function(srna, "pop", "rna_GPencil_stroke_point_pop"); + RNA_def_function_ui_description(func, "Remove a grease pencil stroke point"); + RNA_def_function_flag(func, FUNC_USE_REPORTS); + RNA_def_int(func, "index", -1, INT_MIN, INT_MAX, "Index", "point index", INT_MIN, INT_MAX); } static void rna_def_gpencil_stroke(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; + + static EnumPropertyItem stroke_draw_mode_items[] = { + {0, "SCREEN", 0, "Screen", "Stroke is in screen-space"}, + {GP_STROKE_3DSPACE, "3DSPACE", 0, "3d Space", "Stroke is in 3d-space"}, + {GP_STROKE_2DSPACE, "2DSPACE", 0, "2d Space", "stroke is in 2d-space"}, + {GP_STROKE_2DIMAGE, "2DIMAGE", 0, "2d Image", "Stroke is in 2d-space (but with special 'image' scaling)"}, + {0, NULL, 0, NULL, NULL} + }; srna = RNA_def_struct(brna, "GPencilStroke", NULL); RNA_def_struct_sdna(srna, "bGPDstroke"); @@ -177,15 +323,45 @@ static void rna_def_gpencil_stroke(BlenderRNA *brna) RNA_def_property_collection_sdna(prop, NULL, "points", "totpoints"); RNA_def_property_struct_type(prop, "GPencilStrokePoint"); RNA_def_property_ui_text(prop, "Stroke Points", "Stroke data points"); - - /* Flags - Readonly type-info really... */ - /* TODO... */ + rna_def_gpencil_stroke_points_api(brna, prop); + + prop = RNA_def_property(srna, "draw_mode", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag"); + RNA_def_property_enum_items(prop, stroke_draw_mode_items); + RNA_def_property_ui_text(prop, "Draw Mode", ""); + RNA_def_property_update(prop, 0, "rna_GPencil_update"); +} + +static void rna_def_gpencil_strokes_api(BlenderRNA *brna, PropertyRNA *cprop) +{ + StructRNA *srna; + + FunctionRNA *func; + PropertyRNA *parm; + + RNA_def_property_srna(cprop, "GPencilStrokes"); + srna = RNA_def_struct(brna, "GPencilStrokes", NULL); + RNA_def_struct_sdna(srna, "bGPDframe"); + RNA_def_struct_ui_text(srna, "Grease Pencil Frames", "Collection of grease pencil frames"); + + func = RNA_def_function(srna, "new", "rna_GPencil_stroke_new"); + RNA_def_function_ui_description(func, "Add a new grease pencil frame"); + parm = RNA_def_pointer(func, "stroke", "GPencilStroke", "", "The newly created stroke"); + RNA_def_function_return(func, parm); + + func = RNA_def_function(srna, "remove", "rna_GPencil_stroke_remove"); + RNA_def_function_ui_description(func, "Remove a grease pencil frame"); + RNA_def_function_flag(func, FUNC_USE_REPORTS); + parm = RNA_def_pointer(func, "stroke", "GPencilStroke", "Stroke", "The stroke to remove"); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); } static void rna_def_gpencil_frame(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; + + FunctionRNA *func; srna = RNA_def_struct(brna, "GPencilFrame", NULL); RNA_def_struct_sdna(srna, "bGPDframe"); @@ -196,7 +372,8 @@ static void rna_def_gpencil_frame(BlenderRNA *brna) RNA_def_property_collection_sdna(prop, NULL, "strokes", NULL); RNA_def_property_struct_type(prop, "GPencilStroke"); RNA_def_property_ui_text(prop, "Strokes", "Freehand curves defining the sketch on this frame"); - + rna_def_gpencil_strokes_api(brna, prop); + /* Frame Number */ prop = RNA_def_property(srna, "frame_number", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "framenum"); @@ -211,12 +388,51 @@ static void rna_def_gpencil_frame(BlenderRNA *brna) prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_FRAME_SELECT); RNA_def_property_ui_text(prop, "Select", "Frame is selected for editing in the DopeSheet"); + + func = RNA_def_function(srna, "clear", "rna_GPencil_frame_clear"); + RNA_def_function_ui_description(func, "Remove all the grease pencil frame data"); +} + +static void rna_def_gpencil_frames_api(BlenderRNA *brna, PropertyRNA *cprop) +{ + StructRNA *srna; + + FunctionRNA *func; + PropertyRNA *parm; + + RNA_def_property_srna(cprop, "GPencilFrames"); + srna = RNA_def_struct(brna, "GPencilFrames", NULL); + RNA_def_struct_sdna(srna, "bGPDlayer"); + RNA_def_struct_ui_text(srna, "Grease Pencil Frames", "Collection of grease pencil frames"); + + func = RNA_def_function(srna, "new", "rna_GPencil_frame_new"); + RNA_def_function_ui_description(func, "Add a new grease pencil frame"); + RNA_def_function_flag(func, FUNC_USE_REPORTS); + parm = RNA_def_int(func, "frame_number", 1, MINFRAME, MAXFRAME, "Frame Number", "The frame on which this sketch appears", MINFRAME, MAXFRAME); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm = RNA_def_pointer(func, "frame", "GPencilFrame", "", "The newly created frame"); + RNA_def_function_return(func, parm); + + func = RNA_def_function(srna, "remove", "rna_GPencil_frame_remove"); + RNA_def_function_ui_description(func, "Remove a grease pencil frame"); + RNA_def_function_flag(func, FUNC_USE_REPORTS); + parm = RNA_def_pointer(func, "frame", "GPencilFrame", "Frame", "The frame to remove"); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + + func = RNA_def_function(srna, "copy", "rna_GPencil_frame_copy"); + RNA_def_function_ui_description(func, "Copy a grease pencil frame"); + parm = RNA_def_pointer(func, "source", "GPencilFrame", "Source", "The source frame"); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + parm = RNA_def_pointer(func, "copy", "GPencilFrame", "", "The newly copied frame"); + RNA_def_function_return(func, parm); } static void rna_def_gpencil_layer(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; + + FunctionRNA *func; srna = RNA_def_struct(brna, "GPencilLayer", NULL); RNA_def_struct_sdna(srna, "bGPDlayer"); @@ -234,7 +450,8 @@ static void rna_def_gpencil_layer(BlenderRNA *brna) RNA_def_property_collection_sdna(prop, NULL, "frames", NULL); RNA_def_property_struct_type(prop, "GPencilFrame"); RNA_def_property_ui_text(prop, "Frames", "Sketches for this layer on different frames"); - + rna_def_gpencil_frames_api(brna, prop); + /* Active Frame */ prop = RNA_def_property(srna, "active_frame", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "actframe"); @@ -317,9 +534,12 @@ static void rna_def_gpencil_layer(BlenderRNA *brna) RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", GP_LAYER_NO_XRAY); RNA_def_property_ui_text(prop, "X Ray", "Make the layer draw in front of objects"); RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); + + func = RNA_def_function(srna, "clear", "rna_GPencil_layer_clear"); + RNA_def_function_ui_description(func, "Remove all the grease pencil layer data"); } -static void rna_def_gpencil_layers(BlenderRNA *brna, PropertyRNA *cprop) +static void rna_def_gpencil_layers_api(BlenderRNA *brna, PropertyRNA *cprop) { StructRNA *srna; PropertyRNA *prop; @@ -357,7 +577,8 @@ static void rna_def_gpencil_data(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; - + FunctionRNA *func; + static EnumPropertyItem draw_mode_items[] = { {GP_DATA_VIEWALIGN, "CURSOR", 0, "Cursor", "Draw stroke at the 3D cursor"}, {0, "VIEW", 0, "View", "Stick stroke to the view "}, /* weird, GP_DATA_VIEWALIGN is inverted */ @@ -376,7 +597,7 @@ static void rna_def_gpencil_data(BlenderRNA *brna) RNA_def_property_collection_sdna(prop, NULL, "layers", NULL); RNA_def_property_struct_type(prop, "GPencilLayer"); RNA_def_property_ui_text(prop, "Layers", ""); - rna_def_gpencil_layers(brna, prop); + rna_def_gpencil_layers_api(brna, prop); /* Flags */ prop = RNA_def_property(srna, "draw_mode", PROP_ENUM, PROP_NONE); @@ -390,6 +611,8 @@ static void rna_def_gpencil_data(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Only Endpoints", "Only use the first and last parts of the stroke for snapping"); RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); + func = RNA_def_function(srna, "clear", "rna_GPencil_clear"); + RNA_def_function_ui_description(func, "Remove all the grease pencil data"); } /* --- */ diff --git a/source/blender/makesrna/intern/rna_main_api.c b/source/blender/makesrna/intern/rna_main_api.c index f5c59aa583a..cd9b3965713 100644 --- a/source/blender/makesrna/intern/rna_main_api.c +++ b/source/blender/makesrna/intern/rna_main_api.c @@ -71,6 +71,7 @@ #include "BKE_speaker.h" #include "BKE_movieclip.h" #include "BKE_mask.h" +#include "BKE_gpencil.h" #include "DNA_armature_types.h" #include "DNA_camera_types.h" @@ -92,6 +93,7 @@ #include "DNA_node_types.h" #include "DNA_movieclip_types.h" #include "DNA_mask_types.h" +#include "DNA_gpencil_types.h" #include "ED_screen.h" @@ -561,6 +563,19 @@ static void rna_Main_masks_remove(Main *bmain, Mask *mask) /* XXX python now has invalid pointer? */ } +static void rna_Main_grease_pencil_remove(Main *bmain, ReportList *reports, bGPdata *gpd) +{ + if (ID_REAL_USERS(gpd) <= 0) { + BKE_gpencil_free(gpd); + BKE_libblock_free(&bmain->gpencil, gpd); + } + else + BKE_reportf(reports, RPT_ERROR, "Grease Pencil \"%s\" must have zero users to be removed, found %d", + gpd->id.name + 2, ID_REAL_USERS(gpd)); + + /* XXX python now has invalid pointer? */ +} + /* tag functions, all the same */ static void rna_Main_cameras_tag(Main *bmain, int value) { tag_main_lb(&bmain->camera, value); } static void rna_Main_scenes_tag(Main *bmain, int value) { tag_main_lb(&bmain->scene, value); } @@ -1509,6 +1524,20 @@ void RNA_def_main_gpencil(BlenderRNA *brna, PropertyRNA *cprop) parm = RNA_def_boolean(func, "value", 0, "Value", ""); RNA_def_property_flag(parm, PROP_REQUIRED); + func = RNA_def_function(srna, "new", "gpencil_data_addnew"); + RNA_def_function_flag(func, FUNC_NO_SELF); + parm = RNA_def_string(func, "name", "GreasePencil", 0, "", "New name for the datablock"); + RNA_def_property_flag(parm, PROP_REQUIRED); + /* return type */ + parm = RNA_def_pointer(func, "grease_pencil", "GreasePencil", "", "New grease pencil datablock"); + RNA_def_function_return(func, parm); + + func = RNA_def_function(srna, "remove", "rna_Main_grease_pencil_remove"); + RNA_def_function_flag(func, FUNC_USE_REPORTS); + RNA_def_function_ui_description(func, "Remove a grease pencil instance from the current blendfile"); + parm = RNA_def_pointer(func, "grease_pencil", "GreasePencil", "", "Grease Pencil to remove"); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + prop = RNA_def_property(srna, "is_updated", PROP_BOOLEAN, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_boolean_funcs(prop, "rna_Main_gpencil_is_updated_get", NULL); From 2e81400b77a0b8dad99a11ed269ce81b0ea5023e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 7 Oct 2012 23:58:57 +0000 Subject: [PATCH 090/347] minor edit to type checking macro to avoid clangs static checker tagging the var as possibly NULL. --- source/blender/blenlib/BLI_utildefines.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/blenlib/BLI_utildefines.h b/source/blender/blenlib/BLI_utildefines.h index ebb40c18c21..5321de4393b 100644 --- a/source/blender/blenlib/BLI_utildefines.h +++ b/source/blender/blenlib/BLI_utildefines.h @@ -130,7 +130,7 @@ /* can be used in simple macros */ #define CHECK_TYPE_INLINE(val, type) \ - ((void)(((type *)0) == (val))) + ((void)(((type *)0) != (val))) #ifndef SWAP # define SWAP(type, a, b) { \ From ebb8d3996cfe7936d4a9a9ce85223e4d42646e31 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 8 Oct 2012 00:51:55 +0000 Subject: [PATCH 091/347] code cleanup: replace VECADDISFAC with math function. --- source/blender/render/intern/source/shadeinput.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/source/blender/render/intern/source/shadeinput.c b/source/blender/render/intern/source/shadeinput.c index ff543b8ce06..36e9f4cb785 100644 --- a/source/blender/render/intern/source/shadeinput.c +++ b/source/blender/render/intern/source/shadeinput.c @@ -87,12 +87,6 @@ extern struct Render R; * */ -#define VECADDISFAC(v1,v3,fac) { \ - *(v1 + 0) += *(v3 + 0) * (fac); \ - *(v1 + 1) += *(v3 + 1) * (fac); \ - *(v1 + 2) += *(v3 + 2) * (fac); \ -} (void)0 - /* initialize material variables in shadeinput, * doing inverse gamma correction where applicable */ void shade_input_init_material(ShadeInput *shi) @@ -121,13 +115,13 @@ void shade_material_loop(ShadeInput *shi, ShadeResult *shr) shi->depth--; /* a couple of passes */ - VECADDISFAC(shr->combined, shr_t.combined, fac); + madd_v3_v3fl(shr->combined, shr_t.combined, fac); if (shi->passflag & SCE_PASS_SPEC) - VECADDISFAC(shr->spec, shr_t.spec, fac); + madd_v3_v3fl(shr->spec, shr_t.spec, fac); if (shi->passflag & SCE_PASS_DIFFUSE) - VECADDISFAC(shr->diff, shr_t.diff, fac); + madd_v3_v3fl(shr->diff, shr_t.diff, fac); if (shi->passflag & SCE_PASS_SHADOW) - VECADDISFAC(shr->shad, shr_t.shad, fac); + madd_v3_v3fl(shr->shad, shr_t.shad, fac); negate_v3(shi->vn); negate_v3(shi->facenor); From 5807726ca749af5b1a7fc4387febc473349b2789 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 8 Oct 2012 01:05:37 +0000 Subject: [PATCH 092/347] quiet invalid warning in ffmpeg_log_callback with -Wmissing-format-attribute. --- source/blender/imbuf/intern/util.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/source/blender/imbuf/intern/util.c b/source/blender/imbuf/intern/util.c index 833671e3f2f..2d04b7c7413 100644 --- a/source/blender/imbuf/intern/util.c +++ b/source/blender/imbuf/intern/util.c @@ -223,6 +223,10 @@ static int isqtime(const char *name) #ifdef WITH_FFMPEG +/* BLI_vsnprintf in ffmpeg_log_callback() causes invalid warning */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmissing-format-attribute" + static char ffmpeg_last_error[1024]; static void ffmpeg_log_callback(void *ptr, int level, const char *format, va_list arg) @@ -240,6 +244,8 @@ static void ffmpeg_log_callback(void *ptr, int level, const char *format, va_lis } } +#pragma GCC diagnostic pop + void IMB_ffmpeg_init(void) { av_register_all(); From 99dd59f08c4825fb1f97ea7d94b644047466021a Mon Sep 17 00:00:00 2001 From: Mitchell Stokes Date: Mon, 8 Oct 2012 01:25:21 +0000 Subject: [PATCH 093/347] BGE: Disable depth testing when drawing the overhead profile information in the Blenderplayer. This keeps the text from being blocked by geometry in the scene. --- source/gameengine/GamePlayer/common/GPC_RenderTools.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp b/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp index 9cd6715f3d2..4bf81bf543e 100644 --- a/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp +++ b/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp @@ -359,7 +359,8 @@ void GPC_RenderTools::RenderText2D(RAS_TEXT_RENDER_MODE mode, glGetIntegerv(GL_LIGHTING, (GLint*)&light); glDisable(GL_LIGHTING); - + glDisable(GL_DEPTH_TEST); + // Set up viewing settings glMatrixMode(GL_PROJECTION); glPushMatrix(); From 2fd27753506013d602cbafe9fbb99649ba01c26c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 8 Oct 2012 02:20:47 +0000 Subject: [PATCH 094/347] fix for crash in the sequencer if the video file fails to load (missing NULL check on imbuf), all other uses of sequencer_imbuf_assign_spaces() check for NULL or assume IMB_allocImBuf() succeeds. --- source/blender/blenkernel/intern/sequencer.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index 90c3347a1df..49ed7f80be3 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -1965,13 +1965,16 @@ static ImBuf *copy_from_ibuf_still(SeqRenderData context, Sequence *seq, float n static void copy_to_ibuf_still(SeqRenderData context, Sequence *seq, float nr, ImBuf *ibuf) { + /* warning: ibuf may be NULL if the video fails to load */ if (nr == 0 || nr == seq->len - 1) { /* we have to store a copy, since the passed ibuf * could be preprocessed afterwards (thereby silently * changing the cached image... */ ibuf = IMB_dupImBuf(ibuf); - sequencer_imbuf_assign_spaces(context.scene, ibuf); + if (ibuf) { + sequencer_imbuf_assign_spaces(context.scene, ibuf); + } if (nr == 0) { BKE_sequencer_cache_put(context, seq, seq->start, SEQ_STRIPELEM_IBUF_STARTSTILL, ibuf); From aa1e50be946dfeb17f9bb98b242bdbf6775f1ab6 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 8 Oct 2012 02:51:42 +0000 Subject: [PATCH 095/347] add option to build without blenders default avi codec. --- CMakeLists.txt | 2 ++ SConstruct | 1 + build_files/cmake/config/blender_lite.cmake | 1 + source/blender/CMakeLists.txt | 5 +++- source/blender/blenkernel/CMakeLists.txt | 8 +++++- source/blender/blenkernel/intern/writeavi.c | 22 +++++++++++------ source/blender/imbuf/CMakeLists.txt | 8 +++++- source/blender/imbuf/intern/IMB_anim.h | 4 ++- source/blender/imbuf/intern/anim_movie.c | 22 +++++++++++++++-- source/blender/imbuf/intern/indexer.c | 27 +++++++++++++++++---- source/blender/imbuf/intern/util.c | 5 ++++ 11 files changed, 87 insertions(+), 18 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1f0ef41fe59..9ec75e9c782 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -206,6 +206,7 @@ option(WITH_IMAGE_REDCODE "Enable RedCode Image Support" OFF) option(WITH_IMAGE_FRAMESERVER "Enable image FrameServer Support for rendering" ON) # Audio/Video format support +option(WITH_CODEC_AVI "Enable Blenders own AVI file support (raw/jpeg)" ON) option(WITH_CODEC_FFMPEG "Enable FFMPeg Support (http://ffmpeg.org)" OFF) option(WITH_CODEC_SNDFILE "Enable libsndfile Support (http://www.mega-nerd.com/libsndfile)" OFF) @@ -2123,6 +2124,7 @@ if(FIRST_RUN) info_cfg_option(WITH_OPENAL) info_cfg_option(WITH_SDL) info_cfg_option(WITH_JACK) + info_cfg_option(WITH_CODEC_AVI) info_cfg_option(WITH_CODEC_FFMPEG) info_cfg_option(WITH_CODEC_SNDFILE) diff --git a/SConstruct b/SConstruct index 7676b44f759..7b92a0cb25c 100644 --- a/SConstruct +++ b/SConstruct @@ -366,6 +366,7 @@ else: # TODO, make optional env['CPPFLAGS'].append('-DWITH_AUDASPACE') +env['CPPFLAGS'].append('-DWITH_AVI') # lastly we check for root_build_dir ( we should not do before, otherwise we might do wrong builddir B.root_build_dir = env['BF_BUILDDIR'] diff --git a/build_files/cmake/config/blender_lite.cmake b/build_files/cmake/config/blender_lite.cmake index ae07743191b..de3cfd166b7 100644 --- a/build_files/cmake/config/blender_lite.cmake +++ b/build_files/cmake/config/blender_lite.cmake @@ -10,6 +10,7 @@ set(WITH_SYSTEM_GLEW ON CACHE FORCE BOOL) set(WITH_BUILDINFO OFF CACHE FORCE BOOL) set(WITH_BULLET OFF CACHE FORCE BOOL) +set(WITH_CODEC_AVI OFF CACHE FORCE BOOL) set(WITH_CODEC_FFMPEG OFF CACHE FORCE BOOL) set(WITH_CODEC_SNDFILE OFF CACHE FORCE BOOL) set(WITH_CYCLES OFF CACHE FORCE BOOL) diff --git a/source/blender/CMakeLists.txt b/source/blender/CMakeLists.txt index 92785804b01..ae3f3dce396 100644 --- a/source/blender/CMakeLists.txt +++ b/source/blender/CMakeLists.txt @@ -101,7 +101,6 @@ add_subdirectory(blenloader) add_subdirectory(ikplugin) add_subdirectory(gpu) add_subdirectory(imbuf) -add_subdirectory(avi) add_subdirectory(nodes) add_subdirectory(modifiers) add_subdirectory(makesdna) @@ -124,6 +123,10 @@ if(WITH_IMAGE_CINEON) add_subdirectory(imbuf/intern/cineon) endif() +if(WITH_CODEC_AVI) + add_subdirectory(avi) +endif() + if(WITH_CODEC_QUICKTIME) add_subdirectory(quicktime) endif() diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index efdb80433c6..2a1ff49881f 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -25,7 +25,6 @@ set(INC . - ../avi ../blenfont ../blenlib ../blenloader @@ -292,6 +291,13 @@ if(WITH_IMAGE_HDR) add_definitions(-DWITH_HDR) endif() +if(WITH_CODEC_AVI) + list(APPEND INC + ../avi + ) + add_definitions(-DWITH_AVI) +endif() + if(WITH_CODEC_QUICKTIME) list(APPEND INC ../quicktime diff --git a/source/blender/blenkernel/intern/writeavi.c b/source/blender/blenkernel/intern/writeavi.c index dab44b5463c..9f29cb8b137 100644 --- a/source/blender/blenkernel/intern/writeavi.c +++ b/source/blender/blenkernel/intern/writeavi.c @@ -47,7 +47,11 @@ #include "BKE_report.h" #include "BKE_writeavi.h" -#include "AVI_avi.h" + +/* ********************** general blender movie support ***************************** */ + +#ifdef WITH_AVI +# include "AVI_avi.h" /* callbacks */ static int start_avi(Scene *scene, RenderData *rd, int rectx, int recty, ReportList *reports); @@ -55,30 +59,31 @@ static void end_avi(void); static int append_avi(RenderData *rd, int start_frame, int frame, int *pixels, int rectx, int recty, ReportList *reports); static void filepath_avi(char *string, RenderData *rd); - -/* ********************** general blender movie support ***************************** */ +#endif /* WITH_AVI */ #ifdef WITH_QUICKTIME -#include "quicktime_export.h" +# include "quicktime_export.h" #endif #ifdef WITH_FFMPEG -#include "BKE_writeffmpeg.h" +# include "BKE_writeffmpeg.h" #endif #include "BKE_writeframeserver.h" bMovieHandle *BKE_movie_handle_get(const char imtype) { - static bMovieHandle mh; + static bMovieHandle mh = {0}; /* set the default handle, as builtin */ +#ifdef WITH_AVI mh.start_movie = start_avi; mh.append_movie = append_avi; mh.end_movie = end_avi; mh.get_next_frame = NULL; mh.get_movie_path = filepath_avi; - +#endif + /* do the platform specific handles */ #ifdef WITH_QUICKTIME if (imtype == R_IMF_IMTYPE_QUICKTIME) { @@ -114,6 +119,8 @@ bMovieHandle *BKE_movie_handle_get(const char imtype) /* ****************************************************************** */ +#ifdef WITH_AVI + static AviMovie *avi = NULL; static void filepath_avi(char *string, RenderData *rd) @@ -219,6 +226,7 @@ static void end_avi(void) MEM_freeN(avi); avi = NULL; } +#endif /* WITH_AVI */ /* similar to BKE_makepicstring() */ void BKE_movie_filepath_get(char *string, RenderData *rd) diff --git a/source/blender/imbuf/CMakeLists.txt b/source/blender/imbuf/CMakeLists.txt index bbe70a7d73f..344ae604ed4 100644 --- a/source/blender/imbuf/CMakeLists.txt +++ b/source/blender/imbuf/CMakeLists.txt @@ -25,7 +25,6 @@ set(INC . - ../avi ../blenkernel ../blenlib ../blenloader @@ -143,6 +142,13 @@ if(WITH_IMAGE_REDCODE) add_definitions(-DWITH_REDCODE) endif() +if(WITH_CODEC_AVI) + list(APPEND INC + ../avi + ) + add_definitions(-DWITH_AVI) +endif() + if(WITH_CODEC_QUICKTIME) list(APPEND INC ../quicktime diff --git a/source/blender/imbuf/intern/IMB_anim.h b/source/blender/imbuf/intern/IMB_anim.h index d5cc4929aed..ed349e8f7eb 100644 --- a/source/blender/imbuf/intern/IMB_anim.h +++ b/source/blender/imbuf/intern/IMB_anim.h @@ -62,7 +62,9 @@ #include "imbuf.h" -#include "AVI_avi.h" +#ifdef WITH_AVI +# include "AVI_avi.h" +#endif #ifdef WITH_QUICKTIME # if defined(_WIN32) || defined(__APPLE__) diff --git a/source/blender/imbuf/intern/anim_movie.c b/source/blender/imbuf/intern/anim_movie.c index 394f5169046..4aeba9af89d 100644 --- a/source/blender/imbuf/intern/anim_movie.c +++ b/source/blender/imbuf/intern/anim_movie.c @@ -78,7 +78,9 @@ #include "imbuf.h" -#include "AVI_avi.h" +#ifdef WITH_AVI +# include "AVI_avi.h" +#endif #ifdef WITH_QUICKTIME #if defined(_WIN32) || defined(__APPLE__) @@ -185,6 +187,7 @@ static void an_stringenc(char *string, const char *head, const char *tail, unsig BLI_stringenc(string, head, tail, numlen, pic); } +#ifdef WITH_AVI static void free_anim_avi(struct anim *anim) { #if defined(_WIN32) && !defined(FREE_WINDOWS) @@ -219,6 +222,7 @@ static void free_anim_avi(struct anim *anim) anim->duration = 0; } +#endif /* WITH_AVI */ #ifdef WITH_FFMPEG static void free_anim_ffmpeg(struct anim *anim); @@ -235,7 +239,10 @@ void IMB_free_anim(struct anim *anim) } free_anim_movie(anim); + +#ifdef WITH_AVI free_anim_avi(anim); +#endif #ifdef WITH_QUICKTIME free_anim_quicktime(anim); @@ -287,7 +294,7 @@ struct anim *IMB_open_anim(const char *name, int ib_flags, int streamindex, char return(anim); } - +#ifdef WITH_AVI static int startavi(struct anim *anim) { @@ -397,7 +404,9 @@ static int startavi(struct anim *anim) return 0; } +#endif /* WITH_AVI */ +#ifdef WITH_AVI static ImBuf *avi_fetchibuf(struct anim *anim, int position) { ImBuf *ibuf = NULL; @@ -447,6 +456,7 @@ static ImBuf *avi_fetchibuf(struct anim *anim, int position) return ibuf; } +#endif /* WITH_AVI */ #ifdef WITH_FFMPEG @@ -1206,7 +1216,11 @@ static ImBuf *anim_getnew(struct anim *anim) if (anim == NULL) return(NULL); free_anim_movie(anim); + +#ifdef WITH_AVI free_anim_avi(anim); +#endif + #ifdef WITH_QUICKTIME free_anim_quicktime(anim); #endif @@ -1233,6 +1247,7 @@ static ImBuf *anim_getnew(struct anim *anim) if (startmovie(anim)) return (NULL); ibuf = IMB_allocImBuf(anim->x, anim->y, 24, 0); /* fake */ break; +#ifdef WITH_AVI case ANIM_AVI: if (startavi(anim)) { printf("couldnt start avi\n"); @@ -1240,6 +1255,7 @@ static ImBuf *anim_getnew(struct anim *anim) } ibuf = IMB_allocImBuf(anim->x, anim->y, 24, 0); break; +#endif #ifdef WITH_QUICKTIME case ANIM_QTIME: if (startquicktime(anim)) return (0); @@ -1331,11 +1347,13 @@ struct ImBuf *IMB_anim_absolute(struct anim *anim, int position, IMB_convert_rgba_to_abgr(ibuf); } break; +#ifdef WITH_AVI case ANIM_AVI: ibuf = avi_fetchibuf(anim, position); if (ibuf) anim->curposition = position; break; +#endif #ifdef WITH_QUICKTIME case ANIM_QTIME: ibuf = qtime_fetchibuf(anim, position); diff --git a/source/blender/imbuf/intern/indexer.c b/source/blender/imbuf/intern/indexer.c index f35a4345366..593e08062fe 100644 --- a/source/blender/imbuf/intern/indexer.c +++ b/source/blender/imbuf/intern/indexer.c @@ -36,18 +36,19 @@ #include "IMB_indexer.h" #include "IMB_anim.h" -#include "AVI_avi.h" #include "imbuf.h" #include "MEM_guardedalloc.h" #include "DNA_userdef_types.h" #include "BKE_global.h" +#ifdef WITH_AVI +# include "AVI_avi.h" +#endif + #ifdef WITH_FFMPEG - -#include "ffmpeg_compat.h" - -#endif //WITH_FFMPEG +# include "ffmpeg_compat.h" +#endif static char magic[] = "BlenMIdx"; @@ -989,6 +990,7 @@ static int index_rebuild_ffmpeg(FFmpegIndexBuilderContext *context, * - internal AVI (fallback) rebuilder * ---------------------------------------------------------------------- */ +#ifdef WITH_AVI typedef struct FallbackIndexBuilderContext { int anim_type; @@ -1149,6 +1151,8 @@ static void index_rebuild_fallback(FallbackIndexBuilderContext *context, } } +#endif /* WITH_AVI */ + /* ---------------------------------------------------------------------- * - public API * ---------------------------------------------------------------------- */ @@ -1164,15 +1168,19 @@ IndexBuildContext *IMB_anim_index_rebuild_context(struct anim *anim, IMB_Timecod context = index_ffmpeg_create_context(anim, tcs_in_use, proxy_sizes_in_use, quality); break; #endif +#ifdef WITH_AVI default: context = index_fallback_create_context(anim, tcs_in_use, proxy_sizes_in_use, quality); break; +#endif } if (context) context->anim_type = anim->curtype; return context; + + (void)tcs_in_use, (void)proxy_sizes_in_use, (void)quality; } void IMB_anim_index_rebuild(struct IndexBuildContext *context, @@ -1184,10 +1192,14 @@ void IMB_anim_index_rebuild(struct IndexBuildContext *context, index_rebuild_ffmpeg((FFmpegIndexBuilderContext *)context, stop, do_update, progress); break; #endif +#ifdef WITH_AVI default: index_rebuild_fallback((FallbackIndexBuilderContext *)context, stop, do_update, progress); break; +#endif } + + (void)stop, (void)do_update, (void)progress; } void IMB_anim_index_rebuild_finish(IndexBuildContext *context, short stop) @@ -1198,10 +1210,15 @@ void IMB_anim_index_rebuild_finish(IndexBuildContext *context, short stop) index_rebuild_ffmpeg_finish((FFmpegIndexBuilderContext *)context, stop); break; #endif +#ifdef WITH_AVI default: index_rebuild_fallback_finish((FallbackIndexBuilderContext *)context, stop); break; +#endif } + + (void)stop; + (void)proxy_sizes; /* static defined at top of the file */ } diff --git a/source/blender/imbuf/intern/util.c b/source/blender/imbuf/intern/util.c index 2d04b7c7413..8dd791c8508 100644 --- a/source/blender/imbuf/intern/util.c +++ b/source/blender/imbuf/intern/util.c @@ -211,7 +211,12 @@ int IMB_ispic(const char *filename) static int isavi(const char *name) { +#ifdef WITH_AVI return AVI_is_avi(name); +#else + (void)name; + return FALSE; +#endif } #ifdef WITH_QUICKTIME From 244ce92dbd1f32960e0f909933d99cd0e6027dcc Mon Sep 17 00:00:00 2001 From: Mitchell Stokes Date: Mon, 8 Oct 2012 03:28:11 +0000 Subject: [PATCH 096/347] BGE: Setting up the RAS_ICanvas interface as the primary way to alter the OpenGL viewport. This helps to eliminate OpenGL calls in weird places like the physics code and to reduce glGet calls, which are expensive. There should be no functional changes (except maybe a very slight speed improvement). --- .../BlenderRoutines/KX_BlenderCanvas.cpp | 24 +++++++++++++++++++ .../BlenderRoutines/KX_BlenderCanvas.h | 3 +++ .../GamePlayer/common/GPC_Canvas.cpp | 22 +++++++++++++++++ .../gameengine/GamePlayer/common/GPC_Canvas.h | 3 +++ source/gameengine/Ketsji/KX_Camera.cpp | 8 +++---- source/gameengine/Ketsji/KX_Dome.cpp | 5 ++-- source/gameengine/Ketsji/KX_Dome.h | 2 +- source/gameengine/Ketsji/KX_KetsjiEngine.cpp | 3 +-- source/gameengine/Ketsji/KX_Scene.cpp | 10 +++++++- .../Physics/Bullet/CcdPhysicsEnvironment.cpp | 22 +++++++---------- .../Physics/Bullet/CcdPhysicsEnvironment.h | 2 +- .../Physics/Dummy/DummyPhysicsEnvironment.h | 2 +- .../Physics/common/PHY_IPhysicsEnvironment.h | 2 +- .../Rasterizer/RAS_2DFilterManager.cpp | 3 +-- source/gameengine/Rasterizer/RAS_ICanvas.h | 7 ++++++ 15 files changed, 88 insertions(+), 30 deletions(-) diff --git a/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp b/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp index 4f450bcd668..0b41cceb646 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp +++ b/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp @@ -33,6 +33,7 @@ #include "KX_BlenderCanvas.h" #include "DNA_screen_types.h" #include +#include KX_BlenderCanvas::KX_BlenderCanvas(struct wmWindow *win, RAS_Rect &rect, struct ARegion *ar) : @@ -44,6 +45,8 @@ m_frame_rect(rect) // area boundaries needed for mouse coordinates in Letterbox framing mode m_area_left = ar->winrct.xmin; m_area_top = ar->winrct.ymax; + + glGetIntegerv(GL_VIEWPORT, (GLint*)m_viewport); } KX_BlenderCanvas::~KX_BlenderCanvas() @@ -166,10 +169,31 @@ SetViewPort( m_area_rect.SetRight(minx + x2); m_area_rect.SetTop(miny + y2); + m_viewport[0] = minx+x1; + m_viewport[1] = miny+y1; + m_viewport[2] = vp_width; + m_viewport[3] = vp_height; + glViewport(minx + x1, miny + y1, vp_width, vp_height); glScissor(minx + x1, miny + y1, vp_width, vp_height); } + const int* +KX_BlenderCanvas:: +GetViewPort() { +#ifdef DEBUG + // If we're in a debug build, we might as well make sure our values don't differ + // from what the gpu thinks we have. This could lead to nasty, hard to find bugs. + int viewport[4]; + glGetIntegerv(GL_VIEWPORT, viewport); + assert(viewport[0] == m_viewport[0]); + assert(viewport[1] == m_viewport[1]); + assert(viewport[2] == m_viewport[2]); + assert(viewport[3] == m_viewport[3]); +#endif + + return m_viewport; +} void KX_BlenderCanvas::SetMouseState(RAS_MouseState mousestate) { diff --git a/source/gameengine/BlenderRoutines/KX_BlenderCanvas.h b/source/gameengine/BlenderRoutines/KX_BlenderCanvas.h index ee7997abb39..004f7dd0dd9 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderCanvas.h +++ b/source/gameengine/BlenderRoutines/KX_BlenderCanvas.h @@ -61,6 +61,7 @@ private: /** Rect that defines the area used for rendering, relative to the context */ RAS_Rect m_displayarea; + int m_viewport[4]; public: /* Construct a new canvas. @@ -150,6 +151,8 @@ public: int x1, int y1, int x2, int y2 ); + const int* + GetViewPort(); void SetMouseState( diff --git a/source/gameengine/GamePlayer/common/GPC_Canvas.cpp b/source/gameengine/GamePlayer/common/GPC_Canvas.cpp index 7581484a41f..b5c1c29238a 100644 --- a/source/gameengine/GamePlayer/common/GPC_Canvas.cpp +++ b/source/gameengine/GamePlayer/common/GPC_Canvas.cpp @@ -57,6 +57,8 @@ GPC_Canvas::GPC_Canvas( m_displayarea.m_y1 = 0; m_displayarea.m_x2 = width; m_displayarea.m_y2 = height; + + glGetIntegerv(GL_VIEWPORT, (GLint*)m_viewport); } @@ -121,11 +123,31 @@ void GPC_Canvas::SetViewPort(int x1, int y1, int x2, int y2) * whole canvas/rendertools mess. */ glEnable(GL_SCISSOR_TEST); + + m_viewport[0] = x1; + m_viewport[1] = y1; + m_viewport[2] = x2-x1 + 1; + m_viewport[3] = y2-y1 + 1; glViewport(x1,y1,x2-x1 + 1,y2-y1 + 1); glScissor(x1,y1,x2-x1 + 1,y2-y1 + 1); }; +const int *GPC_Canvas::GetViewPort() +{ +#ifdef DEBUG + // If we're in a debug build, we might as well make sure our values don't differ + // from what the gpu thinks we have. This could lead to nasty, hard to find bugs. + int viewport[4]; + glGetIntegerv(GL_VIEWPORT, viewport); + assert(viewport[0] == m_viewport[0]); + assert(viewport[1] == m_viewport[1]); + assert(viewport[2] == m_viewport[2]); + assert(viewport[3] == m_viewport[3]); +#endif + + return m_viewport; +} void GPC_Canvas::ClearBuffer( int type diff --git a/source/gameengine/GamePlayer/common/GPC_Canvas.h b/source/gameengine/GamePlayer/common/GPC_Canvas.h index 453b9505183..2a597c4c43d 100644 --- a/source/gameengine/GamePlayer/common/GPC_Canvas.h +++ b/source/gameengine/GamePlayer/common/GPC_Canvas.h @@ -90,6 +90,8 @@ protected: * relative to the context */ RAS_Rect m_displayarea; + int *m_viewport; + /** Storage for the banners to display. */ TBannerMap m_banners; /** State of banner display. */ @@ -153,6 +155,7 @@ public: ); void SetViewPort(int x1, int y1, int x2, int y2); + const int *GetViewPort(); void ClearColor(float r, float g, float b, float a); diff --git a/source/gameengine/Ketsji/KX_Camera.cpp b/source/gameengine/Ketsji/KX_Camera.cpp index c0071ab22f6..90912409af1 100644 --- a/source/gameengine/Ketsji/KX_Camera.cpp +++ b/source/gameengine/Ketsji/KX_Camera.cpp @@ -956,7 +956,7 @@ KX_PYMETHODDEF_DOC_O(KX_Camera, getScreenPosition, } } - GLint viewport[4]; + const GLint *viewport; GLdouble win[3]; GLdouble modelmatrix[16]; GLdouble projmatrix[16]; @@ -967,7 +967,7 @@ KX_PYMETHODDEF_DOC_O(KX_Camera, getScreenPosition, m_modelmatrix.getValue(modelmatrix); m_projmatrix.getValue(projmatrix); - glGetIntegerv(GL_VIEWPORT, viewport); + viewport = KX_GetActiveEngine()->GetCanvas()->GetViewPort(); gluProject(vect[0], vect[1], vect[2], modelmatrix, projmatrix, viewport, &win[0], &win[1], &win[2]); @@ -999,7 +999,7 @@ KX_PYMETHODDEF_DOC_VARARGS(KX_Camera, getScreenVect, MT_Vector3 vect; MT_Point3 campos, screenpos; - GLint viewport[4]; + const GLint *viewport; GLdouble win[3]; GLdouble modelmatrix[16]; GLdouble projmatrix[16]; @@ -1010,7 +1010,7 @@ KX_PYMETHODDEF_DOC_VARARGS(KX_Camera, getScreenVect, m_modelmatrix.getValue(modelmatrix); m_projmatrix.getValue(projmatrix); - glGetIntegerv(GL_VIEWPORT, viewport); + viewport = KX_GetActiveEngine()->GetCanvas()->GetViewPort(); vect[0] = x * viewport[2]; vect[1] = y * viewport[3]; diff --git a/source/gameengine/Ketsji/KX_Dome.cpp b/source/gameengine/Ketsji/KX_Dome.cpp index fd3a18a9d2a..87b0cfc1269 100644 --- a/source/gameengine/Ketsji/KX_Dome.cpp +++ b/source/gameengine/Ketsji/KX_Dome.cpp @@ -90,8 +90,7 @@ KX_Dome::KX_Dome ( } //setting the viewport size - GLuint viewport[4]={0}; - glGetIntegerv(GL_VIEWPORT,(GLint *)viewport); + const int *viewport = m_canvas->GetViewPort(); SetViewPort(viewport); @@ -178,7 +177,7 @@ KX_Dome::~KX_Dome (void) glDeleteLists(dlistId, (GLsizei) m_numimages); } -void KX_Dome::SetViewPort(GLuint viewport[4]) +void KX_Dome::SetViewPort(const int viewport[4]) { if (canvaswidth != m_viewport.GetWidth() || canvasheight != m_viewport.GetHeight()) { diff --git a/source/gameengine/Ketsji/KX_Dome.h b/source/gameengine/Ketsji/KX_Dome.h index 24177af5d60..17eec3a5fcb 100644 --- a/source/gameengine/Ketsji/KX_Dome.h +++ b/source/gameengine/Ketsji/KX_Dome.h @@ -119,7 +119,7 @@ public: void RenderDomeFrame(KX_Scene* scene, KX_Camera* cam, int i); void BindImages(int i); - void SetViewPort(GLuint viewport[4]); + void SetViewPort(const int viewport[4]); void CalculateFrustum(KX_Camera* cam); void RotateCamera(KX_Camera* cam, int i); diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp index c2857141058..e446e5338bc 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp @@ -275,8 +275,7 @@ void KX_KetsjiEngine::InitDome(short res, short mode, short angle, float resbuf, void KX_KetsjiEngine::RenderDome() { - GLuint viewport[4]={0}; - glGetIntegerv(GL_VIEWPORT,(GLint *)viewport); + const GLint *viewport = m_canvas->GetViewPort(); m_dome->SetViewPort(viewport); diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp index a4237f9fabe..f6ab9af261e 100644 --- a/source/gameengine/Ketsji/KX_Scene.cpp +++ b/source/gameengine/Ketsji/KX_Scene.cpp @@ -1502,7 +1502,15 @@ void KX_Scene::CalculateVisibleMeshes(RAS_IRasterizer* rasty,KX_Camera* cam, int planes[4].setValue(cplanes[2].getValue()); // top planes[5].setValue(cplanes[3].getValue()); // bottom CullingInfo info(layer); - dbvt_culling = m_physicsEnvironment->cullingTest(PhysicsCullingCallback,&info,planes,5,m_dbvt_occlusion_res); + + double mvmat[16] = {0}; + cam->GetModelviewMatrix().getValue(mvmat); + double pmat[16] = {0}; + cam->GetProjectionMatrix().getValue(pmat); + + dbvt_culling = m_physicsEnvironment->cullingTest(PhysicsCullingCallback,&info,planes,5,m_dbvt_occlusion_res, + KX_GetActiveEngine()->GetCanvas()->GetViewPort(), + mvmat, pmat); } if (!dbvt_culling) { // the physics engine couldn't help us, do it the hard way diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp index 55bbc0d33b9..82a60e756d7 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp +++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp @@ -57,7 +57,6 @@ btRaycastVehicle::btVehicleTuning gTuning; #include "LinearMath/btAabbUtil2.h" #include "MT_Matrix4x4.h" #include "MT_Vector3.h" -#include "GL/glew.h" #ifdef WIN32 void DrawRasterizerLine(const float* from,const float* to,int color); @@ -1309,22 +1308,19 @@ struct OcclusionBuffer m[14] = btScalar(m1[ 2]*m2[12]+m1[ 6]*m2[13]+m1[10]*m2[14]+m1[14]*m2[15]); m[15] = btScalar(m1[ 3]*m2[12]+m1[ 7]*m2[13]+m1[11]*m2[14]+m1[15]*m2[15]); } - void setup(int size) + void setup(int size, const int *view, double modelview[16], double projection[16]) { m_initialized=false; m_occlusion=false; // compute the size of the buffer - GLint v[4]; - GLdouble m[16],p[16]; int maxsize; double ratio; - glGetIntegerv(GL_VIEWPORT,v); - maxsize = (v[2] > v[3]) ? v[2] : v[3]; + maxsize = (view[2] > view[3]) ? view[2] : view[3]; assert(maxsize > 0); ratio = 1.0/(2*maxsize); // ensure even number - m_sizes[0] = 2*((int)(size*v[2]*ratio+0.5)); - m_sizes[1] = 2*((int)(size*v[3]*ratio+0.5)); + m_sizes[0] = 2*((int)(size*view[2]*ratio+0.5)); + m_sizes[1] = 2*((int)(size*view[3]*ratio+0.5)); m_scales[0]=btScalar(m_sizes[0]/2); m_scales[1]=btScalar(m_sizes[1]/2); m_offsets[0]=m_scales[0]+0.5f; @@ -1332,10 +1328,8 @@ struct OcclusionBuffer // prepare matrix // at this time of the rendering, the modelview matrix is the // world to camera transformation and the projection matrix is - // camera to clip transformation. combine both so that - glGetDoublev(GL_MODELVIEW_MATRIX,m); - glGetDoublev(GL_PROJECTION_MATRIX,p); - CMmat4mul(m_wtc,p,m); + // camera to clip transformation. combine both so that + CMmat4mul(m_wtc, projection, modelview); } void initialize() { @@ -1795,7 +1789,7 @@ struct DbvtCullingCallback : btDbvt::ICollide }; static OcclusionBuffer gOcb; -bool CcdPhysicsEnvironment::cullingTest(PHY_CullingCallback callback, void* userData, PHY__Vector4 *planes, int nplanes, int occlusionRes) +bool CcdPhysicsEnvironment::cullingTest(PHY_CullingCallback callback, void* userData, PHY__Vector4 *planes, int nplanes, int occlusionRes, const int *viewport, double modelview[16], double projection[16]) { if (!m_cullingTree) return false; @@ -1812,7 +1806,7 @@ bool CcdPhysicsEnvironment::cullingTest(PHY_CullingCallback callback, void* user // if occlusionRes != 0 => occlusion culling if (occlusionRes) { - gOcb.setup(occlusionRes); + gOcb.setup(occlusionRes, viewport, modelview, projection); dispatcher.m_ocb = &gOcb; // occlusion culling, the direction of the view is taken from the first plan which MUST be the near plane btDbvt::collideOCL(m_cullingTree->m_sets[1].m_root,planes_n,planes_o,planes_n[0],nplanes,dispatcher); diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h index 59e40a6f91a..453380b69ca 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h +++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h @@ -188,7 +188,7 @@ protected: btTypedConstraint* getConstraintById(int constraintId); virtual PHY_IPhysicsController* rayTest(PHY_IRayCastFilterCallback &filterCallback, float fromX,float fromY,float fromZ, float toX,float toY,float toZ); - virtual bool cullingTest(PHY_CullingCallback callback, void* userData, PHY__Vector4* planes, int nplanes, int occlusionRes); + virtual bool cullingTest(PHY_CullingCallback callback, void* userData, PHY__Vector4* planes, int nplanes, int occlusionRes, const int *viewport, double modelview[16], double projection[16]); //Methods for gamelogic collision/physics callbacks diff --git a/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h b/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h index 9c109168b18..4ddfe4d69e0 100644 --- a/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h +++ b/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h @@ -73,7 +73,7 @@ public: } virtual PHY_IPhysicsController* rayTest(PHY_IRayCastFilterCallback &filterCallback, float fromX,float fromY,float fromZ, float toX,float toY,float toZ); - virtual bool cullingTest(PHY_CullingCallback callback, void* userData, PHY__Vector4* planes, int nplanes, int occlusionRes) { return false; } + virtual bool cullingTest(PHY_CullingCallback callback, void* userData, PHY__Vector4* planes, int nplanes, int occlusionRes, const int *viewport, double modelview[16], double projection[16]) { return false; } //gamelogic callbacks diff --git a/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h b/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h index 3f8699d25d2..77016859c3f 100644 --- a/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h +++ b/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h @@ -161,7 +161,7 @@ class PHY_IPhysicsEnvironment //culling based on physical broad phase // the plane number must be set as follow: near, far, left, right, top, botton // the near plane must be the first one and must always be present, it is used to get the direction of the view - virtual bool cullingTest(PHY_CullingCallback callback, void *userData, PHY__Vector4* planeNormals, int planeNumber, int occlusionRes) = 0; + virtual bool cullingTest(PHY_CullingCallback callback, void *userData, PHY__Vector4* planeNormals, int planeNumber, int occlusionRes, const int *viewport, double modelview[16], double projection[16]) = 0; //Methods for gamelogic collision/physics callbacks //todo: diff --git a/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp b/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp index 7312b521788..0ae8908e946 100644 --- a/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp +++ b/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp @@ -398,8 +398,7 @@ void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas) if (num_filters <= 0) return; - GLuint viewport[4]={0}; - glGetIntegerv(GL_VIEWPORT,(GLint *)viewport); + const GLint *viewport = canvas->GetViewPort(); RAS_Rect rect = canvas->GetWindowArea(); int rect_width = rect.GetWidth()+1, rect_height = rect.GetHeight()+1; diff --git a/source/gameengine/Rasterizer/RAS_ICanvas.h b/source/gameengine/Rasterizer/RAS_ICanvas.h index 713a06845ac..f045eb7e423 100644 --- a/source/gameengine/Rasterizer/RAS_ICanvas.h +++ b/source/gameengine/Rasterizer/RAS_ICanvas.h @@ -180,6 +180,13 @@ public: int x2, int y2 ) = 0; + /** + * Get the visible viewport + */ + virtual + const int* + GetViewPort() = 0; + virtual void SetMouseState( From d0f702df8f5c483d3617a25c50076e97060b991a Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 8 Oct 2012 03:33:02 +0000 Subject: [PATCH 097/347] fix [#32799] right click select in filebrowser breaks opening folders own regression since 2.63, The path length for FILE_OT_select_bookmark was too short as well (256 --> FILE_MAXDIR). --- source/blender/editors/space_file/file_ops.c | 39 ++++++++++++++------ 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c index fcbeb064e4d..7a364eb8685 100644 --- a/source/blender/editors/space_file/file_ops.c +++ b/source/blender/editors/space_file/file_ops.c @@ -307,7 +307,7 @@ void FILE_OT_select_border(wmOperatorType *ot) ot->poll = ED_operator_file_active; ot->cancel = WM_border_select_cancel; - /* rna */ + /* properties */ WM_operator_properties_gesture_border(ot, 1); } @@ -347,6 +347,8 @@ static int file_select_invoke(bContext *C, wmOperator *op, wmEvent *event) void FILE_OT_select(wmOperatorType *ot) { + PropertyRNA *prop; + /* identifiers */ ot->name = "Activate/Select File"; ot->description = "Activate/select file"; @@ -356,10 +358,13 @@ void FILE_OT_select(wmOperatorType *ot) ot->invoke = file_select_invoke; ot->poll = ED_operator_file_active; - /* rna */ - RNA_def_boolean(ot->srna, "extend", FALSE, "Extend", "Extend selection instead of deselecting everything first"); - RNA_def_boolean(ot->srna, "fill", FALSE, "Fill", "Select everything beginning with the last selection"); - RNA_def_boolean(ot->srna, "open", TRUE, "Open", "Open a directory when selecting it"); + /* properties */ + prop = RNA_def_boolean(ot->srna, "extend", FALSE, "Extend", "Extend selection instead of deselecting everything first"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); + prop = RNA_def_boolean(ot->srna, "fill", FALSE, "Fill", "Select everything beginning with the last selection"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); + prop = RNA_def_boolean(ot->srna, "open", TRUE, "Open", "Open a directory when selecting it"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); } static int file_select_all_exec(bContext *C, wmOperator *UNUSED(op)) @@ -404,9 +409,7 @@ void FILE_OT_select_all_toggle(wmOperatorType *ot) ot->exec = file_select_all_exec; ot->poll = ED_operator_file_active; - /* rna */ - - + /* properties */ } /* ---------- BOOKMARKS ----------- */ @@ -432,6 +435,8 @@ static int bookmark_select_exec(bContext *C, wmOperator *op) void FILE_OT_select_bookmark(wmOperatorType *ot) { + PropertyRNA *prop; + /* identifiers */ ot->name = "Select Directory"; ot->description = "Select a bookmarked directory"; @@ -441,7 +446,9 @@ void FILE_OT_select_bookmark(wmOperatorType *ot) ot->exec = bookmark_select_exec; ot->poll = ED_operator_file_active; - RNA_def_string(ot->srna, "dir", "", 256, "Dir", ""); + /* properties */ + prop = RNA_def_string(ot->srna, "dir", "", FILE_MAXDIR, "Dir", ""); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); } static int bookmark_add_exec(bContext *C, wmOperator *UNUSED(op)) @@ -498,6 +505,8 @@ static int bookmark_delete_exec(bContext *C, wmOperator *op) void FILE_OT_delete_bookmark(wmOperatorType *ot) { + PropertyRNA *prop; + /* identifiers */ ot->name = "Delete Bookmark"; ot->description = "Delete selected bookmark"; @@ -507,7 +516,9 @@ void FILE_OT_delete_bookmark(wmOperatorType *ot) ot->exec = bookmark_delete_exec; ot->poll = ED_operator_file_active; - RNA_def_int(ot->srna, "index", -1, -1, 20000, "Index", "", -1, 20000); + /* properties */ + prop = RNA_def_int(ot->srna, "index", -1, -1, 20000, "Index", "", -1, 20000); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); } static int reset_recent_exec(bContext *C, wmOperator *UNUSED(op)) @@ -819,7 +830,8 @@ void FILE_OT_execute(struct wmOperatorType *ot) /* api callbacks */ ot->exec = file_exec; ot->poll = file_operator_poll; - + + /* properties */ prop = RNA_def_boolean(ot->srna, "need_active", 0, "Need Active", "Only execute if there's an active selected file in the file list"); RNA_def_property_flag(prop, PROP_SKIP_SAVE); @@ -1123,6 +1135,8 @@ int file_directory_new_exec(bContext *C, wmOperator *op) void FILE_OT_directory_new(struct wmOperatorType *ot) { + PropertyRNA *prop; + /* identifiers */ ot->name = "Create New Directory"; ot->description = "Create a new directory"; @@ -1133,7 +1147,8 @@ void FILE_OT_directory_new(struct wmOperatorType *ot) ot->exec = file_directory_new_exec; ot->poll = ED_operator_file_active; /* <- important, handler is on window level */ - RNA_def_string_dir_path(ot->srna, "directory", "", FILE_MAX, "Directory", "Name of new directory"); + prop = RNA_def_string_dir_path(ot->srna, "directory", "", FILE_MAX, "Directory", "Name of new directory"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); } From 718dea866588b13af6c362bed1bc6e33588fafe3 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Mon, 8 Oct 2012 04:42:06 +0000 Subject: [PATCH 098/347] Patch [#32639] Pose breakdown confirm by Return Key Thanks Julien DUROURE (julien) --- source/blender/editors/armature/poseSlide.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source/blender/editors/armature/poseSlide.c b/source/blender/editors/armature/poseSlide.c index cdcb3ab4683..31398948b82 100644 --- a/source/blender/editors/armature/poseSlide.c +++ b/source/blender/editors/armature/poseSlide.c @@ -631,6 +631,7 @@ static int pose_slide_modal(bContext *C, wmOperator *op, wmEvent *evt) switch (evt->type) { case LEFTMOUSE: /* confirm */ + case RETKEY: { /* return to normal cursor and header status */ ED_area_headerprint(pso->sa, NULL); From 565e7c8e3cbb4aee0c1b8f17b43f63055c4384f7 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Mon, 8 Oct 2012 05:57:52 +0000 Subject: [PATCH 099/347] Display enum descriptions in tooltips for operators using a "type" or "mode" property Changes: This commit adds a second line to the tooltips (below the generic operator description) showing the appropriate description for each enum option. This brings it more into line enum properties in Blender which also show this sort of information. Rationale: Operators such as Snap and Mirror in the Action and Graph Editors use an enum to control their behaviour (respectively, "how to snap" or "what to use as the mirror line"). In the menus, these options are displayed using a submenu, but hovering over each of these items for more information from a tooltip only shows the (relatively unhelpful) generic operator tooltip/description. Another area where these descriptions are useful is for Keying Sets, where it's now possible to see the descriptions for what each Keying Set does/affects/requires. Again, this is more helpful than just the generic tooltip, which would be something like "Insert keyframes using a Keying Set". --- source/blender/editors/interface/interface.c | 35 +++++++++++++++++-- .../editors/space_action/action_edit.c | 27 +++++++------- .../blender/editors/space_graph/graph_edit.c | 33 +++++++++++------ 3 files changed, 69 insertions(+), 26 deletions(-) diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index df18498559e..d442ce1b04b 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -3869,12 +3869,41 @@ void uiButGetStrInfo(bContext *C, uiBut *but, int nbr, ...) } } else if (ELEM3(type, BUT_GET_RNAENUM_IDENTIFIER, BUT_GET_RNAENUM_LABEL, BUT_GET_RNAENUM_TIP)) { + PointerRNA *ptr = NULL; + PropertyRNA *prop = NULL; + int value = 0; + + /* get the enum property... */ if (but->rnaprop && RNA_property_type(but->rnaprop) == PROP_ENUM) { + /* enum property */ + ptr = &but->rnapoin; + prop = but->rnaprop; + value = (but->type == ROW) ? (int)but->hardmax : (int)ui_get_but_val(but); + } + else if (but->optype) { + PointerRNA *opptr = uiButGetOperatorPtrRNA(but); + wmOperatorType *ot = but->optype; + + /* if the default property of the operator is enum and it is set, + * fetch the tooltip of the selected value so that "Snap" and "Mirror" + * operator menus in the Anim Editors will show tooltips for the different + * operations instead of the meaningless generic operator tooltip + */ + if (ot->prop && RNA_property_type(ot->prop) == PROP_ENUM) { + if (RNA_struct_contains_property(opptr, ot->prop)) { + ptr = opptr; + prop = ot->prop; + value = RNA_property_enum_get(opptr, ot->prop); + } + } + } + + /* get strings from matching enum item */ + if (ptr && prop) { if (!item) { int i; - int value = (but->type == ROW) ? (int)but->hardmax : (int)ui_get_but_val(but); - RNA_property_enum_items_gettexted(C, &but->rnapoin, but->rnaprop, &items, &totitems, &free_items); - + + RNA_property_enum_items_gettexted(C, ptr, prop, &items, &totitems, &free_items); for (i = 0, item = items; i < totitems; i++, item++) { if (item->identifier[0] && item->value == value) break; diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c index 7635f85a37e..3865234a25d 100644 --- a/source/blender/editors/space_action/action_edit.c +++ b/source/blender/editors/space_action/action_edit.c @@ -1369,10 +1369,14 @@ void ACTION_OT_frame_jump(wmOperatorType *ot) /* defines for snap keyframes tool */ static EnumPropertyItem prop_actkeys_snap_types[] = { - {ACTKEYS_SNAP_CFRA, "CFRA", 0, "Current frame", ""}, - {ACTKEYS_SNAP_NEAREST_FRAME, "NEAREST_FRAME", 0, "Nearest Frame", ""}, // XXX as single entry? - {ACTKEYS_SNAP_NEAREST_SECOND, "NEAREST_SECOND", 0, "Nearest Second", ""}, // XXX as single entry? - {ACTKEYS_SNAP_NEAREST_MARKER, "NEAREST_MARKER", 0, "Nearest Marker", ""}, + {ACTKEYS_SNAP_CFRA, "CFRA", 0, "Current frame", + "Snap selected keyframes to the current frame"}, + {ACTKEYS_SNAP_NEAREST_FRAME, "NEAREST_FRAME", 0, "Nearest Frame", + "Snap selected keyframes to the nearest (whole) frame. Use to fix accidental sub-frame offsets"}, + {ACTKEYS_SNAP_NEAREST_SECOND, "NEAREST_SECOND", 0, "Nearest Second", + "Snap selected keyframes to the nearest second"}, + {ACTKEYS_SNAP_NEAREST_MARKER, "NEAREST_MARKER", 0, "Nearest Marker", + "Snap selected keyframes to the nearest marker"}, {0, NULL, 0, NULL, NULL} }; @@ -1473,9 +1477,12 @@ void ACTION_OT_snap(wmOperatorType *ot) /* defines for mirror keyframes tool */ static EnumPropertyItem prop_actkeys_mirror_types[] = { - {ACTKEYS_MIRROR_CFRA, "CFRA", 0, "By Times over Current frame", ""}, - {ACTKEYS_MIRROR_XAXIS, "XAXIS", 0, "By Values over Value=0", ""}, - {ACTKEYS_MIRROR_MARKER, "MARKER", 0, "By Times over First Selected Marker", ""}, + {ACTKEYS_MIRROR_CFRA, "CFRA", 0, "By Times over Current frame", + "Flip times of selected keyframes using the current frame as the mirror line"}, + {ACTKEYS_MIRROR_XAXIS, "XAXIS", 0, "By Values over Value=0", + "Flip values of selected keyframes (i.e. negative values become positive, and vica versa)"}, + {ACTKEYS_MIRROR_MARKER, "MARKER", 0, "By Times over First Selected Marker", + "Flip times of selected keyframes using the first selected marker as the reference point"}, {0, NULL, 0, NULL, NULL} }; @@ -1497,12 +1504,8 @@ static void mirror_action_keys(bAnimContext *ac, short mode) /* for 'first selected marker' mode, need to find first selected marker first! */ // XXX should this be made into a helper func in the API? if (mode == ACTKEYS_MIRROR_MARKER) { - TimeMarker *marker = NULL; + TimeMarker *marker = ED_markers_get_first_selected(ac->markers); - /* find first selected marker */ - marker = ED_markers_get_first_selected(ac->markers); - - /* store marker's time (if available) */ if (marker) ked.f1 = (float)marker->frame; else diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c index 7107a6a2369..bff64f8348f 100644 --- a/source/blender/editors/space_graph/graph_edit.c +++ b/source/blender/editors/space_graph/graph_edit.c @@ -1824,12 +1824,18 @@ void GRAPH_OT_frame_jump(wmOperatorType *ot) /* defines for snap keyframes tool */ static EnumPropertyItem prop_graphkeys_snap_types[] = { - {GRAPHKEYS_SNAP_CFRA, "CFRA", 0, "Current Frame", ""}, - {GRAPHKEYS_SNAP_VALUE, "VALUE", 0, "Cursor Value", ""}, - {GRAPHKEYS_SNAP_NEAREST_FRAME, "NEAREST_FRAME", 0, "Nearest Frame", ""}, // XXX as single entry? - {GRAPHKEYS_SNAP_NEAREST_SECOND, "NEAREST_SECOND", 0, "Nearest Second", ""}, // XXX as single entry? - {GRAPHKEYS_SNAP_NEAREST_MARKER, "NEAREST_MARKER", 0, "Nearest Marker", ""}, - {GRAPHKEYS_SNAP_HORIZONTAL, "HORIZONTAL", 0, "Flatten Handles", ""}, + {GRAPHKEYS_SNAP_CFRA, "CFRA", 0, "Current Frame", + "Snap selected keyframes to the current frame"}, + {GRAPHKEYS_SNAP_VALUE, "VALUE", 0, "Cursor Value", + "Set values of selected keyframes to the cursor value (Y/Horizontal component)"}, + {GRAPHKEYS_SNAP_NEAREST_FRAME, "NEAREST_FRAME", 0, "Nearest Frame", + "Snap selected keyframes to the nearest (whole) frame. Use to fix accidental sub-frame offsets"}, + {GRAPHKEYS_SNAP_NEAREST_SECOND, "NEAREST_SECOND", 0, "Nearest Second", + "Snap selected keyframes to the nearest second"}, + {GRAPHKEYS_SNAP_NEAREST_MARKER, "NEAREST_MARKER", 0, "Nearest Marker", + "Snap selected keyframes to the nearest marker"}, + {GRAPHKEYS_SNAP_HORIZONTAL, "HORIZONTAL", 0, "Flatten Handles", + "Flatten handles for a smoother transition"}, {0, NULL, 0, NULL, NULL} }; @@ -1932,11 +1938,16 @@ void GRAPH_OT_snap(wmOperatorType *ot) /* defines for mirror keyframes tool */ static EnumPropertyItem prop_graphkeys_mirror_types[] = { - {GRAPHKEYS_MIRROR_CFRA, "CFRA", 0, "By Times over Current Frame", ""}, - {GRAPHKEYS_MIRROR_VALUE, "VALUE", 0, "By Values over Cursor Value", ""}, - {GRAPHKEYS_MIRROR_YAXIS, "YAXIS", 0, "By Times over Time=0", ""}, - {GRAPHKEYS_MIRROR_XAXIS, "XAXIS", 0, "By Values over Value=0", ""}, - {GRAPHKEYS_MIRROR_MARKER, "MARKER", 0, "By Times over First Selected Marker", ""}, + {GRAPHKEYS_MIRROR_CFRA, "CFRA", 0, "By Times over Current Frame", + "Flip times of selected keyframes using the current frame as the mirror line"}, + {GRAPHKEYS_MIRROR_VALUE, "VALUE", 0, "By Values over Cursor Value", + "Flip values of selectd keyframes using the cursor value (Y/Horizontal component) as the mirror line"}, + {GRAPHKEYS_MIRROR_YAXIS, "YAXIS", 0, "By Times over Time=0", + "Flip times of selected keyframes, effectively reversing the order they appear in"}, + {GRAPHKEYS_MIRROR_XAXIS, "XAXIS", 0, "By Values over Value=0", + "Flip values of selected keyframes (i.e. negative values become positive, and vica versa)"}, + {GRAPHKEYS_MIRROR_MARKER, "MARKER", 0, "By Times over First Selected Marker", + "Flip times of selected keyframes using the first selected marker as the reference point"}, {0, NULL, 0, NULL, NULL} }; From 8b765373e1c33a38848f7b0a4082a9f195e5f420 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Mon, 8 Oct 2012 06:21:36 +0000 Subject: [PATCH 100/347] Bugfix: No enum tooltips displayed for many 3D view navigation tools (+ Code cleanup) * Enum tooltips will only be detected in the case that we assign that as the default property (ot->prop) of the operator. Set all of the offending properties to get this status, since those operators would be useless without that property anyway * Improved the wording/capitalisation of a few of these tooltips and labels --- .../editors/space_view3d/view3d_edit.c | 22 +++++++++++-------- .../editors/space_view3d/view3d_view.c | 1 - 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 504f746637e..4e8981f16bd 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -966,7 +966,6 @@ static int viewrotate_cancel(bContext *C, wmOperator *op) void VIEW3D_OT_rotate(wmOperatorType *ot) { - /* identifiers */ ot->name = "Rotate view"; ot->description = "Rotate the view"; @@ -2901,7 +2900,7 @@ static EnumPropertyItem prop_view_items[] = { {RV3D_VIEW_RIGHT, "RIGHT", 0, "Right", "View From the Right"}, {RV3D_VIEW_TOP, "TOP", 0, "Top", "View From the Top"}, {RV3D_VIEW_BOTTOM, "BOTTOM", 0, "Bottom", "View From the Bottom"}, - {RV3D_VIEW_CAMERA, "CAMERA", 0, "Camera", "View From the active camera"}, + {RV3D_VIEW_CAMERA, "CAMERA", 0, "Camera", "View From the Active Camera"}, {0, NULL, 0, NULL, NULL} }; @@ -3125,7 +3124,7 @@ void VIEW3D_OT_viewnumpad(wmOperatorType *ot) /* identifiers */ ot->name = "View numpad"; - ot->description = "Set the view"; + ot->description = "Use a preset viewpoint"; ot->idname = "VIEW3D_OT_viewnumpad"; /* api callbacks */ @@ -3135,8 +3134,8 @@ void VIEW3D_OT_viewnumpad(wmOperatorType *ot) /* flags */ ot->flag = 0; - prop = RNA_def_enum(ot->srna, "type", prop_view_items, 0, "View", "The Type of view"); - RNA_def_property_flag(prop, PROP_SKIP_SAVE); + ot->prop = RNA_def_enum(ot->srna, "type", prop_view_items, 0, "View", "Preset viewpoint to use"); + RNA_def_property_flag(ot->prop, PROP_SKIP_SAVE); prop = RNA_def_boolean(ot->srna, "align_active", 0, "Align Active", "Align to the active object's axis"); RNA_def_property_flag(prop, PROP_SKIP_SAVE); } @@ -3213,7 +3212,9 @@ void VIEW3D_OT_view_orbit(wmOperatorType *ot) /* flags */ ot->flag = 0; - RNA_def_enum(ot->srna, "type", prop_view_orbit_items, 0, "Orbit", "Direction of View Orbit"); + + /* properties */ + ot->prop = RNA_def_enum(ot->srna, "type", prop_view_orbit_items, 0, "Orbit", "Direction of View Orbit"); } static EnumPropertyItem prop_view_pan_items[] = { @@ -3262,7 +3263,9 @@ void VIEW3D_OT_view_pan(wmOperatorType *ot) /* flags */ ot->flag = 0; - RNA_def_enum(ot->srna, "type", prop_view_pan_items, 0, "Pan", "Direction of View Pan"); + + /* Properties */ + ot->prop = RNA_def_enum(ot->srna, "type", prop_view_pan_items, 0, "Pan", "Direction of View Pan"); } static int viewpersportho_exec(bContext *C, wmOperator *UNUSED(op)) @@ -3290,7 +3293,7 @@ void VIEW3D_OT_view_persportho(wmOperatorType *ot) { /* identifiers */ ot->name = "View Persp/Ortho"; - ot->description = "Switch the current view from perspective/orthographic"; + ot->description = "Switch the current view from perspective/orthographic projection"; ot->idname = "VIEW3D_OT_view_persportho"; /* api callbacks */ @@ -3406,7 +3409,8 @@ void VIEW3D_OT_background_image_remove(wmOperatorType *ot) /* flags */ ot->flag = 0; - + + /* properties */ RNA_def_int(ot->srna, "index", 0, 0, INT_MAX, "Index", "Background image index to remove", 0, INT_MAX); } diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index 84b1505c900..e4a6d7e1b17 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -1647,7 +1647,6 @@ static int localview_exec(bContext *C, wmOperator *op) void VIEW3D_OT_localview(wmOperatorType *ot) { - /* identifiers */ ot->name = "Local View"; ot->description = "Toggle display of selected object(s) separately and centered in view"; From 8b7f410f95cca51f7ff6dc0ca5c6729d0268ccc6 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Mon, 8 Oct 2012 06:28:06 +0000 Subject: [PATCH 101/347] Code cleanup - silence some "uninitialised" warnings in BMesh code There are still a lot more in bmo_bevel.c and bmo_extrude.c, but those don't seem that easy to fix. --- source/blender/bmesh/intern/bmesh_walkers_impl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/bmesh/intern/bmesh_walkers_impl.c b/source/blender/bmesh/intern/bmesh_walkers_impl.c index a72bfe47127..225ea6c2ef6 100644 --- a/source/blender/bmesh/intern/bmesh_walkers_impl.c +++ b/source/blender/bmesh/intern/bmesh_walkers_impl.c @@ -499,7 +499,7 @@ static void *bmw_LoopWalker_step(BMWalker *walker) BMEdge *e = lwalk->cur, *nexte = NULL; BMLoop *l; BMVert *v; - int i; + int i = 0; owalk = *lwalk; BMW_state_remove(walker); @@ -534,7 +534,7 @@ static void *bmw_LoopWalker_step(BMWalker *walker) } else if (l) { /* NORMAL EDGE WITH FACES */ int vert_edge_tot; - int stopi; + int stopi = 0; v = BM_edge_other_vert(e, lwalk->lastv); From 321e9d8011f5d0e200c8206487b3e1253469b552 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 8 Oct 2012 06:38:34 +0000 Subject: [PATCH 102/347] Fix #32803: Incorrect sequencer color space for newly added scenes --- source/blender/blenkernel/intern/scene.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index f8777f87369..96e64f30156 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -54,6 +54,7 @@ #include "BLI_blenlib.h" #include "BLI_utildefines.h" #include "BLI_callbacks.h" +#include "BLI_string.h" #include "BKE_anim.h" #include "BKE_animsys.h" @@ -175,6 +176,9 @@ Scene *BKE_scene_copy(Scene *sce, int type) BKE_color_managed_display_settings_copy(&scen->display_settings, &sce->display_settings); BKE_color_managed_view_settings_copy(&scen->view_settings, &sce->view_settings); BKE_color_managed_view_settings_copy(&scen->r.im_format.view_settings, &sce->r.im_format.view_settings); + + BLI_strncpy(scen->sequencer_colorspace_settings.name, sce->sequencer_colorspace_settings.name, + sizeof(scen->sequencer_colorspace_settings.name)); } /* tool settings */ @@ -350,6 +354,7 @@ Scene *BKE_scene_add(const char *name) Scene *sce; ParticleEditSettings *pset; int a; + const char *colorspace_name; sce = BKE_libblock_alloc(&bmain->scene, ID_SCE, name); sce->lay = sce->layact = 1; @@ -563,8 +568,13 @@ Scene *BKE_scene_add(const char *name) sound_create_scene(sce); + /* color management */ + colorspace_name = IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_DEFAULT_SEQUENCER); + BKE_color_managed_display_settings_init(&sce->display_settings); BKE_color_managed_view_settings_init(&sce->view_settings); + BLI_strncpy(sce->sequencer_colorspace_settings.name, colorspace_name, + sizeof(sce->sequencer_colorspace_settings.name)); return sce; } From 8b7896814f5ee2cea4c43d409f55ff57649c8661 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 8 Oct 2012 07:08:29 +0000 Subject: [PATCH 103/347] code cleanup: reduce change the size of some float vectors that were bigger then they needed to be. update to clang_array_check.py - parse function definitions lazily for some speedup. --- build_files/cmake/clang_array_check.py | 84 +++++++++++-------- .../blender/editors/interface/interface_ops.c | 2 +- source/blender/editors/mesh/editmesh_bvh.c | 6 +- source/blender/editors/mesh/editmesh_rip.c | 2 +- source/blender/editors/mesh/editmesh_tools.c | 2 +- .../editors/sculpt_paint/paint_intern.h | 2 +- .../editors/sculpt_paint/paint_stroke.c | 19 ++--- source/blender/editors/sculpt_paint/sculpt.c | 2 +- .../editors/sculpt_paint/sculpt_intern.h | 2 +- .../editors/space_outliner/outliner_draw.c | 2 +- 10 files changed, 69 insertions(+), 54 deletions(-) diff --git a/build_files/cmake/clang_array_check.py b/build_files/cmake/clang_array_check.py index df45648f975..3070c27f769 100644 --- a/build_files/cmake/clang_array_check.py +++ b/build_files/cmake/clang_array_check.py @@ -19,12 +19,15 @@ Invocation: """ +# delay parsing functions until we need them +USE_LAZY_INIT = True + # ----------------------------------------------------------------------------- # predefined function/arg sizes, handy sometimes, but not complete... defs_precalc = { - "glColor3bv": {0: 3}, - "glColor4bv": {0: 4}, + "glColor3bv": {0: 3}, + "glColor4bv": {0: 4}, "glColor3ubv": {0: 3}, "glColor4ubv": {0: 4}, @@ -32,11 +35,11 @@ defs_precalc = { "glColor4usv": {0: 3}, "glColor4usv": {0: 4}, - "glColor3fv": {0: 3}, - "glColor4fv": {0: 4}, + "glColor3fv": {0: 3}, + "glColor4fv": {0: 4}, - "glColor3dv": {0: 3}, - "glColor4dv": {0: 4}, + "glColor3dv": {0: 3}, + "glColor4dv": {0: 4}, "glVertex2fv": {0: 2}, "glVertex3fv": {0: 3}, @@ -52,12 +55,12 @@ defs_precalc = { "glRasterPos4dv": {0: 4}, "glRasterPos2fv": {0: 2}, - "glRasterPos3fv": {0: 3}, + "glRasterPos3fv": {0: 3}, "glRasterPos4fv": {0: 4}, "glRasterPos2sv": {0: 2}, - "glRasterPos3sv": {0: 3}, - "glRasterPos4sv": {0: 4}, + "glRasterPos3sv": {0: 3}, + "glRasterPos4sv": {0: 4}, "glTexCoord2fv": {0: 2}, "glTexCoord3fv": {0: 3}, @@ -112,10 +115,11 @@ args = sys.argv[2:] # print(args) tu = index.parse(sys.argv[1], args) -print 'Translation unit:', tu.spelling +print('Translation unit: %s' % tu.spelling) # ----------------------------------------------------------------------------- + def function_parm_wash_tokens(parm): # print(parm.kind) assert parm.kind in (CursorKind.PARM_DECL, @@ -174,22 +178,21 @@ def parm_size(node_child): # print(" ".join([t.spelling for t in tokens])) # NOT PERFECT CODE, EXTRACT SIZE FROM TOKENS - if len(tokens) >= 3: # foo [ 1 ] - if ((tokens[-3].kind == TokenKind.PUNCTUATION and tokens[-3].spelling == "[") and - (tokens[-2].kind == TokenKind.LITERAL and tokens[-2].spelling.isdigit()) and - (tokens[-1].kind == TokenKind.PUNCTUATION and tokens[-1].spelling == "]")): + if len(tokens) >= 3: # foo [ 1 ] + if ((tokens[-3].kind == TokenKind.PUNCTUATION and tokens[-3].spelling == "[") and + (tokens[-2].kind == TokenKind.LITERAL and tokens[-2].spelling.isdigit()) and + (tokens[-1].kind == TokenKind.PUNCTUATION and tokens[-1].spelling == "]")): # --- return int(tokens[-2].spelling) return -1 - def function_get_arg_sizes(node): # Return a dict if (index: size) items # {arg_indx: arg_array_size, ... ] arg_sizes = {} - if node.spelling == "BM_vert_create" or 1: + if 1: # node.spelling == "BM_vert_create", for debugging node_parms = [node_child for node_child in node.get_children() if node_child.kind == CursorKind.PARM_DECL] @@ -211,11 +214,19 @@ def function_get_arg_sizes(node): # ----------------------------------------------------------------------------- _defs = {} + def lookup_function_size_def(func_id): - return _defs.get(func_id, ()) + if USE_LAZY_INIT: + result = _defs.get(func_id, {}) + if type(result) != dict: + result = _defs[func_id] = function_get_arg_sizes(result) + return result + else: + return _defs.get(func_id, {}) # ----------------------------------------------------------------------------- + def file_check_arg_sizes(tu): # main checking function @@ -224,7 +235,13 @@ def file_check_arg_sizes(tu): Loop over args and validate sizes for args we KNOW the size of. """ assert node.kind == CursorKind.CALL_EXPR - # print("---", " <~> ".join([" ".join([t.spelling for t in C.get_tokens()]) for C in node.get_children()])) + + if 0: + print("---", + " <~> ".join( + [" ".join([t.spelling for t in C.get_tokens()]) + for C in node.get_children()] + )) # print(node.location) # first child is the function call, skip that. @@ -283,36 +300,32 @@ def file_check_arg_sizes(tu): if size != -1 and size != 0: # nice print! - ''' - print("".join([t.spelling for t in func.get_tokens()]), - i, - " ".join([t.spelling for t in dec.get_tokens()])) - ''' + if 0: + print("".join([t.spelling for t in func.get_tokens()]), + i, + " ".join([t.spelling for t in dec.get_tokens()])) # testing # size_def = 100 - - if size < size_def: + if size < size_def and size != 1: location = node.location print("%s:%d:%d: argument %d is size %d, should be %d" % (location.file, location.line, - location.column, - i + 1, size, size_def - )) - + location.column, + i + 1, size, size_def + )) # we dont really care what we are looking at, just scan entire file for # function calls. - + def recursive_func_call_check(node): - if node.kind == CursorKind.CALL_EXPR: validate_arg_size(node) - + for c in node.get_children(): recursive_func_call_check(c) - + recursive_func_call_check(tu.cursor) @@ -322,7 +335,10 @@ def file_check_arg_sizes(tu): def recursive_arg_sizes(node, ): # print(node.kind, node.spelling) if node.kind == CursorKind.FUNCTION_DECL: - args_sizes = function_get_arg_sizes(node) + if USE_LAZY_INIT: + args_sizes = node + else: + args_sizes = function_get_arg_sizes(node) #if args_sizes: # print(node.spelling, args_sizes) _defs[node.spelling] = args_sizes diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c index 1ee06b1ff64..e4e2598c494 100644 --- a/source/blender/editors/interface/interface_ops.c +++ b/source/blender/editors/interface/interface_ops.c @@ -216,7 +216,7 @@ static void eyedropper_color_set(bContext *C, Eyedropper *eye, const float col[3 /* set sample from accumulated values */ static void eyedropper_color_set_accum(bContext *C, Eyedropper *eye) { - float col[4]; + float col[3]; mul_v3_v3fl(col, eye->accum_col, 1.0f / (float)eye->accum_tot); eyedropper_color_set(C, eye, col); } diff --git a/source/blender/editors/mesh/editmesh_bvh.c b/source/blender/editors/mesh/editmesh_bvh.c index c249d764ac1..e84fa90fe5c 100644 --- a/source/blender/editors/mesh/editmesh_bvh.c +++ b/source/blender/editors/mesh/editmesh_bvh.c @@ -371,9 +371,9 @@ int BMBVH_VertVisible(BMBVHTree *tree, BMEdge *e, RegionView3D *r3d) } #endif -static BMFace *edge_ray_cast(BMBVHTree *tree, const float co[3], const float dir[3], float *hitout, BMEdge *e) +static BMFace *edge_ray_cast(BMBVHTree *tree, const float co[3], const float dir[3], float *r_hitout, BMEdge *e) { - BMFace *f = BMBVH_RayCast(tree, co, dir, hitout, NULL); + BMFace *f = BMBVH_RayCast(tree, co, dir, r_hitout, NULL); if (f && BM_edge_in_face(f, e)) return NULL; @@ -392,7 +392,7 @@ static void scale_point(float c1[3], const float p[3], const float s) int BMBVH_EdgeVisible(BMBVHTree *tree, BMEdge *e, ARegion *ar, View3D *v3d, Object *obedit) { BMFace *f; - float co1[3], co2[3], co3[3], dir1[4], dir2[4], dir3[4]; + float co1[3], co2[3], co3[3], dir1[3], dir2[3], dir3[3]; float origin[3], invmat[4][4]; float epsilon = 0.01f; float end[3]; diff --git a/source/blender/editors/mesh/editmesh_rip.c b/source/blender/editors/mesh/editmesh_rip.c index 001d584416f..0b3d178e2e8 100644 --- a/source/blender/editors/mesh/editmesh_rip.c +++ b/source/blender/editors/mesh/editmesh_rip.c @@ -59,7 +59,7 @@ static float edbm_rip_rip_edgedist(ARegion *ar, float mat[][4], const float co1[3], const float co2[3], const float mvalf[2]) { - float vec1[3], vec2[3]; + float vec1[2], vec2[2]; ED_view3d_project_float_v2_m4(ar, co1, vec1, mat); ED_view3d_project_float_v2_m4(ar, co2, vec2, mat); diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 0d78d850e74..891e1487781 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -765,7 +765,7 @@ static int edbm_dupli_extrude_cursor_invoke(bContext *C, wmOperator *op, wmEvent done = FALSE; BM_ITER_MESH (eed, &iter, vc.em->bm, BM_EDGES_OF_MESH) { if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) { - float co1[3], co2[3]; + float co1[2], co2[2]; if ((ED_view3d_project_float_object(vc.ar, eed->v1->co, co1, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) && (ED_view3d_project_float_object(vc.ar, eed->v2->co, co2, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK)) diff --git a/source/blender/editors/sculpt_paint/paint_intern.h b/source/blender/editors/sculpt_paint/paint_intern.h index 794e7755636..162e2fa15d6 100644 --- a/source/blender/editors/sculpt_paint/paint_intern.h +++ b/source/blender/editors/sculpt_paint/paint_intern.h @@ -51,7 +51,7 @@ struct wmOperator; struct wmOperatorType; /* paint_stroke.c */ -typedef int (*StrokeGetLocation)(struct bContext *C, float location[3], float mouse[2]); +typedef int (*StrokeGetLocation)(struct bContext *C, float location[3], const float mouse[2]); typedef int (*StrokeTestStart)(struct bContext *C, struct wmOperator *op, const float mouse[2]); typedef void (*StrokeUpdateStep)(struct bContext *C, struct PaintStroke *stroke, struct PointerRNA *itemptr); typedef void (*StrokeDone)(const struct bContext *C, struct PaintStroke *stroke); diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c index 7fabaf7f23d..2ae24db7c33 100644 --- a/source/blender/editors/sculpt_paint/paint_stroke.c +++ b/source/blender/editors/sculpt_paint/paint_stroke.c @@ -139,13 +139,13 @@ static float event_tablet_data(wmEvent *event, int *pen_flip) } /* Put the location of the next stroke dot into the stroke RNA and apply it to the mesh */ -static void paint_brush_stroke_add_step(bContext *C, wmOperator *op, wmEvent *event, float mouse_in[2]) +static void paint_brush_stroke_add_step(bContext *C, wmOperator *op, wmEvent *event, const float mouse_in[2]) { Scene *scene = CTX_data_scene(C); Paint *paint = paint_get_active_from_context(C); Brush *brush = paint_brush(paint); PaintStroke *stroke = op->customdata; - float mouse[3]; + float mouse_out[2]; PointerRNA itemptr; float location[3]; float pressure; @@ -159,24 +159,24 @@ static void paint_brush_stroke_add_step(bContext *C, wmOperator *op, wmEvent *ev if (stroke->vc.obact->sculpt) { float delta[2]; - BKE_brush_jitter_pos(scene, brush, mouse_in, mouse); + BKE_brush_jitter_pos(scene, brush, mouse_in, mouse_out); /* XXX: meh, this is round about because * BKE_brush_jitter_pos isn't written in the best way to * be reused here */ if (brush->flag & BRUSH_JITTER_PRESSURE) { - sub_v2_v2v2(delta, mouse, mouse_in); + sub_v2_v2v2(delta, mouse_out, mouse_in); mul_v2_fl(delta, pressure); - add_v2_v2v2(mouse, mouse_in, delta); + add_v2_v2v2(mouse_out, mouse_in, delta); } } else { - copy_v2_v2(mouse, mouse_in); + copy_v2_v2(mouse_out, mouse_in); } /* TODO: can remove the if statement once all modes have this */ if (stroke->get_location) - stroke->get_location(C, location, mouse); + stroke->get_location(C, location, mouse_out); else zero_v3(location); @@ -184,12 +184,11 @@ static void paint_brush_stroke_add_step(bContext *C, wmOperator *op, wmEvent *ev RNA_collection_add(op->ptr, "stroke", &itemptr); RNA_float_set_array(&itemptr, "location", location); - RNA_float_set_array(&itemptr, "mouse", mouse); + RNA_float_set_array(&itemptr, "mouse", mouse_out); RNA_boolean_set(&itemptr, "pen_flip", pen_flip); RNA_float_set(&itemptr, "pressure", pressure); - stroke->last_mouse_position[0] = mouse[0]; - stroke->last_mouse_position[1] = mouse[1]; + copy_v2_v2(stroke->last_mouse_position, mouse_out); stroke->update_step(C, stroke, &itemptr); } diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 3d3e86d2acb..e03c2fbfd21 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -3738,7 +3738,7 @@ static void sculpt_raycast_cb(PBVHNode *node, void *data_v, float *tmin) * (This allows us to ignore the GL depth buffer) * Returns 0 if the ray doesn't hit the mesh, non-zero otherwise */ -int sculpt_stroke_get_location(bContext *C, float out[3], float mouse[2]) +int sculpt_stroke_get_location(bContext *C, float out[3], const float mouse[2]) { ViewContext vc; Object *ob; diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h index 0852378974e..acb906e4a91 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.h +++ b/source/blender/editors/sculpt_paint/sculpt_intern.h @@ -65,7 +65,7 @@ void sculpt_update_mesh_elements(struct Scene *scene, struct Sculpt *sd, struct void free_sculptsession_deformMats(struct SculptSession *ss); /* Stroke */ -int sculpt_stroke_get_location(bContext *C, float out[3], float mouse[2]); +int sculpt_stroke_get_location(bContext *C, float out[3], const float mouse[2]); /* Undo */ diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c index e8aa01af6b2..d2e47427b94 100644 --- a/source/blender/editors/space_outliner/outliner_draw.c +++ b/source/blender/editors/space_outliner/outliner_draw.c @@ -1531,7 +1531,7 @@ static void outliner_draw_tree(bContext *C, uiBlock *block, Scene *scene, ARegio { TreeElement *te; int starty, startx; - float col[4]; + float col[3]; glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // only once From f299813bfaf4634ec29f6b5972f54fbe21dd2707 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Mon, 8 Oct 2012 07:40:57 +0000 Subject: [PATCH 104/347] Do not use nodeLabel() to generate new nodes' names, this is an UI func returning translated strings, which should never get into data. And it may generates dummy names in some situations (like all new Filter nodes were getting "Soften" as name (default option), better to always get "Filter" in this case!). (Note for Lockal: also checked fcurves/drivers, but those names are directly taken from RNA prop name, hence they are as UI label, translated in the current language, but not stored in data. So no problem here ;) ). --- source/blender/blenkernel/intern/node.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 8cede4f51a5..60cb1049a35 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -326,10 +326,13 @@ bNode *nodeAddNode(bNodeTree *ntree, struct bNodeTemplate *ntemp) ntype->initfunc(ntree, node, ntemp); /* initialize the node name with the node label. - * note: do this after the initfunc so nodes get - * their data set which may be used in naming + * note: do this after the initfunc so nodes get their data set which may be used in naming * (node groups for example) */ - BLI_strncpy(node->name, nodeLabel(node), NODE_MAXSTR); + /* XXX Do not use nodeLabel() here, it returns translated content, which should *only* be used + * in UI, *never* in data... + * This solution may be a bit rougher than nodeLabel()'s returned string, but it's simpler + * than adding a "no translate" flag to this func (and labelfunc() as well). */ + BLI_strncpy(node->name, node->typeinfo->name, NODE_MAXSTR); nodeUniqueName(ntree, node); ntree->update |= NTREE_UPDATE_NODES; From 9fa36b12cc6b123ca1c0f1034ab2539c09081db6 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 8 Oct 2012 08:28:05 +0000 Subject: [PATCH 105/347] style cleanup: pep8 --- .../modules/bl_i18n_utils/bl_process_msg.py | 2 +- release/scripts/modules/bpy/path.py | 4 +-- .../scripts/modules/bpy_extras/mesh_utils.py | 2 +- release/scripts/modules/bpy_types.py | 8 ++--- release/scripts/modules/bpyml.py | 2 +- release/scripts/modules/console_python.py | 4 +-- release/scripts/modules/console_shell.py | 4 +-- release/scripts/modules/rna_info.py | 4 +-- release/scripts/modules/rna_xml.py | 2 +- .../startup/bl_operators/add_mesh_torus.py | 8 ++--- release/scripts/startup/bl_operators/anim.py | 6 ++-- release/scripts/startup/bl_operators/clip.py | 14 ++++----- .../scripts/startup/bl_operators/console.py | 2 +- release/scripts/startup/bl_operators/mesh.py | 2 +- .../scripts/startup/bl_operators/object.py | 12 +++---- .../bl_operators/screen_play_rendered_anim.py | 2 +- release/scripts/startup/bl_operators/wm.py | 6 ++-- release/scripts/startup/bl_ui/__init__.py | 4 +-- .../startup/bl_ui/properties_data_armature.py | 7 ++--- .../startup/bl_ui/properties_data_bone.py | 18 +++++------ .../startup/bl_ui/properties_data_modifier.py | 4 +-- .../startup/bl_ui/properties_object.py | 6 ++-- .../startup/bl_ui/properties_particle.py | 31 +++++++++---------- .../startup/bl_ui/properties_physics_cloth.py | 8 ++--- .../bl_ui/properties_physics_common.py | 2 +- .../bl_ui/properties_physics_dynamicpaint.py | 7 ++--- .../startup/bl_ui/properties_physics_field.py | 7 ++--- .../startup/bl_ui/properties_physics_smoke.py | 6 ++-- .../bl_ui/properties_physics_softbody.py | 6 ++-- .../startup/bl_ui/properties_render.py | 2 +- .../startup/bl_ui/properties_texture.py | 10 ++++-- release/scripts/startup/bl_ui/space_clip.py | 4 +-- .../scripts/startup/bl_ui/space_console.py | 2 +- .../scripts/startup/bl_ui/space_userpref.py | 8 ++--- .../startup/bl_ui/space_userpref_keymap.py | 4 +-- release/scripts/startup/bl_ui/space_view3d.py | 8 ++--- .../startup/bl_ui/space_view3d_toolbar.py | 18 ++++++----- .../scripts/startup/keyingsets_builtins.py | 4 +-- 38 files changed, 123 insertions(+), 127 deletions(-) diff --git a/release/scripts/modules/bl_i18n_utils/bl_process_msg.py b/release/scripts/modules/bl_i18n_utils/bl_process_msg.py index 33d3be63b0b..cf545840b6f 100644 --- a/release/scripts/modules/bl_i18n_utils/bl_process_msg.py +++ b/release/scripts/modules/bl_i18n_utils/bl_process_msg.py @@ -298,7 +298,7 @@ def dump_messages_pytext(messages, check_ctxt): # check it has a 'text' argument for (arg_pos, (arg_kw, arg)) in enumerate(func.parameters.items()): if ((arg_kw in translate_kw) and - (arg.is_output == False) and + (arg.is_output is False) and (arg.type == 'STRING')): func_translate_args.setdefault(func_id, []).append((arg_kw, diff --git a/release/scripts/modules/bpy/path.py b/release/scripts/modules/bpy/path.py index 41fe052c434..d32b69b501c 100644 --- a/release/scripts/modules/bpy/path.py +++ b/release/scripts/modules/bpy/path.py @@ -264,8 +264,8 @@ def module_names(path, recursive=False): if recursive: for mod_name, mod_path in module_names(directory, True): modules.append(("%s.%s" % (filename, mod_name), - mod_path, - )) + mod_path, + )) return modules diff --git a/release/scripts/modules/bpy_extras/mesh_utils.py b/release/scripts/modules/bpy_extras/mesh_utils.py index ad0fe06b68b..ad3cf8c08ec 100644 --- a/release/scripts/modules/bpy_extras/mesh_utils.py +++ b/release/scripts/modules/bpy_extras/mesh_utils.py @@ -232,7 +232,7 @@ def edge_loops_from_tessfaces(mesh, tessfaces=None, seams=()): ed_adj = edges[context_loop[-1]] if len(ed_adj) != 2: # the original edge had 2 other edges - if other_dir and flipped == False: + if other_dir and flipped is False: flipped = True # only flip the list once context_loop.reverse() ed_adj[:] = [] diff --git a/release/scripts/modules/bpy_types.py b/release/scripts/modules/bpy_types.py index 9ad9a7affc3..4cd823d9184 100644 --- a/release/scripts/modules/bpy_types.py +++ b/release/scripts/modules/bpy_types.py @@ -689,10 +689,10 @@ class Menu(StructRNA, _GenericUI, metaclass=RNAMeta): files = [] for directory in searchpaths: files.extend([(f, os.path.join(directory, f)) - for f in os.listdir(directory) - if (not f.startswith(".")) - if ((filter_ext is None) or - (filter_ext(os.path.splitext(f)[1]))) + for f in os.listdir(directory) + if (not f.startswith(".")) + if ((filter_ext is None) or + (filter_ext(os.path.splitext(f)[1]))) ]) files.sort() diff --git a/release/scripts/modules/bpyml.py b/release/scripts/modules/bpyml.py index 42d2bf94fba..e942006010b 100644 --- a/release/scripts/modules/bpyml.py +++ b/release/scripts/modules/bpyml.py @@ -160,7 +160,7 @@ if __name__ == "__main__": from bpyml_test import * draw = [ - ui()[ + ui()[ split()[ column()[ prop(data='context.scene.render', property='use_stamp_time', text='Time'), diff --git a/release/scripts/modules/console_python.py b/release/scripts/modules/console_python.py index 582a1c6ae14..18d448b764f 100644 --- a/release/scripts/modules/console_python.py +++ b/release/scripts/modules/console_python.py @@ -30,7 +30,7 @@ _BPY_MAIN_OWN = True def add_scrollback(text, text_type): for l in text.split("\n"): bpy.ops.console.scrollback_append(text=l.replace("\t", " "), - type=text_type) + type=text_type) def replace_help(namespace): @@ -195,7 +195,7 @@ def execute(context): # insert a new blank line bpy.ops.console.history_append(text="", current_character=0, - remove_duplicates=True) + remove_duplicates=True) # Insert the output into the editor # not quite correct because the order might have changed, diff --git a/release/scripts/modules/console_shell.py b/release/scripts/modules/console_shell.py index 8beff24eedb..42348f453cd 100644 --- a/release/scripts/modules/console_shell.py +++ b/release/scripts/modules/console_shell.py @@ -26,7 +26,7 @@ language_id = "shell" def add_scrollback(text, text_type): for l in text.split("\n"): bpy.ops.console.scrollback_append(text=l.replace("\t", " "), - type=text_type) + type=text_type) def shell_run(text): @@ -57,7 +57,7 @@ def execute(context): # insert a new blank line bpy.ops.console.history_append(text="", current_character=0, - remove_duplicates=True) + remove_duplicates=True) sc.prompt = os.getcwd() + PROMPT return {'FINISHED'} diff --git a/release/scripts/modules/rna_info.py b/release/scripts/modules/rna_info.py index 0ef2ac5164d..6f4b63fc99a 100644 --- a/release/scripts/modules/rna_info.py +++ b/release/scripts/modules/rna_info.py @@ -249,7 +249,7 @@ class InfoPropertyRNA: def get_arg_default(self, force=True): default = self.default_str - if default and (force or self.is_required == False): + if default and (force or self.is_required is False): return "%s=%s" % (self.identifier, default) return self.identifier @@ -493,7 +493,7 @@ def BuildRNAInfo(): # Arrange so classes are always defined in the correct order deps_ok = False - while deps_ok == False: + while deps_ok is False: deps_ok = True rna_done = set() diff --git a/release/scripts/modules/rna_xml.py b/release/scripts/modules/rna_xml.py index 2ea978419b9..fc8e3125228 100644 --- a/release/scripts/modules/rna_xml.py +++ b/release/scripts/modules/rna_xml.py @@ -250,7 +250,7 @@ def xml2rna(root_xml, if value_xml.startswith("#"): # read hexidecimal value as float array value_xml_split = value_xml[1:] - value_xml_coerce = [int(value_xml_split[i:i + 2], 16) / 255 for i in range(0, len(value_xml_split), 2)] + value_xml_coerce = [int(value_xml_split[i:i + 2], 16) / 255 for i in range(0, len(value_xml_split), 2)] del value_xml_split else: value_xml_split = value_xml.split() diff --git a/release/scripts/startup/bl_operators/add_mesh_torus.py b/release/scripts/startup/bl_operators/add_mesh_torus.py index 6c48ae72e4b..7da4d8a480d 100644 --- a/release/scripts/startup/bl_operators/add_mesh_torus.py +++ b/release/scripts/startup/bl_operators/add_mesh_torus.py @@ -49,9 +49,9 @@ def add_torus(major_rad, minor_rad, major_seg, minor_seg): angle = 2 * pi * minor_index / minor_seg vec = quat * Vector((major_rad + (cos(angle) * minor_rad), - 0.0, - (sin(angle) * minor_rad), - )) + 0.0, + (sin(angle) * minor_rad), + )) verts.extend(vec[:]) @@ -133,7 +133,7 @@ class AddTorus(Operator, object_utils.AddObjectHelper): ) def execute(self, context): - if self.use_abso == True: + if self.use_abso is True: extra_helper = (self.abso_major_rad - self.abso_minor_rad) * 0.5 self.major_radius = self.abso_minor_rad + extra_helper self.minor_radius = extra_helper diff --git a/release/scripts/startup/bl_operators/anim.py b/release/scripts/startup/bl_operators/anim.py index c5fc3c50f3f..902c7007fb9 100644 --- a/release/scripts/startup/bl_operators/anim.py +++ b/release/scripts/startup/bl_operators/anim.py @@ -214,7 +214,7 @@ class BakeAction(Operator): 'OBJECT' in self.bake_types, self.clear_constraints, True, - ) + ) if action is None: self.report({'INFO'}, "Nothing to bake") @@ -252,8 +252,8 @@ class ClearUselessActions(Operator): for action in bpy.data.actions: # if only user is "fake" user... - if ((self.only_unused is False) or - (action.use_fake_user and action.users == 1)): + if ((self.only_unused is False) or + (action.use_fake_user and action.users == 1)): # if it has F-Curves, then it's a "action library" # (i.e. walk, wave, jump, etc.) diff --git a/release/scripts/startup/bl_operators/clip.py b/release/scripts/startup/bl_operators/clip.py index c45d2f2e702..70967a01d1c 100644 --- a/release/scripts/startup/bl_operators/clip.py +++ b/release/scripts/startup/bl_operators/clip.py @@ -57,7 +57,7 @@ def CLIP_set_viewport_background(context, all_screens, clip, clip_user): space_v3d.show_background_images = True CLIP_spaces_walk(context, all_screens, 'VIEW_3D', 'VIEW_3D', - set_background, clip, clip_user) + set_background, clip, clip_user) def CLIP_camera_for_clip(context, clip): @@ -329,7 +329,7 @@ object's movement caused by this constraint""" if not con: self.report({'ERROR'}, - "Motion Tracking constraint to be converted not found") + "Motion Tracking constraint to be converted not found") return {'CANCELLED'} @@ -341,7 +341,7 @@ object's movement caused by this constraint""" if not clip: self.report({'ERROR'}, - "Movie clip to use tracking data from isn't set") + "Movie clip to use tracking data from isn't set") return {'CANCELLED'} @@ -461,9 +461,9 @@ class CLIP_OT_setup_tracking_scene(Operator): scene.camera = camob camob.matrix_local = (Matrix.Translation((7.481, -6.508, 5.344)) * - Matrix.Rotation(0.815, 4, 'Z') * - Matrix.Rotation(0.011, 4, 'Y') * - Matrix.Rotation(1.109, 4, 'X')) + Matrix.Rotation(0.815, 4, 'Z') * + Matrix.Rotation(0.011, 4, 'Y') * + Matrix.Rotation(1.109, 4, 'X')) return camob @@ -629,7 +629,7 @@ class CLIP_OT_setup_tracking_scene(Operator): if need_stabilization: tree.links.new(distortion.outputs["Image"], - stabilize.inputs["Image"]) + stabilize.inputs["Image"]) tree.links.new(stabilize.outputs["Image"], scale.inputs["Image"]) else: tree.links.new(distortion.outputs["Image"], scale.inputs["Image"]) diff --git a/release/scripts/startup/bl_operators/console.py b/release/scripts/startup/bl_operators/console.py index fd95da02b28..307165a4d18 100644 --- a/release/scripts/startup/bl_operators/console.py +++ b/release/scripts/startup/bl_operators/console.py @@ -129,6 +129,6 @@ class ConsoleLanguage(Operator): # insert a new blank line bpy.ops.console.history_append(text="", current_character=0, - remove_duplicates=True) + remove_duplicates=True) return {'FINISHED'} diff --git a/release/scripts/startup/bl_operators/mesh.py b/release/scripts/startup/bl_operators/mesh.py index 3dc25d84aca..df21349da47 100644 --- a/release/scripts/startup/bl_operators/mesh.py +++ b/release/scripts/startup/bl_operators/mesh.py @@ -92,7 +92,7 @@ class MeshMirrorUV(Operator): puvs[i] = tuple(uv.uv for uv in uv_loops[lstart:lend]) puvs_cpy[i] = tuple(uv.copy() for uv in puvs[i]) puvsel[i] = (False not in - (uv.select for uv in uv_loops[lstart:lend])) + (uv.select for uv in uv_loops[lstart:lend])) # Vert idx of the poly. vidxs[i] = tuple(l.vertex_index for l in loops[lstart:lend]) # As we have no poly.center yet... diff --git a/release/scripts/startup/bl_operators/object.py b/release/scripts/startup/bl_operators/object.py index 5000d718182..4e90f2e8585 100644 --- a/release/scripts/startup/bl_operators/object.py +++ b/release/scripts/startup/bl_operators/object.py @@ -408,13 +408,13 @@ class ShapeTransfer(Operator): n2loc_to = v2_to + target_normals[i2] * edlen_to pt = barycentric_transform(orig_shape_coords[i1], - v2, v1, n1loc, - v2_to, v1_to, n1loc_to) + v2, v1, n1loc, + v2_to, v1_to, n1loc_to) median_coords[i1].append(pt) pt = barycentric_transform(orig_shape_coords[i2], - v1, v2, n2loc, - v1_to, v2_to, n2loc_to) + v1, v2, n2loc, + v1_to, v2_to, n2loc_to) median_coords[i2].append(pt) # apply the offsets to the new shape @@ -507,7 +507,7 @@ class JoinUVs(Operator): if obj_other != obj and obj_other.type == 'MESH': mesh_other = obj_other.data if mesh_other != mesh: - if mesh_other.tag == False: + if mesh_other.tag is False: mesh_other.tag = True if len(mesh_other.loops) != nbr_loops: @@ -520,7 +520,7 @@ class JoinUVs(Operator): len(mesh_other.polygons), nbr_loops, ), - ) + ) else: uv_other = mesh_other.uv_layers.active if not uv_other: diff --git a/release/scripts/startup/bl_operators/screen_play_rendered_anim.py b/release/scripts/startup/bl_operators/screen_play_rendered_anim.py index 32658d353d9..694412e51d7 100644 --- a/release/scripts/startup/bl_operators/screen_play_rendered_anim.py +++ b/release/scripts/startup/bl_operators/screen_play_rendered_anim.py @@ -89,7 +89,7 @@ class PlayRenderedAnim(Operator): if player_path == "": player_path = guess_player_path(preset) - if is_movie == False and preset in {'FRAMECYCLER', 'RV', 'MPLAYER'}: + if is_movie is False and preset in {'FRAMECYCLER', 'RV', 'MPLAYER'}: # replace the number with '#' file_a = rd.frame_path(frame=0) diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py index 21843d80742..eac90a8b091 100644 --- a/release/scripts/startup/bl_operators/wm.py +++ b/release/scripts/startup/bl_operators/wm.py @@ -608,9 +608,9 @@ class WM_OT_context_collection_boolean_set(Operator): except: continue - if value_orig == True: + if value_orig is True: is_set = True - elif value_orig == False: + elif value_orig is False: pass else: self.report({'WARNING'}, "Non boolean value found: %s[ ].%s" % @@ -1583,7 +1583,7 @@ class WM_OT_addon_enable(Operator): "version %d.%d.%d and might not " "function (correctly), " "though it is enabled") % - info_ver) + info_ver) return {'FINISHED'} else: return {'CANCELLED'} diff --git a/release/scripts/startup/bl_ui/__init__.py b/release/scripts/startup/bl_ui/__init__.py index 847807029fa..09d866c2ae5 100644 --- a/release/scripts/startup/bl_ui/__init__.py +++ b/release/scripts/startup/bl_ui/__init__.py @@ -95,7 +95,7 @@ def register(): items = [('All', "All", ""), ('Enabled', "Enabled", ""), ('Disabled', "Disabled", ""), - ] + ] items_unique = set() @@ -120,7 +120,7 @@ def register(): items=[('OFFICIAL', "Official", "Officially supported"), ('COMMUNITY', "Community", "Maintained by community developers"), ('TESTING', "Testing", "Newly contributed scripts (excluded from release builds)"), - ], + ], name="Support", description="Display support level", default={'OFFICIAL', 'COMMUNITY'}, diff --git a/release/scripts/startup/bl_ui/properties_data_armature.py b/release/scripts/startup/bl_ui/properties_data_armature.py index e194d7a1370..50c34be1414 100644 --- a/release/scripts/startup/bl_ui/properties_data_armature.py +++ b/release/scripts/startup/bl_ui/properties_data_armature.py @@ -285,10 +285,9 @@ class DATA_PT_iksolver_itasc(ArmatureButtonsPanel, Panel): row.prop(itasc, "damping_max", text="Damp", slider=True) row.prop(itasc, "damping_epsilon", text="Eps", slider=True) -from bl_ui.properties_animviz import ( - MotionPathButtonsPanel, - OnionSkinButtonsPanel, - ) +from bl_ui.properties_animviz import (MotionPathButtonsPanel, + OnionSkinButtonsPanel, + ) class DATA_PT_motion_paths(MotionPathButtonsPanel, Panel): diff --git a/release/scripts/startup/bl_ui/properties_data_bone.py b/release/scripts/startup/bl_ui/properties_data_bone.py index e6d9affee93..1e70483864c 100644 --- a/release/scripts/startup/bl_ui/properties_data_bone.py +++ b/release/scripts/startup/bl_ui/properties_data_bone.py @@ -251,52 +251,52 @@ class BONE_PT_inverse_kinematics(BoneButtonsPanel, Panel): split.active = pchan.is_in_ik_chain row = split.row() row.prop(pchan, "ik_stiffness_x", text="Stiffness", slider=True) - row.active = pchan.lock_ik_x == False and pchan.is_in_ik_chain + row.active = pchan.lock_ik_x is False and pchan.is_in_ik_chain split = layout.split(percentage=0.25) sub = split.row() sub.prop(pchan, "use_ik_limit_x", text="Limit") - sub.active = pchan.lock_ik_x == False and pchan.is_in_ik_chain + sub.active = pchan.lock_ik_x is False and pchan.is_in_ik_chain sub = split.row(align=True) sub.prop(pchan, "ik_min_x", text="") sub.prop(pchan, "ik_max_x", text="") - sub.active = pchan.lock_ik_x == False and pchan.use_ik_limit_x and pchan.is_in_ik_chain + sub.active = pchan.lock_ik_x is False and pchan.use_ik_limit_x and pchan.is_in_ik_chain split = layout.split(percentage=0.25) split.prop(pchan, "lock_ik_y", icon='LOCKED' if pchan.lock_ik_y else 'UNLOCKED', text="Y") split.active = pchan.is_in_ik_chain row = split.row() row.prop(pchan, "ik_stiffness_y", text="Stiffness", slider=True) - row.active = pchan.lock_ik_y == False and pchan.is_in_ik_chain + row.active = pchan.lock_ik_y is False and pchan.is_in_ik_chain split = layout.split(percentage=0.25) sub = split.row() sub.prop(pchan, "use_ik_limit_y", text="Limit") - sub.active = pchan.lock_ik_y == False and pchan.is_in_ik_chain + sub.active = pchan.lock_ik_y is False and pchan.is_in_ik_chain sub = split.row(align=True) sub.prop(pchan, "ik_min_y", text="") sub.prop(pchan, "ik_max_y", text="") - sub.active = pchan.lock_ik_y == False and pchan.use_ik_limit_y and pchan.is_in_ik_chain + sub.active = pchan.lock_ik_y is False and pchan.use_ik_limit_y and pchan.is_in_ik_chain split = layout.split(percentage=0.25) split.prop(pchan, "lock_ik_z", icon='LOCKED' if pchan.lock_ik_z else 'UNLOCKED', text="Z") split.active = pchan.is_in_ik_chain sub = split.row() sub.prop(pchan, "ik_stiffness_z", text="Stiffness", slider=True) - sub.active = pchan.lock_ik_z == False and pchan.is_in_ik_chain + sub.active = pchan.lock_ik_z is False and pchan.is_in_ik_chain split = layout.split(percentage=0.25) sub = split.row() sub.prop(pchan, "use_ik_limit_z", text="Limit") - sub.active = pchan.lock_ik_z == False and pchan.is_in_ik_chain + sub.active = pchan.lock_ik_z is False and pchan.is_in_ik_chain sub = split.row(align=True) sub.prop(pchan, "ik_min_z", text="") sub.prop(pchan, "ik_max_z", text="") - sub.active = pchan.lock_ik_z == False and pchan.use_ik_limit_z and pchan.is_in_ik_chain + sub.active = pchan.lock_ik_z is False and pchan.use_ik_limit_z and pchan.is_in_ik_chain split = layout.split(percentage=0.25) split.label(text="Stretch:") diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py index ed390be49f5..0398cb36b18 100644 --- a/release/scripts/startup/bl_ui/properties_data_modifier.py +++ b/release/scripts/startup/bl_ui/properties_data_modifier.py @@ -397,7 +397,7 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): col = layout.column() - if md.use_mirror_merge == True: + if md.use_mirror_merge is True: col.prop(md, "merge_threshold") col.label(text="Mirror Object:") col.prop(md, "mirror_object", text="") @@ -559,7 +559,7 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): col = split.column() row = col.row() - row.active = (md.object is None or md.use_object_screw_offset == False) + row.active = (md.object is None or md.use_object_screw_offset is False) row.prop(md, "screw_offset") row = col.row() row.active = (md.object is not None) diff --git a/release/scripts/startup/bl_ui/properties_object.py b/release/scripts/startup/bl_ui/properties_object.py index f2c631b7ab1..8a668b5d95b 100644 --- a/release/scripts/startup/bl_ui/properties_object.py +++ b/release/scripts/startup/bl_ui/properties_object.py @@ -290,10 +290,8 @@ class OBJECT_PT_relations_extras(ObjectButtonsPanel, Panel): row.prop(ob, "slow_parent_offset", text="Offset") -from bl_ui.properties_animviz import ( - MotionPathButtonsPanel, - OnionSkinButtonsPanel, - ) +from bl_ui.properties_animviz import (MotionPathButtonsPanel, + OnionSkinButtonsPanel) class OBJECT_PT_motion_paths(MotionPathButtonsPanel, Panel): diff --git a/release/scripts/startup/bl_ui/properties_particle.py b/release/scripts/startup/bl_ui/properties_particle.py index aa0ea1d2d9e..f29589faa2d 100644 --- a/release/scripts/startup/bl_ui/properties_particle.py +++ b/release/scripts/startup/bl_ui/properties_particle.py @@ -21,12 +21,11 @@ import bpy from bpy.types import Panel from rna_prop_ui import PropertyPanel -from bl_ui.properties_physics_common import ( - point_cache_ui, - effector_weights_ui, - basic_force_field_settings_ui, - basic_force_field_falloff_ui, - ) +from bl_ui.properties_physics_common import (point_cache_ui, + effector_weights_ui, + basic_force_field_settings_ui, + basic_force_field_falloff_ui, + ) def particle_panel_enabled(context, psys): @@ -52,7 +51,7 @@ def particle_panel_poll(cls, context): if not settings: return False - return settings.is_fluid == False and (engine in cls.COMPAT_ENGINES) + return settings.is_fluid is False and (engine in cls.COMPAT_ENGINES) def particle_get_settings(context): @@ -133,13 +132,13 @@ class PARTICLE_PT_context_particles(ParticleButtonsPanel, Panel): split = layout.split(percentage=0.32) col = split.column() col.label(text="Name:") - if part.is_fluid == False: + if part.is_fluid is False: col.label(text="Settings:") col.label(text="Type:") col = split.column() col.prop(psys, "name", text="") - if part.is_fluid == False: + if part.is_fluid is False: row = col.row() row.enabled = particle_panel_enabled(context, psys) row.template_ID(psys, "settings", new="particle.new") @@ -279,7 +278,7 @@ class PARTICLE_PT_hair_dynamics(ParticleButtonsPanel, Panel): cloth = psys.cloth.settings - layout.enabled = psys.use_hair_dynamics and psys.point_cache.is_baked == False + layout.enabled = psys.use_hair_dynamics and psys.point_cache.is_baked is False split = layout.split() @@ -813,7 +812,7 @@ class PARTICLE_PT_render(ParticleButtonsPanel, Panel): sub.active = (part.use_strand_primitive is False) sub.prop(part, "use_render_adaptive") sub = col.column() - sub.active = part.use_render_adaptive or part.use_strand_primitive == True + sub.active = part.use_render_adaptive or part.use_strand_primitive is True sub.prop(part, "adaptive_angle") sub = col.column() sub.active = (part.use_render_adaptive is True and part.use_strand_primitive is False) @@ -831,9 +830,9 @@ class PARTICLE_PT_render(ParticleButtonsPanel, Panel): row = layout.row() col = row.column() - if part.type == 'HAIR' and part.use_strand_primitive == True and part.child_type == 'INTERPOLATED': + if part.type == 'HAIR' and part.use_strand_primitive is True and part.child_type == 'INTERPOLATED': layout.prop(part, "use_simplify") - if part.use_simplify == True: + if part.use_simplify is True: row = layout.row() row.prop(part, "simplify_refsize") row.prop(part, "simplify_rate") @@ -841,7 +840,7 @@ class PARTICLE_PT_render(ParticleButtonsPanel, Panel): row = layout.row() row.prop(part, "use_simplify_viewport") sub = row.row() - sub.active = part.use_simplify_viewport == True + sub.active = part.use_simplify_viewport is True sub.prop(part, "simplify_viewport") elif part.render_type == 'OBJECT': @@ -988,11 +987,11 @@ class PARTICLE_PT_draw(ParticleButtonsPanel, Panel): if part.draw_percentage != 100 and psys is not None: if part.type == 'HAIR': - if psys.use_hair_dynamics and psys.point_cache.is_baked == False: + if psys.use_hair_dynamics and psys.point_cache.is_baked is False: layout.row().label(text="Display percentage makes dynamics inaccurate without baking!") else: phystype = part.physics_type - if phystype != 'NO' and phystype != 'KEYED' and psys.point_cache.is_baked == False: + if phystype != 'NO' and phystype != 'KEYED' and psys.point_cache.is_baked is False: layout.row().label(text="Display percentage makes dynamics inaccurate without baking!") row = layout.row() diff --git a/release/scripts/startup/bl_ui/properties_physics_cloth.py b/release/scripts/startup/bl_ui/properties_physics_cloth.py index 33b977b5f04..e5db1eec37e 100644 --- a/release/scripts/startup/bl_ui/properties_physics_cloth.py +++ b/release/scripts/startup/bl_ui/properties_physics_cloth.py @@ -20,10 +20,8 @@ import bpy from bpy.types import Menu, Panel -from bl_ui.properties_physics_common import ( - point_cache_ui, - effector_weights_ui, - ) +from bl_ui.properties_physics_common import (point_cache_ui, + effector_weights_ui) def cloth_panel_enabled(md): @@ -178,7 +176,7 @@ class PHYSICS_PT_cloth_stiffness(PhysicButtonsPanel, Panel): ob = context.object cloth = context.cloth.settings - layout.active = cloth.use_stiffness_scale and cloth_panel_enabled(md) + layout.active = (cloth.use_stiffness_scale and cloth_panel_enabled(md)) split = layout.split() diff --git a/release/scripts/startup/bl_ui/properties_physics_common.py b/release/scripts/startup/bl_ui/properties_physics_common.py index 7f824d94431..00a35b233da 100644 --- a/release/scripts/startup/bl_ui/properties_physics_common.py +++ b/release/scripts/startup/bl_ui/properties_physics_common.py @@ -160,7 +160,7 @@ def point_cache_ui(self, context, cache, enabled, cachetype): col = split.column() - if cache.is_baked == True: + if cache.is_baked is True: col.operator("ptcache.free_bake", text="Free Bake") else: col.operator("ptcache.bake", text="Bake").bake = True diff --git a/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py b/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py index db0794d8a8a..fa37e9cd10f 100644 --- a/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py +++ b/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py @@ -20,10 +20,9 @@ import bpy from bpy.types import Panel -from bl_ui.properties_physics_common import ( - point_cache_ui, - effector_weights_ui, - ) +from bl_ui.properties_physics_common import (point_cache_ui, + effector_weights_ui, + ) class PhysicButtonsPanel(): diff --git a/release/scripts/startup/bl_ui/properties_physics_field.py b/release/scripts/startup/bl_ui/properties_physics_field.py index 569037cb0da..6b5612d7836 100644 --- a/release/scripts/startup/bl_ui/properties_physics_field.py +++ b/release/scripts/startup/bl_ui/properties_physics_field.py @@ -20,10 +20,9 @@ import bpy from bpy.types import Panel -from bl_ui.properties_physics_common import ( - basic_force_field_settings_ui, - basic_force_field_falloff_ui, - ) +from bl_ui.properties_physics_common import (basic_force_field_settings_ui, + basic_force_field_falloff_ui, + ) class PhysicButtonsPanel(): diff --git a/release/scripts/startup/bl_ui/properties_physics_smoke.py b/release/scripts/startup/bl_ui/properties_physics_smoke.py index 1b333f1e505..acbaad4f961 100644 --- a/release/scripts/startup/bl_ui/properties_physics_smoke.py +++ b/release/scripts/startup/bl_ui/properties_physics_smoke.py @@ -20,10 +20,8 @@ import bpy from bpy.types import Panel -from bl_ui.properties_physics_common import ( - point_cache_ui, - effector_weights_ui, - ) +from bl_ui.properties_physics_common import (point_cache_ui, + effector_weights_ui) class PhysicButtonsPanel(): diff --git a/release/scripts/startup/bl_ui/properties_physics_softbody.py b/release/scripts/startup/bl_ui/properties_physics_softbody.py index b043c1f9b68..a69e7955de5 100644 --- a/release/scripts/startup/bl_ui/properties_physics_softbody.py +++ b/release/scripts/startup/bl_ui/properties_physics_softbody.py @@ -20,10 +20,8 @@ import bpy from bpy.types import Panel -from bl_ui.properties_physics_common import ( - point_cache_ui, - effector_weights_ui, - ) +from bl_ui.properties_physics_common import (point_cache_ui, + effector_weights_ui) def softbody_panel_enabled(md): diff --git a/release/scripts/startup/bl_ui/properties_render.py b/release/scripts/startup/bl_ui/properties_render.py index 74f4c719cd5..544462e1242 100644 --- a/release/scripts/startup/bl_ui/properties_render.py +++ b/release/scripts/startup/bl_ui/properties_render.py @@ -225,7 +225,7 @@ class RENDER_PT_dimensions(RenderButtonsPanel, Panel): # TODO: Change the following to iterate over existing presets custom_framerate = (fps_rate not in {23.98, 24, 25, 29.97, 30, 50, 59.94, 60}) - if custom_framerate == True: + if custom_framerate is True: fps_label_text = "Custom (" + str(fps_rate) + " fps)" else: fps_label_text = str(fps_rate) + " fps" diff --git a/release/scripts/startup/bl_ui/properties_texture.py b/release/scripts/startup/bl_ui/properties_texture.py index 46a17675c91..9e6bfe6889e 100644 --- a/release/scripts/startup/bl_ui/properties_texture.py +++ b/release/scripts/startup/bl_ui/properties_texture.py @@ -111,8 +111,14 @@ class TEXTURE_PT_context_texture(TextureButtonsPanel, Panel): engine = context.scene.render.engine if not (hasattr(context, "texture_slot") or hasattr(context, "texture_node")): return False - return ((context.material or context.world or context.lamp or context.brush or context.texture or context.particle_system or isinstance(context.space_data.pin_id, ParticleSettings)) - and (engine in cls.COMPAT_ENGINES)) + return ((context.material or + context.world or + context.lamp or + context.brush or + context.texture or + context.particle_system or + isinstance(context.space_data.pin_id, ParticleSettings)) and + (engine in cls.COMPAT_ENGINES)) def draw(self, context): layout = self.layout diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py index b0e8a847084..7732a0c6400 100644 --- a/release/scripts/startup/bl_ui/space_clip.py +++ b/release/scripts/startup/bl_ui/space_clip.py @@ -942,7 +942,7 @@ class CLIP_MT_track(Menu): props.action = 'UPTO' props = layout.operator("clip.clear_track_path", - text="Clear Track Path") + text="Clear Track Path") props.action = 'ALL' layout.separator() @@ -957,7 +957,7 @@ class CLIP_MT_track(Menu): layout.separator() props = layout.operator("clip.track_markers", - text="Track Frame Backwards") + text="Track Frame Backwards") props.backwards = True props = layout.operator("clip.track_markers", text="Track Backwards") diff --git a/release/scripts/startup/bl_ui/space_console.py b/release/scripts/startup/bl_ui/space_console.py index 7ded4954f80..5ff179902a3 100644 --- a/release/scripts/startup/bl_ui/space_console.py +++ b/release/scripts/startup/bl_ui/space_console.py @@ -86,7 +86,7 @@ class CONSOLE_MT_language(Menu): def add_scrollback(text, text_type): for l in text.split("\n"): bpy.ops.console.scrollback_append(text=l.replace('\t', ' '), - type=text_type) + type=text_type) if __name__ == "__main__": # only for live edit. bpy.utils.register_module(__name__) diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py index 64bf1e29348..0c3c0e5a696 100644 --- a/release/scripts/startup/bl_ui/space_userpref.py +++ b/release/scripts/startup/bl_ui/space_userpref.py @@ -1084,10 +1084,10 @@ class USERPREF_PT_addons(Panel): continue # check if addon should be visible with current filters - if ((filter == "All") or - (filter == info["category"]) or - (filter == "Enabled" and is_enabled) or - (filter == "Disabled" and not is_enabled)): + if ((filter == "All") or + (filter == info["category"]) or + (filter == "Enabled" and is_enabled) or + (filter == "Disabled" and not is_enabled)): if search and search not in info["name"].lower(): if info["author"]: diff --git a/release/scripts/startup/bl_ui/space_userpref_keymap.py b/release/scripts/startup/bl_ui/space_userpref_keymap.py index 6646da4a91a..da498268b9b 100644 --- a/release/scripts/startup/bl_ui/space_userpref_keymap.py +++ b/release/scripts/startup/bl_ui/space_userpref_keymap.py @@ -218,8 +218,8 @@ class InputKeyMapPanel: layout.context_pointer_set("keymap", km) filtered_items = [kmi for kmi in km.keymap_items - if filter_text in kmi.idname.lower() or - filter_text in kmi.name.lower()] + if (filter_text in kmi.idname.lower() or + filter_text in kmi.name.lower())] if filtered_items: col = layout.column() diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index a77c5818fca..a21d8527158 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -223,8 +223,8 @@ class VIEW3D_MT_transform_armature(VIEW3D_MT_transform_base): layout.separator() obj = context.object - if (obj.type == 'ARMATURE' and obj.mode in {'EDIT', 'POSE'} and - obj.data.draw_type in {'BBONE', 'ENVELOPE'}): + if (obj.type == 'ARMATURE' and obj.mode in {'EDIT', 'POSE'} and + obj.data.draw_type in {'BBONE', 'ENVELOPE'}): layout.operator("transform.transform", text="Scale Envelope/BBone").mode = 'BONE_SIZE' if context.edit_object and context.edit_object.type == 'ARMATURE': @@ -580,7 +580,7 @@ class VIEW3D_MT_select_edit_mesh(Menu): layout.separator() layout.operator("mesh.select_by_number_vertices", text="By Number of Verts") - if context.scene.tool_settings.mesh_select_mode[2] == False: + if context.scene.tool_settings.mesh_select_mode[2] is False: layout.operator("mesh.select_non_manifold", text="Non Manifold") layout.operator("mesh.select_loose_verts", text="Loose Verts/Edges") layout.operator_menu_enum("mesh.select_similar", "type", text="Similar") @@ -2282,7 +2282,7 @@ class VIEW3D_PT_view3d_properties(Panel): if lock_object.type == 'ARMATURE': col.prop_search(view, "lock_bone", lock_object.data, "edit_bones" if lock_object.mode == 'EDIT' - else "bones", + else "bones", text="") else: col.prop(view, "lock_cursor", text="Lock to Cursor") diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py index 1b67b30d17a..0d939b2de78 100644 --- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py +++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py @@ -520,8 +520,8 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel): row = col.row(align=True) ups = toolsettings.unified_paint_settings - if ((ups.use_unified_size and ups.use_locked_size) or - ((not ups.use_unified_size) and brush.use_locked_size)): + if ((ups.use_unified_size and ups.use_locked_size) or + ((not ups.use_unified_size) and brush.use_locked_size)): self.prop_unified_size(row, context, brush, "use_locked_size", icon='LOCKED') self.prop_unified_size(row, context, brush, "unprojected_radius", slider=True, text="Radius") else: @@ -707,8 +707,8 @@ class VIEW3D_PT_tools_brush_texture(Panel, View3DPaintPanel): @classmethod def poll(cls, context): settings = cls.paint_settings(context) - return (settings and settings.brush and (context.sculpt_object or - context.image_paint_object)) + return (settings and settings.brush and + (context.sculpt_object or context.image_paint_object)) def draw(self, context): layout = self.layout @@ -747,10 +747,12 @@ class VIEW3D_PT_tools_brush_stroke(Panel, View3DPaintPanel): @classmethod def poll(cls, context): settings = cls.paint_settings(context) - return (settings and settings.brush and (context.sculpt_object or - context.vertex_paint_object or - context.weight_paint_object or - context.image_paint_object)) + return (settings and + settings.brush and + (context.sculpt_object or + context.vertex_paint_object or + context.weight_paint_object or + context.image_paint_object)) def draw(self, context): layout = self.layout diff --git a/release/scripts/startup/keyingsets_builtins.py b/release/scripts/startup/keyingsets_builtins.py index b7693880f9c..6ad87375738 100644 --- a/release/scripts/startup/keyingsets_builtins.py +++ b/release/scripts/startup/keyingsets_builtins.py @@ -360,10 +360,10 @@ class BUILTIN_KSI_WholeCharacter(KeyingSetInfo): # add rotation properties if they will if bone.lock_rotations_4d: # can check individually - if (bone.lock_rotation == (False, False, False)) and (bone.lock_rotation_w == False): + if (bone.lock_rotation == (False, False, False)) and (bone.lock_rotation_w is False): ksi.addProp(ks, bone, prop) else: - if bone.lock_rotation_w == False: + if bone.lock_rotation_w is False: ksi.addProp(ks, bone, prop, 0) # w = 0 for i in range(3): From e91badc2666aa04af34473d71dc576afb52eec06 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Mon, 8 Oct 2012 08:44:48 +0000 Subject: [PATCH 106/347] Code cleanup - Convert if blocks to switch --- .../editors/space_outliner/outliner_tools.c | 44 ++++++++++++------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c index bf76fdda61e..09df1d57b2b 100644 --- a/source/blender/editors/space_outliner/outliner_tools.c +++ b/source/blender/editors/space_outliner/outliner_tools.c @@ -1160,37 +1160,49 @@ static int outliner_data_operation_exec(bContext *C, wmOperator *op) event = RNA_enum_get(op->ptr, "type"); set_operation_types(soops, &soops->tree, &scenelevel, &objectlevel, &idlevel, &datalevel); - if (datalevel == TSE_POSE_CHANNEL) { - if (event > 0) { + if (event <= 0) + return OPERATOR_CANCELLED; + + switch (datalevel) { + case TSE_POSE_CHANNEL: + { outliner_do_data_operation(soops, datalevel, event, &soops->tree, pchan_cb, NULL); WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL); ED_undo_push(C, "PoseChannel operation"); } - } - else if (datalevel == TSE_BONE) { - if (event > 0) { + break; + + case TSE_BONE: + { outliner_do_data_operation(soops, datalevel, event, &soops->tree, bone_cb, NULL); WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL); ED_undo_push(C, "Bone operation"); } - } - else if (datalevel == TSE_EBONE) { - if (event > 0) { + break; + + case TSE_EBONE: + { outliner_do_data_operation(soops, datalevel, event, &soops->tree, ebone_cb, NULL); WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL); ED_undo_push(C, "EditBone operation"); } - } - else if (datalevel == TSE_SEQUENCE) { - if (event > 0) { + break; + + case TSE_SEQUENCE: + { Scene *scene = CTX_data_scene(C); outliner_do_data_operation(soops, datalevel, event, &soops->tree, sequence_cb, scene); } - } - else if (datalevel == TSE_RNA_STRUCT) { - if (event == 5) { - outliner_do_data_operation(soops, datalevel, event, &soops->tree, data_select_linked_cb, C); - } + break; + + case TSE_RNA_STRUCT: + if (event == 5) { + outliner_do_data_operation(soops, datalevel, event, &soops->tree, data_select_linked_cb, C); + } + break; + + default: + break; } return OPERATOR_FINISHED; From 1487ef9828d576088eac3a792069ea95d15579af Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 8 Oct 2012 09:39:35 +0000 Subject: [PATCH 107/347] quiet msvc warning & allow zero arguments to add functions. --- source/blender/makesrna/intern/rna_curve.c | 4 ++-- source/blender/makesrna/intern/rna_fcurve.c | 2 +- source/blender/makesrna/intern/rna_gpencil.c | 18 +++++++++++------- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c index c47cb8ef2af..8cba5899b76 100644 --- a/source/blender/makesrna/intern/rna_curve.c +++ b/source/blender/makesrna/intern/rna_curve.c @@ -1163,7 +1163,7 @@ static void rna_def_curve_spline_points(BlenderRNA *brna, PropertyRNA *cprop) func = RNA_def_function(srna, "add", "rna_Curve_spline_points_add"); RNA_def_function_ui_description(func, "Add a number of points to this spline"); RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_REPORTS); - RNA_def_int(func, "count", 1, 1, INT_MAX, "Number", "Number of points to add to the spline", 1, INT_MAX); + RNA_def_int(func, "count", 1, 0, INT_MAX, "Number", "Number of points to add to the spline", 0, INT_MAX); #if 0 func= RNA_def_function(srna, "remove", "rna_Curve_spline_remove"); @@ -1190,7 +1190,7 @@ static void rna_def_curve_spline_bezpoints(BlenderRNA *brna, PropertyRNA *cprop) func = RNA_def_function(srna, "add", "rna_Curve_spline_bezpoints_add"); RNA_def_function_ui_description(func, "Add a number of points to this spline"); RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_REPORTS); - RNA_def_int(func, "count", 1, INT_MIN, INT_MAX, "Number", "Number of points to add to the spline", 0, INT_MAX); + RNA_def_int(func, "count", 1, 0, INT_MAX, "Number", "Number of points to add to the spline", 0, INT_MAX); #if 0 func = RNA_def_function(srna, "remove", "rna_Curve_spline_remove"); diff --git a/source/blender/makesrna/intern/rna_fcurve.c b/source/blender/makesrna/intern/rna_fcurve.c index 24b14fdb884..d899b5833bb 100644 --- a/source/blender/makesrna/intern/rna_fcurve.c +++ b/source/blender/makesrna/intern/rna_fcurve.c @@ -1497,7 +1497,7 @@ static void rna_def_fcurve_keyframe_points(BlenderRNA *brna, PropertyRNA *cprop) func = RNA_def_function(srna, "add", "rna_FKeyframe_points_add"); RNA_def_function_ui_description(func, "Add a keyframe point to a F-Curve"); - RNA_def_int(func, "count", 1, 1, INT_MAX, "Number", "Number of points to add to the spline", 1, INT_MAX); + RNA_def_int(func, "count", 1, 0, INT_MAX, "Number", "Number of points to add to the spline", 0, INT_MAX); func = RNA_def_function(srna, "remove", "rna_FKeyframe_points_remove"); RNA_def_function_ui_description(func, "Remove keyframe from an F-Curve"); diff --git a/source/blender/makesrna/intern/rna_gpencil.c b/source/blender/makesrna/intern/rna_gpencil.c index ae1c7fd2d5b..fffee4b61ef 100644 --- a/source/blender/makesrna/intern/rna_gpencil.c +++ b/source/blender/makesrna/intern/rna_gpencil.c @@ -113,12 +113,14 @@ static void rna_GPencilLayer_info_set(PointerRNA *ptr, const char *value) static void rna_GPencil_stroke_point_add(bGPDstroke *stroke, int count) { - if (stroke->points == NULL) - stroke->points = MEM_callocN(sizeof(bGPDspoint) * count, "gp_stroke_points"); - else - stroke->points = MEM_reallocN(stroke->points, sizeof(bGPDspoint) * (stroke->totpoints + count)); + if (count > 0) { + if (stroke->points == NULL) + stroke->points = MEM_callocN(sizeof(bGPDspoint) * count, "gp_stroke_points"); + else + stroke->points = MEM_reallocN(stroke->points, sizeof(bGPDspoint) * (stroke->totpoints + count)); - stroke->totpoints += count; + stroke->totpoints += count; + } } static void rna_GPencil_stroke_point_pop(bGPDstroke *stroke, ReportList *reports, int index) @@ -174,12 +176,14 @@ static void rna_GPencil_stroke_remove(bGPDframe *frame, ReportList *reports, bGP static bGPDframe *rna_GPencil_frame_new(bGPDlayer *layer, ReportList *reports, int frame_number) { + bGPDframe *frame; + if (BKE_gpencil_layer_find_frame(layer, frame_number)) { BKE_reportf(reports, RPT_ERROR, "Frame already exists on this frame number"); return NULL; } - bGPDframe *frame = gpencil_frame_addnew(layer, frame_number); + frame = gpencil_frame_addnew(layer, frame_number); WM_main_add_notifier(NC_GPENCIL | NA_EDITED, NULL); @@ -293,7 +297,7 @@ static void rna_def_gpencil_stroke_points_api(BlenderRNA *brna, PropertyRNA *cpr func = RNA_def_function(srna, "add", "rna_GPencil_stroke_point_add"); RNA_def_function_ui_description(func, "Add a new grease pencil stroke point"); - RNA_def_int(func, "count", 1, 1, INT_MAX, "Number", "Number of points to add to the stroke", 1, INT_MAX); + RNA_def_int(func, "count", 1, 0, INT_MAX, "Number", "Number of points to add to the stroke", 0, INT_MAX); func = RNA_def_function(srna, "pop", "rna_GPencil_stroke_point_pop"); RNA_def_function_ui_description(func, "Remove a grease pencil stroke point"); From 7614428c09de832df4a39038ceec4eb5e2951800 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 8 Oct 2012 10:03:01 +0000 Subject: [PATCH 108/347] style cleanup: pep8 --- build_files/buildbot/master.cfg | 7 ++++--- build_files/buildbot/master_unpack.py | 2 +- build_files/buildbot/slave_pack.py | 6 +++--- build_files/cmake/cmake_static_check_clang_array.py | 2 +- build_files/cmake/cmake_static_check_cppcheck.py | 2 +- build_files/cmake/cmake_static_check_smatch.py | 2 +- build_files/cmake/cmake_static_check_sparse.py | 2 +- build_files/cmake/cmake_static_check_splint.py | 2 +- build_files/cmake/project_source_info.py | 2 +- doc/python_api/sphinx_doc_gen.py | 2 +- source/blender/python/rna_dump.py | 4 ++-- source/tests/batch_import.py | 12 ++++++------ source/tests/bl_load_addons.py | 2 +- source/tests/bl_load_py_modules.py | 2 +- source/tests/bl_mesh_modifiers.py | 2 +- 15 files changed, 26 insertions(+), 25 deletions(-) diff --git a/build_files/buildbot/master.cfg b/build_files/buildbot/master.cfg index 066c133d335..1bd47303b2f 100644 --- a/build_files/buildbot/master.cfg +++ b/build_files/buildbot/master.cfg @@ -28,8 +28,8 @@ c['slavePortnum'] = 9989 from buildbot.changes.svnpoller import SVNPoller c['change_source'] = SVNPoller( - 'https://svn.blender.org/svnroot/bf-blender/trunk/', - pollinterval=1200) + 'https://svn.blender.org/svnroot/bf-blender/trunk/', + pollinterval=1200) # BUILDERS # @@ -137,7 +137,8 @@ c['schedulers'] = [] # builderNames=buildernames, # periodicBuildTimer=24*60*60)) -c['schedulers'].append(timed.Nightly(name='nightly', +c['schedulers'].append(timed.Nightly( + name='nightly', builderNames=buildernames, hour=3, minute=0)) diff --git a/build_files/buildbot/master_unpack.py b/build_files/buildbot/master_unpack.py index f67bd294496..ecacf3bff6f 100644 --- a/build_files/buildbot/master_unpack.py +++ b/build_files/buildbot/master_unpack.py @@ -112,7 +112,7 @@ branch = get_branch(packagename) if platform == '': sys.stderr.write('Failed to detect platform ' + - 'from package: %r\n' % packagename) + 'from package: %r\n' % packagename) sys.exit(1) # extract diff --git a/build_files/buildbot/slave_pack.py b/build_files/buildbot/slave_pack.py index 654efd72876..eafb25ac7b0 100644 --- a/build_files/buildbot/slave_pack.py +++ b/build_files/buildbot/slave_pack.py @@ -50,9 +50,9 @@ if builder.find('scons') != -1: install_dir = os.path.join('..', 'install', builder) scons_options += ['WITH_BF_NOBLENDER=True', 'WITH_BF_PLAYER=False', - 'BF_BUILDDIR=' + build_dir, - 'BF_INSTALLDIR=' + install_dir, - 'WITHOUT_BF_INSTALL=True'] + 'BF_BUILDDIR=' + build_dir, + 'BF_INSTALLDIR=' + install_dir, + 'WITHOUT_BF_INSTALL=True'] config = None bits = None diff --git a/build_files/cmake/cmake_static_check_clang_array.py b/build_files/cmake/cmake_static_check_clang_array.py index 8afaf0805f2..941407170ff 100644 --- a/build_files/cmake/cmake_static_check_clang_array.py +++ b/build_files/cmake/cmake_static_check_clang_array.py @@ -52,7 +52,7 @@ def main(): [c] + [("-I%s" % i) for i in inc_dirs] + [("-D%s" % d) for d in defs] - ) + ) check_commands.append((c, cmd)) diff --git a/build_files/cmake/cmake_static_check_cppcheck.py b/build_files/cmake/cmake_static_check_cppcheck.py index 4ea357162ca..c458e8ede11 100644 --- a/build_files/cmake/cmake_static_check_cppcheck.py +++ b/build_files/cmake/cmake_static_check_cppcheck.py @@ -55,7 +55,7 @@ def main(): [c] + [("-I%s" % i) for i in inc_dirs] + [("-D%s" % d) for d in defs] - ) + ) check_commands.append((c, cmd)) diff --git a/build_files/cmake/cmake_static_check_smatch.py b/build_files/cmake/cmake_static_check_smatch.py index eebb2e94f93..5681d2ae5ed 100644 --- a/build_files/cmake/cmake_static_check_smatch.py +++ b/build_files/cmake/cmake_static_check_smatch.py @@ -50,7 +50,7 @@ def main(): [c] + [("-I%s" % i) for i in inc_dirs] + [("-D%s" % d) for d in defs] - ) + ) check_commands.append((c, cmd)) diff --git a/build_files/cmake/cmake_static_check_sparse.py b/build_files/cmake/cmake_static_check_sparse.py index 8862fc78bb5..4f4eb838dd5 100644 --- a/build_files/cmake/cmake_static_check_sparse.py +++ b/build_files/cmake/cmake_static_check_sparse.py @@ -48,7 +48,7 @@ def main(): [c] + [("-I%s" % i) for i in inc_dirs] + [("-D%s" % d) for d in defs] - ) + ) check_commands.append((c, cmd)) diff --git a/build_files/cmake/cmake_static_check_splint.py b/build_files/cmake/cmake_static_check_splint.py index b753a6122cd..7be28c01af8 100644 --- a/build_files/cmake/cmake_static_check_splint.py +++ b/build_files/cmake/cmake_static_check_splint.py @@ -80,7 +80,7 @@ def main(): [c] + [("-I%s" % i) for i in inc_dirs] + [("-D%s" % d) for d in defs] - ) + ) check_commands.append((c, cmd)) diff --git a/build_files/cmake/project_source_info.py b/build_files/cmake/project_source_info.py index ed17ec5bac4..17a9327a358 100644 --- a/build_files/cmake/project_source_info.py +++ b/build_files/cmake/project_source_info.py @@ -85,7 +85,7 @@ def makefile_log(): print("running make with --dry-run ...") process = subprocess.Popen(["make", "--always-make", "--dry-run", "--keep-going", "VERBOSE=1"], stdout=subprocess.PIPE, - ) + ) while process.poll(): time.sleep(1) diff --git a/doc/python_api/sphinx_doc_gen.py b/doc/python_api/sphinx_doc_gen.py index 186f67b0df6..0e6ef764116 100644 --- a/doc/python_api/sphinx_doc_gen.py +++ b/doc/python_api/sphinx_doc_gen.py @@ -399,7 +399,7 @@ SPHINX_THEMES = {'bf': ['blender-org'], # , 'naiad', available_themes = SPHINX_THEMES['bf'] + SPHINX_THEMES['sphinx'] if ARGS.sphinx_theme not in available_themes: - print ("Please choose a theme among: %s" % ', '.join(available_themes)) + print("Please choose a theme among: %s" % ', '.join(available_themes)) sys.exit() if ARGS.sphinx_theme in SPHINX_THEMES['bf']: diff --git a/source/blender/python/rna_dump.py b/source/blender/python/rna_dump.py index 489f011e693..15cc60d997e 100644 --- a/source/blender/python/rna_dump.py +++ b/source/blender/python/rna_dump.py @@ -95,7 +95,7 @@ def seek(r, txt, recurs): if GEN_PATH: newtxt = txt + '.' + item - if item == 'rna_type' and VERBOSE_TYPE == False: # just avoid because it spits out loads of data + if item == 'rna_type' and VERBOSE_TYPE is False: # just avoid because it spits out loads of data continue value = getattr(r, item, None) @@ -114,7 +114,7 @@ def seek(r, txt, recurs): except: length = 0 - if VERBOSE == False and length >= 4: + if VERBOSE is False and length >= 4: for i in (0, length - 1): if i > 0: if PRINT_DATA: diff --git a/source/tests/batch_import.py b/source/tests/batch_import.py index 5c228c014ca..177ab8ea0b0 100644 --- a/source/tests/batch_import.py +++ b/source/tests/batch_import.py @@ -63,12 +63,12 @@ def clear_scene(): def batch_import(operator="", - path="", - save_path="", - match="", - start=0, - end=sys.maxsize, - ): + path="", + save_path="", + match="", + start=0, + end=sys.maxsize, + ): import addon_utils _reset_all = addon_utils.reset_all # XXX, hack diff --git a/source/tests/bl_load_addons.py b/source/tests/bl_load_addons.py index 21a0101d684..5d9ac750362 100644 --- a/source/tests/bl_load_addons.py +++ b/source/tests/bl_load_addons.py @@ -36,7 +36,7 @@ def reload_addons(do_reload=True, do_reverse=True): for mod_name in list(addons.keys()): addon_utils.disable(mod_name) - assert(bool(addons) == False) + assert(bool(addons) is False) # Run twice each time. for i in (0, 1): diff --git a/source/tests/bl_load_py_modules.py b/source/tests/bl_load_py_modules.py index 619cad67cb8..b634b4c4385 100644 --- a/source/tests/bl_load_py_modules.py +++ b/source/tests/bl_load_py_modules.py @@ -49,7 +49,7 @@ def load_addons(): for mod_name in list(addons.keys()): addon_utils.disable(mod_name) - assert(bool(addons) == False) + assert(bool(addons) is False) for mod in modules: mod_name = mod.__name__ diff --git a/source/tests/bl_mesh_modifiers.py b/source/tests/bl_mesh_modifiers.py index 390679800f6..92fae25df16 100644 --- a/source/tests/bl_mesh_modifiers.py +++ b/source/tests/bl_mesh_modifiers.py @@ -846,7 +846,7 @@ if __name__ == "__main__": @persistent def load_handler(dummy): print("Load Handler:", bpy.data.filepath) - if load_handler.first == False: + if load_handler.first is False: bpy.app.handlers.scene_update_post.remove(load_handler) try: main() From 5b14ce7218e0929d412f7daa4627390bb76de0fc Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 8 Oct 2012 10:04:36 +0000 Subject: [PATCH 109/347] update to ubuntu theme --- .../interface_theme/ubuntu_ambiance.xml | 214 +++++++++--------- 1 file changed, 107 insertions(+), 107 deletions(-) diff --git a/release/scripts/presets/interface_theme/ubuntu_ambiance.xml b/release/scripts/presets/interface_theme/ubuntu_ambiance.xml index d54766ec88f..cc02d2e5c84 100644 --- a/release/scripts/presets/interface_theme/ubuntu_ambiance.xml +++ b/release/scripts/presets/interface_theme/ubuntu_ambiance.xml @@ -1,47 +1,47 @@ - + wire="#93237f"> @@ -71,7 +71,7 @@ - @@ -109,14 +109,14 @@ - + + view_sliders="#9c9c9c"> + list_text="#e2e2e2" + list_text_hi="#f47421" + list_title="#ffffff"> @@ -175,8 +175,8 @@ selected_file="#6b395a" tiles="#3c3b37"> - + list_text="#e2e2e2" + list_text_hi="#f47421" + list_title="#ffffff"> @@ -265,7 +265,7 @@ vertex_size="3"> + back="#29001b"> @@ -333,7 +333,7 @@ view_sliders="#969696"> - + syntax_numbers="#972144" + syntax_string="#6e00ff"> @@ -532,13 +532,13 @@ + text="#dddddd" + text_sel="#dddddd"> @@ -574,7 +574,7 @@ shadetop="20" show_shaded="TRUE" text="#dfdbcf" - text_sel="#fffbed"> + text_sel="#f47421"> @@ -615,7 +615,7 @@ shadetop="25" show_shaded="FALSE" text="#dddddd" - text_sel="#fff7fb"> + text_sel="#ffffff"> @@ -627,7 +627,7 @@ shadetop="5" show_shaded="TRUE" text="#dfdbcf" - text_sel="#ffffff"> + text_sel="#dfdbcf"> @@ -639,16 +639,16 @@ shadetop="21" show_shaded="TRUE" text="#dfdfdf" - text_sel="#ffffff"> + text_sel="#dfdfdf"> - @@ -685,7 +685,7 @@ shadetop="-10" show_shaded="TRUE" text="#dfdbcf" - text_sel="#fffaec"> + text_sel="#ffffff"> @@ -721,7 +721,7 @@ shadetop="25" show_shaded="FALSE" text="#ffffff" - text_sel="#ffffff"> + text_sel="#ff5d0d"> From 5a721a40717576b55c676160e0820e61a637abff Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 8 Oct 2012 10:19:59 +0000 Subject: [PATCH 110/347] speaker and empty where hardly visible --- release/scripts/presets/interface_theme/ubuntu_ambiance.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/release/scripts/presets/interface_theme/ubuntu_ambiance.xml b/release/scripts/presets/interface_theme/ubuntu_ambiance.xml index cc02d2e5c84..05075f06239 100644 --- a/release/scripts/presets/interface_theme/ubuntu_ambiance.xml +++ b/release/scripts/presets/interface_theme/ubuntu_ambiance.xml @@ -21,7 +21,7 @@ edge_select="#f47421" edge_sharp="#ff4c00" edge_facesel="#4b4b4b" - empty="#000000" + empty="#93237f" face="#75757512" extra_face_angle="#002000" extra_face_area="#0059ee" @@ -44,7 +44,7 @@ outline_width="2" panel="#a5a5a57f" skin_root="#000000" - speaker="#000000" + speaker="#93237f" transform="#ffffff" handle_vect="#409030" handle_sel_vect="#82c036" From ea3db4a71ae8e88635ad042222eb318a2dabc682 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 8 Oct 2012 10:50:18 +0000 Subject: [PATCH 111/347] resize info header (was too much white space) --- release/datafiles/startup.blend | Bin 405076 -> 405076 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/release/datafiles/startup.blend b/release/datafiles/startup.blend index 3db58b8fb69676457a180a394a4976e8267402f7..8b0e052fad83d23c6f608d89256a9054b9e9e836 100644 GIT binary patch literal 405076 zcmeF44S-x#eYfvsL$XE`L}`}~aS_z0SP@WGgzRoUa6vu-3Aj=*EMZ|&lWfdxaIsYv zts1E{ZI!oMtC0H9##&pgv|YbK_-LC}{07}xZLzg&)T*>v-HMR+oco;L{N~=BNoIF8 zdEqq!lRMAM`JZ#ijGl``L@~`o9+HiS>7MbUZIE4-5aq|2yxwenD(v z^2s9$<1#xk#B_wfL$^a2IFx~(`wYDF!Yu0xq8R_nEx9K?h&T3|mzQ4n(sdgz?BBTG zg8L{Cnwoa&oS+}|maWqwYCkc)=SR8Zv<%wI=B0a#SbY1x%u0e&k9}?4g~`XU6z@5_ z`26B~Ch~G>N4&gebx#zt-rpbB$#?e=)TbQD^0&OB z{kX&8^OJ4k`S#KIN&2&+w5*QJ%WJ+(FXX}HLN$2ugFEwQ<2dOEkJOL*!sFP_&JQxK z!o!+3#i^X)+MfQowiuxL9LyL{oXROq?_c#PPGd)LDyKM=Q+?t%?&2-REe=cN^(*0V ze1D4{_(48S!o&QgcFXlBUgZ_P`xC4m)vNcb{;6KYtGwd1epRpH)sJ$#$}3*4t6sHR ztN+_WVU457@OWS2Q0=Q8)vNa6Qn`(5w58?7g)f}18r!n1Pr5E2&y(Lz`AN(1Pr>8g zW?5Zde7yT<53t>S^f&VOn77VQt>XS6l!>jh@2nBOYyI+AN0xn|Ctq|tP~`l{`v2(t z9FrG`vAaV(T8?#vcO34~>#eQxv%|AR*^LX2&F}T=tbRrHS3jr6E&01@33bPJ7jMT_ z9z|OG6!IA#H*-@yl|SXP?<;A&r1g`xG4|)nva!Lt-QHNYcz$^D==8!LBw4>b@e|TA zJ)P6{wQ?Sz?r8p_c50p^JxQttpG!v(pOs z+cv}rT_3ek|XL~hR^YV{tAgb9S%D3{Xd{5q) z#&22=<#x*Xx_a}L;lXmDeQ>k!OJ~^L^sapR;ceNo3;B-wmk0W$d@H}o_vqc^TkE0R zkDB?)$9lPBZEiL`4(!@BH~Q@PA>ZfZg`?}@O-ty&{HuH`zsh&}-;i&uhjQz+^EEuO zdFYi58Kv3yRSmaP?z#8_A>Z7T=X^(4FCU<#@~!+T-xGgJzO^38&DYM?+AW)}Zz$ba zv+>IsZmHaJ@o!GcccY&fRKskR%D3{XeE0nw`POhH<7)UdL<<`sj%J)y!gp`kL*}UJu9V%-! zes#kwm3uC}a@zQw;cmPtn$c4ER(_T5&d-r=t%q`@&e!nTE$cUptQnfwfNM6s`SE@9 zw0x&S9p$$=r>uM{zsmRI=gGI$L%Gpu`5L}q!-j#8%{P<_*5PL3SIw-s8ohWZ_=KDG zPx1p?HA>FqQ_8pUt9*}sk$h`Cl-qQ^_k zzLj6)TgP9t9?C72^Y!Y1b=M7!%zpo5rtvS$+iPZo-x_?vv3I?oTcd{xI=NB;qz=s0ZNdOY5m zU2&Is($#Zg_pv9yan8~4*0|2%t={ogy-umhzcr7yPKKiz@wN zSv=l)eC^|{lV43LU?fqHLZeP5vCnR?yzB3VQzlziN9sl~i<30ZPrl3%11JG>z>Tr~0_}Zb( z8yaY`p7 z!vh^FXVW(C<%p2)%L;GnU?gApR(_T5$$uu_S`USe1#rHu4?nIr{hBqKHb+N~tQ%$H4@L)XKznh(?ZnqhqS z6-_vVJ(Cv8@8IU2wPsfpo{V$Mfxao<%CGX>{;%X)>!I9_Y5CsRzoC)ida9?{`13{v zX0PtN6E6$-K3Uz#mkmt2h4QljOZ{=6{?)!K0t@TiDcUrzT48;TZYeqKruYKjZjn|dS zm$}*a3-jhW!fr}K&6S%Ed~e7%`=}b%2lM+d!a)!`jqw|QvG#%tEB z+t7bqgHmZWercuEj`L!xjm^^4@8VO_@_jImUn{@Lw|b`aAlB0P3L~05;Wa~>*9~kO z>2K(Zs%GOW``;ZG&!AQHJ}%#%=Q}>q_&!+2uk+vUrQiGM^JDBsyyqH~rD7oj-ldJ?FIj&38k8??3H@ zuiA3wF<+eQIsVqe?mXjXx9+<5%*{*R@RR%QxZxYEO9$p}?{4<}H{1W1qo3#7fBn*1 z^Knw0gGQf=9C zsJtBO>NxT6rI(Grb?K{)d)?CVt8qKLD#Yve&3_gO1l;c}mO1_O)2F@H_#TSE9X+4D z=Yl2r3>o9%aj(I%(|L8p!Uv3KHw(X`jqSH)ZSB7v9vvR?G1m3jd+rH8kbBMY`i&nM zej~jw{-}A*Zk6*k(s>#>Z)56m&O6lk9OVXAUD~rT>>kCrI{T$lPkmnb^+veX`rZ9s zc)9a`S?);7J%`bsz6C7XE@WA5r*fWTdZE#M&hmL1>W9vU==^W`Q*KWj$8Sdfl~de~ z6sP)BK9tPoH^r%(;@W?h@=$8GeBOr2DQ;_uQ+;YrbFJD_ImJz-IMt`PEPHZ(7J}kb zPH}@jqMxcyabpXMaVn>{$rPvh6xW?rnA%f0#r6IV?WsP;728ue#Z9C*)#tc-^I@p= zR8Db=e@uI-PjO=li*YKaxbYOH`V<$=h{_+TJ(W{j+fQgu^(n4Y^{U&2_Q;ybf6 z-=}&MU-p#xukwoDk>XXa+N~F_@``V7p?%e>?WgQJwXgDu-%IUTr^R zkE?x^SN!7nw6A)V|9bH%ulVs4uX^Pl%`ci4)V|6qzAf#qs$OmP_2N}t@uMkT^{U_X z;#FSp+Fw?^8oyc(<^HR@;`O@f)wrv*{{R8_Hf*1FnvDJvUefv?QSc!tM+%l;@kQD_V_nBe?6|ZcpOb} zI*wK|zT-p7sppY<9&F6lnfW`^J7yWrsEwaA>wRRLTGrfgG_|IDDu2qSURR!T-t~i& z&*Q`A-gwO5dx7uo4i~rS*%Vgtjp@L(J|7Mx*6&)xdOfeR@(1{g_%hclq2NTG4i-?W*l0#<#XN&CBwmJfr=U*wc9H z37@O<8Su-Y!}I5Nx7-^K*rZ$EIrMwtMC#YF^RbB!uf1JOcK=&G>IM)0e!kQ=P@KlW zM9uhjE~ELhU1i%#tlrgLcBSqg6JH*?HN=MV%eBmp|CG-!?`}CZi}(HCl&?>OHe$ZY zH)`={D8D}0J$K_EdP@0IKGmM`oOAwr$8+x1Yb|5HyR0Sq#$A!08|vsz@8jcXxg;&M zUHww&b=8xW@pxMIqEN=a7wc~MM9Xu-J1C@|UwqN3c!K%bp^fo8qH@jq=4RuU z&8E>pm%hIDxh*HBXP#AfG)Z-s@})tTSC4$-#H6MZR2g913WL${6EUK@~eEeKaqTEJxsQoTPNS)M;!y3 zXZ-cE^F6!x3ue`7b-so|zTx>P-=3kX%gya$C9S>8GLHUw|>7wz7OW_#gt#=d;A#k zt@Y6NxO({>9_+tnMngLvF3$Jt;#bY8)#{PDD9?9%M*eQ}ySwUIX8Ks;TlrPKJC7sZ zS`VE^*2{PJRdxIwe$L#7tbN*QQR(_T5$>Yhl z)*jkXoNp9<&AxVEcm@iu%J;0|SB9vLl{0O%I(=W8mhZOemk-cm+`AB!(@BCd=G6I z*|cSbpDwe^`JP?;#j|R)I^QRUe7`w8!FgD_D{>HB8 zq#9W|-?NKfI;&Qz`*3)bPdM}TV4Z*47WRvDeDGtTOO1T4JsA6{)!CWr$GVQ>;=lPx z{#N#ei}P)-(MTMR@p&Dm)p6U!i}9_F=a#?E)%TM+o?BgYSK1MJOL+2#BjPVXobkaY zaGYxD>1lsO%XFN0^l3a_U0-}W_z>6o?Ry{B0gnBS#~G(moQ^ZrjK6=|a_ZA@+ubED zw^n4mpZvJ({eK%`!*N?JYah2=5RTi1dtRm9hixI38{vljjrGUe$MILb?XRY-N6lS6?+=Y@oKJ+u-U`aSG9TfGkE%!U zV0(Oj@`?N*pR_-h?OLAE_dn(DiS>Pu-n_ooxGz-xl5oJLwY9tD)m7gE^*)~U)qV=~ zSC-F&$DdW(C%eDI_p76C;d=m$|MnE8@n183>_=(5%O{V#?}6gg#ACk7xBYz&G*tKJrQA>enmvO-P~ux z>21{La`6p5LTUWLWAnpTT5f$#?d`ac?#DdE?K@sQL-qV9JdV#lKHc}E`eV8K!*k*v zrq{zF+*&Gs*XD^ind9fS`0c8G&wX@G;rAa^*X56|kH65r-;dnBtjL`=6nS)Ik+)u3 zc!%iB|DlXv-CzpK*kYxFxM?GJ`(^V>(mml<&$ zerurP!zA9)vaR){ z--l5>i*Cun8uIm@O8KmF{ikw0`(x!(`BOgS3+0)5P73=GS5=Kqb9@hR4vpjQ9bqKI zo3=acS46IUJul>c%J~fM{5rlt<30AH_V|qX^!12h4b|hb-t~xL zxtZLQPvuYfR2|B*_>sDlKkMalTWj3j>))C^KX>byY|k;D@%&uzpN1w`Z`04u{o@O_ z#W7U49sjuE`MKwRwYl?izw%|y&s|YEKll0jIY0OPS1s=uy5YmSroMPzcbM$*^K<{Y z_uqG(dYjMBefQogmmJ&W^K&m=Hr931>f-sikNNoep3sM$Tf_Oe{o(xFj=zZK=k|WA zqdGAkd-Syoio0q=m;rs4*&o^6_ zp4m40^KM&pPw7YM7*oUk>6;2ksfQgzw>iX z2=cl=Z4DX zh!yxzpD)Vicj$Ne`g~E{#-D}#xcE8ZjX|XI=6z(|gH= z^~J|KHvc%^E8H`}QuE-R6sLJ`u&YLV_sf=3pFTI7QsQ!JMUL+$-j0d??0R;H4WA>l ztob?OBlC{U;=Qq(@}>Qm>L_Zd|2d-fsdIO{B7QDY{*=!>-Dy3gJkz({Fh)1s;eJNG z_^!yi!#&2v{jmGPJ>LG7MW+3<$knf>m(zmdKa0Y?7RP_$-<9*o^mj`Q&p%{r%qFljk;{%AfM7 zL@CeV9FH(A-w?**_FduL&FilT9G~y#i5$nF#$Q~1r6oS==OgR&p`+e-R=nrmcdT6Y zVoGM&Iz5Ox{n=MrzG>d)quB3#<#T^E^`1C)`HWhYfBz!%E2Uwd{SQOoQF-f3^V#&y zhj&!93M|KjW^8;ng=v5@M`dJnlJP{y}s|McYe9PFTJo;-}`j8 ze4%O$>U*Dw)%aV>sdRm$(Ti(%J#=QrtNEUO_h|9^dc|qGs~vxBXQ~k#K!M^(z52~wewrrvv}YCtvX*ZXXP9F!}0T)wt@rucY&2Zyn#SAAftS_x8@`ed-0zALu&mC;ysXr}2uX ze|YD^-`KTt{4rVby1o_SJ3~z5g`wX66Y5g@#(^Jn|L&46 z?7DF8A9u(2Q~&PHt}lJ?rrUq?(`Vcs`f&U0@Bdua&2QS;b=&)o?+ShBy8rj?{#4ue zvhKF^-`W}K*!lXSyKi57^ZRd~eBSeVLLYkWJolC*4}ANNmUMjX)=!45`nFSFx%1PP zzvh$YeBgpNhyLz3?aQM_-}zgI&0D%?>wS0J@s(S5{o~W0xb*H1@4e%efiLxZc=7h` zX5W9a{f{~NdA|Mq)7rbs@4wOK;`sTmU+C?+=)FJQc}m+AJ6lisP#DvEhE|<_`|i%t zao`7fTEbk#bsFP7qi^wh;aKO+H}x#N=H4roKIN~jU+PzR6t}~xf;u(N{QrI&I8N*N zbsDp=@QCBU>>D23QarGDXS~)?4#X1SF-GTMe4_OET__P@q6Iv*!Z}-e-;iW&gd4$VMmBiKXkpf9jRaS zDpQ=wDX#rx^i%aY{+;0y75jA^VX1P8+nVB3Uo0DMuU%M-Q#r*=r8w0`RE*=1`l)h? z8@wXrImIh3%Wf!Kr%~k;H<{v8pW(J-JSN&8u#kHmJtNIjo%7S8?$|-I% z#i>5UwY3)GR8Dc)UR0msc%*)+oZ?hY^@&eO8%~T{9G=v6sOvcGPTQr*Yn+zHo#Itq z@ttc}AF5aJ<#D8Vl~??Z6t8;KZh1T@UgZ_veiiMjUbR~Y^=drVi&uHY5BAf4)vJD&$En&^dBsnrc-5=-UoT$e72kU`?WI#{FK=&p|0=Ke@f5Fm)$j6lr+AfDeA_j&uX@#Py?B*Z{Ah|- zy^1eyziMCQ6~8CNt6sHRFJ9#p-#0-2Rj=l!vIo?@$}4_%idVgglV9Wo#jCvHJFlgE z)vN8NUcAaHen*N|y&8Y@;#FSp?P)(k^(t?AALah5yyCZ}c-5=?*K1$p6|eeLukx>P zpx0ymwg=FDkB~}nVtvDU0s2%?&%ZX3l2UM=(rtb&JwHI0YHpj%Lx5sP1h2uV2 zhR+@GvqyX>9>1QS9UiXY^15*Kx_EEwrhL64*LV;xrCw#*b}G>pg8p zV>{yU)NpHTyIPsLoo`oJj1AjWWm#*xx+Gi!FW&cmtIiko7h|a9;B8mRpYo~RD9_}54{v~q!-soj{*_glmolkj5%M~^1t@V`h8FL@U zU-{N}P36d$aon!%4>rzB|I@2TseRKB`x#wPvR=Ua&#;8YdMwtH99;qpD0e_zjl1-x|)wbpR5VF ziuo$v@)Nqt5s2u8Y}h{9IgDQ~r`(4(uL38C1TN zU*&uBSIM{5L;ZZu?z))H_w3^5;<}n$mFsHq?i!c|%4wJ}E8ohm^4Zt|IxPe@386l{;sR3C*HbE`d`_@3K2!db&(3Y+Q+cK_Uq31GBk6id)%mP7p83AIcs->#NnoiG z|3pY&eRU3enEBlSF*XDzs;YvilHUOA8E z%kTfAuCxFC4VCj~p7HuyKlRuBFRGkJGylHhZh!utyr*&=%`wN^wd5oJ`?)3A_wNqp z(d_!zsdxR&r?39#UFWQS?%Tq7H2;43fj*C>+5VT;)6W|}_lBFNjo(I}3p-2G&Z8+` zPpSPCe{ohZr`s#%(Uh;ngkBpvk4F2K|G%F{6O*&lmcA zr+%-g-+}1!MD1g;QdwCZBV)K-^ag|f23JjH1q ztQo)S<;BkpV}D)bdX1##^||Pn$XCVK@Hs-unx7+13D@S2_r`9@*Y|7ehfvGG`y8SC zDW7@=%5#>*>k4Ec2Q1(Hfv?~7xl1=LU-|CO-|-s(3PtVP=pPu`lmrR_q=&Mic=9o_0O5)cdr!2T>-f;^?8~ma*=JN+>{KX2Y zZ?UFoK2VS2`0NgS(D;r?3%K7~`8@jl2FziBnD^OMS3Z9&*3YQ2B;esW*!>It#IS6bHeRa-db z5$}!N3iX#lsO8}KO8HYh+td0`o=e?(#A3bAL3~c1ANCZckIA`wGn!A8Kjl+xD9`X% z+J58m4Yvogb!XWpc4lLLTG-YVTVA%M?d?E)!i(dxUOw9n@aIas*OCgYEU&4e@^Rv-m#Q8<&=cWZzxR9jwHji4d|X{mRpCPq4`tv`1`cK5PzDZV z;7|q*W#CW-4rSm_1`cK5PzDZV;7|q*W#CW-4rSm_27b;m5RX|NI$rp5w$cy1-9s5T zlz~GTIFx}y890=ILm4=ffkPQMlz~GTIFx}y890=ILm4=ffkPQ+A_Fr!p2#(@-CXTo zQR?r(=&>8pPi>T6BMsFrYLaNj0B82;o@xW(U}c7&z+p}(84C-p15 zRP&}dl~Y{b=Tg6?#dpq+6)8^T6t_FYsXjG2wy+qda*FHxJngAI$MHz*shr|=q&U^5 zxGZ~e;qSqyoZ{NQKzpiBabpXMaVn>{ttn3RDQ+aKF!fXA6gQRPRG;ID?WvsN2ERx@ zRiER2EB{rs+EY2jO{O^2r?|0&#WbGy}Un_*ElVYyZAn1yvi$nG{vi4 z#h1sC;#FSpds4jWRlDW!q z?XF(D$}4_HidVhre|dbXeU(>y`&VgS_3C}si&uHYZ%y&4SN$$;Cu(2i6+e~YRj=Bu z7q9Y)ADpEBs#pClZ*OW}ec$M)&BNS zSo6NlTO0gm-oNTm`|?OVAH?!w;X-;RgxNRFqzf0`SoQZ%+Oo->>vCW2K9BtiEeF3& zdwaf7Y*+11EIBT}{NzOYw=45{yk3vubY4)+`0aNur=E1)TE_!LRwH$m@%_YGe%@LZ zW5aoCm8H%Tt^Ru`H-^8367P-Ol&>@McUFvvwZwC3d~#^9)~RLWvwiqSd9;?rTEh8< zw|qB$ed=e&*1U{o97i#q%AfM7dX#5a`8ze_A>QKOL)qS)W%tkB-$My+IGl$b|6KF@ zMIo2-vQ6RM_$`h-_T-8&-bZz9;cZuLQ%lKb<%wB7i22+eVznJkD;{qUH4JhUA-m5&dN zgT54}aZo$H^!E$0H!q{VIzLpsuf2S1>VCdmjlC(v#_M3EWzF+J4-bC}CEoXcQ@*Yb zxr+HJ-(oHC+(l)u{Q6`!`P}htwks{m<#vDaLwW66w^FYBy7H;~DW58*Jm(z$e!{pkyCVntHd3fsVmh^tkPptFTf0_dIy6Q>Gcn)Og?-v~2a((NASW zt(OnwGuBnB{#a8!fKp@S#pn|9IdSaI@?yPzOuqX5m2o+7G~>4Orj+le{kUdzF`w~z z`ij%_4yV3V9N(i|w5NVF`}YT$jh~CZU+`dda(X*Y*V{VaOXXYnRldjnoqTIOOg+4! zu)chK$VczrFL*FJC*_w9%|{>bY;(LKj&J2x`R?39zO^1ETh6VM??><7FNltdxA__Q z{sr)W{;Tn={3_p*-zMK$4-@n2<$HF2f56+v?BeI*?-x9neJ16WeE;GB%`}xO-^#D@ zJ^Eept@SXzuwK3&y??*p!R)O3diq%!-|Yu6-^#D@-TpoDt@SXvs9wGwy??(T`s7LB zE}!K4nFl!M8sEyV@;&i=@~!pI_qclbe)RtRg0jCG*-vkFbtvD;ukzjZ0QuH>=sdDs zz8}4Rzo4A&2<8S0D-^#D@-TqVZ zt@TjV(fna0Ut2b=8!5lo05=zWpx4B&4*%CF3v zm2c%&`R;p&d}}?FYp&#L)8Gxm>(0A?uAS*SZ#sT<%~rjQ<3hey7V`bXs#g!xL*-lf zRldiw^gUY|=jHY*`C7YWcw}h9noXOBHqB&^Hygh!Z? zjyD}>j{D*V`lfs1KUw`k{K9swT%&v|zsmPyEBV%XsBS+#uFBVj{!N?0lvysZZ*DgJ z!r3%h=+cD`e=_?};hD!3=)i#Tt^6wAqlcyMKhrobw_cU6bsMi;zhz+K+6G59H8mT5 z-fS8zyorDQ*(bBh3tulkzVP~i0p(lyRleI7l5eeta_bi_J%7cr)$s#Q(8=(~=KggX zXS74ubo|x7GO%`}BYbTzLj6)d+M>|TkE0RuJV<3O4bZ->YtIo zn~h)1&QQmy8Mf>9aZ$)Or2RoHU1shdDc{Pk@;&}I@~!nyZdv)dKJ5JtjIOzE^U#(V z?SD5Le|g?+$BSp$uHVOZ9&Ty5z!)CI{k~eax%7GuSC?Hop1e zC+`mV=Dld1JeYqET=`YL_4`__hkE(mFm%njYu63TXl%#2l<(QbUpUKl{XVAee-}P% zy5O8Xitjsq-cf#)Z#AOzAl6d(VtilIKhm#P8e29S|Kfq64Fe;aZ|GP)SI%l|33`Y-_@CV0l$mi-``)?c_upVWcQQt ztYT|nB4AqXOIGra^GyeW<%c(D&XEOG=B9|L0vEEPqd%&w=Y&h>k%bMq% zjD)|L81IeU3iX#lVl9V-{MDOdw?2`4PQ9J;w6rW$lTE&gaWFpk4@^Vf8qX}$A> zbso`ghpqqkFc?}}4{v!}C6jGg@8elt6DQ)0%JKxbv!k|8_H><@`(*3;|0UE)zoSnk zQk=$r&G@k&rSY!w)*gB1vBi_CV!q0^cplrrkiU9kaqvj;+4r>X<*>9iao@Im zZ;e)*PvuYfR6WXb&STLZKe|(|W#K%wEW0c4uG`~pp5l3I(HE~u1%8^A@=4_C*VD^s z!TGlF^?70RgxcmW2sLib9?Y&P7OY9t<1fmne2X>J`&<;u4jw^1dq2T>YFd`-8Gp_H z=C$wGepp>UFOK6gjq}?=1@+cpb=~0&KPqp%fBTa>A6hQf^<{<;wP8*gc3ic#2qC* zvBXa;@ku2t_Hx+qm zw8#@T7J2lhB6q%{$Wy-$Yd+Tcjkb>C(ad~oWT`Pj^SY-T<-Gas9okIl@-X69ov^Rb!v*vx!vW+^(IpGU;{yb?Kn*3{<>y{^wUVtrl_Z+#$s!VcH}N}oS;eN(Zn zgDTc_P|d@I`C;^3Meh4fk@fjW@#BA4Y+s+xOze(~%0 z#f)Ff_{EH0^!Z+XG0)5WW5zFL{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B= z#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0 zX8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4 zV#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8fY#h4PCTznJlh8NZnEiy6O|@rxP1 znDL7lznJlh8NZnEiy6O|@rxP1nDL7lznJlh8NZnEiy6O|@rxP1nDL7lznJlh8NZnE ziy6O|@rxP1nDL7lznJlh8NZnEiy6O|@rxP1nDL7lznJlh8NZnEiy6O|@rxP1nDL7l zznJlh8NZnEiy6O|@rxP1nDL7lznJlh8NZnEiy6O|@rxP1nDL7lznJlh8NZnEiy6P@ z`v>{Oj9<+7#f)Ff_{EH0%=pEOU(EQ$j9<+7#f)Ff_{EH0%=pEOU(EQ$j9<+7#f)Ff z_{EH0%=pEOU(EQ$j9<+7#f)Ff_{EH0%=pEOU(EQ$j9<+7#f)Ff_{EH0%=pEOU(EQ$ zj9<+7#f)Ff_{EH0%=pEOU(EQ$j9<+7#f)Ff_{EH0%=pEOU(EQ$j9<+7#f)Ff_{EH0 z%=pEOU(EQ$j9<+7#f)Ff_{EH0^nIrMV#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0 zX8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4 zV#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBt zFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFZz9i{9?v0X8dBt zFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K z{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B= z#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0 zX8dBtFJ}B=#xMH4mHcAHFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0 zX8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4 zV#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBt zFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y7}{igh4#xG|4V#Y6K{9?v0X8dBt zFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K z{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B= z#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0 z`aQV(V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0 zX8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4 zV#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBt zFJ}B=#xG|4V#Y6K{9?v0X8dBtFFLk-N?X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K z{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B= z#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0 zX8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4qU)Q=FJ}B=#xG|4V#Y6K{9?v0 zX8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4 zV#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBt zFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K z{G#h6%P(g9V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K z{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B= z#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0 zX8dBtFJ}B=#xG|4V#Y6K{9?v0X8fY-ugfoH{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0 zX8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4 zV#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBt zFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}Crzvm#onDL7l zznJlh8NZnEiy6O|@rxP1nDL7lznJlh8NZnEiy6O|@rxP1nDL7lznJlh8NZnEiy6O| z@rxP1nDL7lznJlh8NZnEiy6O|@rxP1nDL7lznJlh8NZnEiy6O|@rxP1nDL7lznJlh z8NZnEiy6O|@rxP1nDL7lznJlh8NZnEiy6O|@rxP1nDL7lznJlh8NZnEiy6O|@rxP1 znDL7lznJlh8NZnEi~c^0{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4 zV#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBt zFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K z{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xMGNQ}T-$znJlh8NZnEiy6O| z@rxP1nDL7lznJlh8NZnEiy6O|@rxP1nDL7lznJlh8NZnEiy6O|@rxP1nDL7lznJlh z8NZnEiy6O|@rxP1nDL7lznJlh8NZnEiy6O|@rxP1nDL7lznJlh8NZnEiy6O|@rxP1 znDL7lznJlh8NZnEiy6O|@rxP1nDL7lznJlh8NZnEiy6O|@rxP1nDL7lznJlh8NZnE ziy6P@@7KvMX8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBt zFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K z{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B=#xG|4V#Y6K{9?v0X8dBtFJ}B= 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 KHHh>-|NaC1H2*CC literal 405076 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 Date: Mon, 8 Oct 2012 11:02:11 +0000 Subject: [PATCH 112/347] Allow user config files in qtcreator project. The blender.config file used for local #defines in qtcreator projects is rewritten on every project update. To avoid losing user settings these can now be written to an optional blender_custom.config file, which is then merged into the main blender.config on updates. --- build_files/cmake/cmake_qtcreator_project.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/build_files/cmake/cmake_qtcreator_project.py b/build_files/cmake/cmake_qtcreator_project.py index 32d20489e6a..c0a5b34318f 100755 --- a/build_files/cmake/cmake_qtcreator_project.py +++ b/build_files/cmake/cmake_qtcreator_project.py @@ -105,7 +105,14 @@ def create_qtc_project_main(): qtc_cfg = os.path.join(PROJECT_DIR, "%s.config" % FILE_NAME) f = open(qtc_cfg, 'w') - f.write("// ADD PREDEFINED MACROS HERE!\n") + f.write("// ADD PREDEFINED MACROS TO %s_custom.config!\n" % FILE_NAME) + qtc_custom_cfg = os.path.join(PROJECT_DIR, "%s_custom.config" % FILE_NAME) + if os.path.exists(qtc_custom_cfg): + f.write(fc.read()) + fc = open(qtc_custom_cfg, 'r') + f.write(fc.read()) + fc.close() + f.write("\n") defines_final = [("#define %s %s" % (item[0], quote_define(item[1]))) for item in defines] if sys.platform != "win32": defines_final += cmake_compiler_defines() From db54caf430071090b9e3bfa86deba778166447ef Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 8 Oct 2012 11:48:51 +0000 Subject: [PATCH 113/347] Fix #32800: Cycles viewport incredible slow with high number of tiles Final rendering is clamping tile resolution if it's too small, which was missing for viewport --- source/blender/editors/space_view3d/view3d_draw.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index c6bcbfbf50d..c5246b1ad1f 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -2856,6 +2856,12 @@ static int view3d_main_area_draw_engine(const bContext *C, ARegion *ar, int draw engine->tile_x = ceil(ar->winx / (float)scene->r.xparts); engine->tile_y = ceil(ar->winy / (float)scene->r.yparts); + /* clamp small tile sizes to prevent inefficient threading utilization + * the same happens for final renders as well + */ + engine->tile_x = MAX2(engine->tile_x, 64); + engine->tile_y = MAX2(engine->tile_x, 64); + type->view_update(engine, C); rv3d->render_engine = engine; From 5a9bb39e34ec7938599e6ece30198b359cf47187 Mon Sep 17 00:00:00 2001 From: Lukas Toenne Date: Mon, 8 Oct 2012 12:02:55 +0000 Subject: [PATCH 114/347] Fix for own commit r51178, duplicate line. --- build_files/cmake/cmake_qtcreator_project.py | 1 - 1 file changed, 1 deletion(-) diff --git a/build_files/cmake/cmake_qtcreator_project.py b/build_files/cmake/cmake_qtcreator_project.py index c0a5b34318f..83ea761e2d1 100755 --- a/build_files/cmake/cmake_qtcreator_project.py +++ b/build_files/cmake/cmake_qtcreator_project.py @@ -108,7 +108,6 @@ def create_qtc_project_main(): f.write("// ADD PREDEFINED MACROS TO %s_custom.config!\n" % FILE_NAME) qtc_custom_cfg = os.path.join(PROJECT_DIR, "%s_custom.config" % FILE_NAME) if os.path.exists(qtc_custom_cfg): - f.write(fc.read()) fc = open(qtc_custom_cfg, 'r') f.write(fc.read()) fc.close() From 6a82b985c30f783fcd927d1044b32a1c9253da35 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 8 Oct 2012 12:15:18 +0000 Subject: [PATCH 115/347] Fix #32815: cycles environment render as lamp crash with resolution >= 1024. --- intern/cycles/render/light.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/intern/cycles/render/light.cpp b/intern/cycles/render/light.cpp index 5c1737bd60a..d77516a1b18 100644 --- a/intern/cycles/render/light.cpp +++ b/intern/cycles/render/light.cpp @@ -68,20 +68,15 @@ static void dump_background_pixels(Device *device, DeviceScene *dscene, int res, main_task.shader_w = width*height; /* disabled splitting for now, there's an issue with multi-GPU mem_copy_from */ -#if 0 list split_tasks; main_task.split_max_size(split_tasks, 128*128); foreach(DeviceTask& task, split_tasks) { device->task_add(task); device->task_wait(); + device->mem_copy_from(d_output, task.shader_x, 1, task.shader_w, sizeof(float4)); } -#else - device->task_add(main_task); - device->task_wait(); -#endif - device->mem_copy_from(d_output, 0, 1, d_output.size(), sizeof(float4)); device->mem_free(d_input); device->mem_free(d_output); From 4a5f09fc6556746a7eb209c60e9259fdec37dcad Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 8 Oct 2012 12:58:37 +0000 Subject: [PATCH 116/347] Fix #32795: Memory leak when rendering to video file --- source/blender/render/intern/source/pipeline.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index b64a6b85ef7..1859de0039d 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -2117,6 +2117,7 @@ static int do_write_image_or_movie(Render *re, Main *bmain, Scene *scene, bMovie /* note; the way it gets 32 bits rects is weak... */ if (ibuf->rect == NULL) { ibuf->rect = MEM_mapallocN(sizeof(int) * rres.rectx * rres.recty, "temp 32 bits rect"); + ibuf->mall |= IB_rect; RE_ResultGet32(re, ibuf->rect); do_free = TRUE; } @@ -2130,6 +2131,7 @@ static int do_write_image_or_movie(Render *re, Main *bmain, Scene *scene, bMovie if (do_free) { MEM_freeN(ibuf->rect); ibuf->rect = NULL; + ibuf->mall &= ~IB_rect; } /* imbuf knows which rects are not part of ibuf */ From 018195ffae81099aafe99b26607688d3aef7c977 Mon Sep 17 00:00:00 2001 From: Gaia Clary Date: Mon, 8 Oct 2012 12:59:12 +0000 Subject: [PATCH 117/347] fix:[#32784] Crash when Exporting to Collada file (.dae) (was a utf8-character conversion problem) --- source/blender/collada/DocumentExporter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/collada/DocumentExporter.cpp b/source/blender/collada/DocumentExporter.cpp index 7683ec1e9cd..bd7ad16dabd 100644 --- a/source/blender/collada/DocumentExporter.cpp +++ b/source/blender/collada/DocumentExporter.cpp @@ -160,7 +160,7 @@ void DocumentExporter::exportCurrentScene(Scene *sce) clear_global_id_map(); COLLADABU::NativeString native_filename = - COLLADABU::NativeString(std::string(this->export_settings->filepath)); + COLLADABU::NativeString(std::string(this->export_settings->filepath), COLLADABU::NativeString::ENCODING_UTF8); COLLADASW::StreamWriter sw(native_filename); fprintf(stdout, "Collada export: %s\n", this->export_settings->filepath); From 82310c2f596972bc91a9ce192ae5f4bf43d4a625 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 8 Oct 2012 13:57:49 +0000 Subject: [PATCH 118/347] committing 'a' to merge into the tag --- source/blender/blenkernel/BKE_blender.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index 56dfdf404f8..741a001142f 100644 --- a/source/blender/blenkernel/BKE_blender.h +++ b/source/blender/blenkernel/BKE_blender.h @@ -51,7 +51,7 @@ extern "C" { /* used by packaging tools */ /* can be left blank, otherwise a,b,c... etc with no quotes */ -#define BLENDER_VERSION_CHAR +#define BLENDER_VERSION_CHAR a /* alpha/beta/rc/release, docs use this */ #define BLENDER_VERSION_CYCLE alpha From de6e47ab3dbe46f1d5ba3e1eef27f14c5b9ccccb Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 8 Oct 2012 17:41:27 +0000 Subject: [PATCH 119/347] Correction to zoom-t-mouse formula which was broken since view2d drag zoom refactoring --- source/blender/editors/interface/view2d_ops.c | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c index 5ac20829480..eb2f6c62351 100644 --- a/source/blender/editors/interface/view2d_ops.c +++ b/source/blender/editors/interface/view2d_ops.c @@ -849,8 +849,8 @@ static void view_zoomdrag_apply(bContext *C, wmOperator *op) float mval_faci = 1.0f - mval_fac; float ofs = (mval_fac * dx) - (mval_faci * dx); - v2d->cur.xmin += ofs - dx; - v2d->cur.xmax += ofs + dx; + v2d->cur.xmin -= ofs + dx; + v2d->cur.xmax -= ofs - dx; } else { v2d->cur.xmin -= dx; @@ -868,8 +868,8 @@ static void view_zoomdrag_apply(bContext *C, wmOperator *op) float mval_faci = 1.0f - mval_fac; float ofs = (mval_fac * dy) - (mval_faci * dy); - v2d->cur.ymin += ofs - dy; - v2d->cur.ymax += ofs + dy; + v2d->cur.ymin -= ofs + dy; + v2d->cur.ymax -= ofs - dy; } else { v2d->cur.ymin -= dy; @@ -1045,13 +1045,13 @@ static int view_zoomdrag_modal(bContext *C, wmOperator *op, wmEvent *event) /* set transform amount, and add current deltas to stored total delta (for redo) */ if (U.uiflag & USER_ZOOM_INVERT) { - RNA_float_set(op->ptr, "deltax", -dx); - RNA_float_set(op->ptr, "deltay", -dy); - } - else { - RNA_float_set(op->ptr, "deltax", dx); - RNA_float_set(op->ptr, "deltay", dy); + dx *= -1; + dy *= -1; } + + RNA_float_set(op->ptr, "deltax", dx); + RNA_float_set(op->ptr, "deltay", dy); + vzd->dx += dx; vzd->dy += dy; From 1d6dff7e344f54b1bff6cf9064c6b96ce1d0aacb Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Mon, 8 Oct 2012 20:01:36 +0000 Subject: [PATCH 120/347] Some minor fixes about curves' tilt... --- source/blender/editors/transform/transform.c | 7 +++++-- source/blender/editors/transform/transform_ops.c | 16 +++++++++++----- source/blender/makesrna/intern/rna_curve.c | 4 ++-- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index be4e580de01..ef32829a71e 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -4037,12 +4037,15 @@ int Tilt(TransInfo *t, const int UNUSED(mval[2])) outputNumInput(&(t->num), c); - sprintf(str, "Tilt: %s %s", &c[0], t->proptext); + sprintf(str, "Tilt: %s° %s", &c[0], t->proptext); final = DEG2RADF(final); + + /* XXX For some reason, this seems needed for this op, else RNA prop is not updated... :/ */ + t->values[0] = final; } else { - sprintf(str, "Tilt: %.2f %s", RAD2DEGF(final), t->proptext); + sprintf(str, "Tilt: %.2f° %s", RAD2DEGF(final), t->proptext); } for (i = 0; i < t->total; i++, td++) { diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c index 81a4c082dcc..6cc5f19e731 100644 --- a/source/blender/editors/transform/transform_ops.c +++ b/source/blender/editors/transform/transform_ops.c @@ -605,8 +605,10 @@ static void TRANSFORM_OT_trackball(struct wmOperatorType *ot) static void TRANSFORM_OT_rotate(struct wmOperatorType *ot) { + PropertyRNA *prop; + /* identifiers */ - ot->name = "Rotate"; + ot->name = "Rotate"; ot->description = "Rotate selected items"; ot->idname = OP_ROTATION; ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING; @@ -618,15 +620,18 @@ static void TRANSFORM_OT_rotate(struct wmOperatorType *ot) ot->cancel = transform_cancel; ot->poll = ED_operator_screenactive; - RNA_def_float_rotation(ot->srna, "value", 1, NULL, -FLT_MAX, FLT_MAX, "Angle", "", -M_PI * 2, M_PI * 2); + prop = RNA_def_float(ot->srna, "value", 0.0f, -FLT_MAX, FLT_MAX, "Angle", "", -M_PI * 2, M_PI * 2); + RNA_def_property_subtype(prop, PROP_ANGLE); Transform_Properties(ot, P_AXIS | P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR | P_GEO_SNAP); } static void TRANSFORM_OT_tilt(struct wmOperatorType *ot) { + PropertyRNA *prop; + /* identifiers */ - ot->name = "Tilt"; + ot->name = "Tilt"; /* optionals - * "Tilt selected vertices" * "Specify an extra axis rotation for selected vertices of 3d curve" */ @@ -641,9 +646,10 @@ static void TRANSFORM_OT_tilt(struct wmOperatorType *ot) ot->cancel = transform_cancel; ot->poll = ED_operator_editcurve_3d; - RNA_def_float_rotation(ot->srna, "value", 1, NULL, -FLT_MAX, FLT_MAX, "Angle", "", -M_PI * 2, M_PI * 2); + prop = RNA_def_float(ot->srna, "value", 0.0, -FLT_MAX, FLT_MAX, "Angle", "", -M_PI * 2, M_PI * 2); + RNA_def_property_subtype(prop, PROP_ANGLE); - Transform_Properties(ot, P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR | P_SNAP); + Transform_Properties(ot, P_PROPORTIONAL | P_MIRROR | P_SNAP); } static void TRANSFORM_OT_warp(struct wmOperatorType *ot) diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c index 8cba5899b76..b42fb0664f8 100644 --- a/source/blender/makesrna/intern/rna_curve.c +++ b/source/blender/makesrna/intern/rna_curve.c @@ -721,7 +721,7 @@ static void rna_def_bpoint(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_Curve_update_data"); /* Number values */ - prop = RNA_def_property(srna, "tilt", PROP_FLOAT, PROP_NONE); + prop = RNA_def_property(srna, "tilt", PROP_FLOAT, PROP_ANGLE); RNA_def_property_float_sdna(prop, NULL, "alfa"); /*RNA_def_property_range(prop, -FLT_MAX, FLT_MAX);*/ RNA_def_property_ui_text(prop, "Tilt", "Tilt in 3D View"); @@ -808,7 +808,7 @@ static void rna_def_beztriple(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_Curve_update_points"); /* Number values */ - prop = RNA_def_property(srna, "tilt", PROP_FLOAT, PROP_NONE); + prop = RNA_def_property(srna, "tilt", PROP_FLOAT, PROP_ANGLE); RNA_def_property_float_sdna(prop, NULL, "alfa"); /*RNA_def_property_range(prop, -FLT_MAX, FLT_MAX);*/ RNA_def_property_ui_text(prop, "Tilt", "Tilt in 3D View"); From bfadb9c27259b1160696de6381c23f2ad06e9751 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Mon, 8 Oct 2012 20:25:07 +0000 Subject: [PATCH 121/347] Minor UI messages typo fixes. --- source/blender/editors/space_action/action_edit.c | 2 +- source/blender/editors/space_graph/graph_edit.c | 4 ++-- source/blender/makesrna/intern/rna_particle.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c index 3865234a25d..39922904da3 100644 --- a/source/blender/editors/space_action/action_edit.c +++ b/source/blender/editors/space_action/action_edit.c @@ -1480,7 +1480,7 @@ static EnumPropertyItem prop_actkeys_mirror_types[] = { {ACTKEYS_MIRROR_CFRA, "CFRA", 0, "By Times over Current frame", "Flip times of selected keyframes using the current frame as the mirror line"}, {ACTKEYS_MIRROR_XAXIS, "XAXIS", 0, "By Values over Value=0", - "Flip values of selected keyframes (i.e. negative values become positive, and vica versa)"}, + "Flip values of selected keyframes (i.e. negative values become positive, and vice versa)"}, {ACTKEYS_MIRROR_MARKER, "MARKER", 0, "By Times over First Selected Marker", "Flip times of selected keyframes using the first selected marker as the reference point"}, {0, NULL, 0, NULL, NULL} diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c index bff64f8348f..15ad590b5d4 100644 --- a/source/blender/editors/space_graph/graph_edit.c +++ b/source/blender/editors/space_graph/graph_edit.c @@ -1941,11 +1941,11 @@ static EnumPropertyItem prop_graphkeys_mirror_types[] = { {GRAPHKEYS_MIRROR_CFRA, "CFRA", 0, "By Times over Current Frame", "Flip times of selected keyframes using the current frame as the mirror line"}, {GRAPHKEYS_MIRROR_VALUE, "VALUE", 0, "By Values over Cursor Value", - "Flip values of selectd keyframes using the cursor value (Y/Horizontal component) as the mirror line"}, + "Flip values of selected keyframes using the cursor value (Y/Horizontal component) as the mirror line"}, {GRAPHKEYS_MIRROR_YAXIS, "YAXIS", 0, "By Times over Time=0", "Flip times of selected keyframes, effectively reversing the order they appear in"}, {GRAPHKEYS_MIRROR_XAXIS, "XAXIS", 0, "By Values over Value=0", - "Flip values of selected keyframes (i.e. negative values become positive, and vica versa)"}, + "Flip values of selected keyframes (i.e. negative values become positive, and vice versa)"}, {GRAPHKEYS_MIRROR_MARKER, "MARKER", 0, "By Times over First Selected Marker", "Flip times of selected keyframes using the first selected marker as the reference point"}, {0, NULL, 0, NULL, NULL} diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c index 89638389fd2..363d2dc020a 100644 --- a/source/blender/makesrna/intern/rna_particle.c +++ b/source/blender/makesrna/intern/rna_particle.c @@ -2135,7 +2135,7 @@ static void rna_def_particle_settings(BlenderRNA *brna) RNA_def_property_float_default(prop, 0.2); RNA_def_property_ui_text(prop, "Adaptive Subframe Threshold", "The relative distance a particle can move before requiring more subframes " - "(target Courant number); 0.1-0.3 is the recommended range"); + "(target current number); 0.1-0.3 is the recommended range"); RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop = RNA_def_property(srna, "jitter_factor", PROP_FLOAT, PROP_NONE); From 6536e2d01a264986cfbfd7fe351e524bb9d778c6 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Mon, 8 Oct 2012 21:03:35 +0000 Subject: [PATCH 122/347] And more UI messages fixes... --- source/blender/editors/object/object_transform.c | 8 +++++--- source/blender/editors/screen/area.c | 2 +- source/blender/editors/space_action/action_edit.c | 2 +- source/blender/editors/space_graph/graph_edit.c | 2 +- source/blender/editors/space_text/text_ops.c | 2 +- source/blender/editors/transform/transform_ops.c | 4 ++-- source/blender/makesrna/intern/rna_gpencil.c | 6 +++--- source/blender/makesrna/intern/rna_object_force.c | 2 +- source/blender/makesrna/intern/rna_space.c | 2 +- source/blender/makesrna/intern/rna_texture.c | 2 +- 10 files changed, 17 insertions(+), 15 deletions(-) diff --git a/source/blender/editors/object/object_transform.c b/source/blender/editors/object/object_transform.c index 9129d651d4d..1b08235b75c 100644 --- a/source/blender/editors/object/object_transform.c +++ b/source/blender/editors/object/object_transform.c @@ -962,8 +962,10 @@ void OBJECT_OT_origin_set(wmOperatorType *ot) { static EnumPropertyItem prop_set_center_types[] = { {GEOMETRY_TO_ORIGIN, "GEOMETRY_ORIGIN", 0, "Geometry to Origin", "Move object geometry to object origin"}, - {ORIGIN_TO_GEOMETRY, "ORIGIN_GEOMETRY", 0, "Origin to Geometry", "Move object origin to center of object geometry"}, - {ORIGIN_TO_CURSOR, "ORIGIN_CURSOR", 0, "Origin to 3D Cursor", "Move object origin to position of the 3d cursor"}, + {ORIGIN_TO_GEOMETRY, "ORIGIN_GEOMETRY", 0, "Origin to Geometry", + "Move object origin to center of object geometry"}, + {ORIGIN_TO_CURSOR, "ORIGIN_CURSOR", 0, "Origin to 3D Cursor", + "Move object origin to position of the 3D cursor"}, {0, NULL, 0, NULL, NULL} }; @@ -975,7 +977,7 @@ void OBJECT_OT_origin_set(wmOperatorType *ot) /* identifiers */ ot->name = "Set Origin"; - ot->description = "Set the object's origin, by either moving the data, or set to center of data, or use 3d cursor"; + ot->description = "Set the object's origin, by either moving the data, or set to center of data, or use 3D cursor"; ot->idname = "OBJECT_OT_origin_set"; /* api callbacks */ diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index 7c377a041e7..ad9b0f61eb1 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -1526,7 +1526,7 @@ int ED_area_header_switchbutton(const bContext *C, uiBlock *block, int yco) but = uiDefIconTextButC(block, ICONTEXTROW, 0, ICON_VIEW3D, editortype_pup(), xco, yco, UI_UNIT_X + 10, UI_UNIT_Y, &(sa->butspacetype), 1.0, SPACEICONMAX, 0, 0, - TIP_("Display current editor type (click for menu of available types)")); + TIP_("Display current editor type (click for a menu of available types)")); uiButSetFunc(but, spacefunc, NULL, NULL); uiButClearFlag(but, UI_BUT_UNDO); /* skip undo on screen buttons */ diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c index 39922904da3..cd036d7cb50 100644 --- a/source/blender/editors/space_action/action_edit.c +++ b/source/blender/editors/space_action/action_edit.c @@ -1372,7 +1372,7 @@ static EnumPropertyItem prop_actkeys_snap_types[] = { {ACTKEYS_SNAP_CFRA, "CFRA", 0, "Current frame", "Snap selected keyframes to the current frame"}, {ACTKEYS_SNAP_NEAREST_FRAME, "NEAREST_FRAME", 0, "Nearest Frame", - "Snap selected keyframes to the nearest (whole) frame. Use to fix accidental sub-frame offsets"}, + "Snap selected keyframes to the nearest (whole) frame (use to fix accidental sub-frame offsets)"}, {ACTKEYS_SNAP_NEAREST_SECOND, "NEAREST_SECOND", 0, "Nearest Second", "Snap selected keyframes to the nearest second"}, {ACTKEYS_SNAP_NEAREST_MARKER, "NEAREST_MARKER", 0, "Nearest Marker", diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c index 15ad590b5d4..c5fa64d3a70 100644 --- a/source/blender/editors/space_graph/graph_edit.c +++ b/source/blender/editors/space_graph/graph_edit.c @@ -1829,7 +1829,7 @@ static EnumPropertyItem prop_graphkeys_snap_types[] = { {GRAPHKEYS_SNAP_VALUE, "VALUE", 0, "Cursor Value", "Set values of selected keyframes to the cursor value (Y/Horizontal component)"}, {GRAPHKEYS_SNAP_NEAREST_FRAME, "NEAREST_FRAME", 0, "Nearest Frame", - "Snap selected keyframes to the nearest (whole) frame. Use to fix accidental sub-frame offsets"}, + "Snap selected keyframes to the nearest (whole) frame (use to fix accidental sub-frame offsets)"}, {GRAPHKEYS_SNAP_NEAREST_SECOND, "NEAREST_SECOND", 0, "Nearest Second", "Snap selected keyframes to the nearest second"}, {GRAPHKEYS_SNAP_NEAREST_MARKER, "NEAREST_MARKER", 0, "Nearest Marker", diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c index 75b8e2f218d..b2fb16ff7fe 100644 --- a/source/blender/editors/space_text/text_ops.c +++ b/source/blender/editors/space_text/text_ops.c @@ -3352,7 +3352,7 @@ void TEXT_OT_to_3d_object(wmOperatorType *ot) /* identifiers */ ot->name = "To 3D Object"; ot->idname = "TEXT_OT_to_3d_object"; - ot->description = "Create 3d text object from active text data block"; + ot->description = "Create 3D text object from active text data block"; /* api callbacks */ ot->exec = text_to_3d_object_exec; diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c index 6cc5f19e731..fc0c174a525 100644 --- a/source/blender/editors/transform/transform_ops.c +++ b/source/blender/editors/transform/transform_ops.c @@ -634,8 +634,8 @@ static void TRANSFORM_OT_tilt(struct wmOperatorType *ot) ot->name = "Tilt"; /* optionals - * "Tilt selected vertices" - * "Specify an extra axis rotation for selected vertices of 3d curve" */ - ot->description = "Tilt selected control vertices of 3d curve"; + * "Specify an extra axis rotation for selected vertices of 3D curve" */ + ot->description = "Tilt selected control vertices of 3D curve"; ot->idname = OP_TILT; ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING; diff --git a/source/blender/makesrna/intern/rna_gpencil.c b/source/blender/makesrna/intern/rna_gpencil.c index fffee4b61ef..b0fcfb9b540 100644 --- a/source/blender/makesrna/intern/rna_gpencil.c +++ b/source/blender/makesrna/intern/rna_gpencil.c @@ -312,9 +312,9 @@ static void rna_def_gpencil_stroke(BlenderRNA *brna) static EnumPropertyItem stroke_draw_mode_items[] = { {0, "SCREEN", 0, "Screen", "Stroke is in screen-space"}, - {GP_STROKE_3DSPACE, "3DSPACE", 0, "3d Space", "Stroke is in 3d-space"}, - {GP_STROKE_2DSPACE, "2DSPACE", 0, "2d Space", "stroke is in 2d-space"}, - {GP_STROKE_2DIMAGE, "2DIMAGE", 0, "2d Image", "Stroke is in 2d-space (but with special 'image' scaling)"}, + {GP_STROKE_3DSPACE, "3DSPACE", 0, "3D Space", "Stroke is in 3D-space"}, + {GP_STROKE_2DSPACE, "2DSPACE", 0, "2D Space", "Stroke is in 2D-space"}, + {GP_STROKE_2DIMAGE, "2DIMAGE", 0, "2D Image", "Stroke is in 2D-space (but with special 'image' scaling)"}, {0, NULL, 0, NULL, NULL} }; diff --git a/source/blender/makesrna/intern/rna_object_force.c b/source/blender/makesrna/intern/rna_object_force.c index 1c896133408..39f85ebc742 100644 --- a/source/blender/makesrna/intern/rna_object_force.c +++ b/source/blender/makesrna/intern/rna_object_force.c @@ -1307,7 +1307,7 @@ static void rna_def_field(BlenderRNA *brna) prop = RNA_def_property(srna, "use_2d_force", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", PFIELD_TEX_2D); - RNA_def_property_ui_text(prop, "2D", "Apply force only in 2d"); + RNA_def_property_ui_text(prop, "2D", "Apply force only in 2D"); RNA_def_property_update(prop, 0, "rna_FieldSettings_update"); prop = RNA_def_property(srna, "use_root_coords", PROP_BOOLEAN, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index ff5f4988cc1..bfd0f731626 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -1324,7 +1324,7 @@ static void rna_def_background_image(BlenderRNA *brna) srna = RNA_def_struct(brna, "BackgroundImage", NULL); RNA_def_struct_sdna(srna, "BGpic"); - RNA_def_struct_ui_text(srna, "Background Image", "Image and settings for display in the 3d View background"); + RNA_def_struct_ui_text(srna, "Background Image", "Image and settings for display in the 3D View background"); prop = RNA_def_property(srna, "source", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "source"); diff --git a/source/blender/makesrna/intern/rna_texture.c b/source/blender/makesrna/intern/rna_texture.c index 45e3d15b9be..202c53cb75d 100644 --- a/source/blender/makesrna/intern/rna_texture.c +++ b/source/blender/makesrna/intern/rna_texture.c @@ -71,7 +71,7 @@ EnumPropertyItem texture_type_items[] = { {TEX_POINTDENSITY, "POINT_DENSITY", ICON_TEXTURE, "Point Density", ""}, {TEX_STUCCI, "STUCCI", ICON_TEXTURE, "Stucci", "Procedural - create a fractal noise texture"}, {TEX_VORONOI, "VORONOI", ICON_TEXTURE, "Voronoi", "Procedural - create cell-like patterns based on Worley noise"}, - {TEX_VOXELDATA, "VOXEL_DATA", ICON_TEXTURE, "Voxel Data", "Create a 3d texture based on volumetric data"}, + {TEX_VOXELDATA, "VOXEL_DATA", ICON_TEXTURE, "Voxel Data", "Create a 3D texture based on volumetric data"}, {TEX_WOOD, "WOOD", ICON_TEXTURE, "Wood", "Procedural - wave generated bands or rings, with optional noise"}, {TEX_OCEAN, "OCEAN", ICON_TEXTURE, "Ocean", "Use a texture generated by an Ocean modifier"}, {0, NULL, 0, NULL, NULL} From a2a9b6b9a3287a59139f1c371731e9b19e71f686 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Tue, 9 Oct 2012 00:59:40 +0000 Subject: [PATCH 123/347] Made the autokeying warning optional by adding a user pref for this By default, this is enabled, so that newbie users who are most likely to be caught short by this will get the benefits of this option, while seasoned animators are likely to know where to go to turn things off (i.e. the scratch- an-itch urge is quite a powerful motivating force...) --- release/scripts/startup/bl_ui/space_userpref.py | 1 + source/blender/editors/transform/transform.c | 8 +++++--- source/blender/makesdna/DNA_userdef_types.h | 1 + source/blender/makesrna/intern/rna_userdef.c | 5 +++++ 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py index 0c3c0e5a696..df30c3ee9ae 100644 --- a/release/scripts/startup/bl_ui/space_userpref.py +++ b/release/scripts/startup/bl_ui/space_userpref.py @@ -324,6 +324,7 @@ class USERPREF_PT_edit(Panel): col.separator() col.prop(edit, "use_auto_keying", text="Auto Keyframing:") + col.prop(edit, "use_auto_keying_warning") sub = col.column() diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index ef32829a71e..2fe68b20806 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -1617,9 +1617,11 @@ static void drawTransformPixel(const struct bContext *UNUSED(C), ARegion *ar, vo Object *ob = OBACT; /* draw autokeyframing hint in the corner */ - if (ob && autokeyframe_cfra_can_key(scene, &ob->id)) { - drawAutoKeyWarning(t, ar); - } + if ((U.autokey_flag & AUTOKEY_FLAG_NOWARNING) == 0) { + if (ob && autokeyframe_cfra_can_key(scene, &ob->id)) { + drawAutoKeyWarning(t, ar); + } + } } void saveTransform(bContext *C, TransInfo *t, wmOperator *op) diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index 218027209a8..4c196a15db1 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -544,6 +544,7 @@ extern UserDef U; /* from blenkernel blender.c */ /* toolsettings->autokey_flag */ #define AUTOKEY_FLAG_ONLYKEYINGSET (1<<6) +#define AUTOKEY_FLAG_NOWARNING (1<<7) #define ANIMRECORD_FLAG_WITHNLA (1<<10) /* transopts */ diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index 9c989121aa4..e1cf7a13f59 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -2745,6 +2745,11 @@ static void rna_def_userdef_edit(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "autokey_flag", AUTOKEY_FLAG_INSERTAVAIL); RNA_def_property_ui_text(prop, "Auto Keyframe Insert Available", "Automatic keyframe insertion in available F-Curves"); + + prop = RNA_def_property(srna, "use_auto_keying_warning", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_negative_sdna(prop, NULL, "autokey_flag", AUTOKEY_FLAG_NOWARNING); + RNA_def_property_ui_text(prop, "Show Auto Keying Warning", + "Show warning indicators when transforming Object and Bones if Auto Keying is enabled"); /* keyframing settings */ prop = RNA_def_property(srna, "use_keyframe_insert_needed", PROP_BOOLEAN, PROP_NONE); From acf3a2790e82f5b3e1eee768dd084af0eac60285 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 9 Oct 2012 01:07:08 +0000 Subject: [PATCH 124/347] api changelog for 2.64 and 2.63 (which I missed last release) --- doc/python_api/rst/change_log.rst | 1499 ++++++++++++++++++++++++ doc/python_api/sphinx_changelog_gen.py | 13 +- 2 files changed, 1507 insertions(+), 5 deletions(-) diff --git a/doc/python_api/rst/change_log.rst b/doc/python_api/rst/change_log.rst index 4d8f9a5171e..c1f3c2e4267 100644 --- a/doc/python_api/rst/change_log.rst +++ b/doc/python_api/rst/change_log.rst @@ -2397,3 +2397,1502 @@ Removed * **ffmpeg_packetsize** * **ffmpeg_video_bitrate** +2.62 to 2.63 +============ + +bpy.types.ThemeView3D +--------------------- + +Added +^^^^^ + +* :class:`bpy.types.ThemeView3D.camera` +* :class:`bpy.types.ThemeView3D.empty` + +bpy.types.KeyingSet +------------------- + +Added +^^^^^ + +* :class:`bpy.types.KeyingSet.bl_description` +* :class:`bpy.types.KeyingSet.bl_idname` + +Renamed +^^^^^^^ + +* **name** -> :class:`bpy.types.KeyingSet.bl_label` + +bpy.types.BlendDataScenes +------------------------- + +Added +^^^^^ + +* :class:`bpy.types.BlendDataScenes.tag` + +bpy.types.RenderEngine +---------------------- + +Added +^^^^^ + +* :class:`bpy.types.RenderEngine.camera_override` + +bpy.types.BackgroundImage +------------------------- + +Added +^^^^^ + +* :class:`bpy.types.BackgroundImage.show_on_foreground` + +bpy.types.CyclesRenderSettings +------------------------------ + +Added +^^^^^ + +* :class:`bpy.types.CyclesRenderSettings.preview_active_layer` +* :class:`bpy.types.CyclesRenderSettings.sample_clamp` + +bpy.types.ToolSettings +---------------------- + +Added +^^^^^ + +* :class:`bpy.types.ToolSettings.double_threshold` + +bpy.types.Image +--------------- + +Added +^^^^^ + +* :class:`bpy.types.Image.render_slot` + +bpy.types.MovieTrackingStabilization +------------------------------------ + +Added +^^^^^ + +* :class:`bpy.types.MovieTrackingStabilization.filter_type` + +bpy.types.DomainFluidSettings +----------------------------- + +Removed +^^^^^^^ + +* **viscosity_preset** + +bpy.types.ParticleSettings +-------------------------- + +Added +^^^^^ + +* :class:`bpy.types.ParticleSettings.use_rotations` + +bpy.types.SceneGameData +----------------------- + +Renamed +^^^^^^^ + +* **dome_tesselation** -> :class:`bpy.types.SceneGameData.dome_tessellation` + +bpy.types.RegionView3D +---------------------- + +Added +^^^^^ + +* :class:`bpy.types.RegionView3D.update` + +bpy.types.Scene +--------------- + +Added +^^^^^ + +* :class:`bpy.types.Scene.active_layer` + +bpy.types.ShaderNodeTexEnvironment +---------------------------------- + +Added +^^^^^ + +* :class:`bpy.types.ShaderNodeTexEnvironment.projection` + +bpy.types.UserPreferencesEdit +----------------------------- + +Added +^^^^^ + +* :class:`bpy.types.UserPreferencesEdit.fcurve_unselected_alpha` + +bpy.types.MeshTextureFace +------------------------- + +Removed +^^^^^^^ + +* **pin_uv** +* **select_uv** + +bpy.types.Menu +-------------- + +Function Arguments +^^^^^^^^^^^^^^^^^^ + +* :class:`bpy.types.Menu.path_menu` (self, searchpaths, operator, props_default, filter_ext), *was (self, searchpaths, operator, props_default)* + +bpy.types.CompositorNodeDistanceMatte +------------------------------------- + +Added +^^^^^ + +* :class:`bpy.types.CompositorNodeDistanceMatte.channel` + +bpy.types.KeyingSetInfo +----------------------- + +Added +^^^^^ + +* :class:`bpy.types.KeyingSetInfo.bl_description` + +bpy.types.KeyingSets +-------------------- + +Function Arguments +^^^^^^^^^^^^^^^^^^ + +* :class:`bpy.types.KeyingSets.new` (idname, name), *was (name)* + +bpy.types.CompositorNodeOutputFile +---------------------------------- + +Added +^^^^^ + +* :class:`bpy.types.CompositorNodeOutputFile.active_input` +* :class:`bpy.types.CompositorNodeOutputFile.active_input_index` +* :class:`bpy.types.CompositorNodeOutputFile.base_path` + +Removed +^^^^^^^ + +* **filepath** +* **frame_end** +* **frame_start** + +Renamed +^^^^^^^ + +* **image_settings** -> :class:`bpy.types.CompositorNodeOutputFile.format` + +bpy.types.CyclesCameraSettings +------------------------------ + +Added +^^^^^ + +* :class:`bpy.types.CyclesCameraSettings.aperture_fstop` +* :class:`bpy.types.CyclesCameraSettings.aperture_type` + +bpy.types.Struct +---------------- + +Added +^^^^^ + +* :class:`bpy.types.Struct.translation_context` + +bpy.types.ThemeSequenceEditor +----------------------------- + +Added +^^^^^ + +* :class:`bpy.types.ThemeSequenceEditor.movieclip_strip` +* :class:`bpy.types.ThemeSequenceEditor.preview_back` + +bpy.types.TexMapping +-------------------- + +Renamed +^^^^^^^ + +* **location** -> :class:`bpy.types.TexMapping.translation` + +bpy.types.ArmatureActuator +-------------------------- + +Added +^^^^^ + +* :class:`bpy.types.ArmatureActuator.influence` + +bpy.types.ThemeTextEditor +------------------------- + +Removed +^^^^^^^ + +* **scroll_bar** + +bpy.types.ThemeUserInterface +---------------------------- + +Added +^^^^^ + +* :class:`bpy.types.ThemeUserInterface.wcol_tooltip` + +bpy.types.MeshEdge +------------------ + +Removed +^^^^^^^ + +* **is_fgon** + +bpy.types.Brush +--------------- + +Added +^^^^^ + +* :class:`bpy.types.Brush.sculpt_capabilities` + +Renamed +^^^^^^^ + +* **use_space_atten** -> :class:`bpy.types.Brush.use_space_attenuation` + +bpy.types.ShaderNodeMapping +--------------------------- + +Renamed +^^^^^^^ + +* **location** -> :class:`bpy.types.ShaderNodeMapping.translation` + +bpy.types.Mesh +-------------- + +Added +^^^^^ + +* :class:`bpy.types.Mesh.auto_texspace` +* :class:`bpy.types.Mesh.calc_tessface` +* :class:`bpy.types.Mesh.loops` +* :class:`bpy.types.Mesh.polygons` +* :class:`bpy.types.Mesh.tessface_uv_textures` +* :class:`bpy.types.Mesh.tessface_vertex_colors` +* :class:`bpy.types.Mesh.tessfaces` +* :class:`bpy.types.Mesh.unit_test_compare` +* :class:`bpy.types.Mesh.uv_layer_clone` +* :class:`bpy.types.Mesh.uv_layer_clone_index` +* :class:`bpy.types.Mesh.uv_layer_stencil` +* :class:`bpy.types.Mesh.uv_layer_stencil_index` +* :class:`bpy.types.Mesh.uv_layers` + +Removed +^^^^^^^ + +* **faces** +* **layers_float** +* **layers_string** + +Renamed +^^^^^^^ + +* **layers_int** -> :class:`bpy.types.Mesh.polygon_layers_float` +* **layers_int** -> :class:`bpy.types.Mesh.polygon_layers_int` +* **layers_int** -> :class:`bpy.types.Mesh.polygon_layers_string` + +Function Arguments +^^^^^^^^^^^^^^^^^^ + +* :class:`bpy.types.Mesh.update` (calc_edges, calc_tessface), *was (calc_edges)* + +bpy.types.Key +------------- + +Added +^^^^^ + +* :class:`bpy.types.Key.eval_time` + +bpy.types.LatticeModifier +------------------------- + +Added +^^^^^ + +* :class:`bpy.types.LatticeModifier.strength` + +bpy.types.UserPreferencesView +----------------------------- + +Added +^^^^^ + +* :class:`bpy.types.UserPreferencesView.quit_dialog` + + +2.63 to 2.64 +============ + +bpy.types.CyclesLampSettings +---------------------------- + +Added +^^^^^ + +* :class:`bpy.types.CyclesLampSettings.samples` + +bpy.types.Histogram +------------------- + +Added +^^^^^ + +* :class:`bpy.types.Histogram.show_line` + +bpy.types.ThemeView3D +--------------------- + +Added +^^^^^ + +* :class:`bpy.types.ThemeView3D.bone_pose_active` +* :class:`bpy.types.ThemeView3D.skin_root` + +bpy.types.GameObjectSettings +---------------------------- + +Added +^^^^^ + +* :class:`bpy.types.GameObjectSettings.fall_speed` +* :class:`bpy.types.GameObjectSettings.jump_speed` +* :class:`bpy.types.GameObjectSettings.step_height` + + +bpy.types.BlendData +------------------- + +Added +^^^^^ + +* :class:`bpy.types.BlendData.masks` + + +bpy.types.TextureNodeMixRGB +--------------------------- + +Added +^^^^^ + +* :class:`bpy.types.TextureNodeMixRGB.use_clamp` + +bpy.types.SmokeCollSettings +--------------------------- + +Added +^^^^^ + +* :class:`bpy.types.SmokeCollSettings.collision_type` + +bpy.types.CompositorNodes +------------------------- + +Added +^^^^^ + +* :class:`bpy.types.CompositorNodes.active` + +bpy.types.RenderEngine +---------------------- + +Added +^^^^^ + +* :class:`bpy.types.RenderEngine.resolution_x` +* :class:`bpy.types.RenderEngine.resolution_y` +* :class:`bpy.types.RenderEngine.tile_x` +* :class:`bpy.types.RenderEngine.tile_y` + +Function Arguments +^^^^^^^^^^^^^^^^^^ + +* :class:`bpy.types.RenderEngine.begin_result` (x, y, w, h, layer), *was (x, y, w, h)* +* :class:`bpy.types.RenderEngine.end_result` (result, cancel), *was (result)* + +bpy.types.BackgroundImage +------------------------- + +Added +^^^^^ + +* :class:`bpy.types.BackgroundImage.draw_depth` +* :class:`bpy.types.BackgroundImage.frame_method` + +bpy.types.SmokeDomainSettings +----------------------------- + +Added +^^^^^ + +* :class:`bpy.types.SmokeDomainSettings.cell_size` +* :class:`bpy.types.SmokeDomainSettings.density` +* :class:`bpy.types.SmokeDomainSettings.domain_resolution` +* :class:`bpy.types.SmokeDomainSettings.scale` +* :class:`bpy.types.SmokeDomainSettings.start_point` + +bpy.types.CyclesRenderSettings +------------------------------ + +Added +^^^^^ + +* :class:`bpy.types.CyclesRenderSettings.aa_samples` +* :class:`bpy.types.CyclesRenderSettings.ao_samples` +* :class:`bpy.types.CyclesRenderSettings.blur_glossy` +* :class:`bpy.types.CyclesRenderSettings.diffuse_samples` +* :class:`bpy.types.CyclesRenderSettings.glossy_samples` +* :class:`bpy.types.CyclesRenderSettings.mesh_light_samples` +* :class:`bpy.types.CyclesRenderSettings.preview_aa_samples` +* :class:`bpy.types.CyclesRenderSettings.preview_start_resolution` +* :class:`bpy.types.CyclesRenderSettings.progressive` +* :class:`bpy.types.CyclesRenderSettings.transmission_samples` + +Removed +^^^^^^^ + +* **blur_caustics** +* **debug_min_size** + +bpy.types.ActionGroup +--------------------- + +Added +^^^^^ + +* :class:`bpy.types.ActionGroup.color_set` +* :class:`bpy.types.ActionGroup.colors` + +Removed +^^^^^^^ + +* **custom_color** + +bpy.types.WipeSequence +---------------------- + +Added +^^^^^ + +* :class:`bpy.types.WipeSequence.input_1` +* :class:`bpy.types.WipeSequence.input_count` + +bpy.types.ToolSettings +---------------------- + +Added +^^^^^ + +* :class:`bpy.types.ToolSettings.snap_node_element` +* :class:`bpy.types.ToolSettings.use_proportional_edit_mask` + +bpy.types.ThemeClipEditor +------------------------- + +Added +^^^^^ + +* :class:`bpy.types.ThemeClipEditor.space_list` +* :class:`bpy.types.ThemeClipEditor.strips` +* :class:`bpy.types.ThemeClipEditor.strips_selected` + +bpy.types.Image +--------------- + +Added +^^^^^ + +* :class:`bpy.types.Image.colorspace_settings` +* :class:`bpy.types.Image.frame_duration` +* :class:`bpy.types.Image.gl_touch` +* :class:`bpy.types.Image.scale` +* :class:`bpy.types.Image.view_as_render` + + +bpy.types.ThemeDopeSheet +------------------------ + +Added +^^^^^ + +* :class:`bpy.types.ThemeDopeSheet.summary` + +bpy.types.MovieClipUser +----------------------- + +Renamed +^^^^^^^ + +* **current_frame** -> :class:`bpy.types.MovieClipUser.frame_current` + +bpy.types.TransformSequence +--------------------------- + +Added +^^^^^ + +* :class:`bpy.types.TransformSequence.input_1` +* :class:`bpy.types.TransformSequence.input_count` + +bpy.types.ImageSequence +----------------------- + +Removed +^^^^^^^ + +* **color_balance** +* **use_color_balance** + +bpy.types.DupliObject +--------------------- + +Added +^^^^^ + +* :class:`bpy.types.DupliObject.index` +* :class:`bpy.types.DupliObject.particle_index` + +bpy.types.RenderSettings +------------------------ + +Removed +^^^^^^^ + +* **use_color_management** +* **use_radiosity** + +bpy.types.Curve +--------------- + +Added +^^^^^ + +* :class:`bpy.types.Curve.bevel_factor_end` +* :class:`bpy.types.Curve.bevel_factor_start` + +bpy.types.MovieClip +------------------- + +Added +^^^^^ + +* :class:`bpy.types.MovieClip.colorspace_settings` +* :class:`bpy.types.MovieClip.frame_duration` +* :class:`bpy.types.MovieClip.frame_offset` +* :class:`bpy.types.MovieClip.frame_start` + +bpy.types.CompositorNodeTree +---------------------------- + +Added +^^^^^ + +* :class:`bpy.types.CompositorNodeTree.chunk_size` +* :class:`bpy.types.CompositorNodeTree.edit_quality` +* :class:`bpy.types.CompositorNodeTree.render_quality` +* :class:`bpy.types.CompositorNodeTree.two_pass` +* :class:`bpy.types.CompositorNodeTree.use_opencl` + +bpy.types.SpaceUVEditor +----------------------- + +Removed +^^^^^^^ + +* **cursor_location** +* **pivot_point** + +bpy.types.RemeshModifier +------------------------ + +Added +^^^^^ + +* :class:`bpy.types.RemeshModifier.use_smooth_shade` + +bpy.types.CurveMapping +---------------------- + +Added +^^^^^ + +* :class:`bpy.types.CurveMapping.update` + +bpy.types.CompositorNodeMixRGB +------------------------------ + +Added +^^^^^ + +* :class:`bpy.types.CompositorNodeMixRGB.use_clamp` + +bpy.types.ParticleSettings +-------------------------- + +Added +^^^^^ + +* :class:`bpy.types.ParticleSettings.use_scale_dupli` + +bpy.types.SceneGameData +----------------------- + +Added +^^^^^ + +* :class:`bpy.types.SceneGameData.deactivation_angular_threshold` +* :class:`bpy.types.SceneGameData.deactivation_linear_threshold` +* :class:`bpy.types.SceneGameData.deactivation_time` + +bpy.types.SoundSequence +----------------------- + +Added +^^^^^ + +* :class:`bpy.types.SoundSequence.show_waveform` + +bpy.types.Scene +--------------- + +Added +^^^^^ + +* :class:`bpy.types.Scene.display_settings` +* :class:`bpy.types.Scene.sequence_editor_clear` +* :class:`bpy.types.Scene.sequence_editor_create` +* :class:`bpy.types.Scene.sequencer_colorspace_settings` +* :class:`bpy.types.Scene.view_settings` + +Removed +^^^^^^^ + +* **collada_export** + +bpy.types.Armature +------------------ + +Removed +^^^^^^^ + +* **use_deform_envelopes** +* **use_deform_preserve_volume** +* **use_deform_vertex_groups** + +bpy.types.MeshUVLoopLayer +------------------------- + +Added +^^^^^ + +* :class:`bpy.types.MeshUVLoopLayer.name` + +bpy.types.CurveMap +------------------ + +Added +^^^^^ + +* :class:`bpy.types.CurveMap.evaluate` + +bpy.types.ShaderNodeTexEnvironment +---------------------------------- + +Added +^^^^^ + +* :class:`bpy.types.ShaderNodeTexEnvironment.image_user` + +bpy.types.SolidifyModifier +-------------------------- + +Added +^^^^^ + +* :class:`bpy.types.SolidifyModifier.use_flip_normals` + +bpy.types.TextureNodeMath +------------------------- + +Added +^^^^^ + +* :class:`bpy.types.TextureNodeMath.use_clamp` + +bpy.types.SceneRenderLayer +-------------------------- + +Added +^^^^^ + +* :class:`bpy.types.SceneRenderLayer.layers_exclude` +* :class:`bpy.types.SceneRenderLayer.samples` + +bpy.types.CompositorNodeViewer +------------------------------ + +Added +^^^^^ + +* :class:`bpy.types.CompositorNodeViewer.center_x` +* :class:`bpy.types.CompositorNodeViewer.center_y` +* :class:`bpy.types.CompositorNodeViewer.tile_order` + +bpy.types.ClothCollisionSettings +-------------------------------- + +Added +^^^^^ + +* :class:`bpy.types.ClothCollisionSettings.vertex_group_self_collisions` + +bpy.types.SpeedControlSequence +------------------------------ + +Added +^^^^^ + +* :class:`bpy.types.SpeedControlSequence.input_1` +* :class:`bpy.types.SpeedControlSequence.input_count` + +bpy.types.ActionConstraint +-------------------------- + +Added +^^^^^ + +* :class:`bpy.types.ActionConstraint.use_bone_object_action` + +bpy.types.CompositorNodeScale +----------------------------- + +Added +^^^^^ + +* :class:`bpy.types.CompositorNodeScale.frame_method` +* :class:`bpy.types.CompositorNodeScale.offset_x` +* :class:`bpy.types.CompositorNodeScale.offset_y` + +bpy.types.SpaceDopeSheetEditor +------------------------------ + +Added +^^^^^ + +* :class:`bpy.types.SpaceDopeSheetEditor.show_group_colors` + +bpy.types.MetaSequence +---------------------- + +Removed +^^^^^^^ + +* **color_balance** +* **use_color_balance** + +bpy.types.ShaderNodeMixRGB +-------------------------- + +Added +^^^^^ + +* :class:`bpy.types.ShaderNodeMixRGB.use_clamp` + +bpy.types.FollowTrackConstraint +------------------------------- + +Added +^^^^^ + +* :class:`bpy.types.FollowTrackConstraint.frame_method` + +bpy.types.EffectSequence +------------------------ + +Removed +^^^^^^^ + +* **color_balance** +* **use_color_balance** + +bpy.types.ThemeNLAEditor +------------------------ + +Added +^^^^^ + +* :class:`bpy.types.ThemeNLAEditor.active_action` +* :class:`bpy.types.ThemeNLAEditor.active_action_unset` +* :class:`bpy.types.ThemeNLAEditor.meta_strips` +* :class:`bpy.types.ThemeNLAEditor.meta_strips_selected` +* :class:`bpy.types.ThemeNLAEditor.sound_strips` +* :class:`bpy.types.ThemeNLAEditor.sound_strips_selected` +* :class:`bpy.types.ThemeNLAEditor.transition_strips` +* :class:`bpy.types.ThemeNLAEditor.transition_strips_selected` +* :class:`bpy.types.ThemeNLAEditor.tweak` +* :class:`bpy.types.ThemeNLAEditor.tweak_duplicate` + +Removed +^^^^^^^ + +* **bars** +* **bars_selected** + +bpy.types.SculptCapabilities +---------------------------- + +Added +^^^^^ + +* :class:`bpy.types.SculptCapabilities.has_overlay` +* :class:`bpy.types.SculptCapabilities.has_texture_angle` +* :class:`bpy.types.SculptCapabilities.has_texture_angle_source` + +bpy.types.ImageFormatSettings +----------------------------- + +Added +^^^^^ + +* :class:`bpy.types.ImageFormatSettings.display_settings` +* :class:`bpy.types.ImageFormatSettings.view_settings` + + +bpy.types.Property +------------------ + +Added +^^^^^ + +* :class:`bpy.types.Property.is_library_editable` + +bpy.types.MovieTrackingTrack +---------------------------- + +Added +^^^^^ + +* :class:`bpy.types.MovieTrackingTrack.grease_pencil` +* :class:`bpy.types.MovieTrackingTrack.motion_model` +* :class:`bpy.types.MovieTrackingTrack.use_alpha_preview` +* :class:`bpy.types.MovieTrackingTrack.use_brute` +* :class:`bpy.types.MovieTrackingTrack.use_mask` +* :class:`bpy.types.MovieTrackingTrack.use_normalization` + +Removed +^^^^^^^ + +* **pattern_max** +* **pattern_min** +* **pyramid_levels** +* **search_max** +* **search_min** +* **tracker** + +bpy.types.CompositorNodeBlur +---------------------------- + +Added +^^^^^ + +* :class:`bpy.types.CompositorNodeBlur.use_variable_size` + +bpy.types.Object +---------------- + +Added +^^^^^ + +* :class:`bpy.types.Object.dm_info` +* :class:`bpy.types.Object.is_deform_modified` +* :class:`bpy.types.Object.layers_local_view` + +Renamed +^^^^^^^ + +* **animation_visualisation** -> :class:`bpy.types.Object.animation_visualization` + +bpy.types.UserPreferencesSystem +------------------------------- + +Added +^^^^^ + +* :class:`bpy.types.UserPreferencesSystem.use_gpu_mipmap` + +Removed +^^^^^^^ + +* **compute_device** +* **compute_device_type** + +bpy.types.Sequence +------------------ + +Added +^^^^^ + +* :class:`bpy.types.Sequence.modifiers` +* :class:`bpy.types.Sequence.use_linear_modifiers` + +Removed +^^^^^^^ + +* **input_1** +* **input_2** +* **input_3** +* **input_count** +* **waveform** + +bpy.types.ConsoleLine +--------------------- + +Added +^^^^^ + +* :class:`bpy.types.ConsoleLine.type` + +bpy.types.Region +---------------- + +Added +^^^^^ + +* :class:`bpy.types.Region.view2d` +* :class:`bpy.types.Region.x` +* :class:`bpy.types.Region.y` + +bpy.types.SpaceClipEditor +------------------------- + +Added +^^^^^ + +* :class:`bpy.types.SpaceClipEditor.grease_pencil_source` +* :class:`bpy.types.SpaceClipEditor.mask` +* :class:`bpy.types.SpaceClipEditor.mask_draw_type` +* :class:`bpy.types.SpaceClipEditor.pivot_point` +* :class:`bpy.types.SpaceClipEditor.show_graph_hidden` +* :class:`bpy.types.SpaceClipEditor.show_graph_only_selected` +* :class:`bpy.types.SpaceClipEditor.show_mask_smooth` +* :class:`bpy.types.SpaceClipEditor.show_seconds` + +bpy.types.NodeSocket +-------------------- + +Added +^^^^^ + +* :class:`bpy.types.NodeSocket.hide` +* :class:`bpy.types.NodeSocket.is_linked` + +bpy.types.MovieClipSequence +--------------------------- + +Removed +^^^^^^^ + +* **color_balance** +* **use_color_balance** + +bpy.types.Node +-------------- + +Added +^^^^^ + +* :class:`bpy.types.Node.color` +* :class:`bpy.types.Node.hide` +* :class:`bpy.types.Node.mute` +* :class:`bpy.types.Node.select` +* :class:`bpy.types.Node.show_options` +* :class:`bpy.types.Node.show_preview` +* :class:`bpy.types.Node.use_custom_color` + +bpy.types.SceneSequence +----------------------- + +Removed +^^^^^^^ + +* **color_balance** +* **use_color_balance** + +bpy.types.CompositorNodeOutputFile +---------------------------------- + +Added +^^^^^ + +* :class:`bpy.types.CompositorNodeOutputFile.file_slots` +* :class:`bpy.types.CompositorNodeOutputFile.layer_slots` + +Removed +^^^^^^^ + +* **active_input** + +bpy.types.ObjectBase +-------------------- + +Added +^^^^^ + +* :class:`bpy.types.ObjectBase.layers_local_view` + +bpy.types.CyclesCameraSettings +------------------------------ + +Added +^^^^^ + +* :class:`bpy.types.CyclesCameraSettings.fisheye_fov` +* :class:`bpy.types.CyclesCameraSettings.fisheye_lens` +* :class:`bpy.types.CyclesCameraSettings.panorama_type` + +bpy.types.CompositorNodeDefocus +------------------------------- + +Removed +^^^^^^^ + +* **samples** + +bpy.types.KeyMapItems +--------------------- + +Function Arguments +^^^^^^^^^^^^^^^^^^ + +* :class:`bpy.types.KeyMapItems.new` (idname, type, value, any, shift, ctrl, alt, oskey, key_modifier, head), *was (idname, type, value, any, shift, ctrl, alt, oskey, key_modifier)* + +bpy.types.CollisionSettings +--------------------------- + +Added +^^^^^ + +* :class:`bpy.types.CollisionSettings.stickiness` + +Removed +^^^^^^^ + +* **stickness** + +bpy.types.GlowSequence +---------------------- + +Added +^^^^^ + +* :class:`bpy.types.GlowSequence.input_1` +* :class:`bpy.types.GlowSequence.input_count` + +bpy.types.MouseSensor +--------------------- + +Added +^^^^^ + +* :class:`bpy.types.MouseSensor.use_pulse` + +bpy.types.MovieSequence +----------------------- + +Removed +^^^^^^^ + +* **color_balance** +* **use_color_balance** + +bpy.types.Pose +-------------- + +Renamed +^^^^^^^ + +* **animation_visualisation** -> :class:`bpy.types.Pose.animation_visualization` + +bpy.types.ThemeSequenceEditor +----------------------------- + +Removed +^^^^^^^ + +* **plugin_strip** + +bpy.types.IMAGE_UV_sculpt +------------------------- + +Added +^^^^^ + +* :class:`bpy.types.IMAGE_UV_sculpt.prop_unified_weight` + +bpy.types.SpaceImageEditor +-------------------------- + +Added +^^^^^ + +* :class:`bpy.types.SpaceImageEditor.cursor_location` +* :class:`bpy.types.SpaceImageEditor.mask` +* :class:`bpy.types.SpaceImageEditor.mask_draw_type` +* :class:`bpy.types.SpaceImageEditor.mode` +* :class:`bpy.types.SpaceImageEditor.pivot_point` +* :class:`bpy.types.SpaceImageEditor.show_mask_smooth` +* :class:`bpy.types.SpaceImageEditor.show_maskedit` + +Removed +^^^^^^^ + +* **curve** +* **use_grease_pencil** +* **use_image_paint** + +bpy.types.UserPreferencesFilePaths +---------------------------------- + +Added +^^^^^ + +* :class:`bpy.types.UserPreferencesFilePaths.i18n_branches_directory` + +Removed +^^^^^^^ + +* **sequence_plugin_directory** +* **texture_plugin_directory** + +bpy.types.CompositorNodeDilateErode +----------------------------------- + +Added +^^^^^ + +* :class:`bpy.types.CompositorNodeDilateErode.edge` +* :class:`bpy.types.CompositorNodeDilateErode.falloff` +* :class:`bpy.types.CompositorNodeDilateErode.type` + +bpy.types.ScrewModifier +----------------------- + +Added +^^^^^ + +* :class:`bpy.types.ScrewModifier.use_smooth_shade` + +bpy.types.SpaceNodeEditor +------------------------- + +Added +^^^^^ + +* :class:`bpy.types.SpaceNodeEditor.cursor_location` +* :class:`bpy.types.SpaceNodeEditor.edit_tree` +* :class:`bpy.types.SpaceNodeEditor.show_highlight` +* :class:`bpy.types.SpaceNodeEditor.use_hidden_preview` + +bpy.types.SpaceView3D +--------------------- + +Added +^^^^^ + +* :class:`bpy.types.SpaceView3D.layers_local_view` +* :class:`bpy.types.SpaceView3D.show_backface_culling` + +bpy.types.Area +-------------- + +Added +^^^^^ + +* :class:`bpy.types.Area.x` +* :class:`bpy.types.Area.y` + +bpy.types.RenderLayer +--------------------- + +Added +^^^^^ + +* :class:`bpy.types.RenderLayer.layers_exclude` + +bpy.types.MovieTracking +----------------------- + +Added +^^^^^ + +* :class:`bpy.types.MovieTracking.dopesheet` + +bpy.types.MovieTrackingSettings +------------------------------- + +Added +^^^^^ + +* :class:`bpy.types.MovieTrackingSettings.default_motion_model` +* :class:`bpy.types.MovieTrackingSettings.use_default_brute` +* :class:`bpy.types.MovieTrackingSettings.use_default_mask` +* :class:`bpy.types.MovieTrackingSettings.use_default_normalization` +* :class:`bpy.types.MovieTrackingSettings.use_tripod_solver` + +Removed +^^^^^^^ + +* **default_pyramid_levels** +* **default_tracker** + +bpy.types.CompositorNodeIDMask +------------------------------ + +Renamed +^^^^^^^ + +* **use_smooth_mask** -> :class:`bpy.types.CompositorNodeIDMask.use_antialiasing` + +bpy.types.UserPreferencesInput +------------------------------ + +Added +^^^^^ + +* :class:`bpy.types.UserPreferencesInput.ndof_orbit_sensitivity` +* :class:`bpy.types.UserPreferencesInput.ndof_view_rotate_method` + +bpy.types.Brush +--------------- + +Added +^^^^^ + +* :class:`bpy.types.Brush.mask_tool` +* :class:`bpy.types.Brush.weight` + +bpy.types.SpaceSequenceEditor +----------------------------- + +Added +^^^^^ + +* :class:`bpy.types.SpaceSequenceEditor.overlay_type` + +Removed +^^^^^^^ + +* **use_grease_pencil** + +bpy.types.MovieTrackingMarkers +------------------------------ + +Function Arguments +^^^^^^^^^^^^^^^^^^ + +* :class:`bpy.types.MovieTrackingMarkers.find_frame` (frame, exact), *was (frame)* + +bpy.types.UILayout +------------------ + +Added +^^^^^ + +* :class:`bpy.types.UILayout.template_colormanaged_view_settings` +* :class:`bpy.types.UILayout.template_colorspace_settings` + +Function Arguments +^^^^^^^^^^^^^^^^^^ + +* :class:`bpy.types.UILayout.template_image_settings` (image_settings, color_management), *was (image_settings)* + +bpy.types.ID +------------ + +Added +^^^^^ + +* :class:`bpy.types.ID.is_library_indirect` + +bpy.types.SpaceGraphEditor +-------------------------- + +Added +^^^^^ + +* :class:`bpy.types.SpaceGraphEditor.show_group_colors` + +bpy.types.Mesh +-------------- + +Added +^^^^^ + +* :class:`bpy.types.Mesh.skin_vertices` + +Removed +^^^^^^^ + +* **sticky** + +bpy.types.ShaderNodes +--------------------- + +Added +^^^^^ + +* :class:`bpy.types.ShaderNodes.active` + +bpy.types.ColorSequence +----------------------- + +Added +^^^^^ + +* :class:`bpy.types.ColorSequence.input_count` + +bpy.types.ShaderNodeMath +------------------------ + +Added +^^^^^ + +* :class:`bpy.types.ShaderNodeMath.use_clamp` + +bpy.types.Paint +--------------- + +Added +^^^^^ + +* :class:`bpy.types.Paint.input_samples` + +bpy.types.ShaderNodeTexImage +---------------------------- + +Added +^^^^^ + +* :class:`bpy.types.ShaderNodeTexImage.image_user` +* :class:`bpy.types.ShaderNodeTexImage.projection` +* :class:`bpy.types.ShaderNodeTexImage.projection_blend` + +bpy.types.UserPreferencesView +----------------------------- + +Added +^^^^^ + +* :class:`bpy.types.UserPreferencesView.use_mouse_depth_cursor` + +Renamed +^^^^^^^ + +* **use_mouse_auto_depth** -> :class:`bpy.types.UserPreferencesView.use_mouse_depth_navigate` + +bpy.types.CompositorNodeMath +---------------------------- + +Added +^^^^^ + +* :class:`bpy.types.CompositorNodeMath.use_clamp` + +bpy.types.Material +------------------ + +Added +^^^^^ + +* :class:`bpy.types.Material.use_uv_project` + +bpy.types.ThemeNodeEditor +------------------------- + +Added +^^^^^ + +* :class:`bpy.types.ThemeNodeEditor.frame_node` +* :class:`bpy.types.ThemeNodeEditor.node_active` +* :class:`bpy.types.ThemeNodeEditor.node_selected` + +bpy.types.Camera +---------------- + +Removed +^^^^^^^ + +* **use_panorama** + +bpy.types.UnifiedPaintSettings +------------------------------ + +Added +^^^^^ + +* :class:`bpy.types.UnifiedPaintSettings.use_unified_weight` +* :class:`bpy.types.UnifiedPaintSettings.weight` + +bpy.types.TextureNodes +---------------------- + +Added +^^^^^ + +* :class:`bpy.types.TextureNodes.active` + +bpy.types.MovieTrackingMarker +----------------------------- + +Added +^^^^^ + +* :class:`bpy.types.MovieTrackingMarker.pattern_bound_box` +* :class:`bpy.types.MovieTrackingMarker.pattern_corners` +* :class:`bpy.types.MovieTrackingMarker.search_max` +* :class:`bpy.types.MovieTrackingMarker.search_min` + +bpy.types.CyclesWorldSettings +----------------------------- + +Added +^^^^^ + +* :class:`bpy.types.CyclesWorldSettings.samples` + +bpy.types.LatticePoint +---------------------- + +Added +^^^^^ + +* :class:`bpy.types.LatticePoint.select` diff --git a/doc/python_api/sphinx_changelog_gen.py b/doc/python_api/sphinx_changelog_gen.py index 3ded1035123..afc253940d4 100644 --- a/doc/python_api/sphinx_changelog_gen.py +++ b/doc/python_api/sphinx_changelog_gen.py @@ -28,15 +28,15 @@ blender --background --python doc/python_api/sphinx_changelog_gen.py -- --dump # create changelog blender --background --python doc/python_api/sphinx_changelog_gen.py -- \ - --api_from blender_2_56_1.py \ - --api_to blender_2_57_0.py \ + --api_from blender_2_63_0.py \ + --api_to blender_2_64_0.py \ --api_out changes.rst # Api comparison can also run without blender -python doc/python_api/sphinx_changelog_gen.py \ - --api_from blender_api_2_56_6.py \ - --api_to blender_api_2_57.py \ +python doc/python_api/sphinx_changelog_gen.py -- \ + --api_from blender_api_2_63_0.py \ + --api_to blender_api_2_64_0.py \ --api_out changes.rst # Save the latest API dump in this folder, renaming it with its revision. @@ -307,6 +307,8 @@ def api_changelog(api_from, api_to, api_out): fout.close() + print("Written: %r" % api_out) + def main(): import sys @@ -347,6 +349,7 @@ def main(): args = parser.parse_args(argv) # In this example we wont use the args if not argv: + print("No args given!") parser.print_help() return From b16ca24d98961e91775d2be90fb544e4f966bae5 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 9 Oct 2012 03:14:38 +0000 Subject: [PATCH 125/347] code cleanup: quiet -Wreorder --- source/gameengine/Ketsji/KX_GameObject.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index 80634c3d8fc..cfc7b81bde5 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -109,10 +109,10 @@ KX_GameObject::KX_GameObject( m_xray(false), m_pHitObject(NULL), m_pObstacleSimulation(NULL), - m_actionManager(NULL), - m_isDeformable(false), + m_pInstanceObjects(NULL), m_pDupliGroupObject(NULL), - m_pInstanceObjects(NULL) + m_actionManager(NULL), + m_isDeformable(false) #ifdef WITH_PYTHON , m_attr_dict(NULL) #endif From 62d3754a40540a246a7b0e50324df548f91c2d9b Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 9 Oct 2012 03:44:29 +0000 Subject: [PATCH 126/347] fix for r51198, text wasn't flashing (gcc4.7, 64bit linux) --- source/blender/editors/transform/transform.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 2fe68b20806..775e8d2de8e 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -1586,7 +1586,8 @@ static void drawAutoKeyWarning(TransInfo *t, ARegion *ar) * We multiply by two to speed up the odd/even time-in-seconds = on/off toggle. * - Always start with warning shown so that animators are more likely to notice when starting to transform */ - show_warning = (int)(t->last_update * 2.0) & 1; + + show_warning = ((int)((t->last_update - floor(t->last_update)) * 2.0) & 1); if ((show_warning) || (t->state == TRANS_STARTING)) { const char printable[] = "Auto Keying On"; From 8d2835b5e55e901483ad839d87f11d7ada4d21a8 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 9 Oct 2012 05:58:09 +0000 Subject: [PATCH 127/347] patch [#31875] Patch to get scene access through a game object from Jay Parker (battery) --- doc/python_api/rst/bge.types.rst | 16 +++++++++++++--- source/gameengine/Ketsji/KX_GameObject.cpp | 14 +++++++++++++- source/gameengine/Ketsji/KX_GameObject.h | 1 + 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/doc/python_api/rst/bge.types.rst b/doc/python_api/rst/bge.types.rst index 6599cfeb2b2..e628db07e83 100644 --- a/doc/python_api/rst/bge.types.rst +++ b/doc/python_api/rst/bge.types.rst @@ -333,7 +333,8 @@ Types .. attribute:: useContinue - The actions continue option, True or False. When True, the action will always play from where last left off, otherwise negative events to this actuator will reset it to its start frame. + The actions continue option, True or False. When True, the action will always play from where last left off, + otherwise negative events to this actuator will reset it to its start frame. :type: boolean @@ -879,7 +880,8 @@ Types .. note:: - Calling ANY method or attribute on an object that has been removed from a scene will raise a SystemError, if an object may have been removed since last accessing it use the :data:`invalid` attribute to check. + Calling ANY method or attribute on an object that has been removed from a scene will raise a SystemError, + if an object may have been removed since last accessing it use the :data:`invalid` attribute to check. KX_GameObject can be subclassed to extend functionality. For example: @@ -999,6 +1001,12 @@ Types :type: :class:`KX_GameObject` or None + .. attribute:: scene + + The object's scene. (read-only). + + :type: :class:`KX_Scene` or None + .. attribute:: visible visibility flag. @@ -4558,7 +4566,9 @@ Types .. data:: KX_ACT_ARMATURE_RUN - Just make sure the armature will be updated on the next graphic frame. This is the only persistent mode of the actuator: it executes automatically once per frame until stopped by a controller + Just make sure the armature will be updated on the next graphic frame. + This is the only persistent mode of the actuator: + it executes automatically once per frame until stopped by a controller :value: 0 diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index cfc7b81bde5..a8f3c54508c 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -1682,7 +1682,8 @@ PyAttributeDef KX_GameObject::Attributes[] = { KX_PYATTRIBUTE_RO_FUNCTION("name", KX_GameObject, pyattr_get_name), KX_PYATTRIBUTE_RO_FUNCTION("parent", KX_GameObject, pyattr_get_parent), KX_PYATTRIBUTE_RO_FUNCTION("members", KX_GameObject, pyattr_get_instance_objects), - KX_PYATTRIBUTE_RO_FUNCTION("group", KX_GameObject, pyattr_get_dupli_group_object), + KX_PYATTRIBUTE_RO_FUNCTION("group", KX_GameObject, pyattr_get_dupli_group_object), + KX_PYATTRIBUTE_RO_FUNCTION("scene", KX_GameObject, pyattr_get_scene), KX_PYATTRIBUTE_RO_FUNCTION("life", KX_GameObject, pyattr_get_life), KX_PYATTRIBUTE_RW_FUNCTION("mass", KX_GameObject, pyattr_get_mass, pyattr_set_mass), KX_PYATTRIBUTE_RW_FUNCTION("linVelocityMin", KX_GameObject, pyattr_get_lin_vel_min, pyattr_set_lin_vel_min), @@ -1988,6 +1989,17 @@ PyObject *KX_GameObject::pyattr_get_instance_objects(void *self_v, const KX_PYAT Py_RETURN_NONE; } +PyObject* KX_GameObject::pyattr_get_scene(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + KX_GameObject *self = static_cast(self_v); + SG_Node *node = self->GetSGNode(); + KX_Scene *scene = static_cast(node->GetSGClientInfo()); + if (scene) { + return scene->GetProxy(); + } + Py_RETURN_NONE; +} + PyObject *KX_GameObject::pyattr_get_dupli_group_object(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { KX_GameObject* self= static_cast(self_v); diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h index 4fde0752a13..4fa3472ba10 100644 --- a/source/gameengine/Ketsji/KX_GameObject.h +++ b/source/gameengine/Ketsji/KX_GameObject.h @@ -980,6 +980,7 @@ public: static PyObject* pyattr_get_dupli_group_object(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); static PyObject* pyattr_get_instance_objects(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); + static PyObject* pyattr_get_scene(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef); static PyObject* pyattr_get_life(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); static PyObject* pyattr_get_mass(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); From b1c4809f505e2ff4249b1c12c0efb2930a4d94ce Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 9 Oct 2012 06:03:57 +0000 Subject: [PATCH 128/347] rename BGE KX_GameObject attrs * group -> group_parent * members -> group_children so its more clear what direction the relationship is. --- doc/python_api/rst/bge.types.rst | 4 ++-- source/gameengine/Ketsji/KX_GameObject.cpp | 8 ++++---- source/gameengine/Ketsji/KX_GameObject.h | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/doc/python_api/rst/bge.types.rst b/doc/python_api/rst/bge.types.rst index e628db07e83..a173137e50c 100644 --- a/doc/python_api/rst/bge.types.rst +++ b/doc/python_api/rst/bge.types.rst @@ -989,13 +989,13 @@ Types :type: :class:`KX_GameObject` or None - .. attribute:: members + .. attribute:: group_children Returns the list of group members if the object is a group object, otherwise None is returned. :type: :class:`CListValue` of :class:`KX_GameObject` or None - .. attribute:: group + .. attribute:: group_parent Returns the group object that the object belongs to or None if the object is not part of a group. diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index a8f3c54508c..3cfb670d227 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -1681,8 +1681,8 @@ PyMethodDef KX_GameObject::Methods[] = { PyAttributeDef KX_GameObject::Attributes[] = { KX_PYATTRIBUTE_RO_FUNCTION("name", KX_GameObject, pyattr_get_name), KX_PYATTRIBUTE_RO_FUNCTION("parent", KX_GameObject, pyattr_get_parent), - KX_PYATTRIBUTE_RO_FUNCTION("members", KX_GameObject, pyattr_get_instance_objects), - KX_PYATTRIBUTE_RO_FUNCTION("group", KX_GameObject, pyattr_get_dupli_group_object), + KX_PYATTRIBUTE_RO_FUNCTION("group_children", KX_GameObject, pyattr_get_group_children), + KX_PYATTRIBUTE_RO_FUNCTION("group_parent", KX_GameObject, pyattr_get_group_parent), KX_PYATTRIBUTE_RO_FUNCTION("scene", KX_GameObject, pyattr_get_scene), KX_PYATTRIBUTE_RO_FUNCTION("life", KX_GameObject, pyattr_get_life), KX_PYATTRIBUTE_RW_FUNCTION("mass", KX_GameObject, pyattr_get_mass, pyattr_set_mass), @@ -1979,7 +1979,7 @@ PyObject *KX_GameObject::pyattr_get_parent(void *self_v, const KX_PYATTRIBUTE_DE Py_RETURN_NONE; } -PyObject *KX_GameObject::pyattr_get_instance_objects(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +PyObject *KX_GameObject::pyattr_get_group_children(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { KX_GameObject* self= static_cast(self_v); CListValue* instances = self->GetInstanceObjects(); @@ -2000,7 +2000,7 @@ PyObject* KX_GameObject::pyattr_get_scene(void *self_v, const KX_PYATTRIBUTE_DEF Py_RETURN_NONE; } -PyObject *KX_GameObject::pyattr_get_dupli_group_object(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +PyObject *KX_GameObject::pyattr_get_group_parent(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { KX_GameObject* self= static_cast(self_v); KX_GameObject* pivot = self->GetDupliGroupObject(); diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h index 4fa3472ba10..621dd988e00 100644 --- a/source/gameengine/Ketsji/KX_GameObject.h +++ b/source/gameengine/Ketsji/KX_GameObject.h @@ -978,8 +978,8 @@ public: static PyObject* pyattr_get_name(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef); static PyObject* pyattr_get_parent(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); - static PyObject* pyattr_get_dupli_group_object(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); - static PyObject* pyattr_get_instance_objects(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); + static PyObject* pyattr_get_group_parent(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); + static PyObject* pyattr_get_group_children(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); static PyObject* pyattr_get_scene(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef); static PyObject* pyattr_get_life(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); From f45acb2bba96341bce7b49cf72bcbd8bbaaafe80 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 9 Oct 2012 06:15:07 +0000 Subject: [PATCH 129/347] patch [#31709] Text editor: scroll margin column along with text by Sebastian Nell (codemanx) The margin ignored horizontal scrolling. --- source/blender/editors/space_text/text_draw.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/source/blender/editors/space_text/text_draw.c b/source/blender/editors/space_text/text_draw.c index 5111d20b8ee..a68524fcdd6 100644 --- a/source/blender/editors/space_text/text_draw.c +++ b/source/blender/editors/space_text/text_draw.c @@ -1741,6 +1741,7 @@ void draw_text_main(SpaceText *st, ARegion *ar) char linenr[12]; int i, x, y, winx, linecount = 0, lineno = 0; int wraplinecount = 0, wrap_skip = 0; + int margin_column_x; if (st->lheight) st->viewlines = (int)ar->winy / st->lheight; else st->viewlines = 0; @@ -1845,10 +1846,14 @@ void draw_text_main(SpaceText *st, ARegion *ar) if (st->flags & ST_SHOW_MARGIN) { UI_ThemeColor(TH_HILITE); - glBegin(GL_LINES); - glVertex2i(x + st->cwidth * st->margin_column, 0); - glVertex2i(x + st->cwidth * st->margin_column, ar->winy - 2); - glEnd(); + margin_column_x = x + st->cwidth * (st->margin_column - st->left); + + if (margin_column_x >= x) { + glBegin(GL_LINES); + glVertex2i(margin_column_x, 0); + glVertex2i(margin_column_x, ar->winy - 2); + glEnd(); + } } /* draw other stuff */ From 0f8c99e58548bd00436284f1cd471c89f28d25f9 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Tue, 9 Oct 2012 08:40:20 +0000 Subject: [PATCH 130/347] RNA minor fixes: *Bezier points' softbody weight was called just "weight", when it is "weight_softbody" for NURBS ones, made it the same! *Added "weight_softbody" to Lattice points as well. --- source/blender/makesrna/intern/rna_curve.c | 3 ++- source/blender/makesrna/intern/rna_lattice.c | 8 +++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c index b42fb0664f8..d7e59f3b9dd 100644 --- a/source/blender/makesrna/intern/rna_curve.c +++ b/source/blender/makesrna/intern/rna_curve.c @@ -814,7 +814,8 @@ static void rna_def_beztriple(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Tilt", "Tilt in 3D View"); RNA_def_property_update(prop, 0, "rna_Curve_update_data"); - prop = RNA_def_property(srna, "weight", PROP_FLOAT, PROP_NONE); + prop = RNA_def_property(srna, "weight_softbody", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "weight"); RNA_def_property_range(prop, 0.01f, 100.0f); RNA_def_property_ui_text(prop, "Weight", "Softbody goal weight"); RNA_def_property_update(prop, 0, "rna_Curve_update_data"); diff --git a/source/blender/makesrna/intern/rna_lattice.c b/source/blender/makesrna/intern/rna_lattice.c index d4082cf3d9f..e4a29d9c674 100644 --- a/source/blender/makesrna/intern/rna_lattice.c +++ b/source/blender/makesrna/intern/rna_lattice.c @@ -240,6 +240,12 @@ static void rna_def_latticepoint(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Deformed Location", ""); RNA_def_property_update(prop, 0, "rna_Lattice_update_data"); + prop = RNA_def_property(srna, "weight_softbody", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "weight"); + RNA_def_property_range(prop, 0.01f, 100.0f); + RNA_def_property_ui_text(prop, "Weight", "Softbody goal weight"); + RNA_def_property_update(prop, 0, "rna_Lattice_update_data"); + prop = RNA_def_property(srna, "groups", PROP_COLLECTION, PROP_NONE); RNA_def_property_collection_funcs(prop, "rna_LatticePoint_groups_begin", "rna_iterator_array_next", "rna_iterator_array_end", "rna_iterator_array_get", @@ -320,7 +326,7 @@ static void rna_def_lattice(BlenderRNA *brna) RNA_def_property_collection_funcs(prop, "rna_Lattice_points_begin", "rna_iterator_array_next", "rna_iterator_array_end", "rna_iterator_array_get", NULL, NULL, NULL, NULL); RNA_def_property_ui_text(prop, "Points", "Points of the lattice"); - + /* pointers */ rna_def_animdata_common(srna); } From 9e0dd178134a973b9091705fd62f12ed9ea6434c Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Tue, 9 Oct 2012 09:14:37 +0000 Subject: [PATCH 131/347] Another refactor for 3D view's edit Transform panel. Main changes: *Get rid of the magic numbers for median arrays, use defines instead, should make things a bit more clear and easy to edit (though there are still a bit of "array magic" on median here and there). *Restore and extend use of RNA prop when a single (control)point of curve or lattice is selected, to allow keyframing (was added by sergey for curve radius in r41494, see [#29122], and reverted by myself in previous refactor r44599). --- .../editors/space_view3d/view3d_buttons.c | 359 +++++++++++------- 1 file changed, 212 insertions(+), 147 deletions(-) diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c index c8aca5674a4..1f7bae0b23e 100644 --- a/source/blender/editors/space_view3d/view3d_buttons.c +++ b/source/blender/editors/space_view3d/view3d_buttons.c @@ -86,13 +86,15 @@ #define B_REDR 2 #define B_OBJECTPANELMEDIAN 1008 +#define NBR_TRANSFORM_PROPERTIES 7 + /* temporary struct for storing transform properties */ typedef struct { float ob_eul[4]; /* used for quat too... */ float ob_scale[3]; /* need temp space due to linked values */ float ob_dims[3]; short link_scale; - float ve_median[9]; + float ve_median[NBR_TRANSFORM_PROPERTIES]; int curdef; float *defweightp; } TransformProperties; @@ -131,17 +133,38 @@ static float compute_scale_factor(const float ve_median, const float median) /* is used for both read and write... */ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float lim) { +/* Get rid of those ugly magic numbers, even in a single func they become confusing! */ +/* Location, common to all. */ +/* XXX Those two *must* remain contiguous (used as array)! */ +#define LOC_X 0 +#define LOC_Y 1 +#define LOC_Z 2 +/* Meshes... */ +#define M_CREASE 3 +#define M_WEIGHT 4 +/* XXX Those two *must* remain contiguous (used as array)! */ +#define M_SKIN_X 5 +#define M_SKIN_Y 6 +/* Curves... */ +#define C_BWEIGHT 3 +#define C_WEIGHT 4 +#define C_RADIUS 5 +#define C_TILT 6 +/*Lattice... */ +#define L_WEIGHT 4 + uiBlock *block = (layout) ? uiLayoutAbsoluteBlock(layout) : NULL; MDeformVert *dvert = NULL; TransformProperties *tfp; - float median[9], ve_median[9]; - int tot, totw, totweight, totedge, totradius, totskinradius; + float median[NBR_TRANSFORM_PROPERTIES], ve_median[NBR_TRANSFORM_PROPERTIES]; + int tot, totedgedata, totcurvedata, totlattdata, totskinradius, totcurvebweight; + int meshdata = FALSE, i; char defstr[320]; - PointerRNA radius_ptr; + PointerRNA data_ptr; - median[0] = median[1] = median[2] = median[3] = median[4] = median[5] = median[6] = median[7] = median[8] = 0.0; - tot = totw = totweight = totedge = totradius = totskinradius = 0; - defstr[0] = 0; + fill_vn_fl(median, NBR_TRANSFORM_PROPERTIES, 0.0f); + tot = totedgedata = totcurvedata = totlattdata = totskinradius = totcurvebweight = 0; + defstr[0] = '\0'; /* make sure we got storage */ if (v3d->properties_storage == NULL) @@ -162,11 +185,11 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float evedef = eve; tot++; - add_v3_v3(median, eve->co); + add_v3_v3(&median[LOC_X], eve->co); vs = (MVertSkin *)CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_MVERT_SKIN); if (vs) { - add_v2_v2(median + 7, vs->radius); /* Third val not used currently. */ + add_v2_v2(&median[M_SKIN_X], vs->radius); /* Third val not used currently. */ totskinradius++; } } @@ -176,12 +199,12 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) { float *f; - totedge++; + totedgedata++; f = (float *)CustomData_bmesh_get(&bm->edata, eed->head.data, CD_CREASE); - median[3] += f ? *f : 0.0f; + median[M_CREASE] += f ? *f : 0.0f; f = (float *)CustomData_bmesh_get(&bm->edata, eed->head.data, CD_BWEIGHT); - median[6] += f ? *f : 0.0f; + median[M_WEIGHT] += f ? *f : 0.0f; } } @@ -211,6 +234,8 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float tfp->defweightp = &dvert->dw[0].weight; } } + + meshdata = totedgedata || totskinradius; } else if (ob->type == OB_CURVE || ob->type == OB_SURF) { Curve *cu = ob->data; @@ -229,22 +254,24 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float a = nu->pntsu; while (a--) { if (bezt->f2 & SELECT) { - add_v3_v3(median, bezt->vec[1]); + add_v3_v3(&median[LOC_X], bezt->vec[1]); tot++; - median[4] += bezt->weight; - totweight++; - median[5] += bezt->radius; - totradius++; - selp = bezt; - seltype = &RNA_BezierSplinePoint; + median[C_WEIGHT] += bezt->weight; + median[C_RADIUS] += bezt->radius; + median[C_TILT] += bezt->alfa; + if (!totcurvedata) { /* I.e. first time... */ + selp = bezt; + seltype = &RNA_BezierSplinePoint; + } + totcurvedata++; } else { if (bezt->f1 & SELECT) { - add_v3_v3(median, bezt->vec[0]); + add_v3_v3(&median[LOC_X], bezt->vec[0]); tot++; } if (bezt->f3 & SELECT) { - add_v3_v3(median, bezt->vec[2]); + add_v3_v3(&median[LOC_X], bezt->vec[2]); tot++; } } @@ -256,16 +283,18 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float a = nu->pntsu * nu->pntsv; while (a--) { if (bp->f1 & SELECT) { - add_v3_v3(median, bp->vec); - median[3] += bp->vec[3]; - totw++; + add_v3_v3(&median[LOC_X], bp->vec); + median[C_BWEIGHT] += bp->vec[3]; + totcurvebweight++; tot++; - median[4] += bp->weight; - totweight++; - median[5] += bp->radius; - totradius++; - selp = bp; - seltype = &RNA_SplinePoint; + median[C_WEIGHT] += bp->weight; + median[C_RADIUS] += bp->radius; + median[C_TILT] += bp->alfa; + if (!totcurvedata) { /* I.e. first time... */ + selp = bp; + seltype = &RNA_SplinePoint; + } + totcurvedata++; } bp++; } @@ -273,84 +302,102 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float nu = nu->next; } - if (totradius == 1) - RNA_pointer_create(&cu->id, seltype, selp, &radius_ptr); + if (totcurvedata == 1) + RNA_pointer_create(&cu->id, seltype, selp, &data_ptr); } else if (ob->type == OB_LATTICE) { Lattice *lt = ob->data; BPoint *bp; int a; + StructRNA *seltype = NULL; + void *selp = NULL; a = lt->editlatt->latt->pntsu * lt->editlatt->latt->pntsv * lt->editlatt->latt->pntsw; bp = lt->editlatt->latt->def; while (a--) { if (bp->f1 & SELECT) { - add_v3_v3(median, bp->vec); + add_v3_v3(&median[LOC_X], bp->vec); tot++; - median[4] += bp->weight; - totweight++; + median[L_WEIGHT] += bp->weight; + if (!totlattdata) { /* I.e. first time... */ + selp = bp; + seltype = &RNA_LatticePoint; + } + totlattdata++; } bp++; } + + if (totlattdata == 1) + RNA_pointer_create(<->id, seltype, selp, &data_ptr); } if (tot == 0) { uiDefBut(block, LABEL, 0, IFACE_("Nothing selected"), 0, 130, 200, 20, NULL, 0, 0, 0, 0, ""); return; } - median[0] /= (float)tot; - median[1] /= (float)tot; - median[2] /= (float)tot; - if (totedge) { - median[3] /= (float)totedge; - median[6] /= (float)totedge; - } - else if (totw) - median[3] /= (float)totw; - if (totweight) - median[4] /= (float)totweight; - if (totradius) - median[5] /= (float)totradius; - if (totskinradius) { - median[7] /= (float)totskinradius; - median[8] /= (float)totskinradius; - } + /* Location, X/Y/Z */ + mul_v3_fl(&median[LOC_X], 1.0f / (float)tot); if (v3d->flag & V3D_GLOBAL_STATS) - mul_m4_v3(ob->obmat, median); + mul_m4_v3(ob->obmat, &median[LOC_X]); + + if (meshdata) { + if (totedgedata) { + median[M_CREASE] /= (float)totedgedata; + median[M_WEIGHT] /= (float)totedgedata; + } + if (totskinradius) { + median[M_SKIN_X] /= (float)totskinradius; + median[M_SKIN_Y] /= (float)totskinradius; + } + } + else if (totcurvedata) { + median[C_WEIGHT] /= (float)totcurvedata; + median[C_RADIUS] /= (float)totcurvedata; + median[C_TILT] /= (float)totcurvedata; + if (totcurvebweight) + median[C_BWEIGHT] /= (float)totcurvebweight; + } + else if (totlattdata) + median[L_WEIGHT] /= (float)totlattdata; if (block) { /* buttons */ uiBut *but; int yi = 200; const int buth = 20 * UI_DPI_ICON_FAC; const int but_margin = 2; + const char *c; memcpy(tfp->ve_median, median, sizeof(tfp->ve_median)); uiBlockBeginAlign(block); if (tot == 1) { - uiDefBut(block, LABEL, 0, IFACE_("Vertex:"), 0, yi -= buth, 200, buth, NULL, 0, 0, 0, 0, ""); - } - else { - uiDefBut(block, LABEL, 0, IFACE_("Median:"), 0, yi -= buth, 200, buth, NULL, 0, 0, 0, 0, ""); + if (totcurvedata) /* Curve */ + c = IFACE_("Control Point:"); + else /* Mesh or lattice */ + c = IFACE_("Vertex:"); } + else + c = IFACE_("Median:"); + uiDefBut(block, LABEL, 0, c, 0, yi -= buth, 200, buth, NULL, 0, 0, 0, 0, ""); uiBlockBeginAlign(block); /* Should be no need to translate these. */ but = uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "X:", 0, yi -= buth, 200, buth, - &(tfp->ve_median[0]), -lim, lim, 10, RNA_TRANSLATION_PREC_DEFAULT, ""); + &(tfp->ve_median[LOC_X]), -lim, lim, 10, RNA_TRANSLATION_PREC_DEFAULT, ""); uiButSetUnitType(but, PROP_UNIT_LENGTH); but = uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Y:", 0, yi -= buth, 200, buth, - &(tfp->ve_median[1]), -lim, lim, 10, RNA_TRANSLATION_PREC_DEFAULT, ""); + &(tfp->ve_median[LOC_Y]), -lim, lim, 10, RNA_TRANSLATION_PREC_DEFAULT, ""); uiButSetUnitType(but, PROP_UNIT_LENGTH); but = uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Z:", 0, yi -= buth, 200, buth, - &(tfp->ve_median[2]), -lim, lim, 10, RNA_TRANSLATION_PREC_DEFAULT, ""); + &(tfp->ve_median[LOC_Z]), -lim, lim, 10, RNA_TRANSLATION_PREC_DEFAULT, ""); uiButSetUnitType(but, PROP_UNIT_LENGTH); - if (totw == tot) { + if (totcurvebweight == tot) { uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "W:", 0, yi -= buth, 200, buth, - &(tfp->ve_median[3]), 0.01, 100.0, 1, 3, ""); + &(tfp->ve_median[C_BWEIGHT]), 0.01, 100.0, 1, 3, ""); } uiBlockBeginAlign(block); @@ -362,60 +409,60 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float &v3d->flag, 0, 0, 0, 0, "Displays local values"); uiBlockEndAlign(block); - if (totweight == 1) { - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Weight:"), - 0, yi -= buth + but_margin, 200, buth, - &(tfp->ve_median[4]), 0.0, 1.0, 1, 3, TIP_("Weight used for SoftBody Goal")); + /* Meshes... */ + if (meshdata) { + if (totedgedata) { + uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, + totedgedata == 1 ? IFACE_("Crease:") : IFACE_("Mean Crease:"), + 0, yi -= buth + but_margin, 200, buth, + &(tfp->ve_median[M_CREASE]), 0.0, 1.0, 1, 3, TIP_("Weight used by SubSurf modifier")); + uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, + totedgedata == 1 ? IFACE_("Bevel Weight:") : IFACE_("Mean Bevel Weight:"), + 0, yi -= buth + but_margin, 200, buth, + &(tfp->ve_median[M_WEIGHT]), 0.0, 1.0, 1, 3, TIP_("Weight used by Bevel modifier")); + } + if (totskinradius) { + uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, + totskinradius == 1 ? IFACE_("Radius X:") : IFACE_("Mean Radius X:"), + 0, yi -= buth + but_margin, 200, buth, + &(tfp->ve_median[M_SKIN_X]), 0.0, 100.0, 1, 3, TIP_("X radius used by Skin modifier")); + uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, + totskinradius == 1 ? IFACE_("Radius Y:") : IFACE_("Mean Radius Y:"), + 0, yi -= buth + but_margin, 200, buth, + &(tfp->ve_median[M_SKIN_Y]), 0.0, 100.0, 1, 3, TIP_("Y radius used by Skin modifier")); + } } - else if (totweight > 1) { + /* Curve... */ + else if (totcurvedata == 1) { + uiDefButR(block, NUM, 0, "Weight", 0, yi -= buth + but_margin, 200, buth, + &data_ptr, "weight_softbody", 0, 0.0, 1.0, 1, 3, NULL); + uiDefButR(block, NUM, 0, "Radius", 0, yi -= buth + but_margin, 200, buth, + &data_ptr, "radius", 0, 0.0, 100.0, 1, 3, NULL); + uiDefButR(block, NUM, 0, "Tilt", 0, yi -= buth + but_margin, 200, buth, + &data_ptr, "tilt", 0, -M_PI * 2.0f, M_PI * 2.0f, 1, 3, NULL); + } + else if (totcurvedata > 1) { uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Mean Weight:"), - 0, yi -= buth, 200, buth, - &(tfp->ve_median[4]), 0.0, 1.0, 1, 3, TIP_("Weight used for SoftBody Goal")); - } - - if (totradius == 1) { - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Radius:"), 0, yi -= buth + but_margin, 200, buth, - &(tfp->ve_median[5]), 0.0, 100.0, 1, 3, TIP_("Radius of curve control points")); - } - else if (totradius > 1) { + &(tfp->ve_median[C_WEIGHT]), 0.0, 1.0, 1, 3, TIP_("Weight used for SoftBody Goal")); uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Mean Radius:"), 0, yi -= buth + but_margin, 200, buth, - &(tfp->ve_median[5]), 0.0, 100.0, 1, 3, TIP_("Radius of curve control points")); + &(tfp->ve_median[C_RADIUS]), 0.0, 100.0, 1, 3, TIP_("Radius of curve control points")); + but = uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Mean Tilt:"), + 0, yi -= buth + but_margin, 200, buth, + &(tfp->ve_median[C_TILT]), -M_PI * 2.0f, M_PI * 2.0f, 1, 3, + TIP_("Tilt (inclination) of curve control points")); + uiButSetUnitType(but, PROP_UNIT_ROTATION); } - - if (totskinradius == 1) { - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Radius X:"), - 0, yi -= buth + but_margin, 200, buth, - &(tfp->ve_median[7]), 0.0, 100.0, 1, 3, TIP_("X radius used by Skin modifier")); - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Radius Y:"), - 0, yi -= buth + but_margin, 200, buth, - &(tfp->ve_median[8]), 0.0, 100.0, 1, 3, TIP_("Y radius used by Skin modifier")); + /* Lattice... */ + else if (totlattdata == 1) { + uiDefButR(block, NUM, 0, "Weight", 0, yi -= buth + but_margin, 200, buth, + &data_ptr, "weight_softbody", 0, 0.0, 1.0, 1, 3, NULL); } - else if (totskinradius > 1) { - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Mean Radius X:"), + else if (totlattdata > 1) { + uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Mean Weight:"), 0, yi -= buth + but_margin, 200, buth, - &(tfp->ve_median[7]), 0.0, 100.0, 1, 3, TIP_("Median X radius used by Skin modifier")); - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Mean Radius Y:"), - 0, yi -= buth + but_margin, 200, buth, - &(tfp->ve_median[8]), 0.0, 100.0, 1, 3, TIP_("Median Y radius used by Skin modifier")); - } - - if (totedge == 1) { - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Crease:"), - 0, yi -= buth + but_margin, 200, buth, - &(tfp->ve_median[3]), 0.0, 1.0, 1, 3, TIP_("Weight used by SubSurf modifier")); - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Bevel Weight:"), - 0, yi -= buth + but_margin, 200, buth, - &(tfp->ve_median[6]), 0.0, 1.0, 1, 3, TIP_("Weight used by Bevel modifier")); - } - else if (totedge > 1) { - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Mean Crease:"), - 0, yi -= buth + but_margin, 200, buth, - &(tfp->ve_median[3]), 0.0, 1.0, 1, 3, TIP_("Weight used by SubSurf modifier")); - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Mean Bevel Weight:"), - 0, yi -= buth + but_margin, 200, buth, - &(tfp->ve_median[6]), 0.0, 1.0, 1, 3, TIP_("Weight used by Bevel modifier")); + &(tfp->ve_median[L_WEIGHT]), 0.0, 1.0, 1, 3, TIP_("Weight used for SoftBody Goal")); } uiBlockEndAlign(block); @@ -427,16 +474,12 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float if (v3d->flag & V3D_GLOBAL_STATS) { invert_m4_m4(ob->imat, ob->obmat); - mul_m4_v3(ob->imat, median); - mul_m4_v3(ob->imat, ve_median); + mul_m4_v3(ob->imat, &median[LOC_X]); + mul_m4_v3(ob->imat, &ve_median[LOC_X]); } - sub_v3_v3v3(median, ve_median, median); - median[3] = ve_median[3] - median[3]; - median[4] = ve_median[4] - median[4]; - median[5] = ve_median[5] - median[5]; - median[6] = ve_median[6] - median[6]; - median[7] = ve_median[7] - median[7]; - median[8] = ve_median[8] - median[8]; + i = NBR_TRANSFORM_PROPERTIES; + while (i--) + median[i] = ve_median[i] - median[i]; if (ob->type == OB_MESH) { Mesh *me = ob->data; @@ -445,20 +488,20 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float BMVert *eve; BMIter iter; - if (len_v3(median) > 0.000001f) { + if (len_v3(&median[LOC_X]) > 0.000001f) { BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { - add_v3_v3(eve->co, median); + add_v3_v3(eve->co, &median[LOC_X]); } } EDBM_mesh_normals_update(em); } - if (median[3] != 0.0f) { + if (median[M_CREASE] != 0.0f) { BMEdge *eed; - const float sca = compute_scale_factor(ve_median[3], median[3]); + const float sca = compute_scale_factor(ve_median[M_CREASE], median[M_CREASE]); if (ELEM(sca, 0.0f, 1.0f)) { BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) { @@ -494,9 +537,9 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float } } - if (median[6] != 0.0f) { + if (median[M_WEIGHT] != 0.0f) { BMEdge *eed; - const float sca = compute_scale_factor(ve_median[6], median[6]); + const float sca = compute_scale_factor(ve_median[M_WEIGHT], median[M_WEIGHT]); if (ELEM(sca, 0.0f, 1.0f)) { BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) { @@ -532,11 +575,11 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float } } - if (median[7] != 0.0f) { + if (median[M_SKIN_X] != 0.0f) { BMVert *eve; /* That one is not clamped to [0.0, 1.0]. */ - float sca = ve_median[7]; - if (ve_median[7] - median[7] == 0.0f) { + float sca = ve_median[M_SKIN_X]; + if (ve_median[M_SKIN_X] - median[M_SKIN_X] == 0.0f) { BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { MVertSkin *vs = (MVertSkin *)CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_MVERT_SKIN); @@ -546,7 +589,7 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float } } else { - sca /= (ve_median[7] - median[7]); + sca /= (ve_median[M_SKIN_X] - median[M_SKIN_X]); BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { MVertSkin *vs = (MVertSkin *)CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_MVERT_SKIN); @@ -556,11 +599,11 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float } } } - if (median[8] != 0.0f) { + if (median[M_SKIN_Y] != 0.0f) { BMVert *eve; /* That one is not clamped to [0.0, 1.0]. */ - float sca = ve_median[8]; - if (ve_median[8] - median[8] == 0.0f) { + float sca = ve_median[M_SKIN_Y]; + if (ve_median[M_SKIN_Y] - median[M_SKIN_Y] == 0.0f) { BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { MVertSkin *vs = (MVertSkin *)CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_MVERT_SKIN); @@ -570,7 +613,7 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float } } else { - sca /= (ve_median[8] - median[8]); + sca /= (ve_median[M_SKIN_Y] - median[M_SKIN_Y]); BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { MVertSkin *vs = (MVertSkin *)CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_MVERT_SKIN); @@ -589,7 +632,7 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float BezTriple *bezt; int a; ListBase *nurbs = BKE_curve_editNurbs_get(cu); - const float scale_w = compute_scale_factor(ve_median[4], median[4]); + const float scale_w = compute_scale_factor(ve_median[C_WEIGHT], median[C_WEIGHT]); nu = nurbs->first; while (nu) { @@ -598,11 +641,11 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float a = nu->pntsu; while (a--) { if (bezt->f2 & SELECT) { - add_v3_v3(bezt->vec[0], median); - add_v3_v3(bezt->vec[1], median); - add_v3_v3(bezt->vec[2], median); + add_v3_v3(bezt->vec[0], &median[LOC_X]); + add_v3_v3(bezt->vec[1], &median[LOC_X]); + add_v3_v3(bezt->vec[2], &median[LOC_X]); - if (median[4] != 0.0f) { + if (median[C_WEIGHT] != 0.0f) { if (ELEM(scale_w, 0.0f, 1.0f)) { bezt->weight = scale_w; } @@ -613,14 +656,15 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float } } - bezt->radius += median[5]; + bezt->radius += median[C_RADIUS]; + bezt->alfa += median[C_TILT]; } else { if (bezt->f1 & SELECT) { - add_v3_v3(bezt->vec[0], median); + add_v3_v3(bezt->vec[0], &median[LOC_X]); } if (bezt->f3 & SELECT) { - add_v3_v3(bezt->vec[2], median); + add_v3_v3(bezt->vec[2], &median[LOC_X]); } } bezt++; @@ -631,10 +675,10 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float a = nu->pntsu * nu->pntsv; while (a--) { if (bp->f1 & SELECT) { - add_v3_v3(bp->vec, median); - bp->vec[3] += median[3]; + add_v3_v3(bp->vec, &median[LOC_X]); + bp->vec[3] += median[C_BWEIGHT]; - if (median[4] != 0.0f) { + if (median[C_WEIGHT] != 0.0f) { if (ELEM(scale_w, 0.0f, 1.0f)) { bp->weight = scale_w; } @@ -645,7 +689,8 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float } } - bp->radius += median[5]; + bp->radius += median[C_RADIUS]; + bp->alfa += median[C_TILT]; } bp++; } @@ -660,15 +705,15 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float Lattice *lt = ob->data; BPoint *bp; int a; - const float scale_w = compute_scale_factor(ve_median[4], median[4]); + const float scale_w = compute_scale_factor(ve_median[L_WEIGHT], median[L_WEIGHT]); a = lt->editlatt->latt->pntsu * lt->editlatt->latt->pntsv * lt->editlatt->latt->pntsw; bp = lt->editlatt->latt->def; while (a--) { if (bp->f1 & SELECT) { - add_v3_v3(bp->vec, median); + add_v3_v3(bp->vec, &median[LOC_X]); - if (median[4] != 0.0f) { + if (median[L_WEIGHT] != 0.0f) { if (ELEM(scale_w, 0.0f, 1.0f)) { bp->weight = scale_w; } @@ -685,7 +730,28 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float /* ED_undo_push(C, "Transform properties"); */ } + +/* Clean up! */ +/* Location, common to all. */ +#undef LOC_X +#undef LOC_Y +#undef LOC_Z +/* Meshes (and lattice)... */ +#undef M_CREASE +#undef M_WEIGHT +#undef M_SKIN_X +#undef M_SKIN_Y +/* Curves... */ +#undef C_BWEIGHT +#undef C_WEIGHT +#undef C_RADIUS +#undef C_TILT +/* Lattice... */ +#undef L_WEIGHT } +#undef NBR_TRANSFORM_PROPERTIES + + #define B_VGRP_PNL_COPY 1 #define B_VGRP_PNL_NORMALIZE 2 #define B_VGRP_PNL_EDIT_SINGLE 8 /* or greater */ @@ -1161,7 +1227,6 @@ static void view3d_panel_object(const bContext *C, Panel *pa) uiBlockSetHandleFunc(block, do_view3d_region_buttons, NULL); col = uiLayoutColumn(pa->layout, FALSE); - /* row = uiLayoutRow(col, FALSE); */ /* UNUSED */ RNA_id_pointer_create(&ob->id, &obptr); if (ob == obedit) { From 58e8d0b57e5559567751bc4c25eaad7bd9919a8f Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 9 Oct 2012 09:38:05 +0000 Subject: [PATCH 132/347] OSX zoom pinch was using inverted direction --- source/blender/editors/interface/view2d_ops.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c index eb2f6c62351..2c8db53b534 100644 --- a/source/blender/editors/interface/view2d_ops.c +++ b/source/blender/editors/interface/view2d_ops.c @@ -941,10 +941,15 @@ static int view_zoomdrag_invoke(bContext *C, wmOperator *op, wmEvent *event) /* As we have only 1D information (magnify value), feed both axes * with magnify information that is stored in x axis */ - fac = 0.01f * (event->x - event->prevx); + fac = 0.01f * (event->prevx - event->x); dx = fac * BLI_rctf_size_x(&v2d->cur) / 10.0f; dy = fac * BLI_rctf_size_y(&v2d->cur) / 10.0f; + if (U.uiflag & USER_ZOOM_INVERT) { + dx *= -1; + dy *= -1; + } + RNA_float_set(op->ptr, "deltax", dx); RNA_float_set(op->ptr, "deltay", dy); From 66edeae182f0afab2eeb8f9988df36aa112972e9 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Tue, 9 Oct 2012 10:20:25 +0000 Subject: [PATCH 133/347] Style cleanup - replace #define lists with enums --- source/blender/makesdna/DNA_userdef_types.h | 409 +++++++++++--------- 1 file changed, 226 insertions(+), 183 deletions(-) diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index 4c196a15db1..c10850d74e6 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -49,11 +49,14 @@ struct ColorBand; #define MAX_STYLE_NAME 64 /* default uifont_id offered by Blender */ -#define UIFONT_DEFAULT 0 -/*#define UIFONT_BITMAP 1*/ /*UNUSED*/ -/* free slots */ -#define UIFONT_CUSTOM1 2 -#define UIFONT_CUSTOM2 3 +typedef enum eUIFont_ID { + UIFONT_DEFAULT = 0, +/* UIFONT_BITMAP = 1 */ /* UNUSED */ + + /* free slots */ + UIFONT_CUSTOM1 = 2, + UIFONT_CUSTOM2 = 3 +} eUIFont_ID; /* default fonts to load/initalize */ /* first font is the default (index 0), others optional */ @@ -64,7 +67,6 @@ typedef struct uiFont { short uifont_id; /* own id */ short r_to_l; /* fonts that read from left to right */ short pad; - } uiFont; /* this state defines appearance of text */ @@ -79,13 +81,14 @@ typedef struct uiFontStyle { short align; /* text align hint */ float shadowalpha; /* total alpha */ float shadowcolor; /* 1 value, typically white or black anyway */ - } uiFontStyle; /* uiFontStyle->align */ -#define UI_STYLE_TEXT_LEFT 0 -#define UI_STYLE_TEXT_CENTER 1 -#define UI_STYLE_TEXT_RIGHT 2 +typedef enum eFontStyle_Align { + UI_STYLE_TEXT_LEFT = 0, + UI_STYLE_TEXT_CENTER = 1, + UI_STYLE_TEXT_RIGHT = 2 +} eFontStyle_Align; /* this is fed to the layout engine and widget code */ @@ -145,7 +148,6 @@ typedef struct uiPanelColors { } uiPanelColors; typedef struct ThemeUI { - /* Interface Elements (buttons, menus, icons) */ uiWidgetColors wcol_regular, wcol_tool, wcol_text; uiWidgetColors wcol_radio, wcol_option, wcol_toggle; @@ -209,8 +211,8 @@ typedef struct ThemeSpace { char vertex[4], vertex_select[4]; char edge[4], edge_select[4]; char edge_seam[4], edge_sharp[4], edge_facesel[4], edge_crease[4]; - char face[4], face_select[4]; // solid faces - char face_dot[4]; // selected color + char face[4], face_select[4]; /* solid faces */ + char face_dot[4]; /* selected color */ char extra_edge_len[4], extra_face_angle[4], extra_face_area[4], pad3[4]; char normal[4]; char vertex_normal[4]; @@ -224,7 +226,7 @@ typedef struct ThemeSpace { char handle_free[4], handle_auto[4], handle_vect[4], handle_align[4], handle_auto_clamped[4]; char handle_sel_free[4], handle_sel_auto[4], handle_sel_vect[4], handle_sel_align[4], handle_sel_auto_clamped[4]; - char ds_channel[4], ds_subchannel[4]; // dopesheet + char ds_channel[4], ds_subchannel[4]; /* dopesheet */ char console_output[4], console_input[4], console_info[4], console_error[4]; char console_cursor[4]; @@ -232,10 +234,10 @@ typedef struct ThemeSpace { char vertex_size, outline_width, facedot_size; char noodle_curving; - char syntaxl[4], syntaxn[4], syntaxb[4]; // syntax for textwindow and nodes + char syntaxl[4], syntaxn[4], syntaxb[4]; /* syntax for textwindow and nodes */ char syntaxv[4], syntaxc[4]; - char movie[4], movieclip[4], mask[4], image[4], scene[4], audio[4]; // for sequence editor + char movie[4], movieclip[4], mask[4], image[4], scene[4], audio[4]; /* for sequence editor */ char effect[4], hpad0[4], transition[4], meta[4]; char editmesh_active[4]; @@ -287,8 +289,10 @@ typedef struct ThemeWireColor { } ThemeWireColor; /* flags for ThemeWireColor */ -#define TH_WIRECOLOR_CONSTCOLS (1<<0) -#define TH_WIRECOLOR_TEXTCOLS (1<<1) +typedef enum eWireColor_Flags { + TH_WIRECOLOR_CONSTCOLS = (1 << 0), + TH_WIRECOLOR_TEXTCOLS = (1 << 1), +} eWireColor_Flags; /* A theme */ typedef struct bTheme { @@ -321,7 +325,6 @@ typedef struct bTheme { /*ThemeWireColor tobj[20];*/ int active_theme_area, pad; - } bTheme; /* for the moment only the name. may want to store options with this later */ @@ -345,8 +348,8 @@ typedef struct UserDef { char pythondir[768]; char sounddir[768]; char i18ndir[768]; - char image_editor[1024]; /* 1024 = FILE_MAX */ - char anim_player[1024]; /* 1024 = FILE_MAX */ + char image_editor[1024]; /* 1024 = FILE_MAX */ + char anim_player[1024]; /* 1024 = FILE_MAX */ int anim_player_preset; short v2d_min_gridsize; /* minimum spacing between gridlines in View2D grids */ @@ -393,7 +396,7 @@ typedef struct UserDef { int memcachelimit; int prefetchframes; short frameserverport; - short pad_rot_angle; /*control the rotation step of the view when PAD2, PAD4, PAD6&PAD8 is use*/ + short pad_rot_angle; /* control the rotation step of the view when PAD2, PAD4, PAD6&PAD8 is use */ short obcenter_dia; short rvisize; /* rotating view icon size */ short rvibright; /* rotating view icon brightness */ @@ -422,7 +425,7 @@ typedef struct UserDef { short autokey_mode; /* autokeying mode */ short autokey_flag; /* flags for autokeying */ - short text_render, pad9; /*options for text rendering*/ + short text_render, pad9; /* options for text rendering */ struct ColorBand coba_weight; /* from texture.h */ @@ -445,218 +448,258 @@ extern UserDef U; /* from blenkernel blender.c */ /* ***************** USERDEF ****************** */ /* userpref/section */ -#define USER_SECTION_INTERFACE 0 -#define USER_SECTION_EDIT 1 -#define USER_SECTION_FILE 2 -#define USER_SECTION_SYSTEM 3 -#define USER_SECTION_THEME 4 -#define USER_SECTION_INPUT 5 -#define USER_SECTION_ADDONS 6 +typedef enum eUserPref_Section { + USER_SECTION_INTERFACE = 0, + USER_SECTION_EDIT = 1, + USER_SECTION_FILE = 2, + USER_SECTION_SYSTEM = 3, + USER_SECTION_THEME = 4, + USER_SECTION_INPUT = 5, + USER_SECTION_ADDONS = 6, +} eUserPref_Section; /* flag */ -#define USER_AUTOSAVE (1 << 0) -/*#define USER_AUTOGRABGRID (1 << 1) deprecated */ -/*#define USER_AUTOROTGRID (1 << 2) deprecated */ -/*#define USER_AUTOSIZEGRID (1 << 3) deprecated */ -#define USER_SCENEGLOBAL (1 << 4) -#define USER_TRACKBALL (1 << 5) -/*#define USER_DUPLILINK (1 << 6) deprecated */ -/*#define USER_FSCOLLUM (1 << 7) deprecated */ -#define USER_MAT_ON_OB (1 << 8) -/*#define USER_NO_CAPSLOCK (1 << 9)*/ /* not used anywhere */ -/*#define USER_VIEWMOVE (1 << 10)*/ /* not used anywhere */ -#define USER_TOOLTIPS (1 << 11) -#define USER_TWOBUTTONMOUSE (1 << 12) -#define USER_NONUMPAD (1 << 13) -#define USER_LMOUSESELECT (1 << 14) -#define USER_FILECOMPRESS (1 << 15) -#define USER_SAVE_PREVIEWS (1 << 16) -#define USER_CUSTOM_RANGE (1 << 17) -#define USER_ADD_EDITMODE (1 << 18) -#define USER_ADD_VIEWALIGNED (1 << 19) -#define USER_RELPATHS (1 << 20) -#define USER_RELEASECONFIRM (1 << 21) -#define USER_SCRIPT_AUTOEXEC_DISABLE (1 << 22) -#define USER_FILENOUI (1 << 23) -#define USER_NONEGFRAMES (1 << 24) -#define USER_TXT_TABSTOSPACES_DISABLE (1 << 25) -#define USER_TOOLTIPS_PYTHON (1 << 26) - +typedef enum eUserPref_Flag { + USER_AUTOSAVE = (1 << 0), +/* USER_AUTOGRABGRID = (1 << 1), deprecated */ +/* USER_AUTOROTGRID = (1 << 2), deprecated */ +/* USER_AUTOSIZEGRID = (1 << 3), deprecated */ + USER_SCENEGLOBAL = (1 << 4), + USER_TRACKBALL = (1 << 5), +/* USER_DUPLILINK = (1 << 6), deprecated */ +/* USER_FSCOLLUM = (1 << 7), deprecated */ + USER_MAT_ON_OB = (1 << 8), +/* USER_NO_CAPSLOCK = (1 << 9), */ /* not used anywhere */ +/* USER_VIEWMOVE = (1 << 10), */ /* not used anywhere */ + USER_TOOLTIPS = (1 << 11), + USER_TWOBUTTONMOUSE = (1 << 12), + USER_NONUMPAD = (1 << 13), + USER_LMOUSESELECT = (1 << 14), + USER_FILECOMPRESS = (1 << 15), + USER_SAVE_PREVIEWS = (1 << 16), + USER_CUSTOM_RANGE = (1 << 17), + USER_ADD_EDITMODE = (1 << 18), + USER_ADD_VIEWALIGNED = (1 << 19), + USER_RELPATHS = (1 << 20), + USER_RELEASECONFIRM = (1 << 21), + USER_SCRIPT_AUTOEXEC_DISABLE = (1 << 22), + USER_FILENOUI = (1 << 23), + USER_NONEGFRAMES = (1 << 24), + USER_TXT_TABSTOSPACES_DISABLE = (1 << 25), + USER_TOOLTIPS_PYTHON = (1 << 26), +} eUserPref_Flag; + /* helper macro for checking frame clamping */ #define FRAMENUMBER_MIN_CLAMP(cfra) { \ if ((U.flag & USER_NONEGFRAMES) && (cfra < 0)) \ cfra = 0; \ } (void)0 -/* viewzom */ -#define USER_ZOOM_CONT 0 -#define USER_ZOOM_SCALE 1 -#define USER_ZOOM_DOLLY 2 +/* viewzoom */ +typedef enum eViewZoom_Style { + USER_ZOOM_CONT = 0, + USER_ZOOM_SCALE = 1, + USER_ZOOM_DOLLY = 2 +} eViewZoom_Style; /* uiflag */ -// old flag for #define USER_KEYINSERTACT (1 << 0) -// old flag for #define USER_KEYINSERTOBJ (1 << 1) -#define USER_WHEELZOOMDIR (1 << 2) -#define USER_FILTERFILEEXTS (1 << 3) -#define USER_DRAWVIEWINFO (1 << 4) -#define USER_PLAINMENUS (1 << 5) // old EVTTOCONSOLE print ghost events, here for tuhopuu compat. --phase - // old flag for hide pulldown was here -/*#define USER_FLIPFULLSCREEN (1 << 7)*/ /* deprecated */ -#define USER_ALLWINCODECS (1 << 8) -#define USER_MENUOPENAUTO (1 << 9) -#define USER_ZBUF_CURSOR (1 << 10) -#define USER_AUTOPERSP (1 << 11) -#define USER_LOCKAROUND (1 << 12) -#define USER_GLOBALUNDO (1 << 13) -#define USER_ORBIT_SELECTION (1 << 14) -#define USER_ZBUF_ORBIT (1 << 15) -#define USER_HIDE_DOT (1 << 16) -#define USER_SHOW_ROTVIEWICON (1 << 17) -#define USER_SHOW_VIEWPORTNAME (1 << 18) -#define USER_CAM_LOCK_NO_PARENT (1 << 19) -#define USER_ZOOM_TO_MOUSEPOS (1 << 20) -#define USER_SHOW_FPS (1 << 21) -#define USER_MMB_PASTE (1 << 22) -#define USER_MENUFIXEDORDER (1 << 23) -#define USER_CONTINUOUS_MOUSE (1 << 24) -#define USER_ZOOM_INVERT (1 << 25) -#define USER_ZOOM_HORIZ (1 << 26) /* for CONTINUE and DOLLY zoom */ -#define USER_SPLASH_DISABLE (1 << 27) -#define USER_HIDE_RECENT (1 << 28) -#define USER_SHOW_THUMBNAILS (1 << 29) -#define USER_QUIT_PROMPT (1 << 30) +typedef enum eUserpref_UI_Flag { + /* flags 0 and 1 were old flags (for autokeying) that aren't used anymore */ + USER_WHEELZOOMDIR = (1 << 2), + USER_FILTERFILEEXTS = (1 << 3), + USER_DRAWVIEWINFO = (1 << 4), + USER_PLAINMENUS = (1 << 5), + /* flags 6 and 7 were old flags that are no-longer used */ + USER_ALLWINCODECS = (1 << 8), + USER_MENUOPENAUTO = (1 << 9), + USER_ZBUF_CURSOR = (1 << 10), + USER_AUTOPERSP = (1 << 11), + USER_LOCKAROUND = (1 << 12), + USER_GLOBALUNDO = (1 << 13), + USER_ORBIT_SELECTION = (1 << 14), + USER_ZBUF_ORBIT = (1 << 15), + USER_HIDE_DOT = (1 << 16), + USER_SHOW_ROTVIEWICON = (1 << 17), + USER_SHOW_VIEWPORTNAME = (1 << 18), + USER_CAM_LOCK_NO_PARENT = (1 << 19), + USER_ZOOM_TO_MOUSEPOS = (1 << 20), + USER_SHOW_FPS = (1 << 21), + USER_MMB_PASTE = (1 << 22), + USER_MENUFIXEDORDER = (1 << 23), + USER_CONTINUOUS_MOUSE = (1 << 24), + USER_ZOOM_INVERT = (1 << 25), + USER_ZOOM_HORIZ = (1 << 26), /* for CONTINUE and DOLLY zoom */ + USER_SPLASH_DISABLE = (1 << 27), + USER_HIDE_RECENT = (1 << 28), + USER_SHOW_THUMBNAILS = (1 << 29), + USER_QUIT_PROMPT = (1 << 30) +} eUserpref_UI_Flag; /* Auto-Keying mode */ +typedef enum eAutokey_Mode { /* AUTOKEY_ON is a bitflag */ -#define AUTOKEY_ON 1 + AUTOKEY_ON = 1, + /* AUTOKEY_ON + 2**n... (i.e. AUTOKEY_MODE_NORMAL = AUTOKEY_ON + 2) to preserve setting, even when autokey turned off */ -#define AUTOKEY_MODE_NORMAL 3 -#define AUTOKEY_MODE_EDITKEYS 5 + AUTOKEY_MODE_NORMAL = 3, + AUTOKEY_MODE_EDITKEYS = 5 +} eAutokey_Mode; /* Auto-Keying flag * U.autokey_flag (not strictly used when autokeying only - is also used when keyframing these days) * note: AUTOKEY_FLAG_* is used with a macro, search for lines like IS_AUTOKEY_FLAG(INSERTAVAIL) */ -#define AUTOKEY_FLAG_INSERTAVAIL (1<<0) -#define AUTOKEY_FLAG_INSERTNEEDED (1<<1) -#define AUTOKEY_FLAG_AUTOMATKEY (1<<2) -#define AUTOKEY_FLAG_XYZ2RGB (1<<3) - -/* toolsettings->autokey_flag */ -#define AUTOKEY_FLAG_ONLYKEYINGSET (1<<6) -#define AUTOKEY_FLAG_NOWARNING (1<<7) -#define ANIMRECORD_FLAG_WITHNLA (1<<10) +typedef enum eAutokey_Flag { + AUTOKEY_FLAG_INSERTAVAIL = (1 << 0), + AUTOKEY_FLAG_INSERTNEEDED = (1 << 1), + AUTOKEY_FLAG_AUTOMATKEY = (1 << 2), + AUTOKEY_FLAG_XYZ2RGB = (1 << 3), + + /* toolsettings->autokey_flag */ + AUTOKEY_FLAG_ONLYKEYINGSET = (1 << 6), + AUTOKEY_FLAG_NOWARNING = (1 << 7), + ANIMRECORD_FLAG_WITHNLA = (1 << 10), +} eAutokey_Flag; /* transopts */ -#define USER_TR_TOOLTIPS (1 << 0) -#define USER_TR_IFACE (1 << 1) -/*#define USER_TR_MENUS (1 << 2) deprecated*/ -/*#define USER_TR_FILESELECT (1 << 3) deprecated*/ -/*#define USER_TR_TEXTEDIT (1 << 4) deprecated*/ -#define USER_DOTRANSLATE (1 << 5) -#define USER_USETEXTUREFONT (1 << 6) -/*#define CONVERT_TO_UTF8 (1 << 7) deprecated*/ +typedef enum eUserpref_Translation_Flags { + USER_TR_TOOLTIPS = (1 << 0), + USER_TR_IFACE = (1 << 1), +/* USER_TR_MENUS = (1 << 2) deprecated */ +/* USER_TR_FILESELECT = (1 << 3) deprecated */ +/* USER_TR_TEXTEDIT = (1 << 4) deprecated */ + USER_DOTRANSLATE = (1 << 5), + USER_USETEXTUREFONT = (1 << 6), +/* CONVERT_TO_UTF8 = (1 << 7) deprecated */ +} eUserpref_Translation_Flags; /* dupflag */ -#define USER_DUP_MESH (1 << 0) -#define USER_DUP_CURVE (1 << 1) -#define USER_DUP_SURF (1 << 2) -#define USER_DUP_FONT (1 << 3) -#define USER_DUP_MBALL (1 << 4) -#define USER_DUP_LAMP (1 << 5) -#define USER_DUP_IPO (1 << 6) -#define USER_DUP_MAT (1 << 7) -#define USER_DUP_TEX (1 << 8) -#define USER_DUP_ARM (1 << 9) -#define USER_DUP_ACT (1 << 10) -#define USER_DUP_PSYS (1 << 11) +typedef enum eDupli_ID_Flags { + USER_DUP_MESH = (1 << 0), + USER_DUP_CURVE = (1 << 1), + USER_DUP_SURF = (1 << 2), + USER_DUP_FONT = (1 << 3), + USER_DUP_MBALL = (1 << 4), + USER_DUP_LAMP = (1 << 5), + USER_DUP_IPO = (1 << 6), + USER_DUP_MAT = (1 << 7), + USER_DUP_TEX = (1 << 8), + USER_DUP_ARM = (1 << 9), + USER_DUP_ACT = (1 << 10), + USER_DUP_PSYS = (1 << 11) +} eDupli_ID_Flags; /* gameflags */ -// #define USER_DEPRECATED_FLAG 1 -// #define USER_DISABLE_SOUND 2 deprecated, don't use without checking for -// backwards compatibilty in do_versions! -#define USER_DISABLE_MIPMAP 4 -#define USER_DISABLE_VBO 8 -#define USER_DISABLE_AA 16 +typedef enum eOpenGL_RenderingOptions { + /* USER_DEPRECATED_FLAG = (1 << 0), */ + /* USER_DISABLE_SOUND = (1 << 1), */ /* deprecated, don't use without checking for */ + /* backwards compatibilty in do_versions! */ + USER_DISABLE_MIPMAP = (1 << 2), + USER_DISABLE_VBO = (1 << 3), + USER_DISABLE_AA = (1 << 4), +} eOpenGL_RenderingOptions; /* wm draw method */ -#define USER_DRAW_TRIPLE 0 -#define USER_DRAW_OVERLAP 1 -#define USER_DRAW_FULL 2 -#define USER_DRAW_AUTOMATIC 3 -#define USER_DRAW_OVERLAP_FLIP 4 +typedef enum eWM_DrawMethod { + USER_DRAW_TRIPLE = 0, + USER_DRAW_OVERLAP = 1, + USER_DRAW_FULL = 2, + USER_DRAW_AUTOMATIC = 3, + USER_DRAW_OVERLAP_FLIP = 4, +} eWM_DrawMethod; -/* text draw options*/ -#define USER_TEXT_DISABLE_AA (1 << 0) +/* text draw options */ +typedef enum eText_Draw_Options { + USER_TEXT_DISABLE_AA = (1 << 0), +} eText_Draw_Options; /* tw_flag (transform widget) */ /* gp_settings (Grease Pencil Settings) */ -#define GP_PAINT_DOSMOOTH (1<<0) -#define GP_PAINT_DOSIMPLIFY (1<<1) +typedef enum eGP_UserdefSettings { + GP_PAINT_DOSMOOTH = (1 << 0), + GP_PAINT_DOSIMPLIFY = (1 << 1), +} eGP_UserdefSettings; /* color picker types */ -#define USER_CP_CIRCLE 0 -#define USER_CP_SQUARE_SV 1 -#define USER_CP_SQUARE_HS 2 -#define USER_CP_SQUARE_HV 3 +typedef enum eColorPicker_Types { + USER_CP_CIRCLE = 0, + USER_CP_SQUARE_SV = 1, + USER_CP_SQUARE_HS = 2, + USER_CP_SQUARE_HV = 3, +} eColorPicker_Types; /* timecode display styles */ +typedef enum eTimecodeStyles { /* as little info as is necessary to show relevant info * with '+' to denote the frames * i.e. HH:MM:SS+FF, MM:SS+FF, SS+FF, or MM:SS */ -#define USER_TIMECODE_MINIMAL 0 + USER_TIMECODE_MINIMAL = 0, + /* reduced SMPTE - (HH:)MM:SS:FF */ -#define USER_TIMECODE_SMPTE_MSF 1 + USER_TIMECODE_SMPTE_MSF = 1, + /* full SMPTE - HH:MM:SS:FF */ -#define USER_TIMECODE_SMPTE_FULL 2 + USER_TIMECODE_SMPTE_FULL = 2, + /* milliseconds for sub-frames - HH:MM:SS.sss */ -#define USER_TIMECODE_MILLISECONDS 3 + USER_TIMECODE_MILLISECONDS = 3, + /* seconds only */ -#define USER_TIMECODE_SECONDS_ONLY 4 + USER_TIMECODE_SECONDS_ONLY = 4, +} eTimecodeStyles; /* theme drawtypes */ -#define TH_MINIMAL 0 -#define TH_ROUNDSHADED 1 -#define TH_ROUNDED 2 -#define TH_OLDSKOOL 3 -#define TH_SHADED 4 +/* XXX: These are probably only for the old UI engine? */ +typedef enum eTheme_DrawTypes { + TH_MINIMAL = 0, + TH_ROUNDSHADED = 1, + TH_ROUNDED = 2, + TH_OLDSKOOL = 3, + TH_SHADED = 4 +} eTheme_DrawTypes; /* ndof_flag (3D mouse options) */ -#define NDOF_SHOW_GUIDE (1 << 0) -#define NDOF_FLY_HELICOPTER (1 << 1) -#define NDOF_LOCK_HORIZON (1 << 2) -/* the following might not need to be saved between sessions, - * but they do need to live somewhere accessible... */ -#define NDOF_SHOULD_PAN (1 << 3) -#define NDOF_SHOULD_ZOOM (1 << 4) -#define NDOF_SHOULD_ROTATE (1 << 5) -/* orbit navigation modes - * only two options, so it's sort of a hybrid bool/enum - * if ((U.ndof_flag & NDOF_ORBIT_MODE) == NDOF_OM_OBJECT)... */ +typedef enum eNdof_Flag { + NDOF_SHOW_GUIDE = (1 << 0), + NDOF_FLY_HELICOPTER = (1 << 1), + NDOF_LOCK_HORIZON = (1 << 2), -// #define NDOF_ORBIT_MODE (1 << 6) -// #define NDOF_OM_TARGETCAMERA 0 -// #define NDOF_OM_OBJECT NDOF_ORBIT_MODE + /* the following might not need to be saved between sessions, + * but they do need to live somewhere accessible... */ + NDOF_SHOULD_PAN = (1 << 3), + NDOF_SHOULD_ZOOM = (1 << 4), + NDOF_SHOULD_ROTATE = (1 << 5), -/* actually... users probably don't care about what the mode - * is called, just that it feels right */ -/* zoom is up/down if this flag is set (otherwise forward/backward) */ -#define NDOF_ZOOM_UPDOWN (1 << 7) -#define NDOF_ZOOM_INVERT (1 << 8) -#define NDOF_ROTATE_INVERT_AXIS (1 << 9) -#define NDOF_TILT_INVERT_AXIS (1 << 10) -#define NDOF_ROLL_INVERT_AXIS (1 << 11) -#define NDOF_PANX_INVERT_AXIS (1 << 12) -#define NDOF_PANY_INVERT_AXIS (1 << 13) -#define NDOF_PANZ_INVERT_AXIS (1 << 14) -#define NDOF_TURNTABLE (1 << 15) + /* orbit navigation modes + * only two options, so it's sort of a hybrid bool/enum + * if ((U.ndof_flag & NDOF_ORBIT_MODE) == NDOF_OM_OBJECT)... */ + + // NDOF_ORBIT_MODE = (1 << 6), + // #define NDOF_OM_TARGETCAMERA 0 + // #define NDOF_OM_OBJECT NDOF_ORBIT_MODE + + /* actually... users probably don't care about what the mode + * is called, just that it feels right */ + /* zoom is up/down if this flag is set (otherwise forward/backward) */ + NDOF_ZOOM_UPDOWN = (1 << 7), + NDOF_ZOOM_INVERT = (1 << 8), + NDOF_ROTATE_INVERT_AXIS = (1 << 9), + NDOF_TILT_INVERT_AXIS = (1 << 10), + NDOF_ROLL_INVERT_AXIS = (1 << 11), + NDOF_PANX_INVERT_AXIS = (1 << 12), + NDOF_PANY_INVERT_AXIS = (1 << 13), + NDOF_PANZ_INVERT_AXIS = (1 << 14), + NDOF_TURNTABLE = (1 << 15), +} eNdof_Flag; /* compute_device_type */ -#define USER_COMPUTE_DEVICE_NONE 0 -#define USER_COMPUTE_DEVICE_OPENCL 1 -#define USER_COMPUTE_DEVICE_CUDA 2 +typedef enum eCompute_Device_Type { + USER_COMPUTE_DEVICE_NONE = 0, + USER_COMPUTE_DEVICE_OPENCL = 1, + USER_COMPUTE_DEVICE_CUDA = 2, +} eCompute_Device_Type; #ifdef __cplusplus } From 33f35647e96b843e0df4c3304173bd39b7cc2dd5 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 9 Oct 2012 10:33:18 +0000 Subject: [PATCH 134/347] Motion Tracking: move keyframe settings to per-tracking object settings --- release/scripts/startup/bl_ui/space_clip.py | 4 ++-- source/blender/blenkernel/BKE_blender.h | 2 +- source/blender/blenkernel/intern/tracking.c | 13 +++++----- source/blender/blenloader/intern/readfile.c | 19 +++++++++++++++ source/blender/editors/space_clip/clip_draw.c | 5 ++-- .../blender/editors/space_clip/tracking_ops.c | 9 ++++--- source/blender/makesdna/DNA_tracking_types.h | 7 +++++- source/blender/makesrna/intern/rna_tracking.c | 24 +++++++++---------- 8 files changed, 53 insertions(+), 30 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py index 7732a0c6400..17dd1c9cdab 100644 --- a/release/scripts/startup/bl_ui/space_clip.py +++ b/release/scripts/startup/bl_ui/space_clip.py @@ -311,8 +311,8 @@ class CLIP_PT_tools_solve(CLIP_PT_tracking_panel, Panel): col = layout.column(align=True) col.active = not settings.use_tripod_solver - col.prop(settings, "keyframe_a") - col.prop(settings, "keyframe_b") + col.prop(tracking_object, "keyframe_a") + col.prop(tracking_object, "keyframe_b") col = layout.column(align=True) col.active = (tracking_object.is_camera and diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index 741a001142f..e1c79f8d6c1 100644 --- a/source/blender/blenkernel/BKE_blender.h +++ b/source/blender/blenkernel/BKE_blender.h @@ -42,7 +42,7 @@ extern "C" { * and keep comment above the defines. * Use STRINGIFY() rather than defining with quotes */ #define BLENDER_VERSION 264 -#define BLENDER_SUBVERSION 1 +#define BLENDER_SUBVERSION 2 /* 262 was the last editmesh release but its has compatibility code for bmesh data, * so set the minversion to 2.61 */ diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index c9d7ec3964f..7d2fd520c37 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -169,8 +169,6 @@ void BKE_tracking_settings_init(MovieTracking *tracking) tracking->settings.default_minimum_correlation = 0.75; tracking->settings.default_pattern_size = 11; tracking->settings.default_search_size = 61; - tracking->settings.keyframe1 = 1; - tracking->settings.keyframe2 = 30; tracking->settings.dist = 1; tracking->settings.object_distance = 1; @@ -1179,6 +1177,8 @@ MovieTrackingObject *BKE_tracking_object_add(MovieTracking *tracking, const char tracking->objectnr = BLI_countlist(&tracking->objects) - 1; object->scale = 1.0f; + object->keyframe1 = 1; + object->keyframe2 = 30; BKE_tracking_object_unique_name(tracking, object); @@ -2755,10 +2755,11 @@ static int reconstruct_refine_intrinsics_get_flags(MovieTracking *tracking, Movi return flags; } -static int reconstruct_count_tracks_on_both_keyframes(MovieTracking *tracking, ListBase *tracksbase) +static int reconstruct_count_tracks_on_both_keyframes(MovieTracking *tracking, MovieTrackingObject *object) { + ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object); int tot = 0; - int frame1 = tracking->settings.keyframe1, frame2 = tracking->settings.keyframe2; + int frame1 = object->keyframe1, frame2 = object->keyframe2; MovieTrackingTrack *track; track = tracksbase->first; @@ -2779,13 +2780,11 @@ static int reconstruct_count_tracks_on_both_keyframes(MovieTracking *tracking, L int BKE_tracking_reconstruction_check(MovieTracking *tracking, MovieTrackingObject *object, char *error_msg, int error_size) { #ifdef WITH_LIBMV - ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object); - if (tracking->settings.motion_flag & TRACKING_MOTION_MODAL) { /* TODO: check for number of tracks? */ return TRUE; } - else if (reconstruct_count_tracks_on_both_keyframes(tracking, tracksbase) < 8) { + else if (reconstruct_count_tracks_on_both_keyframes(tracking, object) < 8) { BLI_strncpy(error_msg, "At least 8 common tracks on both of keyframes are needed for reconstruction", error_size); diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index fdb68d4cc17..606fd48dc2b 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -8016,6 +8016,25 @@ static void do_versions(FileData *fd, Library *lib, Main *main) do_version_ntree_tex_coord_from_dupli_264(NULL, NULL, ntree); } + if (main->versionfile < 264 || (main->versionfile == 264 && main->subversionfile < 2)) { + MovieClip *clip; + + for (clip = main->movieclip.first; clip; clip = clip->id.next) { + MovieTracking *tracking = &clip->tracking; + MovieTrackingObject *tracking_object; + + for (tracking_object = tracking->objects.first; + tracking_object; + tracking_object = tracking_object->next) + { + if (tracking_object->keyframe1 == 0 && tracking_object->keyframe2 == 0) { + tracking_object->keyframe1 = tracking->settings.keyframe1; + tracking_object->keyframe2 = tracking->settings.keyframe2; + } + } + } + } + /* WATCH IT!!!: pointers from libdata have not been converted yet here! */ /* WATCH IT 2!: Userdef struct init has to be in editors/interface/resources.c! */ diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c index 5e940df2a30..d7936c1e2e8 100644 --- a/source/blender/editors/space_clip/clip_draw.c +++ b/source/blender/editors/space_clip/clip_draw.c @@ -117,6 +117,7 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc int *points, totseg, i, a; float sfra = SFRA, efra = EFRA, framelen = ar->winx / (efra - sfra + 1); MovieTracking *tracking = &clip->tracking; + MovieTrackingObject *act_object = BKE_tracking_object_get_active(tracking); MovieTrackingTrack *act_track = BKE_tracking_track_get_active(&clip->tracking); MovieTrackingReconstruction *reconstruction = BKE_tracking_get_active_reconstruction(tracking); @@ -218,8 +219,8 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc /* solver keyframes */ glColor4ub(175, 255, 0, 255); - draw_keyframe(tracking->settings.keyframe1 + clip->start_frame - 1, CFRA, sfra, framelen, 2); - draw_keyframe(tracking->settings.keyframe2 + clip->start_frame - 1, CFRA, sfra, framelen, 2); + draw_keyframe(act_object->keyframe1 + clip->start_frame - 1, CFRA, sfra, framelen, 2); + draw_keyframe(act_object->keyframe2 + clip->start_frame - 1, CFRA, sfra, framelen, 2); /* movie clip animation */ if ((sc->mode == SC_MODE_MASKEDIT) && sc->mask_info.mask) { diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c index 97f7d7bf132..8dc28bbaee0 100644 --- a/source/blender/editors/space_clip/tracking_ops.c +++ b/source/blender/editors/space_clip/tracking_ops.c @@ -1343,7 +1343,6 @@ static int solve_camera_initjob(bContext *C, SolveCameraJob *scj, wmOperator *op MovieClip *clip = ED_space_clip_get_clip(sc); Scene *scene = CTX_data_scene(C); MovieTracking *tracking = &clip->tracking; - MovieTrackingSettings *settings = &clip->tracking.settings; MovieTrackingObject *object = BKE_tracking_object_get_active(tracking); int width, height; @@ -1359,7 +1358,7 @@ static int solve_camera_initjob(bContext *C, SolveCameraJob *scj, wmOperator *op scj->user = sc->user; scj->context = BKE_tracking_reconstruction_context_new(tracking, object, - settings->keyframe1, settings->keyframe2, width, height); + object->keyframe1, object->keyframe2, width, height); tracking->stats = MEM_callocN(sizeof(MovieTrackingStats), "solve camera stats"); @@ -2859,14 +2858,14 @@ static int set_solver_keyframe_exec(bContext *C, wmOperator *op) SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip_get_clip(sc); MovieTracking *tracking = &clip->tracking; - MovieTrackingSettings *settings = &tracking->settings; + MovieTrackingObject *object = BKE_tracking_object_get_active(tracking); int keyframe = RNA_enum_get(op->ptr, "keyframe"); int framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, sc->user.framenr); if (keyframe == 0) - settings->keyframe1 = framenr; + object->keyframe1 = framenr; else - settings->keyframe2 = framenr; + object->keyframe2 = framenr; WM_event_add_notifier(C, NC_MOVIECLIP | ND_DISPLAY, clip); diff --git a/source/blender/makesdna/DNA_tracking_types.h b/source/blender/makesdna/DNA_tracking_types.h index 1ab64ed1cc1..c6cefce2994 100644 --- a/source/blender/makesdna/DNA_tracking_types.h +++ b/source/blender/makesdna/DNA_tracking_types.h @@ -162,7 +162,10 @@ typedef struct MovieTrackingSettings { short speed; /* speed of tracking */ /* ** reconstruction settings ** */ - int keyframe1, keyframe2; /* two keyframes for reconstrution initialization */ + int keyframe1 DNA_DEPRECATED, + keyframe2 DNA_DEPRECATED; /* two keyframes for reconstrution initialization + * were moved to per-tracking object settings + */ /* which camera intrinsics to refine. uses on the REFINE_* flags */ short refine_camera_intrinsics, pad2; @@ -220,6 +223,8 @@ typedef struct MovieTrackingObject { ListBase tracks; /* list of tracks use to tracking this object */ MovieTrackingReconstruction reconstruction; /* reconstruction data for this object */ + + int keyframe1, keyframe2; /* two keyframes for reconstrution initialization */ } MovieTrackingObject; typedef struct MovieTrackingStats { diff --git a/source/blender/makesrna/intern/rna_tracking.c b/source/blender/makesrna/intern/rna_tracking.c index 0c62a280935..4b744b160fc 100644 --- a/source/blender/makesrna/intern/rna_tracking.c +++ b/source/blender/makesrna/intern/rna_tracking.c @@ -567,18 +567,6 @@ static void rna_def_trackingSettings(BlenderRNA *brna) "Limit speed of tracking to make visual feedback easier " "(this does not affect the tracking quality)"); - /* keyframe_a */ - prop = RNA_def_property(srna, "keyframe_a", PROP_INT, PROP_NONE); - RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_int_sdna(prop, NULL, "keyframe1"); - RNA_def_property_ui_text(prop, "Keyframe A", "First keyframe used for reconstruction initialization"); - - /* keyframe_b */ - prop = RNA_def_property(srna, "keyframe_b", PROP_INT, PROP_NONE); - RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_int_sdna(prop, NULL, "keyframe2"); - RNA_def_property_ui_text(prop, "Keyframe B", "Second keyframe used for reconstruction initialization"); - /* intrinsics refinement during bundle adjustment */ prop = RNA_def_property(srna, "refine_intrinsics", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "refine_camera_intrinsics"); @@ -1393,6 +1381,18 @@ static void rna_def_trackingObject(BlenderRNA *brna) RNA_def_property_float_default(prop, 1.0f); RNA_def_property_ui_text(prop, "Scale", "Scale of object solution in camera space"); RNA_def_property_update(prop, NC_MOVIECLIP | NA_EDITED, "rna_trackingObject_flushUpdate"); + + /* keyframe_a */ + prop = RNA_def_property(srna, "keyframe_a", PROP_INT, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_int_sdna(prop, NULL, "keyframe1"); + RNA_def_property_ui_text(prop, "Keyframe A", "First keyframe used for reconstruction initialization"); + + /* keyframe_b */ + prop = RNA_def_property(srna, "keyframe_b", PROP_INT, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_int_sdna(prop, NULL, "keyframe2"); + RNA_def_property_ui_text(prop, "Keyframe B", "Second keyframe used for reconstruction initialization"); } static void rna_def_trackingObjects(BlenderRNA *brna, PropertyRNA *cprop) From 6712e7428257b57732f64efcdcea95b40043000b Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 9 Oct 2012 10:33:24 +0000 Subject: [PATCH 135/347] Motion Tracking; expose View All and Center to Current Frame to View menu of graph view --- release/scripts/startup/bl_ui/space_clip.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py index 17dd1c9cdab..f7b9f59b066 100644 --- a/release/scripts/startup/bl_ui/space_clip.py +++ b/release/scripts/startup/bl_ui/space_clip.py @@ -891,6 +891,12 @@ class CLIP_MT_view(Menu): layout.operator("clip.view_zoom_ratio", text=text).ratio = a / b else: + if sc.view == 'GRAPH': + layout.operator_context = 'INVOKE_REGION_PREVIEW' + layout.operator("clip.graph_center_current_frame") + layout.operator("clip.graph_view_all") + layout.operator_context = 'INVOKE_DEFAULT' + layout.prop(sc, "show_seconds") layout.separator() From fca582a2da1998819434021d26de69ef34748591 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Tue, 9 Oct 2012 10:36:07 +0000 Subject: [PATCH 136/347] Autokey warning - Only show for the active region In response to some of the feedback, I've taken a second look at the situation when multiple views are open, and indeed in that situation having it display in every region and blinking was quite overwhelming (admittedly, I've mainly been testing on single-view setups). Now it only shows for the region that was used for initiating the transform. --- source/blender/editors/transform/transform.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 775e8d2de8e..273d8913497 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -1617,10 +1617,16 @@ static void drawTransformPixel(const struct bContext *UNUSED(C), ARegion *ar, vo Scene *scene = t->scene; Object *ob = OBACT; - /* draw autokeyframing hint in the corner */ + /* draw autokeyframing hint in the corner + * - only draw if enabled (advanced users may be distracted/annoyed), + * for objects that will be autokeyframed (no point ohterwise), + * AND only for the active region (as showing all is too overwhelming) + */ if ((U.autokey_flag & AUTOKEY_FLAG_NOWARNING) == 0) { - if (ob && autokeyframe_cfra_can_key(scene, &ob->id)) { - drawAutoKeyWarning(t, ar); + if (ar == t->ar) { + if (ob && autokeyframe_cfra_can_key(scene, &ob->id)) { + drawAutoKeyWarning(t, ar); + } } } } From 27aa05ec36e85cedad81490189f706e9c709387c Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Tue, 9 Oct 2012 10:41:51 +0000 Subject: [PATCH 137/347] Autokey warning - trying with a slight "calmer" color Now it uses the same color used for indicating keyframes instead of using "error" indications. --- source/blender/editors/transform/transform.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 273d8913497..5e31de96e0e 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -1569,8 +1569,8 @@ static void drawAutoKeyWarning(TransInfo *t, ARegion *ar) { int show_warning; - /* red border around the viewport */ - UI_ThemeColor(TH_REDALERT); + /* colored border around the viewport */ + UI_ThemeColor(TH_VERTEX_SELECT); glBegin(GL_LINE_LOOP); glVertex2f(1, 1); @@ -1596,8 +1596,10 @@ static void drawAutoKeyWarning(TransInfo *t, ARegion *ar) xco = ar->winx - BLF_width_default(printable) - 10; yco = ar->winy - BLF_height_default(printable) - 10; - /* red warning text */ - UI_ThemeColor(TH_REDALERT); + /* warning text (to clarify meaning of overlays) + * - original color was red to match the icon, but that clashes badly with a less nasty border + */ + UI_ThemeColor(TH_VERTEX_SELECT); BLF_draw_default_ascii(xco, ar->winy - 17, 0.0f, printable, sizeof(printable)); /* autokey recording icon... */ From 8730b390fbd222a4c64304992f520cdce94fb710 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 9 Oct 2012 10:56:35 +0000 Subject: [PATCH 138/347] patch [#31919] limit the number of bone deform weights per vertex. Many game engines require a limit of 4. from Kesten Broughton (kestion) Usage: In weight paint mode, select the mesh to have its weights culled. Click on "Limit Weights" button. A sub-panel will appear "Limit Number of Vertex Weights" with a slider field "Limit" which you can set to the appropriate level. The default level is 4, and it gets executed upon pressing "Limit Weights" so you will need to do an "undo" if your max bone limit is above 4. The checkbox "All Deform Weights" will consider all vertex weights, not just bone deform weights. --- release/scripts/startup/bl_ui/space_view3d.py | 1 + .../startup/bl_ui/space_view3d_toolbar.py | 1 + source/blender/editors/object/object_intern.h | 1 + source/blender/editors/object/object_ops.c | 1 + source/blender/editors/object/object_vgroup.c | 172 +++++++++++++++++- 5 files changed, 170 insertions(+), 6 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index a21d8527158..d5648a6d3a2 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -1247,6 +1247,7 @@ class VIEW3D_MT_paint_weight(Menu): layout.operator("object.vertex_group_clean", text="Clean") layout.operator("object.vertex_group_levels", text="Levels") layout.operator("object.vertex_group_blend", text="Blend") + layout.operator("object.vertex_group_limit_total", text="Limit Total") layout.operator("object.vertex_group_fix", text="Fix Deforms") layout.separator() diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py index 0d939b2de78..52ffdff9b4f 100644 --- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py +++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py @@ -967,6 +967,7 @@ class VIEW3D_PT_tools_weightpaint(View3DPanel, Panel): col.operator("object.vertex_group_clean", text="Clean") col.operator("object.vertex_group_levels", text="Levels") col.operator("object.vertex_group_blend", text="Blend") + col.operator("object.vertex_group_limit_total", text="Limit Total") col.operator("object.vertex_group_fix", text="Fix Deforms") diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index 4c83f6ef2ce..a5a69d3dcbc 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -214,6 +214,7 @@ void OBJECT_OT_vertex_group_fix(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_invert(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_blend(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_clean(struct wmOperatorType *ot); +void OBJECT_OT_vertex_group_limit_total(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_mirror(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_set_active(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_sort(struct wmOperatorType *ot); diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index fa40d579e2b..cd4c73a9f1e 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -188,6 +188,7 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_vertex_group_levels); WM_operatortype_append(OBJECT_OT_vertex_group_blend); WM_operatortype_append(OBJECT_OT_vertex_group_clean); + WM_operatortype_append(OBJECT_OT_vertex_group_limit_total); WM_operatortype_append(OBJECT_OT_vertex_group_mirror); WM_operatortype_append(OBJECT_OT_vertex_group_set_active); WM_operatortype_append(OBJECT_OT_vertex_group_sort); diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index b31d2b8b076..0a99340be20 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -83,6 +83,19 @@ static void vgroup_delete_edit_mode(Object *ob, bDeformGroup *defgroup); static void vgroup_delete_object_mode(Object *ob, bDeformGroup *dg); static void vgroup_delete_all(Object *ob); +static int vertex_group_use_vert_sel(Object *ob) +{ + if (ob->mode == OB_MODE_EDIT) { + return TRUE; + } + else if (ob->type == OB_MESH && ((Mesh *)ob->data)->editflag & ME_EDIT_VERT_SEL) { + return TRUE; + } + else { + return FALSE; + } +} + static Lattice *vgroup_edit_lattice(Object *ob) { Lattice *lt = ob->data; @@ -704,7 +717,7 @@ static void vgroup_normalize(Object *ob) int i, dvert_tot = 0; const int def_nr = ob->actdef - 1; - const int use_vert_sel = (ob->type == OB_MESH && ((Mesh *)ob->data)->editflag & ME_EDIT_VERT_SEL) != 0; + const int use_vert_sel = vertex_group_use_vert_sel(ob); if (!BLI_findlink(&ob->defbase, def_nr)) { return; @@ -1109,7 +1122,7 @@ static void vgroup_levels(Object *ob, float offset, float gain) int i, dvert_tot = 0; const int def_nr = ob->actdef - 1; - const int use_vert_sel = (ob->type == OB_MESH && ((Mesh *)ob->data)->editflag & ME_EDIT_VERT_SEL) != 0; + const int use_vert_sel = vertex_group_use_vert_sel(ob); if (!BLI_findlink(&ob->defbase, def_nr)) { return; @@ -1143,7 +1156,7 @@ static void vgroup_normalize_all(Object *ob, int lock_active) int i, dvert_tot = 0; const int def_nr = ob->actdef - 1; - const int use_vert_sel = (ob->type == OB_MESH && ((Mesh *)ob->data)->editflag & ME_EDIT_VERT_SEL) != 0; + const int use_vert_sel = vertex_group_use_vert_sel(ob); if (lock_active && !BLI_findlink(&ob->defbase, def_nr)) { return; @@ -1221,7 +1234,7 @@ static void vgroup_invert(Object *ob, const short auto_assign, const short auto_ MDeformVert *dv, **dvert_array = NULL; int i, dvert_tot = 0; const int def_nr = ob->actdef - 1; - const int use_vert_sel = (ob->type == OB_MESH && ((Mesh *)ob->data)->editflag & ME_EDIT_VERT_SEL) != 0; + const int use_vert_sel = vertex_group_use_vert_sel(ob); if (!BLI_findlink(&ob->defbase, def_nr)) { return; @@ -1389,13 +1402,119 @@ static void vgroup_blend(Object *ob, const float fac) } } +static int inv_cmp_mdef_vert_weights(const void *a1, const void *a2) +{ + /* qsort sorts in ascending order. We want descending order to save a memcopy + * so this compare function is inverted from the standard greater than comparison qsort needs. + * A normal compare function is called with two pointer arguments and should return an integer less than, equal to, + * or greater than zero corresponding to whether its first argument is considered less than, equal to, + * or greater than its second argument. This does the opposite. */ + const struct MDeformWeight *dw1 = a1, *dw2 = a2; + + if (dw1->weight < dw2->weight) return 1; + else if (dw1->weight > dw2->weight) return -1; + else if (&dw1 < &dw2) return 1; /* compare addresses so we have a stable sort algorithm */ + else return -1; +} + +/* Used for limiting the number of influencing bones per vertex when exporting + * skinned meshes. if all_deform_weights is True, limit all deform modifiers + * to max_weights regardless of type, otherwise, only limit the number of influencing bones per vertex*/ +static int vertex_group_limit_total(Object *ob, + const int max_weights, + const int all_deform_weights) +{ + MDeformVert *dv, **dvert_array = NULL; + int i, dvert_tot = 0; + const int use_vert_sel = vertex_group_use_vert_sel(ob); + int is_change = FALSE; + + ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot, use_vert_sel); + + if (dvert_array) { + int defbase_tot = BLI_countlist(&ob->defbase); + const char *vgroup_validmap = (all_deform_weights == FALSE) ? + BKE_objdef_validmap_get(ob, defbase_tot) : + NULL; + int num_to_drop = 0; + + /* only the active group */ + for (i = 0; i < dvert_tot; i++) { + + /* in case its not selected */ + if (!(dv = dvert_array[i])) { + continue; + } + + if (all_deform_weights) { + /* keep only the largest weights, discarding the rest + * qsort will put array in descending order because of invCompare function */ + num_to_drop = dv->totweight - max_weights; + if (num_to_drop > 0) { + qsort(dv->dw, dv->totweight, sizeof(MDeformWeight), inv_cmp_mdef_vert_weights); + dv->dw = MEM_reallocN(dv->dw, sizeof(MDeformWeight) * max_weights); + dv->totweight = max_weights; + is_change = TRUE; + } + } + else { + MDeformWeight *dw_temp; + int bone_count = 0, non_bone_count = 0; + int j; + /* only consider vgroups with bone modifiers attached (in vgroup_validmap) */ + + num_to_drop = dv->totweight - max_weights; + + /* first check if we even need to test further */ + if (num_to_drop > 0) { + /* re-pack dw array so that non-bone weights are first, bone-weighted verts at end + * sort the tail, then copy only the truncated array back to dv->dw */ + dw_temp = MEM_mallocN(sizeof(MDeformWeight) * (dv->totweight), __func__); + bone_count = 0; non_bone_count = 0; + for (j = 0; j < dv->totweight; j++) { + BLI_assert(dv->dw[j].def_nr < defbase_tot); + if (!vgroup_validmap[(dv->dw[j]).def_nr]) { + dw_temp[non_bone_count] = dv->dw[j]; + non_bone_count += 1; + } + else { + dw_temp[dv->totweight - 1 - bone_count] = dv->dw[j]; + bone_count += 1; + } + } + BLI_assert(bone_count + non_bone_count == dv->totweight); + num_to_drop = bone_count - max_weights; + if (num_to_drop > 0) { + qsort(&dw_temp[non_bone_count], bone_count, sizeof(MDeformWeight), inv_cmp_mdef_vert_weights); + dv->totweight -= num_to_drop; + /* Do we want to clean/normalize here? */ + MEM_freeN(dv->dw); + dv->dw = MEM_reallocN(dw_temp, sizeof(MDeformWeight) * dv->totweight); + is_change = TRUE; + } + else { + MEM_freeN(dw_temp); + } + } + } + } + MEM_freeN(dvert_array); + + if (vgroup_validmap) { + MEM_freeN((void *)vgroup_validmap); + } + } + + return is_change; +} + static void vgroup_clean(Object *ob, const float epsilon, int keep_single) { MDeformWeight *dw; MDeformVert *dv, **dvert_array = NULL; int i, dvert_tot = 0; const int def_nr = ob->actdef - 1; - const int use_vert_sel = (ob->type == OB_MESH && ((Mesh *)ob->data)->editflag & ME_EDIT_VERT_SEL) != 0; + const int use_vert_sel = vertex_group_use_vert_sel(ob); if (!BLI_findlink(&ob->defbase, def_nr)) { return; @@ -1431,7 +1550,7 @@ static void vgroup_clean_all(Object *ob, const float epsilon, const int keep_sin { MDeformVert **dvert_array = NULL; int i, dvert_tot = 0; - const int use_vert_sel = (ob->type == OB_MESH && ((Mesh *)ob->data)->editflag & ME_EDIT_VERT_SEL) != 0; + const int use_vert_sel = vertex_group_use_vert_sel(ob); ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot, use_vert_sel); @@ -2665,6 +2784,47 @@ void OBJECT_OT_vertex_group_clean(wmOperatorType *ot) "Keep verts assigned to at least one group when cleaning"); } +static int vertex_group_limit_total_exec(bContext *C, wmOperator *op) +{ + Object *ob = ED_object_context(C); + + const int limit = RNA_int_get(op->ptr, "limit"); + const int all_deform_weights = RNA_boolean_get(op->ptr, "all_deform_weights"); + + if (vertex_group_limit_total(ob, limit, all_deform_weights)) { + + DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); + WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data); + + return OPERATOR_FINISHED; + } + else { + BKE_reportf(op->reports, RPT_WARNING, "No vertex groups limited"); + + /* note, would normally return cancelled, except we want the redo + * UI to show up for users to change */ + return OPERATOR_FINISHED; + } +} + +void OBJECT_OT_vertex_group_limit_total(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Limit Number of Weights per Vertex"; + ot->idname = "OBJECT_OT_vertex_group_limit_total"; + ot->description = "Limits deform weights associated with a vertex to a specified number by removing lowest weights"; + + /* api callbacks */ + ot->poll = vertex_group_poll; + ot->exec = vertex_group_limit_total_exec; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + RNA_def_int(ot->srna, "limit", 4, 1, 32, "Limit", "Maximum number of deform weights", 1, 32); + RNA_def_boolean(ot->srna, "all_deform_weights", FALSE, "All Deform Weights", "Cull all deform weights, not just bones"); +} static int vertex_group_mirror_exec(bContext *C, wmOperator *op) { From ec689d650dd9e32b5f88a4f45f583b6733192ef0 Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Tue, 9 Oct 2012 11:29:29 +0000 Subject: [PATCH 139/347] Fix based on code review Issue 6347064 --- source/blender/editors/object/object_vgroup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index a07bc3edda0..07df556b87d 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -466,7 +466,7 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s dg_dst = defgroup_find_name(ob_dst, dg_src->name); /* get meshes */ - dmesh_src = mesh_get_derived_deform(scene, ob_src, CD_MASK_BAREMESH | CD_MASK_ORIGINDEX); + dmesh_src = mesh_get_derived_deform(scene, ob_src, CD_MASK_BAREMESH); me_dst = ob_dst->data; me_src = ob_src->data; From 4550864f07c7a793c03eaa2c785d5321fb5d52fb Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 9 Oct 2012 11:31:25 +0000 Subject: [PATCH 140/347] Fix #32824: Color management configuration check was missed on file link/append --- source/blender/windowmanager/intern/wm_operators.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index e4d6b3dd465..ec25e8dcffb 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -79,6 +79,7 @@ #include "BIF_glutil.h" /* for paint cursor */ #include "BLF_api.h" +#include "IMB_colormanagement.h" #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" @@ -1838,6 +1839,7 @@ static int wm_link_append_exec(bContext *C, wmOperator *op) /* mark all library linked objects to be updated */ recalc_all_library_objects(bmain); + IMB_colormanagement_check_file_config(bmain); /* append, rather than linking */ if ((flag & FILE_LINK) == 0) { From affb060c200febc1b967fee2c78a3e2ecc6d7c46 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 9 Oct 2012 11:38:42 +0000 Subject: [PATCH 141/347] Revert part of 51209 -- MOUSEZOOM inversion should be done in lots of other places as well, but it's quite large change to be done before 'a' release. For now ignore zoom inverse for 2d view to keep things consistent, would be re-implemented for all areas after this. --- source/blender/editors/interface/view2d_ops.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c index 2c8db53b534..8be2667a015 100644 --- a/source/blender/editors/interface/view2d_ops.c +++ b/source/blender/editors/interface/view2d_ops.c @@ -945,11 +945,6 @@ static int view_zoomdrag_invoke(bContext *C, wmOperator *op, wmEvent *event) dx = fac * BLI_rctf_size_x(&v2d->cur) / 10.0f; dy = fac * BLI_rctf_size_y(&v2d->cur) / 10.0f; - if (U.uiflag & USER_ZOOM_INVERT) { - dx *= -1; - dy *= -1; - } - RNA_float_set(op->ptr, "deltax", dx); RNA_float_set(op->ptr, "deltay", dy); From 35504d627bf87c7d2e528870a3a215bd6b2b1876 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 9 Oct 2012 12:41:37 +0000 Subject: [PATCH 142/347] style cleanup: also made functions static --- source/blender/editors/object/object_vgroup.c | 38 ++++++++++++------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index f7bc87177f8..dea7eb984ad 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -431,7 +431,7 @@ static EnumPropertyItem WT_replace_mode_item[] = { }; /*copy weight*/ -void vgroup_transfer_weight(MVert *mv_dst, float *weight_dst, float weight_src, WT_ReplaceMode replace_mode) +static void vgroup_transfer_weight(MVert *mv_dst, float *weight_dst, float weight_src, WT_ReplaceMode replace_mode) { switch (replace_mode) { @@ -453,8 +453,9 @@ void vgroup_transfer_weight(MVert *mv_dst, float *weight_dst, float weight_src, } } -int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_src, Scene *scene, - WT_Method method, WT_ReplaceMode replace_mode, wmOperator *op) +/* could be exposed externally */ +static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_src, Scene *scene, + WT_Method method, WT_ReplaceMode replace_mode, wmOperator *op) { bDeformGroup *dg_dst; Mesh *me_dst, *me_src; @@ -536,7 +537,7 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s /* copy weight */ dw_src = defvert_find_index(*dv_src, index_src); - if(dw_src && dw_src->weight) { + if (dw_src && dw_src->weight) { dw_dst = defvert_verify_index(*dv_dst, index_dst); vgroup_transfer_weight(mv_dst, &dw_dst->weight, dw_src->weight, replace_mode); } @@ -564,7 +565,7 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s /* copy weight that are not NULL including weight value 0. Existing target weights are overwritten prior to this in relevant cases. */ dw_src = defvert_find_index(dv_array_src[nearest.index], index_src); - if(dw_src && dw_src->weight) { + if (dw_src && dw_src->weight) { dw_dst = defvert_verify_index(*dv_dst, index_dst); vgroup_transfer_weight(mv_dst, &dw_dst->weight, dw_src->weight, replace_mode); } @@ -620,7 +621,7 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s } while (f_index--); /* copy weight that are not NULL including weight value 0. Existing target weights are overwritten prior to this in relevant cases. */ - if(weight > 0) { + if (weight > 0) { dw_dst = defvert_verify_index(*dv_dst, index_dst); vgroup_transfer_weight(mv_dst, &dw_dst->weight, weight, replace_mode); } @@ -674,7 +675,7 @@ int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_s /* copy weight that are not NULL including weight value 0. Existing target weights are overwritten prior to this in relevant cases. */ dw_src = defvert_find_index(dv_array_src[index_nearest_vertex], index_src); - if(dw_src && dw_src->weight) { + if (dw_src && dw_src->weight) { dw_dst = defvert_verify_index(*dv_dst, index_dst); vgroup_transfer_weight(mv_dst, &dw_dst->weight, dw_src->weight, replace_mode); } @@ -3271,14 +3272,21 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) switch (vertex_group_mode) { case WT_REPLACE_ACTIVE_VERTEX_GROUP: - if (!ED_vgroup_transfer_weight( - ob_act, ob_slc, BLI_findlink(&ob_slc->defbase, ob_slc->actdef - 1), scene, method, replace_mode, op)) fail++; + if (!ed_vgroup_transfer_weight(ob_act, ob_slc, + BLI_findlink(&ob_slc->defbase, ob_slc->actdef - 1), + scene, method, replace_mode, op)) + { + fail++; + } break; case WT_REPLACE_ALL_VERTEX_GROUPS: for (dg_src = ob_slc->defbase.first; dg_src; dg_src = dg_src->next) { - if (!ED_vgroup_transfer_weight( - ob_act, ob_slc, dg_src, scene, method, replace_mode, op)) fail++; + if (!ed_vgroup_transfer_weight(ob_act, ob_slc, + dg_src, scene, method, replace_mode, op)) + { + fail++; + } } break; @@ -3296,8 +3304,12 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) CTX_DATA_END; - if (fail != 0) return OPERATOR_CANCELLED; - return OPERATOR_FINISHED; + if (fail != 0) { + return OPERATOR_CANCELLED; + } + else { + return OPERATOR_FINISHED; + } } /* transfers weight from active to selected */ From f92305fcb40c882c10b1e4ede7b6bfdfb18c4941 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Tue, 9 Oct 2012 12:59:20 +0000 Subject: [PATCH 143/347] Bugfix [#32677] Cloth Pinning Does Not Obey Weight Map Problem occured when having more than one weight map available. --- source/blender/blenkernel/intern/cloth.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 4241756a109..da162ab37d0 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -773,11 +773,13 @@ static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm ) else verts->goal= 0.0f; + /* Reset vertex flags */ + verts->flags &= ~CLOTH_VERT_FLAG_PINNED; + verts->flags &= ~CLOTH_VERT_FLAG_NOSELFCOLL; + dvert = dm->getVertData ( dm, i, CD_MDEFORMVERT ); if ( dvert ) { - for ( j = 0; j < dvert->totweight; j++ ) { - verts->flags &= ~CLOTH_VERT_FLAG_PINNED; if (( dvert->dw[j].def_nr == (clmd->sim_parms->vgroup_mass-1)) && (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL )) { verts->goal = dvert->dw [j].weight; @@ -789,7 +791,7 @@ static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm ) */ verts->goal = powf(verts->goal, 4.0f); - if ( verts->goal >=SOFTGOALSNAP ) + if ( verts->goal >= SOFTGOALSNAP ) verts->flags |= CLOTH_VERT_FLAG_PINNED; } @@ -804,7 +806,6 @@ static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm ) } } - verts->flags &= ~CLOTH_VERT_FLAG_NOSELFCOLL; if (clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_SELF ) { if ( dvert->dw[j].def_nr == (clmd->coll_parms->vgroup_selfcol-1)) { if (dvert->dw [j].weight > 0.0f) { From a580c891a7911c46a8d57703858904ca25f29c1a Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Tue, 9 Oct 2012 13:09:03 +0000 Subject: [PATCH 144/347] Bugfix [#32703] elbeem's isSimworldOk() will never return FALSE Fixed as suggested by Campbell, thank you! --- intern/elbeem/intern/utilities.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/intern/elbeem/intern/utilities.cpp b/intern/elbeem/intern/utilities.cpp index c912e70b281..2b9b8d5b8a5 100644 --- a/intern/elbeem/intern/utilities.cpp +++ b/intern/elbeem/intern/utilities.cpp @@ -51,7 +51,7 @@ int getElbeemState(void) { return gElbeemState; } int isSimworldOk(void) { - return (getElbeemState>=0); + return (getElbeemState() >=0); } // last error as string, acces with get/setElbeemErrorString From 97d4fb4161bc82888fc1052e53882ccaae6be1f4 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 9 Oct 2012 13:36:42 +0000 Subject: [PATCH 145/347] code cleanup: make header defines more consistent, JOYSENSOR header guard had a typo too. --- source/blender/blenkernel/BKE_key.h | 2 +- source/blender/blenkernel/BKE_multires.h | 3 +-- .../blenkernel/BKE_navmesh_conversion.h | 2 +- source/blender/blenkernel/BKE_utildefines.h | 2 +- source/blender/blenkernel/nla_private.h | 2 +- source/blender/blenlib/BLI_bpath.h | 2 +- source/blender/blenlib/BLI_dlrbTree.h | 2 +- source/blender/blenlib/BLI_kdopbvh.h | 3 +-- source/blender/blenlib/BLI_utildefines.h | 2 +- source/blender/compositor/intern/COM_Node.h | 6 +++--- .../blender/compositor/intern/COM_NodeBase.h | 6 +++--- .../compositor/nodes/COM_ChannelMatteNode.h | 2 +- .../compositor/nodes/COM_ChromaMatteNode.h | 2 +- .../compositor/nodes/COM_ColorBalanceNode.h | 2 +- .../compositor/nodes/COM_ColorMatteNode.h | 2 +- .../compositor/nodes/COM_ColorRampNode.h | 2 +- .../compositor/nodes/COM_ColorSpillNode.h | 2 +- .../nodes/COM_DifferenceMatteNode.h | 2 +- .../compositor/nodes/COM_DistanceMatteNode.h | 2 +- .../blender/compositor/nodes/COM_FilterNode.h | 6 +++--- .../compositor/nodes/COM_LuminanceMatteNode.h | 6 +++--- .../compositor/nodes/COM_MapValueNode.h | 6 +++--- .../blender/compositor/nodes/COM_MaskNode.h | 6 +++--- .../compositor/nodes/COM_MovieClipNode.h | 6 +++--- .../blender/compositor/nodes/COM_NormalNode.h | 2 +- .../compositor/nodes/COM_TransformNode.h | 6 +++--- .../blender/editors/animation/anim_intern.h | 2 +- .../editors/include/ED_keyframes_draw.h | 1 - source/blender/editors/mesh/mesh_intern.h | 3 +-- source/blender/ikplugin/BIK_api.h | 3 +-- source/blender/ikplugin/intern/ikplugin_api.h | 3 +-- .../blender/ikplugin/intern/iksolver_plugin.h | 3 +-- source/blender/ikplugin/intern/itasc_plugin.h | 3 +-- source/blender/imbuf/IMB_imbuf_types.h | 4 ++-- source/blender/imbuf/intern/dds/BlockDXT.h | 2 +- source/blender/imbuf/intern/dds/Color.h | 2 +- source/blender/imbuf/intern/dds/ColorBlock.h | 2 +- .../imbuf/intern/dds/DirectDrawSurface.h | 2 +- source/blender/imbuf/intern/dds/Image.h | 2 +- source/blender/imbuf/intern/dds/PixelFormat.h | 2 +- source/blender/imbuf/intern/dds/Stream.h | 3 +-- source/blender/makesdna/DNA_mask_types.h | 2 +- source/blender/modifiers/MOD_modifiertypes.h | 2 +- .../modifiers/intern/MOD_boolean_util.h | 2 +- source/blender/python/generic/py_capi_utils.h | 2 +- source/blender/python/intern/bpy_app.h | 2 +- source/blender/python/intern/bpy_app_ffmpeg.h | 2 +- .../blender/python/intern/bpy_app_handlers.h | 2 +- source/blender/python/intern/bpy_driver.h | 2 +- source/blender/python/intern/bpy_traceback.h | 2 +- .../python/mathutils/mathutils_noise.h | 2 +- source/blender/quicktime/quicktime_export.h | 4 ++-- source/blender/quicktime/quicktime_import.h | 6 +++--- source/blender/render/intern/raytrace/svbvh.h | 10 ++++----- .../BlenderRoutines/KX_BlenderCanvas.h | 3 +-- .../gameengine/BlenderRoutines/KX_BlenderGL.h | 7 +++---- .../BlenderRoutines/KX_BlenderInputDevice.h | 2 +- .../KX_BlenderKeyboardDevice.h | 3 +-- .../BlenderRoutines/KX_BlenderMouseDevice.h | 3 +-- .../BlenderRoutines/KX_BlenderRenderTools.h | 5 +---- .../BlenderRoutines/KX_BlenderSystem.h | 3 +-- .../gameengine/Converter/BL_ActionActuator.h | 2 +- .../Converter/BL_ArmatureActuator.h | 6 ++---- .../gameengine/Converter/BL_ArmatureChannel.h | 6 ++---- .../Converter/BL_ArmatureConstraint.h | 5 ++--- .../gameengine/Converter/BL_ArmatureObject.h | 6 ++---- .../Converter/BL_BlenderDataConversion.h | 3 +-- .../Converter/BL_DeformableGameObject.h | 5 ++--- source/gameengine/Converter/BL_MeshDeformer.h | 2 +- .../Converter/BL_ModifierDeformer.h | 5 ++--- .../Converter/BL_ShapeActionActuator.h | 5 ++--- .../gameengine/Converter/BL_ShapeDeformer.h | 2 +- source/gameengine/Converter/BL_SkinDeformer.h | 2 +- .../gameengine/Converter/BlenderWorldInfo.h | 3 +-- .../Converter/KX_BlenderScalarInterpolator.h | 3 +-- .../Converter/KX_BlenderSceneConverter.h | 3 +-- .../Converter/KX_ConvertActuators.h | 4 +--- .../Converter/KX_ConvertControllers.h | 4 +--- .../Converter/KX_ConvertProperties.h | 3 +-- .../gameengine/Converter/KX_ConvertSensors.h | 3 +-- source/gameengine/Converter/KX_IpoConvert.h | 3 +-- .../Converter/KX_SoftBodyDeformer.h | 2 +- source/gameengine/Expressions/BoolValue.h | 3 +-- source/gameengine/Expressions/ConstExpr.h | 3 +-- source/gameengine/Expressions/EXP_C-Api.h | 3 +-- source/gameengine/Expressions/EmptyValue.h | 3 +-- source/gameengine/Expressions/ErrorValue.h | 3 +-- source/gameengine/Expressions/Expression.h | 3 +-- source/gameengine/Expressions/FloatValue.h | 3 +-- .../gameengine/Expressions/IdentifierExpr.h | 3 +-- source/gameengine/Expressions/IfExpr.h | 11 +++------- source/gameengine/Expressions/IntValue.h | 3 +-- source/gameengine/Expressions/KX_HashedPtr.h | 3 +-- source/gameengine/Expressions/KX_Python.h | 3 +-- source/gameengine/Expressions/ListValue.h | 2 +- source/gameengine/Expressions/Operator1Expr.h | 7 +++---- source/gameengine/Expressions/Operator2Expr.h | 2 +- source/gameengine/Expressions/PyObjectPlus.h | 4 ++-- source/gameengine/Expressions/StringValue.h | 5 ++--- source/gameengine/Expressions/Value.h | 21 ++++++------------- source/gameengine/Expressions/VectorValue.h | 3 +-- source/gameengine/Expressions/VoidValue.h | 1 - .../gameengine/GameLogic/SCA_ANDController.h | 3 +-- .../GameLogic/SCA_ActuatorEventManager.h | 3 +-- .../gameengine/GameLogic/SCA_ActuatorSensor.h | 4 ++-- .../GameLogic/SCA_AlwaysEventManager.h | 3 +-- .../gameengine/GameLogic/SCA_AlwaysSensor.h | 3 +-- .../GameLogic/SCA_BasicEventManager.h | 3 +-- source/gameengine/GameLogic/SCA_DelaySensor.h | 3 +-- .../GameLogic/SCA_ExpressionController.h | 3 +-- source/gameengine/GameLogic/SCA_IActuator.h | 3 +-- source/gameengine/GameLogic/SCA_IController.h | 5 ++--- .../gameengine/GameLogic/SCA_IInputDevice.h | 2 +- source/gameengine/GameLogic/SCA_ILogicBrick.h | 5 ++--- source/gameengine/GameLogic/SCA_IObject.h | 3 +-- source/gameengine/GameLogic/SCA_IScene.h | 3 +-- source/gameengine/GameLogic/SCA_ISensor.h | 5 ++--- .../gameengine/GameLogic/SCA_JoystickSensor.h | 10 ++++----- .../GameLogic/SCA_KeyboardManager.h | 3 +-- .../gameengine/GameLogic/SCA_KeyboardSensor.h | 5 +---- .../gameengine/GameLogic/SCA_LogicManager.h | 3 +-- .../gameengine/GameLogic/SCA_MouseManager.h | 3 +-- source/gameengine/GameLogic/SCA_MouseSensor.h | 3 +-- .../gameengine/GameLogic/SCA_NANDController.h | 3 +-- .../gameengine/GameLogic/SCA_NORController.h | 3 +-- .../gameengine/GameLogic/SCA_ORController.h | 3 +-- .../GameLogic/SCA_PropertyActuator.h | 3 +-- .../GameLogic/SCA_PropertyEventManager.h | 3 +-- .../GameLogic/SCA_PythonController.h | 3 +-- .../gameengine/GameLogic/SCA_PythonKeyboard.h | 3 +-- source/gameengine/GameLogic/SCA_PythonMouse.h | 3 +-- .../gameengine/GameLogic/SCA_RandomActuator.h | 2 +- .../GameLogic/SCA_RandomEventManager.h | 3 +-- .../gameengine/GameLogic/SCA_RandomSensor.h | 3 +-- .../GameLogic/SCA_TimeEventManager.h | 3 +-- .../gameengine/GameLogic/SCA_XNORController.h | 3 +-- .../gameengine/GameLogic/SCA_XORController.h | 3 +-- .../gameengine/GamePlayer/common/GPC_Canvas.h | 5 ++--- .../gameengine/GamePlayer/common/GPC_Engine.h | 3 +-- .../GamePlayer/common/GPC_KeyboardDevice.h | 5 ++--- .../GamePlayer/common/GPC_MouseDevice.h | 5 ++--- .../GamePlayer/common/GPC_RawImage.h | 3 +-- .../common/GPC_RawLoadDotBlendArray.h | 3 +-- .../GamePlayer/common/GPC_RawLogoArrays.h | 3 +-- .../GamePlayer/common/GPC_RenderTools.h | 7 ++----- .../gameengine/GamePlayer/common/GPC_System.h | 3 +-- .../gameengine/GamePlayer/ghost/GPG_Canvas.h | 5 ++--- .../GamePlayer/ghost/GPG_KeyboardDevice.h | 5 ++--- .../gameengine/GamePlayer/ghost/GPG_System.h | 5 ++--- source/gameengine/Ketsji/BL_Action.h | 3 +-- source/gameengine/Ketsji/BL_ActionManager.h | 3 +-- source/gameengine/Ketsji/BL_BlenderShader.h | 2 +- source/gameengine/Ketsji/BL_Shader.h | 2 +- source/gameengine/Ketsji/BL_Texture.h | 2 +- .../Ketsji/KXNetwork/KX_NetworkEventManager.h | 3 +-- .../KXNetwork/KX_NetworkMessageActuator.h | 3 +-- .../KXNetwork/KX_NetworkMessageSensor.h | 5 ++--- source/gameengine/Ketsji/KX_ArmatureSensor.h | 2 +- source/gameengine/Ketsji/KX_BlenderMaterial.h | 2 +- .../Ketsji/KX_BulletPhysicsController.h | 3 +-- source/gameengine/Ketsji/KX_Camera.h | 3 +-- source/gameengine/Ketsji/KX_CameraActuator.h | 5 ++--- .../Ketsji/KX_CameraIpoSGController.h | 3 +-- .../gameengine/Ketsji/KX_ClientObjectInfo.h | 3 +-- .../gameengine/Ketsji/KX_ConstraintActuator.h | 3 +-- .../gameengine/Ketsji/KX_ConstraintWrapper.h | 3 +-- .../Ketsji/KX_ConvertPhysicsObject.h | 2 +- source/gameengine/Ketsji/KX_EmptyObject.h | 3 +-- source/gameengine/Ketsji/KX_FontObject.h | 2 +- source/gameengine/Ketsji/KX_GameObject.h | 3 +-- .../gameengine/Ketsji/KX_IPO_SGController.h | 4 +--- .../gameengine/Ketsji/KX_IPhysicsController.h | 3 +-- source/gameengine/Ketsji/KX_ISceneConverter.h | 3 +-- source/gameengine/Ketsji/KX_IpoActuator.h | 3 +-- source/gameengine/Ketsji/KX_KetsjiEngine.h | 4 +--- source/gameengine/Ketsji/KX_Light.h | 3 +-- .../Ketsji/KX_LightIpoSGController.h | 3 +-- .../Ketsji/KX_MaterialIpoController.h | 5 +---- source/gameengine/Ketsji/KX_MeshProxy.h | 5 ++--- source/gameengine/Ketsji/KX_MotionState.h | 3 +-- .../gameengine/Ketsji/KX_MouseFocusSensor.h | 5 ++--- source/gameengine/Ketsji/KX_NavMeshObject.h | 5 ++--- source/gameengine/Ketsji/KX_NearSensor.h | 5 ++--- .../Ketsji/KX_ObColorIpoSGController.h | 3 +-- source/gameengine/Ketsji/KX_ObjectActuator.h | 5 ++--- source/gameengine/Ketsji/KX_ParentActuator.h | 5 ++--- .../gameengine/Ketsji/KX_PhysicsEngineEnums.h | 3 +-- .../Ketsji/KX_PhysicsObjectWrapper.h | 5 ++--- .../Ketsji/KX_PhysicsPropertiesobsolete.h | 3 +-- source/gameengine/Ketsji/KX_PolyProxy.h | 5 ++--- source/gameengine/Ketsji/KX_PolygonMaterial.h | 3 +-- .../Ketsji/KX_PyConstraintBinding.h | 5 ++--- source/gameengine/Ketsji/KX_PyMath.h | 2 +- source/gameengine/Ketsji/KX_PythonInit.h | 3 +-- source/gameengine/Ketsji/KX_PythonSeq.h | 8 +++---- source/gameengine/Ketsji/KX_RadarSensor.h | 3 +-- source/gameengine/Ketsji/KX_RayEventManager.h | 3 +-- source/gameengine/Ketsji/KX_RaySensor.h | 5 ++--- .../Ketsji/KX_SCA_AddObjectActuator.h | 5 ++--- .../Ketsji/KX_SCA_ReplaceMeshActuator.h | 5 ++--- source/gameengine/Ketsji/KX_Scene.h | 3 +-- source/gameengine/Ketsji/KX_SceneActuator.h | 3 +-- source/gameengine/Ketsji/KX_SoundActuator.h | 5 ++--- .../gameengine/Ketsji/KX_SteeringActuator.h | 5 ++--- .../gameengine/Ketsji/KX_TimeCategoryLogger.h | 3 +-- source/gameengine/Ketsji/KX_TimeLogger.h | 3 +-- .../gameengine/Ketsji/KX_TouchEventManager.h | 3 +-- source/gameengine/Ketsji/KX_TouchSensor.h | 3 +-- source/gameengine/Ketsji/KX_TrackToActuator.h | 5 ++--- source/gameengine/Ketsji/KX_VehicleWrapper.h | 4 ++-- source/gameengine/Ketsji/KX_VertexProxy.h | 5 ++--- source/gameengine/Ketsji/KX_WorldInfo.h | 3 +-- .../gameengine/Ketsji/KX_WorldIpoController.h | 3 +-- .../NG_LoopBackNetworkDeviceInterface.h | 3 +-- .../Network/NG_NetworkDeviceInterface.h | 3 +-- source/gameengine/Network/NG_NetworkMessage.h | 3 +-- source/gameengine/Network/NG_NetworkObject.h | 3 +-- source/gameengine/Network/NG_NetworkScene.h | 3 +-- .../Physics/Bullet/CcdGraphicController.h | 2 +- .../Physics/Bullet/CcdPhysicsController.h | 2 +- .../Physics/Bullet/CcdPhysicsEnvironment.h | 4 ++-- .../Physics/Dummy/DummyPhysicsEnvironment.h | 3 +-- .../Physics/common/PHY_DynamicTypes.h | 2 +- .../Physics/common/PHY_IController.h | 3 +-- .../Physics/common/PHY_IGraphicController.h | 3 +-- .../Physics/common/PHY_IMotionState.h | 3 +-- .../Physics/common/PHY_IPhysicsController.h | 3 +-- .../Physics/common/PHY_IPhysicsEnvironment.h | 3 +-- .../gameengine/Physics/common/PHY_IVehicle.h | 2 +- source/gameengine/Physics/common/PHY_Pro.h | 3 +-- .../gameengine/Rasterizer/RAS_BucketManager.h | 3 +-- source/gameengine/Rasterizer/RAS_CameraData.h | 3 +-- source/gameengine/Rasterizer/RAS_Deformer.h | 2 +- source/gameengine/Rasterizer/RAS_ICanvas.h | 3 +-- .../Rasterizer/RAS_IPolygonMaterial.h | 3 +-- .../gameengine/Rasterizer/RAS_IRasterizer.h | 4 +--- .../gameengine/Rasterizer/RAS_IRenderTools.h | 5 +---- .../gameengine/Rasterizer/RAS_LightObject.h | 3 +-- .../Rasterizer/RAS_MaterialBucket.h | 2 +- source/gameengine/Rasterizer/RAS_MeshObject.h | 3 +-- .../gameengine/Rasterizer/RAS_ObjectColor.h | 3 +-- .../RAS_OpenGLRasterizer.h | 4 +--- .../RAS_VAOpenGLRasterizer.h | 3 +-- source/gameengine/Rasterizer/RAS_Rect.h | 3 +-- source/gameengine/Rasterizer/RAS_TexMatrix.h | 3 +-- source/gameengine/Rasterizer/RAS_TexVert.h | 3 +-- source/gameengine/SceneGraph/SG_Controller.h | 3 +-- source/gameengine/SceneGraph/SG_DList.h | 3 +-- source/gameengine/SceneGraph/SG_IObject.h | 3 +-- source/gameengine/SceneGraph/SG_Node.h | 3 +-- source/gameengine/SceneGraph/SG_QList.h | 3 +-- source/gameengine/SceneGraph/SG_Spatial.h | 3 +-- source/gameengine/VideoTexture/VideoFFmpeg.h | 4 ++-- 253 files changed, 333 insertions(+), 543 deletions(-) diff --git a/source/blender/blenkernel/BKE_key.h b/source/blender/blenkernel/BKE_key.h index 01baf8feb2a..d7d75b4c4c9 100644 --- a/source/blender/blenkernel/BKE_key.h +++ b/source/blender/blenkernel/BKE_key.h @@ -92,4 +92,4 @@ extern int slurph_opt; }; #endif -#endif // __BKE_KEY_H__ +#endif /* __BKE_KEY_H__ */ diff --git a/source/blender/blenkernel/BKE_multires.h b/source/blender/blenkernel/BKE_multires.h index 82a791348dd..8fa20eb2cc2 100644 --- a/source/blender/blenkernel/BKE_multires.h +++ b/source/blender/blenkernel/BKE_multires.h @@ -116,5 +116,4 @@ void multires_topology_changed(struct Mesh *me); void old_mdisps_bilinear(float out[3], float (*disps)[3], const int st, float u, float v); int mdisp_rot_face_to_crn(const int corners, const int face_side, const float u, const float v, float *x, float *y); -#endif // __BKE_MULTIRES_H__ - +#endif /* __BKE_MULTIRES_H__ */ diff --git a/source/blender/blenkernel/BKE_navmesh_conversion.h b/source/blender/blenkernel/BKE_navmesh_conversion.h index aab359b307a..cc9c18c764d 100644 --- a/source/blender/blenkernel/BKE_navmesh_conversion.h +++ b/source/blender/blenkernel/BKE_navmesh_conversion.h @@ -60,4 +60,4 @@ int polyFindVertex(const unsigned short *p, const int vertsPerPoly, unsigned sho float distPointToSegmentSq(const float *point, const float *a, const float *b); -#endif //NAVMESH_CONVERSION_H +#endif /* NAVMESH_CONVERSION_H */ diff --git a/source/blender/blenkernel/BKE_utildefines.h b/source/blender/blenkernel/BKE_utildefines.h index 63f5ec59a0b..06f8b89ec05 100644 --- a/source/blender/blenkernel/BKE_utildefines.h +++ b/source/blender/blenkernel/BKE_utildefines.h @@ -38,4 +38,4 @@ extern "C" { } #endif -#endif // __BKE_UTILDEFINES_H__ +#endif /* __BKE_UTILDEFINES_H__ */ diff --git a/source/blender/blenkernel/nla_private.h b/source/blender/blenkernel/nla_private.h index 941a74ec2ab..f068c4c58f0 100644 --- a/source/blender/blenkernel/nla_private.h +++ b/source/blender/blenkernel/nla_private.h @@ -85,4 +85,4 @@ NlaEvalStrip *nlastrips_ctime_get_strip(ListBase *list, ListBase *strips, short void nlastrip_evaluate(PointerRNA *ptr, ListBase *channels, ListBase *modifiers, NlaEvalStrip *nes); void nladata_flush_channels(ListBase *channels); -#endif // __NLA_PRIVATE_H__ +#endif /* __NLA_PRIVATE_H__ */ diff --git a/source/blender/blenlib/BLI_bpath.h b/source/blender/blenlib/BLI_bpath.h index 52b839d11a9..a86b362c271 100644 --- a/source/blender/blenlib/BLI_bpath.h +++ b/source/blender/blenlib/BLI_bpath.h @@ -64,4 +64,4 @@ void BLI_bpath_missing_files_find(struct Main *bmain, const char *searchpath, st void BLI_bpath_relative_convert(struct Main *bmain, const char *basedir, struct ReportList *reports); void BLI_bpath_absolute_convert(struct Main *bmain, const char *basedir, struct ReportList *reports); -#endif // __BLI_BPATH_H__ +#endif /* __BLI_BPATH_H__ */ diff --git a/source/blender/blenlib/BLI_dlrbTree.h b/source/blender/blenlib/BLI_dlrbTree.h index 92356b24403..d04e544376a 100644 --- a/source/blender/blenlib/BLI_dlrbTree.h +++ b/source/blender/blenlib/BLI_dlrbTree.h @@ -158,4 +158,4 @@ void BLI_dlrbTree_insert(DLRBT_Tree *tree, DLRBT_Node *node); /* ********************************************** */ -#endif // __BLI_DLRBTREE_H__ +#endif /* __BLI_DLRBTREE_H__ */ diff --git a/source/blender/blenlib/BLI_kdopbvh.h b/source/blender/blenlib/BLI_kdopbvh.h index 985b5af3b94..c75334a2924 100644 --- a/source/blender/blenlib/BLI_kdopbvh.h +++ b/source/blender/blenlib/BLI_kdopbvh.h @@ -113,5 +113,4 @@ int BLI_bvhtree_range_query(BVHTree *tree, const float co[3], float radius, BVHT } #endif -#endif // __BLI_KDOPBVH_H__ - +#endif /* __BLI_KDOPBVH_H__ */ diff --git a/source/blender/blenlib/BLI_utildefines.h b/source/blender/blenlib/BLI_utildefines.h index 5321de4393b..beb554042ea 100644 --- a/source/blender/blenlib/BLI_utildefines.h +++ b/source/blender/blenlib/BLI_utildefines.h @@ -330,4 +330,4 @@ # define UNLIKELY(x) (x) #endif -#endif // __BLI_UTILDEFINES_H__ +#endif /* __BLI_UTILDEFINES_H__ */ diff --git a/source/blender/compositor/intern/COM_Node.h b/source/blender/compositor/intern/COM_Node.h index e8fd936e749..468a95ed434 100644 --- a/source/blender/compositor/intern/COM_Node.h +++ b/source/blender/compositor/intern/COM_Node.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_Node_h -#define _COM_Node_h +#ifndef __COM_NODE_H__ +#define __COM_NODE_H__ #include "COM_NodeBase.h" #include "COM_InputSocket.h" @@ -152,4 +152,4 @@ protected: private: }; -#endif +#endif /* __COM_NODE_H__ */ diff --git a/source/blender/compositor/intern/COM_NodeBase.h b/source/blender/compositor/intern/COM_NodeBase.h index 64d669b5e9a..e386b5e08a0 100644 --- a/source/blender/compositor/intern/COM_NodeBase.h +++ b/source/blender/compositor/intern/COM_NodeBase.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_NodeBase_h -#define _COM_NodeBase_h +#ifndef __COM_NODEBASE_H__ +#define __COM_NODEBASE_H__ #include "COM_InputSocket.h" #include "COM_OutputSocket.h" @@ -166,4 +166,4 @@ protected: #endif }; -#endif +#endif /* __COM_NODEBASE_H__ */ diff --git a/source/blender/compositor/nodes/COM_ChannelMatteNode.h b/source/blender/compositor/nodes/COM_ChannelMatteNode.h index 4efb06c9f87..29c6000a245 100644 --- a/source/blender/compositor/nodes/COM_ChannelMatteNode.h +++ b/source/blender/compositor/nodes/COM_ChannelMatteNode.h @@ -34,4 +34,4 @@ public: void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; -#endif // COM_ChannelMatteNODE_H +#endif /* COM_ChannelMatteNODE_H */ diff --git a/source/blender/compositor/nodes/COM_ChromaMatteNode.h b/source/blender/compositor/nodes/COM_ChromaMatteNode.h index ddd350aab40..bf5302ccdbb 100644 --- a/source/blender/compositor/nodes/COM_ChromaMatteNode.h +++ b/source/blender/compositor/nodes/COM_ChromaMatteNode.h @@ -34,4 +34,4 @@ public: void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; -#endif // COM_ChromaMatteNODE_H +#endif /* COM_ChromaMatteNODE_H */ diff --git a/source/blender/compositor/nodes/COM_ColorBalanceNode.h b/source/blender/compositor/nodes/COM_ColorBalanceNode.h index cdad02fc831..30d22ef2e63 100644 --- a/source/blender/compositor/nodes/COM_ColorBalanceNode.h +++ b/source/blender/compositor/nodes/COM_ColorBalanceNode.h @@ -35,4 +35,4 @@ public: void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; -#endif // COM_ColorBalanceNODE_H +#endif /* COM_ColorBalanceNODE_H */ diff --git a/source/blender/compositor/nodes/COM_ColorMatteNode.h b/source/blender/compositor/nodes/COM_ColorMatteNode.h index 92a4fa79408..3386476bc85 100644 --- a/source/blender/compositor/nodes/COM_ColorMatteNode.h +++ b/source/blender/compositor/nodes/COM_ColorMatteNode.h @@ -34,4 +34,4 @@ public: void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; -#endif // COM_ColorMatteNODE_H +#endif /* COM_ColorMatteNODE_H */ diff --git a/source/blender/compositor/nodes/COM_ColorRampNode.h b/source/blender/compositor/nodes/COM_ColorRampNode.h index 6c256c09e68..3f00e1c2190 100644 --- a/source/blender/compositor/nodes/COM_ColorRampNode.h +++ b/source/blender/compositor/nodes/COM_ColorRampNode.h @@ -35,4 +35,4 @@ public: void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; -#endif // COM_ColorRampNODE_H +#endif /* COM_ColorRampNODE_H */ diff --git a/source/blender/compositor/nodes/COM_ColorSpillNode.h b/source/blender/compositor/nodes/COM_ColorSpillNode.h index 1d976fc65ae..01722fac826 100644 --- a/source/blender/compositor/nodes/COM_ColorSpillNode.h +++ b/source/blender/compositor/nodes/COM_ColorSpillNode.h @@ -35,4 +35,4 @@ public: void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; -#endif // COM_ColorSpillNODE_H +#endif /* COM_ColorSpillNODE_H */ diff --git a/source/blender/compositor/nodes/COM_DifferenceMatteNode.h b/source/blender/compositor/nodes/COM_DifferenceMatteNode.h index 191b7361c3c..0b571889571 100644 --- a/source/blender/compositor/nodes/COM_DifferenceMatteNode.h +++ b/source/blender/compositor/nodes/COM_DifferenceMatteNode.h @@ -35,4 +35,4 @@ public: void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; -#endif // COM_DifferenceMatteNODE_H +#endif /* COM_DifferenceMatteNODE_H */ diff --git a/source/blender/compositor/nodes/COM_DistanceMatteNode.h b/source/blender/compositor/nodes/COM_DistanceMatteNode.h index 4e6682424e8..46ceae7c4f4 100644 --- a/source/blender/compositor/nodes/COM_DistanceMatteNode.h +++ b/source/blender/compositor/nodes/COM_DistanceMatteNode.h @@ -34,4 +34,4 @@ public: void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; -#endif // COM_DistanceMatteNODE_H +#endif /* COM_DistanceMatteNODE_H */ diff --git a/source/blender/compositor/nodes/COM_FilterNode.h b/source/blender/compositor/nodes/COM_FilterNode.h index d65166944d8..9be3bb02494 100644 --- a/source/blender/compositor/nodes/COM_FilterNode.h +++ b/source/blender/compositor/nodes/COM_FilterNode.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_FilterNode_h_ -#define _COM_FilterNode_h_ +#ifndef __COM_FILTERNODE_H__ +#define __COM_FILTERNODE_H__ #include "COM_Node.h" @@ -35,4 +35,4 @@ public: void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; -#endif // _COM_FilterNode_h_ +#endif /* __COM_FILTERNODE_H__ */ diff --git a/source/blender/compositor/nodes/COM_LuminanceMatteNode.h b/source/blender/compositor/nodes/COM_LuminanceMatteNode.h index 37f3c31113f..a71e68cf636 100644 --- a/source/blender/compositor/nodes/COM_LuminanceMatteNode.h +++ b/source/blender/compositor/nodes/COM_LuminanceMatteNode.h @@ -19,8 +19,8 @@ * Dalai Felinto */ -#ifndef _COM_LuminanceMatteNode_h_ -#define _COM_LuminanceMatteNode_h_ +#ifndef __COM_LUMINANCEMATTENODE_H__ +#define __COM_LUMINANCEMATTENODE_H__ #include "COM_Node.h" @@ -34,4 +34,4 @@ public: void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; -#endif // _COM_LuminanceMatteNode_h_ +#endif /* __COM_LUMINANCEMATTENODE_H__ */ diff --git a/source/blender/compositor/nodes/COM_MapValueNode.h b/source/blender/compositor/nodes/COM_MapValueNode.h index 22aa5459ec0..bd8e3d08e9c 100644 --- a/source/blender/compositor/nodes/COM_MapValueNode.h +++ b/source/blender/compositor/nodes/COM_MapValueNode.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_MapValueNode_h_ -#define _COM_MapValueNode_h_ +#ifndef __COM_MAPVALUENODE_H__ +#define __COM_MAPVALUENODE_H__ #include "COM_Node.h" #include "DNA_node_types.h" @@ -35,4 +35,4 @@ public: void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; -#endif // _COM_MapValueNode_h_ +#endif /* __COM_MAPVALUENODE_H__ */ diff --git a/source/blender/compositor/nodes/COM_MaskNode.h b/source/blender/compositor/nodes/COM_MaskNode.h index cdd5d3c362e..9ef3e5deb50 100644 --- a/source/blender/compositor/nodes/COM_MaskNode.h +++ b/source/blender/compositor/nodes/COM_MaskNode.h @@ -21,8 +21,8 @@ * Sergey Sharybin */ -#ifndef _COM_MaskNode_h_ -#define _COM_MaskNode_h_ +#ifndef __COM_MASKNODE_H__ +#define __COM_MASKNODE_H__ #include "COM_Node.h" #include "DNA_node_types.h" @@ -38,4 +38,4 @@ public: }; -#endif // _COM_MaskNode_h_ +#endif /* __COM_MASKNODE_H__ */ diff --git a/source/blender/compositor/nodes/COM_MovieClipNode.h b/source/blender/compositor/nodes/COM_MovieClipNode.h index 52ea11ea8e9..2fb38860a34 100644 --- a/source/blender/compositor/nodes/COM_MovieClipNode.h +++ b/source/blender/compositor/nodes/COM_MovieClipNode.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_MovieClipNode_h_ -#define _COM_MovieClipNode_h_ +#ifndef __COM_MOVIECLIPNODE_H__ +#define __COM_MOVIECLIPNODE_H__ #include "COM_Node.h" #include "DNA_node_types.h" @@ -36,4 +36,4 @@ public: void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; -#endif // _COM_MovieClipNode_h_ +#endif /* __COM_MOVIECLIPNODE_H__ */ diff --git a/source/blender/compositor/nodes/COM_NormalNode.h b/source/blender/compositor/nodes/COM_NormalNode.h index 660d90040bd..64d4e3a3656 100644 --- a/source/blender/compositor/nodes/COM_NormalNode.h +++ b/source/blender/compositor/nodes/COM_NormalNode.h @@ -35,4 +35,4 @@ public: void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; -#endif // COM_NormalNODE_H +#endif /* COM_NormalNODE_H */ diff --git a/source/blender/compositor/nodes/COM_TransformNode.h b/source/blender/compositor/nodes/COM_TransformNode.h index 57a7a0229ec..666f2da775e 100644 --- a/source/blender/compositor/nodes/COM_TransformNode.h +++ b/source/blender/compositor/nodes/COM_TransformNode.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_TransformNode_h_ -#define _COM_TransformNode_h_ +#ifndef __COM_TRANSFORMNODE_H__ +#define __COM_TRANSFORMNODE_H__ #include "COM_Node.h" #include "DNA_node_types.h" @@ -36,4 +36,4 @@ public: void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; -#endif // _COM_TransformNode_h_ +#endif /* __COM_TRANSFORMNODE_H__ */ diff --git a/source/blender/editors/animation/anim_intern.h b/source/blender/editors/animation/anim_intern.h index bc07bf091de..54c7f7ea30f 100644 --- a/source/blender/editors/animation/anim_intern.h +++ b/source/blender/editors/animation/anim_intern.h @@ -82,4 +82,4 @@ void ANIM_OT_driver_button_remove(struct wmOperatorType *ot); void ANIM_OT_copy_driver_button(struct wmOperatorType *ot); void ANIM_OT_paste_driver_button(struct wmOperatorType *ot); -#endif // __ANIM_INTERN_H__ +#endif /* __ANIM_INTERN_H__ */ diff --git a/source/blender/editors/include/ED_keyframes_draw.h b/source/blender/editors/include/ED_keyframes_draw.h index 8a65699f404..ffee46e30c6 100644 --- a/source/blender/editors/include/ED_keyframes_draw.h +++ b/source/blender/editors/include/ED_keyframes_draw.h @@ -157,4 +157,3 @@ short compare_ab_cfraPtr(void *node, void *data); short actkeyblock_is_valid(ActKeyBlock *ab, struct DLRBT_Tree *keys); #endif /* __ED_KEYFRAMES_DRAW_H__ */ - diff --git a/source/blender/editors/mesh/mesh_intern.h b/source/blender/editors/mesh/mesh_intern.h index de594b87e2c..2676316c66d 100644 --- a/source/blender/editors/mesh/mesh_intern.h +++ b/source/blender/editors/mesh/mesh_intern.h @@ -221,5 +221,4 @@ void MESH_OT_navmesh_face_add(struct wmOperatorType *ot); void MESH_OT_navmesh_reset(struct wmOperatorType *ot); void MESH_OT_navmesh_clear(struct wmOperatorType *ot); -#endif // __MESH_INTERN_H__ - +#endif /* __MESH_INTERN_H__ */ diff --git a/source/blender/ikplugin/BIK_api.h b/source/blender/ikplugin/BIK_api.h index e1d5f50edfb..4fc273bd435 100644 --- a/source/blender/ikplugin/BIK_api.h +++ b/source/blender/ikplugin/BIK_api.h @@ -92,5 +92,4 @@ void BIK_test_constraint(struct Object *ob, struct bConstraint *cons); } #endif -#endif // __BIK_API_H__ - +#endif /* __BIK_API_H__ */ diff --git a/source/blender/ikplugin/intern/ikplugin_api.h b/source/blender/ikplugin/intern/ikplugin_api.h index 77c962269dc..53d9da8e614 100644 --- a/source/blender/ikplugin/intern/ikplugin_api.h +++ b/source/blender/ikplugin/intern/ikplugin_api.h @@ -60,5 +60,4 @@ typedef struct IKPlugin IKPlugin; } #endif -#endif // __IKPLUGIN_API_H__ - +#endif /* __IKPLUGIN_API_H__ */ diff --git a/source/blender/ikplugin/intern/iksolver_plugin.h b/source/blender/ikplugin/intern/iksolver_plugin.h index dd00c5f4add..c2ae4f937e7 100644 --- a/source/blender/ikplugin/intern/iksolver_plugin.h +++ b/source/blender/ikplugin/intern/iksolver_plugin.h @@ -47,5 +47,4 @@ void iksolver_execute_tree(struct Scene *scene, struct Object *ob, struct bPose } #endif -#endif // __IKSOLVER_PLUGIN_H__ - +#endif /* __IKSOLVER_PLUGIN_H__ */ diff --git a/source/blender/ikplugin/intern/itasc_plugin.h b/source/blender/ikplugin/intern/itasc_plugin.h index 0d5fde0bec0..0500125b4c7 100644 --- a/source/blender/ikplugin/intern/itasc_plugin.h +++ b/source/blender/ikplugin/intern/itasc_plugin.h @@ -52,5 +52,4 @@ void itasc_test_constraint(struct Object *ob, struct bConstraint *cons); } #endif -#endif // __ITASC_PLUGIN_H__ - +#endif /* __ITASC_PLUGIN_H__ */ diff --git a/source/blender/imbuf/IMB_imbuf_types.h b/source/blender/imbuf/IMB_imbuf_types.h index f03f709f13f..76c247b2195 100644 --- a/source/blender/imbuf/IMB_imbuf_types.h +++ b/source/blender/imbuf/IMB_imbuf_types.h @@ -242,7 +242,7 @@ typedef struct ImBuf { ((unsigned long)(unsigned char)(ch1) << 8) | \ ((unsigned long)(unsigned char)(ch2) << 16) | \ ((unsigned long)(unsigned char)(ch3) << 24)) -#endif //MAKEFOURCC +#endif /* MAKEFOURCC */ /* * FOURCC codes for DX compressed-texture pixel formats @@ -255,7 +255,7 @@ typedef struct ImBuf { #define FOURCC_DXT4 (MAKEFOURCC('D','X','T','4')) #define FOURCC_DXT5 (MAKEFOURCC('D','X','T','5')) -#endif // DDS +#endif /* DDS */ extern const char *imb_ext_image[]; extern const char *imb_ext_image_qt[]; extern const char *imb_ext_movie[]; diff --git a/source/blender/imbuf/intern/dds/BlockDXT.h b/source/blender/imbuf/intern/dds/BlockDXT.h index c6712f4f058..9b90b744b67 100644 --- a/source/blender/imbuf/intern/dds/BlockDXT.h +++ b/source/blender/imbuf/intern/dds/BlockDXT.h @@ -271,4 +271,4 @@ void mem_read(Stream & mem, BlockATI1 & block); void mem_read(Stream & mem, BlockATI2 & block); void mem_read(Stream & mem, BlockCTX1 & block); -#endif // __BLOCKDXT_H__ +#endif /* __BLOCKDXT_H__ */ diff --git a/source/blender/imbuf/intern/dds/Color.h b/source/blender/imbuf/intern/dds/Color.h index 17de0a596c6..6676057d710 100644 --- a/source/blender/imbuf/intern/dds/Color.h +++ b/source/blender/imbuf/intern/dds/Color.h @@ -96,4 +96,4 @@ public: }; }; -#endif // __COLOR_H__ +#endif /* __COLOR_H__ */ diff --git a/source/blender/imbuf/intern/dds/ColorBlock.h b/source/blender/imbuf/intern/dds/ColorBlock.h index 2bf362f2780..f0864f06e6f 100644 --- a/source/blender/imbuf/intern/dds/ColorBlock.h +++ b/source/blender/imbuf/intern/dds/ColorBlock.h @@ -104,4 +104,4 @@ inline Color32 & ColorBlock::color(uint x, uint y) return m_color[y * 4 + x]; } -#endif // __COLORBLOCK_H__ +#endif /* __COLORBLOCK_H__ */ diff --git a/source/blender/imbuf/intern/dds/DirectDrawSurface.h b/source/blender/imbuf/intern/dds/DirectDrawSurface.h index a851533b1f3..ccac1c08b41 100644 --- a/source/blender/imbuf/intern/dds/DirectDrawSurface.h +++ b/source/blender/imbuf/intern/dds/DirectDrawSurface.h @@ -200,4 +200,4 @@ void mem_read(Stream & mem, DDSCaps & caps); void mem_read(Stream & mem, DDSHeader & header); void mem_read(Stream & mem, DDSHeader10 & header); -#endif // __DIRECTDRAWSURFACE_H__ +#endif /* __DIRECTDRAWSURFACE_H__ */ diff --git a/source/blender/imbuf/intern/dds/Image.h b/source/blender/imbuf/intern/dds/Image.h index 5dcf3011c76..81074fba6b7 100644 --- a/source/blender/imbuf/intern/dds/Image.h +++ b/source/blender/imbuf/intern/dds/Image.h @@ -101,4 +101,4 @@ inline Color32 & Image::pixel(uint x, uint y) return pixel(y * width() + x); } -#endif // __IMAGE_H__ +#endif /* __IMAGE_H__ */ diff --git a/source/blender/imbuf/intern/dds/PixelFormat.h b/source/blender/imbuf/intern/dds/PixelFormat.h index 308ea810f03..ce36fb00b97 100644 --- a/source/blender/imbuf/intern/dds/PixelFormat.h +++ b/source/blender/imbuf/intern/dds/PixelFormat.h @@ -135,4 +135,4 @@ } // PixelFormat namespace -#endif // _DDS_IMAGE_PIXELFORMAT_H +#endif /* __PIXELFORMAT_H__ */ diff --git a/source/blender/imbuf/intern/dds/Stream.h b/source/blender/imbuf/intern/dds/Stream.h index 9f513ca8aba..7fed4ca89e7 100644 --- a/source/blender/imbuf/intern/dds/Stream.h +++ b/source/blender/imbuf/intern/dds/Stream.h @@ -45,5 +45,4 @@ unsigned int mem_read(Stream & mem, unsigned short & i); unsigned int mem_read(Stream & mem, unsigned char & i); unsigned int mem_read(Stream & mem, unsigned char *i, unsigned int cnt); -#endif // __STREAM_H__ - +#endif /* __STREAM_H__ */ diff --git a/source/blender/makesdna/DNA_mask_types.h b/source/blender/makesdna/DNA_mask_types.h index bf388d8c018..5b25d1a072c 100644 --- a/source/blender/makesdna/DNA_mask_types.h +++ b/source/blender/makesdna/DNA_mask_types.h @@ -211,4 +211,4 @@ enum { MASK_ANIMF_EXPAND = (1 << 4) }; -#endif // __DNA_MASK_TYPES_H__ +#endif /* __DNA_MASK_TYPES_H__ */ diff --git a/source/blender/modifiers/MOD_modifiertypes.h b/source/blender/modifiers/MOD_modifiertypes.h index bf411c3b2fc..51e574e276d 100644 --- a/source/blender/modifiers/MOD_modifiertypes.h +++ b/source/blender/modifiers/MOD_modifiertypes.h @@ -79,4 +79,4 @@ extern ModifierTypeInfo modifierType_Skin; /* MOD_util.c */ void modifier_type_init(ModifierTypeInfo *types[]); -#endif //__MOD_MODIFIERTYPES_H__ +#endif /* __MOD_MODIFIERTYPES_H__ */ diff --git a/source/blender/modifiers/intern/MOD_boolean_util.h b/source/blender/modifiers/intern/MOD_boolean_util.h index b996dc6d6ba..209db60f0c9 100644 --- a/source/blender/modifiers/intern/MOD_boolean_util.h +++ b/source/blender/modifiers/intern/MOD_boolean_util.h @@ -51,4 +51,4 @@ int NewBooleanMesh(struct Scene *scene, struct Base *base, struct Base *base_sel struct DerivedMesh *NewBooleanDerivedMesh(struct DerivedMesh *dm, struct Object *ob, struct DerivedMesh *dm_select, struct Object *ob_select, int int_op_type); -#endif // MOD_BOOLEAN_UTILS +#endif /* MOD_BOOLEAN_UTILS */ diff --git a/source/blender/python/generic/py_capi_utils.h b/source/blender/python/generic/py_capi_utils.h index 481cfb17c7a..935a5f9030b 100644 --- a/source/blender/python/generic/py_capi_utils.h +++ b/source/blender/python/generic/py_capi_utils.h @@ -69,4 +69,4 @@ int PyC_FlagSet_ValueFromID(PyC_FlagSet *item, const char *identifier, int int PyC_FlagSet_ToBitfield(PyC_FlagSet *items, PyObject *value, int *r_value, const char *error_prefix); PyObject *PyC_FlagSet_FromBitfield(PyC_FlagSet *items, int flag); -#endif // __PY_CAPI_UTILS_H__ +#endif /* __PY_CAPI_UTILS_H__ */ diff --git a/source/blender/python/intern/bpy_app.h b/source/blender/python/intern/bpy_app.h index 5bf36f04ba0..226bf44a493 100644 --- a/source/blender/python/intern/bpy_app.h +++ b/source/blender/python/intern/bpy_app.h @@ -29,4 +29,4 @@ PyObject *BPY_app_struct(void); -#endif // __BPY_APP_H__ +#endif /* __BPY_APP_H__ */ diff --git a/source/blender/python/intern/bpy_app_ffmpeg.h b/source/blender/python/intern/bpy_app_ffmpeg.h index cadbb021d31..26d6e13f8f4 100644 --- a/source/blender/python/intern/bpy_app_ffmpeg.h +++ b/source/blender/python/intern/bpy_app_ffmpeg.h @@ -29,4 +29,4 @@ PyObject *BPY_app_ffmpeg_struct(void); -#endif // __BPY_APP_FFMPEG_H__ +#endif /* __BPY_APP_FFMPEG_H__ */ diff --git a/source/blender/python/intern/bpy_app_handlers.h b/source/blender/python/intern/bpy_app_handlers.h index 1f1eaf04a8b..40ca43909ed 100644 --- a/source/blender/python/intern/bpy_app_handlers.h +++ b/source/blender/python/intern/bpy_app_handlers.h @@ -29,4 +29,4 @@ PyObject *BPY_app_handlers_struct(void); -#endif // __BPY_APP_HANDLERS_H__ +#endif /* __BPY_APP_HANDLERS_H__ */ diff --git a/source/blender/python/intern/bpy_driver.h b/source/blender/python/intern/bpy_driver.h index 6d1696d6cdc..1fccec7e1b2 100644 --- a/source/blender/python/intern/bpy_driver.h +++ b/source/blender/python/intern/bpy_driver.h @@ -36,4 +36,4 @@ extern PyObject *bpy_pydriver_Dict; float BPY_driver_exec(struct ChannelDriver *driver, const float evaltime); void BPY_driver_reset(void); -#endif // __BPY_DRIVER_H__ +#endif /* __BPY_DRIVER_H__ */ diff --git a/source/blender/python/intern/bpy_traceback.h b/source/blender/python/intern/bpy_traceback.h index 575f9824379..9ac49c370e4 100644 --- a/source/blender/python/intern/bpy_traceback.h +++ b/source/blender/python/intern/bpy_traceback.h @@ -28,4 +28,4 @@ void python_script_error_jump(const char *filepath, int *lineno, int *offset); -#endif // __BPY_TRACEBACK_H__ +#endif /* __BPY_TRACEBACK_H__ */ diff --git a/source/blender/python/mathutils/mathutils_noise.h b/source/blender/python/mathutils/mathutils_noise.h index f4bec88e59a..2ed3e32f4f1 100644 --- a/source/blender/python/mathutils/mathutils_noise.h +++ b/source/blender/python/mathutils/mathutils_noise.h @@ -33,4 +33,4 @@ PyMODINIT_FUNC PyInit_mathutils_noise(void); PyMODINIT_FUNC PyInit_mathutils_noise_types(void); PyMODINIT_FUNC PyInit_mathutils_noise_metrics(void); -#endif // __MATHUTILS_NOISE_H__ +#endif /* __MATHUTILS_NOISE_H__ */ diff --git a/source/blender/quicktime/quicktime_export.h b/source/blender/quicktime/quicktime_export.h index ed896357c90..cef4cb8c2a6 100644 --- a/source/blender/quicktime/quicktime_export.h +++ b/source/blender/quicktime/quicktime_export.h @@ -164,6 +164,6 @@ enum { }; #endif -#endif //(_WIN32) || (__APPLE__) +#endif /* (_WIN32) || (__APPLE__) */ -#endif // __QUICKTIME_IMP_H__ +#endif /* __QUICKTIME_IMP_H__ */ diff --git a/source/blender/quicktime/quicktime_import.h b/source/blender/quicktime/quicktime_import.h index 19bdbb4814c..fb068fc2533 100644 --- a/source/blender/quicktime/quicktime_import.h +++ b/source/blender/quicktime/quicktime_import.h @@ -51,8 +51,8 @@ #import #include #endif -#endif //__MOVIES__ -#endif //USE_QTKIT +#endif /* __MOVIES__ */ +#endif /* USE_QTKIT */ #ifdef _WIN32 #ifndef __FIXMATH__ @@ -76,4 +76,4 @@ ImBuf *qtime_fetchibuf (struct anim *anim, int position); int imb_is_a_quicktime (char *name); ImBuf *imb_quicktime_decode(unsigned char *mem, int size, int flags); -#endif // __QUICKTIME_IMPORT_H__ +#endif /* __QUICKTIME_IMPORT_H__ */ diff --git a/source/blender/render/intern/raytrace/svbvh.h b/source/blender/render/intern/raytrace/svbvh.h index a58094e5021..2f4a337f0f9 100644 --- a/source/blender/render/intern/raytrace/svbvh.h +++ b/source/blender/render/intern/raytrace/svbvh.h @@ -29,12 +29,11 @@ * \ingroup render */ - -#ifdef __SSE__ - #ifndef __SVBVH_H__ #define __SVBVH_H__ +#ifdef __SSE__ + #include "bvh.h" #include "BLI_memarena.h" #include "BKE_global.h" @@ -311,7 +310,6 @@ struct Reorganize_SVBVH { } }; -#endif - -#endif //__SSE__ +#endif /* __SSE__ */ +#endif /* __SVBVH_H__ */ diff --git a/source/gameengine/BlenderRoutines/KX_BlenderCanvas.h b/source/gameengine/BlenderRoutines/KX_BlenderCanvas.h index 004f7dd0dd9..bbec7e0fada 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderCanvas.h +++ b/source/gameengine/BlenderRoutines/KX_BlenderCanvas.h @@ -201,5 +201,4 @@ private: #endif }; -#endif // __KX_BLENDERCANVAS_H__ - +#endif /* __KX_BLENDERCANVAS_H__ */ diff --git a/source/gameengine/BlenderRoutines/KX_BlenderGL.h b/source/gameengine/BlenderRoutines/KX_BlenderGL.h index 3b89538df47..7ba612b19cf 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderGL.h +++ b/source/gameengine/BlenderRoutines/KX_BlenderGL.h @@ -34,7 +34,7 @@ #ifdef __cplusplus extern "C" { -#endif //__cplusplus +#endif /* __cplusplus */ struct wmWindow; struct ARegion; @@ -58,7 +58,6 @@ void BL_print_gamedebug_line_padded(const char* text, int xco, int yco, int widt #ifdef __cplusplus } -#endif //__cplusplus - -#endif //__KX_BLENDERGL_H__ +#endif /* __cplusplus */ +#endif /* __KX_BLENDERGL_H__ */ diff --git a/source/gameengine/BlenderRoutines/KX_BlenderInputDevice.h b/source/gameengine/BlenderRoutines/KX_BlenderInputDevice.h index 43870d9030d..bb476ed497a 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderInputDevice.h +++ b/source/gameengine/BlenderRoutines/KX_BlenderInputDevice.h @@ -75,5 +75,5 @@ public: MEM_CXX_CLASS_ALLOC_FUNCS("GE:BL_BlenderInputDevice") #endif }; -#endif //__KX_BLENDERINPUTDEVICE_H__ +#endif /* __KX_BLENDERINPUTDEVICE_H__ */ diff --git a/source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.h b/source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.h index e9140efce01..dec70203ecb 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.h +++ b/source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.h @@ -59,5 +59,4 @@ private: #endif }; -#endif //__KX_BLENDERKEYBOARDDEVICE_H__ - +#endif /* __KX_BLENDERKEYBOARDDEVICE_H__ */ diff --git a/source/gameengine/BlenderRoutines/KX_BlenderMouseDevice.h b/source/gameengine/BlenderRoutines/KX_BlenderMouseDevice.h index 0571cafd7a1..8746da83a81 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderMouseDevice.h +++ b/source/gameengine/BlenderRoutines/KX_BlenderMouseDevice.h @@ -55,5 +55,4 @@ public: #endif }; -#endif //__KX_BLENDERMOUSEDEVICE_H__ - +#endif /* __KX_BLENDERMOUSEDEVICE_H__ */ diff --git a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h index 54ff4dde947..17c9f6bfb1a 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h +++ b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h @@ -112,7 +112,4 @@ public: #endif }; -#endif //__KX_BLENDERRENDERTOOLS_H__ - - - +#endif /* __KX_BLENDERRENDERTOOLS_H__ */ diff --git a/source/gameengine/BlenderRoutines/KX_BlenderSystem.h b/source/gameengine/BlenderRoutines/KX_BlenderSystem.h index a8e033ed47b..0867ef2421f 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderSystem.h +++ b/source/gameengine/BlenderRoutines/KX_BlenderSystem.h @@ -53,5 +53,4 @@ public: #endif }; -#endif //__KX_BLENDERSYSTEM_H__ - +#endif /* __KX_BLENDERSYSTEM_H__ */ diff --git a/source/gameengine/Converter/BL_ActionActuator.h b/source/gameengine/Converter/BL_ActionActuator.h index 640a9a9ccb7..46075ea933d 100644 --- a/source/gameengine/Converter/BL_ActionActuator.h +++ b/source/gameengine/Converter/BL_ActionActuator.h @@ -108,7 +108,7 @@ public: return 1; } } -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ protected: MT_Point3 m_lastpos; diff --git a/source/gameengine/Converter/BL_ArmatureActuator.h b/source/gameengine/Converter/BL_ArmatureActuator.h index 0c88dccb6f3..a5af2bc9c09 100644 --- a/source/gameengine/Converter/BL_ArmatureActuator.h +++ b/source/gameengine/Converter/BL_ArmatureActuator.h @@ -77,7 +77,7 @@ public: static PyObject *pyattr_get_object(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef); static int pyattr_set_object(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ private: // identify the constraint that this actuator controls @@ -93,6 +93,4 @@ private: int m_type; }; -#endif //__BL_ARMATUREACTUATOR_H__ - - +#endif /* __BL_ARMATUREACTUATOR_H__ */ diff --git a/source/gameengine/Converter/BL_ArmatureChannel.h b/source/gameengine/Converter/BL_ArmatureChannel.h index b764d32e8a7..51114c5df30 100644 --- a/source/gameengine/Converter/BL_ArmatureChannel.h +++ b/source/gameengine/Converter/BL_ArmatureChannel.h @@ -68,7 +68,7 @@ public: static int py_attr_setattr(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); static PyObject *py_attr_get_joint_rotation(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef); static int py_attr_set_joint_rotation(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ }; /* this is a factory class to access bBone data field in the GE. @@ -93,6 +93,4 @@ public: }; - -#endif //__BL_ARMATURECHANNEL_H__ - +#endif /* __BL_ARMATURECHANNEL_H__ */ diff --git a/source/gameengine/Converter/BL_ArmatureConstraint.h b/source/gameengine/Converter/BL_ArmatureConstraint.h index 579153a2e79..98c2954baf4 100644 --- a/source/gameengine/Converter/BL_ArmatureConstraint.h +++ b/source/gameengine/Converter/BL_ArmatureConstraint.h @@ -119,8 +119,7 @@ public: static PyObject *py_attr_getattr(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef); static int py_attr_setattr(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ }; -#endif //__BL_ARMATURECONSTRAINT_H__ - +#endif /* __BL_ARMATURECONSTRAINT_H__ */ diff --git a/source/gameengine/Converter/BL_ArmatureObject.h b/source/gameengine/Converter/BL_ArmatureObject.h index 4e7dc3df2f3..445b9af1b10 100644 --- a/source/gameengine/Converter/BL_ArmatureObject.h +++ b/source/gameengine/Converter/BL_ArmatureObject.h @@ -120,7 +120,7 @@ public: static PyObject *pyattr_get_channels(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); KX_PYMETHOD_DOC_NOARGS(BL_ArmatureObject, update); -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ protected: /* list element: BL_ArmatureConstraint. Use SG_DListHead to have automatic list replication */ @@ -152,6 +152,4 @@ void game_blend_poses(struct bPose *dst, struct bPose *src, float srcweight/*, s void game_copy_pose(struct bPose **dst, struct bPose *src, int copy_con); void game_free_pose(struct bPose *pose); - -#endif - +#endif /* __BL_ARMATUREOBJECT_H__ */ diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.h b/source/gameengine/Converter/BL_BlenderDataConversion.h index e6c35c20f4c..2a7efaac898 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.h +++ b/source/gameengine/Converter/BL_BlenderDataConversion.h @@ -52,5 +52,4 @@ void BL_ConvertBlenderObjects(struct Main* maggie, SCA_IInputDevice::KX_EnumInputs ConvertKeyCode(int key_code); -#endif // __BL_BLENDERDATACONVERSION_H__ - +#endif /* __BL_BLENDERDATACONVERSION_H__ */ diff --git a/source/gameengine/Converter/BL_DeformableGameObject.h b/source/gameengine/Converter/BL_DeformableGameObject.h index d14160d39a3..6653311d496 100644 --- a/source/gameengine/Converter/BL_DeformableGameObject.h +++ b/source/gameengine/Converter/BL_DeformableGameObject.h @@ -34,7 +34,7 @@ #if defined(WIN32) && !defined(FREE_WINDOWS) #pragma warning (disable:4786) // get rid of stupid stl-visual compiler debug warning -#endif //WIN32 +#endif /* WIN32 */ #include "DNA_mesh_types.h" #include "KX_GameObject.h" @@ -104,5 +104,4 @@ protected: #endif }; -#endif - +#endif /* __BL_DEFORMABLEGAMEOBJECT_H__ */ diff --git a/source/gameengine/Converter/BL_MeshDeformer.h b/source/gameengine/Converter/BL_MeshDeformer.h index c84d31c72cd..5cea4100b3f 100644 --- a/source/gameengine/Converter/BL_MeshDeformer.h +++ b/source/gameengine/Converter/BL_MeshDeformer.h @@ -40,7 +40,7 @@ #if defined(WIN32) && !defined(FREE_WINDOWS) #pragma warning (disable:4786) // get rid of stupid stl-visual compiler debug warning -#endif //WIN32 +#endif /* WIN32 */ class BL_DeformableGameObject; diff --git a/source/gameengine/Converter/BL_ModifierDeformer.h b/source/gameengine/Converter/BL_ModifierDeformer.h index 5d0c3bc1317..f04b41df3fc 100644 --- a/source/gameengine/Converter/BL_ModifierDeformer.h +++ b/source/gameengine/Converter/BL_ModifierDeformer.h @@ -34,7 +34,7 @@ #if defined(WIN32) && !defined(FREE_WINDOWS) #pragma warning (disable:4786) // get rid of stupid stl-visual compiler debug warning -#endif //WIN32 +#endif /* WIN32 */ #include "BL_ShapeDeformer.h" #include "BL_DeformableGameObject.h" @@ -111,5 +111,4 @@ protected: #endif }; -#endif - +#endif /* __BL_MODIFIERDEFORMER_H__ */ diff --git a/source/gameengine/Converter/BL_ShapeActionActuator.h b/source/gameengine/Converter/BL_ShapeActionActuator.h index b88631c89d6..f72275b79cf 100644 --- a/source/gameengine/Converter/BL_ShapeActionActuator.h +++ b/source/gameengine/Converter/BL_ShapeActionActuator.h @@ -108,7 +108,7 @@ public: } -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ protected: @@ -141,5 +141,4 @@ protected: struct PointerRNA *m_idptr; }; -#endif - +#endif /* __BL_SHAPEACTIONACTUATOR_H__ */ diff --git a/source/gameengine/Converter/BL_ShapeDeformer.h b/source/gameengine/Converter/BL_ShapeDeformer.h index ecf501d9a91..ff5d1e33348 100644 --- a/source/gameengine/Converter/BL_ShapeDeformer.h +++ b/source/gameengine/Converter/BL_ShapeDeformer.h @@ -34,7 +34,7 @@ #if defined(WIN32) && !defined(FREE_WINDOWS) #pragma warning (disable:4786) // get rid of stupid stl-visual compiler debug warning -#endif //WIN32 +#endif /* WIN32 */ #include "BL_SkinDeformer.h" #include "BL_DeformableGameObject.h" diff --git a/source/gameengine/Converter/BL_SkinDeformer.h b/source/gameengine/Converter/BL_SkinDeformer.h index 48c3c3e6186..f1e1e51dd9b 100644 --- a/source/gameengine/Converter/BL_SkinDeformer.h +++ b/source/gameengine/Converter/BL_SkinDeformer.h @@ -34,7 +34,7 @@ #if defined(WIN32) && !defined(FREE_WINDOWS) #pragma warning (disable:4786) // get rid of stupid stl-visual compiler debug warning -#endif //WIN32 +#endif /* WIN32 */ #include "CTR_HashedPtr.h" #include "BL_MeshDeformer.h" diff --git a/source/gameengine/Converter/BlenderWorldInfo.h b/source/gameengine/Converter/BlenderWorldInfo.h index 2cf706a3089..30de5e89269 100644 --- a/source/gameengine/Converter/BlenderWorldInfo.h +++ b/source/gameengine/Converter/BlenderWorldInfo.h @@ -104,5 +104,4 @@ public: #endif }; -#endif //__BLENDERWORLDINFO_H__ - +#endif /* __BLENDERWORLDINFO_H__ */ diff --git a/source/gameengine/Converter/KX_BlenderScalarInterpolator.h b/source/gameengine/Converter/KX_BlenderScalarInterpolator.h index 980aeef7e60..d828910233f 100644 --- a/source/gameengine/Converter/KX_BlenderScalarInterpolator.h +++ b/source/gameengine/Converter/KX_BlenderScalarInterpolator.h @@ -73,5 +73,4 @@ public: #endif }; -#endif //__KX_BLENDERSCALARINTERPOLATOR_H__ - +#endif /* __KX_BLENDERSCALARINTERPOLATOR_H__ */ diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.h b/source/gameengine/Converter/KX_BlenderSceneConverter.h index b51c2f21ca7..436bdb555c9 100644 --- a/source/gameengine/Converter/KX_BlenderSceneConverter.h +++ b/source/gameengine/Converter/KX_BlenderSceneConverter.h @@ -196,5 +196,4 @@ public: #endif }; -#endif //__KX_BLENDERSCENECONVERTER_H__ - +#endif /* __KX_BLENDERSCENECONVERTER_H__ */ diff --git a/source/gameengine/Converter/KX_ConvertActuators.h b/source/gameengine/Converter/KX_ConvertActuators.h index b7c890458cc..596c8cab936 100644 --- a/source/gameengine/Converter/KX_ConvertActuators.h +++ b/source/gameengine/Converter/KX_ConvertActuators.h @@ -43,6 +43,4 @@ void BL_ConvertActuators(const char* maggiename, class RAS_IRenderTools* rendertools, class KX_BlenderSceneConverter* converter); - -#endif //__KX_CONVERTACTUATORS_H__ - +#endif /* __KX_CONVERTACTUATORS_H__ */ diff --git a/source/gameengine/Converter/KX_ConvertControllers.h b/source/gameengine/Converter/KX_ConvertControllers.h index d1d52f866ec..817a49e1b2f 100644 --- a/source/gameengine/Converter/KX_ConvertControllers.h +++ b/source/gameengine/Converter/KX_ConvertControllers.h @@ -43,6 +43,4 @@ void BL_ConvertControllers( class KX_BlenderSceneConverter* converter ); - -#endif //__KX_CONVERTCONTROLLERS_H__ - +#endif /* __KX_CONVERTCONTROLLERS_H__ */ diff --git a/source/gameengine/Converter/KX_ConvertProperties.h b/source/gameengine/Converter/KX_ConvertProperties.h index 345af3bfa74..8f96cc21af6 100644 --- a/source/gameengine/Converter/KX_ConvertProperties.h +++ b/source/gameengine/Converter/KX_ConvertProperties.h @@ -38,5 +38,4 @@ void BL_ConvertProperties(struct Object* object, class SCA_IScene* scene, bool isInActiveLayer); -#endif //__KX_CONVERTPROPERTIES_H__ - +#endif /* __KX_CONVERTPROPERTIES_H__ */ diff --git a/source/gameengine/Converter/KX_ConvertSensors.h b/source/gameengine/Converter/KX_ConvertSensors.h index 0694815c77e..56248721a37 100644 --- a/source/gameengine/Converter/KX_ConvertSensors.h +++ b/source/gameengine/Converter/KX_ConvertSensors.h @@ -42,5 +42,4 @@ void BL_ConvertSensors(struct Object* blenderobject, class RAS_ICanvas* canvas, class KX_BlenderSceneConverter* converter); -#endif //__KX_CONVERTSENSORS_H__ - +#endif /* __KX_CONVERTSENSORS_H__ */ diff --git a/source/gameengine/Converter/KX_IpoConvert.h b/source/gameengine/Converter/KX_IpoConvert.h index 7bb2df978f6..861a2ba66f2 100644 --- a/source/gameengine/Converter/KX_IpoConvert.h +++ b/source/gameengine/Converter/KX_IpoConvert.h @@ -66,5 +66,4 @@ void BL_ConvertMaterialIpos(struct Object* blenderobject, class KX_BlenderSceneConverter *converter); -#endif //__KX_IPOCONVERT_H__ - +#endif /* __KX_IPOCONVERT_H__ */ diff --git a/source/gameengine/Converter/KX_SoftBodyDeformer.h b/source/gameengine/Converter/KX_SoftBodyDeformer.h index d692d45eb18..de533f1c5ed 100644 --- a/source/gameengine/Converter/KX_SoftBodyDeformer.h +++ b/source/gameengine/Converter/KX_SoftBodyDeformer.h @@ -34,7 +34,7 @@ #if defined(WIN32) && !defined(FREE_WINDOWS) #pragma warning (disable:4786) // get rid of stupid stl-visual compiler debug warning -#endif //WIN32 +#endif /* WIN32 */ #include "RAS_Deformer.h" #include "BL_DeformableGameObject.h" diff --git a/source/gameengine/Expressions/BoolValue.h b/source/gameengine/Expressions/BoolValue.h index 64ac0266baf..b88c839a58e 100644 --- a/source/gameengine/Expressions/BoolValue.h +++ b/source/gameengine/Expressions/BoolValue.h @@ -61,5 +61,4 @@ private: #endif }; -#endif // !defined __BOOLVALUE_H__ - +#endif /* __BOOLVALUE_H__ */ diff --git a/source/gameengine/Expressions/ConstExpr.h b/source/gameengine/Expressions/ConstExpr.h index 86d411cef26..768f2bbd10e 100644 --- a/source/gameengine/Expressions/ConstExpr.h +++ b/source/gameengine/Expressions/ConstExpr.h @@ -51,5 +51,4 @@ private: #endif }; -#endif // !defined(AFX_CONSTEXPR_H__061ECFC3_BE87_11D1_A51C_00A02472FC58__INCLUDED_) - +#endif /* __CONSTEXPR_H__ */ diff --git a/source/gameengine/Expressions/EXP_C-Api.h b/source/gameengine/Expressions/EXP_C-Api.h index 4d43695f9b9..d73b0a209d4 100644 --- a/source/gameengine/Expressions/EXP_C-Api.h +++ b/source/gameengine/Expressions/EXP_C-Api.h @@ -64,5 +64,4 @@ const char* EXP_GetText(EXP_ValueHandle); } #endif -#endif //__EXP_C_API_H__ - +#endif /* __EXP_C_API_H__ */ diff --git a/source/gameengine/Expressions/EmptyValue.h b/source/gameengine/Expressions/EmptyValue.h index 54920359f3f..8eccb97e0f5 100644 --- a/source/gameengine/Expressions/EmptyValue.h +++ b/source/gameengine/Expressions/EmptyValue.h @@ -45,5 +45,4 @@ public: #endif }; -#endif // !defined __EMPTYVALUE_H__ - +#endif /* __EMPTYVALUE_H__ */ diff --git a/source/gameengine/Expressions/ErrorValue.h b/source/gameengine/Expressions/ErrorValue.h index 12bc7c7ffcb..0095528254e 100644 --- a/source/gameengine/Expressions/ErrorValue.h +++ b/source/gameengine/Expressions/ErrorValue.h @@ -43,5 +43,4 @@ private: #endif }; -#endif // !defined __ERRORVALUE_H__ - +#endif /* __ERRORVALUE_H__ */ diff --git a/source/gameengine/Expressions/Expression.h b/source/gameengine/Expressions/Expression.h index 5f5db505331..d1b7eda43f0 100644 --- a/source/gameengine/Expressions/Expression.h +++ b/source/gameengine/Expressions/Expression.h @@ -146,5 +146,4 @@ protected: #endif }; -#endif // !defined __EXPRESSION_H__ - +#endif /* __EXPRESSION_H__ */ diff --git a/source/gameengine/Expressions/FloatValue.h b/source/gameengine/Expressions/FloatValue.h index 59311e5d373..bc6a2d052d4 100644 --- a/source/gameengine/Expressions/FloatValue.h +++ b/source/gameengine/Expressions/FloatValue.h @@ -54,5 +54,4 @@ protected: #endif }; -#endif // !defined __FLOATVALUE_H__ - +#endif /* __FLOATVALUE_H__ */ diff --git a/source/gameengine/Expressions/IdentifierExpr.h b/source/gameengine/Expressions/IdentifierExpr.h index 58e75c4b02e..26eb3691378 100644 --- a/source/gameengine/Expressions/IdentifierExpr.h +++ b/source/gameengine/Expressions/IdentifierExpr.h @@ -56,5 +56,4 @@ public: #endif }; -#endif //__IDENTIFIEREXPR_H__ - +#endif /* __IDENTIFIEREXPR_H__ */ diff --git a/source/gameengine/Expressions/IfExpr.h b/source/gameengine/Expressions/IfExpr.h index f8ed81168d0..80e35471d82 100644 --- a/source/gameengine/Expressions/IfExpr.h +++ b/source/gameengine/Expressions/IfExpr.h @@ -16,12 +16,8 @@ * \ingroup expressions */ -#if !defined(AFX_IFEXPR_H__1F691841_C5C7_11D1_A863_0000B4542BD8__INCLUDED_) -#define AFX_IFEXPR_H__1F691841_C5C7_11D1_A863_0000B4542BD8__INCLUDED_ - -#if defined(_MSC_VER) && _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 +#ifndef __IFEXPR_H__ +#define __IFEXPR_H__ #include "Expression.h" @@ -55,5 +51,4 @@ public: #endif }; -#endif // !defined(AFX_IFEXPR_H__1F691841_C5C7_11D1_A863_0000B4542BD8__INCLUDED_) - +#endif /* __IFEXPR_H__ */ diff --git a/source/gameengine/Expressions/IntValue.h b/source/gameengine/Expressions/IntValue.h index e728467cc4e..8411b09693c 100644 --- a/source/gameengine/Expressions/IntValue.h +++ b/source/gameengine/Expressions/IntValue.h @@ -69,5 +69,4 @@ private: #endif }; -#endif // !defined __INTVALUE_H__ - +#endif /* __INTVALUE_H__ */ diff --git a/source/gameengine/Expressions/KX_HashedPtr.h b/source/gameengine/Expressions/KX_HashedPtr.h index 866689ed203..d822af38c44 100644 --- a/source/gameengine/Expressions/KX_HashedPtr.h +++ b/source/gameengine/Expressions/KX_HashedPtr.h @@ -58,5 +58,4 @@ public: #endif }; -#endif //__KX_HASHEDPTR_H__ - +#endif /* __KX_HASHEDPTR_H__ */ diff --git a/source/gameengine/Expressions/KX_Python.h b/source/gameengine/Expressions/KX_Python.h index 4a7ce4d3fb7..62dd9a13dd4 100644 --- a/source/gameengine/Expressions/KX_Python.h +++ b/source/gameengine/Expressions/KX_Python.h @@ -79,5 +79,4 @@ #undef toupper #endif -#endif // __KX_PYTHON_H__ - +#endif /* __KX_PYTHON_H__ */ diff --git a/source/gameengine/Expressions/ListValue.h b/source/gameengine/Expressions/ListValue.h index 20005088310..5240c54ae4e 100644 --- a/source/gameengine/Expressions/ListValue.h +++ b/source/gameengine/Expressions/ListValue.h @@ -87,5 +87,5 @@ private: bool m_bReleaseContents; }; -#endif // !defined __LISTVALUE_H__ +#endif /* __LISTVALUE_H__ */ diff --git a/source/gameengine/Expressions/Operator1Expr.h b/source/gameengine/Expressions/Operator1Expr.h index 13a1b16500a..3dd76f773f2 100644 --- a/source/gameengine/Expressions/Operator1Expr.h +++ b/source/gameengine/Expressions/Operator1Expr.h @@ -16,8 +16,8 @@ * \ingroup expressions */ -#if !defined(AFX_OPERATOR1EXPR_H__A1653901_BF41_11D1_A51C_00A02472FC58__INCLUDED_) -#define AFX_OPERATOR1EXPR_H__A1653901_BF41_11D1_A51C_00A02472FC58__INCLUDED_ +#ifndef __OPERATOR1EXPR_H__ +#define __OPERATOR1EXPR_H__ #include "Expression.h" @@ -56,5 +56,4 @@ private: #endif }; -#endif // !defined(AFX_OPERATOR1EXPR_H__A1653901_BF41_11D1_A51C_00A02472FC58__INCLUDED_) - +#endif /* __OPERATOR1EXPR_H__ */ diff --git a/source/gameengine/Expressions/Operator2Expr.h b/source/gameengine/Expressions/Operator2Expr.h index 23272930131..8c30b7cd634 100644 --- a/source/gameengine/Expressions/Operator2Expr.h +++ b/source/gameengine/Expressions/Operator2Expr.h @@ -62,5 +62,5 @@ private: #endif }; -#endif // !defined __OPERATOR2EXPR_H__ +#endif /* __OPERATOR2EXPR_H__ */ diff --git a/source/gameengine/Expressions/PyObjectPlus.h b/source/gameengine/Expressions/PyObjectPlus.h index 005bf2f6cb2..83b7c8c8771 100644 --- a/source/gameengine/Expressions/PyObjectPlus.h +++ b/source/gameengine/Expressions/PyObjectPlus.h @@ -548,7 +548,7 @@ public: \ #define Py_HeaderPtr \ public: \ -#endif // WITH_CXX_GUARDEDALLOC +#endif /* WITH_CXX_GUARDEDALLOC */ #endif @@ -633,4 +633,4 @@ public: PyObject *PyUnicode_From_STR_String(const STR_String& str); #endif -#endif // __PYOBJECTPLUS_H__ +#endif /* __PYOBJECTPLUS_H__ */ diff --git a/source/gameengine/Expressions/StringValue.h b/source/gameengine/Expressions/StringValue.h index bc102c6e203..22d433455ec 100644 --- a/source/gameengine/Expressions/StringValue.h +++ b/source/gameengine/Expressions/StringValue.h @@ -45,7 +45,7 @@ public: virtual PyObject* ConvertValueToPython() { return PyUnicode_From_STR_String(m_strString); } -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ private: // data member @@ -57,5 +57,4 @@ private: #endif }; -#endif - +#endif /* __STRINGVALUE_H__ */ diff --git a/source/gameengine/Expressions/Value.h b/source/gameengine/Expressions/Value.h index e0c4daeccd0..92b5e20543c 100644 --- a/source/gameengine/Expressions/Value.h +++ b/source/gameengine/Expressions/Value.h @@ -16,13 +16,13 @@ * \ingroup expressions */ -#if defined(WIN32) && !defined(FREE_WINDOWS) -#pragma warning (disable:4786) -#endif //WIN32 - #ifndef __VALUE_H__ #define __VALUE_H__ +#if defined(WIN32) && !defined(FREE_WINDOWS) +#pragma warning (disable:4786) +#endif /* WIN32 */ + #include // array functionality for the propertylist #include "STR_String.h" // STR_String class @@ -53,14 +53,6 @@ using namespace std; #define assertd(exp) ((void)NULL) #endif - -#ifndef USE_PRAGMA_ONCE -#ifdef WIN32 - #pragma once - -#endif //WIN32 -#endif - enum VALUE_OPERATOR { VALUE_MOD_OPERATOR, // % @@ -233,7 +225,7 @@ public: static PyObject *pyattr_get_name(void * self, const KX_PYATTRIBUTE_DEF * attrdef); virtual PyObject *ConvertKeysToPython( void ); -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ @@ -439,5 +431,4 @@ protected: #endif }; -#endif // !defined _VALUEBASECLASS_H - +#endif /* __VALUE_H__ */ diff --git a/source/gameengine/Expressions/VectorValue.h b/source/gameengine/Expressions/VectorValue.h index b7afa61d4dd..9b9f9612810 100644 --- a/source/gameengine/Expressions/VectorValue.h +++ b/source/gameengine/Expressions/VectorValue.h @@ -90,5 +90,4 @@ protected: #endif }; -#endif // !defined __VECTORVALUE_H__ - +#endif /* __VECTORVALUE_H__ */ diff --git a/source/gameengine/Expressions/VoidValue.h b/source/gameengine/Expressions/VoidValue.h index a1a82f8aa65..e97278b3142 100644 --- a/source/gameengine/Expressions/VoidValue.h +++ b/source/gameengine/Expressions/VoidValue.h @@ -78,4 +78,3 @@ public: }; #endif /* __VOIDVALUE_H__ */ - diff --git a/source/gameengine/GameLogic/SCA_ANDController.h b/source/gameengine/GameLogic/SCA_ANDController.h index ccc3f9be3af..ff152d6d2fb 100644 --- a/source/gameengine/GameLogic/SCA_ANDController.h +++ b/source/gameengine/GameLogic/SCA_ANDController.h @@ -48,5 +48,4 @@ public: virtual void Trigger(SCA_LogicManager* logicmgr); }; -#endif //__SCA_ANDCONTROLLER_H__ - +#endif /* __SCA_ANDCONTROLLER_H__ */ diff --git a/source/gameengine/GameLogic/SCA_ActuatorEventManager.h b/source/gameengine/GameLogic/SCA_ActuatorEventManager.h index dee9ea4e8ba..997be1145db 100644 --- a/source/gameengine/GameLogic/SCA_ActuatorEventManager.h +++ b/source/gameengine/GameLogic/SCA_ActuatorEventManager.h @@ -53,5 +53,4 @@ public: #endif }; -#endif //__SCA_ACTUATOREVENTMANAGER_H__ - +#endif /* __SCA_ACTUATOREVENTMANAGER_H__ */ diff --git a/source/gameengine/GameLogic/SCA_ActuatorSensor.h b/source/gameengine/GameLogic/SCA_ActuatorSensor.h index 894dc2162cf..6005bd3ac6c 100644 --- a/source/gameengine/GameLogic/SCA_ActuatorSensor.h +++ b/source/gameengine/GameLogic/SCA_ActuatorSensor.h @@ -64,7 +64,7 @@ public: static int CheckActuator(void *self, const PyAttributeDef*); -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ }; -#endif +#endif /* __SCA_ACTUATORSENSOR_H__ */ diff --git a/source/gameengine/GameLogic/SCA_AlwaysEventManager.h b/source/gameengine/GameLogic/SCA_AlwaysEventManager.h index cf4063fba1f..47293c75726 100644 --- a/source/gameengine/GameLogic/SCA_AlwaysEventManager.h +++ b/source/gameengine/GameLogic/SCA_AlwaysEventManager.h @@ -47,5 +47,4 @@ public: #endif }; -#endif //__SCA_ALWAYSEVENTMANAGER_H__ - +#endif /* __SCA_ALWAYSEVENTMANAGER_H__ */ diff --git a/source/gameengine/GameLogic/SCA_AlwaysSensor.h b/source/gameengine/GameLogic/SCA_AlwaysSensor.h index d0963fd0ea1..e0ab4279b1c 100644 --- a/source/gameengine/GameLogic/SCA_AlwaysSensor.h +++ b/source/gameengine/GameLogic/SCA_AlwaysSensor.h @@ -50,5 +50,4 @@ public: virtual void Init(); }; -#endif //__SCA_ALWAYSSENSOR_H__ - +#endif /* __SCA_ALWAYSSENSOR_H__ */ diff --git a/source/gameengine/GameLogic/SCA_BasicEventManager.h b/source/gameengine/GameLogic/SCA_BasicEventManager.h index 24206e46a61..a015233454b 100644 --- a/source/gameengine/GameLogic/SCA_BasicEventManager.h +++ b/source/gameengine/GameLogic/SCA_BasicEventManager.h @@ -54,5 +54,4 @@ public: #endif }; -#endif //__SCA_BASICEVENTMANAGER_H__ - +#endif /* __SCA_BASICEVENTMANAGER_H__ */ diff --git a/source/gameengine/GameLogic/SCA_DelaySensor.h b/source/gameengine/GameLogic/SCA_DelaySensor.h index 2c408921f27..b516cd8360e 100644 --- a/source/gameengine/GameLogic/SCA_DelaySensor.h +++ b/source/gameengine/GameLogic/SCA_DelaySensor.h @@ -65,5 +65,4 @@ public: }; -#endif //__KX_ALWAYSSENSOR - +#endif /* __SCA_DELAYSENSOR_H__ */ diff --git a/source/gameengine/GameLogic/SCA_ExpressionController.h b/source/gameengine/GameLogic/SCA_ExpressionController.h index 06edc83ab96..c16944ccde1 100644 --- a/source/gameengine/GameLogic/SCA_ExpressionController.h +++ b/source/gameengine/GameLogic/SCA_ExpressionController.h @@ -63,5 +63,4 @@ public: #endif }; -#endif //__SCA_EXPRESSIONCONTROLLER_H__ - +#endif /* __SCA_EXPRESSIONCONTROLLER_H__ */ diff --git a/source/gameengine/GameLogic/SCA_IActuator.h b/source/gameengine/GameLogic/SCA_IActuator.h index 801483bb882..090df1e75e2 100644 --- a/source/gameengine/GameLogic/SCA_IActuator.h +++ b/source/gameengine/GameLogic/SCA_IActuator.h @@ -164,5 +164,4 @@ public: #endif }; -#endif //__SCA_IACTUATOR_H__ - +#endif /* __SCA_IACTUATOR_H__ */ diff --git a/source/gameengine/GameLogic/SCA_IController.h b/source/gameengine/GameLogic/SCA_IController.h index 656c4299dff..1bc6b60bf1e 100644 --- a/source/gameengine/GameLogic/SCA_IController.h +++ b/source/gameengine/GameLogic/SCA_IController.h @@ -106,8 +106,7 @@ public: static PyObject* pyattr_get_state(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); static PyObject* pyattr_get_sensors(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); static PyObject* pyattr_get_actuators(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ }; -#endif - +#endif /* __SCA_ICONTROLLER_H__ */ diff --git a/source/gameengine/GameLogic/SCA_IInputDevice.h b/source/gameengine/GameLogic/SCA_IInputDevice.h index 66a1209751d..bc4d22eaaaf 100644 --- a/source/gameengine/GameLogic/SCA_IInputDevice.h +++ b/source/gameengine/GameLogic/SCA_IInputDevice.h @@ -320,5 +320,5 @@ public: #endif }; -#endif //__SCA_IINPUTDEVICE_H__ +#endif /* __SCA_IINPUTDEVICE_H__ */ diff --git a/source/gameengine/GameLogic/SCA_ILogicBrick.h b/source/gameengine/GameLogic/SCA_ILogicBrick.h index c5fa9399ab7..dc0aa4ce331 100644 --- a/source/gameengine/GameLogic/SCA_ILogicBrick.h +++ b/source/gameengine/GameLogic/SCA_ILogicBrick.h @@ -159,9 +159,8 @@ protected: /** Convert a a c++ value to KX_TRUE, KX_FALSE in Python. */ PyObject *BoolToPyArg(bool); -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ }; -#endif - +#endif /* __SCA_ILOGICBRICK_H__ */ diff --git a/source/gameengine/GameLogic/SCA_IObject.h b/source/gameengine/GameLogic/SCA_IObject.h index a850d23babf..0189af00322 100644 --- a/source/gameengine/GameLogic/SCA_IObject.h +++ b/source/gameengine/GameLogic/SCA_IObject.h @@ -225,5 +225,4 @@ public: }; -#endif //__SCA_IOBJECT_H__ - +#endif /* __SCA_IOBJECT_H__ */ diff --git a/source/gameengine/GameLogic/SCA_IScene.h b/source/gameengine/GameLogic/SCA_IScene.h index a399e313082..997266976ad 100644 --- a/source/gameengine/GameLogic/SCA_IScene.h +++ b/source/gameengine/GameLogic/SCA_IScene.h @@ -78,5 +78,4 @@ public: #endif }; -#endif //__SCA_ISCENE_H__ - +#endif /* __SCA_ISCENE_H__ */ diff --git a/source/gameengine/GameLogic/SCA_ISensor.h b/source/gameengine/GameLogic/SCA_ISensor.h index 3bb29f3f0a2..091aa675741 100644 --- a/source/gameengine/GameLogic/SCA_ISensor.h +++ b/source/gameengine/GameLogic/SCA_ISensor.h @@ -212,8 +212,7 @@ public: KX_SENSOR_JUST_DEACTIVATED }; -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ }; -#endif //__SCA_ISENSOR_H__ - +#endif /* __SCA_ISENSOR_H__ */ diff --git a/source/gameengine/GameLogic/SCA_JoystickSensor.h b/source/gameengine/GameLogic/SCA_JoystickSensor.h index 5dc35faf244..6c6dc019a5e 100644 --- a/source/gameengine/GameLogic/SCA_JoystickSensor.h +++ b/source/gameengine/GameLogic/SCA_JoystickSensor.h @@ -30,11 +30,11 @@ */ -#ifndef __JOYSENSOR_H_ -#define __JOYSENSOR_H +#ifndef __JOYSENSOR_H__ +#define __JOYSENSOR_H__ #include "SCA_ISensor.h" -#include "./Joystick/SCA_JoystickDefines.h" +#include "Joystick/SCA_JoystickDefines.h" class SCA_JoystickSensor :public SCA_ISensor { @@ -161,8 +161,8 @@ public: return 0; } -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ }; -#endif +#endif /* __JOYSENSOR_H__ */ diff --git a/source/gameengine/GameLogic/SCA_KeyboardManager.h b/source/gameengine/GameLogic/SCA_KeyboardManager.h index fd3c0706fa7..cd1cbf4adee 100644 --- a/source/gameengine/GameLogic/SCA_KeyboardManager.h +++ b/source/gameengine/GameLogic/SCA_KeyboardManager.h @@ -63,5 +63,4 @@ public: #endif }; -#endif //__SCA_KEYBOARDMANAGER_H__ - +#endif /* __SCA_KEYBOARDMANAGER_H__ */ diff --git a/source/gameengine/GameLogic/SCA_KeyboardSensor.h b/source/gameengine/GameLogic/SCA_KeyboardSensor.h index caa141e48f2..c6610d0284e 100644 --- a/source/gameengine/GameLogic/SCA_KeyboardSensor.h +++ b/source/gameengine/GameLogic/SCA_KeyboardSensor.h @@ -138,7 +138,4 @@ bool IsPrintable(int keyIndex); bool IsDelete(int keyIndex); -#endif //__SCA_KEYBOARDSENSOR_H__ - - - +#endif /* __SCA_KEYBOARDSENSOR_H__ */ diff --git a/source/gameengine/GameLogic/SCA_LogicManager.h b/source/gameengine/GameLogic/SCA_LogicManager.h index 817f3a1c22a..f3d02cccf26 100644 --- a/source/gameengine/GameLogic/SCA_LogicManager.h +++ b/source/gameengine/GameLogic/SCA_LogicManager.h @@ -151,5 +151,4 @@ public: #endif }; -#endif //__SCA_LOGICMANAGER_H__ - +#endif /* __SCA_LOGICMANAGER_H__ */ diff --git a/source/gameengine/GameLogic/SCA_MouseManager.h b/source/gameengine/GameLogic/SCA_MouseManager.h index 02c28807566..a57e52070a7 100644 --- a/source/gameengine/GameLogic/SCA_MouseManager.h +++ b/source/gameengine/GameLogic/SCA_MouseManager.h @@ -72,5 +72,4 @@ public: #endif }; -#endif //__SCA_MOUSEMANAGER_H__ - +#endif /* __SCA_MOUSEMANAGER_H__ */ diff --git a/source/gameengine/GameLogic/SCA_MouseSensor.h b/source/gameengine/GameLogic/SCA_MouseSensor.h index d4eff371d4a..8d05a548681 100644 --- a/source/gameengine/GameLogic/SCA_MouseSensor.h +++ b/source/gameengine/GameLogic/SCA_MouseSensor.h @@ -117,5 +117,4 @@ class SCA_MouseSensor : public SCA_ISensor #endif }; -#endif //__SCA_MOUSESENSOR_H__ - +#endif /* __SCA_MOUSESENSOR_H__ */ diff --git a/source/gameengine/GameLogic/SCA_NANDController.h b/source/gameengine/GameLogic/SCA_NANDController.h index 040df7f0ade..a3f02908dd2 100644 --- a/source/gameengine/GameLogic/SCA_NANDController.h +++ b/source/gameengine/GameLogic/SCA_NANDController.h @@ -49,5 +49,4 @@ public: /* --------------------------------------------------------------------- */ }; -#endif //__SCA_NANDCONTROLLER_H__ - +#endif /* __SCA_NANDCONTROLLER_H__ */ diff --git a/source/gameengine/GameLogic/SCA_NORController.h b/source/gameengine/GameLogic/SCA_NORController.h index 1630f8055ec..ec8159de8d1 100644 --- a/source/gameengine/GameLogic/SCA_NORController.h +++ b/source/gameengine/GameLogic/SCA_NORController.h @@ -45,5 +45,4 @@ public: virtual void Trigger(SCA_LogicManager* logicmgr); }; -#endif //__SCA_NORCONTROLLER_H__ - +#endif /* __SCA_NORCONTROLLER_H__ */ diff --git a/source/gameengine/GameLogic/SCA_ORController.h b/source/gameengine/GameLogic/SCA_ORController.h index 9a4e4c7398d..9499c893c72 100644 --- a/source/gameengine/GameLogic/SCA_ORController.h +++ b/source/gameengine/GameLogic/SCA_ORController.h @@ -46,5 +46,4 @@ public: virtual void Trigger(SCA_LogicManager* logicmgr); }; -#endif //__SCA_ORCONTROLLER_H__ - +#endif /* __SCA_ORCONTROLLER_H__ */ diff --git a/source/gameengine/GameLogic/SCA_PropertyActuator.h b/source/gameengine/GameLogic/SCA_PropertyActuator.h index e465098131e..83a6d05df1b 100644 --- a/source/gameengine/GameLogic/SCA_PropertyActuator.h +++ b/source/gameengine/GameLogic/SCA_PropertyActuator.h @@ -86,5 +86,4 @@ public: }; -#endif //__KX_PROPERTYACTUATOR_DOC - +#endif /* __KX_PROPERTYACTUATOR_DOC */ diff --git a/source/gameengine/GameLogic/SCA_PropertyEventManager.h b/source/gameengine/GameLogic/SCA_PropertyEventManager.h index 7a4ec750484..554fe686df2 100644 --- a/source/gameengine/GameLogic/SCA_PropertyEventManager.h +++ b/source/gameengine/GameLogic/SCA_PropertyEventManager.h @@ -52,5 +52,4 @@ public: #endif }; -#endif //__SCA_PROPERTYEVENTMANAGER_H__ - +#endif /* __SCA_PROPERTYEVENTMANAGER_H__ */ diff --git a/source/gameengine/GameLogic/SCA_PythonController.h b/source/gameengine/GameLogic/SCA_PythonController.h index 8a72ce6bad9..f1f10d22711 100644 --- a/source/gameengine/GameLogic/SCA_PythonController.h +++ b/source/gameengine/GameLogic/SCA_PythonController.h @@ -115,5 +115,4 @@ class SCA_PythonController : public SCA_IController #endif }; -#endif //__SCA_PYTHONCONTROLLER_H__ - +#endif /* __SCA_PYTHONCONTROLLER_H__ */ diff --git a/source/gameengine/GameLogic/SCA_PythonKeyboard.h b/source/gameengine/GameLogic/SCA_PythonKeyboard.h index aab49bcb83b..53068f38e6a 100644 --- a/source/gameengine/GameLogic/SCA_PythonKeyboard.h +++ b/source/gameengine/GameLogic/SCA_PythonKeyboard.h @@ -47,5 +47,4 @@ public: #endif }; -#endif //__SCA_PYTHONKEYBOARD_H__ - +#endif /* __SCA_PYTHONKEYBOARD_H__ */ diff --git a/source/gameengine/GameLogic/SCA_PythonMouse.h b/source/gameengine/GameLogic/SCA_PythonMouse.h index f770a54d6e6..bc6e65f07a8 100644 --- a/source/gameengine/GameLogic/SCA_PythonMouse.h +++ b/source/gameengine/GameLogic/SCA_PythonMouse.h @@ -56,5 +56,4 @@ public: #endif }; -#endif //__SCA_PYTHONMOUSE_H__ - +#endif /* __SCA_PYTHONMOUSE_H__ */ diff --git a/source/gameengine/GameLogic/SCA_RandomActuator.h b/source/gameengine/GameLogic/SCA_RandomActuator.h index f61de24c0cc..32b29fc4f43 100644 --- a/source/gameengine/GameLogic/SCA_RandomActuator.h +++ b/source/gameengine/GameLogic/SCA_RandomActuator.h @@ -112,7 +112,7 @@ class SCA_RandomActuator : public SCA_IActuator KX_PYMETHOD_DOC_VARARGS(SCA_RandomActuator, setFloatNormal); KX_PYMETHOD_DOC_VARARGS(SCA_RandomActuator, setFloatNegativeExponential); -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ }; /* end of class KX_EditObjectActuator : public SCA_PropertyActuator */ diff --git a/source/gameengine/GameLogic/SCA_RandomEventManager.h b/source/gameengine/GameLogic/SCA_RandomEventManager.h index b46899b1355..2d83c5fcdca 100644 --- a/source/gameengine/GameLogic/SCA_RandomEventManager.h +++ b/source/gameengine/GameLogic/SCA_RandomEventManager.h @@ -51,5 +51,4 @@ public: #endif }; -#endif //__SCA_RANDOMEVENTMANAGER_H__ - +#endif /* __SCA_RANDOMEVENTMANAGER_H__ */ diff --git a/source/gameengine/GameLogic/SCA_RandomSensor.h b/source/gameengine/GameLogic/SCA_RandomSensor.h index 008445ef878..628562b77e6 100644 --- a/source/gameengine/GameLogic/SCA_RandomSensor.h +++ b/source/gameengine/GameLogic/SCA_RandomSensor.h @@ -68,5 +68,4 @@ public: #endif }; -#endif //__SCA_RANDOMSENSOR_H__ - +#endif /* __SCA_RANDOMSENSOR_H__ */ diff --git a/source/gameengine/GameLogic/SCA_TimeEventManager.h b/source/gameengine/GameLogic/SCA_TimeEventManager.h index 092cf016370..4c929dca23c 100644 --- a/source/gameengine/GameLogic/SCA_TimeEventManager.h +++ b/source/gameengine/GameLogic/SCA_TimeEventManager.h @@ -59,5 +59,4 @@ public: #endif }; -#endif //__SCA_TIMEEVENTMANAGER_H__ - +#endif /* __SCA_TIMEEVENTMANAGER_H__ */ diff --git a/source/gameengine/GameLogic/SCA_XNORController.h b/source/gameengine/GameLogic/SCA_XNORController.h index 5ef4dc67cf2..c257b71273e 100644 --- a/source/gameengine/GameLogic/SCA_XNORController.h +++ b/source/gameengine/GameLogic/SCA_XNORController.h @@ -50,5 +50,4 @@ public: }; -#endif //__SCA_XNORCONTROLLER_H__ - +#endif /* __SCA_XNORCONTROLLER_H__ */ diff --git a/source/gameengine/GameLogic/SCA_XORController.h b/source/gameengine/GameLogic/SCA_XORController.h index 56cd2440863..c64a3380ede 100644 --- a/source/gameengine/GameLogic/SCA_XORController.h +++ b/source/gameengine/GameLogic/SCA_XORController.h @@ -45,5 +45,4 @@ public: virtual void Trigger(SCA_LogicManager* logicmgr); }; -#endif //__SCA_XORCONTROLLER_H__ - +#endif /* __SCA_XORCONTROLLER_H__ */ diff --git a/source/gameengine/GamePlayer/common/GPC_Canvas.h b/source/gameengine/GamePlayer/common/GPC_Canvas.h index 2a597c4c43d..a995dcfaa86 100644 --- a/source/gameengine/GamePlayer/common/GPC_Canvas.h +++ b/source/gameengine/GamePlayer/common/GPC_Canvas.h @@ -38,7 +38,7 @@ #ifdef WIN32 #pragma warning (disable:4786) // suppress stl-MSVC debug info warning #include -#endif // WIN32 +#endif /* WIN32 */ #include "GL/glew.h" @@ -273,5 +273,4 @@ protected: static TBannerId s_bannerId; }; -#endif // __GPC_CANVAS_H__ - +#endif /* __GPC_CANVAS_H__ */ diff --git a/source/gameengine/GamePlayer/common/GPC_Engine.h b/source/gameengine/GamePlayer/common/GPC_Engine.h index 60f0d2af199..6247bd630bb 100644 --- a/source/gameengine/GamePlayer/common/GPC_Engine.h +++ b/source/gameengine/GamePlayer/common/GPC_Engine.h @@ -121,5 +121,4 @@ private: }; -#endif // __GPC_ENGINE_H__ - +#endif /* __GPC_ENGINE_H__ */ diff --git a/source/gameengine/GamePlayer/common/GPC_KeyboardDevice.h b/source/gameengine/GamePlayer/common/GPC_KeyboardDevice.h index 63e051dd1d4..afe7f921a61 100644 --- a/source/gameengine/GamePlayer/common/GPC_KeyboardDevice.h +++ b/source/gameengine/GamePlayer/common/GPC_KeyboardDevice.h @@ -34,7 +34,7 @@ #ifdef WIN32 #pragma warning (disable : 4786) -#endif // WIN32 +#endif /* WIN32 */ #include "SCA_IInputDevice.h" @@ -87,5 +87,4 @@ public: virtual void HookEscape(); }; -#endif // _GPC_KEYBOARDDEVICE_H - +#endif /* __GPC_KEYBOARDDEVICE_H__ */ diff --git a/source/gameengine/GamePlayer/common/GPC_MouseDevice.h b/source/gameengine/GamePlayer/common/GPC_MouseDevice.h index 2db1b1ec34c..7699a9e3eae 100644 --- a/source/gameengine/GamePlayer/common/GPC_MouseDevice.h +++ b/source/gameengine/GamePlayer/common/GPC_MouseDevice.h @@ -34,7 +34,7 @@ #ifdef WIN32 #pragma warning (disable : 4786) -#endif // WIN32 +#endif /* WIN32 */ #include "SCA_IInputDevice.h" @@ -102,5 +102,4 @@ protected: virtual bool ConvertEvent(KX_EnumInputs kxevent, int eventval); }; -#endif // __GPC_MOUSEDEVICE_H__ - +#endif /* __GPC_MOUSEDEVICE_H__ */ diff --git a/source/gameengine/GamePlayer/common/GPC_RawImage.h b/source/gameengine/GamePlayer/common/GPC_RawImage.h index 4d3f45597f8..afff59484b9 100644 --- a/source/gameengine/GamePlayer/common/GPC_RawImage.h +++ b/source/gameengine/GamePlayer/common/GPC_RawImage.h @@ -117,5 +117,4 @@ protected: int m_height; }; -#endif // __GPC_RAWIMAGE_H__ - +#endif /* __GPC_RAWIMAGE_H__ */ diff --git a/source/gameengine/GamePlayer/common/GPC_RawLoadDotBlendArray.h b/source/gameengine/GamePlayer/common/GPC_RawLoadDotBlendArray.h index 6f15276ab83..d5c1b210454 100644 --- a/source/gameengine/GamePlayer/common/GPC_RawLoadDotBlendArray.h +++ b/source/gameengine/GamePlayer/common/GPC_RawLoadDotBlendArray.h @@ -34,5 +34,4 @@ void GetRawLoadingAnimation(unsigned char **data, int *dataSize); -#endif // __GPC_RAWLOADDOTBLENDARRAY_H__ - +#endif /* __GPC_RAWLOADDOTBLENDARRAY_H__ */ diff --git a/source/gameengine/GamePlayer/common/GPC_RawLogoArrays.h b/source/gameengine/GamePlayer/common/GPC_RawLogoArrays.h index ade00020353..bb5c5e220a3 100644 --- a/source/gameengine/GamePlayer/common/GPC_RawLogoArrays.h +++ b/source/gameengine/GamePlayer/common/GPC_RawLogoArrays.h @@ -38,5 +38,4 @@ void GetRawBlender3DLogo(unsigned char **data, int *width, int *height); void GetRawNaNLogo(unsigned char **data, int *width, int *height); #endif -#endif // __GPC_RAWLOGOARRAYS_H__ - +#endif /* __GPC_RAWLOGOARRAYS_H__ */ diff --git a/source/gameengine/GamePlayer/common/GPC_RenderTools.h b/source/gameengine/GamePlayer/common/GPC_RenderTools.h index 166a931beab..1030c09548a 100644 --- a/source/gameengine/GamePlayer/common/GPC_RenderTools.h +++ b/source/gameengine/GamePlayer/common/GPC_RenderTools.h @@ -36,7 +36,7 @@ // don't show stl-warnings #pragma warning (disable:4786) #include -#endif // WIN32 +#endif /* WIN32 */ #include "RAS_IRenderTools.h" @@ -106,7 +106,4 @@ public: virtual void SetClientObject(RAS_IRasterizer *rasty, void* obj); }; -#endif // __GPC_RENDERTOOLS_H__ - - - +#endif /* __GPC_RENDERTOOLS_H__ */ diff --git a/source/gameengine/GamePlayer/common/GPC_System.h b/source/gameengine/GamePlayer/common/GPC_System.h index 03bb7743637..4169064179e 100644 --- a/source/gameengine/GamePlayer/common/GPC_System.h +++ b/source/gameengine/GamePlayer/common/GPC_System.h @@ -59,5 +59,4 @@ public: // NG_NetworkDeviceInterface* m_ndi; }; -#endif // __GPC_SYSTEM_H__ - +#endif /* __GPC_SYSTEM_H__ */ diff --git a/source/gameengine/GamePlayer/ghost/GPG_Canvas.h b/source/gameengine/GamePlayer/ghost/GPG_Canvas.h index d931f605a64..f2d7ec267f3 100644 --- a/source/gameengine/GamePlayer/ghost/GPG_Canvas.h +++ b/source/gameengine/GamePlayer/ghost/GPG_Canvas.h @@ -34,7 +34,7 @@ #ifdef WIN32 #pragma warning (disable : 4786) -#endif // WIN32 +#endif /* WIN32 */ #include "GPC_Canvas.h" @@ -66,5 +66,4 @@ public: void EndDraw() {}; }; -#endif // __GPG_CANVAS_H__ - +#endif /* __GPG_CANVAS_H__ */ diff --git a/source/gameengine/GamePlayer/ghost/GPG_KeyboardDevice.h b/source/gameengine/GamePlayer/ghost/GPG_KeyboardDevice.h index 8d72a621b6a..4c6b8205a42 100644 --- a/source/gameengine/GamePlayer/ghost/GPG_KeyboardDevice.h +++ b/source/gameengine/GamePlayer/ghost/GPG_KeyboardDevice.h @@ -35,7 +35,7 @@ #ifdef WIN32 #pragma warning (disable : 4786) -#endif // WIN32 +#endif /* WIN32 */ #include "GHOST_Types.h" #include "GPC_KeyboardDevice.h" @@ -53,5 +53,4 @@ public: virtual ~GPG_KeyboardDevice(void); }; -#endif //__GPG_KEYBOARDDEVICE_H__ - +#endif /* __GPG_KEYBOARDDEVICE_H__ */ diff --git a/source/gameengine/GamePlayer/ghost/GPG_System.h b/source/gameengine/GamePlayer/ghost/GPG_System.h index 796ad0c2b8c..d68fc812dd3 100644 --- a/source/gameengine/GamePlayer/ghost/GPG_System.h +++ b/source/gameengine/GamePlayer/ghost/GPG_System.h @@ -35,7 +35,7 @@ #ifdef WIN32 #pragma warning (disable:4786) // suppress stl-MSVC debug info warning -#endif // WIN32 +#endif /* WIN32 */ #include "GPC_System.h" @@ -51,5 +51,4 @@ public: virtual double GetTimeInSeconds(); }; -#endif // __GPG_SYSTEM_H__ - +#endif /* __GPG_SYSTEM_H__ */ diff --git a/source/gameengine/Ketsji/BL_Action.h b/source/gameengine/Ketsji/BL_Action.h index ab2adf7fe34..370bbf51d72 100644 --- a/source/gameengine/Ketsji/BL_Action.h +++ b/source/gameengine/Ketsji/BL_Action.h @@ -136,5 +136,4 @@ public: #endif }; -#endif //BL_ACTION - +#endif /* BL_ACTION */ diff --git a/source/gameengine/Ketsji/BL_ActionManager.h b/source/gameengine/Ketsji/BL_ActionManager.h index dbdaa6652ad..600e7b6621e 100644 --- a/source/gameengine/Ketsji/BL_ActionManager.h +++ b/source/gameengine/Ketsji/BL_ActionManager.h @@ -98,5 +98,4 @@ public: #endif }; -#endif //BL_ACTIONMANAGER - +#endif /* BL_ACTIONMANAGER */ diff --git a/source/gameengine/Ketsji/BL_BlenderShader.h b/source/gameengine/Ketsji/BL_BlenderShader.h index f23dbfdf3a5..626c65baadd 100644 --- a/source/gameengine/Ketsji/BL_BlenderShader.h +++ b/source/gameengine/Ketsji/BL_BlenderShader.h @@ -101,4 +101,4 @@ public: #endif }; -#endif//__BL_BLENDERSHADER_H__ +#endif /* __BL_BLENDERSHADER_H__ */ diff --git a/source/gameengine/Ketsji/BL_Shader.h b/source/gameengine/Ketsji/BL_Shader.h index b577a1849a0..82476873b85 100644 --- a/source/gameengine/Ketsji/BL_Shader.h +++ b/source/gameengine/Ketsji/BL_Shader.h @@ -252,4 +252,4 @@ public: #endif }; -#endif//__BL_SHADER_H__ +#endif /* __BL_SHADER_H__ */ diff --git a/source/gameengine/Ketsji/BL_Texture.h b/source/gameengine/Ketsji/BL_Texture.h index a6bd354d260..cd18ef93822 100644 --- a/source/gameengine/Ketsji/BL_Texture.h +++ b/source/gameengine/Ketsji/BL_Texture.h @@ -79,4 +79,4 @@ public: #endif }; -#endif//__BL_TEXTURE_H__ +#endif /* __BL_TEXTURE_H__ */ diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkEventManager.h b/source/gameengine/Ketsji/KXNetwork/KX_NetworkEventManager.h index 3202785ee81..9a13b6d53e2 100644 --- a/source/gameengine/Ketsji/KXNetwork/KX_NetworkEventManager.h +++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkEventManager.h @@ -52,5 +52,4 @@ public: return m_ndi; } }; -#endif //__KX_NETWORKEVENTMANAGER_H__ - +#endif /* __KX_NETWORKEVENTMANAGER_H__ */ diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.h b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.h index 980e1cda6dc..325a7be9bd7 100644 --- a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.h +++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.h @@ -69,5 +69,4 @@ public: }; -#endif //__KX_NETWORKMESSAGEACTUATOR_H__ - +#endif /* __KX_NETWORKMESSAGEACTUATOR_H__ */ diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h index 6b9779de6e3..a1f0692b7b3 100644 --- a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h +++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h @@ -83,9 +83,8 @@ public: static PyObject* pyattr_get_bodies(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef); static PyObject* pyattr_get_subjects(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef); -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ }; -#endif //__KX_NETWORKMESSAGESENSOR_H__ - +#endif /* __KX_NETWORKMESSAGESENSOR_H__ */ diff --git a/source/gameengine/Ketsji/KX_ArmatureSensor.h b/source/gameengine/Ketsji/KX_ArmatureSensor.h index 74603b3ff01..b3ea905d198 100644 --- a/source/gameengine/Ketsji/KX_ArmatureSensor.h +++ b/source/gameengine/Ketsji/KX_ArmatureSensor.h @@ -74,7 +74,7 @@ public: /* --------------------------------------------------------------------- */ static PyObject *pyattr_get_constraint(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef); -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ private: struct bConstraint* m_constraint; diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.h b/source/gameengine/Ketsji/KX_BlenderMaterial.h index a69f5c92d19..1653669ebcc 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.h +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.h @@ -119,7 +119,7 @@ public: KX_PYMETHOD_DOC(KX_BlenderMaterial, setTexture); KX_PYMETHOD_DOC(KX_BlenderMaterial, setBlending); -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ // -------------------------------- // pre calculate to avoid pops/lag at startup diff --git a/source/gameengine/Ketsji/KX_BulletPhysicsController.h b/source/gameengine/Ketsji/KX_BulletPhysicsController.h index 71e806686ca..4813b39a34e 100644 --- a/source/gameengine/Ketsji/KX_BulletPhysicsController.h +++ b/source/gameengine/Ketsji/KX_BulletPhysicsController.h @@ -96,5 +96,4 @@ public: #endif }; -#endif //__KX_BULLETPHYSICSCONTROLLER_H__ - +#endif /* __KX_BULLETPHYSICSCONTROLLER_H__ */ diff --git a/source/gameengine/Ketsji/KX_Camera.h b/source/gameengine/Ketsji/KX_Camera.h index d95d10e8384..6c1dc1edb51 100644 --- a/source/gameengine/Ketsji/KX_Camera.h +++ b/source/gameengine/Ketsji/KX_Camera.h @@ -321,5 +321,4 @@ public: #endif }; -#endif //__KX_CAMERA_H__ - +#endif /* __KX_CAMERA_H__ */ diff --git a/source/gameengine/Ketsji/KX_CameraActuator.h b/source/gameengine/Ketsji/KX_CameraActuator.h index c67174d2830..fb0a7d88dd9 100644 --- a/source/gameengine/Ketsji/KX_CameraActuator.h +++ b/source/gameengine/Ketsji/KX_CameraActuator.h @@ -131,9 +131,8 @@ private : static PyObject* pyattr_get_object(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); static int pyattr_set_object(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ }; -#endif //__KX_CAMERAACTUATOR_H__ - +#endif /* __KX_CAMERAACTUATOR_H__ */ diff --git a/source/gameengine/Ketsji/KX_CameraIpoSGController.h b/source/gameengine/Ketsji/KX_CameraIpoSGController.h index 9b7c1eddf00..1f6f211622c 100644 --- a/source/gameengine/Ketsji/KX_CameraIpoSGController.h +++ b/source/gameengine/Ketsji/KX_CameraIpoSGController.h @@ -94,5 +94,4 @@ public: #endif }; -#endif // __KX_CAMERAIPOSGCONTROLLER_H__ - +#endif /* __KX_CAMERAIPOSGCONTROLLER_H__ */ diff --git a/source/gameengine/Ketsji/KX_ClientObjectInfo.h b/source/gameengine/Ketsji/KX_ClientObjectInfo.h index 6fd1271160a..e947eb4be6d 100644 --- a/source/gameengine/Ketsji/KX_ClientObjectInfo.h +++ b/source/gameengine/Ketsji/KX_ClientObjectInfo.h @@ -84,5 +84,4 @@ public: #endif }; -#endif //__KX_CLIENTOBJECTINFO_H__ - +#endif /* __KX_CLIENTOBJECTINFO_H__ */ diff --git a/source/gameengine/Ketsji/KX_ConstraintActuator.h b/source/gameengine/Ketsji/KX_ConstraintActuator.h index 786e4ff53d2..edb2e5e0180 100644 --- a/source/gameengine/Ketsji/KX_ConstraintActuator.h +++ b/source/gameengine/Ketsji/KX_ConstraintActuator.h @@ -145,5 +145,4 @@ protected: }; -#endif //__KX_CONSTRAINTACTUATOR_H__ - +#endif /* __KX_CONSTRAINTACTUATOR_H__ */ diff --git a/source/gameengine/Ketsji/KX_ConstraintWrapper.h b/source/gameengine/Ketsji/KX_ConstraintWrapper.h index dbc3571cad6..eafc45b5a70 100644 --- a/source/gameengine/Ketsji/KX_ConstraintWrapper.h +++ b/source/gameengine/Ketsji/KX_ConstraintWrapper.h @@ -57,5 +57,4 @@ private: PHY_IPhysicsEnvironment* m_physenv; }; -#endif //__KX_CONSTRAINTWRAPPER_H__ - +#endif /* __KX_CONSTRAINTWRAPPER_H__ */ diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h b/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h index 0f1ce403881..e71037d08a0 100644 --- a/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h +++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h @@ -159,4 +159,4 @@ void KX_ClearBulletSharedShapes(); bool KX_ReInstanceBulletShapeFromMesh(KX_GameObject *gameobj, KX_GameObject *from_gameobj, RAS_MeshObject* from_meshobj); #endif -#endif //__KX_CONVERTPHYSICSOBJECT_H__ +#endif /* __KX_CONVERTPHYSICSOBJECT_H__ */ diff --git a/source/gameengine/Ketsji/KX_EmptyObject.h b/source/gameengine/Ketsji/KX_EmptyObject.h index b99f44c38c5..63a0782a544 100644 --- a/source/gameengine/Ketsji/KX_EmptyObject.h +++ b/source/gameengine/Ketsji/KX_EmptyObject.h @@ -47,5 +47,4 @@ public: #endif }; -#endif //__KX_EMPTYOBJECT_H__ - +#endif /* __KX_EMPTYOBJECT_H__ */ diff --git a/source/gameengine/Ketsji/KX_FontObject.h b/source/gameengine/Ketsji/KX_FontObject.h index ae8b4166238..ac22de6fb6f 100644 --- a/source/gameengine/Ketsji/KX_FontObject.h +++ b/source/gameengine/Ketsji/KX_FontObject.h @@ -76,4 +76,4 @@ protected: }; -#endif //__KX_FONTOBJECT_H__ +#endif /* __KX_FONTOBJECT_H__ */ diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h index 621dd988e00..52fc3da5465 100644 --- a/source/gameengine/Ketsji/KX_GameObject.h +++ b/source/gameengine/Ketsji/KX_GameObject.h @@ -1041,5 +1041,4 @@ public: -#endif //__KX_GAMEOBJECT_H__ - +#endif /* __KX_GAMEOBJECT_H__ */ diff --git a/source/gameengine/Ketsji/KX_IPO_SGController.h b/source/gameengine/Ketsji/KX_IPO_SGController.h index 266b89ff969..cecfa9804db 100644 --- a/source/gameengine/Ketsji/KX_IPO_SGController.h +++ b/source/gameengine/Ketsji/KX_IPO_SGController.h @@ -126,6 +126,4 @@ public: #endif }; -#endif //__KX_IPO_SGCONTROLLER_H__ - - +#endif /* __KX_IPO_SGCONTROLLER_H__ */ diff --git a/source/gameengine/Ketsji/KX_IPhysicsController.h b/source/gameengine/Ketsji/KX_IPhysicsController.h index dd34549c1fb..280b1816a1e 100644 --- a/source/gameengine/Ketsji/KX_IPhysicsController.h +++ b/source/gameengine/Ketsji/KX_IPhysicsController.h @@ -145,5 +145,4 @@ public: #endif }; -#endif //__KX_IPHYSICSCONTROLLER_H__ - +#endif /* __KX_IPHYSICSCONTROLLER_H__ */ diff --git a/source/gameengine/Ketsji/KX_ISceneConverter.h b/source/gameengine/Ketsji/KX_ISceneConverter.h index 919ae1d6de5..18fb336dbe0 100644 --- a/source/gameengine/Ketsji/KX_ISceneConverter.h +++ b/source/gameengine/Ketsji/KX_ISceneConverter.h @@ -93,5 +93,4 @@ public: #endif }; -#endif //__KX_ISCENECONVERTER_H__ - +#endif /* __KX_ISCENECONVERTER_H__ */ diff --git a/source/gameengine/Ketsji/KX_IpoActuator.h b/source/gameengine/Ketsji/KX_IpoActuator.h index 58cdfc28742..1c2f4e49b72 100644 --- a/source/gameengine/Ketsji/KX_IpoActuator.h +++ b/source/gameengine/Ketsji/KX_IpoActuator.h @@ -150,5 +150,4 @@ public: }; -#endif //__KX_IPOACTUATOR_H__ - +#endif /* __KX_IPOACTUATOR_H__ */ diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.h b/source/gameengine/Ketsji/KX_KetsjiEngine.h index e05ba652bbe..972594bd90f 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.h +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.h @@ -447,6 +447,4 @@ protected: #endif }; -#endif //__KX_KETSJIENGINE_H__ - - +#endif /* __KX_KETSJIENGINE_H__ */ diff --git a/source/gameengine/Ketsji/KX_Light.h b/source/gameengine/Ketsji/KX_Light.h index 7426896a92a..52f076c772a 100644 --- a/source/gameengine/Ketsji/KX_Light.h +++ b/source/gameengine/Ketsji/KX_Light.h @@ -83,5 +83,4 @@ public: #endif }; -#endif //__KX_LIGHT_H__ - +#endif /* __KX_LIGHT_H__ */ diff --git a/source/gameengine/Ketsji/KX_LightIpoSGController.h b/source/gameengine/Ketsji/KX_LightIpoSGController.h index 4a1ceba0963..c82fe7bcad5 100644 --- a/source/gameengine/Ketsji/KX_LightIpoSGController.h +++ b/source/gameengine/Ketsji/KX_LightIpoSGController.h @@ -102,5 +102,4 @@ public: #endif }; -#endif // __KX_LIGHTIPOSGCONTROLLER_H__ - +#endif /* __KX_LIGHTIPOSGCONTROLLER_H__ */ diff --git a/source/gameengine/Ketsji/KX_MaterialIpoController.h b/source/gameengine/Ketsji/KX_MaterialIpoController.h index ee5546641c2..a7e9c2cc1c5 100644 --- a/source/gameengine/Ketsji/KX_MaterialIpoController.h +++ b/source/gameengine/Ketsji/KX_MaterialIpoController.h @@ -62,7 +62,4 @@ public: #endif }; - - - -#endif//__KX_MATERIALIPOCONTROLLER_H__ +#endif /* __KX_MATERIALIPOCONTROLLER_H__ */ diff --git a/source/gameengine/Ketsji/KX_MeshProxy.h b/source/gameengine/Ketsji/KX_MeshProxy.h index a05ef6ab2e7..98e73aa626f 100644 --- a/source/gameengine/Ketsji/KX_MeshProxy.h +++ b/source/gameengine/Ketsji/KX_MeshProxy.h @@ -77,7 +77,6 @@ public: static PyObject *pyattr_get_numPolygons(void * self, const KX_PYATTRIBUTE_DEF * attrdef); }; -#endif // WITH_PYTHON - -#endif //__KX_MESHPROXY_H__ +#endif /* WITH_PYTHON */ +#endif /* __KX_MESHPROXY_H__ */ diff --git a/source/gameengine/Ketsji/KX_MotionState.h b/source/gameengine/Ketsji/KX_MotionState.h index 3bead93cbda..116e62f408f 100644 --- a/source/gameengine/Ketsji/KX_MotionState.h +++ b/source/gameengine/Ketsji/KX_MotionState.h @@ -62,5 +62,4 @@ public: #endif }; -#endif //__KX_MOTIONSTATE_H__ - +#endif /* __KX_MOTIONSTATE_H__ */ diff --git a/source/gameengine/Ketsji/KX_MouseFocusSensor.h b/source/gameengine/Ketsji/KX_MouseFocusSensor.h index db9e3697492..a8376dcb4fb 100644 --- a/source/gameengine/Ketsji/KX_MouseFocusSensor.h +++ b/source/gameengine/Ketsji/KX_MouseFocusSensor.h @@ -111,7 +111,7 @@ class KX_MouseFocusSensor : public SCA_MouseSensor static PyObject* pyattr_get_hit_normal(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef); static PyObject* pyattr_get_hit_uv(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef); -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ /* --------------------------------------------------------------------- */ SCA_IObject* m_hitObject; @@ -183,5 +183,4 @@ class KX_MouseFocusSensor : public SCA_MouseSensor KX_KetsjiEngine* m_kxengine; }; -#endif //__KX_MOUSESENSOR - +#endif /* __KX_MOUSESENSOR */ diff --git a/source/gameengine/Ketsji/KX_NavMeshObject.h b/source/gameengine/Ketsji/KX_NavMeshObject.h index db35a011c16..1599361b334 100644 --- a/source/gameengine/Ketsji/KX_NavMeshObject.h +++ b/source/gameengine/Ketsji/KX_NavMeshObject.h @@ -74,8 +74,7 @@ public: KX_PYMETHOD_DOC(KX_NavMeshObject, raycast); KX_PYMETHOD_DOC(KX_NavMeshObject, draw); KX_PYMETHOD_DOC_NOARGS(KX_NavMeshObject, rebuild); -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ }; -#endif //__KX_NAVMESHOBJECT_H__ - +#endif /* __KX_NAVMESHOBJECT_H__ */ diff --git a/source/gameengine/Ketsji/KX_NearSensor.h b/source/gameengine/Ketsji/KX_NearSensor.h index 82f523283ed..ef6e15f602f 100644 --- a/source/gameengine/Ketsji/KX_NearSensor.h +++ b/source/gameengine/Ketsji/KX_NearSensor.h @@ -100,9 +100,8 @@ public: return 0; } -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ }; -#endif //__KX_NEARSENSOR_H__ - +#endif /* __KX_NEARSENSOR_H__ */ diff --git a/source/gameengine/Ketsji/KX_ObColorIpoSGController.h b/source/gameengine/Ketsji/KX_ObColorIpoSGController.h index 9a9b3dac098..a7b0b2c4ffc 100644 --- a/source/gameengine/Ketsji/KX_ObColorIpoSGController.h +++ b/source/gameengine/Ketsji/KX_ObColorIpoSGController.h @@ -77,5 +77,4 @@ public: #endif }; -#endif // __KX_OBCOLORIPOSGCONTROLLER_H__ - +#endif /* __KX_OBCOLORIPOSGCONTROLLER_H__ */ diff --git a/source/gameengine/Ketsji/KX_ObjectActuator.h b/source/gameengine/Ketsji/KX_ObjectActuator.h index 397234488b7..b0efee550af 100644 --- a/source/gameengine/Ketsji/KX_ObjectActuator.h +++ b/source/gameengine/Ketsji/KX_ObjectActuator.h @@ -218,9 +218,8 @@ public: return 0; } -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ }; -#endif //__KX_OBJECTACTUATOR_H__ - +#endif /* __KX_OBJECTACTUATOR_H__ */ diff --git a/source/gameengine/Ketsji/KX_ParentActuator.h b/source/gameengine/Ketsji/KX_ParentActuator.h index f2f5acd3dfb..40baac6b2b2 100644 --- a/source/gameengine/Ketsji/KX_ParentActuator.h +++ b/source/gameengine/Ketsji/KX_ParentActuator.h @@ -84,9 +84,8 @@ public: static PyObject *pyattr_get_object(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef); static int pyattr_set_object(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ }; /* end of class KX_ParentActuator : public SCA_PropertyActuator */ -#endif - +#endif /* __KX_PARENTACTUATOR_H__ */ diff --git a/source/gameengine/Ketsji/KX_PhysicsEngineEnums.h b/source/gameengine/Ketsji/KX_PhysicsEngineEnums.h index 5cebedf8c30..ca99c2e7526 100644 --- a/source/gameengine/Ketsji/KX_PhysicsEngineEnums.h +++ b/source/gameengine/Ketsji/KX_PhysicsEngineEnums.h @@ -39,5 +39,4 @@ enum e_PhysicsEngine UseBullet = 5, }; -#endif //__KX_PHYSICSENGINEENUMS_H__ - +#endif /* __KX_PHYSICSENGINEENUMS_H__ */ diff --git a/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.h b/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.h index a074ff9a3bd..171416c5e8f 100644 --- a/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.h +++ b/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.h @@ -49,12 +49,11 @@ public: KX_PYMETHOD_VARARGS(KX_PhysicsObjectWrapper,SetAngularVelocity); KX_PYMETHOD_VARARGS(KX_PhysicsObjectWrapper,SetActive); -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ private: class PHY_IPhysicsController* m_ctrl; PHY_IPhysicsEnvironment* m_physenv; }; -#endif //__KX_PHYSICSOBJECTWRAPPER_H__ - +#endif /* __KX_PHYSICSOBJECTWRAPPER_H__ */ diff --git a/source/gameengine/Ketsji/KX_PhysicsPropertiesobsolete.h b/source/gameengine/Ketsji/KX_PhysicsPropertiesobsolete.h index 86ba2500763..ee685edb9c1 100644 --- a/source/gameengine/Ketsji/KX_PhysicsPropertiesobsolete.h +++ b/source/gameengine/Ketsji/KX_PhysicsPropertiesobsolete.h @@ -58,5 +58,4 @@ struct KX_MaterialProps { bool m_fh_normal; // Should the object slide off slopes? }; -#endif //__KX_PHYSICSPROPERTIESOBSOLETE_H__ - +#endif /* __KX_PHYSICSPROPERTIESOBSOLETE_H__ */ diff --git a/source/gameengine/Ketsji/KX_PolyProxy.h b/source/gameengine/Ketsji/KX_PolyProxy.h index 9e3556a03f8..f02aa90998e 100644 --- a/source/gameengine/Ketsji/KX_PolyProxy.h +++ b/source/gameengine/Ketsji/KX_PolyProxy.h @@ -80,7 +80,6 @@ public: }; -#endif // WITH_PYTHON - -#endif //__KX_POLYPROXY +#endif /* WITH_PYTHON */ +#endif /* __KX_POLYPROXY */ diff --git a/source/gameengine/Ketsji/KX_PolygonMaterial.h b/source/gameengine/Ketsji/KX_PolygonMaterial.h index 6384008fb7d..89bfb4ff9fb 100644 --- a/source/gameengine/Ketsji/KX_PolygonMaterial.h +++ b/source/gameengine/Ketsji/KX_PolygonMaterial.h @@ -153,5 +153,4 @@ public: }; -#endif // __KX_POLYGONMATERIAL_H__ - +#endif /* __KX_POLYGONMATERIAL_H__ */ diff --git a/source/gameengine/Ketsji/KX_PyConstraintBinding.h b/source/gameengine/Ketsji/KX_PyConstraintBinding.h index 69a6e333cee..b4a520ce71b 100644 --- a/source/gameengine/Ketsji/KX_PyConstraintBinding.h +++ b/source/gameengine/Ketsji/KX_PyConstraintBinding.h @@ -39,7 +39,6 @@ PyObject* initPythonConstraintBinding(); void PHY_SetActiveEnvironment(class PHY_IPhysicsEnvironment* env); PHY_IPhysicsEnvironment* PHY_GetActiveEnvironment(); -#endif // WITH_PYTHON - -#endif //__KX_PYCONSTRAINTBINDING_H__ +#endif /* WITH_PYTHON */ +#endif /* __KX_PYCONSTRAINTBINDING_H__ */ diff --git a/source/gameengine/Ketsji/KX_PyMath.h b/source/gameengine/Ketsji/KX_PyMath.h index d79397ed807..159506946e8 100644 --- a/source/gameengine/Ketsji/KX_PyMath.h +++ b/source/gameengine/Ketsji/KX_PyMath.h @@ -273,4 +273,4 @@ PyObject *PyObjectFrom(const MT_Tuple4 &pos); #endif -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ diff --git a/source/gameengine/Ketsji/KX_PythonInit.h b/source/gameengine/Ketsji/KX_PythonInit.h index 69517b2b1e9..859c31adcd3 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.h +++ b/source/gameengine/Ketsji/KX_PythonInit.h @@ -89,5 +89,4 @@ void KX_RasterizerDrawDebugCircle(const MT_Vector3& center, const MT_Scalar rad const MT_Vector3& normal, int nsector); -#endif //__KX_PYTHONINIT_H__ - +#endif /* __KX_PYTHONINIT_H__ */ diff --git a/source/gameengine/Ketsji/KX_PythonSeq.h b/source/gameengine/Ketsji/KX_PythonSeq.h index 47a01737cdb..568d59119c0 100644 --- a/source/gameengine/Ketsji/KX_PythonSeq.h +++ b/source/gameengine/Ketsji/KX_PythonSeq.h @@ -30,8 +30,8 @@ * \brief Readonly sequence wrapper for lookups on logic bricks */ -#ifndef _adr_py_seq_h_ // only process once, -#define _adr_py_seq_h_ // even if multiply included +#ifndef __KX_PYTHONSEQ_H__ +#define __KX_PYTHONSEQ_H__ #ifdef WITH_PYTHON @@ -63,6 +63,6 @@ typedef struct { PyObject *KX_PythonSeq_CreatePyObject(PyObject *base, short type); -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ -#endif // _adr_py_seq_h_ +#endif /* __KX_PYTHONSEQ_H__ */ diff --git a/source/gameengine/Ketsji/KX_RadarSensor.h b/source/gameengine/Ketsji/KX_RadarSensor.h index 2de58f8b3a0..6a2d50ffa3a 100644 --- a/source/gameengine/Ketsji/KX_RadarSensor.h +++ b/source/gameengine/Ketsji/KX_RadarSensor.h @@ -97,5 +97,4 @@ public: #endif }; -#endif //__KX_RADARSENSOR_H__ - +#endif /* __KX_RADARSENSOR_H__ */ diff --git a/source/gameengine/Ketsji/KX_RayEventManager.h b/source/gameengine/Ketsji/KX_RayEventManager.h index f795495d1c9..07506b9e32b 100644 --- a/source/gameengine/Ketsji/KX_RayEventManager.h +++ b/source/gameengine/Ketsji/KX_RayEventManager.h @@ -50,5 +50,4 @@ public: #endif }; -#endif //__KX_RAYEVENTMANAGER_H__ - +#endif /* __KX_RAYEVENTMANAGER_H__ */ diff --git a/source/gameengine/Ketsji/KX_RaySensor.h b/source/gameengine/Ketsji/KX_RaySensor.h index 27aaa442dcd..9d40fb55747 100644 --- a/source/gameengine/Ketsji/KX_RaySensor.h +++ b/source/gameengine/Ketsji/KX_RaySensor.h @@ -96,9 +96,8 @@ public: /* Attributes */ static PyObject *pyattr_get_hitobject(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ }; -#endif //__KX_RAYSENSOR_H__ - +#endif /* __KX_RAYSENSOR_H__ */ diff --git a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h index 9c8cbfa3d09..7dac93acd21 100644 --- a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h +++ b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h @@ -126,9 +126,8 @@ public: static int pyattr_set_object(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); static PyObject *pyattr_get_objectLastCreated(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef); -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ }; /* end of class KX_SCA_AddObjectActuator : public KX_EditObjectActuator */ -#endif - +#endif /* __KX_SCA_ADDOBJECTACTUATOR_H__ */ diff --git a/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h b/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h index 52a20142442..4370b5d4a4f 100644 --- a/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h +++ b/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h @@ -89,9 +89,8 @@ class KX_SCA_ReplaceMeshActuator : public SCA_IActuator KX_PYMETHOD_DOC(KX_SCA_ReplaceMeshActuator,instantReplaceMesh); -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ }; -#endif - +#endif /* __KX_SCA_REPLACEMESHACTUATOR_H__ */ diff --git a/source/gameengine/Ketsji/KX_Scene.h b/source/gameengine/Ketsji/KX_Scene.h index bb329da99de..c2e468e6da6 100644 --- a/source/gameengine/Ketsji/KX_Scene.h +++ b/source/gameengine/Ketsji/KX_Scene.h @@ -665,5 +665,4 @@ public: typedef std::vector KX_SceneList; -#endif //__KX_SCENE_H__ - +#endif /* __KX_SCENE_H__ */ diff --git a/source/gameengine/Ketsji/KX_SceneActuator.h b/source/gameengine/Ketsji/KX_SceneActuator.h index 0b633334cce..389e9208ef3 100644 --- a/source/gameengine/Ketsji/KX_SceneActuator.h +++ b/source/gameengine/Ketsji/KX_SceneActuator.h @@ -102,9 +102,8 @@ class KX_SceneActuator : public SCA_IActuator static PyObject *pyattr_get_camera(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef); static int pyattr_set_camera(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ }; /* end of class KXSceneActuator */ #endif - diff --git a/source/gameengine/Ketsji/KX_SoundActuator.h b/source/gameengine/Ketsji/KX_SoundActuator.h index fcaf214dd90..1ce44e942e8 100644 --- a/source/gameengine/Ketsji/KX_SoundActuator.h +++ b/source/gameengine/Ketsji/KX_SoundActuator.h @@ -122,9 +122,8 @@ public: static PyObject *pyattr_get_type(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef); static PyObject *pyattr_get_sound(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef); -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ }; -#endif //__KX_SOUNDACTUATOR_H__ - +#endif /* __KX_SOUNDACTUATOR_H__ */ diff --git a/source/gameengine/Ketsji/KX_SteeringActuator.h b/source/gameengine/Ketsji/KX_SteeringActuator.h index 341421d8948..1e8ac9a54f0 100644 --- a/source/gameengine/Ketsji/KX_SteeringActuator.h +++ b/source/gameengine/Ketsji/KX_SteeringActuator.h @@ -114,9 +114,8 @@ public: static PyObject *pyattr_get_steeringVec(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef); -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ }; /* end of class KX_SteeringActuator : public SCA_PropertyActuator */ -#endif - +#endif /* __KX_STEERINGACTUATOR_H__ */ diff --git a/source/gameengine/Ketsji/KX_TimeCategoryLogger.h b/source/gameengine/Ketsji/KX_TimeCategoryLogger.h index ea780739695..d167d0addfe 100644 --- a/source/gameengine/Ketsji/KX_TimeCategoryLogger.h +++ b/source/gameengine/Ketsji/KX_TimeCategoryLogger.h @@ -133,5 +133,4 @@ protected: #endif }; -#endif // __KX_TIMECATEGORYLOGGER_H__ - +#endif /* __KX_TIMECATEGORYLOGGER_H__ */ diff --git a/source/gameengine/Ketsji/KX_TimeLogger.h b/source/gameengine/Ketsji/KX_TimeLogger.h index 83c934ea81b..bafc27b504c 100644 --- a/source/gameengine/Ketsji/KX_TimeLogger.h +++ b/source/gameengine/Ketsji/KX_TimeLogger.h @@ -111,5 +111,4 @@ protected: #endif }; -#endif // __KX_TIMELOGGER_H__ - +#endif /* __KX_TIMELOGGER_H__ */ diff --git a/source/gameengine/Ketsji/KX_TouchEventManager.h b/source/gameengine/Ketsji/KX_TouchEventManager.h index d9a0164fd05..63e9d15959e 100644 --- a/source/gameengine/Ketsji/KX_TouchEventManager.h +++ b/source/gameengine/Ketsji/KX_TouchEventManager.h @@ -85,5 +85,4 @@ public: #endif }; -#endif //__KX_TOUCHEVENTMANAGER_H__ - +#endif /* __KX_TOUCHEVENTMANAGER_H__ */ diff --git a/source/gameengine/Ketsji/KX_TouchSensor.h b/source/gameengine/Ketsji/KX_TouchSensor.h index c80b8598e43..6bd606db8eb 100644 --- a/source/gameengine/Ketsji/KX_TouchSensor.h +++ b/source/gameengine/Ketsji/KX_TouchSensor.h @@ -134,5 +134,4 @@ public: }; -#endif //__KX_TOUCHSENSOR_H__ - +#endif /* __KX_TOUCHSENSOR_H__ */ diff --git a/source/gameengine/Ketsji/KX_TrackToActuator.h b/source/gameengine/Ketsji/KX_TrackToActuator.h index 6329c7b34d9..f5f5c4c2836 100644 --- a/source/gameengine/Ketsji/KX_TrackToActuator.h +++ b/source/gameengine/Ketsji/KX_TrackToActuator.h @@ -77,9 +77,8 @@ class KX_TrackToActuator : public SCA_IActuator static PyObject *pyattr_get_object(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef); static int pyattr_set_object(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ }; /* end of class KX_TrackToActuator : public KX_EditObjectActuator */ -#endif - +#endif /* __KX_TRACKTOACTUATOR_H__ */ diff --git a/source/gameengine/Ketsji/KX_VehicleWrapper.h b/source/gameengine/Ketsji/KX_VehicleWrapper.h index 3684019277c..ccd666e84f3 100644 --- a/source/gameengine/Ketsji/KX_VehicleWrapper.h +++ b/source/gameengine/Ketsji/KX_VehicleWrapper.h @@ -52,11 +52,11 @@ public: KX_PYMETHOD_VARARGS(KX_VehicleWrapper,SetSuspensionCompression); KX_PYMETHOD_VARARGS(KX_VehicleWrapper,SetRollInfluence); -#endif // WITH_PYTHON +#endif /* WITH_PYTHON */ private: PHY_IVehicle* m_vehicle; PHY_IPhysicsEnvironment* m_physenv; }; -#endif //__KX_VEHICLEWRAPPER_H__ +#endif /* __KX_VEHICLEWRAPPER_H__ */ diff --git a/source/gameengine/Ketsji/KX_VertexProxy.h b/source/gameengine/Ketsji/KX_VertexProxy.h index f56e2be26a3..6e193d35b4c 100644 --- a/source/gameengine/Ketsji/KX_VertexProxy.h +++ b/source/gameengine/Ketsji/KX_VertexProxy.h @@ -105,7 +105,6 @@ public: }; -#endif // WITH_PYTHON - -#endif //__KX_VERTEXPROXY_H__ +#endif /* WITH_PYTHON */ +#endif /* __KX_VERTEXPROXY_H__ */ diff --git a/source/gameengine/Ketsji/KX_WorldInfo.h b/source/gameengine/Ketsji/KX_WorldInfo.h index 5b35ca2ec54..a64ca5c191e 100644 --- a/source/gameengine/Ketsji/KX_WorldInfo.h +++ b/source/gameengine/Ketsji/KX_WorldInfo.h @@ -74,5 +74,4 @@ public: #endif }; -#endif //__KX_WORLDINFO_H__ - +#endif /* __KX_WORLDINFO_H__ */ diff --git a/source/gameengine/Ketsji/KX_WorldIpoController.h b/source/gameengine/Ketsji/KX_WorldIpoController.h index 575d4e72f14..63983b3129b 100644 --- a/source/gameengine/Ketsji/KX_WorldIpoController.h +++ b/source/gameengine/Ketsji/KX_WorldIpoController.h @@ -100,5 +100,4 @@ public: #endif }; -#endif // __KX_WORLDIPOCONTROLLER_H__ - +#endif /* __KX_WORLDIPOCONTROLLER_H__ */ diff --git a/source/gameengine/Network/LoopBackNetwork/NG_LoopBackNetworkDeviceInterface.h b/source/gameengine/Network/LoopBackNetwork/NG_LoopBackNetworkDeviceInterface.h index f9d2146a766..7581486c80a 100644 --- a/source/gameengine/Network/LoopBackNetwork/NG_LoopBackNetworkDeviceInterface.h +++ b/source/gameengine/Network/LoopBackNetwork/NG_LoopBackNetworkDeviceInterface.h @@ -60,5 +60,4 @@ public: virtual std::vector RetrieveNetworkMessages(); }; -#endif //__NG_LOOPBACKNETWORKDEVICEINTERFACE_H__ - +#endif /* __NG_LOOPBACKNETWORKDEVICEINTERFACE_H__ */ diff --git a/source/gameengine/Network/NG_NetworkDeviceInterface.h b/source/gameengine/Network/NG_NetworkDeviceInterface.h index 8f903cc64fa..48edbdfc7fe 100644 --- a/source/gameengine/Network/NG_NetworkDeviceInterface.h +++ b/source/gameengine/Network/NG_NetworkDeviceInterface.h @@ -79,5 +79,4 @@ public: #endif }; -#endif //__NG_NETWORKDEVICEINTERFACE_H__ - +#endif /* __NG_NETWORKDEVICEINTERFACE_H__ */ diff --git a/source/gameengine/Network/NG_NetworkMessage.h b/source/gameengine/Network/NG_NetworkMessage.h index 25e7fd97596..5185849f8d7 100644 --- a/source/gameengine/Network/NG_NetworkMessage.h +++ b/source/gameengine/Network/NG_NetworkMessage.h @@ -135,5 +135,4 @@ public: #endif }; -#endif //__NG_NETWORKMESSAGE_H__ - +#endif /* __NG_NETWORKMESSAGE_H__ */ diff --git a/source/gameengine/Network/NG_NetworkObject.h b/source/gameengine/Network/NG_NetworkObject.h index b9858cd8d43..54459cad55d 100644 --- a/source/gameengine/Network/NG_NetworkObject.h +++ b/source/gameengine/Network/NG_NetworkObject.h @@ -52,5 +52,4 @@ public: #endif }; -#endif //__NG_NETWORKOBJECT_H__ - +#endif /* __NG_NETWORKOBJECT_H__ */ diff --git a/source/gameengine/Network/NG_NetworkScene.h b/source/gameengine/Network/NG_NetworkScene.h index 381b71da0d7..10dad210128 100644 --- a/source/gameengine/Network/NG_NetworkScene.h +++ b/source/gameengine/Network/NG_NetworkScene.h @@ -115,5 +115,4 @@ protected: #endif }; -#endif //__NG_NETWORKSCENE_H__ - +#endif /* __NG_NETWORKSCENE_H__ */ diff --git a/source/gameengine/Physics/Bullet/CcdGraphicController.h b/source/gameengine/Physics/Bullet/CcdGraphicController.h index 15edfeb5759..72eb699ce5b 100644 --- a/source/gameengine/Physics/Bullet/CcdGraphicController.h +++ b/source/gameengine/Physics/Bullet/CcdGraphicController.h @@ -87,4 +87,4 @@ private: #endif }; -#endif //BULLET2_PHYSICSCONTROLLER_H +#endif /* BULLET2_PHYSICSCONTROLLER_H */ diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.h b/source/gameengine/Physics/Bullet/CcdPhysicsController.h index 2204f224e7d..6df5c85f5c0 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsController.h +++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.h @@ -665,4 +665,4 @@ class DefaultMotionState : public PHY_IMotionState }; -#endif //__CCDPHYSICSCONTROLLER_H__ +#endif /* __CCDPHYSICSCONTROLLER_H__ */ diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h index 453380b69ca..350ecd2588a 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h +++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h @@ -183,7 +183,7 @@ protected: { return 0; } -#endif //NEW_BULLET_VEHICLE_SUPPORT +#endif /* NEW_BULLET_VEHICLE_SUPPORT */ btTypedConstraint* getConstraintById(int constraintId); @@ -297,4 +297,4 @@ protected: #endif }; -#endif //__CCDPHYSICSENVIRONMENT_H__ +#endif /* __CCDPHYSICSENVIRONMENT_H__ */ diff --git a/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h b/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h index 4ddfe4d69e0..70de9c25553 100644 --- a/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h +++ b/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h @@ -102,5 +102,4 @@ public: #endif }; -#endif //__DUMMYPHYSICSENVIRONMENT_H__ - +#endif /* __DUMMYPHYSICSENVIRONMENT_H__ */ diff --git a/source/gameengine/Physics/common/PHY_DynamicTypes.h b/source/gameengine/Physics/common/PHY_DynamicTypes.h index 6994706ce2d..0fe2533cf93 100644 --- a/source/gameengine/Physics/common/PHY_DynamicTypes.h +++ b/source/gameengine/Physics/common/PHY_DynamicTypes.h @@ -151,4 +151,4 @@ typedef enum PHY_ShapeType { typedef float PHY_Vector3[3]; -#endif //__PHY_DYNAMICTYPES_H__ +#endif /* __PHY_DYNAMICTYPES_H__ */ diff --git a/source/gameengine/Physics/common/PHY_IController.h b/source/gameengine/Physics/common/PHY_IController.h index 729abd8ec04..003c4edf598 100644 --- a/source/gameengine/Physics/common/PHY_IController.h +++ b/source/gameengine/Physics/common/PHY_IController.h @@ -60,5 +60,4 @@ class PHY_IController #endif }; -#endif //__PHY_ICONTROLLER_H__ - +#endif /* __PHY_ICONTROLLER_H__ */ diff --git a/source/gameengine/Physics/common/PHY_IGraphicController.h b/source/gameengine/Physics/common/PHY_IGraphicController.h index af337188818..cb13eda4f18 100644 --- a/source/gameengine/Physics/common/PHY_IGraphicController.h +++ b/source/gameengine/Physics/common/PHY_IGraphicController.h @@ -58,5 +58,4 @@ class PHY_IGraphicController : public PHY_IController #endif }; -#endif //__PHY_IGRAPHICCONTROLLER_H__ - +#endif /* __PHY_IGRAPHICCONTROLLER_H__ */ diff --git a/source/gameengine/Physics/common/PHY_IMotionState.h b/source/gameengine/Physics/common/PHY_IMotionState.h index 72ff37468ee..ccf7cf74724 100644 --- a/source/gameengine/Physics/common/PHY_IMotionState.h +++ b/source/gameengine/Physics/common/PHY_IMotionState.h @@ -65,5 +65,4 @@ class PHY_IMotionState #endif }; -#endif //__PHY_IMOTIONSTATE_H__ - +#endif /* __PHY_IMOTIONSTATE_H__ */ diff --git a/source/gameengine/Physics/common/PHY_IPhysicsController.h b/source/gameengine/Physics/common/PHY_IPhysicsController.h index 7eea2a183a1..bc7671abe80 100644 --- a/source/gameengine/Physics/common/PHY_IPhysicsController.h +++ b/source/gameengine/Physics/common/PHY_IPhysicsController.h @@ -108,5 +108,4 @@ class PHY_IPhysicsController : public PHY_IController #endif }; -#endif //__PHY_IPHYSICSCONTROLLER_H__ - +#endif /* __PHY_IPHYSICSCONTROLLER_H__ */ diff --git a/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h b/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h index 77016859c3f..66ca037aa47 100644 --- a/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h +++ b/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h @@ -185,5 +185,4 @@ class PHY_IPhysicsEnvironment #endif }; -#endif //__PHY_IPHYSICSENVIRONMENT_H__ - +#endif /* __PHY_IPHYSICSENVIRONMENT_H__ */ diff --git a/source/gameengine/Physics/common/PHY_IVehicle.h b/source/gameengine/Physics/common/PHY_IVehicle.h index 731e22d9f0f..ecf7a87c40f 100644 --- a/source/gameengine/Physics/common/PHY_IVehicle.h +++ b/source/gameengine/Physics/common/PHY_IVehicle.h @@ -66,4 +66,4 @@ public: #endif }; -#endif //__PHY_IVEHICLE_H__ +#endif /* __PHY_IVEHICLE_H__ */ diff --git a/source/gameengine/Physics/common/PHY_Pro.h b/source/gameengine/Physics/common/PHY_Pro.h index b930177d3a8..7c5d9c9638e 100644 --- a/source/gameengine/Physics/common/PHY_Pro.h +++ b/source/gameengine/Physics/common/PHY_Pro.h @@ -62,5 +62,4 @@ struct PHY_MaterialProps { bool m_fh_normal; // Should the object slide off slopes? }; -#endif //__PHY_PRO_H__ - +#endif /* __PHY_PRO_H__ */ diff --git a/source/gameengine/Rasterizer/RAS_BucketManager.h b/source/gameengine/Rasterizer/RAS_BucketManager.h index 2650bc9f722..c85a9f65d27 100644 --- a/source/gameengine/Rasterizer/RAS_BucketManager.h +++ b/source/gameengine/Rasterizer/RAS_BucketManager.h @@ -90,5 +90,4 @@ private: #endif }; -#endif //__RAS_BUCKETMANAGER_H__ - +#endif /* __RAS_BUCKETMANAGER_H__ */ diff --git a/source/gameengine/Rasterizer/RAS_CameraData.h b/source/gameengine/Rasterizer/RAS_CameraData.h index 4a70df6e505..7a6bb541a1a 100644 --- a/source/gameengine/Rasterizer/RAS_CameraData.h +++ b/source/gameengine/Rasterizer/RAS_CameraData.h @@ -71,5 +71,4 @@ struct RAS_CameraData } }; -#endif //__RAS_CAMERADATA_H__ - +#endif /* __RAS_CAMERADATA_H__ */ diff --git a/source/gameengine/Rasterizer/RAS_Deformer.h b/source/gameengine/Rasterizer/RAS_Deformer.h index d70e56dc285..6042a7dc4b5 100644 --- a/source/gameengine/Rasterizer/RAS_Deformer.h +++ b/source/gameengine/Rasterizer/RAS_Deformer.h @@ -34,7 +34,7 @@ #if defined(WIN32) && !defined(FREE_WINDOWS) #pragma warning (disable:4786) // get rid of stupid stl-visual compiler debug warning -#endif //WIN32 +#endif /* WIN32 */ #include #include "CTR_Map.h" diff --git a/source/gameengine/Rasterizer/RAS_ICanvas.h b/source/gameengine/Rasterizer/RAS_ICanvas.h index f045eb7e423..53195d79768 100644 --- a/source/gameengine/Rasterizer/RAS_ICanvas.h +++ b/source/gameengine/Rasterizer/RAS_ICanvas.h @@ -231,5 +231,4 @@ protected: #endif }; -#endif //__RAS_ICANVAS_H__ - +#endif /* __RAS_ICANVAS_H__ */ diff --git a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h index 169bc6e4ee6..9fffc8bebc9 100644 --- a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h +++ b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h @@ -202,5 +202,4 @@ inline bool operator < ( const RAS_IPolyMaterial & lhs, const RAS_IPolyMaterial return lhs.Less(rhs); } -#endif //__RAS_IPOLYGONMATERIAL_H__ - +#endif /* __RAS_IPOLYGONMATERIAL_H__ */ diff --git a/source/gameengine/Rasterizer/RAS_IRasterizer.h b/source/gameengine/Rasterizer/RAS_IRasterizer.h index 8efc10f2118..f212b1e6e0b 100644 --- a/source/gameengine/Rasterizer/RAS_IRasterizer.h +++ b/source/gameengine/Rasterizer/RAS_IRasterizer.h @@ -423,6 +423,4 @@ public: #endif }; -#endif //__RAS_IRASTERIZER_H__ - - +#endif /* __RAS_IRASTERIZER_H__ */ diff --git a/source/gameengine/Rasterizer/RAS_IRenderTools.h b/source/gameengine/Rasterizer/RAS_IRenderTools.h index ca6f20b71ad..bccda634222 100644 --- a/source/gameengine/Rasterizer/RAS_IRenderTools.h +++ b/source/gameengine/Rasterizer/RAS_IRenderTools.h @@ -208,7 +208,4 @@ public: #endif }; -#endif //__RAS_IRENDERTOOLS_H__ - - - +#endif /* __RAS_IRENDERTOOLS_H__ */ diff --git a/source/gameengine/Rasterizer/RAS_LightObject.h b/source/gameengine/Rasterizer/RAS_LightObject.h index ddf360683cd..79818def5f0 100644 --- a/source/gameengine/Rasterizer/RAS_LightObject.h +++ b/source/gameengine/Rasterizer/RAS_LightObject.h @@ -64,5 +64,4 @@ struct RAS_LightObject bool m_nospecular; }; -#endif //__RAS_LIGHTOBJECT_H__ - +#endif /* __RAS_LIGHTOBJECT_H__ */ diff --git a/source/gameengine/Rasterizer/RAS_MaterialBucket.h b/source/gameengine/Rasterizer/RAS_MaterialBucket.h index 295f2510313..16ecffb9a32 100644 --- a/source/gameengine/Rasterizer/RAS_MaterialBucket.h +++ b/source/gameengine/Rasterizer/RAS_MaterialBucket.h @@ -254,4 +254,4 @@ private: #endif }; -#endif //__RAS_MATERIAL_BUCKET +#endif /* __RAS_MATERIAL_BUCKET */ diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.h b/source/gameengine/Rasterizer/RAS_MeshObject.h index eb8655c8b1f..99ed59f6057 100644 --- a/source/gameengine/Rasterizer/RAS_MeshObject.h +++ b/source/gameengine/Rasterizer/RAS_MeshObject.h @@ -177,5 +177,4 @@ public: #endif }; -#endif //__RAS_MESHOBJECT_H__ - +#endif /* __RAS_MESHOBJECT_H__ */ diff --git a/source/gameengine/Rasterizer/RAS_ObjectColor.h b/source/gameengine/Rasterizer/RAS_ObjectColor.h index f8fbe69e97b..77feffccffc 100644 --- a/source/gameengine/Rasterizer/RAS_ObjectColor.h +++ b/source/gameengine/Rasterizer/RAS_ObjectColor.h @@ -38,5 +38,4 @@ struct RAS_ObjectColor { float m_blue; }; -#endif //__RAS_OBJECTCOLOR_H__ - +#endif /* __RAS_OBJECTCOLOR_H__ */ diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h index 8b54f507ee0..e6d16378bcf 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h @@ -322,6 +322,4 @@ public: #endif }; -#endif //__RAS_OPENGLRASTERIZER_H__ - - +#endif /* __RAS_OPENGLRASTERIZER_H__ */ diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.h index e881192171f..6b159db05ed 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.h +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.h @@ -67,5 +67,4 @@ private: #endif }; -#endif //__RAS_VAOPENGLRASTERIZER_H__ - +#endif /* __RAS_VAOPENGLRASTERIZER_H__ */ diff --git a/source/gameengine/Rasterizer/RAS_Rect.h b/source/gameengine/Rasterizer/RAS_Rect.h index cb5f7d47457..fc99c9159db 100644 --- a/source/gameengine/Rasterizer/RAS_Rect.h +++ b/source/gameengine/Rasterizer/RAS_Rect.h @@ -101,5 +101,4 @@ public: #endif }; -#endif // __RAS_RECT_H__ - +#endif /* __RAS_RECT_H__ */ diff --git a/source/gameengine/Rasterizer/RAS_TexMatrix.h b/source/gameengine/Rasterizer/RAS_TexMatrix.h index 44ae1b0eb5d..a2dd291d016 100644 --- a/source/gameengine/Rasterizer/RAS_TexMatrix.h +++ b/source/gameengine/Rasterizer/RAS_TexMatrix.h @@ -39,5 +39,4 @@ void RAS_CalcTexMatrix(RAS_TexVert p[3],MT_Point3& origin,MT_Vector3& udir,MT_Vector3& vdir); -#endif //__RAS_TEXMATRIX_H__ - +#endif /* __RAS_TEXMATRIX_H__ */ diff --git a/source/gameengine/Rasterizer/RAS_TexVert.h b/source/gameengine/Rasterizer/RAS_TexVert.h index 15059a9cf12..889769da5ed 100644 --- a/source/gameengine/Rasterizer/RAS_TexVert.h +++ b/source/gameengine/Rasterizer/RAS_TexVert.h @@ -148,5 +148,4 @@ public: #endif }; -#endif //__RAS_TEXVERT_H__ - +#endif /* __RAS_TEXVERT_H__ */ diff --git a/source/gameengine/SceneGraph/SG_Controller.h b/source/gameengine/SceneGraph/SG_Controller.h index 455aaf90d6d..a173633e13c 100644 --- a/source/gameengine/SceneGraph/SG_Controller.h +++ b/source/gameengine/SceneGraph/SG_Controller.h @@ -121,5 +121,4 @@ protected: #endif }; -#endif //__SG_CONTROLLER_H__ - +#endif /* __SG_CONTROLLER_H__ */ diff --git a/source/gameengine/SceneGraph/SG_DList.h b/source/gameengine/SceneGraph/SG_DList.h index be1c1fda2f2..90153f14c07 100644 --- a/source/gameengine/SceneGraph/SG_DList.h +++ b/source/gameengine/SceneGraph/SG_DList.h @@ -248,5 +248,4 @@ public: }; -#endif //__SG_DLIST_H__ - +#endif /* __SG_DLIST_H__ */ diff --git a/source/gameengine/SceneGraph/SG_IObject.h b/source/gameengine/SceneGraph/SG_IObject.h index 53b51507e97..885eb8e1e90 100644 --- a/source/gameengine/SceneGraph/SG_IObject.h +++ b/source/gameengine/SceneGraph/SG_IObject.h @@ -371,5 +371,4 @@ protected : #endif }; -#endif //__SG_IOBJECT_H__ - +#endif /* __SG_IOBJECT_H__ */ diff --git a/source/gameengine/SceneGraph/SG_Node.h b/source/gameengine/SceneGraph/SG_Node.h index 063eeaab01d..bde64f21305 100644 --- a/source/gameengine/SceneGraph/SG_Node.h +++ b/source/gameengine/SceneGraph/SG_Node.h @@ -275,5 +275,4 @@ private: #endif }; -#endif //__SG_NODE_H__ - +#endif /* __SG_NODE_H__ */ diff --git a/source/gameengine/SceneGraph/SG_QList.h b/source/gameengine/SceneGraph/SG_QList.h index bcc56f05615..663f29ebd88 100644 --- a/source/gameengine/SceneGraph/SG_QList.h +++ b/source/gameengine/SceneGraph/SG_QList.h @@ -161,5 +161,4 @@ public: #endif }; -#endif //__SG_QLIST_H__ - +#endif /* __SG_QLIST_H__ */ diff --git a/source/gameengine/SceneGraph/SG_Spatial.h b/source/gameengine/SceneGraph/SG_Spatial.h index 7630af51781..aa917fa70db 100644 --- a/source/gameengine/SceneGraph/SG_Spatial.h +++ b/source/gameengine/SceneGraph/SG_Spatial.h @@ -291,5 +291,4 @@ protected: #endif }; -#endif //__SG_SPATIAL_H__ - +#endif /* __SG_SPATIAL_H__ */ diff --git a/source/gameengine/VideoTexture/VideoFFmpeg.h b/source/gameengine/VideoTexture/VideoFFmpeg.h index cd0edfc09ef..d5b575851ee 100644 --- a/source/gameengine/VideoTexture/VideoFFmpeg.h +++ b/source/gameengine/VideoTexture/VideoFFmpeg.h @@ -209,6 +209,6 @@ inline VideoFFmpeg *getFFmpeg(PyImage *self) return static_cast(self->m_image); } -#endif //WITH_FFMPEG +#endif /* WITH_FFMPEG */ -#endif +#endif /* __VIDEOFFMPEG_H__ */ From 5f52285a0159c1e2d98959c193f293049cfd9440 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 9 Oct 2012 14:28:29 +0000 Subject: [PATCH 146/347] Fix cycles task manager calling pthread_join() twice. I haven't seen any bugs from this but best to fix anyway as it causes undefined behavior. Pointed out on irc by dslammu, thanks! --- intern/cycles/util/util_thread.h | 1 + 1 file changed, 1 insertion(+) diff --git a/intern/cycles/util/util_thread.h b/intern/cycles/util/util_thread.h index 9bea4e7808a..843764ca9d6 100644 --- a/intern/cycles/util/util_thread.h +++ b/intern/cycles/util/util_thread.h @@ -60,6 +60,7 @@ public: bool join() { + joined = true; return pthread_join(pthread_id, NULL) == 0; } From 08fc8c35617f4f80764f39186a3e99160f5e4b61 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 9 Oct 2012 16:29:27 +0000 Subject: [PATCH 147/347] Fixed wrong preset settings for motion tracking --- .../scripts/startup/bl_operators/presets.py | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/release/scripts/startup/bl_operators/presets.py b/release/scripts/startup/bl_operators/presets.py index db492450e28..5482912345d 100644 --- a/release/scripts/startup/bl_operators/presets.py +++ b/release/scripts/startup/bl_operators/presets.py @@ -436,19 +436,19 @@ class AddPresetTrackingSettings(AddPresetBase, Operator): ] preset_values = [ - "default_correlation_min", - "default_pattern_size", - "default_search_size", - "default_frames_limit", - "default_pattern_match", - "default_margin", - "default_motion_model", - "use_default_brute", - "use_default_normalization", - "use_default_mask", - "use_default_red_channel", - "use_default_green_channel", - "use_default_blue_channel" + "settings.default_correlation_min", + "settings.default_pattern_size", + "settings.default_search_size", + "settings.default_frames_limit", + "settings.default_pattern_match", + "settings.default_margin", + "settings.default_motion_model", + "settings.use_default_brute", + "settings.use_default_normalization", + "settings.use_default_mask", + "settings.use_default_red_channel", + "settings.use_default_green_channel", + "settings.use_default_blue_channel" ] preset_subdir = "tracking_settings" From 2a3c65169f401343f48708ad8ce70737b0d394c8 Mon Sep 17 00:00:00 2001 From: Lukas Toenne Date: Tue, 9 Oct 2012 17:30:33 +0000 Subject: [PATCH 148/347] Generalization of node dependency sorting, avoid using the sock->link pointer. This pointer only works for sockets that follow the standard 1-to-n connectivity (an output can be linked to multiple inputs, an input can only have one connection). Future node trees may implement 1-to-1 or n-to-1 linking. --- source/blender/blenkernel/intern/node.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 60cb1049a35..8965488a9b3 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -1641,21 +1641,21 @@ int BKE_node_clipboard_get_type(void) /* ************** dependency stuff *********** */ /* node is guaranteed to be not checked before */ -static int node_get_deplist_recurs(bNode *node, bNode ***nsort) +static int node_get_deplist_recurs(bNodeTree *ntree, bNode *node, bNode ***nsort) { bNode *fromnode; - bNodeSocket *sock; + bNodeLink *link; int level = 0xFFF; node->done = TRUE; /* check linked nodes */ - for (sock = node->inputs.first; sock; sock = sock->next) { - if (sock->link) { - fromnode = sock->link->fromnode; + for (link = ntree->links.first; link; link = link->next) { + if (link->tonode == node) { + fromnode = link->fromnode; if (fromnode) { if (fromnode->done == 0) - fromnode->level = node_get_deplist_recurs(fromnode, nsort); + fromnode->level = node_get_deplist_recurs(ntree, fromnode, nsort); if (fromnode->level <= level) level = fromnode->level - 1; } @@ -1665,7 +1665,7 @@ static int node_get_deplist_recurs(bNode *node, bNode ***nsort) /* check parent node */ if (node->parent) { if (node->parent->done == 0) - node->parent->level = node_get_deplist_recurs(node->parent, nsort); + node->parent->level = node_get_deplist_recurs(ntree, node->parent, nsort); if (node->parent->level <= level) level = node->parent->level - 1; } @@ -1699,7 +1699,7 @@ void ntreeGetDependencyList(struct bNodeTree *ntree, struct bNode ***deplist, in /* recursive check */ for (node = ntree->nodes.first; node; node = node->next) { if (node->done == 0) { - node->level = node_get_deplist_recurs(node, &nsort); + node->level = node_get_deplist_recurs(ntree, node, &nsort); } } } @@ -1717,7 +1717,7 @@ static void ntree_update_node_level(bNodeTree *ntree) /* recursive check */ for (node = ntree->nodes.first; node; node = node->next) { if (node->done == 0) { - node->level = node_get_deplist_recurs(node, NULL); + node->level = node_get_deplist_recurs(ntree, node, NULL); } } } From 94f869a256be307ad68e1c2265f68d760232e9b7 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 9 Oct 2012 18:37:14 +0000 Subject: [PATCH 149/347] Cycles: camera motion blur enabled. Still more work needed to get object motion blur ready. --- intern/cycles/blender/addon/ui.py | 6 +----- intern/cycles/blender/blender_object.cpp | 5 ++++- intern/cycles/blender/blender_sync.cpp | 5 ++++- intern/cycles/kernel/kernel_bvh.h | 4 ++-- intern/cycles/kernel/kernel_camera.h | 8 ++++---- intern/cycles/kernel/kernel_object.h | 14 +++++++------- intern/cycles/kernel/kernel_path.h | 16 ++++++++-------- intern/cycles/kernel/kernel_shader.h | 6 +++--- intern/cycles/kernel/kernel_types.h | 7 ++++--- intern/cycles/render/camera.cpp | 6 ++++++ intern/cycles/render/mesh.cpp | 4 ++++ intern/cycles/render/object.cpp | 6 ++++++ 12 files changed, 53 insertions(+), 34 deletions(-) diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index 4f4b0371839..ca43c345bfa 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -131,13 +131,9 @@ class CyclesRender_PT_light_paths(CyclesButtonsPanel, Panel): class CyclesRender_PT_motion_blur(CyclesButtonsPanel, Panel): - bl_label = "Motion Blur" + bl_label = "Camera Motion Blur" bl_options = {'DEFAULT_CLOSED'} - @classmethod - def poll(cls, context): - return False - def draw_header(self, context): rd = context.scene.render diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp index 27301026d35..3d74c57288b 100644 --- a/intern/cycles/blender/blender_object.cpp +++ b/intern/cycles/blender/blender_object.cpp @@ -17,6 +17,7 @@ */ #include "camera.h" +#include "integrator.h" #include "graph.h" #include "light.h" #include "mesh.h" @@ -227,7 +228,9 @@ void BlenderSync::sync_object(BL::Object b_parent, int b_index, BL::DupliObject object->use_motion = true; } - sync_mesh_motion(b_ob, object->mesh, motion); + /* mesh deformation blur not supported yet */ + if(!scene->integrator->motion_blur) + sync_mesh_motion(b_ob, object->mesh, motion); } return; diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp index b4990eb815a..3d36eba0c4b 100644 --- a/intern/cycles/blender/blender_sync.cpp +++ b/intern/cycles/blender/blender_sync.cpp @@ -149,6 +149,9 @@ void BlenderSync::sync_data(BL::SpaceView3D b_v3d, BL::Object b_override, const void BlenderSync::sync_integrator() { +#ifdef __CAMERA_MOTION__ + BL::RenderSettings r = b_scene.render(); +#endif PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles"); experimental = (RNA_enum_get(&cscene, "feature_set") != 0); @@ -175,7 +178,7 @@ void BlenderSync::sync_integrator() integrator->layer_flag = render_layer.layer; integrator->sample_clamp = get_float(cscene, "sample_clamp"); -#ifdef __MOTION__ +#ifdef __CAMERA_MOTION__ integrator->motion_blur = (!preview && r.use_motion_blur()); #endif diff --git a/intern/cycles/kernel/kernel_bvh.h b/intern/cycles/kernel/kernel_bvh.h index 34a44af8b8d..90aec2e46b3 100644 --- a/intern/cycles/kernel/kernel_bvh.h +++ b/intern/cycles/kernel/kernel_bvh.h @@ -349,7 +349,7 @@ __device_inline float3 bvh_triangle_refine(KernelGlobals *kg, ShaderData *sd, co #ifdef __INTERSECTION_REFINE__ if(isect->object != ~0) { -#ifdef __MOTION__ +#ifdef __OBJECT_MOTION__ Transform tfm = sd->ob_itfm; #else Transform tfm = object_fetch_transform(kg, isect->object, ray->time, OBJECT_INVERSE_TRANSFORM); @@ -370,7 +370,7 @@ __device_inline float3 bvh_triangle_refine(KernelGlobals *kg, ShaderData *sd, co P = P + D*rt; if(isect->object != ~0) { -#ifdef __MOTION__ +#ifdef __OBJECT_MOTION__ Transform tfm = sd->ob_tfm; #else Transform tfm = object_fetch_transform(kg, isect->object, ray->time, OBJECT_TRANSFORM); diff --git a/intern/cycles/kernel/kernel_camera.h b/intern/cycles/kernel/kernel_camera.h index 7fa987197c9..08674d0e379 100644 --- a/intern/cycles/kernel/kernel_camera.h +++ b/intern/cycles/kernel/kernel_camera.h @@ -63,7 +63,7 @@ __device void camera_sample_perspective(KernelGlobals *kg, float raster_x, float /* transform ray from camera to world */ Transform cameratoworld = kernel_data.cam.cameratoworld; -#ifdef __MOTION__ +#ifdef __CAMERA_MOTION__ if(kernel_data.cam.have_motion) transform_motion_interpolate(&cameratoworld, &kernel_data.cam.motion, ray->time); #endif @@ -106,7 +106,7 @@ __device void camera_sample_orthographic(KernelGlobals *kg, float raster_x, floa /* transform ray from camera to world */ Transform cameratoworld = kernel_data.cam.cameratoworld; -#ifdef __MOTION__ +#ifdef __CAMERA_MOTION__ if(kernel_data.cam.have_motion) transform_motion_interpolate(&cameratoworld, &kernel_data.cam.motion, ray->time); #endif @@ -180,7 +180,7 @@ __device void camera_sample_panorama(KernelGlobals *kg, float raster_x, float ra /* transform ray from camera to world */ Transform cameratoworld = kernel_data.cam.cameratoworld; -#ifdef __MOTION__ +#ifdef __CAMERA_MOTION__ if(kernel_data.cam.have_motion) transform_motion_interpolate(&cameratoworld, &kernel_data.cam.motion, ray->time); #endif @@ -212,7 +212,7 @@ __device void camera_sample(KernelGlobals *kg, int x, int y, float filter_u, flo float raster_x = x + kernel_tex_interp(__filter_table, filter_u, FILTER_TABLE_SIZE); float raster_y = y + kernel_tex_interp(__filter_table, filter_v, FILTER_TABLE_SIZE); -#ifdef __MOTION__ +#ifdef __CAMERA_MOTION__ /* motion blur */ if(kernel_data.cam.shuttertime == 0.0f) ray->time = TIME_INVALID; diff --git a/intern/cycles/kernel/kernel_object.h b/intern/cycles/kernel/kernel_object.h index 01da5050c8d..ad43120146a 100644 --- a/intern/cycles/kernel/kernel_object.h +++ b/intern/cycles/kernel/kernel_object.h @@ -31,7 +31,7 @@ __device_inline Transform object_fetch_transform(KernelGlobals *kg, int object, { Transform tfm; -#ifdef __MOTION__ +#ifdef __OBJECT_MOTION__ /* if we do motion blur */ if(sd->flag & SD_OBJECT_MOTION) { /* fetch motion transforms */ @@ -70,7 +70,7 @@ __device_inline Transform object_fetch_transform(KernelGlobals *kg, int object, __device_inline void object_position_transform(KernelGlobals *kg, ShaderData *sd, float3 *P) { -#ifdef __MOTION__ +#ifdef __OBJECT_MOTION__ *P = transform_point(&sd->ob_tfm, *P); #else Transform tfm = object_fetch_transform(kg, sd->object, TIME_INVALID, OBJECT_TRANSFORM); @@ -80,7 +80,7 @@ __device_inline void object_position_transform(KernelGlobals *kg, ShaderData *sd __device_inline void object_inverse_position_transform(KernelGlobals *kg, ShaderData *sd, float3 *P) { -#ifdef __MOTION__ +#ifdef __OBJECT_MOTION__ *P = transform_point(&sd->ob_itfm, *P); #else Transform tfm = object_fetch_transform(kg, sd->object, TIME_INVALID, OBJECT_INVERSE_TRANSFORM); @@ -90,7 +90,7 @@ __device_inline void object_inverse_position_transform(KernelGlobals *kg, Shader __device_inline void object_inverse_normal_transform(KernelGlobals *kg, ShaderData *sd, float3 *N) { -#ifdef __MOTION__ +#ifdef __OBJECT_MOTION__ *N = normalize(transform_direction_transposed(&sd->ob_tfm, *N)); #else Transform tfm = object_fetch_transform(kg, sd->object, TIME_INVALID, OBJECT_TRANSFORM); @@ -100,7 +100,7 @@ __device_inline void object_inverse_normal_transform(KernelGlobals *kg, ShaderDa __device_inline void object_normal_transform(KernelGlobals *kg, ShaderData *sd, float3 *N) { -#ifdef __MOTION__ +#ifdef __OBJECT_MOTION__ *N = normalize(transform_direction_transposed(&sd->ob_itfm, *N)); #else Transform tfm = object_fetch_transform(kg, sd->object, TIME_INVALID, OBJECT_INVERSE_TRANSFORM); @@ -110,7 +110,7 @@ __device_inline void object_normal_transform(KernelGlobals *kg, ShaderData *sd, __device_inline void object_dir_transform(KernelGlobals *kg, ShaderData *sd, float3 *D) { -#ifdef __MOTION__ +#ifdef __OBJECT_MOTION__ *D = transform_direction(&sd->ob_tfm, *D); #else Transform tfm = object_fetch_transform(kg, sd->object, 0.0f, OBJECT_TRANSFORM); @@ -120,7 +120,7 @@ __device_inline void object_dir_transform(KernelGlobals *kg, ShaderData *sd, flo __device_inline float3 object_location(KernelGlobals *kg, ShaderData *sd) { -#ifdef __MOTION__ +#ifdef __OBJECT_MOTION__ return make_float3(sd->ob_tfm.x.w, sd->ob_tfm.y.w, sd->ob_tfm.z.w); #else Transform tfm = object_fetch_transform(kg, sd->object, 0.0f, OBJECT_TRANSFORM); diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h index d606c3d634a..817f254a5e5 100644 --- a/intern/cycles/kernel/kernel_path.h +++ b/intern/cycles/kernel/kernel_path.h @@ -343,7 +343,7 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample, light_ray.P = ray_offset(sd.P, sd.Ng); light_ray.D = ao_D; light_ray.t = kernel_data.background.ao_distance; -#ifdef __MOTION__ +#ifdef __OBJECT_MOTION__ light_ray.time = sd.time; #endif @@ -368,7 +368,7 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample, BsdfEval L_light; bool is_lamp; -#ifdef __MOTION__ +#ifdef __OBJECT_MOTION__ light_ray.time = sd.time; #endif @@ -520,7 +520,7 @@ __device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, int sample, Ray light_ray.P = ray_offset(sd.P, sd.Ng); light_ray.D = ao_D; light_ray.t = kernel_data.background.ao_distance; -#ifdef __MOTION__ +#ifdef __OBJECT_MOTION__ light_ray.time = sd.time; #endif @@ -545,7 +545,7 @@ __device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, int sample, Ray BsdfEval L_light; bool is_lamp; -#ifdef __MOTION__ +#ifdef __OBJECT_MOTION__ light_ray.time = sd.time; #endif @@ -728,7 +728,7 @@ __device float4 kernel_path_non_progressive(KernelGlobals *kg, RNG *rng, int sam light_ray.P = ray_offset(sd.P, sd.Ng); light_ray.D = ao_D; light_ray.t = kernel_data.background.ao_distance; -#ifdef __MOTION__ +#ifdef __OBJECT_MOTION__ light_ray.time = sd.time; #endif @@ -748,7 +748,7 @@ __device float4 kernel_path_non_progressive(KernelGlobals *kg, RNG *rng, int sam BsdfEval L_light; bool is_lamp; -#ifdef __MOTION__ +#ifdef __OBJECT_MOTION__ light_ray.time = sd.time; #endif @@ -867,7 +867,7 @@ __device float4 kernel_path_non_progressive(KernelGlobals *kg, RNG *rng, int sam bsdf_ray.dP = sd.dP; bsdf_ray.dD = bsdf_domega_in; #endif -#ifdef __MOTION__ +#ifdef __OBJECT_MOTION__ bsdf_ray.time = sd.time; #endif @@ -925,7 +925,7 @@ __device void kernel_path_trace(KernelGlobals *kg, float lens_u = path_rng(kg, &rng, sample, PRNG_LENS_U); float lens_v = path_rng(kg, &rng, sample, PRNG_LENS_V); -#ifdef __MOTION__ +#ifdef __CAMERA_MOTION__ float time = path_rng(kg, &rng, sample, PRNG_TIME); #else float time = 0.0f; diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h index b57e27bc8ed..ee4460a8541 100644 --- a/intern/cycles/kernel/kernel_shader.h +++ b/intern/cycles/kernel/kernel_shader.h @@ -68,7 +68,7 @@ __device_inline void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd, #endif /* matrices and time */ -#ifdef __MOTION__ +#ifdef __OBJECT_MOTION__ sd->ob_tfm = object_fetch_transform(kg, sd->object, ray->time, OBJECT_TRANSFORM); sd->ob_itfm = object_fetch_transform(kg, sd->object, ray->time, OBJECT_INVERSE_TRANSFORM); @@ -171,7 +171,7 @@ __device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd, } #endif -#ifdef __MOTION__ +#ifdef __OBJECT_MOTION__ sd->time = time; sd->ob_tfm = object_fetch_transform(kg, sd->object, time, OBJECT_TRANSFORM); @@ -275,7 +275,7 @@ __device_inline void shader_setup_from_background(KernelGlobals *kg, ShaderData sd->I = -sd->P; sd->shader = kernel_data.background.shader; sd->flag = kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*2); -#ifdef __MOTION__ +#ifdef __OBJECT_MOTION__ sd->time = ray->time; #endif sd->ray_length = 0.0f; diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index 48e271a9f3f..b290d4c42d9 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -108,7 +108,8 @@ CCL_NAMESPACE_BEGIN #define __PASSES__ #define __BACKGROUND_MIS__ #define __AO__ -//#define __MOTION__ +#define __CAMERA_MOTION__ +//#define __OBJECT_MOTION__ #endif //#define __SOBOL_FULL_SCREEN__ @@ -129,7 +130,7 @@ enum PathTraceDimension { PRNG_FILTER_V = 1, PRNG_LENS_U = 2, PRNG_LENS_V = 3, -#ifdef __MOTION__ +#ifdef __CAMERA_MOTION__ PRNG_TIME = 4, PRNG_UNUSED = 5, PRNG_BASE_NUM = 6, @@ -426,7 +427,7 @@ typedef struct ShaderData { /* length of the ray being shaded */ float ray_length; -#ifdef __MOTION__ +#ifdef __OBJECT_MOTION__ /* object <-> world space transformations, cached to avoid * re-interpolating them constantly for shading */ Transform ob_tfm; diff --git a/intern/cycles/render/camera.cpp b/intern/cycles/render/camera.cpp index 3fd7a1b28e3..441f17d90e9 100644 --- a/intern/cycles/render/camera.cpp +++ b/intern/cycles/render/camera.cpp @@ -193,6 +193,7 @@ void Camera::device_update(Device *device, DeviceScene *dscene, Scene *scene) } } } +#ifdef __CAMERA_MOTION__ else if(need_motion == Scene::MOTION_BLUR) { /* todo: exact camera position will not be hit this way */ if(use_motion) { @@ -200,6 +201,7 @@ void Camera::device_update(Device *device, DeviceScene *dscene, Scene *scene) kcam->have_motion = 1; } } +#endif /* depth of field */ kcam->aperturesize = aperturesize; @@ -208,7 +210,11 @@ void Camera::device_update(Device *device, DeviceScene *dscene, Scene *scene) kcam->bladesrotation = bladesrotation; /* motion blur */ +#ifdef __CAMERA_MOTION__ kcam->shuttertime = (need_motion == Scene::MOTION_BLUR) ? shuttertime: 0.0f; +#else + kcam->shuttertime = 0.0f; +#endif /* type */ kcam->type = type; diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp index 7037e36f313..014b78dec2b 100644 --- a/intern/cycles/render/mesh.cpp +++ b/intern/cycles/render/mesh.cpp @@ -722,7 +722,11 @@ void MeshManager::device_update(Device *device, DeviceScene *dscene, Scene *scen foreach(Shader *shader, scene->shaders) shader->need_update_attributes = false; +#ifdef __OBJECT_MOTION__ bool motion_blur = scene->need_motion() == Scene::MOTION_BLUR; +#else + bool motion_blur = false; +#endif foreach(Object *object, scene->objects) object->compute_bounds(motion_blur); diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp index d78a82d589a..4a72dcc52f7 100644 --- a/intern/cycles/render/object.cpp +++ b/intern/cycles/render/object.cpp @@ -220,6 +220,7 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene memcpy(&objects[offset+8], &mtfm_pre, sizeof(float4)*4); memcpy(&objects[offset+12], &mtfm_post, sizeof(float4)*4); } +#ifdef __OBJECT_MOTION__ else if(need_motion == Scene::MOTION_BLUR) { if(ob->use_motion) { /* decompose transformations for interpolation */ @@ -234,6 +235,7 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene memcpy(&objects[offset+8], &no_motion, sizeof(float4)); } } +#endif /* dupli object coords */ objects[offset+16] = make_float4(ob->dupli_generated[0], ob->dupli_generated[1], ob->dupli_generated[2], 0.0f); @@ -297,7 +299,11 @@ void ObjectManager::apply_static_transforms(Scene *scene, Progress& progress) /* counter mesh users */ map mesh_users; +#ifdef __OBJECT_MOTION__ bool motion_blur = scene->need_motion() == Scene::MOTION_BLUR; +#else + bool motion_blur = false; +#endif foreach(Object *object, scene->objects) { map::iterator it = mesh_users.find(object->mesh); From afa9eff3a5db340af3203044340bcde31151c261 Mon Sep 17 00:00:00 2001 From: Antony Riakiotakis Date: Tue, 9 Oct 2012 18:56:02 +0000 Subject: [PATCH 150/347] code cleanup: Move smart stitch drawing code inside a draw callback and use ED_region_draw_cb_activate instead of explicitly checking for this specific operator in the main uv drawing function. --- source/blender/editors/uvedit/uvedit_draw.c | 47 ----------- source/blender/editors/uvedit/uvedit_intern.h | 24 ------ .../editors/uvedit/uvedit_smart_stitch.c | 80 ++++++++++++++++++- 3 files changed, 79 insertions(+), 72 deletions(-) diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c index d6794912043..7aaae404d15 100644 --- a/source/blender/editors/uvedit/uvedit_draw.c +++ b/source/blender/editors/uvedit/uvedit_draw.c @@ -453,8 +453,6 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit) int drawfaces, interpedges; Image *ima = sima->image; - StitchPreviewer *stitch_preview = uv_get_stitch_previewer(); - activetf = EDBM_mtexpoly_active_get(em, &efa_act, FALSE, FALSE); /* will be set to NULL if hidden */ activef = BM_active_face_get(bm, FALSE, FALSE); ts = scene->toolsettings; @@ -823,51 +821,6 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit) bglEnd(); } - /* finally draw stitch preview */ - if (stitch_preview) { - int i, index = 0; - glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT); - glEnableClientState(GL_VERTEX_ARRAY); - - glEnable(GL_BLEND); - - UI_ThemeColor4(TH_STITCH_PREVIEW_ACTIVE); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - glVertexPointer(2, GL_FLOAT, 0, stitch_preview->static_tris); - glDrawArrays(GL_TRIANGLES, 0, stitch_preview->num_static_tris * 3); - - glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_polys); - for (i = 0; i < stitch_preview->num_polys; i++) { - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - UI_ThemeColor4(TH_STITCH_PREVIEW_FACE); - glDrawArrays(GL_POLYGON, index, stitch_preview->uvs_per_polygon[i]); - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - UI_ThemeColor4(TH_STITCH_PREVIEW_EDGE); - glDrawArrays(GL_POLYGON, index, stitch_preview->uvs_per_polygon[i]); - - index += stitch_preview->uvs_per_polygon[i]; - } - glPolygonMode(GL_FRONT_AND_BACK, GL_POINT); -#if 0 - UI_ThemeColor4(TH_STITCH_PREVIEW_VERT); - glDrawArrays(GL_TRIANGLES, 0, stitch_preview->num_tris * 3); -#endif - glDisable(GL_BLEND); - - /* draw vert preview */ - glPointSize(pointsize * 2.0f); - UI_ThemeColor4(TH_STITCH_PREVIEW_STITCHABLE); - glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_stitchable); - glDrawArrays(GL_POINTS, 0, stitch_preview->num_stitchable); - - UI_ThemeColor4(TH_STITCH_PREVIEW_UNSTITCHABLE); - glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_unstitchable); - glDrawArrays(GL_POINTS, 0, stitch_preview->num_unstitchable); - - glPopClientAttrib(); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - } - glPointSize(1.0); } diff --git a/source/blender/editors/uvedit/uvedit_intern.h b/source/blender/editors/uvedit/uvedit_intern.h index f0ff79ae25e..3a89d6ce892 100644 --- a/source/blender/editors/uvedit/uvedit_intern.h +++ b/source/blender/editors/uvedit/uvedit_intern.h @@ -75,30 +75,6 @@ void uv_find_nearest_edge(struct Scene *scene, struct Image *ima, struct BMEditM struct UvElement *ED_uv_element_get(struct UvElementMap *map, struct BMFace *efa, struct BMLoop *l); void uvedit_live_unwrap_update(struct SpaceImage *sima, struct Scene *scene, struct Object *obedit); -/* smart stitch */ - -/* object that stores display data for previewing before accepting stitching */ -typedef struct StitchPreviewer { - /* here we'll store the preview triangle indices of the mesh */ - float *preview_polys; - /* uvs per polygon. */ - unsigned int *uvs_per_polygon; - /*number of preview polygons */ - unsigned int num_polys; - /* preview data. These will be either the previewed vertices or edges depending on stitch mode settings */ - float *preview_stitchable; - float *preview_unstitchable; - /* here we'll store the number of elements to be drawn */ - unsigned int num_stitchable; - unsigned int num_unstitchable; - unsigned int preview_uvs; - /* ...and here we'll store the triangles*/ - float *static_tris; - unsigned int num_static_tris; -} StitchPreviewer; - -StitchPreviewer *uv_get_stitch_previewer(void); - /* operators */ void UV_OT_average_islands_scale(struct wmOperatorType *ot); diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c index 4e0e7944e84..49439b8daa5 100644 --- a/source/blender/editors/uvedit/uvedit_smart_stitch.c +++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c @@ -46,6 +46,8 @@ #include "BLI_math_vector.h" #include "BLI_string.h" +#include "BIF_gl.h" + #include "BKE_context.h" #include "BKE_customdata.h" #include "BKE_depsgraph.h" @@ -55,6 +57,7 @@ #include "ED_mesh.h" #include "ED_uvedit.h" #include "ED_screen.h" +#include "ED_space_api.h" #include "RNA_access.h" #include "RNA_define.h" @@ -63,11 +66,32 @@ #include "WM_types.h" #include "UI_view2d.h" +#include "UI_resources.h" #include "uvedit_intern.h" /* ********************** smart stitch operator *********************** */ +/* object that stores display data for previewing before accepting stitching */ +typedef struct StitchPreviewer { + /* here we'll store the preview triangle indices of the mesh */ + float *preview_polys; + /* uvs per polygon. */ + unsigned int *uvs_per_polygon; + /*number of preview polygons */ + unsigned int num_polys; + /* preview data. These will be either the previewed vertices or edges depending on stitch mode settings */ + float *preview_stitchable; + float *preview_unstitchable; + /* here we'll store the number of elements to be drawn */ + unsigned int num_stitchable; + unsigned int num_unstitchable; + unsigned int preview_uvs; + /* ...and here we'll store the triangles*/ + float *static_tris; + unsigned int num_static_tris; +} StitchPreviewer; + struct IslandStitchData; @@ -143,6 +167,8 @@ typedef struct StitchState { int static_island; /* store number of primitives per face so that we can allocate the active island buffer later */ unsigned int *tris_per_island; + + void *draw_handle; } StitchState; typedef struct PreviewPosition { @@ -216,7 +242,7 @@ static void stitch_preview_delete(void) /* "getter method" */ -StitchPreviewer *uv_get_stitch_previewer(void) +static StitchPreviewer *uv_get_stitch_previewer(void) { return _stitch_preview; } @@ -981,6 +1007,55 @@ static void stitch_calculate_edge_normal(BMEditMesh *em, UvEdge *edge, float *no normalize_v2(normal); } +static void stitch_draw(const bContext *C, ARegion *UNUSED(ar), void *arg) +{ + int i, index = 0; + float pointsize = UI_GetThemeValuef(TH_VERTEX_SIZE); + StitchPreviewer *stitch_preview = uv_get_stitch_previewer(); + + glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT); + glEnableClientState(GL_VERTEX_ARRAY); + + glEnable(GL_BLEND); + + UI_ThemeColor4(TH_STITCH_PREVIEW_ACTIVE); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + glVertexPointer(2, GL_FLOAT, 0, stitch_preview->static_tris); + glDrawArrays(GL_TRIANGLES, 0, stitch_preview->num_static_tris * 3); + + glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_polys); + for (i = 0; i < stitch_preview->num_polys; i++) { + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + UI_ThemeColor4(TH_STITCH_PREVIEW_FACE); + glDrawArrays(GL_POLYGON, index, stitch_preview->uvs_per_polygon[i]); + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + UI_ThemeColor4(TH_STITCH_PREVIEW_EDGE); + glDrawArrays(GL_POLYGON, index, stitch_preview->uvs_per_polygon[i]); + + index += stitch_preview->uvs_per_polygon[i]; + } + glPolygonMode(GL_FRONT_AND_BACK, GL_POINT); +#if 0 + UI_ThemeColor4(TH_STITCH_PREVIEW_VERT); + glDrawArrays(GL_TRIANGLES, 0, stitch_preview->num_tris * 3); +#endif + glDisable(GL_BLEND); + + /* draw vert preview */ + glPointSize(pointsize * 2.0f); + UI_ThemeColor4(TH_STITCH_PREVIEW_STITCHABLE); + glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_stitchable); + glDrawArrays(GL_POINTS, 0, stitch_preview->num_stitchable); + + UI_ThemeColor4(TH_STITCH_PREVIEW_UNSTITCHABLE); + glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_unstitchable); + glDrawArrays(GL_POINTS, 0, stitch_preview->num_unstitchable); + + glPopClientAttrib(); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + +} + static int stitch_init(bContext *C, wmOperator *op) { /* for fast edge lookup... */ @@ -1016,6 +1091,7 @@ static int stitch_init(bContext *C, wmOperator *op) state->static_island = RNA_int_get(op->ptr, "static_island"); state->midpoints = RNA_boolean_get(op->ptr, "midpoint_snap"); state->clear_seams = RNA_boolean_get(op->ptr, "clear_seams"); + state->draw_handle = ED_region_draw_cb_activate(CTX_wm_region(C)->type, stitch_draw, NULL, REGION_DRAW_POST_VIEW); /* in uv synch selection, all uv's are visible */ if (ts->uv_flag & UV_SYNC_SELECTION) { state->element_map = EDBM_uv_element_map_create(state->em, 0, 1); @@ -1282,6 +1358,8 @@ static void stitch_exit(bContext *C, wmOperator *op, int finished) if (sa) ED_area_headerprint(sa, NULL); + ED_region_draw_cb_exit(CTX_wm_region(C)->type, stitch_state->draw_handle); + DAG_id_tag_update(obedit->data, 0); WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); From d81d75b20d9aaff0e9139ea064d322cd9371d929 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 9 Oct 2012 22:55:05 +0000 Subject: [PATCH 151/347] transfer weight's now operates on selected vertices (when vertex select is enabled). --- release/scripts/startup/bl_ui/space_view3d.py | 1 + .../startup/bl_ui/space_view3d_toolbar.py | 2 +- source/blender/editors/object/object_vgroup.c | 53 ++++++++++++------- .../editors/uvedit/uvedit_smart_stitch.c | 2 +- 4 files changed, 38 insertions(+), 20 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index d5648a6d3a2..606b14d4221 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -1247,6 +1247,7 @@ class VIEW3D_MT_paint_weight(Menu): layout.operator("object.vertex_group_clean", text="Clean") layout.operator("object.vertex_group_levels", text="Levels") layout.operator("object.vertex_group_blend", text="Blend") + layout.operator("object.vertex_group_transfer_weight", text="Transfer Weights") layout.operator("object.vertex_group_limit_total", text="Limit Total") layout.operator("object.vertex_group_fix", text="Fix Deforms") diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py index b0b8401fe02..d162a97d32c 100644 --- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py +++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py @@ -967,7 +967,7 @@ class VIEW3D_PT_tools_weightpaint(View3DPanel, Panel): col.operator("object.vertex_group_clean", text="Clean") col.operator("object.vertex_group_levels", text="Levels") col.operator("object.vertex_group_blend", text="Blend") - col.operator("object.vertex_group_transfer_weight", text="Transfer weight") + col.operator("object.vertex_group_transfer_weight", text="Transfer Weights") col.operator("object.vertex_group_limit_total", text="Limit Total") col.operator("object.vertex_group_fix", text="Fix Deforms") diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index dea7eb984ad..ab9a4cb07ec 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -406,7 +406,6 @@ typedef enum WT_Method { typedef enum WT_ReplaceMode { WT_REPLACE_ALL_WEIGHTS = 1, WT_REPLACE_EMPTY_WEIGHTS = 2, - WT_REPLACE_SELECTED_WEIGHTS = 3 } WT_ReplaceMode; static EnumPropertyItem WT_vertex_group_mode_item[] = { @@ -426,25 +425,21 @@ static EnumPropertyItem WT_method_item[] = { static EnumPropertyItem WT_replace_mode_item[] = { {WT_REPLACE_ALL_WEIGHTS, "WT_REPLACE_ALL_WEIGHTS", 1, "All", "Overwrites all weights."}, {WT_REPLACE_EMPTY_WEIGHTS, "WT_REPLACE_EMPTY_WEIGHTS", 1, "Empty", "Adds weights to vertices with no weight."}, - {WT_REPLACE_SELECTED_WEIGHTS, "WT_REPLACE_SELECTED_WEIGHTS", 1, "Selected", "Replace selected weights."}, {0, NULL, 0, NULL, NULL} }; /*copy weight*/ -static void vgroup_transfer_weight(MVert *mv_dst, float *weight_dst, float weight_src, WT_ReplaceMode replace_mode) +static void vgroup_transfer_weight(float *r_weight_dst, const float weight_src, const WT_ReplaceMode replace_mode) { switch (replace_mode) { - case WT_REPLACE_ALL_WEIGHTS: - *weight_dst = weight_src; + *r_weight_dst = weight_src; break; case WT_REPLACE_EMPTY_WEIGHTS: - if (*weight_dst == 0) *weight_dst = weight_src; - break; - - case WT_REPLACE_SELECTED_WEIGHTS: - if (mv_dst->flag & SELECT) *weight_dst = weight_src; + if (*r_weight_dst == 0.0f) { + *r_weight_dst = weight_src; + } break; default: @@ -469,9 +464,10 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou int dv_tot_src, dv_tot_dst, i, v_index, index_dst, index_src, index_nearest, index_nearest_vertex; unsigned int f_index; float weight, tmp_weight[4], tmp_co[3], normal[3], tmp_mat[4][4], dist_v1, dist_v2, dist_v3, dist_v4; + const int use_vert_sel = vertex_group_use_vert_sel(ob_dst); /* create new and overwrite vertex group on destination without data */ - if (!defgroup_find_name(ob_dst, dg_src->name) || replace_mode == WT_REPLACE_ALL_WEIGHTS) { + if (!defgroup_find_name(ob_dst, dg_src->name)) { ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_src->name)); ED_vgroup_add_name(ob_dst, dg_src->name); } @@ -495,7 +491,7 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou /* get vertex group arrays */ ED_vgroup_give_parray(ob_src->data, &dv_array_src, &dv_tot_src, FALSE); - ED_vgroup_give_parray(ob_dst->data, &dv_array_dst, &dv_tot_dst, FALSE); + ED_vgroup_give_parray(ob_dst->data, &dv_array_dst, &dv_tot_dst, use_vert_sel); /* get indexes of vertex groups */ index_src = BLI_findindex(&ob_src->defbase, dg_src); @@ -512,6 +508,11 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou /* clear weights */ if (replace_mode == WT_REPLACE_ALL_WEIGHTS) { for(i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++) { + + if (*dv_dst == NULL) { + continue; + } + dw_dst = defvert_verify_index(*dv_dst, index_dst); if (dw_dst) (*dw_dst).weight = 0; } @@ -533,13 +534,17 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou } /* loop through the vertices*/ - for(i = 0, dv_src = dv_array_src, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++, dv_src++, mv_src++) { + for(i = 0, dv_src = dv_array_src, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++, dv_src++, mv_src++, mv_dst++) { + + if (*dv_dst == NULL) { + continue; + } /* copy weight */ dw_src = defvert_find_index(*dv_src, index_src); if (dw_src && dw_src->weight) { dw_dst = defvert_verify_index(*dv_dst, index_dst); - vgroup_transfer_weight(mv_dst, &dw_dst->weight, dw_src->weight, replace_mode); + vgroup_transfer_weight(&dw_dst->weight, dw_src->weight, replace_mode); } } break; @@ -551,6 +556,10 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou /* loop trough vertices */ for(i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++, mv_dst++){ + if (*dv_dst == NULL) { + continue; + } + /* reset nearest */ nearest.dist = FLT_MAX; /* With current binary tree its marginally faster to start searching at the top, as opposed to previous search. */ @@ -567,7 +576,7 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou dw_src = defvert_find_index(dv_array_src[nearest.index], index_src); if (dw_src && dw_src->weight) { dw_dst = defvert_verify_index(*dv_dst, index_dst); - vgroup_transfer_weight(mv_dst, &dw_dst->weight, dw_src->weight, replace_mode); + vgroup_transfer_weight(&dw_dst->weight, dw_src->weight, replace_mode); } } @@ -586,6 +595,10 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou /* loop through the vertices */ for(i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++, mv_dst++) { + if (*dv_dst == NULL) { + continue; + } + /* reset nearest */ nearest.dist = FLT_MAX; /* With current binary tree its marginally faster to start searching at the top, as opposed to previous search. */ @@ -623,7 +636,7 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou /* copy weight that are not NULL including weight value 0. Existing target weights are overwritten prior to this in relevant cases. */ if (weight > 0) { dw_dst = defvert_verify_index(*dv_dst, index_dst); - vgroup_transfer_weight(mv_dst, &dw_dst->weight, weight, replace_mode); + vgroup_transfer_weight(&dw_dst->weight, weight, replace_mode); } } @@ -642,6 +655,10 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou /* loop through the vertices */ for(i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++, mv_dst++){ + if (*dv_dst == NULL) { + continue; + } + /* reset nearest */ nearest.dist = FLT_MAX; /* With current binary tree its marginally faster to start searching at the top, as opposed to previous search. */ @@ -677,7 +694,7 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou dw_src = defvert_find_index(dv_array_src[index_nearest_vertex], index_src); if (dw_src && dw_src->weight) { dw_dst = defvert_verify_index(*dv_dst, index_dst); - vgroup_transfer_weight(mv_dst, &dw_dst->weight, dw_src->weight, replace_mode); + vgroup_transfer_weight(&dw_dst->weight, dw_src->weight, replace_mode); } } @@ -3316,7 +3333,7 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) void OBJECT_OT_vertex_group_transfer_weight(wmOperatorType *ot) { /* identifiers */ - ot->name = "Transfer weight"; + ot->name = "Transfer Weights"; ot->idname = "OBJECT_OT_vertex_group_transfer_weight"; ot->description = "Transfer weight paint to active from selected mesh"; diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c index 49439b8daa5..2b225118472 100644 --- a/source/blender/editors/uvedit/uvedit_smart_stitch.c +++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c @@ -1007,7 +1007,7 @@ static void stitch_calculate_edge_normal(BMEditMesh *em, UvEdge *edge, float *no normalize_v2(normal); } -static void stitch_draw(const bContext *C, ARegion *UNUSED(ar), void *arg) +static void stitch_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void *UNUSED(arg)) { int i, index = 0; float pointsize = UI_GetThemeValuef(TH_VERTEX_SIZE); From c3ca19800c199cfc35455c54310c2445ec4cac8f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 10 Oct 2012 01:22:19 +0000 Subject: [PATCH 152/347] refactor screen foreach functions to accept float[2] arguments rather then int pairs. overall means less converting between float and int (and short in some cases). --- source/blender/blenlib/BLI_math_vector.h | 6 +- source/blender/blenlib/BLI_rect.h | 4 +- .../blenlib/intern/math_vector_inline.c | 42 +++- source/blender/blenlib/intern/rct.c | 53 ++++- source/blender/editors/curve/editcurve.c | 22 +- .../blender/editors/gpencil/gpencil_paint.c | 11 +- source/blender/editors/include/ED_mesh.h | 6 +- source/blender/editors/include/ED_view3d.h | 21 +- source/blender/editors/mesh/editmesh_knife.c | 2 +- .../blender/editors/mesh/editmesh_loopcut.c | 4 +- source/blender/editors/mesh/editmesh_select.c | 115 +++++---- source/blender/editors/mesh/meshtools.c | 4 +- .../blender/editors/object/object_lattice.c | 22 +- .../blender/editors/space_view3d/drawobject.c | 128 +++++----- .../editors/space_view3d/view3d_draw.c | 6 +- .../editors/space_view3d/view3d_select.c | 224 ++++++++++-------- 16 files changed, 380 insertions(+), 290 deletions(-) diff --git a/source/blender/blenlib/BLI_math_vector.h b/source/blender/blenlib/BLI_math_vector.h index de1d423bfad..a471f95d505 100644 --- a/source/blender/blenlib/BLI_math_vector.h +++ b/source/blender/blenlib/BLI_math_vector.h @@ -139,12 +139,16 @@ MINLINE void star_m3_v3(float rmat[3][3], float a[3]); MINLINE float len_squared_v2(const float v[2]); MINLINE float len_squared_v3(const float v[3]); +MINLINE float len_manhattan_v2(const float v[2]); +MINLINE float len_manhattan_v3(const float v[3]); MINLINE float len_v2(const float a[2]); MINLINE float len_v2v2(const float a[2], const float b[2]); MINLINE float len_squared_v2v2(const float a[2], const float b[2]); +MINLINE float len_squared_v3v3(const float a[3], const float b[3]); +MINLINE float len_manhattan_v2v2(const float a[2], const float b[2]); +MINLINE float len_manhattan_v3v3(const float a[3], const float b[3]); MINLINE float len_v3(const float a[3]); MINLINE float len_v3v3(const float a[3], const float b[3]); -MINLINE float len_squared_v3v3(const float a[3], const float b[3]); MINLINE float normalize_v2(float r[2]); MINLINE float normalize_v2_v2(float r[2], const float a[2]); diff --git a/source/blender/blenlib/BLI_rect.h b/source/blender/blenlib/BLI_rect.h index de4c2cf3a86..f84820e94f3 100644 --- a/source/blender/blenlib/BLI_rect.h +++ b/source/blender/blenlib/BLI_rect.h @@ -66,9 +66,7 @@ int BLI_rcti_isect_pt_v(const struct rcti *rect, const int xy[2]); int BLI_rctf_isect_pt(const struct rctf *rect, const float x, const float y); int BLI_rctf_isect_pt_v(const struct rctf *rect, const float xy[2]); int BLI_rcti_isect_segment(const struct rcti *rect, const int s1[2], const int s2[2]); -#if 0 /* NOT NEEDED YET */ -int BLI_rctf_isect_segment(struct rcti *rect, int s1[2], int s2[2]); -#endif +int BLI_rctf_isect_segment(const struct rctf *rect, const float s1[2], const float s2[2]); void BLI_rctf_union(struct rctf *rctf1, const struct rctf *rctf2); void BLI_rcti_union(struct rcti *rcti1, const struct rcti *rcti2); void BLI_rcti_rctf_copy(struct rcti *dst, const struct rctf *src); diff --git a/source/blender/blenlib/intern/math_vector_inline.c b/source/blender/blenlib/intern/math_vector_inline.c index 2cfe999e032..de1038724b0 100644 --- a/source/blender/blenlib/intern/math_vector_inline.c +++ b/source/blender/blenlib/intern/math_vector_inline.c @@ -561,6 +561,16 @@ MINLINE float len_squared_v3(const float v[3]) return v[0] * v[0] + v[1] * v[1] + v[2] * v[2]; } +MINLINE float len_manhattan_v2(const float v[2]) +{ + return fabsf(v[0]) + fabsf(v[1]); +} + +MINLINE float len_manhattan_v3(const float v[3]) +{ + return fabsf(v[0]) + fabsf(v[1]) + fabsf(v[2]); +} + MINLINE float len_v2(const float v[2]) { return sqrtf(v[0] * v[0] + v[1] * v[1]); @@ -588,14 +598,6 @@ MINLINE float len_squared_v2v2(const float a[2], const float b[2]) return dot_v2v2(d, d); } -MINLINE float len_v3v3(const float a[3], const float b[3]) -{ - float d[3]; - - sub_v3_v3v3(d, b, a); - return len_v3(d); -} - MINLINE float len_squared_v3v3(const float a[3], const float b[3]) { float d[3]; @@ -604,6 +606,30 @@ MINLINE float len_squared_v3v3(const float a[3], const float b[3]) return dot_v3v3(d, d); } +MINLINE float len_manhattan_v2v2(const float a[2], const float b[2]) +{ + float d[2]; + + sub_v2_v2v2(d, b, a); + return len_manhattan_v2(d); +} + +MINLINE float len_manhattan_v3v3(const float a[3], const float b[3]) +{ + float d[3]; + + sub_v3_v3v3(d, b, a); + return len_manhattan_v3(d); +} + +MINLINE float len_v3v3(const float a[3], const float b[3]) +{ + float d[3]; + + sub_v3_v3v3(d, b, a); + return len_v3(d); +} + MINLINE float normalize_v2_v2(float r[2], const float a[2]) { float d = dot_v2v2(a, a); diff --git a/source/blender/blenlib/intern/rct.c b/source/blender/blenlib/intern/rct.c index cab383b60f3..2e2619df24e 100644 --- a/source/blender/blenlib/intern/rct.c +++ b/source/blender/blenlib/intern/rct.c @@ -102,7 +102,19 @@ int BLI_rctf_isect_pt_v(const rctf *rect, const float xy[2]) } /* based closely on 'isect_line_line_v2_int', but in modified so corner cases are treated as intersections */ -static int isect_segments(const int v1[2], const int v2[2], const int v3[2], const int v4[2]) +static int isect_segments_i(const int v1[2], const int v2[2], const int v3[2], const int v4[2]) +{ + const double div = (double)((v2[0] - v1[0]) * (v4[1] - v3[1]) - (v2[1] - v1[1]) * (v4[0] - v3[0])); + if (div == 0.0f) { + return 1; /* co-linear */ + } + else { + const double labda = (double)((v1[1] - v3[1]) * (v4[0] - v3[0]) - (v1[0] - v3[0]) * (v4[1] - v3[1])) / div; + const double mu = (double)((v1[1] - v3[1]) * (v2[0] - v1[0]) - (v1[0] - v3[0]) * (v2[1] - v1[1])) / div; + return (labda >= 0.0f && labda <= 1.0f && mu >= 0.0f && mu <= 1.0f); + } +} +static int isect_segments_fl(const float v1[2], const float v2[2], const float v3[2], const float v4[2]) { const double div = (double)((v2[0] - v1[0]) * (v4[1] - v3[1]) - (v2[1] - v1[1]) * (v4[0] - v3[0])); if (div == 0.0f) { @@ -134,14 +146,49 @@ int BLI_rcti_isect_segment(const rcti *rect, const int s1[2], const int s2[2]) /* diagonal: [/] */ tvec1[0] = rect->xmin; tvec1[1] = rect->ymin; tvec2[0] = rect->xmin; tvec2[1] = rect->ymax; - if (isect_segments(s1, s2, tvec1, tvec2)) { + if (isect_segments_i(s1, s2, tvec1, tvec2)) { return 1; } /* diagonal: [\] */ tvec1[0] = rect->xmin; tvec1[1] = rect->ymax; tvec2[0] = rect->xmax; tvec2[1] = rect->ymin; - if (isect_segments(s1, s2, tvec1, tvec2)) { + if (isect_segments_i(s1, s2, tvec1, tvec2)) { + return 1; + } + + /* no intersection */ + return 0; + } +} + +int BLI_rctf_isect_segment(const rctf *rect, const float s1[2], const float s2[2]) +{ + /* first do outside-bounds check for both points of the segment */ + if (s1[0] < rect->xmin && s2[0] < rect->xmin) return 0; + if (s1[0] > rect->xmax && s2[0] > rect->xmax) return 0; + if (s1[1] < rect->ymin && s2[1] < rect->ymin) return 0; + if (s1[1] > rect->ymax && s2[1] > rect->ymax) return 0; + + /* if either points intersect then we definetly intersect */ + if (BLI_rctf_isect_pt_v(rect, s1) || BLI_rctf_isect_pt_v(rect, s2)) { + return 1; + } + else { + /* both points are outside but may insersect the rect */ + float tvec1[2]; + float tvec2[2]; + /* diagonal: [/] */ + tvec1[0] = rect->xmin; tvec1[1] = rect->ymin; + tvec2[0] = rect->xmin; tvec2[1] = rect->ymax; + if (isect_segments_fl(s1, s2, tvec1, tvec2)) { + return 1; + } + + /* diagonal: [\] */ + tvec1[0] = rect->xmin; tvec1[1] = rect->ymax; + tvec2[0] = rect->xmax; tvec2[1] = rect->ymin; + if (isect_segments_fl(s1, s2, tvec1, tvec2)) { return 1; } diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index d22b9f2abfb..14c233abdaf 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -3226,12 +3226,12 @@ void CURVE_OT_subdivide(wmOperatorType *ot) /******************** find nearest ************************/ -static void findnearestNurbvert__doClosest(void *userData, Nurb *nu, BPoint *bp, BezTriple *bezt, int beztindex, int x, int y) +static void findnearestNurbvert__doClosest(void *userData, Nurb *nu, BPoint *bp, BezTriple *bezt, int beztindex, const float screen_co[2]) { - struct { BPoint *bp; BezTriple *bezt; Nurb *nurb; int dist, hpoint, select, mval[2]; } *data = userData; + struct { BPoint *bp; BezTriple *bezt; Nurb *nurb; float dist; int hpoint, select; float mval_fl[2]; } *data = userData; short flag; - short temp; + float dist_test; if (bp) { flag = bp->f1; @@ -3248,12 +3248,12 @@ static void findnearestNurbvert__doClosest(void *userData, Nurb *nu, BPoint *bp, } } - temp = abs(data->mval[0] - x) + abs(data->mval[1] - y); - if ((flag & 1) == data->select) temp += 5; - if (bezt && beztindex == 1) temp += 3; /* middle points get a small disadvantage */ + dist_test = len_manhattan_v2v2(data->mval_fl, screen_co); + if ((flag & SELECT) == data->select) dist_test += 5.0f; + if (bezt && beztindex == 1) dist_test += 3.0f; /* middle points get a small disadvantage */ - if (temp < data->dist) { - data->dist = temp; + if (dist_test < data->dist) { + data->dist = dist_test; data->bp = bp; data->bezt = bezt; @@ -3267,13 +3267,13 @@ static short findnearestNurbvert(ViewContext *vc, short sel, const int mval[2], /* (sel == 1): selected gets a disadvantage */ /* in nurb and bezt or bp the nearest is written */ /* return 0 1 2: handlepunt */ - struct { BPoint *bp; BezTriple *bezt; Nurb *nurb; int dist, hpoint, select, mval[2]; } data = {NULL}; + struct { BPoint *bp; BezTriple *bezt; Nurb *nurb; float dist; int hpoint, select; float mval_fl[2]; } data = {NULL}; data.dist = 100; data.hpoint = 0; data.select = sel; - data.mval[0] = mval[0]; - data.mval[1] = mval[1]; + data.mval_fl[0] = mval[0]; + data.mval_fl[1] = mval[1]; ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); nurbs_foreachScreenVert(vc, findnearestNurbvert__doClosest, &data); diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index c07f0db7114..d0b48772d85 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -787,11 +787,16 @@ static short gp_stroke_eraser_strokeinside(const int mval[], const int UNUSED(mv int rad, int x0, int y0, int x1, int y1) { /* simple within-radius check for now */ - if (edge_inside_circle(mval[0], mval[1], rad, x0, y0, x1, y1)) - return 1; + const float mval_fl[2] = {mval[0], mval[1]}; + const float screen_co_a[2] = {x0, y0}; + const float screen_co_b[2] = {x1, y1}; + + if (edge_inside_circle(mval_fl, rad, screen_co_a, screen_co_b)) { + return TRUE; + } /* not inside */ - return 0; + return FALSE; } static void gp_point_to_xy(ARegion *ar, View2D *v2d, rctf *subrect, bGPDstroke *gps, bGPDspoint *pt, diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index 093872c79f6..f55f7755668 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -142,9 +142,9 @@ int EDBM_backbuf_border_mask_init(struct ViewContext *vc, const int mcords[][2] short xmin, short ymin, short xmax, short ymax); int EDBM_backbuf_circle_init(struct ViewContext *vc, short xs, short ys, short rads); -struct BMVert *EDBM_vert_find_nearest(struct ViewContext *vc, int *dist, short sel, short strict); -struct BMEdge *EDBM_edge_find_nearest(struct ViewContext *vc, int *dist); -struct BMFace *EDBM_face_find_nearest(struct ViewContext *vc, int *dist); +struct BMVert *EDBM_vert_find_nearest(struct ViewContext *vc, float *r_dist, const short sel, const short strict); +struct BMEdge *EDBM_edge_find_nearest(struct ViewContext *vc, float *r_dist); +struct BMFace *EDBM_face_find_nearest(struct ViewContext *vc, float *r_dist); int EDBM_select_pick(struct bContext *C, const int mval[2], short extend, short deselect, short toggle); diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index f71133d3118..c02bc1dcf73 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -167,14 +167,14 @@ void ED_view3d_calc_camera_border(struct Scene *scene, struct ARegion *ar, struc void ED_view3d_calc_camera_border_size(struct Scene *scene, struct ARegion *ar, struct View3D *v3d, struct RegionView3D *rv3d, float size_r[2]); /* drawobject.c iterators */ -void mesh_foreachScreenVert(struct ViewContext *vc, void (*func)(void *userData, struct BMVert *eve, int x, int y, int index), void *userData, eV3DClipTest clipVerts); -void mesh_foreachScreenEdge(struct ViewContext *vc, void (*func)(void *userData, struct BMEdge *eed, int x0, int y0, int x1, int y1, int index), void *userData, eV3DClipTest clipVerts); -void mesh_foreachScreenFace(struct ViewContext *vc, void (*func)(void *userData, struct BMFace *efa, int x, int y, int index), void *userData); -void nurbs_foreachScreenVert(struct ViewContext *vc, void (*func)(void *userData, struct Nurb *nu, struct BPoint *bp, struct BezTriple *bezt, int beztindex, int x, int y), void *userData); -void mball_foreachScreenElem(struct ViewContext *vc, void (*func)(void *userData, struct MetaElem *ml, int x, int y), void *userData); -void lattice_foreachScreenVert(struct ViewContext *vc, void (*func)(void *userData, struct BPoint *bp, int x, int y), void *userData); -void armature_foreachScreenBone(struct ViewContext *vc, void (*func)(void *userData, struct EditBone *ebone, int x0, int y0, int x1, int y1), void *userData); -void pose_foreachScreenBone(struct ViewContext *vc, void (*func)(void *userData, struct bPoseChannel *pchan, int x0, int y0, int x1, int y1), void *userData); +void mesh_foreachScreenVert(struct ViewContext *vc, void (*func)(void *userData, struct BMVert *eve, const float screen_co[2], int index), void *userData, eV3DClipTest clipVerts); +void mesh_foreachScreenEdge(struct ViewContext *vc, void (*func)(void *userData, struct BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], int index), void *userData, eV3DClipTest clipVerts); +void mesh_foreachScreenFace(struct ViewContext *vc, void (*func)(void *userData, struct BMFace *efa, const float screen_co[2], int index), void *userData); +void nurbs_foreachScreenVert(struct ViewContext *vc, void (*func)(void *userData, struct Nurb *nu, struct BPoint *bp, struct BezTriple *bezt, int beztindex, const float screen_co[2]), void *userData); +void mball_foreachScreenElem(struct ViewContext *vc, void (*func)(void *userData, struct MetaElem *ml, const float screen_co[2]), void *userData); +void lattice_foreachScreenVert(struct ViewContext *vc, void (*func)(void *userData, struct BPoint *bp, const float screen_co[2]), void *userData); +void armature_foreachScreenBone(struct ViewContext *vc, void (*func)(void *userData, struct EditBone *ebone, const float screen_co_a[2], const float screen_co_b[2]), void *userData); +void pose_foreachScreenBone(struct ViewContext *vc, void (*func)(void *userData, struct bPoseChannel *pchan, const float screen_co_a[2], const float screen_co_b[2]), void *userData); void ED_view3d_clipping_calc(struct BoundBox *bb, float planes[4][4], struct bglMats *mats, const struct rcti *rect); @@ -191,7 +191,8 @@ void drawcircball(int mode, const float cent[3], float rad, float tmat[][4]); /* backbuffer select and draw support */ void view3d_validate_backbuf(struct ViewContext *vc); struct ImBuf *view3d_read_backbuf(struct ViewContext *vc, short xmin, short ymin, short xmax, short ymax); -unsigned int view3d_sample_backbuf_rect(struct ViewContext *vc, const int mval[2], int size, unsigned int min, unsigned int max, int *dist, short strict, +unsigned int view3d_sample_backbuf_rect(struct ViewContext *vc, const int mval[2], int size, + unsigned int min, unsigned int max, float *dist, short strict, void *handle, unsigned int (*indextest)(void *handle, unsigned int index)); unsigned int view3d_sample_backbuf(struct ViewContext *vc, int x, int y); @@ -215,7 +216,7 @@ int view3d_get_view_aligned_coordinate(struct ViewContext *vc, float fp[3], cons void view3d_get_transformation(const struct ARegion *ar, struct RegionView3D *rv3d, struct Object *ob, struct bglMats *mats); /* XXX should move to BLI_math */ -int edge_inside_circle(int centx, int centy, int rad, int x1, int y1, int x2, int y2); +int edge_inside_circle(const float cent[2], float radius, const float screen_co_a[2], const float screen_co_b[2]); /* get 3d region from context, also if mouse is in header or toolbar */ struct RegionView3D *ED_view3d_context_rv3d(struct bContext *C); diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c index 4f4fc27582c..1d19d35ca34 100644 --- a/source/blender/editors/mesh/editmesh_knife.c +++ b/source/blender/editors/mesh/editmesh_knife.c @@ -1418,7 +1418,7 @@ static void knife_input_ray_cast(KnifeTool_OpData *kcd, const int mval_i[2], static BMFace *knife_find_closest_face(KnifeTool_OpData *kcd, float co[3], float cageco[3], int *is_space) { BMFace *f; - int dist = KMAXDIST; + float dist = KMAXDIST; float origin[3]; float ray[3]; diff --git a/source/blender/editors/mesh/editmesh_loopcut.c b/source/blender/editors/mesh/editmesh_loopcut.c index c0a36e24015..98fae2cc701 100644 --- a/source/blender/editors/mesh/editmesh_loopcut.c +++ b/source/blender/editors/mesh/editmesh_loopcut.c @@ -416,7 +416,7 @@ static int ringcut_invoke(bContext *C, wmOperator *op, wmEvent *evt) Object *obedit = CTX_data_edit_object(C); RingSelOpData *lcd; BMEdge *edge; - int dist = 75; + float dist = 75.0f; if (modifiers_isDeformedByLattice(obedit) || modifiers_isDeformedByArmature(obedit)) BKE_report(op->reports, RPT_WARNING, "Loop cut doesn't work well on deformed edit mesh display"); @@ -513,7 +513,7 @@ static int loopcut_modal(bContext *C, wmOperator *op, wmEvent *event) ED_region_tag_redraw(lcd->ar); break; case MOUSEMOVE: { /* mouse moved somewhere to select another loop */ - int dist = 75; + float dist = 75.0f; BMEdge *edge; lcd->vc.mval[0] = event->mval[0]; diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index 680d15ec51e..2e40419cb16 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -330,9 +330,9 @@ int EDBM_backbuf_circle_init(ViewContext *vc, short xs, short ys, short rads) } -static void findnearestvert__doClosest(void *userData, BMVert *eve, int x, int y, int index) +static void findnearestvert__doClosest(void *userData, BMVert *eve, const float screen_co[2], int index) { - struct { short mval[2], pass, select, strict; int dist, lastIndex, closestIndex; BMVert *closest; } *data = userData; + struct { float mval_fl[2], pass, select, strict; float dist, lastIndex, closestIndex; BMVert *closest; } *data = userData; if (data->pass == 0) { if (index <= data->lastIndex) @@ -344,18 +344,18 @@ static void findnearestvert__doClosest(void *userData, BMVert *eve, int x, int y } if (data->dist > 3) { - int temp = abs(data->mval[0] - x) + abs(data->mval[1] - y); + float dist_test = len_manhattan_v2v2(data->mval_fl, screen_co); if (BM_elem_flag_test(eve, BM_ELEM_SELECT) == data->select) { if (data->strict == 1) { return; } else { - temp += 5; + dist_test += 5; } } - if (temp < data->dist) { - data->dist = temp; + if (dist_test < data->dist) { + data->dist = dist_test; data->closest = eve; data->closestIndex = index; } @@ -382,10 +382,10 @@ static unsigned int findnearestvert__backbufIndextest(void *handle, unsigned int * if 0, unselected vertice are given the bias * strict: if 1, the vertice corresponding to the sel parameter are ignored and not just biased */ -BMVert *EDBM_vert_find_nearest(ViewContext *vc, int *dist, short sel, short strict) +BMVert *EDBM_vert_find_nearest(ViewContext *vc, float *r_dist, const short sel, const short strict) { if (vc->v3d->drawtype > OB_WIRE && (vc->v3d->flag & V3D_ZBUF_SELECT)) { - int distance; + float distance; unsigned int index; BMVert *eve; @@ -400,8 +400,8 @@ BMVert *EDBM_vert_find_nearest(ViewContext *vc, int *dist, short sel, short stri eve = BM_vert_at_index(vc->em->bm, index - 1); - if (eve && distance < *dist) { - *dist = distance; + if (eve && distance < *r_dist) { + *r_dist = distance; return eve; } else { @@ -410,7 +410,7 @@ BMVert *EDBM_vert_find_nearest(ViewContext *vc, int *dist, short sel, short stri } else { - struct { short mval[2], pass, select, strict; int dist, lastIndex, closestIndex; BMVert *closest; } data; + struct { float mval_fl[2], pass, select, strict; float dist, lastIndex, closestIndex; BMVert *closest; } data; static int lastSelectedIndex = 0; static BMVert *lastSelected = NULL; @@ -420,10 +420,10 @@ BMVert *EDBM_vert_find_nearest(ViewContext *vc, int *dist, short sel, short stri } data.lastIndex = lastSelectedIndex; - data.mval[0] = vc->mval[0]; - data.mval[1] = vc->mval[1]; + data.mval_fl[0] = vc->mval[0]; + data.mval_fl[1] = vc->mval[1]; data.select = sel; - data.dist = *dist; + data.dist = *r_dist; data.strict = strict; data.closest = NULL; data.closestIndex = 0; @@ -439,7 +439,7 @@ BMVert *EDBM_vert_find_nearest(ViewContext *vc, int *dist, short sel, short stri mesh_foreachScreenVert(vc, findnearestvert__doClosest, &data, V3D_CLIP_TEST_RV3D_CLIPPING); } - *dist = data.dist; + *r_dist = data.dist; lastSelected = data.closest; lastSelectedIndex = data.closestIndex; @@ -462,18 +462,12 @@ float labda_PdistVL2Dfl(const float v1[2], const float v2[2], const float v3[2]) } /* note; uses v3d, so needs active 3d window */ -static void findnearestedge__doClosest(void *userData, BMEdge *eed, int x0, int y0, int x1, int y1, int UNUSED(index)) +static void findnearestedge__doClosest(void *userData, BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], int UNUSED(index)) { - struct { ViewContext vc; float mval[2]; int dist; BMEdge *closest; } *data = userData; - float v1[2], v2[2]; + struct { ViewContext vc; float mval_fl[2]; float dist; BMEdge *closest; } *data = userData; int distance; - - v1[0] = x0; - v1[1] = y0; - v2[0] = x1; - v2[1] = y1; - - distance = dist_to_line_segment_v2(data->mval, v1, v2); + + distance = dist_to_line_segment_v2(data->mval_fl, screen_co_a, screen_co_b); if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) { distance += 5; @@ -481,7 +475,7 @@ static void findnearestedge__doClosest(void *userData, BMEdge *eed, int x0, int if (distance < data->dist) { if (data->vc.rv3d->rflag & RV3D_CLIPPING) { - float labda = labda_PdistVL2Dfl(data->mval, v1, v2); + float labda = labda_PdistVL2Dfl(data->mval_fl, screen_co_a, screen_co_b); float vec[3]; vec[0] = eed->v1->co[0] + labda * (eed->v2->co[0] - eed->v1->co[0]); @@ -499,11 +493,11 @@ static void findnearestedge__doClosest(void *userData, BMEdge *eed, int x0, int } } } -BMEdge *EDBM_edge_find_nearest(ViewContext *vc, int *dist) +BMEdge *EDBM_edge_find_nearest(ViewContext *vc, float *r_dist) { if (vc->v3d->drawtype > OB_WIRE && (vc->v3d->flag & V3D_ZBUF_SELECT)) { - int distance; + float distance; unsigned int index; BMEdge *eed; @@ -512,8 +506,8 @@ BMEdge *EDBM_edge_find_nearest(ViewContext *vc, int *dist) index = view3d_sample_backbuf_rect(vc, vc->mval, 50, bm_solidoffs, bm_wireoffs, &distance, 0, NULL, NULL); eed = BM_edge_at_index(vc->em->bm, index - 1); - if (eed && distance < *dist) { - *dist = distance; + if (eed && distance < *r_dist) { + *r_dist = distance; return eed; } else { @@ -521,36 +515,37 @@ BMEdge *EDBM_edge_find_nearest(ViewContext *vc, int *dist) } } else { - struct { ViewContext vc; float mval[2]; int dist; BMEdge *closest; } data; + struct { ViewContext vc; float mval_fl[2]; float dist; BMEdge *closest; } data; data.vc = *vc; - data.mval[0] = vc->mval[0]; - data.mval[1] = vc->mval[1]; - data.dist = *dist; + data.mval_fl[0] = vc->mval[0]; + data.mval_fl[1] = vc->mval[1]; + data.dist = *r_dist; data.closest = NULL; ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); mesh_foreachScreenEdge(vc, findnearestedge__doClosest, &data, V3D_CLIP_TEST_REGION); - *dist = data.dist; + *r_dist = data.dist; return data.closest; } } -static void findnearestface__getDistance(void *userData, BMFace *efa, int x, int y, int UNUSED(index)) +static void findnearestface__getDistance(void *userData, BMFace *efa, const float screen_co[2], int UNUSED(index)) { - struct { short mval[2]; int dist; BMFace *toFace; } *data = userData; + struct { float mval_fl[2]; float dist; BMFace *toFace; } *data = userData; if (efa == data->toFace) { - int temp = abs(data->mval[0] - x) + abs(data->mval[1] - y); + const float dist_test = len_manhattan_v2v2(data->mval_fl, screen_co); - if (temp < data->dist) - data->dist = temp; + if (dist_test < data->dist) { + data->dist = dist_test; + } } } -static void findnearestface__doClosest(void *userData, BMFace *efa, int x, int y, int index) +static void findnearestface__doClosest(void *userData, BMFace *efa, const float screen_co[2], int index) { - struct { short mval[2], pass; int dist, lastIndex, closestIndex; BMFace *closest; } *data = userData; + struct { float mval_fl[2], pass; float dist, lastIndex, closestIndex; BMFace *closest; } *data = userData; if (data->pass == 0) { if (index <= data->lastIndex) @@ -562,17 +557,17 @@ static void findnearestface__doClosest(void *userData, BMFace *efa, int x, int y } if (data->dist > 3) { - int temp = abs(data->mval[0] - x) + abs(data->mval[1] - y); + const float dist_test = len_manhattan_v2v2(data->mval_fl, screen_co); - if (temp < data->dist) { - data->dist = temp; + if (dist_test < data->dist) { + data->dist = dist_test; data->closest = efa; data->closestIndex = index; } } } -BMFace *EDBM_face_find_nearest(ViewContext *vc, int *dist) +BMFace *EDBM_face_find_nearest(ViewContext *vc, float *r_dist) { if (vc->v3d->drawtype > OB_WIRE && (vc->v3d->flag & V3D_ZBUF_SELECT)) { @@ -585,17 +580,17 @@ BMFace *EDBM_face_find_nearest(ViewContext *vc, int *dist) efa = BM_face_at_index(vc->em->bm, index - 1); if (efa) { - struct { short mval[2]; int dist; BMFace *toFace; } data; + struct { float mval_fl[2]; float dist; BMFace *toFace; } data; - data.mval[0] = vc->mval[0]; - data.mval[1] = vc->mval[1]; + data.mval_fl[0] = vc->mval[0]; + data.mval_fl[1] = vc->mval[1]; data.dist = 0x7FFF; /* largest short */ data.toFace = efa; mesh_foreachScreenFace(vc, findnearestface__getDistance, &data); - if (vc->em->selectmode == SCE_SELECT_FACE || data.dist < *dist) { /* only faces, no dist check */ - *dist = data.dist; + if ((vc->em->selectmode == SCE_SELECT_FACE) || (data.dist < *r_dist)) { /* only faces, no dist check */ + *r_dist = data.dist; return efa; } } @@ -603,7 +598,7 @@ BMFace *EDBM_face_find_nearest(ViewContext *vc, int *dist) return NULL; } else { - struct { short mval[2], pass; int dist, lastIndex, closestIndex; BMFace *closest; } data; + struct { float mval_fl[2], pass; float dist, lastIndex, closestIndex; BMFace *closest; } data; static int lastSelectedIndex = 0; static BMFace *lastSelected = NULL; @@ -613,9 +608,9 @@ BMFace *EDBM_face_find_nearest(ViewContext *vc, int *dist) } data.lastIndex = lastSelectedIndex; - data.mval[0] = vc->mval[0]; - data.mval[1] = vc->mval[1]; - data.dist = *dist; + data.mval_fl[0] = vc->mval[0]; + data.mval_fl[1] = vc->mval[1]; + data.dist = *r_dist; data.closest = NULL; data.closestIndex = 0; ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); @@ -623,13 +618,13 @@ BMFace *EDBM_face_find_nearest(ViewContext *vc, int *dist) data.pass = 0; mesh_foreachScreenFace(vc, findnearestface__doClosest, &data); - if (data.dist > 3) { + if (data.dist > 3.0f) { data.pass = 1; ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); mesh_foreachScreenFace(vc, findnearestface__doClosest, &data); } - *dist = data.dist; + *r_dist = data.dist; lastSelected = data.closest; lastSelectedIndex = data.closestIndex; @@ -645,7 +640,7 @@ BMFace *EDBM_face_find_nearest(ViewContext *vc, int *dist) static int unified_findnearest(ViewContext *vc, BMVert **r_eve, BMEdge **r_eed, BMFace **r_efa) { BMEditMesh *em = vc->em; - int dist = 75; + float dist = 75.0f; *r_eve = NULL; *r_eed = NULL; @@ -1004,7 +999,7 @@ static void mouse_mesh_loop(bContext *C, int mval[2], short extend, short ring) BMEditMesh *em; BMEdge *eed; int select = TRUE; - int dist = 50; + float dist = 50.0f; float mvalf[2]; em_setup_viewcontext(C, &vc); @@ -1392,7 +1387,7 @@ static int mouse_mesh_shortest_path(bContext *C, int mval[2]) ViewContext vc; BMEditMesh *em; BMEdge *e; - int dist = 50; + float dist = 75.0f; em_setup_viewcontext(C, &vc); vc.mval[0] = mval[0]; diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c index f265113708a..b5521a5ecea 100644 --- a/source/blender/editors/mesh/meshtools.c +++ b/source/blender/editors/mesh/meshtools.c @@ -1192,7 +1192,7 @@ int ED_mesh_pick_face(bContext *C, Mesh *me, const int mval[2], unsigned int *in /* sample rect to increase chances of selecting, so that when clicking * on an edge in the backbuf, we can still select a face */ - int dummy_dist; + float dummy_dist; *index = view3d_sample_backbuf_rect(&vc, mval, size, 1, me->totpoly + 1, &dummy_dist, 0, NULL, NULL); } else { @@ -1277,7 +1277,7 @@ int ED_mesh_pick_vert(bContext *C, Mesh *me, const int mval[2], unsigned int *in /* sample rect to increase chances of selecting, so that when clicking * on an face in the backbuf, we can still select a vert */ - int dummy_dist; + float dummy_dist; *index = view3d_sample_backbuf_rect(&vc, mval, size, 1, me->totvert + 1, &dummy_dist, 0, NULL, NULL); } else { diff --git a/source/blender/editors/object/object_lattice.c b/source/blender/editors/object/object_lattice.c index 1f7be0bf9a6..aa9e4d83774 100644 --- a/source/blender/editors/object/object_lattice.c +++ b/source/blender/editors/object/object_lattice.c @@ -302,16 +302,16 @@ void LATTICE_OT_make_regular(wmOperatorType *ot) /****************************** Mouse Selection *************************/ -static void findnearestLattvert__doClosest(void *userData, BPoint *bp, int x, int y) +static void findnearestLattvert__doClosest(void *userData, BPoint *bp, const float screen_co[2]) { - struct { BPoint *bp; short dist, select; int mval[2]; } *data = userData; - float temp = abs(data->mval[0] - x) + abs(data->mval[1] - y); + struct { BPoint *bp; float dist; int select; float mval_fl[2]; } *data = userData; + float dist_test = len_manhattan_v2v2(data->mval_fl, screen_co); - if ((bp->f1 & SELECT) == data->select) - temp += 5; + if ((bp->f1 & SELECT) && data->select) + dist_test += 5.0f; - if (temp < data->dist) { - data->dist = temp; + if (dist_test < data->dist) { + data->dist = dist_test; data->bp = bp; } @@ -322,12 +322,12 @@ static BPoint *findnearestLattvert(ViewContext *vc, const int mval[2], int sel) /* sel==1: selected gets a disadvantage */ /* in nurb and bezt or bp the nearest is written */ /* return 0 1 2: handlepunt */ - struct { BPoint *bp; short dist, select; int mval[2]; } data = {NULL}; + struct { BPoint *bp; float dist; int select; float mval_fl[2]; } data = {NULL}; data.dist = 100; data.select = sel; - data.mval[0] = mval[0]; - data.mval[1] = mval[1]; + data.mval_fl[0] = mval[0]; + data.mval_fl[1] = mval[1]; ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); lattice_foreachScreenVert(vc, findnearestLattvert__doClosest, &data); @@ -341,7 +341,7 @@ int mouse_lattice(bContext *C, const int mval[2], int extend, int deselect, int BPoint *bp = NULL; view3d_set_viewcontext(C, &vc); - bp = findnearestLattvert(&vc, mval, 1); + bp = findnearestLattvert(&vc, mval, TRUE); if (bp) { if (extend) { diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 1b008c27fc0..fb308db0926 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -119,22 +119,22 @@ typedef enum eWireDrawMode { /* user data structures for derived mesh callbacks */ typedef struct foreachScreenVert_userData { - void (*func)(void *userData, BMVert *eve, int x, int y, int index); + void (*func)(void *userData, BMVert *eve, const float screen_co_b[2], int index); void *userData; ViewContext vc; eV3DClipTest clipVerts; } foreachScreenVert_userData; typedef struct foreachScreenEdge_userData { - void (*func)(void *userData, BMEdge *eed, int x0, int y0, int x1, int y1, int index); + void (*func)(void *userData, BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], int index); void *userData; ViewContext vc; - rcti win_rect; /* copy of: vc.ar->winx/winy, use for faster tests, minx/y will always be 0 */ + rctf win_rect; /* copy of: vc.ar->winx/winy, use for faster tests, minx/y will always be 0 */ eV3DClipTest clipVerts; } foreachScreenEdge_userData; typedef struct foreachScreenFace_userData { - void (*func)(void *userData, BMFace *efa, int x, int y, int index); + void (*func)(void *userData, BMFace *efa, const float screen_co_b[2], int index); void *userData; ViewContext vc; } foreachScreenFace_userData; @@ -1870,7 +1870,7 @@ static void lattice_draw_verts(Lattice *lt, DispList *dl, short sel) bglEnd(); } -void lattice_foreachScreenVert(ViewContext *vc, void (*func)(void *userData, BPoint *bp, int x, int y), void *userData) +void lattice_foreachScreenVert(ViewContext *vc, void (*func)(void *userData, BPoint *bp, const float screen_co[2]), void *userData) { Object *obedit = vc->obedit; Lattice *lt = obedit->data; @@ -1883,11 +1883,11 @@ void lattice_foreachScreenVert(ViewContext *vc, void (*func)(void *userData, BPo for (i = 0; i < N; i++, bp++, co += 3) { if (bp->hide == 0) { - int screen_co[2]; - if (ED_view3d_project_int_object(vc->ar, dl ? co : bp->vec, screen_co, - V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_OK) + float screen_co[2]; + if (ED_view3d_project_float_object(vc->ar, dl ? co : bp->vec, screen_co, + V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_OK) { - func(userData, bp, screen_co[0], screen_co[1]); + func(userData, bp, screen_co); } } } @@ -1993,19 +1993,19 @@ static void mesh_foreachScreenVert__mapFunc(void *userData, int index, const flo const eV3DProjTest flag = (data->clipVerts == V3D_CLIP_TEST_OFF) ? V3D_PROJ_TEST_NOP : V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN; - int screen_co[2]; + float screen_co[2]; - if (ED_view3d_project_int_object(data->vc.ar, co, screen_co, flag) != V3D_PROJ_RET_OK) { + if (ED_view3d_project_float_object(data->vc.ar, co, screen_co, flag) != V3D_PROJ_RET_OK) { return; } - data->func(data->userData, eve, screen_co[0], screen_co[1], index); + data->func(data->userData, eve, screen_co, index); } } void mesh_foreachScreenVert( ViewContext *vc, - void (*func)(void *userData, BMVert *eve, int x, int y, int index), + void (*func)(void *userData, BMVert *eve, const float screen_co[2], int index), void *userData, eV3DClipTest clipVerts) { foreachScreenVert_userData data; @@ -2060,17 +2060,17 @@ static void mesh_foreachScreenEdge__mapFunc(void *userData, int index, const flo BMEdge *eed = EDBM_edge_at_index(data->vc.em, index); if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { - int screen_co_a[2]; - int screen_co_b[2]; + float screen_co_a[2]; + float screen_co_b[2]; const eV3DProjTest flag = (data->clipVerts == V3D_CLIP_TEST_RV3D_CLIPPING) ? V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN : V3D_PROJ_TEST_NOP; - if (ED_view3d_project_int_object(data->vc.ar, v0co, screen_co_a, flag) != V3D_PROJ_RET_OK) { + if (ED_view3d_project_float_object(data->vc.ar, v0co, screen_co_a, flag) != V3D_PROJ_RET_OK) { return; } - if (ED_view3d_project_int_object(data->vc.ar, v1co, screen_co_b, flag) != V3D_PROJ_RET_OK) { + if (ED_view3d_project_float_object(data->vc.ar, v1co, screen_co_b, flag) != V3D_PROJ_RET_OK) { return; } @@ -2079,21 +2079,19 @@ static void mesh_foreachScreenEdge__mapFunc(void *userData, int index, const flo } else { if (data->clipVerts == V3D_CLIP_TEST_REGION) { - if (!BLI_rcti_isect_segment(&data->win_rect, screen_co_a, screen_co_b)) { + if (!BLI_rctf_isect_segment(&data->win_rect, screen_co_a, screen_co_b)) { return; } } } - data->func(data->userData, eed, - screen_co_a[0], screen_co_a[1], - screen_co_b[0], screen_co_b[1], index); + data->func(data->userData, eed, screen_co_a, screen_co_b, index); } } void mesh_foreachScreenEdge( ViewContext *vc, - void (*func)(void *userData, BMEdge *eed, int x0, int y0, int x1, int y1, int index), + void (*func)(void *userData, BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], int index), void *userData, eV3DClipTest clipVerts) { foreachScreenEdge_userData data; @@ -2126,18 +2124,18 @@ static void mesh_foreachScreenFace__mapFunc(void *userData, int index, const flo BMFace *efa = EDBM_face_at_index(data->vc.em, index); if (efa && !BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { - int screen_co[2]; - if (ED_view3d_project_int_object(data->vc.ar, cent, screen_co, + float screen_co[2]; + if (ED_view3d_project_float_object(data->vc.ar, cent, screen_co, V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) { - data->func(data->userData, efa, screen_co[0], screen_co[1], index); + data->func(data->userData, efa, screen_co, index); } } } void mesh_foreachScreenFace( ViewContext *vc, - void (*func)(void *userData, BMFace *efa, int x, int y, int index), + void (*func)(void *userData, BMFace *efa, const float screen_co_b[2], int index), void *userData) { foreachScreenFace_userData data; @@ -2158,7 +2156,7 @@ void mesh_foreachScreenFace( void nurbs_foreachScreenVert( ViewContext *vc, - void (*func)(void *userData, Nurb *nu, BPoint *bp, BezTriple *bezt, int beztindex, int x, int y), + void (*func)(void *userData, Nurb *nu, BPoint *bp, BezTriple *bezt, int beztindex, const float screen_co_b[2]), void *userData) { Curve *cu = vc->obedit->data; @@ -2174,30 +2172,30 @@ void nurbs_foreachScreenVert( BezTriple *bezt = &nu->bezt[i]; if (bezt->hide == 0) { - int screen_co[2]; + float screen_co[2]; if (cu->drawflag & CU_HIDE_HANDLES) { - if (ED_view3d_project_int_object(vc->ar, bezt->vec[1], screen_co, - V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_OK) + if (ED_view3d_project_float_object(vc->ar, bezt->vec[1], screen_co, + V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_OK) { - func(userData, nu, NULL, bezt, 1, screen_co[0], screen_co[1]); + func(userData, nu, NULL, bezt, 1, screen_co); } } else { - if (ED_view3d_project_int_object(vc->ar, bezt->vec[0], screen_co, - V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_OK) + if (ED_view3d_project_float_object(vc->ar, bezt->vec[0], screen_co, + V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_OK) { - func(userData, nu, NULL, bezt, 0, screen_co[0], screen_co[1]); + func(userData, nu, NULL, bezt, 0, screen_co); } - if (ED_view3d_project_int_object(vc->ar, bezt->vec[1], screen_co, - V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_OK) + if (ED_view3d_project_float_object(vc->ar, bezt->vec[1], screen_co, + V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_OK) { - func(userData, nu, NULL, bezt, 1, screen_co[0], screen_co[1]); + func(userData, nu, NULL, bezt, 1, screen_co); } - if (ED_view3d_project_int_object(vc->ar, bezt->vec[2], screen_co, - V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_OK) + if (ED_view3d_project_float_object(vc->ar, bezt->vec[2], screen_co, + V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_OK) { - func(userData, nu, NULL, bezt, 2, screen_co[0], screen_co[1]); + func(userData, nu, NULL, bezt, 2, screen_co); } } } @@ -2208,11 +2206,11 @@ void nurbs_foreachScreenVert( BPoint *bp = &nu->bp[i]; if (bp->hide == 0) { - int screen_co[2]; - if (ED_view3d_project_int_object(vc->ar, bp->vec, screen_co, - V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_OK) + float screen_co[2]; + if (ED_view3d_project_float_object(vc->ar, bp->vec, screen_co, + V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_OK) { - func(userData, nu, bp, NULL, -1, screen_co[0], screen_co[1]); + func(userData, nu, bp, NULL, -1, screen_co); } } } @@ -2223,18 +2221,18 @@ void nurbs_foreachScreenVert( /* ED_view3d_init_mats_rv3d must be called first */ void mball_foreachScreenElem( struct ViewContext *vc, - void (*func)(void *userData, struct MetaElem *ml, int x, int y), + void (*func)(void *userData, struct MetaElem *ml, const float screen_co_b[2]), void *userData) { MetaBall *mb = (MetaBall *)vc->obedit->data; MetaElem *ml; for (ml = mb->editelems->first; ml; ml = ml->next) { - int screen_co[2]; - if (ED_view3d_project_int_object(vc->ar, &ml->x, screen_co, - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) + float screen_co[2]; + if (ED_view3d_project_float_object(vc->ar, &ml->x, screen_co, + V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) { - func(userData, ml, screen_co[0], screen_co[1]); + func(userData, ml, screen_co); } } } @@ -2242,7 +2240,7 @@ void mball_foreachScreenElem( /* ED_view3d_init_mats_rv3d must be called first */ void armature_foreachScreenBone( struct ViewContext *vc, - void (*func)(void *userData, struct EditBone *ebone, int x0, int y0, int x1, int y1), + void (*func)(void *userData, struct EditBone *ebone, const float screen_co_a[2], const float screen_co_b[2]), void *userData) { bArmature *arm = vc->obedit->data; @@ -2250,12 +2248,12 @@ void armature_foreachScreenBone( for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { if (EBONE_VISIBLE(arm, ebone)) { - int screen_co_a[2], screen_co_b[2]; + float screen_co_a[2], screen_co_b[2]; int points_proj_tot = 0; /* project head location to screenspace */ - if (ED_view3d_project_int_object(vc->ar, ebone->head, screen_co_a, - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) + if (ED_view3d_project_float_object(vc->ar, ebone->head, screen_co_a, + V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) { points_proj_tot++; } @@ -2265,8 +2263,8 @@ void armature_foreachScreenBone( } /* project tail location to screenspace */ - if (ED_view3d_project_int_object(vc->ar, ebone->tail, screen_co_b, - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) + if (ED_view3d_project_float_object(vc->ar, ebone->tail, screen_co_b, + V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) { points_proj_tot++; } @@ -2276,9 +2274,7 @@ void armature_foreachScreenBone( } if (points_proj_tot) { /* at least one point's projection worked */ - func(userData, ebone, - screen_co_a[0], screen_co_a[1], - screen_co_b[0], screen_co_b[1]); + func(userData, ebone, screen_co_a, screen_co_b); } } } @@ -2288,7 +2284,7 @@ void armature_foreachScreenBone( /* almost _exact_ copy of #armature_foreachScreenBone */ void pose_foreachScreenBone( struct ViewContext *vc, - void (*func)(void *userData, struct bPoseChannel *pchan, int x0, int y0, int x1, int y1), + void (*func)(void *userData, struct bPoseChannel *pchan, const float screen_co_a[2], const float screen_co_b[2]), void *userData) { bArmature *arm = vc->obact->data; @@ -2297,12 +2293,12 @@ void pose_foreachScreenBone( for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) { if (PBONE_VISIBLE(arm, pchan->bone)) { - int screen_co_a[2], screen_co_b[2]; + float screen_co_a[2], screen_co_b[2]; int points_proj_tot = 0; /* project head location to screenspace */ - if (ED_view3d_project_int_object(vc->ar, pchan->pose_head, screen_co_a, - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) + if (ED_view3d_project_float_object(vc->ar, pchan->pose_head, screen_co_a, + V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) { points_proj_tot++; } @@ -2312,8 +2308,8 @@ void pose_foreachScreenBone( } /* project tail location to screenspace */ - if (ED_view3d_project_int_object(vc->ar, pchan->pose_tail, screen_co_b, - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) + if (ED_view3d_project_float_object(vc->ar, pchan->pose_tail, screen_co_b, + V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) { points_proj_tot++; } @@ -2323,9 +2319,7 @@ void pose_foreachScreenBone( } if (points_proj_tot) { /* at least one point's projection worked */ - func(userData, pchan, - screen_co_a[0], screen_co_a[1], - screen_co_b[0], screen_co_b[1]); + func(userData, pchan, screen_co_a, screen_co_b); } } } diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index c5246b1ad1f..88375c409b8 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -1462,7 +1462,7 @@ ImBuf *view3d_read_backbuf(ViewContext *vc, short xmin, short ymin, short xmax, /* smart function to sample a rect spiralling outside, nice for backbuf selection */ unsigned int view3d_sample_backbuf_rect(ViewContext *vc, const int mval[2], int size, - unsigned int min, unsigned int max, int *dist, short strict, + unsigned int min, unsigned int max, float *r_dist, short strict, void *handle, unsigned int (*indextest)(void *handle, unsigned int index)) { struct ImBuf *buf; @@ -1500,13 +1500,13 @@ unsigned int view3d_sample_backbuf_rect(ViewContext *vc, const int mval[2], int if (strict) { indexok = indextest(handle, *tbuf - min + 1); if (indexok) { - *dist = (short) sqrt( (float)distance); + *r_dist = sqrtf((float)distance); index = *tbuf - min + 1; goto exit; } } else { - *dist = (short) sqrt( (float)distance); /* XXX, this distance is wrong - */ + *r_dist = sqrtf((float)distance); /* XXX, this distance is wrong - */ index = *tbuf - min + 1; /* messy yah, but indices start at 1 */ goto exit; } diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index 5f0bb180711..d40dc5c67ca 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -258,6 +258,8 @@ static void edbm_backbuf_check_and_select_tfaces(Mesh *me, int select) typedef struct LassoSelectUserData { ViewContext *vc; const rcti *rect; + const rctf *rect_fl; + rctf _rect_fl; const int (*mcords)[2]; int moves; int select; @@ -273,7 +275,11 @@ static void view3d_userdata_lassoselect_init(LassoSelectUserData *r_data, const int moves, const int select) { r_data->vc = vc; + r_data->rect = rect; + r_data->rect_fl = &r_data->_rect_fl; + BLI_rctf_rcti_copy(&r_data->_rect_fl, rect); + r_data->mcords = mcords; r_data->moves = moves; r_data->select = select; @@ -314,29 +320,29 @@ static int view3d_selectable_data(bContext *C) /* helper also for borderselect */ -static int edge_fully_inside_rect(const rcti *rect, int x1, int y1, int x2, int y2) +static int edge_fully_inside_rect(const rctf *rect, const float v1[2], const float v2[2]) { - return BLI_rcti_isect_pt(rect, x1, y1) && BLI_rcti_isect_pt(rect, x2, y2); + return BLI_rctf_isect_pt_v(rect, v1) && BLI_rctf_isect_pt_v(rect, v2); } -static int edge_inside_rect(const rcti *rect, int x1, int y1, int x2, int y2) +static int edge_inside_rect(const rctf *rect, const float v1[2], const float v2[2]) { int d1, d2, d3, d4; /* check points in rect */ - if (edge_fully_inside_rect(rect, x1, y1, x2, y2)) return 1; + if (edge_fully_inside_rect(rect, v1, v2)) return 1; /* check points completely out rect */ - if (x1 < rect->xmin && x2 < rect->xmin) return 0; - if (x1 > rect->xmax && x2 > rect->xmax) return 0; - if (y1 < rect->ymin && y2 < rect->ymin) return 0; - if (y1 > rect->ymax && y2 > rect->ymax) return 0; + if (v1[0] < rect->xmin && v2[0] < rect->xmin) return 0; + if (v1[0] > rect->xmax && v2[0] > rect->xmax) return 0; + if (v1[1] < rect->ymin && v2[1] < rect->ymin) return 0; + if (v1[1] > rect->ymax && v2[1] > rect->ymax) return 0; /* simple check lines intersecting. */ - d1 = (y1 - y2) * (x1 - rect->xmin) + (x2 - x1) * (y1 - rect->ymin); - d2 = (y1 - y2) * (x1 - rect->xmin) + (x2 - x1) * (y1 - rect->ymax); - d3 = (y1 - y2) * (x1 - rect->xmax) + (x2 - x1) * (y1 - rect->ymax); - d4 = (y1 - y2) * (x1 - rect->xmax) + (x2 - x1) * (y1 - rect->ymin); + d1 = (v1[1] - v2[1]) * (v1[0] - rect->xmin) + (v2[0] - v1[0]) * (v1[1] - rect->ymin); + d2 = (v1[1] - v2[1]) * (v1[0] - rect->xmin) + (v2[0] - v1[0]) * (v1[1] - rect->ymax); + d3 = (v1[1] - v2[1]) * (v1[0] - rect->xmax) + (v2[0] - v1[0]) * (v1[1] - rect->ymax); + d4 = (v1[1] - v2[1]) * (v1[0] - rect->xmax) + (v2[0] - v1[0]) * (v1[1] - rect->ymin); if (d1 < 0 && d2 < 0 && d3 < 0 && d4 < 0) return 0; if (d1 > 0 && d2 > 0 && d3 > 0 && d4 > 0) return 0; @@ -344,7 +350,7 @@ static int edge_inside_rect(const rcti *rect, int x1, int y1, int x2, int y2) return 1; } -static void do_lasso_select_pose__doSelectBone(void *userData, struct bPoseChannel *pchan, int x0, int y0, int x1, int y1) +static void do_lasso_select_pose__doSelectBone(void *userData, struct bPoseChannel *pchan, const float screen_co_a[2], const float screen_co_b[2]) { LassoSelectUserData *data = userData; bArmature *arm = data->vc->obact->data; @@ -353,6 +359,11 @@ static void do_lasso_select_pose__doSelectBone(void *userData, struct bPoseChann int is_point_done = FALSE; int points_proj_tot = 0; + const int x0 = screen_co_a[0]; + const int y0 = screen_co_a[1]; + const int x1 = screen_co_b[0]; + const int y1 = screen_co_b[1]; + /* project head location to screenspace */ if (x0 != IS_CLIPPED) { points_proj_tot++; @@ -394,12 +405,12 @@ static void do_lasso_select_pose(ViewContext *vc, Object *ob, const int mcords[] return; } + BLI_lasso_boundbox(&rect, mcords, moves); + view3d_userdata_lassoselect_init(&data, vc, &rect, mcords, moves, select); ED_view3d_init_mats_rv3d(vc->obact, vc->rv3d); - BLI_lasso_boundbox(&rect, mcords, moves); - pose_foreachScreenBone(vc, do_lasso_select_pose__doSelectBone, &data); if (data.is_change) { @@ -445,23 +456,28 @@ static void do_lasso_select_objects(ViewContext *vc, const int mcords[][2], cons } } -static void do_lasso_select_mesh__doSelectVert(void *userData, BMVert *eve, int x, int y, int UNUSED(index)) +static void do_lasso_select_mesh__doSelectVert(void *userData, BMVert *eve, const float screen_co[2], int UNUSED(index)) { LassoSelectUserData *data = userData; - if (BLI_rcti_isect_pt(data->rect, x, y) && - BLI_lasso_is_point_inside(data->mcords, data->moves, x, y, IS_CLIPPED)) + if (BLI_rctf_isect_pt_v(data->rect_fl, screen_co) && + BLI_lasso_is_point_inside(data->mcords, data->moves, screen_co[0], screen_co[1], IS_CLIPPED)) { BM_vert_select_set(data->vc->em->bm, eve, data->select); } } -static void do_lasso_select_mesh__doSelectEdge(void *userData, BMEdge *eed, int x0, int y0, int x1, int y1, int index) +static void do_lasso_select_mesh__doSelectEdge(void *userData, BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], int index) { LassoSelectUserData *data = userData; if (EDBM_backbuf_check(bm_solidoffs + index)) { + const int x0 = screen_co_a[0]; + const int y0 = screen_co_a[1]; + const int x1 = screen_co_b[0]; + const int y1 = screen_co_b[1]; + if (data->pass == 0) { - if (edge_fully_inside_rect(data->rect, x0, y0, x1, y1) && + if (edge_fully_inside_rect(data->rect_fl, screen_co_a, screen_co_b) && BLI_lasso_is_point_inside(data->mcords, data->moves, x0, y0, IS_CLIPPED) && BLI_lasso_is_point_inside(data->mcords, data->moves, x1, y1, IS_CLIPPED)) { @@ -476,12 +492,12 @@ static void do_lasso_select_mesh__doSelectEdge(void *userData, BMEdge *eed, int } } } -static void do_lasso_select_mesh__doSelectFace(void *userData, BMFace *efa, int x, int y, int UNUSED(index)) +static void do_lasso_select_mesh__doSelectFace(void *userData, BMFace *efa, const float screen_co[2], int UNUSED(index)) { LassoSelectUserData *data = userData; - if (BLI_rcti_isect_pt(data->rect, x, y) && - BLI_lasso_is_point_inside(data->mcords, data->moves, x, y, IS_CLIPPED)) + if (BLI_rctf_isect_pt_v(data->rect_fl, screen_co) && + BLI_lasso_is_point_inside(data->mcords, data->moves, screen_co[0], screen_co[1], IS_CLIPPED)) { BM_face_select_set(data->vc->em->bm, efa, data->select); } @@ -494,11 +510,11 @@ static void do_lasso_select_mesh(ViewContext *vc, const int mcords[][2], short m rcti rect; int bbsel; - BLI_lasso_boundbox(&rect, mcords, moves); - /* set editmesh */ vc->em = BMEdit_FromObject(vc->obedit); + BLI_lasso_boundbox(&rect, mcords, moves); + view3d_userdata_lassoselect_init(&data, vc, &rect, mcords, moves, select); if (extend == 0 && select) @@ -542,13 +558,13 @@ static void do_lasso_select_mesh(ViewContext *vc, const int mcords[][2], short m EDBM_selectmode_flush(vc->em); } -static void do_lasso_select_curve__doSelect(void *userData, Nurb *UNUSED(nu), BPoint *bp, BezTriple *bezt, int beztindex, int x, int y) +static void do_lasso_select_curve__doSelect(void *userData, Nurb *UNUSED(nu), BPoint *bp, BezTriple *bezt, int beztindex, const float screen_co[2]) { LassoSelectUserData *data = userData; Object *obedit = data->vc->obedit; Curve *cu = (Curve *)obedit->data; - if (BLI_lasso_is_point_inside(data->mcords, data->moves, x, y, IS_CLIPPED)) { + if (BLI_lasso_is_point_inside(data->mcords, data->moves, screen_co[0], screen_co[1], IS_CLIPPED)) { if (bp) { bp->f1 = data->select ? (bp->f1 | SELECT) : (bp->f1 & ~SELECT); if (bp == cu->lastsel && !(bp->f1 & SELECT)) cu->lastsel = NULL; @@ -578,8 +594,11 @@ static void do_lasso_select_curve__doSelect(void *userData, Nurb *UNUSED(nu), BP static void do_lasso_select_curve(ViewContext *vc, const int mcords[][2], short moves, short extend, short select) { LassoSelectUserData data; + rcti rect; - view3d_userdata_lassoselect_init(&data, vc, NULL, mcords, moves, select); + BLI_lasso_boundbox(&rect, mcords, moves); + + view3d_userdata_lassoselect_init(&data, vc, &rect, mcords, moves, select); if (extend == 0 && select) CU_deselect_all(vc->obedit); @@ -588,19 +607,23 @@ static void do_lasso_select_curve(ViewContext *vc, const int mcords[][2], short nurbs_foreachScreenVert(vc, do_lasso_select_curve__doSelect, &data); } -static void do_lasso_select_lattice__doSelect(void *userData, BPoint *bp, int x, int y) +static void do_lasso_select_lattice__doSelect(void *userData, BPoint *bp, const float screen_co[2]) { LassoSelectUserData *data = userData; - if (BLI_lasso_is_point_inside(data->mcords, data->moves, x, y, IS_CLIPPED)) { + if (BLI_rctf_isect_pt_v(data->rect_fl, screen_co) && + BLI_lasso_is_point_inside(data->mcords, data->moves, screen_co[0], screen_co[1], IS_CLIPPED)) { bp->f1 = data->select ? (bp->f1 | SELECT) : (bp->f1 & ~SELECT); } } static void do_lasso_select_lattice(ViewContext *vc, const int mcords[][2], short moves, short extend, short select) { LassoSelectUserData data; + rcti rect; - view3d_userdata_lassoselect_init(&data, vc, NULL, mcords, moves, select); + BLI_lasso_boundbox(&rect, mcords, moves); + + view3d_userdata_lassoselect_init(&data, vc, &rect, mcords, moves, select); if (extend == 0 && select) ED_setflagsLatt(vc->obedit, 0); @@ -609,7 +632,7 @@ static void do_lasso_select_lattice(ViewContext *vc, const int mcords[][2], shor lattice_foreachScreenVert(vc, do_lasso_select_lattice__doSelect, &data); } -static void do_lasso_select_armature__doSelectBone(void *userData, struct EditBone *ebone, int x0, int y0, int x1, int y1) +static void do_lasso_select_armature__doSelectBone(void *userData, struct EditBone *ebone, const float screen_co_a[2], const float screen_co_b[2]) { LassoSelectUserData *data = userData; bArmature *arm = data->vc->obedit->data; @@ -618,6 +641,11 @@ static void do_lasso_select_armature__doSelectBone(void *userData, struct EditBo int is_point_done = FALSE; int points_proj_tot = 0; + const int x0 = screen_co_a[0]; + const int y0 = screen_co_a[1]; + const int x1 = screen_co_b[0]; + const int y1 = screen_co_b[1]; + /* project head location to screenspace */ if (x0 != IS_CLIPPED) { points_proj_tot++; @@ -660,12 +688,12 @@ static void do_lasso_select_armature(ViewContext *vc, const int mcords[][2], sho LassoSelectUserData data; rcti rect; + BLI_lasso_boundbox(&rect, mcords, moves); + view3d_userdata_lassoselect_init(&data, vc, &rect, mcords, moves, select); ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); - BLI_lasso_boundbox(&rect, mcords, moves); - if (extend == 0 && select) ED_armature_deselect_all_visible(vc->obedit); @@ -679,12 +707,12 @@ static void do_lasso_select_armature(ViewContext *vc, const int mcords[][2], sho } } -static void do_lasso_select_mball__doSelectElem(void *userData, struct MetaElem *ml, int x, int y) +static void do_lasso_select_mball__doSelectElem(void *userData, struct MetaElem *ml, const float screen_co[2]) { LassoSelectUserData *data = userData; - if (BLI_rcti_isect_pt(data->rect, x, y) && - BLI_lasso_is_point_inside(data->mcords, data->moves, x, y, INT_MAX)) { + if (BLI_rctf_isect_pt_v(data->rect_fl, screen_co) && + BLI_lasso_is_point_inside(data->mcords, data->moves, screen_co[0], screen_co[1], INT_MAX)) { if (data->select) ml->flag |= SELECT; else ml->flag &= ~SELECT; data->is_change = TRUE; @@ -700,12 +728,12 @@ static void do_lasso_select_meta(ViewContext *vc, const int mcords[][2], short m if (extend == 0 && select) BKE_mball_deselect_all(mb); + BLI_lasso_boundbox(&rect, mcords, moves); + view3d_userdata_lassoselect_init(&data, vc, &rect, mcords, moves, select); ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); - BLI_lasso_boundbox(&rect, mcords, moves); - mball_foreachScreenElem(vc, do_lasso_select_mball__doSelectElem, &data); } @@ -1583,6 +1611,8 @@ static int mouse_select(bContext *C, const int mval[2], short extend, short dese typedef struct BoxSelectUserData { ViewContext *vc; const rcti *rect; + const rctf *rect_fl; + rctf _rect_fl; int select; /* runtime */ @@ -1595,7 +1625,11 @@ static void view3d_userdata_boxselect_init(BoxSelectUserData *r_data, ViewContext *vc, const rcti *rect, const int select) { r_data->vc = vc; + r_data->rect = rect; + r_data->rect_fl = &r_data->_rect_fl; + BLI_rctf_rcti_copy(&r_data->_rect_fl, rect); + r_data->select = select; /* runtime */ @@ -1604,23 +1638,20 @@ static void view3d_userdata_boxselect_init(BoxSelectUserData *r_data, r_data->is_change = FALSE; } -int edge_inside_circle(int centx, int centy, int radius, int x1, int y1, int x2, int y2) +int edge_inside_circle(const float cent[2], float radius, const float screen_co_a[2], const float screen_co_b[2]) { int radius_squared = radius * radius; /* check points in circle itself */ - if ((x1 - centx) * (x1 - centx) + (y1 - centy) * (y1 - centy) <= radius_squared) { + if (len_squared_v2v2(cent, screen_co_a) <= radius_squared) { return TRUE; } - else if ((x2 - centx) * (x2 - centx) + (y2 - centy) * (y2 - centy) <= radius_squared) { + if (len_squared_v2v2(cent, screen_co_b) <= radius_squared) { return TRUE; } else { - const float cent[2] = {centx, centy}; - const float v1[2] = {x1, y1}; - const float v2[2] = {x2, y2}; /* pointdistline */ - if (dist_squared_to_line_segment_v2(cent, v1, v2) < (float)radius_squared) { + if (dist_squared_to_line_segment_v2(cent, screen_co_a, screen_co_b) < (float)radius_squared) { return TRUE; } } @@ -1628,13 +1659,13 @@ int edge_inside_circle(int centx, int centy, int radius, int x1, int y1, int x2, return FALSE; } -static void do_nurbs_box_select__doSelect(void *userData, Nurb *UNUSED(nu), BPoint *bp, BezTriple *bezt, int beztindex, int x, int y) +static void do_nurbs_box_select__doSelect(void *userData, Nurb *UNUSED(nu), BPoint *bp, BezTriple *bezt, int beztindex, const float screen_co[2]) { BoxSelectUserData *data = userData; Object *obedit = data->vc->obedit; Curve *cu = (Curve *)obedit->data; - if (BLI_rcti_isect_pt(data->rect, x, y)) { + if (BLI_rctf_isect_pt_v(data->rect_fl, screen_co)) { if (bp) { bp->f1 = data->select ? (bp->f1 | SELECT) : (bp->f1 & ~SELECT); if (bp == cu->lastsel && !(bp->f1 & SELECT)) cu->lastsel = NULL; @@ -1675,11 +1706,11 @@ static int do_nurbs_box_select(ViewContext *vc, rcti *rect, int select, int exte return OPERATOR_FINISHED; } -static void do_lattice_box_select__doSelect(void *userData, BPoint *bp, int x, int y) +static void do_lattice_box_select__doSelect(void *userData, BPoint *bp, const float screen_co[2]) { BoxSelectUserData *data = userData; - if (BLI_rcti_isect_pt(data->rect, x, y)) { + if (BLI_rctf_isect_pt_v(data->rect_fl, screen_co)) { bp->f1 = data->select ? (bp->f1 | SELECT) : (bp->f1 & ~SELECT); } } @@ -1698,37 +1729,37 @@ static int do_lattice_box_select(ViewContext *vc, rcti *rect, int select, int ex return OPERATOR_FINISHED; } -static void do_mesh_box_select__doSelectVert(void *userData, BMVert *eve, int x, int y, int UNUSED(index)) +static void do_mesh_box_select__doSelectVert(void *userData, BMVert *eve, const float screen_co[2], int UNUSED(index)) { BoxSelectUserData *data = userData; - if (BLI_rcti_isect_pt(data->rect, x, y)) { + if (BLI_rctf_isect_pt_v(data->rect_fl, screen_co)) { BM_vert_select_set(data->vc->em->bm, eve, data->select); } } -static void do_mesh_box_select__doSelectEdge(void *userData, BMEdge *eed, int x0, int y0, int x1, int y1, int index) +static void do_mesh_box_select__doSelectEdge(void *userData, BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], int index) { BoxSelectUserData *data = userData; if (EDBM_backbuf_check(bm_solidoffs + index)) { if (data->pass == 0) { - if (edge_fully_inside_rect(data->rect, x0, y0, x1, y1)) { + if (edge_fully_inside_rect(data->rect_fl, screen_co_a, screen_co_b)) { BM_edge_select_set(data->vc->em->bm, eed, data->select); data->is_done = TRUE; } } else { - if (edge_inside_rect(data->rect, x0, y0, x1, y1)) { + if (edge_inside_rect(data->rect_fl, screen_co_a, screen_co_b)) { BM_edge_select_set(data->vc->em->bm, eed, data->select); } } } } -static void do_mesh_box_select__doSelectFace(void *userData, BMFace *efa, int x, int y, int UNUSED(index)) +static void do_mesh_box_select__doSelectFace(void *userData, BMFace *efa, const float screen_co[2], int UNUSED(index)) { BoxSelectUserData *data = userData; - if (BLI_rcti_isect_pt(data->rect, x, y)) { + if (BLI_rctf_isect_pt_v(data->rect_fl, screen_co)) { BM_face_select_set(data->vc->em->bm, efa, data->select); } } @@ -2216,7 +2247,8 @@ void VIEW3D_OT_select(wmOperatorType *ot) typedef struct CircleSelectUserData { ViewContext *vc; short select; - int mval[2]; + int mval[2]; + float mval_fl[2]; float radius; float radius_squared; @@ -2230,6 +2262,9 @@ static void view3d_userdata_circleselect_init(CircleSelectUserData *r_data, r_data->vc = vc; r_data->select = select; copy_v2_v2_int(r_data->mval, mval); + r_data->mval_fl[0] = mval[0]; + r_data->mval_fl[1] = mval[1]; + r_data->radius = rad; r_data->radius_squared = rad * rad; @@ -2237,31 +2272,27 @@ static void view3d_userdata_circleselect_init(CircleSelectUserData *r_data, r_data->is_change = FALSE; } -static void mesh_circle_doSelectVert(void *userData, BMVert *eve, int x, int y, int UNUSED(index)) +static void mesh_circle_doSelectVert(void *userData, BMVert *eve, const float screen_co[2], int UNUSED(index)) { CircleSelectUserData *data = userData; - const float delta[2] = {(float)(x - data->mval[0]), - (float)(y - data->mval[1])}; - if (len_squared_v2(delta) <= data->radius_squared) { + if (len_squared_v2v2(data->mval_fl, screen_co) <= data->radius_squared) { BM_vert_select_set(data->vc->em->bm, eve, data->select); } } -static void mesh_circle_doSelectEdge(void *userData, BMEdge *eed, int x0, int y0, int x1, int y1, int UNUSED(index)) +static void mesh_circle_doSelectEdge(void *userData, BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], int UNUSED(index)) { CircleSelectUserData *data = userData; - if (edge_inside_circle(data->mval[0], data->mval[1], (int)data->radius, x0, y0, x1, y1)) { + if (edge_inside_circle(data->mval_fl, (int)data->radius, screen_co_a, screen_co_b)) { BM_edge_select_set(data->vc->em->bm, eed, data->select); } } -static void mesh_circle_doSelectFace(void *userData, BMFace *efa, int x, int y, int UNUSED(index)) +static void mesh_circle_doSelectFace(void *userData, BMFace *efa, const float screen_co[2], int UNUSED(index)) { CircleSelectUserData *data = userData; - const float delta[2] = {(float)(x - data->mval[0]), - (float)(y - data->mval[1])}; - if (len_squared_v2(delta) <= data->radius_squared) { + if (len_squared_v2v2(data->mval_fl, screen_co) <= data->radius_squared) { BM_face_select_set(data->vc->em->bm, efa, data->select); } } @@ -2345,16 +2376,13 @@ static void paint_vertsel_circle_select(ViewContext *vc, int select, const int m } -static void nurbscurve_circle_doSelect(void *userData, Nurb *UNUSED(nu), BPoint *bp, BezTriple *bezt, int beztindex, int x, int y) +static void nurbscurve_circle_doSelect(void *userData, Nurb *UNUSED(nu), BPoint *bp, BezTriple *bezt, int beztindex, const float screen_co[2]) { CircleSelectUserData *data = userData; Object *obedit = data->vc->obedit; Curve *cu = (Curve *)obedit->data; - const float delta[2] = {(float)(x - data->mval[0]), - (float)(y - data->mval[1])}; - - if (len_squared_v2(delta) <= data->radius_squared) { + if (len_squared_v2v2(data->mval_fl, screen_co) <= data->radius_squared) { if (bp) { bp->f1 = data->select ? (bp->f1 | SELECT) : (bp->f1 & ~SELECT); @@ -2392,13 +2420,11 @@ static void nurbscurve_circle_select(ViewContext *vc, int select, const int mval } -static void latticecurve_circle_doSelect(void *userData, BPoint *bp, int x, int y) +static void latticecurve_circle_doSelect(void *userData, BPoint *bp, const float screen_co[2]) { CircleSelectUserData *data = userData; - const float delta[2] = {(float)(x - data->mval[0]), - (float)(y - data->mval[1])}; - if (len_squared_v2(delta) <= data->radius_squared) { + if (len_squared_v2v2(data->mval_fl, screen_co) <= data->radius_squared) { bp->f1 = data->select ? (bp->f1 | SELECT) : (bp->f1 & ~SELECT); } } @@ -2414,13 +2440,11 @@ static void lattice_circle_select(ViewContext *vc, int select, const int mval[2] /* NOTE: pose-bone case is copied from editbone case... */ -static short pchan_circle_doSelectJoint(void *userData, bPoseChannel *pchan, int x, int y) +static short pchan_circle_doSelectJoint(void *userData, bPoseChannel *pchan, const float screen_co[2]) { CircleSelectUserData *data = userData; - const float delta[2] = {(float)(x - data->mval[0]), - (float)(y - data->mval[1])}; - if (len_squared_v2(delta) <= data->radius_squared) { + if (len_squared_v2v2(data->mval_fl, screen_co) <= data->radius_squared) { if (data->select) pchan->bone->flag |= BONE_SELECTED; else @@ -2429,7 +2453,7 @@ static short pchan_circle_doSelectJoint(void *userData, bPoseChannel *pchan, int } return 0; } -static void do_circle_select_pose__doSelectBone(void *userData, struct bPoseChannel *pchan, int x0, int y0, int x1, int y1) +static void do_circle_select_pose__doSelectBone(void *userData, struct bPoseChannel *pchan, const float screen_co_a[2], const float screen_co_b[2]) { CircleSelectUserData *data = userData; bArmature *arm = data->vc->obact->data; @@ -2439,17 +2463,17 @@ static void do_circle_select_pose__doSelectBone(void *userData, struct bPoseChan int points_proj_tot = 0; /* project head location to screenspace */ - if (x0 != IS_CLIPPED) { + if (screen_co_a[0] != IS_CLIPPED) { points_proj_tot++; - if (pchan_circle_doSelectJoint(data, pchan, x0, y0)) { + if (pchan_circle_doSelectJoint(data, pchan, screen_co_a)) { is_point_done = TRUE; } } /* project tail location to screenspace */ - if (x1 != IS_CLIPPED) { + if (screen_co_b[0] != IS_CLIPPED) { points_proj_tot++; - if (pchan_circle_doSelectJoint(data, pchan, x1, y1)) { + if (pchan_circle_doSelectJoint(data, pchan, screen_co_a)) { is_point_done = TRUE; } } @@ -2462,7 +2486,7 @@ static void do_circle_select_pose__doSelectBone(void *userData, struct bPoseChan * It works nicer to only do this if the head or tail are not in the circle, * otherwise there is no way to circle select joints alone */ if ((is_point_done == FALSE) && (points_proj_tot == 2) && - edge_inside_circle(data->mval[0], data->mval[1], data->radius, x0, y0, x1, y1)) + edge_inside_circle(data->mval_fl, data->radius, screen_co_a, screen_co_b)) { if (data->select) pchan->bone->flag |= BONE_SELECTED; else pchan->bone->flag &= ~BONE_SELECTED; @@ -2494,13 +2518,11 @@ static void pose_circle_select(ViewContext *vc, int select, const int mval[2], f } } -static short armature_circle_doSelectJoint(void *userData, EditBone *ebone, int x, int y, short head) +static short armature_circle_doSelectJoint(void *userData, EditBone *ebone, const float screen_co[2], short head) { CircleSelectUserData *data = userData; - const float delta[2] = {(float)(x - data->mval[0]), - (float)(y - data->mval[1])}; - - if (len_squared_v2(delta) <= data->radius_squared) { + + if (len_squared_v2v2(data->mval_fl, screen_co) <= data->radius_squared) { if (head) { if (data->select) ebone->flag |= BONE_ROOTSEL; @@ -2517,7 +2539,7 @@ static short armature_circle_doSelectJoint(void *userData, EditBone *ebone, int } return 0; } -static void do_circle_select_armature__doSelectBone(void *userData, struct EditBone *ebone, int x0, int y0, int x1, int y1) +static void do_circle_select_armature__doSelectBone(void *userData, struct EditBone *ebone, const float screen_co_a[2], const float screen_co_b[2]) { CircleSelectUserData *data = userData; bArmature *arm = data->vc->obedit->data; @@ -2527,17 +2549,17 @@ static void do_circle_select_armature__doSelectBone(void *userData, struct EditB int points_proj_tot = 0; /* project head location to screenspace */ - if (x0 != IS_CLIPPED) { + if (screen_co_a[0] != IS_CLIPPED) { points_proj_tot++; - if (armature_circle_doSelectJoint(data, ebone, x0, y0, TRUE)) { + if (armature_circle_doSelectJoint(data, ebone, screen_co_a, TRUE)) { is_point_done = TRUE; } } /* project tail location to screenspace */ - if (x1 != IS_CLIPPED) { + if (screen_co_b[0] != IS_CLIPPED) { points_proj_tot++; - if (armature_circle_doSelectJoint(data, ebone, x1, y1, FALSE)) { + if (armature_circle_doSelectJoint(data, ebone, screen_co_b, FALSE)) { is_point_done = TRUE; } } @@ -2550,7 +2572,7 @@ static void do_circle_select_armature__doSelectBone(void *userData, struct EditB * It works nicer to only do this if the head or tail are not in the circle, * otherwise there is no way to circle select joints alone */ if ((is_point_done == FALSE) && (points_proj_tot == 2) && - edge_inside_circle(data->mval[0], data->mval[1], data->radius, x0, y0, x1, y1)) + edge_inside_circle(data->mval_fl, data->radius, screen_co_a, screen_co_b)) { if (data->select) ebone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); else ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); @@ -2578,13 +2600,11 @@ static void armature_circle_select(ViewContext *vc, int select, const int mval[2 } } -static void do_circle_select_mball__doSelectElem(void *userData, struct MetaElem *ml, int x, int y) +static void do_circle_select_mball__doSelectElem(void *userData, struct MetaElem *ml, const float screen_co[2]) { CircleSelectUserData *data = userData; - const float delta[2] = {(float)(x - data->mval[0]), - (float)(y - data->mval[1])}; - if (len_squared_v2(delta) <= data->radius_squared) { + if (len_squared_v2v2(data->mval_fl, screen_co) <= data->radius_squared) { if (data->select) ml->flag |= SELECT; else ml->flag &= ~SELECT; data->is_change = TRUE; From b3bf6b527bcdeb682b595e1baf3abdeafa68ac36 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 10 Oct 2012 01:54:02 +0000 Subject: [PATCH 153/347] object center selection now uses floats, also fix own error in circle selection in recent refactor. --- source/blender/editors/mesh/editmesh_slide.c | 3 ++- .../editors/space_view3d/view3d_select.c | 25 ++++++++++++------- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/source/blender/editors/mesh/editmesh_slide.c b/source/blender/editors/mesh/editmesh_slide.c index eaf0c14a0a8..a0cf5efabd9 100644 --- a/source/blender/editors/mesh/editmesh_slide.c +++ b/source/blender/editors/mesh/editmesh_slide.c @@ -409,7 +409,8 @@ static void vtx_slide_find_edge(VertexSlideOp *vso, wmEvent *event) /* Nearest edge */ BMEdge *nst_edge = NULL; - const float mval_float[] = { (float)event->mval[0], (float)event->mval[1]}; + const float mval_float[2] = {(float)event->mval[0], + (float)event->mval[1]}; /* Set mouse coords */ copy_v2_v2_int(vso->view_context->mval, event->mval); diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index d40dc5c67ca..afd69d56d21 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -1415,9 +1415,12 @@ static int mouse_select(bContext *C, const int mval[2], short extend, short dese View3D *v3d = CTX_wm_view3d(C); Scene *scene = CTX_data_scene(C); Base *base, *startbase = NULL, *basact = NULL, *oldbasact = NULL; - int temp, a, dist = 100; + int a; + float dist = 100.0f; int retval = 0; short hits; + const float mval_fl[2] = {(float)mval[0], (float)mval[1]}; + /* setup view context for argument to callbacks */ view3d_set_viewcontext(C, &vc); @@ -1438,13 +1441,16 @@ static int mouse_select(bContext *C, const int mval[2], short extend, short dese base = startbase; while (base) { if (BASE_SELECTABLE(v3d, base)) { - ED_view3d_project_base(ar, base); - temp = abs(base->sx - mval[0]) + abs(base->sy - mval[1]); - if (base == BASACT) temp += 10; - if (temp < dist) { - - dist = temp; - basact = base; + float screen_co[2]; + if (ED_view3d_project_float_global(ar, base->object->obmat[3], screen_co, + V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) + { + float dist_temp = len_manhattan_v2v2(mval_fl, screen_co); + if (base == BASACT) dist_temp += 10.0f; + if (dist_temp < dist) { + dist = dist_temp; + basact = base; + } } } base = base->next; @@ -2653,11 +2659,12 @@ static int object_circle_select(ViewContext *vc, int select, const int mval[2], const float radius_squared = rad * rad; const float mval_fl[2] = {mval[0], mval[1]}; int is_change = FALSE; + int select_flag = select ? SELECT : 0; Base *base; select = select ? BA_SELECT : BA_DESELECT; for (base = FIRSTBASE; base; base = base->next) { - if (((base->flag & SELECT) == 0) && BASE_SELECTABLE(vc->v3d, base)) { + if (BASE_SELECTABLE(vc->v3d, base) && ((base->flag & SELECT) != select_flag)) { float screen_co[2]; if (ED_view3d_project_float_global(vc->ar, base->object->obmat[3], screen_co, V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) From 22bf1e13db56589debe2f9e41001e8474956e58e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 10 Oct 2012 03:13:02 +0000 Subject: [PATCH 154/347] code cleanup: split `foreach` object data iterator functions out of drawobject.c (since they are used for selection too), into their own file: object_iterators.c --- source/blender/editors/include/ED_object.h | 68 ++- source/blender/editors/include/ED_view3d.h | 18 - source/blender/editors/mesh/editmesh_select.c | 1 + source/blender/editors/object/CMakeLists.txt | 1 + .../blender/editors/object/object_iterators.c | 429 ++++++++++++++++++ .../blender/editors/space_view3d/drawobject.c | 382 +--------------- 6 files changed, 496 insertions(+), 403 deletions(-) create mode 100644 source/blender/editors/object/object_iterators.c diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h index 9836d690e53..aa145dfd906 100644 --- a/source/blender/editors/include/ED_object.h +++ b/source/blender/editors/include/ED_object.h @@ -35,22 +35,31 @@ extern "C" { #endif +struct BMEdge; +struct BMFace; +struct BMVert; +struct BPoint; struct Base; -struct bConstraint; -struct bContext; -struct bPoseChannel; +struct BezTriple; struct Curve; +struct EditBone; struct EnumPropertyItem; struct ID; struct KeyBlock; struct Lattice; struct Main; struct Mesh; +struct MetaElem; struct ModifierData; +struct Nurb; struct Object; struct ReportList; struct Scene; struct View3D; +struct ViewContext; +struct bConstraint; +struct bContext; +struct bPoseChannel; struct wmEvent; struct wmKeyConfig; struct wmKeyMap; @@ -82,8 +91,10 @@ typedef enum eParentType { PAR_TRIA } eParentType; +#ifdef __RNA_TYPES_H__ extern struct EnumPropertyItem prop_clear_parent_types[]; extern struct EnumPropertyItem prop_make_parent_types[]; +#endif int ED_object_parent_set(struct ReportList *reports, struct Main *bmain, struct Scene *scene, struct Object *ob, struct Object *par, int partype, int xmirror, int keep_transform); @@ -183,9 +194,58 @@ int ED_object_iter_other(struct Main *bmain, struct Object *orig_ob, int include int ED_object_multires_update_totlevels_cb(struct Object *ob, void *totlevel_v); -/* ibject_select.c */ +/* object_select.c */ void ED_object_select_linked_by_id(struct bContext *C, struct ID *id); + +/* object_iterators.c */ + +/* enum for passing to foreach functions to test RV3D_CLIPPING */ +typedef enum eV3DClipTest { + V3D_CLIP_TEST_OFF = 0, /* clipping is off */ + V3D_CLIP_TEST_RV3D_CLIPPING = 1, /* clip single points */ + V3D_CLIP_TEST_REGION = 2 /* use for edges to check if both verts are in the view, but not RV3D_CLIPPING */ +} eV3DClipTest; + +/* foreach iterators */ +void mesh_foreachScreenVert( + struct ViewContext *vc, + void (*func)(void *userData, struct BMVert *eve, const float screen_co[2], int index), + void *userData, eV3DClipTest clipVerts); +void mesh_foreachScreenEdge( + struct ViewContext *vc, + void (*func)(void *userData, struct BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], + int index), + void *userData, eV3DClipTest clipVerts); +void mesh_foreachScreenFace( + struct ViewContext *vc, + void (*func)(void *userData, struct BMFace *efa, const float screen_co[2], int index), + void *userData); +void nurbs_foreachScreenVert( + struct ViewContext *vc, + void (*func)(void *userData, struct Nurb *nu, struct BPoint *bp, struct BezTriple *bezt, + int beztindex, const float screen_co[2]), + void *userData); +void mball_foreachScreenElem( + struct ViewContext *vc, + void (*func)(void *userData, struct MetaElem *ml, const float screen_co[2]), + void *userData); +void lattice_foreachScreenVert( + struct ViewContext *vc, + void (*func)(void *userData, struct BPoint *bp, + const float screen_co[2]), + void *userData); +void armature_foreachScreenBone( + struct ViewContext *vc, + void (*func)(void *userData, struct EditBone *ebone, + const float screen_co_a[2], const float screen_co_b[2]), + void *userData); +void pose_foreachScreenBone( + struct ViewContext *vc, + void (*func)(void *userData, struct bPoseChannel *pchan, + const float screen_co_a[2], const float screen_co_b[2]), + void *userData); + #ifdef __cplusplus } #endif diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index c02bc1dcf73..ce8b874ae27 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -80,13 +80,6 @@ typedef struct ViewDepths { char damaged; } ViewDepths; -/* enum for passing to foreach functions to test RV3D_CLIPPING */ -typedef enum eV3DClipTest { - V3D_CLIP_TEST_OFF = 0, /* clipping is off */ - V3D_CLIP_TEST_RV3D_CLIPPING = 1, /* clip single points */ - V3D_CLIP_TEST_REGION = 2 /* use for edges to check if both verts are in the view, but not RV3D_CLIPPING */ -} eV3DClipTest; - float *give_cursor(struct Scene *scene, struct View3D *v3d); int initgrabz(struct RegionView3D *rv3d, float x, float y, float z); @@ -166,17 +159,6 @@ void ED_view3d_ob_project_mat_get(struct RegionView3D *v3d, struct Object *ob, f void ED_view3d_calc_camera_border(struct Scene *scene, struct ARegion *ar, struct View3D *v3d, struct RegionView3D *rv3d, struct rctf *viewborder_r, short no_shift); void ED_view3d_calc_camera_border_size(struct Scene *scene, struct ARegion *ar, struct View3D *v3d, struct RegionView3D *rv3d, float size_r[2]); -/* drawobject.c iterators */ -void mesh_foreachScreenVert(struct ViewContext *vc, void (*func)(void *userData, struct BMVert *eve, const float screen_co[2], int index), void *userData, eV3DClipTest clipVerts); -void mesh_foreachScreenEdge(struct ViewContext *vc, void (*func)(void *userData, struct BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], int index), void *userData, eV3DClipTest clipVerts); -void mesh_foreachScreenFace(struct ViewContext *vc, void (*func)(void *userData, struct BMFace *efa, const float screen_co[2], int index), void *userData); -void nurbs_foreachScreenVert(struct ViewContext *vc, void (*func)(void *userData, struct Nurb *nu, struct BPoint *bp, struct BezTriple *bezt, int beztindex, const float screen_co[2]), void *userData); -void mball_foreachScreenElem(struct ViewContext *vc, void (*func)(void *userData, struct MetaElem *ml, const float screen_co[2]), void *userData); -void lattice_foreachScreenVert(struct ViewContext *vc, void (*func)(void *userData, struct BPoint *bp, const float screen_co[2]), void *userData); -void armature_foreachScreenBone(struct ViewContext *vc, void (*func)(void *userData, struct EditBone *ebone, const float screen_co_a[2], const float screen_co_b[2]), void *userData); -void pose_foreachScreenBone(struct ViewContext *vc, void (*func)(void *userData, struct bPoseChannel *pchan, const float screen_co_a[2], const float screen_co_b[2]), void *userData); - - void ED_view3d_clipping_calc(struct BoundBox *bb, float planes[4][4], struct bglMats *mats, const struct rcti *rect); void ED_view3d_clipping_local(struct RegionView3D *rv3d, float mat[][4]); int ED_view3d_clipping_test(struct RegionView3D *rv3d, const float vec[3], const int is_local); diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index 2e40419cb16..e6a2c065bbf 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -57,6 +57,7 @@ #include "ED_mesh.h" #include "ED_screen.h" #include "ED_uvedit.h" +#include "ED_object.h" #include "ED_view3d.h" #include "BIF_gl.h" diff --git a/source/blender/editors/object/CMakeLists.txt b/source/blender/editors/object/CMakeLists.txt index 05c042a4182..a6745f95ea0 100644 --- a/source/blender/editors/object/CMakeLists.txt +++ b/source/blender/editors/object/CMakeLists.txt @@ -46,6 +46,7 @@ set(SRC object_edit.c object_group.c object_hook.c + object_iterators.c object_lattice.c object_modifier.c object_ops.c diff --git a/source/blender/editors/object/object_iterators.c b/source/blender/editors/object/object_iterators.c new file mode 100644 index 00000000000..7e0d00ee5ac --- /dev/null +++ b/source/blender/editors/object/object_iterators.c @@ -0,0 +1,429 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Blender Foundation, full recode and added functions + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/object/object_iterators.c + * \ingroup edobj + */ + +#include "DNA_curve_types.h" +#include "DNA_lattice_types.h" +#include "DNA_meta_types.h" +#include "DNA_armature_types.h" +#include "DNA_object_types.h" + +#include "BLI_utildefines.h" +#include "BLI_blenlib.h" + +#include "BKE_armature.h" +#include "BKE_curve.h" +#include "BKE_DerivedMesh.h" +#include "BKE_displist.h" + +#include "bmesh.h" + +#include "ED_mesh.h" +#include "ED_screen.h" +#include "ED_armature.h" +#include "ED_object.h" +#include "ED_view3d.h" + + +typedef struct foreachScreenVert_userData { + void (*func)(void *userData, BMVert *eve, const float screen_co_b[2], int index); + void *userData; + ViewContext vc; + eV3DClipTest clipVerts; +} foreachScreenVert_userData; + +/* user data structures for derived mesh callbacks */ +typedef struct foreachScreenEdge_userData { + void (*func)(void *userData, BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], int index); + void *userData; + ViewContext vc; + rctf win_rect; /* copy of: vc.ar->winx/winy, use for faster tests, minx/y will always be 0 */ + eV3DClipTest clipVerts; +} foreachScreenEdge_userData; + +typedef struct foreachScreenFace_userData { + void (*func)(void *userData, BMFace *efa, const float screen_co_b[2], int index); + void *userData; + ViewContext vc; +} foreachScreenFace_userData; + + +/* Note! - foreach funcs should be called while drawing or directly after + * if not, ED_view3d_init_mats_rv3d() can be used for selection tools + * but would not give correct results with dupli's for eg. which don't + * use the object matrix in the usual way */ + +/* ------------------------------------------------------------------------ */ + +static void mesh_foreachScreenVert__mapFunc(void *userData, int index, const float co[3], + const float UNUSED(no_f[3]), const short UNUSED(no_s[3])) +{ + foreachScreenVert_userData *data = userData; + BMVert *eve = EDBM_vert_at_index(data->vc.em, index); + + if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) { + const eV3DProjTest flag = (data->clipVerts == V3D_CLIP_TEST_OFF) ? + V3D_PROJ_TEST_NOP : + V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN; + float screen_co[2]; + + if (ED_view3d_project_float_object(data->vc.ar, co, screen_co, flag) != V3D_PROJ_RET_OK) { + return; + } + + data->func(data->userData, eve, screen_co, index); + } +} + +void mesh_foreachScreenVert( + ViewContext *vc, + void (*func)(void *userData, BMVert *eve, const float screen_co[2], int index), + void *userData, eV3DClipTest clipVerts) +{ + foreachScreenVert_userData data; + DerivedMesh *dm = editbmesh_get_derived_cage(vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH); + + data.vc = *vc; + data.func = func; + data.userData = userData; + data.clipVerts = clipVerts; + + if (clipVerts != V3D_CLIP_TEST_OFF) + ED_view3d_clipping_local(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */ + + EDBM_index_arrays_init(vc->em, 1, 0, 0); + dm->foreachMappedVert(dm, mesh_foreachScreenVert__mapFunc, &data); + EDBM_index_arrays_free(vc->em); + + dm->release(dm); +} + +/* ------------------------------------------------------------------------ */ + +static void mesh_foreachScreenEdge__mapFunc(void *userData, int index, const float v0co[3], const float v1co[3]) +{ + foreachScreenEdge_userData *data = userData; + BMEdge *eed = EDBM_edge_at_index(data->vc.em, index); + + if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { + float screen_co_a[2]; + float screen_co_b[2]; + + const eV3DProjTest flag = (data->clipVerts == V3D_CLIP_TEST_RV3D_CLIPPING) ? + V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN : + V3D_PROJ_TEST_NOP; + + if (ED_view3d_project_float_object(data->vc.ar, v0co, screen_co_a, flag) != V3D_PROJ_RET_OK) { + return; + } + if (ED_view3d_project_float_object(data->vc.ar, v1co, screen_co_b, flag) != V3D_PROJ_RET_OK) { + return; + } + + if (data->clipVerts == V3D_CLIP_TEST_RV3D_CLIPPING) { + /* pass */ + } + else { + if (data->clipVerts == V3D_CLIP_TEST_REGION) { + if (!BLI_rctf_isect_segment(&data->win_rect, screen_co_a, screen_co_b)) { + return; + } + } + } + + data->func(data->userData, eed, screen_co_a, screen_co_b, index); + } +} + +void mesh_foreachScreenEdge( + ViewContext *vc, + void (*func)(void *userData, BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], int index), + void *userData, eV3DClipTest clipVerts) +{ + foreachScreenEdge_userData data; + DerivedMesh *dm = editbmesh_get_derived_cage(vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH); + + data.vc = *vc; + + data.win_rect.xmin = 0; + data.win_rect.ymin = 0; + data.win_rect.xmax = vc->ar->winx; + data.win_rect.ymax = vc->ar->winy; + + data.func = func; + data.userData = userData; + data.clipVerts = clipVerts; + + if (clipVerts != V3D_CLIP_TEST_OFF) + ED_view3d_clipping_local(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */ + + EDBM_index_arrays_init(vc->em, 0, 1, 0); + dm->foreachMappedEdge(dm, mesh_foreachScreenEdge__mapFunc, &data); + EDBM_index_arrays_free(vc->em); + + dm->release(dm); +} + +/* ------------------------------------------------------------------------ */ + +static void mesh_foreachScreenFace__mapFunc(void *userData, int index, const float cent[3], const float UNUSED(no[3])) +{ + foreachScreenFace_userData *data = userData; + BMFace *efa = EDBM_face_at_index(data->vc.em, index); + + if (efa && !BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { + float screen_co[2]; + if (ED_view3d_project_float_object(data->vc.ar, cent, screen_co, + V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) + { + data->func(data->userData, efa, screen_co, index); + } + } +} + +void mesh_foreachScreenFace( + ViewContext *vc, + void (*func)(void *userData, BMFace *efa, const float screen_co_b[2], int index), + void *userData) +{ + foreachScreenFace_userData data; + DerivedMesh *dm = editbmesh_get_derived_cage(vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH); + + data.vc = *vc; + data.func = func; + data.userData = userData; + + ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); + + EDBM_index_arrays_init(vc->em, 0, 0, 1); + dm->foreachMappedFaceCenter(dm, mesh_foreachScreenFace__mapFunc, &data); + EDBM_index_arrays_free(vc->em); + + dm->release(dm); +} + +/* ------------------------------------------------------------------------ */ + +void nurbs_foreachScreenVert( + ViewContext *vc, + void (*func)(void *userData, Nurb *nu, BPoint *bp, BezTriple *bezt, int beztindex, const float screen_co_b[2]), + void *userData) +{ + Curve *cu = vc->obedit->data; + Nurb *nu; + int i; + ListBase *nurbs = BKE_curve_editNurbs_get(cu); + + ED_view3d_clipping_local(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */ + + for (nu = nurbs->first; nu; nu = nu->next) { + if (nu->type == CU_BEZIER) { + for (i = 0; i < nu->pntsu; i++) { + BezTriple *bezt = &nu->bezt[i]; + + if (bezt->hide == 0) { + float screen_co[2]; + + if (cu->drawflag & CU_HIDE_HANDLES) { + if (ED_view3d_project_float_object(vc->ar, bezt->vec[1], screen_co, + V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_OK) + { + func(userData, nu, NULL, bezt, 1, screen_co); + } + } + else { + if (ED_view3d_project_float_object(vc->ar, bezt->vec[0], screen_co, + V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_OK) + { + func(userData, nu, NULL, bezt, 0, screen_co); + } + if (ED_view3d_project_float_object(vc->ar, bezt->vec[1], screen_co, + V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_OK) + { + func(userData, nu, NULL, bezt, 1, screen_co); + } + if (ED_view3d_project_float_object(vc->ar, bezt->vec[2], screen_co, + V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_OK) + { + func(userData, nu, NULL, bezt, 2, screen_co); + } + } + } + } + } + else { + for (i = 0; i < nu->pntsu * nu->pntsv; i++) { + BPoint *bp = &nu->bp[i]; + + if (bp->hide == 0) { + float screen_co[2]; + if (ED_view3d_project_float_object(vc->ar, bp->vec, screen_co, + V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_OK) + { + func(userData, nu, bp, NULL, -1, screen_co); + } + } + } + } + } +} + +/* ------------------------------------------------------------------------ */ + +/* ED_view3d_init_mats_rv3d must be called first */ +void mball_foreachScreenElem( + struct ViewContext *vc, + void (*func)(void *userData, struct MetaElem *ml, const float screen_co_b[2]), + void *userData) +{ + MetaBall *mb = (MetaBall *)vc->obedit->data; + MetaElem *ml; + + for (ml = mb->editelems->first; ml; ml = ml->next) { + float screen_co[2]; + if (ED_view3d_project_float_object(vc->ar, &ml->x, screen_co, + V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) + { + func(userData, ml, screen_co); + } + } +} + +/* ------------------------------------------------------------------------ */ + +void lattice_foreachScreenVert(ViewContext *vc, void (*func)(void *userData, BPoint *bp, const float screen_co[2]), void *userData) +{ + Object *obedit = vc->obedit; + Lattice *lt = obedit->data; + BPoint *bp = lt->editlatt->latt->def; + DispList *dl = BKE_displist_find(&obedit->disp, DL_VERTS); + float *co = dl ? dl->verts : NULL; + int i, N = lt->editlatt->latt->pntsu * lt->editlatt->latt->pntsv * lt->editlatt->latt->pntsw; + + ED_view3d_clipping_local(vc->rv3d, obedit->obmat); /* for local clipping lookups */ + + for (i = 0; i < N; i++, bp++, co += 3) { + if (bp->hide == 0) { + float screen_co[2]; + if (ED_view3d_project_float_object(vc->ar, dl ? co : bp->vec, screen_co, + V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_OK) + { + func(userData, bp, screen_co); + } + } + } +} + +/* ------------------------------------------------------------------------ */ + +/* ED_view3d_init_mats_rv3d must be called first */ +void armature_foreachScreenBone( + struct ViewContext *vc, + void (*func)(void *userData, struct EditBone *ebone, const float screen_co_a[2], const float screen_co_b[2]), + void *userData) +{ + bArmature *arm = vc->obedit->data; + EditBone *ebone; + + for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { + if (EBONE_VISIBLE(arm, ebone)) { + float screen_co_a[2], screen_co_b[2]; + int points_proj_tot = 0; + + /* project head location to screenspace */ + if (ED_view3d_project_float_object(vc->ar, ebone->head, screen_co_a, + V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) + { + points_proj_tot++; + } + else { + screen_co_a[0] = IS_CLIPPED; /* weak */ + /* screen_co_a[1]: intentionally dont set this so we get errors on misuse */ + } + + /* project tail location to screenspace */ + if (ED_view3d_project_float_object(vc->ar, ebone->tail, screen_co_b, + V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) + { + points_proj_tot++; + } + else { + screen_co_b[0] = IS_CLIPPED; /* weak */ + /* screen_co_b[1]: intentionally dont set this so we get errors on misuse */ + } + + if (points_proj_tot) { /* at least one point's projection worked */ + func(userData, ebone, screen_co_a, screen_co_b); + } + } + } +} + +/* ------------------------------------------------------------------------ */ + +/* ED_view3d_init_mats_rv3d must be called first */ +/* almost _exact_ copy of #armature_foreachScreenBone */ +void pose_foreachScreenBone( + struct ViewContext *vc, + void (*func)(void *userData, struct bPoseChannel *pchan, const float screen_co_a[2], const float screen_co_b[2]), + void *userData) +{ + bArmature *arm = vc->obact->data; + bPose *pose = vc->obact->pose; + bPoseChannel *pchan; + + for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) { + if (PBONE_VISIBLE(arm, pchan->bone)) { + float screen_co_a[2], screen_co_b[2]; + int points_proj_tot = 0; + + /* project head location to screenspace */ + if (ED_view3d_project_float_object(vc->ar, pchan->pose_head, screen_co_a, + V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) + { + points_proj_tot++; + } + else { + screen_co_a[0] = IS_CLIPPED; /* weak */ + /* screen_co_a[1]: intentionally dont set this so we get errors on misuse */ + } + + /* project tail location to screenspace */ + if (ED_view3d_project_float_object(vc->ar, pchan->pose_tail, screen_co_b, + V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) + { + points_proj_tot++; + } + else { + screen_co_b[0] = IS_CLIPPED; /* weak */ + /* screen_co_b[1]: intentionally dont set this so we get errors on misuse */ + } + + if (points_proj_tot) { /* at least one point's projection worked */ + func(userData, pchan, screen_co_a, screen_co_b); + } + } + } +} diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index fb308db0926..eb17aa2b8ce 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -27,10 +27,6 @@ * \ingroup spview3d */ - -#include -#include - #include "MEM_guardedalloc.h" #include "DNA_camera_types.h" @@ -40,21 +36,14 @@ #include "DNA_lattice_types.h" #include "DNA_material_types.h" #include "DNA_mesh_types.h" -#include "DNA_meshdata_types.h" #include "DNA_meta_types.h" #include "DNA_scene_types.h" #include "DNA_smoke_types.h" -#include "DNA_speaker_types.h" #include "DNA_world_types.h" -#include "DNA_armature_types.h" #include "DNA_object_types.h" -#include "BLI_utildefines.h" #include "BLI_blenlib.h" #include "BLI_math.h" -#include "BLI_edgehash.h" -#include "BLI_rand.h" -#include "BLI_utildefines.h" #include "BKE_anim.h" /* for the where_on_path function */ #include "BKE_armature.h" @@ -79,13 +68,10 @@ #include "BKE_pointcache.h" #include "BKE_scene.h" #include "BKE_unit.h" -#include "BKE_movieclip.h" #include "BKE_tracking.h" #include "BKE_tessmesh.h" -#include "smoke_API.h" - #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" @@ -100,16 +86,13 @@ #include "ED_screen.h" #include "ED_sculpt.h" #include "ED_types.h" -#include "ED_curve.h" /* for curve_editnurbs */ -#include "ED_armature.h" #include "UI_resources.h" #include "WM_api.h" -#include "wm_subwindow.h" #include "BLF_api.h" -#include "view3d_intern.h" /* own include */ +#include "view3d_intern.h" /* bad level include */ typedef enum eWireDrawMode { OBDRAW_WIRE_OFF = 0, @@ -117,28 +100,6 @@ typedef enum eWireDrawMode { OBDRAW_WIRE_ON_DEPTH = 2 } eWireDrawMode; -/* user data structures for derived mesh callbacks */ -typedef struct foreachScreenVert_userData { - void (*func)(void *userData, BMVert *eve, const float screen_co_b[2], int index); - void *userData; - ViewContext vc; - eV3DClipTest clipVerts; -} foreachScreenVert_userData; - -typedef struct foreachScreenEdge_userData { - void (*func)(void *userData, BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], int index); - void *userData; - ViewContext vc; - rctf win_rect; /* copy of: vc.ar->winx/winy, use for faster tests, minx/y will always be 0 */ - eV3DClipTest clipVerts; -} foreachScreenEdge_userData; - -typedef struct foreachScreenFace_userData { - void (*func)(void *userData, BMFace *efa, const float screen_co_b[2], int index); - void *userData; - ViewContext vc; -} foreachScreenFace_userData; - typedef struct drawDMVerts_userData { BMEditMesh *em; /* BMESH BRANCH ONLY */ @@ -1870,29 +1831,6 @@ static void lattice_draw_verts(Lattice *lt, DispList *dl, short sel) bglEnd(); } -void lattice_foreachScreenVert(ViewContext *vc, void (*func)(void *userData, BPoint *bp, const float screen_co[2]), void *userData) -{ - Object *obedit = vc->obedit; - Lattice *lt = obedit->data; - BPoint *bp = lt->editlatt->latt->def; - DispList *dl = BKE_displist_find(&obedit->disp, DL_VERTS); - float *co = dl ? dl->verts : NULL; - int i, N = lt->editlatt->latt->pntsu * lt->editlatt->latt->pntsv * lt->editlatt->latt->pntsw; - - ED_view3d_clipping_local(vc->rv3d, obedit->obmat); /* for local clipping lookups */ - - for (i = 0; i < N; i++, bp++, co += 3) { - if (bp->hide == 0) { - float screen_co[2]; - if (ED_view3d_project_float_object(vc->ar, dl ? co : bp->vec, screen_co, - V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_OK) - { - func(userData, bp, screen_co); - } - } - } -} - static void drawlattice__point(Lattice *lt, DispList *dl, int u, int v, int w, int use_wcol) { int index = ((w * lt->pntsv + v) * lt->pntsu) + u; @@ -1979,53 +1917,6 @@ static void drawlattice(Scene *scene, View3D *v3d, Object *ob) /* ***************** ******************** */ -/* Note! - foreach funcs should be called while drawing or directly after - * if not, ED_view3d_init_mats_rv3d() can be used for selection tools - * but would not give correct results with dupli's for eg. which don't - * use the object matrix in the usual way */ -static void mesh_foreachScreenVert__mapFunc(void *userData, int index, const float co[3], - const float UNUSED(no_f[3]), const short UNUSED(no_s[3])) -{ - foreachScreenVert_userData *data = userData; - BMVert *eve = EDBM_vert_at_index(data->vc.em, index); - - if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) { - const eV3DProjTest flag = (data->clipVerts == V3D_CLIP_TEST_OFF) ? - V3D_PROJ_TEST_NOP : - V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN; - float screen_co[2]; - - if (ED_view3d_project_float_object(data->vc.ar, co, screen_co, flag) != V3D_PROJ_RET_OK) { - return; - } - - data->func(data->userData, eve, screen_co, index); - } -} - -void mesh_foreachScreenVert( - ViewContext *vc, - void (*func)(void *userData, BMVert *eve, const float screen_co[2], int index), - void *userData, eV3DClipTest clipVerts) -{ - foreachScreenVert_userData data; - DerivedMesh *dm = editbmesh_get_derived_cage(vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH); - - data.vc = *vc; - data.func = func; - data.userData = userData; - data.clipVerts = clipVerts; - - if (clipVerts != V3D_CLIP_TEST_OFF) - ED_view3d_clipping_local(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */ - - EDBM_index_arrays_init(vc->em, 1, 0, 0); - dm->foreachMappedVert(dm, mesh_foreachScreenVert__mapFunc, &data); - EDBM_index_arrays_free(vc->em); - - dm->release(dm); -} - /* draw callback */ static void drawSelectedVertices__mapFunc(void *userData, int index, const float co[3], const float UNUSED(no_f[3]), const short UNUSED(no_s[3])) @@ -2054,277 +1945,6 @@ static void drawSelectedVertices(DerivedMesh *dm, Mesh *me) glEnd(); } -static void mesh_foreachScreenEdge__mapFunc(void *userData, int index, const float v0co[3], const float v1co[3]) -{ - foreachScreenEdge_userData *data = userData; - BMEdge *eed = EDBM_edge_at_index(data->vc.em, index); - - if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { - float screen_co_a[2]; - float screen_co_b[2]; - - const eV3DProjTest flag = (data->clipVerts == V3D_CLIP_TEST_RV3D_CLIPPING) ? - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN : - V3D_PROJ_TEST_NOP; - - if (ED_view3d_project_float_object(data->vc.ar, v0co, screen_co_a, flag) != V3D_PROJ_RET_OK) { - return; - } - if (ED_view3d_project_float_object(data->vc.ar, v1co, screen_co_b, flag) != V3D_PROJ_RET_OK) { - return; - } - - if (data->clipVerts == V3D_CLIP_TEST_RV3D_CLIPPING) { - /* pass */ - } - else { - if (data->clipVerts == V3D_CLIP_TEST_REGION) { - if (!BLI_rctf_isect_segment(&data->win_rect, screen_co_a, screen_co_b)) { - return; - } - } - } - - data->func(data->userData, eed, screen_co_a, screen_co_b, index); - } -} - -void mesh_foreachScreenEdge( - ViewContext *vc, - void (*func)(void *userData, BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], int index), - void *userData, eV3DClipTest clipVerts) -{ - foreachScreenEdge_userData data; - DerivedMesh *dm = editbmesh_get_derived_cage(vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH); - - data.vc = *vc; - - data.win_rect.xmin = 0; - data.win_rect.ymin = 0; - data.win_rect.xmax = vc->ar->winx; - data.win_rect.ymax = vc->ar->winy; - - data.func = func; - data.userData = userData; - data.clipVerts = clipVerts; - - if (clipVerts != V3D_CLIP_TEST_OFF) - ED_view3d_clipping_local(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */ - - EDBM_index_arrays_init(vc->em, 0, 1, 0); - dm->foreachMappedEdge(dm, mesh_foreachScreenEdge__mapFunc, &data); - EDBM_index_arrays_free(vc->em); - - dm->release(dm); -} - -static void mesh_foreachScreenFace__mapFunc(void *userData, int index, const float cent[3], const float UNUSED(no[3])) -{ - foreachScreenFace_userData *data = userData; - BMFace *efa = EDBM_face_at_index(data->vc.em, index); - - if (efa && !BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { - float screen_co[2]; - if (ED_view3d_project_float_object(data->vc.ar, cent, screen_co, - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) - { - data->func(data->userData, efa, screen_co, index); - } - } -} - -void mesh_foreachScreenFace( - ViewContext *vc, - void (*func)(void *userData, BMFace *efa, const float screen_co_b[2], int index), - void *userData) -{ - foreachScreenFace_userData data; - DerivedMesh *dm = editbmesh_get_derived_cage(vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH); - - data.vc = *vc; - data.func = func; - data.userData = userData; - - ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); - - EDBM_index_arrays_init(vc->em, 0, 0, 1); - dm->foreachMappedFaceCenter(dm, mesh_foreachScreenFace__mapFunc, &data); - EDBM_index_arrays_free(vc->em); - - dm->release(dm); -} - -void nurbs_foreachScreenVert( - ViewContext *vc, - void (*func)(void *userData, Nurb *nu, BPoint *bp, BezTriple *bezt, int beztindex, const float screen_co_b[2]), - void *userData) -{ - Curve *cu = vc->obedit->data; - Nurb *nu; - int i; - ListBase *nurbs = BKE_curve_editNurbs_get(cu); - - ED_view3d_clipping_local(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */ - - for (nu = nurbs->first; nu; nu = nu->next) { - if (nu->type == CU_BEZIER) { - for (i = 0; i < nu->pntsu; i++) { - BezTriple *bezt = &nu->bezt[i]; - - if (bezt->hide == 0) { - float screen_co[2]; - - if (cu->drawflag & CU_HIDE_HANDLES) { - if (ED_view3d_project_float_object(vc->ar, bezt->vec[1], screen_co, - V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_OK) - { - func(userData, nu, NULL, bezt, 1, screen_co); - } - } - else { - if (ED_view3d_project_float_object(vc->ar, bezt->vec[0], screen_co, - V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_OK) - { - func(userData, nu, NULL, bezt, 0, screen_co); - } - if (ED_view3d_project_float_object(vc->ar, bezt->vec[1], screen_co, - V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_OK) - { - func(userData, nu, NULL, bezt, 1, screen_co); - } - if (ED_view3d_project_float_object(vc->ar, bezt->vec[2], screen_co, - V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_OK) - { - func(userData, nu, NULL, bezt, 2, screen_co); - } - } - } - } - } - else { - for (i = 0; i < nu->pntsu * nu->pntsv; i++) { - BPoint *bp = &nu->bp[i]; - - if (bp->hide == 0) { - float screen_co[2]; - if (ED_view3d_project_float_object(vc->ar, bp->vec, screen_co, - V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_OK) - { - func(userData, nu, bp, NULL, -1, screen_co); - } - } - } - } - } -} - -/* ED_view3d_init_mats_rv3d must be called first */ -void mball_foreachScreenElem( - struct ViewContext *vc, - void (*func)(void *userData, struct MetaElem *ml, const float screen_co_b[2]), - void *userData) -{ - MetaBall *mb = (MetaBall *)vc->obedit->data; - MetaElem *ml; - - for (ml = mb->editelems->first; ml; ml = ml->next) { - float screen_co[2]; - if (ED_view3d_project_float_object(vc->ar, &ml->x, screen_co, - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) - { - func(userData, ml, screen_co); - } - } -} - -/* ED_view3d_init_mats_rv3d must be called first */ -void armature_foreachScreenBone( - struct ViewContext *vc, - void (*func)(void *userData, struct EditBone *ebone, const float screen_co_a[2], const float screen_co_b[2]), - void *userData) -{ - bArmature *arm = vc->obedit->data; - EditBone *ebone; - - for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { - if (EBONE_VISIBLE(arm, ebone)) { - float screen_co_a[2], screen_co_b[2]; - int points_proj_tot = 0; - - /* project head location to screenspace */ - if (ED_view3d_project_float_object(vc->ar, ebone->head, screen_co_a, - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) - { - points_proj_tot++; - } - else { - screen_co_a[0] = IS_CLIPPED; /* weak */ - /* screen_co_a[1]: intentionally dont set this so we get errors on misuse */ - } - - /* project tail location to screenspace */ - if (ED_view3d_project_float_object(vc->ar, ebone->tail, screen_co_b, - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) - { - points_proj_tot++; - } - else { - screen_co_b[0] = IS_CLIPPED; /* weak */ - /* screen_co_b[1]: intentionally dont set this so we get errors on misuse */ - } - - if (points_proj_tot) { /* at least one point's projection worked */ - func(userData, ebone, screen_co_a, screen_co_b); - } - } - } -} - -/* ED_view3d_init_mats_rv3d must be called first */ -/* almost _exact_ copy of #armature_foreachScreenBone */ -void pose_foreachScreenBone( - struct ViewContext *vc, - void (*func)(void *userData, struct bPoseChannel *pchan, const float screen_co_a[2], const float screen_co_b[2]), - void *userData) -{ - bArmature *arm = vc->obact->data; - bPose *pose = vc->obact->pose; - bPoseChannel *pchan; - - for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) { - if (PBONE_VISIBLE(arm, pchan->bone)) { - float screen_co_a[2], screen_co_b[2]; - int points_proj_tot = 0; - - /* project head location to screenspace */ - if (ED_view3d_project_float_object(vc->ar, pchan->pose_head, screen_co_a, - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) - { - points_proj_tot++; - } - else { - screen_co_a[0] = IS_CLIPPED; /* weak */ - /* screen_co_a[1]: intentionally dont set this so we get errors on misuse */ - } - - /* project tail location to screenspace */ - if (ED_view3d_project_float_object(vc->ar, pchan->pose_tail, screen_co_b, - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) - { - points_proj_tot++; - } - else { - screen_co_b[0] = IS_CLIPPED; /* weak */ - /* screen_co_b[1]: intentionally dont set this so we get errors on misuse */ - } - - if (points_proj_tot) { /* at least one point's projection worked */ - func(userData, pchan, screen_co_a, screen_co_b); - } - } - } -} - /* ************** DRAW MESH ****************** */ /* First section is all the "simple" draw routines, From a17e1eea23f2323f4a8655ca8fe5967cce266e39 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 10 Oct 2012 04:03:22 +0000 Subject: [PATCH 155/347] refactor foreachScreen functions for clipping, now the projection clipping flag is passed down directly rather then converting the enum into a flag, also fix own recent crash lasso seleting in object mode with pose objects. --- source/blender/editors/curve/editcurve.c | 2 +- source/blender/editors/include/ED_object.h | 23 ++--- source/blender/editors/include/ED_view3d.h | 23 +++-- source/blender/editors/mesh/editmesh_select.c | 12 +-- .../blender/editors/object/object_iterators.c | 96 ++++++++----------- .../blender/editors/object/object_lattice.c | 2 +- .../editors/space_view3d/view3d_select.c | 50 +++++----- .../editors/space_view3d/view3d_view.c | 26 ++--- 8 files changed, 114 insertions(+), 120 deletions(-) diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index 14c233abdaf..42b42a594ce 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -3276,7 +3276,7 @@ static short findnearestNurbvert(ViewContext *vc, short sel, const int mval[2], data.mval_fl[1] = mval[1]; ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); - nurbs_foreachScreenVert(vc, findnearestNurbvert__doClosest, &data); + nurbs_foreachScreenVert(vc, findnearestNurbvert__doClosest, &data, V3D_PROJ_TEST_CLIP_DEFAULT); *nurb = data.nurb; *bezt = data.bezt; diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h index aa145dfd906..f792d8b1a87 100644 --- a/source/blender/editors/include/ED_object.h +++ b/source/blender/editors/include/ED_object.h @@ -200,51 +200,46 @@ void ED_object_select_linked_by_id(struct bContext *C, struct ID *id); /* object_iterators.c */ -/* enum for passing to foreach functions to test RV3D_CLIPPING */ -typedef enum eV3DClipTest { - V3D_CLIP_TEST_OFF = 0, /* clipping is off */ - V3D_CLIP_TEST_RV3D_CLIPPING = 1, /* clip single points */ - V3D_CLIP_TEST_REGION = 2 /* use for edges to check if both verts are in the view, but not RV3D_CLIPPING */ -} eV3DClipTest; +#include "ED_view3d.h" /* XXX, needed for eV3DProjTest */ /* foreach iterators */ void mesh_foreachScreenVert( struct ViewContext *vc, void (*func)(void *userData, struct BMVert *eve, const float screen_co[2], int index), - void *userData, eV3DClipTest clipVerts); + void *userData, const eV3DProjTest clip_flag); void mesh_foreachScreenEdge( struct ViewContext *vc, void (*func)(void *userData, struct BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], int index), - void *userData, eV3DClipTest clipVerts); + void *userData, const eV3DProjTest clip_flag); void mesh_foreachScreenFace( struct ViewContext *vc, void (*func)(void *userData, struct BMFace *efa, const float screen_co[2], int index), - void *userData); + void *userData, const eV3DProjTest clip_flag); void nurbs_foreachScreenVert( struct ViewContext *vc, void (*func)(void *userData, struct Nurb *nu, struct BPoint *bp, struct BezTriple *bezt, int beztindex, const float screen_co[2]), - void *userData); + void *userData, const eV3DProjTest clip_flag); void mball_foreachScreenElem( struct ViewContext *vc, void (*func)(void *userData, struct MetaElem *ml, const float screen_co[2]), - void *userData); + void *userData, const eV3DProjTest clip_flag); void lattice_foreachScreenVert( struct ViewContext *vc, void (*func)(void *userData, struct BPoint *bp, const float screen_co[2]), - void *userData); + void *userData, const eV3DProjTest clip_flag); void armature_foreachScreenBone( struct ViewContext *vc, void (*func)(void *userData, struct EditBone *ebone, const float screen_co_a[2], const float screen_co_b[2]), - void *userData); + void *userData, const eV3DProjTest clip_flag); void pose_foreachScreenBone( struct ViewContext *vc, void (*func)(void *userData, struct bPoseChannel *pchan, const float screen_co_a[2], const float screen_co_b[2]), - void *userData); + void *userData, const eV3DProjTest clip_flag); #ifdef __cplusplus } diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index ce8b874ae27..d0243527b83 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -50,6 +50,8 @@ struct Nurb; struct Object; struct RegionView3D; struct Scene; +struct bScreen; +struct ScrArea; struct View3D; struct ViewContext; struct bContext; @@ -126,24 +128,27 @@ typedef enum { V3D_PROJ_TEST_CLIP_WIN = (1 << 1), } eV3DProjTest; +#define V3D_PROJ_TEST_CLIP_DEFAULT (V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) +#define V3D_PROJ_TEST_ALL (V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) + /* *** short *** */ eV3DProjStatus ED_view3d_project_short_ex(struct ARegion *ar, float perspmat[4][4], const int is_local, - const float co[3], short r_co[2], eV3DProjTest flag); -eV3DProjStatus ED_view3d_project_short_global(struct ARegion *ar, const float co[3], short r_co[2], eV3DProjTest flag); -eV3DProjStatus ED_view3d_project_short_object(struct ARegion *ar, const float co[3], short r_co[2], eV3DProjTest flag); + const float co[3], short r_co[2], const eV3DProjTest flag); +eV3DProjStatus ED_view3d_project_short_global(struct ARegion *ar, const float co[3], short r_co[2], const eV3DProjTest flag); +eV3DProjStatus ED_view3d_project_short_object(struct ARegion *ar, const float co[3], short r_co[2], const eV3DProjTest flag); /* *** int *** */ eV3DProjStatus ED_view3d_project_int_ex(struct ARegion *ar, float perspmat[4][4], const int is_local, - const float co[3], int r_co[2], eV3DProjTest flag); -eV3DProjStatus ED_view3d_project_int_global(struct ARegion *ar, const float co[3], int r_co[2], eV3DProjTest flag); -eV3DProjStatus ED_view3d_project_int_object(struct ARegion *ar, const float co[3], int r_co[2], eV3DProjTest flag); + const float co[3], int r_co[2], const eV3DProjTest flag); +eV3DProjStatus ED_view3d_project_int_global(struct ARegion *ar, const float co[3], int r_co[2], const eV3DProjTest flag); +eV3DProjStatus ED_view3d_project_int_object(struct ARegion *ar, const float co[3], int r_co[2], const eV3DProjTest flag); /* *** float *** */ eV3DProjStatus ED_view3d_project_float_ex(struct ARegion *ar, float perspmat[4][4], const int is_local, - const float co[3], float r_co[2], eV3DProjTest flag); -eV3DProjStatus ED_view3d_project_float_global(struct ARegion *ar, const float co[3], float r_co[2], eV3DProjTest flag); -eV3DProjStatus ED_view3d_project_float_object(struct ARegion *ar, const float co[3], float r_co[2], eV3DProjTest flag); + const float co[3], float r_co[2], const eV3DProjTest flag); +eV3DProjStatus ED_view3d_project_float_global(struct ARegion *ar, const float co[3], float r_co[2], const eV3DProjTest flag); +eV3DProjStatus ED_view3d_project_float_object(struct ARegion *ar, const float co[3], float r_co[2], const eV3DProjTest flag); void ED_view3d_project_float_v2_m4(const struct ARegion *a, const float co[3], float r_co[2], float mat[4][4]); void ED_view3d_project_float_v3_m4(struct ARegion *a, const float co[3], float r_co[3], float mat[4][4]); diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index e6a2c065bbf..32643cb20cd 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -433,11 +433,11 @@ BMVert *EDBM_vert_find_nearest(ViewContext *vc, float *r_dist, const short sel, ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); - mesh_foreachScreenVert(vc, findnearestvert__doClosest, &data, V3D_CLIP_TEST_RV3D_CLIPPING); + mesh_foreachScreenVert(vc, findnearestvert__doClosest, &data, V3D_PROJ_TEST_CLIP_DEFAULT); if (data.dist > 3) { data.pass = 1; - mesh_foreachScreenVert(vc, findnearestvert__doClosest, &data, V3D_CLIP_TEST_RV3D_CLIPPING); + mesh_foreachScreenVert(vc, findnearestvert__doClosest, &data, V3D_PROJ_TEST_CLIP_DEFAULT); } *r_dist = data.dist; @@ -525,7 +525,7 @@ BMEdge *EDBM_edge_find_nearest(ViewContext *vc, float *r_dist) data.closest = NULL; ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); - mesh_foreachScreenEdge(vc, findnearestedge__doClosest, &data, V3D_CLIP_TEST_REGION); + mesh_foreachScreenEdge(vc, findnearestedge__doClosest, &data, V3D_PROJ_TEST_CLIP_WIN); *r_dist = data.dist; return data.closest; @@ -588,7 +588,7 @@ BMFace *EDBM_face_find_nearest(ViewContext *vc, float *r_dist) data.dist = 0x7FFF; /* largest short */ data.toFace = efa; - mesh_foreachScreenFace(vc, findnearestface__getDistance, &data); + mesh_foreachScreenFace(vc, findnearestface__getDistance, &data, V3D_PROJ_TEST_CLIP_DEFAULT); if ((vc->em->selectmode == SCE_SELECT_FACE) || (data.dist < *r_dist)) { /* only faces, no dist check */ *r_dist = data.dist; @@ -617,12 +617,12 @@ BMFace *EDBM_face_find_nearest(ViewContext *vc, float *r_dist) ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); data.pass = 0; - mesh_foreachScreenFace(vc, findnearestface__doClosest, &data); + mesh_foreachScreenFace(vc, findnearestface__doClosest, &data, V3D_PROJ_TEST_CLIP_DEFAULT); if (data.dist > 3.0f) { data.pass = 1; ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); - mesh_foreachScreenFace(vc, findnearestface__doClosest, &data); + mesh_foreachScreenFace(vc, findnearestface__doClosest, &data, V3D_PROJ_TEST_CLIP_DEFAULT); } *r_dist = data.dist; diff --git a/source/blender/editors/object/object_iterators.c b/source/blender/editors/object/object_iterators.c index 7e0d00ee5ac..1d38db9d59b 100644 --- a/source/blender/editors/object/object_iterators.c +++ b/source/blender/editors/object/object_iterators.c @@ -31,7 +31,8 @@ #include "DNA_object_types.h" #include "BLI_utildefines.h" -#include "BLI_blenlib.h" +#include "BLI_listbase.h" +#include "BLI_rect.h" #include "BKE_armature.h" #include "BKE_curve.h" @@ -51,7 +52,7 @@ typedef struct foreachScreenVert_userData { void (*func)(void *userData, BMVert *eve, const float screen_co_b[2], int index); void *userData; ViewContext vc; - eV3DClipTest clipVerts; + eV3DProjTest clip_flag; } foreachScreenVert_userData; /* user data structures for derived mesh callbacks */ @@ -60,13 +61,14 @@ typedef struct foreachScreenEdge_userData { void *userData; ViewContext vc; rctf win_rect; /* copy of: vc.ar->winx/winy, use for faster tests, minx/y will always be 0 */ - eV3DClipTest clipVerts; + eV3DProjTest clip_flag; } foreachScreenEdge_userData; typedef struct foreachScreenFace_userData { void (*func)(void *userData, BMFace *efa, const float screen_co_b[2], int index); void *userData; ViewContext vc; + eV3DProjTest clip_flag; } foreachScreenFace_userData; @@ -84,12 +86,9 @@ static void mesh_foreachScreenVert__mapFunc(void *userData, int index, const flo BMVert *eve = EDBM_vert_at_index(data->vc.em, index); if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) { - const eV3DProjTest flag = (data->clipVerts == V3D_CLIP_TEST_OFF) ? - V3D_PROJ_TEST_NOP : - V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN; float screen_co[2]; - if (ED_view3d_project_float_object(data->vc.ar, co, screen_co, flag) != V3D_PROJ_RET_OK) { + if (ED_view3d_project_float_object(data->vc.ar, co, screen_co, data->clip_flag) != V3D_PROJ_RET_OK) { return; } @@ -100,7 +99,7 @@ static void mesh_foreachScreenVert__mapFunc(void *userData, int index, const flo void mesh_foreachScreenVert( ViewContext *vc, void (*func)(void *userData, BMVert *eve, const float screen_co[2], int index), - void *userData, eV3DClipTest clipVerts) + void *userData, eV3DProjTest clip_flag) { foreachScreenVert_userData data; DerivedMesh *dm = editbmesh_get_derived_cage(vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH); @@ -108,10 +107,11 @@ void mesh_foreachScreenVert( data.vc = *vc; data.func = func; data.userData = userData; - data.clipVerts = clipVerts; + data.clip_flag = clip_flag; - if (clipVerts != V3D_CLIP_TEST_OFF) + if (clip_flag & V3D_PROJ_TEST_CLIP_BB) { ED_view3d_clipping_local(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */ + } EDBM_index_arrays_init(vc->em, 1, 0, 0); dm->foreachMappedVert(dm, mesh_foreachScreenVert__mapFunc, &data); @@ -131,25 +131,16 @@ static void mesh_foreachScreenEdge__mapFunc(void *userData, int index, const flo float screen_co_a[2]; float screen_co_b[2]; - const eV3DProjTest flag = (data->clipVerts == V3D_CLIP_TEST_RV3D_CLIPPING) ? - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN : - V3D_PROJ_TEST_NOP; - - if (ED_view3d_project_float_object(data->vc.ar, v0co, screen_co_a, flag) != V3D_PROJ_RET_OK) { + if (ED_view3d_project_float_object(data->vc.ar, v0co, screen_co_a, data->clip_flag) != V3D_PROJ_RET_OK) { return; } - if (ED_view3d_project_float_object(data->vc.ar, v1co, screen_co_b, flag) != V3D_PROJ_RET_OK) { + if (ED_view3d_project_float_object(data->vc.ar, v1co, screen_co_b, data->clip_flag) != V3D_PROJ_RET_OK) { return; } - if (data->clipVerts == V3D_CLIP_TEST_RV3D_CLIPPING) { - /* pass */ - } - else { - if (data->clipVerts == V3D_CLIP_TEST_REGION) { - if (!BLI_rctf_isect_segment(&data->win_rect, screen_co_a, screen_co_b)) { - return; - } + if (data->clip_flag & V3D_PROJ_TEST_CLIP_WIN) { + if (!BLI_rctf_isect_segment(&data->win_rect, screen_co_a, screen_co_b)) { + return; } } @@ -160,7 +151,7 @@ static void mesh_foreachScreenEdge__mapFunc(void *userData, int index, const flo void mesh_foreachScreenEdge( ViewContext *vc, void (*func)(void *userData, BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], int index), - void *userData, eV3DClipTest clipVerts) + void *userData, eV3DProjTest clip_flag) { foreachScreenEdge_userData data; DerivedMesh *dm = editbmesh_get_derived_cage(vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH); @@ -174,10 +165,11 @@ void mesh_foreachScreenEdge( data.func = func; data.userData = userData; - data.clipVerts = clipVerts; + data.clip_flag = clip_flag; - if (clipVerts != V3D_CLIP_TEST_OFF) + if (clip_flag & V3D_PROJ_TEST_CLIP_BB) { ED_view3d_clipping_local(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */ + } EDBM_index_arrays_init(vc->em, 0, 1, 0); dm->foreachMappedEdge(dm, mesh_foreachScreenEdge__mapFunc, &data); @@ -195,8 +187,7 @@ static void mesh_foreachScreenFace__mapFunc(void *userData, int index, const flo if (efa && !BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { float screen_co[2]; - if (ED_view3d_project_float_object(data->vc.ar, cent, screen_co, - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) + if (ED_view3d_project_float_object(data->vc.ar, cent, screen_co, data->clip_flag) == V3D_PROJ_RET_OK) { data->func(data->userData, efa, screen_co, index); } @@ -206,7 +197,7 @@ static void mesh_foreachScreenFace__mapFunc(void *userData, int index, const flo void mesh_foreachScreenFace( ViewContext *vc, void (*func)(void *userData, BMFace *efa, const float screen_co_b[2], int index), - void *userData) + void *userData, const eV3DProjTest clip_flag) { foreachScreenFace_userData data; DerivedMesh *dm = editbmesh_get_derived_cage(vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH); @@ -214,6 +205,7 @@ void mesh_foreachScreenFace( data.vc = *vc; data.func = func; data.userData = userData; + data.clip_flag = clip_flag; ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); @@ -229,14 +221,16 @@ void mesh_foreachScreenFace( void nurbs_foreachScreenVert( ViewContext *vc, void (*func)(void *userData, Nurb *nu, BPoint *bp, BezTriple *bezt, int beztindex, const float screen_co_b[2]), - void *userData) + void *userData, const eV3DProjTest clip_flag) { Curve *cu = vc->obedit->data; Nurb *nu; int i; ListBase *nurbs = BKE_curve_editNurbs_get(cu); - ED_view3d_clipping_local(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */ + if (clip_flag & V3D_PROJ_TEST_CLIP_BB) { + ED_view3d_clipping_local(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */ + } for (nu = nurbs->first; nu; nu = nu->next) { if (nu->type == CU_BEZIER) { @@ -296,15 +290,14 @@ void nurbs_foreachScreenVert( void mball_foreachScreenElem( struct ViewContext *vc, void (*func)(void *userData, struct MetaElem *ml, const float screen_co_b[2]), - void *userData) + void *userData, const eV3DProjTest clip_flag) { MetaBall *mb = (MetaBall *)vc->obedit->data; MetaElem *ml; for (ml = mb->editelems->first; ml; ml = ml->next) { float screen_co[2]; - if (ED_view3d_project_float_object(vc->ar, &ml->x, screen_co, - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) + if (ED_view3d_project_float_object(vc->ar, &ml->x, screen_co, clip_flag) == V3D_PROJ_RET_OK) { func(userData, ml, screen_co); } @@ -313,7 +306,10 @@ void mball_foreachScreenElem( /* ------------------------------------------------------------------------ */ -void lattice_foreachScreenVert(ViewContext *vc, void (*func)(void *userData, BPoint *bp, const float screen_co[2]), void *userData) +void lattice_foreachScreenVert( + ViewContext *vc, + void (*func)(void *userData, BPoint *bp, const float screen_co[2]), + void *userData, const eV3DProjTest clip_flag) { Object *obedit = vc->obedit; Lattice *lt = obedit->data; @@ -322,14 +318,14 @@ void lattice_foreachScreenVert(ViewContext *vc, void (*func)(void *userData, BPo float *co = dl ? dl->verts : NULL; int i, N = lt->editlatt->latt->pntsu * lt->editlatt->latt->pntsv * lt->editlatt->latt->pntsw; - ED_view3d_clipping_local(vc->rv3d, obedit->obmat); /* for local clipping lookups */ + if (clip_flag & V3D_PROJ_TEST_CLIP_BB) { + ED_view3d_clipping_local(vc->rv3d, obedit->obmat); /* for local clipping lookups */ + } for (i = 0; i < N; i++, bp++, co += 3) { if (bp->hide == 0) { float screen_co[2]; - if (ED_view3d_project_float_object(vc->ar, dl ? co : bp->vec, screen_co, - V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_OK) - { + if (ED_view3d_project_float_object(vc->ar, dl ? co : bp->vec, screen_co, clip_flag) == V3D_PROJ_RET_OK) { func(userData, bp, screen_co); } } @@ -342,7 +338,7 @@ void lattice_foreachScreenVert(ViewContext *vc, void (*func)(void *userData, BPo void armature_foreachScreenBone( struct ViewContext *vc, void (*func)(void *userData, struct EditBone *ebone, const float screen_co_a[2], const float screen_co_b[2]), - void *userData) + void *userData, const eV3DProjTest clip_flag) { bArmature *arm = vc->obedit->data; EditBone *ebone; @@ -353,9 +349,7 @@ void armature_foreachScreenBone( int points_proj_tot = 0; /* project head location to screenspace */ - if (ED_view3d_project_float_object(vc->ar, ebone->head, screen_co_a, - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) - { + if (ED_view3d_project_float_object(vc->ar, ebone->head, screen_co_a, clip_flag) == V3D_PROJ_RET_OK) { points_proj_tot++; } else { @@ -364,9 +358,7 @@ void armature_foreachScreenBone( } /* project tail location to screenspace */ - if (ED_view3d_project_float_object(vc->ar, ebone->tail, screen_co_b, - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) - { + if (ED_view3d_project_float_object(vc->ar, ebone->tail, screen_co_b, clip_flag) == V3D_PROJ_RET_OK) { points_proj_tot++; } else { @@ -388,7 +380,7 @@ void armature_foreachScreenBone( void pose_foreachScreenBone( struct ViewContext *vc, void (*func)(void *userData, struct bPoseChannel *pchan, const float screen_co_a[2], const float screen_co_b[2]), - void *userData) + void *userData, const eV3DProjTest clip_flag) { bArmature *arm = vc->obact->data; bPose *pose = vc->obact->pose; @@ -400,9 +392,7 @@ void pose_foreachScreenBone( int points_proj_tot = 0; /* project head location to screenspace */ - if (ED_view3d_project_float_object(vc->ar, pchan->pose_head, screen_co_a, - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) - { + if (ED_view3d_project_float_object(vc->ar, pchan->pose_head, screen_co_a, clip_flag) == V3D_PROJ_RET_OK) { points_proj_tot++; } else { @@ -411,9 +401,7 @@ void pose_foreachScreenBone( } /* project tail location to screenspace */ - if (ED_view3d_project_float_object(vc->ar, pchan->pose_tail, screen_co_b, - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) - { + if (ED_view3d_project_float_object(vc->ar, pchan->pose_tail, screen_co_b, clip_flag) == V3D_PROJ_RET_OK) { points_proj_tot++; } else { diff --git a/source/blender/editors/object/object_lattice.c b/source/blender/editors/object/object_lattice.c index aa9e4d83774..d8974ea677c 100644 --- a/source/blender/editors/object/object_lattice.c +++ b/source/blender/editors/object/object_lattice.c @@ -330,7 +330,7 @@ static BPoint *findnearestLattvert(ViewContext *vc, const int mval[2], int sel) data.mval_fl[1] = mval[1]; ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); - lattice_foreachScreenVert(vc, findnearestLattvert__doClosest, &data); + lattice_foreachScreenVert(vc, findnearestLattvert__doClosest, &data, V3D_PROJ_TEST_CLIP_DEFAULT); return data.bp; } diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index afd69d56d21..dc3cfa41e37 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -398,6 +398,7 @@ static void do_lasso_select_pose__doSelectBone(void *userData, struct bPoseChann } static void do_lasso_select_pose(ViewContext *vc, Object *ob, const int mcords[][2], short moves, short select) { + ViewContext vc_tmp; LassoSelectUserData data; rcti rect; @@ -405,13 +406,16 @@ static void do_lasso_select_pose(ViewContext *vc, Object *ob, const int mcords[] return; } + vc_tmp = *vc; + vc_tmp.obact = ob; + BLI_lasso_boundbox(&rect, mcords, moves); view3d_userdata_lassoselect_init(&data, vc, &rect, mcords, moves, select); ED_view3d_init_mats_rv3d(vc->obact, vc->rv3d); - pose_foreachScreenBone(vc, do_lasso_select_pose__doSelectBone, &data); + pose_foreachScreenBone(&vc_tmp, do_lasso_select_pose__doSelectBone, &data, V3D_PROJ_TEST_CLIP_DEFAULT); if (data.is_change) { bArmature *arm = ob->data; @@ -531,17 +535,17 @@ static void do_lasso_select_mesh(ViewContext *vc, const int mcords[][2], short m edbm_backbuf_check_and_select_verts(vc->em, select); } else { - mesh_foreachScreenVert(vc, do_lasso_select_mesh__doSelectVert, &data, V3D_CLIP_TEST_RV3D_CLIPPING); + mesh_foreachScreenVert(vc, do_lasso_select_mesh__doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT); } } if (ts->selectmode & SCE_SELECT_EDGE) { /* Does both bbsel and non-bbsel versions (need screen cos for both) */ data.pass = 0; - mesh_foreachScreenEdge(vc, do_lasso_select_mesh__doSelectEdge, &data, V3D_CLIP_TEST_OFF); + mesh_foreachScreenEdge(vc, do_lasso_select_mesh__doSelectEdge, &data, V3D_PROJ_TEST_NOP); if (data.is_done == 0) { data.pass = 1; - mesh_foreachScreenEdge(vc, do_lasso_select_mesh__doSelectEdge, &data, V3D_CLIP_TEST_OFF); + mesh_foreachScreenEdge(vc, do_lasso_select_mesh__doSelectEdge, &data, V3D_PROJ_TEST_NOP); } } @@ -550,7 +554,7 @@ static void do_lasso_select_mesh(ViewContext *vc, const int mcords[][2], short m edbm_backbuf_check_and_select_faces(vc->em, select); } else { - mesh_foreachScreenFace(vc, do_lasso_select_mesh__doSelectFace, &data); + mesh_foreachScreenFace(vc, do_lasso_select_mesh__doSelectFace, &data, V3D_PROJ_TEST_CLIP_DEFAULT); } } @@ -604,7 +608,7 @@ static void do_lasso_select_curve(ViewContext *vc, const int mcords[][2], short CU_deselect_all(vc->obedit); ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */ - nurbs_foreachScreenVert(vc, do_lasso_select_curve__doSelect, &data); + nurbs_foreachScreenVert(vc, do_lasso_select_curve__doSelect, &data, V3D_PROJ_TEST_CLIP_DEFAULT); } static void do_lasso_select_lattice__doSelect(void *userData, BPoint *bp, const float screen_co[2]) @@ -629,7 +633,7 @@ static void do_lasso_select_lattice(ViewContext *vc, const int mcords[][2], shor ED_setflagsLatt(vc->obedit, 0); ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */ - lattice_foreachScreenVert(vc, do_lasso_select_lattice__doSelect, &data); + lattice_foreachScreenVert(vc, do_lasso_select_lattice__doSelect, &data, V3D_PROJ_TEST_CLIP_DEFAULT); } static void do_lasso_select_armature__doSelectBone(void *userData, struct EditBone *ebone, const float screen_co_a[2], const float screen_co_b[2]) @@ -697,7 +701,7 @@ static void do_lasso_select_armature(ViewContext *vc, const int mcords[][2], sho if (extend == 0 && select) ED_armature_deselect_all_visible(vc->obedit); - armature_foreachScreenBone(vc, do_lasso_select_armature__doSelectBone, &data); + armature_foreachScreenBone(vc, do_lasso_select_armature__doSelectBone, &data, V3D_PROJ_TEST_CLIP_DEFAULT); if (data.is_change) { bArmature *arm = vc->obedit->data; @@ -734,7 +738,7 @@ static void do_lasso_select_meta(ViewContext *vc, const int mcords[][2], short m ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); - mball_foreachScreenElem(vc, do_lasso_select_mball__doSelectElem, &data); + mball_foreachScreenElem(vc, do_lasso_select_mball__doSelectElem, &data, V3D_PROJ_TEST_CLIP_DEFAULT); } static int do_paintvert_box_select(ViewContext *vc, rcti *rect, int select, int extend) @@ -1707,7 +1711,7 @@ static int do_nurbs_box_select(ViewContext *vc, rcti *rect, int select, int exte CU_deselect_all(vc->obedit); ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */ - nurbs_foreachScreenVert(vc, do_nurbs_box_select__doSelect, &data); + nurbs_foreachScreenVert(vc, do_nurbs_box_select__doSelect, &data, V3D_PROJ_TEST_CLIP_DEFAULT); return OPERATOR_FINISHED; } @@ -1730,7 +1734,7 @@ static int do_lattice_box_select(ViewContext *vc, rcti *rect, int select, int ex ED_setflagsLatt(vc->obedit, 0); ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */ - lattice_foreachScreenVert(vc, do_lattice_box_select__doSelect, &data); + lattice_foreachScreenVert(vc, do_lattice_box_select__doSelect, &data, V3D_PROJ_TEST_CLIP_DEFAULT); return OPERATOR_FINISHED; } @@ -1791,18 +1795,18 @@ static int do_mesh_box_select(ViewContext *vc, rcti *rect, int select, int exten edbm_backbuf_check_and_select_verts(vc->em, select); } else { - mesh_foreachScreenVert(vc, do_mesh_box_select__doSelectVert, &data, V3D_CLIP_TEST_RV3D_CLIPPING); + mesh_foreachScreenVert(vc, do_mesh_box_select__doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT); } } if (ts->selectmode & SCE_SELECT_EDGE) { /* Does both bbsel and non-bbsel versions (need screen cos for both) */ data.pass = 0; - mesh_foreachScreenEdge(vc, do_mesh_box_select__doSelectEdge, &data, V3D_CLIP_TEST_OFF); + mesh_foreachScreenEdge(vc, do_mesh_box_select__doSelectEdge, &data, V3D_PROJ_TEST_NOP); if (data.is_done == 0) { data.pass = 1; - mesh_foreachScreenEdge(vc, do_mesh_box_select__doSelectEdge, &data, V3D_CLIP_TEST_OFF); + mesh_foreachScreenEdge(vc, do_mesh_box_select__doSelectEdge, &data, V3D_PROJ_TEST_NOP); } } @@ -1811,7 +1815,7 @@ static int do_mesh_box_select(ViewContext *vc, rcti *rect, int select, int exten edbm_backbuf_check_and_select_faces(vc->em, select); } else { - mesh_foreachScreenFace(vc, do_mesh_box_select__doSelectFace, &data); + mesh_foreachScreenFace(vc, do_mesh_box_select__doSelectFace, &data, V3D_PROJ_TEST_CLIP_DEFAULT); } } @@ -2321,7 +2325,7 @@ static void mesh_circle_select(ViewContext *vc, int select, const int mval[2], f edbm_backbuf_check_and_select_verts(vc->em, select == LEFTMOUSE); } else { - mesh_foreachScreenVert(vc, mesh_circle_doSelectVert, &data, V3D_CLIP_TEST_RV3D_CLIPPING); + mesh_foreachScreenVert(vc, mesh_circle_doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT); } } @@ -2330,7 +2334,7 @@ static void mesh_circle_select(ViewContext *vc, int select, const int mval[2], f edbm_backbuf_check_and_select_edges(vc->em, select == LEFTMOUSE); } else { - mesh_foreachScreenEdge(vc, mesh_circle_doSelectEdge, &data, V3D_CLIP_TEST_OFF); + mesh_foreachScreenEdge(vc, mesh_circle_doSelectEdge, &data, V3D_PROJ_TEST_NOP); } } @@ -2339,7 +2343,7 @@ static void mesh_circle_select(ViewContext *vc, int select, const int mval[2], f edbm_backbuf_check_and_select_faces(vc->em, select == LEFTMOUSE); } else { - mesh_foreachScreenFace(vc, mesh_circle_doSelectFace, &data); + mesh_foreachScreenFace(vc, mesh_circle_doSelectFace, &data, V3D_PROJ_TEST_CLIP_DEFAULT); } } @@ -2422,7 +2426,7 @@ static void nurbscurve_circle_select(ViewContext *vc, int select, const int mval view3d_userdata_circleselect_init(&data, vc, select, mval, rad); ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */ - nurbs_foreachScreenVert(vc, nurbscurve_circle_doSelect, &data); + nurbs_foreachScreenVert(vc, nurbscurve_circle_doSelect, &data, V3D_PROJ_TEST_CLIP_DEFAULT); } @@ -2441,7 +2445,7 @@ static void lattice_circle_select(ViewContext *vc, int select, const int mval[2] view3d_userdata_circleselect_init(&data, vc, select, mval, rad); ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */ - lattice_foreachScreenVert(vc, latticecurve_circle_doSelect, &data); + lattice_foreachScreenVert(vc, latticecurve_circle_doSelect, &data, V3D_PROJ_TEST_CLIP_DEFAULT); } @@ -2510,7 +2514,7 @@ static void pose_circle_select(ViewContext *vc, int select, const int mval[2], f ED_view3d_init_mats_rv3d(vc->obact, vc->rv3d); /* for foreach's screen/vert projection */ - pose_foreachScreenBone(vc, do_circle_select_pose__doSelectBone, &data); + pose_foreachScreenBone(vc, do_circle_select_pose__doSelectBone, &data, V3D_PROJ_TEST_CLIP_DEFAULT); if (data.is_change) { bArmature *arm = vc->obact->data; @@ -2597,7 +2601,7 @@ static void armature_circle_select(ViewContext *vc, int select, const int mval[2 ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); - armature_foreachScreenBone(vc, do_circle_select_armature__doSelectBone, &data); + armature_foreachScreenBone(vc, do_circle_select_armature__doSelectBone, &data, V3D_PROJ_TEST_CLIP_DEFAULT); if (data.is_change) { ED_armature_sync_selection(arm->edbo); @@ -2624,7 +2628,7 @@ static void mball_circle_select(ViewContext *vc, int select, const int mval[2], ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); - mball_foreachScreenElem(vc, do_circle_select_mball__doSelectElem, &data); + mball_foreachScreenElem(vc, do_circle_select_mball__doSelectElem, &data, V3D_PROJ_TEST_CLIP_DEFAULT); } /** Callbacks for circle selection in Editmode */ diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index e4a6d7e1b17..aee9d9d332a 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -860,8 +860,7 @@ void ED_view3d_project_float_v3_m4(ARegion *ar, const float vec[3], float r_co[3 eV3DProjStatus ED_view3d_project_base(struct ARegion *ar, struct Base *base) { - eV3DProjStatus ret = ED_view3d_project_short_global(ar, base->object->obmat[3], &base->sx, - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN); + eV3DProjStatus ret = ED_view3d_project_short_global(ar, base->object->obmat[3], &base->sx, V3D_PROJ_TEST_CLIP_DEFAULT); if (ret != V3D_PROJ_RET_OK) { base->sx = IS_CLIPPED; @@ -912,10 +911,13 @@ int ED_view3d_boundbox_clip(RegionView3D *rv3d, float obmat[][4], BoundBox *bb) */ static eV3DProjStatus ed_view3d_project__internal(ARegion *ar, float perspmat[4][4], const int is_local, /* normally hidden */ - const float co[3], float r_co[2], eV3DProjTest flag) + const float co[3], float r_co[2], const eV3DProjTest flag) { float fx, fy, vec4[4]; + /* check for bad flags */ + BLI_assert((flag & V3D_PROJ_TEST_ALL) == flag); + if (flag & V3D_PROJ_TEST_CLIP_BB) { RegionView3D *rv3d = ar->regiondata; if (rv3d->rflag & RV3D_CLIPPING) { @@ -953,7 +955,7 @@ static eV3DProjStatus ed_view3d_project__internal(ARegion *ar, } eV3DProjStatus ED_view3d_project_short_ex(ARegion *ar, float perspmat[4][4], const int is_local, - const float co[3], short r_co[2], eV3DProjTest flag) + const float co[3], short r_co[2], const eV3DProjTest flag) { float tvec[2]; eV3DProjStatus ret = ed_view3d_project__internal(ar, perspmat, is_local, co, tvec, flag); @@ -972,7 +974,7 @@ eV3DProjStatus ED_view3d_project_short_ex(ARegion *ar, float perspmat[4][4], con } eV3DProjStatus ED_view3d_project_int_ex(ARegion *ar, float perspmat[4][4], const int is_local, - const float co[3], int r_co[2], eV3DProjTest flag) + const float co[3], int r_co[2], const eV3DProjTest flag) { float tvec[2]; eV3DProjStatus ret = ed_view3d_project__internal(ar, perspmat, is_local, co, tvec, flag); @@ -991,7 +993,7 @@ eV3DProjStatus ED_view3d_project_int_ex(ARegion *ar, float perspmat[4][4], const } eV3DProjStatus ED_view3d_project_float_ex(ARegion *ar, float perspmat[4][4], const int is_local, - const float co[3], float r_co[2], eV3DProjTest flag) + const float co[3], float r_co[2], const eV3DProjTest flag) { float tvec[2]; eV3DProjStatus ret = ed_view3d_project__internal(ar, perspmat, is_local, co, tvec, flag); @@ -1009,39 +1011,39 @@ eV3DProjStatus ED_view3d_project_float_ex(ARegion *ar, float perspmat[4][4], con } /* --- short --- */ -eV3DProjStatus ED_view3d_project_short_global(ARegion *ar, const float co[3], short r_co[2], eV3DProjTest flag) +eV3DProjStatus ED_view3d_project_short_global(ARegion *ar, const float co[3], short r_co[2], const eV3DProjTest flag) { RegionView3D *rv3d = ar->regiondata; return ED_view3d_project_short_ex(ar, rv3d->persmat, FALSE, co, r_co, flag); } /* object space, use ED_view3d_init_mats_rv3d before calling */ -eV3DProjStatus ED_view3d_project_short_object(ARegion *ar, const float co[3], short r_co[2], eV3DProjTest flag) +eV3DProjStatus ED_view3d_project_short_object(ARegion *ar, const float co[3], short r_co[2], const eV3DProjTest flag) { RegionView3D *rv3d = ar->regiondata; return ED_view3d_project_short_ex(ar, rv3d->persmatob, TRUE, co, r_co, flag); } /* --- int --- */ -eV3DProjStatus ED_view3d_project_int_global(ARegion *ar, const float co[3], int r_co[2], eV3DProjTest flag) +eV3DProjStatus ED_view3d_project_int_global(ARegion *ar, const float co[3], int r_co[2], const eV3DProjTest flag) { RegionView3D *rv3d = ar->regiondata; return ED_view3d_project_int_ex(ar, rv3d->persmat, FALSE, co, r_co, flag); } /* object space, use ED_view3d_init_mats_rv3d before calling */ -eV3DProjStatus ED_view3d_project_int_object(ARegion *ar, const float co[3], int r_co[2], eV3DProjTest flag) +eV3DProjStatus ED_view3d_project_int_object(ARegion *ar, const float co[3], int r_co[2], const eV3DProjTest flag) { RegionView3D *rv3d = ar->regiondata; return ED_view3d_project_int_ex(ar, rv3d->persmatob, TRUE, co, r_co, flag); } /* --- float --- */ -eV3DProjStatus ED_view3d_project_float_global(ARegion *ar, const float co[3], float r_co[2], eV3DProjTest flag) +eV3DProjStatus ED_view3d_project_float_global(ARegion *ar, const float co[3], float r_co[2], const eV3DProjTest flag) { RegionView3D *rv3d = ar->regiondata; return ED_view3d_project_float_ex(ar, rv3d->persmat, FALSE, co, r_co, flag); } /* object space, use ED_view3d_init_mats_rv3d before calling */ -eV3DProjStatus ED_view3d_project_float_object(ARegion *ar, const float co[3], float r_co[2], eV3DProjTest flag) +eV3DProjStatus ED_view3d_project_float_object(ARegion *ar, const float co[3], float r_co[2], const eV3DProjTest flag) { RegionView3D *rv3d = ar->regiondata; return ED_view3d_project_float_ex(ar, rv3d->persmatob, TRUE, co, r_co, flag); From 7dc19e0bc7c1ae4094fefeadc13019e64eb20e08 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 10 Oct 2012 04:47:53 +0000 Subject: [PATCH 156/347] use __restrict for string functions args so the compiler can assume they dont overlap. also avoid comparing int/size_t in for loops. --- source/blender/blenlib/BLI_string.h | 20 ++++++++-------- source/blender/blenlib/BLI_string_utf8.h | 12 +++++----- source/blender/blenlib/intern/string.c | 29 +++++++++++++----------- 3 files changed, 32 insertions(+), 29 deletions(-) diff --git a/source/blender/blenlib/BLI_string.h b/source/blender/blenlib/BLI_string.h index 666c74ca36f..943597b6688 100644 --- a/source/blender/blenlib/BLI_string.h +++ b/source/blender/blenlib/BLI_string.h @@ -74,7 +74,7 @@ __attribute__((nonnull)) * \param str2 second string for append * \retval Returns dst */ -char *BLI_strdupcat(const char *str1, const char *str2) +char *BLI_strdupcat(const char *__restrict str1, const char *__restrict str2) #ifdef __GNUC__ __attribute__((warn_unused_result)) __attribute__((nonnull)) @@ -91,7 +91,7 @@ __attribute__((nonnull)) * the size of dst) * \retval Returns dst */ -char *BLI_strncpy(char *dst, const char *src, const size_t maxncpy) +char *BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t maxncpy) #ifdef __GNUC__ __attribute__((nonnull)) #endif @@ -107,7 +107,7 @@ __attribute__((nonnull)) * Assume that the strings returned must be freed afterwards, and that the inputs will contain * data we want... */ -char *BLI_str_quoted_substrN(const char *str, const char *prefix) +char *BLI_str_quoted_substrN(const char *__restrict str, const char *__restrict prefix) #ifdef __GNUC__ __attribute__((warn_unused_result)) __attribute__((nonnull)) @@ -124,7 +124,7 @@ __attribute__((nonnull)) * \param newText The text in the string to find and replace * \retval Returns the duplicated string */ -char *BLI_replacestr(char *str, const char *oldText, const char *newText) +char *BLI_replacestr(char *__restrict str, const char *__restrict oldText, const char *__restrict newText) #ifdef __GNUC__ __attribute__((warn_unused_result)) __attribute__((nonnull)) @@ -134,7 +134,7 @@ __attribute__((nonnull)) /* * Replacement for snprintf */ -size_t BLI_snprintf(char *buffer, size_t len, const char *format, ...) +size_t BLI_snprintf(char *__restrict buffer, size_t len, const char *__restrict format, ...) #ifdef __GNUC__ __attribute__ ((format(printf, 3, 4))) __attribute__((nonnull)) @@ -144,7 +144,7 @@ __attribute__((nonnull)) /* * Replacement for vsnprintf */ -size_t BLI_vsnprintf(char *buffer, size_t count, const char *format, va_list arg) +size_t BLI_vsnprintf(char *__restrict buffer, size_t count, const char *__restrict format, va_list arg) #ifdef __GNUC__ __attribute__ ((format(printf, 3, 0))) #endif @@ -154,7 +154,7 @@ __attribute__ ((format(printf, 3, 0))) * Print formatted string into a newly mallocN'd string * and return it. */ -char *BLI_sprintfN(const char *format, ...) +char *BLI_sprintfN(const char *__restrict format, ...) #ifdef __GNUC__ __attribute__ ((format(printf, 1, 2))) __attribute__((warn_unused_result)) @@ -162,7 +162,7 @@ __attribute__((nonnull)) #endif ; -size_t BLI_strescape(char *dst, const char *src, const size_t maxlen) +size_t BLI_strescape(char *__restrict dst, const char *__restrict src, const size_t maxlen) #ifdef __GNUC__ __attribute__((nonnull)) #endif @@ -216,12 +216,12 @@ __attribute__((nonnull)) #endif ; /* time var is global */ -void BLI_ascii_strtolower(char *str, int len) +void BLI_ascii_strtolower(char *str, const size_t len) #ifdef __GNUC__ __attribute__((nonnull)) #endif ; -void BLI_ascii_strtoupper(char *str, int len) +void BLI_ascii_strtoupper(char *str, const size_t len) #ifdef __GNUC__ __attribute__((nonnull)) #endif diff --git a/source/blender/blenlib/BLI_string_utf8.h b/source/blender/blenlib/BLI_string_utf8.h index 56ed4beba53..47980d104fe 100644 --- a/source/blender/blenlib/BLI_string_utf8.h +++ b/source/blender/blenlib/BLI_string_utf8.h @@ -31,16 +31,16 @@ extern "C" { #endif -char *BLI_strncpy_utf8(char *dst, const char *src, size_t maxncpy); -char *BLI_strncat_utf8(char *dst, const char *src, size_t maxncpy); +char *BLI_strncpy_utf8(char *__restrict dst, const char *__restrict src, size_t maxncpy); +char *BLI_strncat_utf8(char *__restrict dst, const char *__restrict src, size_t maxncpy); int BLI_utf8_invalid_byte(const char *str, int length); int BLI_utf8_invalid_strip(char *str, int length); int BLI_str_utf8_size(const char *p); /* warning, can return -1 on bad chars */ /* copied from glib */ unsigned int BLI_str_utf8_as_unicode(const char *p); -unsigned int BLI_str_utf8_as_unicode_and_size(const char *p, size_t *index); -unsigned int BLI_str_utf8_as_unicode_step(const char *p, size_t *index); +unsigned int BLI_str_utf8_as_unicode_and_size(const char *__restrict p, size_t *__restrict index); +unsigned int BLI_str_utf8_as_unicode_step(const char *__restrict p, size_t *__restrict index); size_t BLI_str_utf8_from_unicode(unsigned int c, char *outbuf); char *BLI_str_find_prev_char_utf8(const char *str, const char *p); @@ -50,8 +50,8 @@ char *BLI_str_prev_char_utf8(const char *p); /* wchar_t functions, copied from blenders own font.c originally */ size_t BLI_wstrlen_utf8(const wchar_t *src); size_t BLI_strlen_utf8(const char *strc); -size_t BLI_strncpy_wchar_as_utf8(char *dst, const wchar_t *src, const size_t maxcpy); -size_t BLI_strncpy_wchar_from_utf8(wchar_t *dst, const char *src, const size_t maxcpy); +size_t BLI_strncpy_wchar_as_utf8(char *__restrict dst, const wchar_t *__restrict src, const size_t maxcpy); +size_t BLI_strncpy_wchar_from_utf8(wchar_t *__restrict dst, const char *__restrict src, const size_t maxcpy); #define BLI_UTF8_MAX 6 #define BLI_UTF8_ERR ((unsigned int)-1) diff --git a/source/blender/blenlib/intern/string.c b/source/blender/blenlib/intern/string.c index 8501db7c8b8..4b64a650b52 100644 --- a/source/blender/blenlib/intern/string.c +++ b/source/blender/blenlib/intern/string.c @@ -296,11 +296,12 @@ char *BLI_strcasestr(const char *s, const char *find) int BLI_strcasecmp(const char *s1, const char *s2) { - int i; + register int i; + register char c1, c2; for (i = 0;; i++) { - char c1 = tolower(s1[i]); - char c2 = tolower(s2[i]); + c1 = tolower(s1[i]); + c2 = tolower(s2[i]); if (c1 < c2) { return -1; @@ -318,11 +319,12 @@ int BLI_strcasecmp(const char *s1, const char *s2) int BLI_strncasecmp(const char *s1, const char *s2, size_t len) { - int i; + register size_t i; + register char c1, c2; for (i = 0; i < len; i++) { - char c1 = tolower(s1[i]); - char c2 = tolower(s2[i]); + c1 = tolower(s1[i]); + c2 = tolower(s2[i]); if (c1 < c2) { return -1; @@ -341,15 +343,16 @@ int BLI_strncasecmp(const char *s1, const char *s2, size_t len) /* natural string compare, keeping numbers in order */ int BLI_natstrcmp(const char *s1, const char *s2) { - int d1 = 0, d2 = 0; + register int d1 = 0, d2 = 0; + register char c1, c2; /* if both chars are numeric, to a strtol(). * then increase string deltas as long they are * numeric, else do a tolower and char compare */ while (1) { - char c1 = tolower(s1[d1]); - char c2 = tolower(s2[d2]); + c1 = tolower(s1[d1]); + c2 = tolower(s2[d2]); if (isdigit(c1) && isdigit(c2) ) { int val1, val2; @@ -419,18 +422,18 @@ size_t BLI_strnlen(const char *str, size_t maxlen) return end ? (size_t) (end - str) : maxlen; } -void BLI_ascii_strtolower(char *str, int len) +void BLI_ascii_strtolower(char *str, const size_t len) { - int i; + size_t i; for (i = 0; i < len; i++) if (str[i] >= 'A' && str[i] <= 'Z') str[i] += 'a' - 'A'; } -void BLI_ascii_strtoupper(char *str, int len) +void BLI_ascii_strtoupper(char *str, const size_t len) { - int i; + size_t i; for (i = 0; i < len; i++) if (str[i] >= 'a' && str[i] <= 'z') From 9829ba31b9654fd402ef6ca5cee78cc474d01225 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 10 Oct 2012 05:56:49 +0000 Subject: [PATCH 157/347] Color Management: fixed color management-less texture rendering There was a missing check for whether color management enabled or not when converting byte textures to linear space. This commit also fixes wrong texture preview rendering, which was applying sRGB transform twice, making procedural textures bright. This will make float textures being previewed dark (in a linear space) but that's how it used to behave in pre-OCIO color management. --- source/blender/editors/render/render_preview.c | 13 ++----------- source/blender/render/intern/include/render_types.h | 3 +++ source/blender/render/intern/source/envmap.c | 1 + source/blender/render/intern/source/pipeline.c | 4 ++++ .../blender/render/intern/source/render_texture.c | 10 +++++----- 5 files changed, 15 insertions(+), 16 deletions(-) diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c index 817067422af..96276d5eb1b 100644 --- a/source/blender/editors/render/render_preview.c +++ b/source/blender/editors/render/render_preview.c @@ -273,16 +273,7 @@ static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPre /* exception: don't apply render part of display transform for texture previews or icons */ if ((id && sp->pr_method == PR_ICON_RENDER) || id_type == ID_TE) { - ColorManagedDisplaySettings *display_settings = &sce->display_settings; - ColorManagedViewSettings *view_settings = &sce->view_settings; - - const char *default_view_name = IMB_colormanagement_view_get_default_name(display_settings->display_device); - - view_settings->exposure = 0.0f; - view_settings->gamma = 1.0f; - view_settings->flag &= ~COLORMANAGE_VIEW_USE_CURVES; - - BLI_strncpy(view_settings->view_transform, default_view_name, sizeof(view_settings->view_transform)); + BKE_scene_disable_color_management(sce); } if ((id && sp->pr_method == PR_ICON_RENDER) && id_type != ID_WO) @@ -550,7 +541,7 @@ static int ed_preview_draw_rect(ScrArea *sa, Scene *sce, ID *id, int split, int * color managed as well? */ IMB_buffer_byte_from_float(rect_byte, rres.rectf, - 4, dither, IB_PROFILE_SRGB, IB_PROFILE_LINEAR_RGB, do_predivide, + 4, dither, IB_PROFILE_SRGB, IB_PROFILE_SRGB, do_predivide, rres.rectx, rres.recty, rres.rectx, rres.rectx); } diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h index 85dbd9356f4..8474d9ff09e 100644 --- a/source/blender/render/intern/include/render_types.h +++ b/source/blender/render/intern/include/render_types.h @@ -120,6 +120,9 @@ struct Render /* state settings */ short flag, osa, ok, result_ok; + /* due to performance issues, getting initialized from color management settings once on Render initialization */ + short scene_color_manage; + /* result of rendering */ RenderResult *result; /* if render with single-layer option, other rendered layers are stored here */ diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c index 03eb21dfa23..96b33a0bf1a 100644 --- a/source/blender/render/intern/source/envmap.c +++ b/source/blender/render/intern/source/envmap.c @@ -154,6 +154,7 @@ static Render *envmap_render_copy(Render *re, EnvMap *env) RE_InitState(envre, NULL, &envre->r, NULL, cuberes, cuberes, NULL); envre->scene = re->scene; /* unsure about this... */ + envre->scene_color_manage = re->scene_color_manage; envre->lay = re->lay; /* view stuff in env render */ diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index 1859de0039d..84d57aa7d09 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -1519,6 +1519,7 @@ void RE_MergeFullSample(Render *re, Main *bmain, Scene *sce, bNodeTree *ntree) re->main = bmain; re->scene = sce; + re->scene_color_manage = BKE_scene_check_color_management_enabled(sce); /* first call RE_ReadRenderResult on every renderlayer scene. this creates Render structs */ @@ -2014,6 +2015,7 @@ static int render_initialize_from_main(Render *re, Main *bmain, Scene *scene, Sc re->main = bmain; re->scene = scene; + re->scene_color_manage = BKE_scene_check_color_management_enabled(scene); re->camera_override = camera_override; re->lay = lay; @@ -2352,6 +2354,7 @@ void RE_PreviewRender(Render *re, Main *bmain, Scene *sce) re->main = bmain; re->scene = sce; + re->scene_color_manage = BKE_scene_check_color_management_enabled(sce); re->lay = sce->lay; camera = RE_GetCamera(re); @@ -2396,6 +2399,7 @@ int RE_ReadRenderResult(Scene *scene, Scene *scenode) re = RE_NewRender(scene->id.name); RE_InitState(re, NULL, &scene->r, NULL, winx, winy, &disprect); re->scene = scene; + re->scene_color_manage = BKE_scene_check_color_management_enabled(scene); BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); success = render_result_exr_file_read(re, 0); diff --git a/source/blender/render/intern/source/render_texture.c b/source/blender/render/intern/source/render_texture.c index 0511b03b42d..3e2ce95af50 100644 --- a/source/blender/render/intern/source/render_texture.c +++ b/source/blender/render/intern/source/render_texture.c @@ -1234,7 +1234,7 @@ int multitex_nodes(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, ImBuf *ibuf = BKE_image_get_ibuf(tex->ima, &tex->iuser); /* don't linearize float buffers, assumed to be linear */ - if (ibuf && !(ibuf->rect_float)) + if (ibuf && !(ibuf->rect_float) && R.scene_color_manage) IMB_colormanagement_colorspace_to_scene_linear_v3(&texres->tr, ibuf->rect_colorspace); } } @@ -2384,7 +2384,7 @@ void do_material_tex(ShadeInput *shi, Render *re) ImBuf *ibuf = BKE_image_get_ibuf(ima, &tex->iuser); /* don't linearize float buffers, assumed to be linear */ - if (ibuf && !(ibuf->rect_float)) + if (ibuf && !(ibuf->rect_float) && R.scene_color_manage) IMB_colormanagement_colorspace_to_scene_linear_v3(tcol, ibuf->rect_colorspace); } @@ -2896,7 +2896,7 @@ void do_halo_tex(HaloRen *har, float xn, float yn, float col_r[4]) ImBuf *ibuf = BKE_image_get_ibuf(ima, &mtex->tex->iuser); /* don't linearize float buffers, assumed to be linear */ - if (ibuf && !(ibuf->rect_float)) + if (ibuf && !(ibuf->rect_float) && R.scene_color_manage) IMB_colormanagement_colorspace_to_scene_linear_v3(&texres.tr, ibuf->rect_colorspace); } @@ -3115,7 +3115,7 @@ void do_sky_tex(const float rco[3], float lo[3], const float dxyview[2], float h ImBuf *ibuf = BKE_image_get_ibuf(ima, &tex->iuser); /* don't linearize float buffers, assumed to be linear */ - if (ibuf && !(ibuf->rect_float)) + if (ibuf && !(ibuf->rect_float) && R.scene_color_manage) IMB_colormanagement_colorspace_to_scene_linear_v3(tcol, ibuf->rect_colorspace); } @@ -3329,7 +3329,7 @@ void do_lamp_tex(LampRen *la, const float lavec[3], ShadeInput *shi, float col_r ImBuf *ibuf = BKE_image_get_ibuf(ima, &tex->iuser); /* don't linearize float buffers, assumed to be linear */ - if (ibuf && !(ibuf->rect_float)) + if (ibuf && !(ibuf->rect_float) && R.scene_color_manage) IMB_colormanagement_colorspace_to_scene_linear_v3(&texres.tr, ibuf->rect_colorspace); } From 3606cd5216e328efd4e0a13f74b3fde10592d1b2 Mon Sep 17 00:00:00 2001 From: Gaia Clary Date: Wed, 10 Oct 2012 08:04:04 +0000 Subject: [PATCH 158/347] Cosmetic: Changed label of the 'Install Addon...' Button to 'Install from File...' --- release/scripts/startup/bl_operators/wm.py | 2 +- release/scripts/startup/bl_ui/space_userpref.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py index eac90a8b091..af33f80bdf8 100644 --- a/release/scripts/startup/bl_operators/wm.py +++ b/release/scripts/startup/bl_operators/wm.py @@ -1668,7 +1668,7 @@ class WM_OT_theme_install(Operator): class WM_OT_addon_install(Operator): "Install an addon" bl_idname = "wm.addon_install" - bl_label = "Install Addon..." + bl_label = "Install from File..." overwrite = BoolProperty( name="Overwrite", diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py index df30c3ee9ae..39e2cf40569 100644 --- a/release/scripts/startup/bl_ui/space_userpref.py +++ b/release/scripts/startup/bl_ui/space_userpref.py @@ -92,7 +92,7 @@ class USERPREF_HT_header(Header): layout.operator("wm.keyconfig_import") layout.operator("wm.keyconfig_export") elif userpref.active_section == 'ADDONS': - layout.operator("wm.addon_install") + layout.operator("wm.addon_install", icon="FILESEL") layout.menu("USERPREF_MT_addons_dev_guides") elif userpref.active_section == 'THEMES': layout.operator("ui.reset_default_theme") From cf3a5d94f0d4b8cd67fd7600e6c22972e173cc60 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 10 Oct 2012 08:07:28 +0000 Subject: [PATCH 159/347] Fix #32780: Maya keymap selection issues Maya keymap used LMB press to select object and also used tweak event of LMB for border select. This lead to selecting object under the cursor before border select could start. This could be pain when working on huge scenes. Solved by switching selection from LMB press to release. --- release/scripts/presets/keyconfig/maya.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/release/scripts/presets/keyconfig/maya.py b/release/scripts/presets/keyconfig/maya.py index fe011a51e22..b5df519cf59 100644 --- a/release/scripts/presets/keyconfig/maya.py +++ b/release/scripts/presets/keyconfig/maya.py @@ -133,42 +133,42 @@ kmi = km.keymap_items.new('wm.context_toggle_enum', 'Z', 'PRESS', alt=True) kmi.properties.data_path = 'space_data.viewport_shade' kmi.properties.value_1 = 'TEXTURED' kmi.properties.value_2 = 'SOLID' -kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'PRESS') +kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'RELEASE') kmi.properties.extend = False kmi.properties.center = False kmi.properties.object = False kmi.properties.enumerate = False -kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'PRESS', shift=True) +kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'RELEASE', shift=True) kmi.properties.extend = True kmi.properties.center = False kmi.properties.object = False kmi.properties.enumerate = False -kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'PRESS', ctrl=True) +kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'RELEASE', ctrl=True) kmi.properties.extend = False kmi.properties.center = True kmi.properties.object = False kmi.properties.enumerate = False -kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'PRESS', alt=True) +kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'RELEASE', alt=True) kmi.properties.extend = False kmi.properties.center = False kmi.properties.object = False kmi.properties.enumerate = True -kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'PRESS', shift=True, ctrl=True) +kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'RELEASE', shift=True, ctrl=True) kmi.properties.extend = True kmi.properties.center = True kmi.properties.object = False kmi.properties.enumerate = False -kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'PRESS', ctrl=True, alt=True) +kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'RELEASE', ctrl=True, alt=True) kmi.properties.extend = False kmi.properties.center = True kmi.properties.object = False kmi.properties.enumerate = True -kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'PRESS', shift=True, alt=True) +kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'RELEASE', shift=True, alt=True) kmi.properties.extend = True kmi.properties.center = False kmi.properties.object = False kmi.properties.enumerate = True -kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'PRESS', shift=True, ctrl=True, alt=True) +kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'RELEASE', shift=True, ctrl=True, alt=True) kmi.properties.extend = True kmi.properties.center = True kmi.properties.object = False From 89969a07f0f665f83ef0cea6e2302f2237407196 Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Wed, 10 Oct 2012 08:29:13 +0000 Subject: [PATCH 160/347] Changing clear weight code from "assigning 0" to "removing". Its less efficient but better practice. + Some style clean. --- source/blender/editors/object/object_vgroup.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index ab9a4cb07ec..f1a31f8bfaa 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -507,14 +507,13 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou /* clear weights */ if (replace_mode == WT_REPLACE_ALL_WEIGHTS) { - for(i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++) { + for (i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++) { - if (*dv_dst == NULL) { - continue; - } + if (*dv_dst == NULL) continue; dw_dst = defvert_verify_index(*dv_dst, index_dst); - if (dw_dst) (*dw_dst).weight = 0; + /* remove vertex from group */ + if (dw_dst) defvert_remove_group(*dv_dst, dw_dst); } } @@ -562,7 +561,7 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou /* reset nearest */ nearest.dist = FLT_MAX; - /* With current binary tree its marginally faster to start searching at the top, as opposed to previous search. */ + /* with current binary tree its marginally faster to start searching at the top, as opposed to previous search. */ nearest.index = -1; /* transform into target space */ @@ -601,7 +600,7 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou /* reset nearest */ nearest.dist = FLT_MAX; - /* With current binary tree its marginally faster to start searching at the top, as opposed to previous search. */ + /* with current binary tree its marginally faster to start searching at the top, as opposed to previous search. */ nearest.index = -1; /* transform into target space */ From cc8c0d89e33613dcaa4398012d7786ee491a7510 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Wed, 10 Oct 2012 08:46:07 +0000 Subject: [PATCH 161/347] Graph Editor: Added a filtering option for Drivers mode to only show F-Curves with errors This filtering option is useful when rigging and you want to figure out if any of your drivers are not functioning, and/or which one(s) are not, so that you can go through fixing them. It saves you from having to check on each one individually, or going into the console to try to infer which ones are not working. --- .../scripts/startup/bl_ui/space_dopesheet.py | 4 +++ .../blender/editors/animation/anim_filter.c | 28 +++++++++++++++++++ source/blender/makesdna/DNA_action_types.h | 1 + source/blender/makesrna/intern/rna_action.c | 7 +++++ 4 files changed, 40 insertions(+) diff --git a/release/scripts/startup/bl_ui/space_dopesheet.py b/release/scripts/startup/bl_ui/space_dopesheet.py index 8e955338480..8a47a631e82 100644 --- a/release/scripts/startup/bl_ui/space_dopesheet.py +++ b/release/scripts/startup/bl_ui/space_dopesheet.py @@ -29,6 +29,7 @@ from bpy.types import Header, Menu def dopesheet_filter(layout, context, genericFiltersOnly=False): dopesheet = context.space_data.dopesheet is_nla = context.area.type == 'NLA_EDITOR' + is_drivers = (context.area.type == 'GRAPH_EDITOR' and context.space_data.mode == 'DRIVERS') row = layout.row(align=True) row.prop(dopesheet, "show_only_selected", text="") @@ -37,6 +38,9 @@ def dopesheet_filter(layout, context, genericFiltersOnly=False): if is_nla: row.prop(dopesheet, "show_missing_nla", text="") + if is_drivers: + row.prop(dopesheet, "show_only_errors", text="") + if not genericFiltersOnly: if bpy.data.groups: row = layout.row(align=True) diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c index 8b0593d48ac..d913779a883 100644 --- a/source/blender/editors/animation/anim_filter.c +++ b/source/blender/editors/animation/anim_filter.c @@ -980,6 +980,27 @@ static short skip_fcurve_with_name(bDopeSheet *ads, FCurve *fcu, ID *owner_id) return 1; } +/* Check if F-Curve has errors and/or is disabled + * > returns: (bool) True if F-Curve has errors/is disabled + */ +static short fcurve_has_errors(FCurve *fcu) +{ + /* F-Curve disabled - path eval error */ + if (fcu->flag & FCURVE_DISABLED) { + return 1; + } + + /* driver? */ + if (fcu->driver) { + /* for now, just check if the entire thing got disabled... */ + if (fcu->driver->flag & DRIVER_FLAG_INVALID) + return 1; + } + + /* no errors found */ + return 0; +} + /* find the next F-Curve that is usable for inclusion */ static FCurve *animfilter_fcurve_next(bDopeSheet *ads, FCurve *first, bActionGroup *grp, int filter_mode, ID *owner_id) { @@ -1018,6 +1039,13 @@ static FCurve *animfilter_fcurve_next(bDopeSheet *ads, FCurve *first, bActionGro continue; } + /* error-based filtering... */ + if ((ads) && (ads->filterflag & ADS_FILTER_ONLY_ERRORS)) { + /* skip if no errors... */ + if (fcurve_has_errors(fcu) == 0) + continue; + } + /* this F-Curve can be used, so return it */ return fcu; } diff --git a/source/blender/makesdna/DNA_action_types.h b/source/blender/makesdna/DNA_action_types.h index d75c6019825..d8d1ad78451 100644 --- a/source/blender/makesdna/DNA_action_types.h +++ b/source/blender/makesdna/DNA_action_types.h @@ -563,6 +563,7 @@ typedef enum eDopeSheet_FilterFlag { /* general filtering 3 */ ADS_FILTER_INCL_HIDDEN = (1 << 26), /* include 'hidden' channels too (i.e. those from hidden Objects/Bones) */ ADS_FILTER_BY_FCU_NAME = (1 << 27), /* for F-Curves, filter by the displayed name (i.e. to isolate all Location curves only) */ + ADS_FILTER_ONLY_ERRORS = (1 << 28), /* show only F-Curves which are disabled/have errors - for debugging drivers */ /* combination filters (some only used at runtime) */ ADS_FILTER_NOOBDATA = (ADS_FILTER_NOCAM | ADS_FILTER_NOMAT | ADS_FILTER_NOLAM | ADS_FILTER_NOCUR | ADS_FILTER_NOPART | ADS_FILTER_NOARM | ADS_FILTER_NOSPK) diff --git a/source/blender/makesrna/intern/rna_action.c b/source/blender/makesrna/intern/rna_action.c index 00a257ab4f9..f08b9084b3c 100644 --- a/source/blender/makesrna/intern/rna_action.c +++ b/source/blender/makesrna/intern/rna_action.c @@ -287,6 +287,13 @@ static void rna_def_dopesheet(BlenderRNA *brna) RNA_def_property_ui_icon(prop, ICON_GHOST_ENABLED, 0); RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL); + /* Debug Filtering Settings */ + prop = RNA_def_property(srna, "show_only_errors", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "filterflag", ADS_FILTER_ONLY_ERRORS); + RNA_def_property_ui_text(prop, "Show Errors", "Only include F-Curves and Drivers that are disabled or have errors"); + RNA_def_property_ui_icon(prop, ICON_HELP, 0); // XXX: this doesn't quite fit? + RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL); + /* Object Group Filtering Settings */ prop = RNA_def_property(srna, "show_only_group_objects", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "filterflag", ADS_FILTER_ONLYOBGROUP); From 33489b3b74b1ae4e5ee00ee93f24fbdb0e81da2b Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 10 Oct 2012 08:46:52 +0000 Subject: [PATCH 162/347] fix for crash when entering fly mode in a camera view that has no camera (rare but possible situation). --- source/blender/editors/space_view3d/view3d_fly.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source/blender/editors/space_view3d/view3d_fly.c b/source/blender/editors/space_view3d/view3d_fly.c index c743b88e889..cd358dea869 100644 --- a/source/blender/editors/space_view3d/view3d_fly.c +++ b/source/blender/editors/space_view3d/view3d_fly.c @@ -284,6 +284,11 @@ static int initFlyInfo(bContext *C, FlyInfo *fly, wmOperator *op, wmEvent *event puts("\n-- fly begin --"); #endif + /* sanity check: for rare but possible case (if lib-linking the camera fails) */ + if ((fly->rv3d->persp == RV3D_CAMOB) && (fly->v3d->camera == NULL)) { + fly->rv3d->persp = RV3D_PERSP; + } + if (fly->rv3d->persp == RV3D_CAMOB && fly->v3d->camera->id.lib) { BKE_report(op->reports, RPT_ERROR, "Cannot fly a camera from an external library"); return FALSE; From 7c351d3d0917ad5b5159f6a2a317de478ade6826 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 10 Oct 2012 08:47:53 +0000 Subject: [PATCH 163/347] fix error setting quadview when there is no camera in the scene, the view would glitch/jump when accessing afterwards. --- source/blender/editors/screen/screen_ops.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index c64a4a37f3a..5eac841dec6 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -2716,6 +2716,8 @@ static int region_quadview_exec(bContext *C, wmOperator *op) /* lock views and set them */ if (sa->spacetype == SPACE_VIEW3D) { + View3D *v3d = sa->spacedata.first; + /* run ED_view3d_lock() so the correct 'rv3d->viewquat' is set, * otherwise when restoring rv3d->localvd the 'viewquat' won't * match the 'view', set on entering localview See: [#26315], @@ -2743,7 +2745,15 @@ static int region_quadview_exec(bContext *C, wmOperator *op) ar = ar->next; rv3d = ar->regiondata; - rv3d->view = RV3D_VIEW_CAMERA; rv3d->persp = RV3D_CAMOB; + + /* check if we have a camera */ + if (v3d->camera) { + rv3d->view = RV3D_VIEW_CAMERA; rv3d->persp = RV3D_CAMOB; + } + else { + rv3d->view = RV3D_VIEW_PERSPORTHO; rv3d->persp = RV3D_PERSP; + } + ED_view3d_lock(rv3d); view3d_localview_update_rv3d(rv3d); } From 495e3f3f36383dd532ec94e11377651f91394ddd Mon Sep 17 00:00:00 2001 From: Ove Murberg Henriksen Date: Wed, 10 Oct 2012 08:50:56 +0000 Subject: [PATCH 164/347] Its silly to use "verify index" because it will add non existing and remove them afterwards. --- source/blender/editors/object/object_vgroup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index f1a31f8bfaa..b5643cdb9cb 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -511,7 +511,7 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou if (*dv_dst == NULL) continue; - dw_dst = defvert_verify_index(*dv_dst, index_dst); + dw_dst = defvert_find_index(*dv_dst, index_dst); /* remove vertex from group */ if (dw_dst) defvert_remove_group(*dv_dst, dw_dst); } From dac3ddc5316bdab2464c92f5b026c8b34d8ba618 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 10 Oct 2012 10:05:56 +0000 Subject: [PATCH 165/347] minor refactor, move view selected rv3d specific logic into its own static function. --- .../editors/space_view3d/view3d_edit.c | 115 ++++++++++-------- .../editors/space_view3d/view3d_view.c | 20 +-- 2 files changed, 74 insertions(+), 61 deletions(-) diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 4e8981f16bd..2b2453d6dc2 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -2282,23 +2282,78 @@ void VIEW3D_OT_view_all(wmOperatorType *ot) RNA_def_boolean(ot->srna, "center", 0, "Center", ""); } +static void viewselected_rv3d_from_minmax(bContext *C, View3D *v3d, ARegion *ar, + const float min[3], const float max[3], + int ok_dist) +{ + RegionView3D *rv3d = ar->regiondata; + float afm[3]; + float size; + + /* SMOOTHVIEW */ + float new_ofs[3]; + float new_dist; + + sub_v3_v3v3(afm, max, min); + size = MAX3(afm[0], afm[1], afm[2]); + + if (ok_dist) { + /* fix up zoom distance if needed */ + + if (rv3d->is_persp) { + if (size <= v3d->near * 1.5f) { + /* do not zoom closer than the near clipping plane */ + size = v3d->near * 1.5f; + } + } + else { /* ortho */ + if (size < 0.0001f) { + /* bounding box was a single point so do not zoom */ + ok_dist = 0; + } + else { + /* adjust zoom so it looks nicer */ + size *= 0.7f; + } + } + } + + add_v3_v3v3(new_ofs, min, max); + mul_v3_fl(new_ofs, -0.5f); + + new_dist = size; + + /* correction for window aspect ratio */ + if (ar->winy > 2 && ar->winx > 2) { + size = (float)ar->winx / (float)ar->winy; + if (size < 1.0f) size = 1.0f / size; + new_dist *= size; + } + + if (rv3d->persp == RV3D_CAMOB && !ED_view3d_camera_lock_check(v3d, rv3d)) { + rv3d->persp = RV3D_PERSP; + view3d_smooth_view(C, v3d, ar, v3d->camera, NULL, new_ofs, NULL, ok_dist ? &new_dist : NULL, NULL); + } + else { + view3d_smooth_view(C, v3d, ar, NULL, NULL, new_ofs, NULL, ok_dist ? &new_dist : NULL, NULL); + } + + /* smooth view does viewlock RV3D_BOXVIEW copy */ +} + /* like a localview without local!, was centerview() in 2.4x */ static int viewselected_exec(bContext *C, wmOperator *UNUSED(op)) { ARegion *ar = CTX_wm_region(C); View3D *v3d = CTX_wm_view3d(C); - RegionView3D *rv3d = CTX_wm_region_view3d(C); + RegionView3D *rv3d = ar->regiondata; Scene *scene = CTX_data_scene(C); Object *ob = OBACT; Object *obedit = CTX_data_edit_object(C); - float size, min[3], max[3], afm[3]; + float min[3], max[3]; int ok = 0, ok_dist = 1; const short skip_camera = ED_view3d_camera_lock_check(v3d, rv3d); - /* SMOOTHVIEW */ - float new_ofs[3]; - float new_dist; - INIT_MINMAX(min, max); if (ob && (ob->mode & OB_MODE_WEIGHT_PAINT)) { @@ -2368,53 +2423,11 @@ static int viewselected_exec(bContext *C, wmOperator *UNUSED(op)) } } - if (ok == 0) return OPERATOR_FINISHED; - - sub_v3_v3v3(afm, max, min); - size = MAX3(afm[0], afm[1], afm[2]); - - if (ok_dist) { - /* fix up zoom distance if needed */ - - if (rv3d->is_persp) { - if (size <= v3d->near * 1.5f) { - /* do not zoom closer than the near clipping plane */ - size = v3d->near * 1.5f; - } - } - else { /* ortho */ - if (size < 0.0001f) { - /* bounding box was a single point so do not zoom */ - ok_dist = 0; - } - else { - /* adjust zoom so it looks nicer */ - size *= 0.7f; - } - } + if (ok == 0) { + return OPERATOR_FINISHED; } - add_v3_v3v3(new_ofs, min, max); - mul_v3_fl(new_ofs, -0.5f); - - new_dist = size; - - /* correction for window aspect ratio */ - if (ar->winy > 2 && ar->winx > 2) { - size = (float)ar->winx / (float)ar->winy; - if (size < 1.0f) size = 1.0f / size; - new_dist *= size; - } - - if (rv3d->persp == RV3D_CAMOB && !ED_view3d_camera_lock_check(v3d, rv3d)) { - rv3d->persp = RV3D_PERSP; - view3d_smooth_view(C, v3d, ar, v3d->camera, NULL, new_ofs, NULL, ok_dist ? &new_dist : NULL, NULL); - } - else { - view3d_smooth_view(C, v3d, ar, NULL, NULL, new_ofs, NULL, ok_dist ? &new_dist : NULL, NULL); - } - - /* smooth view does viewlock RV3D_BOXVIEW copy */ + viewselected_rv3d_from_minmax(C, v3d, ar, min, max, ok_dist); // XXX BIF_view3d_previewrender_signal(curarea, PR_DBASE|PR_DISPRECT); diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index aee9d9d332a..26242773e28 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -125,7 +125,7 @@ struct SmoothView3DStore { /* will start timer if appropriate */ /* the arguments are the desired situation */ void view3d_smooth_view(bContext *C, View3D *v3d, ARegion *ar, Object *oldcamera, Object *camera, - float *ofs, float *quat, float *dist, float *lens) + float *ofs, float *quat, float *dist, float *lens) { wmWindowManager *wm = CTX_wm_manager(C); wmWindow *win = CTX_wm_window(C); @@ -140,7 +140,7 @@ void view3d_smooth_view(bContext *C, View3D *v3d, ARegion *ar, Object *oldcamera copy_qt_qt(sms.new_quat, rv3d->viewquat); sms.new_dist = rv3d->dist; sms.new_lens = v3d->lens; - sms.to_camera = 0; + sms.to_camera = FALSE; /* note on camera locking, this is a little confusing but works ok. * we may be changing the view 'as if' there is no active camera, but in fact @@ -162,22 +162,22 @@ void view3d_smooth_view(bContext *C, View3D *v3d, ARegion *ar, Object *oldcamera if (camera) { ED_view3d_from_object(camera, sms.new_ofs, sms.new_quat, &sms.new_dist, &sms.new_lens); - sms.to_camera = 1; /* restore view3d values in end */ + sms.to_camera = TRUE; /* restore view3d values in end */ } if (C && U.smooth_viewtx) { - int changed = 0; /* zero means no difference */ + int changed = FALSE; /* zero means no difference */ if (oldcamera != camera) - changed = 1; + changed = TRUE; else if (sms.new_dist != rv3d->dist) - changed = 1; + changed = TRUE; else if (sms.new_lens != v3d->lens) - changed = 1; + changed = TRUE; else if (!equals_v3v3(sms.new_ofs, rv3d->ofs)) - changed = 1; + changed = TRUE; else if (!equals_v4v4(sms.new_quat, rv3d->viewquat)) - changed = 1; + changed = TRUE; /* The new view is different from the old one * so animate the view */ @@ -241,7 +241,7 @@ void view3d_smooth_view(bContext *C, View3D *v3d, ARegion *ar, Object *oldcamera /* if we get here nothing happens */ if (ok == FALSE) { - if (sms.to_camera == 0) { + if (sms.to_camera == FALSE) { copy_v3_v3(rv3d->ofs, sms.new_ofs); copy_qt_qt(rv3d->viewquat, sms.new_quat); rv3d->dist = sms.new_dist; From 6514290d1daf62b34f4f927f6c9129b2c558b337 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 10 Oct 2012 11:36:24 +0000 Subject: [PATCH 166/347] option for view3d-selected to use all regions (nice for viewing selected in quad-view), currently not assigned to any keys. --- .../editors/space_view3d/view3d_edit.c | 28 ++++++++++++++++--- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 2b2453d6dc2..c808566077e 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -2342,17 +2342,17 @@ static void viewselected_rv3d_from_minmax(bContext *C, View3D *v3d, ARegion *ar, } /* like a localview without local!, was centerview() in 2.4x */ -static int viewselected_exec(bContext *C, wmOperator *UNUSED(op)) +static int viewselected_exec(bContext *C, wmOperator *op) { ARegion *ar = CTX_wm_region(C); View3D *v3d = CTX_wm_view3d(C); - RegionView3D *rv3d = ar->regiondata; Scene *scene = CTX_data_scene(C); Object *ob = OBACT; Object *obedit = CTX_data_edit_object(C); float min[3], max[3]; int ok = 0, ok_dist = 1; - const short skip_camera = ED_view3d_camera_lock_check(v3d, rv3d); + const short skip_camera = ED_view3d_camera_lock_check(v3d, ar->regiondata); + const short use_all_regions = RNA_boolean_get(op->ptr, "use_all_regions"); INIT_MINMAX(min, max); @@ -2427,7 +2427,22 @@ static int viewselected_exec(bContext *C, wmOperator *UNUSED(op)) return OPERATOR_FINISHED; } - viewselected_rv3d_from_minmax(C, v3d, ar, min, max, ok_dist); + if (use_all_regions) { + ScrArea *sa = CTX_wm_area(C); + ARegion *ar_iter; + for (ar_iter = sa->regionbase.first; ar_iter; ar_iter = ar_iter->next) { + if (ar_iter->regiontype == RGN_TYPE_WINDOW) { + RegionView3D *rv3d = ar_iter->regiondata; + /* when using all regions, don't jump out of camera view */ + if (rv3d->persp != RV3D_CAMOB) { + viewselected_rv3d_from_minmax(C, v3d, ar_iter, min, max, ok_dist); + } + } + } + } + else { + viewselected_rv3d_from_minmax(C, v3d, ar, min, max, ok_dist); + } // XXX BIF_view3d_previewrender_signal(curarea, PR_DBASE|PR_DISPRECT); @@ -2436,6 +2451,7 @@ static int viewselected_exec(bContext *C, wmOperator *UNUSED(op)) void VIEW3D_OT_view_selected(wmOperatorType *ot) { + PropertyRNA *prop; /* identifiers */ ot->name = "View Selected"; @@ -2448,6 +2464,10 @@ void VIEW3D_OT_view_selected(wmOperatorType *ot) /* flags */ ot->flag = 0; + + /* rna later */ + prop = RNA_def_boolean(ot->srna, "use_all_regions", 0, "All Regions", "View selected for all regions"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); } static int view_lock_clear_exec(bContext *C, wmOperator *UNUSED(op)) From 844916d46edf82311cde48186f179416875d9fb5 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 10 Oct 2012 11:37:38 +0000 Subject: [PATCH 167/347] check addons are enabled before disabling them (would cause python exceptions when removing a disabled addon). --- release/scripts/modules/addon_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release/scripts/modules/addon_utils.py b/release/scripts/modules/addon_utils.py index ab68c9424cd..6658ee7fb2b 100644 --- a/release/scripts/modules/addon_utils.py +++ b/release/scripts/modules/addon_utils.py @@ -311,7 +311,7 @@ def disable(module_name, default_set=True): # possible this addon is from a previous session and didn't load a # module this time. So even if the module is not found, still disable # the addon in the user prefs. - if mod: + if mod and getattr(mod, "__addon_enabled__", False) is not False: mod.__addon_enabled__ = False mod.__addon_persistent = False From cc50d58b20c6e50aea8a5b23772e180237a200fe Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 10 Oct 2012 12:22:45 +0000 Subject: [PATCH 168/347] add `All Regions` option to view_all (homekey), de-duplicate functions with view-selected. --- .../editors/space_view3d/view3d_edit.c | 226 +++++++++--------- 1 file changed, 108 insertions(+), 118 deletions(-) diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index c808566077e..329286953d6 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -2178,111 +2178,7 @@ void VIEW3D_OT_dolly(wmOperatorType *ot) RNA_def_int(ot->srna, "my", 0, 0, INT_MAX, "Zoom Position Y", "", 0, INT_MAX); } - - -static int view3d_all_exec(bContext *C, wmOperator *op) /* was view3d_home() in 2.4x */ -{ - ARegion *ar = CTX_wm_region(C); - View3D *v3d = CTX_wm_view3d(C); - RegionView3D *rv3d = CTX_wm_region_view3d(C); - Scene *scene = CTX_data_scene(C); - Base *base; - float *curs; - const short skip_camera = ED_view3d_camera_lock_check(v3d, rv3d); - - int center = RNA_boolean_get(op->ptr, "center"); - - float size, min[3], max[3], afm[3]; - int ok = 1, onedone = FALSE; - - if (center) { - /* in 2.4x this also move the cursor to (0, 0, 0) (with shift+c). */ - curs = give_cursor(scene, v3d); - zero_v3(min); - zero_v3(max); - zero_v3(curs); - } - else { - INIT_MINMAX(min, max); - } - - for (base = scene->base.first; base; base = base->next) { - if (BASE_VISIBLE(v3d, base)) { - onedone = TRUE; - - if (skip_camera && base->object == v3d->camera) { - continue; - } - - BKE_object_minmax(base->object, min, max, FALSE); - } - } - if (!onedone) { - ED_region_tag_redraw(ar); - /* TODO - should this be cancel? - * I think no, because we always move the cursor, with or without - * object, but in this case there is no change in the scene, - * only the cursor so I choice a ED_region_tag like - * view3d_smooth_view do for the center_cursor. - * See bug #22640 - */ - return OPERATOR_FINISHED; - } - - sub_v3_v3v3(afm, max, min); - size = 0.7f * MAX3(afm[0], afm[1], afm[2]); - if (size == 0.0f) ok = 0; - - if (ok) { - float new_dist; - float new_ofs[3]; - - new_dist = size; - new_ofs[0] = -(min[0] + max[0]) / 2.0f; - new_ofs[1] = -(min[1] + max[1]) / 2.0f; - new_ofs[2] = -(min[2] + max[2]) / 2.0f; - - /* correction for window aspect ratio */ - if (ar->winy > 2 && ar->winx > 2) { - size = (float)ar->winx / (float)ar->winy; - if (size < 1.0f) size = 1.0f / size; - new_dist *= size; - } - - if ((rv3d->persp == RV3D_CAMOB) && !ED_view3d_camera_lock_check(v3d, rv3d)) { - rv3d->persp = RV3D_PERSP; - view3d_smooth_view(C, v3d, ar, v3d->camera, NULL, new_ofs, NULL, &new_dist, NULL); - } - else { - view3d_smooth_view(C, v3d, ar, NULL, NULL, new_ofs, NULL, &new_dist, NULL); - } - } -// XXX BIF_view3d_previewrender_signal(curarea, PR_DBASE|PR_DISPRECT); - - WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d); - - return OPERATOR_FINISHED; -} - - -void VIEW3D_OT_view_all(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "View All"; - ot->description = "View all objects in scene"; - ot->idname = "VIEW3D_OT_view_all"; - - /* api callbacks */ - ot->exec = view3d_all_exec; - ot->poll = ED_operator_region_view3d_active; - - /* flags */ - ot->flag = 0; - - RNA_def_boolean(ot->srna, "center", 0, "Center", ""); -} - -static void viewselected_rv3d_from_minmax(bContext *C, View3D *v3d, ARegion *ar, +static void view3d_from_minmax(bContext *C, View3D *v3d, ARegion *ar, const float min[3], const float max[3], int ok_dist) { @@ -2341,6 +2237,110 @@ static void viewselected_rv3d_from_minmax(bContext *C, View3D *v3d, ARegion *ar, /* smooth view does viewlock RV3D_BOXVIEW copy */ } +/* same as view3d_from_minmax but for all regions (except cameras) */ +static void view3d_from_minmax_multi(bContext *C, View3D *v3d, + const float min[3], const float max[3], + const int ok_dist) +{ + ScrArea *sa = CTX_wm_area(C); + ARegion *ar; + for (ar = sa->regionbase.first; ar; ar = ar->next) { + if (ar->regiontype == RGN_TYPE_WINDOW) { + RegionView3D *rv3d = ar->regiondata; + /* when using all regions, don't jump out of camera view, + * but _do_ allow locked cameras to be moved */ + if ((rv3d->persp != RV3D_CAMOB) || ED_view3d_camera_lock_check(v3d, rv3d)) { + view3d_from_minmax(C, v3d, ar, min, max, ok_dist); + } + } + } +} + +static int view3d_all_exec(bContext *C, wmOperator *op) /* was view3d_home() in 2.4x */ +{ + ARegion *ar = CTX_wm_region(C); + View3D *v3d = CTX_wm_view3d(C); + RegionView3D *rv3d = CTX_wm_region_view3d(C); + Scene *scene = CTX_data_scene(C); + Base *base; + float *curs; + const short skip_camera = ED_view3d_camera_lock_check(v3d, rv3d); + const short use_all_regions = RNA_boolean_get(op->ptr, "use_all_regions"); + int center = RNA_boolean_get(op->ptr, "center"); + + float min[3], max[3]; + int ok = 1, onedone = FALSE; + + if (center) { + /* in 2.4x this also move the cursor to (0, 0, 0) (with shift+c). */ + curs = give_cursor(scene, v3d); + zero_v3(min); + zero_v3(max); + zero_v3(curs); + } + else { + INIT_MINMAX(min, max); + } + + for (base = scene->base.first; base; base = base->next) { + if (BASE_VISIBLE(v3d, base)) { + onedone = TRUE; + + if (skip_camera && base->object == v3d->camera) { + continue; + } + + BKE_object_minmax(base->object, min, max, FALSE); + } + } + if (!onedone) { + ED_region_tag_redraw(ar); + /* TODO - should this be cancel? + * I think no, because we always move the cursor, with or without + * object, but in this case there is no change in the scene, + * only the cursor so I choice a ED_region_tag like + * view3d_smooth_view do for the center_cursor. + * See bug #22640 + */ + return OPERATOR_FINISHED; + } + + if (ok == 0) { + return OPERATOR_FINISHED; + } + + if (use_all_regions) { + view3d_from_minmax_multi(C, v3d, min, max, TRUE); + } + else { + view3d_from_minmax(C, v3d, ar, min, max, TRUE); + } + + return OPERATOR_FINISHED; +} + + +void VIEW3D_OT_view_all(wmOperatorType *ot) +{ + PropertyRNA *prop; + + /* identifiers */ + ot->name = "View All"; + ot->description = "View all objects in scene"; + ot->idname = "VIEW3D_OT_view_all"; + + /* api callbacks */ + ot->exec = view3d_all_exec; + ot->poll = ED_operator_region_view3d_active; + + /* flags */ + ot->flag = 0; + + prop = RNA_def_boolean(ot->srna, "use_all_regions", 0, "All Regions", "View selected for all regions"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); + RNA_def_boolean(ot->srna, "center", 0, "Center", ""); +} + /* like a localview without local!, was centerview() in 2.4x */ static int viewselected_exec(bContext *C, wmOperator *op) { @@ -2428,22 +2428,12 @@ static int viewselected_exec(bContext *C, wmOperator *op) } if (use_all_regions) { - ScrArea *sa = CTX_wm_area(C); - ARegion *ar_iter; - for (ar_iter = sa->regionbase.first; ar_iter; ar_iter = ar_iter->next) { - if (ar_iter->regiontype == RGN_TYPE_WINDOW) { - RegionView3D *rv3d = ar_iter->regiondata; - /* when using all regions, don't jump out of camera view */ - if (rv3d->persp != RV3D_CAMOB) { - viewselected_rv3d_from_minmax(C, v3d, ar_iter, min, max, ok_dist); - } - } - } + view3d_from_minmax_multi(C, v3d, min, max, ok_dist); } else { - viewselected_rv3d_from_minmax(C, v3d, ar, min, max, ok_dist); + view3d_from_minmax(C, v3d, ar, min, max, ok_dist); } - + // XXX BIF_view3d_previewrender_signal(curarea, PR_DBASE|PR_DISPRECT); return OPERATOR_FINISHED; From 38e6a2f2f2a2234ea444203310289ce4ee55549a Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 10 Oct 2012 12:30:47 +0000 Subject: [PATCH 169/347] fix error changing the view with a lock-camera-to-view on and smooth-view disabled. --- source/blender/editors/space_view3d/view3d_view.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index 26242773e28..f70c375eb29 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -248,6 +248,8 @@ void view3d_smooth_view(bContext *C, View3D *v3d, ARegion *ar, Object *oldcamera v3d->lens = sms.new_lens; } + ED_view3d_camera_lock_sync(v3d, rv3d); + if (rv3d->viewlock & RV3D_BOXVIEW) view3d_boxview_copy(sa, ar); From b4671d67edef053118ae53b12b2672603a8bf9b6 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 10 Oct 2012 12:54:36 +0000 Subject: [PATCH 170/347] - Ctrl+NumpadDel is now view-selected (all regions), ... was view cursor. - Ctrl+Home: is now view-all (all regions). --- source/blender/editors/space_view3d/view3d_ops.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c index 14c02c2357e..cb4f85430c5 100644 --- a/source/blender/editors/space_view3d/view3d_ops.c +++ b/source/blender/editors/space_view3d/view3d_ops.c @@ -136,8 +136,10 @@ void view3d_keymap(wmKeyConfig *keyconf) WM_keymap_verify_item(keymap, "VIEW3D_OT_move", MIDDLEMOUSE, KM_PRESS, KM_SHIFT, 0); WM_keymap_verify_item(keymap, "VIEW3D_OT_zoom", MIDDLEMOUSE, KM_PRESS, KM_CTRL, 0); WM_keymap_verify_item(keymap, "VIEW3D_OT_dolly", MIDDLEMOUSE, KM_PRESS, KM_CTRL | KM_SHIFT, 0); - WM_keymap_verify_item(keymap, "VIEW3D_OT_view_selected", PADPERIOD, KM_PRESS, 0, 0); - WM_keymap_verify_item(keymap, "VIEW3D_OT_view_center_cursor", PADPERIOD, KM_PRESS, KM_CTRL, 0); + kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_view_selected", PADPERIOD, KM_PRESS, KM_CTRL, 0); + RNA_boolean_set(kmi->ptr, "use_all_regions", TRUE); + kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_view_selected", PADPERIOD, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "use_all_regions", FALSE); WM_keymap_verify_item(keymap, "VIEW3D_OT_view_lock_to_active", PADPERIOD, KM_PRESS, KM_SHIFT, 0); WM_keymap_verify_item(keymap, "VIEW3D_OT_view_lock_clear", PADPERIOD, KM_PRESS, KM_ALT, 0); @@ -169,6 +171,9 @@ void view3d_keymap(wmKeyConfig *keyconf) kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_view_all", HOMEKEY, KM_PRESS, 0, 0); RNA_boolean_set(kmi->ptr, "center", FALSE); /* only without camera view */ + kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_view_all", HOMEKEY, KM_PRESS, KM_CTRL, 0); + RNA_boolean_set(kmi->ptr, "use_all_regions", TRUE); + RNA_boolean_set(kmi->ptr, "center", FALSE); /* only without camera view */ kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_view_all", CKEY, KM_PRESS, KM_SHIFT, 0); RNA_boolean_set(kmi->ptr, "center", TRUE); From f0a9b664694dacb0388a8e078d46753dc6a36352 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 10 Oct 2012 13:02:20 +0000 Subject: [PATCH 171/347] Cycles: Anisotropic BSDF enabled, with tangents now computed from the active UV map. It's using the Ward BSDF currently, which has some energy loss so might be a bit dark. More/better BSDF options can be implemented later. Patch by Mike Farnsworth, some modifications by me. Currently it's not possible yet to set a custom tangent, that will follow as part of per-bsdf normals patch. --- intern/cycles/blender/blender_mesh.cpp | 83 +++++++++++++++++++ intern/cycles/blender/blender_shader.cpp | 4 + intern/cycles/kernel/kernel_montecarlo.h | 2 +- intern/cycles/kernel/kernel_shader.h | 5 ++ intern/cycles/kernel/kernel_types.h | 3 + intern/cycles/kernel/svm/bsdf_ward.h | 5 +- intern/cycles/kernel/svm/svm.h | 14 +++- intern/cycles/kernel/svm/svm_closure.h | 21 ++++- intern/cycles/kernel/svm/svm_geometry.h | 25 ++++-- intern/cycles/kernel/svm/svm_types.h | 4 +- intern/cycles/render/attribute.cpp | 2 + intern/cycles/render/graph.cpp | 6 ++ intern/cycles/render/graph.h | 1 + intern/cycles/render/nodes.cpp | 31 +++++++ intern/cycles/render/nodes.h | 2 + intern/cycles/util/util_types.h | 1 + source/blender/blenkernel/intern/node.c | 1 + .../makesrna/intern/rna_nodetree_types.h | 1 + source/blender/nodes/CMakeLists.txt | 2 +- source/blender/nodes/NOD_shader.h | 1 + .../nodes/node_shader_bsdf_anisotropic.c | 2 +- 21 files changed, 198 insertions(+), 18 deletions(-) diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp index 9764f24a893..8f737be9765 100644 --- a/intern/cycles/blender/blender_mesh.cpp +++ b/intern/cycles/blender/blender_mesh.cpp @@ -33,6 +33,28 @@ CCL_NAMESPACE_BEGIN /* Find/Add */ +static float3 tri_calc_tangent(float3 v0, float3 v1, float3 v2, float3 tx0, float3 tx1, float3 tx2) +{ + float3 duv1 = tx2 - tx0; + float3 duv2 = tx2 - tx1; + float3 dp1 = v2 - v0; + float3 dp2 = v2 - v1; + float det = duv1[0] * duv2[1] - duv1[1] * duv2[0]; + + if(det != 0.0f) { + return normalize(dp1 * duv2[1] - dp2 * duv1[1]); + } + else { + /* give back a sane default, using a valid edge as a fallback */ + float3 edge = v1 - v0; + + if(len(edge) == 0.0f) + edge = v2 - v0; + + return normalize(edge); + } +} + static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector& used_shaders) { /* create vertices */ @@ -157,6 +179,67 @@ static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector< } } } + + /* create texcoord-based tangent attributes */ + { + BL::Mesh::tessface_uv_textures_iterator l; + + for(b_mesh.tessface_uv_textures.begin(l); l != b_mesh.tessface_uv_textures.end(); ++l) { + AttributeStandard std = (l->active_render())? ATTR_STD_TANGENT: ATTR_STD_NONE; + + if(!mesh->need_attribute(scene, std)) + continue; + + Attribute *attr = mesh->attributes.add(std, ustring("Tangent")); + + /* compute average tangents per vertex */ + float3 *tangents = attr->data_float3(); + memset(tangents, 0, sizeof(float3)*mesh->verts.size()); + + BL::MeshTextureFaceLayer::data_iterator t; + + size_t fi = 0; /* face index */ + b_mesh.tessfaces.begin(f); + for(l->data.begin(t); t != l->data.end() && f != b_mesh.tessfaces.end(); ++t, ++fi, ++f) { + int4 vi = get_int4(f->vertices_raw()); + + float3 tx0 = get_float3(t->uv1()); + float3 tx1 = get_float3(t->uv2()); + float3 tx2 = get_float3(t->uv3()); + + float3 v0 = mesh->verts[vi[0]]; + float3 v1 = mesh->verts[vi[1]]; + float3 v2 = mesh->verts[vi[2]]; + + /* calculate tangent for the triangle; + * get vertex positions, and find change in position with respect + * to the texture coords in the first texture coord dimension */ + float3 tangent0 = tri_calc_tangent(v0, v1, v2, tx0, tx1, tx2); + + if(nverts[fi] == 4) { + /* quad tangent */ + float3 tx3 = get_float3(t->uv4()); + float3 v3 = mesh->verts[vi[3]]; + float3 tangent1 = tri_calc_tangent(v0, v2, v3, tx0, tx2, tx3); + + tangents[vi[0]] += 0.5f*(tangent0 + tangent1); + tangents[vi[1]] += tangent0; + tangents[vi[2]] += 0.5f*(tangent0 + tangent1); + tangents[vi[3]] += tangent1; + } + else { + /* triangle tangent */ + tangents[vi[0]] += tangent0; + tangents[vi[1]] += tangent0; + tangents[vi[2]] += tangent0; + } + } + + /* normalize tangent vectors */ + for(int i = 0; i < mesh->verts.size(); i++) + tangents[i] = normalize(tangents[i]); + } + } } static void create_subd_mesh(Mesh *mesh, BL::Mesh b_mesh, PointerRNA *cmesh, const vector& used_shaders) diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp index b6d5cc623bb..56548613647 100644 --- a/intern/cycles/blender/blender_shader.cpp +++ b/intern/cycles/blender/blender_shader.cpp @@ -315,6 +315,10 @@ static ShaderNode *add_node(BL::BlendData b_data, BL::Scene b_scene, ShaderGraph node = new HoldoutNode(); break; } + case BL::ShaderNode::type_BSDF_ANISOTROPIC: { + node = new WardBsdfNode(); + break; + } case BL::ShaderNode::type_BSDF_DIFFUSE: { node = new DiffuseBsdfNode(); break; diff --git a/intern/cycles/kernel/kernel_montecarlo.h b/intern/cycles/kernel/kernel_montecarlo.h index d0b588a88d4..48d1aa64c9f 100644 --- a/intern/cycles/kernel/kernel_montecarlo.h +++ b/intern/cycles/kernel/kernel_montecarlo.h @@ -72,7 +72,7 @@ __device void to_unit_disk(float *x, float *y) __device void make_orthonormals_tangent(const float3 N, const float3 T, float3 *a, float3 *b) { - *b = cross(N, T); + *b = normalize(cross(N, T)); *a = cross(*b, N); } diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h index ee4460a8541..1ed5e3d352c 100644 --- a/intern/cycles/kernel/kernel_shader.h +++ b/intern/cycles/kernel/kernel_shader.h @@ -93,6 +93,7 @@ __device_inline void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd, #ifdef __DPDU__ /* dPdu/dPdv */ triangle_dPdudv(kg, &sd->dPdu, &sd->dPdv, sd->prim); + sd->T = make_float3(0.0f, 0.0f, 0.0f); #endif #ifdef __INSTANCING__ @@ -117,6 +118,7 @@ __device_inline void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd, #ifdef __DPDU__ sd->dPdu = -sd->dPdu; sd->dPdv = -sd->dPdv; + sd->T = make_float3(0.0f, 0.0f, 0.0f); #endif } @@ -208,6 +210,8 @@ __device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd, } #endif } + + sd->T = make_float3(0.0f, 0.0f, 0.0f); #endif /* backfacing test */ @@ -293,6 +297,7 @@ __device_inline void shader_setup_from_background(KernelGlobals *kg, ShaderData /* dPdu/dPdv */ sd->dPdu = make_float3(0.0f, 0.0f, 0.0f); sd->dPdv = make_float3(0.0f, 0.0f, 0.0f); + sd->T = make_float3(0.0f, 0.0f, 0.0f); #endif #ifdef __RAY_DIFFERENTIALS__ diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index b290d4c42d9..ae9b0ac6d99 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -447,6 +447,9 @@ typedef struct ShaderData { /* differential of P w.r.t. parametric coordinates. note that dPdu is * not readily suitable as a tangent for shading on triangles. */ float3 dPdu, dPdv; + + /* tangent for shading */ + float3 T; #endif #ifdef __MULTI_CLOSURE__ diff --git a/intern/cycles/kernel/svm/bsdf_ward.h b/intern/cycles/kernel/svm/bsdf_ward.h index 6ae45948a73..56b8ad72c89 100644 --- a/intern/cycles/kernel/svm/bsdf_ward.h +++ b/intern/cycles/kernel/svm/bsdf_ward.h @@ -67,7 +67,7 @@ __device float3 bsdf_ward_eval_reflect(const ShaderData *sd, const ShaderClosure float m_ax = sc->data0; float m_ay = sc->data1; float3 m_N = sd->N; - float3 m_T = normalize(sd->dPdu); + float3 m_T = sd->T; float cosNO = dot(m_N, I); float cosNI = dot(m_N, omega_in); @@ -90,6 +90,7 @@ __device float3 bsdf_ward_eval_reflect(const ShaderData *sd, const ShaderClosure *pdf = exp_val / denom; return make_float3 (out, out, out); } + return make_float3 (0, 0, 0); } @@ -108,7 +109,7 @@ __device int bsdf_ward_sample(const ShaderData *sd, const ShaderClosure *sc, flo float m_ax = sc->data0; float m_ay = sc->data1; float3 m_N = sd->N; - float3 m_T = normalize(sd->dPdu); + float3 m_T = sd->T; float cosNO = dot(m_N, sd->I); if(cosNO > 0) { diff --git a/intern/cycles/kernel/svm/svm.h b/intern/cycles/kernel/svm/svm.h index 5b0f192ea47..e5167a4f670 100644 --- a/intern/cycles/kernel/svm/svm.h +++ b/intern/cycles/kernel/svm/svm.h @@ -205,6 +205,14 @@ __device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ShaderT case NODE_CLOSURE_WEIGHT: svm_node_closure_weight(sd, stack, node.y); break; +#ifdef __DPDU__ + case NODE_CLOSURE_SET_TANGENT: + svm_node_closure_set_tangent(sd, node.y, node.z, node.w); + break; + case NODE_CLOSURE_TANGENT: + svm_node_closure_tangent(sd, stack, node.y); + break; +#endif case NODE_EMISSION_WEIGHT: svm_node_emission_weight(kg, sd, stack, node); break; @@ -261,14 +269,14 @@ __device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ShaderT svm_node_camera(kg, sd, stack, node.y, node.z, node.w); break; case NODE_GEOMETRY: - svm_node_geometry(sd, stack, node.y, node.z); + svm_node_geometry(kg, sd, stack, node.y, node.z); break; #ifdef __EXTRA_NODES__ case NODE_GEOMETRY_BUMP_DX: - svm_node_geometry_bump_dx(sd, stack, node.y, node.z); + svm_node_geometry_bump_dx(kg, sd, stack, node.y, node.z); break; case NODE_GEOMETRY_BUMP_DY: - svm_node_geometry_bump_dy(sd, stack, node.y, node.z); + svm_node_geometry_bump_dy(kg, sd, stack, node.y, node.z); break; case NODE_LIGHT_PATH: svm_node_light_path(sd, stack, node.y, node.z, path_flag); diff --git a/intern/cycles/kernel/svm/svm_closure.h b/intern/cycles/kernel/svm/svm_closure.h index 935504026ef..c942d50908c 100644 --- a/intern/cycles/kernel/svm/svm_closure.h +++ b/intern/cycles/kernel/svm/svm_closure.h @@ -179,7 +179,7 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st float roughness_u = param1; float roughness_v = param2; - bsdf_ward_setup(sd, sc, normalize(sd->dPdu), roughness_u, roughness_v); + bsdf_ward_setup(sd, sc, normalize(sd->T), roughness_u, roughness_v); break; } #endif @@ -425,5 +425,24 @@ __device void svm_node_add_closure(ShaderData *sd, float *stack, uint unused, #endif } +#ifdef __DPDU__ +__device_inline void svm_node_closure_store_tangent(ShaderData *sd, float3 tangent) +{ + sd->T = normalize(tangent); +} + +__device void svm_node_closure_set_tangent(ShaderData *sd, uint x, uint y, uint z) +{ + float3 tangent = make_float3(__int_as_float(x), __int_as_float(y), __int_as_float(z)); + svm_node_closure_store_tangent(sd, tangent); +} + +__device void svm_node_closure_tangent(ShaderData *sd, float *stack, uint tangent_offset) +{ + float3 tangent = stack_load_float3(stack, tangent_offset); + svm_node_closure_store_tangent(sd, tangent); +} +#endif + CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/svm/svm_geometry.h b/intern/cycles/kernel/svm/svm_geometry.h index 22741bdb067..582c079fd6a 100644 --- a/intern/cycles/kernel/svm/svm_geometry.h +++ b/intern/cycles/kernel/svm/svm_geometry.h @@ -20,7 +20,7 @@ CCL_NAMESPACE_BEGIN /* Geometry Node */ -__device void svm_node_geometry(ShaderData *sd, float *stack, uint type, uint out_offset) +__device void svm_node_geometry(KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint out_offset) { float3 data; @@ -28,7 +28,16 @@ __device void svm_node_geometry(ShaderData *sd, float *stack, uint type, uint ou case NODE_GEOM_P: data = sd->P; break; case NODE_GEOM_N: data = sd->N; break; #ifdef __DPDU__ - case NODE_GEOM_T: data = normalize(sd->dPdu); break; + case NODE_GEOM_T: { + int attr_offset = find_attribute(kg, sd, ATTR_STD_TANGENT); + + if(attr_offset == ATTR_STD_NOT_FOUND) + data = normalize(sd->dPdu); + else + data = triangle_attribute_float3(kg, sd, ATTR_ELEMENT_VERTEX, attr_offset, NULL, NULL); + + break; + } #endif case NODE_GEOM_I: data = sd->I; break; case NODE_GEOM_Ng: data = sd->Ng; break; @@ -40,7 +49,7 @@ __device void svm_node_geometry(ShaderData *sd, float *stack, uint type, uint ou stack_store_float3(stack, out_offset, data); } -__device void svm_node_geometry_bump_dx(ShaderData *sd, float *stack, uint type, uint out_offset) +__device void svm_node_geometry_bump_dx(KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint out_offset) { #ifdef __RAY_DIFFERENTIALS__ float3 data; @@ -48,16 +57,16 @@ __device void svm_node_geometry_bump_dx(ShaderData *sd, float *stack, uint type, switch(type) { case NODE_GEOM_P: data = sd->P + sd->dP.dx; break; case NODE_GEOM_uv: data = make_float3(sd->u + sd->du.dx, sd->v + sd->dv.dx, 0.0f); break; - default: svm_node_geometry(sd, stack, type, out_offset); return; + default: svm_node_geometry(kg, sd, stack, type, out_offset); return; } stack_store_float3(stack, out_offset, data); #else - svm_node_geometry(sd, stack, type, out_offset); + svm_node_geometry(kg, sd, stack, type, out_offset); #endif } -__device void svm_node_geometry_bump_dy(ShaderData *sd, float *stack, uint type, uint out_offset) +__device void svm_node_geometry_bump_dy(KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint out_offset) { #ifdef __RAY_DIFFERENTIALS__ float3 data; @@ -65,12 +74,12 @@ __device void svm_node_geometry_bump_dy(ShaderData *sd, float *stack, uint type, switch(type) { case NODE_GEOM_P: data = sd->P + sd->dP.dy; break; case NODE_GEOM_uv: data = make_float3(sd->u + sd->du.dy, sd->v + sd->dv.dy, 0.0f); break; - default: svm_node_geometry(sd, stack, type, out_offset); return; + default: svm_node_geometry(kg, sd, stack, type, out_offset); return; } stack_store_float3(stack, out_offset, data); #else - svm_node_geometry(sd, stack, type, out_offset); + svm_node_geometry(kg, sd, stack, type, out_offset); #endif } diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h index ee423573cdf..22afa304432 100644 --- a/intern/cycles/kernel/svm/svm_types.h +++ b/intern/cycles/kernel/svm/svm_types.h @@ -92,7 +92,9 @@ typedef enum NodeType { NODE_LIGHT_FALLOFF, NODE_OBJECT_INFO, NODE_PARTICLE_INFO, - NODE_TEX_BRICK + NODE_TEX_BRICK, + NODE_CLOSURE_SET_TANGENT, + NODE_CLOSURE_TANGENT, } NodeType; typedef enum NodeAttributeType { diff --git a/intern/cycles/render/attribute.cpp b/intern/cycles/render/attribute.cpp index 5122c1af410..4bcaef0fb17 100644 --- a/intern/cycles/render/attribute.cpp +++ b/intern/cycles/render/attribute.cpp @@ -162,6 +162,8 @@ Attribute *AttributeSet::add(AttributeStandard std, ustring name) attr = add(name, TypeDesc::TypeNormal, Attribute::FACE); else if(std == ATTR_STD_UV) attr = add(name, TypeDesc::TypePoint, Attribute::CORNER); + else if(std == ATTR_STD_TANGENT) + attr = add(name, TypeDesc::TypeVector, Attribute::VERTEX); else if(std == ATTR_STD_GENERATED) attr = add(name, TypeDesc::TypePoint, Attribute::VERTEX); else if(std == ATTR_STD_POSITION_UNDEFORMED) diff --git a/intern/cycles/render/graph.cpp b/intern/cycles/render/graph.cpp index 62758128a73..c13102e9567 100644 --- a/intern/cycles/render/graph.cpp +++ b/intern/cycles/render/graph.cpp @@ -468,6 +468,12 @@ void ShaderGraph::default_inputs(bool do_osl) connect(geom->output("Position"), input); } + else if(input->default_value == ShaderInput::TANGENT) { + if(!geom) + geom = new GeometryNode(); + + connect(geom->output("Tangent"), input); + } } } } diff --git a/intern/cycles/render/graph.h b/intern/cycles/render/graph.h index c3b674d0f23..d485ed02150 100644 --- a/intern/cycles/render/graph.h +++ b/intern/cycles/render/graph.h @@ -112,6 +112,7 @@ public: INCOMING, NORMAL, POSITION, + TANGENT, NONE }; diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index 4e16eea2774..da31a528310 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -1221,12 +1221,35 @@ WardBsdfNode::WardBsdfNode() { closure = CLOSURE_BSDF_WARD_ID; + add_input("Tangent", SHADER_SOCKET_VECTOR, ShaderInput::TANGENT); + add_input("Roughness U", SHADER_SOCKET_FLOAT, 0.2f); add_input("Roughness V", SHADER_SOCKET_FLOAT, 0.2f); } +void WardBsdfNode::attributes(AttributeRequestSet *attributes) +{ + ShaderInput *tangent_in = input("Tangent"); + + if(!tangent_in->link) + attributes->add(ATTR_STD_TANGENT); + + ShaderNode::attributes(attributes); +} + void WardBsdfNode::compile(SVMCompiler& compiler) { + ShaderInput *tangent_in = input("Tangent"); + + if(tangent_in->link) { + int attr = compiler.attribute(ATTR_STD_TANGENT); + compiler.stack_assign(tangent_in); + compiler.add_node(NODE_ATTR, attr, tangent_in->stack_offset, NODE_ATTR_FLOAT3); + compiler.add_node(NODE_CLOSURE_TANGENT, tangent_in->stack_offset); + } + else + compiler.add_node(NODE_CLOSURE_SET_TANGENT, tangent_in->value); + BsdfNode::compile(compiler, input("Roughness U"), input("Roughness V")); } @@ -1566,6 +1589,14 @@ GeometryNode::GeometryNode() add_output("Backfacing", SHADER_SOCKET_FLOAT); } +void GeometryNode::attributes(AttributeRequestSet *attributes) +{ + if(!output("Tangent")->links.empty()) + attributes->add(ATTR_STD_TANGENT); + + ShaderNode::attributes(attributes); +} + void GeometryNode::compile(SVMCompiler& compiler) { ShaderOutput *out; diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h index e8e584dd8ef..6e5d7be0091 100644 --- a/intern/cycles/render/nodes.h +++ b/intern/cycles/render/nodes.h @@ -201,6 +201,7 @@ public: class WardBsdfNode : public BsdfNode { public: SHADER_NODE_CLASS(WardBsdfNode) + void attributes(AttributeRequestSet *attributes); }; class DiffuseBsdfNode : public BsdfNode { @@ -278,6 +279,7 @@ public: class GeometryNode : public ShaderNode { public: SHADER_NODE_CLASS(GeometryNode) + void attributes(AttributeRequestSet *attributes); }; class TextureCoordinateNode : public ShaderNode { diff --git a/intern/cycles/util/util_types.h b/intern/cycles/util/util_types.h index 5c6b9d5bb78..f2c02cadcbf 100644 --- a/intern/cycles/util/util_types.h +++ b/intern/cycles/util/util_types.h @@ -449,6 +449,7 @@ typedef enum AttributeStandard { ATTR_STD_VERTEX_NORMAL, ATTR_STD_FACE_NORMAL, ATTR_STD_UV, + ATTR_STD_TANGENT, ATTR_STD_GENERATED, ATTR_STD_POSITION_UNDEFORMED, ATTR_STD_POSITION_UNDISPLACED, diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 8965488a9b3..2fd54baf96f 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -2248,6 +2248,7 @@ static void registerShaderNodes(bNodeTreeType *ttype) register_node_type_sh_particle_info(ttype); register_node_type_sh_background(ttype); + register_node_type_sh_bsdf_anisotropic(ttype); register_node_type_sh_bsdf_diffuse(ttype); register_node_type_sh_bsdf_glossy(ttype); register_node_type_sh_bsdf_glass(ttype); diff --git a/source/blender/makesrna/intern/rna_nodetree_types.h b/source/blender/makesrna/intern/rna_nodetree_types.h index db1e1e16adf..aa48a8cf26d 100644 --- a/source/blender/makesrna/intern/rna_nodetree_types.h +++ b/source/blender/makesrna/intern/rna_nodetree_types.h @@ -67,6 +67,7 @@ DefNode( ShaderNode, SH_NODE_ADD_SHADER, 0, "AD DefNode( ShaderNode, SH_NODE_ATTRIBUTE, def_sh_attribute, "ATTRIBUTE", Attribute, "Attribute", "" ) DefNode( ShaderNode, SH_NODE_BACKGROUND, 0, "BACKGROUND", Background, "Background", "" ) DefNode( ShaderNode, SH_NODE_HOLDOUT, 0, "HOLDOUT", Holdout, "Holdout", "" ) +DefNode( ShaderNode, SH_NODE_BSDF_ANISOTROPIC, 0, "BSDF_ANISOTROPIC", BsdfAnisotropic, "Anisotropic Bsdf", "" ) DefNode( ShaderNode, SH_NODE_BSDF_DIFFUSE, 0, "BSDF_DIFFUSE", BsdfDiffuse, "Diffuse Bsdf", "" ) DefNode( ShaderNode, SH_NODE_BSDF_GLOSSY, def_glossy, "BSDF_GLOSSY", BsdfGlossy, "Glossy Bsdf", "" ) DefNode( ShaderNode, SH_NODE_BSDF_GLASS, def_glossy, "BSDF_GLASS", BsdfGlass, "Glass Bsdf", "" ) diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt index 08e0e7b0f93..f4e427ce3e3 100644 --- a/source/blender/nodes/CMakeLists.txt +++ b/source/blender/nodes/CMakeLists.txt @@ -146,7 +146,7 @@ set(SRC shader/nodes/node_shader_vectMath.c shader/nodes/node_shader_attribute.c shader/nodes/node_shader_background.c - # shader/nodes/node_shader_bsdf_anisotropic.c # XXX, why not included? + shader/nodes/node_shader_bsdf_anisotropic.c shader/nodes/node_shader_bsdf_diffuse.c shader/nodes/node_shader_bsdf_glossy.c shader/nodes/node_shader_bsdf_glass.c diff --git a/source/blender/nodes/NOD_shader.h b/source/blender/nodes/NOD_shader.h index 49428c06e5f..306dd50d7e2 100644 --- a/source/blender/nodes/NOD_shader.h +++ b/source/blender/nodes/NOD_shader.h @@ -88,6 +88,7 @@ void register_node_type_sh_bsdf_glass(struct bNodeTreeType *ttype); void register_node_type_sh_bsdf_translucent(struct bNodeTreeType *ttype); void register_node_type_sh_bsdf_transparent(struct bNodeTreeType *ttype); void register_node_type_sh_bsdf_velvet(struct bNodeTreeType *ttype); +void register_node_type_sh_bsdf_anisotropic(struct bNodeTreeType *ttype); void register_node_type_sh_emission(struct bNodeTreeType *ttype); void register_node_type_sh_holdout(struct bNodeTreeType *ttype); void register_node_type_sh_volume_transparent(struct bNodeTreeType *ttype); diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.c index 9157728b546..2b368420a76 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.c +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.c @@ -51,7 +51,7 @@ void register_node_type_sh_bsdf_anisotropic(bNodeTreeType *ttype) { static bNodeType ntype; - node_type_base(ttype, &ntype, SH_NODE_BSDF_ANISOTROPIC, "Glossy Anisotropic BSDF", NODE_CLASS_SHADER, 0); + node_type_base(ttype, &ntype, SH_NODE_BSDF_ANISOTROPIC, "Anisotropic BSDF", NODE_CLASS_SHADER, 0); node_type_compatibility(&ntype, NODE_NEW_SHADING); node_type_socket_templates(&ntype, sh_node_bsdf_anisotropic_in, sh_node_bsdf_anisotropic_out); node_type_size(&ntype, 150, 60, 200); From cb634b910010c04543cb3361f7a16a261e5b9f89 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Wed, 10 Oct 2012 13:18:07 +0000 Subject: [PATCH 172/347] Google Summer of Code project: "Smoke Simulator Improvements & Fire". Documentation & Test blend files: ------------------ http://wiki.blender.org/index.php/User:MiikaH/GSoC-2012-Smoke-Simulator-Improvements Credits: ------------------ Miika Hamalainen (MiikaH): Student / Main programmer Daniel Genrich (Genscher): Mentor / Programmer of merged patches from Smoke2 branch Google: For Google Summer of Code 2012 --- intern/smoke/CMakeLists.txt | 2 + intern/smoke/extern/smoke_API.h | 51 +- intern/smoke/intern/FLUID_3D.cpp | 396 ++- intern/smoke/intern/FLUID_3D.h | 46 +- intern/smoke/intern/FLUID_3D_SOLVERS.cpp | 1 - intern/smoke/intern/FLUID_3D_STATIC.cpp | 28 - intern/smoke/intern/WTURBULENCE.cpp | 151 +- intern/smoke/intern/WTURBULENCE.h | 19 +- intern/smoke/intern/smoke_API.cpp | 406 ++- intern/smoke/intern/spectrum.cpp | 411 +++ intern/smoke/intern/spectrum.h | 6 + release/datafiles/blender_icons.png | Bin 227018 -> 209196 bytes .../bl_operators/object_quick_effects.py | 63 +- .../startup/bl_ui/properties_particle.py | 2 +- .../startup/bl_ui/properties_physics_cloth.py | 2 +- .../bl_ui/properties_physics_common.py | 4 +- .../bl_ui/properties_physics_dynamicpaint.py | 2 +- .../startup/bl_ui/properties_physics_field.py | 8 + .../startup/bl_ui/properties_physics_smoke.py | 177 +- .../bl_ui/properties_physics_softbody.py | 2 +- .../startup/bl_ui/properties_texture.py | 4 + source/blender/blenkernel/BKE_smoke.h | 6 +- source/blender/blenkernel/intern/depsgraph.c | 17 +- source/blender/blenkernel/intern/effect.c | 21 +- source/blender/blenkernel/intern/pointcache.c | 160 +- source/blender/blenkernel/intern/smoke.c | 2860 ++++++++++------- source/blender/blenkernel/intern/texture.c | 2 +- source/blender/blenlib/BLI_math_vector.h | 1 + source/blender/blenlib/BLI_utildefines.h | 5 + .../blenlib/intern/math_vector_inline.c | 7 + source/blender/blenloader/intern/readfile.c | 51 +- source/blender/editors/include/UI_icons.h | 2 +- source/blender/editors/object/object_add.c | 3 +- .../blender/editors/space_view3d/drawobject.c | 118 +- .../blender/editors/space_view3d/drawvolume.c | 263 +- .../editors/space_view3d/view3d_intern.h | 11 +- source/blender/gpu/GPU_extensions.h | 2 +- source/blender/gpu/intern/gpu_draw.c | 42 +- source/blender/gpu/intern/gpu_extensions.c | 14 +- source/blender/makesdna/DNA_object_force.h | 7 +- source/blender/makesdna/DNA_smoke_types.h | 111 +- source/blender/makesdna/DNA_texture_types.h | 9 + source/blender/makesrna/intern/rna_material.c | 6 + source/blender/makesrna/intern/rna_modifier.c | 25 - .../makesrna/intern/rna_object_force.c | 19 + source/blender/makesrna/intern/rna_smoke.c | 250 +- source/blender/makesrna/intern/rna_texture.c | 3 +- source/blender/modifiers/intern/MOD_smoke.c | 59 +- .../render/intern/source/render_texture.c | 20 + .../blender/render/intern/source/voxeldata.c | 167 +- 50 files changed, 4206 insertions(+), 1836 deletions(-) create mode 100644 intern/smoke/intern/spectrum.cpp create mode 100644 intern/smoke/intern/spectrum.h diff --git a/intern/smoke/CMakeLists.txt b/intern/smoke/CMakeLists.txt index 9524f7b2935..11f173a6835 100644 --- a/intern/smoke/CMakeLists.txt +++ b/intern/smoke/CMakeLists.txt @@ -40,6 +40,7 @@ set(SRC intern/FLUID_3D_SOLVERS.cpp intern/FLUID_3D_STATIC.cpp intern/LU_HELPER.cpp + intern/spectrum.cpp intern/SPHERE.cpp intern/WTURBULENCE.cpp intern/smoke_API.cpp @@ -53,6 +54,7 @@ set(SRC intern/LU_HELPER.h intern/MERSENNETWISTER.h intern/OBSTACLE.h + intern/spectrum.h intern/SPHERE.h intern/VEC3.h intern/WAVELET_NOISE.h diff --git a/intern/smoke/extern/smoke_API.h b/intern/smoke/extern/smoke_API.h index a0eb1bf38e0..98c63f08fbd 100644 --- a/intern/smoke/extern/smoke_API.h +++ b/intern/smoke/extern/smoke_API.h @@ -37,17 +37,23 @@ extern "C" { struct FLUID_3D; -// export -void smoke_export(struct FLUID_3D *fluid, float *dt, float *dx, float **dens, float **densold, float **heat, float **heatold, float **vx, float **vy, float **vz, float **vxold, float **vyold, float **vzold, unsigned char **obstacles); - // low res -struct FLUID_3D *smoke_init(int *res, float *p0, float dtdef); +struct FLUID_3D *smoke_init(int *res, float dx, float dtdef, int use_heat, int use_fire, int use_colors); void smoke_free(struct FLUID_3D *fluid); -void smoke_initBlenderRNA(struct FLUID_3D *fluid, float *alpha, float *beta, float *dt_factor, float *vorticity, int *border_colli); -void smoke_step(struct FLUID_3D *fluid, float dtSubdiv); +void smoke_initBlenderRNA(struct FLUID_3D *fluid, float *alpha, float *beta, float *dt_factor, float *vorticity, int *border_colli, float *burning_rate, + float *flame_smoke, float *flame_smoke_color, float *flame_vorticity, float *flame_ignition_temp, float *flame_max_temp); +void smoke_step(struct FLUID_3D *fluid, float gravity[3], float dtSubdiv); float *smoke_get_density(struct FLUID_3D *fluid); +float *smoke_get_flame(struct FLUID_3D *fluid); +float *smoke_get_fuel(struct FLUID_3D *fluid); +float *smoke_get_react(struct FLUID_3D *fluid); +float *smoke_get_color_r(struct FLUID_3D *fluid); +float *smoke_get_color_g(struct FLUID_3D *fluid); +float *smoke_get_color_b(struct FLUID_3D *fluid); +void smoke_get_rgba(struct FLUID_3D *fluid, float *data, int sequential); +void smoke_get_rgba_from_density(struct FLUID_3D *fluid, float color[3], float *data, int sequential); float *smoke_get_heat(struct FLUID_3D *fluid); float *smoke_get_velocity_x(struct FLUID_3D *fluid); float *smoke_get_velocity_y(struct FLUID_3D *fluid); @@ -68,19 +74,44 @@ size_t smoke_get_index2d(int x, int max_x, int y); void smoke_dissolve(struct FLUID_3D *fluid, int speed, int log); // wavelet turbulence functions -struct WTURBULENCE *smoke_turbulence_init(int *res, int amplify, int noisetype); +struct WTURBULENCE *smoke_turbulence_init(int *res, int amplify, int noisetype, int use_fire, int use_colors); void smoke_turbulence_free(struct WTURBULENCE *wt); void smoke_turbulence_step(struct WTURBULENCE *wt, struct FLUID_3D *fluid); float *smoke_turbulence_get_density(struct WTURBULENCE *wt); +float *smoke_turbulence_get_color_r(struct WTURBULENCE *wt); +float *smoke_turbulence_get_color_g(struct WTURBULENCE *wt); +float *smoke_turbulence_get_color_b(struct WTURBULENCE *wt); +void smoke_turbulence_get_rgba(struct WTURBULENCE *wt, float *data, int sequential); +void smoke_turbulence_get_rgba_from_density(struct WTURBULENCE *wt, float color[3], float *data, int sequential); +float *smoke_turbulence_get_flame(struct WTURBULENCE *wt); +float *smoke_turbulence_get_fuel(struct WTURBULENCE *wt); +float *smoke_turbulence_get_react(struct WTURBULENCE *wt); void smoke_turbulence_get_res(struct WTURBULENCE *wt, int *res); +int smoke_turbulence_get_cells(struct WTURBULENCE *wt); void smoke_turbulence_set_noise(struct WTURBULENCE *wt, int type); void smoke_initWaveletBlenderRNA(struct WTURBULENCE *wt, float *strength); - void smoke_dissolve_wavelet(struct WTURBULENCE *wt, int speed, int log); -// export -void smoke_turbulence_export(struct WTURBULENCE *wt, float **dens, float **densold, float **tcu, float **tcv, float **tcw); +/* export */ +void smoke_export(struct FLUID_3D *fluid, float *dt, float *dx, float **dens, float **react, float **flame, float **fuel, float **heat, float **heatold, + float **vx, float **vy, float **vz, float **r, float **g, float **b, unsigned char **obstacles); +void smoke_turbulence_export(struct WTURBULENCE *wt, float **dens, float **react, float **flame, float **fuel, + float **r, float **g, float **b, float **tcu, float **tcv, float **tcw); + +/* flame spectrum */ +void flame_get_spectrum(unsigned char *spec, int width, float t1, float t2); + +/* data fields */ +int smoke_has_heat(struct FLUID_3D *fluid); +int smoke_has_fuel(struct FLUID_3D *fluid); +int smoke_has_colors(struct FLUID_3D *fluid); +int smoke_turbulence_has_fuel(struct WTURBULENCE *wt); +int smoke_turbulence_has_colors(struct WTURBULENCE *wt); + +void smoke_ensure_heat(struct FLUID_3D *fluid); +void smoke_ensure_fire(struct FLUID_3D *fluid, struct WTURBULENCE *wt); +void smoke_ensure_colors(struct FLUID_3D *fluid, struct WTURBULENCE *wt, float init_r, float init_g, float init_b); #ifdef __cplusplus } diff --git a/intern/smoke/intern/FLUID_3D.cpp b/intern/smoke/intern/FLUID_3D.cpp index e006132ea8f..b7b353352e2 100644 --- a/intern/smoke/intern/FLUID_3D.cpp +++ b/intern/smoke/intern/FLUID_3D.cpp @@ -44,16 +44,11 @@ // Construction/Destruction ////////////////////////////////////////////////////////////////////// -FLUID_3D::FLUID_3D(int *res, float *p0, float dtdef) : +FLUID_3D::FLUID_3D(int *res, float dx, float dtdef, int init_heat, int init_fire, int init_colors) : _xRes(res[0]), _yRes(res[1]), _zRes(res[2]), _res(0.0f) { // set simulation consts _dt = dtdef; // just in case. set in step from a RNA factor - - // start point of array - _p0[0] = p0[0]; - _p0[1] = p0[1]; - _p0[2] = p0[2]; _iterations = 100; _tempAmb = 0; @@ -72,7 +67,10 @@ FLUID_3D::FLUID_3D(int *res, float *p0, float dtdef) : */ // scale the constants according to the refinement of the grid - _dx = 1.0f / (float)_maxRes; + if (!dx) + _dx = 1.0f / (float)_maxRes; + else + _dx = dx; _constantScaling = 64.0f / _maxRes; _constantScaling = (_constantScaling < 1.0f) ? 1.0f : _constantScaling; _vorticityEps = 2.0f / _constantScaling; // Just in case set a default value @@ -94,8 +92,6 @@ FLUID_3D::FLUID_3D(int *res, float *p0, float dtdef) : _zForce = new float[_totalCells]; _density = new float[_totalCells]; _densityOld = new float[_totalCells]; - _heat = new float[_totalCells]; - _heatOld = new float[_totalCells]; _obstacles = new unsigned char[_totalCells]; // set 0 at end of step // For threaded version: @@ -103,7 +99,6 @@ FLUID_3D::FLUID_3D(int *res, float *p0, float dtdef) : _yVelocityTemp = new float[_totalCells]; _zVelocityTemp = new float[_totalCells]; _densityTemp = new float[_totalCells]; - _heatTemp = new float[_totalCells]; // DG TODO: check if alloc went fine @@ -111,8 +106,6 @@ FLUID_3D::FLUID_3D(int *res, float *p0, float dtdef) : { _density[x] = 0.0f; _densityOld[x] = 0.0f; - _heat[x] = 0.0f; - _heatOld[x] = 0.0f; _xVelocity[x] = 0.0f; _yVelocity[x] = 0.0f; _zVelocity[x] = 0.0f; @@ -128,6 +121,25 @@ FLUID_3D::FLUID_3D(int *res, float *p0, float dtdef) : _obstacles[x] = false; } + /* heat */ + _heat = _heatOld = _heatTemp = NULL; + if (init_heat) { + initHeat(); + } + // Fire simulation + _flame = _fuel = _fuelTemp = _fuelOld = NULL; + _react = _reactTemp = _reactOld = NULL; + if (init_fire) { + initFire(); + } + // Smoke color + _color_r = _color_rOld = _color_rTemp = NULL; + _color_g = _color_gOld = _color_gTemp = NULL; + _color_b = _color_bOld = _color_bTemp = NULL; + if (init_colors) { + initColors(0.0f, 0.0f, 0.0f); + } + // boundary conditions of the fluid domain // set default values -> vertically non-colliding _domainBcFront = true; @@ -138,9 +150,70 @@ FLUID_3D::FLUID_3D(int *res, float *p0, float dtdef) : _domainBcRight = _domainBcLeft; _colloPrev = 1; // default value +} - setBorderObstacles(); // walls +void FLUID_3D::initHeat() +{ + if (!_heat) { + _heat = new float[_totalCells]; + _heatOld = new float[_totalCells]; + _heatTemp = new float[_totalCells]; + for (int x = 0; x < _totalCells; x++) + { + _heat[x] = 0.0f; + _heatOld[x] = 0.0f; + } + } +} + +void FLUID_3D::initFire() +{ + if (!_flame) { + _flame = new float[_totalCells]; + _fuel = new float[_totalCells]; + _fuelTemp = new float[_totalCells]; + _fuelOld = new float[_totalCells]; + _react = new float[_totalCells]; + _reactTemp = new float[_totalCells]; + _reactOld = new float[_totalCells]; + + for (int x = 0; x < _totalCells; x++) + { + _flame[x] = 0.0f; + _fuel[x] = 0.0f; + _fuelTemp[x] = 0.0f; + _fuelOld[x] = 0.0f; + _react[x] = 0.0f; + _reactTemp[x] = 0.0f; + _reactOld[x] = 0.0f; + } + } +} + +void FLUID_3D::initColors(float init_r, float init_g, float init_b) +{ + if (!_color_r) { + _color_r = new float[_totalCells]; + _color_rOld = new float[_totalCells]; + _color_rTemp = new float[_totalCells]; + _color_g = new float[_totalCells]; + _color_gOld = new float[_totalCells]; + _color_gTemp = new float[_totalCells]; + _color_b = new float[_totalCells]; + _color_bOld = new float[_totalCells]; + _color_bTemp = new float[_totalCells]; + + for (int x = 0; x < _totalCells; x++) + { + _color_r[x] = _density[x] * init_r; + _color_rOld[x] = 0.0f; + _color_g[x] = _density[x] * init_g; + _color_gOld[x] = 0.0f; + _color_b[x] = _density[x] * init_b; + _color_bOld[x] = 0.0f; + } + } } void FLUID_3D::setBorderObstacles() @@ -204,7 +277,6 @@ FLUID_3D::~FLUID_3D() if (_heat) delete[] _heat; if (_heatOld) delete[] _heatOld; if (_obstacles) delete[] _obstacles; - // if (_wTurbulence) delete _wTurbulence; if (_xVelocityTemp) delete[] _xVelocityTemp; if (_yVelocityTemp) delete[] _yVelocityTemp; @@ -212,23 +284,48 @@ FLUID_3D::~FLUID_3D() if (_densityTemp) delete[] _densityTemp; if (_heatTemp) delete[] _heatTemp; + if (_flame) delete[] _flame; + if (_fuel) delete[] _fuel; + if (_fuelTemp) delete[] _fuelTemp; + if (_fuelOld) delete[] _fuelOld; + if (_react) delete[] _react; + if (_reactTemp) delete[] _reactTemp; + if (_reactOld) delete[] _reactOld; + + if (_color_r) delete[] _color_r; + if (_color_rOld) delete[] _color_rOld; + if (_color_rTemp) delete[] _color_rTemp; + if (_color_g) delete[] _color_g; + if (_color_gOld) delete[] _color_gOld; + if (_color_gTemp) delete[] _color_gTemp; + if (_color_b) delete[] _color_b; + if (_color_bOld) delete[] _color_bOld; + if (_color_bTemp) delete[] _color_bTemp; + // printf("deleted fluid\n"); } // init direct access functions from blender -void FLUID_3D::initBlenderRNA(float *alpha, float *beta, float *dt_factor, float *vorticity, int *borderCollision) +void FLUID_3D::initBlenderRNA(float *alpha, float *beta, float *dt_factor, float *vorticity, int *borderCollision, float *burning_rate, + float *flame_smoke, float *flame_smoke_color, float *flame_vorticity, float *flame_ignition_temp, float *flame_max_temp) { _alpha = alpha; _beta = beta; _dtFactor = dt_factor; _vorticityRNA = vorticity; _borderColli = borderCollision; + _burning_rate = burning_rate; + _flame_smoke = flame_smoke; + _flame_smoke_color = flame_smoke_color; + _flame_vorticity = flame_vorticity; + _ignition_temp = flame_ignition_temp; + _max_temp = flame_max_temp; } ////////////////////////////////////////////////////////////////////// // step simulation once ////////////////////////////////////////////////////////////////////// -void FLUID_3D::step(float dt) +void FLUID_3D::step(float dt, float gravity[3]) { #if 0 // If border rules have been changed @@ -281,7 +378,7 @@ void FLUID_3D::step(float dt) wipeBoundariesSL(zBegin, zEnd); addVorticity(zBegin, zEnd); - addBuoyancy(_heat, _density, zBegin, zEnd); + addBuoyancy(_heat, _density, gravity, zBegin, zEnd); addForce(zBegin, zEnd); #if PARALLEL==1 @@ -312,13 +409,15 @@ void FLUID_3D::step(float dt) if (i==0) { #endif - project(); + project(); #if PARALLEL==1 } - else + else if (i==1) { #endif - diffuseHeat(); + if (_heat) { + diffuseHeat(); + } #if PARALLEL==1 } } @@ -338,6 +437,13 @@ void FLUID_3D::step(float dt) SWAP_POINTERS(_density, _densityOld); SWAP_POINTERS(_heat, _heatOld); + SWAP_POINTERS(_fuel, _fuelOld); + SWAP_POINTERS(_react, _reactOld); + + SWAP_POINTERS(_color_r, _color_rOld); + SWAP_POINTERS(_color_g, _color_gOld); + SWAP_POINTERS(_color_b, _color_bOld); + advectMacCormackBegin(0, _zRes); #if PARALLEL==1 @@ -398,11 +504,8 @@ void FLUID_3D::step(float dt) SWAP_POINTERS(_yVelocity, _yForce); SWAP_POINTERS(_zVelocity, _zForce); - - - _totalTime += _dt; - _totalSteps++; + _totalSteps++; for (int i = 0; i < _totalCells; i++) { @@ -643,6 +746,15 @@ void FLUID_3D::wipeBoundaries(int zBegin, int zEnd) setZeroBorder(_yVelocity, _res, zBegin, zEnd); setZeroBorder(_zVelocity, _res, zBegin, zEnd); setZeroBorder(_density, _res, zBegin, zEnd); + if (_fuel) { + setZeroBorder(_fuel, _res, zBegin, zEnd); + setZeroBorder(_react, _res, zBegin, zEnd); + } + if (_color_r) { + setZeroBorder(_color_r, _res, zBegin, zEnd); + setZeroBorder(_color_g, _res, zBegin, zEnd); + setZeroBorder(_color_b, _res, zBegin, zEnd); + } } void FLUID_3D::wipeBoundariesSL(int zBegin, int zEnd) @@ -668,6 +780,15 @@ void FLUID_3D::wipeBoundariesSL(int zBegin, int zEnd) _yVelocity[index] = 0.0f; _zVelocity[index] = 0.0f; _density[index] = 0.0f; + if (_fuel) { + _fuel[index] = 0.0f; + _react[index] = 0.0f; + } + if (_color_r) { + _color_r[index] = 0.0f; + _color_g[index] = 0.0f; + _color_b[index] = 0.0f; + } // right slab index += _xRes - 1; @@ -675,6 +796,15 @@ void FLUID_3D::wipeBoundariesSL(int zBegin, int zEnd) _yVelocity[index] = 0.0f; _zVelocity[index] = 0.0f; _density[index] = 0.0f; + if (_fuel) { + _fuel[index] = 0.0f; + _react[index] = 0.0f; + } + if (_color_r) { + _color_r[index] = 0.0f; + _color_g[index] = 0.0f; + _color_b[index] = 0.0f; + } } ///////////////////////////////////// @@ -690,6 +820,15 @@ void FLUID_3D::wipeBoundariesSL(int zBegin, int zEnd) _yVelocity[index] = 0.0f; _zVelocity[index] = 0.0f; _density[index] = 0.0f; + if (_fuel) { + _fuel[index] = 0.0f; + _react[index] = 0.0f; + } + if (_color_r) { + _color_r[index] = 0.0f; + _color_g[index] = 0.0f; + _color_b[index] = 0.0f; + } // top slab index += slabSize - _xRes; @@ -697,6 +836,15 @@ void FLUID_3D::wipeBoundariesSL(int zBegin, int zEnd) _yVelocity[index] = 0.0f; _zVelocity[index] = 0.0f; _density[index] = 0.0f; + if (_fuel) { + _fuel[index] = 0.0f; + _react[index] = 0.0f; + } + if (_color_r) { + _color_r[index] = 0.0f; + _color_g[index] = 0.0f; + _color_b[index] = 0.0f; + } } @@ -717,6 +865,15 @@ void FLUID_3D::wipeBoundariesSL(int zBegin, int zEnd) _yVelocity[index] = 0.0f; _zVelocity[index] = 0.0f; _density[index] = 0.0f; + if (_fuel) { + _fuel[index] = 0.0f; + _react[index] = 0.0f; + } + if (_color_r) { + _color_r[index] = 0.0f; + _color_g[index] = 0.0f; + _color_b[index] = 0.0f; + } } if (zEnd == _zRes) @@ -735,6 +892,15 @@ void FLUID_3D::wipeBoundariesSL(int zBegin, int zEnd) _yVelocity[indexx] = 0.0f; _zVelocity[indexx] = 0.0f; _density[indexx] = 0.0f; + if (_fuel) { + _fuel[index] = 0.0f; + _react[index] = 0.0f; + } + if (_color_r) { + _color_r[index] = 0.0f; + _color_g[index] = 0.0f; + _color_b[index] = 0.0f; + } } } @@ -781,35 +947,6 @@ void FLUID_3D::project() if(!_domainBcTop) setNeumannZ(_zVelocity, _res, 0, _zRes); else setZeroZ(_zVelocity, _res, 0, _zRes); - /* - { - float maxx = 0, maxy = 0, maxz = 0; - for(unsigned int i = 0; i < _xRes * _yRes * _zRes; i++) - { - if(_xVelocity[i] > maxx) - maxx = _xVelocity[i]; - if(_yVelocity[i] > maxy) - maxy = _yVelocity[i]; - if(_zVelocity[i] > maxz) - maxz = _zVelocity[i]; - } - printf("Max velx: %f, vely: %f, velz: %f\n", maxx, maxy, maxz); - } - */ - - /* - { - float maxvalue = 0; - for(unsigned int i = 0; i < _xRes * _yRes * _zRes; i++) - { - if(_heat[i] > maxvalue) - maxvalue = _heat[i]; - - } - printf("Max heat: %f\n", maxvalue); - } - */ - // calculate divergence index = _slabSize + _xRes + 1; for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes) @@ -1007,7 +1144,6 @@ void FLUID_3D::diffuseHeat() for (int x = 0; x < _totalCells; x++) if (_obstacles[x]) _heat[x] = 0.0f; - } ////////////////////////////////////////////////////////////////////// @@ -1175,7 +1311,7 @@ void FLUID_3D::setObstacleBoundaries(float *_pressure, int zBegin, int zEnd) ////////////////////////////////////////////////////////////////////// // add buoyancy forces ////////////////////////////////////////////////////////////////////// -void FLUID_3D::addBuoyancy(float *heat, float *density, int zBegin, int zEnd) +void FLUID_3D::addBuoyancy(float *heat, float *density, float gravity[3], int zBegin, int zEnd) { int index = zBegin*_slabSize; @@ -1183,7 +1319,10 @@ void FLUID_3D::addBuoyancy(float *heat, float *density, int zBegin, int zEnd) for (int y = 0; y < _yRes; y++) for (int x = 0; x < _xRes; x++, index++) { - _zForce[index] += *_alpha * density[index] + (*_beta * (heat[index] - _tempAmb)); // DG: was _yForce, changed for Blender + float buoyancy = *_alpha * density[index] + (*_beta * (((heat) ? heat[index] : 0.0f) - _tempAmb)); + _xForce[index] -= gravity[0] * buoyancy; + _yForce[index] -= gravity[1] * buoyancy; + _zForce[index] -= gravity[2] * buoyancy; } } @@ -1192,8 +1331,10 @@ void FLUID_3D::addBuoyancy(float *heat, float *density, int zBegin, int zEnd) ////////////////////////////////////////////////////////////////////// void FLUID_3D::addVorticity(int zBegin, int zEnd) { + // set flame vorticity from RNA value + float flame_vorticity = (*_flame_vorticity)/_constantScaling; //int x,y,z,index; - if(_vorticityEps<=0.) return; + if(_vorticityEps+flame_vorticity<=0.) return; int _blockSize=zEnd-zBegin; int _blockTotalCells = _slabSize * (_blockSize+2); @@ -1300,14 +1441,15 @@ void FLUID_3D::addVorticity(int zBegin, int zEnd) float magnitude = sqrtf(N[0] * N[0] + N[1] * N[1] + N[2] * N[2]); if (magnitude > FLT_EPSILON) { + float flame_vort = (_fuel) ? _fuel[index]*flame_vorticity : 0.0f; magnitude = 1.0f / magnitude; N[0] *= magnitude; N[1] *= magnitude; N[2] *= magnitude; - _xForce[index] += (N[1] * _zVorticity[vIndex] - N[2] * _yVorticity[vIndex]) * _dx * eps; - _yForce[index] += (N[2] * _xVorticity[vIndex] - N[0] * _zVorticity[vIndex]) * _dx * eps; - _zForce[index] += (N[0] * _yVorticity[vIndex] - N[1] * _xVorticity[vIndex]) * _dx * eps; + _xForce[index] += (N[1] * _zVorticity[vIndex] - N[2] * _yVorticity[vIndex]) * _dx * (eps + flame_vort); + _yForce[index] += (N[2] * _xVorticity[vIndex] - N[0] * _zVorticity[vIndex]) * _dx * (eps + flame_vort); + _zForce[index] += (N[0] * _yVorticity[vIndex] - N[1] * _xVorticity[vIndex]) * _dx * (eps + flame_vort); } } // if vIndex++; @@ -1328,14 +1470,9 @@ void FLUID_3D::advectMacCormackBegin(int zBegin, int zEnd) { Vec3Int res = Vec3Int(_xRes,_yRes,_zRes); - if(!_domainBcLeft) copyBorderX(_xVelocityOld, res, zBegin, zEnd); - else setZeroX(_xVelocityOld, res, zBegin, zEnd); - - if(!_domainBcFront) copyBorderY(_yVelocityOld, res, zBegin, zEnd); - else setZeroY(_yVelocityOld, res, zBegin, zEnd); - - if(!_domainBcTop) copyBorderZ(_zVelocityOld, res, zBegin, zEnd); - else setZeroZ(_zVelocityOld, res, zBegin, zEnd); + setZeroX(_xVelocityOld, res, zBegin, zEnd); + setZeroY(_yVelocityOld, res, zBegin, zEnd); + setZeroZ(_zVelocityOld, res, zBegin, zEnd); } ////////////////////////////////////////////////////////////////////// @@ -1355,7 +1492,18 @@ void FLUID_3D::advectMacCormackEnd1(int zBegin, int zEnd) // advectFieldMacCormack1(dt, xVelocity, yVelocity, zVelocity, oldField, newField, res) advectFieldMacCormack1(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _densityOld, _densityTemp, res, zBegin, zEnd); - advectFieldMacCormack1(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _heatOld, _heatTemp, res, zBegin, zEnd); + if (_heat) { + advectFieldMacCormack1(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _heatOld, _heatTemp, res, zBegin, zEnd); + } + if (_fuel) { + advectFieldMacCormack1(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _fuelOld, _fuelTemp, res, zBegin, zEnd); + advectFieldMacCormack1(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _reactOld, _reactTemp, res, zBegin, zEnd); + } + if (_color_r) { + advectFieldMacCormack1(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _color_rOld, _color_rTemp, res, zBegin, zEnd); + advectFieldMacCormack1(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _color_gOld, _color_gTemp, res, zBegin, zEnd); + advectFieldMacCormack1(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _color_bOld, _color_bTemp, res, zBegin, zEnd); + } advectFieldMacCormack1(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _xVelocityOld, _xVelocity, res, zBegin, zEnd); advectFieldMacCormack1(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _yVelocityOld, _yVelocity, res, zBegin, zEnd); advectFieldMacCormack1(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _zVelocityOld, _zVelocity, res, zBegin, zEnd); @@ -1371,17 +1519,30 @@ void FLUID_3D::advectMacCormackEnd2(int zBegin, int zEnd) const float dt0 = _dt / _dx; Vec3Int res = Vec3Int(_xRes,_yRes,_zRes); - // use force array as temp arrays + // use force array as temp array float* t1 = _xForce; // advectFieldMacCormack2(dt, xVelocity, yVelocity, zVelocity, oldField, newField, tempfield, temp, res, obstacles) + /* finish advection */ advectFieldMacCormack2(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _densityOld, _density, _densityTemp, t1, res, _obstacles, zBegin, zEnd); - advectFieldMacCormack2(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _heatOld, _heat, _heatTemp, t1, res, _obstacles, zBegin, zEnd); + if (_heat) { + advectFieldMacCormack2(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _heatOld, _heat, _heatTemp, t1, res, _obstacles, zBegin, zEnd); + } + if (_fuel) { + advectFieldMacCormack2(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _fuelOld, _fuel, _fuelTemp, t1, res, _obstacles, zBegin, zEnd); + advectFieldMacCormack2(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _reactOld, _react, _reactTemp, t1, res, _obstacles, zBegin, zEnd); + } + if (_color_r) { + advectFieldMacCormack2(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _color_rOld, _color_r, _color_rTemp, t1, res, _obstacles, zBegin, zEnd); + advectFieldMacCormack2(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _color_gOld, _color_g, _color_gTemp, t1, res, _obstacles, zBegin, zEnd); + advectFieldMacCormack2(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _color_bOld, _color_b, _color_bTemp, t1, res, _obstacles, zBegin, zEnd); + } advectFieldMacCormack2(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _xVelocityOld, _xVelocityTemp, _xVelocity, t1, res, _obstacles, zBegin, zEnd); advectFieldMacCormack2(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _yVelocityOld, _yVelocityTemp, _yVelocity, t1, res, _obstacles, zBegin, zEnd); advectFieldMacCormack2(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _zVelocityOld, _zVelocityTemp, _zVelocity, t1, res, _obstacles, zBegin, zEnd); + /* set boundary conditions for velocity */ if(!_domainBcLeft) copyBorderX(_xVelocityTemp, res, zBegin, zEnd); else setZeroX(_xVelocityTemp, res, zBegin, zEnd); @@ -1391,40 +1552,71 @@ void FLUID_3D::advectMacCormackEnd2(int zBegin, int zEnd) if(!_domainBcTop) copyBorderZ(_zVelocityTemp, res, zBegin, zEnd); else setZeroZ(_zVelocityTemp, res, zBegin, zEnd); + /* clear data boundaries */ setZeroBorder(_density, res, zBegin, zEnd); - setZeroBorder(_heat, res, zBegin, zEnd); -#if 0 - { - const size_t index_ = _slabSize + _xRes + 1; - int bb=0; - int bt=0; + if (_fuel) { + setZeroBorder(_fuel, res, zBegin, zEnd); + setZeroBorder(_react, res, zBegin, zEnd); + } + if (_color_r) { + setZeroBorder(_color_r, res, zBegin, zEnd); + setZeroBorder(_color_g, res, zBegin, zEnd); + setZeroBorder(_color_b, res, zBegin, zEnd); + } +} - if (zBegin == 0) {bb = 1;} - if (zEnd == _zRes) {bt = 1;} - - for (int z = zBegin + bb; z < zEnd - bt; z++) - { - size_t index = index_ +(z-1)*_slabSize; - for (int y = 1; y < _yRes - 1; y++, index += 2) - { - for (int x = 1; x < _xRes - 1; x++, index++) - { - // clean custom velocities from moving obstacles again - if (_obstacles[index]) - { - _xVelocity[index] = - _yVelocity[index] = - _zVelocity[index] = 0.0f; - } - } +void FLUID_3D::processBurn(float *fuel, float *smoke, float *react, float *flame, float *heat, + float *r, float *g, float *b, int total_cells, float dt) +{ + float burning_rate = *_burning_rate; + float flame_smoke = *_flame_smoke; + float ignition_point = *_ignition_temp; + float temp_max = *_max_temp; + + for (int index = 0; index < total_cells; index++) + { + float orig_fuel = fuel[index]; + float orig_smoke = smoke[index]; + float smoke_emit = 0.0f; + float react_coord = 0.0f; + + /* process fuel */ + fuel[index] -= burning_rate * dt; + if (fuel[index] < 0.0f) fuel[index] = 0.0f; + /* process reaction coordinate */ + if (orig_fuel) { + react[index] *= fuel[index]/orig_fuel; + react_coord = react[index]; + } + else { + react[index] = 0.0f; + } + + /* emit smoke based on fuel burn rate and "flame_smoke" factor */ + smoke_emit = (orig_fuel < 1.0f) ? (1.0f - orig_fuel)*0.5f : 0.0f; + smoke_emit = (smoke_emit + 0.5f) * (orig_fuel-fuel[index]) * 0.1f * flame_smoke; + smoke[index] += smoke_emit; + CLAMP(smoke[index], 0.0f, 1.0f); + + /* model flame temperature curve from the reaction coordinate (fuel) */ + if (react_coord>0.0f) { + /* do a smooth falloff for rest of the values */ + flame[index] = pow(react_coord, 0.5f); + } + else + flame[index] = 0.0f; + + /* set fluid temperature from the flame temperature profile */ + if (heat && flame[index]) + heat[index] = (1.0f-flame[index])*ignition_point + flame[index]*temp_max; + + /* mix new color */ + if (r && smoke_emit) { + float smoke_factor = smoke[index]/(orig_smoke+smoke_emit); + r[index] = (r[index] + _flame_smoke_color[0] * smoke_emit) * smoke_factor; + g[index] = (g[index] + _flame_smoke_color[1] * smoke_emit) * smoke_factor; + b[index] = (b[index] + _flame_smoke_color[2] * smoke_emit) * smoke_factor; } } - } -#endif - - /*int begin=zBegin * _slabSize; - int end=begin + (zEnd - zBegin) * _slabSize; - for (int x = begin; x < end; x++) - _xForce[x] = _yForce[x] = 0.0f;*/ } diff --git a/intern/smoke/intern/FLUID_3D.h b/intern/smoke/intern/FLUID_3D.h index ac77148ce84..8cadf3bc989 100644 --- a/intern/smoke/intern/FLUID_3D.h +++ b/intern/smoke/intern/FLUID_3D.h @@ -46,11 +46,16 @@ class WTURBULENCE; class FLUID_3D { public: - FLUID_3D(int *res, /* int amplify, */ float *p0, float dtdef); + FLUID_3D(int *res, float dx, float dtdef, int init_heat, int init_fire, int init_colors); FLUID_3D() {}; virtual ~FLUID_3D(); - void initBlenderRNA(float *alpha, float *beta, float *dt_factor, float *vorticity, int *border_colli); + void initHeat(); + void initFire(); + void initColors(float init_r, float init_g, float init_b); + + void initBlenderRNA(float *alpha, float *beta, float *dt_factor, float *vorticity, int *border_colli, float *burning_rate, + float *flame_smoke, float *flame_smoke_color, float *flame_vorticity, float *ignition_temp, float *max_temp); // create & allocate vector noise advection void initVectorNoise(int amplify); @@ -58,7 +63,7 @@ class FLUID_3D void addSmokeColumn(); static void addSmokeTestCase(float* field, Vec3Int res); - void step(float dt); + void step(float dt, float gravity[3]); void addObstacle(OBSTACLE* obstacle); const float* xVelocity() { return _xVelocity; }; @@ -115,6 +120,27 @@ class FLUID_3D float* _heatTemp; float* _densityTemp; + // fire simulation + float *_flame; + float *_fuel; + float *_fuelTemp; + float *_fuelOld; + float *_react; + float *_reactTemp; + float *_reactOld; + + // smoke color + float *_color_r; + float *_color_rOld; + float *_color_rTemp; + float *_color_g; + float *_color_gOld; + float *_color_gTemp; + float *_color_b; + float *_color_bOld; + float *_color_bTemp; + + // CG fields int _iterations; @@ -153,14 +179,16 @@ class FLUID_3D void wipeBoundariesSL(int zBegin, int zEnd); void addForce(int zBegin, int zEnd); void addVorticity(int zBegin, int zEnd); - void addBuoyancy(float *heat, float *density, int zBegin, int zEnd); + void addBuoyancy(float *heat, float *density, float gravity[3], int zBegin, int zEnd); // solver stuff void project(); void diffuseHeat(); + void diffuseColor(); void solvePressure(float* field, float* b, unsigned char* skip); void solvePressurePre(float* field, float* b, unsigned char* skip); void solveHeat(float* field, float* b, unsigned char* skip); + void solveDiffusion(float* field, float* b, float* factor); // handle obstacle boundaries @@ -174,6 +202,16 @@ class FLUID_3D void advectMacCormackEnd1(int zBegin, int zEnd); void advectMacCormackEnd2(int zBegin, int zEnd); + /* burning */ + float *_burning_rate; // RNA pointer + float *_flame_smoke; // RNA pointer + float *_flame_smoke_color; // RNA pointer + float *_flame_vorticity; // RNA pointer + float *_ignition_temp; // RNA pointer + float *_max_temp; // RNA pointer + void processBurn(float *fuel, float *smoke, float *react, float *flame, float *heat, + float *r, float *g, float *b, int total_cells, float dt); + // boundary setting functions static void copyBorderX(float* field, Vec3Int res, int zBegin, int zEnd); static void copyBorderY(float* field, Vec3Int res, int zBegin, int zEnd); diff --git a/intern/smoke/intern/FLUID_3D_SOLVERS.cpp b/intern/smoke/intern/FLUID_3D_SOLVERS.cpp index 3cf94eb00a9..42a8b2d6923 100644 --- a/intern/smoke/intern/FLUID_3D_SOLVERS.cpp +++ b/intern/smoke/intern/FLUID_3D_SOLVERS.cpp @@ -165,7 +165,6 @@ void FLUID_3D::solveHeat(float* field, float* b, unsigned char* skip) if (_Acenter) delete[] _Acenter; } - void FLUID_3D::solvePressurePre(float* field, float* b, unsigned char* skip) { int x, y, z; diff --git a/intern/smoke/intern/FLUID_3D_STATIC.cpp b/intern/smoke/intern/FLUID_3D_STATIC.cpp index c7a0ddcd04c..ac485ad983a 100644 --- a/intern/smoke/intern/FLUID_3D_STATIC.cpp +++ b/intern/smoke/intern/FLUID_3D_STATIC.cpp @@ -92,18 +92,10 @@ void FLUID_3D::setNeumannX(float* field, Vec3Int res, int zBegin, int zEnd) // left slab index = y * res[0] + z * slabSize; field[index] = field[index + 2]; - /* only allow outwards flux */ - if(field[index]>0.) field[index] = 0.; - index += 1; - if(field[index]>0.) field[index] = 0.; // right slab index = y * res[0] + z * slabSize + res[0] - 1; field[index] = field[index - 2]; - /* only allow outwards flux */ - if(field[index]<0.) field[index] = 0.; - index -= 1; - if(field[index]<0.) field[index] = 0.; } } @@ -120,18 +112,10 @@ void FLUID_3D::setNeumannY(float* field, Vec3Int res, int zBegin, int zEnd) // front slab index = x + z * slabSize; field[index] = field[index + 2 * res[0]]; - /* only allow outwards flux */ - if(field[index]>0.) field[index] = 0.; - index += res[0]; - if(field[index]>0.) field[index] = 0.; // back slab index = x + z * slabSize + slabSize - res[0]; field[index] = field[index - 2 * res[0]]; - /* only allow outwards flux */ - if(field[index]<0.) field[index] = 0.; - index -= res[0]; - if(field[index]<0.) field[index] = 0.; } } @@ -152,14 +136,6 @@ void FLUID_3D::setNeumannZ(float* field, Vec3Int res, int zBegin, int zEnd) // front slab index = x + y * res[0]; field[index] = field[index + 2 * slabSize]; - /* only allow outwards flux */ - - // DG: Disable this for z-axis. - // The problem is that smoke somehow gets sucked in again - // from the TOP slab when this is enabled - // if(field[index]>0.) field[index] = 0.; - // index += slabSize; - // if(field[index]>0.) field[index] = 0.; } } @@ -170,10 +146,6 @@ void FLUID_3D::setNeumannZ(float* field, Vec3Int res, int zBegin, int zEnd) // back slab index = x + y * res[0] + cellsslab; field[index] = field[index - 2 * slabSize]; - /* only allow outwards flux */ - if(field[index]<0.) field[index] = 0.; - index -= slabSize; - if(field[index]<0.) field[index] = 0.; } } diff --git a/intern/smoke/intern/WTURBULENCE.cpp b/intern/smoke/intern/WTURBULENCE.cpp index 671198065e8..1c89f5d681b 100644 --- a/intern/smoke/intern/WTURBULENCE.cpp +++ b/intern/smoke/intern/WTURBULENCE.cpp @@ -51,7 +51,7 @@ static const float persistence = 0.56123f; ////////////////////////////////////////////////////////////////////// // constructor ////////////////////////////////////////////////////////////////////// -WTURBULENCE::WTURBULENCE(int xResSm, int yResSm, int zResSm, int amplify, int noisetype) +WTURBULENCE::WTURBULENCE(int xResSm, int yResSm, int zResSm, int amplify, int noisetype, int init_fire, int init_colors) { // if noise magnitude is below this threshold, its contribution // is negilgible, so stop evaluating new octaves @@ -87,12 +87,26 @@ WTURBULENCE::WTURBULENCE(int xResSm, int yResSm, int zResSm, int amplify, int no // allocate high resolution density field _totalStepsBig = 0; _densityBig = new float[_totalCellsBig]; - _densityBigOld = new float[_totalCellsBig]; + _densityBigOld = new float[_totalCellsBig]; for(int i = 0; i < _totalCellsBig; i++) { _densityBig[i] = _densityBigOld[i] = 0.; } + + /* fire */ + _flameBig = _fuelBig = _fuelBigOld = NULL; + _reactBig = _reactBigOld = NULL; + if (init_fire) { + initFire(); + } + /* colors */ + _color_rBig = _color_rBigOld = NULL; + _color_gBig = _color_gBigOld = NULL; + _color_bBig = _color_bBigOld = NULL; + if (init_colors) { + initColors(0.0f, 0.0f, 0.0f); + } // allocate & init texture coordinates _tcU = new float[_totalCellsSm]; @@ -128,12 +142,64 @@ WTURBULENCE::WTURBULENCE(int xResSm, int yResSm, int zResSm, int amplify, int no */ } +void WTURBULENCE::initFire() +{ + if (!_fuelBig) { + _flameBig = new float[_totalCellsBig]; + _fuelBig = new float[_totalCellsBig]; + _fuelBigOld = new float[_totalCellsBig]; + _reactBig = new float[_totalCellsBig]; + _reactBigOld = new float[_totalCellsBig]; + + for(int i = 0; i < _totalCellsBig; i++) { + _flameBig[i] = + _fuelBig[i] = + _fuelBigOld[i] = 0.; + _reactBig[i] = + _reactBigOld[i] = 0.; + } + } +} + +void WTURBULENCE::initColors(float init_r, float init_g, float init_b) +{ + if (!_color_rBig) { + _color_rBig = new float[_totalCellsBig]; + _color_rBigOld = new float[_totalCellsBig]; + _color_gBig = new float[_totalCellsBig]; + _color_gBigOld = new float[_totalCellsBig]; + _color_bBig = new float[_totalCellsBig]; + _color_bBigOld = new float[_totalCellsBig]; + + for(int i = 0; i < _totalCellsBig; i++) { + _color_rBig[i] = _densityBig[i] * init_r; + _color_rBigOld[i] = 0.0f; + _color_gBig[i] = _densityBig[i] * init_g; + _color_gBigOld[i] = 0.0f; + _color_bBig[i] = _densityBig[i] * init_b; + _color_bBigOld[i] = 0.0f; + } + } +} + ////////////////////////////////////////////////////////////////////// // destructor ////////////////////////////////////////////////////////////////////// WTURBULENCE::~WTURBULENCE() { delete[] _densityBig; delete[] _densityBigOld; + if (_flameBig) delete[] _flameBig; + if (_fuelBig) delete[] _fuelBig; + if (_fuelBigOld) delete[] _fuelBigOld; + if (_reactBig) delete[] _reactBig; + if (_reactBigOld) delete[] _reactBigOld; + + if (_color_rBig) delete[] _color_rBig; + if (_color_rBigOld) delete[] _color_rBigOld; + if (_color_gBig) delete[] _color_gBig; + if (_color_gBigOld) delete[] _color_gBigOld; + if (_color_bBig) delete[] _color_bBig; + if (_color_bBigOld) delete[] _color_bBigOld; delete[] _tcU; delete[] _tcV; @@ -757,8 +823,10 @@ void WTURBULENCE::stepTurbulenceFull(float dtOrg, float* xvel, float* yvel, floa // enlarge timestep to match grid const float dt = dtOrg * _amplify; const float invAmp = 1.0f / _amplify; - float *tempBig1 = (float *)calloc(_totalCellsBig, sizeof(float)); - float *tempBig2 = (float *)calloc(_totalCellsBig, sizeof(float)); + float *tempFuelBig = NULL, *tempReactBig = NULL; + float *tempColor_rBig = NULL, *tempColor_gBig = NULL, *tempColor_bBig = NULL; + float *tempDensityBig = (float *)calloc(_totalCellsBig, sizeof(float)); + float *tempBig = (float *)calloc(_totalCellsBig, sizeof(float)); float *bigUx = (float *)calloc(_totalCellsBig, sizeof(float)); float *bigUy = (float *)calloc(_totalCellsBig, sizeof(float)); float *bigUz = (float *)calloc(_totalCellsBig, sizeof(float)); @@ -767,11 +835,21 @@ void WTURBULENCE::stepTurbulenceFull(float dtOrg, float* xvel, float* yvel, floa float *eigMin = (float *)calloc(_totalCellsSm, sizeof(float)); float *eigMax = (float *)calloc(_totalCellsSm, sizeof(float)); + if (_fuelBig) { + tempFuelBig = (float *)calloc(_totalCellsBig, sizeof(float)); + tempReactBig = (float *)calloc(_totalCellsBig, sizeof(float)); + } + if (_color_rBig) { + tempColor_rBig = (float *)calloc(_totalCellsBig, sizeof(float)); + tempColor_gBig = (float *)calloc(_totalCellsBig, sizeof(float)); + tempColor_bBig = (float *)calloc(_totalCellsBig, sizeof(float)); + } + memset(_tcTemp, 0, sizeof(float)*_totalCellsSm); // prepare textures - advectTextureCoordinates(dtOrg, xvel,yvel,zvel, tempBig1, tempBig2); + advectTextureCoordinates(dtOrg, xvel,yvel,zvel, tempDensityBig, tempBig); // do wavelet decomposition of energy computeEnergy(_energy, xvel, yvel, zvel, obstacles); @@ -972,6 +1050,11 @@ void WTURBULENCE::stepTurbulenceFull(float dtOrg, float* xvel, float* yvel, floa // prepare density for an advection SWAP_POINTERS(_densityBig, _densityBigOld); + SWAP_POINTERS(_fuelBig, _fuelBigOld); + SWAP_POINTERS(_reactBig, _reactBigOld); + SWAP_POINTERS(_color_rBig, _color_rBigOld); + SWAP_POINTERS(_color_gBig, _color_gBigOld); + SWAP_POINTERS(_color_bBig, _color_bBigOld); // based on the maximum velocity present, see if we need to substep, // but cap the maximum number of substeps to 5 @@ -1017,7 +1100,21 @@ void WTURBULENCE::stepTurbulenceFull(float dtOrg, float* xvel, float* yvel, floa int zEnd = (int)((float)(i+1)*partSize + 0.5f); #endif FLUID_3D::advectFieldMacCormack1(dtSubdiv, bigUx, bigUy, bigUz, - _densityBigOld, tempBig1, _resBig, zBegin, zEnd); + _densityBigOld, tempDensityBig, _resBig, zBegin, zEnd); + if (_fuelBig) { + FLUID_3D::advectFieldMacCormack1(dtSubdiv, bigUx, bigUy, bigUz, + _fuelBigOld, tempFuelBig, _resBig, zBegin, zEnd); + FLUID_3D::advectFieldMacCormack1(dtSubdiv, bigUx, bigUy, bigUz, + _reactBigOld, tempReactBig, _resBig, zBegin, zEnd); + } + if (_color_rBig) { + FLUID_3D::advectFieldMacCormack1(dtSubdiv, bigUx, bigUy, bigUz, + _color_rBigOld, tempColor_rBig, _resBig, zBegin, zEnd); + FLUID_3D::advectFieldMacCormack1(dtSubdiv, bigUx, bigUy, bigUz, + _color_gBigOld, tempColor_gBig, _resBig, zBegin, zEnd); + FLUID_3D::advectFieldMacCormack1(dtSubdiv, bigUx, bigUy, bigUz, + _color_bBigOld, tempColor_bBig, _resBig, zBegin, zEnd); + } #if PARALLEL==1 } @@ -1030,18 +1127,43 @@ void WTURBULENCE::stepTurbulenceFull(float dtOrg, float* xvel, float* yvel, floa int zEnd = (int)((float)(i+1)*partSize + 0.5f); #endif FLUID_3D::advectFieldMacCormack2(dtSubdiv, bigUx, bigUy, bigUz, - _densityBigOld, _densityBig, tempBig1, tempBig2, _resBig, NULL, zBegin, zEnd); + _densityBigOld, _densityBig, tempDensityBig, tempBig, _resBig, NULL, zBegin, zEnd); + if (_fuelBig) { + FLUID_3D::advectFieldMacCormack2(dtSubdiv, bigUx, bigUy, bigUz, + _fuelBigOld, _fuelBig, tempFuelBig, tempBig, _resBig, NULL, zBegin, zEnd); + FLUID_3D::advectFieldMacCormack2(dtSubdiv, bigUx, bigUy, bigUz, + _reactBigOld, _reactBig, tempReactBig, tempBig, _resBig, NULL, zBegin, zEnd); + } + if (_color_rBig) { + FLUID_3D::advectFieldMacCormack2(dtSubdiv, bigUx, bigUy, bigUz, + _color_rBigOld, _color_rBig, tempColor_rBig, tempBig, _resBig, NULL, zBegin, zEnd); + FLUID_3D::advectFieldMacCormack2(dtSubdiv, bigUx, bigUy, bigUz, + _color_gBigOld, _color_gBig, tempColor_gBig, tempBig, _resBig, NULL, zBegin, zEnd); + FLUID_3D::advectFieldMacCormack2(dtSubdiv, bigUx, bigUy, bigUz, + _color_bBigOld, _color_bBig, tempColor_bBig, tempBig, _resBig, NULL, zBegin, zEnd); + } #if PARALLEL==1 } } #endif - if (substep < totalSubsteps - 1) + if (substep < totalSubsteps - 1) { SWAP_POINTERS(_densityBig, _densityBigOld); + SWAP_POINTERS(_fuelBig, _fuelBigOld); + SWAP_POINTERS(_reactBig, _reactBigOld); + SWAP_POINTERS(_color_rBig, _color_rBigOld); + SWAP_POINTERS(_color_gBig, _color_gBigOld); + SWAP_POINTERS(_color_bBig, _color_bBigOld); + } } // substep - free(tempBig1); - free(tempBig2); + free(tempDensityBig); + if (tempFuelBig) free(tempFuelBig); + if (tempReactBig) free(tempReactBig); + if (tempColor_rBig) free(tempColor_rBig); + if (tempColor_gBig) free(tempColor_gBig); + if (tempColor_bBig) free(tempColor_bBig); + free(tempBig); free(bigUx); free(bigUy); free(bigUz); @@ -1050,6 +1172,15 @@ void WTURBULENCE::stepTurbulenceFull(float dtOrg, float* xvel, float* yvel, floa // wipe the density borders FLUID_3D::setZeroBorder(_densityBig, _resBig, 0 , _resBig[2]); + if (_fuelBig) { + FLUID_3D::setZeroBorder(_fuelBig, _resBig, 0 , _resBig[2]); + FLUID_3D::setZeroBorder(_reactBig, _resBig, 0 , _resBig[2]); + } + if (_color_rBig) { + FLUID_3D::setZeroBorder(_color_rBig, _resBig, 0 , _resBig[2]); + FLUID_3D::setZeroBorder(_color_gBig, _resBig, 0 , _resBig[2]); + FLUID_3D::setZeroBorder(_color_bBig, _resBig, 0 , _resBig[2]); + } // reset texture coordinates now in preparation for next timestep // Shouldn't do this before generating the noise because then the diff --git a/intern/smoke/intern/WTURBULENCE.h b/intern/smoke/intern/WTURBULENCE.h index f31ca100fdf..1655bd95d32 100644 --- a/intern/smoke/intern/WTURBULENCE.h +++ b/intern/smoke/intern/WTURBULENCE.h @@ -36,10 +36,13 @@ class WTURBULENCE { public: // both config files can be NULL, altCfg might override values from noiseCfg - WTURBULENCE(int xResSm, int yResSm, int zResSm, int amplify, int noisetype); + WTURBULENCE(int xResSm, int yResSm, int zResSm, int amplify, int noisetype, int init_fire, int init_colors); /// destructor virtual ~WTURBULENCE(); + + void initFire(); + void initColors(float init_r, float init_g, float init_b); void setNoise(int type); void initBlenderRNA(float *strength); @@ -63,6 +66,8 @@ class WTURBULENCE // access functions inline float* getDensityBig() { return _densityBig; } + inline float* getFlameBig() { return _flameBig; } + inline float* getFuelBig() { return _fuelBig; } inline float* getArrayTcU() { return _tcU; } inline float* getArrayTcV() { return _tcV; } inline float* getArrayTcW() { return _tcW; } @@ -111,6 +116,18 @@ class WTURBULENCE float* _densityBig; float* _densityBigOld; + float* _flameBig; + float* _fuelBig; + float* _fuelBigOld; + float* _reactBig; + float* _reactBigOld; + + float* _color_rBig; + float* _color_rBigOld; + float* _color_gBig; + float* _color_gBigOld; + float* _color_bBig; + float* _color_bBigOld; // texture coordinates for noise float* _tcU; diff --git a/intern/smoke/intern/smoke_API.cpp b/intern/smoke/intern/smoke_API.cpp index 4bbf8e0a82b..e51c3176699 100644 --- a/intern/smoke/intern/smoke_API.cpp +++ b/intern/smoke/intern/smoke_API.cpp @@ -30,6 +30,7 @@ #include "FLUID_3D.h" #include "WTURBULENCE.h" +#include "spectrum.h" #include #include @@ -37,22 +38,16 @@ #include "../extern/smoke_API.h" /* to ensure valid prototypes */ -// y in smoke is z in blender -extern "C" FLUID_3D *smoke_init(int *res, float *p0, float dtdef) +extern "C" FLUID_3D *smoke_init(int *res, float dx, float dtdef, int use_heat, int use_fire, int use_colors) { - // smoke lib uses y as top-bottom/vertical axis where blender uses z - FLUID_3D *fluid = new FLUID_3D(res, p0, dtdef); - - // printf("xres: %d, yres: %d, zres: %d\n", res[0], res[1], res[2]); - + FLUID_3D *fluid = new FLUID_3D(res, dx, dtdef, use_heat, use_fire, use_colors); return fluid; } -extern "C" WTURBULENCE *smoke_turbulence_init(int *res, int amplify, int noisetype) +extern "C" WTURBULENCE *smoke_turbulence_init(int *res, int amplify, int noisetype, int use_fire, int use_colors) { - // initialize wavelet turbulence if(amplify) - return new WTURBULENCE(res[0],res[1],res[2], amplify, noisetype); + return new WTURBULENCE(res[0],res[1],res[2], amplify, noisetype, use_fire, use_colors); else return NULL; } @@ -71,7 +66,6 @@ extern "C" void smoke_turbulence_free(WTURBULENCE *wt) extern "C" size_t smoke_get_index(int x, int max_x, int y, int max_y, int z /*, int max_z */) { - // // const int index = x + y * smd->res[0] + z * smd->res[0]*smd->res[1]; return x + y * max_x + z * max_x*max_y; } @@ -80,100 +74,28 @@ extern "C" size_t smoke_get_index2d(int x, int max_x, int y /*, int max_y, int z return x + y * max_x; } -extern "C" void smoke_step(FLUID_3D *fluid, float dtSubdiv) +extern "C" void smoke_step(FLUID_3D *fluid, float gravity[3], float dtSubdiv) { - fluid->step(dtSubdiv); + if (fluid->_fuel) { + fluid->processBurn(fluid->_fuel, fluid->_density, fluid->_react, fluid->_flame, fluid->_heat, + fluid->_color_r, fluid->_color_g, fluid->_color_b, fluid->_totalCells, (*fluid->_dtFactor)*dtSubdiv); + } + fluid->step(dtSubdiv, gravity); } extern "C" void smoke_turbulence_step(WTURBULENCE *wt, FLUID_3D *fluid) { + if (wt->_fuelBig) { + fluid->processBurn(wt->_fuelBig, wt->_densityBig, wt->_reactBig, wt->_flameBig, 0, + wt->_color_rBig, wt->_color_gBig, wt->_color_bBig, wt->_totalCellsBig, fluid->_dt); + } wt->stepTurbulenceFull(fluid->_dt/fluid->_dx, fluid->_xVelocity, fluid->_yVelocity, fluid->_zVelocity, fluid->_obstacles); } -extern "C" void smoke_initBlenderRNA(FLUID_3D *fluid, float *alpha, float *beta, float *dt_factor, float *vorticity, int *border_colli) +extern "C" void smoke_initBlenderRNA(FLUID_3D *fluid, float *alpha, float *beta, float *dt_factor, float *vorticity, int *border_colli, float *burning_rate, + float *flame_smoke, float *flame_smoke_color, float *flame_vorticity, float *flame_ignition_temp, float *flame_max_temp) { - fluid->initBlenderRNA(alpha, beta, dt_factor, vorticity, border_colli); -} - -extern "C" void smoke_dissolve(FLUID_3D *fluid, int speed, int log) -{ - float *density = fluid->_density; - //float *densityOld = fluid->_densityOld; - float *heat = fluid->_heat; - - if(log) - { - /* max density/speed = dydx */ - float dydx = 1.0 / (float)speed; - size_t size= fluid->_xRes * fluid->_yRes * fluid->_zRes; - - for(size_t i = 0; i < size; i++) - { - density[i] *= (1.0 - dydx); - - if(density[i] < 0.0f) - density[i] = 0.0f; - - heat[i] *= (1.0 - dydx); - - /*if(heat[i] < 0.0f) - heat[i] = 0.0f;*/ - } - } - else // linear falloff - { - /* max density/speed = dydx */ - float dydx = 1.0 / (float)speed; - size_t size= fluid->_xRes * fluid->_yRes * fluid->_zRes; - - for(size_t i = 0; i < size; i++) - { - density[i] -= dydx; - - if(density[i] < 0.0f) - density[i] = 0.0f; - - if(abs(heat[i]) < dydx) heat[i] = 0.0f; - else if (heat[i]>0.0f) heat[i] -= dydx; - else if (heat[i]<0.0f) heat[i] += dydx; - - } - } -} - -extern "C" void smoke_dissolve_wavelet(WTURBULENCE *wt, int speed, int log) -{ - float *density = wt->getDensityBig(); - Vec3Int r = wt->getResBig(); - - if(log) - { - /* max density/speed = dydx */ - float dydx = 1.0 / (float)speed; - size_t size= r[0] * r[1] * r[2]; - - for(size_t i = 0; i < size; i++) - { - density[i] *= (1.0 - dydx); - - if(density[i] < 0.0f) - density[i] = 0.0f; - } - } - else // linear falloff - { - /* max density/speed = dydx */ - float dydx = 1.0 / (float)speed; - size_t size= r[0] * r[1] * r[2]; - - for(size_t i = 0; i < size; i++) - { - density[i] -= dydx; - - if(density[i] < 0.0f) - density[i] = 0.0f; - } - } + fluid->initBlenderRNA(alpha, beta, dt_factor, vorticity, border_colli, burning_rate, flame_smoke, flame_smoke_color, flame_vorticity, flame_ignition_temp, flame_max_temp); } extern "C" void smoke_initWaveletBlenderRNA(WTURBULENCE *wt, float *strength) @@ -181,36 +103,105 @@ extern "C" void smoke_initWaveletBlenderRNA(WTURBULENCE *wt, float *strength) wt->initBlenderRNA(strength); } -template < class T > inline T ABS( T a ) +static void data_dissolve(float *density, float *heat, float *r, float *g, float *b, int total_cells, int speed, int log) { - return (0 < a) ? a : -a ; + if(log) + { + /* max density/speed = dydx */ + float fac = 1.0f - (1.0f / (float)speed); + + for(size_t i = 0; i < total_cells; i++) + { + /* density */ + density[i] *= fac; + + /* heat */ + if (heat) { + heat[i] *= fac; + } + + /* color */ + if (r) { + r[i] *= fac; + g[i] *= fac; + b[i] *= fac; + } + } + } + else // linear falloff + { + /* max density/speed = dydx */ + float dydx = 1.0f / (float)speed; + + for(size_t i = 0; i < total_cells; i++) + { + float d = density[i]; + /* density */ + density[i] -= dydx; + if(density[i] < 0.0f) + density[i] = 0.0f; + + /* heat */ + if (heat) { + if(abs(heat[i]) < dydx) heat[i] = 0.0f; + else if (heat[i]>0.0f) heat[i] -= dydx; + else if (heat[i]<0.0f) heat[i] += dydx; + } + + /* color */ + if (r && d) { + r[i] *= (density[i]/d); + g[i] *= (density[i]/d); + b[i] *= (density[i]/d); + } + + } + } } -extern "C" void smoke_export(FLUID_3D *fluid, float *dt, float *dx, float **dens, float **densold, float **heat, float **heatold, float **vx, float **vy, float **vz, float **vxold, float **vyold, float **vzold, unsigned char **obstacles) +extern "C" void smoke_dissolve(FLUID_3D *fluid, int speed, int log) +{ + data_dissolve(fluid->_density, fluid->_heat, fluid->_color_r, fluid->_color_g, fluid->_color_b, fluid->_totalCells, speed, log); +} + +extern "C" void smoke_dissolve_wavelet(WTURBULENCE *wt, int speed, int log) +{ + data_dissolve(wt->_densityBig, 0, wt->_color_rBig, wt->_color_gBig, wt->_color_bBig, wt->_totalCellsBig, speed, log); +} + +extern "C" void smoke_export(FLUID_3D *fluid, float *dt, float *dx, float **dens, float **react, float **flame, float **fuel, float **heat, + float **heatold, float **vx, float **vy, float **vz, float **r, float **g, float **b, unsigned char **obstacles) { *dens = fluid->_density; - *densold = fluid->_densityOld; + *fuel = fluid->_fuel; + *react = fluid->_react; + *flame = fluid->_flame; *heat = fluid->_heat; *heatold = fluid->_heatOld; *vx = fluid->_xVelocity; *vy = fluid->_yVelocity; *vz = fluid->_zVelocity; - *vxold = fluid->_xVelocityOld; - *vyold = fluid->_yVelocityOld; - *vzold = fluid->_zVelocityOld; + *r = fluid->_color_r; + *g = fluid->_color_g; + *b = fluid->_color_b; *obstacles = fluid->_obstacles; *dt = fluid->_dt; *dx = fluid->_dx; - } -extern "C" void smoke_turbulence_export(WTURBULENCE *wt, float **dens, float **densold, float **tcu, float **tcv, float **tcw) +extern "C" void smoke_turbulence_export(WTURBULENCE *wt, float **dens, float **react, float **flame, float **fuel, + float **r, float **g, float **b , float **tcu, float **tcv, float **tcw) { if(!wt) return; *dens = wt->_densityBig; - *densold = wt->_densityBigOld; + *fuel = wt->_fuelBig; + *react = wt->_reactBig; + *flame = wt->_flameBig; + *r = wt->_color_rBig; + *g = wt->_color_gBig; + *b = wt->_color_bBig; *tcu = wt->_tcU; *tcv = wt->_tcV; *tcw = wt->_tcW; @@ -221,6 +212,16 @@ extern "C" float *smoke_get_density(FLUID_3D *fluid) return fluid->_density; } +extern "C" float *smoke_get_fuel(FLUID_3D *fluid) +{ + return fluid->_fuel; +} + +extern "C" float *smoke_get_react(FLUID_3D *fluid) +{ + return fluid->_react; +} + extern "C" float *smoke_get_heat(FLUID_3D *fluid) { return fluid->_heat; @@ -256,15 +257,137 @@ extern "C" float *smoke_get_force_z(FLUID_3D *fluid) return fluid->_zForce; } +extern "C" float *smoke_get_flame(FLUID_3D *fluid) +{ + return fluid->_flame; +} + +extern "C" float *smoke_get_color_r(FLUID_3D *fluid) +{ + return fluid->_color_r; +} + +extern "C" float *smoke_get_color_g(FLUID_3D *fluid) +{ + return fluid->_color_g; +} + +extern "C" float *smoke_get_color_b(FLUID_3D *fluid) +{ + return fluid->_color_b; +} + +static void get_rgba(float *r, float *g, float *b, float *a, int total_cells, float *data, int sequential) +{ + int i; + int m = 4, i_g = 1, i_b = 2, i_a = 3; + /* sequential data */ + if (sequential) { + m = 1; + i_g *= total_cells; + i_b *= total_cells; + i_a *= total_cells; + } + + for (i=0; i_color_r, fluid->_color_g, fluid->_color_b, fluid->_density, fluid->_totalCells, data, sequential); +} + +extern "C" void smoke_turbulence_get_rgba(WTURBULENCE *wt, float *data, int sequential) +{ + get_rgba(wt->_color_rBig, wt->_color_gBig, wt->_color_bBig, wt->_densityBig, wt->_totalCellsBig, data, sequential); +} + +/* get a single color premultiplied voxel grid */ +static void get_rgba_from_density(float color[3], float *a, int total_cells, float *data, int sequential) +{ + int i; + int m = 4, i_g = 1, i_b = 2, i_a = 3; + /* sequential data */ + if (sequential) { + m = 1; + i_g *= total_cells; + i_b *= total_cells; + i_a *= total_cells; + } + + for (i=0; i_density, fluid->_totalCells, data, sequential); +} + +extern "C" void smoke_turbulence_get_rgba_from_density(WTURBULENCE *wt, float color[3], float *data, int sequential) +{ + get_rgba_from_density(color, wt->_densityBig, wt->_totalCellsBig, data, sequential); +} + extern "C" float *smoke_turbulence_get_density(WTURBULENCE *wt) { return wt ? wt->getDensityBig() : NULL; } +extern "C" float *smoke_turbulence_get_fuel(WTURBULENCE *wt) +{ + return wt ? wt->getFuelBig() : NULL; +} + +extern "C" float *smoke_turbulence_get_react(WTURBULENCE *wt) +{ + return wt ? wt->_reactBig : NULL; +} + +extern "C" float *smoke_turbulence_get_color_r(WTURBULENCE *wt) +{ + return wt ? wt->_color_rBig : NULL; +} + +extern "C" float *smoke_turbulence_get_color_g(WTURBULENCE *wt) +{ + return wt ? wt->_color_gBig : NULL; +} + +extern "C" float *smoke_turbulence_get_color_b(WTURBULENCE *wt) +{ + return wt ? wt->_color_bBig : NULL; +} + +extern "C" float *smoke_turbulence_get_flame(WTURBULENCE *wt) +{ + return wt ? wt->getFlameBig() : NULL; +} + extern "C" void smoke_turbulence_get_res(WTURBULENCE *wt, int *res) { - if(wt) - { + if(wt) { Vec3Int r = wt->getResBig(); res[0] = r[0]; res[1] = r[1]; @@ -272,6 +395,15 @@ extern "C" void smoke_turbulence_get_res(WTURBULENCE *wt, int *res) } } +extern "C" int smoke_turbulence_get_cells(WTURBULENCE *wt) +{ + if(wt) { + Vec3Int r = wt->getResBig(); + return r[0]*r[1]*r[2]; + } + return 0; +} + extern "C" unsigned char *smoke_get_obstacle(FLUID_3D *fluid) { return fluid->_obstacles; @@ -295,3 +427,61 @@ extern "C" void smoke_turbulence_set_noise(WTURBULENCE *wt, int type) { wt->setNoise(type); } + +extern "C" void flame_get_spectrum(unsigned char *spec, int width, float t1, float t2) +{ + spectrum(t1, t2, width, spec); +} + +extern "C" int smoke_has_heat(FLUID_3D *fluid) +{ + return (fluid->_heat) ? 1 : 0; +} + +extern "C" int smoke_has_fuel(FLUID_3D *fluid) +{ + return (fluid->_fuel) ? 1 : 0; +} + +extern "C" int smoke_has_colors(FLUID_3D *fluid) +{ + return (fluid->_color_r && fluid->_color_g && fluid->_color_b) ? 1 : 0; +} + +extern "C" int smoke_turbulence_has_fuel(WTURBULENCE *wt) +{ + return (wt->_fuelBig) ? 1 : 0; +} + +extern "C" int smoke_turbulence_has_colors(WTURBULENCE *wt) +{ + return (wt->_color_rBig && wt->_color_gBig && wt->_color_bBig) ? 1 : 0; +} + +/* additional field initialization */ +extern "C" void smoke_ensure_heat(FLUID_3D *fluid) +{ + if (fluid) { + fluid->initHeat(); + } +} + +extern "C" void smoke_ensure_fire(FLUID_3D *fluid, WTURBULENCE *wt) +{ + if (fluid) { + fluid->initFire(); + } + if (wt) { + wt->initFire(); + } +} + +extern "C" void smoke_ensure_colors(FLUID_3D *fluid, WTURBULENCE *wt, float init_r, float init_g, float init_b) +{ + if (fluid) { + fluid->initColors(init_r, init_g, init_b); + } + if (wt) { + wt->initColors(init_r, init_g, init_b); + } +} \ No newline at end of file diff --git a/intern/smoke/intern/spectrum.cpp b/intern/smoke/intern/spectrum.cpp new file mode 100644 index 00000000000..34725c12c92 --- /dev/null +++ b/intern/smoke/intern/spectrum.cpp @@ -0,0 +1,411 @@ +/* + Colour Rendering of Spectra + + by John Walker + http://www.fourmilab.ch/ + + Last updated: March 9, 2003 + + This program is in the public domain. + + For complete information about the techniques employed in + this program, see the World-Wide Web document: + + http://www.fourmilab.ch/documents/specrend/ + + The xyz_to_rgb() function, which was wrong in the original + version of this program, was corrected by: + + Andrew J. S. Hamilton 21 May 1999 + Andrew.Hamilton@Colorado.EDU + http://casa.colorado.edu/~ajsh/ + + who also added the gamma correction facilities and + modified constrain_rgb() to work by desaturating the + colour by adding white. + + A program which uses these functions to plot CIE + "tongue" diagrams called "ppmcie" is included in + the Netpbm graphics toolkit: + http://netpbm.sourceforge.net/ + (The program was called cietoppm in earlier + versions of Netpbm.) + +*/ + +#include +#include + +/* A colour system is defined by the CIE x and y coordinates of + its three primary illuminants and the x and y coordinates of + the white point. */ + +struct colourSystem { + char *name; /* Colour system name */ + double xRed, yRed, /* Red x, y */ + xGreen, yGreen, /* Green x, y */ + xBlue, yBlue, /* Blue x, y */ + xWhite, yWhite, /* White point x, y */ + gamma; /* Gamma correction for system */ +}; + +/* White point chromaticities. */ + +#define IlluminantC 0.3101, 0.3162 /* For NTSC television */ +#define IlluminantD65 0.3127, 0.3291 /* For EBU and SMPTE */ +#define IlluminantE 0.33333333, 0.33333333 /* CIE equal-energy illuminant */ + +/* Gamma of nonlinear correction. + + See Charles Poynton's ColorFAQ Item 45 and GammaFAQ Item 6 at: + + http://www.poynton.com/ColorFAQ.html + http://www.poynton.com/GammaFAQ.html + +*/ + +#define GAMMA_REC709 0 /* Rec. 709 */ + +static struct colourSystem + /* Name xRed yRed xGreen yGreen xBlue yBlue White point Gamma */ + NTSCsystem = { "NTSC", 0.67, 0.33, 0.21, 0.71, 0.14, 0.08, IlluminantC, GAMMA_REC709 }, + EBUsystem = { "EBU (PAL/SECAM)", 0.64, 0.33, 0.29, 0.60, 0.15, 0.06, IlluminantD65, GAMMA_REC709 }, + SMPTEsystem = { "SMPTE", 0.630, 0.340, 0.310, 0.595, 0.155, 0.070, IlluminantD65, GAMMA_REC709 }, + HDTVsystem = { "HDTV", 0.670, 0.330, 0.210, 0.710, 0.150, 0.060, IlluminantD65, GAMMA_REC709 }, + CIEsystem = { "CIE", 0.7355, 0.2645, 0.2658, 0.7243, 0.1669, 0.0085, IlluminantE, GAMMA_REC709 }, + Rec709system = { "CIE REC 709", 0.64, 0.33, 0.30, 0.60, 0.15, 0.06, IlluminantD65, GAMMA_REC709 }; + +/* UPVP_TO_XY + + Given 1976 coordinates u', v', determine 1931 chromaticities x, y + +*/ + +void upvp_to_xy(double up, double vp, double *xc, double *yc) +{ + *xc = (9 * up) / ((6 * up) - (16 * vp) + 12); + *yc = (4 * vp) / ((6 * up) - (16 * vp) + 12); +} + +/* XY_TO_UPVP + + Given 1931 chromaticities x, y, determine 1976 coordinates u', v' + +*/ + +void xy_to_upvp(double xc, double yc, double *up, double *vp) +{ + *up = (4 * xc) / ((-2 * xc) + (12 * yc) + 3); + *vp = (9 * yc) / ((-2 * xc) + (12 * yc) + 3); +} + +/* XYZ_TO_RGB + + Given an additive tricolour system CS, defined by the CIE x + and y chromaticities of its three primaries (z is derived + trivially as 1-(x+y)), and a desired chromaticity (XC, YC, + ZC) in CIE space, determine the contribution of each + primary in a linear combination which sums to the desired + chromaticity. If the requested chromaticity falls outside + the Maxwell triangle (colour gamut) formed by the three + primaries, one of the r, g, or b weights will be negative. + + Caller can use constrain_rgb() to desaturate an + outside-gamut colour to the closest representation within + the available gamut and/or norm_rgb to normalise the RGB + components so the largest nonzero component has value 1. + +*/ + +void xyz_to_rgb(struct colourSystem *cs, + double xc, double yc, double zc, + double *r, double *g, double *b) +{ + double xr, yr, zr, xg, yg, zg, xb, yb, zb; + double xw, yw, zw; + double rx, ry, rz, gx, gy, gz, bx, by, bz; + double rw, gw, bw; + + xr = cs->xRed; yr = cs->yRed; zr = 1 - (xr + yr); + xg = cs->xGreen; yg = cs->yGreen; zg = 1 - (xg + yg); + xb = cs->xBlue; yb = cs->yBlue; zb = 1 - (xb + yb); + + xw = cs->xWhite; yw = cs->yWhite; zw = 1 - (xw + yw); + + /* xyz -> rgb matrix, before scaling to white. */ + + rx = (yg * zb) - (yb * zg); ry = (xb * zg) - (xg * zb); rz = (xg * yb) - (xb * yg); + gx = (yb * zr) - (yr * zb); gy = (xr * zb) - (xb * zr); gz = (xb * yr) - (xr * yb); + bx = (yr * zg) - (yg * zr); by = (xg * zr) - (xr * zg); bz = (xr * yg) - (xg * yr); + + /* White scaling factors. + Dividing by yw scales the white luminance to unity, as conventional. */ + + rw = ((rx * xw) + (ry * yw) + (rz * zw)) / yw; + gw = ((gx * xw) + (gy * yw) + (gz * zw)) / yw; + bw = ((bx * xw) + (by * yw) + (bz * zw)) / yw; + + /* xyz -> rgb matrix, correctly scaled to white. */ + + rx = rx / rw; ry = ry / rw; rz = rz / rw; + gx = gx / gw; gy = gy / gw; gz = gz / gw; + bx = bx / bw; by = by / bw; bz = bz / bw; + + /* rgb of the desired point */ + + *r = (rx * xc) + (ry * yc) + (rz * zc); + *g = (gx * xc) + (gy * yc) + (gz * zc); + *b = (bx * xc) + (by * yc) + (bz * zc); +} + +/* INSIDE_GAMUT + + Test whether a requested colour is within the gamut + achievable with the primaries of the current colour + system. This amounts simply to testing whether all the + primary weights are non-negative. */ + +int inside_gamut(double r, double g, double b) +{ + return (r >= 0) && (g >= 0) && (b >= 0); +} + +/* CONSTRAIN_RGB + + If the requested RGB shade contains a negative weight for + one of the primaries, it lies outside the colour gamut + accessible from the given triple of primaries. Desaturate + it by adding white, equal quantities of R, G, and B, enough + to make RGB all positive. The function returns 1 if the + components were modified, zero otherwise. + +*/ + +int constrain_rgb(double *r, double *g, double *b) +{ + double w; + + /* Amount of white needed is w = - min(0, *r, *g, *b) */ + + w = (0 < *r) ? 0 : *r; + w = (w < *g) ? w : *g; + w = (w < *b) ? w : *b; + w = -w; + + /* Add just enough white to make r, g, b all positive. */ + + if (w > 0) { + *r += w; *g += w; *b += w; + return 1; /* Colour modified to fit RGB gamut */ + } + + return 0; /* Colour within RGB gamut */ +} + +/* GAMMA_CORRECT_RGB + + Transform linear RGB values to nonlinear RGB values. Rec. + 709 is ITU-R Recommendation BT. 709 (1990) ``Basic + Parameter Values for the HDTV Standard for the Studio and + for International Programme Exchange'', formerly CCIR Rec. + 709. For details see + + http://www.poynton.com/ColorFAQ.html + http://www.poynton.com/GammaFAQ.html +*/ + +void gamma_correct(const struct colourSystem *cs, double *c) +{ + double gamma; + + gamma = cs->gamma; + + if (gamma == GAMMA_REC709) { + /* Rec. 709 gamma correction. */ + double cc = 0.018; + + if (*c < cc) { + *c *= ((1.099 * pow(cc, 0.45)) - 0.099) / cc; + } else { + *c = (1.099 * pow(*c, 0.45)) - 0.099; + } + } else { + /* Nonlinear colour = (Linear colour)^(1/gamma) */ + *c = pow(*c, 1.0 / gamma); + } +} + +void gamma_correct_rgb(const struct colourSystem *cs, double *r, double *g, double *b) +{ + gamma_correct(cs, r); + gamma_correct(cs, g); + gamma_correct(cs, b); +} + +/* NORM_RGB + + Normalise RGB components so the most intense (unless all + are zero) has a value of 1. + +*/ + +void norm_rgb(double *r, double *g, double *b) +{ +#define Max(a, b) (((a) > (b)) ? (a) : (b)) + double greatest = Max(*r, Max(*g, *b)); + + if (greatest > 0) { + *r /= greatest; + *g /= greatest; + *b /= greatest; + } +#undef Max +} + +/* SPECTRUM_TO_XYZ + + Calculate the CIE X, Y, and Z coordinates corresponding to + a light source with spectral distribution given by the + function SPEC_INTENS, which is called with a series of + wavelengths between 380 and 780 nm (the argument is + expressed in meters), which returns emittance at that + wavelength in arbitrary units. The chromaticity + coordinates of the spectrum are returned in the x, y, and z + arguments which respect the identity: + + x + y + z = 1. +*/ + +void spectrum_to_xyz(double (*spec_intens)(double wavelength), + double *x, double *y, double *z) +{ + int i; + double lambda, X = 0, Y = 0, Z = 0, XYZ; + + /* CIE colour matching functions xBar, yBar, and zBar for + wavelengths from 380 through 780 nanometers, every 5 + nanometers. For a wavelength lambda in this range: + + cie_colour_match[(lambda - 380) / 5][0] = xBar + cie_colour_match[(lambda - 380) / 5][1] = yBar + cie_colour_match[(lambda - 380) / 5][2] = zBar + + To save memory, this table can be declared as floats + rather than doubles; (IEEE) float has enough + significant bits to represent the values. It's declared + as a double here to avoid warnings about "conversion + between floating-point types" from certain persnickety + compilers. */ + + static double cie_colour_match[81][3] = { + {0.0014,0.0000,0.0065}, {0.0022,0.0001,0.0105}, {0.0042,0.0001,0.0201}, + {0.0076,0.0002,0.0362}, {0.0143,0.0004,0.0679}, {0.0232,0.0006,0.1102}, + {0.0435,0.0012,0.2074}, {0.0776,0.0022,0.3713}, {0.1344,0.0040,0.6456}, + {0.2148,0.0073,1.0391}, {0.2839,0.0116,1.3856}, {0.3285,0.0168,1.6230}, + {0.3483,0.0230,1.7471}, {0.3481,0.0298,1.7826}, {0.3362,0.0380,1.7721}, + {0.3187,0.0480,1.7441}, {0.2908,0.0600,1.6692}, {0.2511,0.0739,1.5281}, + {0.1954,0.0910,1.2876}, {0.1421,0.1126,1.0419}, {0.0956,0.1390,0.8130}, + {0.0580,0.1693,0.6162}, {0.0320,0.2080,0.4652}, {0.0147,0.2586,0.3533}, + {0.0049,0.3230,0.2720}, {0.0024,0.4073,0.2123}, {0.0093,0.5030,0.1582}, + {0.0291,0.6082,0.1117}, {0.0633,0.7100,0.0782}, {0.1096,0.7932,0.0573}, + {0.1655,0.8620,0.0422}, {0.2257,0.9149,0.0298}, {0.2904,0.9540,0.0203}, + {0.3597,0.9803,0.0134}, {0.4334,0.9950,0.0087}, {0.5121,1.0000,0.0057}, + {0.5945,0.9950,0.0039}, {0.6784,0.9786,0.0027}, {0.7621,0.9520,0.0021}, + {0.8425,0.9154,0.0018}, {0.9163,0.8700,0.0017}, {0.9786,0.8163,0.0014}, + {1.0263,0.7570,0.0011}, {1.0567,0.6949,0.0010}, {1.0622,0.6310,0.0008}, + {1.0456,0.5668,0.0006}, {1.0026,0.5030,0.0003}, {0.9384,0.4412,0.0002}, + {0.8544,0.3810,0.0002}, {0.7514,0.3210,0.0001}, {0.6424,0.2650,0.0000}, + {0.5419,0.2170,0.0000}, {0.4479,0.1750,0.0000}, {0.3608,0.1382,0.0000}, + {0.2835,0.1070,0.0000}, {0.2187,0.0816,0.0000}, {0.1649,0.0610,0.0000}, + {0.1212,0.0446,0.0000}, {0.0874,0.0320,0.0000}, {0.0636,0.0232,0.0000}, + {0.0468,0.0170,0.0000}, {0.0329,0.0119,0.0000}, {0.0227,0.0082,0.0000}, + {0.0158,0.0057,0.0000}, {0.0114,0.0041,0.0000}, {0.0081,0.0029,0.0000}, + {0.0058,0.0021,0.0000}, {0.0041,0.0015,0.0000}, {0.0029,0.0010,0.0000}, + {0.0020,0.0007,0.0000}, {0.0014,0.0005,0.0000}, {0.0010,0.0004,0.0000}, + {0.0007,0.0002,0.0000}, {0.0005,0.0002,0.0000}, {0.0003,0.0001,0.0000}, + {0.0002,0.0001,0.0000}, {0.0002,0.0001,0.0000}, {0.0001,0.0000,0.0000}, + {0.0001,0.0000,0.0000}, {0.0001,0.0000,0.0000}, {0.0000,0.0000,0.0000} + }; + + for (i = 0, lambda = 380; lambda < 780.1; i++, lambda += 5) { + double Me; + + Me = (*spec_intens)(lambda); + X += Me * cie_colour_match[i][0]; + Y += Me * cie_colour_match[i][1]; + Z += Me * cie_colour_match[i][2]; + } + XYZ = (X + Y + Z); + *x = X / XYZ; + *y = Y / XYZ; + *z = Z / XYZ; +} + +/* BB_SPECTRUM + + Calculate, by Planck's radiation law, the emittance of a black body + of temperature bbTemp at the given wavelength (in metres). */ + +double bbTemp = 5000; /* Hidden temperature argument + to BB_SPECTRUM. */ +double bb_spectrum(double wavelength) +{ + double wlm = wavelength * 1e-9; /* Wavelength in meters */ + + return (3.74183e-16 * pow(wlm, -5.0)) / + (exp(1.4388e-2 / (wlm * bbTemp)) - 1.0); +} + +void xyz_to_lms(double x, double y, double z, double* l, double* m, double* s) +{ + *l = 0.3897*x + 0.6890*y - 0.0787*z; + *m = -0.2298*x + 1.1834*y + 0.0464*z; + *s = z; +} + +void lms_to_xyz(double l, double m, double s, double* x, double *y, double* z) +{ + *x = 1.9102*l - 1.1121*m + 0.2019*s; + *y = 0.3709*l + 0.6290*m + 0.0000*s; + *z = s; +} + +void spectrum(double t1, double t2, int N, unsigned char* d) +{ + int i,j,dj; + double X,Y,Z,R,G,B,L,M,S, Lw, Mw, Sw; + struct colourSystem *cs = &CIEsystem; + + j = 0; dj = 1; + if (t10.1)? B*255 : 0; + j += dj; + } +} diff --git a/intern/smoke/intern/spectrum.h b/intern/smoke/intern/spectrum.h new file mode 100644 index 00000000000..9edd9ad887c --- /dev/null +++ b/intern/smoke/intern/spectrum.h @@ -0,0 +1,6 @@ +#ifndef __SPECTRUM_H +#define __SPECTRUM_H + +void spectrum(double t1, double t2, int n, unsigned char* d); + +#endif diff --git a/release/datafiles/blender_icons.png b/release/datafiles/blender_icons.png index a0d460b0153b68d4fff7eaaa3bdcfd3a3f6b62e4..09a63f4c47d68266d158493cad880c7d4abcfaf0 100644 GIT binary patch literal 209196 zcmZ^~byQnT^fnqoaEg0zC{os@xlNGIRg{@J2yiS_1$8Lf}^*Dl)u9`sH^q`~zey zr6L6Y)W`Wgswczmsm{Ja2wgJ=LibQb_19di*4^#B0S zg={{4R8xaGxH`B%9UQ3@K7OQjbat?^`Cv0IQzN65iGI5c}Xt6rT{*JD# z?zp|Uc-*dbIQeng`gq(q2_Xg~m2;%0BP$^!jNqSzh~^yNCaSw00|F5!O#_($$~v-b zCf|KfafV07L-S~yfhHh?GjF{PpyTWmPoOHwYkrCTfp5^?3;=HS4Wa+F{B=4-cn51w=BZWRCz7c<9Z79xIsuXRC=oc#gp}A!CkMO)nnMSTJqAmi1 zr!|KacO9=@Hi|QqWlLadQ45O)5kR2uh1gLql9nHrE0PLthjwchupy6T;*3FiiPerY!y+CNT5_(Y`v3?P8x3dFK#^IE9_@*cz0o4mo>fkzxazOBcXHU zPf>yFwQpJ2-l+_gTbJ@A99;PwuNvv?FHHFRf-Cd0;oboHZITj z?)XK~B|`Rb0&#H3ilRtpG5e6t<%$wKzs6U~MJ1q@AlS&XC5rDba7T?%JE)ToAj!y) z7JX6At574rXhd$L)DHe8OCjr4;H@s8ZeF23C&x=#6Y*ParJ!>P_bJn7YXK@;@JA1o@TUM3K@+Vcw^$qZ}-TpaCqV}f0@-^==oJs{H7Z1L;oJS z`2JY^SpOKu9r%bW*H^hQ=J>CLi5xpUzN&|!H@ElACW8}(CvykGALP?`>ur~_(mPpS zffr$aV7Fuf0~G%lmF6q`PlgZg3R4{u&jQbq|X9N-*~AFv<1%T)eNE0R<^1iZj<=D7#n(fEllm~Lm8DKBF*k%EH!IOON;d3 zuwkpw-$Qw66s0u0Y+1x?p*o5ps&C6W4T@lWHfYwvH}7hc!qUb@*-~9nwucCZ8;94@ zd>Fy$9?9Ue^>^#cuWAUT1?4yu38mjnHj93aX&h>-lvbC@D8+MhmZP#9G9xqBYKvAZ z)(MuERPPj~)M}NwO4-O}mK|5*lo;0f%6dUUi_GeNYBTE!Rb8a8D|r-^Pq7?yUg>Mg zXoIy2Z95MG4}-IsAQg}A=M@+j$Je$%UB}t-3$J zF2+g*EQX(}bjp9HH03mHv**E+XUwiBQJulR_$T;?o zo1fmgMt)T{IA983XKL5O1LY*)q9+w5wIXXGi6fnk@r}KR6^_k&`~en~ufmF|>wV&Xm+Y_@4#KVLMs z6;hh|ZoOgNd0Fw-``_Pw+kTa@1aT^oq}NRUp7{N?8m!;lSP#QpByYYS|2@UObQ5th z=X|o8vl}})crtgK;ePF2eB=74_lS5?jP(smIUG5BFzzt!%OJy`0;5qmeR;9!WUfli z{lv+{B|AU+k>NxuZ7pT3Of8~4w|$}gynX!Y{3`yc!K$?wtLSgOG{Wl8AfgXRN zH4ep%gj9%wUkCI2sUDxtobtED7)cl*0aH(fO}R71a|mubu4C>D?s4ui?r-w0#Fu96 zR@PpMr{lv_EAzeyvH7%JVQwn-W`eCj(^W`6aOYoiyVt+dT9RZYDxEU*nAm4`HLchT}r7Vs^L3# z_T%5AU2$4*`Jmz80~Lxym&62Fz>U%X$0;LvUP8W>@;7CEaHdLbmV18Jx$Ew1r1ilh zkrjGC>PzEI>%=9Mzspli0Kb|07Sd~f`MQ$vNVn*f?NU`qPQxk$e^r(NO0eXOi7>H!kfrkW%OJ%9jshEJ~>+g)IQnRyRxgwXi>ZKu=BBV zadKWc7Xkp+s0z|jTAs$oMkpBsGWcSW^!qt36V#+==uD_UMXcZokc?VV1fC2Iy)_Ol z2n#2Yv0{fjo{32)oNkbA{rc7TN9XJ6>e$5b8l@xWrQh|*zb{}F4>xZkZKIR@eZx2q zIhr7zBmIVaPhub)f*kPwqrn)81_FUlInedSRUsFy>XvU0@|nSJ?==-V#>**Mmv{A- z-c5G#Uwlq4|5jWvRL*f^l)A0)>El9-`Guouf&{*K+AZ+!*^SKSKt3epowinu5u3%XaCFFSPo6kI1kyQRhA9ABo?A_dZt3L`KPeU%) zWIpkK4aO}X{!6yNkqD7*=ScbZ%K;($@75M89n+#;isQa?+`N1ZbxfF)l zxn&cQzuQxFLT((WVsH;@wY?yN+UVkT0XWsw<@j}*{-hbz9Mioq)yj+&7aN*u_|xb& zWEF6c#c26<$vb|;*LJy6TWpEFo!IXn^Wv(A!z+2RVh(y=5~r2zIzgI^(_{o!$z4|asi%V3I4}AGiE;zeIF95eN0A*yz2oggJE6tKscT`Zc5Hy_ z`yagvRldu|N@);oI|&%GW}T<3r8pf=SjN1Zg`}11ri~UO|Ir@|!Lwk7#_2>l5R71^ zk%oUX=tD?R#${r^7S|&&tw}=z9Lm#o?mdoQuvgFZsO)MYZ5*#KkxRwS^mwpntzp~4B+c_AT z)x~pMPO76nh#8(PWxH=0ps@cx?1ZBd#BDKzlOW>pFT^TE-0xwYqY|2zZ6@M&wW<}G zjQbg_PdZ80u8{@M?yRuI<20|u@3E=HX*;aNc{fVX z<6q8DCeOaQLv%jB-Le}1rM#0y^hfWOSoT?fS_}!-Dglqx7_~;VUOj#1#RyB1*pppr!`!{ma4_FDg?Ojm0zvDxi` zw$%D@EQ4#?#(~MG&6RS6k%+#%=d_5}6>0Jd3_#m3?nCSMC?m1>X?}0~j@kH|iOoY0 zA^3VE<1gdKsZ)nyDnp==aw4q^j=~CK(mSQ5QyE*Zs{a3WE$YCf21^mo{RxVCmwi=S z5)zU)01V5EA5-+la9*?5nB7z7D_MY z51+g|L&L&GxPQce8ae`AU!EQN(AG7Vii_epYG#R<#a8yOu6_EpdP2-zZUQXVm>wLS zl+RE99+ z{^j#%8XLZ$quzBfNB5J4>)$CU--}_!BAIBSBB$+v2ETL0c0jEy?( z_p*yVgrWyWW4^tfbbiwNVKrVgHu`jb*tOj>;KAZ4hR-N|rt$IXIku zUElVzosiFAJMnB z9v?B-^-z!Xuuz~f)oa3FAv{k~`oK*({tAK$q6*}Sjw6wPShQ`2D$pVg#CIr4wJEK(dx8F!dn#xt?8Y5Toa&BS zLS{M#IYSl0Ge9b?o2pZZ?A0ptLJ%xz=_ zv5wR^ZvMoxa55`z8bycN?B`pm3k=dy^naIzolaiO?h zm{ih$hEF?+In*HqrjoUDW)}6wTc$m}K!JEkj2GJSfV)i;1hzoAgi@Uu-XJ{$wu=%p zZrurTT8n=uTYW7zMLs`-|Dl!1%`%wzm1AvngC%esbZg$LFzf8e1KEIcAH%U)`Sh(P zauVU@zzUpzy8y*A#eBiCYhk8-FSWzFGNQat$}-gq>G@S1VPvlEwET1=4DdPbVY%#ZY>CU3Rhw<9h)4+omcl_mOpXp6*KeF-DX{F*v}r(Xn6lvs zc3wh)fDT3sE0i-q`oF^7xNr!o-EMW>{`r9fL;Z^PPH_hr0^dDxqlU^&dxP;Tq_zhL zOC#_Z<5J^wlmRsuyy-t)r@_t#Go@y5?;mWXXxk7+CBaTiW@sTKc~qKjO@Yv{gLn2- zh7;CVILq3~2ayew!-gfuW)bpHD`aB*vVp-&N9A40=3Q-GbvM{Pkg=J}i!pKo+2~vf zf%muGBnGJ1aI~~D9vK}Dyq)j=T_N0SU5?BZ`WMq!i6tfjc?(^T@Qrp++Q!4 z{7TW4%z1PuVlt^!7R;}1{?`3&Al`t9tkc8f09l!_%`WPeDS zwveA18pWR~Vzudd2bLKr%rlK8BPl!AUhBm4C79CK`ye)@F|h|fIGyTtWJfJ6gi~I0WCKUT!bS~?cZXg7R_XLc9*^Z2*$1%Jw4R0g z9`rA2wD!Zky`z_>UOEq=VG7taGu zy>{g26ZyK(@LaXN(p5&gF0ak1*1wSkAlz|+K0s86JY1dds?jg$E|pv`N2PdTF`$`y z$qn>9GY+h3-DpkZ1-nM0r5&nvWE?L~GvK7(hKoG9HiZ!lmPU94E9cYPTkxHYUur8A zq|dIRvnLx%Mo7vFO<YeeAKS6_@OMnC4e-MW}j5ueatAwN;dNeHY$vDx9w3=7FC1=WKwXGjWouKna7#98K1)B_m?B+46dUF4>0k|x(Qd0o6Jsq~qB4#-w21e+DFoSwPlowl&FTWfPm zR4Na|Ut?PgdoIx_S$=ebcUDXdG}4BJv=Z zLCDKu&BDDmuxVJtMm6*jk{nI1S=!u{-{?;YdeGRe+c_*0b_xG|nh1)IJDPi6DP@Gjw#(i-n$DrLjvmJF{cT4IKIyiF z`q7M#4eLRCDS3RkwvWnK)oYmE!zT)%ARML^2JZNYGshvZwMtFK$~QAv7})|2>>dWw z@uAWxL{dajSWjxAwy>e(xVHXL0%9a8OI)g_1#RAkvSi+L91Ff@_Y5exBV^9R$As5@ zS$W{?|I$d;r*~%i?ml}+WSD3`q25FRWm)Io64|ZO?$@$|DcG@Map}5V!B|5I6<~#J z$XWF8#9?mUsr~xO%nkflTBr=JrXWIwGP@K~Le;aO<$icj8?X2ItmzCa_-*<`uz6Z2 zJ}<={h_FXh2R?e<%gQ_Bf%%uCQxP^BlC7 zz$-7B@(!h`x~h=yti6YSW`uH#Y7f`_NDPfI{)b~F^bMIqitAboG45L zBQ`K?24@8cvZ~!;HBQ#Lot9hZh)m0RF*) zg#aX}nB(-U3_{}?i`+zqGOPS9xj^cxb4Vw;e5>X5xxVG+8c$2Opx}#-ljWdyaU?4y z7|3QD(PFFHjuAT+y4LRDAr~tEfNXkdY-^P%lX~P-A37}Hgbg3w80tA)u>U@OuxLq93NwqBsUib>_ z9;|4{>DtdlIR@@TL2Bk~UW!Sldw4BT`R5XOf#oKse2Rjf$LYYq0?0ZgX$mU5In@LXVnf_q za%5?__~^Q)yrU2!fGn}=2|eaiQCg^^l1)QPYasP!(>&OpV_{ch-t+`QPi=9%_Lm$Q zV7e;4NZJ$Ya|8h!WKEk@@47VOQupoX4O)R41>oa9c4^6(TcpJrP6u8Nj_DCmIcvm@@vwz&0G{;Qe7gx0t`$3H~#V6FQ@1gm69E< z-uu%ct||NM`h<=t7`W|{(GUyUlmnh&Bm^Uzxzf18Ee8~6Xf|O^*TG8UOyd3}2Y7vt zv(1?+YH&pSqiImI5EuU)Bi|I=UK zY?|-8VMbqaFX4-;RFLsr(+&%1mzJ;b9`bg|TC>VpVmTeyM4`tz1T;-y=f$>pWdUc8sm8k()b6pYN(&eNugAq zcDH0(PMu#Ot4rbZfpf=ie)}xZCFKj-cax|QvreXQ5mU4?X|(5*<$vgCL__3icJA5p zmfkEQ+FD%B>xkMlpe2uOlHyioO5hvqz|B)qhtM&t zf8vyv`p}B~kzektQyz3dihmv@OPeHy@?)~|3re1(x_3^{ZBGOsYQ`rUEPDB#>H6<< z@g?1jrc0j`*@rEUKidJy=06v5!NJwJBEl+$4|4NIB}VPSU{Mz<=XW$f^FeSXqu=?$ zI;qRwvvUP(Dv7+S{Wd#%7a~8GYP7|MZyp>n%*i66G@zW6?;o#Seuz)Js3_(NH)eAp zXWV#Pz{ohRo=6-pZut-1<)5b;%wdprkW?@1HJ}fzJlc1dEwy8?%{QXo}LHfbUmv z3GZW2!Qgw>VIc1CtxKP>xrXt012n5Nf=LD_kXr{@x72&KX zG}a{~H~P3~sSDA2scRQERb~k^;jssi-e_S?NG!#nH0mGSeT9q8D8WC}!cR6lc|-eN zso;y90|IgZ0u#F{|C6N@L8G7U;wNYH4xj=t>ohQswrsQXVz^#&H`%;`zwS_AfNVCI zI>r-{ntOUi57vDdBp3Bmi#rhPdqG$2^z7sB;UX}%VT$AP8FFEkcslzS#|AR^6XTY6 z@J)3+Cg$p=#M}Q{|66|UN^<$!d^v}sq|tClF|t%C9UXvG?|p4s|LGTUz1xwF*BLLi z(q7MJd}!)eo|q43{O*+TA-SZxC#86FFBb{-dmHngepIKOoNzSHORZ+QKWMur2r+n{ z;=|{G9|wN~-qO$eNqg62v*^}R8``JAAv{sOfS0FH@)$4wm4Vo|GJ9j0A&wScqqp}K zNrHMp|HPel4>&HgBMG8yX22lrL_q&N{ibx6d-_Z0 zroxX6II!73o#aW4Kol1#6j|)Y{^_SDz&qkpO7Q(2!K*o0*)EUOMM=nXSf029*cD*^;F3aAoh?=*Z-meKs+En}Oie-dSGZ zw)h9IE2(c0Z$3bVcyWlB!&_i|-Ts}69bP{c>&?R#JAIn7sfbvUs0I;(IRJ?4#<29XeXkqK zII*!6IB2!z1((U|*EHhz$IZ<{5FLpFd*(TP;3si?;~VQVVwC!5zsDQ23uzNVMsQxr zKJP^a7bT5!9sp9dp>lquWp!bZ*(fST(OT-+aBR@@#c9+D9tbrU>$!`8fg*v7nqC?V z73Gp6x#9jl{88QY?c=Tkp0Cqc1uV};Il56<11p!f+lpX*4;6LEvB_X6be^ako2-wn zvx@~91&{)=f{WVIdBc3mv-_|kA8p?>cRy=y|NYme+KQALOR_({;ok9zReuU!YyKU* zV*fJe3g0hljY!V!Aed@EY=EzZ2^tJjr^UOlAE`yKzgNb`X}8~poK>*mGC7243_E9P z8v=`+1&M=fb%-yAq^O>*s`eb~3Wfu#JTLYn2ZqBDi7yq|$WaR6XzdU}R71m(fA`(X zKnG)(Ql>PCVUOzEMv_VQsZE<~j6{3G@NJxi&*(uYq*bNnb zq>eFl-{p(z+o;{BE5}PcbNWkwazQ5^xZUd}jkfav%D-T~VUuL%C19fQP>_LEjFjtn8Scn9a+Gm`1V8vd7(V3IDS-_`!cGNuj@Ljw+k!V=sh%_mDpN zD~L1FggTIB$SfC_fsxUS6t}qfQ(7{)PbTF!T@Qf9DhYy3Q^tGJa#Dj~_`^z*`1l2ax`p=x3?4 zEgJxARrEkZN+pf-`y3)||11Csw-T@S38DSDXP^c__xfXGNu_lSbhYG0$ITB?kOqs$ zw-!!gbn5M)zeX#U*eN5e_Cycmdo+NudeUNFg^FzBDaE?>NVIDWg#v&K3mtneTCbOy z&y&0l>skBsJ|*uWTrQ`@tNg;P*x%gRU+3pFw@2ULLl89g^ld$nt4EO51$RETu_ z<}4}^A}LnTp_`(OwP&YZ8)z1AJ8%5UdMcpPMSj`*c5S6zmwVPiYEDS1LRTj%y5!=%dbJ;fXwLCd8BrL>w|ttU zBk_*7(5|l&7Ie7^jLIVkS^97=Q!tEdM0_vD1&CX|$-UHVzfh0j-DVSz&|+1iBBZ)J;oY_j*u^Qo_5=S^sPDmWbm3V z#VO>!d9c%%&FfZua2|3<#w+FEUW{YS;Y~~i^bB~}+Emn7QRx zb2U=uP0YaU|MgPUKEi)pwq4PU^Y-t5d85(rCNJIF%#dkk@lZblB#wASLb`JLC0Gni7ah zq#itlNJCd}ZDEUv-E(!DiM;b$*hVVnVG`A|^(7g?MwfS(m)6`)8>>dI{YuVy9LVY} zi?8`1V<5QK?2T^t;Z}hR9MZu-5&CwTnXdoCYIx%0^pxW+MkX4b0J9k4p(xjmLGv~O zSGxlOrdwUC&*ybbB8@w}(K22{foy@{C*%bM@4FQPuaD}w(F3uj|HDKYw z?15}L->S@h*)(uEAp_@-itK@0G)TrRjzMI+wnV6|u@V4roqpX_+X zTPSWvQ2qf(y~S};NN+k^tr+>ofy{&1^m>SD%aetd5R*C)C`3=jgiP3#Ny-ovd3}lU zLO9~RXE5eNA18%xPTEf@Hqdf)LXMD&Goqxi+6PSc;&tz%8cAq=7w7gq8dRz&D8mtm zV2a4agz}-P=ahJfi8WB?J(SzJjSL%sbUbv10PPKOFNB&wei$DT)j9OY1&=i3lSk<5 zD%HaU#-H|?CQF8s)~JN}Od+od0jgx&cDp5~0WU5ZyJ5Ku@PwxMVpR06XidYfC!ajB z_qGi%KSPHk^G8NCE0YardnDN6U}_||%1?tj433Bz2P1Z^TOJC3)`4p$@WYKtFzd}{ z_Q1ukp(^XiJUjv$ghYyhekWC%{b#ac;u0R~33)iA0XZuoiUi0UgTsi|u!fTFVKWw$ zufxRK;gzyV=WrI}Mg(bfj2E&K>6otZTGn5vA#wr;oo6c zpz#|XsB<;m_G(w@tQi$Z1|h*mCVcAUMQ>U-{a((o7)cQQujk{z7Cy3C>sYjQDh!T2 zd3UQ*y59cO%|e#B(SFsqoS1@Gi@>hfi1-v@6W4rV?pa87LzX46`bwCP)TAPml)G4&;48vN>fAONQM2lu1VW~ZPKu2Cw4iYcq-hxPa{%Im_zbeST;(*lk4;gF5cs* zD@hh0nCs+w%8OY%D5*je+)e9(MVz$c7*RLTC*X#B3Yb*!4NI;fvY5vH0*~>7s~F*X zOa`xtX?p$!PZtQ{DBKK$JS=FlXp{^IVeQPxb2*&x6o2Fl!uY7T*mkiydYjQGbwW&e zhr^p^1qkLyNt|fY-*oLjn<&4nd=A<>L6+RZwiLqy;QaS1n zMPLIWmcf|}Y_kH=)c<5z;#RzDN(juH^=zgT%25t1-t zaUeycTf&QiNyaPRV{(X_59a{q;-D&FhwX{7(f-IA)*k5vzI=ST_VhKB_k?+W;1K zXefUml}1q@6R48VZxqGJ*ZSNJ%i=1VZo((9@vLaKQgRY3@k~Ez_eq$S zPfmk66rFJSm$(9>&qI^h7|!2yXUrSdPfngEq`cbusc|4@AyX^lwOcsZ^&j_ zNixBUux`cp#b(Yh*pDf6l;e8W&JJ+Z1g^1h)9?Hy&o`IV3J4h;3jP&7Q%gY zxkF9%&uvv@I4GmOQKmtzN&SKsFoa22t;F`)MqbZ8?q%gL6%`9t<1Q1+;02I{o6 z^*&!j_h4Oie4|3Wn0_%>HhPmb=ZI835RL&`6(=C0ThzxpNfmci^FpdUN|}r5=%g?k z8%HLUswgyl#SqxC1Y2=vdT2RrY=nDe1)}Yu-09Eg?kTIE9{eW7(V%FrpDw#_N}pw3^op_fbouPEZDM_K^OxORuCnJ* zNHq7qRG(WKhDIKMj5VN4l_s9CfJ>O)X-hiHR1JZG)Qamvnd1>oaHpz-A^d# z)}S0aq?u(ke!tO7QEhs50(3Gj8=Z<_pYY(dA9nMa0p-YH7<}w%#y%%}1D%DFg%!q~ zZKfvFL)=@DND;<}+qHDNusT3?;=wfP7l5Q8-_a?Y8|1UL^&5z}JEy#;M1lPCb?#8h z_Uo8~9z4%tdd(=KtE7O^k9G5SA$dCoNs*$#C>RX3<-53|g1H|%9{;sl$t(al-|3W7 z-P=lg|J=7sD|dKz-{C?xWfra@XYV+*gPzKwh($}zwAO`D%Wi`Yt^ey_Zq^x``u8K8 zd}?ZW>(~>Bfa!NOR66Xvg0<*ast`L_4*`|={V?~DI9CP#m-~HD#UG*8KkseNB+5QPF!CzZ7X(Px zV<2zBdPxNAb3k2&GA?Rz1pZkxq7=T*4cOx9!e>S6iUpPgIkWP~rB|`&a@3uS}VwQV=bCXBTL0o%&iyI90T&rH6_XQSC{a zPZF{8B#+VNa}!=!HI0;!WUoEuuwLD&d552@Yv z0h!#EcPp9^sK0zQluGBn90cLM@=RHHr7$*X6~NxS<*yE=fQkXCt&-t{z#Y|W#*k$G zqyV6)_G9#QMB-0UyDTR!ad_|*Y#Yq_ZLSby-%-ovM(jo+au;HCvH(}G10exw3Y z2vSC5o+fd4vC+2Ug2>AXE^c1lNUi64 z(nI1Bt9xm2Xp(@Tp>#@ldbG)HI|6<4){?>B;@c^cR!Pj_wO}I1Te-0VIb2e|v3#%0 z-2(%KF8bB~O)bT){=cZD9enXPQ3^Q955y9H6GN_&b$ynZi;3l>5gm#fL$m+Cl#n_N zxQ-hq7f(}9c1MMD%+s^Yp?`hT#*hQIhC?ndPV}S+q1+)$sizjR@!&s-i#MrfbTutS zlvX%j|GF~$@U=p+0}H&)Ul=jOL)3tS=ugJ=J(32Qd|50k=1kq4E(u(vD<&11Y5SP>==f_6ozUC(oN}d>O!Z zwqK?m3+ijZT?@xi8hMU7V0Cx_@%o_v^!w#A@*Dn6-R@qinRd5BkXib>N$0UpirgbO zeBy?R;(jU@Q}BGU(!3tO5f(FF+WBR7c9e4a>`KFwXqe)E2)-ORzo#I+dC5IG+nnV4 zr}f>~Ryv1F5Q#|AUR*ukV7Cg)7Rsnyj?(VI!DEP6<60|tL z5D5kH=Ot6rZ!O_^c7zMB{0K5STXY#@>rHkBq!uZOe@PQ_2Awy=f3c9*m|i6=UYeC} zS`tQPiBwb@AHG=xRE(gIL8vvistn}j@QGjbX>_h?sV}VLT~lxGyPGZJF~NXU-cqGB z!_gKw7u*{E-JB(}qa-A=qb;N@`rw}5)!LswZx6(JxEKgcsHbq%dp@C=KXQI+(qB4( z6@&DjUO;XtDZLyX7E)y#M?*@+?^`Xi;{hh&)}XI@uy-HP{)cV+e~480`Lkh%rI=)@ zNPCgl$UFUKqQS`>f!C8buf7%|mHz4<`4LD0E7AG!e1t{;Rn&@eV7hPfm3;oI zm8${?x0+V>Jp65g(wj{Y4@f_J5-o}yt(c2h(E4Ge@*n#_Ivb8Vd@jLfupIqH76Z0Q z9UVkOYJqQ%^Lo*+r~H-%FpcdZl8#p{FoARHU`&8*Z{jw)R%P8+*dNljv4?~-yOe5e z;iZx6h8LK!aQA0D%4l{Vn#HF%vKYfU@+9De=1;Y;9}D)*0ItNvB0XhcpZsZz?tqWg z{Z$zSVSt1iYT(lChRkfqOH`EV$=Owdx&ggFvb8a2TNE(PNo-!z;al45HisD$T_>6R zEbu3JVaMpt1uWSzyqto03A{Zt+f{vB62pE0(@Y~~e8Vs#7O;Lo6Sg|U%AF>E2OVqL zGgCOT-YPdB?Ejk`+IRN0wQn)Izi+bn56%wgw%buMhAyp)5t%Q!_fwd5 zGkD5h1)O#!%nADv@}I^ZD`(3VGX+PhtQ&Nr0?_asQPN#w$uRk}KH}Cfkf5kX!wWJo zY=3y}k^XxOX$UG~gTUmG!OCzp%pY5l1#{@9)QG5L7MJ-LvfU5GTM(?EAA^u4{$I4* zts}L^nHw7H?*8u|HmUD!+jEpawoW3p5l?>TqT{V7dH5y#$aLSKlX+k1ywX=sPq5)K z%hg=lY5wgS@LG)n* z#yIGmrZd-tl{nX>yV3dZju~+BO(>~TIWE)Bo@O*TKXTxr5a?uvMmkO$6gy3G_h4A3 zUK}PG9F`wTCeXIjVf5>$G^-r-q`kN$!}rK7vGvQU3xgyJL(w;m0jY|AAr_>&nR4xY zQG}PaYZpipX%m^w>N9us7{B4?0Bpbf@!WnxXDS)1!ygD^0h!NPoC{I~{z7T##)Cy% zDUOjGX)vmIihWwuRUL@fY$mw%N4DgH(h?QOM^wo*$;awIQE9~_T3DE&rzU0#Dg0Y~ zhr_r42=4w;fz$RlOTqPu(5K**hkb6`2Fu)*AMTYcSA)Lw0c#LIjje%W?I%?1z&$Q0 z%`)Z0eN8wsrcUW%0WjQUt8!0ikgWExIvI*7$8Im?k$+IjKsH@`)8N_n28)4M5VzMl z>r-*{uSv)C<;KsYRXvCERWdinOK8VefdiVIa&wkFItK5J+OCAM)-&Z;8ES|en>@Ys zL$SadNLGofiPoO~7iI4l9$ENrZN|23+qRuf(y?u)W7|o`Ham9Gad&L9W2<9pcAqmd z@BhqozRc&ks&>_`r)od@x7NBBC~L+eG^@$Lic~4|^ufU6WcxBoiO1}H+g}Gjibv^eK$B{^?R2{{eYI%5#$M0TE1I&8_q!WZB7FuIZmlOyxKEh;j zdHy02Sxk^ipld$y&C?`QnnC>RtaMAZhxVyn$SRqqwul7!53Dx&Uw1CgX zi>dR|=}~({-XJ#9>r!vHQi8_Th1FYlHCh>O4HO-ax*QucZ@-cu-Vb;vOFLS_54$PU z`5E{bjy_)b2^gYBRNuzVb;{V53X%mFwj+2}LokSa8u#uziET$&U1=Ddb^Q2B%^nXS zAQPBY+^==6cTl*`1Fy+o(4{p4$7V7BQ@I^TmHroeLv(cF>9}D8p4>U_1L=o?YS^4o zVo04iRzSYtN=0mrC9=0|>93~3#b|>WyB*MT>LIakU!>IEn zv$?l8&W9UzyLE_Tr0#_=FPClM;})G}+jq)M-r6gRT#uL!N+dJC%tJGl6l7w3u&DZ2 zE#V3@ldClAw2Ff?t@3?4#ehF*?|#@hQhc;pN9EGJ^D^dJ9oI}$)C;YUgr9z6?+gwO zhCogq7CR@796fcq-lvpHc}j@*W6S)Lz)4_NEIONGDo>DposQea=^CQv#nkhTbC*6H zv?^-~emN?Jpgco3o|s2?LFUY2aQJ!ad*3ZZ5D}nl`;P#Fe5&Jdc?DL-O@W|i{k{W< zm;0#xj%jSlB#!AeXUA@8k?pzjO@8os>K4 zxfIg%MQ>)U*+kaE4IsipOoFUdK zL=a2-Sz+Zq8p#m~^(qQ+4+4W60CtmJPfZK$S7bEfi41>3f@#rkFOE(9oAy9X=m~PB zbNQ)3C4YRSm0Y@`m8?~$l&p=Vm7Ka8m8?Y=m3V$Tk+@i9i%!@ap`tsG_pkaAEfG#{ z0Y(N=T^zKhD^T!>S?9An9rNsW7G)v{C!5dO!yK?FU>vwK+bfj~#>k$>Pu+^vB3FVA zXSe8Cl_lVtW)ZEYJs;B>@G_KQnM@VOHTiUp%<6k=xLZD&Juoe7k5;8gh>AW`hZTcW ziwdkCbYQ2JoNEqD*KSY@h#KQU8X!56%0$Mi3GW57v@v|hu{C*gNgl&t&`~WHvr;!) zzsB5ZwU7rkbAGp3nfg7g3g+Wg!6BNG3mG$a)!vtuX+aMwiuH={+CkWJt_xv+5?Vf( zSUL`pXIMhco(?)DKyMY=&mKK2XVp)PVyAM}>bNCjvr+5x=9Pwd*tPy$go45;@wOir zvXd)5yRd>pJ((+zAw7 zHt)}fP&-Wc#%ox5_Xwvs>C&s3n?!nx_2v#sbFX(am3ttUqI5X9&V{l?G(i(iNKcJc zk|5bjMPATi{Fb6}1ch+o0d+bczJltxf6=zpBkVNuSXgR%fDZnUmPk_dH&B7hwWpaB zkST;hawGBMJo}gTh;8!T-rsp6KUC}NYF*i(n^8fW&?cPPNIm5_Y9^wIzmAYNC{)m_ zX(|vW39IkoQMDv;d;I;A{vj>{o<&@VIi5`(^JHnkeeGm!cH_A^b^cX;3)+uOL=({CI^njct)m+3 zPWKP!f<--rz)vhqDul~GPaWg}IH9m8W|TvngJkS@=5e(Ku|h5qR`leK6QyLgg~?jOln< zL_mP-3b7C^uA=7D9@~nU#tqC&y&Cr(aSpsJ#o{vT@%2coO^oPzT`&j9w$xC`w){5B zDQdmZ9)taCdW?JILV-d^>6BQQ^3&sz>A2{(|1hGOd>R94@B2fxUIBe#>3fMRYM5XJ z+*=WNO%Ij(tS0JvC$TRP(l6O}w!p>QIDBr^4L@YMUw%&ULeiY1?$`RXdL>t-3g&x& zbpc(N!#Vn?Dpp6XF&0*-_g>vw)Vs+cEZfOQ_+^U!QlNHYS8>+QoD{ZEM{$%Eucek6 zNc5qB#Vx?H7f5cAAhoyHE?Y>Nk0etW4`X4v3M*h-s7*KJ{_o!GmY#x_FdYaeUvSNngtBdd_GHh7uGsY^P*HvcVugV5r;`UA z(*y;yI&9FjXnjeP`Lx;wZwr@4ZpOjfZdo=!2hvot;Ee1HXoTiyLet*Fj3tra<=2A$ ztc9FEKzU_UT?a9NHRt5k83OyL0DN!9f6}1oerp!6F@%Y7LdKg%Il?r%^xOm*MK9Rt zxvLaPjp~-tV(mYhe+W$T0~ymn=&zrC2zrVIw%-@|=EYuD<> z72TX24Dc^jMRLm@psUO6W2~xDqcoTfb_MIlapZ=vsvLW{fSt|!HC1`PM=NrftuFEo z+Xdq%ldNg0lFc)RKSDW~FHOC-oL3-K@B4c8Yl40dPJ32;Mv~H?tL` zW0J)z5b7~wNt!br=-<|G<`=_}&w*&cNeh43v}H4I+glgfdI|bIinFe4%2&eP;L3{@ z8IM*G;qULa-52D-s>n{->jC)gnWn5&OVYGK8Gh#ci(WUQ`UBSdNjF0%EegJ|-v)W8 zSC_g9t(rVA|BOF2gcWEdP{COgO075}R^dOa63AOIN)vp7K;+?DT{M+Rs0`{zE>j&c z#kw@gJYgojCWt=zJe*s@HD66FL44&fZ4ld0U`{mnIDB{b1~20)&hoYXghTdi>g;cZ z30b>`z_nDZ1hl}uphfHcHFnBawkXC}vSRFOeL=f$TgS3MrJrh#c7B^ZBcUsKXO+tM z?S{uDmJpYk3?>U9*2%hc!( zR^&*nRCkovc$4>mi-Rx&aVBjE9L^3Agd&Sx9137mVJ`t^_NOZ_FZ*`}sp-tO+MFWx z*i%F_y4EikloBP?h&|wRo~=~Ip>T6O#G)XbkEg$FYMt1Qh7-$UheBO{SZojGdTzvW?)LCvrqaWu*;;!b-7r^u}g zc@$$QbfkW43$;?riWqG9I(h493RrPA>R6cYrPv*Fln8Oe)L4W8;36@4X69ux(0`KY zjKUpQezt>^k1mNpRv( z)jjK%Wgj+u=wE6#>7WNLh{txCv14*=$pEg{t9VzijiV{hyBslsA72n`5}aYKx$r3w z=8d+eIq~rtz*z(deTtR5U|WX_X_^o$2ECeZZY3%onAi4 zz}MG@FS@F5w(z~BpncB+$%?BY@Y_u~52S`y1ncZ(h@%D!!BkzJN>4YU^D(}$FGxAB zz!}Q6iF8r3GZW{g{F9HYJR)tce z_6lDRKq`8%IOG|Ed*w-kU#U?&q%qSl1V|{|39v9Cpi(hQn)rM*2_q3E(CzsSpN2vAm$(7_97zmSAT(`{ON^nobs;}ar%p1))RC97i=L{;yPEV1)9x`=jGG$D<>@u=S+a#7Bcw~;2e zX!&Ewe4xmkUzeMCS=<_yjTm#c4k&YzUs`ze#Q{VkD zK+BYb$VoVm6L^4p%n3cLgrx3``eqR|F~qe%aIW8Q!6aMkg_-J)iVB!c0aFrR@x3l< zG^UY!s*l-VYxEq@C!O!y--2r?=Uz{KD+>Te$f7wvR8x;2WDnyOxcCuxann3L4XV>a z%yqu>o!imf)0>>}tT|qw#(ZB94v;Bi#`)|4nc}5}*#z!0#w$dY#j zV|=9~=4LtbZO$X(#D+l!A+I~Z^xVy^fgGUktYo;?ox8!@5j)-32itY?JeNTQ#~_Ol zqgZ5E07|qma{PW~{9Nj7W2jW_fu)2vQoqO(%&?09*p@U8{xvGpnDh#R=R8!vZ={T$ zPTjR9Fh5LB{4}LtMF52m-X=v;d z&i%qz5sL9mlp18~!C2~<6Ce>IA5G_fvIHv;N#P)S5O6JgN`=1jL_QKq;Cv6!ZZzYK z6FH>~_|=*M63y|Uc9 zE>tU^9L4eS0k|y*c21OF3C@QiC$VBdYU>Wu3J}n2ND|eJyJ^M9RB~uKNA(LcUIqOk zU9`2a151LSFewx$L<`$FMOip4XJSQ!Y;O<*Rv!yQH|Z_|hb5sb51MdZLuRHajURtz zCk~-cv($mt$!_DH@A`oDZiMJOJPP1k;8s4d|j-oeG^u|cJlrYF(nIn@= zSB#ZcZTjgvz}&=Ib;jpSV=^1O6>#0$0MX8a%0D!dB+POpjw|!@8r4sUpb}nv6vf52 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φg+l$+wl8Ev2sLxC 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 z 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

oxENBPoG&XG1J`^5EE^4s2Ox;~L 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 diff --git a/release/scripts/startup/bl_operators/object_quick_effects.py b/release/scripts/startup/bl_operators/object_quick_effects.py index 35b496b6dd0..cd0b63a6b78 100644 --- a/release/scripts/startup/bl_operators/object_quick_effects.py +++ b/release/scripts/startup/bl_operators/object_quick_effects.py @@ -299,7 +299,6 @@ class QuickSmoke(Operator): style = EnumProperty( name="Smoke Style", items=(('STREAM', "Stream", ""), - ('PUFF', "Puff", ""), ('FIRE', "Fire", ""), ), default='STREAM', @@ -328,20 +327,9 @@ class QuickSmoke(Operator): bpy.ops.object.modifier_add(fake_context, type='SMOKE') obj.modifiers[-1].smoke_type = 'FLOW' - psys = obj.particle_systems[-1] - if self.style == 'PUFF': - psys.settings.frame_end = psys.settings.frame_start - psys.settings.emit_from = 'VOLUME' - psys.settings.distribution = 'RAND' - elif self.style == 'FIRE': - psys.settings.effector_weights.gravity = -1 - psys.settings.lifetime = 5 - psys.settings.count = 100000 + if self.style == 'FIRE': + obj.modifiers[-1].flow_settings.smoke_flow_type = 'FIRE' - obj.modifiers[-2].flow_settings.initial_velocity = True - obj.modifiers[-2].flow_settings.temperature = 2 - - psys.settings.use_render_emitter = self.show_flows if not self.show_flows: obj.draw_type = 'WIRE' @@ -361,8 +349,6 @@ class QuickSmoke(Operator): bpy.ops.object.modifier_add(type='SMOKE') obj.modifiers[-1].smoke_type = 'DOMAIN' if self.style == 'FIRE': - obj.modifiers[-1].domain_settings.use_dissolve_smoke = True - obj.modifiers[-1].domain_settings.dissolve_speed = 20 obj.modifiers[-1].domain_settings.use_high_resolution = True # create a volume material with a voxel data texture for the domain @@ -373,6 +359,7 @@ class QuickSmoke(Operator): mat.type = 'VOLUME' mat.volume.density = 0 mat.volume.density_scale = 5 + mat.volume.step_size = 0.1 tex = bpy.data.textures.new("Smoke Density", 'VOXEL_DATA') tex.voxel_data.domain_object = obj @@ -381,29 +368,35 @@ class QuickSmoke(Operator): tex_slot.texture = tex tex_slot.use_map_color_emission = False tex_slot.use_map_density = True + tex_slot.use_map_color_reflection = True - # for fire add a second texture for emission and emission color - if self.style == 'FIRE': - mat.volume.emission = 5 - tex = bpy.data.textures.new("Smoke Heat", 'VOXEL_DATA') - tex.voxel_data.domain_object = obj - tex.use_color_ramp = True + # for fire add a second texture for flame emission + mat.volume.emission_color = Vector((0.0, 0.0, 0.0)) + tex = bpy.data.textures.new("Flame", 'VOXEL_DATA') + tex.voxel_data.domain_object = obj + tex.voxel_data.smoke_data_type = 'SMOKEFLAME' + tex.use_color_ramp = True - tex_slot = mat.texture_slots.add() - tex_slot.texture = tex + tex_slot = mat.texture_slots.add() + tex_slot.texture = tex - ramp = tex.color_ramp + # add color ramp for flame color + ramp = tex.color_ramp + # dark orange + elem = ramp.elements.new(0.333) + elem.color[0] = 0.2 + elem.color[1] = 0.03 + elem.color[2] = 0 + elem.color[3] = 1 + # yellow glow + elem = ramp.elements.new(0.666) + elem.color[0] = elem.color[3] = 1 + elem.color[1] = 0.65 + elem.color[2] = 0.25 - elem = ramp.elements.new(0.333) - elem.color[0] = elem.color[3] = 1 - elem.color[1] = elem.color[2] = 0 - - elem = ramp.elements.new(0.666) - elem.color[0] = elem.color[1] = elem.color[3] = 1 - elem.color[2] = 0 - - mat.texture_slots[1].use_map_emission = True - mat.texture_slots[1].blend_type = 'MULTIPLY' + mat.texture_slots[1].use_map_density = True + mat.texture_slots[1].use_map_emission = True + mat.texture_slots[1].emission_factor = 5 return {'FINISHED'} diff --git a/release/scripts/startup/bl_ui/properties_particle.py b/release/scripts/startup/bl_ui/properties_particle.py index f29589faa2d..6fcd56fb99e 100644 --- a/release/scripts/startup/bl_ui/properties_particle.py +++ b/release/scripts/startup/bl_ui/properties_particle.py @@ -1124,7 +1124,7 @@ class PARTICLE_PT_field_weights(ParticleButtonsPanel, Panel): def draw(self, context): part = particle_get_settings(context) - effector_weights_ui(self, context, part.effector_weights) + effector_weights_ui(self, context, part.effector_weights, 'PSYS') if part.type == 'HAIR': row = self.layout.row() diff --git a/release/scripts/startup/bl_ui/properties_physics_cloth.py b/release/scripts/startup/bl_ui/properties_physics_cloth.py index e5db1eec37e..5a44294f0e0 100644 --- a/release/scripts/startup/bl_ui/properties_physics_cloth.py +++ b/release/scripts/startup/bl_ui/properties_physics_cloth.py @@ -197,7 +197,7 @@ class PHYSICS_PT_cloth_field_weights(PhysicButtonsPanel, Panel): def draw(self, context): cloth = context.cloth.settings - effector_weights_ui(self, context, cloth.effector_weights) + effector_weights_ui(self, context, cloth.effector_weights, 'CLOTH') if __name__ == "__main__": # only for live edit. bpy.utils.register_module(__name__) diff --git a/release/scripts/startup/bl_ui/properties_physics_common.py b/release/scripts/startup/bl_ui/properties_physics_common.py index 00a35b233da..b94df3148a9 100644 --- a/release/scripts/startup/bl_ui/properties_physics_common.py +++ b/release/scripts/startup/bl_ui/properties_physics_common.py @@ -179,7 +179,7 @@ def point_cache_ui(self, context, cache, enabled, cachetype): col.operator("ptcache.bake_all", text="Update All To Frame").bake = False -def effector_weights_ui(self, context, weights): +def effector_weights_ui(self, context, weights, weight_type): layout = self.layout layout.prop(weights, "group") @@ -200,6 +200,8 @@ def effector_weights_ui(self, context, weights): col.prop(weights, "wind", slider=True) col.prop(weights, "curve_guide", slider=True) col.prop(weights, "texture", slider=True) + if weight_type != 'SMOKE': + col.prop(weights, "smokeflow", slider=True) col = split.column() col.prop(weights, "harmonic", slider=True) diff --git a/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py b/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py index fa37e9cd10f..1df2936b2d4 100644 --- a/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py +++ b/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py @@ -349,7 +349,7 @@ class PHYSICS_PT_dp_effects(PhysicButtonsPanel, Panel): col = layout.column() col.active = surface.use_drip - effector_weights_ui(self, context, surface.effector_weights) + effector_weights_ui(self, context, surface.effector_weights, 'DYNAMIC_PAINT') layout.label(text="Surface Movement:") row = layout.row() diff --git a/release/scripts/startup/bl_ui/properties_physics_field.py b/release/scripts/startup/bl_ui/properties_physics_field.py index 6b5612d7836..933a9aa12a3 100644 --- a/release/scripts/startup/bl_ui/properties_physics_field.py +++ b/release/scripts/startup/bl_ui/properties_physics_field.py @@ -112,6 +112,14 @@ class PHYSICS_PT_field(PhysicButtonsPanel, Panel): col = split.column() col.prop(field, "use_object_coords") col.prop(field, "use_2d_force") + elif field.type == 'SMOKE_FLOW': + col = split.column() + col.prop(field, "strength") + col.prop(field, "flow") + col = split.column() + col.label(text="Domain Object:") + col.prop(field, "source_object", "") + col.prop(field, "use_smoke_density") else: basic_force_field_settings_ui(self, context, field) diff --git a/release/scripts/startup/bl_ui/properties_physics_smoke.py b/release/scripts/startup/bl_ui/properties_physics_smoke.py index acbaad4f961..ce5053f0ecf 100644 --- a/release/scripts/startup/bl_ui/properties_physics_smoke.py +++ b/release/scripts/startup/bl_ui/properties_physics_smoke.py @@ -76,28 +76,40 @@ class PHYSICS_PT_smoke(PhysicButtonsPanel, Panel): elif md.smoke_type == 'FLOW': flow = md.flow_settings + + layout.prop(flow, "smoke_flow_type", expand=False) - split = layout.split() + if flow.smoke_flow_type != "OUTFLOW": + split = layout.split() + col = split.column() + col.label(text="Flow Source:") + col.prop(flow, "smoke_flow_source", expand=False, text="") + if flow.smoke_flow_source == "PARTICLES": + col.label(text="Particle System:") + col.prop_search(flow, "particle_system", ob, "particle_systems", text="") + else: + col.prop(flow, "surface_distance") + col.prop(flow, "volume_density") - col = split.column() - col.prop(flow, "use_outflow") - col.label(text="Particle System:") - col.prop_search(flow, "particle_system", ob, "particle_systems", text="") + sub = col.column(align=True) - sub = col.column() - sub.active = not md.flow_settings.use_outflow + sub.prop(flow, "initial_velocity") + sub = sub.column() + sub.active = flow.initial_velocity + sub.prop(flow, "velocity_factor") + if flow.smoke_flow_source == "MESH": + sub.prop(flow, "velocity_normal") + #sub.prop(flow, "velocity_random") - sub.prop(flow, "initial_velocity", text="Initial Velocity") - sub = sub.column() - sub.active = flow.initial_velocity - sub.prop(flow, "velocity_factor", text="Multiplier") - - sub = split.column() - sub.active = not md.flow_settings.use_outflow - sub.label(text="Initial Values:") - sub.prop(flow, "use_absolute") - sub.prop(flow, "density") - sub.prop(flow, "temperature") + sub = split.column() + sub.label(text="Initial Values:") + sub.prop(flow, "use_absolute") + if flow.smoke_flow_type in {'SMOKE', 'BOTH'}: + sub.prop(flow, "density") + sub.prop(flow, "temperature") + sub.prop(flow, "smoke_color") + if flow.smoke_flow_type in {'FIRE', 'BOTH'}: + sub.prop(flow, "fuel_amount") elif md.smoke_type == 'COLLISION': coll = md.coll_settings @@ -106,36 +118,99 @@ class PHYSICS_PT_smoke(PhysicButtonsPanel, Panel): col = split.column() col.prop(coll, "collision_type") - - -class PHYSICS_PT_smoke_groups(PhysicButtonsPanel, Panel): - bl_label = "Smoke Groups" + +class PHYSICS_PT_smoke_flow_advanced(PhysicButtonsPanel, Panel): + bl_label = "Smoke Flow Advanced" 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) + return md and (md.smoke_type == 'FLOW') and (md.flow_settings.smoke_flow_source == "MESH") + + def draw(self, context): + layout = self.layout + ob = context.object + flow = context.smoke.flow_settings + + split = layout.split() + col = split.column() + + col.prop(flow, "use_texture") + sub = col.column() + sub.active = flow.use_texture + sub.prop(flow, "noise_texture", text="") + sub.label(text="Mapping:") + sub.prop(flow, "texture_map_type", expand=False, text="") + if flow.texture_map_type == "UV": + sub.prop_search(flow, "uv_layer", ob.data, "uv_textures", text="") + if flow.texture_map_type == "AUTO": + sub.prop(flow, "texture_size") + sub.prop(flow, "texture_offset") + + col = split.column() + col.label(text="Vertex Group:") + col.prop_search(flow, "density_vertex_group", ob, "vertex_groups", text="") + +class PHYSICS_PT_smoke_fire(PhysicButtonsPanel, Panel): + bl_label = "Smoke Flames" + bl_options = {'DEFAULT_CLOSED'} + + @classmethod + def poll(cls, context): + md = context.smoke + return md and (md.smoke_type == 'DOMAIN') + + def draw(self, context): + layout = self.layout + domain = context.smoke.domain_settings + + split = layout.split() + split.enabled = not domain.point_cache.is_baked + + col = split.column(align=True) + col.label(text="Reaction:") + col.prop(domain, "burning_rate") + col.prop(domain, "flame_smoke") + col.prop(domain, "flame_vorticity") + + col = split.column(align=True) + col.label(text="Temperatures:") + col.prop(domain, "flame_ignition") + col.prop(domain, "flame_max_temp") + col.prop(domain, "flame_smoke_color") + +class PHYSICS_PT_smoke_adaptive_domain(PhysicButtonsPanel, Panel): + bl_label = "Smoke Adaptive Domain" + bl_options = {'DEFAULT_CLOSED'} + + @classmethod + def poll(cls, context): + md = context.smoke + return md and (md.smoke_type == 'DOMAIN') + + def draw_header(self, context): + md = context.smoke.domain_settings + + self.layout.prop(md, "use_adaptive_domain", text="") def draw(self, context): layout = self.layout - group = context.smoke.domain_settings - + domain = context.smoke.domain_settings + layout.active = domain.use_adaptive_domain + split = layout.split() + split.enabled = not domain.point_cache.is_baked + + col = split.column(align=True) + col.label(text="Resolution:") + col.prop(domain, "additional_res") + col.prop(domain, "adapt_margin") - col = split.column() - col.label(text="Flow Group:") - col.prop(group, "fluid_group", text="") - - #col.label(text="Effector Group:") - #col.prop(group, "effector_group", text="") - - col = split.column() - col.label(text="Collision Group:") - col.prop(group, "collision_group", text="") - + col = split.column(align=True) + col.label(text="Advanced:") + col.prop(domain, "adapt_threshold") class PHYSICS_PT_smoke_highres(PhysicButtonsPanel, Panel): bl_label = "Smoke High Resolution" @@ -174,6 +249,32 @@ class PHYSICS_PT_smoke_highres(PhysicButtonsPanel, Panel): layout.prop(md, "show_high_resolution") +class PHYSICS_PT_smoke_groups(PhysicButtonsPanel, Panel): + bl_label = "Smoke Groups" + 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): + layout = self.layout + domain = context.smoke.domain_settings + + split = layout.split() + + col = split.column() + col.label(text="Flow Group:") + col.prop(domain, "fluid_group", text="") + + #col.label(text="Effector Group:") + #col.prop(domain, "effector_group", text="") + + col = split.column() + col.label(text="Collision Group:") + col.prop(domain, "collision_group", text="") class PHYSICS_PT_smoke_cache(PhysicButtonsPanel, Panel): bl_label = "Smoke Cache" @@ -209,7 +310,7 @@ class PHYSICS_PT_smoke_field_weights(PhysicButtonsPanel, Panel): def draw(self, context): domain = context.smoke.domain_settings - effector_weights_ui(self, context, domain.effector_weights) + effector_weights_ui(self, context, domain.effector_weights, 'SMOKE') if __name__ == "__main__": # only for live edit. bpy.utils.register_module(__name__) diff --git a/release/scripts/startup/bl_ui/properties_physics_softbody.py b/release/scripts/startup/bl_ui/properties_physics_softbody.py index a69e7955de5..79d676533a5 100644 --- a/release/scripts/startup/bl_ui/properties_physics_softbody.py +++ b/release/scripts/startup/bl_ui/properties_physics_softbody.py @@ -231,7 +231,7 @@ class PHYSICS_PT_softbody_field_weights(PhysicButtonsPanel, Panel): md = context.soft_body softbody = md.settings - effector_weights_ui(self, context, softbody.effector_weights) + effector_weights_ui(self, context, softbody.effector_weights, 'SOFTBODY') if __name__ == "__main__": # only for live edit. bpy.utils.register_module(__name__) diff --git a/release/scripts/startup/bl_ui/properties_texture.py b/release/scripts/startup/bl_ui/properties_texture.py index 9e6bfe6889e..d4752e4e7b5 100644 --- a/release/scripts/startup/bl_ui/properties_texture.py +++ b/release/scripts/startup/bl_ui/properties_texture.py @@ -887,8 +887,12 @@ class TEXTURE_PT_mapping(TextureSlotPanel, Panel): col = split.column() if tex.texture_coords in {'ORCO', 'UV'}: col.prop(tex, "use_from_dupli") + if (idblock.type == 'VOLUME' and tex.texture_coords == 'ORCO'): + col.prop(tex, "use_map_to_bounds") elif tex.texture_coords == 'OBJECT': col.prop(tex, "use_from_original") + if (idblock.type == 'VOLUME'): + col.prop(tex, "use_map_to_bounds") else: col.label() diff --git a/source/blender/blenkernel/BKE_smoke.h b/source/blender/blenkernel/BKE_smoke.h index 1f824ccbafc..3a9d2b86b41 100644 --- a/source/blender/blenkernel/BKE_smoke.h +++ b/source/blender/blenkernel/BKE_smoke.h @@ -35,8 +35,10 @@ typedef float (*bresenham_callback)(float *result, float *input, int res[3], int *pixel, float *tRay, float correct); -void smokeModifier_do(struct SmokeModifierData *smd, struct Scene *scene, struct Object *ob, struct DerivedMesh *dm); +struct DerivedMesh *smokeModifier_do(struct SmokeModifierData *smd, struct Scene *scene, struct Object *ob, struct DerivedMesh *dm); +void smoke_reallocate_fluid(struct SmokeDomainSettings *sds, float dx, int res[3], int free_old); +void smoke_reallocate_highres_fluid(struct SmokeDomainSettings *sds, float dx, int res[3], int free_old); void smokeModifier_free(struct SmokeModifierData *smd); void smokeModifier_reset(struct SmokeModifierData *smd); void smokeModifier_reset_turbulence(struct SmokeModifierData *smd); @@ -44,5 +46,7 @@ void smokeModifier_createType(struct SmokeModifierData *smd); void smokeModifier_copy(struct SmokeModifierData *smd, struct SmokeModifierData *tsmd); long long smoke_get_mem_req(int xres, int yres, int zres, int amplify); +float smoke_get_velocity_at(struct Object *ob, float position[3], float velocity[3]); +int smoke_get_data_flags(struct SmokeDomainSettings *sds); #endif /* __BKE_SMOKE_H__ */ diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index 31a6f768f89..9b52fbae626 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -400,8 +400,7 @@ static void dag_add_material_driver_relations(DagForest *dag, DagNode *node, Mat } } -static void dag_add_collision_field_relation(DagForest *dag, Scene *scene, Object *ob, DagNode *node) -{ +static void dag_add_collision_field_relation(DagForest *dag, Scene *scene, Object *ob, DagNode *node, int skip_forcefield){ Base *base; DagNode *node2; @@ -411,6 +410,8 @@ static void dag_add_collision_field_relation(DagForest *dag, Scene *scene, Objec if ((base->lay & ob->lay) && base->object->pd) { Object *ob1 = base->object; if ((ob1->pd->deflect || ob1->pd->forcefield) && (ob1 != ob)) { + if (skip_forcefield && ob1->pd->forcefield == skip_forcefield) + continue; node2 = dag_get_node(dag, ob1); dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Field Collision"); } @@ -570,12 +571,14 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O /* softbody collision */ if ((ob->type == OB_MESH) || (ob->type == OB_CURVE) || (ob->type == OB_LATTICE)) { if (ob->particlesystem.first || - modifiers_isModifierEnabled(ob, eModifierType_Softbody) || - modifiers_isModifierEnabled(ob, eModifierType_Cloth) || - modifiers_isModifierEnabled(ob, eModifierType_Smoke) || - modifiers_isModifierEnabled(ob, eModifierType_DynamicPaint)) + modifiers_isModifierEnabled(ob, eModifierType_Softbody) || + modifiers_isModifierEnabled(ob, eModifierType_Cloth) || + modifiers_isModifierEnabled(ob, eModifierType_DynamicPaint)) { - dag_add_collision_field_relation(dag, scene, ob, node); /* TODO: use effectorweight->group */ + dag_add_collision_field_relation(dag, scene, ob, node, 0); /* TODO: use effectorweight->group */ + } + else if (modifiers_isModifierEnabled(ob, eModifierType_Smoke)) { + dag_add_collision_field_relation(dag, scene, ob, node, PFIELD_SMOKEFLOW); } } diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c index 4f4bafd00b4..495814acbee 100644 --- a/source/blender/blenkernel/intern/effect.c +++ b/source/blender/blenkernel/intern/effect.c @@ -84,6 +84,7 @@ #include "BKE_object.h" #include "BKE_particle.h" #include "BKE_scene.h" +#include "BKE_smoke.h" #include "RE_render_ext.h" @@ -137,6 +138,9 @@ PartDeflect *object_add_collision_fields(int type) case PFIELD_TEXTURE: pd->f_size = 1.0f; break; + case PFIELD_SMOKEFLOW: + pd->f_flow = 1.0f; + break; } pd->flag = PFIELD_DO_LOCATION|PFIELD_DO_ROTATION; @@ -922,12 +926,27 @@ static void do_physical_effector(EffectorCache *eff, EffectorData *efd, Effected mul_v3_fl(force, -efd->falloff * fac * (strength * fac + damp)); break; + case PFIELD_SMOKEFLOW: + zero_v3(force); + if (pd->f_source) { + float density; + if ((density = smoke_get_velocity_at(pd->f_source, point->loc, force)) >= 0.0f) { + float influence = strength * efd->falloff; + if (pd->flag & PFIELD_SMOKE_DENSITY) + influence *= density; + mul_v3_fl(force, influence); + /* apply flow */ + madd_v3_v3fl(total_force, point->vel, -pd->f_flow * influence); + } + } + break; + } if (pd->flag & PFIELD_DO_LOCATION) { madd_v3_v3fl(total_force, force, 1.0f/point->vel_to_sec); - if (ELEM(pd->forcefield, PFIELD_HARMONIC, PFIELD_DRAG)==0 && pd->f_flow != 0.0f) { + if (ELEM3(pd->forcefield, PFIELD_HARMONIC, PFIELD_DRAG, PFIELD_SMOKEFLOW)==0 && pd->f_flow != 0.0f) { madd_v3_v3fl(total_force, point->vel, -pd->f_flow * efd->falloff); } } diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index 8c0d19ba1fd..6b90ec88362 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -532,20 +532,31 @@ static int ptcache_smoke_totpoint(void *smoke_v, int UNUSED(cfra)) SmokeDomainSettings *sds = smd->domain; if (sds->fluid) { - return sds->res[0]*sds->res[1]*sds->res[2]; + return sds->base_res[0]*sds->base_res[1]*sds->base_res[2]; } else return 0; } + +#define SMOKE_CACHE_VERSION "1.04" + static int ptcache_smoke_write(PTCacheFile *pf, void *smoke_v) { SmokeModifierData *smd= (SmokeModifierData *)smoke_v; SmokeDomainSettings *sds = smd->domain; int ret = 0; + int fluid_fields = smoke_get_data_flags(sds); + + /* version header */ + ptcache_file_write(pf, SMOKE_CACHE_VERSION, 4, sizeof(char)); + ptcache_file_write(pf, &fluid_fields, 1, sizeof(int)); + ptcache_file_write(pf, &sds->active_fields, 1, sizeof(int)); + ptcache_file_write(pf, &sds->res, 3, sizeof(int)); + ptcache_file_write(pf, &sds->dx, 1, sizeof(float)); if (sds->fluid) { size_t res = sds->res[0]*sds->res[1]*sds->res[2]; - float dt, dx, *dens, *densold, *heat, *heatold, *vx, *vy, *vz, *vxold, *vyold, *vzold; + float dt, dx, *dens, *react, *fuel, *flame, *heat, *heatold, *vx, *vy, *vz, *r, *g, *b; unsigned char *obstacles; unsigned int in_len = sizeof(float)*(unsigned int)res; unsigned char *out = (unsigned char *)MEM_callocN(LZO_OUT_LEN(in_len)*4, "pointcache_lzo_buffer"); @@ -553,22 +564,40 @@ static int ptcache_smoke_write(PTCacheFile *pf, void *smoke_v) int mode=1; // light if (sds->cache_comp == SM_CACHE_HEAVY) mode=2; // heavy - smoke_export(sds->fluid, &dt, &dx, &dens, &densold, &heat, &heatold, &vx, &vy, &vz, &vxold, &vyold, &vzold, &obstacles); + smoke_export(sds->fluid, &dt, &dx, &dens, &react, &flame, &fuel, &heat, &heatold, &vx, &vy, &vz, &r, &g, &b, &obstacles); ptcache_file_compressed_write(pf, (unsigned char *)sds->shadow, in_len, out, mode); ptcache_file_compressed_write(pf, (unsigned char *)dens, in_len, out, mode); - ptcache_file_compressed_write(pf, (unsigned char *)densold, in_len, out, mode); - ptcache_file_compressed_write(pf, (unsigned char *)heat, in_len, out, mode); - ptcache_file_compressed_write(pf, (unsigned char *)heatold, in_len, out, mode); + if (fluid_fields & SM_ACTIVE_HEAT) { + ptcache_file_compressed_write(pf, (unsigned char *)heat, in_len, out, mode); + ptcache_file_compressed_write(pf, (unsigned char *)heatold, in_len, out, mode); + } + if (fluid_fields & SM_ACTIVE_FIRE) { + ptcache_file_compressed_write(pf, (unsigned char *)flame, in_len, out, mode); + ptcache_file_compressed_write(pf, (unsigned char *)fuel, in_len, out, mode); + ptcache_file_compressed_write(pf, (unsigned char *)react, in_len, out, mode); + } + if (fluid_fields & SM_ACTIVE_COLORS) { + ptcache_file_compressed_write(pf, (unsigned char *)r, in_len, out, mode); + ptcache_file_compressed_write(pf, (unsigned char *)g, in_len, out, mode); + ptcache_file_compressed_write(pf, (unsigned char *)b, in_len, out, mode); + } ptcache_file_compressed_write(pf, (unsigned char *)vx, in_len, out, mode); ptcache_file_compressed_write(pf, (unsigned char *)vy, in_len, out, mode); ptcache_file_compressed_write(pf, (unsigned char *)vz, in_len, out, mode); - ptcache_file_compressed_write(pf, (unsigned char *)vxold, in_len, out, mode); - ptcache_file_compressed_write(pf, (unsigned char *)vyold, in_len, out, mode); - ptcache_file_compressed_write(pf, (unsigned char *)vzold, in_len, out, mode); ptcache_file_compressed_write(pf, (unsigned char *)obstacles, (unsigned int)res, out, mode); ptcache_file_write(pf, &dt, 1, sizeof(float)); ptcache_file_write(pf, &dx, 1, sizeof(float)); + ptcache_file_write(pf, &sds->p0, 3, sizeof(float)); + ptcache_file_write(pf, &sds->p1, 3, sizeof(float)); + ptcache_file_write(pf, &sds->dp0, 3, sizeof(float)); + ptcache_file_write(pf, &sds->shift, 3, sizeof(int)); + ptcache_file_write(pf, &sds->obj_shift_f, 3, sizeof(float)); + ptcache_file_write(pf, &sds->obmat, 16, sizeof(float)); + ptcache_file_write(pf, &sds->base_res, 3, sizeof(int)); + ptcache_file_write(pf, &sds->res_min, 3, sizeof(int)); + ptcache_file_write(pf, &sds->res_max, 3, sizeof(int)); + ptcache_file_write(pf, &sds->active_color, 3, sizeof(float)); MEM_freeN(out); @@ -579,7 +608,7 @@ static int ptcache_smoke_write(PTCacheFile *pf, void *smoke_v) int res_big_array[3]; int res_big; int res = sds->res[0]*sds->res[1]*sds->res[2]; - float *dens, *densold, *tcu, *tcv, *tcw; + float *dens, *react, *fuel, *flame, *tcu, *tcv, *tcw, *r, *g, *b; unsigned int in_len = sizeof(float)*(unsigned int)res; unsigned int in_len_big; unsigned char *out; @@ -593,11 +622,20 @@ static int ptcache_smoke_write(PTCacheFile *pf, void *smoke_v) in_len_big = sizeof(float) * (unsigned int)res_big; - smoke_turbulence_export(sds->wt, &dens, &densold, &tcu, &tcv, &tcw); + smoke_turbulence_export(sds->wt, &dens, &react, &flame, &fuel, &r, &g, &b, &tcu, &tcv, &tcw); out = (unsigned char *)MEM_callocN(LZO_OUT_LEN(in_len_big), "pointcache_lzo_buffer"); ptcache_file_compressed_write(pf, (unsigned char *)dens, in_len_big, out, mode); - ptcache_file_compressed_write(pf, (unsigned char *)densold, in_len_big, out, mode); + if (fluid_fields & SM_ACTIVE_FIRE) { + ptcache_file_compressed_write(pf, (unsigned char *)flame, in_len_big, out, mode); + ptcache_file_compressed_write(pf, (unsigned char *)fuel, in_len_big, out, mode); + ptcache_file_compressed_write(pf, (unsigned char *)react, in_len_big, out, mode); + } + if (fluid_fields & SM_ACTIVE_COLORS) { + ptcache_file_compressed_write(pf, (unsigned char *)r, in_len_big, out, mode); + ptcache_file_compressed_write(pf, (unsigned char *)g, in_len_big, out, mode); + ptcache_file_compressed_write(pf, (unsigned char *)b, in_len_big, out, mode); + } MEM_freeN(out); out = (unsigned char *)MEM_callocN(LZO_OUT_LEN(in_len), "pointcache_lzo_buffer"); @@ -615,34 +653,95 @@ static int ptcache_smoke_read(PTCacheFile *pf, void *smoke_v) { SmokeModifierData *smd= (SmokeModifierData *)smoke_v; SmokeDomainSettings *sds = smd->domain; + char version[4]; + int ch_res[3]; + float ch_dx; + int fluid_fields = smoke_get_data_flags(sds); + int cache_fields = 0; + int active_fields = 0; + int reallocate = 0; + + /* version header */ + ptcache_file_read(pf, version, 4, sizeof(char)); + if (strncmp(version, SMOKE_CACHE_VERSION, 4)) return 0; + /* fluid info */ + ptcache_file_read(pf, &cache_fields, 1, sizeof(int)); + ptcache_file_read(pf, &active_fields, 1, sizeof(int)); + ptcache_file_read(pf, &ch_res, 3, sizeof(int)); + ptcache_file_read(pf, &ch_dx, 1, sizeof(float)); + + /* check if resolution has changed */ + if (sds->res[0] != ch_res[0] || + sds->res[1] != ch_res[1] || + sds->res[2] != ch_res[2]) { + if (sds->flags & MOD_SMOKE_ADAPTIVE_DOMAIN) + reallocate = 1; + else + return 0; + } + /* check if active fields have changed */ + if (fluid_fields != cache_fields || + active_fields != sds->active_fields) + reallocate = 1; + + /* reallocate fluid if needed*/ + if (reallocate) { + sds->active_fields = active_fields; + smoke_reallocate_fluid(sds, ch_dx, ch_res, 1); + sds->dx = ch_dx; + VECCOPY(sds->res, ch_res); + sds->total_cells = ch_res[0]*ch_res[1]*ch_res[2]; + if(sds->flags & MOD_SMOKE_HIGHRES) { + smoke_reallocate_highres_fluid(sds, ch_dx, ch_res, 1); + } + } if (sds->fluid) { size_t res = sds->res[0]*sds->res[1]*sds->res[2]; - float dt, dx, *dens, *densold, *heat, *heatold, *vx, *vy, *vz, *vxold, *vyold, *vzold; + float dt, dx, *dens, *react, *fuel, *flame, *heat, *heatold, *vx, *vy, *vz, *r, *g, *b; unsigned char *obstacles; unsigned int out_len = (unsigned int)res * sizeof(float); - smoke_export(sds->fluid, &dt, &dx, &dens, &densold, &heat, &heatold, &vx, &vy, &vz, &vxold, &vyold, &vzold, &obstacles); + smoke_export(sds->fluid, &dt, &dx, &dens, &react, &flame, &fuel, &heat, &heatold, &vx, &vy, &vz, &r, &g, &b, &obstacles); ptcache_file_compressed_read(pf, (unsigned char *)sds->shadow, out_len); ptcache_file_compressed_read(pf, (unsigned char*)dens, out_len); - ptcache_file_compressed_read(pf, (unsigned char*)densold, out_len); - ptcache_file_compressed_read(pf, (unsigned char*)heat, out_len); - ptcache_file_compressed_read(pf, (unsigned char*)heatold, out_len); + if (cache_fields & SM_ACTIVE_HEAT) { + ptcache_file_compressed_read(pf, (unsigned char*)heat, out_len); + ptcache_file_compressed_read(pf, (unsigned char*)heatold, out_len); + } + if (cache_fields & SM_ACTIVE_FIRE) { + ptcache_file_compressed_read(pf, (unsigned char*)flame, out_len); + ptcache_file_compressed_read(pf, (unsigned char*)fuel, out_len); + ptcache_file_compressed_read(pf, (unsigned char*)react, out_len); + } + if (cache_fields & SM_ACTIVE_COLORS) { + ptcache_file_compressed_read(pf, (unsigned char*)r, out_len); + ptcache_file_compressed_read(pf, (unsigned char*)g, out_len); + ptcache_file_compressed_read(pf, (unsigned char*)b, out_len); + } ptcache_file_compressed_read(pf, (unsigned char*)vx, out_len); ptcache_file_compressed_read(pf, (unsigned char*)vy, out_len); ptcache_file_compressed_read(pf, (unsigned char*)vz, out_len); - ptcache_file_compressed_read(pf, (unsigned char*)vxold, out_len); - ptcache_file_compressed_read(pf, (unsigned char*)vyold, out_len); - ptcache_file_compressed_read(pf, (unsigned char*)vzold, out_len); ptcache_file_compressed_read(pf, (unsigned char*)obstacles, (unsigned int)res); ptcache_file_read(pf, &dt, 1, sizeof(float)); ptcache_file_read(pf, &dx, 1, sizeof(float)); + ptcache_file_read(pf, &sds->p0, 3, sizeof(float)); + ptcache_file_read(pf, &sds->p1, 3, sizeof(float)); + ptcache_file_read(pf, &sds->dp0, 3, sizeof(float)); + ptcache_file_read(pf, &sds->shift, 3, sizeof(int)); + ptcache_file_read(pf, &sds->obj_shift_f, 3, sizeof(float)); + ptcache_file_read(pf, &sds->obmat, 16, sizeof(float)); + ptcache_file_read(pf, &sds->base_res, 3, sizeof(int)); + ptcache_file_read(pf, &sds->res_min, 3, sizeof(int)); + ptcache_file_read(pf, &sds->res_max, 3, sizeof(int)); + ptcache_file_read(pf, &sds->active_color, 3, sizeof(float)); + } - if (pf->data_types & (1<wt) { + if (pf->data_types & (1<wt) { int res = sds->res[0]*sds->res[1]*sds->res[2]; int res_big, res_big_array[3]; - float *dens, *densold, *tcu, *tcv, *tcw; + float *dens, *react, *fuel, *flame, *tcu, *tcv, *tcw, *r, *g, *b; unsigned int out_len = sizeof(float)*(unsigned int)res; unsigned int out_len_big; @@ -650,16 +749,23 @@ static int ptcache_smoke_read(PTCacheFile *pf, void *smoke_v) res_big = res_big_array[0]*res_big_array[1]*res_big_array[2]; out_len_big = sizeof(float) * (unsigned int)res_big; - smoke_turbulence_export(sds->wt, &dens, &densold, &tcu, &tcv, &tcw); + smoke_turbulence_export(sds->wt, &dens, &react, &flame, &fuel, &r, &g, &b, &tcu, &tcv, &tcw); ptcache_file_compressed_read(pf, (unsigned char*)dens, out_len_big); - ptcache_file_compressed_read(pf, (unsigned char*)densold, out_len_big); + if (cache_fields & SM_ACTIVE_FIRE) { + ptcache_file_compressed_read(pf, (unsigned char*)flame, out_len_big); + ptcache_file_compressed_read(pf, (unsigned char*)fuel, out_len_big); + } + if (cache_fields & SM_ACTIVE_COLORS) { + ptcache_file_compressed_read(pf, (unsigned char*)r, out_len_big); + ptcache_file_compressed_read(pf, (unsigned char*)g, out_len_big); + ptcache_file_compressed_read(pf, (unsigned char*)b, out_len_big); + } ptcache_file_compressed_read(pf, (unsigned char*)tcu, out_len); ptcache_file_compressed_read(pf, (unsigned char*)tcv, out_len); ptcache_file_compressed_read(pf, (unsigned char*)tcw, out_len); } - } return 1; } @@ -2466,10 +2572,10 @@ int BKE_ptcache_id_reset(Scene *scene, PTCacheID *pid, int mode) sbFreeSimulation(pid->calldata); else if (pid->type == PTCACHE_TYPE_PARTICLES) psys_reset(pid->calldata, PSYS_RESET_DEPSGRAPH); - else if (pid->type == PTCACHE_TYPE_SMOKE_DOMAIN) + /*else if (pid->type == PTCACHE_TYPE_SMOKE_DOMAIN) smokeModifier_reset(pid->calldata); else if (pid->type == PTCACHE_TYPE_SMOKE_HIGHRES) - smokeModifier_reset_turbulence(pid->calldata); + smokeModifier_reset_turbulence(pid->calldata);*/ else if (pid->type == PTCACHE_TYPE_DYNAMICPAINT) dynamicPaint_clearSurface((DynamicPaintSurface*)pid->calldata); } diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c index 5e67e094e43..a07c58746df 100644 --- a/source/blender/blenkernel/intern/smoke.c +++ b/source/blender/blenkernel/intern/smoke.c @@ -51,18 +51,7 @@ #include "BLI_kdtree.h" #include "BLI_kdopbvh.h" #include "BLI_utildefines.h" - -#include "BKE_bvhutils.h" -#include "BKE_cdderivedmesh.h" -#include "BKE_collision.h" -#include "BKE_customdata.h" -#include "BKE_DerivedMesh.h" -#include "BKE_effect.h" -#include "BKE_modifier.h" -#include "BKE_particle.h" -#include "BKE_pointcache.h" -#include "BKE_smoke.h" - +#include "BLI_voxel.h" #include "DNA_customdata_types.h" #include "DNA_group_types.h" @@ -75,8 +64,20 @@ #include "DNA_scene_types.h" #include "DNA_smoke_types.h" +#include "BKE_bvhutils.h" +#include "BKE_cdderivedmesh.h" +#include "BKE_collision.h" +#include "BKE_customdata.h" +#include "BKE_deform.h" +#include "BKE_DerivedMesh.h" +#include "BKE_effect.h" +#include "BKE_modifier.h" +#include "BKE_particle.h" +#include "BKE_pointcache.h" #include "BKE_smoke.h" +#include "RE_shader_ext.h" + /* UNUSED so far, may be enabled later */ /* #define USE_SMOKE_COLLISION_DM */ @@ -103,7 +104,7 @@ static void tend ( void ) { QueryPerformanceCounter ( &liCurrentTime ); } -static double UNUSED_FUNCTION(tval)( void ) +static double tval( void ) { return ((double)( (liCurrentTime.QuadPart - liStartTime.QuadPart)* (double)1000.0/(double)liFrequency.QuadPart )); } @@ -134,590 +135,220 @@ struct Scene; struct DerivedMesh; struct SmokeModifierData; -#define TRI_UVOFFSET (1./4.) - // timestep default value for nice appearance 0.1f #define DT_DEFAULT 0.1f -/* forward declerations */ -static void calcTriangleDivs(Object *ob, MVert *verts, int numverts, MFace *tris, int numfaces, int numtris, int **tridivs, float cell_len); -static void get_cell(const float p0[3], const int res[3], float dx, const float pos[3], int cell[3], int correct); -static void fill_scs_points(Object *ob, DerivedMesh *dm, SmokeCollSettings *scs); +#define ADD_IF_LOWER_POS(a,b) (MIN2((a)+(b), MAX2((a),(b)))) +#define ADD_IF_LOWER_NEG(a,b) (MAX2((a)+(b), MIN2((a),(b)))) +#define ADD_IF_LOWER(a,b) (((b)>0)?ADD_IF_LOWER_POS((a),(b)):ADD_IF_LOWER_NEG((a),(b))) #else /* WITH_SMOKE */ /* Stubs to use when smoke is disabled */ -struct WTURBULENCE *smoke_turbulence_init(int *UNUSED(res), int UNUSED(amplify), int UNUSED(noisetype)) { return NULL; } -// struct FLUID_3D *smoke_init(int *UNUSED(res), float *UNUSED(p0)) { return NULL; } +struct WTURBULENCE *smoke_turbulence_init(int *UNUSED(res), int UNUSED(amplify), int UNUSED(noisetype), int UNUSED(use_fire), int UNUSED(use_colors)) { return NULL; } +//struct FLUID_3D *smoke_init(int *UNUSED(res), float *UNUSED(dx), float *UNUSED(dtdef), int UNUSED(use_heat), int UNUSED(use_fire), int UNUSED(use_colors)) { return NULL; } void smoke_free(struct FLUID_3D *UNUSED(fluid)) {} float *smoke_get_density(struct FLUID_3D *UNUSED(fluid)) { return NULL; } void smoke_turbulence_free(struct WTURBULENCE *UNUSED(wt)) {} void smoke_initWaveletBlenderRNA(struct WTURBULENCE *UNUSED(wt), float *UNUSED(strength)) {} -void smoke_initBlenderRNA(struct FLUID_3D *UNUSED(fluid), float *UNUSED(alpha), float *UNUSED(beta), float *UNUSED(dt_factor), float *UNUSED(vorticity), int *UNUSED(border_colli)) {} -long long smoke_get_mem_req(int UNUSED(xres), int UNUSED(yres), int UNUSED(zres), int UNUSED(amplify)) { return 0; } -void smokeModifier_do(SmokeModifierData *UNUSED(smd), Scene *UNUSED(scene), Object *UNUSED(ob), DerivedMesh *UNUSED(dm)) {} +void smoke_initBlenderRNA(struct FLUID_3D *UNUSED(fluid), float *UNUSED(alpha), float *UNUSED(beta), float *UNUSED(dt_factor), float *UNUSED(vorticity), + int *UNUSED(border_colli), float *UNUSED(burning_rate), float *UNUSED(flame_smoke), float *UNUSED(flame_smoke_color), + float *UNUSED(flame_vorticity), float *UNUSED(flame_ignition_temp), float *UNUSED(flame_max_temp)) {} +struct DerivedMesh *smokeModifier_do(SmokeModifierData *UNUSED(smd), Scene *UNUSED(scene), Object *UNUSED(ob), DerivedMesh *UNUSED(dm)) { return NULL; } +float smoke_get_velocity_at(struct Object *UNUSED(ob), float UNUSED(position[3]), float UNUSED(velocity[3])) { return 0.0f; } +void flame_get_spectrum(unsigned char *UNUSED(spec), int UNUSED(width), float UNUSED(t1), float UNUSED(t2)) {} #endif /* WITH_SMOKE */ #ifdef WITH_SMOKE -static int smokeModifier_init (SmokeModifierData *smd, Object *ob, Scene *scene, DerivedMesh *dm) +void smoke_reallocate_fluid(SmokeDomainSettings *sds, float dx, int res[3], int free_old) +{ + int use_heat = (sds->active_fields & SM_ACTIVE_HEAT); + int use_fire = (sds->active_fields & (SM_ACTIVE_HEAT|SM_ACTIVE_FIRE)); + int use_colors = (sds->active_fields & SM_ACTIVE_COLORS); + + if (free_old && sds->fluid) + smoke_free(sds->fluid); + if (!MIN3(res[0],res[1],res[2])) { + sds->fluid = NULL; + return; + } + sds->fluid = smoke_init(res, dx, DT_DEFAULT, use_heat, use_fire, use_colors); + smoke_initBlenderRNA(sds->fluid, &(sds->alpha), &(sds->beta), &(sds->time_scale), &(sds->vorticity), &(sds->border_collisions), + &(sds->burning_rate), &(sds->flame_smoke), sds->flame_smoke_color, &(sds->flame_vorticity), &(sds->flame_ignition), &(sds->flame_max_temp)); + + /* reallocate shadow buffer */ + if (sds->shadow) + MEM_freeN(sds->shadow); + sds->shadow = MEM_callocN(sizeof(float) * res[0] * res[1] * res[2], "SmokeDomainShadow"); +} + +void smoke_reallocate_highres_fluid(SmokeDomainSettings *sds, float dx, int res[3], int free_old) +{ + int use_fire = (sds->active_fields & (SM_ACTIVE_HEAT|SM_ACTIVE_FIRE)); + int use_colors = (sds->active_fields & SM_ACTIVE_COLORS); + + if (free_old && sds->wt) + smoke_turbulence_free(sds->wt); + if (!MIN3(res[0],res[1],res[2])) { + sds->wt = NULL; + return; + } + sds->wt = smoke_turbulence_init(res, sds->amplify + 1, sds->noise, use_fire, use_colors); + sds->res_wt[0] = res[0] * (sds->amplify + 1); + sds->res_wt[1] = res[1] * (sds->amplify + 1); + sds->res_wt[2] = res[2] * (sds->amplify + 1); + sds->dx_wt = dx / (sds->amplify + 1); + smoke_initWaveletBlenderRNA(sds->wt, &(sds->strength)); +} + +/* convert global position to domain cell space */ +static void smoke_pos_to_cell(SmokeDomainSettings *sds, float pos[3]) +{ + mul_m4_v3(sds->imat, pos); + sub_v3_v3(pos, sds->p0); + pos[0] *= 1.0f/sds->cell_size[0]; + pos[1] *= 1.0f/sds->cell_size[1]; + pos[2] *= 1.0f/sds->cell_size[2]; +} + +/* set domain resolution and dimensions from object derivedmesh */ +static void smoke_set_domain_from_derivedmesh(SmokeDomainSettings *sds, Object *ob, DerivedMesh *dm) +{ + size_t i; + float min[3] = {FLT_MAX, FLT_MAX, FLT_MAX}, max[3] = {-FLT_MAX, -FLT_MAX, -FLT_MAX}; + float size[3]; + MVert *verts = dm->getVertArray(dm); + float scale = 0.0; + int res; + + res = sds->maxres; + + // get BB of domain + for(i = 0; i < dm->getNumVerts(dm); i++) + { + // min BB + min[0] = MIN2(min[0], verts[i].co[0]); + min[1] = MIN2(min[1], verts[i].co[1]); + min[2] = MIN2(min[2], verts[i].co[2]); + + // max BB + max[0] = MAX2(max[0], verts[i].co[0]); + max[1] = MAX2(max[1], verts[i].co[1]); + max[2] = MAX2(max[2], verts[i].co[2]); + } + + /* set domain bounds */ + copy_v3_v3(sds->p0, min); + copy_v3_v3(sds->p1, max); + sds->dx = 1.0f / res; + + /* calculate domain dimensions */ + sub_v3_v3v3(size, max, min); + copy_v3_v3(sds->cell_size, size); + mul_v3_v3(size, ob->size); + copy_v3_v3(sds->global_size, size); + copy_v3_v3(sds->dp0, min); + + invert_m4_m4(sds->imat, ob->obmat); + + // prevent crash when initializing a plane as domain + if((size[0] < FLT_EPSILON) || (size[1] < FLT_EPSILON) || (size[2] < FLT_EPSILON)) + return; + + /* define grid resolutions from longest domain side */ + if (size[0] > MAX2(size[1], size[2])) { + scale = res / size[0]; + sds->scale = size[0] / ob->size[0]; + sds->base_res[0] = res; + sds->base_res[1] = (int)(size[1] * scale + 0.5); + sds->base_res[2] = (int)(size[2] * scale + 0.5); + } + else if (size[1] > MAX2(size[0], size[2])) { + scale = res / size[1]; + sds->scale = size[1] / ob->size[1]; + sds->base_res[0] = (int)(size[0] * scale + 0.5); + sds->base_res[1] = res; + sds->base_res[2] = (int)(size[2] * scale + 0.5); + } + else { + scale = res / size[2]; + sds->scale = size[2] / ob->size[2]; + sds->base_res[0] = (int)(size[0] * scale + 0.5); + sds->base_res[1] = (int)(size[1] * scale + 0.5); + sds->base_res[2] = res; + } + + /* set cell size */ + sds->cell_size[0] /= (float)sds->base_res[0]; + sds->cell_size[1] /= (float)sds->base_res[1]; + sds->cell_size[2] /= (float)sds->base_res[2]; +} + +static int smokeModifier_init(SmokeModifierData *smd, Object *ob, Scene *scene, DerivedMesh *dm) { if((smd->type & MOD_SMOKE_TYPE_DOMAIN) && smd->domain && !smd->domain->fluid) { - size_t i; - float min[3] = {FLT_MAX, FLT_MAX, FLT_MAX}, max[3] = {-FLT_MAX, -FLT_MAX, -FLT_MAX}; - float size[3]; - MVert *verts = dm->getVertArray(dm); - float scale = 0.0; - int res; + SmokeDomainSettings *sds = smd->domain; + int res[3]; + /* set domain dimensions from derivedmesh */ + smoke_set_domain_from_derivedmesh(sds, ob, dm); + /* reset domain values */ + zero_v3_int(sds->shift); + zero_v3(sds->shift_f); + add_v3_fl(sds->shift_f, 0.5f); + zero_v3(sds->prev_loc); + mul_m4_v3(ob->obmat, sds->prev_loc); - res = smd->domain->maxres; - - // get BB of domain - for(i = 0; i < dm->getNumVerts(dm); i++) - { - float tmp[3]; - - copy_v3_v3(tmp, verts[i].co); - mul_m4_v3(ob->obmat, tmp); - - // min BB - min[0] = MIN2(min[0], tmp[0]); - min[1] = MIN2(min[1], tmp[1]); - min[2] = MIN2(min[2], tmp[2]); - - // max BB - max[0] = MAX2(max[0], tmp[0]); - max[1] = MAX2(max[1], tmp[1]); - max[2] = MAX2(max[2], tmp[2]); - } - - copy_v3_v3(smd->domain->p0, min); - copy_v3_v3(smd->domain->p1, max); - - // calc other res with max_res provided - sub_v3_v3v3(size, max, min); - - // prevent crash when initializing a plane as domain - if((size[0] < FLT_EPSILON) || (size[1] < FLT_EPSILON) || (size[2] < FLT_EPSILON)) - return 0; - - if(size[0] > size[1]) - { - if(size[0] > size[2]) - { - scale = res / size[0]; - smd->domain->scale = size[0]; - smd->domain->dx = 1.0f / res; - smd->domain->res[0] = res; - smd->domain->res[1] = (int)(size[1] * scale + 0.5); - smd->domain->res[2] = (int)(size[2] * scale + 0.5); - } - else { - scale = res / size[2]; - smd->domain->scale = size[2]; - smd->domain->dx = 1.0f / res; - smd->domain->res[2] = res; - smd->domain->res[0] = (int)(size[0] * scale + 0.5); - smd->domain->res[1] = (int)(size[1] * scale + 0.5); - } + /* set resolutions */ + if (smd->domain->flags & MOD_SMOKE_ADAPTIVE_DOMAIN) { + res[0] = res[1] = res[2] = 1; /* use minimum res for adaptive init */ } else { - if(size[1] > size[2]) - { - scale = res / size[1]; - smd->domain->scale = size[1]; - smd->domain->dx = 1.0f / res; - smd->domain->res[1] = res; - smd->domain->res[0] = (int)(size[0] * scale + 0.5); - smd->domain->res[2] = (int)(size[2] * scale + 0.5); - } - else { - scale = res / size[2]; - smd->domain->scale = size[2]; - smd->domain->dx = 1.0f / res; - smd->domain->res[2] = res; - smd->domain->res[0] = (int)(size[0] * scale + 0.5); - smd->domain->res[1] = (int)(size[1] * scale + 0.5); - } + VECCOPY(res, sds->base_res); } + VECCOPY(sds->res, res); + sds->total_cells = sds->res[0]*sds->res[1]*sds->res[2]; + sds->res_min[0] = sds->res_min[1] = sds->res_min[2] = 0; + VECCOPY(sds->res_max, res); - // TODO: put in failsafe if res<=0 - dg + /* allocate fluid */ + smoke_reallocate_fluid(sds, sds->dx, sds->res, 0); - // dt max is 0.1 - smd->domain->fluid = smoke_init(smd->domain->res, smd->domain->p0, DT_DEFAULT); smd->time = scene->r.cfra; - if(smd->domain->flags & MOD_SMOKE_HIGHRES) - { - smd->domain->wt = smoke_turbulence_init(smd->domain->res, smd->domain->amplify + 1, smd->domain->noise); - smd->domain->res_wt[0] = smd->domain->res[0] * (smd->domain->amplify + 1); - smd->domain->res_wt[1] = smd->domain->res[1] * (smd->domain->amplify + 1); - smd->domain->res_wt[2] = smd->domain->res[2] * (smd->domain->amplify + 1); - smd->domain->dx_wt = smd->domain->dx / (smd->domain->amplify + 1); + /* allocate highres fluid */ + if(sds->flags & MOD_SMOKE_HIGHRES) { + smoke_reallocate_highres_fluid(sds, sds->dx, sds->res, 0); } + /* allocate shadow buffer */ + if(!sds->shadow) + sds->shadow = MEM_callocN(sizeof(float) * sds->res[0] * sds->res[1] * sds->res[2], "SmokeDomainShadow"); - if(!smd->domain->shadow) - smd->domain->shadow = MEM_callocN(sizeof(float) * smd->domain->res[0] * smd->domain->res[1] * smd->domain->res[2], "SmokeDomainShadow"); - - smoke_initBlenderRNA(smd->domain->fluid, &(smd->domain->alpha), &(smd->domain->beta), &(smd->domain->time_scale), &(smd->domain->vorticity), &(smd->domain->border_collisions)); - - if(smd->domain->wt) - { - smoke_initWaveletBlenderRNA(smd->domain->wt, &(smd->domain->strength)); - } return 1; } else if((smd->type & MOD_SMOKE_TYPE_FLOW) && smd->flow) { - // handle flow object here - // XXX TODO - smd->time = scene->r.cfra; return 1; } else if((smd->type & MOD_SMOKE_TYPE_COLL)) { - // todo: delete this when loading colls work -dg - if(!smd->coll) { smokeModifier_createType(smd); } - if(!smd->coll->points) - { - // init collision points - SmokeCollSettings *scs = smd->coll; + smd->time = scene->r.cfra; - smd->time = scene->r.cfra; - - // copy obmat - copy_m4_m4(scs->mat, ob->obmat); - copy_m4_m4(scs->mat_old, ob->obmat); - - DM_ensure_tessface(dm); - fill_scs_points(ob, dm, scs); - } - - if(!smd->coll->bvhtree) - { - smd->coll->bvhtree = NULL; // bvhtree_build_from_smoke ( ob->obmat, dm->getTessFaceArray(dm), dm->getNumTessFaces(dm), dm->getVertArray(dm), dm->getNumVerts(dm), 0.0 ); - } return 1; } return 2; } -static void fill_scs_points(Object *ob, DerivedMesh *dm, SmokeCollSettings *scs) -{ - MVert *mvert = dm->getVertArray(dm); - MFace *mface = dm->getTessFaceArray(dm); - int i = 0, divs = 0; - - // DG TODO: need to do this dynamically according to the domain object! - float cell_len = scs->dx; - int newdivs = 0; - int quads = 0, facecounter = 0; - - // count quads - for(i = 0; i < dm->getNumTessFaces(dm); i++) - { - if(mface[i].v4) - quads++; - } - - scs->numtris = dm->getNumTessFaces(dm) + quads; - scs->tridivs = NULL; - calcTriangleDivs(ob, mvert, dm->getNumVerts(dm), mface, dm->getNumTessFaces(dm), scs->numtris, &(scs->tridivs), cell_len); - - // count triangle divisions - for(i = 0; i < dm->getNumTessFaces(dm) + quads; i++) - { - divs += (scs->tridivs[3 * i] + 1) * (scs->tridivs[3 * i + 1] + 1) * (scs->tridivs[3 * i + 2] + 1); - } - - scs->points = MEM_callocN(sizeof(float) * (dm->getNumVerts(dm) + divs) * 3, "SmokeCollPoints"); - scs->points_old = MEM_callocN(sizeof(float) * (dm->getNumVerts(dm) + divs) * 3, "SmokeCollPointsOld"); - - for(i = 0; i < dm->getNumVerts(dm); i++) - { - float tmpvec[3]; - copy_v3_v3(tmpvec, mvert[i].co); - // mul_m4_v3(ob->obmat, tmpvec); // DG: use local coordinates, we save MAT anyway - copy_v3_v3(&scs->points[i * 3], tmpvec); - } - - for(i = 0, facecounter = 0; i < dm->getNumTessFaces(dm); i++) - { - int again = 0; - do - { - int j, k; - int divs1 = scs->tridivs[3 * facecounter + 0]; - int divs2 = scs->tridivs[3 * facecounter + 1]; - //int divs3 = scs->tridivs[3 * facecounter + 2]; - float side1[3], side2[3], trinormorg[3], trinorm[3]; - - if(again == 1 && mface[i].v4) - { - sub_v3_v3v3(side1, mvert[ mface[i].v3 ].co, mvert[ mface[i].v1 ].co); - sub_v3_v3v3(side2, mvert[ mface[i].v4 ].co, mvert[ mface[i].v1 ].co); - } - else { - sub_v3_v3v3(side1, mvert[ mface[i].v2 ].co, mvert[ mface[i].v1 ].co); - sub_v3_v3v3(side2, mvert[ mface[i].v3 ].co, mvert[ mface[i].v1 ].co); - } - - cross_v3_v3v3(trinormorg, side1, side2); - normalize_v3(trinormorg); - copy_v3_v3(trinorm, trinormorg); - mul_v3_fl(trinorm, 0.25 * cell_len); - - for(j = 0; j <= divs1; j++) - { - for(k = 0; k <= divs2; k++) - { - float p1[3], p2[3], p3[3], p[3]={0,0,0}; - const float uf = (float)(j + TRI_UVOFFSET) / (float)(divs1 + 0.0); - const float vf = (float)(k + TRI_UVOFFSET) / (float)(divs2 + 0.0); - float tmpvec[3]; - - if(uf+vf > 1.0) - { - // printf("bigger - divs1: %d, divs2: %d\n", divs1, divs2); - continue; - } - - copy_v3_v3(p1, mvert[ mface[i].v1 ].co); - if(again == 1 && mface[i].v4) - { - copy_v3_v3(p2, mvert[ mface[i].v3 ].co); - copy_v3_v3(p3, mvert[ mface[i].v4 ].co); - } - else { - copy_v3_v3(p2, mvert[ mface[i].v2 ].co); - copy_v3_v3(p3, mvert[ mface[i].v3 ].co); - } - - mul_v3_fl(p1, (1.0-uf-vf)); - mul_v3_fl(p2, uf); - mul_v3_fl(p3, vf); - - add_v3_v3v3(p, p1, p2); - add_v3_v3(p, p3); - - if(newdivs > divs) - printf("mem problem\n"); - - // mMovPoints.push_back(p + trinorm); - add_v3_v3v3(tmpvec, p, trinorm); - // mul_m4_v3(ob->obmat, tmpvec); // DG: use local coordinates, we save MAT anyway - copy_v3_v3(&scs->points[3 * (dm->getNumVerts(dm) + newdivs)], tmpvec); - newdivs++; - - if(newdivs > divs) - printf("mem problem\n"); - - // mMovPoints.push_back(p - trinorm); - copy_v3_v3(tmpvec, p); - sub_v3_v3(tmpvec, trinorm); - // mul_m4_v3(ob->obmat, tmpvec); // DG: use local coordinates, we save MAT anyway - copy_v3_v3(&scs->points[3 * (dm->getNumVerts(dm) + newdivs)], tmpvec); - newdivs++; - } - } - - if(again == 0 && mface[i].v4) - again++; - else - again = 0; - - facecounter++; - - } while(again!=0); - } - - scs->numverts = dm->getNumVerts(dm); - // DG TODO: also save triangle count? - - scs->numpoints = dm->getNumVerts(dm) + newdivs; - - for(i = 0; i < scs->numpoints * 3; i++) - { - scs->points_old[i] = scs->points[i]; - } -} - - -static void fill_scs_points_anim(Object *UNUSED(ob), DerivedMesh *dm, SmokeCollSettings *scs) -{ - MVert *mvert = dm->getVertArray(dm); - MFace *mface = dm->getTessFaceArray(dm); - int quads = 0, numtris = 0, facecounter = 0; - unsigned int i = 0; - int divs = 0, newdivs = 0; - - // DG TODO: need to do this dynamically according to the domain object! - float cell_len = scs->dx; - - // count quads - for(i = 0; i < dm->getNumTessFaces(dm); i++) - { - if(mface[i].v4) - quads++; - } - - numtris = dm->getNumTessFaces(dm) + quads; - - // check if mesh changed topology - if(scs->numtris != numtris) - return; - if(scs->numverts != dm->getNumVerts(dm)) - return; - - // update new positions - for(i = 0; i < dm->getNumVerts(dm); i++) - { - float tmpvec[3]; - copy_v3_v3(tmpvec, mvert[i].co); - copy_v3_v3(&scs->points[i * 3], tmpvec); - } - - // for every triangle // update div points - for(i = 0, facecounter = 0; i < dm->getNumTessFaces(dm); i++) - { - int again = 0; - do - { - int j, k; - int divs1 = scs->tridivs[3 * facecounter + 0]; - int divs2 = scs->tridivs[3 * facecounter + 1]; - float srcside1[3], srcside2[3], destside1[3], destside2[3], src_trinormorg[3], dest_trinormorg[3], src_trinorm[3], dest_trinorm[3]; - - if(again == 1 && mface[i].v4) - { - sub_v3_v3v3(srcside1, &scs->points_old[mface[i].v3 * 3], &scs->points_old[mface[i].v1 * 3]); - sub_v3_v3v3(destside1, &scs->points[mface[i].v3 * 3], &scs->points[mface[i].v1 * 3]); - - sub_v3_v3v3(srcside2, &scs->points_old[mface[i].v4 * 3], &scs->points_old[mface[i].v1 * 3]); - sub_v3_v3v3(destside2, &scs->points[mface[i].v4 * 3], &scs->points[mface[i].v1 * 3]); - } - else { - sub_v3_v3v3(srcside1, &scs->points_old[mface[i].v2 * 3], &scs->points_old[mface[i].v1 * 3]); - sub_v3_v3v3(destside1, &scs->points[mface[i].v2 * 3], &scs->points[mface[i].v1 * 3]); - - sub_v3_v3v3(srcside2, &scs->points_old[mface[i].v3 * 3], &scs->points_old[mface[i].v1 * 3]); - sub_v3_v3v3(destside2, &scs->points[mface[i].v3 * 3], &scs->points[mface[i].v1 * 3]); - } - - cross_v3_v3v3(src_trinormorg, srcside1, srcside2); - cross_v3_v3v3(dest_trinormorg, destside1, destside2); - - normalize_v3(src_trinormorg); - normalize_v3(dest_trinormorg); - - copy_v3_v3(src_trinorm, src_trinormorg); - copy_v3_v3(dest_trinorm, dest_trinormorg); - - mul_v3_fl(src_trinorm, 0.25 * cell_len); - mul_v3_fl(dest_trinorm, 0.25 * cell_len); - - for(j = 0; j <= divs1; j++) - { - for(k = 0; k <= divs2; k++) - { - float src_p1[3], src_p2[3], src_p3[3], src_p[3]={0,0,0}; - float dest_p1[3], dest_p2[3], dest_p3[3], dest_p[3]={0,0,0}; - const float uf = (float)(j + TRI_UVOFFSET) / (float)(divs1 + 0.0); - const float vf = (float)(k + TRI_UVOFFSET) / (float)(divs2 + 0.0); - float src_tmpvec[3], dest_tmpvec[3]; - - if(uf+vf > 1.0) - { - // printf("bigger - divs1: %d, divs2: %d\n", divs1, divs2); - continue; - } - - copy_v3_v3(src_p1, &scs->points_old[mface[i].v1 * 3]); - copy_v3_v3(dest_p1, &scs->points[mface[i].v1 * 3]); - if(again == 1 && mface[i].v4) - { - copy_v3_v3(src_p2, &scs->points_old[mface[i].v3 * 3]); - copy_v3_v3(dest_p2, &scs->points[mface[i].v3 * 3]); - - copy_v3_v3(src_p3,&scs->points_old[mface[i].v4 * 3]); - copy_v3_v3(dest_p3, &scs->points[mface[i].v4 * 3]); - } - else { - copy_v3_v3(src_p2, &scs->points_old[mface[i].v2 * 3]); - copy_v3_v3(dest_p2, &scs->points[mface[i].v2 * 3]); - copy_v3_v3(src_p3, &scs->points_old[mface[i].v3 * 3]); - copy_v3_v3(dest_p3, &scs->points[mface[i].v3 * 3]); - } - - mul_v3_fl(src_p1, (1.0-uf-vf)); - mul_v3_fl(dest_p1, (1.0-uf-vf)); - - mul_v3_fl(src_p2, uf); - mul_v3_fl(dest_p2, uf); - - mul_v3_fl(src_p3, vf); - mul_v3_fl(dest_p3, vf); - - add_v3_v3v3(src_p, src_p1, src_p2); - add_v3_v3v3(dest_p, dest_p1, dest_p2); - - add_v3_v3(src_p, src_p3); - add_v3_v3(dest_p, dest_p3); - - if(newdivs > divs) - printf("mem problem\n"); - - // mMovPoints.push_back(p + trinorm); - add_v3_v3v3(src_tmpvec, src_p, src_trinorm); - add_v3_v3v3(dest_tmpvec, dest_p, dest_trinorm); - - // mul_m4_v3(ob->obmat, tmpvec); // DG: use local coordinates, we save MAT anyway - copy_v3_v3(&scs->points_old[3 * (dm->getNumVerts(dm) + newdivs)], src_tmpvec); - copy_v3_v3(&scs->points[3 * (dm->getNumVerts(dm) + newdivs)], dest_tmpvec); - newdivs++; - - if(newdivs > divs) - printf("mem problem\n"); - - // mMovPoints.push_back(p - trinorm); - copy_v3_v3(src_tmpvec, src_p); - copy_v3_v3(dest_tmpvec, dest_p); - - sub_v3_v3(src_tmpvec, src_trinorm); - sub_v3_v3(dest_tmpvec, dest_trinorm); - - // mul_m4_v3(ob->obmat, tmpvec); // DG: use local coordinates, we save MAT anyway - copy_v3_v3(&scs->points_old[3 * (dm->getNumVerts(dm) + newdivs)], src_tmpvec); - copy_v3_v3(&scs->points[3 * (dm->getNumVerts(dm) + newdivs)], dest_tmpvec); - newdivs++; - } - } - - if(again == 0 && mface[i].v4) - again++; - else - again = 0; - - facecounter++; - - } while(again!=0); - } - - // scs->numpoints = dm->getNumVerts(dm) + newdivs; - -} - -/*! init triangle divisions */ -static void calcTriangleDivs(Object *ob, MVert *verts, int UNUSED(numverts), MFace *faces, int numfaces, int numtris, int **tridivs, float cell_len) -{ - // mTriangleDivs1.resize( faces.size() ); - // mTriangleDivs2.resize( faces.size() ); - // mTriangleDivs3.resize( faces.size() ); - - size_t i = 0, facecounter = 0; - float maxscale[3] = {1,1,1}; // = channelFindMaxVf(mcScale); get max scale value - float maxpart = ABS(maxscale[0]); - float scaleFac = 0; - float fsTri = 0; - if(ABS(maxscale[1])>maxpart) maxpart = ABS(maxscale[1]); - if(ABS(maxscale[2])>maxpart) maxpart = ABS(maxscale[2]); - scaleFac = 1.0 / maxpart; - // featureSize = mLevel[mMaxRefine].nodeSize - fsTri = cell_len * 0.75 * scaleFac; // fsTri = cell_len * 0.9; - - if(*tridivs) - MEM_freeN(*tridivs); - - *tridivs = MEM_callocN(sizeof(int) * numtris * 3, "Smoke_Tridivs"); - - for(i = 0, facecounter = 0; i < numfaces; i++) - { - float p0[3], p1[3], p2[3]; - float side1[3]; - float side2[3]; - float side3[3]; - int divs1=0, divs2=0, divs3=0; - - copy_v3_v3(p0, verts[faces[i].v1].co); - mul_m4_v3(ob->obmat, p0); - copy_v3_v3(p1, verts[faces[i].v2].co); - mul_m4_v3(ob->obmat, p1); - copy_v3_v3(p2, verts[faces[i].v3].co); - mul_m4_v3(ob->obmat, p2); - - sub_v3_v3v3(side1, p1, p0); - sub_v3_v3v3(side2, p2, p0); - sub_v3_v3v3(side3, p1, p2); - - if(dot_v3v3(side1, side1) > fsTri*fsTri) - { - float tmp = normalize_v3(side1); - divs1 = (int)ceil(tmp/fsTri); - } - if(dot_v3v3(side2, side2) > fsTri*fsTri) - { - float tmp = normalize_v3(side2); - divs2 = (int)ceil(tmp/fsTri); - - /* - // debug - if(i==0) - printf("b tmp: %f, fsTri: %f, divs2: %d\n", tmp, fsTri, divs2); - */ - - } - - (*tridivs)[3 * facecounter + 0] = divs1; - (*tridivs)[3 * facecounter + 1] = divs2; - (*tridivs)[3 * facecounter + 2] = divs3; - - // TODO quad case - if(faces[i].v4) - { - divs1=0, divs2=0, divs3=0; - - facecounter++; - - copy_v3_v3(p0, verts[faces[i].v3].co); - mul_m4_v3(ob->obmat, p0); - copy_v3_v3(p1, verts[faces[i].v4].co); - mul_m4_v3(ob->obmat, p1); - copy_v3_v3(p2, verts[faces[i].v1].co); - mul_m4_v3(ob->obmat, p2); - - sub_v3_v3v3(side1, p1, p0); - sub_v3_v3v3(side2, p2, p0); - sub_v3_v3v3(side3, p1, p2); - - if(dot_v3v3(side1, side1) > fsTri*fsTri) - { - float tmp = normalize_v3(side1); - divs1 = (int)ceil(tmp/fsTri); - } - if(dot_v3v3(side2, side2) > fsTri*fsTri) - { - float tmp = normalize_v3(side2); - divs2 = (int)ceil(tmp/fsTri); - } - - (*tridivs)[3 * facecounter + 0] = divs1; - (*tridivs)[3 * facecounter + 1] = divs2; - (*tridivs)[3 * facecounter + 2] = divs3; - } - facecounter++; - } -} - #endif /* WITH_SMOKE */ static void smokeModifier_freeDomain(SmokeModifierData *smd) @@ -750,14 +381,8 @@ static void smokeModifier_freeFlow(SmokeModifierData *smd) { if(smd->flow) { -/* - if(smd->flow->bvh) - { - free_bvhtree_from_mesh(smd->flow->bvh); - MEM_freeN(smd->flow->bvh); - } - smd->flow->bvh = NULL; -*/ + if (smd->flow->dm) smd->flow->dm->release(smd->flow->dm); + if (smd->flow->verts_old) MEM_freeN(smd->flow->verts_old); MEM_freeN(smd->flow); smd->flow = NULL; } @@ -769,36 +394,18 @@ static void smokeModifier_freeCollision(SmokeModifierData *smd) { SmokeCollSettings *scs = smd->coll; - if(scs->numpoints) + if(scs->numverts) { - if(scs->points) + if(scs->verts_old) { - MEM_freeN(scs->points); - scs->points = NULL; - } - if(scs->points_old) - { - MEM_freeN(scs->points_old); - scs->points_old = NULL; - } - if(scs->tridivs) - { - MEM_freeN(scs->tridivs); - scs->tridivs = NULL; + MEM_freeN(scs->verts_old); + scs->verts_old = NULL; } } - if(scs->bvhtree) - { - BLI_bvhtree_free(scs->bvhtree); - scs->bvhtree = NULL; - } - -#ifdef USE_SMOKE_COLLISION_DM if(smd->coll->dm) smd->coll->dm->release(smd->coll->dm); smd->coll->dm = NULL; -#endif MEM_freeN(smd->coll); smd->coll = NULL; @@ -833,39 +440,23 @@ void smokeModifier_reset(struct SmokeModifierData *smd) smokeModifier_reset_turbulence(smd); smd->time = -1; - - // printf("reset domain end\n"); + smd->domain->total_cells = 0; + smd->domain->active_fields = 0; } else if(smd->flow) { - /* - if(smd->flow->bvh) - { - free_bvhtree_from_mesh(smd->flow->bvh); - MEM_freeN(smd->flow->bvh); - } - smd->flow->bvh = NULL; - */ + if (smd->flow->verts_old) MEM_freeN(smd->flow->verts_old); + smd->flow->verts_old = NULL; + smd->flow->numverts = 0; } else if(smd->coll) { SmokeCollSettings *scs = smd->coll; - if(scs->numpoints && scs->points) + if(scs->numverts && scs->verts_old) { - MEM_freeN(scs->points); - scs->points = NULL; - - if(scs->points_old) - { - MEM_freeN(scs->points_old); - scs->points_old = NULL; - } - if(scs->tridivs) - { - MEM_freeN(scs->tridivs); - scs->tridivs = NULL; - } + MEM_freeN(scs->verts_old); + scs->verts_old = NULL; } } } @@ -908,8 +499,7 @@ void smokeModifier_createType(struct SmokeModifierData *smd) smd->domain->fluid_group = NULL; smd->domain->coll_group = NULL; smd->domain->maxres = 32; - smd->domain->amplify = 1; - smd->domain->omega = 1.0; + smd->domain->amplify = 1; smd->domain->alpha = -0.001; smd->domain->beta = 0.1; smd->domain->time_scale = 1.0; @@ -919,7 +509,21 @@ void smokeModifier_createType(struct SmokeModifierData *smd) smd->domain->strength = 2.0; smd->domain->noise = MOD_SMOKE_NOISEWAVE; smd->domain->diss_speed = 5; - // init 3dview buffer + smd->domain->active_fields = 0; + + smd->domain->adapt_margin = 4; + smd->domain->adapt_res = 0; + smd->domain->adapt_threshold = 0.02f; + + smd->domain->burning_rate = 0.75f; + smd->domain->flame_smoke = 1.0f; + smd->domain->flame_vorticity = 0.5f; + smd->domain->flame_ignition = 1.25f; + smd->domain->flame_max_temp = 1.75f; + /* color */ + smd->domain->flame_smoke_color[0] = 0.7f; + smd->domain->flame_smoke_color[1] = 0.7f; + smd->domain->flame_smoke_color[2] = 0.7f; smd->domain->viewsettings = MOD_SMOKE_VIEW_SHOWBIG; smd->domain->effector_weights = BKE_add_effector_weights(NULL); @@ -934,11 +538,20 @@ void smokeModifier_createType(struct SmokeModifierData *smd) smd->flow->smd = smd; /* set some standard values */ - smd->flow->density = 1.0; - smd->flow->temp = 1.0; + smd->flow->density = 1.0f; + smd->flow->fuel_amount = 1.0f; + smd->flow->temp = 1.0f; smd->flow->flags = MOD_SMOKE_FLOW_ABSOLUTE; - smd->flow->vel_multi = 1.0; + smd->flow->vel_multi = 1.0f; + smd->flow->surface_distance = 1.5f; + smd->flow->source = MOD_SMOKE_FLOW_SOURCE_MESH; + smd->flow->texture_size = 1.0f; + smd->flow->color[0] = 0.7f; + smd->flow->color[1] = 0.7f; + smd->flow->color[2] = 0.7f; + + smd->flow->dm = NULL; smd->flow->psys = NULL; } @@ -950,15 +563,10 @@ void smokeModifier_createType(struct SmokeModifierData *smd) smd->coll = MEM_callocN(sizeof(SmokeCollSettings), "SmokeColl"); smd->coll->smd = smd; - smd->coll->points = NULL; - smd->coll->points_old = NULL; - smd->coll->tridivs = NULL; - smd->coll->vel = NULL; - smd->coll->numpoints = 0; - smd->coll->numtris = 0; - smd->coll->bvhtree = NULL; + smd->coll->verts_old = NULL; + smd->coll->numverts = 0; smd->coll->type = 0; // static obstacle - smd->coll->dx = 1.0f / 50.0f; + smd->coll->dm = NULL; #ifdef USE_SMOKE_COLLISION_DM smd->coll->dm = NULL; @@ -975,32 +583,61 @@ void smokeModifier_copy(struct SmokeModifierData *smd, struct SmokeModifierData smokeModifier_createType(tsmd); if (tsmd->domain) { - tsmd->domain->maxres = smd->domain->maxres; - tsmd->domain->amplify = smd->domain->amplify; - tsmd->domain->omega = smd->domain->omega; - tsmd->domain->alpha = smd->domain->alpha; - tsmd->domain->beta = smd->domain->beta; - tsmd->domain->flags = smd->domain->flags; - tsmd->domain->strength = smd->domain->strength; - tsmd->domain->noise = smd->domain->noise; - tsmd->domain->diss_speed = smd->domain->diss_speed; - tsmd->domain->viewsettings = smd->domain->viewsettings; tsmd->domain->fluid_group = smd->domain->fluid_group; tsmd->domain->coll_group = smd->domain->coll_group; + + tsmd->domain->adapt_margin = smd->domain->adapt_margin; + tsmd->domain->adapt_res = smd->domain->adapt_res; + tsmd->domain->adapt_threshold = smd->domain->adapt_threshold; + + tsmd->domain->alpha = smd->domain->alpha; + tsmd->domain->beta = smd->domain->beta; + tsmd->domain->amplify = smd->domain->amplify; + tsmd->domain->maxres = smd->domain->maxres; + tsmd->domain->flags = smd->domain->flags; + tsmd->domain->viewsettings = smd->domain->viewsettings; + tsmd->domain->noise = smd->domain->noise; + tsmd->domain->diss_speed = smd->domain->diss_speed; + tsmd->domain->strength = smd->domain->strength; + + tsmd->domain->border_collisions = smd->domain->border_collisions; tsmd->domain->vorticity = smd->domain->vorticity; tsmd->domain->time_scale = smd->domain->time_scale; - tsmd->domain->border_collisions = smd->domain->border_collisions; + + tsmd->domain->burning_rate = smd->domain->burning_rate; + tsmd->domain->flame_smoke = smd->domain->flame_smoke; + tsmd->domain->flame_vorticity = smd->domain->flame_vorticity; + tsmd->domain->flame_ignition = smd->domain->flame_ignition; + tsmd->domain->flame_max_temp = smd->domain->flame_max_temp; + copy_v3_v3(tsmd->domain->flame_smoke_color, smd->domain->flame_smoke_color); MEM_freeN(tsmd->domain->effector_weights); tsmd->domain->effector_weights = MEM_dupallocN(smd->domain->effector_weights); } else if (tsmd->flow) { - tsmd->flow->density = smd->flow->density; - tsmd->flow->temp = smd->flow->temp; tsmd->flow->psys = smd->flow->psys; - tsmd->flow->type = smd->flow->type; - tsmd->flow->flags = smd->flow->flags; + tsmd->flow->noise_texture = smd->flow->noise_texture; + tsmd->flow->vel_multi = smd->flow->vel_multi; + tsmd->flow->vel_normal = smd->flow->vel_normal; + tsmd->flow->vel_random = smd->flow->vel_random; + + tsmd->flow->density = smd->flow->density; + copy_v3_v3(tsmd->flow->color, smd->flow->color); + tsmd->flow->fuel_amount = smd->flow->fuel_amount; + tsmd->flow->temp = smd->flow->temp; + tsmd->flow->volume_density = smd->flow->volume_density; + tsmd->flow->surface_distance = smd->flow->surface_distance; + + tsmd->flow->texture_size = smd->flow->texture_size; + tsmd->flow->texture_offset = smd->flow->texture_offset; + BLI_strncpy(tsmd->flow->uvlayer_name, tsmd->flow->uvlayer_name, sizeof(tsmd->flow->uvlayer_name)); + tsmd->flow->vgroup_density = smd->flow->vgroup_density; + + tsmd->flow->type = smd->flow->type; + tsmd->flow->source = smd->flow->source; + tsmd->flow->texture_type = smd->flow->texture_type; + tsmd->flow->flags = smd->flow->flags; } else if (tsmd->coll) { ; @@ -1011,7 +648,7 @@ void smokeModifier_copy(struct SmokeModifierData *smd, struct SmokeModifierData #ifdef WITH_SMOKE // forward decleration -static void smoke_calc_transparency(float *result, float *input, float *p0, float *p1, int res[3], float dx, float *light, bresenham_callback cb, float correct); +static void smoke_calc_transparency(SmokeDomainSettings *sds, Scene *scene); static float calc_voxel_transp(float *result, float *input, int res[3], int *pixel, float *tRay, float correct); static int get_lamp(Scene *scene, float *light) @@ -1038,44 +675,127 @@ static int get_lamp(Scene *scene, float *light) return found_lamp; } -static void smoke_calc_domain(Scene *UNUSED(scene), Object *UNUSED(ob), SmokeModifierData *UNUSED(smd)) +static void obstacles_from_derivedmesh(Object *coll_ob, SmokeDomainSettings *sds, SmokeCollSettings *scs, unsigned char *obstacle_map, float *velocityX, float *velocityY, float *velocityZ, float dt) { -#if 0 - SmokeDomainSettings *sds = smd->domain; - GroupObject *go = NULL; - Base *base = NULL; - - /* do collisions, needs to be done before emission, so that smoke isn't emitted inside collision cells */ - if(1) + if (!scs->dm) return; { - unsigned int i; - Object **collobjs = NULL; - unsigned int numcollobj = 0; - collobjs = get_collisionobjects(scene, ob, sds->coll_group, &numcollobj); + DerivedMesh *dm = NULL; + MVert *mvert = NULL; + MFace *mface = NULL; + BVHTreeFromMesh treeData = {0}; + int numverts, i, z; + int *res = sds->res; + + float surface_distance = 0.6; + + float *vert_vel = NULL; + int has_velocity = 0; + + tstart(); + + dm = CDDM_copy(scs->dm); + CDDM_calc_normals(dm); + mvert = dm->getVertArray(dm); + mface = dm->getTessFaceArray(dm); + numverts = dm->getNumVerts(dm); + + // DG TODO + // if(scs->type > SM_COLL_STATIC) + // if line above is used, the code is in trouble if the object moves but is declared as "does not move" - for(i = 0; i < numcollobj; i++) { - Object *collob= collobjs[i]; - SmokeModifierData *smd2 = (SmokeModifierData*)modifiers_findByType(collob, eModifierType_Smoke); - - // check for active smoke modifier - // if(md && md->mode & (eModifierMode_Realtime | eModifierMode_Render)) - // SmokeModifierData *smd2 = (SmokeModifierData *)md; + vert_vel = MEM_callocN(sizeof(float) * numverts * 3, "smoke_obs_velocity"); - if((smd2->type & MOD_SMOKE_TYPE_COLL) && smd2->coll && smd2->coll->points && smd2->coll->points_old) - { - // ??? anything to do here? - - // TODO: only something to do for ANIMATED obstacles: need to update positions + if (scs->numverts != numverts || !scs->verts_old) { + if (scs->verts_old) MEM_freeN(scs->verts_old); + scs->verts_old = MEM_callocN(sizeof(float) * numverts * 3, "smoke_obs_verts_old"); + scs->numverts = numverts; + } + else { + has_velocity = 1; } } - if(collobjs) - MEM_freeN(collobjs); - } + /* Transform collider vertices to + * domain grid space for fast lookups */ + for (i = 0; i < numverts; i++) { + float n[3]; + float co[3]; -#endif + /* vert pos */ + mul_m4_v3(coll_ob->obmat, mvert[i].co); + smoke_pos_to_cell(sds, mvert[i].co); + + /* vert normal */ + normal_short_to_float_v3(n, mvert[i].no); + mul_mat3_m4_v3(coll_ob->obmat, n); + mul_mat3_m4_v3(sds->imat, n); + normalize_v3(n); + normal_float_to_short_v3(mvert[i].no, n); + + /* vert velocity */ + VECADD(co, mvert[i].co, sds->shift); + if (has_velocity) + { + sub_v3_v3v3(&vert_vel[i*3], co, &scs->verts_old[i*3]); + mul_v3_fl(&vert_vel[i*3], sds->dx/dt); + } + copy_v3_v3(&scs->verts_old[i*3], co); + } + + if (bvhtree_from_mesh_faces(&treeData, dm, 0.0f, 4, 6)) { + #pragma omp parallel for schedule(static) + for (z = sds->res_min[2]; z < sds->res_max[2]; z++) { + int x,y; + for (x = sds->res_min[0]; x < sds->res_max[0]; x++) + for (y = sds->res_min[1]; y < sds->res_max[1]; y++) { + int index = smoke_get_index(x-sds->res_min[0], sds->res[0], y-sds->res_min[1], sds->res[1], z-sds->res_min[2]); + + float ray_start[3] = {(float)x + 0.5f, (float)y + 0.5f, (float)z + 0.5f}; + BVHTreeNearest nearest = {0}; + nearest.index = -1; + nearest.dist = surface_distance * surface_distance; /* find_nearest uses squared distance */ + + /* find the nearest point on the mesh */ + if (BLI_bvhtree_find_nearest(treeData.tree, ray_start, &nearest, treeData.nearest_callback, &treeData) != -1) { + float weights[4]; + int v1, v2, v3, f_index = nearest.index; + + /* calculate barycentric weights for nearest point */ + v1 = mface[f_index].v1; + v2 = (nearest.flags & BVH_ONQUAD) ? mface[f_index].v3 : mface[f_index].v2; + v3 = (nearest.flags & BVH_ONQUAD) ? mface[f_index].v4 : mface[f_index].v3; + interp_weights_face_v3(weights, mvert[v1].co, mvert[v2].co, mvert[v3].co, NULL, nearest.co); + + // DG TODO + if(has_velocity) + { + /* apply object velocity */ + { + float hit_vel[3]; + interp_v3_v3v3v3(hit_vel, &vert_vel[v1*3], &vert_vel[v2*3], &vert_vel[v3*3], weights); + velocityX[index] += hit_vel[0]; + velocityY[index] += hit_vel[1]; + velocityZ[index] += hit_vel[2]; + } + } + + /* tag obstacle cells */ + obstacle_map[index] = 1; + + if(has_velocity) + obstacle_map[index] |= 8; + } + } + } + } + /* free bvh tree */ + free_bvhtree_from_mesh(&treeData); + dm->release(dm); + + if (vert_vel) MEM_freeN(vert_vel); + } } /* Animated obstacles: dx_step = ((x_new - x_old) / totalsteps) * substep */ @@ -1092,7 +812,12 @@ static void update_obstacles(Scene *scene, Object *ob, SmokeDomainSettings *sds, float *velxOrig = smoke_get_velocity_x(sds->fluid); float *velyOrig = smoke_get_velocity_y(sds->fluid); float *velzOrig = smoke_get_velocity_z(sds->fluid); - // float *density = smoke_get_density(sds->fluid); + float *density = smoke_get_density(sds->fluid); + float *fuel = smoke_get_fuel(sds->fluid); + float *flame = smoke_get_flame(sds->fluid); + float *r = smoke_get_color_r(sds->fluid); + float *g = smoke_get_color_g(sds->fluid); + float *b = smoke_get_color_b(sds->fluid); unsigned int z; smoke_get_ob_velocity(sds->fluid, &velx, &vely, &velz); @@ -1100,15 +825,6 @@ static void update_obstacles(Scene *scene, Object *ob, SmokeDomainSettings *sds, // TODO: delete old obstacle flags for(z = 0; z < sds->res[0] * sds->res[1] * sds->res[2]; z++) { - if(obstacles[z]) - { - // density[z] = 0; - - velxOrig[z] = 0; - velyOrig[z] = 0; - velzOrig[z] = 0; - } - if(obstacles[z] & 8) // Do not delete static obstacles { obstacles[z] = 0; @@ -1119,6 +835,7 @@ static void update_obstacles(Scene *scene, Object *ob, SmokeDomainSettings *sds, velz[z] = 0; } + collobjs = get_collisionobjects(scene, ob, sds->coll_group, &numcollobj, eModifierType_Smoke); // update obstacle tags in cells @@ -1129,105 +846,799 @@ static void update_obstacles(Scene *scene, Object *ob, SmokeDomainSettings *sds, // DG TODO: check if modifier is active? - if((smd2->type & MOD_SMOKE_TYPE_COLL) && smd2->coll && smd2->coll->points && smd2->coll->points_old) + if((smd2->type & MOD_SMOKE_TYPE_COLL) && smd2->coll) { SmokeCollSettings *scs = smd2->coll; - unsigned int i; - - /* - // DG TODO: support static cobstacles, but basicly we could even support static + rigid with one set of code - if(scs->type > SM_COLL_STATIC) - */ - - /* Handle collisions */ - for(i = 0; i < scs->numpoints; i++) - { - // 1. get corresponding cell - int cell[3]; - float pos[3], oldpos[3], vel[3]; - float cPos[3], cOldpos[3]; /* current position in substeps */ - int badcell = 0; - size_t index; - int j; - - // translate local points into global positions - copy_v3_v3(cPos, &scs->points[3 * i]); - mul_m4_v3(scs->mat, cPos); - copy_v3_v3(pos, cPos); - - copy_v3_v3(cOldpos, &scs->points_old[3 * i]); - mul_m4_v3(scs->mat_old, cOldpos); - copy_v3_v3(oldpos, cOldpos); - - /* support for rigid bodies, armatures etc */ - { - float tmp[3]; - - /* x_current = x_old + (x_new - x_old) * step_current / steps_total */ - float mulStep = (float)(((float)substep) / ((float)totalsteps)); - - sub_v3_v3v3(tmp, cPos, cOldpos); - mul_v3_fl(tmp, mulStep); - add_v3_v3(cOldpos, tmp); - } - - sub_v3_v3v3(vel, pos, oldpos); - /* Scale velocity to incorperate the object movement during this step */ - mul_v3_fl(vel, 1.0 / (totalsteps * dt * sds->scale)); - // mul_v3_fl(vel, 1.0 / dt); - - // DG TODO: cap velocity to maxVelMag (or maxvel) - - // oldpos + velocity * dt = newpos - get_cell(sds->p0, sds->res, sds->dx*sds->scale, cOldpos /* use current position here instead of "pos" */, cell, 0); - - // check if cell is valid (in the domain boundary) - for(j = 0; j < 3; j++) - if((cell[j] > sds->res[j] - 1) || (cell[j] < 0)) - { - badcell = 1; - break; - } - - if(badcell) - continue; - - // 2. set cell values (heat, density and velocity) - index = smoke_get_index(cell[0], sds->res[0], cell[1], sds->res[1], cell[2]); - - // Don't overwrite existing obstacles - if(obstacles[index]) - continue; - - // printf("cell[0]: %d, cell[1]: %d, cell[2]: %d\n", cell[0], cell[1], cell[2]); - // printf("res[0]: %d, res[1]: %d, res[2]: %d, index: %d\n\n", sds->res[0], sds->res[1], sds->res[2], index); - obstacles[index] = 1 | 8 /* ANIMATED */; - - if(len_v3(vel) > FLT_EPSILON) - { - // Collision object is moving - - velx[index] = vel[0]; // use "+="? - vely[index] = vel[1]; - velz[index] = vel[2]; - } - } + obstacles_from_derivedmesh(collob, sds, scs, obstacles, velx, vely, velz, dt); } } if(collobjs) MEM_freeN(collobjs); + + /* obstacle cells should not contain any velocity from the smoke simulation */ + for(z = 0; z < sds->res[0] * sds->res[1] * sds->res[2]; z++) + { + if(obstacles[z]) + { + velxOrig[z] = 0; + velyOrig[z] = 0; + velzOrig[z] = 0; + density[z] = 0; + if (fuel) { + fuel[z] = 0; + flame[z] = 0; + } + if (r) { + r[z] = 0; + g[z] = 0; + b[z] = 0; + } + } + } } -static void update_flowsfluids(Scene *scene, Object *ob, SmokeDomainSettings *sds, float time) + +typedef struct EmissionMap { + float *influence; + float *velocity; + int min[3], max[3], res[3]; + int total_cells, valid; +} EmissionMap; + +static void em_boundInsert(EmissionMap *em, float point[3]) +{ + int i = 0; + if (!em->valid) { + VECCOPY(em->min, point); + VECCOPY(em->max, point); + em->valid = 1; + } + else { + for (; i < 3; i++) { + if (point[i] < em->min[i]) em->min[i] = (int)floor(point[i]); + if (point[i] > em->max[i]) em->max[i] = (int)ceil(point[i]); + } + } +} + +static void clampBoundsInDomain(SmokeDomainSettings *sds, int min[3], int max[3], float *min_vel, float *max_vel, int margin, float dt) +{ + int i; + for (i=0; i<3; i++) { + int adapt = (sds->flags & MOD_SMOKE_ADAPTIVE_DOMAIN) ? sds->adapt_res : 0; + /* add margin */ + min[i] -= margin; + max[i] += margin; + + /* adapt to velocity */ + if (min_vel && min_vel[i]<0.0f) { + min[i] += (int)ceil(min_vel[i] * dt); + } + if (max_vel && max_vel[i]>0.0f) { + max[i] += (int)ceil(max_vel[i] * dt); + } + + /* clamp within domain max size */ + CLAMP(min[i], -adapt, sds->base_res[i]+adapt); + CLAMP(max[i], -adapt, sds->base_res[i]+adapt); + } +} + +static void em_allocateData(EmissionMap *em, int use_velocity) { + int i, res[3]; + + for (i=0; i<3; i++) { + res[i] = em->max[i] - em->min[i]; + if (res[i] <= 0) + return; + } + em->total_cells = res[0]*res[1]*res[2]; + copy_v3_v3_int(em->res, res); + + + em->influence = MEM_callocN(sizeof(float) * em->total_cells, "smoke_flow_influence"); + if (use_velocity) + em->velocity = MEM_callocN(sizeof(float) * em->total_cells * 3, "smoke_flow_velocity"); +} + +static void em_freeData(EmissionMap *em) { + if (em->influence) + MEM_freeN(em->influence); + if (em->velocity) + MEM_freeN(em->velocity); +} + + +static void emit_from_particles(Object *flow_ob, SmokeDomainSettings *sds, SmokeFlowSettings *sfs, EmissionMap *em, Scene *scene, float time, float dt) +{ + if(sfs && sfs->psys && sfs->psys->part && sfs->psys->part->type==PART_EMITTER) // is particle system selected + { + ParticleSimulationData sim; + ParticleSystem *psys = sfs->psys; + float *particle_pos; + float *particle_vel; + int totpart=psys->totpart, totchild; + int p = 0; + int valid_particles = 0; + + sim.scene = scene; + sim.ob = flow_ob; + sim.psys = psys; + + if(psys->part->type==PART_HAIR) + { + // TODO: PART_HAIR not supported whatsoever + totchild=0; + } + else + totchild=psys->totchild*psys->part->disp/100; + + particle_pos = MEM_callocN(sizeof(float) * (totpart+totchild) * 3, "smoke_flow_particles"); + particle_vel = MEM_callocN(sizeof(float) * (totpart+totchild) * 3, "smoke_flow_particles"); + + /* calculate local position for each particle */ + for(p=0; pparticles[p].flag & (PARS_NO_DISP|PARS_UNEXIST)) + continue; + } + else { + /* handle child particle */ + ChildParticle *cpa = &psys->child[p - totpart]; + if(psys->particles[cpa->parent].flag & (PARS_NO_DISP|PARS_UNEXIST)) + continue; + } + + state.time = time; + if(psys_get_particle_state(&sim, p, &state, 0) == 0) + continue; + + /* location */ + pos = &particle_pos[valid_particles*3]; + copy_v3_v3(pos, state.co); + smoke_pos_to_cell(sds, pos); + + /* velocity */ + copy_v3_v3(&particle_vel[valid_particles*3], state.vel); + mul_mat3_m4_v3(sds->imat, &particle_vel[valid_particles*3]); + + /* calculate emission map bounds */ + em_boundInsert(em, pos); + valid_particles++; + } + + /* set emission map */ + clampBoundsInDomain(sds, em->min, em->max, NULL, NULL, 1, dt); + em_allocateData(em, sfs->flags & MOD_SMOKE_FLOW_INITVELOCITY); + + for(p=0; pmin[0]; + cell[1] = floor(particle_pos[p*3+1]) - em->min[1]; + cell[2] = floor(particle_pos[p*3+2]) - em->min[2]; + /* check if cell is valid (in the domain boundary) */ + for(i = 0; i < 3; i++) { + if((cell[i] > em->res[i] - 1) || (cell[i] < 0)) { + badcell = 1; + break; + } + } + if(badcell) + continue; + /* get cell index */ + index = smoke_get_index(cell[0], em->res[0], cell[1], em->res[1], cell[2]); + /* Add influence to emission map */ + em->influence[index] = 1.0f; + /* Uses particle velocity as initial velocity for smoke */ + if(sfs->flags & MOD_SMOKE_FLOW_INITVELOCITY && (psys->part->phystype != PART_PHYS_NO)) + { + VECADDFAC(&em->velocity[index*3], &em->velocity[index*3], &particle_vel[p*3], sfs->vel_multi); + } + } // particles loop + + /* free data */ + if (particle_pos) + MEM_freeN(particle_pos); + if (particle_vel) + MEM_freeN(particle_vel); + } +} + +static void get_texture_value(Tex *texture, float *tex_co, TexResult *texres) +{ + int result_type; + + /* no node textures for now */ + result_type = multitex_ext_safe(texture, tex_co, texres); + + /* if the texture gave an RGB value, we assume it didn't give a valid + * intensity, since this is in the context of modifiers don't use perceptual color conversion. + * if the texture didn't give an RGB value, copy the intensity across + */ + if (result_type & TEX_RGB) { + texres->tin = (1.0f / 3.0f) * (texres->tr + texres->tg + texres->tb); + } + else { + copy_v3_fl(&texres->tr, texres->tin); + } +} + +static void emit_from_derivedmesh(Object *flow_ob, SmokeDomainSettings *sds, SmokeFlowSettings *sfs, EmissionMap *em, float dt) +{ + if (!sfs->dm) return; + { + DerivedMesh *dm = sfs->dm; + int defgrp_index = sfs->vgroup_density-1; + MDeformVert *dvert = NULL; + MVert *mvert = NULL; + MVert *mvert_orig = NULL; + MFace *mface = NULL; + MTFace *tface = NULL; + BVHTreeFromMesh treeData = {0}; + int numOfVerts, i, z; + float flow_center[3] = {0}; + + float *vert_vel = NULL; + int has_velocity = 0; + + CDDM_calc_normals(dm); + mvert = dm->getVertArray(dm); + mvert_orig = dm->dupVertArray(dm); /* copy original mvert and restore when done */ + mface = dm->getTessFaceArray(dm); + numOfVerts = dm->getNumVerts(dm); + dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT); + tface = CustomData_get_layer_named(&dm->faceData, CD_MTFACE, sfs->uvlayer_name); + + if (sfs->flags & MOD_SMOKE_FLOW_INITVELOCITY) { + vert_vel = MEM_callocN(sizeof(float) * numOfVerts * 3, "smoke_flow_velocity"); + + if (sfs->numverts != numOfVerts || !sfs->verts_old) { + if (sfs->verts_old) MEM_freeN(sfs->verts_old); + sfs->verts_old = MEM_callocN(sizeof(float) * numOfVerts * 3, "smoke_flow_verts_old"); + sfs->numverts = numOfVerts; + } + else { + has_velocity = 1; + } + } + + /* Transform dm vertices to + * domain grid space for fast lookups */ + for (i = 0; i < numOfVerts; i++) { + float n[3]; + /* vert pos */ + mul_m4_v3(flow_ob->obmat, mvert[i].co); + smoke_pos_to_cell(sds, mvert[i].co); + /* vert normal */ + normal_short_to_float_v3(n, mvert[i].no); + mul_mat3_m4_v3(flow_ob->obmat, n); + mul_mat3_m4_v3(sds->imat, n); + normalize_v3(n); + normal_float_to_short_v3(mvert[i].no, n); + /* vert velocity */ + if (sfs->flags & MOD_SMOKE_FLOW_INITVELOCITY) { + float co[3]; + VECADD(co, mvert[i].co, sds->shift); + if (has_velocity) { + sub_v3_v3v3(&vert_vel[i*3], co, &sfs->verts_old[i*3]); + mul_v3_fl(&vert_vel[i*3], sds->dx/dt); + } + copy_v3_v3(&sfs->verts_old[i*3], co); + } + + /* calculate emission map bounds */ + em_boundInsert(em, mvert[i].co); + } + mul_m4_v3(flow_ob->obmat, flow_center); + smoke_pos_to_cell(sds, flow_center); + + /* set emission map */ + clampBoundsInDomain(sds, em->min, em->max, NULL, NULL, sfs->surface_distance, dt); + em_allocateData(em, sfs->flags & MOD_SMOKE_FLOW_INITVELOCITY); + + if (bvhtree_from_mesh_faces(&treeData, dm, 0.0f, 4, 6)) { + #pragma omp parallel for schedule(static) + for (z = em->min[2]; z < em->max[2]; z++) { + int x,y; + for (x = em->min[0]; x < em->max[0]; x++) + for (y = em->min[1]; y < em->max[1]; y++) { + int index = smoke_get_index(x-em->min[0], em->res[0], y-em->min[1], em->res[1], z-em->min[2]); + + float ray_start[3] = {(float)x + 0.5f, (float)y + 0.5f, (float)z + 0.5f}; + float ray_dir[3] = {1.0f, 0.0f, 0.0f}; + + BVHTreeRayHit hit = {0}; + BVHTreeNearest nearest = {0}; + + float volume_factor = 0.0f; + float sample_str = 0.0f; + + hit.index = -1; + hit.dist = 9999; + nearest.index = -1; + nearest.dist = sfs->surface_distance * sfs->surface_distance; /* find_nearest uses squared distance */ + + /* Check volume collision */ + if (sfs->volume_density) { + if (BLI_bvhtree_ray_cast(treeData.tree, ray_start, ray_dir, 0.0f, &hit, treeData.raycast_callback, &treeData) != -1) { + float dot = ray_dir[0] * hit.no[0] + ray_dir[1] * hit.no[1] + ray_dir[2] * hit.no[2]; + /* If ray and hit face normal are facing same direction + * hit point is inside a closed mesh. */ + if (dot >= 0) { + /* Also cast a ray in opposite direction to make sure + * point is at least surrounded by two faces */ + negate_v3(ray_dir); + hit.index = -1; + hit.dist = 9999; + + BLI_bvhtree_ray_cast(treeData.tree, ray_start, ray_dir, 0.0f, &hit, treeData.raycast_callback, &treeData); + if (hit.index != -1) { + volume_factor = sfs->volume_density; + nearest.dist = hit.dist*hit.dist; + } + } + } + } + + /* find the nearest point on the mesh */ + if (BLI_bvhtree_find_nearest(treeData.tree, ray_start, &nearest, treeData.nearest_callback, &treeData) != -1) { + float weights[4]; + int v1, v2, v3, f_index = nearest.index; + float n1[3], n2[3], n3[3], hit_normal[3]; + + /* emit from surface based on distance */ + if (sfs->surface_distance) { + sample_str = sqrtf(nearest.dist) / sfs->surface_distance; + CLAMP(sample_str, 0.0f, 1.0f); + sample_str = pow(1.0f - sample_str, 0.5f); + } + else + sample_str = 0.0f; + + /* calculate barycentric weights for nearest point */ + v1 = mface[f_index].v1; + v2 = (nearest.flags & BVH_ONQUAD) ? mface[f_index].v3 : mface[f_index].v2; + v3 = (nearest.flags & BVH_ONQUAD) ? mface[f_index].v4 : mface[f_index].v3; + interp_weights_face_v3(weights, mvert[v1].co, mvert[v2].co, mvert[v3].co, NULL, nearest.co); + + if(sfs->flags & MOD_SMOKE_FLOW_INITVELOCITY) { + /* apply normal directional velocity */ + if (sfs->vel_normal) { + /* interpolate vertex normal vectors to get nearest point normal */ + normal_short_to_float_v3(n1, mvert[v1].no); + normal_short_to_float_v3(n2, mvert[v2].no); + normal_short_to_float_v3(n3, mvert[v3].no); + interp_v3_v3v3v3(hit_normal, n1, n2, n3, weights); + normalize_v3(hit_normal); + /* apply normal directional and random velocity + * - TODO: random disabled for now since it doesnt really work well as pressure calc smoothens it out... */ + em->velocity[index*3] += hit_normal[0]*sfs->vel_normal * 0.25f; + em->velocity[index*3+1] += hit_normal[1]*sfs->vel_normal * 0.25f; + em->velocity[index*3+2] += hit_normal[2]*sfs->vel_normal * 0.25f; + /* TODO: for fire emitted from mesh surface we can use + * Vf = Vs + (Ps/Pf - 1)*S to model gaseous expansion from solid to fuel */ + } + /* apply object velocity */ + if (has_velocity && sfs->vel_multi) { + float hit_vel[3]; + interp_v3_v3v3v3(hit_vel, &vert_vel[v1*3], &vert_vel[v2*3], &vert_vel[v3*3], weights); + em->velocity[index*3] += hit_vel[0] * sfs->vel_multi; + em->velocity[index*3+1] += hit_vel[1] * sfs->vel_multi; + em->velocity[index*3+2] += hit_vel[2] * sfs->vel_multi; + } + } + + /* apply vertex group influence if used */ + if (defgrp_index >= 0 && dvert) { + float weight_mask = defvert_find_weight(&dvert[v1], defgrp_index) * weights[0] + + defvert_find_weight(&dvert[v2], defgrp_index) * weights[1] + + defvert_find_weight(&dvert[v3], defgrp_index) * weights[2]; + sample_str *= weight_mask; + } + + /* apply emission texture */ + if ((sfs->flags & MOD_SMOKE_FLOW_TEXTUREEMIT) && sfs->noise_texture) { + float tex_co[3] = {0}; + TexResult texres; + + if (sfs->texture_type == MOD_SMOKE_FLOW_TEXTURE_MAP_AUTO) { + tex_co[0] = ((float)(x - flow_center[0]) / sds->base_res[0]) / sfs->texture_size; + tex_co[1] = ((float)(y - flow_center[1]) / sds->base_res[1]) / sfs->texture_size; + tex_co[2] = ((float)(z - flow_center[2]) / sds->base_res[2] - sfs->texture_offset) / sfs->texture_size; + } + else if (tface) { + interp_v2_v2v2v2(tex_co, tface[f_index].uv[0], tface[f_index].uv[(nearest.flags & BVH_ONQUAD) ? 2 : 1], + tface[f_index].uv[(nearest.flags & BVH_ONQUAD) ? 3 : 2], weights); + /* map between -1.0f and 1.0f */ + tex_co[0] = tex_co[0] * 2.0f - 1.0f; + tex_co[1] = tex_co[1] * 2.0f - 1.0f; + tex_co[2] = sfs->texture_offset; + } + texres.nor = NULL; + get_texture_value(sfs->noise_texture, tex_co, &texres); + sample_str *= texres.tin; + } + } + + /* multiply initial velocity by emitter influence */ + if(sfs->flags & MOD_SMOKE_FLOW_INITVELOCITY) { + mul_v3_fl(&em->velocity[index*3], sample_str); + } + + /* apply final influence based on volume factor */ + em->influence[index] = MAX2(volume_factor, sample_str); + } + } + } + /* free bvh tree */ + free_bvhtree_from_mesh(&treeData); + /* restore original mverts */ + CustomData_set_layer(&dm->vertData, CD_MVERT, mvert_orig); + if (mvert) + MEM_freeN(mvert); + + if (vert_vel) MEM_freeN(vert_vel); + } +} + +static void adjustDomainResolution(SmokeDomainSettings *sds, int new_shift[3], EmissionMap *emaps, unsigned int numflowobj, float dt) +{ + int min[3]={32767,32767,32767}, max[3]={-32767,-32767,-32767}, res[3]; + int total_cells = 1, res_changed = 0, shift_changed = 0; + float min_vel[3], max_vel[3]; + int x,y,z, i; + float *density = smoke_get_density(sds->fluid); + float *fuel = smoke_get_fuel(sds->fluid); + float *vx = smoke_get_velocity_x(sds->fluid); + float *vy = smoke_get_velocity_y(sds->fluid); + float *vz = smoke_get_velocity_z(sds->fluid); + + INIT_MINMAX(min_vel, max_vel); + + /* Calculate bounds for current domain content */ + for(x = sds->res_min[0]; x < sds->res_max[0]; x++) + for(y = sds->res_min[1]; y < sds->res_max[1]; y++) + for(z = sds->res_min[2]; z < sds->res_max[2]; z++) + { + int xn = x-new_shift[0]; + int yn = y-new_shift[1]; + int zn = z-new_shift[2]; + int index = smoke_get_index(x-sds->res_min[0], sds->res[0], y-sds->res_min[1], sds->res[1], z-sds->res_min[2]); + float max_den = (fuel) ? MAX2(density[index], fuel[index]) : density[index]; + + /* content bounds (use shifted coordinates) */ + if (max_den >= sds->adapt_threshold) { + if (min[0] > xn) min[0] = xn; + if (min[1] > yn) min[1] = yn; + if (min[2] > zn) min[2] = zn; + if (max[0] < xn) max[0] = xn; + if (max[1] < yn) max[1] = yn; + if (max[2] < zn) max[2] = zn; + } + /* velocity bounds */ + if (min_vel[0] > vx[index]) min_vel[0] = vx[index]; + if (min_vel[1] > vy[index]) min_vel[1] = vy[index]; + if (min_vel[2] > vz[index]) min_vel[2] = vz[index]; + if (max_vel[0] < vx[index]) max_vel[0] = vx[index]; + if (max_vel[1] < vy[index]) max_vel[1] = vy[index]; + if (max_vel[2] < vz[index]) max_vel[2] = vz[index]; + } + + /* also apply emission maps */ + for(i = 0; i < numflowobj; i++) + { + EmissionMap *em = &emaps[i]; + + for(x = em->min[0]; x < em->max[0]; x++) + for(y = em->min[1]; y < em->max[1]; y++) + for(z = em->min[2]; z < em->max[2]; z++) + { + int index = smoke_get_index(x-em->min[0], em->res[0], y-em->min[1], em->res[1], z-em->min[2]); + float max_den = em->influence[index]; + + /* density bounds */ + if (max_den >= sds->adapt_threshold) { + if (min[0] > x) min[0] = x; + if (min[1] > y) min[1] = y; + if (min[2] > z) min[2] = z; + if (max[0] < x) max[0] = x; + if (max[1] < y) max[1] = y; + if (max[2] < z) max[2] = z; + } + /* velocity bounds */ + if (em->velocity) { + if (min_vel[0] > em->velocity[index*3]) min_vel[0] = em->velocity[index*3]; + if (min_vel[1] > em->velocity[index*3+1]) min_vel[1] = em->velocity[index*3+1]; + if (min_vel[2] > em->velocity[index*3+2]) min_vel[2] = em->velocity[index*3+2]; + if (max_vel[0] < em->velocity[index*3]) max_vel[0] = em->velocity[index*3]; + if (max_vel[1] < em->velocity[index*3+1]) max_vel[1] = em->velocity[index*3+1]; + if (max_vel[2] < em->velocity[index*3+2]) max_vel[2] = em->velocity[index*3+2]; + } + } + } + + /* calculate new bounds based on these values */ + clampBoundsInDomain(sds, min, max, min_vel, max_vel, sds->adapt_margin+1, dt); + + for (i=0; i<3; i++) { + /* calculate new resolution */ + res[i] = max[i] - min[i]; + total_cells *= res[i]; + + if (new_shift[i]) + shift_changed = 1; + + /* if no content set minimum dimensions */ + if (res[i] <= 0) { + int j; + for (j=0; j<3; j++) { + min[j] = 0; + max[j] = 1; + res[j] = 1; + } + res_changed = 1; + total_cells = 1; + break; + } + if (min[i] != sds->res_min[i] || max[i] != sds->res_max[i]) + res_changed = 1; + } + + if (res_changed || shift_changed) { + struct FLUID_3D *fluid_old = sds->fluid; + struct WTURBULENCE *turb_old = sds->wt; + /* allocate new fluid data */ + smoke_reallocate_fluid(sds, sds->dx, res, 0); + if(sds->flags & MOD_SMOKE_HIGHRES) { + smoke_reallocate_highres_fluid(sds, sds->dx, res, 0); + } + + /* copy values from old fluid to new */ + if (sds->total_cells>1 && total_cells>1) { + /* low res smoke */ + float *o_dens, *o_react, *o_flame, *o_fuel, *o_heat, *o_heatold, *o_vx, *o_vy, *o_vz, *o_r, *o_g, *o_b; + float *n_dens, *n_react, *n_flame, *n_fuel, *n_heat, *n_heatold, *n_vx, *n_vy, *n_vz, *n_r, *n_g, *n_b; + float dummy; + unsigned char *dummy_p; + /* high res smoke */ + int wt_res_old[3]; + float *o_wt_dens, *o_wt_react, *o_wt_flame, *o_wt_fuel, *o_wt_tcu, *o_wt_tcv, *o_wt_tcw, *o_wt_r, *o_wt_g, *o_wt_b; + float *n_wt_dens, *n_wt_react, *n_wt_flame, *n_wt_fuel, *n_wt_tcu, *n_wt_tcv, *n_wt_tcw, *n_wt_r, *n_wt_g, *n_wt_b; + + smoke_export(fluid_old, &dummy, &dummy, &o_dens, &o_react, &o_flame, &o_fuel, &o_heat, &o_heatold, &o_vx, &o_vy, &o_vz, &o_r, &o_g, &o_b, &dummy_p); + smoke_export(sds->fluid, &dummy, &dummy, &n_dens, &n_react, &n_flame, &n_fuel, &n_heat, &n_heatold, &n_vx, &n_vy, &n_vz, &n_r, &n_g, &n_b, &dummy_p); + + if(sds->flags & MOD_SMOKE_HIGHRES) { + smoke_turbulence_export(turb_old, &o_wt_dens, &o_wt_react, &o_wt_flame, &o_wt_fuel, &o_wt_r, &o_wt_g, &o_wt_b, &o_wt_tcu, &o_wt_tcv, &o_wt_tcw); + smoke_turbulence_get_res(turb_old, wt_res_old); + smoke_turbulence_export(sds->wt, &n_wt_dens, &n_wt_react, &n_wt_flame, &n_wt_fuel, &n_wt_r, &n_wt_g, &n_wt_b, &n_wt_tcu, &n_wt_tcv, &n_wt_tcw); + } + + + for(x = sds->res_min[0]; x < sds->res_max[0]; x++) + for(y = sds->res_min[1]; y < sds->res_max[1]; y++) + for(z = sds->res_min[2]; z < sds->res_max[2]; z++) + { + /* old grid index */ + int xo = x-sds->res_min[0]; + int yo = y-sds->res_min[1]; + int zo = z-sds->res_min[2]; + int index_old = smoke_get_index(xo, sds->res[0], yo, sds->res[1], zo); + /* new grid index */ + int xn = x-min[0]-new_shift[0]; + int yn = y-min[1]-new_shift[1]; + int zn = z-min[2]-new_shift[2]; + int index_new = smoke_get_index(xn, res[0], yn, res[1], zn); + + /* skip if outside new domain */ + if (xn<0 || xn>=res[0] || + yn<0 || yn>=res[1] || + zn<0 || zn>=res[2]) + continue; + + /* copy data */ + n_dens[index_new] = o_dens[index_old]; + /* heat */ + if (n_heat && o_heat) { + n_heat[index_new] = o_heat[index_old]; + n_heatold[index_new] = o_heatold[index_old]; + } + /* fuel */ + if (n_fuel && o_fuel) { + n_flame[index_new] = o_flame[index_old]; + n_fuel[index_new] = o_fuel[index_old]; + n_react[index_new] = o_react[index_old]; + } + /* color */ + if (o_r && n_r) { + n_r[index_new] = o_r[index_old]; + n_g[index_new] = o_g[index_old]; + n_b[index_new] = o_b[index_old]; + } + n_vx[index_new] = o_vx[index_old]; + n_vy[index_new] = o_vy[index_old]; + n_vz[index_new] = o_vz[index_old]; + + if(sds->flags & MOD_SMOKE_HIGHRES && turb_old) { + int block_size = sds->amplify + 1; + int i,j,k; + /* old grid index */ + int xx_o = xo*block_size; + int yy_o = yo*block_size; + int zz_o = zo*block_size; + /* new grid index */ + int xx_n = xn*block_size; + int yy_n = yn*block_size; + int zz_n = zn*block_size; + + n_wt_tcu[index_new] = o_wt_tcu[index_old]; + n_wt_tcv[index_new] = o_wt_tcv[index_old]; + n_wt_tcw[index_new] = o_wt_tcw[index_old]; + + for(i = 0; i < block_size; i++) + for(j = 0; j < block_size; j++) + for(k = 0; k < block_size; k++) + { + int big_index_old = smoke_get_index(xx_o+i, wt_res_old[0], yy_o+j, wt_res_old[1], zz_o+k); + int big_index_new = smoke_get_index(xx_n+i, sds->res_wt[0], yy_n+j, sds->res_wt[1], zz_n+k); + /* copy data */ + n_wt_dens[big_index_new] = o_wt_dens[big_index_old]; + if (n_wt_flame && o_wt_flame) { + n_wt_flame[big_index_new] = o_wt_flame[big_index_old]; + n_wt_fuel[big_index_new] = o_wt_fuel[big_index_old]; + n_wt_react[big_index_new] = o_wt_react[big_index_old]; + } + if (n_wt_r && o_wt_r) { + n_wt_r[big_index_new] = o_wt_r[big_index_old]; + n_wt_g[big_index_new] = o_wt_g[big_index_old]; + n_wt_b[big_index_new] = o_wt_b[big_index_old]; + } + } + } + } + } + smoke_free(fluid_old); + if (turb_old) + smoke_turbulence_free(turb_old); + + /* set new domain dimensions */ + VECCOPY(sds->res_min, min); + VECCOPY(sds->res_max, max); + VECCOPY(sds->res, res); + sds->total_cells = total_cells; + } +} + +BLI_INLINE void apply_outflow_fields(int index, float *density, float *heat, float *fuel, float *react, float *color_r, float *color_g, float *color_b) +{ + density[index] = 0.f; + if (heat) { + heat[index] = 0.f; + } + if (fuel) { + fuel[index] = 0.f; + react[index] = 0.f; + } + if (color_r) { + color_r[index] = 0.f; + color_g[index] = 0.f; + color_b[index] = 0.f; + } +} + +BLI_INLINE void apply_inflow_fields(SmokeFlowSettings *sfs, float emission_value, int index, float *density, float *heat, float *fuel, float *react, float *color_r, float *color_g, float *color_b) +{ + int absolute_flow = (sfs->flags & MOD_SMOKE_FLOW_ABSOLUTE); + float dens_old = density[index]; + float fuel_old = (fuel) ? fuel[index] : 0.0f; + float dens_flow = (sfs->type == MOD_SMOKE_FLOW_TYPE_FIRE) ? 0.0f : emission_value * sfs->density; + float fuel_flow = emission_value * sfs->fuel_amount; + /* add heat */ + if (heat) { + heat[index] = MAX2(emission_value*sfs->temp, heat[index]); + } + /* absolute */ + if (absolute_flow) { + if (sfs->type != MOD_SMOKE_FLOW_TYPE_FIRE) { + if (dens_flow > density[index]) + density[index] = dens_flow; + } + if (sfs->type != MOD_SMOKE_FLOW_TYPE_SMOKE && fuel && fuel_flow) { + if (fuel_flow > fuel[index]) + fuel[index] = fuel_flow; + } + } + /* additive */ + else { + if (sfs->type != MOD_SMOKE_FLOW_TYPE_FIRE) { + density[index] += dens_flow; + CLAMP(density[index], 0.0f, 1.0f); + } + if (sfs->type != MOD_SMOKE_FLOW_TYPE_SMOKE && fuel && sfs->fuel_amount) { + fuel[index] += fuel_flow; + CLAMP(fuel[index], 0.0f, 10.0f); + } + } + + /* set color */ + if (color_r && dens_flow) { + float total_dens = density[index]/(dens_old+dens_flow); + color_r[index] = (color_r[index] + sfs->color[0] * dens_flow) * total_dens; + color_g[index] = (color_g[index] + sfs->color[1] * dens_flow) * total_dens; + color_b[index] = (color_b[index] + sfs->color[2] * dens_flow) * total_dens; + } + + /* set fire reaction coordinate */ + if (fuel && fuel[index]) { + /* instead of using 1.0 for all new fuel add slight falloff + * to reduce flow blockiness */ + float value = 1.0f - pow(1.0f - emission_value, 2.0f); + + if (value > react[index]) { + float f = fuel_flow / fuel[index]; + react[index] = value*f + (1.0f - f)*react[index]; + } + } +} + +static void update_flowsfluids(Scene *scene, Object *ob, SmokeDomainSettings *sds, float time, float dt) { Object **flowobjs = NULL; + EmissionMap *emaps = NULL; unsigned int numflowobj = 0; unsigned int flowIndex; + int new_shift[3] = {0}; + int active_fields = sds->active_fields; + + /* calculate domain shift for current frame if using adaptive domain */ + if (sds->flags & MOD_SMOKE_ADAPTIVE_DOMAIN) { + int total_shift[3]; + float frame_shift_f[3]; + float ob_loc[3] = {0}; + + mul_m4_v3(ob->obmat, ob_loc); + + VECSUB(frame_shift_f, ob_loc, sds->prev_loc); + copy_v3_v3(sds->prev_loc, ob_loc); + /* convert global space shift to local "cell" space */ + mul_mat3_m4_v3(sds->imat, frame_shift_f); + frame_shift_f[0] = frame_shift_f[0]/sds->cell_size[0]; + frame_shift_f[1] = frame_shift_f[1]/sds->cell_size[1]; + frame_shift_f[2] = frame_shift_f[2]/sds->cell_size[2]; + /* add to total shift */ + VECADD(sds->shift_f, sds->shift_f, frame_shift_f); + /* convert to integer */ + total_shift[0] = floor(sds->shift_f[0]); + total_shift[1] = floor(sds->shift_f[1]); + total_shift[2] = floor(sds->shift_f[2]); + VECSUB(new_shift, total_shift, sds->shift); + copy_v3_v3_int(sds->shift, total_shift); + + /* calculate new domain boundary points so that smoke doesnt slide on sub-cell movement */ + sds->p0[0] = sds->dp0[0] - sds->cell_size[0]*(sds->shift_f[0]-total_shift[0] - 0.5f); + sds->p0[1] = sds->dp0[1] - sds->cell_size[1]*(sds->shift_f[1]-total_shift[1] - 0.5f); + sds->p0[2] = sds->dp0[2] - sds->cell_size[2]*(sds->shift_f[2]-total_shift[2] - 0.5f); + sds->p1[0] = sds->p0[0] + sds->cell_size[0]*sds->base_res[0]; + sds->p1[1] = sds->p0[1] + sds->cell_size[1]*sds->base_res[1]; + sds->p1[2] = sds->p0[2] + sds->cell_size[2]*sds->base_res[2]; + } flowobjs = get_collisionobjects(scene, ob, sds->fluid_group, &numflowobj, eModifierType_Smoke); - // update obstacle tags in cells + /* init emission maps for each flow */ + emaps = MEM_callocN(sizeof(struct EmissionMap) * numflowobj, "smoke_flow_maps"); + + /* Prepare flow emission maps */ for(flowIndex = 0; flowIndex < numflowobj; flowIndex++) { Object *collob= flowobjs[flowIndex]; @@ -1238,289 +1649,249 @@ static void update_flowsfluids(Scene *scene, Object *ob, SmokeDomainSettings *sd { // we got nice flow object SmokeFlowSettings *sfs = smd2->flow; + EmissionMap *em = &emaps[flowIndex]; - if(sfs && sfs->psys && sfs->psys->part && sfs->psys->part->type==PART_EMITTER) // is particle system selected + if (sfs->source == MOD_SMOKE_FLOW_SOURCE_PARTICLES) { + emit_from_particles(collob, sds, sfs, em, scene, time, dt); + } + else { + emit_from_derivedmesh(collob, sds, sfs, em, dt); + } + + /* update required data fields */ + if (em->total_cells && sfs->type != MOD_SMOKE_FLOW_TYPE_OUTFLOW) { + /* activate heat field if flow produces any heat */ + if (sfs->temp) { + active_fields |= SM_ACTIVE_HEAT; + } + /* activate fuel field if flow adds any fuel */ + if (sfs->type != MOD_SMOKE_FLOW_TYPE_SMOKE && sfs->fuel_amount) { + active_fields |= SM_ACTIVE_FIRE; + } + /* activate color field if flows add smoke with varying colors */ + if (sfs->type != MOD_SMOKE_FLOW_TYPE_FIRE && sfs->density) { + if (!(active_fields & SM_ACTIVE_COLOR_SET)) { + copy_v3_v3(sds->active_color, sfs->color); + active_fields |= SM_ACTIVE_COLOR_SET; + } + else if (!equals_v3v3(sds->active_color, sfs->color)) { + active_fields |= SM_ACTIVE_COLORS; + } + } + } + } + } + + /* monitor active fields based on domain settings */ + /* if domain has fire, activate new fields if required */ + if (active_fields & SM_ACTIVE_FIRE) { + /* heat is always needed for fire */ + active_fields |= SM_ACTIVE_HEAT; + /* also activate colors if domain smoke color differs from active color */ + if (!(active_fields & SM_ACTIVE_COLOR_SET)) { + copy_v3_v3(sds->active_color, sds->flame_smoke_color); + active_fields |= SM_ACTIVE_COLOR_SET; + } + else if (!equals_v3v3(sds->active_color, sds->flame_smoke_color)) { + active_fields |= SM_ACTIVE_COLORS; + } + } + + /* Adjust domain size if needed */ + if (sds->flags & MOD_SMOKE_ADAPTIVE_DOMAIN) { + adjustDomainResolution(sds, new_shift, emaps, numflowobj, dt); + } + + /* Initialize new data fields if any */ + if (active_fields & SM_ACTIVE_HEAT) { + smoke_ensure_heat(sds->fluid); + } + if (active_fields & SM_ACTIVE_FIRE) { + smoke_ensure_fire(sds->fluid, sds->wt); + } + if (active_fields & SM_ACTIVE_COLORS) { + /* initialize all smoke with "active_color" */ + smoke_ensure_colors(sds->fluid, sds->wt, sds->active_color[0], sds->active_color[1], sds->active_color[2]); + } + sds->active_fields = active_fields; + + /* Apply emission data */ + if (sds->fluid) { + for(flowIndex = 0; flowIndex < numflowobj; flowIndex++) + { + Object *collob= flowobjs[flowIndex]; + SmokeModifierData *smd2 = (SmokeModifierData*)modifiers_findByType(collob, eModifierType_Smoke); + + // check for initialized smoke object + if((smd2->type & MOD_SMOKE_TYPE_FLOW) && smd2->flow) { - ParticleSimulationData sim; - ParticleSystem *psys = sfs->psys; - int totpart=psys->totpart, totchild; - int p = 0; - float *density = smoke_get_density(sds->fluid); - float *bigdensity = smoke_turbulence_get_density(sds->wt); - float *heat = smoke_get_heat(sds->fluid); - float *velocity_x = smoke_get_velocity_x(sds->fluid); - float *velocity_y = smoke_get_velocity_y(sds->fluid); - float *velocity_z = smoke_get_velocity_z(sds->fluid); - unsigned char *obstacle = smoke_get_obstacle(sds->fluid); + // we got nice flow object + SmokeFlowSettings *sfs = smd2->flow; + EmissionMap *em = &emaps[flowIndex]; + + float *density = smoke_get_density(sds->fluid); + float *color_r = smoke_get_color_r(sds->fluid); + float *color_g = smoke_get_color_g(sds->fluid); + float *color_b = smoke_get_color_b(sds->fluid); + float *fuel = smoke_get_fuel(sds->fluid); + float *react = smoke_get_react(sds->fluid); + float *bigdensity = smoke_turbulence_get_density(sds->wt); + float *bigfuel = smoke_turbulence_get_fuel(sds->wt); + float *bigreact = smoke_turbulence_get_react(sds->wt); + float *bigcolor_r = smoke_turbulence_get_color_r(sds->wt); + float *bigcolor_g = smoke_turbulence_get_color_g(sds->wt); + float *bigcolor_b = smoke_turbulence_get_color_b(sds->wt); + float *heat = smoke_get_heat(sds->fluid); + float *velocity_x = smoke_get_velocity_x(sds->fluid); + float *velocity_y = smoke_get_velocity_y(sds->fluid); + float *velocity_z = smoke_get_velocity_z(sds->fluid); + //unsigned char *obstacle = smoke_get_obstacle(sds->fluid); // DG TODO UNUSED unsigned char *obstacleAnim = smoke_get_obstacle_anim(sds->fluid); int bigres[3]; - short absolute_flow = (sfs->flags & MOD_SMOKE_FLOW_ABSOLUTE); - short high_emission_smoothing = bigdensity ? (sds->flags & MOD_SMOKE_HIGH_SMOOTH) : 0; + short high_emission_smoothing = (sds->flags & MOD_SMOKE_HIGH_SMOOTH); + float *velocity_map = em->velocity; + float *emission_map = em->influence; - /* - * A temporary volume map used to store whole emissive - * area to be added to smoke density and interpolated - * for high resolution smoke. - */ - float *temp_emission_map = NULL; + int ii, jj, kk, gx, gy, gz, ex, ey, ez, dx, dy, dz, block_size; + size_t e_index, d_index, index_big; - sim.scene = scene; - sim.ob = collob; - sim.psys = psys; - - // initialize temp emission map - if(!(sfs->type & MOD_SMOKE_FLOW_TYPE_OUTFLOW)) - { - int i; - temp_emission_map = MEM_callocN(sizeof(float) * sds->res[0]*sds->res[1]*sds->res[2], "SmokeTempEmission"); - // set whole volume to 0.0f - for (i=0; ires[0]*sds->res[1]*sds->res[2]; i++) { - temp_emission_map[i] = 0.0f; - } - } - - // mostly copied from particle code - if(psys->part->type==PART_HAIR) - { - /* - if(psys->childcache) - { - totchild = psys->totchildcache; - } - else - */ - - // TODO: PART_HAIR not supported whatsoever - totchild=0; - } - else - totchild=psys->totchild*psys->part->disp/100; - - for(p=0; pparticles[p].flag & (PARS_NO_DISP|PARS_UNEXIST)) - continue; - } - else { - /* handle child particle */ - ChildParticle *cpa = &psys->child[p - totpart]; - - if(psys->particles[cpa->parent].flag & (PARS_NO_DISP|PARS_UNEXIST)) - continue; - } - - state.time = time; - if(psys_get_particle_state(&sim, p, &state, 0) == 0) - continue; - - // copy_v3_v3(pos, pa->state.co); - // mul_m4_v3(ob->imat, pos); - // 1. get corresponding cell - get_cell(sds->p0, sds->res, sds->dx*sds->scale, state.co, cell, 0); - // check if cell is valid (in the domain boundary) - for(i = 0; i < 3; i++) - { - if((cell[i] > sds->res[i] - 1) || (cell[i] < 0)) - { - badcell = 1; - break; - } - } - if(badcell) - continue; - // 2. set cell values (heat, density and velocity) - index = smoke_get_index(cell[0], sds->res[0], cell[1], sds->res[1], cell[2]); - if(!(sfs->type & MOD_SMOKE_FLOW_TYPE_OUTFLOW) && !(obstacle[index])) // this is inflow - { - // heat[index] += sfs->temp * 0.1; - // density[index] += sfs->density * 0.1; - heat[index] = sfs->temp; - - // Add emitter density to temp emission map - temp_emission_map[index] = sfs->density; - - // Uses particle velocity as initial velocity for smoke - if(sfs->flags & MOD_SMOKE_FLOW_INITVELOCITY && (psys->part->phystype != PART_PHYS_NO)) + // loop through every emission map cell + for(gx = em->min[0]; gx < em->max[0]; gx++) + for(gy = em->min[1]; gy < em->max[1]; gy++) + for(gz = em->min[2]; gz < em->max[2]; gz++) { - velocity_x[index] = state.vel[0]*sfs->vel_multi; - velocity_y[index] = state.vel[1]*sfs->vel_multi; - velocity_z[index] = state.vel[2]*sfs->vel_multi; - } - } - else if(sfs->type & MOD_SMOKE_FLOW_TYPE_OUTFLOW) // outflow - { - heat[index] = 0.f; - density[index] = 0.f; - velocity_x[index] = 0.f; - velocity_y[index] = 0.f; - velocity_z[index] = 0.f; - // we need different handling for the high-res feature - if(bigdensity) - { - // init all surrounding cells according to amplification, too - int i, j, k; - smoke_turbulence_get_res(sds->wt, bigres); + /* get emission map index */ + ex = gx-em->min[0]; + ey = gy-em->min[1]; + ez = gz-em->min[2]; + e_index = smoke_get_index(ex, em->res[0], ey, em->res[1], ez); + if (!emission_map[e_index]) continue; + /* get domain index */ + dx = gx-sds->res_min[0]; + dy = gy-sds->res_min[1]; + dz = gz-sds->res_min[2]; + d_index = smoke_get_index(dx, sds->res[0], dy, sds->res[1], dz); - for(i = 0; i < sds->amplify + 1; i++) - for(j = 0; j < sds->amplify + 1; j++) - for(k = 0; k < sds->amplify + 1; k++) - { - index = smoke_get_index((sds->amplify + 1)* cell[0] + i, bigres[0], (sds->amplify + 1)* cell[1] + j, bigres[1], (sds->amplify + 1)* cell[2] + k); - bigdensity[index] = 0.f; - } - } - } - } // particles loop + if(sfs->type == MOD_SMOKE_FLOW_TYPE_OUTFLOW) { // outflow + apply_outflow_fields(d_index, density, heat, fuel, react, color_r, color_g, color_b); + } + else { // inflow + apply_inflow_fields(sfs, emission_map[e_index], d_index, density, heat, fuel, react, color_r, color_g, color_b); - // apply emission values - if(!(sfs->type & MOD_SMOKE_FLOW_TYPE_OUTFLOW)) - { - // initialize variables - int ii, jj, kk, x, y, z, block_size; - size_t index, index_big; + /* initial velocity */ + if(sfs->flags & MOD_SMOKE_FLOW_INITVELOCITY) { + velocity_x[d_index] = ADD_IF_LOWER(velocity_x[d_index], velocity_map[e_index*3]); + velocity_y[d_index] = ADD_IF_LOWER(velocity_y[d_index], velocity_map[e_index*3+1]); + velocity_z[d_index] = ADD_IF_LOWER(velocity_z[d_index], velocity_map[e_index*3+2]); + } + } - smoke_turbulence_get_res(sds->wt, bigres); - block_size = sds->amplify + 1; // high res block size - - // loop through every low res cell - for(x = 0; x < sds->res[0]; x++) - for(y = 0; y < sds->res[1]; y++) - for(z = 0; z < sds->res[2]; z++) - { + /* loop through high res blocks if high res enabled */ + if (bigdensity) { // neighbor cell emission densities (for high resolution smoke smooth interpolation) float c000, c001, c010, c011, c100, c101, c110, c111; - c000 = (x>0 && y>0 && z>0) ? temp_emission_map[smoke_get_index(x-1, sds->res[0], y-1, sds->res[1], z-1)] : 0; - c001 = (x>0 && y>0) ? temp_emission_map[smoke_get_index(x-1, sds->res[0], y-1, sds->res[1], z)] : 0; - c010 = (x>0 && z>0) ? temp_emission_map[smoke_get_index(x-1, sds->res[0], y, sds->res[1], z-1)] : 0; - c011 = (x>0) ? temp_emission_map[smoke_get_index(x-1, sds->res[0], y, sds->res[1], z)] : 0; - - c100 = (y>0 && z>0) ? temp_emission_map[smoke_get_index(x, sds->res[0], y-1, sds->res[1], z-1)] : 0; - c101 = (y>0) ? temp_emission_map[smoke_get_index(x, sds->res[0], y-1, sds->res[1], z)] : 0; - c110 = (z>0) ? temp_emission_map[smoke_get_index(x, sds->res[0], y, sds->res[1], z-1)] : 0; - c111 = temp_emission_map[smoke_get_index(x, sds->res[0], y, sds->res[1], z)]; // this cell - - // get cell index - index = smoke_get_index(x, sds->res[0], y, sds->res[1], z); - - // add emission to low resolution density - if (absolute_flow) - { - if (temp_emission_map[index]>0) - density[index] = temp_emission_map[index]; - } - else - { - density[index] += temp_emission_map[index]; - - if (density[index]>1) - density[index]=1.0f; - } - smoke_turbulence_get_res(sds->wt, bigres); + block_size = sds->amplify + 1; // high res block size - /* loop through high res blocks if high res enabled */ - if (bigdensity) - for(ii = 0; ii < block_size; ii++) - for(jj = 0; jj < block_size; jj++) - for(kk = 0; kk < block_size; kk++) + c000 = (ex>0 && ey>0 && ez>0) ? emission_map[smoke_get_index(ex-1, em->res[0], ey-1, em->res[1], ez-1)] : 0; + c001 = (ex>0 && ey>0) ? emission_map[smoke_get_index(ex-1, em->res[0], ey-1, em->res[1], ez)] : 0; + c010 = (ex>0 && ez>0) ? emission_map[smoke_get_index(ex-1, em->res[0], ey, em->res[1], ez-1)] : 0; + c011 = (ex>0) ? emission_map[smoke_get_index(ex-1, em->res[0], ey, em->res[1], ez)] : 0; + + c100 = (ey>0 && ez>0) ? emission_map[smoke_get_index(ex, em->res[0], ey-1, em->res[1], ez-1)] : 0; + c101 = (ey>0) ? emission_map[smoke_get_index(ex, em->res[0], ey-1, em->res[1], ez)] : 0; + c110 = (ez>0) ? emission_map[smoke_get_index(ex, em->res[0], ey, em->res[1], ez-1)] : 0; + c111 = emission_map[smoke_get_index(ex, em->res[0], ey, em->res[1], ez)]; // this cell + + for(ii = 0; ii < block_size; ii++) + for(jj = 0; jj < block_size; jj++) + for(kk = 0; kk < block_size; kk++) + { + + float fx,fy,fz, interpolated_value; + int shift_x, shift_y, shift_z; + + + /* + * Do volume interpolation if emitter smoothing + * is enabled + */ + if (high_emission_smoothing) { + /* get relative block position + * for interpolation smoothing */ + fx = (float)ii/block_size + 0.5f/block_size; + fy = (float)jj/block_size + 0.5f/block_size; + fz = (float)kk/block_size + 0.5f/block_size; - float fx,fy,fz, interpolated_value; - int shift_x, shift_y, shift_z; + /* calculate trilinear interpolation */ + interpolated_value = c000 * (1-fx) * (1-fy) * (1-fz) + + c100 * fx * (1-fy) * (1-fz) + + c010 * (1-fx) * fy * (1-fz) + + c001 * (1-fx) * (1-fy) * fz + + c101 * fx * (1-fy) * fz + + c011 * (1-fx) * fy * fz + + c110 * fx * fy * (1-fz) + + c111 * fx * fy * fz; - /* - * Do volume interpolation if emitter smoothing - * is enabled - */ - if (high_emission_smoothing) - { - // convert block position to relative - // for interpolation smoothing - fx = (float)ii/block_size + 0.5f/block_size; - fy = (float)jj/block_size + 0.5f/block_size; - fz = (float)kk/block_size + 0.5f/block_size; + /* add some contrast / sharpness + * depending on hi-res block size */ + interpolated_value = (interpolated_value-0.4f)*(block_size/2) + 0.4f; + CLAMP(interpolated_value, 0.0f, 1.0f); - // calculate trilinear interpolation - interpolated_value = c000 * (1-fx) * (1-fy) * (1-fz) + - c100 * fx * (1-fy) * (1-fz) + - c010 * (1-fx) * fy * (1-fz) + - c001 * (1-fx) * (1-fy) * fz + - c101 * fx * (1-fy) * fz + - c011 * (1-fx) * fy * fz + - c110 * fx * fy * (1-fz) + - c111 * fx * fy * fz; + /* shift smoke block index + * (because pixel center is actually + * in halfway of the low res block) */ + shift_x = (dx < 1) ? 0 : block_size/2; + shift_y = (dy < 1) ? 0 : block_size/2; + shift_z = (dz < 1) ? 0 : block_size/2; + } + else + { + /* without interpolation use same low resolution + * block value for all hi-res blocks */ + interpolated_value = c111; + shift_x = 0; + shift_y = 0; + shift_z = 0; + } + /* get shifted index for current high resolution block */ + index_big = smoke_get_index(block_size * dx + ii - shift_x, bigres[0], block_size * dy + jj - shift_y, bigres[1], block_size * dz + kk - shift_z); - // add some contrast / sharpness - // depending on hi-res block size - - interpolated_value = (interpolated_value-0.4f*sfs->density)*(block_size/2) + 0.4f*sfs->density; - if (interpolated_value<0.0f) interpolated_value = 0.0f; - if (interpolated_value>1.0f) interpolated_value = 1.0f; - - // shift smoke block index - // (because pixel center is actually - // in halfway of the low res block) - shift_x = (x < 1) ? 0 : block_size/2; - shift_y = (y < 1) ? 0 : block_size/2; - shift_z = (z < 1) ? 0 : block_size/2; - } - else - { - // without interpolation use same low resolution - // block value for all hi-res blocks - interpolated_value = c111; - shift_x = 0; - shift_y = 0; - shift_z = 0; + if(sfs->type == MOD_SMOKE_FLOW_TYPE_OUTFLOW) { // outflow + if (interpolated_value) { + apply_outflow_fields(index_big, bigdensity, NULL, bigfuel, bigreact, bigcolor_r, bigcolor_g, bigcolor_b); } + } + else { // inflow + apply_inflow_fields(sfs, interpolated_value, index_big, bigdensity, NULL, bigfuel, bigreact, bigcolor_r, bigcolor_g, bigcolor_b); + } + } // hires loop + } // bigdensity + } // low res loop - // get shifted index for current high resolution block - index_big = smoke_get_index(block_size * x + ii - shift_x, bigres[0], block_size * y + jj - shift_y, bigres[1], block_size * z + kk - shift_z); + // free emission maps + em_freeData(em); - // add emission data to high resolution density - if (absolute_flow) - { - if (interpolated_value > 0) - bigdensity[index_big] = interpolated_value; - } - else - { - bigdensity[index_big] += interpolated_value; - - if (bigdensity[index_big]>1) - bigdensity[index_big]=1.0f; - } - } // end of hires loop - - } // end of low res loop - - // free temporary emission map - if (temp_emission_map) - MEM_freeN(temp_emission_map); - - } // end emission - } + } // end emission } } if(flowobjs) MEM_freeN(flowobjs); + if(emaps) + MEM_freeN(emaps); } static void update_effectors(Scene *scene, Object *ob, SmokeDomainSettings *sds, float UNUSED(dt)) { - ListBase *effectors = pdInitEffectors(scene, ob, NULL, sds->effector_weights); + ListBase *effectors; + /* make sure smoke flow influence is 0.0f */ + sds->effector_weights->weight[PFIELD_SMOKEFLOW] = 0.0f; + effectors = pdInitEffectors(scene, ob, NULL, sds->effector_weights); if(effectors) { @@ -1532,76 +1903,110 @@ static void update_effectors(Scene *scene, Object *ob, SmokeDomainSettings *sds, float *velocity_y = smoke_get_velocity_y(sds->fluid); float *velocity_z = smoke_get_velocity_z(sds->fluid); unsigned char *obstacle = smoke_get_obstacle(sds->fluid); - int x, y, z; + int x; // precalculate wind forces + #pragma omp parallel for schedule(static) for(x = 0; x < sds->res[0]; x++) + { + int y, z; for(y = 0; y < sds->res[1]; y++) for(z = 0; z < sds->res[2]; z++) - { - EffectedPoint epoint; - float voxelCenter[3] = {0,0,0}, vel[3] = {0,0,0}, retvel[3] = {0,0,0}; - unsigned int index = smoke_get_index(x, sds->res[0], y, sds->res[1], z); + { + EffectedPoint epoint; + float mag; + float voxelCenter[3] = {0,0,0}, vel[3] = {0,0,0}, retvel[3] = {0,0,0}; + unsigned int index = smoke_get_index(x, sds->res[0], y, sds->res[1], z); - if((density[index] < FLT_EPSILON) || obstacle[index]) - continue; + if((density[index] < FLT_EPSILON) || obstacle[index]) + continue; - vel[0] = velocity_x[index]; - vel[1] = velocity_y[index]; - vel[2] = velocity_z[index]; + vel[0] = velocity_x[index]; + vel[1] = velocity_y[index]; + vel[2] = velocity_z[index]; - voxelCenter[0] = sds->p0[0] + sds->dx * sds->scale * x + sds->dx * sds->scale * 0.5; - voxelCenter[1] = sds->p0[1] + sds->dx * sds->scale * y + sds->dx * sds->scale * 0.5; - voxelCenter[2] = sds->p0[2] + sds->dx * sds->scale * z + sds->dx * sds->scale * 0.5; + /* convert vel to global space */ + mag = len_v3(vel); + mul_mat3_m4_v3(sds->obmat, vel); + normalize_v3(vel); + mul_v3_fl(vel, mag); - pd_point_from_loc(scene, voxelCenter, vel, index, &epoint); - pdDoEffectors(effectors, NULL, sds->effector_weights, &epoint, retvel, NULL); + voxelCenter[0] = sds->p0[0] + sds->cell_size[0] * ((float)(x+sds->res_min[0]) + 0.5f); + voxelCenter[1] = sds->p0[1] + sds->cell_size[1] * ((float)(y+sds->res_min[1]) + 0.5f); + voxelCenter[2] = sds->p0[2] + sds->cell_size[2] * ((float)(z+sds->res_min[2]) + 0.5f); + mul_m4_v3(sds->obmat, voxelCenter); - // TODO dg - do in force! - force_x[index] = MIN2(MAX2(-1.0, retvel[0] * 0.2), 1.0); - force_y[index] = MIN2(MAX2(-1.0, retvel[1] * 0.2), 1.0); - force_z[index] = MIN2(MAX2(-1.0, retvel[2] * 0.2), 1.0); + pd_point_from_loc(scene, voxelCenter, vel, index, &epoint); + pdDoEffectors(effectors, NULL, sds->effector_weights, &epoint, retvel, NULL); + + /* convert retvel to local space */ + mag = len_v3(retvel); + mul_mat3_m4_v3(sds->imat, retvel); + normalize_v3(retvel); + mul_v3_fl(retvel, mag); + + // TODO dg - do in force! + force_x[index] = MIN2(MAX2(-1.0, retvel[0] * 0.2), 1.0); + force_y[index] = MIN2(MAX2(-1.0, retvel[1] * 0.2), 1.0); + force_z[index] = MIN2(MAX2(-1.0, retvel[2] * 0.2), 1.0); + } } } pdEndEffectors(&effectors); } -static void step(Scene *scene, Object *ob, SmokeModifierData *smd, float fps) +static void step(Scene *scene, Object *ob, SmokeModifierData *smd, DerivedMesh *domain_dm, float fps) { + SmokeDomainSettings *sds = smd->domain; /* stability values copied from wturbulence.cpp */ const int maxSubSteps = 25; float maxVel; // maxVel should be 1.5 (1.5 cell max movement) * dx (cell size) - float dt = DT_DEFAULT; + float dt; float maxVelMag = 0.0f; int totalSubsteps; int substep = 0; float dtSubdiv; - - SmokeDomainSettings *sds = smd->domain; + float gravity[3] = {0.0f, 0.0f, -1.0f}; + float gravity_mag; /* get max velocity and lower the dt value if it is too high */ - size_t size= sds->res[0] * sds->res[1] * sds->res[2]; - + size_t size = sds->res[0] * sds->res[1] * sds->res[2]; float *velX = smoke_get_velocity_x(sds->fluid); float *velY = smoke_get_velocity_y(sds->fluid); float *velZ = smoke_get_velocity_z(sds->fluid); size_t i; - /* adapt timestep for different framerates, dt = 0.1 is at 25fps */ - dt *= (25.0f / fps); + /* update object state */ + invert_m4_m4(sds->imat, ob->obmat); + copy_m4_m4(sds->obmat, ob->obmat); + smoke_set_domain_from_derivedmesh(sds, ob, domain_dm); + /* use global gravity if enabled */ + if (scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY) { + copy_v3_v3(gravity, scene->physics_settings.gravity); + /* map default value to 1.0 */ + mul_v3_fl(gravity, 1.0f/9.810f); + } + /* convert gravity to domain space */ + gravity_mag = len_v3(gravity); + mul_mat3_m4_v3(sds->imat, gravity); + normalize_v3(gravity); + mul_v3_fl(gravity, gravity_mag); + + /* adapt timestep for different framerates, dt = 0.1 is at 25fps */ + dt = DT_DEFAULT * (25.0f / fps); // maximum timestep/"CFL" constraint: dt < 5.0 *dx / maxVel maxVel = (sds->dx * 5.0); - for(i = 0; i < size; i++) + /*for(i = 0; i < size; i++) { float vtemp = (velX[i]*velX[i]+velY[i]*velY[i]+velZ[i]*velZ[i]); if(vtemp > maxVelMag) maxVelMag = vtemp; - } + }*/ maxVelMag = sqrt(maxVelMag) * dt * sds->time_scale; totalSubsteps = (int)((maxVelMag / maxVel) + 1.0f); /* always round up */ @@ -1618,35 +2023,116 @@ static void step(Scene *scene, Object *ob, SmokeModifierData *smd, float fps) for(substep = 0; substep < totalSubsteps; substep++) { // calc animated obstacle velocities + update_flowsfluids(scene, ob, sds, smd->time, dtSubdiv); update_obstacles(scene, ob, sds, dtSubdiv, substep, totalSubsteps); - update_flowsfluids(scene, ob, sds, smd->time); - update_effectors(scene, ob, sds, dtSubdiv); // DG TODO? problem --> uses forces instead of velocity, need to check how they need to be changed with variable dt - smoke_step(sds->fluid, dtSubdiv); - - // move animated obstacle: Done in update_obstacles() */ - - // where to delete old obstacles from array? Done in update_obstacles() */ + if (sds->total_cells > 1) { + update_effectors(scene, ob, sds, dtSubdiv); // DG TODO? problem --> uses forces instead of velocity, need to check how they need to be changed with variable dt + smoke_step(sds->fluid, gravity, dtSubdiv); + } } } -void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedMesh *dm) +static DerivedMesh *createDomainGeometry(SmokeDomainSettings *sds, Object *ob) +{ + DerivedMesh *result; + MVert *mverts; + MPoly *mpolys; + MLoop *mloops; + float min[3]; + float max[3]; + float *co; + MPoly *mp; + MLoop *ml; + + int num_verts = 8; + int num_faces = 6; + int i; + float ob_loc[3] = {0}; + float ob_cache_loc[3] = {0}; + + /* dont generate any mesh if there isnt any content */ + if (sds->total_cells <= 1) { + num_verts = 0; + num_faces = 0; + } + + result = CDDM_new(num_verts, 0, 0, num_faces * 4, num_faces); + mverts = CDDM_get_verts(result); + mpolys = CDDM_get_polys(result); + mloops = CDDM_get_loops(result); + + + if (num_verts) { + /* volume bounds */ + VECMADD(min, sds->p0, sds->cell_size, sds->res_min); + VECMADD(max, sds->p0, sds->cell_size, sds->res_max); + + /* set vertices */ + /* top slab */ + co = mverts[0].co; co[0] = min[0]; co[1] = min[1]; co[2] = max[2]; + co = mverts[1].co; co[0] = max[0]; co[1] = min[1]; co[2] = max[2]; + co = mverts[2].co; co[0] = max[0]; co[1] = max[1]; co[2] = max[2]; + co = mverts[3].co; co[0] = min[0]; co[1] = max[1]; co[2] = max[2]; + /* bottom slab */ + co = mverts[4].co; co[0] = min[0]; co[1] = min[1]; co[2] = min[2]; + co = mverts[5].co; co[0] = max[0]; co[1] = min[1]; co[2] = min[2]; + co = mverts[6].co; co[0] = max[0]; co[1] = max[1]; co[2] = min[2]; + co = mverts[7].co; co[0] = min[0]; co[1] = max[1]; co[2] = min[2]; + + /* create faces */ + /* top */ + mp = &mpolys[0]; ml = &mloops[0 * 4]; mp->loopstart = 0 * 4; mp->totloop = 4; + ml[0].v = 0; ml[1].v = 1; ml[2].v = 2; ml[3].v = 3; + /* right */ + mp = &mpolys[1]; ml = &mloops[1 * 4]; mp->loopstart = 1 * 4; mp->totloop = 4; + ml[0].v = 2; ml[1].v = 1; ml[2].v = 5; ml[3].v = 6; + /* bottom */ + mp = &mpolys[2]; ml = &mloops[2 * 4]; mp->loopstart = 2 * 4; mp->totloop = 4; + ml[0].v = 7; ml[1].v = 6; ml[2].v = 5; ml[3].v = 4; + /* left */ + mp = &mpolys[3]; ml = &mloops[3 * 4]; mp->loopstart = 3 * 4; mp->totloop = 4; + ml[0].v = 0; ml[1].v = 3; ml[2].v = 7; ml[3].v = 4; + /* front */ + mp = &mpolys[4]; ml = &mloops[4 * 4]; mp->loopstart = 4 * 4; mp->totloop = 4; + ml[0].v = 3; ml[1].v = 2; ml[2].v = 6; ml[3].v = 7; + /* back */ + mp = &mpolys[5]; ml = &mloops[5 * 4]; mp->loopstart = 5 * 4; mp->totloop = 4; + ml[0].v = 1; ml[1].v = 0; ml[2].v = 4; ml[3].v = 5; + + /* calculate required shift to match domain's global position + * it was originally simulated at (if object moves without smoke step) */ + invert_m4_m4(ob->imat, ob->obmat); + mul_m4_v3(ob->obmat, ob_loc); + mul_m4_v3(sds->obmat, ob_cache_loc); + VECSUB(sds->obj_shift_f, ob_cache_loc, ob_loc); + /* convert shift to local space and apply to vertices */ + mul_mat3_m4_v3(ob->imat, sds->obj_shift_f); + /* apply */ + for (i=0; iobj_shift_f); + } + } + + + CDDM_calc_edges(result); + return result; +} + +void smokeModifier_process(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedMesh *dm) { if((smd->type & MOD_SMOKE_TYPE_FLOW)) { if(scene->r.cfra >= smd->time) smokeModifier_init(smd, ob, scene, dm); + if (smd->flow->dm) smd->flow->dm->release(smd->flow->dm); + smd->flow->dm = CDDM_copy(dm); + DM_ensure_tessface(smd->flow->dm); + if(scene->r.cfra > smd->time) { - // XXX TODO smd->time = scene->r.cfra; - - // rigid movement support - /* - copy_m4_m4(smd->flow->mat_old, smd->flow->mat); - copy_m4_m4(smd->flow->mat, ob->obmat); - */ } else if(scene->r.cfra < smd->time) { @@ -1656,99 +2142,27 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM } else if(smd->type & MOD_SMOKE_TYPE_COLL) { - /* Check if domain resolution changed */ - /* DG TODO: can this be solved more elegant using dependancy graph? */ - { - SmokeCollSettings *scs = smd->coll; - Base *base = scene->base.first; - int changed = 0; - float dx = FLT_MAX; - float scale = 1.0f; - int haveDomain = 0; - - for ( ; base; base = base->next) - { - SmokeModifierData *smd2 = (SmokeModifierData *)modifiers_findByType(base->object, eModifierType_Smoke); - - if (smd2 && (smd2->type & MOD_SMOKE_TYPE_DOMAIN) && smd2->domain) - { - SmokeDomainSettings *sds = smd2->domain; - - if(sds->dx * sds->scale < dx) - { - dx = sds->dx; - scale = sds->scale; - changed = 1; - } - - haveDomain = 1; - } - } - - if(!haveDomain) - return; - - if(changed) - { - if(dx*scale != scs->dx) - { - scs->dx = dx*scale; - smokeModifier_reset(smd); - } - } - } - if(scene->r.cfra >= smd->time) smokeModifier_init(smd, ob, scene, dm); - if(scene->r.cfra > smd->time) + if(smd->coll) { - unsigned int i; - SmokeCollSettings *scs = smd->coll; - float *points_old = scs->points_old; - float *points = scs->points; - unsigned int numpoints = scs->numpoints; + if (smd->coll->dm) + smd->coll->dm->release(smd->coll->dm); - // XXX TODO <-- DG: what is TODO here? - smd->time = scene->r.cfra; - - // rigid movement support - copy_m4_m4(scs->mat_old, scs->mat); - copy_m4_m4(scs->mat, ob->obmat); - - if(scs->type != SM_COLL_ANIMATED) // if(not_animated) - { - // nothing to do, "mat" is already up to date - } - else - { - // XXX TODO: need to update positions + divs - - if(scs->numverts != dm->getNumVerts(dm)) - { - // DG TODO: reset modifier? - return; - } - - for(i = 0; i < numpoints * 3; i++) - { - points_old[i] = points[i]; - } - - DM_ensure_tessface(dm); - fill_scs_points_anim(ob, dm, scs); - } + smd->coll->dm = CDDM_copy(dm); + DM_ensure_tessface(smd->coll->dm); } - else if(scene->r.cfra < smd->time) + + smd->time = scene->r.cfra; + if(scene->r.cfra < smd->time) { - smd->time = scene->r.cfra; smokeModifier_reset(smd); } } else if(smd->type & MOD_SMOKE_TYPE_DOMAIN) { SmokeDomainSettings *sds = smd->domain; - float light[3]; PointCache *cache = NULL; PTCacheID pid; int startframe, endframe, framenr; @@ -1765,6 +2179,7 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM if(!smd->domain->fluid || framenr == startframe) { BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED); + smokeModifier_reset(smd); BKE_ptcache_validate(cache, framenr); cache->flag &= ~PTCACHE_REDO_NEEDED; } @@ -1773,15 +2188,12 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM return; smd->domain->flags &= ~MOD_SMOKE_FILE_LOAD; - CLAMP(framenr, startframe, endframe); /* If already viewing a pre/after frame, no need to reload */ if ((smd->time == framenr) && (framenr != scene->r.cfra)) return; - // printf("startframe: %d, framenr: %d\n", startframe, framenr); - if(smokeModifier_init(smd, ob, scene, dm)==0) { printf("bad smokeModifier_init\n"); @@ -1805,15 +2217,12 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM tstart(); - smoke_calc_domain(scene, ob, smd); - /* if on second frame, write cache for first frame */ if((int)smd->time == startframe && (cache->flag & PTCACHE_OUTDATED || cache->last_exact==0)) { // create shadows straight after domain initialization so we get nice shadows for startframe, too - if(get_lamp(scene, light)) - smoke_calc_transparency(sds->shadow, smoke_get_density(sds->fluid), sds->p0, sds->p1, sds->res, sds->dx, light, calc_voxel_transp, -7.0*sds->dx); + smoke_calc_transparency(sds, scene); - if(sds->wt) + if(sds->wt && sds->total_cells>1) { if(sds->flags & MOD_SMOKE_DISSOLVE) smoke_dissolve_wavelet(sds->wt, sds->diss_speed, sds->flags & MOD_SMOKE_DISSOLVE_LOG); @@ -1828,8 +2237,6 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM /* do simulation */ - // low res - // simulate the actual smoke (c++ code in intern/smoke) // DG: interesting commenting this line + deactivating loading of noise files if(framenr!=startframe) @@ -1837,12 +2244,11 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM if(sds->flags & MOD_SMOKE_DISSOLVE) smoke_dissolve(sds->fluid, sds->diss_speed, sds->flags & MOD_SMOKE_DISSOLVE_LOG); - step(scene, ob, smd, scene->r.frs_sec / scene->r.frs_sec_base); + step(scene, ob, smd, dm, scene->r.frs_sec / scene->r.frs_sec_base); } // create shadows before writing cache so they get stored - if(get_lamp(scene, light)) - smoke_calc_transparency(sds->shadow, smoke_get_density(sds->fluid), sds->p0, sds->p1, sds->res, sds->dx, light, calc_voxel_transp, -7.0*sds->dx); + smoke_calc_transparency(sds, scene); if(sds->wt) { @@ -1860,6 +2266,20 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM } } +struct DerivedMesh *smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedMesh *dm) +{ + smokeModifier_process(smd, scene, ob, dm); + + /* return generated geometry for adaptive domain */ + if(smd->type & MOD_SMOKE_TYPE_DOMAIN && smd->domain && + smd->domain->flags & MOD_SMOKE_ADAPTIVE_DOMAIN && + smd->domain->base_res[0]) + { + return createDomainGeometry(smd->domain, ob); + } + else return CDDM_copy(dm); +} + static float calc_voxel_transp(float *result, float *input, int res[3], int *pixel, float *tRay, float correct) { const size_t index = smoke_get_index(pixel[0], res[0], pixel[1], res[1], pixel[2]); @@ -1876,24 +2296,6 @@ static float calc_voxel_transp(float *result, float *input, int res[3], int *pix return *tRay; } -long long smoke_get_mem_req(int xres, int yres, int zres, int amplify) -{ - int totalCells = xres * yres * zres; - int amplifiedCells = totalCells * amplify * amplify * amplify; - - // print out memory requirements - long long int coarseSize = sizeof(float) * totalCells * 22 + - sizeof(unsigned char) * totalCells; - - long long int fineSize = sizeof(float) * amplifiedCells * 7 + // big grids - sizeof(float) * totalCells * 8 + // small grids - sizeof(float) * 128 * 128 * 128; // noise tile - - long long int totalMB = (coarseSize + fineSize) / (1024 * 1024); - - return totalMB; -} - static void bresenham_linie_3D(int x1, int y1, int z1, int x2, int y2, int z2, float *tRay, bresenham_callback cb, float *result, float *input, int res[3], float correct) { int dx, dy, dz, i, l, m, n, x_inc, y_inc, z_inc, err_1, err_2, dx2, dy2, dz2; @@ -1977,80 +2379,142 @@ static void bresenham_linie_3D(int x1, int y1, int z1, int x2, int y2, int z2, f cb(result, input, res, pixel, tRay, correct); } -static void get_cell(const float p0[3], const int res[3], float dx, const float pos[3], int cell[3], int correct) +static void smoke_calc_transparency(SmokeDomainSettings *sds, Scene *scene) { - float tmp[3]; + float bv[6] = {0}; + float light[3]; + int a, z, slabsize=sds->res[0]*sds->res[1], size= sds->res[0]*sds->res[1]*sds->res[2]; + float *density = smoke_get_density(sds->fluid); + float correct = -7.0*sds->dx; - sub_v3_v3v3(tmp, pos, p0); - mul_v3_fl(tmp, 1.0 / dx); + if (!get_lamp(scene, light)) return; - if (correct) { - cell[0] = MIN2(res[0] - 1, MAX2(0, (int)floor(tmp[0]))); - cell[1] = MIN2(res[1] - 1, MAX2(0, (int)floor(tmp[1]))); - cell[2] = MIN2(res[2] - 1, MAX2(0, (int)floor(tmp[2]))); - } - else { - cell[0] = (int)floor(tmp[0]); - cell[1] = (int)floor(tmp[1]); - cell[2] = (int)floor(tmp[2]); - } -} - -static void smoke_calc_transparency(float *result, float *input, float *p0, float *p1, int res[3], float dx, float *light, bresenham_callback cb, float correct) -{ - float bv[6]; - int a, z, slabsize=res[0]*res[1], size= res[0]*res[1]*res[2]; + /* convert light pos to sim cell space */ + mul_m4_v3(sds->imat, light); + light[0] = (light[0] - sds->p0[0]) / sds->cell_size[0] - 0.5f; + light[1] = (light[1] - sds->p0[1]) / sds->cell_size[1] - 0.5f; + light[2] = (light[2] - sds->p0[2]) / sds->cell_size[2] - 0.5f; for(a=0; ashadow[a]= -1.0f; - bv[0] = p0[0]; - bv[1] = p1[0]; - // y - bv[2] = p0[1]; - bv[3] = p1[1]; - // z - bv[4] = p0[2]; - bv[5] = p1[2]; + /* calculate domain bounds in sim cell space */ + // 0,2,4 = 0.0f + bv[1] = (float)sds->res[0]; // x + bv[3] = (float)sds->res[1]; // y + bv[5] = (float)sds->res[2]; // z // #pragma omp parallel for schedule(static,1) - for(z = 0; z < res[2]; z++) + for(z = 0; z < sds->res[2]; z++) { size_t index = z*slabsize; int x,y; - for(y = 0; y < res[1]; y++) - for(x = 0; x < res[0]; x++, index++) + for(y = 0; y < sds->res[1]; y++) + for(x = 0; x < sds->res[0]; x++, index++) { float voxelCenter[3]; float pos[3]; int cell[3]; float tRay = 1.0; - if(result[index] >= 0.0f) + if(sds->shadow[index] >= 0.0f) continue; - voxelCenter[0] = p0[0] + dx * x + dx * 0.5; - voxelCenter[1] = p0[1] + dx * y + dx * 0.5; - voxelCenter[2] = p0[2] + dx * z + dx * 0.5; + voxelCenter[0] = (float)x; + voxelCenter[1] = (float)y; + voxelCenter[2] = (float)z; - // get starting position (in voxel coords) + // get starting cell (light pos) if(BLI_bvhtree_bb_raycast(bv, light, voxelCenter, pos) > FLT_EPSILON) { - // we're ouside - get_cell(p0, res, dx, pos, cell, 1); + // we're ouside -> use point on side of domain + cell[0] = (int)floor(pos[0]); + cell[1] = (int)floor(pos[1]); + cell[2] = (int)floor(pos[2]); } else { - // we're inside - get_cell(p0, res, dx, light, cell, 1); + // we're inside -> use light itself + cell[0] = (int)floor(light[0]); + cell[1] = (int)floor(light[1]); + cell[2] = (int)floor(light[2]); } + /* clamp within grid bounds */ + CLAMP(cell[0], 0, sds->res[0]-1); + CLAMP(cell[1], 0, sds->res[1]-1); + CLAMP(cell[2], 0, sds->res[2]-1); - bresenham_linie_3D(cell[0], cell[1], cell[2], x, y, z, &tRay, cb, result, input, res, correct); + bresenham_linie_3D(cell[0], cell[1], cell[2], x, y, z, &tRay, calc_voxel_transp, sds->shadow, density, sds->res, correct); // convention -> from a RGBA float array, use G value for tRay // #pragma omp critical - result[index] = tRay; + sds->shadow[index] = tRay; } } } +/* get smoke velocity and density at given coordinates +* returns fluid density or -1.0f if outside domain*/ +float smoke_get_velocity_at(struct Object *ob, float position[3], float velocity[3]) +{ + SmokeModifierData *smd = (SmokeModifierData*)modifiers_findByType(ob, eModifierType_Smoke); + zero_v3(velocity); + + if(smd && (smd->type & MOD_SMOKE_TYPE_DOMAIN) && smd->domain && smd->domain->fluid) { + SmokeDomainSettings *sds = smd->domain; + float time_mult = 25.f * DT_DEFAULT; + float vel_mag; + float *velX = smoke_get_velocity_x(sds->fluid); + float *velY = smoke_get_velocity_y(sds->fluid); + float *velZ = smoke_get_velocity_z(sds->fluid); + float density = 0.0f, fuel = 0.0f; + float pos[3]; + copy_v3_v3(pos, position); + smoke_pos_to_cell(sds, pos); + + /* check if point is outside domain max bounds */ + if (pos[0] < sds->res_min[0] || pos[1] < sds->res_min[1] || pos[2] < sds->res_min[2]) return -1.0f; + if (pos[0] > sds->res_max[0] || pos[1] > sds->res_max[1] || pos[2] > sds->res_max[2]) return -1.0f; + + /* map pos between 0.0 - 1.0 */ + pos[0] = (pos[0] - sds->res_min[0]) / ((float)sds->res[0]); + pos[1] = (pos[1] - sds->res_min[1]) / ((float)sds->res[1]); + pos[2] = (pos[2] - sds->res_min[2]) / ((float)sds->res[2]); + + + /* check if point is outside active area */ + if (smd->domain->flags & MOD_SMOKE_ADAPTIVE_DOMAIN) { + if (pos[0] < 0.0f || pos[1] < 0.0f || pos[2] < 0.0f) return 0.0f; + if (pos[0] > 1.0f || pos[1] > 1.0f || pos[2] > 1.0f) return 0.0f; + } + + /* get interpolated velocity */ + velocity[0] = BLI_voxel_sample_trilinear(velX, sds->res, pos) * sds->global_size[0] * time_mult; + velocity[1] = BLI_voxel_sample_trilinear(velY, sds->res, pos) * sds->global_size[1] * time_mult; + velocity[2] = BLI_voxel_sample_trilinear(velZ, sds->res, pos) * sds->global_size[2] * time_mult; + + /* convert velocity direction to global space */ + vel_mag = len_v3(velocity); + mul_mat3_m4_v3(sds->obmat, velocity); + normalize_v3(velocity); + mul_v3_fl(velocity, vel_mag); + + /* use max value of fuel or smoke density */ + density = BLI_voxel_sample_trilinear(smoke_get_density(sds->fluid), sds->res, pos); + if (smoke_has_fuel(sds->fluid)) { + fuel = BLI_voxel_sample_trilinear(smoke_get_fuel(sds->fluid), sds->res, pos); + } + return MAX2(density, fuel); + } + return -1.0f; +} + +int smoke_get_data_flags(SmokeDomainSettings *sds) { + int flags = 0; + if (smoke_has_heat(sds->fluid)) flags |= SM_ACTIVE_HEAT; + if (smoke_has_fuel(sds->fluid)) flags |= SM_ACTIVE_FIRE; + if (smoke_has_colors(sds->fluid)) flags |= SM_ACTIVE_COLORS; + + return flags; +} + #endif /* WITH_SMOKE */ diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c index 9dd83181521..300d272b86b 100644 --- a/source/blender/blenkernel/intern/texture.c +++ b/source/blender/blenkernel/intern/texture.c @@ -571,7 +571,7 @@ void default_mtex(MTex *mtex) mtex->size[1] = 1.0; mtex->size[2] = 1.0; mtex->tex = NULL; - mtex->texflag = MTEX_3TAP_BUMP | MTEX_BUMP_OBJECTSPACE; + mtex->texflag = MTEX_3TAP_BUMP | MTEX_BUMP_OBJECTSPACE | MTEX_MAPTO_BOUNDS; mtex->colormodel = 0; mtex->r = 1.0; mtex->g = 0.0; diff --git a/source/blender/blenlib/BLI_math_vector.h b/source/blender/blenlib/BLI_math_vector.h index a471f95d505..83b07bae53f 100644 --- a/source/blender/blenlib/BLI_math_vector.h +++ b/source/blender/blenlib/BLI_math_vector.h @@ -67,6 +67,7 @@ MINLINE void copy_v2_v2_short(short r[2], const short a[2]); MINLINE void copy_v3_v3_short(short r[3], const short a[3]); MINLINE void copy_v4_v4_short(short r[4], const short a[4]); /* int */ +MINLINE void zero_v3_int(int r[3]); MINLINE void copy_v2_v2_int(int r[2], const int a[2]); MINLINE void copy_v3_v3_int(int r[3], const int a[3]); MINLINE void copy_v4_v4_int(int r[4], const int a[4]); diff --git a/source/blender/blenlib/BLI_utildefines.h b/source/blender/blenlib/BLI_utildefines.h index beb554042ea..47c2256c1e1 100644 --- a/source/blender/blenlib/BLI_utildefines.h +++ b/source/blender/blenlib/BLI_utildefines.h @@ -193,6 +193,11 @@ *(v1 + 1) = *(v2 + 1) + *(v3 + 1) * (fac); \ *(v1 + 2) = *(v2 + 2) + *(v3 + 2) * (fac); \ } (void)0 +#define VECMADD(v1, v2, v3, v4) { \ + *(v1) = *(v2) + *(v3) * (*(v4)); \ + *(v1 + 1) = *(v2 + 1) + *(v3 + 1) * (*(v4 + 1)); \ + *(v1 + 2) = *(v2 + 2) + *(v3 + 2) * (*(v4 + 2)); \ +} (void)0 #define VECSUBFAC(v1, v2, v3, fac) { \ *(v1) = *(v2) - *(v3) * (fac); \ *(v1 + 1) = *(v2 + 1) - *(v3 + 1) * (fac); \ diff --git a/source/blender/blenlib/intern/math_vector_inline.c b/source/blender/blenlib/intern/math_vector_inline.c index de1038724b0..191b0e16025 100644 --- a/source/blender/blenlib/intern/math_vector_inline.c +++ b/source/blender/blenlib/intern/math_vector_inline.c @@ -121,6 +121,13 @@ MINLINE void copy_v4_v4_char(char r[4], const char a[4]) } /* short */ +MINLINE void zero_v3_int(int r[3]) +{ + r[0] = 0; + r[1] = 0; + r[2] = 0; +} + MINLINE void copy_v2_v2_short(short r[2], const short a[2]) { r[0] = a[0]; diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 606fd48dc2b..9171e78e7ad 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -3335,6 +3335,8 @@ static void lib_link_partdeflect(FileData *fd, ID *id, PartDeflect *pd) { if (pd && pd->tex) pd->tex = newlibadr_us(fd, id->lib, pd->tex); + if (pd && pd->f_source) + pd->f_source = newlibadr_us(fd, id->lib, pd->f_source); } static void lib_link_particlesettings(FileData *fd, Main *main) @@ -4333,6 +4335,9 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb) smd->coll = NULL; smd->flow = newdataadr(fd, smd->flow); smd->flow->smd = smd; + smd->flow->dm = NULL; + smd->flow->verts_old = NULL; + smd->flow->numverts = 0; smd->flow->psys = newdataadr(fd, smd->flow->psys); } else if (smd->type == MOD_SMOKE_TYPE_COLL) { @@ -4341,11 +4346,15 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb) smd->coll = newdataadr(fd, smd->coll); if (smd->coll) { smd->coll->smd = smd; - smd->coll->points = NULL; - smd->coll->numpoints = 0; + smd->coll->verts_old = NULL; + smd->coll->numverts = 0; + smd->coll->dm = NULL; } else { smd->type = 0; + smd->flow = NULL; + smd->domain = NULL; + smd->coll = NULL; } } } @@ -8038,6 +8047,44 @@ static void do_versions(FileData *fd, Library *lib, Main *main) /* WATCH IT!!!: pointers from libdata have not been converted yet here! */ /* WATCH IT 2!: Userdef struct init has to be in editors/interface/resources.c! */ + { + Object *ob; + + for (ob = main->object.first; ob; ob = ob->id.next) { + ModifierData *md; + for (md = ob->modifiers.first; md; md = md->next) { + if (md->type == eModifierType_Smoke) { + SmokeModifierData *smd = (SmokeModifierData *)md; + if ((smd->type & MOD_SMOKE_TYPE_DOMAIN) && smd->domain) { + /* keep branch saves if possible */ + if (!smd->domain->flame_max_temp) { + smd->domain->burning_rate = 0.75f; + smd->domain->flame_smoke = 1.0f; + smd->domain->flame_vorticity = 0.5f; + smd->domain->flame_ignition = 1.25f; + smd->domain->flame_max_temp = 1.75f; + smd->domain->adapt_threshold = 0.02f; + smd->domain->adapt_margin = 4; + smd->domain->flame_smoke_color[0] = 0.7f; + smd->domain->flame_smoke_color[1] = 0.7f; + smd->domain->flame_smoke_color[2] = 0.7f; + } + } + else if ((smd->type & MOD_SMOKE_TYPE_FLOW) && smd->flow) { + if (!smd->flow->texture_size) { + smd->flow->fuel_amount = 1.0; + smd->flow->surface_distance = 1.5; + smd->flow->color[0] = 0.7f; + smd->flow->color[1] = 0.7f; + smd->flow->color[2] = 0.7f; + smd->flow->texture_size = 1.0f; + } + } + } + } + } + } + /* don't forget to set version number in blender.c! */ } diff --git a/source/blender/editors/include/UI_icons.h b/source/blender/editors/include/UI_icons.h index ef7b8ed3a41..8f50edd1240 100644 --- a/source/blender/editors/include/UI_icons.h +++ b/source/blender/editors/include/UI_icons.h @@ -450,8 +450,8 @@ DEF_ICON(FORCE_CURVE) DEF_ICON(FORCE_BOID) DEF_ICON(FORCE_TURBULENCE) DEF_ICON(FORCE_DRAG) +DEF_ICON(FORCE_SMOKEFLOW) #ifndef DEF_ICON_BLANK_SKIP - DEF_ICON(BLANK672) DEF_ICON(BLANK673) DEF_ICON(BLANK674) DEF_ICON(BLANK675) diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index 43a32cd662e..dc20e0d69cd 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -136,6 +136,7 @@ static EnumPropertyItem field_type_items[] = { {PFIELD_BOID, "BOID", ICON_FORCE_BOID, "Boid", ""}, {PFIELD_TURBULENCE, "TURBULENCE", ICON_FORCE_TURBULENCE, "Turbulence", ""}, {PFIELD_DRAG, "DRAG", ICON_FORCE_DRAG, "Drag", ""}, + {PFIELD_SMOKEFLOW, "SMOKE", ICON_FORCE_SMOKEFLOW, "Smoke Flow", ""}, {0, NULL, 0, NULL, NULL} }; @@ -356,7 +357,7 @@ Object *ED_object_add_type(bContext *C, int type, const float loc[3], const floa Scene *scene = CTX_data_scene(C); Object *ob; - /* For as long scene has editmode... */ + /* for as long scene has editmode... */ if (CTX_data_edit_object(C)) ED_object_exit_editmode(C, EM_FREEDATA | EM_FREEUNDO | EM_WAITCURSOR | EM_DO_UNDO); /* freedata, and undo */ diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index eb17aa2b8ce..dd3c7408511 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -6625,72 +6625,74 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short } /* only draw domains */ - if (smd->domain && smd->domain->fluid) { - if (CFRA < smd->domain->point_cache[0]->startframe) { - /* don't show smoke before simulation starts, this could be made an option in the future */ + if (smd->domain) { + SmokeDomainSettings *sds = smd->domain; + float p0[3], p1[3], viewnormal[3]; + BoundBox bb; + + glLoadMatrixf(rv3d->viewmat); + glMultMatrixf(ob->obmat); + + /* draw adaptive domain bounds */ + if (sds->flags & MOD_SMOKE_ADAPTIVE_DOMAIN) { + /* draw domain max bounds */ + VECSUBFAC(p0, sds->p0, sds->cell_size, sds->adapt_res); + VECADDFAC(p1, sds->p1, sds->cell_size, sds->adapt_res); + BKE_boundbox_init_from_minmax(&bb, p0, p1); + draw_box(bb.vec); + + /* draw base resolution bounds */ + /*BKE_boundbox_init_from_minmax(&bb, sds->p0, sds->p1); + draw_box(bb.vec);*/ } - else if (!smd->domain->wt || !(smd->domain->viewsettings & MOD_SMOKE_VIEW_SHOWBIG)) { -// #if 0 - smd->domain->tex = NULL; - GPU_create_smoke(smd, 0); - draw_volume(ar, smd->domain->tex, - smd->domain->p0, smd->domain->p1, - smd->domain->res, smd->domain->dx, - smd->domain->tex_shadow); - GPU_free_smoke(smd); -// #endif -#if 0 - int x, y, z; - float *density = smoke_get_density(smd->domain->fluid); - glLoadMatrixf(rv3d->viewmat); - // glMultMatrixf(ob->obmat); + /* don't show smoke before simulation starts, this could be made an option in the future */ + if (smd->domain->fluid && CFRA >= smd->domain->point_cache[0]->startframe) { - if (col || (ob->flag & SELECT)) cpack(0xFFFFFF); - glDepthMask(GL_FALSE); - glEnable(GL_BLEND); - + // get view vector + copy_v3_v3(viewnormal, rv3d->viewinv[2]); + mul_mat3_m4_v3(ob->imat, viewnormal); + normalize_v3(viewnormal); - // glPointSize(3.0); - bglBegin(GL_POINTS); + /* set dynamic boundaries to draw the volume */ + p0[0] = sds->p0[0] + sds->cell_size[0]*sds->res_min[0] + sds->obj_shift_f[0]; + p0[1] = sds->p0[1] + sds->cell_size[1]*sds->res_min[1] + sds->obj_shift_f[1]; + p0[2] = sds->p0[2] + sds->cell_size[2]*sds->res_min[2] + sds->obj_shift_f[2]; + p1[0] = sds->p0[0] + sds->cell_size[0]*sds->res_max[0] + sds->obj_shift_f[0]; + p1[1] = sds->p0[1] + sds->cell_size[1]*sds->res_max[1] + sds->obj_shift_f[1]; + p1[2] = sds->p0[2] + sds->cell_size[2]*sds->res_max[2] + sds->obj_shift_f[2]; - for (x = 0; x < smd->domain->res[0]; x++) { - for (y = 0; y < smd->domain->res[1]; y++) { - for (z = 0; z < smd->domain->res[2]; z++) { - float tmp[3]; - int index = smoke_get_index(x, smd->domain->res[0], y, smd->domain->res[1], z); + /* scale cube to global space to equalize volume slicing on all axises + * (its scaled back before drawing) */ + mul_v3_v3(p0, ob->size); + mul_v3_v3(p1, ob->size); - if (density[index] > FLT_EPSILON) { - float color[3]; - copy_v3_v3(tmp, smd->domain->p0); - tmp[0] += smd->domain->dx * x + smd->domain->dx * 0.5; - tmp[1] += smd->domain->dx * y + smd->domain->dx * 0.5; - tmp[2] += smd->domain->dx * z + smd->domain->dx * 0.5; - color[0] = color[1] = color[2] = density[index]; - glColor3fv(color); - bglVertex3fv(tmp); - } - } - } + if (!sds->wt || !(sds->viewsettings & MOD_SMOKE_VIEW_SHOWBIG)) { + smd->domain->tex = NULL; + GPU_create_smoke(smd, 0); + draw_smoke_volume(sds, ob, ar, sds->tex, + p0, p1, + sds->res, sds->dx, sds->scale*sds->maxres, + viewnormal, sds->tex_shadow, sds->tex_flame); + GPU_free_smoke(smd); + } + else if (sds->wt && (sds->viewsettings & MOD_SMOKE_VIEW_SHOWBIG)) { + sds->tex = NULL; + GPU_create_smoke(smd, 1); + draw_smoke_volume(sds, ob, ar, sds->tex, + p0, p1, + sds->res_wt, sds->dx, sds->scale*sds->maxres, + viewnormal, sds->tex_shadow, sds->tex_flame); + GPU_free_smoke(smd); } - bglEnd(); - glPointSize(1.0); - - glMultMatrixf(ob->obmat); - glDisable(GL_BLEND); - glDepthMask(GL_TRUE); - if (col) cpack(col); -#endif - } - else if (smd->domain->wt && (smd->domain->viewsettings & MOD_SMOKE_VIEW_SHOWBIG)) { - smd->domain->tex = NULL; - GPU_create_smoke(smd, 1); - draw_volume(ar, smd->domain->tex, - smd->domain->p0, smd->domain->p1, - smd->domain->res_wt, smd->domain->dx_wt, - smd->domain->tex_shadow); - GPU_free_smoke(smd); + /* smoke debug render */ + #ifdef SMOKE_DEBUG_VELOCITY + draw_smoke_velocity(smd->domain, ob); + #endif + #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 2c2d4039225..7215e8ec6b4 100644 --- a/source/blender/editors/space_view3d/drawvolume.c +++ b/source/blender/editors/space_view3d/drawvolume.c @@ -36,6 +36,7 @@ #include "DNA_scene_types.h" #include "DNA_screen_types.h" +#include "DNA_smoke_types.h" #include "DNA_view3d_types.h" #include "BLI_utildefines.h" @@ -156,12 +157,9 @@ static int convex(const float p0[3], const float up[3], const float a[3], const return dot_v3v3(up, tmp) >= 0; } -void draw_volume(ARegion *ar, GPUTexture *tex, float min[3], float max[3], int res[3], float dx, GPUTexture *tex_shadow) +void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob, ARegion *ar, GPUTexture *tex, float min[3], float max[3], int res[3], float dx, float base_scale, float viewnormal[3], GPUTexture *tex_shadow, GPUTexture *tex_flame) { - RegionView3D *rv3d = ar->regiondata; - - float viewnormal[3]; - int i, j, n, good_index; + int i, j, k, n, good_index; float d /*, d0 */ /* UNUSED */, dd, ds; float *points = NULL; int numpoints = 0; @@ -193,24 +191,72 @@ void draw_volume(ARegion *ar, GPUTexture *tex, float min[3], float max[3], int r {{-1.0f, 1.0f, -1.0f}, {2.0f, 0.0f, 0.0f}} }; + unsigned char *spec_data; + float *spec_pixels; + GPUTexture *tex_spec; + /* Fragment program to calculate the view3d of smoke */ - /* using 2 textures, density and shadow */ - const char *text = "!!ARBfp1.0\n" + /* using 4 textures, density, shadow, flame and flame spectrum */ + const char *shader_basic = "!!ARBfp1.0\n" "PARAM dx = program.local[0];\n" "PARAM darkness = program.local[1];\n" + "PARAM render = program.local[2];\n" "PARAM f = {1.442695041, 1.442695041, 1.442695041, 0.01};\n" - "TEMP temp, shadow, value;\n" + "TEMP temp, shadow, flame, spec, value;\n" "TEX temp, fragment.texcoord[0], texture[0], 3D;\n" "TEX shadow, fragment.texcoord[0], texture[1], 3D;\n" - "MUL value, temp, darkness;\n" - "MUL value, value, dx;\n" - "MUL value, value, f;\n" + "TEX flame, fragment.texcoord[0], texture[2], 3D;\n" + "TEX spec, flame.r, texture[3], 1D;\n" + /* calculate shading factor from density */ + "MUL value.r, temp.a, darkness.a;\n" + "MUL value.r, value.r, dx.r;\n" + "MUL value.r, value.r, f.r;\n" "EX2 temp, -value.r;\n" - "SUB temp.a, 1.0, temp.r;\n" + /* alpha */ + "SUB temp.a, 1.0, temp.r;\n" + /* shade colors */ "MUL temp.r, temp.r, shadow.r;\n" "MUL temp.g, temp.g, shadow.r;\n" "MUL temp.b, temp.b, shadow.r;\n" - "MOV result.color, temp;\n" + "MUL temp.r, temp.r, darkness.r;\n" + "MUL temp.g, temp.g, darkness.g;\n" + "MUL temp.b, temp.b, darkness.b;\n" + /* for now this just replace smoke shading if rendering fire */ + "CMP result.color, render.r, temp, spec;\n" + "END\n"; + + /* color shader */ + const char *shader_color = "!!ARBfp1.0\n" + "PARAM dx = program.local[0];\n" + "PARAM darkness = program.local[1];\n" + "PARAM render = program.local[2];\n" + "PARAM f = {1.442695041, 1.442695041, 1.442695041, 1.442695041};\n" + "TEMP temp, shadow, flame, spec, value;\n" + "TEX temp, fragment.texcoord[0], texture[0], 3D;\n" + "TEX shadow, fragment.texcoord[0], texture[1], 3D;\n" + "TEX flame, fragment.texcoord[0], texture[2], 3D;\n" + "TEX spec, flame.r, texture[3], 1D;\n" + /* unpremultiply volume texture */ + "RCP value.r, temp.a;\n" + "MUL temp.r, temp.r, value.r;\n" + "MUL temp.g, temp.g, value.r;\n" + "MUL temp.b, temp.b, value.r;\n" + /* calculate shading factor from density */ + "MUL value.r, temp.a, darkness.a;\n" + "MUL value.r, value.r, dx.r;\n" + "MUL value.r, value.r, f.r;\n" + "EX2 value.r, -value.r;\n" + /* alpha */ + "SUB temp.a, 1.0, value.r;\n" + /* shade colors */ + "MUL temp.r, temp.r, shadow.r;\n" + "MUL temp.g, temp.g, shadow.r;\n" + "MUL temp.b, temp.b, shadow.r;\n" + "MUL temp.r, temp.r, value.r;\n" + "MUL temp.g, temp.g, value.r;\n" + "MUL temp.b, temp.b, value.r;\n" + /* for now this just replace smoke shading if rendering fire */ + "CMP result.color, render.r, temp, spec;\n" "END\n"; GLuint prog; @@ -223,6 +269,32 @@ void draw_volume(ARegion *ar, GPUTexture *tex, float min[3], float max[3], int r } tstart(); + /* generate flame spectrum texture */ + #define SPEC_WIDTH 256 + #define FIRE_THRESH 7 + #define MAX_FIRE_ALPHA 0.06f + #define FULL_ON_FIRE 100 + spec_data = malloc(SPEC_WIDTH*4 * sizeof(unsigned char)); + flame_get_spectrum(spec_data, SPEC_WIDTH, 1500, 3000); + spec_pixels = malloc(SPEC_WIDTH*4*16*16 * sizeof(float)); + for (i=0;i<16;i++){ + for (j=0;j<16;j++) { + for (k=0;k=FIRE_THRESH) { + spec_pixels[index] = ((float)spec_data[k*4])/255.0f; + spec_pixels[index+1] = ((float)spec_data[k*4+1])/255.0f; + spec_pixels[index+2] = ((float)spec_data[k*4+2])/255.0f; + spec_pixels[index+3] = MAX_FIRE_ALPHA*( + (k>FULL_ON_FIRE) ? 1.0f : (k-FIRE_THRESH)/((float)FULL_ON_FIRE-FIRE_THRESH)); + } else { + spec_pixels[index] = spec_pixels[index+1] = spec_pixels[index+2] = spec_pixels[index+3] = 0.0f; + } + } + } + } + + tex_spec = GPU_texture_create_1D(SPEC_WIDTH, spec_pixels, NULL); sub_v3_v3v3(size, max, min); @@ -294,26 +366,11 @@ void draw_volume(ARegion *ar, GPUTexture *tex, float min[3], float max[3], int r edges[11][1][0] = size[0]; glGetBooleanv(GL_BLEND, (GLboolean *)&gl_blend); - glGetBooleanv(GL_DEPTH_TEST, (GLboolean *)&gl_depth); - - glLoadMatrixf(rv3d->viewmat); - // glMultMatrixf(ob->obmat); + glGetBooleanv(GL_DEPTH_TEST, (GLboolean *)&gl_depth); glDepthMask(GL_FALSE); glDisable(GL_DEPTH_TEST); glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - -#if 0 - printf("Viewinv:\n"); - printf("%f, %f, %f\n", rv3d->viewinv[0][0], rv3d->viewinv[0][1], rv3d->viewinv[0][2]); - printf("%f, %f, %f\n", rv3d->viewinv[1][0], rv3d->viewinv[1][1], rv3d->viewinv[1][2]); - printf("%f, %f, %f\n", rv3d->viewinv[2][0], rv3d->viewinv[2][1], rv3d->viewinv[2][2]); -#endif - - /* get view vector */ - copy_v3_v3(viewnormal, rv3d->viewinv[2]); - normalize_v3(viewnormal); /* find cube vertex that is closest to the viewer */ for (i = 0; i < 8; i++) { @@ -344,12 +401,19 @@ void draw_volume(ARegion *ar, GPUTexture *tex, float min[3], float max[3], int r glGenProgramsARB(1, &prog); glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, prog); - glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei)strlen(text), text); + /* set shader */ + if (sds->active_fields & SM_ACTIVE_COLORS) + glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei)strlen(shader_color), shader_color); + else + glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei)strlen(shader_basic), shader_basic); /* cell spacing */ glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 0, dx, dx, dx, 1.0); /* custom parameter for smoke style (higher = thicker) */ - glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 1, 7.0, 7.0, 7.0, 1.0); + if (sds->active_fields & SM_ACTIVE_COLORS) + glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 1, 1.0, 1.0, 1.0, 10.0); + else + glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 1, sds->active_color[0], sds->active_color[1], sds->active_color[2], 10.0); } else printf("Your gfx card does not support 3D View smoke drawing.\n"); @@ -360,6 +424,11 @@ void draw_volume(ARegion *ar, GPUTexture *tex, float min[3], float max[3], int r else printf("No volume shadow\n"); + if (tex_flame) { + GPU_texture_bind(tex_flame, 2); + GPU_texture_bind(tex_spec, 3); + } + if (!GPU_non_power_of_two_support()) { cor[0] = (float)res[0] / (float)power_of_2_max_i(res[0]); cor[1] = (float)res[1] / (float)power_of_2_max_i(res[1]); @@ -373,7 +442,7 @@ void draw_volume(ARegion *ar, GPUTexture *tex, float min[3], float max[3], int r /* d0 = (viewnormal[0]*cv[i][0] + viewnormal[1]*cv[i][1] + viewnormal[2]*cv[i][2]); */ /* UNUSED */ ds = (ABS(viewnormal[0]) * size[0] + ABS(viewnormal[1]) * size[1] + ABS(viewnormal[2]) * size[2]); - dd = ds / 96.f; + dd = MAX3(sds->global_size[0],sds->global_size[1],sds->global_size[2])/128.f; n = 0; good_index = i; @@ -416,14 +485,29 @@ void draw_volume(ARegion *ar, GPUTexture *tex, float min[3], float max[3], int r } } - // printf("numpoints: %d\n", numpoints); + /* render fire slice */ + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 2, 1.0, 0.0, 0.0, 0.0); glBegin(GL_POLYGON); glColor3f(1.0, 1.0, 1.0); for (i = 0; i < numpoints; i++) { glTexCoord3d((points[i * 3 + 0] - min[0]) * cor[0] / size[0], (points[i * 3 + 1] - min[1]) * cor[1] / size[1], (points[i * 3 + 2] - min[2]) * cor[2] / size[2]); - glVertex3f(points[i * 3 + 0], points[i * 3 + 1], points[i * 3 + 2]); + glVertex3f(points[i * 3 + 0]/ob->size[0], points[i * 3 + 1]/ob->size[1], points[i * 3 + 2]/ob->size[2]); + } + glEnd(); + + /* render smoke slice */ + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 2, -1.0, 0.0, 0.0, 0.0); + glBegin(GL_POLYGON); + glColor3f(1.0, 1.0, 1.0); + for (i = 0; i < numpoints; i++) { + glTexCoord3d((points[i * 3 + 0] - min[0]) * cor[0] / size[0], + (points[i * 3 + 1] - min[1]) * cor[1] / size[1], + (points[i * 3 + 2] - min[2]) * cor[2] / size[2]); + glVertex3f(points[i * 3 + 0]/ob->size[0], points[i * 3 + 1]/ob->size[1], points[i * 3 + 2]/ob->size[2]); } glEnd(); } @@ -436,6 +520,14 @@ void draw_volume(ARegion *ar, GPUTexture *tex, float min[3], float max[3], int r if (tex_shadow) GPU_texture_unbind(tex_shadow); GPU_texture_unbind(tex); + if (tex_flame) { + GPU_texture_unbind(tex_flame); + GPU_texture_unbind(tex_spec); + } + GPU_texture_free(tex_spec); + + free(spec_data); + free(spec_pixels); if (GLEW_ARB_fragment_program) { glDisable(GL_FRAGMENT_PROGRAM_ARB); @@ -454,3 +546,106 @@ void draw_volume(ARegion *ar, GPUTexture *tex, float min[3], float max[3], int r glDepthMask(GL_TRUE); } } + +#ifdef SMOKE_DEBUG_VELOCITY +void draw_smoke_velocity(SmokeDomainSettings *domain, Object *ob) +{ + 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); + + float min[3]; + float *cell_size = domain->cell_size; + float step_size = ((float)MAX3(base_res[0], base_res[1], base_res[2]))/16.f; + float vf = domain->scale / 16.f * 2.f; /* velocity factor */ + + glLineWidth(1.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 (x0p0, domain->obj_shift_f); + + for (x=floor(x0); x= 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); + + 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(); + } + } +} +#endif + +#ifdef SMOKE_DEBUG_HEAT +void draw_smoke_heat(SmokeDomainSettings *domain, Object *ob) +{ + 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 *heat = smoke_get_heat(domain->fluid); + + float min[3]; + float *cell_size = domain->cell_size; + float step_size = ((float)MAX3(base_res[0], base_res[1], base_res[2]))/16.f; + float vf = domain->scale / 16.f * 2.f; /* velocity factor */ + + /* 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 (x0p0, domain->obj_shift_f); + + for (x=floor(x0); x= 0.01f) { + float col_gb = 1.0f - heat[index]; + CLAMP(col_gb, 0.0f, 1.0f); + glColor3f(1.0f, col_gb, col_gb); + glPointSize(24.0f * heat[index]); + + glBegin(GL_POINTS); + glVertex3f(pos[0], pos[1], pos[2]); + glEnd(); + } + } +} +#endif diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h index 5bfabf4fc4a..8d7a6421a34 100644 --- a/source/blender/editors/space_view3d/view3d_intern.h +++ b/source/blender/editors/space_view3d/view3d_intern.h @@ -212,7 +212,16 @@ ARegion *view3d_has_tools_region(ScrArea *sa); extern const char *view3d_context_dir[]; /* doc access */ /* draw_volume.c */ -void draw_volume(struct ARegion *ar, struct GPUTexture *tex, float min[3], float max[3], int res[3], float dx, struct GPUTexture *tex_shadow); +void draw_smoke_volume(struct SmokeDomainSettings *sds, struct Object *ob, struct ARegion *ar, struct GPUTexture *tex, float min[3], float max[3], int res[3], float dx, float base_scale, float viewnormal[3], struct GPUTexture *tex_shadow, struct GPUTexture *tex_flame); +//#define SMOKE_DEBUG_VELOCITY +//#define SMOKE_DEBUG_HEAT + +#ifdef SMOKE_DEBUG_VELOCITY +void draw_smoke_velocity(struct SmokeDomainSettings *domain, struct Object *ob); +#endif +#ifdef SMOKE_DEBUG_HEAT +void draw_smoke_heat(struct SmokeDomainSettings *domain, struct Object *ob); +#endif /* workaround for trivial but noticeable camera bug caused by imprecision * between view border calculation in 2D/3D space, workaround for bug [#28037]. diff --git a/source/blender/gpu/GPU_extensions.h b/source/blender/gpu/GPU_extensions.h index 198d002ff0d..f4bb5da0495 100644 --- a/source/blender/gpu/GPU_extensions.h +++ b/source/blender/gpu/GPU_extensions.h @@ -107,7 +107,7 @@ int GPU_type_matches(GPUDeviceType device, GPUOSType os, GPUDriverType driver); GPUTexture *GPU_texture_create_1D(int w, float *pixels, char err_out[256]); GPUTexture *GPU_texture_create_2D(int w, int h, float *pixels, char err_out[256]); -GPUTexture *GPU_texture_create_3D(int w, int h, int depth, float *fpixels); +GPUTexture *GPU_texture_create_3D(int w, int h, int depth, int channels, float *fpixels); GPUTexture *GPU_texture_create_depth(int w, int h, char err_out[256]); GPUTexture *GPU_texture_create_vsm_shadow_map(int size, char err_out[256]); GPUTexture *GPU_texture_from_blender(struct Image *ima, diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c index 956c76aec20..ac05f1e8309 100644 --- a/source/blender/gpu/intern/gpu_draw.c +++ b/source/blender/gpu/intern/gpu_draw.c @@ -1019,21 +1019,53 @@ void GPU_free_smoke(SmokeModifierData *smd) if (smd->domain->tex_shadow) GPU_texture_free(smd->domain->tex_shadow); smd->domain->tex_shadow = NULL; + + if (smd->domain->tex_flame) + GPU_texture_free(smd->domain->tex_flame); + smd->domain->tex_flame = NULL; } } void GPU_create_smoke(SmokeModifierData *smd, int highres) { #ifdef WITH_SMOKE - if (smd->type & MOD_SMOKE_TYPE_DOMAIN && !smd->domain->tex && !highres) - smd->domain->tex = GPU_texture_create_3D(smd->domain->res[0], smd->domain->res[1], smd->domain->res[2], smoke_get_density(smd->domain->fluid)); - else if (smd->type & MOD_SMOKE_TYPE_DOMAIN && !smd->domain->tex && highres) - smd->domain->tex = GPU_texture_create_3D(smd->domain->res_wt[0], smd->domain->res_wt[1], smd->domain->res_wt[2], smoke_turbulence_get_density(smd->domain->wt)); + if (smd->type & MOD_SMOKE_TYPE_DOMAIN) { + SmokeDomainSettings *sds = smd->domain; + if (!sds->tex && !highres) { + /* rgba texture for color + density */ + if (smoke_has_colors(sds->fluid)) { + float *data = MEM_callocN(sizeof(float)*sds->total_cells*4, "smokeColorTexture"); + smoke_get_rgba(sds->fluid, data, 0); + sds->tex = GPU_texture_create_3D(sds->res[0], sds->res[1], sds->res[2], 4, data); + MEM_freeN(data); + } + /* density only */ + else { + sds->tex = GPU_texture_create_3D(sds->res[0], sds->res[1], sds->res[2], 1, smoke_get_density(sds->fluid)); + } + sds->tex_flame = (smoke_has_fuel(sds->fluid)) ? GPU_texture_create_3D(sds->res[0], sds->res[1], sds->res[2], 1, smoke_get_flame(sds->fluid)) : NULL; + } + else if (!sds->tex && highres) { + /* rgba texture for color + density */ + if (smoke_turbulence_has_colors(sds->wt)) { + float *data = MEM_callocN(sizeof(float)*smoke_turbulence_get_cells(sds->wt)*4, "smokeColorTexture"); + smoke_turbulence_get_rgba(sds->wt, data, 0); + sds->tex = GPU_texture_create_3D(sds->res_wt[0], sds->res_wt[1], sds->res_wt[2], 4, data); + MEM_freeN(data); + } + /* density only */ + else { + sds->tex = GPU_texture_create_3D(sds->res_wt[0], sds->res_wt[1], sds->res_wt[2], 1, smoke_turbulence_get_density(sds->wt)); + } + sds->tex_flame = (smoke_turbulence_has_fuel(sds->wt)) ? GPU_texture_create_3D(sds->res_wt[0], sds->res_wt[1], sds->res_wt[2], 1, smoke_turbulence_get_flame(sds->wt)) : NULL; + } - smd->domain->tex_shadow = GPU_texture_create_3D(smd->domain->res[0], smd->domain->res[1], smd->domain->res[2], smd->domain->shadow); + sds->tex_shadow = GPU_texture_create_3D(sds->res[0], sds->res[1], sds->res[2], 1, sds->shadow); + } #else // WITH_SMOKE (void)highres; smd->domain->tex= NULL; + smd->domain->tex_flame= NULL; smd->domain->tex_shadow= NULL; #endif // WITH_SMOKE } diff --git a/source/blender/gpu/intern/gpu_extensions.c b/source/blender/gpu/intern/gpu_extensions.c index c5f427fbcab..798868a5efe 100644 --- a/source/blender/gpu/intern/gpu_extensions.c +++ b/source/blender/gpu/intern/gpu_extensions.c @@ -442,7 +442,7 @@ static GPUTexture *GPU_texture_create_nD(int w, int h, int n, float *fpixels, in } -GPUTexture *GPU_texture_create_3D(int w, int h, int depth, float *fpixels) +GPUTexture *GPU_texture_create_3D(int w, int h, int depth, int channels, float *fpixels) { GPUTexture *tex; GLenum type, format, internalformat; @@ -480,9 +480,15 @@ GPUTexture *GPU_texture_create_3D(int w, int h, int depth, float *fpixels) GPU_print_error("3D glBindTexture"); - type = GL_FLOAT; // GL_UNSIGNED_BYTE - format = GL_RED; - internalformat = GL_INTENSITY; + type = GL_FLOAT; + if (channels == 4) { + format = GL_RGBA; + internalformat = GL_RGBA; + } + else { + format = GL_RED; + internalformat = GL_INTENSITY; + } //if (fpixels) // pixels = GPU_texture_convert_pixels(w*h*depth, fpixels); diff --git a/source/blender/makesdna/DNA_object_force.h b/source/blender/makesdna/DNA_object_force.h index 1dd2aa6c59b..67d540db177 100644 --- a/source/blender/makesdna/DNA_object_force.h +++ b/source/blender/makesdna/DNA_object_force.h @@ -54,6 +54,7 @@ typedef enum PFieldType { PFIELD_BOID = 10, /* Defines predator / goal for boids */ PFIELD_TURBULENCE = 11, /* Force defined by BLI_gTurbulence */ PFIELD_DRAG = 12, /* Linear & quadratic drag */ + PFIELD_SMOKEFLOW = 13, /* Force based on smoke simulation air flow */ NUM_PFIELD_TYPES } PFieldType; @@ -110,14 +111,17 @@ typedef struct PartDeflect { struct RNG *rng; /* random noise generator for e.g. wind */ float f_noise; /* noise of force */ int seed; /* noise random seed */ + + struct Object *f_source; /* force source object */ } PartDeflect; typedef struct EffectorWeights { struct Group *group; /* only use effectors from this group of objects */ - float weight[13]; /* effector type specific weights */ + float weight[14]; /* effector type specific weights */ float global_gravity; short flag, rt[3]; + int pad; } EffectorWeights; /* EffectorWeights->flag */ @@ -365,6 +369,7 @@ typedef struct SoftBody { #define PFIELD_DO_LOCATION (1<<14) #define PFIELD_DO_ROTATION (1<<15) #define PFIELD_GUIDE_PATH_WEIGHT (1<<16) /* apply curve weights */ +#define PFIELD_SMOKE_DENSITY (1<<17) /* multiply smoke force by density */ /* pd->falloff */ #define PFIELD_FALL_SPHERE 0 diff --git a/source/blender/makesdna/DNA_smoke_types.h b/source/blender/makesdna/DNA_smoke_types.h index cceb7333478..76ba3fcf7f8 100644 --- a/source/blender/makesdna/DNA_smoke_types.h +++ b/source/blender/makesdna/DNA_smoke_types.h @@ -39,6 +39,7 @@ #define MOD_SMOKE_HIGH_SMOOTH (1<<5) /* smoothens high res emission*/ #define MOD_SMOKE_FILE_LOAD (1<<6) /* flag for file load */ +#define MOD_SMOKE_ADAPTIVE_DOMAIN (1<<7) /* noise */ #define MOD_SMOKE_NOISEWAVE (1<<0) @@ -61,6 +62,12 @@ #define SM_COLL_RIGID 1 #define SM_COLL_ANIMATED 2 +/* smoke data fileds (active_fields) */ +#define SM_ACTIVE_HEAT (1<<0) +#define SM_ACTIVE_FIRE (1<<1) +#define SM_ACTIVE_COLORS (1<<2) +#define SM_ACTIVE_COLOR_SET (1<<3) + typedef struct SmokeDomainSettings { struct SmokeModifierData *smd; /* for fast RNA access */ struct FLUID_3D *fluid; @@ -71,17 +78,37 @@ typedef struct SmokeDomainSettings { struct GPUTexture *tex; struct GPUTexture *tex_wt; struct GPUTexture *tex_shadow; + struct GPUTexture *tex_flame; float *shadow; - float p0[3]; /* start point of BB */ - float p1[3]; /* end point of BB */ - float dx; /* edge length of one cell */ - float omega; /* smoke color - from 0 to 1 */ - float temp; /* fluid temperature */ - float tempAmb; /* ambient temperature */ + + /* simulation data */ + float p0[3]; /* start point of BB in local space (includes sub-cell shift for adaptive domain)*/ + float p1[3]; /* end point of BB in local space */ + float dp0[3]; /* difference from object center to grid start point */ + float cell_size[3]; /* size of simulation cell in local space */ + float global_size[3]; /* global size of domain axises */ + float prev_loc[3]; + int shift[3]; /* current domain shift in simulation cells */ + float shift_f[3]; /* exact domain shift */ + float obj_shift_f[3]; /* how much object has shifted since previous smoke frame (used to "lock" domain while drawing) */ + float imat[4][4]; /* domain object imat */ + float obmat[4][4]; /* domain obmat */ + + int base_res[3]; /* initial "non-adapted" resolution */ + int res_min[3]; /* cell min */ + int res_max[3]; /* cell max */ + int res[3]; /* data resolution (res_max-res_min) */ + int total_cells; + float dx; /* 1.0f / res */ + float scale; /* largest domain size */ + + /* user settings */ + int adapt_margin; + int adapt_res; + float adapt_threshold; + float alpha; float beta; - float scale; /* largest domain size */ - int res[3]; /* domain resolution */ int amplify; /* wavelet amplification */ int maxres; /* longest axis on the BB gets this resolution assigned */ int flags; /* show up-res or low res, etc */ @@ -92,7 +119,6 @@ typedef struct SmokeDomainSettings { float strength; int res_wt[3]; float dx_wt; - int v3dnum; int cache_comp; int cache_high_comp; @@ -103,31 +129,67 @@ typedef struct SmokeDomainSettings { int border_collisions; /* How domain border collisions are handled */ float time_scale; float vorticity; - int pad2; + int active_fields; + float active_color[3]; /* monitor color situation of simulation */ + int pad; + + /* flame parameters */ + float burning_rate, flame_smoke, flame_vorticity; + float flame_ignition, flame_max_temp; + float flame_smoke_color[3]; } SmokeDomainSettings; /* inflow / outflow */ /* type */ -#define MOD_SMOKE_FLOW_TYPE_OUTFLOW (1<<1) +#define MOD_SMOKE_FLOW_TYPE_SMOKE 0 +#define MOD_SMOKE_FLOW_TYPE_FIRE 1 +#define MOD_SMOKE_FLOW_TYPE_OUTFLOW 2 +#define MOD_SMOKE_FLOW_TYPE_SMOKEFIRE 3 + +/* flow source */ +#define MOD_SMOKE_FLOW_SOURCE_PARTICLES 0 +#define MOD_SMOKE_FLOW_SOURCE_MESH 1 + +/* flow texture type */ +#define MOD_SMOKE_FLOW_TEXTURE_MAP_AUTO 0 +#define MOD_SMOKE_FLOW_TEXTURE_MAP_UV 1 /* flags */ #define MOD_SMOKE_FLOW_ABSOLUTE (1<<1) /*old style emission*/ #define MOD_SMOKE_FLOW_INITVELOCITY (1<<2) /* passes particles speed to the smoke */ +#define MOD_SMOKE_FLOW_TEXTUREEMIT (1<<3) /* use texture to control emission speed */ typedef struct SmokeFlowSettings { struct SmokeModifierData *smd; /* for fast RNA access */ + struct DerivedMesh *dm; struct ParticleSystem *psys; + struct Tex *noise_texture; + + /* initial velocity */ + float *verts_old; /* previous vertex positions in domain space */ + int numverts; + float vel_multi; // Multiplier for inherited velocity + float vel_normal; + float vel_random; + /* emission */ float density; + float color[3]; + float fuel_amount; float temp; /* delta temperature (temp - ambient temp) */ - float velocity[2]; /* UNUSED, velocity taken from particles */ - float vel_multi; // Multiplier for particle velocity - float vgrp_heat_scale[2]; /* min and max scaling for vgroup_heat */ - short vgroup_flow; /* where inflow/outflow happens - red=1=action */ + float volume_density; /* density emitted within mesh volume */ + float surface_distance; /* maximum emission distance from mesh surface */ + /* texture control */ + float texture_size; + float texture_offset; + int pad; + char uvlayer_name[64]; /* MAX_CUSTOMDATA_LAYER_NAME */ short vgroup_density; - short vgroup_heat; - short type; /* inflow =0 or outflow = 1 */ + + short type; /* smoke, flames, both, outflow */ + short source; + short texture_type; int flags; /* absolute emission etc*/ } SmokeFlowSettings; @@ -139,20 +201,11 @@ typedef struct SmokeFlowSettings { /* collision objects (filled with smoke) */ typedef struct SmokeCollSettings { struct SmokeModifierData *smd; /* for fast RNA access */ - struct BVHTree *bvhtree; /* bounding volume hierarchy for this cloth object */ - float *points; - float *points_old; - float *vel; // UNUSED - int *tridivs; - float mat[4][4]; - float mat_old[4][4]; - int numpoints; - int numverts; // check if mesh changed - int numtris; - float dx; /* global domain cell length taken from (scale / resolution) */ + struct DerivedMesh *dm; + float *verts_old; + int numverts; short type; // static = 0, rigid = 1, dynamic = 2 short pad; - int pad2; } SmokeCollSettings; #endif diff --git a/source/blender/makesdna/DNA_texture_types.h b/source/blender/makesdna/DNA_texture_types.h index 9fdd9216549..ce94a229750 100644 --- a/source/blender/makesdna/DNA_texture_types.h +++ b/source/blender/makesdna/DNA_texture_types.h @@ -171,6 +171,9 @@ typedef struct VoxelData { short flag; short extend; short smoked_type; + short data_type; + short pad; + int _pad; struct Object *object; /* for rendering smoke sims */ float int_multiplier; @@ -470,6 +473,7 @@ typedef struct ColorMapping { #define MTEX_BUMP_TEXTURESPACE 2048 /* #define MTEX_BUMP_FLIPPED 4096 */ /* UNUSED */ #define MTEX_BICUBIC_BUMP 8192 +#define MTEX_MAPTO_BOUNDS 16384 /* blendtype */ #define MTEX_BLEND 0 @@ -577,6 +581,11 @@ typedef struct ColorMapping { #define TEX_VD_SMOKEDENSITY 0 #define TEX_VD_SMOKEHEAT 1 #define TEX_VD_SMOKEVEL 2 +#define TEX_VD_SMOKEFLAME 3 + +/* data_type */ +#define TEX_VD_INTENSITY 0 +#define TEX_VD_RGBA_PREMUL 1 /******************** Ocean *****************************/ /* output */ diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c index 96529de074b..ed40f8cffb6 100644 --- a/source/blender/makesrna/intern/rna_material.c +++ b/source/blender/makesrna/intern/rna_material.c @@ -468,6 +468,12 @@ static void rna_def_material_mtex(BlenderRNA *brna) "from their parent"); RNA_def_property_update(prop, 0, "rna_Material_update"); + prop = RNA_def_property(srna, "use_map_to_bounds", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "texflag", MTEX_MAPTO_BOUNDS); + RNA_def_property_ui_text(prop, "Map to Bounds", + "Map coordinates in object bounds"); + RNA_def_property_update(prop, 0, "rna_Material_update"); + prop = RNA_def_property(srna, "use_from_original", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "texflag", MTEX_OB_DUPLI_ORIG); RNA_def_property_ui_text(prop, "From Original", diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index 1b26c0447ff..8a8bb2a2384 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -257,9 +257,6 @@ static void rna_Smoke_set_type(Main *bmain, Scene *scene, PointerRNA *ptr) { SmokeModifierData *smd = (SmokeModifierData *)ptr->data; Object *ob = (Object *)ptr->id.data; - ParticleSystemModifierData *psmd = NULL; - ParticleSystem *psys = NULL; - ParticleSettings *part = NULL; /* nothing changed */ if ((smd->type & MOD_SMOKE_TYPE_DOMAIN) && smd->domain) @@ -273,28 +270,6 @@ static void rna_Smoke_set_type(Main *bmain, Scene *scene, PointerRNA *ptr) ob->dt = OB_WIRE; break; case MOD_SMOKE_TYPE_FLOW: - for (psys = ob->particlesystem.first; psys; psys = psys->next) - if (psys->part->type == PART_EMITTER) - break; - if (ob->type == OB_MESH && !psys) { - /* add particle system */ - psmd = (ParticleSystemModifierData *)object_add_particle_system(scene, ob, NULL); - if (psmd) { - psys = psmd->psys; - part = psys->part; - part->lifetime = 1.0f; - part->sta = 1.0f; - part->end = 250.0f; - part->ren_as = PART_DRAW_NOT; - part->flag |= PART_UNBORN; - part->draw_as = PART_DRAW_DOT; - BLI_strncpy(psys->name, "SmokeParticles", sizeof(psys->name)); - psys->recalc |= (PSYS_RECALC_RESET | PSYS_RECALC_PHYS); - DAG_id_tag_update(ptr->id.data, OB_RECALC_DATA); - } - } - if (smd->flow) - smd->flow->psys = psys; case MOD_SMOKE_TYPE_COLL: case 0: default: diff --git a/source/blender/makesrna/intern/rna_object_force.c b/source/blender/makesrna/intern/rna_object_force.c index 39f85ebc742..940d59ec9b3 100644 --- a/source/blender/makesrna/intern/rna_object_force.c +++ b/source/blender/makesrna/intern/rna_object_force.c @@ -1056,6 +1056,13 @@ static void rna_def_effector_weight(BlenderRNA *brna) RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3); RNA_def_property_ui_text(prop, "Drag", "Drag effector weight"); RNA_def_property_update(prop, 0, "rna_EffectorWeight_update"); + + prop = RNA_def_property(srna, "smokeflow", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "weight[13]"); + RNA_def_property_range(prop, -200.0f, 200.0f); + RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3); + RNA_def_property_ui_text(prop, "Smoke Flow", "Smoke Flow effector weight"); + RNA_def_property_update(prop, 0, "rna_EffectorWeight_update"); } static void rna_def_field(BlenderRNA *brna) @@ -1082,6 +1089,7 @@ static void rna_def_field(BlenderRNA *brna) {PFIELD_BOID, "BOID", ICON_FORCE_BOID, "Boid", ""}, {PFIELD_TURBULENCE, "TURBULENCE", ICON_FORCE_TURBULENCE, "Turbulence", "Create turbulence with a noise field"}, {PFIELD_DRAG, "DRAG", ICON_FORCE_DRAG, "Drag", "Create a force that dampens motion"}, + {PFIELD_SMOKEFLOW, "SMOKE_FLOW", ICON_FORCE_SMOKEFLOW, "Smoke Flow", "Create a force based on smoke simulation air flow"}, {0, NULL, 0, NULL, NULL} }; @@ -1334,6 +1342,11 @@ static void rna_def_field(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "flag", PFIELD_MULTIPLE_SPRINGS); RNA_def_property_ui_text(prop, "Multiple Springs", "Every point is effected by multiple springs"); RNA_def_property_update(prop, 0, "rna_FieldSettings_update"); + + prop = RNA_def_property(srna, "use_smoke_density", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", PFIELD_SMOKE_DENSITY); + RNA_def_property_ui_text(prop, "Apply Density", "Adjust force strength based on smoke density"); + RNA_def_property_update(prop, 0, "rna_FieldSettings_update"); /* Pointer */ @@ -1342,6 +1355,12 @@ static void rna_def_field(BlenderRNA *brna) RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Texture", "Texture to use as force"); RNA_def_property_update(prop, 0, "rna_FieldSettings_update"); + + prop = RNA_def_property(srna, "source_object", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "f_source"); + RNA_def_property_ui_text(prop, "Domain Object", "Select domain object of the smoke simulation"); + RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_update(prop, 0, "rna_FieldSettings_update"); /********** Curve Guide Field Settings **********/ diff --git a/source/blender/makesrna/intern/rna_smoke.c b/source/blender/makesrna/intern/rna_smoke.c index e8818248609..417530acc14 100644 --- a/source/blender/makesrna/intern/rna_smoke.c +++ b/source/blender/makesrna/intern/rna_smoke.c @@ -65,14 +65,20 @@ static void rna_Smoke_dependency_update(Main *bmain, Scene *scene, PointerRNA *p DAG_scene_sort(bmain, scene); } +static void rna_Smoke_resetCache(Main *bmain, Scene *scene, PointerRNA *ptr) +{ + SmokeDomainSettings *settings = (SmokeDomainSettings *)ptr->data; + if (settings->smd && settings->smd->domain) + settings->point_cache[0]->flag |= PTCACHE_OUTDATED; + DAG_id_tag_update(ptr->id.data, OB_RECALC_DATA); +} + static void rna_Smoke_reset(Main *bmain, Scene *scene, PointerRNA *ptr) { SmokeDomainSettings *settings = (SmokeDomainSettings *)ptr->data; smokeModifier_reset(settings->smd); - - if (settings->smd && settings->smd->domain) - settings->point_cache[0]->flag |= PTCACHE_OUTDATED; + rna_Smoke_resetCache(bmain, scene, ptr); rna_Smoke_update(bmain, scene, ptr); } @@ -142,6 +148,30 @@ static void rna_SmokeModifier_density_get(PointerRNA *ptr, float *values) memcpy(values, density, size * sizeof(float)); } +static void rna_SmokeFlow_density_vgroup_get(PointerRNA *ptr, char *value) +{ + SmokeFlowSettings *flow = (SmokeFlowSettings *)ptr->data; + rna_object_vgroup_name_index_get(ptr, value, flow->vgroup_density); +} + +static int rna_SmokeFlow_density_vgroup_length(PointerRNA *ptr) +{ + SmokeFlowSettings *flow = (SmokeFlowSettings *)ptr->data; + return rna_object_vgroup_name_index_length(ptr, flow->vgroup_density); +} + +static void rna_SmokeFlow_density_vgroup_set(PointerRNA *ptr, const char *value) +{ + SmokeFlowSettings *flow = (SmokeFlowSettings *)ptr->data; + rna_object_vgroup_name_index_set(ptr, value, &flow->vgroup_density); +} + +static void rna_SmokeFlow_uvlayer_set(PointerRNA *ptr, const char *value) +{ + SmokeFlowSettings *flow = (SmokeFlowSettings *)ptr->data; + rna_object_uvlayer_name_set(ptr, value, flow->uvlayer_name, sizeof(flow->uvlayer_name)); +} + #else static void rna_def_smoke_domain_settings(BlenderRNA *brna) @@ -217,7 +247,7 @@ static void rna_def_smoke_domain_settings(BlenderRNA *brna) RNA_def_property_ui_range(prop, -5.0, 5.0, 0.02, 5); RNA_def_property_ui_text(prop, "Density", "How much density affects smoke motion (higher value results in faster rising smoke)"); - RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_resetCache"); prop = RNA_def_property(srna, "beta", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "beta"); @@ -225,7 +255,7 @@ static void rna_def_smoke_domain_settings(BlenderRNA *brna) RNA_def_property_ui_range(prop, -5.0, 5.0, 0.02, 5); RNA_def_property_ui_text(prop, "Heat", "How much heat affects smoke motion (higher value results in faster rising smoke)"); - RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_resetCache"); prop = RNA_def_property(srna, "collision_group", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "coll_group"); @@ -253,24 +283,24 @@ static void rna_def_smoke_domain_settings(BlenderRNA *brna) RNA_def_property_range(prop, 0.0, 10.0); RNA_def_property_ui_range(prop, 0.0, 10.0, 1, 2); RNA_def_property_ui_text(prop, "Strength", "Strength of noise"); - RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_resetCache"); prop = RNA_def_property(srna, "dissolve_speed", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "diss_speed"); RNA_def_property_range(prop, 1.0, 10000.0); RNA_def_property_ui_range(prop, 1.0, 10000.0, 1, 0); RNA_def_property_ui_text(prop, "Dissolve Speed", "Dissolve Speed"); - RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_resetCache"); prop = RNA_def_property(srna, "use_dissolve_smoke", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_SMOKE_DISSOLVE); RNA_def_property_ui_text(prop, "Dissolve Smoke", "Enable smoke to disappear over time"); - RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_resetCache"); prop = RNA_def_property(srna, "use_dissolve_smoke_log", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_SMOKE_DISSOLVE_LOG); RNA_def_property_ui_text(prop, "Logarithmic dissolve", "Using 1/x "); - RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_resetCache"); prop = RNA_def_property(srna, "point_cache", PROP_POINTER, PROP_NONE); RNA_def_property_flag(prop, PROP_NEVER_NULL); @@ -297,21 +327,21 @@ static void rna_def_smoke_domain_settings(BlenderRNA *brna) prop = RNA_def_property(srna, "smooth_emitter", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_SMOKE_HIGH_SMOOTH); RNA_def_property_ui_text(prop, "Smooth Emitter", "Smooth emitted smoke to avoid blockiness"); - RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_resetCache"); prop = RNA_def_property(srna, "time_scale", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "time_scale"); RNA_def_property_range(prop, 0.2, 1.5); RNA_def_property_ui_range(prop, 0.2, 1.5, 0.02, 5); RNA_def_property_ui_text(prop, "Time Scale", "Adjust simulation speed"); - RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_resetCache"); prop = RNA_def_property(srna, "vorticity", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "vorticity"); RNA_def_property_range(prop, 0.01, 4.0); RNA_def_property_ui_range(prop, 0.01, 4.0, 0.02, 5); RNA_def_property_ui_text(prop, "Vorticity", "Amount of turbulence/rotation in fluid"); - RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_resetCache"); prop = RNA_def_property(srna, "density", PROP_FLOAT, PROP_NONE); RNA_def_property_array(prop, 32); @@ -321,25 +351,80 @@ static void rna_def_smoke_domain_settings(BlenderRNA *brna) RNA_def_property_float_funcs(prop, "rna_SmokeModifier_density_get", NULL, NULL); RNA_def_property_ui_text(prop, "Density", "Smoke density"); - prop = RNA_def_property(srna, "cell_size", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "dx"); + prop = RNA_def_property(srna, "cell_size", PROP_FLOAT, PROP_XYZ); /* can change each frame when using adaptive domain */ RNA_def_property_clear_flag(prop, PROP_EDITABLE); - RNA_def_property_ui_text(prop, "dx", "Cell Size"); + RNA_def_property_ui_text(prop, "cell_size", "Cell Size"); - prop = RNA_def_property(srna, "start_point", PROP_FLOAT, PROP_XYZ); + prop = RNA_def_property(srna, "start_point", PROP_FLOAT, PROP_XYZ); /* can change each frame when using adaptive domain */ RNA_def_property_float_sdna(prop, NULL, "p0"); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "p0", "Start point"); - prop = RNA_def_property(srna, "scale", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "scale"); - RNA_def_property_clear_flag(prop, PROP_EDITABLE); - RNA_def_property_ui_text(prop, "scale", "Domain scale factor"); - - prop = RNA_def_property(srna, "domain_resolution", PROP_INT, PROP_XYZ); + prop = RNA_def_property(srna, "domain_resolution", PROP_INT, PROP_XYZ); /* can change each frame when using adaptive domain */ RNA_def_property_int_sdna(prop, NULL, "res"); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "res", "Smoke Grid Resolution"); + + prop = RNA_def_property(srna, "burning_rate", PROP_FLOAT, PROP_NONE); + RNA_def_property_range(prop, 0.01, 4.0); + RNA_def_property_ui_range(prop, 0.01, 2.0, 1.0, 5); + RNA_def_property_ui_text(prop, "Speed", "Speed of the burning reaction. Use larger values for smaller flame"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_resetCache"); + + prop = RNA_def_property(srna, "flame_smoke", PROP_FLOAT, PROP_NONE); + RNA_def_property_range(prop, 0.0, 8.0); + RNA_def_property_ui_range(prop, 0.0, 4.0, 1.0, 5); + RNA_def_property_ui_text(prop, "Smoke", "Amount of smoke created by burning fuel"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_resetCache"); + + prop = RNA_def_property(srna, "flame_vorticity", PROP_FLOAT, PROP_NONE); + RNA_def_property_range(prop, 0.0, 2.0); + RNA_def_property_ui_range(prop, 0.0, 1.0, 1.0, 5); + RNA_def_property_ui_text(prop, "Vorticity", "Additional vorticity for the flames"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_resetCache"); + + prop = RNA_def_property(srna, "flame_ignition", PROP_FLOAT, PROP_NONE); + RNA_def_property_range(prop, 0.5, 5.0); + RNA_def_property_ui_range(prop, 0.5, 2.5, 1.0, 5); + RNA_def_property_ui_text(prop, "Ignition", "Minimum temperature of flames"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_resetCache"); + + prop = RNA_def_property(srna, "flame_max_temp", PROP_FLOAT, PROP_NONE); + RNA_def_property_range(prop, 1.0, 10.0); + RNA_def_property_ui_range(prop, 1.0, 5.0, 1.0, 5); + RNA_def_property_ui_text(prop, "Maximum", "Maximum temperature of flames"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_resetCache"); + + prop = RNA_def_property(srna, "flame_smoke_color", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Smoke Color", "Color of smoke emitted from burning fuel"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_resetCache"); + + prop = RNA_def_property(srna, "use_adaptive_domain", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_SMOKE_ADAPTIVE_DOMAIN); + RNA_def_property_ui_text(prop, "Adaptive Domain", "Adapt simulation resolution and size to fluid"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + + prop = RNA_def_property(srna, "additional_res", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "adapt_res"); + RNA_def_property_range(prop, 0, 512); + RNA_def_property_ui_range(prop, 0, 512, 2, 0); + RNA_def_property_ui_text(prop, "Additional", "Maximum number of additional cells"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_resetCache"); + + prop = RNA_def_property(srna, "adapt_margin", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "adapt_margin"); + RNA_def_property_range(prop, 2, 24); + RNA_def_property_ui_range(prop, 2, 24, 2, 0); + RNA_def_property_ui_text(prop, "Margin", "Margin added around fluid to minimize boundary interference"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_resetCache"); + + prop = RNA_def_property(srna, "adapt_threshold", PROP_FLOAT, PROP_NONE); + RNA_def_property_range(prop, 0.01, 0.5); + RNA_def_property_ui_range(prop, 0.01, 0.5, 1.0, 5); + RNA_def_property_ui_text(prop, "Threshold", "Maximum amount of fluid cell can contain before it's considered empty"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_resetCache"); } static void rna_def_smoke_flow_settings(BlenderRNA *brna) @@ -347,6 +432,26 @@ static void rna_def_smoke_flow_settings(BlenderRNA *brna) StructRNA *srna; PropertyRNA *prop; + static EnumPropertyItem smoke_flow_types[] = { + {MOD_SMOKE_FLOW_TYPE_OUTFLOW, "OUTFLOW", 0, "Outflow", "Delete smoke from simulation"}, + {MOD_SMOKE_FLOW_TYPE_SMOKE, "SMOKE", 0, "Smoke", "Add smoke"}, + {MOD_SMOKE_FLOW_TYPE_SMOKEFIRE, "BOTH", 0, "Fire + Smoke", "Add fire and smoke"}, + {MOD_SMOKE_FLOW_TYPE_FIRE, "FIRE", 0, "Fire", "Add fire"}, + {0, NULL, 0, NULL, NULL} + }; + + static EnumPropertyItem smoke_flow_sources[] = { + {MOD_SMOKE_FLOW_SOURCE_PARTICLES, "PARTICLES", ICON_PARTICLES, "Particle System", "Emit smoke from particles"}, + {MOD_SMOKE_FLOW_SOURCE_MESH, "MESH", ICON_META_CUBE, "Mesh", "Emit smoke from mesh surface or volume"}, + {0, NULL, 0, NULL, NULL} + }; + + static EnumPropertyItem smoke_flow_texture_types[] = { + {MOD_SMOKE_FLOW_TEXTURE_MAP_AUTO, "AUTO", 0, "Generated", "Generated coordinates centered to flow object"}, + {MOD_SMOKE_FLOW_TEXTURE_MAP_UV, "UV", 0, "UV", "Use UV layer for texture coordinates"}, + {0, NULL, 0, NULL, NULL} + }; + srna = RNA_def_struct(brna, "SmokeFlowSettings", NULL); RNA_def_struct_ui_text(srna, "Flow Settings", "Smoke flow settings"); RNA_def_struct_sdna(srna, "SmokeFlowSettings"); @@ -354,11 +459,23 @@ static void rna_def_smoke_flow_settings(BlenderRNA *brna) prop = RNA_def_property(srna, "density", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "density"); - RNA_def_property_range(prop, 0.001, 1); - RNA_def_property_ui_range(prop, 0.001, 1.0, 1.0, 4); + RNA_def_property_range(prop, 0.0, 1); + RNA_def_property_ui_range(prop, 0.0, 1.0, 1.0, 4); RNA_def_property_ui_text(prop, "Density", ""); RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + prop = RNA_def_property(srna, "smoke_color", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_float_sdna(prop, NULL, "color"); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Smoke Color", "Color of smoke"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + + prop = RNA_def_property(srna, "fuel_amount", PROP_FLOAT, PROP_NONE); + RNA_def_property_range(prop, 0.0, 10); + RNA_def_property_ui_range(prop, 0.0, 5.0, 1.0, 4); + RNA_def_property_ui_text(prop, "Flame Rate", ""); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + prop = RNA_def_property(srna, "temperature", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "temp"); RNA_def_property_range(prop, -10, 10); @@ -373,9 +490,16 @@ static void rna_def_smoke_flow_settings(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Particle Systems", "Particle systems emitted from the object"); RNA_def_property_update(prop, 0, "rna_Smoke_reset_dependancy"); - prop = RNA_def_property(srna, "use_outflow", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "type", MOD_SMOKE_FLOW_TYPE_OUTFLOW); - RNA_def_property_ui_text(prop, "Outflow", "Delete smoke from simulation"); + prop = RNA_def_property(srna, "smoke_flow_type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "type"); + RNA_def_property_enum_items(prop, smoke_flow_types); + RNA_def_property_ui_text(prop, "Flow Type", "Change how flow affects the simulation"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + + prop = RNA_def_property(srna, "smoke_flow_source", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "source"); + RNA_def_property_enum_items(prop, smoke_flow_sources); + RNA_def_property_ui_text(prop, "Source", "Change how smoke is emitted"); RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); prop = RNA_def_property(srna, "use_absolute", PROP_BOOLEAN, PROP_NONE); @@ -385,14 +509,82 @@ static void rna_def_smoke_flow_settings(BlenderRNA *brna) prop = RNA_def_property(srna, "initial_velocity", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_SMOKE_FLOW_INITVELOCITY); - RNA_def_property_ui_text(prop, "Initial Velocity", "Smoke inherits its velocity from the emitter particle"); + RNA_def_property_ui_text(prop, "Initial Velocity", "Smoke has some initial velocity when it is emitted"); RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); prop = RNA_def_property(srna, "velocity_factor", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "vel_multi"); RNA_def_property_range(prop, -2.0, 2.0); RNA_def_property_ui_range(prop, -2.0, 2.0, 0.05, 5); - RNA_def_property_ui_text(prop, "Multiplier", "Multiplier to adjust velocity passed to smoke"); + RNA_def_property_ui_text(prop, "Source", "Multiplier of source velocity passed to smoke"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + + prop = RNA_def_property(srna, "velocity_normal", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "vel_normal"); + RNA_def_property_range(prop, -2.0, 2.0); + RNA_def_property_ui_range(prop, -2.0, 2.0, 0.05, 5); + RNA_def_property_ui_text(prop, "Normal", "Amount of normal directional velocity"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + + prop = RNA_def_property(srna, "velocity_random", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "vel_random"); + RNA_def_property_range(prop, 0.0, 2.0); + RNA_def_property_ui_range(prop, 0.0, 2.0, 0.05, 5); + RNA_def_property_ui_text(prop, "Random", "Amount of random velocity"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + + prop = RNA_def_property(srna, "volume_density", PROP_FLOAT, PROP_NONE); + RNA_def_property_range(prop, 0.0, 1.0); + RNA_def_property_ui_range(prop, 0.0, 1.0, 0.05, 5); + RNA_def_property_ui_text(prop, "Volume", "Factor for smoke emitted from inside the mesh volume"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + + prop = RNA_def_property(srna, "surface_distance", PROP_FLOAT, PROP_NONE); + RNA_def_property_range(prop, 0.5, 10.0); + RNA_def_property_ui_range(prop, 0.5, 5.0, 0.05, 5); + RNA_def_property_ui_text(prop, "Surface", "Maximum distance from mesh surface to emit smoke"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + + prop = RNA_def_property(srna, "density_vertex_group", PROP_STRING, PROP_NONE); + RNA_def_property_string_funcs(prop, "rna_SmokeFlow_density_vgroup_get", + "rna_SmokeFlow_density_vgroup_length", + "rna_SmokeFlow_density_vgroup_set"); + RNA_def_property_ui_text(prop, "Vertex Group", + "Name of Vertex Group which determines surface emission rate"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + + prop = RNA_def_property(srna, "use_texture", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_SMOKE_FLOW_TEXTUREEMIT); + RNA_def_property_ui_text(prop, "Use Texture", "Use a texture to controll emission strength"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + + prop = RNA_def_property(srna, "texture_map_type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "texture_type"); + RNA_def_property_enum_items(prop, smoke_flow_texture_types); + RNA_def_property_ui_text(prop, "Mapping", "Texture mapping type"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + + prop = RNA_def_property(srna, "uv_layer", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "uvlayer_name"); + RNA_def_property_ui_text(prop, "UV Map", "UV map name"); + RNA_def_property_string_funcs(prop, NULL, NULL, "rna_SmokeFlow_uvlayer_set"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + + prop = RNA_def_property(srna, "noise_texture", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Texture", "Texture that controls emission strength"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + + prop = RNA_def_property(srna, "texture_size", PROP_FLOAT, PROP_NONE); + RNA_def_property_range(prop, 0.01, 10.0); + RNA_def_property_ui_range(prop, 0.1, 5.0, 0.05, 5); + RNA_def_property_ui_text(prop, "Size", "Size of texture mapping"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + + prop = RNA_def_property(srna, "texture_offset", PROP_FLOAT, PROP_NONE); + RNA_def_property_range(prop, 0.0, 200.0); + RNA_def_property_ui_range(prop, 0.0, 100.0, 0.05, 5); + RNA_def_property_ui_text(prop, "Offset", "Z-offset of texture mapping"); RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); } diff --git a/source/blender/makesrna/intern/rna_texture.c b/source/blender/makesrna/intern/rna_texture.c index 202c53cb75d..e77c5d13a6b 100644 --- a/source/blender/makesrna/intern/rna_texture.c +++ b/source/blender/makesrna/intern/rna_texture.c @@ -1800,7 +1800,8 @@ static void rna_def_texture_voxeldata(BlenderRNA *brna) }; static EnumPropertyItem smoked_type_items[] = { - {TEX_VD_SMOKEDENSITY, "SMOKEDENSITY", 0, "Density", "Use smoke density as texture data"}, + {TEX_VD_SMOKEDENSITY, "SMOKEDENSITY", 0, "Smoke", "Use smoke density and color as texture data"}, + {TEX_VD_SMOKEFLAME, "SMOKEFLAME", 0, "Flame", "Use flame temperature as texture data"}, {TEX_VD_SMOKEHEAT, "SMOKEHEAT", 0, "Heat", "Use smoke heat as texture data. Values from -2.0 to 2.0 are used"}, {TEX_VD_SMOKEVEL, "SMOKEVEL", 0, "Velocity", "Use smoke velocity as texture data"}, {0, NULL, 0, NULL, NULL} diff --git a/source/blender/modifiers/intern/MOD_smoke.c b/source/blender/modifiers/intern/MOD_smoke.c index b9b3b89e06d..4b2ce47b8d9 100644 --- a/source/blender/modifiers/intern/MOD_smoke.c +++ b/source/blender/modifiers/intern/MOD_smoke.c @@ -81,19 +81,31 @@ static void freeData(ModifierData *md) smokeModifier_free(smd); } -static void deformVerts(ModifierData *md, Object *ob, - DerivedMesh *derivedData, - float (*vertexCos)[3], - int UNUSED(numVerts), - ModifierApplyFlag UNUSED(flag)) +static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md) +{ + SmokeModifierData *smd = (SmokeModifierData *)md; + CustomDataMask dataMask = 0; + + if (smd && (smd->type & MOD_SMOKE_TYPE_FLOW) && smd->flow) { + if (smd->flow->source == MOD_SMOKE_FLOW_SOURCE_MESH) { + /* vertex groups */ + if (smd->flow->vgroup_density) + dataMask |= CD_MASK_MDEFORMVERT; + /* uv layer */ + if (smd->flow->texture_type == MOD_SMOKE_FLOW_TEXTURE_MAP_UV) + dataMask |= CD_MASK_MTFACE; + } + } + return dataMask; +} + +static DerivedMesh *applyModifier(ModifierData *md, Object *ob, + DerivedMesh *dm, + ModifierApplyFlag UNUSED(flag)) { SmokeModifierData *smd = (SmokeModifierData *) md; - DerivedMesh *dm = get_cddm(ob, NULL, derivedData, vertexCos); - smokeModifier_do(smd, md->scene, ob, dm); - - if (dm != derivedData) - dm->release(dm); + return smokeModifier_do(smd, md->scene, ob, dm); } static int dependsOnTime(ModifierData *UNUSED(md)) @@ -102,11 +114,11 @@ static int dependsOnTime(ModifierData *UNUSED(md)) } static void updateDepgraph(ModifierData *md, DagForest *forest, - struct Scene *scene, - Object *UNUSED(ob), + struct Scene *scene, struct Object *ob, DagNode *obNode) { SmokeModifierData *smd = (SmokeModifierData *) md; + Base *base; if (smd && (smd->type & MOD_SMOKE_TYPE_DOMAIN) && smd->domain) { if (smd->domain->fluid_group || smd->domain->coll_group) { @@ -139,8 +151,7 @@ static void updateDepgraph(ModifierData *md, DagForest *forest, } } else { - Base *base = scene->base.first; - + base = scene->base.first; for (; base; base = base->next) { SmokeModifierData *smd2 = (SmokeModifierData *)modifiers_findByType(base->object, eModifierType_Smoke); @@ -150,6 +161,14 @@ static void updateDepgraph(ModifierData *md, DagForest *forest, } } } + /* add relation to all "smoke flow" force fields */ + base = scene->base.first; + for (; base; base = base->next) { + if (base->object->pd && base->object->pd->forcefield == PFIELD_SMOKEFLOW && base->object->pd->f_source == ob) { + DagNode *node2 = dag_get_node(forest, base->object); + dag_add_relation(forest, obNode, node2, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Field Source Object"); + } + } } } @@ -167,26 +186,30 @@ static void foreachIDLink(ModifierData *md, Object *ob, walk(userData, ob, (ID **)&smd->domain->effector_weights->group); } } + + if (smd->type == MOD_SMOKE_TYPE_FLOW && smd->flow) { + walk(userData, ob, (ID **)&smd->flow->noise_texture); + } } ModifierTypeInfo modifierType_Smoke = { /* name */ "Smoke", /* structName */ "SmokeModifierData", /* structSize */ sizeof(SmokeModifierData), - /* type */ eModifierTypeType_OnlyDeform, + /* type */ eModifierTypeType_Constructive, /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_UsesPointCache | eModifierTypeFlag_Single, /* copyData */ copyData, - /* deformVerts */ deformVerts, + /* deformVerts */ NULL, /* deformMatrices */ NULL, /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, - /* applyModifier */ NULL, + /* applyModifier */ applyModifier, /* applyModifierEM */ NULL, /* initData */ initData, - /* requiredDataMask */ NULL, + /* requiredDataMask */ requiredDataMask, /* freeData */ freeData, /* isDisabled */ NULL, /* updateDepgraph */ updateDepgraph, diff --git a/source/blender/render/intern/source/render_texture.c b/source/blender/render/intern/source/render_texture.c index 3e2ce95af50..9bd2395ca79 100644 --- a/source/blender/render/intern/source/render_texture.c +++ b/source/blender/render/intern/source/render_texture.c @@ -2660,6 +2660,13 @@ void do_volume_tex(ShadeInput *shi, const float *xyz, int mapto_flag, float col_ mul_m4_v3(shi->obi->duplitexmat, co); } mul_m4_v3(ob->imat_ren, co); + + if (mtex->texflag & MTEX_MAPTO_BOUNDS && ob->bb) { + /* use bb vec[0] as min and bb vec[6] as max */ + co[0] = (co[0] - ob->bb->vec[0][0]) / (ob->bb->vec[6][0]-ob->bb->vec[0][0]) * 2.0f - 1.0f; + co[1] = (co[1] - ob->bb->vec[0][1]) / (ob->bb->vec[6][1]-ob->bb->vec[0][1]) * 2.0f - 1.0f; + co[2] = (co[2] - ob->bb->vec[0][2]) / (ob->bb->vec[6][2]-ob->bb->vec[0][2]) * 2.0f - 1.0f; + } } } /* not really orco, but 'local' */ @@ -2672,6 +2679,13 @@ void do_volume_tex(ShadeInput *shi, const float *xyz, int mapto_flag, float col_ Object *ob= shi->obi->ob; copy_v3_v3(co, xyz); mul_m4_v3(ob->imat_ren, co); + + if (mtex->texflag & MTEX_MAPTO_BOUNDS && ob->bb) { + /* use bb vec[0] as min and bb vec[6] as max */ + co[0] = (co[0] - ob->bb->vec[0][0]) / (ob->bb->vec[6][0]-ob->bb->vec[0][0]) * 2.0f - 1.0f; + co[1] = (co[1] - ob->bb->vec[0][1]) / (ob->bb->vec[6][1]-ob->bb->vec[0][1]) * 2.0f - 1.0f; + co[2] = (co[2] - ob->bb->vec[0][2]) / (ob->bb->vec[6][2]-ob->bb->vec[0][2]) * 2.0f - 1.0f; + } } } else if (mtex->texco==TEXCO_GLOB) { @@ -2738,6 +2752,12 @@ void do_volume_tex(ShadeInput *shi, const float *xyz, int mapto_flag, float col_ if ((rgbnor & TEX_RGB) == 0) { copy_v3_v3(tcol, &mtex->r); } + else if (mtex->mapto & MAP_DENSITY) { + copy_v3_v3(tcol, &texres.tr); + if (texres.talpha) { + texres.tin = stencilTin; + } + } else { copy_v3_v3(tcol, &texres.tr); if (texres.talpha) { diff --git a/source/blender/render/intern/source/voxeldata.c b/source/blender/render/intern/source/voxeldata.c index d73171648fb..7eccacb816d 100644 --- a/source/blender/render/intern/source/voxeldata.c +++ b/source/blender/render/intern/source/voxeldata.c @@ -227,69 +227,102 @@ static void init_frame_smoke(VoxelData *vd, float cfra) /* draw code for smoke */ if ((md = (ModifierData *)modifiers_findByType(ob, eModifierType_Smoke))) { SmokeModifierData *smd = (SmokeModifierData *)md; - + SmokeDomainSettings *sds = smd->domain; - if (smd->domain && smd->domain->fluid) { - if (cfra < smd->domain->point_cache[0]->startframe) + if (sds && sds->fluid) { + if (cfra < sds->point_cache[0]->startframe) ; /* don't show smoke before simulation starts, this could be made an option in the future */ else if (vd->smoked_type == TEX_VD_SMOKEHEAT) { size_t totRes; size_t i; float *heat; - copy_v3_v3_int(vd->resol, smd->domain->res); + if (!smoke_has_heat(sds->fluid)) return; + + copy_v3_v3_int(vd->resol, sds->res); totRes = vd_resol_size(vd); - - /* scaling heat values from -2.0-2.0 to 0.0-1.0 */ vd->dataset = MEM_mapallocN(sizeof(float) * (totRes), "smoke data"); + /* get heat data */ + heat = smoke_get_heat(sds->fluid); - - heat = smoke_get_heat(smd->domain->fluid); - + /* scale heat values from -2.0-2.0 to 0.0-1.0 */ for (i = 0; i < totRes; i++) { vd->dataset[i] = (heat[i] + 2.0f) / 4.0f; } - - /* vd->dataset = smoke_get_heat(smd->domain->fluid); */ } else if (vd->smoked_type == TEX_VD_SMOKEVEL) { size_t totRes; size_t i; float *xvel, *yvel, *zvel; - copy_v3_v3_int(vd->resol, smd->domain->res); + copy_v3_v3_int(vd->resol, sds->res); totRes = vd_resol_size(vd); - - /* scaling heat values from -2.0-2.0 to 0.0-1.0 */ vd->dataset = MEM_mapallocN(sizeof(float) * (totRes), "smoke data"); + /* get velocity data */ + xvel = smoke_get_velocity_x(sds->fluid); + yvel = smoke_get_velocity_y(sds->fluid); + zvel = smoke_get_velocity_z(sds->fluid); - xvel = smoke_get_velocity_x(smd->domain->fluid); - yvel = smoke_get_velocity_y(smd->domain->fluid); - zvel = smoke_get_velocity_z(smd->domain->fluid); - + /* map velocities between 0 and 0.3f */ for (i = 0; i < totRes; i++) { vd->dataset[i] = sqrt(xvel[i] * xvel[i] + yvel[i] * yvel[i] + zvel[i] * zvel[i]) * 3.0f; } } - else { + else if (vd->smoked_type == TEX_VD_SMOKEFLAME) { size_t totRes; - float *density; + float *flame; - if (smd->domain->flags & MOD_SMOKE_HIGHRES) { - smoke_turbulence_get_res(smd->domain->wt, vd->resol); - density = smoke_turbulence_get_density(smd->domain->wt); + if (sds->flags & MOD_SMOKE_HIGHRES) { + if (!smoke_turbulence_has_fuel(sds->wt)) return; + smoke_turbulence_get_res(sds->wt, vd->resol); + flame = smoke_turbulence_get_flame(sds->wt); } else { - copy_v3_v3_int(vd->resol, smd->domain->res); - density = smoke_get_density(smd->domain->fluid); + if (!smoke_has_fuel(sds->fluid)) return; + copy_v3_v3_int(vd->resol, sds->res); + flame = smoke_get_flame(sds->fluid); + } + + /* always store copy, as smoke internal data can change */ + totRes= vd_resol_size(vd); + vd->dataset = MEM_mapallocN(sizeof(float)*(totRes), "smoke data"); + memcpy(vd->dataset, flame, sizeof(float)*totRes); + } + else { + size_t totCells; + int depth = 4; + vd->data_type = TEX_VD_RGBA_PREMUL; + + /* data resolution */ + if (sds->flags & MOD_SMOKE_HIGHRES) { + smoke_turbulence_get_res(sds->wt, vd->resol); + } + else { + copy_v3_v3_int(vd->resol, sds->res); } /* TODO: is_vd_res_ok(rvd) doesnt check this resolution */ - totRes = vd_resol_size(vd); + totCells = vd_resol_size(vd) * depth; /* always store copy, as smoke internal data can change */ - vd->dataset = MEM_mapallocN(sizeof(float) * (totRes), "smoke data"); - memcpy(vd->dataset, density, sizeof(float) * totRes); + vd->dataset = MEM_mapallocN(sizeof(float) * totCells, "smoke data"); + + if (sds->flags & MOD_SMOKE_HIGHRES) { + if (smoke_turbulence_has_colors(sds->wt)) { + smoke_turbulence_get_rgba(sds->wt, vd->dataset, 1); + } + else { + smoke_turbulence_get_rgba_from_density(sds->wt, sds->active_color, vd->dataset, 1); + } + } + else { + if (smoke_has_colors(sds->fluid)) { + smoke_get_rgba(sds->fluid, vd->dataset, 1); + } + else { + smoke_get_rgba_from_density(sds->fluid, sds->active_color, vd->dataset, 1); + } + } } /* end of fluid condition */ } } @@ -320,6 +353,8 @@ void cache_voxeldata(Tex *tex, int scene_frame) MEM_freeN(vd->dataset); vd->dataset = NULL; } + /* reset data_type */ + vd->data_type = TEX_VD_INTENSITY; if (vd->flag & TEX_VD_STILL) curframe = vd->still_frame; @@ -379,9 +414,11 @@ void make_voxeldata(struct Render *re) int voxeldatatex(struct Tex *tex, const float texvec[3], struct TexResult *texres) { - int retval = TEX_INT; VoxelData *vd = tex->vd; - float co[3], offset[3] = {0.5, 0.5, 0.5}; + float co[3], offset[3] = {0.5, 0.5, 0.5}, a; + int retval = (vd->data_type == TEX_VD_RGBA_PREMUL) ? TEX_RGB : TEX_INT; + int depth = (vd->data_type == TEX_VD_RGBA_PREMUL) ? 4 : 1; + int ch; if (vd->dataset == NULL) { texres->tin = 0.0f; @@ -420,29 +457,61 @@ int voxeldatatex(struct Tex *tex, const float texvec[3], struct TexResult *texre break; } } - - switch (vd->interp_type) { - case TEX_VD_NEARESTNEIGHBOR: - texres->tin = BLI_voxel_sample_nearest(vd->dataset, vd->resol, co); - break; - case TEX_VD_LINEAR: - texres->tin = BLI_voxel_sample_trilinear(vd->dataset, vd->resol, co); - break; - case TEX_VD_QUADRATIC: - texres->tin = BLI_voxel_sample_triquadratic(vd->dataset, vd->resol, co); - break; - case TEX_VD_TRICUBIC_CATROM: - case TEX_VD_TRICUBIC_BSPLINE: - texres->tin = BLI_voxel_sample_tricubic(vd->dataset, vd->resol, co, (vd->interp_type == TEX_VD_TRICUBIC_BSPLINE)); - break; + + for (ch = 0; ch < depth; ch++) { + float *dataset = vd->dataset + ch*vd->resol[0]*vd->resol[1]*vd->resol[2]; + float *result = &texres->tin; + + if (vd->data_type == TEX_VD_RGBA_PREMUL) { + switch (ch) { + case 0: + result = &texres->tr; + break; + case 1: + result = &texres->tg; + break; + case 2: + result = &texres->tb; + break; + } + } + + switch (vd->interp_type) { + case TEX_VD_NEARESTNEIGHBOR: + *result = BLI_voxel_sample_nearest(dataset, vd->resol, co); + break; + case TEX_VD_LINEAR: + *result = BLI_voxel_sample_trilinear(dataset, vd->resol, co); + break; + case TEX_VD_QUADRATIC: + *result = BLI_voxel_sample_triquadratic(dataset, vd->resol, co); + break; + case TEX_VD_TRICUBIC_CATROM: + case TEX_VD_TRICUBIC_BSPLINE: + *result = BLI_voxel_sample_tricubic(dataset, vd->resol, co, (vd->interp_type == TEX_VD_TRICUBIC_BSPLINE)); + break; + } } - + + a = texres->tin; texres->tin *= vd->int_multiplier; BRICONT; - texres->tr = texres->tin; - texres->tg = texres->tin; - texres->tb = texres->tin; + if (vd->data_type == TEX_VD_RGBA_PREMUL) { + /* unmultiply */ + if (a>0.001f) { + texres->tr /= a; + texres->tg /= a; + texres->tb /= a; + } + texres->talpha = 1; + } + else { + texres->tr = texres->tin; + texres->tg = texres->tin; + texres->tb = texres->tin; + } + texres->ta = texres->tin; BRICONTRGB; From 725cfab2dc8a505d16680c114b6b7c0e6d7326a5 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 10 Oct 2012 13:36:53 +0000 Subject: [PATCH 173/347] workaround for feedback loop when viewing-selected/all with a locked camera. the camera could try include its own boundbox in its view. now just skip the camera if 'All Regions' and lock view option is enabled. --- source/blender/editors/space_view3d/view3d_edit.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 329286953d6..39f644489d2 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -2260,12 +2260,13 @@ static int view3d_all_exec(bContext *C, wmOperator *op) /* was view3d_home() in { ARegion *ar = CTX_wm_region(C); View3D *v3d = CTX_wm_view3d(C); - RegionView3D *rv3d = CTX_wm_region_view3d(C); Scene *scene = CTX_data_scene(C); Base *base; float *curs; - const short skip_camera = ED_view3d_camera_lock_check(v3d, rv3d); const short use_all_regions = RNA_boolean_get(op->ptr, "use_all_regions"); + const short skip_camera = (ED_view3d_camera_lock_check(v3d, ar->regiondata) || + /* any one of the regions may be locked */ + (use_all_regions && v3d->flag2 & V3D_LOCK_CAMERA)); int center = RNA_boolean_get(op->ptr, "center"); float min[3], max[3]; @@ -2351,8 +2352,10 @@ static int viewselected_exec(bContext *C, wmOperator *op) Object *obedit = CTX_data_edit_object(C); float min[3], max[3]; int ok = 0, ok_dist = 1; - const short skip_camera = ED_view3d_camera_lock_check(v3d, ar->regiondata); const short use_all_regions = RNA_boolean_get(op->ptr, "use_all_regions"); + const short skip_camera = (ED_view3d_camera_lock_check(v3d, ar->regiondata) || + /* any one of the regions may be locked */ + (use_all_regions && v3d->flag2 & V3D_LOCK_CAMERA)); INIT_MINMAX(min, max); From 56f798db8c0643062fb2f6902a02978a71ac477c Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 10 Oct 2012 14:21:58 +0000 Subject: [PATCH 174/347] Cycles: make anistropic BSDF / tangent work without UV map, based on generated coordinates map to a sphere. --- intern/cycles/blender/blender_mesh.cpp | 125 +++++++++++++++++++------ 1 file changed, 96 insertions(+), 29 deletions(-) diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp index 8f737be9765..bbc9b00b0dc 100644 --- a/intern/cycles/blender/blender_mesh.cpp +++ b/intern/cycles/blender/blender_mesh.cpp @@ -33,7 +33,23 @@ CCL_NAMESPACE_BEGIN /* Find/Add */ -static float3 tri_calc_tangent(float3 v0, float3 v1, float3 v2, float3 tx0, float3 tx1, float3 tx2) +static float3 tangent_uv_from_generated(float3 P) +{ + float length = len(P); + + if(length == 0.0f) + return make_float3(0.0f, 0.0f, 0.0f); + + float u = 0.0f; + if(!(P.x == 0.0f && P.y == 0.0f)) + u = (1.0f - atan2f(P.x, P.y))/(2.0f*M_PI_F); + + float v = 1.0f - acosf(clamp(P.z/length, -1.0f, 1.0f))/M_PI_F; + + return make_float3(u, v, 0.0f); +} + +static float3 tangent_from_triangle(float3 v0, float3 v1, float3 v2, float3 tx0, float3 tx1, float3 tx2) { float3 duv1 = tx2 - tx0; float3 duv2 = tx2 - tx1; @@ -89,27 +105,6 @@ static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector< nverts.push_back(n); } - /* create generated coordinates. todo: we should actually get the orco - * coordinates from modifiers, for now we use texspace loc/size which - * is available in the api. */ - if(mesh->need_attribute(scene, ATTR_STD_GENERATED)) { - Attribute *attr = mesh->attributes.add(ATTR_STD_GENERATED); - float3 loc = get_float3(b_mesh.texspace_location()); - float3 size = get_float3(b_mesh.texspace_size()); - - if(size.x != 0.0f) size.x = 0.5f/size.x; - if(size.y != 0.0f) size.y = 0.5f/size.y; - if(size.z != 0.0f) size.z = 0.5f/size.z; - - loc = loc*size - make_float3(0.5f, 0.5f, 0.5f); - - float3 *fdata = attr->data_float3(); - size_t i = 0; - - for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v) - fdata[i++] = get_float3(v->co())*size - loc; - } - /* create vertex color attributes */ { BL::Mesh::tessface_vertex_colors_iterator l; @@ -181,16 +176,16 @@ static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector< } /* create texcoord-based tangent attributes */ - { + bool need_tangent = mesh->need_attribute(scene, ATTR_STD_TANGENT); + + if(need_tangent) { BL::Mesh::tessface_uv_textures_iterator l; for(b_mesh.tessface_uv_textures.begin(l); l != b_mesh.tessface_uv_textures.end(); ++l) { - AttributeStandard std = (l->active_render())? ATTR_STD_TANGENT: ATTR_STD_NONE; - - if(!mesh->need_attribute(scene, std)) + if(!l->active_render()) continue; - Attribute *attr = mesh->attributes.add(std, ustring("Tangent")); + Attribute *attr = mesh->attributes.add(ATTR_STD_TANGENT, ustring("Tangent")); /* compute average tangents per vertex */ float3 *tangents = attr->data_float3(); @@ -214,13 +209,85 @@ static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector< /* calculate tangent for the triangle; * get vertex positions, and find change in position with respect * to the texture coords in the first texture coord dimension */ - float3 tangent0 = tri_calc_tangent(v0, v1, v2, tx0, tx1, tx2); + float3 tangent0 = tangent_from_triangle(v0, v1, v2, tx0, tx1, tx2); if(nverts[fi] == 4) { /* quad tangent */ float3 tx3 = get_float3(t->uv4()); float3 v3 = mesh->verts[vi[3]]; - float3 tangent1 = tri_calc_tangent(v0, v2, v3, tx0, tx2, tx3); + float3 tangent1 = tangent_from_triangle(v0, v2, v3, tx0, tx2, tx3); + + tangents[vi[0]] += 0.5f*(tangent0 + tangent1); + tangents[vi[1]] += tangent0; + tangents[vi[2]] += 0.5f*(tangent0 + tangent1); + tangents[vi[3]] += tangent1; + } + else { + /* triangle tangent */ + tangents[vi[0]] += tangent0; + tangents[vi[1]] += tangent0; + tangents[vi[2]] += tangent0; + } + } + + /* normalize tangent vectors */ + for(int i = 0; i < mesh->verts.size(); i++) + tangents[i] = normalize(tangents[i]); + + need_tangent = false; + } + } + + /* create generated coordinates. todo: we should actually get the orco + * coordinates from modifiers, for now we use texspace loc/size which + * is available in the api. */ + if(mesh->need_attribute(scene, ATTR_STD_GENERATED) || need_tangent) { + Attribute *attr = mesh->attributes.add(ATTR_STD_GENERATED); + float3 loc = get_float3(b_mesh.texspace_location()); + float3 size = get_float3(b_mesh.texspace_size()); + + if(size.x != 0.0f) size.x = 0.5f/size.x; + if(size.y != 0.0f) size.y = 0.5f/size.y; + if(size.z != 0.0f) size.z = 0.5f/size.z; + + loc = loc*size - make_float3(0.5f, 0.5f, 0.5f); + + float3 *generated = attr->data_float3(); + size_t i = 0; + + for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v) + generated[i++] = get_float3(v->co())*size - loc; + + /* if there is no UV map, we generated tangents from generated coordinates */ + if(need_tangent) { + Attribute *attr = mesh->attributes.add(ATTR_STD_TANGENT, ustring("Tangent")); + + /* compute average tangents per vertex */ + float3 *tangents = attr->data_float3(); + memset(tangents, 0, sizeof(float3)*mesh->verts.size()); + + size_t fi = 0; /* face index */ + for(b_mesh.tessfaces.begin(f); f != b_mesh.tessfaces.end(); ++fi, ++f) { + int4 vi = get_int4(f->vertices_raw()); + + float3 tx0 = tangent_uv_from_generated(generated[vi[0]]); + float3 tx1 = tangent_uv_from_generated(generated[vi[1]]); + float3 tx2 = tangent_uv_from_generated(generated[vi[2]]); + + float3 v0 = mesh->verts[vi[0]]; + float3 v1 = mesh->verts[vi[1]]; + float3 v2 = mesh->verts[vi[2]]; + + /* calculate tangent for the triangle; + * get vertex positions, and find change in position with respect + * to the texture coords in the first texture coord dimension */ + float3 tangent0 = tangent_from_triangle(v0, v1, v2, tx0, tx1, tx2); + + if(nverts[fi] == 4) { + /* quad tangent */ + float3 tx3 = tangent_uv_from_generated(generated[vi[3]]); + float3 v3 = mesh->verts[vi[3]]; + float3 tangent1 = tangent_from_triangle(v0, v2, v3, tx0, tx2, tx3); tangents[vi[0]] += 0.5f*(tangent0 + tangent1); tangents[vi[1]] += tangent0; From e9a61cd29db61513dedeb4d656e7dadff7439b1a Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 10 Oct 2012 14:28:47 +0000 Subject: [PATCH 175/347] quiet compiler warnings from recent merge. --- source/blender/blenkernel/intern/smoke.c | 17 ++- .../blender/editors/space_view3d/drawobject.c | 16 +-- .../blender/editors/space_view3d/drawvolume.c | 126 +++++++++--------- .../editors/space_view3d/view3d_intern.h | 7 +- 4 files changed, 90 insertions(+), 76 deletions(-) diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c index a07c58746df..a20d88c03c7 100644 --- a/source/blender/blenkernel/intern/smoke.c +++ b/source/blender/blenkernel/intern/smoke.c @@ -684,7 +684,6 @@ static void obstacles_from_derivedmesh(Object *coll_ob, SmokeDomainSettings *sds MFace *mface = NULL; BVHTreeFromMesh treeData = {0}; int numverts, i, z; - int *res = sds->res; float surface_distance = 0.6; @@ -799,7 +798,8 @@ static void obstacles_from_derivedmesh(Object *coll_ob, SmokeDomainSettings *sds } /* Animated obstacles: dx_step = ((x_new - x_old) / totalsteps) * substep */ -static void update_obstacles(Scene *scene, Object *ob, SmokeDomainSettings *sds, float dt, int substep, int totalsteps) +static void update_obstacles(Scene *scene, Object *ob, SmokeDomainSettings *sds, float dt, + int UNUSED(substep), int UNUSED(totalsteps)) { Object **collobjs = NULL; unsigned int numcollobj = 0; @@ -1540,7 +1540,7 @@ BLI_INLINE void apply_inflow_fields(SmokeFlowSettings *sfs, float emission_value { int absolute_flow = (sfs->flags & MOD_SMOKE_FLOW_ABSOLUTE); float dens_old = density[index]; - float fuel_old = (fuel) ? fuel[index] : 0.0f; + // float fuel_old = (fuel) ? fuel[index] : 0.0f; /* UNUSED */ float dens_flow = (sfs->type == MOD_SMOKE_FLOW_TYPE_FIRE) ? 0.0f : emission_value * sfs->density; float fuel_flow = emission_value * sfs->fuel_amount; /* add heat */ @@ -1972,12 +1972,14 @@ static void step(Scene *scene, Object *ob, SmokeModifierData *smd, DerivedMesh * float gravity[3] = {0.0f, 0.0f, -1.0f}; float gravity_mag; +#if 0 /* UNUSED */ /* get max velocity and lower the dt value if it is too high */ size_t size = sds->res[0] * sds->res[1] * sds->res[2]; float *velX = smoke_get_velocity_x(sds->fluid); float *velY = smoke_get_velocity_y(sds->fluid); float *velZ = smoke_get_velocity_z(sds->fluid); size_t i; +#endif /* update object state */ invert_m4_m4(sds->imat, ob->obmat); @@ -2001,12 +2003,13 @@ static void step(Scene *scene, Object *ob, SmokeModifierData *smd, DerivedMesh * // maximum timestep/"CFL" constraint: dt < 5.0 *dx / maxVel maxVel = (sds->dx * 5.0); - /*for(i = 0; i < size; i++) - { +#if 0 + for (i = 0; i < size; i++) { float vtemp = (velX[i]*velX[i]+velY[i]*velY[i]+velZ[i]*velZ[i]); if(vtemp > maxVelMag) maxVelMag = vtemp; - }*/ + } +#endif maxVelMag = sqrt(maxVelMag) * dt * sds->time_scale; totalSubsteps = (int)((maxVelMag / maxVel) + 1.0f); /* always round up */ @@ -2119,7 +2122,7 @@ static DerivedMesh *createDomainGeometry(SmokeDomainSettings *sds, Object *ob) return result; } -void smokeModifier_process(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedMesh *dm) +static void smokeModifier_process(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedMesh *dm) { if((smd->type & MOD_SMOKE_TYPE_FLOW)) { diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index dd3c7408511..7bb22891b07 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -6670,19 +6670,19 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short if (!sds->wt || !(sds->viewsettings & MOD_SMOKE_VIEW_SHOWBIG)) { smd->domain->tex = NULL; GPU_create_smoke(smd, 0); - draw_smoke_volume(sds, ob, ar, sds->tex, - p0, p1, - sds->res, sds->dx, sds->scale*sds->maxres, - viewnormal, sds->tex_shadow, sds->tex_flame); + draw_smoke_volume(sds, ob, sds->tex, + p0, p1, + sds->res, sds->dx, sds->scale * sds->maxres, + viewnormal, sds->tex_shadow, sds->tex_flame); GPU_free_smoke(smd); } else if (sds->wt && (sds->viewsettings & MOD_SMOKE_VIEW_SHOWBIG)) { sds->tex = NULL; GPU_create_smoke(smd, 1); - draw_smoke_volume(sds, ob, ar, sds->tex, - p0, p1, - sds->res_wt, sds->dx, sds->scale*sds->maxres, - viewnormal, sds->tex_shadow, sds->tex_flame); + draw_smoke_volume(sds, ob, sds->tex, + p0, p1, + sds->res_wt, sds->dx, sds->scale * sds->maxres, + viewnormal, sds->tex_shadow, sds->tex_flame); GPU_free_smoke(smd); } diff --git a/source/blender/editors/space_view3d/drawvolume.c b/source/blender/editors/space_view3d/drawvolume.c index 7215e8ec6b4..8cc55363a5e 100644 --- a/source/blender/editors/space_view3d/drawvolume.c +++ b/source/blender/editors/space_view3d/drawvolume.c @@ -157,7 +157,10 @@ static int convex(const float p0[3], const float up[3], const float a[3], const return dot_v3v3(up, tmp) >= 0; } -void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob, ARegion *ar, GPUTexture *tex, float min[3], float max[3], int res[3], float dx, float base_scale, float viewnormal[3], GPUTexture *tex_shadow, GPUTexture *tex_flame) +void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob, + GPUTexture *tex, float min[3], float max[3], + int res[3], float dx, float UNUSED(base_scale), float viewnormal[3], + GPUTexture *tex_shadow, GPUTexture *tex_flame) { int i, j, k, n, good_index; float d /*, d0 */ /* UNUSED */, dd, ds; @@ -197,67 +200,70 @@ void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob, ARegion *ar, GPUTex /* Fragment program to calculate the view3d of smoke */ /* using 4 textures, density, shadow, flame and flame spectrum */ - const char *shader_basic = "!!ARBfp1.0\n" - "PARAM dx = program.local[0];\n" - "PARAM darkness = program.local[1];\n" - "PARAM render = program.local[2];\n" - "PARAM f = {1.442695041, 1.442695041, 1.442695041, 0.01};\n" - "TEMP temp, shadow, flame, spec, value;\n" - "TEX temp, fragment.texcoord[0], texture[0], 3D;\n" - "TEX shadow, fragment.texcoord[0], texture[1], 3D;\n" - "TEX flame, fragment.texcoord[0], texture[2], 3D;\n" - "TEX spec, flame.r, texture[3], 1D;\n" - /* calculate shading factor from density */ - "MUL value.r, temp.a, darkness.a;\n" - "MUL value.r, value.r, dx.r;\n" - "MUL value.r, value.r, f.r;\n" - "EX2 temp, -value.r;\n" - /* alpha */ - "SUB temp.a, 1.0, temp.r;\n" - /* shade colors */ - "MUL temp.r, temp.r, shadow.r;\n" - "MUL temp.g, temp.g, shadow.r;\n" - "MUL temp.b, temp.b, shadow.r;\n" - "MUL temp.r, temp.r, darkness.r;\n" - "MUL temp.g, temp.g, darkness.g;\n" - "MUL temp.b, temp.b, darkness.b;\n" - /* for now this just replace smoke shading if rendering fire */ - "CMP result.color, render.r, temp, spec;\n" - "END\n"; + const char *shader_basic = + "!!ARBfp1.0\n" + "PARAM dx = program.local[0];\n" + "PARAM darkness = program.local[1];\n" + "PARAM render = program.local[2];\n" + "PARAM f = {1.442695041, 1.442695041, 1.442695041, 0.01};\n" + "TEMP temp, shadow, flame, spec, value;\n" + "TEX temp, fragment.texcoord[0], texture[0], 3D;\n" + "TEX shadow, fragment.texcoord[0], texture[1], 3D;\n" + "TEX flame, fragment.texcoord[0], texture[2], 3D;\n" + "TEX spec, flame.r, texture[3], 1D;\n" + /* calculate shading factor from density */ + "MUL value.r, temp.a, darkness.a;\n" + "MUL value.r, value.r, dx.r;\n" + "MUL value.r, value.r, f.r;\n" + "EX2 temp, -value.r;\n" + /* alpha */ + "SUB temp.a, 1.0, temp.r;\n" + /* shade colors */ + "MUL temp.r, temp.r, shadow.r;\n" + "MUL temp.g, temp.g, shadow.r;\n" + "MUL temp.b, temp.b, shadow.r;\n" + "MUL temp.r, temp.r, darkness.r;\n" + "MUL temp.g, temp.g, darkness.g;\n" + "MUL temp.b, temp.b, darkness.b;\n" + /* for now this just replace smoke shading if rendering fire */ + "CMP result.color, render.r, temp, spec;\n" + "END\n"; /* color shader */ - const char *shader_color = "!!ARBfp1.0\n" - "PARAM dx = program.local[0];\n" - "PARAM darkness = program.local[1];\n" - "PARAM render = program.local[2];\n" - "PARAM f = {1.442695041, 1.442695041, 1.442695041, 1.442695041};\n" - "TEMP temp, shadow, flame, spec, value;\n" - "TEX temp, fragment.texcoord[0], texture[0], 3D;\n" - "TEX shadow, fragment.texcoord[0], texture[1], 3D;\n" - "TEX flame, fragment.texcoord[0], texture[2], 3D;\n" - "TEX spec, flame.r, texture[3], 1D;\n" - /* unpremultiply volume texture */ - "RCP value.r, temp.a;\n" - "MUL temp.r, temp.r, value.r;\n" - "MUL temp.g, temp.g, value.r;\n" - "MUL temp.b, temp.b, value.r;\n" - /* calculate shading factor from density */ - "MUL value.r, temp.a, darkness.a;\n" - "MUL value.r, value.r, dx.r;\n" - "MUL value.r, value.r, f.r;\n" - "EX2 value.r, -value.r;\n" - /* alpha */ - "SUB temp.a, 1.0, value.r;\n" - /* shade colors */ - "MUL temp.r, temp.r, shadow.r;\n" - "MUL temp.g, temp.g, shadow.r;\n" - "MUL temp.b, temp.b, shadow.r;\n" - "MUL temp.r, temp.r, value.r;\n" - "MUL temp.g, temp.g, value.r;\n" - "MUL temp.b, temp.b, value.r;\n" - /* for now this just replace smoke shading if rendering fire */ - "CMP result.color, render.r, temp, spec;\n" - "END\n"; + const char *shader_color = + "!!ARBfp1.0\n" + "PARAM dx = program.local[0];\n" + "PARAM darkness = program.local[1];\n" + "PARAM render = program.local[2];\n" + "PARAM f = {1.442695041, 1.442695041, 1.442695041, 1.442695041};\n" + "TEMP temp, shadow, flame, spec, value;\n" + "TEX temp, fragment.texcoord[0], texture[0], 3D;\n" + "TEX shadow, fragment.texcoord[0], texture[1], 3D;\n" + "TEX flame, fragment.texcoord[0], texture[2], 3D;\n" + "TEX spec, flame.r, texture[3], 1D;\n" + /* unpremultiply volume texture */ + "RCP value.r, temp.a;\n" + "MUL temp.r, temp.r, value.r;\n" + "MUL temp.g, temp.g, value.r;\n" + "MUL temp.b, temp.b, value.r;\n" + /* calculate shading factor from density */ + "MUL value.r, temp.a, darkness.a;\n" + "MUL value.r, value.r, dx.r;\n" + "MUL value.r, value.r, f.r;\n" + "EX2 value.r, -value.r;\n" + /* alpha */ + "SUB temp.a, 1.0, value.r;\n" + /* shade colors */ + "MUL temp.r, temp.r, shadow.r;\n" + "MUL temp.g, temp.g, shadow.r;\n" + "MUL temp.b, temp.b, shadow.r;\n" + "MUL temp.r, temp.r, value.r;\n" + "MUL temp.g, temp.g, value.r;\n" + "MUL temp.b, temp.b, value.r;\n" + /* for now this just replace smoke shading if rendering fire */ + "CMP result.color, render.r, temp, spec;\n" + "END\n"; + GLuint prog; diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h index 8d7a6421a34..e364014c42f 100644 --- a/source/blender/editors/space_view3d/view3d_intern.h +++ b/source/blender/editors/space_view3d/view3d_intern.h @@ -40,6 +40,7 @@ struct ARegionType; struct BoundBox; struct DerivedMesh; struct Object; +struct SmokeDomainSettings; struct ViewContext; struct bAnimVizSettings; struct bContext; @@ -212,7 +213,11 @@ ARegion *view3d_has_tools_region(ScrArea *sa); extern const char *view3d_context_dir[]; /* doc access */ /* draw_volume.c */ -void draw_smoke_volume(struct SmokeDomainSettings *sds, struct Object *ob, struct ARegion *ar, struct GPUTexture *tex, float min[3], float max[3], int res[3], float dx, float base_scale, float viewnormal[3], struct GPUTexture *tex_shadow, struct GPUTexture *tex_flame); +void draw_smoke_volume(struct SmokeDomainSettings *sds, struct Object *ob, + struct GPUTexture *tex, float min[3], float max[3], + int res[3], float dx, float base_scale, float viewnormal[3], + struct GPUTexture *tex_shadow, struct GPUTexture *tex_flame); + //#define SMOKE_DEBUG_VELOCITY //#define SMOKE_DEBUG_HEAT From fe09b24e86e340e733f91c8ed9fcc7b8519157f4 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 10 Oct 2012 15:56:43 +0000 Subject: [PATCH 176/347] Cycles: per-BSDF normal input and new Bump node. Each BSDF node now has a Normal input, which can be used to set a custom normal for the BSDF, for example if you want to have only bump on one of the layers in a multilayer material. The Bump node can be used to generate a normal from a scalar value, the same as what happens when you connect a scalar value to the displacement output. Documentation has been updated with the latest changes: http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/Nodes Patch by Agustin Benavidez, some implementation tweaks by me. --- intern/cycles/blender/blender_shader.cpp | 4 + intern/cycles/kernel/kernel_types.h | 1 + .../cycles/kernel/svm/bsdf_ashikhmin_velvet.h | 4 +- intern/cycles/kernel/svm/bsdf_diffuse.h | 8 +- intern/cycles/kernel/svm/bsdf_microfacet.h | 12 +-- intern/cycles/kernel/svm/bsdf_oren_nayar.h | 12 +-- intern/cycles/kernel/svm/bsdf_reflection.h | 2 +- intern/cycles/kernel/svm/bsdf_refraction.h | 2 +- intern/cycles/kernel/svm/bsdf_ward.h | 4 +- intern/cycles/kernel/svm/bsdf_westin.h | 8 +- intern/cycles/kernel/svm/svm.h | 9 ++- intern/cycles/kernel/svm/svm_closure.h | 34 +++++++- intern/cycles/kernel/svm/svm_displace.h | 26 +++++-- intern/cycles/kernel/svm/svm_types.h | 1 + intern/cycles/render/graph.cpp | 78 ++++++++++++++++++- intern/cycles/render/graph.h | 1 + intern/cycles/render/nodes.cpp | 58 +++++++++++++- intern/cycles/render/nodes.h | 5 ++ source/blender/blenkernel/BKE_node.h | 1 + source/blender/blenkernel/intern/node.c | 1 + .../makesrna/intern/rna_nodetree_types.h | 3 +- source/blender/nodes/CMakeLists.txt | 1 + source/blender/nodes/NOD_shader.h | 1 + .../nodes/node_shader_bsdf_anisotropic.c | 1 + .../shader/nodes/node_shader_bsdf_diffuse.c | 1 + .../shader/nodes/node_shader_bsdf_glass.c | 1 + .../shader/nodes/node_shader_bsdf_glossy.c | 1 + .../nodes/node_shader_bsdf_translucent.c | 1 + .../shader/nodes/node_shader_bsdf_velvet.c | 1 + .../nodes/shader/nodes/node_shader_bump.c | 63 +++++++++++++++ 30 files changed, 299 insertions(+), 46 deletions(-) create mode 100644 source/blender/nodes/shader/nodes/node_shader_bump.c diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp index 56548613647..98ac8692f36 100644 --- a/intern/cycles/blender/blender_shader.cpp +++ b/intern/cycles/blender/blender_shader.cpp @@ -402,6 +402,10 @@ static ShaderNode *add_node(BL::BlendData b_data, BL::Scene b_scene, ShaderGraph node = new ParticleInfoNode(); break; } + case BL::ShaderNode::type_BUMP: { + node = new BumpNode(); + break; + } case BL::ShaderNode::type_TEX_IMAGE: { BL::ShaderNodeTexImage b_image_node(b_node); BL::Image b_image(b_image_node.image()); diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index ae9b0ac6d99..be49aa54e47 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -370,6 +370,7 @@ typedef struct ShaderClosure { #endif float data0; float data1; + float3 N; } ShaderClosure; diff --git a/intern/cycles/kernel/svm/bsdf_ashikhmin_velvet.h b/intern/cycles/kernel/svm/bsdf_ashikhmin_velvet.h index 40249dbe9c6..785fc038e9e 100644 --- a/intern/cycles/kernel/svm/bsdf_ashikhmin_velvet.h +++ b/intern/cycles/kernel/svm/bsdf_ashikhmin_velvet.h @@ -58,7 +58,7 @@ __device void bsdf_ashikhmin_velvet_blur(ShaderClosure *sc, float roughness) __device float3 bsdf_ashikhmin_velvet_eval_reflect(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { float m_invsigma2 = sc->data0; - float3 m_N = sd->N; + float3 m_N = sc->N; float cosNO = dot(m_N, I); float cosNI = dot(m_N, omega_in); @@ -106,7 +106,7 @@ __device float bsdf_ashikhmin_velvet_albedo(const ShaderData *sd, const ShaderCl __device int bsdf_ashikhmin_velvet_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) { float m_invsigma2 = sc->data0; - float3 m_N = sd->N; + float3 m_N = sc->N; // we are viewing the surface from above - send a ray out with uniform // distribution over the hemisphere diff --git a/intern/cycles/kernel/svm/bsdf_diffuse.h b/intern/cycles/kernel/svm/bsdf_diffuse.h index edf8dd93341..6a67c184854 100644 --- a/intern/cycles/kernel/svm/bsdf_diffuse.h +++ b/intern/cycles/kernel/svm/bsdf_diffuse.h @@ -53,7 +53,7 @@ __device void bsdf_diffuse_blur(ShaderClosure *sc, float roughness) __device float3 bsdf_diffuse_eval_reflect(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { - float3 m_N = sd->N; + float3 m_N = sc->N; float cos_pi = fmaxf(dot(m_N, omega_in), 0.0f) * M_1_PI_F; *pdf = cos_pi; @@ -72,7 +72,7 @@ __device float bsdf_diffuse_albedo(const ShaderData *sd, const ShaderClosure *sc __device int bsdf_diffuse_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) { - float3 m_N = sd->N; + float3 m_N = sc->N; // distribution over the hemisphere sample_cos_hemisphere(m_N, randu, randv, omega_in, pdf); @@ -116,7 +116,7 @@ __device float3 bsdf_translucent_eval_reflect(const ShaderData *sd, const Shader __device float3 bsdf_translucent_eval_transmit(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { - float3 m_N = sd->N; + float3 m_N = sc->N; float cos_pi = fmaxf(-dot(m_N, omega_in), 0.0f) * M_1_PI_F; *pdf = cos_pi; @@ -130,7 +130,7 @@ __device float bsdf_translucent_albedo(const ShaderData *sd, const ShaderClosure __device int bsdf_translucent_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) { - float3 m_N = sd->N; + float3 m_N = sc->N; // we are viewing the surface from the right side - send a ray out with cosine // distribution over the hemisphere diff --git a/intern/cycles/kernel/svm/bsdf_microfacet.h b/intern/cycles/kernel/svm/bsdf_microfacet.h index d8f0310bd02..60f8e23818c 100644 --- a/intern/cycles/kernel/svm/bsdf_microfacet.h +++ b/intern/cycles/kernel/svm/bsdf_microfacet.h @@ -76,7 +76,7 @@ __device float3 bsdf_microfacet_ggx_eval_reflect(const ShaderData *sd, const Sha float m_ag = sc->data0; //float m_eta = sc->data1; int m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID; - float3 m_N = sd->N; + float3 m_N = sc->N; if(m_refractive) return make_float3 (0, 0, 0); float cosNO = dot(m_N, I); @@ -113,7 +113,7 @@ __device float3 bsdf_microfacet_ggx_eval_transmit(const ShaderData *sd, const Sh float m_ag = sc->data0; float m_eta = sc->data1; int m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID; - float3 m_N = sd->N; + float3 m_N = sc->N; if(!m_refractive) return make_float3 (0, 0, 0); float cosNO = dot(m_N, I); @@ -154,7 +154,7 @@ __device int bsdf_microfacet_ggx_sample(const ShaderData *sd, const ShaderClosur float m_ag = sc->data0; float m_eta = sc->data1; int m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID; - float3 m_N = sd->N; + float3 m_N = sc->N; float cosNO = dot(m_N, sd->I); if(cosNO > 0) { @@ -302,7 +302,7 @@ __device float3 bsdf_microfacet_beckmann_eval_reflect(const ShaderData *sd, cons float m_ab = sc->data0; //float m_eta = sc->data1; int m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID; - float3 m_N = sd->N; + float3 m_N = sc->N; if(m_refractive) return make_float3 (0, 0, 0); float cosNO = dot(m_N, I); @@ -341,7 +341,7 @@ __device float3 bsdf_microfacet_beckmann_eval_transmit(const ShaderData *sd, con float m_ab = sc->data0; float m_eta = sc->data1; int m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID; - float3 m_N = sd->N; + float3 m_N = sc->N; if(!m_refractive) return make_float3 (0, 0, 0); float cosNO = dot(m_N, I); @@ -384,7 +384,7 @@ __device int bsdf_microfacet_beckmann_sample(const ShaderData *sd, const ShaderC float m_ab = sc->data0; float m_eta = sc->data1; int m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID; - float3 m_N = sd->N; + float3 m_N = sc->N; float cosNO = dot(m_N, sd->I); if(cosNO > 0) { diff --git a/intern/cycles/kernel/svm/bsdf_oren_nayar.h b/intern/cycles/kernel/svm/bsdf_oren_nayar.h index a7edccdc423..04fbb091fb4 100644 --- a/intern/cycles/kernel/svm/bsdf_oren_nayar.h +++ b/intern/cycles/kernel/svm/bsdf_oren_nayar.h @@ -57,9 +57,9 @@ __device void bsdf_oren_nayar_blur(ShaderClosure *sc, float roughness) __device float3 bsdf_oren_nayar_eval_reflect(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { - if (dot(sd->N, omega_in) > 0.0f) { + if (dot(sc->N, omega_in) > 0.0f) { *pdf = 0.5f * M_1_PI_F; - return bsdf_oren_nayar_get_intensity(sc, sd->N, I, omega_in); + return bsdf_oren_nayar_get_intensity(sc, sc->N, I, omega_in); } else { *pdf = 0.0f; @@ -79,15 +79,15 @@ __device float bsdf_oren_nayar_albedo(const ShaderData *sd, const ShaderClosure __device int bsdf_oren_nayar_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) { - sample_uniform_hemisphere(sd->N, randu, randv, omega_in, pdf); + sample_uniform_hemisphere(sc->N, randu, randv, omega_in, pdf); if (dot(sd->Ng, *omega_in) > 0.0f) { - *eval = bsdf_oren_nayar_get_intensity(sc, sd->N, sd->I, *omega_in); + *eval = bsdf_oren_nayar_get_intensity(sc, sc->N, sd->I, *omega_in); #ifdef __RAY_DIFFERENTIALS__ // TODO: find a better approximation for the bounce - *domega_in_dx = (2.0f * dot(sd->N, sd->dI.dx)) * sd->N - sd->dI.dx; - *domega_in_dy = (2.0f * dot(sd->N, sd->dI.dy)) * sd->N - sd->dI.dy; + *domega_in_dx = (2.0f * dot(sc->N, sd->dI.dx)) * sc->N - sd->dI.dx; + *domega_in_dy = (2.0f * dot(sc->N, sd->dI.dy)) * sc->N - sd->dI.dy; *domega_in_dx *= 125.0f; *domega_in_dy *= 125.0f; #endif diff --git a/intern/cycles/kernel/svm/bsdf_reflection.h b/intern/cycles/kernel/svm/bsdf_reflection.h index 09b4e0e48f0..7ce38050a9a 100644 --- a/intern/cycles/kernel/svm/bsdf_reflection.h +++ b/intern/cycles/kernel/svm/bsdf_reflection.h @@ -69,7 +69,7 @@ __device float bsdf_reflection_albedo(const ShaderData *sd, const ShaderClosure __device int bsdf_reflection_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) { //const BsdfReflectionClosure *self = (const BsdfReflectionClosure*)sc->data; - float3 m_N = sd->N; + float3 m_N = sc->N; // only one direction is possible float cosNO = dot(m_N, sd->I); diff --git a/intern/cycles/kernel/svm/bsdf_refraction.h b/intern/cycles/kernel/svm/bsdf_refraction.h index c9c268999c0..7579a4c6276 100644 --- a/intern/cycles/kernel/svm/bsdf_refraction.h +++ b/intern/cycles/kernel/svm/bsdf_refraction.h @@ -71,7 +71,7 @@ __device float bsdf_refraction_albedo(const ShaderData *sd, const ShaderClosure __device int bsdf_refraction_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) { float m_eta = sc->data0; - float3 m_N = sd->N; + float3 m_N = sc->N; float3 R, T; #ifdef __RAY_DIFFERENTIALS__ diff --git a/intern/cycles/kernel/svm/bsdf_ward.h b/intern/cycles/kernel/svm/bsdf_ward.h index 56b8ad72c89..3c08a3d54d3 100644 --- a/intern/cycles/kernel/svm/bsdf_ward.h +++ b/intern/cycles/kernel/svm/bsdf_ward.h @@ -66,7 +66,7 @@ __device float3 bsdf_ward_eval_reflect(const ShaderData *sd, const ShaderClosure { float m_ax = sc->data0; float m_ay = sc->data1; - float3 m_N = sd->N; + float3 m_N = sc->N; float3 m_T = sd->T; float cosNO = dot(m_N, I); @@ -108,7 +108,7 @@ __device int bsdf_ward_sample(const ShaderData *sd, const ShaderClosure *sc, flo { float m_ax = sc->data0; float m_ay = sc->data1; - float3 m_N = sd->N; + float3 m_N = sc->N; float3 m_T = sd->T; float cosNO = dot(m_N, sd->I); diff --git a/intern/cycles/kernel/svm/bsdf_westin.h b/intern/cycles/kernel/svm/bsdf_westin.h index 3e7c27f44a4..75f935e3267 100644 --- a/intern/cycles/kernel/svm/bsdf_westin.h +++ b/intern/cycles/kernel/svm/bsdf_westin.h @@ -62,7 +62,7 @@ __device void bsdf_westin_backscatter_blur(ShaderClosure *sc, float roughness) __device float3 bsdf_westin_backscatter_eval_reflect(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { float m_invroughness = sc->data0; - float3 m_N = sd->N; + float3 m_N = sc->N; // pdf is implicitly 0 (no indirect sampling) float cosNO = dot(m_N, I); @@ -89,7 +89,7 @@ __device float bsdf_westin_backscatter_albedo(const ShaderData *sd, const Shader __device int bsdf_westin_backscatter_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) { float m_invroughness = sc->data0; - float3 m_N = sd->N; + float3 m_N = sc->N; float cosNO = dot(m_N, sd->I); if(cosNO > 0) { @@ -151,7 +151,7 @@ __device void bsdf_westin_sheen_blur(ShaderClosure *sc, float roughness) __device float3 bsdf_westin_sheen_eval_reflect(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { float m_edginess = sc->data0; - float3 m_N = sd->N; + float3 m_N = sc->N; // pdf is implicitly 0 (no indirect sampling) float cosNO = dot(m_N, I); @@ -178,7 +178,7 @@ __device float bsdf_westin_sheen_albedo(const ShaderData *sd, const ShaderClosur __device int bsdf_westin_sheen_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) { float m_edginess = sc->data0; - float3 m_N = sd->N; + float3 m_N = sc->N; // we are viewing the surface from the right side - send a ray out with cosine // distribution over the hemisphere diff --git a/intern/cycles/kernel/svm/svm.h b/intern/cycles/kernel/svm/svm.h index e5167a4f670..5e22edc4696 100644 --- a/intern/cycles/kernel/svm/svm.h +++ b/intern/cycles/kernel/svm/svm.h @@ -185,7 +185,7 @@ __device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ShaderT break; } case NODE_CLOSURE_BSDF: - svm_node_closure_bsdf(kg, sd, stack, node, randb, path_flag); + svm_node_closure_bsdf(kg, sd, stack, node, randb, path_flag, &offset); break; case NODE_CLOSURE_EMISSION: svm_node_closure_emission(sd, stack, node); @@ -342,7 +342,7 @@ __device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ShaderT svm_node_set_displacement(sd, stack, node.y); break; case NODE_SET_BUMP: - svm_node_set_bump(sd, stack, node.y, node.z, node.w); + svm_node_set_bump(kg, sd, stack, node); break; case NODE_MATH: svm_node_math(kg, sd, stack, node.y, node.z, node.w, &offset); @@ -370,6 +370,9 @@ __device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ShaderT case NODE_TEX_COORD_BUMP_DY: svm_node_tex_coord_bump_dy(kg, sd, stack, node.y, node.z); break; + case NODE_CLOSURE_SET_NORMAL: + svm_node_set_normal(kg, sd, stack, node.y, node.z ); + break; #endif case NODE_EMISSION_SET_WEIGHT_TOTAL: svm_node_emission_set_weight_total(kg, sd, node.y, node.z, node.w); @@ -384,7 +387,7 @@ __device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ShaderT case NODE_LIGHT_FALLOFF: svm_node_light_falloff(sd, stack, node); break; -#endif +#endif case NODE_END: default: #ifndef __MULTI_CLOSURE__ diff --git a/intern/cycles/kernel/svm/svm_closure.h b/intern/cycles/kernel/svm/svm_closure.h index c942d50908c..6a0e6915e99 100644 --- a/intern/cycles/kernel/svm/svm_closure.h +++ b/intern/cycles/kernel/svm/svm_closure.h @@ -57,7 +57,7 @@ __device_inline void svm_node_closure_set_mix_weight(ShaderClosure *sc, float mi #endif } -__device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, float randb, int path_flag) +__device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, float randb, int path_flag, int *offset) { uint type, param1_offset, param2_offset; @@ -66,11 +66,19 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st decode_node_uchar4(node.y, &type, ¶m1_offset, ¶m2_offset, &mix_weight_offset); float mix_weight = (stack_valid(mix_weight_offset)? stack_load_float(stack, mix_weight_offset): 1.0f); + /* note we read this extra node before weight check, so offset is added */ + uint4 data_node = read_node(kg, offset); + if(mix_weight == 0.0f) return; + + float3 N = stack_valid(data_node.y)? stack_load_float3(stack, data_node.y): sd->N; #else decode_node_uchar4(node.y, &type, ¶m1_offset, ¶m2_offset, NULL); float mix_weight = 1.0f; + + uint4 data_node = read_node(kg, offset); + float3 N = stack_valid(data_node.y)? stack_load_float3(stack, data_node.y): sd->N; #endif float param1 = (stack_valid(param1_offset))? stack_load_float(stack, param1_offset): __int_as_float(node.z); @@ -79,6 +87,7 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st switch(type) { case CLOSURE_BSDF_DIFFUSE_ID: { ShaderClosure *sc = svm_node_closure_get(sd); + sc->N = N; svm_node_closure_set_mix_weight(sc, mix_weight); float roughness = param1; @@ -90,12 +99,14 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st } case CLOSURE_BSDF_TRANSLUCENT_ID: { ShaderClosure *sc = svm_node_closure_get(sd); + sc->N = N; svm_node_closure_set_mix_weight(sc, mix_weight); bsdf_translucent_setup(sd, sc); break; } case CLOSURE_BSDF_TRANSPARENT_ID: { ShaderClosure *sc = svm_node_closure_get(sd); + sc->N = N; svm_node_closure_set_mix_weight(sc, mix_weight); bsdf_transparent_setup(sd, sc); break; @@ -108,6 +119,7 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st break; #endif ShaderClosure *sc = svm_node_closure_get(sd); + sc->N = N; svm_node_closure_set_mix_weight(sc, mix_weight); float roughness = param1; @@ -134,13 +146,14 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st eta = (sd->flag & SD_BACKFACING)? 1.0f/eta: eta; /* fresnel */ - float cosNO = dot(sd->N, sd->I); + float cosNO = dot(N, sd->I); float fresnel = fresnel_dielectric_cos(cosNO, eta); float roughness = param1; #ifdef __MULTI_CLOSURE__ /* reflection */ ShaderClosure *sc = svm_node_closure_get(sd); + sc->N = N; float3 weight = sc->weight; float sample_weight = sc->sample_weight; @@ -150,6 +163,7 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st /* refraction */ sc = svm_node_closure_get(sd); + sc->N = N; sc->weight = weight; sc->sample_weight = sample_weight; @@ -158,6 +172,7 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st svm_node_glossy_setup(sd, sc, type, eta, roughness, true); #else ShaderClosure *sc = svm_node_closure_get(sd); + sc->N = N; bool refract = (randb > fresnel); @@ -174,17 +189,19 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st break; #endif ShaderClosure *sc = svm_node_closure_get(sd); + sc->N = N; svm_node_closure_set_mix_weight(sc, mix_weight); float roughness_u = param1; float roughness_v = param2; - bsdf_ward_setup(sd, sc, normalize(sd->T), roughness_u, roughness_v); + bsdf_ward_setup(sd, sc, sd->T, roughness_u, roughness_v); break; } #endif case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID: { ShaderClosure *sc = svm_node_closure_get(sd); + sc->N = N; svm_node_closure_set_mix_weight(sc, mix_weight); /* sigma */ @@ -425,6 +442,8 @@ __device void svm_node_add_closure(ShaderData *sd, float *stack, uint unused, #endif } +/* Tangent */ + #ifdef __DPDU__ __device_inline void svm_node_closure_store_tangent(ShaderData *sd, float3 tangent) { @@ -444,5 +463,14 @@ __device void svm_node_closure_tangent(ShaderData *sd, float *stack, uint tangen } #endif +/* (Bump) normal */ + +__device void svm_node_set_normal(KernelGlobals *kg, ShaderData *sd, float *stack, uint in_direction, uint out_normal) +{ + float3 normal = stack_load_float3(stack, in_direction); + sd->N = normal; + stack_store_float3(stack, out_normal, normal); +} + CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/svm/svm_displace.h b/intern/cycles/kernel/svm/svm_displace.h index b1677f67eca..92f23990ad1 100644 --- a/intern/cycles/kernel/svm/svm_displace.h +++ b/intern/cycles/kernel/svm/svm_displace.h @@ -20,23 +20,35 @@ CCL_NAMESPACE_BEGIN /* Bump Node */ -__device void svm_node_set_bump(ShaderData *sd, float *stack, uint c_offset, uint x_offset, uint y_offset) +__device void svm_node_set_bump(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node) { #ifdef __RAY_DIFFERENTIALS__ + /* get normal input */ + float3 normal_in = stack_valid(node.y)? stack_load_float3(stack, node.y): sd->N; + + /* get surface tangents from normal */ + float3 Rx = cross(sd->dP.dy, normal_in); + float3 Ry = cross(normal_in, sd->dP.dx); + + /* get bump values */ + uint c_offset, x_offset, y_offset, intensity_offset; + decode_node_uchar4(node.z, &c_offset, &x_offset, &y_offset, &intensity_offset); + float h_c = stack_load_float(stack, c_offset); float h_x = stack_load_float(stack, x_offset); float h_y = stack_load_float(stack, y_offset); - float3 Rx = cross(sd->dP.dy, sd->N); - float3 Ry = cross(sd->N, sd->dP.dx); - + /* compute surface gradient and determinant */ float det = dot(sd->dP.dx, Rx); float3 surfgrad = (h_x - h_c)*Rx + (h_y - h_c)*Ry; + float intensity = stack_load_float(stack, intensity_offset); - surfgrad *= 0.1f; /* todo: remove this factor */ - + surfgrad *= intensity; float absdet = fabsf(det); - sd->N = normalize(absdet*sd->N - signf(det)*surfgrad); + + /* compute and output perturbed normal */ + float3 outN = normalize(absdet*normal_in - signf(det)*surfgrad); + stack_store_float3(stack, node.w, outN); #endif } diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h index 22afa304432..327d9cfa014 100644 --- a/intern/cycles/kernel/svm/svm_types.h +++ b/intern/cycles/kernel/svm/svm_types.h @@ -95,6 +95,7 @@ typedef enum NodeType { NODE_TEX_BRICK, NODE_CLOSURE_SET_TANGENT, NODE_CLOSURE_TANGENT, + NODE_CLOSURE_SET_NORMAL, } NodeType; typedef enum NodeAttributeType { diff --git a/intern/cycles/render/graph.cpp b/intern/cycles/render/graph.cpp index c13102e9567..c1c976dc193 100644 --- a/intern/cycles/render/graph.cpp +++ b/intern/cycles/render/graph.cpp @@ -229,6 +229,8 @@ void ShaderGraph::finalize(bool do_bump, bool do_osl) if(!finalized) { clean(); default_inputs(do_osl); + refine_bump_nodes(); + if(do_bump) bump_from_displacement(); @@ -484,6 +486,61 @@ void ShaderGraph::default_inputs(bool do_osl) add(texco); } +void ShaderGraph::refine_bump_nodes() +{ + /* we transverse the node graph looking for bump nodes, when we find them, + * like in bump_from_displacement(), we copy the sub-graph defined from "bump" + * input to the inputs "center","dx" and "dy" What is in "bump" input is moved + * to "center" input. */ + + foreach(ShaderNode *node, nodes) { + if(node->name == ustring("bump") && node->input("Height")->link) { + ShaderInput *bump_input = node->input("Height"); + set nodes_bump; + + /* make 2 extra copies of the subgraph defined in Bump input */ + map nodes_dx; + map nodes_dy; + + /* find dependencies for the given input */ + find_dependencies(nodes_bump, bump_input ); + + copy_nodes(nodes_bump, nodes_dx); + copy_nodes(nodes_bump, nodes_dy); + + /* mark nodes to indicate they are use for bump computation, so + that any texture coordinates are shifted by dx/dy when sampling */ + foreach(ShaderNode *node, nodes_bump) + node->bump = SHADER_BUMP_CENTER; + foreach(NodePair& pair, nodes_dx) + pair.second->bump = SHADER_BUMP_DX; + foreach(NodePair& pair, nodes_dy) + pair.second->bump = SHADER_BUMP_DY; + + ShaderOutput *out = bump_input->link; + ShaderOutput *out_dx = nodes_dx[out->parent]->output(out->name); + ShaderOutput *out_dy = nodes_dy[out->parent]->output(out->name); + + connect(out_dx, node->input("SampleX")); + connect(out_dy, node->input("SampleY")); + + /* add generated nodes */ + foreach(NodePair& pair, nodes_dx) + add(pair.second); + foreach(NodePair& pair, nodes_dy) + add(pair.second); + + /* connect what is conected is bump to samplecenter input*/ + connect(out , node->input("SampleCenter")); + + /* bump input is just for connectivity purpose for the graph input, + * we reconected this input to samplecenter, so lets disconnect it + * from bump input */ + disconnect(bump_input); + } + } +} + void ShaderGraph::bump_from_displacement() { /* generate bump mapping automatically from displacement. bump mapping is @@ -497,7 +554,7 @@ void ShaderGraph::bump_from_displacement() * different shifted coordinates. * * these 3 displacement values are then fed into the bump node, which will - * modify the normal. */ + * output the the perturbed normal. */ ShaderInput *displacement_in = output()->input("Displacement"); @@ -526,6 +583,12 @@ void ShaderGraph::bump_from_displacement() foreach(NodePair& pair, nodes_dy) pair.second->bump = SHADER_BUMP_DY; + /* add set normal node and connect the bump normal ouput to the set normal + * output, so it can finally set the shader normal, note we are only doing + * this for bump from displacement, this will be the only bump allowed to + * overwrite the shader normal */ + ShaderNode *set_normal = add(new SetNormalNode()); + /* add bump node and connect copied graphs to it */ ShaderNode *bump = add(new BumpNode()); @@ -537,6 +600,9 @@ void ShaderGraph::bump_from_displacement() connect(out_center, bump->input("SampleCenter")); connect(out_dx, bump->input("SampleX")); connect(out_dy, bump->input("SampleY")); + + /* connect the bump out to the set normal in: */ + connect(bump->output("Normal"), set_normal->input("Direction")); /* connect bump output to normal input nodes that aren't set yet. actually * this will only set the normal input to the geometry node that we created @@ -544,8 +610,14 @@ void ShaderGraph::bump_from_displacement() foreach(ShaderNode *node, nodes) foreach(ShaderInput *input, node->inputs) if(!input->link && input->default_value == ShaderInput::NORMAL) - connect(bump->output("Normal"), input); - + connect(set_normal->output("Normal"), input); + + /* for displacement bump, clear the normal input in case the above loop + * connected the setnormal out to the bump normalin */ + ShaderInput *bump_normal_in = bump->input("NormalIn"); + if(bump_normal_in) + bump_normal_in->link = NULL; + /* finally, add the copied nodes to the graph. we can't do this earlier * because we would create dependency cycles in the above loop */ foreach(NodePair& pair, nodes_center) diff --git a/intern/cycles/render/graph.h b/intern/cycles/render/graph.h index d485ed02150..acafe1d5278 100644 --- a/intern/cycles/render/graph.h +++ b/intern/cycles/render/graph.h @@ -235,6 +235,7 @@ protected: void break_cycles(ShaderNode *node, vector& visited, vector& on_stack); void clean(); void bump_from_displacement(); + void refine_bump_nodes(); void default_inputs(bool do_osl); }; diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index da31a528310..b4ef93a4ff8 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -1175,7 +1175,7 @@ BsdfNode::BsdfNode() closure = ccl::CLOSURE_BSDF_DIFFUSE_ID; add_input("Color", SHADER_SOCKET_COLOR, make_float3(0.8f, 0.8f, 0.8f)); - add_input("Normal", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, true); + add_input("Normal", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL); add_output("BSDF", SHADER_SOCKET_CLOSURE); } @@ -1183,6 +1183,7 @@ BsdfNode::BsdfNode() void BsdfNode::compile(SVMCompiler& compiler, ShaderInput *param1, ShaderInput *param2) { ShaderInput *color_in = input("Color"); + ShaderInput *normal_in = input("Normal"); if(color_in->link) { compiler.stack_assign(color_in); @@ -1203,6 +1204,10 @@ void BsdfNode::compile(SVMCompiler& compiler, ShaderInput *param1, ShaderInput * compiler.closure_mix_weight_offset()), __float_as_int((param1)? param1->value.x: 0.0f), __float_as_int((param2)? param2->value.x: 0.0f)); + + if(normal_in->link) + compiler.stack_assign(normal_in); + compiler.add_node(NODE_CLOSURE_BSDF, normal_in->stack_offset); } void BsdfNode::compile(SVMCompiler& compiler) @@ -2215,7 +2220,7 @@ static ShaderEnum mix_type_init() enm.insert("Burn", NODE_MIX_BURN); enm.insert("Hue", NODE_MIX_HUE); enm.insert("Saturation", NODE_MIX_SAT); - enm.insert("Value", NODE_MIX_VAL ); + enm.insert("Value", NODE_MIX_VAL); enm.insert("Color", NODE_MIX_COLOR); enm.insert("Soft Light", NODE_MIX_SOFT); enm.insert("Linear Light", NODE_MIX_LINEAR); @@ -2586,6 +2591,7 @@ OutputNode::OutputNode() add_input("Surface", SHADER_SOCKET_CLOSURE); add_input("Volume", SHADER_SOCKET_CLOSURE); add_input("Displacement", SHADER_SOCKET_FLOAT); + add_input("Normal", SHADER_SOCKET_NORMAL); } void OutputNode::compile(SVMCompiler& compiler) @@ -2733,9 +2739,15 @@ void VectorMathNode::compile(OSLCompiler& compiler) BumpNode::BumpNode() : ShaderNode("bump") { + /* this input is used by the user, but after graph transform it is no longer + * used and moved to sampler center/x/y instead */ + add_input("Height", SHADER_SOCKET_NORMAL); + add_input("SampleCenter", SHADER_SOCKET_FLOAT); add_input("SampleX", SHADER_SOCKET_FLOAT); add_input("SampleY", SHADER_SOCKET_FLOAT); + add_input("NormalIn", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL); + add_input("Strength", SHADER_SOCKET_FLOAT, 0.1f); add_output("Normal", SHADER_SOCKET_NORMAL); } @@ -2745,12 +2757,25 @@ void BumpNode::compile(SVMCompiler& compiler) ShaderInput *center_in = input("SampleCenter"); ShaderInput *dx_in = input("SampleX"); ShaderInput *dy_in = input("SampleY"); + ShaderInput *normal_in = input("NormalIn"); + ShaderInput *intensity_in = input("Strength"); + ShaderOutput *normal_out = output("Normal"); compiler.stack_assign(center_in); compiler.stack_assign(dx_in); compiler.stack_assign(dy_in); + compiler.stack_assign(intensity_in); + compiler.stack_assign(normal_out); - compiler.add_node(NODE_SET_BUMP, center_in->stack_offset, dx_in->stack_offset, dy_in->stack_offset); + if(normal_in->link) + compiler.stack_assign(normal_in); + + /* pack all parameters in the node */ + compiler.add_node(NODE_SET_BUMP, + normal_in->stack_offset, + compiler.encode_uchar4(center_in->stack_offset, dx_in->stack_offset, + dy_in->stack_offset, intensity_in->stack_offset), + normal_out->stack_offset); } void BumpNode::compile(OSLCompiler& compiler) @@ -2819,17 +2844,44 @@ void RGBRampNode::compile(OSLCompiler& compiler) /* NB: cycles float3 type is actually 4 floats! need to use an explicit array */ float ramp_color[RAMP_TABLE_SIZE][3]; float ramp_alpha[RAMP_TABLE_SIZE]; + for (int i = 0; i < RAMP_TABLE_SIZE; ++i) { ramp_color[i][0] = ramp[i].x; ramp_color[i][1] = ramp[i].y; ramp_color[i][2] = ramp[i].z; ramp_alpha[i] = ramp[i].w; } + compiler.parameter_color_array("ramp_color", ramp_color, RAMP_TABLE_SIZE); compiler.parameter_array("ramp_alpha", ramp_alpha, RAMP_TABLE_SIZE); compiler.add(this, "node_rgb_ramp"); } +/* Set Normal Node */ + +SetNormalNode::SetNormalNode() +: ShaderNode("set_normal") +{ + add_input("Direction", SHADER_SOCKET_VECTOR); + add_output("Normal", SHADER_SOCKET_NORMAL); +} + +void SetNormalNode::compile(SVMCompiler& compiler) +{ + ShaderInput *direction_in = input("Direction"); + ShaderOutput *normal_out = output("Normal"); + + compiler.stack_assign(direction_in); + compiler.stack_assign(normal_out); + + compiler.add_node(NODE_CLOSURE_SET_NORMAL, direction_in->stack_offset, normal_out->stack_offset); +} + +void SetNormalNode::compile(OSLCompiler& compiler) +{ + compiler.add(this, "set_normal"); +} + CCL_NAMESPACE_END diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h index 6e5d7be0091..fbc61e12fd4 100644 --- a/intern/cycles/render/nodes.h +++ b/intern/cycles/render/nodes.h @@ -440,6 +440,11 @@ public: float4 ramp[RAMP_TABLE_SIZE]; }; +class SetNormalNode : public ShaderNode { +public: + SHADER_NODE_CLASS(SetNormalNode) +}; + CCL_NAMESPACE_END #endif /* __NODES_H__ */ diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index acd6f120f93..92c4f9c4842 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -551,6 +551,7 @@ struct ShadeResult; #define SH_NODE_OBJECT_INFO 167 #define SH_NODE_PARTICLE_INFO 168 #define SH_NODE_TEX_BRICK 169 +#define SH_NODE_BUMP 170 /* custom defines options for Material node */ #define SH_NODE_MAT_DIFF 1 diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 2fd54baf96f..ab83bf4e5a4 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -2246,6 +2246,7 @@ static void registerShaderNodes(bNodeTreeType *ttype) register_node_type_sh_layer_weight(ttype); register_node_type_sh_tex_coord(ttype); register_node_type_sh_particle_info(ttype); + register_node_type_sh_bump(ttype); register_node_type_sh_background(ttype); register_node_type_sh_bsdf_anisotropic(ttype); diff --git a/source/blender/makesrna/intern/rna_nodetree_types.h b/source/blender/makesrna/intern/rna_nodetree_types.h index aa48a8cf26d..6d97e959112 100644 --- a/source/blender/makesrna/intern/rna_nodetree_types.h +++ b/source/blender/makesrna/intern/rna_nodetree_types.h @@ -82,6 +82,7 @@ DefNode( ShaderNode, SH_NODE_LIGHT_PATH, 0, "LI DefNode( ShaderNode, SH_NODE_LIGHT_FALLOFF, 0, "LIGHT_FALLOFF", LightFalloff, "Light Falloff", "" ) DefNode( ShaderNode, SH_NODE_OBJECT_INFO, 0, "OBJECT_INFO", ObjectInfo, "Object Info", "" ) DefNode( ShaderNode, SH_NODE_PARTICLE_INFO, 0, "PARTICLE_INFO", ParticleInfo, "Particle Info", "" ) +DefNode( ShaderNode, SH_NODE_BUMP, 0, "BUMP", BumpNode, "Bump", "" ) DefNode( ShaderNode, SH_NODE_TEX_IMAGE, def_sh_tex_image, "TEX_IMAGE", TexImage, "Image Texture", "" ) DefNode( ShaderNode, SH_NODE_TEX_ENVIRONMENT, def_sh_tex_environment, "TEX_ENVIRONMENT", TexEnvironment, "Environment Texture","" ) DefNode( ShaderNode, SH_NODE_TEX_SKY, def_sh_tex_sky, "TEX_SKY", TexSky, "Sky Texture", "" ) @@ -92,7 +93,7 @@ DefNode( ShaderNode, SH_NODE_TEX_WAVE, def_sh_tex_wave, "TE DefNode( ShaderNode, SH_NODE_TEX_MUSGRAVE, def_sh_tex_musgrave, "TEX_MUSGRAVE", TexMusgrave, "Musgrave Texture", "" ) DefNode( ShaderNode, SH_NODE_TEX_VORONOI, def_sh_tex_voronoi, "TEX_VORONOI", TexVoronoi, "Voronoi Texture", "" ) DefNode( ShaderNode, SH_NODE_TEX_CHECKER, def_sh_tex_checker, "TEX_CHECKER", TexChecker, "Checker Texture", "" ) -DefNode( ShaderNode, SH_NODE_TEX_BRICK, def_sh_tex_brick, "TEX_BRICK", TexBrick, "Brick Texture", "" ) +DefNode( ShaderNode, SH_NODE_TEX_BRICK, def_sh_tex_brick, "TEX_BRICK", TexBrick, "Brick Texture", "" ) DefNode( ShaderNode, SH_NODE_TEX_COORD, def_sh_tex_coord, "TEX_COORD", TexCoord, "Texture Coordinate","" ) DefNode( CompositorNode, CMP_NODE_VIEWER, def_cmp_viewer, "VIEWER", Viewer, "Viewer", "" ) diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt index f4e427ce3e3..a6de5e2fdba 100644 --- a/source/blender/nodes/CMakeLists.txt +++ b/source/blender/nodes/CMakeLists.txt @@ -153,6 +153,7 @@ set(SRC shader/nodes/node_shader_bsdf_translucent.c shader/nodes/node_shader_bsdf_transparent.c shader/nodes/node_shader_bsdf_velvet.c + shader/nodes/node_shader_bump.c shader/nodes/node_shader_emission.c shader/nodes/node_shader_fresnel.c shader/nodes/node_shader_layer_weight.c diff --git a/source/blender/nodes/NOD_shader.h b/source/blender/nodes/NOD_shader.h index 306dd50d7e2..7585ed0d61c 100644 --- a/source/blender/nodes/NOD_shader.h +++ b/source/blender/nodes/NOD_shader.h @@ -110,6 +110,7 @@ void register_node_type_sh_tex_wave(struct bNodeTreeType *ttype); void register_node_type_sh_tex_musgrave(struct bNodeTreeType *ttype); void register_node_type_sh_tex_noise(struct bNodeTreeType *ttype); void register_node_type_sh_tex_checker(struct bNodeTreeType *ttype); +void register_node_type_sh_bump(struct bNodeTreeType *ttype); #endif diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.c index 2b368420a76..ffad6b06eee 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.c +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.c @@ -33,6 +33,7 @@ static bNodeSocketTemplate sh_node_bsdf_anisotropic_in[]= { { SOCK_RGBA, 1, N_("Color"), 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, { SOCK_FLOAT, 1, N_("Roughness U"), 0.2f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, { SOCK_FLOAT, 1, N_("Roughness V"), 0.2f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_VECTOR, 1, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE}, { -1, 0, "" } }; diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_diffuse.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_diffuse.c index d2e2db3e78a..f9507d9a755 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_diffuse.c +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_diffuse.c @@ -32,6 +32,7 @@ static bNodeSocketTemplate sh_node_bsdf_diffuse_in[]= { { SOCK_RGBA, 1, N_("Color"), 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, { SOCK_FLOAT, 1, N_("Roughness"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_VECTOR, 1, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE}, { -1, 0, "" } }; diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_glass.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_glass.c index 8ff0ad57742..858301a052d 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_glass.c +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_glass.c @@ -33,6 +33,7 @@ static bNodeSocketTemplate sh_node_bsdf_glass_in[]= { { SOCK_RGBA, 1, N_("Color"), 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, { SOCK_FLOAT, 1, N_("Roughness"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, { SOCK_FLOAT, 1, N_("IOR"), 1.45f, 0.0f, 0.0f, 0.0f, 1.0f, 1000.0f}, + { SOCK_VECTOR, 1, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE}, { -1, 0, "" } }; diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.c index d28b3454f02..30697d75eae 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.c +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.c @@ -32,6 +32,7 @@ static bNodeSocketTemplate sh_node_bsdf_glossy_in[]= { { SOCK_RGBA, 1, N_("Color"), 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, { SOCK_FLOAT, 1, N_("Roughness"), 0.2f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_VECTOR, 1, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE}, { -1, 0, "" } }; diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_translucent.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_translucent.c index a3ba3ac7ff3..1023fd2f3fc 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_translucent.c +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_translucent.c @@ -31,6 +31,7 @@ static bNodeSocketTemplate sh_node_bsdf_translucent_in[]= { { SOCK_RGBA, 1, N_("Color"), 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + { SOCK_VECTOR, 1, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE}, { -1, 0, "" } }; diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_velvet.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_velvet.c index 04a1c1b32df..c1483d41c94 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_velvet.c +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_velvet.c @@ -32,6 +32,7 @@ static bNodeSocketTemplate sh_node_bsdf_velvet_in[]= { { SOCK_RGBA, 1, N_("Color"), 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, { SOCK_FLOAT, 1, N_("Sigma"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_VECTOR, 1, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE}, { -1, 0, "" } }; diff --git a/source/blender/nodes/shader/nodes/node_shader_bump.c b/source/blender/nodes/shader/nodes/node_shader_bump.c new file mode 100644 index 00000000000..fc612ccc65b --- /dev/null +++ b/source/blender/nodes/shader/nodes/node_shader_bump.c @@ -0,0 +1,63 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2005 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/nodes/shader/nodes/node_shader_bump.c + * \ingroup shdnodes + */ + + + +#include "node_shader_util.h" + + +/* **************** BUMP ******************** */ +static bNodeSocketTemplate sh_node_bump_in[]= { + { SOCK_FLOAT, 1, "Strength", 0.1f, 0.0f, 0.0f, 0.0f, -1000.0f, 1000.0f}, + { SOCK_FLOAT, 1, "Height", 1.0f, 1.0f, 1.0f, 1.0f, -1000.0f, 1000.0f, PROP_NONE, SOCK_HIDE_VALUE}, + { -1, 0, "" } +}; + +static bNodeSocketTemplate sh_node_bump_out[]= { + { SOCK_VECTOR, 0, "Normal"}, + { -1, 0, "" } +}; + + +/* node type definition */ +void register_node_type_sh_bump(bNodeTreeType *ttype) +{ + static bNodeType ntype; + + node_type_base(ttype, &ntype, SH_NODE_BUMP, "Bump", NODE_CLASS_OP_VECTOR, NODE_OPTIONS); + node_type_compatibility(&ntype, NODE_NEW_SHADING); + node_type_socket_templates(&ntype, sh_node_bump_in, sh_node_bump_out); + node_type_size(&ntype, 150, 60, 200); + node_type_storage(&ntype, "BumpNode", node_free_standard_storage, node_copy_standard_storage); + node_type_exec(&ntype, NULL); + + nodeRegisterType(ttype, &ntype); +} From 57004cfb5a495adbb2aa890659b6540e3490a750 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 10 Oct 2012 23:44:07 +0000 Subject: [PATCH 177/347] style cleanup: also add helper makefile targets: * tbz - makes a tar.bz2 of an svn export * test_style_qtc - outputs style checks in qtc task format. --- GNUmakefile | 24 + source/blender/blenkernel/intern/anim.c | 4 +- source/blender/blenkernel/intern/customdata.c | 10 +- source/blender/blenkernel/intern/ipo.c | 2 +- source/blender/blenkernel/intern/smoke.c | 1022 ++++++++--------- .../blender/editors/armature/meshlaplacian.c | 4 +- .../editors/interface/interface_widgets.c | 12 +- .../blender/editors/object/object_iterators.c | 6 +- source/blender/editors/object/object_vgroup.c | 8 +- .../editors/physics/dynamicpaint_ops.c | 38 +- .../blender/editors/space_image/image_ops.c | 3 +- .../blender/editors/space_view3d/drawvolume.c | 113 +- 12 files changed, 632 insertions(+), 614 deletions(-) diff --git a/GNUmakefile b/GNUmakefile index 90d76dfe432..58707a03d75 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -168,6 +168,7 @@ help: @echo " * test_pep8 - checks all python script are pep8 which are tagged to use the stricter formatting" @echo " * test_deprecated - checks for deprecation tags in our code which may need to be removed" @echo " * test_style - checks C/C++ conforms with blenders style guide: http://wiki.blender.org/index.php/Dev:Doc/CodeStyle" + @echo " * test_style_qtc - same as test_style but outputs QtCreator tasks format" @echo "" @echo "Static Source Code Checking (not associated with building blender)" @echo " * check_cppcheck - run blender source through cppcheck (C & C++)" @@ -178,6 +179,9 @@ help: @echo " * check_spelling_c - check for spelling errors (C/C++ only)" @echo " * check_spelling_py - check for spelling errors (Python only)" @echo "" + @echo "Utilities (not associated with building blender)" + @echo " * tbz - create a compressed svn export 'blender_archive.tar.bz2'" + @echo "" @echo "Documentation Targets (not associated with building blender)" @echo " * doc_py - generate sphinx python api docs" @echo " * doc_doxy - generate doxygen C/C++ docs" @@ -223,6 +227,14 @@ test_style: # run our own checks on C/C++ style PYTHONIOENCODING=utf_8 python3.2 $(BLENDER_DIR)/source/tools/check_style_c.py $(BLENDER_DIR)/source/blender $(BLENDER_DIR)/source/creator --no-length-check +test_style_qtc: + # run our own checks on C/C++ style + USE_QTC_TASK=1 \ + PYTHONIOENCODING=utf_8 python3.2 $(BLENDER_DIR)/source/tools/check_style_c.py $(BLENDER_DIR)/source/blender $(BLENDER_DIR)/source/creator --no-length-check > \ + test_style.tasks + + @echo "written: test_style.tasks" + # ----------------------------------------------------------------------------- # Project Files # @@ -267,6 +279,18 @@ check_spelling_py: check_spelling_c: cd $(BUILD_DIR) ; PYTHONIOENCODING=utf_8 python3.2 $(BLENDER_DIR)/source/tools/spell_check_source.py $(BLENDER_DIR)/source + +# ----------------------------------------------------------------------------- +# Utilities +# + +tbz: + svn export . blender_archive + tar cjf blender_archive.tar.bz2 blender_archive/ + rm -rf blender_archive/ + @echo "blender_archive.tar.bz2 written" + + # ----------------------------------------------------------------------------- # Documentation # diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index 58d20fff2bc..f44cb6d6b19 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -1678,8 +1678,8 @@ ListBase *object_duplilist_ex(Scene *sce, Object *ob, int update, int for_render ListBase *duplilist = MEM_mallocN(sizeof(ListBase), "duplilist"); int flag = 0; - if(update) flag |= DUPLILIST_DO_UPDATE; - if(for_render) flag |= DUPLILIST_FOR_RENDER; + if (update) flag |= DUPLILIST_DO_UPDATE; + if (for_render) flag |= DUPLILIST_FOR_RENDER; duplilist->first = duplilist->last = NULL; object_duplilist_recursive((ID *)sce, sce, ob, duplilist, NULL, 0, 0, flag); diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index efcc00c401d..423bd93c70f 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -2358,7 +2358,9 @@ void CustomData_bmesh_free_block(CustomData *data, void **block) const LayerTypeInfo *typeInfo; int i; - if (!*block) return; + if (*block == NULL) + return; + for (i = 0; i < data->totlayer; ++i) { if (!(data->layers[i].flag & CD_FLAG_NOFREE)) { typeInfo = layerType_getInfo(data->layers[i].type); @@ -2394,7 +2396,7 @@ void CustomData_bmesh_copy_data(const CustomData *source, CustomData *dest, const LayerTypeInfo *typeInfo; int dest_i, src_i; - if (!*dest_block) { + if (*dest_block == NULL) { CustomData_bmesh_alloc_block(dest, dest_block); if (*dest_block) memset(*dest_block, 0, dest->totsize); @@ -2614,7 +2616,7 @@ void CustomData_bmesh_set_default(CustomData *data, void **block) const LayerTypeInfo *typeInfo; int i; - if (!*block) + if (*block == NULL) CustomData_bmesh_alloc_block(data, block); for (i = 0; i < data->totlayer; ++i) { @@ -2634,7 +2636,7 @@ void CustomData_to_bmesh_block(const CustomData *source, CustomData *dest, const LayerTypeInfo *typeInfo; int dest_i, src_i, src_offset; - if (!*dest_block) + if (*dest_block == NULL) CustomData_bmesh_alloc_block(dest, dest_block); /* copies a layer at a time */ diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c index 5216aefab58..b7e33f1cf71 100644 --- a/source/blender/blenkernel/intern/ipo.c +++ b/source/blender/blenkernel/intern/ipo.c @@ -2093,7 +2093,7 @@ void do_versions_ipos_to_animato(Main *main) bAction *new_act; /* add a new action for this, and convert all data into that action */ - new_act = add_empty_action(id->name+2); + new_act = add_empty_action(id->name + 2); ipo_to_animato(NULL, ipo, NULL, NULL, NULL, NULL, &new_act->curves, &drivers); new_act->idroot = ipo->blocktype; } diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c index a20d88c03c7..519c4008e0d 100644 --- a/source/blender/blenkernel/intern/smoke.c +++ b/source/blender/blenkernel/intern/smoke.c @@ -95,38 +95,38 @@ static LARGE_INTEGER liFrequency; static LARGE_INTEGER liStartTime; static LARGE_INTEGER liCurrentTime; -static void tstart ( void ) +static void tstart(void) { - QueryPerformanceFrequency ( &liFrequency ); - QueryPerformanceCounter ( &liStartTime ); + QueryPerformanceFrequency(&liFrequency); + QueryPerformanceCounter(&liStartTime); } -static void tend ( void ) +static void tend(void) { - QueryPerformanceCounter ( &liCurrentTime ); + QueryPerformanceCounter(&liCurrentTime); } -static double tval( void ) +static double tval(void) { - return ((double)( (liCurrentTime.QuadPart - liStartTime.QuadPart)* (double)1000.0/(double)liFrequency.QuadPart )); + return ((double)( (liCurrentTime.QuadPart - liStartTime.QuadPart) * (double)1000.0 / (double)liFrequency.QuadPart)); } #else #include static struct timeval _tstart, _tend; static struct timezone tz; -static void tstart ( void ) +static void tstart(void) { - gettimeofday ( &_tstart, &tz ); + gettimeofday(&_tstart, &tz); } -static void tend ( void ) +static void tend(void) { - gettimeofday ( &_tend,&tz ); + gettimeofday(&_tend, &tz); } -static double UNUSED_FUNCTION(tval)( void ) +static double UNUSED_FUNCTION(tval) (void) { double t1, t2; - t1 = ( double ) _tstart.tv_sec*1000 + ( double ) _tstart.tv_usec/ ( 1000 ); - t2 = ( double ) _tend.tv_sec*1000 + ( double ) _tend.tv_usec/ ( 1000 ); - return t2-t1; + t1 = ( double ) _tstart.tv_sec * 1000 + ( double ) _tstart.tv_usec / (1000); + t2 = ( double ) _tend.tv_sec * 1000 + ( double ) _tend.tv_usec / (1000); + return t2 - t1; } #endif @@ -138,9 +138,9 @@ struct SmokeModifierData; // timestep default value for nice appearance 0.1f #define DT_DEFAULT 0.1f -#define ADD_IF_LOWER_POS(a,b) (MIN2((a)+(b), MAX2((a),(b)))) -#define ADD_IF_LOWER_NEG(a,b) (MAX2((a)+(b), MIN2((a),(b)))) -#define ADD_IF_LOWER(a,b) (((b)>0)?ADD_IF_LOWER_POS((a),(b)):ADD_IF_LOWER_NEG((a),(b))) +#define ADD_IF_LOWER_POS(a, b) (MIN2((a) + (b), MAX2((a), (b)))) +#define ADD_IF_LOWER_NEG(a, b) (MAX2((a) + (b), MIN2((a), (b)))) +#define ADD_IF_LOWER(a, b) (((b) > 0) ? ADD_IF_LOWER_POS((a), (b)) : ADD_IF_LOWER_NEG((a), (b))) #else /* WITH_SMOKE */ @@ -152,8 +152,8 @@ float *smoke_get_density(struct FLUID_3D *UNUSED(fluid)) { return NULL; } void smoke_turbulence_free(struct WTURBULENCE *UNUSED(wt)) {} void smoke_initWaveletBlenderRNA(struct WTURBULENCE *UNUSED(wt), float *UNUSED(strength)) {} void smoke_initBlenderRNA(struct FLUID_3D *UNUSED(fluid), float *UNUSED(alpha), float *UNUSED(beta), float *UNUSED(dt_factor), float *UNUSED(vorticity), - int *UNUSED(border_colli), float *UNUSED(burning_rate), float *UNUSED(flame_smoke), float *UNUSED(flame_smoke_color), - float *UNUSED(flame_vorticity), float *UNUSED(flame_ignition_temp), float *UNUSED(flame_max_temp)) {} + int *UNUSED(border_colli), float *UNUSED(burning_rate), float *UNUSED(flame_smoke), float *UNUSED(flame_smoke_color), + float *UNUSED(flame_vorticity), float *UNUSED(flame_ignition_temp), float *UNUSED(flame_max_temp)) {} struct DerivedMesh *smokeModifier_do(SmokeModifierData *UNUSED(smd), Scene *UNUSED(scene), Object *UNUSED(ob), DerivedMesh *UNUSED(dm)) { return NULL; } float smoke_get_velocity_at(struct Object *UNUSED(ob), float UNUSED(position[3]), float UNUSED(velocity[3])) { return 0.0f; } void flame_get_spectrum(unsigned char *UNUSED(spec), int UNUSED(width), float UNUSED(t1), float UNUSED(t2)) {} @@ -165,18 +165,18 @@ void flame_get_spectrum(unsigned char *UNUSED(spec), int UNUSED(width), float UN void smoke_reallocate_fluid(SmokeDomainSettings *sds, float dx, int res[3], int free_old) { int use_heat = (sds->active_fields & SM_ACTIVE_HEAT); - int use_fire = (sds->active_fields & (SM_ACTIVE_HEAT|SM_ACTIVE_FIRE)); + int use_fire = (sds->active_fields & (SM_ACTIVE_HEAT | SM_ACTIVE_FIRE)); int use_colors = (sds->active_fields & SM_ACTIVE_COLORS); if (free_old && sds->fluid) smoke_free(sds->fluid); - if (!MIN3(res[0],res[1],res[2])) { + if (!MIN3(res[0], res[1], res[2])) { sds->fluid = NULL; return; } sds->fluid = smoke_init(res, dx, DT_DEFAULT, use_heat, use_fire, use_colors); smoke_initBlenderRNA(sds->fluid, &(sds->alpha), &(sds->beta), &(sds->time_scale), &(sds->vorticity), &(sds->border_collisions), - &(sds->burning_rate), &(sds->flame_smoke), sds->flame_smoke_color, &(sds->flame_vorticity), &(sds->flame_ignition), &(sds->flame_max_temp)); + &(sds->burning_rate), &(sds->flame_smoke), sds->flame_smoke_color, &(sds->flame_vorticity), &(sds->flame_ignition), &(sds->flame_max_temp)); /* reallocate shadow buffer */ if (sds->shadow) @@ -186,19 +186,19 @@ void smoke_reallocate_fluid(SmokeDomainSettings *sds, float dx, int res[3], int void smoke_reallocate_highres_fluid(SmokeDomainSettings *sds, float dx, int res[3], int free_old) { - int use_fire = (sds->active_fields & (SM_ACTIVE_HEAT|SM_ACTIVE_FIRE)); + int use_fire = (sds->active_fields & (SM_ACTIVE_HEAT | SM_ACTIVE_FIRE)); int use_colors = (sds->active_fields & SM_ACTIVE_COLORS); if (free_old && sds->wt) smoke_turbulence_free(sds->wt); - if (!MIN3(res[0],res[1],res[2])) { + if (!MIN3(res[0], res[1], res[2])) { sds->wt = NULL; return; } sds->wt = smoke_turbulence_init(res, sds->amplify + 1, sds->noise, use_fire, use_colors); sds->res_wt[0] = res[0] * (sds->amplify + 1); - sds->res_wt[1] = res[1] * (sds->amplify + 1); - sds->res_wt[2] = res[2] * (sds->amplify + 1); + sds->res_wt[1] = res[1] * (sds->amplify + 1); + sds->res_wt[2] = res[2] * (sds->amplify + 1); sds->dx_wt = dx / (sds->amplify + 1); smoke_initWaveletBlenderRNA(sds->wt, &(sds->strength)); } @@ -208,9 +208,9 @@ static void smoke_pos_to_cell(SmokeDomainSettings *sds, float pos[3]) { mul_m4_v3(sds->imat, pos); sub_v3_v3(pos, sds->p0); - pos[0] *= 1.0f/sds->cell_size[0]; - pos[1] *= 1.0f/sds->cell_size[1]; - pos[2] *= 1.0f/sds->cell_size[2]; + pos[0] *= 1.0f / sds->cell_size[0]; + pos[1] *= 1.0f / sds->cell_size[1]; + pos[2] *= 1.0f / sds->cell_size[2]; } /* set domain resolution and dimensions from object derivedmesh */ @@ -226,7 +226,7 @@ static void smoke_set_domain_from_derivedmesh(SmokeDomainSettings *sds, Object * res = sds->maxres; // get BB of domain - for(i = 0; i < dm->getNumVerts(dm); i++) + for (i = 0; i < dm->getNumVerts(dm); i++) { // min BB min[0] = MIN2(min[0], verts[i].co[0]); @@ -254,7 +254,7 @@ static void smoke_set_domain_from_derivedmesh(SmokeDomainSettings *sds, Object * invert_m4_m4(sds->imat, ob->obmat); // prevent crash when initializing a plane as domain - if((size[0] < FLT_EPSILON) || (size[1] < FLT_EPSILON) || (size[2] < FLT_EPSILON)) + if ((size[0] < FLT_EPSILON) || (size[1] < FLT_EPSILON) || (size[2] < FLT_EPSILON)) return; /* define grid resolutions from longest domain side */ @@ -288,7 +288,7 @@ static void smoke_set_domain_from_derivedmesh(SmokeDomainSettings *sds, Object * static int smokeModifier_init(SmokeModifierData *smd, Object *ob, Scene *scene, DerivedMesh *dm) { - if((smd->type & MOD_SMOKE_TYPE_DOMAIN) && smd->domain && !smd->domain->fluid) + if ((smd->type & MOD_SMOKE_TYPE_DOMAIN) && smd->domain && !smd->domain->fluid) { SmokeDomainSettings *sds = smd->domain; int res[3]; @@ -309,7 +309,7 @@ static int smokeModifier_init(SmokeModifierData *smd, Object *ob, Scene *scene, VECCOPY(res, sds->base_res); } VECCOPY(sds->res, res); - sds->total_cells = sds->res[0]*sds->res[1]*sds->res[2]; + sds->total_cells = sds->res[0] * sds->res[1] * sds->res[2]; sds->res_min[0] = sds->res_min[1] = sds->res_min[2] = 0; VECCOPY(sds->res_max, res); @@ -319,24 +319,24 @@ static int smokeModifier_init(SmokeModifierData *smd, Object *ob, Scene *scene, smd->time = scene->r.cfra; /* allocate highres fluid */ - if(sds->flags & MOD_SMOKE_HIGHRES) { + if (sds->flags & MOD_SMOKE_HIGHRES) { smoke_reallocate_highres_fluid(sds, sds->dx, sds->res, 0); } /* allocate shadow buffer */ - if(!sds->shadow) + if (!sds->shadow) sds->shadow = MEM_callocN(sizeof(float) * sds->res[0] * sds->res[1] * sds->res[2], "SmokeDomainShadow"); return 1; } - else if((smd->type & MOD_SMOKE_TYPE_FLOW) && smd->flow) + else if ((smd->type & MOD_SMOKE_TYPE_FLOW) && smd->flow) { smd->time = scene->r.cfra; return 1; } - else if((smd->type & MOD_SMOKE_TYPE_COLL)) + else if ((smd->type & MOD_SMOKE_TYPE_COLL)) { - if(!smd->coll) + if (!smd->coll) { smokeModifier_createType(smd); } @@ -353,20 +353,20 @@ static int smokeModifier_init(SmokeModifierData *smd, Object *ob, Scene *scene, static void smokeModifier_freeDomain(SmokeModifierData *smd) { - if(smd->domain) + if (smd->domain) { - if(smd->domain->shadow) - MEM_freeN(smd->domain->shadow); - smd->domain->shadow = NULL; + if (smd->domain->shadow) + MEM_freeN(smd->domain->shadow); + smd->domain->shadow = NULL; - if(smd->domain->fluid) + if (smd->domain->fluid) smoke_free(smd->domain->fluid); - if(smd->domain->wt) + if (smd->domain->wt) smoke_turbulence_free(smd->domain->wt); - if(smd->domain->effector_weights) - MEM_freeN(smd->domain->effector_weights); + if (smd->domain->effector_weights) + MEM_freeN(smd->domain->effector_weights); smd->domain->effector_weights = NULL; BKE_ptcache_free_list(&(smd->domain->ptcaches[0])); @@ -379,7 +379,7 @@ static void smokeModifier_freeDomain(SmokeModifierData *smd) static void smokeModifier_freeFlow(SmokeModifierData *smd) { - if(smd->flow) + if (smd->flow) { if (smd->flow->dm) smd->flow->dm->release(smd->flow->dm); if (smd->flow->verts_old) MEM_freeN(smd->flow->verts_old); @@ -390,20 +390,20 @@ static void smokeModifier_freeFlow(SmokeModifierData *smd) static void smokeModifier_freeCollision(SmokeModifierData *smd) { - if(smd->coll) + if (smd->coll) { SmokeCollSettings *scs = smd->coll; - if(scs->numverts) + if (scs->numverts) { - if(scs->verts_old) + if (scs->verts_old) { MEM_freeN(scs->verts_old); scs->verts_old = NULL; } } - if(smd->coll->dm) + if (smd->coll->dm) smd->coll->dm->release(smd->coll->dm); smd->coll->dm = NULL; @@ -414,7 +414,7 @@ static void smokeModifier_freeCollision(SmokeModifierData *smd) void smokeModifier_reset_turbulence(struct SmokeModifierData *smd) { - if(smd && smd->domain && smd->domain->wt) + if (smd && smd->domain && smd->domain->wt) { smoke_turbulence_free(smd->domain->wt); smd->domain->wt = NULL; @@ -423,15 +423,15 @@ void smokeModifier_reset_turbulence(struct SmokeModifierData *smd) void smokeModifier_reset(struct SmokeModifierData *smd) { - if(smd) + if (smd) { - if(smd->domain) + if (smd->domain) { - if(smd->domain->shadow) + if (smd->domain->shadow) MEM_freeN(smd->domain->shadow); smd->domain->shadow = NULL; - if(smd->domain->fluid) + if (smd->domain->fluid) { smoke_free(smd->domain->fluid); smd->domain->fluid = NULL; @@ -443,17 +443,17 @@ void smokeModifier_reset(struct SmokeModifierData *smd) smd->domain->total_cells = 0; smd->domain->active_fields = 0; } - else if(smd->flow) + else if (smd->flow) { if (smd->flow->verts_old) MEM_freeN(smd->flow->verts_old); smd->flow->verts_old = NULL; smd->flow->numverts = 0; } - else if(smd->coll) + else if (smd->coll) { SmokeCollSettings *scs = smd->coll; - if(scs->numverts && scs->verts_old) + if (scs->numverts && scs->verts_old) { MEM_freeN(scs->verts_old); scs->verts_old = NULL; @@ -464,7 +464,7 @@ void smokeModifier_reset(struct SmokeModifierData *smd) void smokeModifier_free(SmokeModifierData *smd) { - if(smd) + if (smd) { smokeModifier_freeDomain(smd); smokeModifier_freeFlow(smd); @@ -474,11 +474,11 @@ void smokeModifier_free(SmokeModifierData *smd) void smokeModifier_createType(struct SmokeModifierData *smd) { - if(smd) + if (smd) { - if(smd->type & MOD_SMOKE_TYPE_DOMAIN) + if (smd->type & MOD_SMOKE_TYPE_DOMAIN) { - if(smd->domain) + if (smd->domain) smokeModifier_freeDomain(smd); smd->domain = MEM_callocN(sizeof(SmokeDomainSettings), "SmokeDomain"); @@ -494,12 +494,12 @@ void smokeModifier_createType(struct SmokeModifierData *smd) smd->domain->ptcaches[1].first = smd->domain->ptcaches[1].last = NULL; /* set some standard values */ smd->domain->fluid = NULL; - smd->domain->wt = NULL; + smd->domain->wt = NULL; smd->domain->eff_group = NULL; smd->domain->fluid_group = NULL; smd->domain->coll_group = NULL; smd->domain->maxres = 32; - smd->domain->amplify = 1; + smd->domain->amplify = 1; smd->domain->alpha = -0.001; smd->domain->beta = 0.1; smd->domain->time_scale = 1.0; @@ -528,9 +528,9 @@ void smokeModifier_createType(struct SmokeModifierData *smd) smd->domain->viewsettings = MOD_SMOKE_VIEW_SHOWBIG; smd->domain->effector_weights = BKE_add_effector_weights(NULL); } - else if(smd->type & MOD_SMOKE_TYPE_FLOW) + else if (smd->type & MOD_SMOKE_TYPE_FLOW) { - if(smd->flow) + if (smd->flow) smokeModifier_freeFlow(smd); smd->flow = MEM_callocN(sizeof(SmokeFlowSettings), "SmokeFlow"); @@ -555,9 +555,9 @@ void smokeModifier_createType(struct SmokeModifierData *smd) smd->flow->psys = NULL; } - else if(smd->type & MOD_SMOKE_TYPE_COLL) + else if (smd->type & MOD_SMOKE_TYPE_COLL) { - if(smd->coll) + if (smd->coll) smokeModifier_freeCollision(smd); smd->coll = MEM_callocN(sizeof(SmokeCollSettings), "SmokeColl"); @@ -579,7 +579,7 @@ void smokeModifier_copy(struct SmokeModifierData *smd, struct SmokeModifierData { tsmd->type = smd->type; tsmd->time = smd->time; - + smokeModifier_createType(tsmd); if (tsmd->domain) { @@ -610,10 +610,10 @@ void smokeModifier_copy(struct SmokeModifierData *smd, struct SmokeModifierData tsmd->domain->flame_ignition = smd->domain->flame_ignition; tsmd->domain->flame_max_temp = smd->domain->flame_max_temp; copy_v3_v3(tsmd->domain->flame_smoke_color, smd->domain->flame_smoke_color); - + MEM_freeN(tsmd->domain->effector_weights); tsmd->domain->effector_weights = MEM_dupallocN(smd->domain->effector_weights); - } + } else if (tsmd->flow) { tsmd->flow->psys = smd->flow->psys; tsmd->flow->noise_texture = smd->flow->noise_texture; @@ -652,20 +652,20 @@ static void smoke_calc_transparency(SmokeDomainSettings *sds, Scene *scene); static float calc_voxel_transp(float *result, float *input, int res[3], int *pixel, float *tRay, float correct); static int get_lamp(Scene *scene, float *light) -{ - Base *base_tmp = NULL; +{ + Base *base_tmp = NULL; int found_lamp = 0; // try to find a lamp, preferably local - for(base_tmp = scene->base.first; base_tmp; base_tmp= base_tmp->next) { - if(base_tmp->object->type == OB_LAMP) { + for (base_tmp = scene->base.first; base_tmp; base_tmp = base_tmp->next) { + if (base_tmp->object->type == OB_LAMP) { Lamp *la = base_tmp->object->data; - if(la->type == LA_LOCAL) { + if (la->type == LA_LOCAL) { copy_v3_v3(light, base_tmp->object->obmat[3]); return 1; } - else if(!found_lamp) { + else if (!found_lamp) { copy_v3_v3(light, base_tmp->object->obmat[3]); found_lamp = 1; } @@ -717,7 +717,7 @@ static void obstacles_from_derivedmesh(Object *coll_ob, SmokeDomainSettings *sds } /* Transform collider vertices to - * domain grid space for fast lookups */ + * domain grid space for fast lookups */ for (i = 0; i < numverts; i++) { float n[3]; float co[3]; @@ -735,58 +735,58 @@ static void obstacles_from_derivedmesh(Object *coll_ob, SmokeDomainSettings *sds /* vert velocity */ VECADD(co, mvert[i].co, sds->shift); - if (has_velocity) + if (has_velocity) { - sub_v3_v3v3(&vert_vel[i*3], co, &scs->verts_old[i*3]); - mul_v3_fl(&vert_vel[i*3], sds->dx/dt); + sub_v3_v3v3(&vert_vel[i * 3], co, &scs->verts_old[i * 3]); + mul_v3_fl(&vert_vel[i * 3], sds->dx / dt); } - copy_v3_v3(&scs->verts_old[i*3], co); + copy_v3_v3(&scs->verts_old[i * 3], co); } if (bvhtree_from_mesh_faces(&treeData, dm, 0.0f, 4, 6)) { #pragma omp parallel for schedule(static) for (z = sds->res_min[2]; z < sds->res_max[2]; z++) { - int x,y; + int x, y; for (x = sds->res_min[0]; x < sds->res_max[0]; x++) - for (y = sds->res_min[1]; y < sds->res_max[1]; y++) { - int index = smoke_get_index(x-sds->res_min[0], sds->res[0], y-sds->res_min[1], sds->res[1], z-sds->res_min[2]); + for (y = sds->res_min[1]; y < sds->res_max[1]; y++) { + int index = smoke_get_index(x - sds->res_min[0], sds->res[0], y - sds->res_min[1], sds->res[1], z - sds->res_min[2]); - float ray_start[3] = {(float)x + 0.5f, (float)y + 0.5f, (float)z + 0.5f}; - BVHTreeNearest nearest = {0}; - nearest.index = -1; - nearest.dist = surface_distance * surface_distance; /* find_nearest uses squared distance */ + float ray_start[3] = {(float)x + 0.5f, (float)y + 0.5f, (float)z + 0.5f}; + BVHTreeNearest nearest = {0}; + nearest.index = -1; + nearest.dist = surface_distance * surface_distance; /* find_nearest uses squared distance */ - /* find the nearest point on the mesh */ - if (BLI_bvhtree_find_nearest(treeData.tree, ray_start, &nearest, treeData.nearest_callback, &treeData) != -1) { - float weights[4]; - int v1, v2, v3, f_index = nearest.index; + /* find the nearest point on the mesh */ + if (BLI_bvhtree_find_nearest(treeData.tree, ray_start, &nearest, treeData.nearest_callback, &treeData) != -1) { + float weights[4]; + int v1, v2, v3, f_index = nearest.index; - /* calculate barycentric weights for nearest point */ - v1 = mface[f_index].v1; - v2 = (nearest.flags & BVH_ONQUAD) ? mface[f_index].v3 : mface[f_index].v2; - v3 = (nearest.flags & BVH_ONQUAD) ? mface[f_index].v4 : mface[f_index].v3; - interp_weights_face_v3(weights, mvert[v1].co, mvert[v2].co, mvert[v3].co, NULL, nearest.co); + /* calculate barycentric weights for nearest point */ + v1 = mface[f_index].v1; + v2 = (nearest.flags & BVH_ONQUAD) ? mface[f_index].v3 : mface[f_index].v2; + v3 = (nearest.flags & BVH_ONQUAD) ? mface[f_index].v4 : mface[f_index].v3; + interp_weights_face_v3(weights, mvert[v1].co, mvert[v2].co, mvert[v3].co, NULL, nearest.co); - // DG TODO - if(has_velocity) - { - /* apply object velocity */ + // DG TODO + if (has_velocity) { - float hit_vel[3]; - interp_v3_v3v3v3(hit_vel, &vert_vel[v1*3], &vert_vel[v2*3], &vert_vel[v3*3], weights); - velocityX[index] += hit_vel[0]; - velocityY[index] += hit_vel[1]; - velocityZ[index] += hit_vel[2]; + /* apply object velocity */ + { + float hit_vel[3]; + interp_v3_v3v3v3(hit_vel, &vert_vel[v1 * 3], &vert_vel[v2 * 3], &vert_vel[v3 * 3], weights); + velocityX[index] += hit_vel[0]; + velocityY[index] += hit_vel[1]; + velocityZ[index] += hit_vel[2]; + } } + + /* tag obstacle cells */ + obstacle_map[index] = 1; + + if (has_velocity) + obstacle_map[index] |= 8; } - - /* tag obstacle cells */ - obstacle_map[index] = 1; - - if(has_velocity) - obstacle_map[index] |= 8; } - } } } /* free bvh tree */ @@ -823,9 +823,9 @@ static void update_obstacles(Scene *scene, Object *ob, SmokeDomainSettings *sds, smoke_get_ob_velocity(sds->fluid, &velx, &vely, &velz); // TODO: delete old obstacle flags - for(z = 0; z < sds->res[0] * sds->res[1] * sds->res[2]; z++) + for (z = 0; z < sds->res[0] * sds->res[1] * sds->res[2]; z++) { - if(obstacles[z] & 8) // Do not delete static obstacles + if (obstacles[z] & 8) // Do not delete static obstacles { obstacles[z] = 0; } @@ -839,27 +839,27 @@ static void update_obstacles(Scene *scene, Object *ob, SmokeDomainSettings *sds, collobjs = get_collisionobjects(scene, ob, sds->coll_group, &numcollobj, eModifierType_Smoke); // update obstacle tags in cells - for(collIndex = 0; collIndex < numcollobj; collIndex++) + for (collIndex = 0; collIndex < numcollobj; collIndex++) { - Object *collob= collobjs[collIndex]; - SmokeModifierData *smd2 = (SmokeModifierData*)modifiers_findByType(collob, eModifierType_Smoke); + Object *collob = collobjs[collIndex]; + SmokeModifierData *smd2 = (SmokeModifierData *)modifiers_findByType(collob, eModifierType_Smoke); // DG TODO: check if modifier is active? - - if((smd2->type & MOD_SMOKE_TYPE_COLL) && smd2->coll) + + if ((smd2->type & MOD_SMOKE_TYPE_COLL) && smd2->coll) { SmokeCollSettings *scs = smd2->coll; obstacles_from_derivedmesh(collob, sds, scs, obstacles, velx, vely, velz, dt); } } - if(collobjs) + if (collobjs) MEM_freeN(collobjs); /* obstacle cells should not contain any velocity from the smoke simulation */ - for(z = 0; z < sds->res[0] * sds->res[1] * sds->res[2]; z++) + for (z = 0; z < sds->res[0] * sds->res[1] * sds->res[2]; z++) { - if(obstacles[z]) + if (obstacles[z]) { velxOrig[z] = 0; velyOrig[z] = 0; @@ -905,35 +905,35 @@ static void em_boundInsert(EmissionMap *em, float point[3]) static void clampBoundsInDomain(SmokeDomainSettings *sds, int min[3], int max[3], float *min_vel, float *max_vel, int margin, float dt) { int i; - for (i=0; i<3; i++) { + for (i = 0; i < 3; i++) { int adapt = (sds->flags & MOD_SMOKE_ADAPTIVE_DOMAIN) ? sds->adapt_res : 0; /* add margin */ min[i] -= margin; max[i] += margin; /* adapt to velocity */ - if (min_vel && min_vel[i]<0.0f) { + if (min_vel && min_vel[i] < 0.0f) { min[i] += (int)ceil(min_vel[i] * dt); } - if (max_vel && max_vel[i]>0.0f) { + if (max_vel && max_vel[i] > 0.0f) { max[i] += (int)ceil(max_vel[i] * dt); } /* clamp within domain max size */ - CLAMP(min[i], -adapt, sds->base_res[i]+adapt); - CLAMP(max[i], -adapt, sds->base_res[i]+adapt); + CLAMP(min[i], -adapt, sds->base_res[i] + adapt); + CLAMP(max[i], -adapt, sds->base_res[i] + adapt); } } static void em_allocateData(EmissionMap *em, int use_velocity) { int i, res[3]; - for (i=0; i<3; i++) { + for (i = 0; i < 3; i++) { res[i] = em->max[i] - em->min[i]; if (res[i] <= 0) return; } - em->total_cells = res[0]*res[1]*res[2]; + em->total_cells = res[0] * res[1] * res[2]; copy_v3_v3_int(em->res, res); @@ -952,13 +952,13 @@ static void em_freeData(EmissionMap *em) { static void emit_from_particles(Object *flow_ob, SmokeDomainSettings *sds, SmokeFlowSettings *sfs, EmissionMap *em, Scene *scene, float time, float dt) { - if(sfs && sfs->psys && sfs->psys->part && sfs->psys->part->type==PART_EMITTER) // is particle system selected + if (sfs && sfs->psys && sfs->psys->part && sfs->psys->part->type == PART_EMITTER) // is particle system selected { ParticleSimulationData sim; ParticleSystem *psys = sfs->psys; float *particle_pos; float *particle_vel; - int totpart=psys->totpart, totchild; + int totpart = psys->totpart, totchild; int p = 0; int valid_particles = 0; @@ -966,45 +966,45 @@ static void emit_from_particles(Object *flow_ob, SmokeDomainSettings *sds, Smoke sim.ob = flow_ob; sim.psys = psys; - if(psys->part->type==PART_HAIR) + if (psys->part->type == PART_HAIR) { // TODO: PART_HAIR not supported whatsoever - totchild=0; + totchild = 0; } else - totchild=psys->totchild*psys->part->disp/100; + totchild = psys->totchild * psys->part->disp / 100; - particle_pos = MEM_callocN(sizeof(float) * (totpart+totchild) * 3, "smoke_flow_particles"); - particle_vel = MEM_callocN(sizeof(float) * (totpart+totchild) * 3, "smoke_flow_particles"); + particle_pos = MEM_callocN(sizeof(float) * (totpart + totchild) * 3, "smoke_flow_particles"); + particle_vel = MEM_callocN(sizeof(float) * (totpart + totchild) * 3, "smoke_flow_particles"); /* calculate local position for each particle */ - for(p=0; pparticles[p].flag & (PARS_NO_DISP|PARS_UNEXIST)) + if (p < totpart) { + if (psys->particles[p].flag & (PARS_NO_DISP | PARS_UNEXIST)) continue; } else { /* handle child particle */ ChildParticle *cpa = &psys->child[p - totpart]; - if(psys->particles[cpa->parent].flag & (PARS_NO_DISP|PARS_UNEXIST)) + if (psys->particles[cpa->parent].flag & (PARS_NO_DISP | PARS_UNEXIST)) continue; } state.time = time; - if(psys_get_particle_state(&sim, p, &state, 0) == 0) + if (psys_get_particle_state(&sim, p, &state, 0) == 0) continue; /* location */ - pos = &particle_pos[valid_particles*3]; + pos = &particle_pos[valid_particles * 3]; copy_v3_v3(pos, state.co); smoke_pos_to_cell(sds, pos); /* velocity */ - copy_v3_v3(&particle_vel[valid_particles*3], state.vel); - mul_mat3_m4_v3(sds->imat, &particle_vel[valid_particles*3]); + copy_v3_v3(&particle_vel[valid_particles * 3], state.vel); + mul_mat3_m4_v3(sds->imat, &particle_vel[valid_particles * 3]); /* calculate emission map bounds */ em_boundInsert(em, pos); @@ -1015,7 +1015,7 @@ static void emit_from_particles(Object *flow_ob, SmokeDomainSettings *sds, Smoke clampBoundsInDomain(sds, em->min, em->max, NULL, NULL, 1, dt); em_allocateData(em, sfs->flags & MOD_SMOKE_FLOW_INITVELOCITY); - for(p=0; pmin[0]; - cell[1] = floor(particle_pos[p*3+1]) - em->min[1]; - cell[2] = floor(particle_pos[p*3+2]) - em->min[2]; + cell[0] = floor(particle_pos[p * 3]) - em->min[0]; + cell[1] = floor(particle_pos[p * 3 + 1]) - em->min[1]; + cell[2] = floor(particle_pos[p * 3 + 2]) - em->min[2]; /* check if cell is valid (in the domain boundary) */ - for(i = 0; i < 3; i++) { - if((cell[i] > em->res[i] - 1) || (cell[i] < 0)) { + for (i = 0; i < 3; i++) { + if ((cell[i] > em->res[i] - 1) || (cell[i] < 0)) { badcell = 1; break; } } - if(badcell) + if (badcell) continue; /* get cell index */ index = smoke_get_index(cell[0], em->res[0], cell[1], em->res[1], cell[2]); /* Add influence to emission map */ em->influence[index] = 1.0f; /* Uses particle velocity as initial velocity for smoke */ - if(sfs->flags & MOD_SMOKE_FLOW_INITVELOCITY && (psys->part->phystype != PART_PHYS_NO)) + if (sfs->flags & MOD_SMOKE_FLOW_INITVELOCITY && (psys->part->phystype != PART_PHYS_NO)) { - VECADDFAC(&em->velocity[index*3], &em->velocity[index*3], &particle_vel[p*3], sfs->vel_multi); + VECADDFAC(&em->velocity[index * 3], &em->velocity[index * 3], &particle_vel[p * 3], sfs->vel_multi); } - } // particles loop + } // particles loop /* free data */ if (particle_pos) @@ -1078,7 +1078,7 @@ static void emit_from_derivedmesh(Object *flow_ob, SmokeDomainSettings *sds, Smo if (!sfs->dm) return; { DerivedMesh *dm = sfs->dm; - int defgrp_index = sfs->vgroup_density-1; + int defgrp_index = sfs->vgroup_density - 1; MDeformVert *dvert = NULL; MVert *mvert = NULL; MVert *mvert_orig = NULL; @@ -1093,7 +1093,7 @@ static void emit_from_derivedmesh(Object *flow_ob, SmokeDomainSettings *sds, Smo CDDM_calc_normals(dm); mvert = dm->getVertArray(dm); - mvert_orig = dm->dupVertArray(dm); /* copy original mvert and restore when done */ + mvert_orig = dm->dupVertArray(dm); /* copy original mvert and restore when done */ mface = dm->getTessFaceArray(dm); numOfVerts = dm->getNumVerts(dm); dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT); @@ -1113,7 +1113,7 @@ static void emit_from_derivedmesh(Object *flow_ob, SmokeDomainSettings *sds, Smo } /* Transform dm vertices to - * domain grid space for fast lookups */ + * domain grid space for fast lookups */ for (i = 0; i < numOfVerts; i++) { float n[3]; /* vert pos */ @@ -1130,10 +1130,10 @@ static void emit_from_derivedmesh(Object *flow_ob, SmokeDomainSettings *sds, Smo float co[3]; VECADD(co, mvert[i].co, sds->shift); if (has_velocity) { - sub_v3_v3v3(&vert_vel[i*3], co, &sfs->verts_old[i*3]); - mul_v3_fl(&vert_vel[i*3], sds->dx/dt); + sub_v3_v3v3(&vert_vel[i * 3], co, &sfs->verts_old[i * 3]); + mul_v3_fl(&vert_vel[i * 3], sds->dx / dt); } - copy_v3_v3(&sfs->verts_old[i*3], co); + copy_v3_v3(&sfs->verts_old[i * 3], co); } /* calculate emission map bounds */ @@ -1149,135 +1149,135 @@ static void emit_from_derivedmesh(Object *flow_ob, SmokeDomainSettings *sds, Smo if (bvhtree_from_mesh_faces(&treeData, dm, 0.0f, 4, 6)) { #pragma omp parallel for schedule(static) for (z = em->min[2]; z < em->max[2]; z++) { - int x,y; + int x, y; for (x = em->min[0]; x < em->max[0]; x++) - for (y = em->min[1]; y < em->max[1]; y++) { - int index = smoke_get_index(x-em->min[0], em->res[0], y-em->min[1], em->res[1], z-em->min[2]); + for (y = em->min[1]; y < em->max[1]; y++) { + int index = smoke_get_index(x - em->min[0], em->res[0], y - em->min[1], em->res[1], z - em->min[2]); - float ray_start[3] = {(float)x + 0.5f, (float)y + 0.5f, (float)z + 0.5f}; - float ray_dir[3] = {1.0f, 0.0f, 0.0f}; + float ray_start[3] = {(float)x + 0.5f, (float)y + 0.5f, (float)z + 0.5f}; + float ray_dir[3] = {1.0f, 0.0f, 0.0f}; - BVHTreeRayHit hit = {0}; - BVHTreeNearest nearest = {0}; + BVHTreeRayHit hit = {0}; + BVHTreeNearest nearest = {0}; - float volume_factor = 0.0f; - float sample_str = 0.0f; + float volume_factor = 0.0f; + float sample_str = 0.0f; - hit.index = -1; - hit.dist = 9999; - nearest.index = -1; - nearest.dist = sfs->surface_distance * sfs->surface_distance; /* find_nearest uses squared distance */ + hit.index = -1; + hit.dist = 9999; + nearest.index = -1; + nearest.dist = sfs->surface_distance * sfs->surface_distance; /* find_nearest uses squared distance */ - /* Check volume collision */ - if (sfs->volume_density) { - if (BLI_bvhtree_ray_cast(treeData.tree, ray_start, ray_dir, 0.0f, &hit, treeData.raycast_callback, &treeData) != -1) { - float dot = ray_dir[0] * hit.no[0] + ray_dir[1] * hit.no[1] + ray_dir[2] * hit.no[2]; - /* If ray and hit face normal are facing same direction - * hit point is inside a closed mesh. */ - if (dot >= 0) { - /* Also cast a ray in opposite direction to make sure - * point is at least surrounded by two faces */ - negate_v3(ray_dir); - hit.index = -1; - hit.dist = 9999; + /* Check volume collision */ + if (sfs->volume_density) { + if (BLI_bvhtree_ray_cast(treeData.tree, ray_start, ray_dir, 0.0f, &hit, treeData.raycast_callback, &treeData) != -1) { + float dot = ray_dir[0] * hit.no[0] + ray_dir[1] * hit.no[1] + ray_dir[2] * hit.no[2]; + /* If ray and hit face normal are facing same direction + * hit point is inside a closed mesh. */ + if (dot >= 0) { + /* Also cast a ray in opposite direction to make sure + * point is at least surrounded by two faces */ + negate_v3(ray_dir); + hit.index = -1; + hit.dist = 9999; - BLI_bvhtree_ray_cast(treeData.tree, ray_start, ray_dir, 0.0f, &hit, treeData.raycast_callback, &treeData); - if (hit.index != -1) { - volume_factor = sfs->volume_density; - nearest.dist = hit.dist*hit.dist; + BLI_bvhtree_ray_cast(treeData.tree, ray_start, ray_dir, 0.0f, &hit, treeData.raycast_callback, &treeData); + if (hit.index != -1) { + volume_factor = sfs->volume_density; + nearest.dist = hit.dist * hit.dist; + } } } } + + /* find the nearest point on the mesh */ + if (BLI_bvhtree_find_nearest(treeData.tree, ray_start, &nearest, treeData.nearest_callback, &treeData) != -1) { + float weights[4]; + int v1, v2, v3, f_index = nearest.index; + float n1[3], n2[3], n3[3], hit_normal[3]; + + /* emit from surface based on distance */ + if (sfs->surface_distance) { + sample_str = sqrtf(nearest.dist) / sfs->surface_distance; + CLAMP(sample_str, 0.0f, 1.0f); + sample_str = pow(1.0f - sample_str, 0.5f); + } + else + sample_str = 0.0f; + + /* calculate barycentric weights for nearest point */ + v1 = mface[f_index].v1; + v2 = (nearest.flags & BVH_ONQUAD) ? mface[f_index].v3 : mface[f_index].v2; + v3 = (nearest.flags & BVH_ONQUAD) ? mface[f_index].v4 : mface[f_index].v3; + interp_weights_face_v3(weights, mvert[v1].co, mvert[v2].co, mvert[v3].co, NULL, nearest.co); + + if (sfs->flags & MOD_SMOKE_FLOW_INITVELOCITY) { + /* apply normal directional velocity */ + if (sfs->vel_normal) { + /* interpolate vertex normal vectors to get nearest point normal */ + normal_short_to_float_v3(n1, mvert[v1].no); + normal_short_to_float_v3(n2, mvert[v2].no); + normal_short_to_float_v3(n3, mvert[v3].no); + interp_v3_v3v3v3(hit_normal, n1, n2, n3, weights); + normalize_v3(hit_normal); + /* apply normal directional and random velocity + * - TODO: random disabled for now since it doesnt really work well as pressure calc smoothens it out... */ + em->velocity[index * 3] += hit_normal[0] * sfs->vel_normal * 0.25f; + em->velocity[index * 3 + 1] += hit_normal[1] * sfs->vel_normal * 0.25f; + em->velocity[index * 3 + 2] += hit_normal[2] * sfs->vel_normal * 0.25f; + /* TODO: for fire emitted from mesh surface we can use + * Vf = Vs + (Ps/Pf - 1)*S to model gaseous expansion from solid to fuel */ + } + /* apply object velocity */ + if (has_velocity && sfs->vel_multi) { + float hit_vel[3]; + interp_v3_v3v3v3(hit_vel, &vert_vel[v1 * 3], &vert_vel[v2 * 3], &vert_vel[v3 * 3], weights); + em->velocity[index * 3] += hit_vel[0] * sfs->vel_multi; + em->velocity[index * 3 + 1] += hit_vel[1] * sfs->vel_multi; + em->velocity[index * 3 + 2] += hit_vel[2] * sfs->vel_multi; + } + } + + /* apply vertex group influence if used */ + if (defgrp_index >= 0 && dvert) { + float weight_mask = defvert_find_weight(&dvert[v1], defgrp_index) * weights[0] + + defvert_find_weight(&dvert[v2], defgrp_index) * weights[1] + + defvert_find_weight(&dvert[v3], defgrp_index) * weights[2]; + sample_str *= weight_mask; + } + + /* apply emission texture */ + if ((sfs->flags & MOD_SMOKE_FLOW_TEXTUREEMIT) && sfs->noise_texture) { + float tex_co[3] = {0}; + TexResult texres; + + if (sfs->texture_type == MOD_SMOKE_FLOW_TEXTURE_MAP_AUTO) { + tex_co[0] = ((float)(x - flow_center[0]) / sds->base_res[0]) / sfs->texture_size; + tex_co[1] = ((float)(y - flow_center[1]) / sds->base_res[1]) / sfs->texture_size; + tex_co[2] = ((float)(z - flow_center[2]) / sds->base_res[2] - sfs->texture_offset) / sfs->texture_size; + } + else if (tface) { + interp_v2_v2v2v2(tex_co, tface[f_index].uv[0], tface[f_index].uv[(nearest.flags & BVH_ONQUAD) ? 2 : 1], + tface[f_index].uv[(nearest.flags & BVH_ONQUAD) ? 3 : 2], weights); + /* map between -1.0f and 1.0f */ + tex_co[0] = tex_co[0] * 2.0f - 1.0f; + tex_co[1] = tex_co[1] * 2.0f - 1.0f; + tex_co[2] = sfs->texture_offset; + } + texres.nor = NULL; + get_texture_value(sfs->noise_texture, tex_co, &texres); + sample_str *= texres.tin; + } + } + + /* multiply initial velocity by emitter influence */ + if (sfs->flags & MOD_SMOKE_FLOW_INITVELOCITY) { + mul_v3_fl(&em->velocity[index * 3], sample_str); + } + + /* apply final influence based on volume factor */ + em->influence[index] = MAX2(volume_factor, sample_str); } - - /* find the nearest point on the mesh */ - if (BLI_bvhtree_find_nearest(treeData.tree, ray_start, &nearest, treeData.nearest_callback, &treeData) != -1) { - float weights[4]; - int v1, v2, v3, f_index = nearest.index; - float n1[3], n2[3], n3[3], hit_normal[3]; - - /* emit from surface based on distance */ - if (sfs->surface_distance) { - sample_str = sqrtf(nearest.dist) / sfs->surface_distance; - CLAMP(sample_str, 0.0f, 1.0f); - sample_str = pow(1.0f - sample_str, 0.5f); - } - else - sample_str = 0.0f; - - /* calculate barycentric weights for nearest point */ - v1 = mface[f_index].v1; - v2 = (nearest.flags & BVH_ONQUAD) ? mface[f_index].v3 : mface[f_index].v2; - v3 = (nearest.flags & BVH_ONQUAD) ? mface[f_index].v4 : mface[f_index].v3; - interp_weights_face_v3(weights, mvert[v1].co, mvert[v2].co, mvert[v3].co, NULL, nearest.co); - - if(sfs->flags & MOD_SMOKE_FLOW_INITVELOCITY) { - /* apply normal directional velocity */ - if (sfs->vel_normal) { - /* interpolate vertex normal vectors to get nearest point normal */ - normal_short_to_float_v3(n1, mvert[v1].no); - normal_short_to_float_v3(n2, mvert[v2].no); - normal_short_to_float_v3(n3, mvert[v3].no); - interp_v3_v3v3v3(hit_normal, n1, n2, n3, weights); - normalize_v3(hit_normal); - /* apply normal directional and random velocity - * - TODO: random disabled for now since it doesnt really work well as pressure calc smoothens it out... */ - em->velocity[index*3] += hit_normal[0]*sfs->vel_normal * 0.25f; - em->velocity[index*3+1] += hit_normal[1]*sfs->vel_normal * 0.25f; - em->velocity[index*3+2] += hit_normal[2]*sfs->vel_normal * 0.25f; - /* TODO: for fire emitted from mesh surface we can use - * Vf = Vs + (Ps/Pf - 1)*S to model gaseous expansion from solid to fuel */ - } - /* apply object velocity */ - if (has_velocity && sfs->vel_multi) { - float hit_vel[3]; - interp_v3_v3v3v3(hit_vel, &vert_vel[v1*3], &vert_vel[v2*3], &vert_vel[v3*3], weights); - em->velocity[index*3] += hit_vel[0] * sfs->vel_multi; - em->velocity[index*3+1] += hit_vel[1] * sfs->vel_multi; - em->velocity[index*3+2] += hit_vel[2] * sfs->vel_multi; - } - } - - /* apply vertex group influence if used */ - if (defgrp_index >= 0 && dvert) { - float weight_mask = defvert_find_weight(&dvert[v1], defgrp_index) * weights[0] + - defvert_find_weight(&dvert[v2], defgrp_index) * weights[1] + - defvert_find_weight(&dvert[v3], defgrp_index) * weights[2]; - sample_str *= weight_mask; - } - - /* apply emission texture */ - if ((sfs->flags & MOD_SMOKE_FLOW_TEXTUREEMIT) && sfs->noise_texture) { - float tex_co[3] = {0}; - TexResult texres; - - if (sfs->texture_type == MOD_SMOKE_FLOW_TEXTURE_MAP_AUTO) { - tex_co[0] = ((float)(x - flow_center[0]) / sds->base_res[0]) / sfs->texture_size; - tex_co[1] = ((float)(y - flow_center[1]) / sds->base_res[1]) / sfs->texture_size; - tex_co[2] = ((float)(z - flow_center[2]) / sds->base_res[2] - sfs->texture_offset) / sfs->texture_size; - } - else if (tface) { - interp_v2_v2v2v2(tex_co, tface[f_index].uv[0], tface[f_index].uv[(nearest.flags & BVH_ONQUAD) ? 2 : 1], - tface[f_index].uv[(nearest.flags & BVH_ONQUAD) ? 3 : 2], weights); - /* map between -1.0f and 1.0f */ - tex_co[0] = tex_co[0] * 2.0f - 1.0f; - tex_co[1] = tex_co[1] * 2.0f - 1.0f; - tex_co[2] = sfs->texture_offset; - } - texres.nor = NULL; - get_texture_value(sfs->noise_texture, tex_co, &texres); - sample_str *= texres.tin; - } - } - - /* multiply initial velocity by emitter influence */ - if(sfs->flags & MOD_SMOKE_FLOW_INITVELOCITY) { - mul_v3_fl(&em->velocity[index*3], sample_str); - } - - /* apply final influence based on volume factor */ - em->influence[index] = MAX2(volume_factor, sample_str); - } } } /* free bvh tree */ @@ -1293,10 +1293,10 @@ static void emit_from_derivedmesh(Object *flow_ob, SmokeDomainSettings *sds, Smo static void adjustDomainResolution(SmokeDomainSettings *sds, int new_shift[3], EmissionMap *emaps, unsigned int numflowobj, float dt) { - int min[3]={32767,32767,32767}, max[3]={-32767,-32767,-32767}, res[3]; + int min[3] = {32767, 32767, 32767}, max[3] = {-32767, -32767, -32767}, res[3]; int total_cells = 1, res_changed = 0, shift_changed = 0; float min_vel[3], max_vel[3]; - int x,y,z, i; + int x, y, z, i; float *density = smoke_get_density(sds->fluid); float *fuel = smoke_get_fuel(sds->fluid); float *vx = smoke_get_velocity_x(sds->fluid); @@ -1306,14 +1306,14 @@ static void adjustDomainResolution(SmokeDomainSettings *sds, int new_shift[3], E INIT_MINMAX(min_vel, max_vel); /* Calculate bounds for current domain content */ - for(x = sds->res_min[0]; x < sds->res_max[0]; x++) - for(y = sds->res_min[1]; y < sds->res_max[1]; y++) - for(z = sds->res_min[2]; z < sds->res_max[2]; z++) + for (x = sds->res_min[0]; x < sds->res_max[0]; x++) + for (y = sds->res_min[1]; y < sds->res_max[1]; y++) + for (z = sds->res_min[2]; z < sds->res_max[2]; z++) { - int xn = x-new_shift[0]; - int yn = y-new_shift[1]; - int zn = z-new_shift[2]; - int index = smoke_get_index(x-sds->res_min[0], sds->res[0], y-sds->res_min[1], sds->res[1], z-sds->res_min[2]); + int xn = x - new_shift[0]; + int yn = y - new_shift[1]; + int zn = z - new_shift[2]; + int index = smoke_get_index(x - sds->res_min[0], sds->res[0], y - sds->res_min[1], sds->res[1], z - sds->res_min[2]); float max_den = (fuel) ? MAX2(density[index], fuel[index]) : density[index]; /* content bounds (use shifted coordinates) */ @@ -1335,15 +1335,15 @@ static void adjustDomainResolution(SmokeDomainSettings *sds, int new_shift[3], E } /* also apply emission maps */ - for(i = 0; i < numflowobj; i++) + for (i = 0; i < numflowobj; i++) { EmissionMap *em = &emaps[i]; - for(x = em->min[0]; x < em->max[0]; x++) - for(y = em->min[1]; y < em->max[1]; y++) - for(z = em->min[2]; z < em->max[2]; z++) + for (x = em->min[0]; x < em->max[0]; x++) + for (y = em->min[1]; y < em->max[1]; y++) + for (z = em->min[2]; z < em->max[2]; z++) { - int index = smoke_get_index(x-em->min[0], em->res[0], y-em->min[1], em->res[1], z-em->min[2]); + int index = smoke_get_index(x - em->min[0], em->res[0], y - em->min[1], em->res[1], z - em->min[2]); float max_den = em->influence[index]; /* density bounds */ @@ -1357,20 +1357,20 @@ static void adjustDomainResolution(SmokeDomainSettings *sds, int new_shift[3], E } /* velocity bounds */ if (em->velocity) { - if (min_vel[0] > em->velocity[index*3]) min_vel[0] = em->velocity[index*3]; - if (min_vel[1] > em->velocity[index*3+1]) min_vel[1] = em->velocity[index*3+1]; - if (min_vel[2] > em->velocity[index*3+2]) min_vel[2] = em->velocity[index*3+2]; - if (max_vel[0] < em->velocity[index*3]) max_vel[0] = em->velocity[index*3]; - if (max_vel[1] < em->velocity[index*3+1]) max_vel[1] = em->velocity[index*3+1]; - if (max_vel[2] < em->velocity[index*3+2]) max_vel[2] = em->velocity[index*3+2]; + if (min_vel[0] > em->velocity[index * 3]) min_vel[0] = em->velocity[index * 3]; + if (min_vel[1] > em->velocity[index * 3 + 1]) min_vel[1] = em->velocity[index * 3 + 1]; + if (min_vel[2] > em->velocity[index * 3 + 2]) min_vel[2] = em->velocity[index * 3 + 2]; + if (max_vel[0] < em->velocity[index * 3]) max_vel[0] = em->velocity[index * 3]; + if (max_vel[1] < em->velocity[index * 3 + 1]) max_vel[1] = em->velocity[index * 3 + 1]; + if (max_vel[2] < em->velocity[index * 3 + 2]) max_vel[2] = em->velocity[index * 3 + 2]; } } } /* calculate new bounds based on these values */ - clampBoundsInDomain(sds, min, max, min_vel, max_vel, sds->adapt_margin+1, dt); + clampBoundsInDomain(sds, min, max, min_vel, max_vel, sds->adapt_margin + 1, dt); - for (i=0; i<3; i++) { + for (i = 0; i < 3; i++) { /* calculate new resolution */ res[i] = max[i] - min[i]; total_cells *= res[i]; @@ -1381,7 +1381,7 @@ static void adjustDomainResolution(SmokeDomainSettings *sds, int new_shift[3], E /* if no content set minimum dimensions */ if (res[i] <= 0) { int j; - for (j=0; j<3; j++) { + for (j = 0; j < 3; j++) { min[j] = 0; max[j] = 1; res[j] = 1; @@ -1399,12 +1399,12 @@ static void adjustDomainResolution(SmokeDomainSettings *sds, int new_shift[3], E struct WTURBULENCE *turb_old = sds->wt; /* allocate new fluid data */ smoke_reallocate_fluid(sds, sds->dx, res, 0); - if(sds->flags & MOD_SMOKE_HIGHRES) { + if (sds->flags & MOD_SMOKE_HIGHRES) { smoke_reallocate_highres_fluid(sds, sds->dx, res, 0); } /* copy values from old fluid to new */ - if (sds->total_cells>1 && total_cells>1) { + if (sds->total_cells > 1 && total_cells > 1) { /* low res smoke */ float *o_dens, *o_react, *o_flame, *o_fuel, *o_heat, *o_heatold, *o_vx, *o_vy, *o_vz, *o_r, *o_g, *o_b; float *n_dens, *n_react, *n_flame, *n_fuel, *n_heat, *n_heatold, *n_vx, *n_vy, *n_vz, *n_r, *n_g, *n_b; @@ -1418,32 +1418,32 @@ static void adjustDomainResolution(SmokeDomainSettings *sds, int new_shift[3], E smoke_export(fluid_old, &dummy, &dummy, &o_dens, &o_react, &o_flame, &o_fuel, &o_heat, &o_heatold, &o_vx, &o_vy, &o_vz, &o_r, &o_g, &o_b, &dummy_p); smoke_export(sds->fluid, &dummy, &dummy, &n_dens, &n_react, &n_flame, &n_fuel, &n_heat, &n_heatold, &n_vx, &n_vy, &n_vz, &n_r, &n_g, &n_b, &dummy_p); - if(sds->flags & MOD_SMOKE_HIGHRES) { + if (sds->flags & MOD_SMOKE_HIGHRES) { smoke_turbulence_export(turb_old, &o_wt_dens, &o_wt_react, &o_wt_flame, &o_wt_fuel, &o_wt_r, &o_wt_g, &o_wt_b, &o_wt_tcu, &o_wt_tcv, &o_wt_tcw); smoke_turbulence_get_res(turb_old, wt_res_old); smoke_turbulence_export(sds->wt, &n_wt_dens, &n_wt_react, &n_wt_flame, &n_wt_fuel, &n_wt_r, &n_wt_g, &n_wt_b, &n_wt_tcu, &n_wt_tcv, &n_wt_tcw); } - for(x = sds->res_min[0]; x < sds->res_max[0]; x++) - for(y = sds->res_min[1]; y < sds->res_max[1]; y++) - for(z = sds->res_min[2]; z < sds->res_max[2]; z++) + for (x = sds->res_min[0]; x < sds->res_max[0]; x++) + for (y = sds->res_min[1]; y < sds->res_max[1]; y++) + for (z = sds->res_min[2]; z < sds->res_max[2]; z++) { /* old grid index */ - int xo = x-sds->res_min[0]; - int yo = y-sds->res_min[1]; - int zo = z-sds->res_min[2]; + int xo = x - sds->res_min[0]; + int yo = y - sds->res_min[1]; + int zo = z - sds->res_min[2]; int index_old = smoke_get_index(xo, sds->res[0], yo, sds->res[1], zo); /* new grid index */ - int xn = x-min[0]-new_shift[0]; - int yn = y-min[1]-new_shift[1]; - int zn = z-min[2]-new_shift[2]; + int xn = x - min[0] - new_shift[0]; + int yn = y - min[1] - new_shift[1]; + int zn = z - min[2] - new_shift[2]; int index_new = smoke_get_index(xn, res[0], yn, res[1], zn); /* skip if outside new domain */ - if (xn<0 || xn>=res[0] || - yn<0 || yn>=res[1] || - zn<0 || zn>=res[2]) + if (xn < 0 || xn >= res[0] || + yn < 0 || yn >= res[1] || + zn < 0 || zn >= res[2]) continue; /* copy data */ @@ -1469,28 +1469,28 @@ static void adjustDomainResolution(SmokeDomainSettings *sds, int new_shift[3], E n_vy[index_new] = o_vy[index_old]; n_vz[index_new] = o_vz[index_old]; - if(sds->flags & MOD_SMOKE_HIGHRES && turb_old) { + if (sds->flags & MOD_SMOKE_HIGHRES && turb_old) { int block_size = sds->amplify + 1; - int i,j,k; + int i, j, k; /* old grid index */ - int xx_o = xo*block_size; - int yy_o = yo*block_size; - int zz_o = zo*block_size; + int xx_o = xo * block_size; + int yy_o = yo * block_size; + int zz_o = zo * block_size; /* new grid index */ - int xx_n = xn*block_size; - int yy_n = yn*block_size; - int zz_n = zn*block_size; + int xx_n = xn * block_size; + int yy_n = yn * block_size; + int zz_n = zn * block_size; n_wt_tcu[index_new] = o_wt_tcu[index_old]; n_wt_tcv[index_new] = o_wt_tcv[index_old]; n_wt_tcw[index_new] = o_wt_tcw[index_old]; - for(i = 0; i < block_size; i++) - for(j = 0; j < block_size; j++) - for(k = 0; k < block_size; k++) + for (i = 0; i < block_size; i++) + for (j = 0; j < block_size; j++) + for (k = 0; k < block_size; k++) { - int big_index_old = smoke_get_index(xx_o+i, wt_res_old[0], yy_o+j, wt_res_old[1], zz_o+k); - int big_index_new = smoke_get_index(xx_n+i, sds->res_wt[0], yy_n+j, sds->res_wt[1], zz_n+k); + int big_index_old = smoke_get_index(xx_o + i, wt_res_old[0], yy_o + j, wt_res_old[1], zz_o + k); + int big_index_new = smoke_get_index(xx_n + i, sds->res_wt[0], yy_n + j, sds->res_wt[1], zz_n + k); /* copy data */ n_wt_dens[big_index_new] = o_wt_dens[big_index_old]; if (n_wt_flame && o_wt_flame) { @@ -1545,7 +1545,7 @@ BLI_INLINE void apply_inflow_fields(SmokeFlowSettings *sfs, float emission_value float fuel_flow = emission_value * sfs->fuel_amount; /* add heat */ if (heat) { - heat[index] = MAX2(emission_value*sfs->temp, heat[index]); + heat[index] = MAX2(emission_value * sfs->temp, heat[index]); } /* absolute */ if (absolute_flow) { @@ -1572,7 +1572,7 @@ BLI_INLINE void apply_inflow_fields(SmokeFlowSettings *sfs, float emission_value /* set color */ if (color_r && dens_flow) { - float total_dens = density[index]/(dens_old+dens_flow); + float total_dens = density[index] / (dens_old + dens_flow); color_r[index] = (color_r[index] + sfs->color[0] * dens_flow) * total_dens; color_g[index] = (color_g[index] + sfs->color[1] * dens_flow) * total_dens; color_b[index] = (color_b[index] + sfs->color[2] * dens_flow) * total_dens; @@ -1586,7 +1586,7 @@ BLI_INLINE void apply_inflow_fields(SmokeFlowSettings *sfs, float emission_value if (value > react[index]) { float f = fuel_flow / fuel[index]; - react[index] = value*f + (1.0f - f)*react[index]; + react[index] = value * f + (1.0f - f) * react[index]; } } } @@ -1612,9 +1612,9 @@ static void update_flowsfluids(Scene *scene, Object *ob, SmokeDomainSettings *sd copy_v3_v3(sds->prev_loc, ob_loc); /* convert global space shift to local "cell" space */ mul_mat3_m4_v3(sds->imat, frame_shift_f); - frame_shift_f[0] = frame_shift_f[0]/sds->cell_size[0]; - frame_shift_f[1] = frame_shift_f[1]/sds->cell_size[1]; - frame_shift_f[2] = frame_shift_f[2]/sds->cell_size[2]; + frame_shift_f[0] = frame_shift_f[0] / sds->cell_size[0]; + frame_shift_f[1] = frame_shift_f[1] / sds->cell_size[1]; + frame_shift_f[2] = frame_shift_f[2] / sds->cell_size[2]; /* add to total shift */ VECADD(sds->shift_f, sds->shift_f, frame_shift_f); /* convert to integer */ @@ -1625,12 +1625,12 @@ static void update_flowsfluids(Scene *scene, Object *ob, SmokeDomainSettings *sd copy_v3_v3_int(sds->shift, total_shift); /* calculate new domain boundary points so that smoke doesnt slide on sub-cell movement */ - sds->p0[0] = sds->dp0[0] - sds->cell_size[0]*(sds->shift_f[0]-total_shift[0] - 0.5f); - sds->p0[1] = sds->dp0[1] - sds->cell_size[1]*(sds->shift_f[1]-total_shift[1] - 0.5f); - sds->p0[2] = sds->dp0[2] - sds->cell_size[2]*(sds->shift_f[2]-total_shift[2] - 0.5f); - sds->p1[0] = sds->p0[0] + sds->cell_size[0]*sds->base_res[0]; - sds->p1[1] = sds->p0[1] + sds->cell_size[1]*sds->base_res[1]; - sds->p1[2] = sds->p0[2] + sds->cell_size[2]*sds->base_res[2]; + sds->p0[0] = sds->dp0[0] - sds->cell_size[0] * (sds->shift_f[0] - total_shift[0] - 0.5f); + sds->p0[1] = sds->dp0[1] - sds->cell_size[1] * (sds->shift_f[1] - total_shift[1] - 0.5f); + sds->p0[2] = sds->dp0[2] - sds->cell_size[2] * (sds->shift_f[2] - total_shift[2] - 0.5f); + sds->p1[0] = sds->p0[0] + sds->cell_size[0] * sds->base_res[0]; + sds->p1[1] = sds->p0[1] + sds->cell_size[1] * sds->base_res[1]; + sds->p1[2] = sds->p0[2] + sds->cell_size[2] * sds->base_res[2]; } flowobjs = get_collisionobjects(scene, ob, sds->fluid_group, &numflowobj, eModifierType_Smoke); @@ -1639,13 +1639,13 @@ static void update_flowsfluids(Scene *scene, Object *ob, SmokeDomainSettings *sd emaps = MEM_callocN(sizeof(struct EmissionMap) * numflowobj, "smoke_flow_maps"); /* Prepare flow emission maps */ - for(flowIndex = 0; flowIndex < numflowobj; flowIndex++) + for (flowIndex = 0; flowIndex < numflowobj; flowIndex++) { - Object *collob= flowobjs[flowIndex]; - SmokeModifierData *smd2 = (SmokeModifierData*)modifiers_findByType(collob, eModifierType_Smoke); + Object *collob = flowobjs[flowIndex]; + SmokeModifierData *smd2 = (SmokeModifierData *)modifiers_findByType(collob, eModifierType_Smoke); // check for initialized smoke object - if((smd2->type & MOD_SMOKE_TYPE_FLOW) && smd2->flow) + if ((smd2->type & MOD_SMOKE_TYPE_FLOW) && smd2->flow) { // we got nice flow object SmokeFlowSettings *sfs = smd2->flow; @@ -1717,18 +1717,18 @@ static void update_flowsfluids(Scene *scene, Object *ob, SmokeDomainSettings *sd /* Apply emission data */ if (sds->fluid) { - for(flowIndex = 0; flowIndex < numflowobj; flowIndex++) + for (flowIndex = 0; flowIndex < numflowobj; flowIndex++) { - Object *collob= flowobjs[flowIndex]; - SmokeModifierData *smd2 = (SmokeModifierData*)modifiers_findByType(collob, eModifierType_Smoke); + Object *collob = flowobjs[flowIndex]; + SmokeModifierData *smd2 = (SmokeModifierData *)modifiers_findByType(collob, eModifierType_Smoke); // check for initialized smoke object - if((smd2->type & MOD_SMOKE_TYPE_FLOW) && smd2->flow) + if ((smd2->type & MOD_SMOKE_TYPE_FLOW) && smd2->flow) { // we got nice flow object SmokeFlowSettings *sfs = smd2->flow; EmissionMap *em = &emaps[flowIndex]; - + float *density = smoke_get_density(sds->fluid); float *color_r = smoke_get_color_r(sds->fluid); float *color_g = smoke_get_color_g(sds->fluid); @@ -1745,7 +1745,7 @@ static void update_flowsfluids(Scene *scene, Object *ob, SmokeDomainSettings *sd float *velocity_x = smoke_get_velocity_x(sds->fluid); float *velocity_y = smoke_get_velocity_y(sds->fluid); float *velocity_z = smoke_get_velocity_z(sds->fluid); - //unsigned char *obstacle = smoke_get_obstacle(sds->fluid); + //unsigned char *obstacle = smoke_get_obstacle(sds->fluid); // DG TODO UNUSED unsigned char *obstacleAnim = smoke_get_obstacle_anim(sds->fluid); int bigres[3]; short high_emission_smoothing = (sds->flags & MOD_SMOKE_HIGH_SMOOTH); @@ -1756,33 +1756,33 @@ static void update_flowsfluids(Scene *scene, Object *ob, SmokeDomainSettings *sd size_t e_index, d_index, index_big; // loop through every emission map cell - for(gx = em->min[0]; gx < em->max[0]; gx++) - for(gy = em->min[1]; gy < em->max[1]; gy++) - for(gz = em->min[2]; gz < em->max[2]; gz++) + for (gx = em->min[0]; gx < em->max[0]; gx++) + for (gy = em->min[1]; gy < em->max[1]; gy++) + for (gz = em->min[2]; gz < em->max[2]; gz++) { /* get emission map index */ - ex = gx-em->min[0]; - ey = gy-em->min[1]; - ez = gz-em->min[2]; + ex = gx - em->min[0]; + ey = gy - em->min[1]; + ez = gz - em->min[2]; e_index = smoke_get_index(ex, em->res[0], ey, em->res[1], ez); if (!emission_map[e_index]) continue; /* get domain index */ - dx = gx-sds->res_min[0]; - dy = gy-sds->res_min[1]; - dz = gz-sds->res_min[2]; + dx = gx - sds->res_min[0]; + dy = gy - sds->res_min[1]; + dz = gz - sds->res_min[2]; d_index = smoke_get_index(dx, sds->res[0], dy, sds->res[1], dz); - if(sfs->type == MOD_SMOKE_FLOW_TYPE_OUTFLOW) { // outflow + if (sfs->type == MOD_SMOKE_FLOW_TYPE_OUTFLOW) { // outflow apply_outflow_fields(d_index, density, heat, fuel, react, color_r, color_g, color_b); } else { // inflow apply_inflow_fields(sfs, emission_map[e_index], d_index, density, heat, fuel, react, color_r, color_g, color_b); /* initial velocity */ - if(sfs->flags & MOD_SMOKE_FLOW_INITVELOCITY) { - velocity_x[d_index] = ADD_IF_LOWER(velocity_x[d_index], velocity_map[e_index*3]); - velocity_y[d_index] = ADD_IF_LOWER(velocity_y[d_index], velocity_map[e_index*3+1]); - velocity_z[d_index] = ADD_IF_LOWER(velocity_z[d_index], velocity_map[e_index*3+2]); + if (sfs->flags & MOD_SMOKE_FLOW_INITVELOCITY) { + velocity_x[d_index] = ADD_IF_LOWER(velocity_x[d_index], velocity_map[e_index * 3]); + velocity_y[d_index] = ADD_IF_LOWER(velocity_y[d_index], velocity_map[e_index * 3 + 1]); + velocity_z[d_index] = ADD_IF_LOWER(velocity_z[d_index], velocity_map[e_index * 3 + 2]); } } @@ -1792,64 +1792,63 @@ static void update_flowsfluids(Scene *scene, Object *ob, SmokeDomainSettings *sd float c000, c001, c010, c011, c100, c101, c110, c111; smoke_turbulence_get_res(sds->wt, bigres); - block_size = sds->amplify + 1; // high res block size + block_size = sds->amplify + 1; // high res block size - c000 = (ex>0 && ey>0 && ez>0) ? emission_map[smoke_get_index(ex-1, em->res[0], ey-1, em->res[1], ez-1)] : 0; - c001 = (ex>0 && ey>0) ? emission_map[smoke_get_index(ex-1, em->res[0], ey-1, em->res[1], ez)] : 0; - c010 = (ex>0 && ez>0) ? emission_map[smoke_get_index(ex-1, em->res[0], ey, em->res[1], ez-1)] : 0; - c011 = (ex>0) ? emission_map[smoke_get_index(ex-1, em->res[0], ey, em->res[1], ez)] : 0; + c000 = (ex > 0 && ey > 0 && ez > 0) ? emission_map[smoke_get_index(ex - 1, em->res[0], ey - 1, em->res[1], ez - 1)] : 0; + c001 = (ex > 0 && ey > 0) ? emission_map[smoke_get_index(ex - 1, em->res[0], ey - 1, em->res[1], ez)] : 0; + c010 = (ex > 0 && ez > 0) ? emission_map[smoke_get_index(ex - 1, em->res[0], ey, em->res[1], ez - 1)] : 0; + c011 = (ex > 0) ? emission_map[smoke_get_index(ex - 1, em->res[0], ey, em->res[1], ez)] : 0; - c100 = (ey>0 && ez>0) ? emission_map[smoke_get_index(ex, em->res[0], ey-1, em->res[1], ez-1)] : 0; - c101 = (ey>0) ? emission_map[smoke_get_index(ex, em->res[0], ey-1, em->res[1], ez)] : 0; - c110 = (ez>0) ? emission_map[smoke_get_index(ex, em->res[0], ey, em->res[1], ez-1)] : 0; + c100 = (ey > 0 && ez > 0) ? emission_map[smoke_get_index(ex, em->res[0], ey - 1, em->res[1], ez - 1)] : 0; + c101 = (ey > 0) ? emission_map[smoke_get_index(ex, em->res[0], ey - 1, em->res[1], ez)] : 0; + c110 = (ez > 0) ? emission_map[smoke_get_index(ex, em->res[0], ey, em->res[1], ez - 1)] : 0; c111 = emission_map[smoke_get_index(ex, em->res[0], ey, em->res[1], ez)]; // this cell - for(ii = 0; ii < block_size; ii++) - for(jj = 0; jj < block_size; jj++) - for(kk = 0; kk < block_size; kk++) + for (ii = 0; ii < block_size; ii++) + for (jj = 0; jj < block_size; jj++) + for (kk = 0; kk < block_size; kk++) { - float fx,fy,fz, interpolated_value; + float fx, fy, fz, interpolated_value; int shift_x, shift_y, shift_z; /* - * Do volume interpolation if emitter smoothing - * is enabled - */ + * Do volume interpolation if emitter smoothing + * is enabled + */ if (high_emission_smoothing) { /* get relative block position * for interpolation smoothing */ - fx = (float)ii/block_size + 0.5f/block_size; - fy = (float)jj/block_size + 0.5f/block_size; - fz = (float)kk/block_size + 0.5f/block_size; + fx = (float)ii / block_size + 0.5f / block_size; + fy = (float)jj / block_size + 0.5f / block_size; + fz = (float)kk / block_size + 0.5f / block_size; /* calculate trilinear interpolation */ - interpolated_value = c000 * (1-fx) * (1-fy) * (1-fz) + - c100 * fx * (1-fy) * (1-fz) + - c010 * (1-fx) * fy * (1-fz) + - c001 * (1-fx) * (1-fy) * fz + - c101 * fx * (1-fy) * fz + - c011 * (1-fx) * fy * fz + - c110 * fx * fy * (1-fz) + - c111 * fx * fy * fz; + interpolated_value = c000 * (1 - fx) * (1 - fy) * (1 - fz) + + c100 * fx * (1 - fy) * (1 - fz) + + c010 * (1 - fx) * fy * (1 - fz) + + c001 * (1 - fx) * (1 - fy) * fz + + c101 * fx * (1 - fy) * fz + + c011 * (1 - fx) * fy * fz + + c110 * fx * fy * (1 - fz) + + c111 * fx * fy * fz; /* add some contrast / sharpness * depending on hi-res block size */ - interpolated_value = (interpolated_value-0.4f)*(block_size/2) + 0.4f; + interpolated_value = (interpolated_value - 0.4f) * (block_size / 2) + 0.4f; CLAMP(interpolated_value, 0.0f, 1.0f); /* shift smoke block index * (because pixel center is actually * in halfway of the low res block) */ - shift_x = (dx < 1) ? 0 : block_size/2; - shift_y = (dy < 1) ? 0 : block_size/2; - shift_z = (dz < 1) ? 0 : block_size/2; + shift_x = (dx < 1) ? 0 : block_size / 2; + shift_y = (dy < 1) ? 0 : block_size / 2; + shift_z = (dz < 1) ? 0 : block_size / 2; } - else - { + else { /* without interpolation use same low resolution * block value for all hi-res blocks */ interpolated_value = c111; @@ -1859,9 +1858,9 @@ static void update_flowsfluids(Scene *scene, Object *ob, SmokeDomainSettings *sd } /* get shifted index for current high resolution block */ - index_big = smoke_get_index(block_size * dx + ii - shift_x, bigres[0], block_size * dy + jj - shift_y, bigres[1], block_size * dz + kk - shift_z); + index_big = smoke_get_index(block_size * dx + ii - shift_x, bigres[0], block_size * dy + jj - shift_y, bigres[1], block_size * dz + kk - shift_z); - if(sfs->type == MOD_SMOKE_FLOW_TYPE_OUTFLOW) { // outflow + if (sfs->type == MOD_SMOKE_FLOW_TYPE_OUTFLOW) { // outflow if (interpolated_value) { apply_outflow_fields(index_big, bigdensity, NULL, bigfuel, bigreact, bigcolor_r, bigcolor_g, bigcolor_b); } @@ -1880,9 +1879,9 @@ static void update_flowsfluids(Scene *scene, Object *ob, SmokeDomainSettings *sd } } - if(flowobjs) + if (flowobjs) MEM_freeN(flowobjs); - if(emaps) + if (emaps) MEM_freeN(emaps); } @@ -1893,7 +1892,7 @@ static void update_effectors(Scene *scene, Object *ob, SmokeDomainSettings *sds, sds->effector_weights->weight[PFIELD_SMOKEFLOW] = 0.0f; effectors = pdInitEffectors(scene, ob, NULL, sds->effector_weights); - if(effectors) + if (effectors) { float *density = smoke_get_density(sds->fluid); float *force_x = smoke_get_force_x(sds->fluid); @@ -1907,49 +1906,49 @@ static void update_effectors(Scene *scene, Object *ob, SmokeDomainSettings *sds, // precalculate wind forces #pragma omp parallel for schedule(static) - for(x = 0; x < sds->res[0]; x++) + for (x = 0; x < sds->res[0]; x++) { int y, z; - for(y = 0; y < sds->res[1]; y++) - for(z = 0; z < sds->res[2]; z++) - { - EffectedPoint epoint; - float mag; - float voxelCenter[3] = {0,0,0}, vel[3] = {0,0,0}, retvel[3] = {0,0,0}; - unsigned int index = smoke_get_index(x, sds->res[0], y, sds->res[1], z); + for (y = 0; y < sds->res[1]; y++) + for (z = 0; z < sds->res[2]; z++) + { + EffectedPoint epoint; + float mag; + float voxelCenter[3] = {0, 0, 0}, vel[3] = {0, 0, 0}, retvel[3] = {0, 0, 0}; + unsigned int index = smoke_get_index(x, sds->res[0], y, sds->res[1], z); - if((density[index] < FLT_EPSILON) || obstacle[index]) - continue; + if ((density[index] < FLT_EPSILON) || obstacle[index]) + continue; - vel[0] = velocity_x[index]; - vel[1] = velocity_y[index]; - vel[2] = velocity_z[index]; + vel[0] = velocity_x[index]; + vel[1] = velocity_y[index]; + vel[2] = velocity_z[index]; - /* convert vel to global space */ - mag = len_v3(vel); - mul_mat3_m4_v3(sds->obmat, vel); - normalize_v3(vel); - mul_v3_fl(vel, mag); + /* convert vel to global space */ + mag = len_v3(vel); + mul_mat3_m4_v3(sds->obmat, vel); + normalize_v3(vel); + mul_v3_fl(vel, mag); - voxelCenter[0] = sds->p0[0] + sds->cell_size[0] * ((float)(x+sds->res_min[0]) + 0.5f); - voxelCenter[1] = sds->p0[1] + sds->cell_size[1] * ((float)(y+sds->res_min[1]) + 0.5f); - voxelCenter[2] = sds->p0[2] + sds->cell_size[2] * ((float)(z+sds->res_min[2]) + 0.5f); - mul_m4_v3(sds->obmat, voxelCenter); + voxelCenter[0] = sds->p0[0] + sds->cell_size[0] * ((float)(x + sds->res_min[0]) + 0.5f); + voxelCenter[1] = sds->p0[1] + sds->cell_size[1] * ((float)(y + sds->res_min[1]) + 0.5f); + voxelCenter[2] = sds->p0[2] + sds->cell_size[2] * ((float)(z + sds->res_min[2]) + 0.5f); + mul_m4_v3(sds->obmat, voxelCenter); - pd_point_from_loc(scene, voxelCenter, vel, index, &epoint); - pdDoEffectors(effectors, NULL, sds->effector_weights, &epoint, retvel, NULL); + pd_point_from_loc(scene, voxelCenter, vel, index, &epoint); + pdDoEffectors(effectors, NULL, sds->effector_weights, &epoint, retvel, NULL); - /* convert retvel to local space */ - mag = len_v3(retvel); - mul_mat3_m4_v3(sds->imat, retvel); - normalize_v3(retvel); - mul_v3_fl(retvel, mag); + /* convert retvel to local space */ + mag = len_v3(retvel); + mul_mat3_m4_v3(sds->imat, retvel); + normalize_v3(retvel); + mul_v3_fl(retvel, mag); - // TODO dg - do in force! - force_x[index] = MIN2(MAX2(-1.0, retvel[0] * 0.2), 1.0); - force_y[index] = MIN2(MAX2(-1.0, retvel[1] * 0.2), 1.0); - force_z[index] = MIN2(MAX2(-1.0, retvel[2] * 0.2), 1.0); - } + // TODO dg - do in force! + force_x[index] = MIN2(MAX2(-1.0, retvel[0] * 0.2), 1.0); + force_y[index] = MIN2(MAX2(-1.0, retvel[1] * 0.2), 1.0); + force_z[index] = MIN2(MAX2(-1.0, retvel[2] * 0.2), 1.0); + } } } @@ -1973,7 +1972,7 @@ static void step(Scene *scene, Object *ob, SmokeModifierData *smd, DerivedMesh * float gravity_mag; #if 0 /* UNUSED */ - /* get max velocity and lower the dt value if it is too high */ + /* get max velocity and lower the dt value if it is too high */ size_t size = sds->res[0] * sds->res[1] * sds->res[2]; float *velX = smoke_get_velocity_x(sds->fluid); float *velY = smoke_get_velocity_y(sds->fluid); @@ -1990,7 +1989,7 @@ static void step(Scene *scene, Object *ob, SmokeModifierData *smd, DerivedMesh * if (scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY) { copy_v3_v3(gravity, scene->physics_settings.gravity); /* map default value to 1.0 */ - mul_v3_fl(gravity, 1.0f/9.810f); + mul_v3_fl(gravity, 1.0f / 9.810f); } /* convert gravity to domain space */ gravity_mag = len_v3(gravity); @@ -2005,8 +2004,8 @@ static void step(Scene *scene, Object *ob, SmokeModifierData *smd, DerivedMesh * #if 0 for (i = 0; i < size; i++) { - float vtemp = (velX[i]*velX[i]+velY[i]*velY[i]+velZ[i]*velZ[i]); - if(vtemp > maxVelMag) + float vtemp = (velX[i] * velX[i] + velY[i] * velY[i] + velZ[i] * velZ[i]); + if (vtemp > maxVelMag) maxVelMag = vtemp; } #endif @@ -2017,13 +2016,13 @@ static void step(Scene *scene, Object *ob, SmokeModifierData *smd, DerivedMesh * totalSubsteps = (totalSubsteps > maxSubSteps) ? maxSubSteps : totalSubsteps; /* Disable substeps for now, since it results in numerical instability */ - totalSubsteps = 1.0f; + totalSubsteps = 1.0f; dtSubdiv = (float)dt / (float)totalSubsteps; // printf("totalSubsteps: %d, maxVelMag: %f, dt: %f\n", totalSubsteps, maxVelMag, dt); - for(substep = 0; substep < totalSubsteps; substep++) + for (substep = 0; substep < totalSubsteps; substep++) { // calc animated obstacle velocities update_flowsfluids(scene, ob, sds, smd->time, dtSubdiv); @@ -2059,7 +2058,7 @@ static DerivedMesh *createDomainGeometry(SmokeDomainSettings *sds, Object *ob) num_verts = 0; num_faces = 0; } - + result = CDDM_new(num_verts, 0, 0, num_faces * 4, num_faces); mverts = CDDM_get_verts(result); mpolys = CDDM_get_polys(result); @@ -2104,7 +2103,7 @@ static DerivedMesh *createDomainGeometry(SmokeDomainSettings *sds, Object *ob) ml[0].v = 1; ml[1].v = 0; ml[2].v = 4; ml[3].v = 5; /* calculate required shift to match domain's global position - * it was originally simulated at (if object moves without smoke step) */ + * it was originally simulated at (if object moves without smoke step) */ invert_m4_m4(ob->imat, ob->obmat); mul_m4_v3(ob->obmat, ob_loc); mul_m4_v3(sds->obmat, ob_cache_loc); @@ -2112,7 +2111,7 @@ static DerivedMesh *createDomainGeometry(SmokeDomainSettings *sds, Object *ob) /* convert shift to local space and apply to vertices */ mul_mat3_m4_v3(ob->imat, sds->obj_shift_f); /* apply */ - for (i=0; iobj_shift_f); } } @@ -2123,34 +2122,34 @@ static DerivedMesh *createDomainGeometry(SmokeDomainSettings *sds, Object *ob) } static void smokeModifier_process(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedMesh *dm) -{ - if((smd->type & MOD_SMOKE_TYPE_FLOW)) +{ + if ((smd->type & MOD_SMOKE_TYPE_FLOW)) { - if(scene->r.cfra >= smd->time) + if (scene->r.cfra >= smd->time) smokeModifier_init(smd, ob, scene, dm); if (smd->flow->dm) smd->flow->dm->release(smd->flow->dm); smd->flow->dm = CDDM_copy(dm); DM_ensure_tessface(smd->flow->dm); - if(scene->r.cfra > smd->time) + if (scene->r.cfra > smd->time) { smd->time = scene->r.cfra; } - else if(scene->r.cfra < smd->time) + else if (scene->r.cfra < smd->time) { smd->time = scene->r.cfra; smokeModifier_reset(smd); } } - else if(smd->type & MOD_SMOKE_TYPE_COLL) + else if (smd->type & MOD_SMOKE_TYPE_COLL) { - if(scene->r.cfra >= smd->time) + if (scene->r.cfra >= smd->time) smokeModifier_init(smd, ob, scene, dm); - if(smd->coll) + if (smd->coll) { - if (smd->coll->dm) + if (smd->coll->dm) smd->coll->dm->release(smd->coll->dm); smd->coll->dm = CDDM_copy(dm); @@ -2158,12 +2157,12 @@ static void smokeModifier_process(SmokeModifierData *smd, Scene *scene, Object * } smd->time = scene->r.cfra; - if(scene->r.cfra < smd->time) + if (scene->r.cfra < smd->time) { smokeModifier_reset(smd); } } - else if(smd->type & MOD_SMOKE_TYPE_DOMAIN) + else if (smd->type & MOD_SMOKE_TYPE_DOMAIN) { SmokeDomainSettings *sds = smd->domain; PointCache *cache = NULL; @@ -2179,7 +2178,7 @@ static void smokeModifier_process(SmokeModifierData *smd, Scene *scene, Object * BKE_ptcache_id_from_smoke(&pid, ob, smd); BKE_ptcache_id_time(&pid, scene, framenr, &startframe, &endframe, ×cale); - if(!smd->domain->fluid || framenr == startframe) + if (!smd->domain->fluid || framenr == startframe) { BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED); smokeModifier_reset(smd); @@ -2187,7 +2186,7 @@ static void smokeModifier_process(SmokeModifierData *smd, Scene *scene, Object * cache->flag &= ~PTCACHE_REDO_NEEDED; } - if(!smd->domain->fluid && (framenr != startframe) && (smd->domain->flags & MOD_SMOKE_FILE_LOAD)==0 && (cache->flag & PTCACHE_BAKED)==0) + if (!smd->domain->fluid && (framenr != startframe) && (smd->domain->flags & MOD_SMOKE_FILE_LOAD) == 0 && (cache->flag & PTCACHE_BAKED) == 0) return; smd->domain->flags &= ~MOD_SMOKE_FILE_LOAD; @@ -2197,21 +2196,21 @@ static void smokeModifier_process(SmokeModifierData *smd, Scene *scene, Object * if ((smd->time == framenr) && (framenr != scene->r.cfra)) return; - if(smokeModifier_init(smd, ob, scene, dm)==0) + if (smokeModifier_init(smd, ob, scene, dm) == 0) { printf("bad smokeModifier_init\n"); return; } /* try to read from cache */ - if(BKE_ptcache_read(&pid, (float)framenr) == PTCACHE_READ_EXACT) { + if (BKE_ptcache_read(&pid, (float)framenr) == PTCACHE_READ_EXACT) { BKE_ptcache_validate(cache, framenr); smd->time = framenr; return; } - + /* only calculate something when we advanced a single frame */ - if(framenr != (int)smd->time+1) + if (framenr != (int)smd->time + 1) return; /* don't simulate if viewing start frame, but scene frame is not real start frame */ @@ -2221,20 +2220,20 @@ static void smokeModifier_process(SmokeModifierData *smd, Scene *scene, Object * tstart(); /* if on second frame, write cache for first frame */ - if((int)smd->time == startframe && (cache->flag & PTCACHE_OUTDATED || cache->last_exact==0)) { + if ((int)smd->time == startframe && (cache->flag & PTCACHE_OUTDATED || cache->last_exact == 0)) { // create shadows straight after domain initialization so we get nice shadows for startframe, too smoke_calc_transparency(sds, scene); - if(sds->wt && sds->total_cells>1) + if (sds->wt && sds->total_cells > 1) { - if(sds->flags & MOD_SMOKE_DISSOLVE) + if (sds->flags & MOD_SMOKE_DISSOLVE) smoke_dissolve_wavelet(sds->wt, sds->diss_speed, sds->flags & MOD_SMOKE_DISSOLVE_LOG); smoke_turbulence_step(sds->wt, sds->fluid); } BKE_ptcache_write(&pid, startframe); } - + // set new time smd->time = scene->r.cfra; @@ -2242,26 +2241,26 @@ static void smokeModifier_process(SmokeModifierData *smd, Scene *scene, Object * // simulate the actual smoke (c++ code in intern/smoke) // DG: interesting commenting this line + deactivating loading of noise files - if(framenr!=startframe) + if (framenr != startframe) { - if(sds->flags & MOD_SMOKE_DISSOLVE) + if (sds->flags & MOD_SMOKE_DISSOLVE) smoke_dissolve(sds->fluid, sds->diss_speed, sds->flags & MOD_SMOKE_DISSOLVE_LOG); - + step(scene, ob, smd, dm, scene->r.frs_sec / scene->r.frs_sec_base); } // create shadows before writing cache so they get stored smoke_calc_transparency(sds, scene); - if(sds->wt) + if (sds->wt) { - if(sds->flags & MOD_SMOKE_DISSOLVE) + if (sds->flags & MOD_SMOKE_DISSOLVE) smoke_dissolve_wavelet(sds->wt, sds->diss_speed, sds->flags & MOD_SMOKE_DISSOLVE_LOG); smoke_turbulence_step(sds->wt, sds->fluid); } - + BKE_ptcache_validate(cache, framenr); - if(framenr != startframe) + if (framenr != startframe) BKE_ptcache_write(&pid, framenr); tend(); @@ -2269,14 +2268,13 @@ static void smokeModifier_process(SmokeModifierData *smd, Scene *scene, Object * } } -struct DerivedMesh *smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedMesh *dm) -{ +struct DerivedMesh *smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedMesh *dm){ smokeModifier_process(smd, scene, ob, dm); /* return generated geometry for adaptive domain */ - if(smd->type & MOD_SMOKE_TYPE_DOMAIN && smd->domain && - smd->domain->flags & MOD_SMOKE_ADAPTIVE_DOMAIN && - smd->domain->base_res[0]) + if (smd->type & MOD_SMOKE_TYPE_DOMAIN && smd->domain && + smd->domain->flags & MOD_SMOKE_ADAPTIVE_DOMAIN && + smd->domain->base_res[0]) { return createDomainGeometry(smd->domain, ob); } @@ -2288,13 +2286,13 @@ static float calc_voxel_transp(float *result, float *input, int res[3], int *pix const size_t index = smoke_get_index(pixel[0], res[0], pixel[1], res[1], pixel[2]); // T_ray *= T_vox - *tRay *= exp(input[index]*correct); - - if(result[index] < 0.0f) + *tRay *= exp(input[index] * correct); + + if (result[index] < 0.0f) { -// #pragma omp critical - result[index] = *tRay; - } +// #pragma omp critical + result[index] = *tRay; + } return *tRay; } @@ -2326,7 +2324,7 @@ static void bresenham_linie_3D(int x1, int y1, int z1, int x2, int y2, int z2, f err_1 = dy2 - l; err_2 = dz2 - l; for (i = 0; i < l; i++) { - if(cb(result, input, res, pixel, tRay, correct) <= FLT_EPSILON) + if (cb(result, input, res, pixel, tRay, correct) <= FLT_EPSILON) break; if (err_1 > 0) { pixel[1] += y_inc; @@ -2340,12 +2338,12 @@ static void bresenham_linie_3D(int x1, int y1, int z1, int x2, int y2, int z2, f err_2 += dz2; pixel[0] += x_inc; } - } + } else if ((m >= l) && (m >= n)) { err_1 = dx2 - m; err_2 = dz2 - m; for (i = 0; i < m; i++) { - if(cb(result, input, res, pixel, tRay, correct) <= FLT_EPSILON) + if (cb(result, input, res, pixel, tRay, correct) <= FLT_EPSILON) break; if (err_1 > 0) { pixel[0] += x_inc; @@ -2359,12 +2357,12 @@ static void bresenham_linie_3D(int x1, int y1, int z1, int x2, int y2, int z2, f err_2 += dz2; pixel[1] += y_inc; } - } + } else { err_1 = dy2 - n; err_2 = dx2 - n; for (i = 0; i < n; i++) { - if(cb(result, input, res, pixel, tRay, correct) <= FLT_EPSILON) + if (cb(result, input, res, pixel, tRay, correct) <= FLT_EPSILON) break; if (err_1 > 0) { pixel[1] += y_inc; @@ -2386,9 +2384,9 @@ static void smoke_calc_transparency(SmokeDomainSettings *sds, Scene *scene) { float bv[6] = {0}; float light[3]; - int a, z, slabsize=sds->res[0]*sds->res[1], size= sds->res[0]*sds->res[1]*sds->res[2]; + int a, z, slabsize = sds->res[0] * sds->res[1], size = sds->res[0] * sds->res[1] * sds->res[2]; float *density = smoke_get_density(sds->fluid); - float correct = -7.0*sds->dx; + float correct = -7.0 * sds->dx; if (!get_lamp(scene, light)) return; @@ -2398,8 +2396,8 @@ static void smoke_calc_transparency(SmokeDomainSettings *sds, Scene *scene) light[1] = (light[1] - sds->p0[1]) / sds->cell_size[1] - 0.5f; light[2] = (light[2] - sds->p0[2]) / sds->cell_size[2] - 0.5f; - for(a=0; ashadow[a]= -1.0f; + for (a = 0; a < size; a++) + sds->shadow[a] = -1.0f; /* calculate domain bounds in sim cell space */ // 0,2,4 = 0.0f @@ -2408,27 +2406,27 @@ static void smoke_calc_transparency(SmokeDomainSettings *sds, Scene *scene) bv[5] = (float)sds->res[2]; // z // #pragma omp parallel for schedule(static,1) - for(z = 0; z < sds->res[2]; z++) + for (z = 0; z < sds->res[2]; z++) { - size_t index = z*slabsize; - int x,y; + size_t index = z * slabsize; + int x, y; - for(y = 0; y < sds->res[1]; y++) - for(x = 0; x < sds->res[0]; x++, index++) + for (y = 0; y < sds->res[1]; y++) + for (x = 0; x < sds->res[0]; x++, index++) { float voxelCenter[3]; float pos[3]; int cell[3]; float tRay = 1.0; - if(sds->shadow[index] >= 0.0f) - continue; + if (sds->shadow[index] >= 0.0f) + continue; voxelCenter[0] = (float)x; voxelCenter[1] = (float)y; voxelCenter[2] = (float)z; // get starting cell (light pos) - if(BLI_bvhtree_bb_raycast(bv, light, voxelCenter, pos) > FLT_EPSILON) + if (BLI_bvhtree_bb_raycast(bv, light, voxelCenter, pos) > FLT_EPSILON) { // we're ouside -> use point on side of domain cell[0] = (int)floor(pos[0]); @@ -2442,27 +2440,27 @@ static void smoke_calc_transparency(SmokeDomainSettings *sds, Scene *scene) cell[2] = (int)floor(light[2]); } /* clamp within grid bounds */ - CLAMP(cell[0], 0, sds->res[0]-1); - CLAMP(cell[1], 0, sds->res[1]-1); - CLAMP(cell[2], 0, sds->res[2]-1); + CLAMP(cell[0], 0, sds->res[0] - 1); + CLAMP(cell[1], 0, sds->res[1] - 1); + CLAMP(cell[2], 0, sds->res[2] - 1); bresenham_linie_3D(cell[0], cell[1], cell[2], x, y, z, &tRay, calc_voxel_transp, sds->shadow, density, sds->res, correct); // convention -> from a RGBA float array, use G value for tRay // #pragma omp critical - sds->shadow[index] = tRay; + sds->shadow[index] = tRay; } } } /* get smoke velocity and density at given coordinates -* returns fluid density or -1.0f if outside domain*/ + * returns fluid density or -1.0f if outside domain*/ float smoke_get_velocity_at(struct Object *ob, float position[3], float velocity[3]) { - SmokeModifierData *smd = (SmokeModifierData*)modifiers_findByType(ob, eModifierType_Smoke); + SmokeModifierData *smd = (SmokeModifierData *)modifiers_findByType(ob, eModifierType_Smoke); zero_v3(velocity); - if(smd && (smd->type & MOD_SMOKE_TYPE_DOMAIN) && smd->domain && smd->domain->fluid) { + if (smd && (smd->type & MOD_SMOKE_TYPE_DOMAIN) && smd->domain && smd->domain->fluid) { SmokeDomainSettings *sds = smd->domain; float time_mult = 25.f * DT_DEFAULT; float vel_mag; diff --git a/source/blender/editors/armature/meshlaplacian.c b/source/blender/editors/armature/meshlaplacian.c index e7efd7936c0..82fef00b1e6 100644 --- a/source/blender/editors/armature/meshlaplacian.c +++ b/source/blender/editors/armature/meshlaplacian.c @@ -1221,7 +1221,7 @@ static void harmonic_ray_callback(void *userdata, int index, const BVHTreeRay *r else normal_quad_v3(no, face[0], face[1], face[2], face[3]); - dist = len_v3v3(ray->origin, co)/len_v3(isec->vec); + dist = len_v3v3(ray->origin, co) / len_v3(isec->vec); if (dist < hit->dist) { hit->index = index; hit->dist = dist; @@ -1257,7 +1257,7 @@ static MDefBoundIsect *meshdeform_ray_tree_intersect(MeshDeformBind *mdb, float if (BLI_bvhtree_ray_cast(mdb->bvhtree, isect_mdef.start, isect_mdef.vec, 0.0, &hit, harmonic_ray_callback, data) != -1) { - len= isect_mdef.labda; + len = isect_mdef.labda; isect_mdef.face = mface = mface1 + hit.index; /* create MDefBoundIsect */ diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index 0e1fd87c985..3203237496f 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -3094,14 +3094,10 @@ static int widget_roundbox_set(uiBut *but, rcti *rect) if (but->active) { int direction = ui_button_open_menu_direction(but); - if (direction == UI_TOP) - roundbox &= ~(UI_CNR_TOP_RIGHT|UI_CNR_TOP_LEFT); - else if (direction == UI_DOWN) - roundbox &= ~(UI_CNR_BOTTOM_RIGHT|UI_CNR_BOTTOM_LEFT); - else if (direction == UI_LEFT) - roundbox &= ~(UI_CNR_TOP_LEFT|UI_CNR_BOTTOM_LEFT); - else if (direction == UI_RIGHT) - roundbox &= ~(UI_CNR_TOP_RIGHT|UI_CNR_BOTTOM_RIGHT); + if (direction == UI_TOP) roundbox &= ~(UI_CNR_TOP_RIGHT | UI_CNR_TOP_LEFT); + else if (direction == UI_DOWN) roundbox &= ~(UI_CNR_BOTTOM_RIGHT | UI_CNR_BOTTOM_LEFT); + else if (direction == UI_LEFT) roundbox &= ~(UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT); + else if (direction == UI_RIGHT) roundbox &= ~(UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT); } return roundbox; diff --git a/source/blender/editors/object/object_iterators.c b/source/blender/editors/object/object_iterators.c index 1d38db9d59b..c1841711435 100644 --- a/source/blender/editors/object/object_iterators.c +++ b/source/blender/editors/object/object_iterators.c @@ -187,8 +187,7 @@ static void mesh_foreachScreenFace__mapFunc(void *userData, int index, const flo if (efa && !BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { float screen_co[2]; - if (ED_view3d_project_float_object(data->vc.ar, cent, screen_co, data->clip_flag) == V3D_PROJ_RET_OK) - { + if (ED_view3d_project_float_object(data->vc.ar, cent, screen_co, data->clip_flag) == V3D_PROJ_RET_OK) { data->func(data->userData, efa, screen_co, index); } } @@ -297,8 +296,7 @@ void mball_foreachScreenElem( for (ml = mb->editelems->first; ml; ml = ml->next) { float screen_co[2]; - if (ED_view3d_project_float_object(vc->ar, &ml->x, screen_co, clip_flag) == V3D_PROJ_RET_OK) - { + if (ED_view3d_project_float_object(vc->ar, &ml->x, screen_co, clip_flag) == V3D_PROJ_RET_OK) { func(userData, ml, screen_co); } } diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index b5643cdb9cb..a92cfa472aa 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -533,7 +533,7 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou } /* loop through the vertices*/ - for(i = 0, dv_src = dv_array_src, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++, dv_src++, mv_src++, mv_dst++) { + for (i = 0, dv_src = dv_array_src, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++, dv_src++, mv_src++, mv_dst++) { if (*dv_dst == NULL) { continue; @@ -553,7 +553,7 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou bvhtree_from_mesh_verts(&tree_mesh_vertices_src, dmesh_src, FLT_EPSILON, 2, 6); /* loop trough vertices */ - for(i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++, mv_dst++){ + for (i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++, mv_dst++) { if (*dv_dst == NULL) { continue; @@ -592,7 +592,7 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou bvhtree_from_mesh_faces(&tree_mesh_faces_src, dmesh_src, FLT_EPSILON, 2, 6); /* loop through the vertices */ - for(i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++, mv_dst++) { + for (i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++, mv_dst++) { if (*dv_dst == NULL) { continue; @@ -652,7 +652,7 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou bvhtree_from_mesh_faces(&tree_mesh_faces_src, dmesh_src, FLT_EPSILON, 2, 6); /* loop through the vertices */ - for(i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++, mv_dst++){ + for (i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++, mv_dst++) { if (*dv_dst == NULL) { continue; diff --git a/source/blender/editors/physics/dynamicpaint_ops.c b/source/blender/editors/physics/dynamicpaint_ops.c index 70fe87e5c01..5b69e6745c0 100644 --- a/source/blender/editors/physics/dynamicpaint_ops.c +++ b/source/blender/editors/physics/dynamicpaint_ops.c @@ -73,9 +73,9 @@ static int surface_slot_add_exec(bContext *C, wmOperator *UNUSED(op)) /* set preview for this surface only and set active */ canvas->active_sur = 0; - for (surface=surface->prev; surface; surface=surface->prev) { - surface->flags &= ~MOD_DPAINT_PREVIEW; - canvas->active_sur++; + for (surface = surface->prev; surface; surface = surface->prev) { + surface->flags &= ~MOD_DPAINT_PREVIEW; + canvas->active_sur++; } return OPERATOR_FINISHED; @@ -94,26 +94,26 @@ void DPAINT_OT_surface_slot_add(wmOperatorType *ot) ot->poll = ED_operator_object_active_editable; /* flags */ - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } static int surface_slot_remove_exec(bContext *C, wmOperator *UNUSED(op)) { DynamicPaintModifierData *pmd = NULL; - Object *cObject = ED_object_context(C); + Object *obj_ctx = ED_object_context(C); DynamicPaintCanvasSettings *canvas; DynamicPaintSurface *surface; - int id=0; + int id = 0; /* Make sure we're dealing with a canvas */ - pmd = (DynamicPaintModifierData *)modifiers_findByType(cObject, eModifierType_DynamicPaint); + pmd = (DynamicPaintModifierData *)modifiers_findByType(obj_ctx, eModifierType_DynamicPaint); if (!pmd || !pmd->canvas) return OPERATOR_CANCELLED; canvas = pmd->canvas; surface = canvas->surfaces.first; /* find active surface and remove it */ - for (; surface; surface=surface->next) { + for (; surface; surface = surface->next) { if (id == canvas->active_sur) { canvas->active_sur -= 1; dynamicPaint_freeSurface(surface); @@ -123,8 +123,8 @@ static int surface_slot_remove_exec(bContext *C, wmOperator *UNUSED(op)) } dynamicPaint_resetPreview(canvas); - DAG_id_tag_update(&cObject->id, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, cObject); + DAG_id_tag_update(&obj_ctx->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, obj_ctx); return OPERATOR_FINISHED; } @@ -142,7 +142,7 @@ void DPAINT_OT_surface_slot_remove(wmOperatorType *ot) ot->poll = ED_operator_object_active_editable; /* flags */ - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } static int type_toggle_exec(bContext *C, wmOperator *op) @@ -151,7 +151,7 @@ static int type_toggle_exec(bContext *C, wmOperator *op) Object *cObject = ED_object_context(C); Scene *scene = CTX_data_scene(C); DynamicPaintModifierData *pmd = (DynamicPaintModifierData *)modifiers_findByType(cObject, eModifierType_DynamicPaint); - int type= RNA_enum_get(op->ptr, "type"); + int type = RNA_enum_get(op->ptr, "type"); if (!pmd) return OPERATOR_CANCELLED; @@ -170,7 +170,7 @@ static int type_toggle_exec(bContext *C, wmOperator *op) /* update dependency */ DAG_id_tag_update(&cObject->id, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, cObject); + WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, cObject); DAG_scene_sort(CTX_data_main(C), scene); return OPERATOR_FINISHED; @@ -190,10 +190,10 @@ void DPAINT_OT_type_toggle(wmOperatorType *ot) ot->poll = ED_operator_object_active_editable; /* flags */ - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ - prop= RNA_def_enum(ot->srna, "type", prop_dynamicpaint_type_items, MOD_DYNAMICPAINT_TYPE_CANVAS, "Type", ""); + prop = RNA_def_enum(ot->srna, "type", prop_dynamicpaint_type_items, MOD_DYNAMICPAINT_TYPE_CANVAS, "Type", ""); ot->prop = prop; } @@ -203,7 +203,7 @@ static int output_toggle_exec(bContext *C, wmOperator *op) Scene *scene = CTX_data_scene(C); DynamicPaintSurface *surface; DynamicPaintModifierData *pmd = (DynamicPaintModifierData *)modifiers_findByType(ob, eModifierType_DynamicPaint); - int output= RNA_enum_get(op->ptr, "output"); /* currently only 1/0 */ + int output = RNA_enum_get(op->ptr, "output"); /* currently only 1/0 */ if (!pmd || !pmd->canvas) return OPERATOR_CANCELLED; surface = get_activeSurface(pmd->canvas); @@ -258,7 +258,7 @@ void DPAINT_OT_output_toggle(wmOperatorType *ot) ot->poll = ED_operator_object_active_editable; /* flags */ - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ ot->prop = RNA_def_enum(ot->srna, "output", prop_output_toggle_types, 0, "Output Toggle", ""); @@ -274,7 +274,7 @@ void DPAINT_OT_output_toggle(wmOperatorType *ot) static int dynamicPaint_bakeImageSequence(bContext *C, DynamicPaintSurface *surface, Object *cObject) { DynamicPaintCanvasSettings *canvas = surface->canvas; - Scene *scene= CTX_data_scene(C); + Scene *scene = CTX_data_scene(C); wmWindow *win = CTX_wm_window(C); int frame = 1; int frames; @@ -291,7 +291,7 @@ static int dynamicPaint_bakeImageSequence(bContext *C, DynamicPaintSurface *surf if (!dynamicPaint_createUVSurface(surface)) return 0; /* Loop through selected frames */ - for (frame=surface->start_frame; frame<=surface->end_frame; frame++) { + for (frame = surface->start_frame; frame <= surface->end_frame; frame++) { float progress = (frame - surface->start_frame) / (float)frames * 100; surface->current_frame = frame; diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index 4f57b2249d1..c7ad82dec85 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -1259,8 +1259,7 @@ static void save_image_doit(bContext *C, SpaceImage *sima, wmOperator *op, SaveI BKE_image_release_renderresult(scene, ima); } else { - if (BKE_imbuf_write_as(colormanaged_ibuf, simopts->filepath, &simopts->im_format, save_copy)) - { + if (BKE_imbuf_write_as(colormanaged_ibuf, simopts->filepath, &simopts->im_format, save_copy)) { ok = TRUE; } } diff --git a/source/blender/editors/space_view3d/drawvolume.c b/source/blender/editors/space_view3d/drawvolume.c index 8cc55363a5e..ebb48960b80 100644 --- a/source/blender/editors/space_view3d/drawvolume.c +++ b/source/blender/editors/space_view3d/drawvolume.c @@ -133,7 +133,7 @@ static int intersect_edges(float *points, float a, float b, float c, float d, fl int i; float t; int numpoints = 0; - + for (i = 0; i < 12; i++) { t = -(a * edges[i][0][0] + b * edges[i][0][1] + c * edges[i][0][2] + d) / (a * edges[i][1][0] + b * edges[i][1][1] + c * edges[i][1][2]); @@ -280,21 +280,22 @@ void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob, #define FIRE_THRESH 7 #define MAX_FIRE_ALPHA 0.06f #define FULL_ON_FIRE 100 - spec_data = malloc(SPEC_WIDTH*4 * sizeof(unsigned char)); + spec_data = malloc(SPEC_WIDTH * 4 * sizeof(unsigned char)); flame_get_spectrum(spec_data, SPEC_WIDTH, 1500, 3000); - spec_pixels = malloc(SPEC_WIDTH*4*16*16 * sizeof(float)); - for (i=0;i<16;i++){ - for (j=0;j<16;j++) { - for (k=0;k=FIRE_THRESH) { - spec_pixels[index] = ((float)spec_data[k*4])/255.0f; - spec_pixels[index+1] = ((float)spec_data[k*4+1])/255.0f; - spec_pixels[index+2] = ((float)spec_data[k*4+2])/255.0f; - spec_pixels[index+3] = MAX_FIRE_ALPHA*( - (k>FULL_ON_FIRE) ? 1.0f : (k-FIRE_THRESH)/((float)FULL_ON_FIRE-FIRE_THRESH)); - } else { - spec_pixels[index] = spec_pixels[index+1] = spec_pixels[index+2] = spec_pixels[index+3] = 0.0f; + spec_pixels = malloc(SPEC_WIDTH * 4 * 16 * 16 * sizeof(float)); + for (i = 0; i < 16; i++) { + for (j = 0; j < 16; j++) { + for (k = 0; k < SPEC_WIDTH; k++) { + int index = (j * SPEC_WIDTH * 16 + i * SPEC_WIDTH + k) * 4; + if (k >= FIRE_THRESH) { + spec_pixels[index] = ((float)spec_data[k * 4]) / 255.0f; + spec_pixels[index + 1] = ((float)spec_data[k * 4 + 1]) / 255.0f; + spec_pixels[index + 2] = ((float)spec_data[k * 4 + 2]) / 255.0f; + spec_pixels[index + 3] = MAX_FIRE_ALPHA * ( + (k > FULL_ON_FIRE) ? 1.0f : (k - FIRE_THRESH) / ((float)FULL_ON_FIRE - FIRE_THRESH)); + } + else { + spec_pixels[index] = spec_pixels[index + 1] = spec_pixels[index + 2] = spec_pixels[index + 3] = 0.0f; } } } @@ -372,7 +373,7 @@ void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob, edges[11][1][0] = size[0]; glGetBooleanv(GL_BLEND, (GLboolean *)&gl_blend); - glGetBooleanv(GL_DEPTH_TEST, (GLboolean *)&gl_depth); + glGetBooleanv(GL_DEPTH_TEST, (GLboolean *)&gl_depth); glDepthMask(GL_FALSE); glDisable(GL_DEPTH_TEST); @@ -382,9 +383,9 @@ void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob, for (i = 0; i < 8; i++) { float x, y, z; - x = cv[i][0] - viewnormal[0]*size[0]*0.5f; - y = cv[i][1] - viewnormal[1]*size[1]*0.5f; - z = cv[i][2] - viewnormal[2]*size[2]*0.5f; + x = cv[i][0] - viewnormal[0] * size[0] * 0.5f; + y = cv[i][1] - viewnormal[1] * size[1] * 0.5f; + z = cv[i][2] - viewnormal[2] * size[2] * 0.5f; if ((x >= min[0]) && (x <= max[0]) && (y >= min[1]) && (y <= max[1]) && @@ -448,7 +449,7 @@ void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob, /* d0 = (viewnormal[0]*cv[i][0] + viewnormal[1]*cv[i][1] + viewnormal[2]*cv[i][2]); */ /* UNUSED */ ds = (ABS(viewnormal[0]) * size[0] + ABS(viewnormal[1]) * size[1] + ABS(viewnormal[2]) * size[2]); - dd = MAX3(sds->global_size[0],sds->global_size[1],sds->global_size[2])/128.f; + dd = MAX3(sds->global_size[0], sds->global_size[1], sds->global_size[2]) / 128.f; n = 0; good_index = i; @@ -500,7 +501,7 @@ void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob, glTexCoord3d((points[i * 3 + 0] - min[0]) * cor[0] / size[0], (points[i * 3 + 1] - min[1]) * cor[1] / size[1], (points[i * 3 + 2] - min[2]) * cor[2] / size[2]); - glVertex3f(points[i * 3 + 0]/ob->size[0], points[i * 3 + 1]/ob->size[1], points[i * 3 + 2]/ob->size[2]); + glVertex3f(points[i * 3 + 0] / ob->size[0], points[i * 3 + 1] / ob->size[1], points[i * 3 + 2] / ob->size[2]); } glEnd(); @@ -513,7 +514,7 @@ void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob, glTexCoord3d((points[i * 3 + 0] - min[0]) * cor[0] / size[0], (points[i * 3 + 1] - min[1]) * cor[1] / size[1], (points[i * 3 + 2] - min[2]) * cor[2] / size[2]); - glVertex3f(points[i * 3 + 0]/ob->size[0], points[i * 3 + 1]/ob->size[1], points[i * 3 + 2]/ob->size[2]); + glVertex3f(points[i * 3 + 0] / ob->size[0], points[i * 3 + 1] / ob->size[1], points[i * 3 + 2] / ob->size[2]); } glEnd(); } @@ -549,15 +550,15 @@ void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob, if (gl_depth) { glEnable(GL_DEPTH_TEST); - glDepthMask(GL_TRUE); + glDepthMask(GL_TRUE); } } #ifdef SMOKE_DEBUG_VELOCITY void draw_smoke_velocity(SmokeDomainSettings *domain, Object *ob) { - float x,y,z; - float x0,y0,z0; + float x, y, z; + float x0, y0, z0; int *base_res = domain->base_res; int *res = domain->res; int *res_min = domain->res_min; @@ -568,27 +569,27 @@ void draw_smoke_velocity(SmokeDomainSettings *domain, Object *ob) float min[3]; float *cell_size = domain->cell_size; - float step_size = ((float)MAX3(base_res[0], base_res[1], base_res[2]))/16.f; + float step_size = ((float)MAX3(base_res[0], base_res[1], base_res[2])) / 16.f; float vf = domain->scale / 16.f * 2.f; /* velocity factor */ glLineWidth(1.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 (x0shift[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; add_v3_v3v3(min, domain->p0, domain->obj_shift_f); - for (x=floor(x0); x= 0.01f) { @@ -599,21 +600,21 @@ void draw_smoke_velocity(SmokeDomainSettings *domain, Object *ob) 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); + 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); + glVertex3f(pos[0] + vel_x[index] * vf, pos[1] + vel_y[index] * vf, pos[2] + vel_z[index] * vf); glEnd(); } - } + } } #endif #ifdef SMOKE_DEBUG_HEAT void draw_smoke_heat(SmokeDomainSettings *domain, Object *ob) { - float x,y,z; - float x0,y0,z0; + float x, y, z; + float x0, y0, z0; int *base_res = domain->base_res; int *res = domain->res; int *res_min = domain->res_min; @@ -622,24 +623,24 @@ void draw_smoke_heat(SmokeDomainSettings *domain, Object *ob) float min[3]; float *cell_size = domain->cell_size; - float step_size = ((float)MAX3(base_res[0], base_res[1], base_res[2]))/16.f; + float step_size = ((float)MAX3(base_res[0], base_res[1], base_res[2])) / 16.f; float vf = domain->scale / 16.f * 2.f; /* velocity factor */ /* 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 (x0shift[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; add_v3_v3v3(min, domain->p0, domain->obj_shift_f); - for (x=floor(x0); x= 0.01f) { @@ -652,6 +653,6 @@ void draw_smoke_heat(SmokeDomainSettings *domain, Object *ob) glVertex3f(pos[0], pos[1], pos[2]); glEnd(); } - } + } } #endif From 563aa57db25124590b7628c35d87912d864666d8 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 11 Oct 2012 00:56:34 +0000 Subject: [PATCH 178/347] fix [#32829] Crash when making linked Mesh with UV Map local --- source/blender/blenkernel/intern/mesh.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index 1aaeebf5109..1936cc0ea99 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -576,7 +576,7 @@ static void expand_local_mesh(Mesh *me) for (i = 0; i < me->pdata.totlayer; i++) { if (me->pdata.layers[i].type == CD_MTEXPOLY) { - MTexPoly *txface = (MTexPoly *)me->fdata.layers[i].data; + MTexPoly *txface = (MTexPoly *)me->pdata.layers[i].data; for (a = 0; a < me->totpoly; a++, txface++) { /* special case: ima always local immediately */ From 0bf1a16203f5ad523a54666b78604fdcdffc8b9e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 11 Oct 2012 03:25:19 +0000 Subject: [PATCH 179/347] style cleanup --- .../blender/editors/space_view3d/drawobject.c | 81 ++++++++++--------- 1 file changed, 43 insertions(+), 38 deletions(-) diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 7bb22891b07..82e7fe60301 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -745,10 +745,10 @@ void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, int depth_write, floa mul_m4_v3(mat, vos->vec); if (ED_view3d_project_short_ex(ar, - (vos->flag & V3D_CACHE_TEXT_GLOBALSPACE) ? rv3d->persmat : rv3d->persmatob, - (vos->flag & V3D_CACHE_TEXT_LOCALCLIP) != 0, - vos->vec, vos->sco, - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) + (vos->flag & V3D_CACHE_TEXT_GLOBALSPACE) ? rv3d->persmat : rv3d->persmatob, + (vos->flag & V3D_CACHE_TEXT_LOCALCLIP) != 0, + vos->vec, vos->sco, + V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) { tot++; } @@ -819,7 +819,9 @@ void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, int depth_write, floa if (depth_write) { if (v3d->zbuf) glEnable(GL_DEPTH_TEST); } - else glDepthMask(1); + else { + glDepthMask(1); + } glMatrixMode(GL_PROJECTION); glPopMatrix(); @@ -861,7 +863,7 @@ static void drawcube(void) glEnd(); } -/* draws a cube on given the scaling of the cube, assuming that +/* draws a cube on given the scaling of the cube, assuming that * all required matrices have been set (used for drawing empties) */ static void drawcube_size(float size) @@ -1245,8 +1247,10 @@ static void drawlamp(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, glVertex3fv(tvec); glEnd(); } - else circ(0.0, 0.0, fabsf(z)); - + else { + circ(0.0, 0.0, fabsf(z)); + } + /* draw the circle/square representing spotbl */ if (la->type == LA_SPOT) { float spotblcirc = fabs(z) * (1 - pow(la->spotblend, 2)); @@ -1390,7 +1394,7 @@ static void draw_limit_line(float sta, float end, unsigned int col) glVertex3f(0.0, 0.0, -end); glEnd(); glPointSize(1.0); -} +} /* yafray: draw camera focus point (cross, similar to aqsis code in tuhopuu) */ @@ -1947,7 +1951,7 @@ static void drawSelectedVertices(DerivedMesh *dm, Mesh *me) /* ************** DRAW MESH ****************** */ -/* First section is all the "simple" draw routines, +/* First section is all the "simple" draw routines, * ones that just pass some sort of primitive to GL, * with perhaps various options to control lighting, * color, etc. @@ -2182,7 +2186,7 @@ static DMDrawOption draw_dm_edges_sel__setDrawOptions(void *userData, int index) return DM_DRAW_OPTION_SKIP; } } -static void draw_dm_edges_sel(BMEditMesh *em, DerivedMesh *dm, unsigned char *baseCol, +static void draw_dm_edges_sel(BMEditMesh *em, DerivedMesh *dm, unsigned char *baseCol, unsigned char *selCol, unsigned char *actCol, BMEdge *eed_act) { drawDMEdgesSel_userData data; @@ -2204,7 +2208,7 @@ static DMDrawOption draw_dm_edges__setDrawOptions(void *userData, int index) return DM_DRAW_OPTION_NORMAL; } -static void draw_dm_edges(BMEditMesh *em, DerivedMesh *dm) +static void draw_dm_edges(BMEditMesh *em, DerivedMesh *dm) { dm->drawMappedEdges(dm, draw_dm_edges__setDrawOptions, em); } @@ -2328,7 +2332,7 @@ static int draw_dm_faces_sel__compareDrawOptions(void *userData, int index, int } /* also draws the active face */ -static void draw_dm_faces_sel(BMEditMesh *em, DerivedMesh *dm, unsigned char *baseCol, +static void draw_dm_faces_sel(BMEditMesh *em, DerivedMesh *dm, unsigned char *baseCol, unsigned char *selCol, unsigned char *actCol, BMFace *efa_act) { drawDMFacesSel_userData data; @@ -2425,9 +2429,9 @@ static void draw_dm_bweights(BMEditMesh *em, Scene *scene, DerivedMesh *dm) /* EditMesh drawing routines*/ -static void draw_em_fancy_verts(Scene *scene, View3D *v3d, Object *obedit, +static void draw_em_fancy_verts(Scene *scene, View3D *v3d, Object *obedit, BMEditMesh *em, DerivedMesh *cageDM, BMVert *eve_act, - RegionView3D *rv3d) + RegionView3D *rv3d) { ToolSettings *ts = scene->toolsettings; int sel; @@ -2547,7 +2551,7 @@ static void draw_em_fancy_edges(BMEditMesh *em, Scene *scene, View3D *v3d, glEnable(GL_DEPTH_TEST); } } -} +} static void draw_em_measure_stats(View3D *v3d, Object *ob, BMEditMesh *em, UnitSettings *unit) { @@ -2812,7 +2816,7 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, if (ese->type == BM_FACE) { efa_act = (BMFace *)ese->data; } - else + else #endif if (ese->htype == BM_EDGE) { eed_act = (BMEdge *)ese->ele; @@ -2981,13 +2985,12 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, static void draw_mesh_object_outline(View3D *v3d, Object *ob, DerivedMesh *dm) { - if ((v3d->transp == FALSE) && /* not when we draw the transparent pass */ (ob->mode & OB_MODE_ALL_PAINT) == FALSE) /* not when painting (its distracting) - campbell */ { glLineWidth(UI_GetThemeValuef(TH_OUTLINE_WIDTH) * 2.0f); glDepthMask(0); - + /* if transparent, we cannot draw the edges for solid select... edges have no material info. * drawFacesSolid() doesn't draw the transparent faces */ if (ob->dtx & OB_DRAWTRANSP) { @@ -5480,7 +5483,7 @@ static void drawspiral(const float cent[3], float rad, float tmat[][4], int star glEnd(); } -/* draws a circle on x-z plane given the scaling of the circle, assuming that +/* draws a circle on x-z plane given the scaling of the circle, assuming that * all required matrices have been set (used for drawing empties) */ static void drawcircle_size(float size) @@ -6642,8 +6645,10 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short draw_box(bb.vec); /* draw base resolution bounds */ - /*BKE_boundbox_init_from_minmax(&bb, sds->p0, sds->p1); - draw_box(bb.vec);*/ +#if 0 + BKE_boundbox_init_from_minmax(&bb, sds->p0, sds->p1); + draw_box(bb.vec); +#endif } /* don't show smoke before simulation starts, this could be made an option in the future */ @@ -6655,15 +6660,15 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short normalize_v3(viewnormal); /* set dynamic boundaries to draw the volume */ - p0[0] = sds->p0[0] + sds->cell_size[0]*sds->res_min[0] + sds->obj_shift_f[0]; - p0[1] = sds->p0[1] + sds->cell_size[1]*sds->res_min[1] + sds->obj_shift_f[1]; - p0[2] = sds->p0[2] + sds->cell_size[2]*sds->res_min[2] + sds->obj_shift_f[2]; - p1[0] = sds->p0[0] + sds->cell_size[0]*sds->res_max[0] + sds->obj_shift_f[0]; - p1[1] = sds->p0[1] + sds->cell_size[1]*sds->res_max[1] + sds->obj_shift_f[1]; - p1[2] = sds->p0[2] + sds->cell_size[2]*sds->res_max[2] + sds->obj_shift_f[2]; + p0[0] = sds->p0[0] + sds->cell_size[0] * sds->res_min[0] + sds->obj_shift_f[0]; + p0[1] = sds->p0[1] + sds->cell_size[1] * sds->res_min[1] + sds->obj_shift_f[1]; + p0[2] = sds->p0[2] + sds->cell_size[2] * sds->res_min[2] + sds->obj_shift_f[2]; + p1[0] = sds->p0[0] + sds->cell_size[0] * sds->res_max[0] + sds->obj_shift_f[0]; + p1[1] = sds->p0[1] + sds->cell_size[1] * sds->res_max[1] + sds->obj_shift_f[1]; + p1[2] = sds->p0[2] + sds->cell_size[2] * sds->res_max[2] + sds->obj_shift_f[2]; /* scale cube to global space to equalize volume slicing on all axises - * (its scaled back before drawing) */ + * (its scaled back before drawing) */ mul_v3_v3(p0, ob->size); mul_v3_v3(p1, ob->size); @@ -6687,12 +6692,12 @@ 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 - #ifdef SMOKE_DEBUG_HEAT - draw_smoke_heat(smd->domain, ob); - #endif +#ifdef SMOKE_DEBUG_VELOCITY + draw_smoke_velocity(smd->domain, ob); +#endif +#ifdef SMOKE_DEBUG_HEAT + draw_smoke_heat(smd->domain, ob); +#endif } } } @@ -6954,7 +6959,7 @@ static void bbs_mesh_verts(BMEditMesh *em, DerivedMesh *dm, int offset) dm->foreachMappedVert(dm, bbs_mesh_verts__mapFunc, ptrs); bglEnd(); glPointSize(1.0); -} +} static DMDrawOption bbs_mesh_wire__setDrawOptions(void *userData, int index) { @@ -6974,7 +6979,7 @@ static void bbs_mesh_wire(BMEditMesh *em, DerivedMesh *dm, int offset) { void *ptrs[2] = {(void *)(intptr_t) offset, em}; dm->drawMappedEdges(dm, bbs_mesh_wire__setDrawOptions, ptrs); -} +} static DMDrawOption bbs_mesh_solid__setSolidDrawOptions(void *userData, int index) { @@ -7153,7 +7158,7 @@ void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec /* assumes all matrices/etc set OK */ /* helper function for drawing object instances - meshes */ -static void draw_object_mesh_instance(Scene *scene, View3D *v3d, RegionView3D *rv3d, +static void draw_object_mesh_instance(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, const short dt, int outline) { Mesh *me = ob->data; From d876e4876f45b9358e007108525756ba6cae5d2c Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Thu, 11 Oct 2012 08:26:49 +0000 Subject: [PATCH 180/347] Limit Distance Constraint - jpbouza Feature Request The Limit Distance constraint is now allowed to use the owner/target space settings. Previously this wasn't exposed it didn't seem sensible/useful. However, this can be useful when dealing with dependencies between bones and the armature gets scaled. Usage notes: - It is advised to select the same space for both owner and target, otherwise the comparisons are meaningless --- release/scripts/startup/bl_ui/properties_object_constraint.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/release/scripts/startup/bl_ui/properties_object_constraint.py b/release/scripts/startup/bl_ui/properties_object_constraint.py index fba7bd8712a..1eac232de88 100644 --- a/release/scripts/startup/bl_ui/properties_object_constraint.py +++ b/release/scripts/startup/bl_ui/properties_object_constraint.py @@ -485,6 +485,8 @@ class ConstraintButtonsPanel(): row.prop(con, "use_transform_limit") row.label() + self.space_template(layout, con) + def STRETCH_TO(self, context, layout, con): self.target_template(layout, con) From fc1467df5f35f3ec148513d3fed21b6347471bda Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Thu, 11 Oct 2012 09:53:17 +0000 Subject: [PATCH 181/347] Auto key warning - Stripping down to basics Now just a static icon + text display in corner of view. No blinking. No red/orange text. No window borders. --- source/blender/editors/transform/transform.c | 58 ++++++-------------- source/blender/editors/transform/transform.h | 2 - 2 files changed, 16 insertions(+), 44 deletions(-) diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 5e31de96e0e..5baca2c16b5 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -90,7 +90,6 @@ #include "BLI_linklist.h" #include "BLI_smallhash.h" #include "BLI_array.h" -#include "PIL_time.h" #include "UI_interface_icons.h" #include "UI_resources.h" @@ -1276,7 +1275,6 @@ int transformEvent(TransInfo *t, wmEvent *event) t->redraw |= t->handleEvent(t, event); if (handled || t->redraw) { - t->last_update = PIL_check_seconds_timer(); return 0; } else { @@ -1567,50 +1565,26 @@ static void drawTransformView(const struct bContext *C, ARegion *UNUSED(ar), voi /* just draw a little warning message in the top-right corner of the viewport to warn that autokeying is enabled */ static void drawAutoKeyWarning(TransInfo *t, ARegion *ar) { - int show_warning; + const char printable[] = "Auto Keying On"; + int xco, yco; - /* colored border around the viewport */ - UI_ThemeColor(TH_VERTEX_SELECT); + xco = ar->winx - BLF_width_default(printable) - 10; + yco = ar->winy - BLF_height_default(printable) - 10; - glBegin(GL_LINE_LOOP); - glVertex2f(1, 1); - glVertex2f(1, ar->winy-1); - glVertex2f(ar->winx-1, ar->winy-1); - glVertex2f(ar->winx-1, 1); - glEnd(); - - /* Entire warning should "blink" to catch periphery attention without being overly distracting - * much like how a traditional recording sign in the corner of a camcorder works - * - * - Blink frequency here is 0.5 secs (i.e. a compromise between epilepsy-inducing flicker + too slow to notice). - * We multiply by two to speed up the odd/even time-in-seconds = on/off toggle. - * - Always start with warning shown so that animators are more likely to notice when starting to transform + /* warning text (to clarify meaning of overlays) + * - original color was red to match the icon, but that clashes badly with a less nasty border */ - - show_warning = ((int)((t->last_update - floor(t->last_update)) * 2.0) & 1); + UI_ThemeColorShade(TH_TEXT_HI, -50); + BLF_draw_default_ascii(xco, ar->winy - 17, 0.0f, printable, sizeof(printable)); - if ((show_warning) || (t->state == TRANS_STARTING)) { - const char printable[] = "Auto Keying On"; - int xco, yco; - - xco = ar->winx - BLF_width_default(printable) - 10; - yco = ar->winy - BLF_height_default(printable) - 10; - - /* warning text (to clarify meaning of overlays) - * - original color was red to match the icon, but that clashes badly with a less nasty border - */ - UI_ThemeColor(TH_VERTEX_SELECT); - BLF_draw_default_ascii(xco, ar->winy - 17, 0.0f, printable, sizeof(printable)); - - /* autokey recording icon... */ - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_BLEND); - - xco -= (ICON_DEFAULT_WIDTH + 2); - UI_icon_draw(xco, yco, ICON_REC); - - glDisable(GL_BLEND); - } + /* autokey recording icon... */ + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + + xco -= (ICON_DEFAULT_WIDTH + 2); + UI_icon_draw(xco, yco, ICON_REC); + + glDisable(GL_BLEND); } static void drawTransformPixel(const struct bContext *UNUSED(C), ARegion *ar, void *arg) diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index 40f53423d37..1f9775821d1 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -323,8 +323,6 @@ typedef struct TransInfo { float axis[3]; float axis_orig[3]; /* TransCon can change 'axis', store the original value here */ - double last_update; /* Time of last update (in seconds) */ - void *view; struct bContext *context; /* Only valid (non null) during an operator called function. */ struct ScrArea *sa; From 1e448fa3e23a86d130c203a367a1ba2f9200a23d Mon Sep 17 00:00:00 2001 From: Jens Verwiebe Date: Thu, 11 Oct 2012 10:15:37 +0000 Subject: [PATCH 182/347] OSX/cmake: after osl librenew with globals patch, forcing oiio is not longer needed --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9ec75e9c782..38e3c5b2b01 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1609,7 +1609,7 @@ elseif(APPLE) if(WITH_OPENIMAGEIO) set(OPENIMAGEIO ${LIBDIR}/openimageio) set(OPENIMAGEIO_INCLUDE_DIRS ${OPENIMAGEIO}/include) - set(OPENIMAGEIO_LIBRARIES -force_load ${OPENIMAGEIO}/lib/libOpenImageIO.a ${PNG_LIBRARIES} ${JPEG_LIBRARIES} ${TIFF_LIBRARY} ${OPENEXR_LIBRARIES} ${ZLIB_LIBRARIES}) + set(OPENIMAGEIO_LIBRARIES ${OPENIMAGEIO}/lib/libOpenImageIO.a ${PNG_LIBRARIES} ${JPEG_LIBRARIES} ${TIFF_LIBRARY} ${OPENEXR_LIBRARIES} ${ZLIB_LIBRARIES}) set(OPENIMAGEIO_LIBPATH ${OPENIMAGEIO}/lib ${JPEG_LIBPATH} ${PNG_LIBPATH} ${TIFF_LIBPATH} ${OPENEXR_LIBPATH} ${ZLIB_LIBPATH}) set(OPENIMAGEIO_DEFINITIONS "-DOIIO_STATIC_BUILD") endif() From 38e5562447c54b2df27cf15b933bcf23dadc98b9 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Thu, 11 Oct 2012 10:19:38 +0000 Subject: [PATCH 183/347] Removed duplicate include of stdio.h At least on mingw, this doesn't seem to be needed. --- source/blender/editors/transform/transform.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 5baca2c16b5..ccb9fe4d076 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -96,8 +96,6 @@ #include "transform.h" -#include // XXX: duplicated??? - static void drawTransformApply(const struct bContext *C, ARegion *ar, void *arg); static int doEdgeSlide(TransInfo *t, float perc); From 0e6e171cddf6740d9c20113303b82695943e0899 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Thu, 11 Oct 2012 18:41:07 +0000 Subject: [PATCH 184/347] Revert part of own r51193 (now I know where Courant comes from...), and add another exception to UI messages spellchecker! Thanks to Lockal for pointing this. --- release/scripts/modules/bl_i18n_utils/spell_check_utils.py | 1 + source/blender/makesrna/intern/rna_particle.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/release/scripts/modules/bl_i18n_utils/spell_check_utils.py b/release/scripts/modules/bl_i18n_utils/spell_check_utils.py index 46b369146b7..609af832865 100644 --- a/release/scripts/modules/bl_i18n_utils/spell_check_utils.py +++ b/release/scripts/modules/bl_i18n_utils/spell_check_utils.py @@ -376,6 +376,7 @@ dict_uimsgs = { "catmull", "catrom", "chebychev", + "courant", "kutta", "lennard", "minkowski", diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c index 363d2dc020a..89638389fd2 100644 --- a/source/blender/makesrna/intern/rna_particle.c +++ b/source/blender/makesrna/intern/rna_particle.c @@ -2135,7 +2135,7 @@ static void rna_def_particle_settings(BlenderRNA *brna) RNA_def_property_float_default(prop, 0.2); RNA_def_property_ui_text(prop, "Adaptive Subframe Threshold", "The relative distance a particle can move before requiring more subframes " - "(target current number); 0.1-0.3 is the recommended range"); + "(target Courant number); 0.1-0.3 is the recommended range"); RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop = RNA_def_property(srna, "jitter_factor", PROP_FLOAT, PROP_NONE); From 4124e2e0c9d42ec8d84ef06025932abeb333cd65 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 11 Oct 2012 23:42:26 +0000 Subject: [PATCH 185/347] get the width and height of the font at once when drawing auto-key, also move BLF'g global font init into its own static function. --- source/blender/blenfont/BLF_api.h | 1 + source/blender/blenfont/intern/blf.c | 118 ++++++++++--------- source/blender/editors/transform/transform.c | 9 +- 3 files changed, 70 insertions(+), 58 deletions(-) diff --git a/source/blender/blenfont/BLF_api.h b/source/blender/blenfont/BLF_api.h index ce10951d6ff..6f348ccc267 100644 --- a/source/blender/blenfont/BLF_api.h +++ b/source/blender/blenfont/BLF_api.h @@ -109,6 +109,7 @@ float BLF_fixed_width(int fontid); * of the string, using the default font and both value * are multiplied by the aspect of the font. */ +void BLF_width_and_height_default(const char *str, float *width, float *height); float BLF_width_default(const char *str); float BLF_height_default(const char *str); diff --git a/source/blender/blenfont/intern/blf.c b/source/blender/blenfont/intern/blf.c index 92fcb576e7d..f3cc92e7a27 100644 --- a/source/blender/blenfont/intern/blf.c +++ b/source/blender/blenfont/intern/blf.c @@ -69,7 +69,7 @@ static int global_font_dpi = 72; int blf_mono_font = -1; int blf_mono_font_render = -1; -static FontBLF *BLF_get(int fontid) +static FontBLF *blf_get(int fontid) { if (fontid >= 0 && fontid < BLF_MAX_FONT) return global_font[fontid]; @@ -141,6 +141,21 @@ static int blf_search_available(void) return -1; } +static int blf_global_font_init(void) +{ + if (global_font_default == -1) { + global_font_default = blf_search("default"); + } + + if (global_font_default == -1) { + printf("Warning: Can't find default font!\n"); + return 0; + } + else { + return 1; + } +} + int BLF_load(const char *name) { FontBLF *font; @@ -219,7 +234,7 @@ int BLF_load_unique(const char *name) void BLF_metrics_attach(int fontid, unsigned char *mem, int mem_size) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font) { blf_font_attach_from_mem(font, mem, mem_size); @@ -311,7 +326,7 @@ void BLF_unload(const char *name) void BLF_enable(int fontid, int option) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font) { font->flags |= option; @@ -320,7 +335,7 @@ void BLF_enable(int fontid, int option) void BLF_disable(int fontid, int option) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font) { font->flags &= ~option; @@ -329,7 +344,7 @@ void BLF_disable(int fontid, int option) void BLF_enable_default(int option) { - FontBLF *font = BLF_get(global_font_default); + FontBLF *font = blf_get(global_font_default); if (font) { font->flags |= option; @@ -338,7 +353,7 @@ void BLF_enable_default(int option) void BLF_disable_default(int option) { - FontBLF *font = BLF_get(global_font_default); + FontBLF *font = blf_get(global_font_default); if (font) { font->flags &= ~option; @@ -347,7 +362,7 @@ void BLF_disable_default(int option) void BLF_aspect(int fontid, float x, float y, float z) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font) { font->aspect[0] = x; @@ -358,7 +373,7 @@ void BLF_aspect(int fontid, float x, float y, float z) void BLF_matrix(int fontid, const double m[16]) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font) { memcpy(font->m, m, sizeof(font->m)); @@ -367,7 +382,7 @@ void BLF_matrix(int fontid, const double m[16]) void BLF_position(int fontid, float x, float y, float z) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font) { float xa, ya, za; @@ -416,7 +431,7 @@ void BLF_position(int fontid, float x, float y, float z) void BLF_size(int fontid, int size, int dpi) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font) { blf_font_size(font, size, dpi); @@ -425,7 +440,7 @@ void BLF_size(int fontid, int size, int dpi) void BLF_blur(int fontid, int size) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font) { font->blur = size; @@ -437,13 +452,8 @@ void BLF_draw_default(float x, float y, float z, const char *str, size_t len) if (!str) return; - if (global_font_default == -1) - global_font_default = blf_search("default"); - - if (global_font_default == -1) { - printf("Warning: Can't found default font!!\n"); + if (!blf_global_font_init()) return; - } BLF_size(global_font_default, global_font_points, global_font_dpi); BLF_position(global_font_default, x, y, z); @@ -456,13 +466,8 @@ void BLF_draw_default_ascii(float x, float y, float z, const char *str, size_t l if (!str) return; - if (global_font_default == -1) - global_font_default = blf_search("default"); - - if (global_font_default == -1) { - printf("Warning: Can't found default font!!\n"); + if (!blf_global_font_init()) return; - } BLF_size(global_font_default, global_font_points, global_font_dpi); BLF_position(global_font_default, x, y, z); @@ -471,7 +476,7 @@ void BLF_draw_default_ascii(float x, float y, float z, const char *str, size_t l void BLF_rotation_default(float angle) { - FontBLF *font = BLF_get(global_font_default); + FontBLF *font = blf_get(global_font_default); if (font) { font->angle = angle; @@ -543,7 +548,7 @@ static void blf_draw__end(GLint mode, GLint param) void BLF_draw(int fontid, const char *str, size_t len) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); GLint mode, param; if (font && font->glyph_cache) { @@ -555,7 +560,7 @@ void BLF_draw(int fontid, const char *str, size_t len) void BLF_draw_ascii(int fontid, const char *str, size_t len) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); GLint mode, param; if (font && font->glyph_cache) { @@ -567,7 +572,7 @@ void BLF_draw_ascii(int fontid, const char *str, size_t len) void BLF_boundbox(int fontid, const char *str, rctf *box) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font) { blf_font_boundbox(font, str, box); @@ -576,16 +581,29 @@ void BLF_boundbox(int fontid, const char *str, rctf *box) void BLF_width_and_height(int fontid, const char *str, float *width, float *height) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font && font->glyph_cache) { blf_font_width_and_height(font, str, width, height); } + else { + *width = *height = 0.0f; + } +} + +void BLF_width_and_height_default(const char *str, float *width, float *height) +{ + if (!blf_global_font_init()) { + *width = *height = 0.0f; + return; + } + + BLF_width_and_height(global_font_default, str, width, height); } float BLF_width(int fontid, const char *str) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font && font->glyph_cache) { return blf_font_width(font, str); @@ -596,7 +614,7 @@ float BLF_width(int fontid, const char *str) float BLF_fixed_width(int fontid) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font && font->glyph_cache) { return blf_font_fixed_width(font); @@ -607,13 +625,8 @@ float BLF_fixed_width(int fontid) float BLF_width_default(const char *str) { - if (global_font_default == -1) - global_font_default = blf_search("default"); - - if (global_font_default == -1) { - printf("Error: Can't found default font!!\n"); + if (!blf_global_font_init()) return 0.0f; - } BLF_size(global_font_default, global_font_points, global_font_dpi); return BLF_width(global_font_default, str); @@ -621,7 +634,7 @@ float BLF_width_default(const char *str) float BLF_height(int fontid, const char *str) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font && font->glyph_cache) { return blf_font_height(font, str); @@ -632,7 +645,7 @@ float BLF_height(int fontid, const char *str) float BLF_height_max(int fontid) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font && font->glyph_cache) { return font->glyph_cache->max_glyph_height; @@ -643,7 +656,7 @@ float BLF_height_max(int fontid) float BLF_width_max(int fontid) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font && font->glyph_cache) { return font->glyph_cache->max_glyph_width; @@ -654,7 +667,7 @@ float BLF_width_max(int fontid) float BLF_descender(int fontid) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font && font->glyph_cache) { return font->glyph_cache->descender; @@ -665,7 +678,7 @@ float BLF_descender(int fontid) float BLF_ascender(int fontid) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font && font->glyph_cache) { return font->glyph_cache->ascender; @@ -676,13 +689,8 @@ float BLF_ascender(int fontid) float BLF_height_default(const char *str) { - if (global_font_default == -1) - global_font_default = blf_search("default"); - - if (global_font_default == -1) { - printf("Error: Can't found default font!!\n"); + if (!blf_global_font_init()) return 0.0f; - } BLF_size(global_font_default, global_font_points, global_font_dpi); @@ -691,7 +699,7 @@ float BLF_height_default(const char *str) void BLF_rotation(int fontid, float angle) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font) { font->angle = angle; @@ -700,7 +708,7 @@ void BLF_rotation(int fontid, float angle) void BLF_clipping(int fontid, float xmin, float ymin, float xmax, float ymax) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font) { font->clip_rec.xmin = xmin; @@ -712,7 +720,7 @@ void BLF_clipping(int fontid, float xmin, float ymin, float xmax, float ymax) void BLF_clipping_default(float xmin, float ymin, float xmax, float ymax) { - FontBLF *font = BLF_get(global_font_default); + FontBLF *font = blf_get(global_font_default); if (font) { font->clip_rec.xmin = xmin; @@ -724,7 +732,7 @@ void BLF_clipping_default(float xmin, float ymin, float xmax, float ymax) void BLF_shadow(int fontid, int level, float r, float g, float b, float a) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font) { font->shadow = level; @@ -737,7 +745,7 @@ void BLF_shadow(int fontid, int level, float r, float g, float b, float a) void BLF_shadow_offset(int fontid, int x, int y) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font) { font->shadow_x = x; @@ -747,7 +755,7 @@ void BLF_shadow_offset(int fontid, int x, int y) void BLF_buffer(int fontid, float *fbuf, unsigned char *cbuf, int w, int h, int nch, struct ColorManagedDisplay *display) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font) { font->buf_info.fbuf = fbuf; @@ -761,7 +769,7 @@ void BLF_buffer(int fontid, float *fbuf, unsigned char *cbuf, int w, int h, int void BLF_buffer_col(int fontid, float r, float g, float b, float a) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font) { font->buf_info.col[0] = r; @@ -773,7 +781,7 @@ void BLF_buffer_col(int fontid, float r, float g, float b, float a) void BLF_draw_buffer(int fontid, const char *str) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font && font->glyph_cache && (font->buf_info.fbuf || font->buf_info.cbuf)) { blf_font_buffer(font, str); diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index ccb9fe4d076..39b0ab4b3a6 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -1561,13 +1561,16 @@ static void drawTransformView(const struct bContext *C, ARegion *UNUSED(ar), voi } /* just draw a little warning message in the top-right corner of the viewport to warn that autokeying is enabled */ -static void drawAutoKeyWarning(TransInfo *t, ARegion *ar) +static void drawAutoKeyWarning(TransInfo *UNUSED(t), ARegion *ar) { const char printable[] = "Auto Keying On"; + float printable_size[2]; int xco, yco; + + BLF_width_and_height_default(printable, &printable_size[0], &printable_size[1]); - xco = ar->winx - BLF_width_default(printable) - 10; - yco = ar->winy - BLF_height_default(printable) - 10; + xco = ar->winx - (int)printable_size[0] - 10; + yco = ar->winy - (int)printable_size[1] - 10; /* warning text (to clarify meaning of overlays) * - original color was red to match the icon, but that clashes badly with a less nasty border From 28c20e456ff2c1cc85676e2dbf68d997d630e8a7 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 11 Oct 2012 23:46:12 +0000 Subject: [PATCH 186/347] fix for many RNA definitions having soft/hard ranges swapped, make this BLI_assert() on debug builds. --- source/blender/editors/armature/poseobject.c | 2 +- source/blender/editors/curve/editcurve.c | 4 +- source/blender/editors/mesh/editmesh_select.c | 4 +- source/blender/editors/mesh/editmesh_tools.c | 12 +++--- .../blender/editors/render/render_shading.c | 6 ++- source/blender/editors/space_clip/clip_ops.c | 4 +- .../blender/editors/space_clip/tracking_ops.c | 2 +- .../blender/editors/space_image/image_ops.c | 4 +- .../editors/space_sequencer/sequencer_edit.c | 4 +- .../makesdna/DNA_windowmanager_types.h | 2 +- source/blender/makesrna/intern/rna_define.c | 43 ++++++++++++++++--- .../blender/makesrna/intern/rna_image_api.c | 4 +- source/blender/makesrna/intern/rna_main_api.c | 4 +- .../blender/makesrna/intern/rna_texture_api.c | 4 +- source/blender/windowmanager/WM_types.h | 12 +++++- .../windowmanager/intern/wm_operators.c | 2 +- 16 files changed, 78 insertions(+), 35 deletions(-) diff --git a/source/blender/editors/armature/poseobject.c b/source/blender/editors/armature/poseobject.c index 189b2e977c2..365500a517b 100644 --- a/source/blender/editors/armature/poseobject.c +++ b/source/blender/editors/armature/poseobject.c @@ -1511,7 +1511,7 @@ void POSE_OT_group_assign(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ - RNA_def_int(ot->srna, "type", 0, 0, 10, "Bone Group Index", "", 0, INT_MAX); + RNA_def_int(ot->srna, "type", 0, 0, INT_MAX, "Bone Group Index", "", 0, 10); } diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index 42b42a594ce..98dc8aa6eb9 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -4421,7 +4421,7 @@ void CURVE_OT_spin(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; RNA_def_float_vector_xyz(ot->srna, "center", 3, NULL, -FLT_MAX, FLT_MAX, "Center", "Center in global view space", -FLT_MAX, FLT_MAX); - RNA_def_float_vector(ot->srna, "axis", 3, NULL, -1.0f, 1.0f, "Axis", "Axis in global view space", -FLT_MAX, FLT_MAX); + RNA_def_float_vector(ot->srna, "axis", 3, NULL, -FLT_MAX, FLT_MAX, "Axis", "Axis in global view space", -1.0f, 1.0f); } /***************** add vertex operator **********************/ @@ -5652,7 +5652,7 @@ void CURVE_OT_select_nth(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - RNA_def_int(ot->srna, "nth", 2, 2, 100, "Nth Selection", "", 1, INT_MAX); + RNA_def_int(ot->srna, "nth", 2, 2, INT_MAX, "Nth Selection", "", 2, 100); } /********************** add duplicate operator *********************/ diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index 32643cb20cd..fe3860de839 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -2292,8 +2292,8 @@ void MESH_OT_select_nth(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - RNA_def_int(ot->srna, "nth", 2, 2, 100, "Nth Selection", "", 1, INT_MAX); - RNA_def_int(ot->srna, "offset", 0, 0, 100, "Offset", "", 0, INT_MAX); + RNA_def_int(ot->srna, "nth", 2, 2, INT_MAX, "Nth Selection", "", 2, 100); + RNA_def_int(ot->srna, "offset", 0, 0, INT_MAX, "Offset", "", 0, 100); } void em_setup_viewcontext(bContext *C, ViewContext *vc) diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 891e1487781..44810048ad2 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -429,8 +429,8 @@ void MESH_OT_extrude_repeat(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* props */ - RNA_def_float(ot->srna, "offset", 2.0f, 0.0f, 100.0f, "Offset", "", 0.0f, FLT_MAX); - RNA_def_int(ot->srna, "steps", 10, 0, 180, "Steps", "", 0, INT_MAX); + RNA_def_float(ot->srna, "offset", 2.0f, 0.0f, FLT_MAX, "Offset", "", 0.0f, 100.0f); + RNA_def_int(ot->srna, "steps", 10, 0, INT_MAX, "Steps", "", 0, 180); } /* generic extern called extruder */ @@ -1607,7 +1607,7 @@ void MESH_OT_vertices_smooth(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - RNA_def_int(ot->srna, "repeat", 1, 1, 100, "Number of times to smooth the mesh", "", 1, INT_MAX); + RNA_def_int(ot->srna, "repeat", 1, 1, 1000, "Number of times to smooth the mesh", "", 1, 100); RNA_def_boolean(ot->srna, "xaxis", 1, "X-Axis", "Smooth along the X axis"); RNA_def_boolean(ot->srna, "yaxis", 1, "Y-Axis", "Smooth along the Y axis"); RNA_def_boolean(ot->srna, "zaxis", 1, "Z-Axis", "Smooth along the Z axis"); @@ -3542,7 +3542,7 @@ void MESH_OT_spin(wmOperatorType *ot) RNA_def_float(ot->srna, "degrees", 90.0f, -FLT_MAX, FLT_MAX, "Degrees", "Degrees", -360.0f, 360.0f); RNA_def_float_vector(ot->srna, "center", 3, NULL, -FLT_MAX, FLT_MAX, "Center", "Center in global view space", -FLT_MAX, FLT_MAX); - RNA_def_float_vector(ot->srna, "axis", 3, NULL, -1.0f, 1.0f, "Axis", "Axis in global view space", -FLT_MAX, FLT_MAX); + RNA_def_float_vector(ot->srna, "axis", 3, NULL, -FLT_MAX, FLT_MAX, "Axis", "Axis in global view space", -1.0f, 1.0f); } @@ -3666,8 +3666,8 @@ void MESH_OT_screw(wmOperatorType *ot) RNA_def_float_vector(ot->srna, "center", 3, NULL, -FLT_MAX, FLT_MAX, "Center", "Center in global view space", -FLT_MAX, FLT_MAX); - RNA_def_float_vector(ot->srna, "axis", 3, NULL, -1.0f, 1.0f, - "Axis", "Axis in global view space", -FLT_MAX, FLT_MAX); + RNA_def_float_vector(ot->srna, "axis", 3, NULL, -FLT_MAX, FLT_MAX, + "Axis", "Axis in global view space", -1.0f, 1.0f); } static int edbm_select_by_number_vertices_exec(bContext *C, wmOperator *op) diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c index 8bdd4e544e8..25a01d38dd5 100644 --- a/source/blender/editors/render/render_shading.c +++ b/source/blender/editors/render/render_shading.c @@ -747,7 +747,11 @@ void TEXTURE_OT_envmap_save(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER; /* no undo since this doesnt modify the env-map */ /* properties */ - prop = RNA_def_float_array(ot->srna, "layout", 12, default_envmap_layout, 0.0f, 0.0f, "File layout", "Flat array describing the X,Y position of each cube face in the output image, where 1 is the size of a face - order is [+Z -Z +Y -X -Y +X] (use -1 to skip a face)", 0.0f, 0.0f); + prop = RNA_def_float_array(ot->srna, "layout", 12, default_envmap_layout, 0.0f, 0.0f, + "File layout", + "Flat array describing the X,Y position of each cube face in the output image, " + "where 1 is the size of a face - order is [+Z -Z +Y -X -Y +X] " + "(use -1 to skip a face)", 0.0f, 0.0f); RNA_def_property_flag(prop, PROP_HIDDEN); WM_operator_properties_filesel(ot, FOLDERFILE | IMAGEFILE | MOVIEFILE, FILE_SPECIAL, FILE_SAVE, diff --git a/source/blender/editors/space_clip/clip_ops.c b/source/blender/editors/space_clip/clip_ops.c index 5c338f3e6f1..be5fa08f931 100644 --- a/source/blender/editors/space_clip/clip_ops.c +++ b/source/blender/editors/space_clip/clip_ops.c @@ -579,7 +579,7 @@ void CLIP_OT_view_zoom(wmOperatorType *ot) ot->flag = OPTYPE_BLOCKING | OPTYPE_GRAB_POINTER; /* properties */ - RNA_def_float(ot->srna, "factor", 0.0f, 0.0f, FLT_MAX, + RNA_def_float(ot->srna, "factor", 0.0f, -FLT_MAX, FLT_MAX, "Factor", "Zoom factor, values higher than 1.0 zoom in, lower values zoom out", -FLT_MAX, FLT_MAX); } @@ -700,7 +700,7 @@ void CLIP_OT_view_zoom_ratio(wmOperatorType *ot) ot->poll = ED_space_clip_view_clip_poll; /* properties */ - RNA_def_float(ot->srna, "ratio", 0.0f, 0.0f, FLT_MAX, + RNA_def_float(ot->srna, "ratio", 0.0f, -FLT_MAX, FLT_MAX, "Ratio", "Zoom ratio, 1.0 is 1:1, higher is zoomed in, lower is zoomed out", -FLT_MAX, FLT_MAX); } diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c index 8dc28bbaee0..1af6237689c 100644 --- a/source/blender/editors/space_clip/tracking_ops.c +++ b/source/blender/editors/space_clip/tracking_ops.c @@ -154,7 +154,7 @@ void CLIP_OT_add_marker(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ - RNA_def_float_vector(ot->srna, "location", 2, NULL, -FLT_MIN, FLT_MAX, + RNA_def_float_vector(ot->srna, "location", 2, NULL, -FLT_MAX, FLT_MAX, "Location", "Location of marker on frame", -1.0f, 1.0f); } diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index c7ad82dec85..405fb5a9243 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -496,7 +496,7 @@ void IMAGE_OT_view_zoom(wmOperatorType *ot) ot->flag = OPTYPE_BLOCKING; /* properties */ - RNA_def_float(ot->srna, "factor", 0.0f, 0.0f, FLT_MAX, + RNA_def_float(ot->srna, "factor", 0.0f, -FLT_MAX, FLT_MAX, "Factor", "Zoom factor, values higher than 1.0 zoom in, lower values zoom out", -FLT_MAX, FLT_MAX); } @@ -800,7 +800,7 @@ void IMAGE_OT_view_zoom_ratio(wmOperatorType *ot) ot->poll = space_image_main_area_poll; /* properties */ - RNA_def_float(ot->srna, "ratio", 0.0f, 0.0f, FLT_MAX, + RNA_def_float(ot->srna, "ratio", 0.0f, -FLT_MAX, FLT_MAX, "Ratio", "Zoom ratio, 1.0 is 1:1, higher is zoomed in, lower is zoomed out", -FLT_MAX, FLT_MAX); } diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index 459a8d54d12..95d827f9392 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -1853,7 +1853,7 @@ void SEQUENCER_OT_images_separate(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - RNA_def_int(ot->srna, "length", 1, 1, 1000, "Length", "Length of each frame", 1, INT_MAX); + RNA_def_int(ot->srna, "length", 1, 1, INT_MAX, "Length", "Length of each frame", 1, 1000); } @@ -2188,7 +2188,7 @@ void SEQUENCER_OT_view_zoom_ratio(wmOperatorType *ot) ot->poll = ED_operator_sequencer_active; /* properties */ - RNA_def_float(ot->srna, "ratio", 1.0f, 0.0f, FLT_MAX, + RNA_def_float(ot->srna, "ratio", 1.0f, -FLT_MAX, FLT_MAX, "Ratio", "Zoom ratio, 1.0 is 1:1, higher is zoomed in, lower is zoomed out", -FLT_MAX, FLT_MAX); } diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h index 780ca0b5878..2294abc0735 100644 --- a/source/blender/makesdna/DNA_windowmanager_types.h +++ b/source/blender/makesdna/DNA_windowmanager_types.h @@ -334,7 +334,7 @@ typedef struct wmOperator { #define OPERATOR_FLAGS_ALL ((1<<5)-1) /* sanity checks for debug mode only */ -#define OPERATOR_RETVAL_CHECK(ret) BLI_assert(ret != 0 && (ret & OPERATOR_FLAGS_ALL) == ret) +#define OPERATOR_RETVAL_CHECK(ret) (void)ret, BLI_assert(ret != 0 && (ret & OPERATOR_FLAGS_ALL) == ret) /* wmOperator flag */ #define OP_GRAB_POINTER 1 diff --git a/source/blender/makesrna/intern/rna_define.c b/source/blender/makesrna/intern/rna_define.c index 45092d09ce1..d4e0ba68d9d 100644 --- a/source/blender/makesrna/intern/rna_define.c +++ b/source/blender/makesrna/intern/rna_define.c @@ -46,6 +46,17 @@ #include "rna_internal.h" + +#ifdef DEBUG +# define ASSERT_SOFT_HARD_LIMITS \ + if (softmin < hardmin || softmax > hardmax) { \ + fprintf(stderr, "Error with soft/hard limits: %s.%s\n", CONTAINER_RNA_ID(cont), identifier); \ + BLI_assert(!"invalid soft/hard limits"); \ + } (void)0 +#else +# define ASSERT_SOFT_HARD_LIMITS (void)0 +#endif + /* Global used during defining */ BlenderDefRNA DefRNA = {NULL, {NULL, NULL}, {NULL, NULL}, NULL, 0, 0, 0, 1}; @@ -2248,12 +2259,15 @@ PropertyRNA *RNA_def_boolean_vector(StructOrFunctionRNA *cont_, const char *iden return prop; } -PropertyRNA *RNA_def_int(StructOrFunctionRNA *cont_, const char *identifier, int default_value, int hardmin, - int hardmax, const char *ui_name, const char *ui_description, int softmin, int softmax) +PropertyRNA *RNA_def_int(StructOrFunctionRNA *cont_, const char *identifier, int default_value, + int hardmin, int hardmax, const char *ui_name, const char *ui_description, + int softmin, int softmax) { ContainerRNA *cont = cont_; PropertyRNA *prop; + ASSERT_SOFT_HARD_LIMITS; + prop = RNA_def_property(cont, identifier, PROP_INT, PROP_NONE); RNA_def_property_int_default(prop, default_value); if (hardmin != hardmax) RNA_def_property_range(prop, hardmin, hardmax); @@ -2270,6 +2284,8 @@ PropertyRNA *RNA_def_int_vector(StructOrFunctionRNA *cont_, const char *identifi ContainerRNA *cont = cont_; PropertyRNA *prop; + ASSERT_SOFT_HARD_LIMITS; + prop = RNA_def_property(cont, identifier, PROP_INT, PROP_XYZ); /* XXX */ if (len != 0) RNA_def_property_array(prop, len); if (default_value) RNA_def_property_int_array_default(prop, default_value); @@ -2287,6 +2303,8 @@ PropertyRNA *RNA_def_int_array(StructOrFunctionRNA *cont_, const char *identifie ContainerRNA *cont = cont_; PropertyRNA *prop; + ASSERT_SOFT_HARD_LIMITS; + prop = RNA_def_property(cont, identifier, PROP_INT, PROP_NONE); if (len != 0) RNA_def_property_array(prop, len); if (default_value) RNA_def_property_int_array_default(prop, default_value); @@ -2426,6 +2444,8 @@ PropertyRNA *RNA_def_float(StructOrFunctionRNA *cont_, const char *identifier, f ContainerRNA *cont = cont_; PropertyRNA *prop; + ASSERT_SOFT_HARD_LIMITS; + prop = RNA_def_property(cont, identifier, PROP_FLOAT, PROP_NONE); RNA_def_property_float_default(prop, default_value); if (hardmin != hardmax) RNA_def_property_range(prop, hardmin, hardmax); @@ -2442,6 +2462,8 @@ PropertyRNA *RNA_def_float_vector(StructOrFunctionRNA *cont_, const char *identi ContainerRNA *cont = cont_; PropertyRNA *prop; + ASSERT_SOFT_HARD_LIMITS; + prop = RNA_def_property(cont, identifier, PROP_FLOAT, PROP_XYZ); if (len != 0) RNA_def_property_array(prop, len); if (default_value) RNA_def_property_float_array_default(prop, default_value); @@ -2472,6 +2494,8 @@ PropertyRNA *RNA_def_float_color(StructOrFunctionRNA *cont_, const char *identif ContainerRNA *cont = cont_; PropertyRNA *prop; + ASSERT_SOFT_HARD_LIMITS; + prop = RNA_def_property(cont, identifier, PROP_FLOAT, PROP_COLOR); if (len != 0) RNA_def_property_array(prop, len); if (default_value) RNA_def_property_float_array_default(prop, default_value); @@ -2489,10 +2513,9 @@ PropertyRNA *RNA_def_float_matrix(StructOrFunctionRNA *cont_, const char *identi { ContainerRNA *cont = cont_; PropertyRNA *prop; - int length[2]; + const int length[2] = {rows, columns}; - length[0] = rows; - length[1] = columns; + ASSERT_SOFT_HARD_LIMITS; prop = RNA_def_property(cont, identifier, PROP_FLOAT, PROP_MATRIX); RNA_def_property_multi_array(prop, 2, length); @@ -2510,7 +2533,9 @@ PropertyRNA *RNA_def_float_rotation(StructOrFunctionRNA *cont_, const char *iden { ContainerRNA *cont = cont_; PropertyRNA *prop; - + + ASSERT_SOFT_HARD_LIMITS; + prop = RNA_def_property(cont, identifier, PROP_FLOAT, (len != 0) ? PROP_EULER : PROP_ANGLE); if (len != 0) { RNA_def_property_array(prop, len); @@ -2534,6 +2559,8 @@ PropertyRNA *RNA_def_float_array(StructOrFunctionRNA *cont_, const char *identif ContainerRNA *cont = cont_; PropertyRNA *prop; + ASSERT_SOFT_HARD_LIMITS; + prop = RNA_def_property(cont, identifier, PROP_FLOAT, PROP_NONE); if (len != 0) RNA_def_property_array(prop, len); if (default_value) RNA_def_property_float_array_default(prop, default_value); @@ -2551,6 +2578,8 @@ PropertyRNA *RNA_def_float_percentage(StructOrFunctionRNA *cont_, const char *id ContainerRNA *cont = cont_; PropertyRNA *prop; + ASSERT_SOFT_HARD_LIMITS; + prop = RNA_def_property(cont, identifier, PROP_FLOAT, PROP_PERCENTAGE); RNA_def_property_float_default(prop, default_value); if (hardmin != hardmax) RNA_def_property_range(prop, hardmin, hardmax); @@ -2567,6 +2596,8 @@ PropertyRNA *RNA_def_float_factor(StructOrFunctionRNA *cont_, const char *identi ContainerRNA *cont = cont_; PropertyRNA *prop; + ASSERT_SOFT_HARD_LIMITS; + prop = RNA_def_property(cont, identifier, PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_default(prop, default_value); if (hardmin != hardmax) RNA_def_property_range(prop, hardmin, hardmax); diff --git a/source/blender/makesrna/intern/rna_image_api.c b/source/blender/makesrna/intern/rna_image_api.c index 7766dff4273..ab501909052 100644 --- a/source/blender/makesrna/intern/rna_image_api.c +++ b/source/blender/makesrna/intern/rna_image_api.c @@ -297,9 +297,9 @@ void RNA_api_image(StructRNA *srna) func = RNA_def_function(srna, "scale", "rna_Image_scale"); RNA_def_function_ui_description(func, "Scale the image in pixels"); RNA_def_function_flag(func, FUNC_USE_REPORTS); - parm = RNA_def_int(func, "width", 0, 1, 10000, "", "Width", 1, 10000); + parm = RNA_def_int(func, "width", 1, 1, 10000, "", "Width", 1, 10000); RNA_def_property_flag(parm, PROP_REQUIRED); - parm = RNA_def_int(func, "height", 0, 1, 10000, "", "Height", 1, 10000); + parm = RNA_def_int(func, "height", 1, 1, 10000, "", "Height", 1, 10000); RNA_def_property_flag(parm, PROP_REQUIRED); func = RNA_def_function(srna, "gl_touch", "rna_Image_gl_touch"); diff --git a/source/blender/makesrna/intern/rna_main_api.c b/source/blender/makesrna/intern/rna_main_api.c index cd9b3965713..8e21ab3f7e9 100644 --- a/source/blender/makesrna/intern/rna_main_api.c +++ b/source/blender/makesrna/intern/rna_main_api.c @@ -990,9 +990,9 @@ void RNA_def_main_images(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_ui_description(func, "Add a new image to the main database"); parm = RNA_def_string(func, "name", "Image", 0, "", "New name for the datablock"); RNA_def_property_flag(parm, PROP_REQUIRED); - parm = RNA_def_int(func, "width", 1024, 1, INT_MAX, "", "Width of the image", 0, INT_MAX); + parm = RNA_def_int(func, "width", 1024, 1, INT_MAX, "", "Width of the image", 1, INT_MAX); RNA_def_property_flag(parm, PROP_REQUIRED); - parm = RNA_def_int(func, "height", 1024, 1, INT_MAX, "", "Height of the image", 0, INT_MAX); + parm = RNA_def_int(func, "height", 1024, 1, INT_MAX, "", "Height of the image", 1, INT_MAX); RNA_def_property_flag(parm, PROP_REQUIRED); RNA_def_boolean(func, "alpha", 0, "Alpha", "Use alpha channel"); RNA_def_boolean(func, "float_buffer", 0, "Float Buffer", "Create an image with floating point color"); diff --git a/source/blender/makesrna/intern/rna_texture_api.c b/source/blender/makesrna/intern/rna_texture_api.c index a2880510958..5be9d3a0dec 100644 --- a/source/blender/makesrna/intern/rna_texture_api.c +++ b/source/blender/makesrna/intern/rna_texture_api.c @@ -120,10 +120,10 @@ void RNA_api_environment_map(StructRNA *srna) RNA_def_pointer(func, "scene", "Scene", "", "Overrides the scene from which image parameters are taken"); - RNA_def_float_array(func, "layout", 12, default_layout, 0.0f, 0.0f, "File layout", + RNA_def_float_array(func, "layout", 12, default_layout, 0.0f, 1000.0f, "File layout", "Flat array describing the X,Y position of each cube face in the " "output image, where 1 is the size of a face - order is [+Z -Z +Y -X -Y +X] " - "(use -1 to skip a face)", 0.0f, 0.0f); + "(use -1 to skip a face)", 0.0f, 1000.0f); } #endif diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h index ad828cef6d5..764d274bfba 100644 --- a/source/blender/windowmanager/WM_types.h +++ b/source/blender/windowmanager/WM_types.h @@ -539,7 +539,11 @@ typedef struct wmOperatorType { /* verify if the operator can be executed in the current context, note * that the operator might still fail to execute even if this return true */ - int (*poll)(struct bContext *); + int (*poll)(struct bContext *) +#ifdef __GNUC__ + __attribute__((warn_unused_result)) +#endif + ; /* optional panel for redo and repeat, autogenerated if not set */ void (*ui)(struct bContext *, struct wmOperator *); @@ -563,7 +567,11 @@ typedef struct wmOperatorType { /* only used for operators defined with python * use to store pointers to python functions */ void *pyop_data; - int (*pyop_poll)(struct bContext *, struct wmOperatorType *ot); + int (*pyop_poll)(struct bContext *, struct wmOperatorType *ot) +#ifdef __GNUC__ + __attribute__((warn_unused_result)) +#endif + ; /* RNA integration */ ExtensionRNA ext; diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index ec25e8dcffb..19c2a58fdfc 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -1233,7 +1233,7 @@ static void WM_OT_debug_menu(wmOperatorType *ot) ot->exec = wm_debug_menu_exec; ot->poll = WM_operator_winactive; - RNA_def_int(ot->srna, "debug_value", 0, -10000, 10000, "Debug Value", "", INT_MIN, INT_MAX); + RNA_def_int(ot->srna, "debug_value", 0, SHRT_MIN, SHRT_MAX, "Debug Value", "", -10000, 10000); } From 40186a8c1166284c27c05dd86560ada8625652ea Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 12 Oct 2012 00:18:32 +0000 Subject: [PATCH 187/347] remove BLI_noise from BLI_blenlib.h, not that many files need this. --- source/blender/blenkernel/intern/effect.c | 1 + source/blender/blenkernel/intern/fmodifier.c | 1 + source/blender/blenkernel/intern/particle.c | 1 + source/blender/blenlib/BLI_blenlib.h | 2 -- source/blender/editors/mesh/editmesh_tools.c | 1 + source/blender/python/mathutils/mathutils_noise.c | 1 + source/blender/render/intern/source/pointdensity.c | 1 + source/blender/render/intern/source/render_texture.c | 1 + 8 files changed, 7 insertions(+), 2 deletions(-) diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c index 495814acbee..a9571406b7e 100644 --- a/source/blender/blenkernel/intern/effect.c +++ b/source/blender/blenkernel/intern/effect.c @@ -54,6 +54,7 @@ #include "BLI_math.h" #include "BLI_blenlib.h" +#include "BLI_noise.h" #include "BLI_jitter.h" #include "BLI_rand.h" #include "BLI_utildefines.h" diff --git a/source/blender/blenkernel/intern/fmodifier.c b/source/blender/blenkernel/intern/fmodifier.c index 68321076398..1e6eb77f666 100644 --- a/source/blender/blenkernel/intern/fmodifier.c +++ b/source/blender/blenkernel/intern/fmodifier.c @@ -42,6 +42,7 @@ #include "BLF_translation.h" #include "BLI_blenlib.h" +#include "BLI_noise.h" #include "BLI_math.h" /* windows needs for M_PI */ #include "BLI_utildefines.h" diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 89dadcd8dd5..cf5ea7e074f 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -48,6 +48,7 @@ #include "DNA_dynamicpaint_types.h" #include "BLI_blenlib.h" +#include "BLI_noise.h" #include "BLI_math.h" #include "BLI_utildefines.h" #include "BLI_kdtree.h" diff --git a/source/blender/blenlib/BLI_blenlib.h b/source/blender/blenlib/BLI_blenlib.h index 74b477bacaf..03b75975af4 100644 --- a/source/blender/blenlib/BLI_blenlib.h +++ b/source/blender/blenlib/BLI_blenlib.h @@ -78,8 +78,6 @@ extern "C" { #include "BLI_rect.h" -#include "BLI_noise.h" - #ifdef __cplusplus } #endif diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 44810048ad2..ee12e971325 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -42,6 +42,7 @@ #include "RNA_access.h" #include "BLI_blenlib.h" +#include "BLI_noise.h" #include "BLI_math.h" #include "BLI_rand.h" diff --git a/source/blender/python/mathutils/mathutils_noise.c b/source/blender/python/mathutils/mathutils_noise.c index da32e36dc02..4977663038d 100644 --- a/source/blender/python/mathutils/mathutils_noise.c +++ b/source/blender/python/mathutils/mathutils_noise.c @@ -43,6 +43,7 @@ #include "BLI_blenlib.h" #include "BLI_math.h" +#include "BLI_noise.h" #include "BLI_utildefines.h" #include "MEM_guardedalloc.h" diff --git a/source/blender/render/intern/source/pointdensity.c b/source/blender/render/intern/source/pointdensity.c index a93dde7e813..ea92be6153c 100644 --- a/source/blender/render/intern/source/pointdensity.c +++ b/source/blender/render/intern/source/pointdensity.c @@ -36,6 +36,7 @@ #include "BLI_math.h" #include "BLI_blenlib.h" +#include "BLI_noise.h" #include "BLI_kdopbvh.h" #include "BLI_utildefines.h" diff --git a/source/blender/render/intern/source/render_texture.c b/source/blender/render/intern/source/render_texture.c index 9bd2395ca79..030b7d68163 100644 --- a/source/blender/render/intern/source/render_texture.c +++ b/source/blender/render/intern/source/render_texture.c @@ -35,6 +35,7 @@ #include "BLI_blenlib.h" #include "BLI_math.h" +#include "BLI_noise.h" #include "BLI_rand.h" #include "BLI_utildefines.h" From f97dfdf227d1fa324a9c41bb83e53b5a46578a4d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 12 Oct 2012 03:24:47 +0000 Subject: [PATCH 188/347] quiet clang static checker warning by returning an error for invalid situation getting an IDProp mapping from a PyObject. also print the path installed to when installing an addon. --- release/scripts/startup/bl_operators/wm.py | 7 +++++-- source/blender/python/generic/idprop_py_api.c | 4 +++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py index af33f80bdf8..21cd2b47f71 100644 --- a/release/scripts/startup/bl_operators/wm.py +++ b/release/scripts/startup/bl_operators/wm.py @@ -1822,8 +1822,11 @@ class WM_OT_addon_install(Operator): # in case a new module path was created to install this addon. bpy.utils.refresh_script_paths() - # TODO, should not be a warning. - #~ self.report({'WARNING'}, "File installed to '%s'\n" % path_dest) + # print message + msg = "File %r installed into %r\n" % (pyfile, path_dest) + self.report({'INFO'}, msg) + print(msg) + return {'FINISHED'} def invoke(self, context, event): diff --git a/source/blender/python/generic/idprop_py_api.c b/source/blender/python/generic/idprop_py_api.c index 06b6192a091..23af0683d18 100644 --- a/source/blender/python/generic/idprop_py_api.c +++ b/source/blender/python/generic/idprop_py_api.c @@ -427,6 +427,8 @@ const char *BPy_IDProperty_Map_ValidateAndCreate(PyObject *name_obj, IDProperty return error; } break; + default: + return "internal error with idp array.type"; } } else if (PyMapping_Check(ob)) { @@ -471,7 +473,7 @@ const char *BPy_IDProperty_Map_ValidateAndCreate(PyObject *name_obj, IDProperty if (group->type == IDP_IDPARRAY) { IDP_AppendArray(group, prop); - // IDP_FreeProperty(item); // IDP_AppendArray does a shallow copy (memcpy), only free memory + // IDP_FreeProperty(item); /* IDP_AppendArray does a shallow copy (memcpy), only free memory */ MEM_freeN(prop); } else { From 8437980b8136bb3930e0ae13c13c5e1075a3471e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 12 Oct 2012 03:59:50 +0000 Subject: [PATCH 189/347] optimization for PyObject -> ID-property sequence conversion, use PySequence_Fast. --- source/blender/python/generic/idprop_py_api.c | 41 +++++++++++-------- 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/source/blender/python/generic/idprop_py_api.c b/source/blender/python/generic/idprop_py_api.c index 23af0683d18..d4ec8137399 100644 --- a/source/blender/python/generic/idprop_py_api.c +++ b/source/blender/python/generic/idprop_py_api.c @@ -300,40 +300,34 @@ static PyObject *BPy_IDGroup_Map_GetItem(BPy_IDProperty *self, PyObject *item) } /* returns NULL on success, error string on failure */ -static int idp_sequence_type(PyObject *seq) +static int idp_sequence_type(PyObject *seq_fast) { PyObject *item; int type = IDP_INT; - Py_ssize_t i, len = PySequence_Size(seq); + Py_ssize_t i, len = PySequence_Fast_GET_SIZE(seq_fast); for (i = 0; i < len; i++) { - item = PySequence_GetItem(seq, i); + item = PySequence_Fast_GET_ITEM(seq_fast, i); if (PyFloat_Check(item)) { if (type == IDP_IDPARRAY) { /* mixed dict/int */ - Py_DECREF(item); return -1; } type = IDP_DOUBLE; } else if (PyLong_Check(item)) { if (type == IDP_IDPARRAY) { /* mixed dict/int */ - Py_DECREF(item); return -1; } } else if (PyMapping_Check(item)) { if (i != 0 && (type != IDP_IDPARRAY)) { /* mixed dict/int */ - Py_DECREF(item); return -1; } type = IDP_IDPARRAY; } else { - Py_XDECREF(item); return -1; } - - Py_DECREF(item); } return type; @@ -386,50 +380,61 @@ const char *BPy_IDProperty_Map_ValidateAndCreate(PyObject *name_obj, IDProperty //prop->subtype = IDP_STRING_SUB_BYTE; } else if (PySequence_Check(ob)) { + PyObject *ob_seq_fast = PySequence_Fast(ob, "py -> idprop"); PyObject *item; int i; - if ((val.array.type = idp_sequence_type(ob)) == -1) + if (ob_seq_fast == NULL) { + PyErr_Print(); + PyErr_Clear(); + return "error converting the sequence"; + } + + if ((val.array.type = idp_sequence_type(ob_seq_fast)) == -1) { + Py_DECREF(ob_seq_fast); return "only floats, ints and dicts are allowed in ID property arrays"; + } /* validate sequence and derive type. * we assume IDP_INT unless we hit a float * number; then we assume it's */ - val.array.len = PySequence_Size(ob); + val.array.len = PySequence_Fast_GET_SIZE(ob_seq_fast); switch (val.array.type) { case IDP_DOUBLE: prop = IDP_New(IDP_ARRAY, &val, name); for (i = 0; i < val.array.len; i++) { - item = PySequence_GetItem(ob, i); + item = PySequence_Fast_GET_ITEM(ob_seq_fast, i); ((double *)IDP_Array(prop))[i] = (float)PyFloat_AsDouble(item); - Py_DECREF(item); } break; case IDP_INT: prop = IDP_New(IDP_ARRAY, &val, name); for (i = 0; i < val.array.len; i++) { - item = PySequence_GetItem(ob, i); + item = PySequence_Fast_GET_ITEM(ob_seq_fast, i); ((int *)IDP_Array(prop))[i] = (int)PyLong_AsSsize_t(item); - Py_DECREF(item); } break; case IDP_IDPARRAY: prop = IDP_NewIDPArray(name); for (i = 0; i < val.array.len; i++) { const char *error; - item = PySequence_GetItem(ob, i); + item = PySequence_Fast_GET_ITEM(ob_seq_fast, i); error = BPy_IDProperty_Map_ValidateAndCreate(NULL, prop, item); - Py_DECREF(item); - if (error) + if (error) { + Py_DECREF(ob_seq_fast); return error; + } } break; default: + Py_DECREF(ob_seq_fast); return "internal error with idp array.type"; } + + Py_DECREF(ob_seq_fast); } else if (PyMapping_Check(ob)) { PyObject *keys, *vals, *key, *pval; From 3d9812c5d1340affd4304835f59f72f7eba10cd7 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 12 Oct 2012 04:00:41 +0000 Subject: [PATCH 190/347] fix for own error in copy_as_script(), imports were incorrect. --- release/scripts/modules/console_python.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/release/scripts/modules/console_python.py b/release/scripts/modules/console_python.py index 18d448b764f..60dfa2b6344 100644 --- a/release/scripts/modules/console_python.py +++ b/release/scripts/modules/console_python.py @@ -294,8 +294,8 @@ def copy_as_script(context): sc = context.space_data lines = [ "import bpy", - "import bpy.context as C", - "import bpy.data as D", + "from bpy import data as D", + "from bpy import context as C", "from mathutils import *", "from math import *", "", From d4ed5ab92a80cc953947e25262591d8c5f39fcd5 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 12 Oct 2012 14:03:43 +0000 Subject: [PATCH 191/347] code cleanup: video playback move frame step into the PlayState struct. --- .../windowmanager/intern/wm_playanim.c | 47 ++++++++++--------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/source/blender/windowmanager/intern/wm_playanim.c b/source/blender/windowmanager/intern/wm_playanim.c index 35cc1545c40..cf5bce568d5 100644 --- a/source/blender/windowmanager/intern/wm_playanim.c +++ b/source/blender/windowmanager/intern/wm_playanim.c @@ -89,6 +89,8 @@ typedef struct PlayState { short stopped; short go; + int fstep; + /* current picture */ struct PlayAnimPict *picture; @@ -213,7 +215,6 @@ typedef struct PlayAnimPict { static struct ListBase picsbase = {NULL, NULL}; static int fromdisk = FALSE; -static int fstep = 1; static float zoomx = 1.0, zoomy = 1.0; static double ptottime = 0.0, swaptime = 0.04; @@ -229,7 +230,7 @@ static int pupdate_time(void) return (ptottime < 0); } -static void playanim_toscreen(PlayAnimPict *picture, struct ImBuf *ibuf, int fontid) +static void playanim_toscreen(PlayAnimPict *picture, struct ImBuf *ibuf, int fontid, int fstep) { if (ibuf == NULL) { @@ -287,7 +288,7 @@ static void build_pict_list(char *first, int totframes, int fstep, int fontid) int pic; ibuf = IMB_anim_absolute(anim, 0, IMB_TC_NONE, IMB_PROXY_NONE); if (ibuf) { - playanim_toscreen(NULL, ibuf, fontid); + playanim_toscreen(NULL, ibuf, fontid, fstep); IMB_freeImBuf(ibuf); } @@ -390,7 +391,7 @@ static void build_pict_list(char *first, int totframes, int fstep, int fontid) ibuf = IMB_loadiffname(picture->name, picture->IB_flags, NULL); } if (ibuf) { - playanim_toscreen(picture, ibuf, fontid); + playanim_toscreen(picture, ibuf, fontid, fstep); IMB_freeImBuf(ibuf); } pupdate_time(); @@ -446,34 +447,34 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void) if (val) ps->pingpong = !ps->pingpong; break; case GHOST_kKeyNumpad1: - if (val) swaptime = fstep / 60.0; + if (val) swaptime = ps->fstep / 60.0; break; case GHOST_kKeyNumpad2: - if (val) swaptime = fstep / 50.0; + if (val) swaptime = ps->fstep / 50.0; break; case GHOST_kKeyNumpad3: - if (val) swaptime = fstep / 30.0; + if (val) swaptime = ps->fstep / 30.0; break; case GHOST_kKeyNumpad4: if (g_WS.qual & WS_QUAL_SHIFT) - swaptime = fstep / 24.0; + swaptime = ps->fstep / 24.0; else - swaptime = fstep / 25.0; + swaptime = ps->fstep / 25.0; break; case GHOST_kKeyNumpad5: - if (val) swaptime = fstep / 20.0; + if (val) swaptime = ps->fstep / 20.0; break; case GHOST_kKeyNumpad6: - if (val) swaptime = fstep / 15.0; + if (val) swaptime = ps->fstep / 15.0; break; case GHOST_kKeyNumpad7: - if (val) swaptime = fstep / 12.0; + if (val) swaptime = ps->fstep / 12.0; break; case GHOST_kKeyNumpad8: - if (val) swaptime = fstep / 10.0; + if (val) swaptime = ps->fstep / 10.0; break; case GHOST_kKeyNumpad9: - if (val) swaptime = fstep / 6.0; + if (val) swaptime = ps->fstep / 6.0; break; case GHOST_kKeyLeftArrow: if (val) { @@ -531,10 +532,10 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void) if (val) { if (g_WS.qual & WS_QUAL_SHIFT) { if (ps->curframe_ibuf) - printf(" Name: %s | Speed: %.2f frames/s\n", ps->curframe_ibuf->name, fstep / swaptime); + printf(" Name: %s | Speed: %.2f frames/s\n", ps->curframe_ibuf->name, ps->fstep / swaptime); } else { - swaptime = fstep / 5.0; + swaptime = ps->fstep / 5.0; } } break; @@ -675,7 +676,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void) glPixelZoom(zoomx, zoomy); glEnable(GL_DITHER); ptottime = 0.0; - playanim_toscreen(ps->picture, ps->curframe_ibuf, ps->fontid); + playanim_toscreen(ps->picture, ps->curframe_ibuf, ps->fontid, ps->fstep); break; } @@ -747,6 +748,8 @@ void WM_main_playanim(int argc, const char **argv) ps.picture = NULL; /* resetmap = FALSE */ + ps.fstep = 1; + ps.fontid = -1; while (argc > 1) { @@ -794,8 +797,8 @@ void WM_main_playanim(int argc, const char **argv) argv++; break; case 'j': - fstep = MIN2(MAXFRAME, MAX2(1, atoi(argv[2]))); - swaptime *= fstep; + ps.fstep = MIN2(MAXFRAME, MAX2(1, atoi(argv[2]))); + swaptime *= ps.fstep; argc--; argv++; break; @@ -894,11 +897,11 @@ void WM_main_playanim(int argc, const char **argv) efra = MAXFRAME; } - build_pict_list(filepath, (efra - sfra) + 1, fstep, ps.fontid); + build_pict_list(filepath, (efra - sfra) + 1, ps.fstep, ps.fontid); for (i = 2; i < argc; i++) { BLI_strncpy(filepath, argv[i], sizeof(filepath)); - build_pict_list(filepath, (efra - sfra) + 1, fstep, ps.fontid); + build_pict_list(filepath, (efra - sfra) + 1, ps.fstep, ps.fontid); } IMB_freeImBuf(ibuf); @@ -970,7 +973,7 @@ void WM_main_playanim(int argc, const char **argv) while (pupdate_time()) PIL_sleep_ms(1); ptottime -= swaptime; - playanim_toscreen(ps.picture, ibuf, ps.fontid); + playanim_toscreen(ps.picture, ibuf, ps.fontid, ps.fstep); } /* else deleten */ else { printf("error: can't play this image type\n"); From 67e27685709a050d92d7e8a0463006f0b4d46ef1 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 12 Oct 2012 14:35:10 +0000 Subject: [PATCH 192/347] quiet some -Wshadow warnings --- source/blender/blenkernel/BKE_sequencer.h | 24 +++++++++---------- source/blender/blenkernel/intern/brush.c | 4 ++-- source/blender/blenkernel/intern/curve.c | 3 ++- source/blender/blenkernel/intern/depsgraph.c | 1 - source/blender/blenkernel/intern/implicit.c | 17 +++++++------ source/blender/blenkernel/intern/mesh.c | 2 +- .../blender/blenkernel/intern/mesh_validate.c | 9 +++---- source/blender/blenkernel/intern/multires.c | 1 - source/blender/blenkernel/intern/object.c | 4 ++-- .../editors/armature/editarmature_retarget.c | 6 +---- .../blender/editors/interface/interface_ops.c | 4 ++-- source/blender/editors/mask/mask_add.c | 16 ++++++------- source/blender/editors/mask/mask_ops.c | 6 ++--- source/blender/editors/mesh/editmesh_tools.c | 8 +++---- .../blender/editors/object/object_shapekey.c | 6 ++--- .../blender/editors/object/object_transform.c | 21 ++++++++++++---- source/blender/editors/object/object_vgroup.c | 7 +++--- .../editors/physics/physics_pointcache.c | 6 ++--- .../editors/sculpt_paint/paint_cursor.c | 2 +- .../editors/sculpt_paint/paint_image.c | 18 +++++++------- .../editors/sculpt_paint/paint_vertex.c | 16 ++++++------- source/blender/editors/sculpt_paint/sculpt.c | 14 +++++------ .../editors/space_buttons/buttons_context.c | 2 +- .../editors/space_clip/tracking_select.c | 1 - source/blender/editors/space_nla/nla_draw.c | 2 -- source/blender/editors/space_node/drawnode.c | 1 - source/blender/editors/space_node/node_edit.c | 3 ++- .../editors/space_node/node_templates.c | 6 ++--- .../editors/space_sequencer/sequencer_edit.c | 8 ++++--- .../blender/editors/space_view3d/drawmesh.c | 3 +-- .../editors/space_view3d/view3d_buttons.c | 6 +++-- .../editors/space_view3d/view3d_select.c | 8 +++---- source/blender/editors/transform/transform.c | 8 ++++--- .../transform/transform_orientations.c | 9 ++++--- source/blender/editors/uvedit/uvedit_ops.c | 14 ++++++----- .../editors/uvedit/uvedit_unwrap_ops.c | 4 +++- 36 files changed, 138 insertions(+), 132 deletions(-) diff --git a/source/blender/blenkernel/BKE_sequencer.h b/source/blender/blenkernel/BKE_sequencer.h index 80431682d6f..1667c119790 100644 --- a/source/blender/blenkernel/BKE_sequencer.h +++ b/source/blender/blenkernel/BKE_sequencer.h @@ -68,27 +68,27 @@ void BKE_sequence_iterator_begin(struct Editing *ed, SeqIterator *iter, int use_ void BKE_sequence_iterator_next(SeqIterator *iter); void BKE_sequence_iterator_end(SeqIterator *iter); -#define SEQP_BEGIN(ed, _seq) \ +#define SEQP_BEGIN(_ed, _seq) \ { \ - SeqIterator iter; \ - for (BKE_sequence_iterator_begin(ed, &iter, 1); \ - iter.valid; \ - BKE_sequence_iterator_next(&iter)) \ + SeqIterator iter_macro; \ + for (BKE_sequence_iterator_begin(_ed, &iter_macro, 1); \ + iter_macro.valid; \ + BKE_sequence_iterator_next(&iter_macro)) \ { \ - _seq = iter.seq; + _seq = iter_macro.seq; #define SEQ_BEGIN(ed, _seq) \ { \ - SeqIterator iter; \ - for (BKE_sequence_iterator_begin(ed, &iter, 0); \ - iter.valid; \ - BKE_sequence_iterator_next(&iter)) \ + SeqIterator iter_macro; \ + for (BKE_sequence_iterator_begin(ed, &iter_macro, 0); \ + iter_macro.valid; \ + BKE_sequence_iterator_next(&iter_macro)) \ { \ - _seq = iter.seq; + _seq = iter_macro.seq; #define SEQ_END \ } \ - BKE_sequence_iterator_end(&iter); \ + BKE_sequence_iterator_end(&iter_macro); \ } typedef struct SeqRenderData { diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index ce39eea5ceb..f4efc30068c 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -741,7 +741,7 @@ void BKE_brush_scale_unprojected_radius(float *unprojected_radius, } /* scale brush size to reflect a change in the brush's unprojected radius */ -void BKE_brush_scale_size(int *BKE_brush_size_get, +void BKE_brush_scale_size(int *r_brush_size, float new_unprojected_radius, float old_unprojected_radius) { @@ -749,7 +749,7 @@ void BKE_brush_scale_size(int *BKE_brush_size_get, /* avoid division by zero */ if (old_unprojected_radius != 0) scale /= new_unprojected_radius; - (*BKE_brush_size_get) = (int)((float)(*BKE_brush_size_get) * scale); + (*r_brush_size) = (int)((float)(*r_brush_size) * scale); } /* Brush Painting */ diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index 0bda3b266b8..e09e2eeb493 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -2109,7 +2109,7 @@ static void make_bevel_list_3D_tangent(BevList *bl) BevPoint *bevp2, *bevp1, *bevp0; /* standard for all make_bevel_list_3D_* funcs */ int nr; - float bevp0_tan[3], cross_tmp[3]; + float bevp0_tan[3]; bevel_list_calc_bisect(bl); if (bl->poly == -1) /* check its not cyclic */ @@ -2123,6 +2123,7 @@ static void make_bevel_list_3D_tangent(BevList *bl) nr = bl->nr; while (nr--) { + float cross_tmp[3]; cross_v3_v3v3(cross_tmp, bevp1->tan, bevp1->dir); cross_v3_v3v3(bevp1->tan, cross_tmp, bevp1->dir); normalize_v3(bevp1->tan); diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index 9b52fbae626..20b029371f1 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -444,7 +444,6 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O if (ob->type == OB_ARMATURE) { if (ob->pose) { bPoseChannel *pchan; - bConstraint *con; for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { for (con = pchan->constraints.first; con; con = con->next) { diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index 2b23e8450ae..235d7858e17 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -857,23 +857,22 @@ DO_INLINE float fbderiv(float length, float L) DO_INLINE float fbstar(float length, float L, float kb, float cb) { - float tempfb = kb * fb(length, L); - - float fbstar = cb * (length - L); + float tempfb_fl = kb * fb(length, L); + float fbstar_fl = cb * (length - L); - if (tempfb < fbstar) - return fbstar; + if (tempfb_fl < fbstar_fl) + return fbstar_fl; else - return tempfb; + return tempfb_fl; } // function to calculae bending spring force (taken from Choi & Co) DO_INLINE float fbstar_jacobi(float length, float L, float kb, float cb) { - float tempfb = kb * fb(length, L); - float fbstar = cb * (length - L); + float tempfb_fl = kb * fb(length, L); + float fbstar_fl = cb * (length - L); - if (tempfb < fbstar) { + if (tempfb_fl < fbstar_fl) { return cb; } else { diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index 1936cc0ea99..c244317ccb7 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -2039,7 +2039,7 @@ static void bm_corners_to_loops_ex(ID *id, CustomData *fdata, CustomData *ldata, MDisps *ld = CustomData_get(ldata, loopstart, CD_MDISPS); MDisps *fd = CustomData_get(fdata, findex, CD_MDISPS); float (*disps)[3] = fd->disps; - int i, tot = mf->v4 ? 4 : 3; + int tot = mf->v4 ? 4 : 3; int side, corners; if (CustomData_external_test(fdata, CD_MDISPS)) { diff --git a/source/blender/blenkernel/intern/mesh_validate.c b/source/blender/blenkernel/intern/mesh_validate.c index 79e3fc19d20..c4d663e17bd 100644 --- a/source/blender/blenkernel/intern/mesh_validate.c +++ b/source/blender/blenkernel/intern/mesh_validate.c @@ -228,7 +228,6 @@ int BKE_mesh_validate_arrays(Mesh *mesh, } for (i = 1; i < totvert; i++, mv++) { - int j; int fix_normal = TRUE; for (j = 0; j < 3; j++) { @@ -717,7 +716,6 @@ int BKE_mesh_validate_arrays(Mesh *mesh, MDeformVert *dv; for (i = 0, dv = dverts; i < totvert; i++, dv++) { MDeformWeight *dw; - unsigned int j; for (j = 0, dw = dv->dw; j < dv->totweight; j++, dw++) { /* note, greater then max defgroups is accounted for in our code, but not < 0 */ @@ -914,7 +912,7 @@ void BKE_mesh_calc_edges(Mesh *mesh, int update) { CustomData edata; EdgeHashIterator *ehi; - MPoly *mp = mesh->mpoly; + MPoly *mp; MEdge *med, *med_orig; EdgeHash *eh = BLI_edgehash_new(); int i, totedge, totpoly = mesh->totpoly; @@ -932,7 +930,7 @@ void BKE_mesh_calc_edges(Mesh *mesh, int update) } /* mesh loops (bmesh only) */ - for (i = 0; i < totpoly; i++, mp++) { + for (mp = mesh->mpoly, i = 0; i < totpoly; mp++, i++) { MLoop *l = &mesh->mloop[mp->loopstart]; int j, l_prev = (l + (mp->totloop - 1))->v; for (j = 0; j < mp->totloop; j++, l++) { @@ -970,8 +968,7 @@ void BKE_mesh_calc_edges(Mesh *mesh, int update) if (mesh->totpoly) { /* second pass, iterate through all loops again and assign * the newly created edges to them. */ - MPoly *mp = mesh->mpoly; - for (i = 0; i < mesh->totpoly; i++, mp++) { + for (mp = mesh->mpoly, i = 0; i < mesh->totpoly; mp++, i++) { MLoop *l = &mesh->mloop[mp->loopstart]; MLoop *l_prev = (l + (mp->totloop - 1)); int j; diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c index 591524e5156..58348483c61 100644 --- a/source/blender/blenkernel/intern/multires.c +++ b/source/blender/blenkernel/intern/multires.c @@ -1161,7 +1161,6 @@ void multires_modifier_update_mdisps(struct DerivedMesh *dm) int totlvl = ccgdm->multires.totlvl; if (lvl < totlvl) { - Mesh *me = ob->data; DerivedMesh *lowdm, *cddm, *highdm; CCGElem **highGridData, **lowGridData, **subGridData, **gridData, *diffGrid; CCGKey highGridKey, lowGridKey; diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 65ab97e0dad..a0d27737705 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -689,8 +689,8 @@ void BKE_object_unlink(Object *ob) if (so->treestore) { TreeStoreElem *tselem = so->treestore->data; - int a; - for (a = 0; a < so->treestore->usedelem; a++, tselem++) { + int i; + for (i = 0; i < so->treestore->usedelem; i++, tselem++) { if (tselem->id == (ID *)ob) tselem->id = NULL; } } diff --git a/source/blender/editors/armature/editarmature_retarget.c b/source/blender/editors/armature/editarmature_retarget.c index fad06f0d020..196d03020e7 100644 --- a/source/blender/editors/armature/editarmature_retarget.c +++ b/source/blender/editors/armature/editarmature_retarget.c @@ -1962,7 +1962,6 @@ static void retargetArctoArcAggresive(bContext *C, RigGraph *rigg, RigArc *iarc, ReebArcIterator arc_iter; BArcIterator *iter = (BArcIterator *)&arc_iter; RigEdge *edge; - EmbedBucket *bucket = NULL; ReebNode *node_start, *node_end; ReebArc *earc = iarc->link_mesh; float angle_weight = 1.0; // GET FROM CONTEXT @@ -1996,8 +1995,6 @@ static void retargetArctoArcAggresive(bContext *C, RigGraph *rigg, RigArc *iarc, /* equal number of joints and potential position, just fill them in */ if (nb_joints == earc->bcount) { - int i; - /* init with first values */ for (i = 0; i < nb_joints; i++) { best_positions[i] = i + 1; @@ -2011,7 +2008,6 @@ static void retargetArctoArcAggresive(bContext *C, RigGraph *rigg, RigArc *iarc, MemoNode *result; #endif float **positions_cache = MEM_callocN(sizeof(float *) * (nb_positions + 2), "positions cache"); - int i; positions_cache[0] = node_start->p; positions_cache[nb_positions + 1] = node_end->p; @@ -2053,7 +2049,7 @@ static void retargetArctoArcAggresive(bContext *C, RigGraph *rigg, RigArc *iarc, { float *no = NULL; if (i < nb_joints) { - bucket = IT_peek(iter, best_positions[i]); + EmbedBucket *bucket = IT_peek(iter, best_positions[i]); vec1 = bucket->p; no = bucket->no; } diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c index e4e2598c494..ba2feebd2f8 100644 --- a/source/blender/editors/interface/interface_ops.c +++ b/source/blender/editors/interface/interface_ops.c @@ -857,8 +857,8 @@ static int editsource_exec(bContext *C, wmOperator *op) !BLI_ghashIterator_isDone(&ghi); BLI_ghashIterator_step(&ghi)) { - uiBut *but = BLI_ghashIterator_getKey(&ghi); - if (but && ui_editsource_uibut_match(&ui_editsource_info->but_orig, but)) { + uiBut *but_key = BLI_ghashIterator_getKey(&ghi); + if (but_key && ui_editsource_uibut_match(&ui_editsource_info->but_orig, but_key)) { but_store = BLI_ghashIterator_getValue(&ghi); break; } diff --git a/source/blender/editors/mask/mask_add.c b/source/blender/editors/mask/mask_add.c index a254a6a9278..c929436bc82 100644 --- a/source/blender/editors/mask/mask_add.c +++ b/source/blender/editors/mask/mask_add.c @@ -97,7 +97,7 @@ static int find_nearest_diff_point(const bContext *C, Mask *mask, const float no &tot_diff_point); if (diff_points) { - int i, tot_point; + int j, tot_point; unsigned int tot_feather_point; float *feather_points = NULL, *points; @@ -114,26 +114,26 @@ static int find_nearest_diff_point(const bContext *C, Mask *mask, const float no tot_point = tot_diff_point; } - for (i = 0; i < tot_point - 1; i++) { + for (j = 0; j < tot_point - 1; j++) { float cur_dist, a[2], b[2]; - a[0] = points[2 * i] * scalex; - a[1] = points[2 * i + 1] * scaley; + a[0] = points[2 * j] * scalex; + a[1] = points[2 * j + 1] * scaley; - b[0] = points[2 * i + 2] * scalex; - b[1] = points[2 * i + 3] * scaley; + b[0] = points[2 * j + 2] * scalex; + b[1] = points[2 * j + 3] * scaley; cur_dist = dist_to_line_segment_v2(co, a, b); if (cur_dist < dist) { if (tangent) - sub_v2_v2v2(tangent, &diff_points[2 * i + 2], &diff_points[2 * i]); + sub_v2_v2v2(tangent, &diff_points[2 * j + 2], &diff_points[2 * j]); point_masklay = masklay; point_spline = spline; point = use_deform ? &spline->points[(cur_point - spline->points_deform)] : cur_point; dist = cur_dist; - u = (float)i / tot_point; + u = (float)j / tot_point; } } diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c index 88fbb91edfb..bea6b153d20 100644 --- a/source/blender/editors/mask/mask_ops.c +++ b/source/blender/editors/mask/mask_ops.c @@ -483,15 +483,15 @@ static void *slide_point_customdata(bContext *C, wmOperator *op, wmEvent *event) customdata->uw = uw; if (uw) { - float co[2]; + float co_uw[2]; float weight_scalar = BKE_mask_point_weight_scalar(spline, point, uw->u); customdata->weight = uw->w; customdata->weight_scalar = weight_scalar; - BKE_mask_point_segment_co(spline, point, uw->u, co); + BKE_mask_point_segment_co(spline, point, uw->u, co_uw); BKE_mask_point_normal(spline, point, uw->u, customdata->no); - madd_v2_v2v2fl(customdata->feather, co, customdata->no, uw->w * weight_scalar); + madd_v2_v2v2fl(customdata->feather, co_uw, customdata->no, uw->w * weight_scalar); } else { BezTriple *bezt = &point->bezt; diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index ee12e971325..2d46de024dd 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -3852,8 +3852,8 @@ static void sort_bmelem_flag(Scene *scene, Object *ob, char *pblock[3] = {NULL, NULL, NULL}, *pb; BMElemSort *sblock[3] = {NULL, NULL, NULL}, *sb; int *map[3] = {NULL, NULL, NULL}, *mp; - int totelem[3] = {0, 0, 0}, tot; - int affected[3] = {0, 0, 0}, aff; + int totelem[3] = {0, 0, 0}; + int affected[3] = {0, 0, 0}; int i, j; if (!(types && flag && action)) @@ -4228,8 +4228,8 @@ static void sort_bmelem_flag(Scene *scene, Object *ob, if (pb && sb && !map[j]) { char *p_blk; BMElemSort *s_blk; - tot = totelem[j]; - aff = affected[j]; + int tot = totelem[j]; + int aff = affected[j]; qsort(sb, aff, sizeof(BMElemSort), bmelemsort_comp); diff --git a/source/blender/editors/object/object_shapekey.c b/source/blender/editors/object/object_shapekey.c index cfd4945688b..86a55a9b278 100644 --- a/source/blender/editors/object/object_shapekey.c +++ b/source/blender/editors/object/object_shapekey.c @@ -162,15 +162,15 @@ static int object_shape_key_mirror(bContext *C, Object *ob) kb = BLI_findlink(&key->block, ob->shapenr - 1); if (kb) { - int i1, i2; - float *fp1, *fp2; - float tvec[3]; char *tag_elem = MEM_callocN(sizeof(char) * kb->totelem, "shape_key_mirror"); if (ob->type == OB_MESH) { Mesh *me = ob->data; MVert *mv; + int i1, i2; + float *fp1, *fp2; + float tvec[3]; mesh_octree_table(ob, NULL, NULL, 's'); diff --git a/source/blender/editors/object/object_transform.c b/source/blender/editors/object/object_transform.c index 1b08235b75c..e2a32a743bb 100644 --- a/source/blender/editors/object/object_transform.c +++ b/source/blender/editors/object/object_transform.c @@ -381,8 +381,8 @@ static int apply_objects_internal(bContext *C, ReportList *reports, int apply_lo { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); - float rsmat[3][3], tmat[3][3], obmat[3][3], iobmat[3][3], mat[4][4], scale; - int a, change = 1; + float rsmat[3][3], obmat[3][3], iobmat[3][3], mat[4][4], scale; + int change = 1; /* first check if we can execute */ CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) @@ -464,6 +464,7 @@ static int apply_objects_internal(bContext *C, ReportList *reports, int apply_lo copy_v3_v3(mat[3], ob->loc); if (!(apply_scale && apply_rot)) { + float tmat[3][3]; /* correct for scale and rotation that is still applied */ BKE_object_to_mat3(ob, obmat); invert_m3_m3(iobmat, obmat); @@ -476,6 +477,7 @@ static int apply_objects_internal(bContext *C, ReportList *reports, int apply_lo if (ob->type == OB_MESH) { Mesh *me = ob->data; MVert *mvert; + int a; if (apply_scale) multiresModifier_scale_disp(scene, ob); @@ -518,6 +520,7 @@ static int apply_objects_internal(bContext *C, ReportList *reports, int apply_lo Nurb *nu; BPoint *bp; BezTriple *bezt; + int a; scale = mat3_to_scale(rsmat); @@ -896,6 +899,8 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) /* offset other selected objects */ if (do_inverse_offset && (centermode != GEOMETRY_TO_ORIGIN)) { + CollectionPointerLink *ctx_link_other; + /* was the object data modified * note: the functions above must set 'cent' */ copy_v3_v3(centn, cent); @@ -910,8 +915,16 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) ignore_parent_tx(bmain, scene, ob); /* other users? */ - CTX_DATA_BEGIN (C, Object *, ob_other, selected_editable_objects) + //CTX_DATA_BEGIN (C, Object *, ob_other, selected_editable_objects) + //{ + + /* use existing context looper */ + for (ctx_link_other = ctx_data_list.first; + ctx_link_other; + ctx_link_other = ctx_link_other->next) { + Object *ob_other = ctx_link_other->ptr.data; + if ((ob_other->flag & OB_DONE) == 0 && ((ob->data && (ob->data == ob_other->data)) || (ob->dup_group == ob_other->dup_group && @@ -931,7 +944,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) ignore_parent_tx(bmain, scene, ob_other); } } - CTX_DATA_END; + //CTX_DATA_END; } } } diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index a92cfa472aa..95be54814f0 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -918,7 +918,6 @@ void ED_vgroup_select_by_name(Object *ob, const char *name) static void vgroup_select_verts(Object *ob, int select) { const int def_nr = ob->actdef - 1; - MDeformVert *dv; if (!BLI_findlink(&ob->defbase, def_nr)) { return; @@ -934,7 +933,7 @@ static void vgroup_select_verts(Object *ob, int select) BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) { if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) { - dv = CustomData_bmesh_get(&em->bm->vdata, eve->head.data, CD_MDEFORMVERT); + MDeformVert *dv = CustomData_bmesh_get(&em->bm->vdata, eve->head.data, CD_MDEFORMVERT); if (defvert_find_index(dv, def_nr)) { BM_vert_select_set(em->bm, eve, select); } @@ -971,6 +970,7 @@ static void vgroup_select_verts(Object *ob, int select) Lattice *lt = vgroup_edit_lattice(ob); if (lt->dvert) { + MDeformVert *dv; BPoint *bp; int a, tot; @@ -2451,7 +2451,6 @@ static void vgroup_delete_all(Object *ob) /* only in editmode */ static void vgroup_assign_verts(Object *ob, const float weight) { - MDeformVert *dv; const int def_nr = ob->actdef - 1; if (!BLI_findlink(&ob->defbase, def_nr)) @@ -2471,6 +2470,7 @@ static void vgroup_assign_verts(Object *ob, const float weight) /* Go through the list of editverts and assign them */ BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { + MDeformVert *dv; MDeformWeight *dw; dv = CustomData_bmesh_get(&em->bm->vdata, eve->head.data, CD_MDEFORMVERT); /* can be NULL */ dw = defvert_verify_index(dv, def_nr); @@ -2505,6 +2505,7 @@ static void vgroup_assign_verts(Object *ob, const float weight) } else if (ob->type == OB_LATTICE) { Lattice *lt = vgroup_edit_lattice(ob); + MDeformVert *dv; BPoint *bp; int a, tot; diff --git a/source/blender/editors/physics/physics_pointcache.c b/source/blender/editors/physics/physics_pointcache.c index 218ae628d3f..bbce94b6215 100644 --- a/source/blender/editors/physics/physics_pointcache.c +++ b/source/blender/editors/physics/physics_pointcache.c @@ -325,9 +325,9 @@ static int ptcache_add_new_exec(bContext *C, wmOperator *UNUSED(op)) for (pid=pidlist.first; pid; pid=pid->next) { if (pid->cache == cache) { - PointCache *cache = BKE_ptcache_add(pid->ptcaches); - cache->step = pid->default_step; - *(pid->cache_ptr) = cache; + PointCache *cache_new = BKE_ptcache_add(pid->ptcaches); + cache_new->step = pid->default_step; + *(pid->cache_ptr) = cache_new; break; } } diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c index e3d714b1917..5e23a144408 100644 --- a/source/blender/editors/sculpt_paint/paint_cursor.c +++ b/source/blender/editors/sculpt_paint/paint_cursor.c @@ -340,7 +340,6 @@ static int sculpt_get_brush_geometry(bContext *C, ViewContext *vc, { Scene *scene = CTX_data_scene(C); Paint *paint = paint_get_active_from_context(C); - Brush *brush = paint_brush(paint); float window[2]; int hit; @@ -350,6 +349,7 @@ static int sculpt_get_brush_geometry(bContext *C, ViewContext *vc, if (vc->obact->sculpt && vc->obact->sculpt->pbvh && sculpt_stroke_get_location(C, location, window)) { + Brush *brush = paint_brush(paint); *pixel_radius = project_brush_radius(vc, BKE_brush_unprojected_radius_get(scene, brush), diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c index c6aaae6b879..f60d34428b3 100644 --- a/source/blender/editors/sculpt_paint/paint_image.c +++ b/source/blender/editors/sculpt_paint/paint_image.c @@ -2554,7 +2554,6 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i float (*outset_uv)[2] = ps->faceSeamUVs[face_index]; float insetCos[4][3]; /* inset face coords. NOTE!!! ScreenSace for ortho, Worldspace in prespective view */ - float fac; float *vCoSS[4]; /* vertex screenspace coords */ float bucket_clip_edges[2][2]; /* store the screenspace coords of the face, clipped by the bucket's screen aligned rectangle */ @@ -2636,6 +2635,7 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i /* test we're inside uvspace bucket and triangle bounds */ if (isect_point_quad_v2(uv, seam_subsection[0], seam_subsection[1], seam_subsection[2], seam_subsection[3])) { + float fac; /* We need to find the closest point along the face edge, * getting the screen_px_from_*** wont work because our actual location @@ -2670,9 +2670,9 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i #if 1 /* get the UV on the line since we want to copy the pixels from there for bleeding */ float uv_close[2]; - float fac = closest_to_line_v2(uv_close, uv, tf_uv_pxoffset[fidx1], tf_uv_pxoffset[fidx2]); - if (fac < 0.0f) copy_v2_v2(uv_close, tf_uv_pxoffset[fidx1]); - else if (fac > 1.0f) copy_v2_v2(uv_close, tf_uv_pxoffset[fidx2]); + float uv_fac = closest_to_line_v2(uv_close, uv, tf_uv_pxoffset[fidx1], tf_uv_pxoffset[fidx2]); + if (uv_fac < 0.0f) copy_v2_v2(uv_close, tf_uv_pxoffset[fidx1]); + else if (uv_fac > 1.0f) copy_v2_v2(uv_close, tf_uv_pxoffset[fidx2]); if (side) { barycentric_weights_v2(tf_uv_pxoffset[0], tf_uv_pxoffset[2], tf_uv_pxoffset[3], uv_close, w); @@ -2683,16 +2683,16 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i #else /* this is buggy with quads, don't use for now */ /* Cheat, we know where we are along the edge so work out the weights from that */ - fac = fac1 + (fac * (fac2 - fac1)); + uv_fac = fac1 + (uv_fac * (fac2 - fac1)); w[0] = w[1] = w[2] = 0.0; if (side) { - w[fidx1 ? fidx1 - 1 : 0] = 1.0f - fac; - w[fidx2 ? fidx2 - 1 : 0] = fac; + w[fidx1 ? fidx1 - 1 : 0] = 1.0f - uv_fac; + w[fidx2 ? fidx2 - 1 : 0] = uv_fac; } else { - w[fidx1] = 1.0f - fac; - w[fidx2] = fac; + w[fidx1] = 1.0f - uv_fac; + w[fidx2] = uv_fac; } #endif } diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c index 6b3017b8638..bb931dd1ff2 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.c @@ -1535,7 +1535,6 @@ static void enforce_locks(MDeformVert *odv, MDeformVert *ndv, } else { /* reset the weights */ - unsigned int i; MDeformWeight *dw_old = odv->dw; MDeformWeight *dw_new = ndv->dw; @@ -2049,7 +2048,6 @@ static int wpaint_stroke_test_start(bContext *C, wmOperator *op, const float UNU Object *ob = CTX_data_active_object(C); struct WPaintData *wpd; Mesh *me; - bDeformGroup *dg; float mat[4][4], imat[4][4]; @@ -2098,12 +2096,14 @@ static int wpaint_stroke_test_start(bContext *C, wmOperator *op, const float UNU return FALSE; } - /* check if we are attempting to paint onto a locked vertex group, - * and other options disallow it from doing anything useful */ - dg = BLI_findlink(&ob->defbase, (ob->actdef - 1)); - if (dg->flag & DG_LOCK_WEIGHT) { - BKE_report(op->reports, RPT_WARNING, "Active group is locked, aborting"); - return FALSE; + { + /* check if we are attempting to paint onto a locked vertex group, + * and other options disallow it from doing anything useful */ + bDeformGroup *dg = BLI_findlink(&ob->defbase, (ob->actdef - 1)); + if (dg->flag & DG_LOCK_WEIGHT) { + BKE_report(op->reports, RPT_WARNING, "Active group is locked, aborting"); + return FALSE; + } } /* ALLOCATIONS! no return after this line */ diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index e03c2fbfd21..092ec32e724 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -3536,8 +3536,6 @@ static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob, StrokeCache *cache = ss->cache; Brush *brush = paint_brush(&sd->paint); - int dx, dy; - /* RNA_float_get_array(ptr, "location", cache->traced_location); */ if (cache->first_time || @@ -3606,8 +3604,8 @@ static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob, if (brush->flag & BRUSH_ANCHORED) { int hit = 0; - dx = cache->mouse[0] - cache->initial_mouse[0]; - dy = cache->mouse[1] - cache->initial_mouse[1]; + const float dx = cache->mouse[0] - cache->initial_mouse[0]; + const float dy = cache->mouse[1] - cache->initial_mouse[1]; sd->anchored_size = cache->pixel_radius = sqrt(dx * dx + dy * dy); @@ -3617,8 +3615,8 @@ static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob, float halfway[2]; float out[3]; - halfway[0] = (float)dx * 0.5f + cache->initial_mouse[0]; - halfway[1] = (float)dy * 0.5f + cache->initial_mouse[1]; + halfway[0] = dx * 0.5f + cache->initial_mouse[0]; + halfway[1] = dy * 0.5f + cache->initial_mouse[1]; if (sculpt_stroke_get_location(C, out, halfway)) { copy_v3_v3(sd->anchored_location, out); @@ -3665,8 +3663,8 @@ static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob, sculpt_update_brush_delta(sd, ob, brush); if (brush->sculpt_tool == SCULPT_TOOL_ROTATE) { - dx = cache->mouse[0] - cache->initial_mouse[0]; - dy = cache->mouse[1] - cache->initial_mouse[1]; + const float dx = cache->mouse[0] - cache->initial_mouse[0]; + const float dy = cache->mouse[1] - cache->initial_mouse[1]; cache->vertex_rotation = -atan2f(dx, dy) * cache->bstrength; diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c index c41d2521ee8..7e232a02536 100644 --- a/source/blender/editors/space_buttons/buttons_context.c +++ b/source/blender/editors/space_buttons/buttons_context.c @@ -900,7 +900,7 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r } else { /* get settings from active particle system instead */ - PointerRNA *ptr = get_pointer_type(path, &RNA_ParticleSystem); + ptr = get_pointer_type(path, &RNA_ParticleSystem); if (ptr && ptr->data) { ParticleSettings *part = ((ParticleSystem *)ptr->data)->part; diff --git a/source/blender/editors/space_clip/tracking_select.c b/source/blender/editors/space_clip/tracking_select.c index 4f62d3fdc2f..7e3fabd1f66 100644 --- a/source/blender/editors/space_clip/tracking_select.c +++ b/source/blender/editors/space_clip/tracking_select.c @@ -291,7 +291,6 @@ static int select_invoke(bContext *C, wmOperator *op, wmEvent *event) MovieTrackingTrack *track = tracking_marker_check_slide(C, event, NULL, NULL, NULL); if (track) { - SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip_get_clip(sc); clip->tracking.act_track = track; diff --git a/source/blender/editors/space_nla/nla_draw.c b/source/blender/editors/space_nla/nla_draw.c index 92f014fd804..5c8e7e99a8c 100644 --- a/source/blender/editors/space_nla/nla_draw.c +++ b/source/blender/editors/space_nla/nla_draw.c @@ -849,8 +849,6 @@ static void draw_nla_channel_list_gl(bAnimContext *ac, ListBase *anim_data, View /* draw NLA-action line 'status-icons' - only when there's an action */ if ((ale->type == ANIMTYPE_NLAACTION) && (ale->data)) { - AnimData *adt = ale->adt; - offset += 16; /* now draw some indicator icons */ diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 470f82195a4..67508f2087a 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -3098,7 +3098,6 @@ void draw_nodespace_back_pix(const bContext *C, ARegion *ar, SpaceNode *snode) void *lock; ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock); if (ibuf) { - SpaceNode *snode = CTX_wm_space_node(C); float x, y; unsigned char *display_buffer; void *cache_handle; diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index 64a8d96a74f..f0afc647ed5 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -1935,7 +1935,7 @@ static int node_clipboard_copy_exec(bContext *C, wmOperator *UNUSED(op)) bNodeTree *ntree = snode->edittree; bNode *gnode = node_tree_get_editgroup(snode->nodetree); float gnode_x = 0.0f, gnode_y = 0.0f; - bNode *node, *new_node; + bNode *node; bNodeLink *link, *newlink; ED_preview_kill_jobs(C); @@ -1950,6 +1950,7 @@ static int node_clipboard_copy_exec(bContext *C, wmOperator *UNUSED(op)) for (node = ntree->nodes.first; node; node = node->next) { if (node->flag & SELECT) { + bNode *new_node; new_node = nodeCopyNode(NULL, node); BKE_node_clipboard_add_node(new_node); } diff --git a/source/blender/editors/space_node/node_templates.c b/source/blender/editors/space_node/node_templates.c index 3d93a6c14a1..42480c0c2d9 100644 --- a/source/blender/editors/space_node/node_templates.c +++ b/source/blender/editors/space_node/node_templates.c @@ -147,7 +147,7 @@ static void node_socket_remove(Main *bmain, bNodeTree *ntree, bNode *node_to, bN static void node_socket_add_replace(Main *bmain, bNodeTree *ntree, bNode *node_to, bNodeSocket *sock_to, bNodeTemplate *ntemp, int sock_num) { bNode *node_from; - bNodeSocket *sock_from; + bNodeSocket *sock_from_tmp; bNode *node_prev = NULL; /* unlink existing node */ @@ -183,8 +183,8 @@ static void node_socket_add_replace(Main *bmain, bNodeTree *ntree, bNode *node_t nodeSetActive(ntree, node_from); /* add link */ - sock_from = BLI_findlink(&node_from->outputs, sock_num); - nodeAddLink(ntree, node_from, sock_from, node_to, sock_to); + sock_from_tmp = BLI_findlink(&node_from->outputs, sock_num); + nodeAddLink(ntree, node_from, sock_from_tmp, node_to, sock_to); /* copy input sockets from previous node */ if (node_prev && node_from != node_prev) { diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index 95d827f9392..c22ab90906a 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -2620,7 +2620,6 @@ static int sequencer_copy_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); Editing *ed = BKE_sequencer_editing_get(scene, FALSE); - Sequence *seq; ListBase nseqbase = {NULL, NULL}; @@ -2656,8 +2655,11 @@ static int sequencer_copy_exec(bContext *C, wmOperator *op) seqbase_clipboard_frame = scene->r.cfra; /* Need to remove anything that references the current scene */ - for (seq = seqbase_clipboard.first; seq; seq = seq->next) { - seq_copy_del_sound(scene, seq); + { + Sequence *seq; + for (seq = seqbase_clipboard.first; seq; seq = seq->next) { + seq_copy_del_sound(scene, seq); + } } return OPERATOR_FINISHED; diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c index e4c21a9c2c8..cded7bbbdfc 100644 --- a/source/blender/editors/space_view3d/drawmesh.c +++ b/source/blender/editors/space_view3d/drawmesh.c @@ -533,8 +533,7 @@ static void update_tface_color_layer(DerivedMesh *dm) } else { float col[3]; - Material *ma = give_current_material(Gtexdraw.ob, mface[i].mat_nr + 1); - + if (ma) { if (Gtexdraw.color_profile) linearrgb_to_srgb_v3_v3(col, &ma->r); else copy_v3_v3(col, &ma->r); diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c index 1f7bae0b23e..0a55df192ea 100644 --- a/source/blender/editors/space_view3d/view3d_buttons.c +++ b/source/blender/editors/space_view3d/view3d_buttons.c @@ -158,7 +158,7 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float TransformProperties *tfp; float median[NBR_TRANSFORM_PROPERTIES], ve_median[NBR_TRANSFORM_PROPERTIES]; int tot, totedgedata, totcurvedata, totlattdata, totskinradius, totcurvebweight; - int meshdata = FALSE, i; + int meshdata = FALSE; char defstr[320]; PointerRNA data_ptr; @@ -470,6 +470,8 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float } else { /* apply */ + int i; + memcpy(ve_median, tfp->ve_median, sizeof(tfp->ve_median)); if (v3d->flag & V3D_GLOBAL_STATS) { @@ -485,10 +487,10 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float Mesh *me = ob->data; BMEditMesh *em = me->edit_btmesh; BMesh *bm = em->bm; - BMVert *eve; BMIter iter; if (len_v3(&median[LOC_X]) > 0.000001f) { + BMVert *eve; BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index dc3cfa41e37..a111799a27c 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -2014,12 +2014,10 @@ static int do_object_pose_box_select(bContext *C, ViewContext *vc, rcti *rect, i } if (bone_selected) { - Object *ob = base->object; - - if (ob && (ob->type == OB_ARMATURE)) { - bArmature *arm = ob->data; + if (base->object && (base->object->type == OB_ARMATURE)) { + bArmature *arm = base->object->data; - WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob); + WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, base->object); if (arm && (arm->flag & ARM_HAS_VIZ_DEPS)) { /* mask modifier ('armature' mode), etc. */ diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 39b0ab4b3a6..1ce99534181 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -4860,10 +4860,9 @@ static int createSlideVerts(TransInfo *t) { BMEditMesh *em = BMEdit_FromObject(t->obedit); BMesh *bm = em->bm; - BMIter iter, iter2; + BMIter iter; BMEdge *e, *e1; BMVert *v, *v2, *first; - BMLoop *l, *l1, *l2; TransDataSlideVert *sv_array; BMBVHTree *btree = BMBVH_NewBVH(em, BMBVH_RESPECT_HIDDEN, NULL, NULL); SmallHash table; @@ -4903,6 +4902,7 @@ static int createSlideVerts(TransInfo *t) /*ensure valid selection*/ BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(v, BM_ELEM_SELECT)) { + BMIter iter2; numsel = 0; BM_ITER_ELEM (e, &iter2, v, BM_EDGES_OF_VERT) { if (BM_elem_flag_test(e, BM_ELEM_SELECT)) { @@ -4955,6 +4955,8 @@ static int createSlideVerts(TransInfo *t) j = 0; while (1) { + BMLoop *l, *l1, *l2; + v = NULL; BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(v, BM_ELEM_TAG)) @@ -5088,7 +5090,7 @@ static int createSlideVerts(TransInfo *t) if (BM_elem_flag_test(e, BM_ELEM_SELECT)) { BMIter iter2; BMEdge *e2; - float vec1[3], mval[2] = {t->mval[0], t->mval[1]}, d; + float vec1[3], d; /* search cross edges for visible edge to the mouse cursor, * then use the shared vertex to calculate screen vector*/ diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c index 0e25739c34a..845d5b73f0c 100644 --- a/source/blender/editors/transform/transform_orientations.c +++ b/source/blender/editors/transform/transform_orientations.c @@ -631,7 +631,6 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3], /* if there's an edge available, use that for the tangent */ if (em->bm->totedgesel >= 1) { BMEdge *eed = NULL; - BMIter iter; BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) { if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) { @@ -746,14 +745,14 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3], MetaBall *mb = obedit->data; if (mb->lastelem) { - float mat[4][4]; + float qmat[3][3]; /* Rotation of MetaElem is stored in quat */ - quat_to_mat4(mat, mb->lastelem->quat); + quat_to_mat3(qmat, mb->lastelem->quat); - copy_v3_v3(normal, mat[2]); + copy_v3_v3(normal, qmat[2]); - negate_v3_v3(plane, mat[1]); + negate_v3_v3(plane, qmat[1]); result = ORIENTATION_FACE; } diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c index 6e655faf35f..e3d52fcaa9b 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -170,7 +170,6 @@ void ED_object_assign_active_image(Main *bmain, Object *ob, int mat_nr, Image *i void ED_uvedit_assign_image(Main *bmain, Scene *scene, Object *obedit, Image *ima, Image *previma) { BMEditMesh *em; - BMFace *efa; BMIter iter; MTexPoly *tf; int update = 0; @@ -198,6 +197,8 @@ void ED_uvedit_assign_image(Main *bmain, Scene *scene, Object *obedit, Image *im ED_object_assign_active_image(bmain, obedit, efa->mat_nr + 1, ima); } else { + BMFace *efa; + /* old shading system, assign image to selected faces */ #ifdef USE_SWITCH_ASPECT float prev_aspect[2], fprev_aspect; @@ -1310,9 +1311,7 @@ static void weld_align_uv(bContext *C, int tool) Object *obedit; Image *ima; BMEditMesh *em; - BMIter iter, liter; MTexPoly *tf; - MLoopUV *luv; float cent[2], min[2], max[2]; scene = CTX_data_scene(C); @@ -1324,6 +1323,7 @@ static void weld_align_uv(bContext *C, int tool) INIT_MINMAX2(min, max); if (tool == 'a') { + BMIter iter, liter; BMFace *efa; BMLoop *l; @@ -1335,7 +1335,7 @@ static void weld_align_uv(bContext *C, int tool) BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { if (uvedit_uv_select_test(em, scene, l)) { - luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + MLoopUV *luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); DO_MINMAX2(luv->uv, min, max); } } @@ -1347,6 +1347,7 @@ static void weld_align_uv(bContext *C, int tool) uvedit_center(scene, ima, obedit, cent, 0); if (tool == 'x' || tool == 'w') { + BMIter iter, liter; BMFace *efa; BMLoop *l; @@ -1357,7 +1358,7 @@ static void weld_align_uv(bContext *C, int tool) BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { if (uvedit_uv_select_test(em, scene, l)) { - luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + MLoopUV *luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); luv->uv[0] = cent[0]; } @@ -1366,6 +1367,7 @@ static void weld_align_uv(bContext *C, int tool) } if (tool == 'y' || tool == 'w') { + BMIter iter, liter; BMFace *efa; BMLoop *l; @@ -1376,7 +1378,7 @@ static void weld_align_uv(bContext *C, int tool) BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { if (uvedit_uv_select_test(em, scene, l)) { - luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + MLoopUV *luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); luv->uv[1] = cent[1]; } diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c index 7c06fbd2a9d..26f8641743e 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c @@ -223,7 +223,7 @@ static ParamHandle *construct_param_handle(Scene *scene, BMEditMesh *em, BMLoop *ls[3]; float *co[4]; float *uv[4]; - int i, lsel; + int lsel; if ((BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) || (sel && BM_elem_flag_test(efa, BM_ELEM_SELECT) == 0)) continue; @@ -245,6 +245,7 @@ static ParamHandle *construct_param_handle(Scene *scene, BMEditMesh *em, // tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); // UNUSED if (efa->len == 3 || efa->len == 4) { + int i; /* for quads let parametrize split, it can make better decisions * about which split is best for unwrapping than scanfill */ i = 0; @@ -291,6 +292,7 @@ static ParamHandle *construct_param_handle(Scene *scene, BMEditMesh *em, BLI_scanfill_calc_ex(&sf_ctx, TRUE, efa->no); for (sf_tri = sf_ctx.fillfacebase.first; sf_tri; sf_tri = sf_tri->next) { + int i; ls[0] = sf_tri->v1->tmp.p; ls[1] = sf_tri->v2->tmp.p; ls[2] = sf_tri->v3->tmp.p; From 1958fda91f8974b6096c7b3427f9af13d26d9dbd Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Fri, 12 Oct 2012 18:10:15 +0000 Subject: [PATCH 193/347] Templates: * UI Panel: Add examples for different button sizes. --- release/scripts/templates/ui_panel.py | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/release/scripts/templates/ui_panel.py b/release/scripts/templates/ui_panel.py index 9ffa0cbeeea..cacdb83e815 100644 --- a/release/scripts/templates/ui_panel.py +++ b/release/scripts/templates/ui_panel.py @@ -22,7 +22,7 @@ class LayoutDemoPanel(bpy.types.Panel): row.prop(scene, "frame_end") # Create an row where the buttons are aligned to each other. - layout.label(text=" Aligned Row") + layout.label(text=" Aligned Row:") row = layout.row(align=True) row.prop(scene, "frame_start") @@ -39,9 +39,26 @@ class LayoutDemoPanel(bpy.types.Panel): # Second column, aligned col = split.column(align=True) - col.label(text="Column Two") + col.label(text="Column Two:") col.prop(scene, "frame_start") col.prop(scene, "frame_end") + + # Big render button + layout.label(text="Big Button:") + row = layout.row() + row.scale_y = 3.0 + row.operator("render.render") + + # Different sizes in a row + layout.label(text="Different button sizes:") + row = layout.row(align=True) + row.operator("render.render") + + sub = row.row() + sub.scale_x = 2.0 + sub.operator("render.render") + + row.operator("render.render") def register(): From 13d829e57db6b0bb6ab3c3551676a9fa3bcfd55c Mon Sep 17 00:00:00 2001 From: Jiri Hnidek Date: Fri, 12 Oct 2012 18:19:39 +0000 Subject: [PATCH 194/347] * Fix small bug in Python operator example; improved example of modal operator --- doc/python_api/examples/bpy.types.Operator.4.py | 4 ++-- doc/python_api/examples/bpy.types.Operator.5.py | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/doc/python_api/examples/bpy.types.Operator.4.py b/doc/python_api/examples/bpy.types.Operator.4.py index 861496c6d18..885ed857842 100644 --- a/doc/python_api/examples/bpy.types.Operator.4.py +++ b/doc/python_api/examples/bpy.types.Operator.4.py @@ -26,8 +26,8 @@ class CustomDrawOperator(bpy.types.Operator): return {'FINISHED'} def invoke(self, context, event): - context.window_manager.fileselect_add(self) - return {'RUNNING_MODAL'} + wm = context.window_manager + return wm.invoke_props_dialog(self) def draw(self, context): layout = self.layout diff --git a/doc/python_api/examples/bpy.types.Operator.5.py b/doc/python_api/examples/bpy.types.Operator.5.py index e123768431b..4a0abcb62c3 100644 --- a/doc/python_api/examples/bpy.types.Operator.5.py +++ b/doc/python_api/examples/bpy.types.Operator.5.py @@ -40,15 +40,17 @@ class ModalOperator(bpy.types.Operator): elif event.type == 'LEFTMOUSE': # Confirm return {'FINISHED'} elif event.type in ('RIGHTMOUSE', 'ESC'): # Cancel + context.object.location.x = self.init_loc_x return {'CANCELLED'} return {'RUNNING_MODAL'} def invoke(self, context, event): + self.init_loc_x = context.object.location.x self.value = event.mouse_x self.execute(context) - print(context.window_manager.modal_handler_add(self)) + context.window_manager.modal_handler_add(self) return {'RUNNING_MODAL'} From a798623fff69c992a14f73369876f75e59e7b4ca Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Sat, 13 Oct 2012 01:19:23 +0000 Subject: [PATCH 195/347] Bugfix [#32865] Usercounts for World Textures not decremented after preview render When adjusting settings for world textures (with Both/World preview modes), every tweak would result in the usercount of the texture increasing. As a result, before long the texture would claim to have over 100 users. Fortunately, this only appeared to be just a cosmetic issue (i.e. no real memory leak here), though it was a bit unsettling. NOTE: this is still a bit glitchy, as now we have flickering when updating texture settings - the texture still temporarily has a second user during preview rendering. --- source/blender/editors/render/render_preview.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c index 96276d5eb1b..694d2302fbd 100644 --- a/source/blender/editors/render/render_preview.c +++ b/source/blender/editors/render/render_preview.c @@ -809,7 +809,7 @@ static void shader_preview_free(void *customdata) /* get rid of copied world */ BLI_remlink(&pr_main->world, sp->worldcopy); - BKE_world_free_ex(sp->worldcopy, FALSE); + BKE_world_free_ex(sp->worldcopy, TRUE); /* [#32865] - we need to unlink the texture copies, unlike for materials */ properties = IDP_GetProperties((ID *)sp->worldcopy, FALSE); if (properties) { From 7412e321a35d757f098112ad612b3a8e142e59f6 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 13 Oct 2012 01:46:57 +0000 Subject: [PATCH 196/347] add support for ripping off a single face from a single vertex when the vertex has 3 surrounding verts & faces. --- source/blender/bmesh/intern/bmesh_queries.c | 8 ++ source/blender/bmesh/intern/bmesh_queries.h | 1 + source/blender/editors/mesh/editmesh_rip.c | 101 +++++++++++++++++--- 3 files changed, 95 insertions(+), 15 deletions(-) diff --git a/source/blender/bmesh/intern/bmesh_queries.c b/source/blender/bmesh/intern/bmesh_queries.c index d850eb34477..4f09a17b6ce 100644 --- a/source/blender/bmesh/intern/bmesh_queries.c +++ b/source/blender/bmesh/intern/bmesh_queries.c @@ -297,6 +297,14 @@ int BM_edge_in_face(BMFace *f, BMEdge *e) return FALSE; } +/** + * Returns whether or not a given edge is is part of a given loop. + */ +int BM_edge_in_loop(BMEdge *e, BMLoop *l) +{ + return (l->e == e || l->prev->e == e); +} + /** * Returns whether or not two vertices are in * a given edge diff --git a/source/blender/bmesh/intern/bmesh_queries.h b/source/blender/bmesh/intern/bmesh_queries.h index 36ffc296759..6cffc1138b0 100644 --- a/source/blender/bmesh/intern/bmesh_queries.h +++ b/source/blender/bmesh/intern/bmesh_queries.h @@ -31,6 +31,7 @@ int BM_vert_in_face(BMFace *f, BMVert *v); int BM_verts_in_face(BMesh *bm, BMFace *f, BMVert **varr, int len); int BM_edge_in_face(BMFace *f, BMEdge *e); +int BM_edge_in_loop(BMEdge *e, BMLoop *l); int BM_vert_in_edge(BMEdge *e, BMVert *v); int BM_verts_in_edge(BMVert *v1, BMVert *v2, BMEdge *e); diff --git a/source/blender/editors/mesh/editmesh_rip.c b/source/blender/editors/mesh/editmesh_rip.c index 0b3d178e2e8..f85763f660c 100644 --- a/source/blender/editors/mesh/editmesh_rip.c +++ b/source/blender/editors/mesh/editmesh_rip.c @@ -55,8 +55,35 @@ #include "mesh_intern.h" -/* helper to find edge for edge_rip */ +/** + * helper to find edge for edge_rip, + * + * \param inset is used so we get some useful distance + * when comparing multiple edges that meet at the same + * point and would result in teh same distance. + */ +#define INSET_DEFAULT 0.00001f static float edbm_rip_rip_edgedist(ARegion *ar, float mat[][4], + const float co1[3], const float co2[3], const float mvalf[2], + const float inset) +{ + float vec1[2], vec2[2]; + + ED_view3d_project_float_v2_m4(ar, co1, vec1, mat); + ED_view3d_project_float_v2_m4(ar, co2, vec2, mat); + + if (inset != 0.0f) { + const float dist = inset / len_v2v2(vec1, vec2); + interp_v2_v2v2(vec1, vec1, vec2, dist); + interp_v2_v2v2(vec2, vec2, vec1, dist); + } + + /* TODO: use dist_squared_to_line_segment_v2() looks like we only ever use for comparison */ + return dist_to_line_segment_v2(mvalf, vec1, vec2); +} + +#if 0 +static float edbm_rip_rip_linedist(ARegion *ar, float mat[][4], const float co1[3], const float co2[3], const float mvalf[2]) { float vec1[2], vec2[2]; @@ -64,9 +91,22 @@ static float edbm_rip_rip_edgedist(ARegion *ar, float mat[][4], ED_view3d_project_float_v2_m4(ar, co1, vec1, mat); ED_view3d_project_float_v2_m4(ar, co2, vec2, mat); - /* TODO: use dist_squared_to_line_segment_v2() looks like we only ever use for comparison */ - return dist_to_line_segment_v2(mvalf, vec1, vec2); + return dist_to_line_v2(mvalf, vec1, vec2); } +#endif + +/* calculaters a point along the loop tangent which can be used to measure against edges */ +static void edbm_calc_loop_co(BMLoop *l, float l_mid_co[3]) +{ + BM_loop_calc_face_tangent(l, l_mid_co); + + /* scale to average of surrounding edge size, only needs to be approx, but should + * be roughly equivalent to the check below which uses the middle of the edge. */ + mul_v3_fl(l_mid_co, (BM_edge_calc_length(l->e) + BM_edge_calc_length(l->prev->e)) / 2.0f); + + add_v3_v3(l_mid_co, l->v->co); +} + static float edbm_rip_edge_side_measure(BMEdge *e, BMLoop *e_l, ARegion *ar, @@ -417,7 +457,7 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, wmEvent *event) totboundary_edge += (is_boundary != 0 || BM_edge_is_wire(e)); if (!BM_elem_flag_test(e, BM_ELEM_HIDDEN)) { if (is_boundary == FALSE && BM_edge_is_manifold(e)) { - d = edbm_rip_rip_edgedist(ar, projectMat, e->v1->co, e->v2->co, fmval); + d = edbm_rip_rip_edgedist(ar, projectMat, e->v1->co, e->v2->co, fmval, INSET_DEFAULT); if (d < dist) { dist = d; e2 = e; @@ -426,6 +466,42 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, wmEvent *event) } } + /* if we are ripping a single vertex from 3 faces, + * then measure the distance to the face corner as well as the edge */ + if (BM_vert_face_count(v) == 3 && + BM_vert_edge_count(v) == 3) + { + BMEdge *e_all[3]; + BMLoop *l_all[3]; + int i1, i2; + + BM_iter_as_array(bm, BM_EDGES_OF_VERT, v, (void **)e_all, 3); + BM_iter_as_array(bm, BM_LOOPS_OF_VERT, v, (void **)l_all, 3); + + /* not do a loop similar to the one above, but test against loops */ + for (i1 = 0; i1 < 3; i1++) { + /* consider wire as boundary for this purpose, + * otherwise we can't a face away from a wire edge */ + float l_mid_co[3]; + l = l_all[i1]; + edbm_calc_loop_co(l, l_mid_co); + d = edbm_rip_rip_edgedist(ar, projectMat, l->v->co, l_mid_co, fmval, INSET_DEFAULT); + + if (d < dist) { + dist = d; + + /* find the edge that is not in this loop */ + e2 = NULL; + for (i2 = 0; i2 < 3; i2++) { + if (!BM_edge_in_loop(e_all[i2], l)) { + e2 = e_all[i2]; + break; + } + } + BLI_assert(e2 != NULL); + } + } + } } /* should we go ahead with edge rip or do we need to do special case, split off vertex?: @@ -473,14 +549,9 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, wmEvent *event) BM_ITER_ELEM (l, &iter, vout[i], BM_LOOPS_OF_VERT) { if (!BM_elem_flag_test(l->f, BM_ELEM_HIDDEN)) { float l_mid_co[3]; - BM_loop_calc_face_tangent(l, l_mid_co); + edbm_calc_loop_co(l, l_mid_co); - /* scale to average of surrounding edge size, only needs to be approx, but should - * be roughly equivalent to the check below which uses the middle of the edge. */ - mul_v3_fl(l_mid_co, (BM_edge_calc_length(l->e) + BM_edge_calc_length(l->prev->e)) / 2.0f); - add_v3_v3(l_mid_co, v->co); - - d = edbm_rip_rip_edgedist(ar, projectMat, v->co, l_mid_co, fmval); + d = edbm_rip_rip_edgedist(ar, projectMat, v->co, l_mid_co, fmval, INSET_DEFAULT); if (d < dist) { dist = d; @@ -496,7 +567,7 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, wmEvent *event) float e_mid_co[3]; mid_v3_v3v3(e_mid_co, e->v1->co, e->v2->co); - d = edbm_rip_rip_edgedist(ar, projectMat, v->co, e_mid_co, fmval); + d = edbm_rip_rip_edgedist(ar, projectMat, v->co, e_mid_co, fmval, INSET_DEFAULT); if (d < dist) { dist = d; @@ -593,7 +664,7 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, wmEvent *event) add_v3_v3v3(l_corner_co, l_prev_co, l_next_co); add_v3_v3(l_corner_co, l->v->co); - d = edbm_rip_rip_edgedist(ar, projectMat, l->v->co, l_corner_co, fmval); + d = edbm_rip_rip_edgedist(ar, projectMat, l->v->co, l_corner_co, fmval, INSET_DEFAULT); if (d < dist) { v_best = v; dist = d; @@ -643,7 +714,7 @@ static int edbm_rip_invoke__edge(bContext *C, wmOperator *op, wmEvent *event) ED_view3d_ob_project_mat_get(rv3d, obedit, projectMat); - /* important this runs on the original selection, before tempering with tagging */ + /* important this runs on the original selection, before tampering with tagging */ eloop_pairs = edbm_ripsel_looptag_helper(bm); /* expand edge selection */ @@ -678,7 +749,7 @@ static int edbm_rip_invoke__edge(bContext *C, wmOperator *op, wmEvent *event) BMLoop *l_a = e2->l; BMLoop *l_b = l_a->radial_next; - /* find the best face to follow, this what the edge won't point away from + /* find the best face to follow, this way the edge won't point away from * the mouse when there are more then 4 (takes the shortest face fan around) */ l = (edbm_rip_edge_side_measure(e2, l_a, ar, projectMat, fmval) < edbm_rip_edge_side_measure(e2, l_b, ar, projectMat, fmval)) ? l_a : l_b; From da155c2dcbff2cf020dd817e8dca9b941accb4fb Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 13 Oct 2012 03:54:27 +0000 Subject: [PATCH 197/347] style cleanup: spelling --- source/blender/editors/mesh/editmesh_rip.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/source/blender/editors/mesh/editmesh_rip.c b/source/blender/editors/mesh/editmesh_rip.c index f85763f660c..215522bf74e 100644 --- a/source/blender/editors/mesh/editmesh_rip.c +++ b/source/blender/editors/mesh/editmesh_rip.c @@ -704,12 +704,8 @@ static int edbm_rip_invoke__edge(bContext *C, wmOperator *op, wmEvent *event) BMEdge *e, *e2; BMVert *v; const int totedge_orig = bm->totedge; - int i; float projectMat[4][4], fmval[3] = {event->mval[0], event->mval[1]}; - int totedge; - int all_minifold; - EdgeLoopPair *eloop_pairs; ED_view3d_ob_project_mat_get(rv3d, obedit, projectMat); @@ -719,10 +715,14 @@ static int edbm_rip_invoke__edge(bContext *C, wmOperator *op, wmEvent *event) /* expand edge selection */ BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { + int all_manifold; + int totedge_manifold; /* manifold, visible edges */ + int i; + e2 = NULL; i = 0; - totedge = 0; - all_minifold = TRUE; + totedge_manifold = 0; + all_manifold = TRUE; BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) { if (!BM_edge_is_wire(e) && @@ -734,18 +734,18 @@ static int edbm_rip_invoke__edge(bContext *C, wmOperator *op, wmEvent *event) e2 = e; i++; } - totedge++; + totedge_manifold++; } /** #BM_vert_other_disk_edge has no hidden checks so don't check hidden here */ - if ((all_minifold == TRUE) && (BM_edge_is_manifold(e) == FALSE)) { - all_minifold = FALSE; + if ((all_manifold == TRUE) && (BM_edge_is_manifold(e) == FALSE)) { + all_manifold = FALSE; } } /* single edge, extend */ if (i == 1 && e2->l) { - if ((totedge == 4) || (all_minifold == FALSE)) { + if ((totedge_manifold == 4) || (all_manifold == FALSE)) { BMLoop *l_a = e2->l; BMLoop *l_b = l_a->radial_next; From f81b06cfa5a3510ae7a16d14e2b3a9b7569a9b5a Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 13 Oct 2012 03:59:06 +0000 Subject: [PATCH 198/347] improve edge rip when the edge has only 2 other connected edges. common case ripping an edge of the default cube, it didn't run the edge size check. --- source/blender/editors/mesh/editmesh_rip.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/mesh/editmesh_rip.c b/source/blender/editors/mesh/editmesh_rip.c index 215522bf74e..c7f3c1c75ca 100644 --- a/source/blender/editors/mesh/editmesh_rip.c +++ b/source/blender/editors/mesh/editmesh_rip.c @@ -745,7 +745,10 @@ static int edbm_rip_invoke__edge(bContext *C, wmOperator *op, wmEvent *event) /* single edge, extend */ if (i == 1 && e2->l) { - if ((totedge_manifold == 4) || (all_manifold == FALSE)) { + /* note: if the case of 3 edges has one change in loop stepping, + * if this becomes more involved we may be better off splitting + * the 3 edge case into its own else-if branch */ + if ((totedge_manifold == 4 || totedge_manifold == 3) || (all_manifold == FALSE)) { BMLoop *l_a = e2->l; BMLoop *l_b = l_a->radial_next; @@ -759,7 +762,9 @@ static int edbm_rip_invoke__edge(bContext *C, wmOperator *op, wmEvent *event) * not crashing but adds duplicate edge. */ if (BM_edge_is_manifold(l->e)) { l = l->radial_next; - l = BM_face_other_edge_loop(l->f, l->e, v); + + if (totedge_manifold != 3) + l = BM_face_other_edge_loop(l->f, l->e, v); if (l) { BM_elem_flag_enable(l->e, BM_ELEM_TAG); From 3fa24c7d5f647098fb6961664e8fbf75fe812e22 Mon Sep 17 00:00:00 2001 From: Gaia Clary Date: Sat, 13 Oct 2012 10:31:35 +0000 Subject: [PATCH 199/347] differenciate log message for enabled/disabled modules --- release/scripts/modules/addon_utils.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/release/scripts/modules/addon_utils.py b/release/scripts/modules/addon_utils.py index 6658ee7fb2b..2aaef769c0b 100644 --- a/release/scripts/modules/addon_utils.py +++ b/release/scripts/modules/addon_utils.py @@ -323,7 +323,9 @@ def disable(module_name, default_set=True): import traceback traceback.print_exc() else: - print("addon_utils.disable", module_name, "not loaded") + if mod: state = "enabled" + else: state = "loaded" + print("addon_utils.disable: %s not %s." % (module_name, state)) # could be in more then once, unlikely but better do this just in case. addons = _bpy.context.user_preferences.addons From 4941f8ac44bc1efc4ae52e527b70796f63e10871 Mon Sep 17 00:00:00 2001 From: Gaia Clary Date: Sat, 13 Oct 2012 10:33:09 +0000 Subject: [PATCH 200/347] added filter for user installed addons --- release/scripts/startup/bl_ui/__init__.py | 9 +++++---- release/scripts/startup/bl_ui/space_userpref.py | 9 ++++++++- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/release/scripts/startup/bl_ui/__init__.py b/release/scripts/startup/bl_ui/__init__.py index 09d866c2ae5..e4be84d5396 100644 --- a/release/scripts/startup/bl_ui/__init__.py +++ b/release/scripts/startup/bl_ui/__init__.py @@ -92,9 +92,10 @@ def register(): def addon_filter_items(self, context): import addon_utils - items = [('All', "All", ""), - ('Enabled', "Enabled", ""), - ('Disabled', "Disabled", ""), + items = [('All', "All", "All Addons"), + ('User', "User", "All Addons Installed by User"), + ('Enabled', "Enabled", "All Enabled Addons"), + ('Disabled', "Disabled", "All Disabled Addons"), ] items_unique = set() @@ -119,7 +120,7 @@ def register(): WindowManager.addon_support = EnumProperty( items=[('OFFICIAL', "Official", "Officially supported"), ('COMMUNITY', "Community", "Maintained by community developers"), - ('TESTING', "Testing", "Newly contributed scripts (excluded from release builds)"), + ('TESTING', "Testing", "Newly contributed scripts (excluded from release builds)") ], name="Support", description="Display support level", diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py index 39e2cf40569..87d8a13e856 100644 --- a/release/scripts/startup/bl_ui/space_userpref.py +++ b/release/scripts/startup/bl_ui/space_userpref.py @@ -1040,6 +1040,9 @@ class USERPREF_PT_addons(Panel): userpref = context.user_preferences used_ext = {ext.module for ext in userpref.addons} + userpref_addons_folder = os.path.join(bpy.context.user_preferences.filepaths.script_directory,"addons") + scripts_addons_folder = bpy.utils.user_resource('SCRIPTS', "addons") + # collect the categories that can be filtered on addons = [(mod, addon_utils.module_bl_info(mod)) for mod in addon_utils.modules(addon_utils.addons_fake_modules)] @@ -1088,7 +1091,11 @@ class USERPREF_PT_addons(Panel): if ((filter == "All") or (filter == info["category"]) or (filter == "Enabled" and is_enabled) or - (filter == "Disabled" and not is_enabled)): + (filter == "Disabled" and not is_enabled) or + (filter == "User" and + ( mod.__file__.startswith(userpref_addons_folder) or + mod.__file__.startswith(scripts_addons_folder))) + ): if search and search not in info["name"].lower(): if info["author"]: From 29ab21ee95bd76dd7fae788c0300082f96fe88a1 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 13 Oct 2012 10:41:34 +0000 Subject: [PATCH 201/347] fix for own error, leaving in test code to set the smooth flag. --- source/blender/editors/mesh/editmesh_rip.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/source/blender/editors/mesh/editmesh_rip.c b/source/blender/editors/mesh/editmesh_rip.c index c7f3c1c75ca..8321272c80b 100644 --- a/source/blender/editors/mesh/editmesh_rip.c +++ b/source/blender/editors/mesh/editmesh_rip.c @@ -277,7 +277,6 @@ static EdgeLoopPair *edbm_ripsel_looptag_helper(BMesh *bm) uid_start = uid; while ((e = edbm_ripsel_edge_mark_step(v_step, uid))) { - BM_elem_flag_disable(e, BM_ELEM_SMOOTH); v_step = BM_edge_other_vert((e_step = e), v_step); uid++; /* only different line */ tot++; @@ -294,7 +293,6 @@ static EdgeLoopPair *edbm_ripsel_looptag_helper(BMesh *bm) v_step = e_first->v1; while ((e = edbm_ripsel_edge_mark_step(v_step, uid))) { - BM_elem_flag_disable(e, BM_ELEM_SMOOTH); v_step = BM_edge_other_vert((e_step = e), v_step); uid--; /* only different line */ tot++; From b6b2f37f2759a4738d6db970a7bda21709783f81 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Sat, 13 Oct 2012 10:42:38 +0000 Subject: [PATCH 202/347] Lattice Editing: Distortion-Free "Flip" Operator This operator (Ctrl-F) allows you to flip the lattice coordinates without inverting the normals of meshes deformed by the lattice (or the lattice's deformation space for that matter). Unlike the traditional mirror tool, this tool is aware of the fact that the vertex order for lattice control points matters, and that simply mirroring the coordinates will only cause the lattice to have an inverted deform along a particular axis (i.e. it will be scaling by a negative scaling factor along that axis). The problems (as I discovered the other day) with having such an inverted deformation space are that: - the normals of meshes/objects inside that will be incorrect/flipped (and will disappear in GLSL shading mode for instance) - transforming objects deformed by the lattices will become really tricky and counter-intuitive (e.g. rotate in opposite direction by asymmetric amounts to get desired result) - it is not always immediately obvious that problems have occurred Specific use cases this operator is meant to solve: 1) You've created a lattice-based deformer for one cartoonish eye. Now you want to make the second eye, but want to save some time crafting that basic shape again but mirrored. 2) You've got an even more finely crafted setup for stretchy-rigs, and now need to apply it to other parts of the rig. Notes: * I've implemented a separate operator for this vs extending/patching mirror transform tool as it's easier to implement this way, but also because there are still some cases where the old mirroring seems valid (i.e. you explicitly want these sort of distortion effects). * Currently this doesn't take selections into account, as it doesn't seem useful to do so. --- release/scripts/startup/bl_ui/space_view3d.py | 1 + source/blender/editors/object/object_intern.h | 1 + .../blender/editors/object/object_lattice.c | 252 +++++++++++++++++- source/blender/editors/object/object_ops.c | 3 + 4 files changed, 256 insertions(+), 1 deletion(-) diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 606b14d4221..1d09f0e045d 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -2147,6 +2147,7 @@ class VIEW3D_MT_edit_lattice(Menu): layout.menu("VIEW3D_MT_transform") layout.menu("VIEW3D_MT_mirror") layout.menu("VIEW3D_MT_snap") + layout.operator_menu_enum("lattice.flip", "axis") layout.separator() diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index 727286c3d80..0be9c92897e 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -138,6 +138,7 @@ void OBJECT_OT_hook_recenter(struct wmOperatorType *ot); /* object_lattice.c */ void LATTICE_OT_select_all(struct wmOperatorType *ot); void LATTICE_OT_make_regular(struct wmOperatorType *ot); +void LATTICE_OT_flip(struct wmOperatorType *ot); /* object_group.c */ void GROUP_OT_create(struct wmOperatorType *ot); diff --git a/source/blender/editors/object/object_lattice.c b/source/blender/editors/object/object_lattice.c index d8974ea677c..ac9c4f7adee 100644 --- a/source/blender/editors/object/object_lattice.c +++ b/source/blender/editors/object/object_lattice.c @@ -46,6 +46,7 @@ #include "DNA_scene_types.h" #include "RNA_access.h" +#include "RNA_define.h" #include "BKE_context.h" #include "BKE_depsgraph.h" @@ -167,7 +168,7 @@ void load_editLatt(Object *obedit) } } -/************************** Operators *************************/ +/************************** Select All Operator *************************/ void ED_setflagsLatt(Object *obedit, int flag) { @@ -254,6 +255,8 @@ void LATTICE_OT_select_all(wmOperatorType *ot) WM_operator_properties_select_all(ot); } +/************************** Make Regular Operator *************************/ + static int make_regular_poll(bContext *C) { Object *ob; @@ -300,6 +303,253 @@ void LATTICE_OT_make_regular(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } +/************************** Flip Verts Operator *************************/ + +/* flipping options */ +typedef enum eLattice_FlipAxes { + LATTICE_FLIP_U = 0, + LATTICE_FLIP_V = 1, + LATTICE_FLIP_W = 2 +} eLattice_FlipAxes; + +/* Helper macro for accessing item at index (u, v, w) + * < lt: (Lattice) + * < U: (int) u-axis coordinate of point + * < V: (int) v-axis coordinate of point + * < W: (int) w-axis coordinate of point + * < dimU: (int) number of points per row or number of columns (U-Axis) + * < dimV: (int) number of rows (V-Axis) + * > returns: (BPoint *) pointer to BPoint at this index + */ +#define LATTICE_PT(lt, U, V, W, dimU, dimV) \ + ( (lt)->def + \ + ((dimU) * (dimV)) * (W) + \ + (dimU) * (V) + \ + (U) \ + ) + +/* Flip midpoint value so that relative distances between midpoint and neighbour-pair is maintained + * ! Assumes that uvw <=> xyz (i.e. axis-aligned index-axes with coordinate-axes) + * - Helper for lattice_flip_exec() + */ +static void lattice_flip_point_value(Lattice *lt, int u, int v, int w, float mid, eLattice_FlipAxes axis) +{ + BPoint *bp; + float diff; + + /* just the point in the middle (unpaired) */ + bp = LATTICE_PT(lt, u, v, w, lt->pntsu, lt->pntsv); + + /* flip over axis */ + diff = mid - bp->vec[axis]; + bp->vec[axis] = mid + diff; +} + +/* Swap pairs of lattice points along a specified axis + * - Helper for lattice_flip_exec() + */ +static void lattice_swap_point_pairs(Lattice *lt, int u, int v, int w, float mid, eLattice_FlipAxes axis) +{ + BPoint *bpA, *bpB; + + int numU = lt->pntsu; + int numV = lt->pntsv; + int numW = lt->pntsw; + + int u0 = u, u1 = u; + int v0 = v, v1 = v; + int w0 = w, w1 = w; + + /* get pair index by just overriding the relevant pair-value + * - "-1" else buffer overflow + */ + switch (axis) { + case LATTICE_FLIP_U: + u1 = numU - u - 1; + break; + case LATTICE_FLIP_V: + v1 = numV - v - 1; + break; + case LATTICE_FLIP_W: + w1 = numW - w - 1; + break; + } + + /* get points to operate on */ + bpA = LATTICE_PT(lt, u0, v0, w0, numU, numV); + bpB = LATTICE_PT(lt, u1, v1, w1, numU, numV); + + /* Swap all coordinates, so that flipped coordinates belong to + * the indices on the correct side of the lattice. + * + * Coords: (-2 4) |0| (3 4) --> (3 4) |0| (-2 4) + * Indices: (0,L) (1,R) --> (0,L) (1,R) + */ + swap_v3_v3(bpA->vec, bpB->vec); + + /* However, we need to mirror the coordinate values on the axis we're dealing with, + * otherwise we'd have effectively only rotated the points around. If we don't do this, + * we'd just be reimplementing the naive mirroring algorithm, which causes unwanted deforms + * such as flipped normals, etc. + * + * Coords: (3 4) |0| (-2 4) --\ + * \-> (-3 4) |0| (2 4) + * Indices: (0,L) (1,R) --> (0,L) (1,R) + */ + lattice_flip_point_value(lt, u0, v0, w0, mid, axis); + lattice_flip_point_value(lt, u1, v1, w1, mid, axis); +} + +static int lattice_flip_exec(bContext *C, wmOperator *op) +{ + Object *obedit = CTX_data_edit_object(C); + Lattice *lt; + + eLattice_FlipAxes axis = RNA_enum_get(op->ptr, "axis"); + int numU, numV, numW; + int totP; + + float mid = 0.0f; + short isOdd = 0; + + /* get lattice - we need the "edit lattice" from the lattice... confusing... */ + lt = (Lattice *)obedit->data; + lt = lt->editlatt->latt; + + numU = lt->pntsu; + numV = lt->pntsv; + numW = lt->pntsw; + totP = numU * numV * numW; + + /* First Pass: determine midpoint - used for flipping center verts if there are odd number of points on axis */ + switch (axis) { + case LATTICE_FLIP_U: + isOdd = numU & 1; + break; + case LATTICE_FLIP_V: + isOdd = numV & 1; + break; + case LATTICE_FLIP_W: + isOdd = numW & 1; + break; + + default: + printf("lattice_flip(): Unknown flipping axis (%d)\n", axis); + return OPERATOR_CANCELLED; + } + + if (isOdd) { + BPoint *bp; + float avgInv = 1.0f / (float)totP; + int i; + + /* midpoint calculation - assuming that u/v/w are axis-aligned */ + for (i = 0, bp = lt->def; i < totP; i++, bp++) { + mid += bp->vec[axis] * avgInv; + } + } + + /* Second Pass: swap pairs of vertices per axis, assuming they are all sorted */ + switch (axis) { + case LATTICE_FLIP_U: + { + int u, v, w; + + /* v/w strips - front to back, top to bottom */ + for (w = 0; w < numW; w++) { + for (v = 0; v < numV; v++) { + /* swap coordinates of pairs of vertices on u */ + for (u = 0; u < (numU / 2); u++) { + lattice_swap_point_pairs(lt, u, v, w, mid, axis); + } + + /* flip u-coordinate of midpoint (i.e. unpaired point on u) */ + if (isOdd) { + u = (numU / 2); + lattice_flip_point_value(lt, u, v, w, mid, axis); + } + } + } + } + break; + case LATTICE_FLIP_V: + { + int u, v, w; + + /* u/w strips - front to back, left to right */ + for (w = 0; w < numW; w++) { + for (u = 0; u < numU; u++) { + /* swap coordinates of pairs of vertices on v */ + for (v = 0; v < (numV / 2); v++) { + lattice_swap_point_pairs(lt, u, v, w, mid, axis); + } + + /* flip v-coordinate of midpoint (i.e. unpaired point on v) */ + if (isOdd) { + v = (numV / 2); + lattice_flip_point_value(lt, u, v, w, mid, axis); + } + } + } + } + break; + case LATTICE_FLIP_W: + { + int u, v, w; + + for (v = 0; v < numV; v++) { + for (u = 0; u < numU; u++) { + /* swap coordinates of pairs of vertices on w */ + for (w = 0; w < (numW / 2); w++) { + lattice_swap_point_pairs(lt, u, v, w, mid, axis); + } + + /* flip w-coordinate of midpoint (i.e. unpaired point on w) */ + if (isOdd) { + w = (numW / 2); + lattice_flip_point_value(lt, u, v, w, mid, axis); + } + } + } + } + break; + + default: /* shouldn't happen, but just in case */ + break; + } + + /* updates */ + DAG_id_tag_update(&obedit->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); + + return OPERATOR_FINISHED; +} + +void LATTICE_OT_flip(wmOperatorType *ot) +{ + static EnumPropertyItem flip_items[] = { + {LATTICE_FLIP_U, "U", 0, "U (X) Axis", ""}, + {LATTICE_FLIP_V, "V", 0, "V (Y) Axis", ""}, + {LATTICE_FLIP_W, "W", 0, "W (Z) Axis", ""}, + {0, NULL, 0, NULL, NULL}}; + + /* identifiers */ + ot->name = "Flip (Distortion Free)"; + ot->description = "Mirror all control points without inverting the lattice deform"; + ot->idname = "LATTICE_OT_flip"; + + /* api callbacks */ + ot->poll = ED_operator_editlattice; + ot->invoke = WM_menu_invoke; + ot->exec = lattice_flip_exec; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + ot->prop = RNA_def_enum(ot->srna, "axis", flip_items, LATTICE_FLIP_U, "Flip Axis", "Coordinates along this axis get flipped"); +} + /****************************** Mouse Selection *************************/ static void findnearestLattvert__doClosest(void *userData, BPoint *bp, const float screen_co[2]) diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index 65d0c966dc2..b6d3594c826 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -211,6 +211,7 @@ void ED_operatortypes_object(void) WM_operatortype_append(LATTICE_OT_select_all); WM_operatortype_append(LATTICE_OT_make_regular); + WM_operatortype_append(LATTICE_OT_flip); WM_operatortype_append(OBJECT_OT_group_add); WM_operatortype_append(OBJECT_OT_group_link); @@ -424,6 +425,8 @@ void ED_keymap_object(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "OBJECT_OT_vertex_parent_set", PKEY, KM_PRESS, KM_CTRL, 0); + WM_keymap_add_item(keymap, "LATTICE_OT_flip", FKEY, KM_PRESS, KM_CTRL, 0); + /* menus */ WM_keymap_add_menu(keymap, "VIEW3D_MT_hook", HKEY, KM_PRESS, KM_CTRL, 0); From 4ef69febebf88ddd7b912eea07145276725c81bd Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Sat, 13 Oct 2012 11:08:00 +0000 Subject: [PATCH 203/347] More spell check exceptions... --- release/scripts/modules/bl_i18n_utils/spell_check_utils.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/release/scripts/modules/bl_i18n_utils/spell_check_utils.py b/release/scripts/modules/bl_i18n_utils/spell_check_utils.py index 609af832865..6911b0317e7 100644 --- a/release/scripts/modules/bl_i18n_utils/spell_check_utils.py +++ b/release/scripts/modules/bl_i18n_utils/spell_check_utils.py @@ -37,10 +37,12 @@ dict_uimsgs = { "aren", # aren't "betweens", # yuck! in-betweens! "boolean", "booleans", + "couldn", #couldn't "decrement", "derivate", "doesn", # doesn't "fader", + "hasn", # hasn't "hoc", # ad-hoc "indices", "iridas", @@ -290,6 +292,7 @@ dict_uimsgs = { "crossfade", "deinterlace", "dropoff", + "dv", "eigenvectors", "equirectangular", "fisheye", @@ -303,6 +306,7 @@ dict_uimsgs = { "midtones", "mipmap", "mipmaps", "mip", "ngon", "ngons", + "ntsc", "nurb", "nurbs", "perlin", "phong", @@ -347,6 +351,8 @@ dict_uimsgs = { "metaelement", "metaelements", "metastrip", "metastrips", "movieclip", + "mpoly", + "mtex", "nabla", "navmesh", "outliner", @@ -362,6 +368,7 @@ dict_uimsgs = { "stucci", "sunsky", "subsurf", + "tessface", "tessfaces", "texface", "timeline", "timelines", "tosphere", From ee67123748c80463164278e1f295c5ae6ff728f7 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 13 Oct 2012 11:23:04 +0000 Subject: [PATCH 204/347] code cleanup: minor edits on recent commit. --- release/scripts/modules/addon_utils.py | 5 ++--- release/scripts/startup/bl_ui/space_userpref.py | 6 ++---- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/release/scripts/modules/addon_utils.py b/release/scripts/modules/addon_utils.py index 2aaef769c0b..7e604c5de4c 100644 --- a/release/scripts/modules/addon_utils.py +++ b/release/scripts/modules/addon_utils.py @@ -323,9 +323,8 @@ def disable(module_name, default_set=True): import traceback traceback.print_exc() else: - if mod: state = "enabled" - else: state = "loaded" - print("addon_utils.disable: %s not %s." % (module_name, state)) + print("addon_utils.disable: %s not %s." % + (module_name, "disabled" if mod is None else "loaded")) # could be in more then once, unlikely but better do this just in case. addons = _bpy.context.user_preferences.addons diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py index 87d8a13e856..d5dd07610b6 100644 --- a/release/scripts/startup/bl_ui/space_userpref.py +++ b/release/scripts/startup/bl_ui/space_userpref.py @@ -1040,7 +1040,7 @@ class USERPREF_PT_addons(Panel): userpref = context.user_preferences used_ext = {ext.module for ext in userpref.addons} - userpref_addons_folder = os.path.join(bpy.context.user_preferences.filepaths.script_directory,"addons") + userpref_addons_folder = os.path.join(userpref.filepaths.script_directory, "addons") scripts_addons_folder = bpy.utils.user_resource('SCRIPTS', "addons") # collect the categories that can be filtered on @@ -1092,9 +1092,7 @@ class USERPREF_PT_addons(Panel): (filter == info["category"]) or (filter == "Enabled" and is_enabled) or (filter == "Disabled" and not is_enabled) or - (filter == "User" and - ( mod.__file__.startswith(userpref_addons_folder) or - mod.__file__.startswith(scripts_addons_folder))) + (filter == "User" and (mod.__file__.startswith(scripts_addons_folder, userpref_addons_folder))) ): if search and search not in info["name"].lower(): From 51105bb2bd57b1a56517b30384304326b6bc75fb Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Sat, 13 Oct 2012 12:11:01 +0000 Subject: [PATCH 205/347] Fix for wrong cycles tangent in some cases, was missing transform. --- intern/cycles/kernel/svm/svm_geometry.h | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/intern/cycles/kernel/svm/svm_geometry.h b/intern/cycles/kernel/svm/svm_geometry.h index 582c079fd6a..30afd6322a7 100644 --- a/intern/cycles/kernel/svm/svm_geometry.h +++ b/intern/cycles/kernel/svm/svm_geometry.h @@ -29,12 +29,18 @@ __device void svm_node_geometry(KernelGlobals *kg, ShaderData *sd, float *stack, case NODE_GEOM_N: data = sd->N; break; #ifdef __DPDU__ case NODE_GEOM_T: { - int attr_offset = find_attribute(kg, sd, ATTR_STD_TANGENT); + if(sd->object != ~0) { + int attr_offset = find_attribute(kg, sd, ATTR_STD_TANGENT); - if(attr_offset == ATTR_STD_NOT_FOUND) - data = normalize(sd->dPdu); + if(attr_offset != ATTR_STD_NOT_FOUND) { + data = triangle_attribute_float3(kg, sd, ATTR_ELEMENT_VERTEX, attr_offset, NULL, NULL); + object_normal_transform(kg, sd, &data); + } + else + data = normalize(sd->dPdu); + } else - data = triangle_attribute_float3(kg, sd, ATTR_ELEMENT_VERTEX, attr_offset, NULL, NULL); + data = normalize(sd->dPdu); break; } From 3b88a29abfdba618cc874f06ac8312218ae29b00 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Sat, 13 Oct 2012 12:38:32 +0000 Subject: [PATCH 206/347] Cycles: progressive refine option Just makes progressive refine :) This means the whole image would be refined gradually using as much threads as it's set in performance settings. Having enough tiles is required to have this option working as it's expected. Technically it's implemented by repeatedly computing next sample for all the tiles before switching to next sample. This works around 7-12% slower than regular tile-based rendering, so use this option only if you really need it. This commit also fixes progressive update of image when Save Buffers option is enabled. And one more thing this commit fixes is handling display buffer with Save Buffers option enabled. If this option is enabled image buffer wouldn't have neither byte nor float buffer until image is fully rendered which could backfire in missing image while rendering in cases color management cache became full. This issue solved by allocating byte buffer for image buffer from tile update callback. Patch was reviewed by Brecht. He also made some minor edits to original version to patch. Thanks, man! --- intern/cycles/blender/addon/properties.py | 5 + intern/cycles/blender/addon/ui.py | 2 + intern/cycles/blender/blender_session.cpp | 7 +- intern/cycles/blender/blender_sync.cpp | 8 +- intern/cycles/device/device_cpu.cpp | 24 +++-- intern/cycles/device/device_cuda.cpp | 6 +- intern/cycles/device/device_opencl.cpp | 6 +- intern/cycles/device/device_task.h | 1 + intern/cycles/render/session.cpp | 93 ++++++++++++++++--- intern/cycles/render/session.h | 9 ++ intern/cycles/render/tile.cpp | 2 + intern/cycles/render/tile.h | 2 + source/blender/blenkernel/intern/image.c | 14 ++- .../operations/COM_ViewerBaseOperation.cpp | 2 +- .../blender/editors/render/render_internal.c | 4 +- .../editors/sculpt_paint/paint_image.c | 2 +- source/blender/imbuf/IMB_colormanagement.h | 3 +- source/blender/imbuf/intern/colormanagement.c | 4 +- 18 files changed, 158 insertions(+), 36 deletions(-) diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index 0fadfa0afc8..f2a88f0d96c 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -284,6 +284,11 @@ class CyclesRenderSettings(bpy.types.PropertyGroup): description="Cache last built BVH to disk for faster re-render if no geometry changed", default=False, ) + cls.use_progressive_refine = BoolProperty( + name="Progressive Refine", + description="Instead of rendering each tile until it is finished, refine the whole image progressively so rendering can be stopped manually when the noise is low enough", + default=False, + ) @classmethod def unregister(cls): diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index ca43c345bfa..93309f63a84 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -198,6 +198,8 @@ class CyclesRender_PT_performance(CyclesButtonsPanel, Panel): sub.prop(rd, "parts_x", text="X") sub.prop(rd, "parts_y", text="Y") + sub.prop(cscene, "use_progressive_refine") + subsub = sub.column() subsub.enabled = not rd.use_border subsub.prop(rd, "use_save_buffers") diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp index 7b80c520e72..0a09102bd4f 100644 --- a/intern/cycles/blender/blender_session.cpp +++ b/intern/cycles/blender/blender_session.cpp @@ -466,9 +466,12 @@ void BlenderSession::get_progress(float& progress, double& total_time) session->progress.get_tile(tile, total_time, tile_time); sample = session->progress.get_sample(); - samples_per_tile = session->tile_manager.state.num_samples; + samples_per_tile = session->params.samples; - progress = ((float)sample/(float)(tile_total * samples_per_tile)); + if(samples_per_tile) + progress = ((float)sample/(float)(tile_total * samples_per_tile)); + else + progress = 0.0; } void BlenderSession::update_status_progress() diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp index 3d36eba0c4b..00130f357dd 100644 --- a/intern/cycles/blender/blender_sync.cpp +++ b/intern/cycles/blender/blender_sync.cpp @@ -380,8 +380,14 @@ SessionParams BlenderSync::get_session_params(BL::RenderEngine b_engine, BL::Use params.reset_timeout = get_float(cscene, "debug_reset_timeout"); params.text_timeout = get_float(cscene, "debug_text_timeout"); + params.progressive_refine = get_boolean(cscene, "use_progressive_refine"); + if(background) { - params.progressive = false; + if(params.progressive_refine) + params.progressive = true; + else + params.progressive = false; + params.start_resolution = INT_MAX; } else diff --git a/intern/cycles/device/device_cpu.cpp b/intern/cycles/device/device_cpu.cpp index 4c54671b0d0..b727a83d024 100644 --- a/intern/cycles/device/device_cpu.cpp +++ b/intern/cycles/device/device_cpu.cpp @@ -135,8 +135,10 @@ public: void thread_path_trace(DeviceTask& task) { - if(task_pool.cancelled()) - return; + if(task_pool.cancelled()) { + if(task.need_finish_queue == false) + return; + } #ifdef WITH_OSL if(kernel_osl_use(kg)) @@ -154,8 +156,10 @@ public: #ifdef WITH_OPTIMIZED_KERNEL if(system_cpu_support_optimized()) { for(int sample = start_sample; sample < end_sample; sample++) { - if (task.get_cancel() || task_pool.cancelled()) - break; + if (task.get_cancel() || task_pool.cancelled()) { + if(task.need_finish_queue == false) + break; + } for(int y = tile.y; y < tile.y + tile.h; y++) { for(int x = tile.x; x < tile.x + tile.w; x++) { @@ -173,8 +177,10 @@ public: #endif { for(int sample = start_sample; sample < end_sample; sample++) { - if (task.get_cancel() || task_pool.cancelled()) - break; + if (task.get_cancel() || task_pool.cancelled()) { + if(task.need_finish_queue == false) + break; + } for(int y = tile.y; y < tile.y + tile.h; y++) { for(int x = tile.x; x < tile.x + tile.w; x++) { @@ -191,8 +197,10 @@ public: task.release_tile(tile); - if(task_pool.cancelled()) - break; + if(task_pool.cancelled()) { + if(task.need_finish_queue == false) + break; + } } #ifdef WITH_OSL diff --git a/intern/cycles/device/device_cuda.cpp b/intern/cycles/device/device_cuda.cpp index c8dcfdc2f3d..04b4cb0950a 100644 --- a/intern/cycles/device/device_cuda.cpp +++ b/intern/cycles/device/device_cuda.cpp @@ -837,8 +837,10 @@ public: int end_sample = tile.start_sample + tile.num_samples; for(int sample = start_sample; sample < end_sample; sample++) { - if (task->get_cancel()) - break; + if (task->get_cancel()) { + if(task->need_finish_queue == false) + break; + } path_trace(tile, sample); diff --git a/intern/cycles/device/device_opencl.cpp b/intern/cycles/device/device_opencl.cpp index 673ffdf79fd..aa4f17ea325 100644 --- a/intern/cycles/device/device_opencl.cpp +++ b/intern/cycles/device/device_opencl.cpp @@ -686,8 +686,10 @@ public: int end_sample = tile.start_sample + tile.num_samples; for(int sample = start_sample; sample < end_sample; sample++) { - if (task->get_cancel()) - break; + if (task->get_cancel()) { + if(task->need_finish_queue == false) + break; + } path_trace(tile, sample); diff --git a/intern/cycles/device/device_task.h b/intern/cycles/device/device_task.h index cfb3d8d988e..8ca8b88ea49 100644 --- a/intern/cycles/device/device_task.h +++ b/intern/cycles/device/device_task.h @@ -65,6 +65,7 @@ public: boost::function release_tile; boost::function get_cancel; + bool need_finish_queue; protected: double last_update_time; }; diff --git a/intern/cycles/render/session.cpp b/intern/cycles/render/session.cpp index cd410e4e011..65b20f1dd2c 100644 --- a/intern/cycles/render/session.cpp +++ b/intern/cycles/render/session.cpp @@ -96,6 +96,9 @@ Session::~Session() display->write(device, params.output_path); } + foreach(RenderBuffers *buffers, tile_buffers) + delete buffers; + delete buffers; delete display; delete scene; @@ -173,6 +176,8 @@ bool Session::draw_gpu(BufferParams& buffer_params) void Session::run_gpu() { + bool tiles_written = false; + start_time = time_dt(); reset_time = time_dt(); paused_time = 0.0; @@ -267,10 +272,15 @@ void Session::run_gpu() if(device->error_message() != "") progress.set_cancel(device->error_message()); + tiles_written = update_progressive_refine(progress.get_cancel()); + if(progress.get_cancel()) break; } } + + if(!tiles_written) + update_progressive_refine(true); } /* CPU Session */ @@ -313,8 +323,12 @@ bool Session::draw_cpu(BufferParams& buffer_params) bool Session::acquire_tile(Device *tile_device, RenderTile& rtile) { - if(progress.get_cancel()) - return false; + if(progress.get_cancel()) { + if(params.progressive_refine == false) { + /* for progressive refine current sample should be finished for all tiles */ + return false; + } + } thread_scoped_lock tile_lock(tile_mutex); @@ -338,7 +352,7 @@ bool Session::acquire_tile(Device *tile_device, RenderTile& rtile) /* in case of a permant buffer, return it, otherwise we will allocate * a new temporary buffer */ - if(!write_render_tile_cb) { + if(!params.background) { tile_manager.state.buffer.get_offset_stride(rtile.offset, rtile.stride); rtile.buffer = buffers->buffer.device_pointer; @@ -360,9 +374,35 @@ bool Session::acquire_tile(Device *tile_device, RenderTile& rtile) buffer_params.get_offset_stride(rtile.offset, rtile.stride); - /* allocate buffers */ RenderBuffers *tilebuffers = new RenderBuffers(tile_device); - tilebuffers->reset(tile_device, buffer_params); + + /* allocate buffers */ + if(params.progressive_refine) { + int tile_x = rtile.x / params.tile_size.x; + int tile_y = rtile.y / params.tile_size.y; + + int tile_index = tile_y * tile_manager.state.tile_w + tile_x; + + tile_lock.lock(); + + if(tile_buffers.size() == 0) + tile_buffers.resize(tile_manager.state.num_tiles, NULL); + + tilebuffers = tile_buffers[tile_index]; + if(tilebuffers == NULL) { + tilebuffers = new RenderBuffers(tile_device); + tile_buffers[tile_index] = tilebuffers; + + tilebuffers->reset(tile_device, buffer_params); + } + + tile_lock.unlock(); + } + else { + tilebuffers = new RenderBuffers(tile_device); + + tilebuffers->reset(tile_device, buffer_params); + } rtile.buffer = tilebuffers->buffer.device_pointer; rtile.rng_state = tilebuffers->rng_state.device_pointer; @@ -377,9 +417,11 @@ void Session::update_tile_sample(RenderTile& rtile) thread_scoped_lock tile_lock(tile_mutex); if(update_render_tile_cb) { - /* todo: optimize this by making it thread safe and removing lock */ + if(params.progressive_refine == false) { + /* todo: optimize this by making it thread safe and removing lock */ - update_render_tile_cb(rtile); + update_render_tile_cb(rtile); + } } update_status_time(); @@ -390,10 +432,12 @@ void Session::release_tile(RenderTile& rtile) thread_scoped_lock tile_lock(tile_mutex); if(write_render_tile_cb) { - /* todo: optimize this by making it thread safe and removing lock */ - write_render_tile_cb(rtile); + if(params.progressive_refine == false) { + /* todo: optimize this by making it thread safe and removing lock */ + write_render_tile_cb(rtile); - delete rtile.buffers; + delete rtile.buffers; + } } update_status_time(); @@ -401,6 +445,8 @@ void Session::release_tile(RenderTile& rtile) void Session::run_cpu() { + bool tiles_written = false; + { /* reset once to start */ thread_scoped_lock reset_lock(delayed_reset.mutex); @@ -502,10 +548,15 @@ void Session::run_cpu() if(device->error_message() != "") progress.set_cancel(device->error_message()); + + tiles_written = update_progressive_refine(progress.get_cancel()); } progress.set_update(); } + + if(!tiles_written) + update_progressive_refine(true); } void Session::run() @@ -722,6 +773,7 @@ void Session::path_trace() task.get_cancel = function_bind(&Progress::get_cancel, &this->progress); task.update_tile_sample = function_bind(&Session::update_tile_sample, this, _1); task.update_progress_sample = function_bind(&Session::update_progress_sample, this); + task.need_finish_queue = params.progressive_refine; device->task_add(task); } @@ -752,5 +804,24 @@ void Session::tonemap() display_outdated = false; } -CCL_NAMESPACE_END +bool Session::update_progressive_refine(bool cancel) +{ + int sample = tile_manager.state.sample + 1; + if(params.progressive_refine) { + foreach(RenderBuffers *buffers, tile_buffers) { + RenderTile rtile; + rtile.buffers = buffers; + rtile.sample = sample; + + if(rtile.sample == params.samples || cancel) + write_render_tile_cb(rtile); + else + update_render_tile_cb(rtile); + } + } + + return sample == params.samples; +} + +CCL_NAMESPACE_END diff --git a/intern/cycles/render/session.h b/intern/cycles/render/session.h index eda8b3da60e..dc3e7504766 100644 --- a/intern/cycles/render/session.h +++ b/intern/cycles/render/session.h @@ -25,6 +25,7 @@ #include "util_progress.h" #include "util_thread.h" +#include "util_vector.h" CCL_NAMESPACE_BEGIN @@ -42,6 +43,7 @@ class SessionParams { public: DeviceInfo device; bool background; + bool progressive_refine; string output_path; bool progressive; @@ -58,6 +60,7 @@ public: SessionParams() { background = false; + progressive_refine = false; output_path = ""; progressive = false; @@ -76,6 +79,7 @@ public: { return !(device.type == params.device.type && device.id == params.device.id && background == params.background + && progressive_refine == params.progressive_refine && output_path == params.output_path /* && samples == params.samples */ && progressive == params.progressive @@ -173,6 +177,11 @@ protected: double reset_time; double preview_time; double paused_time; + + /* progressive refine */ + bool update_progressive_refine(bool cancel); + + vector tile_buffers; }; CCL_NAMESPACE_END diff --git a/intern/cycles/render/tile.cpp b/intern/cycles/render/tile.cpp index 874f1a6b3aa..02c0ee640a3 100644 --- a/intern/cycles/render/tile.cpp +++ b/intern/cycles/render/tile.cpp @@ -102,6 +102,8 @@ void TileManager::set_tiles() } state.num_tiles = state.tiles.size(); + state.tile_w = (tile_size.x >= image_w) ? 1 : (image_w + tile_size.x - 1) / tile_size.x; + state.tile_h = (tile_size.y >= image_h) ? 1 : (image_h + tile_size.y - 1) / tile_size.y; state.buffer.width = image_w; state.buffer.height = image_h; diff --git a/intern/cycles/render/tile.h b/intern/cycles/render/tile.h index d820f74e3bd..587dfbe4f1a 100644 --- a/intern/cycles/render/tile.h +++ b/intern/cycles/render/tile.h @@ -54,6 +54,8 @@ public: int resolution_divider; int num_tiles; int num_rendered_tiles; + int tile_w; + int tile_h; list tiles; } state; diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index c003a86a0b7..9a1ea15da97 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -2617,11 +2617,21 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **lock_ /* free rect buffer if float buffer changes, so it can be recreated with * the updated result, and also in case we got byte buffer from sequencer, * so we don't keep reference to freed buffer */ - if (ibuf->rect_float != rectf || rect || !rectf) + if (ibuf->rect_float != rectf || rect) imb_freerectImBuf(ibuf); - if (rect) + if (rect) { ibuf->rect = rect; + } + else { + /* byte buffer of render result has been freed, make sure image buffers + * does not reference to this buffer anymore + * need check for whether byte buffer was allocated and owned by image itself + * or if it's reusing buffer from render result + */ + if ((ibuf->mall & IB_rect) == 0) + ibuf->rect = NULL; + } if (rectf) { ibuf->rect_float = rectf; diff --git a/source/blender/compositor/operations/COM_ViewerBaseOperation.cpp b/source/blender/compositor/operations/COM_ViewerBaseOperation.cpp index d9ca131721f..55a001530ee 100644 --- a/source/blender/compositor/operations/COM_ViewerBaseOperation.cpp +++ b/source/blender/compositor/operations/COM_ViewerBaseOperation.cpp @@ -107,7 +107,7 @@ void ViewerBaseOperation:: updateImage(rcti *rect) { IMB_partial_display_buffer_update(this->m_ibuf, this->m_outputBuffer, NULL, getWidth(), 0, 0, this->m_viewSettings, this->m_displaySettings, - rect->xmin, rect->ymin, rect->xmax, rect->ymax); + rect->xmin, rect->ymin, rect->xmax, rect->ymax, FALSE); WM_main_add_notifier(NC_WINDOW | ND_DRAW, NULL); } diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c index c08ea2b6429..b61280f14ce 100644 --- a/source/blender/editors/render/render_internal.c +++ b/source/blender/editors/render/render_internal.c @@ -80,7 +80,6 @@ void image_buffer_rect_update(Scene *scene, RenderResult *rr, ImBuf *ibuf, volat float *rectf = NULL; int ymin, ymax, xmin, xmax; int rymin, rxmin; - /* unsigned char *rectc; */ /* UNUSED */ /* if renrect argument, we only refresh scanlines */ if (renrect) { @@ -143,11 +142,10 @@ void image_buffer_rect_update(Scene *scene, RenderResult *rr, ImBuf *ibuf, volat imb_addrectImBuf(ibuf); rectf += 4 * (rr->rectx * ymin + xmin); - /* rectc = (unsigned char *)(ibuf->rect + ibuf->x * rymin + rxmin); */ /* UNUSED */ IMB_partial_display_buffer_update(ibuf, rectf, NULL, rr->rectx, rxmin, rymin, &scene->view_settings, &scene->display_settings, - rxmin, rymin, rxmin + xmax, rymin + ymax); + rxmin, rymin, rxmin + xmax, rymin + ymax, TRUE); } /* ****************************** render invoking ***************** */ diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c index f60d34428b3..480d4ee6ac1 100644 --- a/source/blender/editors/sculpt_paint/paint_image.c +++ b/source/blender/editors/sculpt_paint/paint_image.c @@ -4249,7 +4249,7 @@ static void imapaint_image_update(Scene *scene, SpaceImage *sima, Image *image, IMB_partial_display_buffer_update(ibuf, ibuf->rect_float, (unsigned char *) ibuf->rect, ibuf->x, 0, 0, &scene->view_settings, &scene->display_settings, imapaintpartial.x1, imapaintpartial.y1, - imapaintpartial.x2, imapaintpartial.y2); + imapaintpartial.x2, imapaintpartial.y2, FALSE); } else { ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID; diff --git a/source/blender/imbuf/IMB_colormanagement.h b/source/blender/imbuf/IMB_colormanagement.h index e2604241caf..0653956e113 100644 --- a/source/blender/imbuf/IMB_colormanagement.h +++ b/source/blender/imbuf/IMB_colormanagement.h @@ -130,7 +130,8 @@ void IMB_colormanagement_colorspace_items_add(struct EnumPropertyItem **items, i void IMB_partial_display_buffer_update(struct ImBuf *ibuf, const float *linear_buffer, const unsigned char *buffer_byte, int stride, int offset_x, int offset_y, const struct ColorManagedViewSettings *view_settings, const struct ColorManagedDisplaySettings *display_settings, - int xmin, int ymin, int xmax, int ymax); + int xmin, int ymin, int xmax, int ymax, + int update_orig_byte_buffer); /* ** Pixel processor functions ** */ struct ColormanageProcessor *IMB_colormanagement_display_processor_new(const struct ColorManagedViewSettings *view_settings, diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c index 37510c10e9a..40b07c02cd7 100644 --- a/source/blender/imbuf/intern/colormanagement.c +++ b/source/blender/imbuf/intern/colormanagement.c @@ -2382,9 +2382,9 @@ static void partial_buffer_update_rect(ImBuf *ibuf, unsigned char *display_buffe void IMB_partial_display_buffer_update(ImBuf *ibuf, const float *linear_buffer, const unsigned char *byte_buffer, int stride, int offset_x, int offset_y, const ColorManagedViewSettings *view_settings, const ColorManagedDisplaySettings *display_settings, - int xmin, int ymin, int xmax, int ymax) + int xmin, int ymin, int xmax, int ymax, int update_orig_byte_buffer) { - if (ibuf->rect && ibuf->rect_float) { + if ((ibuf->rect && ibuf->rect_float) || update_orig_byte_buffer) { /* update byte buffer created by legacy color management */ unsigned char *rect = (unsigned char *) ibuf->rect; From 9f21b799c42e65d4f88338085bc13f5b205b983f Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Sat, 13 Oct 2012 13:40:05 +0000 Subject: [PATCH 207/347] And more UI messages spell check. --- .../scripts/modules/bl_i18n_utils/spell_check_utils.py | 4 ++++ source/blender/blenkernel/intern/packedFile.c | 2 +- source/blender/editors/armature/editarmature.c | 2 +- source/blender/editors/mesh/editmesh_tools.c | 2 +- source/blender/editors/mesh/mesh_data.c | 2 +- source/blender/editors/object/object_bake.c | 2 +- source/blender/editors/object/object_constraint.c | 4 ++-- source/blender/editors/object/object_transform.c | 2 +- source/blender/editors/render/render_opengl.c | 2 +- source/blender/editors/sculpt_paint/paint_image.c | 2 +- source/blender/editors/space_info/info_ops.c | 4 ++-- source/blender/editors/space_nla/nla_edit.c | 6 +++--- source/blender/editors/space_view3d/view3d_view.c | 2 +- source/blender/makesrna/intern/rna_main_api.c | 2 +- source/blender/makesrna/intern/rna_nodetree.c | 8 ++++---- source/blender/makesrna/intern/rna_smoke.c | 2 +- source/blender/makesrna/intern/rna_ui.c | 2 +- source/blender/render/intern/source/pipeline.c | 2 +- 18 files changed, 28 insertions(+), 24 deletions(-) diff --git a/release/scripts/modules/bl_i18n_utils/spell_check_utils.py b/release/scripts/modules/bl_i18n_utils/spell_check_utils.py index 6911b0317e7..ae463917f88 100644 --- a/release/scripts/modules/bl_i18n_utils/spell_check_utils.py +++ b/release/scripts/modules/bl_i18n_utils/spell_check_utils.py @@ -92,6 +92,7 @@ dict_uimsgs = { "gridline", "hemi", "inscatter", "inscattering", + "libdata", "lightless", "lookup", "lookups", "mathutils", @@ -103,6 +104,7 @@ dict_uimsgs = { "multires", "multiresolution", "multisampling", "multitexture", + "multiuser", "namespace", "keyconfig", "playhead", @@ -327,6 +329,7 @@ dict_uimsgs = { "ztransp", # Blender terms + "audaspace", "bbone", "breakdowner", "bspline", @@ -456,6 +459,7 @@ dict_uimsgs = { "dop", # BLI K-Dop BVH "ik", "nla", + "py", "qbvh", "rna", "rvo", diff --git a/source/blender/blenkernel/intern/packedFile.c b/source/blender/blenkernel/intern/packedFile.c index 03342d0f6d1..f2069229ac2 100644 --- a/source/blender/blenkernel/intern/packedFile.c +++ b/source/blender/blenkernel/intern/packedFile.c @@ -323,7 +323,7 @@ int writePackedFile(ReportList *reports, const char *filename, PackedFile *pf, i if (remove_tmp) { if (ret_value == RET_ERROR) { if (BLI_rename(tempname, name) != 0) { - BKE_reportf(reports, RPT_ERROR, "Error restoring tempfile. Check files: '%s' '%s'", tempname, name); + BKE_reportf(reports, RPT_ERROR, "Error restoring temp file. Check files: '%s' '%s'", tempname, name); } } else { diff --git a/source/blender/editors/armature/editarmature.c b/source/blender/editors/armature/editarmature.c index ffdced3262f..584bbf7a0aa 100644 --- a/source/blender/editors/armature/editarmature.c +++ b/source/blender/editors/armature/editarmature.c @@ -5152,7 +5152,7 @@ static int pose_clear_transform_generic_exec(bContext *C, wmOperator *op, /* sanity checks */ if (ELEM(NULL, clear_func, default_ksName)) { - BKE_report(op->reports, RPT_ERROR, "Programming error: missing clear transform func or Keying Set Name"); + BKE_report(op->reports, RPT_ERROR, "Programming error: missing clear transform function or Keying Set Name"); return OPERATOR_CANCELLED; } diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 2d46de024dd..69cfe79728e 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -3079,7 +3079,7 @@ static int edbm_separate_exec(bContext *C, wmOperator *op) } else { if (type == 0) { - BKE_report(op->reports, RPT_ERROR, "Selecton not supported in object mode"); + BKE_report(op->reports, RPT_ERROR, "Selection not supported in object mode"); return OPERATOR_CANCELLED; } diff --git a/source/blender/editors/mesh/mesh_data.c b/source/blender/editors/mesh/mesh_data.c index 735492cb553..c0ab7826fcf 100644 --- a/source/blender/editors/mesh/mesh_data.c +++ b/source/blender/editors/mesh/mesh_data.c @@ -1227,7 +1227,7 @@ void ED_mesh_loops_add(Mesh *mesh, ReportList *reports, int count) void ED_mesh_polys_add(Mesh *mesh, ReportList *reports, int count) { if (mesh->edit_btmesh) { - BKE_report(reports, RPT_ERROR, "Can't add polys in edit mode."); + BKE_report(reports, RPT_ERROR, "Can't add polygons in edit mode."); return; } diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c index 6d124377821..a35ba8813e8 100644 --- a/source/blender/editors/object/object_bake.c +++ b/source/blender/editors/object/object_bake.c @@ -985,7 +985,7 @@ static int multiresbake_check(bContext *C, wmOperator *op) ImBuf *ibuf = BKE_image_get_ibuf(ima, NULL); if (!ibuf) { - BKE_report(op->reports, RPT_ERROR, "Baking should happend to image with image buffer"); + BKE_report(op->reports, RPT_ERROR, "Baking should happen to image with image buffer"); ok = 0; } diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c index 56f2426b1b0..80993d6cca7 100644 --- a/source/blender/editors/object/object_constraint.c +++ b/source/blender/editors/object/object_constraint.c @@ -853,7 +853,7 @@ static int childof_clear_inverse_exec(bContext *C, wmOperator *op) bChildOfConstraint *data = (con) ? (bChildOfConstraint *)con->data : NULL; if (data == NULL) { - BKE_report(op->reports, RPT_ERROR, "Childof constraint not found"); + BKE_report(op->reports, RPT_ERROR, "Child Of constraint not found"); return OPERATOR_CANCELLED; } @@ -1073,7 +1073,7 @@ static int objectsolver_clear_inverse_exec(bContext *C, wmOperator *op) bObjectSolverConstraint *data = (con) ? (bObjectSolverConstraint *)con->data : NULL; if (data == NULL) { - BKE_report(op->reports, RPT_ERROR, "Childof constraint not found"); + BKE_report(op->reports, RPT_ERROR, "Child Of constraint not found"); return OPERATOR_CANCELLED; } diff --git a/source/blender/editors/object/object_transform.c b/source/blender/editors/object/object_transform.c index e2a32a743bb..3b508f1d3c6 100644 --- a/source/blender/editors/object/object_transform.c +++ b/source/blender/editors/object/object_transform.c @@ -217,7 +217,7 @@ static int object_clear_transform_generic_exec(bContext *C, wmOperator *op, /* sanity checks */ if (ELEM(NULL, clear_func, default_ksName)) { - BKE_report(op->reports, RPT_ERROR, "Programming error: missing clear transform func or Keying Set Name"); + BKE_report(op->reports, RPT_ERROR, "Programming error: missing clear transform function or Keying Set Name"); return OPERATOR_CANCELLED; } diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c index 85ae923f881..1d0e5bb6d44 100644 --- a/source/blender/editors/render/render_opengl.c +++ b/source/blender/editors/render/render_opengl.c @@ -342,7 +342,7 @@ static int screen_opengl_render_init(bContext *C, wmOperator *op) ofs = GPU_offscreen_create(sizex, sizey, err_out); if (!ofs) { - BKE_reportf(op->reports, RPT_ERROR, "Failed to create OpenGL offscreen buffer, %s", err_out); + BKE_reportf(op->reports, RPT_ERROR, "Failed to create OpenGL off-screen buffer, %s", err_out); return 0; } diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c index 480d4ee6ac1..34ff5efacc9 100644 --- a/source/blender/editors/sculpt_paint/paint_image.c +++ b/source/blender/editors/sculpt_paint/paint_image.c @@ -5890,7 +5890,7 @@ static int texture_paint_image_from_view_exec(bContext *C, wmOperator *op) if (!ibuf) { /* Mostly happens when OpenGL offscreen buffer was failed to create, */ /* but could be other reasons. Should be handled in the future. nazgul */ - BKE_reportf(op->reports, RPT_ERROR, "Failed to create OpenGL offscreen buffer: %s", err_out); + BKE_reportf(op->reports, RPT_ERROR, "Failed to create OpenGL off-screen buffer: %s", err_out); return OPERATOR_CANCELLED; } diff --git a/source/blender/editors/space_info/info_ops.c b/source/blender/editors/space_info/info_ops.c index 805ff1794c9..fe36bc98144 100644 --- a/source/blender/editors/space_info/info_ops.c +++ b/source/blender/editors/space_info/info_ops.c @@ -124,7 +124,7 @@ static const EnumPropertyItem unpack_all_method_items[] = { {PF_WRITE_LOCAL, "WRITE_LOCAL", 0, "Write files to current directory (overwrite existing files)", ""}, {PF_USE_ORIGINAL, "USE_ORIGINAL", 0, "Use files in original location (create when necessary)", ""}, {PF_WRITE_ORIGINAL, "WRITE_ORIGINAL", 0, "Write files to original location (overwrite existing files)", ""}, - {PF_KEEP, "KEEP", 0, "Disable AutoPack, keep all packed files", ""}, + {PF_KEEP, "KEEP", 0, "Disable Auto-pack, keep all packed files", ""}, /* {PF_ASK, "ASK", 0, "Ask for each file", ""}, */ {0, NULL, 0, NULL, NULL}}; @@ -150,7 +150,7 @@ static int unpack_all_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event) count = countPackedFiles(bmain); if (!count) { - BKE_report(op->reports, RPT_WARNING, "No packed files. Autopack disabled"); + BKE_report(op->reports, RPT_WARNING, "No packed files. Auto-pack disabled"); G.fileflags &= ~G_AUTOPACK; return OPERATOR_CANCELLED; } diff --git a/source/blender/editors/space_nla/nla_edit.c b/source/blender/editors/space_nla/nla_edit.c index 950060dde5f..ebc4383d143 100644 --- a/source/blender/editors/space_nla/nla_edit.c +++ b/source/blender/editors/space_nla/nla_edit.c @@ -121,7 +121,7 @@ static int nlaedit_enable_tweakmode_exec(bContext *C, wmOperator *op) /* if no blocks, popup error? */ if (anim_data.first == NULL) { - BKE_report(op->reports, RPT_ERROR, "No AnimData blocks to enter tweakmode for"); + BKE_report(op->reports, RPT_ERROR, "No AnimData blocks to enter tweak mode for"); return OPERATOR_CANCELLED; } @@ -147,7 +147,7 @@ static int nlaedit_enable_tweakmode_exec(bContext *C, wmOperator *op) WM_event_add_notifier(C, NC_ANIMATION | ND_NLA_ACTCHANGE, NULL); } else { - BKE_report(op->reports, RPT_ERROR, "No active strip(s) to enter tweakmode on"); + BKE_report(op->reports, RPT_ERROR, "No active strip(s) to enter tweak mode on"); return OPERATOR_CANCELLED; } @@ -190,7 +190,7 @@ static int nlaedit_disable_tweakmode_exec(bContext *C, wmOperator *op) /* if no blocks, popup error? */ if (anim_data.first == NULL) { - BKE_report(op->reports, RPT_ERROR, "No AnimData blocks to enter tweakmode for"); + BKE_report(op->reports, RPT_ERROR, "No AnimData blocks to enter tweak mode for"); return OPERATOR_CANCELLED; } diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index f70c375eb29..6bdb6930fda 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -1462,7 +1462,7 @@ static int view3d_localview_init(Main *bmain, Scene *scene, ScrArea *sa, ReportL locallay = free_localbit(bmain); if (locallay == 0) { - BKE_reportf(reports, RPT_ERROR, "No more than 8 localviews"); + BKE_reportf(reports, RPT_ERROR, "No more than 8 local views"); ok = FALSE; } else { diff --git a/source/blender/makesrna/intern/rna_main_api.c b/source/blender/makesrna/intern/rna_main_api.c index 8e21ab3f7e9..be8f84fd2a4 100644 --- a/source/blender/makesrna/intern/rna_main_api.c +++ b/source/blender/makesrna/intern/rna_main_api.c @@ -128,7 +128,7 @@ static void rna_Main_scenes_remove(Main *bmain, bContext *C, ReportList *reports else if (scene->id.next) newscene = scene->id.next; else { - BKE_reportf(reports, RPT_ERROR, "Scene \"%s\" is the last, cant ve removed", scene->id.name + 2); + BKE_reportf(reports, RPT_ERROR, "Scene \"%s\" is the last, can't be removed", scene->id.name + 2); return; } diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index d650c8dbf69..dff08990dec 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -756,7 +756,7 @@ static bNode *rna_NodeTree_node_texture_new(bNodeTree *ntree, bContext *C, Repor static void rna_NodeTree_node_remove(bNodeTree *ntree, ReportList *reports, bNode *node) { if (BLI_findindex(&ntree->nodes, node) == -1) { - BKE_reportf(reports, RPT_ERROR, "Unable to locate node '%s' in nodetree", node->name); + BKE_reportf(reports, RPT_ERROR, "Unable to locate node '%s' in node tree", node->name); } else { if (node->id) @@ -827,7 +827,7 @@ static bNodeLink *rna_NodeTree_link_new(bNodeTree *ntree, ReportList *reports, static void rna_NodeTree_link_remove(bNodeTree *ntree, ReportList *reports, bNodeLink *link) { if (BLI_findindex(&ntree->links, link) == -1) { - BKE_reportf(reports, RPT_ERROR, "Unable to locate link in nodetree"); + BKE_reportf(reports, RPT_ERROR, "Unable to locate link in node tree"); } else { nodeRemLink(ntree, link); @@ -882,7 +882,7 @@ static bNodeSocket *rna_NodeTree_input_expose(bNodeTree *ntree, ReportList *repo int index, in_out; if (!nodeFindNode(ntree, sock, &node, &index, &in_out)) - BKE_reportf(reports, RPT_ERROR, "Unable to locate socket in nodetree"); + BKE_reportf(reports, RPT_ERROR, "Unable to locate socket in node tree"); else if (in_out != SOCK_IN) BKE_reportf(reports, RPT_ERROR, "Socket is not an input"); else { @@ -906,7 +906,7 @@ static bNodeSocket *rna_NodeTree_output_expose(bNodeTree *ntree, ReportList *rep int index, in_out; if (!nodeFindNode(ntree, sock, &node, &index, &in_out)) - BKE_reportf(reports, RPT_ERROR, "Unable to locate socket in nodetree"); + BKE_reportf(reports, RPT_ERROR, "Unable to locate socket in node tree"); else if (in_out != SOCK_OUT) BKE_reportf(reports, RPT_ERROR, "Socket is not an output"); else { diff --git a/source/blender/makesrna/intern/rna_smoke.c b/source/blender/makesrna/intern/rna_smoke.c index 417530acc14..faad2407516 100644 --- a/source/blender/makesrna/intern/rna_smoke.c +++ b/source/blender/makesrna/intern/rna_smoke.c @@ -555,7 +555,7 @@ static void rna_def_smoke_flow_settings(BlenderRNA *brna) prop = RNA_def_property(srna, "use_texture", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_SMOKE_FLOW_TEXTUREEMIT); - RNA_def_property_ui_text(prop, "Use Texture", "Use a texture to controll emission strength"); + RNA_def_property_ui_text(prop, "Use Texture", "Use a texture to control emission strength"); RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); prop = RNA_def_property(srna, "texture_map_type", PROP_ENUM, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_ui.c b/source/blender/makesrna/intern/rna_ui.c index 70d94bfc7ed..7bfa7ccc3c2 100644 --- a/source/blender/makesrna/intern/rna_ui.c +++ b/source/blender/makesrna/intern/rna_ui.c @@ -85,7 +85,7 @@ static ARegionType *region_type_find(ReportList *reports, int space_type, int re /* region type not found? abort */ if (art == NULL) { - BKE_report(reports, RPT_ERROR, "Region not found in spacetype"); + BKE_report(reports, RPT_ERROR, "Region not found in space type"); return NULL; } diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index 84d57aa7d09..869a9d59444 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -1900,7 +1900,7 @@ int RE_is_rendering_allowed(Scene *scene, Object *camera_override, ReportList *r if (scene->r.scemode & R_DOCOMP) { if (scene->use_nodes) { if (!scene->nodetree) { - BKE_report(reports, RPT_ERROR, "No Nodetree in Scene"); + BKE_report(reports, RPT_ERROR, "No node tree in Scene"); return 0; } From 3d6ab52f2b2918282b55c2d8b6e0de78941a2f1e Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Sat, 13 Oct 2012 13:55:14 +0000 Subject: [PATCH 208/347] Add translation of reports messages (only direct uses of BKE_report(f)/BKE_reports_append(f) funcs for now). Already adds quite a bunch of new msgids! --- .../scripts/modules/bl_i18n_utils/settings.py | 4 +++- source/blender/blenkernel/intern/report.c | 20 ++++++++++++------- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/release/scripts/modules/bl_i18n_utils/settings.py b/release/scripts/modules/bl_i18n_utils/settings.py index d323dd37979..6dd53b1fbc5 100644 --- a/release/scripts/modules/bl_i18n_utils/settings.py +++ b/release/scripts/modules/bl_i18n_utils/settings.py @@ -98,7 +98,9 @@ PYGETTEXT_KEYWORDS = (() + tuple((r"{}\(\s*" + _msg_re + r"\s*\)").format(it) for it in ("IFACE_", "TIP_", "N_")) + tuple((r"{}\(\s*" + _ctxt_re + r"\s*,\s*" + _msg_re + r"\s*\)").format(it) - for it in ("CTX_IFACE_", "CTX_TIP_", "CTX_N_")) + for it in ("CTX_IFACE_", "CTX_TIP_", "CTX_N_")) + + tuple(("{}\\([^\"',]+,(?:[^\"',]+,)?\\s*" + _msg_re + r"\s*(?:\)|,)").format(it) + for it in ("BKE_report", "BKE_reportf", "BKE_reports_prepend", "BKE_reports_prependf")) ) ESCAPE_RE = ( diff --git a/source/blender/blenkernel/intern/report.c b/source/blender/blenkernel/intern/report.c index 3a66ec23412..59806bdeaf5 100644 --- a/source/blender/blenkernel/intern/report.c +++ b/source/blender/blenkernel/intern/report.c @@ -34,6 +34,8 @@ #include "BLI_dynstr.h" #include "BLI_utildefines.h" +#include "BLF_translation.h" + #include "BKE_report.h" #include "BKE_global.h" /* G.background only */ @@ -87,10 +89,11 @@ void BKE_reports_clear(ReportList *reports) reports->list.first = reports->list.last = NULL; } -void BKE_report(ReportList *reports, ReportType type, const char *message) +void BKE_report(ReportList *reports, ReportType type, const char *_message) { Report *report; int len; + const char *message = TIP_(_message); /* in background mode always print otherwise there are cases the errors wont be displayed, * but still add to the report list since this is used for python exception handling */ @@ -114,14 +117,15 @@ void BKE_report(ReportList *reports, ReportType type, const char *message) } } -void BKE_reportf(ReportList *reports, ReportType type, const char *format, ...) +void BKE_reportf(ReportList *reports, ReportType type, const char *_format, ...) { DynStr *ds; Report *report; va_list args; + const char *format = TIP_(_format); if (G.background || !reports || ((reports->flag & RPT_PRINT) && (type >= reports->printlevel))) { - va_start(args, format); + va_start(args, _format); vprintf(format, args); va_end(args); fprintf(stdout, "\n"); /* otherise each report needs to include a \n */ @@ -132,7 +136,7 @@ void BKE_reportf(ReportList *reports, ReportType type, const char *format, ...) report = MEM_callocN(sizeof(Report), "Report"); ds = BLI_dynstr_new(); - va_start(args, format); + va_start(args, _format); BLI_dynstr_vappendf(ds, format, args); va_end(args); @@ -147,10 +151,11 @@ void BKE_reportf(ReportList *reports, ReportType type, const char *format, ...) } } -void BKE_reports_prepend(ReportList *reports, const char *prepend) +void BKE_reports_prepend(ReportList *reports, const char *_prepend) { Report *report; DynStr *ds; + const char *prepend = TIP_(_prepend); if (!reports) return; @@ -169,18 +174,19 @@ void BKE_reports_prepend(ReportList *reports, const char *prepend) } } -void BKE_reports_prependf(ReportList *reports, const char *prepend, ...) +void BKE_reports_prependf(ReportList *reports, const char *_prepend, ...) { Report *report; DynStr *ds; va_list args; + const char *prepend = TIP_(_prepend); if (!reports) return; for (report = reports->list.first; report; report = report->next) { ds = BLI_dynstr_new(); - va_start(args, prepend); + va_start(args, _prepend); BLI_dynstr_vappendf(ds, prepend, args); va_end(args); From b50fc8ac689cc6e39aa34b427234efab6e1965ae Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Sat, 13 Oct 2012 15:44:50 +0000 Subject: [PATCH 209/347] More UI messages fixes. Also forgot to translate reports' titles, and change some usages of BKE_reportf to simple BKE_report, when the former is not needed! --- source/blender/blenkernel/intern/anim.c | 6 +++-- source/blender/blenkernel/intern/packedFile.c | 3 ++- source/blender/blenkernel/intern/report.c | 27 ++++++++++++------- source/blender/blenloader/intern/readfile.c | 2 +- source/blender/blenloader/intern/writefile.c | 12 ++++----- .../blender/editors/interface/interface_ops.c | 2 +- .../makesrna/intern/rna_animation_api.c | 2 +- source/blender/makesrna/intern/rna_nodetree.c | 16 +++++------ .../blender/makesrna/intern/rna_object_api.c | 2 +- source/blender/makesrna/intern/rna_wm.c | 6 ++--- .../quicktime/apple/quicktime_export.c | 16 +++++------ .../windowmanager/intern/wm_init_exit.c | 2 +- .../windowmanager/intern/wm_operators.c | 7 ++--- 13 files changed, 58 insertions(+), 45 deletions(-) diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index f44cb6d6b19..622658e0a49 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -40,6 +40,8 @@ #include "BLI_rand.h" #include "BLI_utildefines.h" +#include "BLF_translation.h" + #include "DNA_anim_types.h" #include "DNA_armature_types.h" #include "DNA_group_types.h" @@ -174,10 +176,10 @@ bMotionPath *animviz_verify_motionpaths(ReportList *reports, Scene *scene, Objec /* avoid 0 size allocs */ if (avs->path_sf >= avs->path_ef) { BKE_reportf(reports, RPT_ERROR, - "Motion Path frame extents invalid for %s (%d to %d).%s\n", + "Motion Path frame extents invalid for %s (%d to %d)%s", (pchan) ? pchan->name : ob->id.name, avs->path_sf, avs->path_ef, - (avs->path_sf == avs->path_ef) ? " Cannot have single-frame paths." : ""); + (avs->path_sf == avs->path_ef) ? TIP_(", cannot have single-frame paths") : ""); return NULL; } diff --git a/source/blender/blenkernel/intern/packedFile.c b/source/blender/blenkernel/intern/packedFile.c index f2069229ac2..f16748bf20a 100644 --- a/source/blender/blenkernel/intern/packedFile.c +++ b/source/blender/blenkernel/intern/packedFile.c @@ -238,7 +238,8 @@ void packAll(Main *bmain, ReportList *reports) ima->packedfile = newPackedFile(reports, ima->name, ID_BLEND_PATH(bmain, &ima->id)); } else if (ELEM(ima->source, IMA_SRC_SEQUENCE, IMA_SRC_MOVIE)) { - BKE_reportf(reports, RPT_WARNING, "Image '%s' skipped, movies and image sequences not supported.", ima->id.name + 2); + BKE_reportf(reports, RPT_WARNING, "Image '%s' skipped, movies and image sequences not supported", + ima->id.name + 2); } } } diff --git a/source/blender/blenkernel/intern/report.c b/source/blender/blenkernel/intern/report.c index 59806bdeaf5..ae6f4f35519 100644 --- a/source/blender/blenkernel/intern/report.c +++ b/source/blender/blenkernel/intern/report.c @@ -46,15 +46,24 @@ static const char *report_type_str(int type) { switch (type) { - case RPT_DEBUG: return "Debug"; - case RPT_INFO: return "Info"; - case RPT_OPERATOR: return "Operator"; - case RPT_WARNING: return "Warning"; - case RPT_ERROR: return "Error"; - case RPT_ERROR_INVALID_INPUT: return "Invalid Input Error"; - case RPT_ERROR_INVALID_CONTEXT: return "Invalid Context Error"; - case RPT_ERROR_OUT_OF_MEMORY: return "Out Of Memory Error"; - default: return "Undefined Type"; + case RPT_DEBUG: + return TIP_("Debug"); + case RPT_INFO: + return TIP_("Info"); + case RPT_OPERATOR: + return TIP_("Operator"); + case RPT_WARNING: + return TIP_("Warning"); + case RPT_ERROR: + return TIP_("Error"); + case RPT_ERROR_INVALID_INPUT: + return TIP_("Invalid Input Error"); + case RPT_ERROR_INVALID_CONTEXT: + return TIP_("Invalid Context Error"); + case RPT_ERROR_OUT_OF_MEMORY: + return TIP_("Out Of Memory Error"); + default: + return TIP_("Undefined Type"); } } diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 9171e78e7ad..1e14eb55dc0 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -6611,7 +6611,7 @@ void convert_tface_mt(FileData *fd, Main *main) G.main = main; if (!(do_version_tface(main, 1))) { - BKE_report(fd->reports, RPT_WARNING, "Texface conversion problem. Error in console"); + BKE_report(fd->reports, RPT_WARNING, "Texface conversion problem (error in console)"); } //XXX hack, material.c uses G.main allover the place, instead of main diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 536376ac577..a825cf4ef98 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -3022,7 +3022,7 @@ int BLO_write_file(Main *mainvar, const char *filepath, int write_flags, ReportL file = BLI_open(tempname, O_BINARY+O_WRONLY+O_CREAT+O_TRUNC, 0666); if (file == -1) { - BKE_reportf(reports, RPT_ERROR, "Can't open file %s for writing: %s.", tempname, strerror(errno)); + BKE_reportf(reports, RPT_ERROR, "Can't open file %s for writing: %s", tempname, strerror(errno)); return 0; } @@ -3073,7 +3073,7 @@ int BLO_write_file(Main *mainvar, const char *filepath, int write_flags, ReportL if (write_flags & G_FILE_HISTORY) { int err_hist = do_history(filepath, reports); if (err_hist) { - BKE_report(reports, RPT_ERROR, "Version backup failed. File saved with @"); + BKE_report(reports, RPT_ERROR, "Version backup failed (file saved with @)"); return 0; } } @@ -3090,23 +3090,23 @@ int BLO_write_file(Main *mainvar, const char *filepath, int write_flags, ReportL if (0==ret) { /* now rename to real file name, and delete temp @ file too */ if (BLI_rename(gzname, filepath) != 0) { - BKE_report(reports, RPT_ERROR, "Can't change old file. File saved with @."); + BKE_report(reports, RPT_ERROR, "Can't change old file (file saved with @)"); return 0; } BLI_delete(tempname, 0, 0); } else if (-1==ret) { - BKE_report(reports, RPT_ERROR, "Failed opening .gz file."); + BKE_report(reports, RPT_ERROR, "Failed opening .gz file"); return 0; } else if (-2==ret) { - BKE_report(reports, RPT_ERROR, "Failed opening .blend file for compression."); + BKE_report(reports, RPT_ERROR, "Failed opening .blend file for compression"); return 0; } } else if (BLI_rename(tempname, filepath) != 0) { - BKE_report(reports, RPT_ERROR, "Can't change old file. File saved with @"); + BKE_report(reports, RPT_ERROR, "Can't change old file (file saved with @)"); return 0; } diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c index ba2feebd2f8..f9a325944e4 100644 --- a/source/blender/editors/interface/interface_ops.c +++ b/source/blender/editors/interface/interface_ops.c @@ -808,7 +808,7 @@ static int editsource_text_edit(bContext *C, wmOperator *op, if (text == NULL) { BKE_reportf(op->reports, RPT_WARNING, - "file: '%s' can't be opened", filepath); + "File: '%s' can't be opened", filepath); return OPERATOR_CANCELLED; } else { diff --git a/source/blender/makesrna/intern/rna_animation_api.c b/source/blender/makesrna/intern/rna_animation_api.c index 39128b48cd8..b93fd9daa36 100644 --- a/source/blender/makesrna/intern/rna_animation_api.c +++ b/source/blender/makesrna/intern/rna_animation_api.c @@ -60,7 +60,7 @@ static void rna_KeyingSet_context_refresh(KeyingSet *ks, bContext *C, ReportList break; case MODIFYKEY_MISSING_TYPEINFO: - BKE_report(reports, RPT_ERROR, "Incomplete built-in Keying Set. Appears to be missing type info"); + BKE_report(reports, RPT_ERROR, "Incomplete built-in Keying Set, appears to be missing type info"); break; } } diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index dff08990dec..ce0f588a4ba 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -689,7 +689,7 @@ static bNode *rna_NodeTree_node_new(bNodeTree *ntree, bContext *C, ReportList *r bNodeTemplate ntemp; if (type == NODE_GROUP && group == NULL) { - BKE_reportf(reports, RPT_ERROR, "node type \'GROUP\' missing group argument"); + BKE_report(reports, RPT_ERROR, "Node type 'GROUP' missing group argument"); return NULL; } @@ -700,7 +700,7 @@ static bNode *rna_NodeTree_node_new(bNodeTree *ntree, bContext *C, ReportList *r node = nodeAddNode(ntree, &ntemp); if (node == NULL) { - BKE_reportf(reports, RPT_ERROR, "Unable to create node"); + BKE_report(reports, RPT_ERROR, "Unable to create node"); } else { ntreeUpdateTree(ntree); /* update group node socket links*/ @@ -800,7 +800,7 @@ static bNodeLink *rna_NodeTree_link_new(bNodeTree *ntree, ReportList *reports, nodeFindNode(ntree, tosock, &tonode, NULL, &to_in_out); if (&from_in_out == &to_in_out) { - BKE_reportf(reports, RPT_ERROR, "Same input/output direction of sockets"); + BKE_report(reports, RPT_ERROR, "Same input/output direction of sockets"); return NULL; } @@ -827,7 +827,7 @@ static bNodeLink *rna_NodeTree_link_new(bNodeTree *ntree, ReportList *reports, static void rna_NodeTree_link_remove(bNodeTree *ntree, ReportList *reports, bNodeLink *link) { if (BLI_findindex(&ntree->links, link) == -1) { - BKE_reportf(reports, RPT_ERROR, "Unable to locate link in node tree"); + BKE_report(reports, RPT_ERROR, "Unable to locate link in node tree"); } else { nodeRemLink(ntree, link); @@ -882,9 +882,9 @@ static bNodeSocket *rna_NodeTree_input_expose(bNodeTree *ntree, ReportList *repo int index, in_out; if (!nodeFindNode(ntree, sock, &node, &index, &in_out)) - BKE_reportf(reports, RPT_ERROR, "Unable to locate socket in node tree"); + BKE_report(reports, RPT_ERROR, "Unable to locate socket in node tree"); else if (in_out != SOCK_IN) - BKE_reportf(reports, RPT_ERROR, "Socket is not an input"); + BKE_report(reports, RPT_ERROR, "Socket is not an input"); else { /* XXX should check if tree is a group here! no good way to do this currently. */ gsock = node_group_add_socket(ntree, sock->name, sock->type, SOCK_IN); @@ -906,9 +906,9 @@ static bNodeSocket *rna_NodeTree_output_expose(bNodeTree *ntree, ReportList *rep int index, in_out; if (!nodeFindNode(ntree, sock, &node, &index, &in_out)) - BKE_reportf(reports, RPT_ERROR, "Unable to locate socket in node tree"); + BKE_report(reports, RPT_ERROR, "Unable to locate socket in node tree"); else if (in_out != SOCK_OUT) - BKE_reportf(reports, RPT_ERROR, "Socket is not an output"); + BKE_report(reports, RPT_ERROR, "Socket is not an output"); else { /* XXX should check if tree is a group here! no good way to do this currently. */ gsock = node_group_add_socket(ntree, sock->name, sock->type, SOCK_OUT); diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c index 879a77527cd..5f5bdb765b1 100644 --- a/source/blender/makesrna/intern/rna_object_api.c +++ b/source/blender/makesrna/intern/rna_object_api.c @@ -158,7 +158,7 @@ Mesh *rna_Object_to_mesh(Object *ob, ReportList *reports, Scene *sce, int apply_ /* BKE_mesh_from_nurbs changes the type to a mesh, check it worked */ if (tmpobj->type != OB_MESH) { BKE_libblock_free_us(&(G.main->object), tmpobj); - BKE_report(reports, RPT_ERROR, "cant convert curve to mesh. Does the curve have any segments?"); + BKE_report(reports, RPT_ERROR, "Can't convert curve to mesh (does the curve have any segments?)"); return NULL; } diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c index d8753f4ff43..30bdc717f50 100644 --- a/source/blender/makesrna/intern/rna_wm.c +++ b/source/blender/makesrna/intern/rna_wm.c @@ -1062,7 +1062,7 @@ static StructRNA *rna_Operator_register(Main *bmain, ReportList *reports, void * } else { BKE_reportf(reports, RPT_ERROR, - "registering operator class: '%s', invalid bl_idname '%s', at position %d", + "Registering operator class: '%s', invalid bl_idname '%s', at position %d", identifier, _operator_idname, i); return NULL; } @@ -1071,7 +1071,7 @@ static StructRNA *rna_Operator_register(Main *bmain, ReportList *reports, void * } if (i > ((int)sizeof(dummyop.idname)) - 3) { - BKE_reportf(reports, RPT_ERROR, "registering operator class: '%s', invalid bl_idname '%s', " + BKE_reportf(reports, RPT_ERROR, "Registering operator class: '%s', invalid bl_idname '%s', " "is too long, maximum length is %d", identifier, _operator_idname, (int)sizeof(dummyop.idname) - 3); return NULL; @@ -1079,7 +1079,7 @@ static StructRNA *rna_Operator_register(Main *bmain, ReportList *reports, void * if (dot != 1) { BKE_reportf(reports, RPT_ERROR, - "registering operator class: '%s', invalid bl_idname '%s', must contain 1 '.' character", + "Registering operator class: '%s', invalid bl_idname '%s', must contain 1 '.' character", identifier, _operator_idname); return NULL; } diff --git a/source/blender/quicktime/apple/quicktime_export.c b/source/blender/quicktime/apple/quicktime_export.c index 659fd997c1f..e376cba9a9f 100644 --- a/source/blender/quicktime/apple/quicktime_export.c +++ b/source/blender/quicktime/apple/quicktime_export.c @@ -218,7 +218,7 @@ static OSErr QT_SaveCodecSettingsToScene(RenderData *rd, ReportList *reports) /* retreive codecdata from quicktime in a atomcontainer */ myErr = SCGetSettingsAsAtomContainer(qtdata->theComponent, &myContainer); if (myErr != noErr) { - BKE_reportf(reports, RPT_ERROR, "Quicktime: SCGetSettingsAsAtomContainer failed\n"); + BKE_report(reports, RPT_ERROR, "Quicktime: SCGetSettingsAsAtomContainer failed"); goto bail; } @@ -238,7 +238,7 @@ static OSErr QT_SaveCodecSettingsToScene(RenderData *rd, ReportList *reports) GetCodecInfo(&ci, qtdata->gSpatialSettings.codecType, 0); } else { - BKE_reportf(reports, RPT_ERROR, "Quicktime: QT_SaveCodecSettingsToScene failed\n"); + BKE_report(reports, RPT_ERROR, "Quicktime: QT_SaveCodecSettingsToScene failed"); } QTUnlockContainer(myContainer); @@ -268,7 +268,7 @@ static OSErr QT_GetCodecSettingsFromScene(RenderData *rd, ReportList *reports) if (qcd->cdParms && qcd->cdSize) { myErr = SCSetSettingsFromAtomContainer((GraphicsExportComponent)qtdata->theComponent, (QTAtomContainer)myHandle); if (myErr != noErr) { - BKE_reportf(reports, RPT_ERROR, "Quicktime: SCSetSettingsFromAtomContainer failed\n"); + BKE_report(reports, RPT_ERROR, "Quicktime: SCSetSettingsFromAtomContainer failed"); goto bail; } @@ -295,7 +295,7 @@ static OSErr QT_GetCodecSettingsFromScene(RenderData *rd, ReportList *reports) } else { - BKE_reportf(reports, RPT_ERROR, "Quicktime: QT_GetCodecSettingsFromScene failed\n"); + BKE_report(reports, RPT_ERROR, "Quicktime: QT_GetCodecSettingsFromScene failed"); } bail: if (myHandle != NULL) @@ -414,7 +414,7 @@ static void QT_StartAddVideoSamplesToMedia(const Rect *trackFrame, int rectx, in gTemporalSettings = qtdata->gTemporalSettings; if (qtdata->gSpatialSettings.codecType == kH264CodecType) { if (gTemporalSettings.temporalQuality != codecMinQuality) { - BKE_reportf(reports, RPT_WARNING, "Only minimum quality compression supported for QuickTime H.264.\n"); + BKE_report(reports, RPT_WARNING, "Only minimum quality compression supported for QuickTime H.264"); gTemporalSettings.temporalQuality = codecMinQuality; } } @@ -564,7 +564,7 @@ int start_qt(struct Scene *scene, struct RenderData *rd, int rectx, int recty, R /* hack: create an empty file to make FSPathMakeRef() happy */ myFile = open(theFullPath, O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRUSR | S_IWUSR); if (myFile < 0) { - BKE_reportf(reports, RPT_ERROR, "error while creating movie file!\n"); + BKE_report(reports, RPT_ERROR, "error while creating movie file!"); /* do something? */ } close(myFile); @@ -599,7 +599,7 @@ int start_qt(struct Scene *scene, struct RenderData *rd, int rectx, int recty, R #endif } else { - //printf("Created QuickTime movie: %s\n", name); + /* printf("Created QuickTime movie: %s\n", name); */ QT_CreateMyVideoTrack(rectx, recty, reports); } @@ -636,7 +636,7 @@ void end_qt(void) DisposeMovie(qtexport->theMovie); - //printf("Finished QuickTime movie.\n"); + /* printf("Finished QuickTime movie.\n"); */ } #ifdef __APPLE__ diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c index 9bb3b2a0e69..658a13a8918 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.c @@ -302,7 +302,7 @@ int WM_init_game(bContext *C) else { ReportTimerInfo *rti; - BKE_report(&wm->reports, RPT_ERROR, "No valid 3D View found. Game auto start is not possible."); + BKE_report(&wm->reports, RPT_ERROR, "No valid 3D View found, game auto start is not possible"); /* After adding the report to the global list, reset the report timer. */ WM_event_remove_timer(wm, NULL, wm->reports.reporttimer); diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 19c2a58fdfc..8496cd8041a 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -1162,7 +1162,7 @@ int WM_operator_props_popup(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) if ((op->type->flag & OPTYPE_REGISTER) == 0) { BKE_reportf(op->reports, RPT_ERROR, - "Operator '%s' does not have register enabled, incorrect invoke function.", op->type->idname); + "Operator '%s' does not have register enabled, incorrect invoke function", op->type->idname); return OPERATOR_CANCELLED; } @@ -1193,11 +1193,12 @@ int WM_operator_redo_popup(bContext *C, wmOperator *op) { /* CTX_wm_reports(C) because operator is on stack, not active in event system */ if ((op->type->flag & OPTYPE_REGISTER) == 0) { - BKE_reportf(CTX_wm_reports(C), RPT_ERROR, "Operator redo '%s' does not have register enabled, incorrect invoke function.", op->type->idname); + BKE_reportf(CTX_wm_reports(C), RPT_ERROR, + "Operator redo '%s' does not have register enabled, incorrect invoke function", op->type->idname); return OPERATOR_CANCELLED; } if (op->type->poll && op->type->poll(C) == 0) { - BKE_reportf(CTX_wm_reports(C), RPT_ERROR, "Operator redo '%s': wrong context.", op->type->idname); + BKE_reportf(CTX_wm_reports(C), RPT_ERROR, "Operator redo '%s': wrong context", op->type->idname); return OPERATOR_CANCELLED; } From 34f674c60ebb69f3ae9bc3a15f15709c5c15978a Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Sat, 13 Oct 2012 16:42:12 +0000 Subject: [PATCH 210/347] Make zoom direction consistent all over the editors Was discussed in De Balie with lots of artists and we agreed it makes more sense to behave this way --- source/blender/editors/interface/view2d_ops.c | 28 +++++++++---------- source/blender/editors/space_clip/clip_ops.c | 18 +++++++++--- .../blender/editors/space_image/image_ops.c | 18 +++++++++--- .../editors/space_view3d/view3d_edit.c | 16 +++++------ 4 files changed, 50 insertions(+), 30 deletions(-) diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c index 8be2667a015..12e04d392b4 100644 --- a/source/blender/editors/interface/view2d_ops.c +++ b/source/blender/editors/interface/view2d_ops.c @@ -827,6 +827,11 @@ static void view_zoomdrag_apply(bContext *C, wmOperator *op) dx = RNA_float_get(op->ptr, "deltax"); dy = RNA_float_get(op->ptr, "deltay"); + if (U.uiflag & USER_ZOOM_INVERT) { + dx *= -1; + dy *= -1; + } + /* continuous zoom shouldn't move that fast... */ if (U.viewzoom == USER_ZOOM_CONT) { // XXX store this setting as RNA prop? double time = PIL_check_seconds_timer(); @@ -849,12 +854,12 @@ static void view_zoomdrag_apply(bContext *C, wmOperator *op) float mval_faci = 1.0f - mval_fac; float ofs = (mval_fac * dx) - (mval_faci * dx); - v2d->cur.xmin -= ofs + dx; - v2d->cur.xmax -= ofs - dx; + v2d->cur.xmin += ofs + dx; + v2d->cur.xmax += ofs - dx; } else { - v2d->cur.xmin -= dx; - v2d->cur.xmax += dx; + v2d->cur.xmin += dx; + v2d->cur.xmax -= dx; } } } @@ -868,12 +873,12 @@ static void view_zoomdrag_apply(bContext *C, wmOperator *op) float mval_faci = 1.0f - mval_fac; float ofs = (mval_fac * dy) - (mval_faci * dy); - v2d->cur.ymin -= ofs + dy; - v2d->cur.ymax -= ofs - dy; + v2d->cur.ymin += ofs + dy; + v2d->cur.ymax += ofs - dy; } else { - v2d->cur.ymin -= dy; - v2d->cur.ymax += dy; + v2d->cur.ymin += dy; + v2d->cur.ymax -= dy; } } } @@ -941,7 +946,7 @@ static int view_zoomdrag_invoke(bContext *C, wmOperator *op, wmEvent *event) /* As we have only 1D information (magnify value), feed both axes * with magnify information that is stored in x axis */ - fac = 0.01f * (event->prevx - event->x); + fac = 0.01f * (event->x - event->prevx); dx = fac * BLI_rctf_size_x(&v2d->cur) / 10.0f; dy = fac * BLI_rctf_size_y(&v2d->cur) / 10.0f; @@ -1044,11 +1049,6 @@ static int view_zoomdrag_modal(bContext *C, wmOperator *op, wmEvent *event) } /* set transform amount, and add current deltas to stored total delta (for redo) */ - if (U.uiflag & USER_ZOOM_INVERT) { - dx *= -1; - dy *= -1; - } - RNA_float_set(op->ptr, "deltax", dx); RNA_float_set(op->ptr, "deltay", dy); diff --git a/source/blender/editors/space_clip/clip_ops.c b/source/blender/editors/space_clip/clip_ops.c index be5fa08f931..c67ee5c8a81 100644 --- a/source/blender/editors/space_clip/clip_ops.c +++ b/source/blender/editors/space_clip/clip_ops.c @@ -514,9 +514,14 @@ static int view_zoom_exec(bContext *C, wmOperator *op) static int view_zoom_invoke(bContext *C, wmOperator *op, wmEvent *event) { if (event->type == MOUSEZOOM) { - float factor; + float delta, factor; - factor = 1.0f + (event->x - event->prevx + event->y - event->prevy) / 300.0f; + delta = event->x - event->prevx + event->y - event->prevy; + + if (U.uiflag & USER_ZOOM_INVERT) + delta *= -1; + + factor = 1.0f + delta / 300.0f; RNA_float_set(op->ptr, "factor", factor); sclip_zoom_set_factor_exec(C, event, factor); @@ -533,11 +538,16 @@ static int view_zoom_invoke(bContext *C, wmOperator *op, wmEvent *event) static int view_zoom_modal(bContext *C, wmOperator *op, wmEvent *event) { ViewZoomData *vpd = op->customdata; - float factor; + float delta, factor; switch (event->type) { case MOUSEMOVE: - factor = 1.0f + (vpd->x - event->x + vpd->y - event->y) / 300.0f; + delta = event->x - vpd->x + event->y - vpd->y; + + if (U.uiflag & USER_ZOOM_INVERT) + delta *= -1; + + factor = 1.0f + delta / 300.0f; RNA_float_set(op->ptr, "factor", factor); sclip_zoom_set(C, vpd->zoom * factor, vpd->location); ED_region_tag_redraw(CTX_wm_region(C)); diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index 405fb5a9243..a66e6d6a6b8 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -430,11 +430,16 @@ static int image_view_zoom_invoke(bContext *C, wmOperator *op, wmEvent *event) if (event->type == MOUSEZOOM) { SpaceImage *sima = CTX_wm_space_image(C); ARegion *ar = CTX_wm_region(C); - float factor, location[2]; + float delta, factor, location[2]; UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &location[0], &location[1]); - factor = 1.0f + (event->x - event->prevx + event->y - event->prevy) / 300.0f; + delta = event->x - event->prevx + event->y - event->prevy; + + if (U.uiflag & USER_ZOOM_INVERT) + delta *= -1; + + factor = 1.0f + delta / 300.0f; RNA_float_set(op->ptr, "factor", factor); sima_zoom_set(sima, ar, sima->zoom * factor, location); ED_region_tag_redraw(CTX_wm_region(C)); @@ -452,11 +457,16 @@ static int image_view_zoom_modal(bContext *C, wmOperator *op, wmEvent *event) SpaceImage *sima = CTX_wm_space_image(C); ARegion *ar = CTX_wm_region(C); ViewZoomData *vpd = op->customdata; - float factor; + float delta, factor; switch (event->type) { case MOUSEMOVE: - factor = 1.0f + (vpd->x - event->x + vpd->y - event->y) / 300.0f; + delta = event->x - vpd->x + event->y - vpd->y; + + if (U.uiflag & USER_ZOOM_INVERT) + delta *= -1; + + factor = 1.0f + delta / 300.0f; RNA_float_set(op->ptr, "factor", factor); sima_zoom_set(sima, ar, vpd->zoom * factor, vpd->location); ED_region_tag_redraw(CTX_wm_region(C)); diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 39f644489d2..2ada1199cb3 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -1636,7 +1636,7 @@ static void viewzoom_apply(ViewOpsData *vod, int x, int y, const short viewzoom, if (use_cam_zoom) { float delta; delta = (x - vod->origx + y - vod->origy) / 10.0f; - vod->rv3d->camzoom = vod->camzoom0 + (zoom_invert ? delta : -delta); + vod->rv3d->camzoom = vod->camzoom0 + (zoom_invert ? -delta : delta); CLAMP(vod->rv3d->camzoom, RV3D_CAMZOOM_MIN, RV3D_CAMZOOM_MAX); } @@ -1691,11 +1691,11 @@ static void viewzoom_apply(ViewOpsData *vod, int x, int y, const short viewzoom, if (use_cam_zoom) { /* zfac is ignored in this case, see below */ #if 0 - zfac = vod->camzoom0 * (2.0f * ((len2 / len1) - 1.0f) + 1.0f) / vod->rv3d->camzoom; + zfac = vod->camzoom0 * (2.0f * ((len1 / len2) - 1.0f) + 1.0f) / vod->rv3d->camzoom; #endif } else { - zfac = vod->dist0 * (2.0f * ((len2 / len1) - 1.0f) + 1.0f) / vod->rv3d->dist; + zfac = vod->dist0 * (2.0f * ((len1 / len2) - 1.0f) + 1.0f) / vod->rv3d->dist; } } @@ -1888,12 +1888,12 @@ static int viewzoom_invoke(bContext *C, wmOperator *op, wmEvent *event) if (U.uiflag & USER_ZOOM_HORIZ) { vod->origx = vod->oldx = event->x; - viewzoom_apply(vod, event->prevx, event->prevy, USER_ZOOM_DOLLY, FALSE); + viewzoom_apply(vod, event->prevx, event->prevy, USER_ZOOM_DOLLY, (U.uiflag & USER_ZOOM_INVERT) == 0); } else { /* Set y move = x move as MOUSEZOOM uses only x axis to pass magnification value */ vod->origy = vod->oldy = vod->origy + event->x - event->prevx; - viewzoom_apply(vod, event->prevx, event->prevy, USER_ZOOM_DOLLY, FALSE); + viewzoom_apply(vod, event->prevx, event->prevy, USER_ZOOM_DOLLY, (U.uiflag & USER_ZOOM_INVERT) == 0); } ED_view3d_depth_tag_update(vod->rv3d); @@ -1971,7 +1971,7 @@ static void viewdolly_apply(ViewOpsData *vod, int x, int y, const short zoom_inv if (zoom_invert) SWAP(float, len1, len2); - zfac = 1.0f + ((len2 - len1) * 0.01f * vod->rv3d->dist); + zfac = 1.0f + ((len1 - len2) * 0.01f * vod->rv3d->dist); } if (zfac != 1.0f) @@ -2107,13 +2107,13 @@ static int viewdolly_invoke(bContext *C, wmOperator *op, wmEvent *event) if (U.uiflag & USER_ZOOM_HORIZ) { vod->origx = vod->oldx = event->x; - viewdolly_apply(vod, event->prevx, event->prevy, FALSE); + viewdolly_apply(vod, event->prevx, event->prevy, (U.uiflag & USER_ZOOM_INVERT) == 0); } else { /* Set y move = x move as MOUSEZOOM uses only x axis to pass magnification value */ vod->origy = vod->oldy = vod->origy + event->x - event->prevx; - viewdolly_apply(vod, event->prevx, event->prevy, FALSE); + viewdolly_apply(vod, event->prevx, event->prevy, (U.uiflag & USER_ZOOM_INVERT) == 0); } ED_view3d_depth_tag_update(vod->rv3d); From e4cffb88363f59b7291ffc5453b9a1da5b1fed62 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Sat, 13 Oct 2012 21:32:58 +0000 Subject: [PATCH 211/347] Minor: precision in template_list doc, that only one list is allowed per template... Note: I should really try to remove this stupid limitation! --- source/blender/makesrna/intern/rna_ui_api.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/blender/makesrna/intern/rna_ui_api.c b/source/blender/makesrna/intern/rna_ui_api.c index 006e1ad3903..2e1c62cce53 100644 --- a/source/blender/makesrna/intern/rna_ui_api.c +++ b/source/blender/makesrna/intern/rna_ui_api.c @@ -439,7 +439,8 @@ void RNA_api_ui_layout(StructRNA *srna) RNA_def_boolean(func, "compact", 0, "", "Use more compact layout"); func = RNA_def_function(srna, "template_list", "uiTemplateList"); - RNA_def_function_ui_description(func, "Item. A list widget to display data. e.g. vertexgroups"); + RNA_def_function_ui_description(func, "Item. A list widget to display data, e.g. vertexgroups " + "(WARNING: only one per panel allowed!)."); RNA_def_function_flag(func, FUNC_USE_CONTEXT); parm = RNA_def_pointer(func, "data", "AnyType", "", "Data from which to take property"); RNA_def_property_flag(parm, PROP_REQUIRED | PROP_RNAPTR); From 3867633728d9229710eaa1409ab8c642a3126967 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 14 Oct 2012 03:56:47 +0000 Subject: [PATCH 212/347] use safer string copy functions and change the define for FILE_MAX_LIBEXTRA to use MAX_ID_NAME (now greater then 32). --- source/blender/editors/space_file/filelist.c | 17 +++++++++-------- .../editors/space_sequencer/sequencer_edit.c | 2 +- source/blender/makesdna/DNA_space_types.h | 2 +- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c index ce522ec7e3f..5da198cd972 100644 --- a/source/blender/editors/space_file/filelist.c +++ b/source/blender/editors/space_file/filelist.c @@ -1225,11 +1225,12 @@ void filelist_from_main(struct FileList *filelist) if (ok) { if (!filelist->hide_dot || id->name[2] != '.') { memset(files, 0, sizeof(struct direntry)); - if (id->lib == NULL) + if (id->lib == NULL) { files->relname = BLI_strdup(id->name + 2); + } else { - files->relname = MEM_mallocN(FILE_MAX + 32, "filename for lib"); - sprintf(files->relname, "%s | %s", id->lib->name, id->name + 2); + files->relname = MEM_mallocN(FILE_MAX + (MAX_ID_NAME - 2), "filename for lib"); + BLI_snprintf(files->relname, FILE_MAX + (MAX_ID_NAME - 2) + 3, "%s | %s", id->lib->name, id->name + 2); } files->type |= S_IFREG; #if 0 // XXXXX TODO show the selection status of the objects @@ -1239,7 +1240,7 @@ void filelist_from_main(struct FileList *filelist) } else if (idcode == ID_SCE) { if ( ((Scene *)id)->r.scemode & R_BG_RENDER) files->selflag |= SELECTED_FILE; - } + } } #endif files->nr = totbl + 1; @@ -1248,10 +1249,10 @@ void filelist_from_main(struct FileList *filelist) if (idcode == ID_MA || idcode == ID_TE || idcode == ID_LA || idcode == ID_WO || idcode == ID_IM) { files->flags |= IMAGEFILE; } - if (id->lib && fake) BLI_snprintf(files->extra, sizeof(files->extra), "LF %d", id->us); - else if (id->lib) BLI_snprintf(files->extra, sizeof(files->extra), "L %d", id->us); - else if (fake) BLI_snprintf(files->extra, sizeof(files->extra), "F %d", id->us); - else BLI_snprintf(files->extra, sizeof(files->extra), " %d", id->us); + if (id->lib && fake) BLI_snprintf(files->extra, sizeof(files->extra), "LF %d", id->us); + else if (id->lib) BLI_snprintf(files->extra, sizeof(files->extra), "L %d", id->us); + else if (fake) BLI_snprintf(files->extra, sizeof(files->extra), "F %d", id->us); + else BLI_snprintf(files->extra, sizeof(files->extra), " %d", id->us); if (id->lib) { if (totlib == 0) firstlib = files; diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index c22ab90906a..0bce990788a 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -1574,7 +1574,7 @@ static int apply_unique_name_cb(Sequence *seq, void *arg_pt) Scene *scene = (Scene *)arg_pt; char name[sizeof(seq->name) - 2]; - strcpy(name, seq->name + 2); + BLI_strncpy_utf8(name, seq->name + 2, sizeof(name)); BKE_sequence_base_unique_name_recursive(&scene->ed->seqbase, seq); BKE_sequencer_dupe_animdata(scene, name, seq->name + 2); return 1; diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 4b8fc9c7ed6..2469656ecd7 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -618,7 +618,7 @@ enum FileSortTypeE { #define FILE_MAXFILE 256 #define FILE_MAX 1024 -#define FILE_MAX_LIBEXTRA (FILE_MAX + 32) +#define FILE_MAX_LIBEXTRA (FILE_MAX + MAX_ID_NAME) /* filesel types */ #define FILE_UNIX 8 From 68d68e13b65a38d37768114e2b43964f26f96983 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 14 Oct 2012 04:11:34 +0000 Subject: [PATCH 213/347] fix for error compiling on some platforms: use ll suffix for 64bit ints in BLI_endian_switch_int64() --- source/blender/blenlib/BLI_endian_switch_inline.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/source/blender/blenlib/BLI_endian_switch_inline.h b/source/blender/blenlib/BLI_endian_switch_inline.h index 6aa0405861e..4bc6d3828b9 100644 --- a/source/blender/blenlib/BLI_endian_switch_inline.h +++ b/source/blender/blenlib/BLI_endian_switch_inline.h @@ -74,12 +74,12 @@ BLI_INLINE void BLI_endian_switch_int64(int64_t *val) { int64_t tval = *val; *val = ((tval >> 56)) | - ((tval << 40) & 0x00ff000000000000l) | - ((tval << 24) & 0x0000ff0000000000l) | - ((tval << 8) & 0x000000ff00000000l) | - ((tval >> 8) & 0x00000000ff000000l) | - ((tval >> 24) & 0x0000000000ff0000l) | - ((tval >> 40) & 0x000000000000ff00l) | + ((tval << 40) & 0x00ff000000000000ll) | + ((tval << 24) & 0x0000ff0000000000ll) | + ((tval << 8) & 0x000000ff00000000ll) | + ((tval >> 8) & 0x00000000ff000000ll) | + ((tval >> 24) & 0x0000000000ff0000ll) | + ((tval >> 40) & 0x000000000000ff00ll) | ((tval << 56)); } BLI_INLINE void BLI_endian_switch_uint64(uint64_t *val) From 64b187a92838004d967f716f8ede7526d9e6608f Mon Sep 17 00:00:00 2001 From: Mitchell Stokes Date: Sun, 14 Oct 2012 04:22:38 +0000 Subject: [PATCH 214/347] Blenderplayer: Fixing a crash on startup when the graphics driver tried to use uninitialized memory. I had fixed this previously in Swiss, but it looks like I missed grabbing the fix when bringing the GetViewPort() changes into trunk. --- source/gameengine/GamePlayer/common/GPC_Canvas.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/gameengine/GamePlayer/common/GPC_Canvas.h b/source/gameengine/GamePlayer/common/GPC_Canvas.h index a995dcfaa86..ec5375c0e13 100644 --- a/source/gameengine/GamePlayer/common/GPC_Canvas.h +++ b/source/gameengine/GamePlayer/common/GPC_Canvas.h @@ -90,7 +90,7 @@ protected: * relative to the context */ RAS_Rect m_displayarea; - int *m_viewport; + int m_viewport[4]; /** Storage for the banners to display. */ TBannerMap m_banners; From 643f331cb5557086289d70adad28157ac9cea237 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 14 Oct 2012 04:42:11 +0000 Subject: [PATCH 215/347] Rip-fill mesh tool (option for rip operator) Alt+V will fill the area inbetween the ripped faces - a bit like extrude. faces are flipped to match existing geometry and customdata (uv, vcols etc) is copied from surrounding geometry too. --- release/scripts/startup/bl_ui/space_view3d.py | 1 + source/blender/bmesh/intern/bmesh_queries.c | 38 +++ source/blender/bmesh/intern/bmesh_queries.h | 1 + source/blender/editors/mesh/editmesh_rip.c | 228 ++++++++++++++++-- source/blender/editors/mesh/mesh_ops.c | 14 +- 5 files changed, 259 insertions(+), 23 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 1d09f0e045d..e7ad1c5ff37 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -1778,6 +1778,7 @@ class VIEW3D_MT_edit_mesh_vertices(Menu): layout.operator("mesh.merge") layout.operator("mesh.rip_move") + layout.operator("mesh.rip_move_fill") layout.operator("mesh.split") layout.operator_menu_enum("mesh.separate", "type") layout.operator("mesh.vert_connect") diff --git a/source/blender/bmesh/intern/bmesh_queries.c b/source/blender/bmesh/intern/bmesh_queries.c index 4f09a17b6ce..6bf4e3db1d3 100644 --- a/source/blender/bmesh/intern/bmesh_queries.c +++ b/source/blender/bmesh/intern/bmesh_queries.c @@ -323,6 +323,44 @@ BMVert *BM_edge_other_vert(BMEdge *e, BMVert *v) return bmesh_edge_other_vert_get(e, v); } +/** + * Given a edge and a loop (assumes the edge is manifold). returns + * the other faces loop, sharing the same vertex. + * + *

+ * +-------------------+
+ * |                   |
+ * |                   |
+ * |l_other <-- return |
+ * +-------------------+ <-- A manifold edge between 2 faces
+ * |l    e  <-- edge   |
+ * |^ <-------- loop   |
+ * |                   |
+ * +-------------------+
+ * 
+ */ +BMLoop *BM_edge_other_loop(BMEdge *e, BMLoop *l) +{ + BMLoop *l_other; + + BLI_assert(BM_edge_is_manifold(e)); + BLI_assert(BM_vert_in_edge(e, l->v)); + + l_other = (e->l == l) ? l->radial_next : l; + + if (l_other->v == l->v) { + /* pass */ + } + else if (l_other->next->v == l->v) { + l_other = l_other->next; + } + else { + BLI_assert(0); + } + + return l_other; +} + /** * The function takes a vertex at the center of a fan and returns the opposite edge in the fan. * All edges in the fan must be manifold, otherwise return NULL. diff --git a/source/blender/bmesh/intern/bmesh_queries.h b/source/blender/bmesh/intern/bmesh_queries.h index 6cffc1138b0..84a5ffacec7 100644 --- a/source/blender/bmesh/intern/bmesh_queries.h +++ b/source/blender/bmesh/intern/bmesh_queries.h @@ -40,6 +40,7 @@ float BM_edge_calc_length(BMEdge *e); int BM_edge_face_pair(BMEdge *e, BMFace **r_fa, BMFace **r_fb); int BM_edge_loop_pair(BMEdge *e, BMLoop **r_la, BMLoop **r_lb); BMVert *BM_edge_other_vert(BMEdge *e, BMVert *v); +BMLoop *BM_edge_other_loop(BMEdge *e, BMLoop *l); BMLoop *BM_face_other_edge_loop(BMFace *f, BMEdge *e, BMVert *v); BMLoop *BM_face_other_vert_loop(BMFace *f, BMVert *v_prev, BMVert *v); BMLoop *BM_loop_other_vert_loop(BMLoop *l, BMVert *v); diff --git a/source/blender/editors/mesh/editmesh_rip.c b/source/blender/editors/mesh/editmesh_rip.c index 8321272c80b..b8b8cd2aa4e 100644 --- a/source/blender/editors/mesh/editmesh_rip.c +++ b/source/blender/editors/mesh/editmesh_rip.c @@ -63,9 +63,9 @@ * point and would result in teh same distance. */ #define INSET_DEFAULT 0.00001f -static float edbm_rip_rip_edgedist(ARegion *ar, float mat[][4], - const float co1[3], const float co2[3], const float mvalf[2], - const float inset) +static float edbm_rip_edgedist(ARegion *ar, float mat[][4], + const float co1[3], const float co2[3], const float mvalf[2], + const float inset) { float vec1[2], vec2[2]; @@ -83,8 +83,8 @@ static float edbm_rip_rip_edgedist(ARegion *ar, float mat[][4], } #if 0 -static float edbm_rip_rip_linedist(ARegion *ar, float mat[][4], - const float co1[3], const float co2[3], const float mvalf[2]) +static float edbm_rip_linedist(ARegion *ar, float mat[][4], + const float co1[3], const float co2[3], const float mvalf[2]) { float vec1[2], vec2[2]; @@ -382,6 +382,140 @@ static void edbm_ripsel_deselect_helper(BMesh *bm, EdgeLoopPair *eloop_pairs, } /* --- end 'ripsel' selection handling code --- */ + +/* --- face-fill code --- */ +/** + * return an un-ordered array of loop pairs + * use for rebuilding face-fill + */ + +typedef struct UnorderedLoopPair { + BMLoop *l_pair[2]; + char flag; +} UnorderedLoopPair; +enum { + ULP_FLIP_0 = (1 << 0), + ULP_FLIP_1 = (1 << 1) +}; + +static UnorderedLoopPair *edbm_tagged_loop_pairs_to_fill(BMesh *bm) +{ + BMIter iter; + BMEdge *e; + + unsigned int total_tag = 0; + /* count tags, could be pre-calculated */ + BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { + if (BM_elem_flag_test(e, BM_ELEM_TAG)) { + total_tag++; + } + } + + if (total_tag) { + UnorderedLoopPair *uloop_pairs = MEM_mallocN(total_tag * sizeof(UnorderedLoopPair), __func__); + UnorderedLoopPair *ulp = uloop_pairs; + + BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { + if (BM_elem_flag_test(e, BM_ELEM_TAG)) { + BMLoop *l1, *l2; + if (BM_edge_loop_pair(e, &l1, &l2)) { + BMVert *v_cmp = l1->e->v1; + ulp->flag = (((l1->v != v_cmp) ? ULP_FLIP_0 : 0) | + ((l2->v == v_cmp) ? ULP_FLIP_1 : 0)); + } + else { + ulp->flag = 0; + } + ulp->l_pair[0] = l1; + ulp->l_pair[1] = l2; + + ulp++; + } + } + + return uloop_pairs; + } + else { + return NULL; + } +} + +static void edbm_tagged_loop_pairs_do_fill_faces(BMesh *bm, UnorderedLoopPair *uloop_pairs) +{ + UnorderedLoopPair *ulp; + unsigned int total_tag = MEM_allocN_len(uloop_pairs) / sizeof(UnorderedLoopPair); + unsigned int i; + + for (i = 0, ulp = uloop_pairs; i < total_tag; i++, ulp++) { + if ((ulp->l_pair[0] && ulp->l_pair[1]) && + (ulp->l_pair[0]->e != ulp->l_pair[1]->e)) + { + /* time has come to make a face! */ + BMVert *v_shared = BM_edge_share_vert(ulp->l_pair[0]->e, ulp->l_pair[1]->e); + BMFace *f, *f_example = ulp->l_pair[0]->f; + BMLoop *l_iter; + BMVert *f_verts[4]; + + if (v_shared == NULL) { + /* quad */ + f_verts[0] = ulp->l_pair[0]->e->v1; + f_verts[1] = ulp->l_pair[1]->e->v1; + f_verts[2] = ulp->l_pair[1]->e->v2; + f_verts[3] = ulp->l_pair[0]->e->v2; + + if (ulp->flag & ULP_FLIP_0) { + SWAP(BMVert *, f_verts[0], f_verts[3]); + } + if (ulp->flag & ULP_FLIP_1) { + SWAP(BMVert *, f_verts[1], f_verts[2]); + } + } + else { + /* tri */ + f_verts[0] = v_shared; + f_verts[1] = BM_edge_other_vert(ulp->l_pair[0]->e, v_shared); + f_verts[2] = BM_edge_other_vert(ulp->l_pair[1]->e, v_shared); + f_verts[3] = NULL; + + /* don't use the flip flags */ + if (v_shared == ulp->l_pair[0]->v) { + SWAP(BMVert *, f_verts[0], f_verts[1]); + } + } + + /* face should never exist */ + BLI_assert(BM_face_exists(bm, f_verts, f_verts[3] ? 4 : 3, &f) == FALSE); + + f = BM_face_create_quad_tri_v(bm, f_verts, f_verts[3] ? 4 : 3, f_example, FALSE); + + l_iter = BM_FACE_FIRST_LOOP(f); + + if (f_verts[3]) { + BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[0]->e, ulp->l_pair[0]), l_iter); l_iter = l_iter->next; + BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[1]->e, ulp->l_pair[1]->next), l_iter); l_iter = l_iter->next; + BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[1]->e, ulp->l_pair[1]), l_iter); l_iter = l_iter->next; + BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[0]->e, ulp->l_pair[0]->next), l_iter); + } + else { + if (v_shared == f_verts[0]) { + BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[0]->e, ulp->l_pair[0]->next), l_iter); l_iter = l_iter->next; + BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[0]->e, ulp->l_pair[0]), l_iter); l_iter = l_iter->next; + BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[1]->e, ulp->l_pair[1]->next), l_iter); l_iter = l_iter->next; + } + else { + BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[1]->e, ulp->l_pair[1]), l_iter); l_iter = l_iter->next; + BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[0]->e, ulp->l_pair[0]), l_iter); l_iter = l_iter->next; + BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[0]->e, ulp->l_pair[0]->next), l_iter); l_iter = l_iter->next; + } + } + + } + } +} + +/* --- end 'face-fill' code --- */ + + static int edbm_rip_call_edgesplit(BMEditMesh *em, wmOperator *op) { BMOperator bmop; @@ -404,6 +538,8 @@ static int edbm_rip_call_edgesplit(BMEditMesh *em, wmOperator *op) */ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, wmEvent *event) { + const int do_fill = RNA_boolean_get(op->ptr, "use_fill"); + UnorderedLoopPair *fill_uloop_pairs = NULL; Object *obedit = CTX_data_edit_object(C); ARegion *ar = CTX_wm_region(C); RegionView3D *rv3d = CTX_wm_region_view3d(C); @@ -455,7 +591,7 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, wmEvent *event) totboundary_edge += (is_boundary != 0 || BM_edge_is_wire(e)); if (!BM_elem_flag_test(e, BM_ELEM_HIDDEN)) { if (is_boundary == FALSE && BM_edge_is_manifold(e)) { - d = edbm_rip_rip_edgedist(ar, projectMat, e->v1->co, e->v2->co, fmval, INSET_DEFAULT); + d = edbm_rip_edgedist(ar, projectMat, e->v1->co, e->v2->co, fmval, INSET_DEFAULT); if (d < dist) { dist = d; e2 = e; @@ -483,7 +619,7 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, wmEvent *event) float l_mid_co[3]; l = l_all[i1]; edbm_calc_loop_co(l, l_mid_co); - d = edbm_rip_rip_edgedist(ar, projectMat, l->v->co, l_mid_co, fmval, INSET_DEFAULT); + d = edbm_rip_edgedist(ar, projectMat, l->v->co, l_mid_co, fmval, INSET_DEFAULT); if (d < dist) { dist = d; @@ -549,7 +685,7 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, wmEvent *event) float l_mid_co[3]; edbm_calc_loop_co(l, l_mid_co); - d = edbm_rip_rip_edgedist(ar, projectMat, v->co, l_mid_co, fmval, INSET_DEFAULT); + d = edbm_rip_edgedist(ar, projectMat, v->co, l_mid_co, fmval, INSET_DEFAULT); if (d < dist) { dist = d; @@ -565,7 +701,7 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, wmEvent *event) float e_mid_co[3]; mid_v3_v3v3(e_mid_co, e->v1->co, e->v2->co); - d = edbm_rip_rip_edgedist(ar, projectMat, v->co, e_mid_co, fmval, INSET_DEFAULT); + d = edbm_rip_edgedist(ar, projectMat, v->co, e_mid_co, fmval, INSET_DEFAULT); if (d < dist) { dist = d; @@ -612,32 +748,58 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, wmEvent *event) return OPERATOR_CANCELLED; } + /* *** Execute the split! *** */ + /* unlike edge split, for single vertex split we only use the operator in one of the cases + * but both allocate fill */ + /* rip two adjacent edges */ if (BM_edge_is_boundary(e2) || BM_vert_face_count(v) == 2) { + /* Don't run the edge split operator in this case */ + + BM_elem_flag_enable(e2, BM_ELEM_TAG); /* only for face-fill (we don't call the operator) */ + + /* keep directly before edgesplit */ + if (do_fill) { + fill_uloop_pairs = edbm_tagged_loop_pairs_to_fill(bm); + } + l = e2->l; ripvert = BM_face_vert_separate(bm, l->f, v); BLI_assert(ripvert); if (!ripvert) { + if (fill_uloop_pairs) MEM_freeN(fill_uloop_pairs); return OPERATOR_CANCELLED; } } - else if (BM_edge_is_manifold(e2)) { - l = e2->l; - e = BM_face_other_edge_loop(l->f, e2, v)->e; - BM_elem_flag_enable(e, BM_ELEM_TAG); + else { + if (BM_edge_is_manifold(e2)) { + l = e2->l; + e = BM_face_other_edge_loop(l->f, e2, v)->e; + BM_elem_flag_enable(e, BM_ELEM_TAG); - l = e2->l->radial_next; - e = BM_face_other_edge_loop(l->f, e2, v)->e; - BM_elem_flag_enable(e, BM_ELEM_TAG); + l = e2->l->radial_next; + e = BM_face_other_edge_loop(l->f, e2, v)->e; + BM_elem_flag_enable(e, BM_ELEM_TAG); + } + else { + /* looks like there are no split edges, we could just return/report-error? - Campbell */ + } + + /* keep directly before edgesplit */ + if (do_fill) { + fill_uloop_pairs = edbm_tagged_loop_pairs_to_fill(bm); + } + + if (!edbm_rip_call_edgesplit(em, op)) { + if (fill_uloop_pairs) MEM_freeN(fill_uloop_pairs); + return OPERATOR_CANCELLED; + } } dist = FLT_MAX; - if (!edbm_rip_call_edgesplit(em, op)) { - return OPERATOR_CANCELLED; - } - else { + { /* --- select which vert --- */ BMVert *v_best = NULL; float l_prev_co[3], l_next_co[3], l_corner_co[3]; @@ -662,7 +824,7 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, wmEvent *event) add_v3_v3v3(l_corner_co, l_prev_co, l_next_co); add_v3_v3(l_corner_co, l->v->co); - d = edbm_rip_rip_edgedist(ar, projectMat, l->v->co, l_corner_co, fmval, INSET_DEFAULT); + d = edbm_rip_edgedist(ar, projectMat, l->v->co, l_corner_co, fmval, INSET_DEFAULT); if (d < dist) { v_best = v; dist = d; @@ -679,6 +841,12 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, wmEvent *event) } } + if (do_fill && fill_uloop_pairs) { + edbm_tagged_loop_pairs_do_fill_faces(bm, fill_uloop_pairs); + MEM_freeN(fill_uloop_pairs); + } + + if (totvert_orig == bm->totvert) { BKE_report(op->reports, RPT_ERROR, "No vertices could be ripped"); return OPERATOR_CANCELLED; @@ -692,6 +860,8 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, wmEvent *event) */ static int edbm_rip_invoke__edge(bContext *C, wmOperator *op, wmEvent *event) { + const int do_fill = RNA_boolean_get(op->ptr, "use_fill"); + UnorderedLoopPair *fill_uloop_pairs = NULL; Object *obedit = CTX_data_edit_object(C); ARegion *ar = CTX_wm_region(C); RegionView3D *rv3d = CTX_wm_region_view3d(C); @@ -765,6 +935,7 @@ static int edbm_rip_invoke__edge(bContext *C, wmOperator *op, wmEvent *event) l = BM_face_other_edge_loop(l->f, l->e, v); if (l) { + BLI_assert(!BM_elem_flag_test(l->e, BM_ELEM_TAG)); BM_elem_flag_enable(l->e, BM_ELEM_TAG); } } @@ -773,13 +944,20 @@ static int edbm_rip_invoke__edge(bContext *C, wmOperator *op, wmEvent *event) e = BM_vert_other_disk_edge(v, e2); if (e) { + BLI_assert(!BM_elem_flag_test(e, BM_ELEM_TAG)); BM_elem_flag_enable(e, BM_ELEM_TAG); } } } } + /* keep directly before edgesplit */ + if (do_fill) { + fill_uloop_pairs = edbm_tagged_loop_pairs_to_fill(bm); + } + if (!edbm_rip_call_edgesplit(em, op)) { + if (fill_uloop_pairs) MEM_freeN(fill_uloop_pairs); return OPERATOR_CANCELLED; } @@ -792,6 +970,11 @@ static int edbm_rip_invoke__edge(bContext *C, wmOperator *op, wmEvent *event) ar, projectMat, fmval); MEM_freeN(eloop_pairs); + if (do_fill && fill_uloop_pairs) { + edbm_tagged_loop_pairs_do_fill_faces(bm, fill_uloop_pairs); + MEM_freeN(fill_uloop_pairs); + } + if (totedge_orig == bm->totedge) { BKE_report(op->reports, RPT_ERROR, "No edges could be ripped"); return OPERATOR_CANCELLED; @@ -878,5 +1061,6 @@ void MESH_OT_rip(wmOperatorType *ot) /* to give to transform */ Transform_Properties(ot, P_PROPORTIONAL); - RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Editing", ""); + RNA_def_boolean(ot->srna, "mirror", FALSE, "Mirror Editing", ""); + RNA_def_boolean(ot->srna, "use_fill", FALSE, "Fill", "Fille the ripped region"); } diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c index 3ac8719f304..8ba9b3fe4e7 100644 --- a/source/blender/editors/mesh/mesh_ops.c +++ b/source/blender/editors/mesh/mesh_ops.c @@ -209,7 +209,17 @@ void ED_operatormacros_mesh(void) ot = WM_operatortype_append_macro("MESH_OT_rip_move", "Rip", "Rip polygons and move the result", OPTYPE_UNDO | OPTYPE_REGISTER); - WM_operatortype_macro_define(ot, "MESH_OT_rip"); + otmacro = WM_operatortype_macro_define(ot, "MESH_OT_rip"); + RNA_boolean_set(otmacro->ptr, "use_fill", FALSE); + otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate"); + RNA_enum_set(otmacro->ptr, "proportional", 0); + RNA_boolean_set(otmacro->ptr, "mirror", FALSE); + + /* annoying we can't pass 'use_fill' through the macro */ + ot = WM_operatortype_append_macro("MESH_OT_rip_move_fill", "Rip Fill", "Rip-fill polygons and move the result", + OPTYPE_UNDO | OPTYPE_REGISTER); + otmacro = WM_operatortype_macro_define(ot, "MESH_OT_rip"); + RNA_boolean_set(otmacro->ptr, "use_fill", TRUE); otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate"); RNA_enum_set(otmacro->ptr, "proportional", 0); RNA_boolean_set(otmacro->ptr, "mirror", FALSE); @@ -324,6 +334,8 @@ void ED_keymap_mesh(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "MESH_OT_tris_convert_to_quads", JKEY, KM_PRESS, KM_ALT, 0); WM_keymap_add_item(keymap, "MESH_OT_rip_move", VKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "MESH_OT_rip_move_fill", VKEY, KM_PRESS, KM_ALT, 0); + WM_keymap_add_item(keymap, "MESH_OT_merge", MKEY, KM_PRESS, KM_ALT, 0); WM_keymap_add_item(keymap, "TRANSFORM_OT_shrink_fatten", SKEY, KM_PRESS, KM_ALT, 0); From 76e2706b300960d3ed98178128198fa1015ec001 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Sun, 14 Oct 2012 06:59:01 +0000 Subject: [PATCH 216/347] Fixed missing display buffer and mipmaps invalidation in cases only few of selected objects failed to bake. --- source/blender/editors/object/object_bake.c | 23 +++++++++++-------- source/blender/imbuf/intern/colormanagement.c | 2 +- .../blender/render/intern/source/rendercore.c | 5 ++-- 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c index a35ba8813e8..9af0eda880a 100644 --- a/source/blender/editors/object/object_bake.c +++ b/source/blender/editors/object/object_bake.c @@ -900,7 +900,7 @@ static void finish_images(MultiresBakeRender *bkr) RE_bake_ibuf_filter(ibuf, (char *)ibuf->userdata, bkr->bake_filter); - ibuf->userflags |= IB_BITMAPDIRTY | IB_DISPLAY_BUFFER_INVALID;; + ibuf->userflags |= IB_BITMAPDIRTY | IB_DISPLAY_BUFFER_INVALID; if (ibuf->rect_float) ibuf->userflags |= IB_RECT_INVALID; @@ -1366,20 +1366,23 @@ static void finish_bake_internal(BakeRender *bkr) if (bkr->prev_r_raytrace == 0) bkr->scene->r.mode &= ~R_RAYTRACE; - /* force OpenGL reload and mipmap recalc */ for (ima = G.main->image.first; ima; ima = ima->id.next) { ImBuf *ibuf = BKE_image_get_ibuf(ima, NULL); - if (bkr->result == BAKE_RESULT_OK) { - if (ima->ok == IMA_OK_LOADED) { - if (ibuf) { - if (ibuf->userflags & IB_BITMAPDIRTY) { - ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID; - GPU_free_image(ima); - imb_freemipmapImBuf(ibuf); - } + /* some of the images could have been changed during bake, + * so recreate mipmaps regardless bake result status + */ + if (ima->ok == IMA_OK_LOADED) { + if (ibuf) { + if (ibuf->userflags & IB_BITMAPDIRTY) { + GPU_free_image(ima); + imb_freemipmapImBuf(ibuf); } + + /* invalidate display buffers for changed images */ + if (ibuf->userflags & IB_BITMAPDIRTY) + ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID; } } diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c index 40b07c02cd7..de9cf09e036 100644 --- a/source/blender/imbuf/intern/colormanagement.c +++ b/source/blender/imbuf/intern/colormanagement.c @@ -1822,7 +1822,7 @@ unsigned char *IMB_display_buffer_acquire(ImBuf *ibuf, const ColorManagedViewSet if (global_tot_display) ibuf->display_buffer_flags = MEM_callocN(sizeof(unsigned int) * global_tot_display, "imbuf display_buffer_flags"); } - else if (ibuf->userflags & IB_DISPLAY_BUFFER_INVALID) { + else if (ibuf->userflags & IB_DISPLAY_BUFFER_INVALID) { /* all display buffers were marked as invalid from other areas, * now propagate this flag to internal color management routines */ diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c index 285cd02c4ff..ee88706117f 100644 --- a/source/blender/render/intern/source/rendercore.c +++ b/source/blender/render/intern/source/rendercore.c @@ -2513,7 +2513,9 @@ static int get_next_bake_face(BakeShade *bs) /* clear image */ if (R.r.bake_flag & R_BAKE_CLEAR) IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? vec_alpha : vec_solid); - + + ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID; + /* might be read by UI to set active image for display */ R.bakebuf= ima; } @@ -2733,7 +2735,6 @@ int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_up RE_bake_ibuf_filter(ibuf, (char *)ibuf->userdata, re->r.bake_filter); ibuf->userflags |= IB_BITMAPDIRTY; - if (ibuf->rect_float) IMB_rect_from_float(ibuf); } } From 27e54f4d37d70b5f2c63c2cdbbca722f01fed414 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 14 Oct 2012 07:40:16 +0000 Subject: [PATCH 217/347] code cleanup: remove redundant casts. quiet some qualifier warnings. --- intern/ghost/intern/GHOST_DisplayManagerX11.cpp | 4 ++-- intern/ghost/intern/GHOST_SystemX11.cpp | 10 +++++----- source/blender/blenlib/intern/math_base_inline.c | 10 +++++----- .../blender/compositor/intern/COM_ExecutionSystem.cpp | 2 +- .../compositor/intern/COM_ExecutionSystemHelper.cpp | 4 ++-- source/blender/compositor/intern/COM_Node.cpp | 10 +++++----- source/blender/compositor/intern/COM_OpenCLDevice.cpp | 2 +- .../blender/compositor/nodes/COM_DilateErodeNode.cpp | 2 +- source/blender/compositor/nodes/COM_KeyingNode.cpp | 2 +- .../operations/COM_ConvertDepthToRadiusOperation.cpp | 4 ++-- .../operations/COM_FastGaussianBlurOperation.cpp | 4 ++-- .../compositor/operations/COM_GlareGhostOperation.cpp | 8 ++++---- .../compositor/operations/COM_MaskOperation.cpp | 2 +- .../operations/COM_MovieDistortionOperation.h | 8 ++++---- .../operations/COM_ScreenLensDistortionOperation.cpp | 4 ++-- .../operations/COM_VariableSizeBokehBlurOperation.cpp | 2 +- source/blender/editors/mask/mask_select.c | 2 +- source/blender/editors/space_clip/clip_editor.c | 3 ++- source/blender/editors/space_clip/tracking_select.c | 2 +- source/blender/editors/space_node/node_select.c | 2 +- source/blender/editors/space_view3d/view3d_select.c | 2 +- source/blender/editors/uvedit/uvedit_ops.c | 2 +- 22 files changed, 46 insertions(+), 45 deletions(-) diff --git a/intern/ghost/intern/GHOST_DisplayManagerX11.cpp b/intern/ghost/intern/GHOST_DisplayManagerX11.cpp index 0bd90854a31..3d702c02b0f 100644 --- a/intern/ghost/intern/GHOST_DisplayManagerX11.cpp +++ b/intern/ghost/intern/GHOST_DisplayManagerX11.cpp @@ -89,7 +89,7 @@ getNumDisplaySettings( #else /* We only have one X11 setting at the moment. */ GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n"); - numSettings = GHOST_TInt32(1); + numSettings = 1; #endif return GHOST_kSuccess; @@ -160,7 +160,7 @@ getCurrentDisplaySetting( /* According to the xf86vidmodegetallmodelines man page, * "The first element of the array corresponds to the current video mode." */ - return getDisplaySetting(display, GHOST_TInt32(0), setting); + return getDisplaySetting(display, 0, setting); } diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp index 232bea6749b..3ba84e157ed 100644 --- a/intern/ghost/intern/GHOST_SystemX11.cpp +++ b/intern/ghost/intern/GHOST_SystemX11.cpp @@ -1456,7 +1456,7 @@ void GHOST_SystemX11::getClipboard_xcout(XEvent evt, /* check size and format of the property */ XGetWindowProperty(m_display, win, m_xclip_out, 0, 0, False, AnyPropertyType, &pty_type, &pty_format, - &pty_items, &pty_size, (unsigned char **) &buffer); + &pty_items, &pty_size, &buffer); if (pty_format != 8) { /* property does not contain text, delete it @@ -1484,7 +1484,7 @@ void GHOST_SystemX11::getClipboard_xcout(XEvent evt, * text, we know the size. */ XGetWindowProperty(m_display, win, m_xclip_out, 0, (long) pty_size, False, AnyPropertyType, &pty_type, &pty_format, - &pty_items, &pty_size, (unsigned char **) &buffer); + &pty_items, &pty_size, &buffer); /* allocate memory to accommodate data in *txt */ if (*len == 0) { @@ -1538,12 +1538,12 @@ GHOST_TUns8 *GHOST_SystemX11::getClipboard(bool selection) const if (sseln == m_clipboard) { sel_buf = (unsigned char *)malloc(strlen(txt_cut_buffer) + 1); strcpy((char *)sel_buf, txt_cut_buffer); - return((GHOST_TUns8 *)sel_buf); + return sel_buf; } else { sel_buf = (unsigned char *)malloc(strlen(txt_select_buffer) + 1); strcpy((char *)sel_buf, txt_select_buffer); - return((GHOST_TUns8 *)sel_buf); + return sel_buf; } } else if (owner == None) @@ -1594,7 +1594,7 @@ GHOST_TUns8 *GHOST_SystemX11::getClipboard(bool selection) const else free(sel_buf); - return (GHOST_TUns8 *)tmp_data; + return tmp_data; } return(NULL); } diff --git a/source/blender/blenlib/intern/math_base_inline.c b/source/blender/blenlib/intern/math_base_inline.c index 97fc431d8fa..21ecfccf9d9 100644 --- a/source/blender/blenlib/intern/math_base_inline.c +++ b/source/blender/blenlib/intern/math_base_inline.c @@ -59,34 +59,34 @@ MINLINE float saacos(float fac) { if (fac <= -1.0f) return (float)M_PI; else if (fac >= 1.0f) return 0.0; - else return (float)acos(fac); + else return acosf(fac); } MINLINE float saasin(float fac) { if (fac <= -1.0f) return (float)-M_PI / 2.0f; else if (fac >= 1.0f) return (float)M_PI / 2.0f; - else return (float)asin(fac); + else return asinf(fac); } MINLINE float sasqrt(float fac) { if (fac <= 0.0f) return 0.0f; - return (float)sqrt(fac); + return sqrtf(fac); } MINLINE float saacosf(float fac) { if (fac <= -1.0f) return (float)M_PI; else if (fac >= 1.0f) return 0.0f; - else return (float)acosf(fac); + else return acosf(fac); } MINLINE float saasinf(float fac) { if (fac <= -1.0f) return (float)-M_PI / 2.0f; else if (fac >= 1.0f) return (float)M_PI / 2.0f; - else return (float)asinf(fac); + else return asinf(fac); } MINLINE float sasqrtf(float fac) diff --git a/source/blender/compositor/intern/COM_ExecutionSystem.cpp b/source/blender/compositor/intern/COM_ExecutionSystem.cpp index a13717c9d86..0018cbbae9f 100644 --- a/source/blender/compositor/intern/COM_ExecutionSystem.cpp +++ b/source/blender/compositor/intern/COM_ExecutionSystem.cpp @@ -50,7 +50,7 @@ ExecutionSystem::ExecutionSystem(RenderData *rd, bNodeTree *editingtree, bool re this->m_context.setbNodeTree(editingtree); this->m_context.setFastCalculation(fastcalculation); bNode *gnode; - for (gnode = (bNode *)editingtree->nodes.first; gnode; gnode = (bNode *)gnode->next) { + for (gnode = (bNode *)editingtree->nodes.first; gnode; gnode = gnode->next) { if (gnode->type == NODE_GROUP && gnode->typeinfo->group_edit_get(gnode)) { this->m_context.setActivegNode(gnode); break; diff --git a/source/blender/compositor/intern/COM_ExecutionSystemHelper.cpp b/source/blender/compositor/intern/COM_ExecutionSystemHelper.cpp index 33a5cafebbe..506bd42ace3 100644 --- a/source/blender/compositor/intern/COM_ExecutionSystemHelper.cpp +++ b/source/blender/compositor/intern/COM_ExecutionSystemHelper.cpp @@ -51,7 +51,7 @@ void ExecutionSystemHelper::addbNodeTree(ExecutionSystem &system, int nodes_star while (node != NULL) { Node *nnode = addNode(nodes, node, isActiveGroup, system.getContext().isFastCalculation()); nnode->setbNodeGroup(groupnode); - node = (bNode *)node->next; + node = node->next; } NodeRange node_range(nodes.begin() + nodes_start, nodes.end()); @@ -60,7 +60,7 @@ void ExecutionSystemHelper::addbNodeTree(ExecutionSystem &system, int nodes_star bNodeLink *nodelink = (bNodeLink *)tree->links.first; while (nodelink != NULL) { addNodeLink(node_range, links, nodelink); - nodelink = (bNodeLink *)nodelink->next; + nodelink = nodelink->next; } /* Expand group nodes */ diff --git a/source/blender/compositor/intern/COM_Node.cpp b/source/blender/compositor/intern/COM_Node.cpp index 5922b0e6b08..300d7ef1952 100644 --- a/source/blender/compositor/intern/COM_Node.cpp +++ b/source/blender/compositor/intern/COM_Node.cpp @@ -51,7 +51,7 @@ Node::Node(bNode *editorNode, bool create_sockets): NodeBase() if (input->type == SOCK_VECTOR) dt = COM_DT_VECTOR; this->addInputSocket(dt, (InputSocketResizeMode)input->resizemode, input); - input = (bNodeSocket *)input->next; + input = input->next; } bNodeSocket *output = (bNodeSocket *)editorNode->outputs.first; while (output != NULL) { @@ -60,14 +60,14 @@ Node::Node(bNode *editorNode, bool create_sockets): NodeBase() if (output->type == SOCK_VECTOR) dt = COM_DT_VECTOR; this->addOutputSocket(dt, output); - output = (bNodeSocket *)output->next; + output = output->next; } } } void Node::addSetValueOperation(ExecutionSystem *graph, InputSocket *inputsocket, int editorNodeInputSocketIndex) { - bNodeSocket *bSock = (bNodeSocket *)this->getEditorInputSocket(editorNodeInputSocketIndex); + bNodeSocket *bSock = this->getEditorInputSocket(editorNodeInputSocketIndex); SetValueOperation *operation = new SetValueOperation(); bNodeSocketValueFloat *val = (bNodeSocketValueFloat *)bSock->default_value; operation->setValue(val->value); @@ -114,7 +114,7 @@ SocketConnection *Node::addLink(ExecutionSystem *graph, OutputSocket *outputSock void Node::addSetColorOperation(ExecutionSystem *graph, InputSocket *inputsocket, int editorNodeInputSocketIndex) { - bNodeSocket *bSock = (bNodeSocket *)this->getEditorInputSocket(editorNodeInputSocketIndex); + bNodeSocket *bSock = this->getEditorInputSocket(editorNodeInputSocketIndex); SetColorOperation *operation = new SetColorOperation(); bNodeSocketValueRGBA *val = (bNodeSocketValueRGBA *)bSock->default_value; operation->setChannel1(val->value[0]); @@ -127,7 +127,7 @@ void Node::addSetColorOperation(ExecutionSystem *graph, InputSocket *inputsocket void Node::addSetVectorOperation(ExecutionSystem *graph, InputSocket *inputsocket, int editorNodeInputSocketIndex) { - bNodeSocket *bSock = (bNodeSocket *)this->getEditorInputSocket(editorNodeInputSocketIndex); + bNodeSocket *bSock = this->getEditorInputSocket(editorNodeInputSocketIndex); bNodeSocketValueVector *val = (bNodeSocketValueVector *)bSock->default_value; SetVectorOperation *operation = new SetVectorOperation(); operation->setX(val->value[0]); diff --git a/source/blender/compositor/intern/COM_OpenCLDevice.cpp b/source/blender/compositor/intern/COM_OpenCLDevice.cpp index d23ed245844..d5da079c9fd 100644 --- a/source/blender/compositor/intern/COM_OpenCLDevice.cpp +++ b/source/blender/compositor/intern/COM_OpenCLDevice.cpp @@ -74,7 +74,7 @@ cl_mem OpenCLDevice::COM_clAttachMemoryBufferToKernelParameter(cl_kernel kernel, { cl_int error; - MemoryBuffer *result = (MemoryBuffer *)reader->getInputMemoryBuffer(inputMemoryBuffers); + MemoryBuffer *result = reader->getInputMemoryBuffer(inputMemoryBuffers); const cl_image_format imageFormat = { CL_RGBA, diff --git a/source/blender/compositor/nodes/COM_DilateErodeNode.cpp b/source/blender/compositor/nodes/COM_DilateErodeNode.cpp index 5cfc29ecce2..0fb7ea7d264 100644 --- a/source/blender/compositor/nodes/COM_DilateErodeNode.cpp +++ b/source/blender/compositor/nodes/COM_DilateErodeNode.cpp @@ -79,7 +79,7 @@ void DilateErodeNode::convertToOperations(ExecutionSystem *graph, CompositorCont CompositorQuality quality = context->getQuality(); /* initialize node data */ - NodeBlurData *data = (NodeBlurData *)&this->m_alpha_blur; + NodeBlurData *data = &this->m_alpha_blur; memset(data, 0, sizeof(*data)); data->filtertype = R_FILTER_GAUSS; diff --git a/source/blender/compositor/nodes/COM_KeyingNode.cpp b/source/blender/compositor/nodes/COM_KeyingNode.cpp index 6bc9afba32c..51ea2913e65 100644 --- a/source/blender/compositor/nodes/COM_KeyingNode.cpp +++ b/source/blender/compositor/nodes/COM_KeyingNode.cpp @@ -151,7 +151,7 @@ OutputSocket *KeyingNode::setupFeather(ExecutionSystem *graph, CompositorContext CompositorQuality quality = context->getQuality(); /* initialize node data */ - NodeBlurData *data = (NodeBlurData *)&this->m_alpha_blur; + NodeBlurData *data = &this->m_alpha_blur; memset(data, 0, sizeof(*data)); data->filtertype = R_FILTER_GAUSS; diff --git a/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cpp b/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cpp index 88289f12ebb..f6b23f6afd2 100644 --- a/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cpp +++ b/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cpp @@ -64,8 +64,8 @@ void ConvertDepthToRadiusOperation::initExecution() this->m_inverseFocalDistance = 1.0f / focalDistance; this->m_aspect = (this->getWidth() > this->getHeight()) ? (this->getHeight() / (float)this->getWidth()) : (this->getWidth() / (float)this->getHeight()); this->m_aperture = 0.5f * (this->m_cam_lens / (this->m_aspect * cam_sensor)) / this->m_fStop; - float minsz = min(getWidth(), getHeight()); - this->m_dof_sp = (float)minsz / ((cam_sensor / 2.0f) / this->m_cam_lens); // <- == aspect * MIN2(img->x, img->y) / tan(0.5f * fov); + const float minsz = min(getWidth(), getHeight()); + this->m_dof_sp = minsz / ((cam_sensor / 2.0f) / this->m_cam_lens); // <- == aspect * MIN2(img->x, img->y) / tan(0.5f * fov); if (this->m_blurPostOperation) { m_blurPostOperation->setSigma(min(m_aperture * 128.0f, this->m_maxRadius)); diff --git a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp index 2b2928c98db..262252f7d8c 100644 --- a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp @@ -128,8 +128,8 @@ void FastGaussianBlurOperation::IIR_gauss(MemoryBuffer *src, float sigma, unsign // XXX The YVV macro defined below explicitly expects sources of at least 3x3 pixels, // so just skiping blur along faulty direction if src's def is below that limit! - if (src_width < 3) xy &= ~(int) 1; - if (src_height < 3) xy &= ~(int) 2; + if (src_width < 3) xy &= ~1; + if (src_height < 3) xy &= ~2; if (xy < 1) return; // see "Recursive Gabor Filtering" by Young/VanVliet diff --git a/source/blender/compositor/operations/COM_GlareGhostOperation.cpp b/source/blender/compositor/operations/COM_GlareGhostOperation.cpp index ace04237b29..c4f8b3a0ddb 100644 --- a/source/blender/compositor/operations/COM_GlareGhostOperation.cpp +++ b/source/blender/compositor/operations/COM_GlareGhostOperation.cpp @@ -79,9 +79,9 @@ void GlareGhostOperation::generateGlare(float *data, MemoryBuffer *inputTile, No sc = 2.13; isc = -0.97; for (y = 0; y < gbuf->getHeight() && (!breaked); y++) { - v = (float)(y + 0.5f) / (float)gbuf->getHeight(); + v = ((float)y + 0.5f) / (float)gbuf->getHeight(); for (x = 0; x < gbuf->getWidth(); x++) { - u = (float)(x + 0.5f) / (float)gbuf->getWidth(); + u = ((float)x + 0.5f) / (float)gbuf->getWidth(); s = (u - 0.5f) * sc + 0.5f, t = (v - 0.5f) * sc + 0.5f; tbuf1->readCubic(c, s * gbuf->getWidth(), t * gbuf->getHeight()); sm = smoothMask(s, t); @@ -100,9 +100,9 @@ void GlareGhostOperation::generateGlare(float *data, MemoryBuffer *inputTile, No memset(tbuf1->getBuffer(), 0, tbuf1->getWidth() * tbuf1->getHeight() * COM_NUMBER_OF_CHANNELS * sizeof(float)); for (n = 1; n < settings->iter && (!breaked); n++) { for (y = 0; y < gbuf->getHeight() && (!breaked); y++) { - v = (float)(y + 0.5f) / (float)gbuf->getHeight(); + v = ((float)y + 0.5f) / (float)gbuf->getHeight(); for (x = 0; x < gbuf->getWidth(); x++) { - u = (float)(x + 0.5f) / (float)gbuf->getWidth(); + u = ((float)x + 0.5f) / (float)gbuf->getWidth(); tc[0] = tc[1] = tc[2] = 0.f; for (p = 0; p < 4; p++) { np = (n << 2) + p; diff --git a/source/blender/compositor/operations/COM_MaskOperation.cpp b/source/blender/compositor/operations/COM_MaskOperation.cpp index 36b3f2023ae..ba1059c4eb5 100644 --- a/source/blender/compositor/operations/COM_MaskOperation.cpp +++ b/source/blender/compositor/operations/COM_MaskOperation.cpp @@ -73,7 +73,7 @@ void MaskOperation::initExecution() for (masklay = (MaskLayer *)mask_temp->masklayers.first; masklay; - masklay = (MaskLayer *)masklay->next) + masklay = masklay->next) { masklay_shape = BKE_mask_layer_shape_varify_frame(masklay, this->m_frame_number); BKE_mask_layer_shape_from_mask(masklay, masklay_shape); diff --git a/source/blender/compositor/operations/COM_MovieDistortionOperation.h b/source/blender/compositor/operations/COM_MovieDistortionOperation.h index f3eeb2f48ba..93cc555fdbc 100644 --- a/source/blender/compositor/operations/COM_MovieDistortionOperation.h +++ b/source/blender/compositor/operations/COM_MovieDistortionOperation.h @@ -115,10 +115,10 @@ public: if (!this->m_bufferCalculated[offset]) { //float overscan = 0.0f; - float w = (float)this->m_width /* / (1 + overscan) */; - float h = (float)this->m_height /* / (1 + overscan) */; - float aspx = (float)w / this->m_calibration_width; - float aspy = (float)h / this->m_calibration_height; + const float w = (float)this->m_width /* / (1 + overscan) */; + const float h = (float)this->m_height /* / (1 + overscan) */; + const float aspx = w / (float)this->m_calibration_width; + const float aspy = h / (float)this->m_calibration_height; float in[2]; float out[2]; diff --git a/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp b/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp index 193ab669f40..fd9cc1fddcb 100644 --- a/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp +++ b/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp @@ -98,7 +98,7 @@ void ScreenLensDistortionOperation::executePixel(float output[4], int x, int y, const float sd = 1.0f / (float)ds; for (z = 0; z < ds; ++z) { - const float tz = ((float)z + (jit ? BLI_frand() : 0.5f)) * sd; + const float tz = (z + (jit ? BLI_frand() : 0.5f)) * sd; t = 1.0f - (this->m_kr4 + tz * this->m_drg) * uv_dot; d = 1.0f / (1.0f + sqrtf(t)); const float nx = (u * d + 0.5f) * width - 0.5f; @@ -116,7 +116,7 @@ void ScreenLensDistortionOperation::executePixel(float output[4], int x, int y, const float sd = 1.0f / (float)ds; for (z = 0; z < ds; ++z) { - const float tz = ((float)z + (jit ? BLI_frand() : 0.5f)) * sd; + const float tz = (z + (jit ? BLI_frand() : 0.5f)) * sd; t = 1.0f - (this->m_kg4 + tz * this->m_dgb) * uv_dot; d = 1.0f / (1.0f + sqrtf(t)); const float nx = (u * d + 0.5f) * width - 0.5f; diff --git a/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp b/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp index 7ccc91072bc..b8e15934c30 100644 --- a/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp @@ -192,7 +192,7 @@ void VariableSizeBokehBlurOperation::executeOpenCL(OpenCLDevice *device, cl_int maxBlur; cl_float threshold = this->m_threshold; - MemoryBuffer *sizeMemoryBuffer = (MemoryBuffer *)this->m_inputSizeProgram->getInputMemoryBuffer(inputMemoryBuffers); + MemoryBuffer *sizeMemoryBuffer = this->m_inputSizeProgram->getInputMemoryBuffer(inputMemoryBuffers); const float max_dim = max(m_width, m_height); cl_float scalar = this->m_do_size_scale ? (max_dim / 100.0f) : 1.0f; diff --git a/source/blender/editors/mask/mask_select.c b/source/blender/editors/mask/mask_select.c index 69cfdf4e51b..dc204909577 100644 --- a/source/blender/editors/mask/mask_select.c +++ b/source/blender/editors/mask/mask_select.c @@ -557,7 +557,7 @@ static int clip_lasso_select_exec(bContext *C, wmOperator *op) select = !RNA_boolean_get(op->ptr, "deselect"); do_lasso_select_mask(C, mcords, mcords_tot, select); - MEM_freeN(mcords); + MEM_freeN((void *)mcords); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c index 167353e7cb7..b495ca32813 100644 --- a/source/blender/editors/space_clip/clip_editor.c +++ b/source/blender/editors/space_clip/clip_editor.c @@ -44,6 +44,7 @@ #include "BLI_utildefines.h" #include "BLI_math.h" +#include "BLI_string.h" #include "BLI_rect.h" #include "GPU_extensions.h" @@ -692,7 +693,7 @@ int ED_space_clip_load_movieclip_buffer(SpaceClip *sc, ImBuf *ibuf, const unsign context->start_frame = clip->start_frame; context->frame_offset = clip->frame_offset; - strcpy(context->colorspace, clip->colorspace_settings.name); + BLI_strncpy(context->colorspace, clip->colorspace_settings.name, sizeof(context->colorspace)); } else { /* displaying exactly the same image which was loaded t oa texture, diff --git a/source/blender/editors/space_clip/tracking_select.c b/source/blender/editors/space_clip/tracking_select.c index 7e3fabd1f66..feb523237ba 100644 --- a/source/blender/editors/space_clip/tracking_select.c +++ b/source/blender/editors/space_clip/tracking_select.c @@ -476,7 +476,7 @@ static int clip_lasso_select_exec(bContext *C, wmOperator *op) select = !RNA_boolean_get(op->ptr, "deselect"); do_lasso_select_marker(C, mcords, mcords_tot, select); - MEM_freeN(mcords); + MEM_freeN((void *)mcords); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/space_node/node_select.c b/source/blender/editors/space_node/node_select.c index b0916a50c37..a3efa15c54a 100644 --- a/source/blender/editors/space_node/node_select.c +++ b/source/blender/editors/space_node/node_select.c @@ -593,7 +593,7 @@ static int node_lasso_select_exec(bContext *C, wmOperator *op) select = !RNA_boolean_get(op->ptr, "deselect"); do_lasso_select_node(C, mcords, mcords_tot, select); - MEM_freeN(mcords); + MEM_freeN((void *)mcords); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index a111799a27c..9fd7cfafae0 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -943,7 +943,7 @@ static int view3d_lasso_select_exec(bContext *C, wmOperator *op) select = !RNA_boolean_get(op->ptr, "deselect"); view3d_lasso_select(C, &vc, mcords, mcords_tot, extend, select); - MEM_freeN(mcords); + MEM_freeN((void *)mcords); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c index e3d52fcaa9b..e5826435197 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -2829,7 +2829,7 @@ static int uv_lasso_select_exec(bContext *C, wmOperator *op) select = !RNA_boolean_get(op->ptr, "deselect"); change = do_lasso_select_mesh_uv(C, mcords, mcords_tot, select); - MEM_freeN(mcords); + MEM_freeN((void *)mcords); return change ? OPERATOR_FINISHED : OPERATOR_CANCELLED; } From 3a947cf537aa8c818ee1b0df8cbadd47f878a497 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 14 Oct 2012 08:49:01 +0000 Subject: [PATCH 218/347] code cleanup: remove redundant casts --- extern/libmv/third_party/ceres/CMakeLists.txt | 2 +- intern/dualcon/CMakeLists.txt | 5 ++++- intern/itasc/CMakeLists.txt | 4 ++-- intern/smoke/CMakeLists.txt | 2 +- source/blender/blenkernel/CMakeLists.txt | 2 +- source/blender/ikplugin/CMakeLists.txt | 4 +++- source/gameengine/BlenderRoutines/CMakeLists.txt | 2 +- .../gameengine/BlenderRoutines/KX_BlenderCanvas.cpp | 8 ++++---- .../gameengine/BlenderRoutines/KX_BlenderCanvas.h | 4 ++-- source/gameengine/Converter/BL_ArmatureChannel.cpp | 4 ++-- source/gameengine/Converter/BL_ArmatureObject.cpp | 13 ++++++++----- source/gameengine/Converter/BL_MeshDeformer.h | 2 +- source/gameengine/Converter/BL_ModifierDeformer.cpp | 2 +- source/gameengine/Converter/BL_SkinDeformer.cpp | 4 ++-- source/gameengine/Converter/CMakeLists.txt | 6 ++++-- .../Converter/KX_BlenderScalarInterpolator.cpp | 2 +- .../gameengine/Converter/KX_BlenderSceneConverter.h | 10 +++++----- source/gameengine/Ketsji/CMakeLists.txt | 4 +++- source/gameengine/Physics/Bullet/CMakeLists.txt | 2 +- source/gameengine/Rasterizer/RAS_MeshObject.cpp | 2 +- 20 files changed, 48 insertions(+), 36 deletions(-) diff --git a/extern/libmv/third_party/ceres/CMakeLists.txt b/extern/libmv/third_party/ceres/CMakeLists.txt index 0ce8e273f4a..e2f06d74646 100644 --- a/extern/libmv/third_party/ceres/CMakeLists.txt +++ b/extern/libmv/third_party/ceres/CMakeLists.txt @@ -28,13 +28,13 @@ set(INC . - ../../../Eigen3 include internal ../gflags ) set(INC_SYS + ../../../Eigen3 ) set(SRC diff --git a/intern/dualcon/CMakeLists.txt b/intern/dualcon/CMakeLists.txt index caa1ea09b04..da5e10fe6a7 100644 --- a/intern/dualcon/CMakeLists.txt +++ b/intern/dualcon/CMakeLists.txt @@ -19,6 +19,9 @@ set(INC . intern +) + +set(INC_SYS ../../extern/Eigen3 ) @@ -42,5 +45,5 @@ set(SRC dualcon.h ) -blender_add_lib(bf_intern_dualcon "${SRC}" "${INC}" "") +blender_add_lib(bf_intern_dualcon "${SRC}" "${INC}" "${INC_SYS}") diff --git a/intern/itasc/CMakeLists.txt b/intern/itasc/CMakeLists.txt index f4bc0326ea1..ab2ed6d10eb 100644 --- a/intern/itasc/CMakeLists.txt +++ b/intern/itasc/CMakeLists.txt @@ -24,11 +24,11 @@ # ***** END GPL LICENSE BLOCK ***** set(INC - ../../extern/Eigen3 + ) set(INC_SYS - + ../../extern/Eigen3 ) set(SRC diff --git a/intern/smoke/CMakeLists.txt b/intern/smoke/CMakeLists.txt index 11f173a6835..3b8a4c06e69 100644 --- a/intern/smoke/CMakeLists.txt +++ b/intern/smoke/CMakeLists.txt @@ -26,10 +26,10 @@ set(INC intern ../memutil - ../../extern/bullet2/src ) set(INC_SYS + ../../extern/bullet2/src ${PNG_INCLUDE_DIR} ${ZLIB_INCLUDE_DIRS} ) diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index 2a1ff49881f..f24b58658f6 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -249,7 +249,7 @@ if(WITH_AUDASPACE) endif() if(WITH_BULLET) - list(APPEND INC + list(APPEND INC_SYS ../../../extern/bullet2/src ) add_definitions(-DUSE_BULLET) diff --git a/source/blender/ikplugin/CMakeLists.txt b/source/blender/ikplugin/CMakeLists.txt index 903267c5618..0a0e0e664b4 100644 --- a/source/blender/ikplugin/CMakeLists.txt +++ b/source/blender/ikplugin/CMakeLists.txt @@ -56,9 +56,11 @@ endif() if(WITH_IK_ITASC) add_definitions(-DWITH_IK_ITASC) list(APPEND INC - ../../../extern/Eigen3 ../../../intern/itasc ) + list(APPEND INC_SYS + ../../../extern/Eigen3 + ) list(APPEND SRC intern/itasc_plugin.cpp intern/itasc_plugin.h diff --git a/source/gameengine/BlenderRoutines/CMakeLists.txt b/source/gameengine/BlenderRoutines/CMakeLists.txt index fa0994d788a..a053e069153 100644 --- a/source/gameengine/BlenderRoutines/CMakeLists.txt +++ b/source/gameengine/BlenderRoutines/CMakeLists.txt @@ -23,7 +23,6 @@ set(INC ../../blender/makesdna ../../blender/makesrna ../../blender/windowmanager - ../../../extern/bullet2/src ../../../intern/container ../../../intern/guardedalloc ../../../intern/moto/include @@ -31,6 +30,7 @@ set(INC ) set(INC_SYS + ../../../extern/bullet2/src ${PTHREADS_INCLUDE_DIRS} ${GLEW_INCLUDE_PATH} ) diff --git a/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp b/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp index 0b41cceb646..1afa5d3d07b 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp +++ b/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp @@ -119,14 +119,14 @@ int KX_BlenderCanvas::GetHeight( int KX_BlenderCanvas::GetMouseX(int x) { - float left = GetWindowArea().GetLeft(); - return float(x - (left - m_area_left)); + int left = GetWindowArea().GetLeft(); + return x - (left - m_area_left); } int KX_BlenderCanvas::GetMouseY(int y) { - float top = GetWindowArea().GetTop(); - return float(y - (m_area_top - top)); + int top = GetWindowArea().GetTop(); + return y - (m_area_top - top); } float KX_BlenderCanvas::GetMouseNormalizedX(int x) diff --git a/source/gameengine/BlenderRoutines/KX_BlenderCanvas.h b/source/gameengine/BlenderRoutines/KX_BlenderCanvas.h index bbec7e0fada..244394a115d 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderCanvas.h +++ b/source/gameengine/BlenderRoutines/KX_BlenderCanvas.h @@ -192,8 +192,8 @@ private: struct wmWindow* m_win; RAS_Rect m_frame_rect; RAS_Rect m_area_rect; - short m_area_left; - short m_area_top; + int m_area_left; + int m_area_top; #ifdef WITH_CXX_GUARDEDALLOC diff --git a/source/gameengine/Converter/BL_ArmatureChannel.cpp b/source/gameengine/Converter/BL_ArmatureChannel.cpp index e588d1d310c..8f5547c337c 100644 --- a/source/gameengine/Converter/BL_ArmatureChannel.cpp +++ b/source/gameengine/Converter/BL_ArmatureChannel.cpp @@ -455,12 +455,12 @@ PyObject *BL_ArmatureBone::py_bone_get_children(void *self, const struct KX_PYAT Bone* bone = reinterpret_cast(self); Bone* child; int count = 0; - for (child=(Bone*)bone->childbase.first; child; child=(Bone*)child->next) + for (child = (Bone *)bone->childbase.first; child; child = child->next) count++; PyObject *childrenlist = PyList_New(count); - for (count = 0, child=(Bone*)bone->childbase.first; child; child=(Bone*)child->next, ++count) + for (count = 0, child = (Bone *)bone->childbase.first; child; child = child->next, ++count) PyList_SET_ITEM(childrenlist,count,NewProxyPlus_Ext(NULL,&Type,child,false)); return childrenlist; diff --git a/source/gameengine/Converter/BL_ArmatureObject.cpp b/source/gameengine/Converter/BL_ArmatureObject.cpp index da73d7a762a..ed97b9ff73f 100644 --- a/source/gameengine/Converter/BL_ArmatureObject.cpp +++ b/source/gameengine/Converter/BL_ArmatureObject.cpp @@ -105,7 +105,7 @@ void game_copy_pose(bPose **dst, bPose *src, int copy_constraint) for (; pchan; pchan=pchan->next, outpchan=outpchan->next) BLI_ghash_insert(ghash, pchan, outpchan); - for (pchan=(bPoseChannel*)out->chanbase.first; pchan; pchan=(bPoseChannel*)pchan->next) { + for (pchan = (bPoseChannel*)out->chanbase.first; pchan; pchan = pchan->next) { pchan->parent= (bPoseChannel*)BLI_ghash_lookup(ghash, pchan->parent); pchan->child= (bPoseChannel*)BLI_ghash_lookup(ghash, pchan->child); @@ -186,7 +186,10 @@ void game_blend_poses(bPose *dst, bPose *src, float srcweight/*, short mode*/) if (schan->rotmode) dchan->eul[i] = (dchan->eul[i]*dstweight) + (schan->eul[i]*srcweight); } - for (dcon= (bConstraint*)dchan->constraints.first, scon= (bConstraint*)schan->constraints.first; dcon && scon; dcon= (bConstraint*)dcon->next, scon= (bConstraint*)scon->next) { + for (dcon= (bConstraint *)dchan->constraints.first, scon= (bConstraint *)schan->constraints.first; + dcon && scon; + dcon = dcon->next, scon = scon->next) + { /* no 'add' option for constraint blending */ dcon->enforce= dcon->enforce*(1.0f-srcweight) + scon->enforce*srcweight; } @@ -282,8 +285,8 @@ void BL_ArmatureObject::LoadConstraints(KX_BlenderSceneConverter* converter) KX_GameObject* gamesubtarget; // and locate the constraint - for (pchan = (bPoseChannel*)m_pose->chanbase.first; pchan; pchan=(bPoseChannel*)pchan->next) { - for (pcon = (bConstraint*)pchan->constraints.first; pcon; pcon=(bConstraint*)pcon->next) { + for (pchan = (bPoseChannel *)m_pose->chanbase.first; pchan; pchan = pchan->next) { + for (pcon = (bConstraint *)pchan->constraints.first; pcon; pcon = pcon->next) { if (pcon->flag & CONSTRAINT_DISABLE) continue; // which constraint should we support? @@ -315,7 +318,7 @@ void BL_ArmatureObject::LoadConstraints(KX_BlenderSceneConverter* converter) } if (target->next != NULL) { // secondary target - target = (bConstraintTarget*)target->next; + target = target->next; if (target->tar && target->tar != m_objArma) { // only track external object blendtarget = target->tar; diff --git a/source/gameengine/Converter/BL_MeshDeformer.h b/source/gameengine/Converter/BL_MeshDeformer.h index 5cea4100b3f..7bee55bd119 100644 --- a/source/gameengine/Converter/BL_MeshDeformer.h +++ b/source/gameengine/Converter/BL_MeshDeformer.h @@ -70,7 +70,7 @@ public: virtual RAS_Deformer* GetReplica() {return NULL;} virtual void ProcessReplica(); struct Mesh* GetMesh() { return m_bmesh; } - virtual class RAS_MeshObject* GetRasMesh() { return (RAS_MeshObject*)m_pMeshObject; } + virtual class RAS_MeshObject* GetRasMesh() { return m_pMeshObject; } virtual float (* GetTransVerts(int *tot))[3] { *tot= m_tvtot; return m_transverts; } // virtual void InitDeform(double time) {} diff --git a/source/gameengine/Converter/BL_ModifierDeformer.cpp b/source/gameengine/Converter/BL_ModifierDeformer.cpp index eafed8497ba..22f62975f2c 100644 --- a/source/gameengine/Converter/BL_ModifierDeformer.cpp +++ b/source/gameengine/Converter/BL_ModifierDeformer.cpp @@ -113,7 +113,7 @@ bool BL_ModifierDeformer::HasCompatibleDeformer(Object *ob) if ((ob->gameflag & OB_SOFT_BODY) != 0) return false; ModifierData* md; - for (md = (ModifierData*)ob->modifiers.first; md; md = (ModifierData*)md->next) { + for (md = (ModifierData *)ob->modifiers.first; md; md = md->next) { if (modifier_dependsOnTime(md)) continue; if (!(md->mode & eModifierMode_Realtime)) diff --git a/source/gameengine/Converter/BL_SkinDeformer.cpp b/source/gameengine/Converter/BL_SkinDeformer.cpp index c175c1e3b7b..2dc6e302f4f 100644 --- a/source/gameengine/Converter/BL_SkinDeformer.cpp +++ b/source/gameengine/Converter/BL_SkinDeformer.cpp @@ -72,7 +72,7 @@ static short get_deformflags(struct Object *bmeshobj) short flags = ARM_DEF_VGROUP; ModifierData *md; - for (md = (ModifierData*)bmeshobj->modifiers.first; md; md = (ModifierData*)md->next) + for (md = (ModifierData *)bmeshobj->modifiers.first; md; md = md->next) { if (md->type == eModifierType_Armature) { @@ -249,7 +249,7 @@ void BL_SkinDeformer::BGEDeformVerts() int i; for (i=0, dg=(bDeformGroup*)m_objMesh->defbase.first; dg; - ++i, dg=(bDeformGroup*)dg->next) + ++i, dg = dg->next) { m_dfnrToPC[i] = BKE_pose_channel_find_name(par_arma->pose, dg->name); diff --git a/source/gameengine/Converter/CMakeLists.txt b/source/gameengine/Converter/CMakeLists.txt index 1826f1ad25b..309017e84b1 100644 --- a/source/gameengine/Converter/CMakeLists.txt +++ b/source/gameengine/Converter/CMakeLists.txt @@ -49,8 +49,6 @@ set(INC ../../blender/makesdna ../../blender/makesrna ../../blender/windowmanager - ../../../extern/bullet2/src - ../../../extern/Eigen3 ../../../intern/container ../../../intern/guardedalloc ../../../intern/moto/include @@ -59,6 +57,7 @@ set(INC ) set(INC_SYS + ../../../extern/Eigen3 ${PTHREADS_INCLUDE_DIRS} ) @@ -110,6 +109,9 @@ set(SRC ) if(WITH_BULLET) + list(APPEND INC_SYS + ../../../extern/bullet2/src + ) add_definitions(-DUSE_BULLET) endif() diff --git a/source/gameengine/Converter/KX_BlenderScalarInterpolator.cpp b/source/gameengine/Converter/KX_BlenderScalarInterpolator.cpp index 72212581d4b..1e1bc738301 100644 --- a/source/gameengine/Converter/KX_BlenderScalarInterpolator.cpp +++ b/source/gameengine/Converter/KX_BlenderScalarInterpolator.cpp @@ -52,7 +52,7 @@ BL_InterpolatorList::BL_InterpolatorList(bAction *action) if (action==NULL) return; - for (FCurve *fcu= (FCurve *)action->curves.first; fcu; fcu= (FCurve *)fcu->next) { + for (FCurve *fcu = (FCurve *)action->curves.first; fcu; fcu = fcu->next) { if (fcu->rna_path) { BL_ScalarInterpolator *new_ipo = new BL_ScalarInterpolator(fcu); //assert(new_ipo); diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.h b/source/gameengine/Converter/KX_BlenderSceneConverter.h index 436bdb555c9..34a1117a0eb 100644 --- a/source/gameengine/Converter/KX_BlenderSceneConverter.h +++ b/source/gameengine/Converter/KX_BlenderSceneConverter.h @@ -165,11 +165,11 @@ public: printf("\t m_materials: %d\n", (int)m_materials.size()); printf("\nMappings...\n"); - printf("\t m_map_blender_to_gameobject: %d\n", (int)m_map_blender_to_gameobject.size()); - printf("\t m_map_mesh_to_gamemesh: %d\n", (int)m_map_mesh_to_gamemesh.size()); - printf("\t m_map_blender_to_gameactuator: %d\n", (int)m_map_blender_to_gameactuator.size()); - printf("\t m_map_blender_to_gamecontroller: %d\n", (int)m_map_blender_to_gamecontroller.size()); - printf("\t m_map_blender_to_gameAdtList: %d\n", (int)m_map_blender_to_gameAdtList.size()); + printf("\t m_map_blender_to_gameobject: %d\n", m_map_blender_to_gameobject.size()); + printf("\t m_map_mesh_to_gamemesh: %d\n", m_map_mesh_to_gamemesh.size()); + printf("\t m_map_blender_to_gameactuator: %d\n", m_map_blender_to_gameactuator.size()); + printf("\t m_map_blender_to_gamecontroller: %d\n", m_map_blender_to_gamecontroller.size()); + printf("\t m_map_blender_to_gameAdtList: %d\n", m_map_blender_to_gameAdtList.size()); #ifdef WITH_CXX_GUARDEDALLOC MEM_printmemlist_pydict(); diff --git a/source/gameengine/Ketsji/CMakeLists.txt b/source/gameengine/Ketsji/CMakeLists.txt index 269311b7e00..b42c2c27075 100644 --- a/source/gameengine/Ketsji/CMakeLists.txt +++ b/source/gameengine/Ketsji/CMakeLists.txt @@ -248,9 +248,11 @@ endif() if(WITH_BULLET) list(APPEND INC - ../../../extern/bullet2/src ../Physics/Bullet ) + list(APPEND INC + ../../../extern/bullet2/src + ) add_definitions(-DUSE_BULLET) endif() diff --git a/source/gameengine/Physics/Bullet/CMakeLists.txt b/source/gameengine/Physics/Bullet/CMakeLists.txt index cdae3cc5526..43b1bfe7468 100644 --- a/source/gameengine/Physics/Bullet/CMakeLists.txt +++ b/source/gameengine/Physics/Bullet/CMakeLists.txt @@ -37,7 +37,6 @@ set(INC ../../../blender/blenkernel ../../../blender/blenlib ../../../blender/makesdna - ../../../../extern/bullet2/src ../../../../intern/container ../../../../intern/guardedalloc ../../../../intern/moto/include @@ -45,6 +44,7 @@ set(INC ) set(INC_SYS + ../../../../extern/bullet2/src ${GLEW_INCLUDE_PATH} ${PYTHON_INCLUDE_DIRS} ) diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.cpp b/source/gameengine/Rasterizer/RAS_MeshObject.cpp index c50aa28e9fc..21d2e6d5a7b 100644 --- a/source/gameengine/Rasterizer/RAS_MeshObject.cpp +++ b/source/gameengine/Rasterizer/RAS_MeshObject.cpp @@ -584,7 +584,7 @@ void RAS_MeshObject::CheckWeightCache(Object* obj) if (!m_mesh->key) return; - for (kbindex=0, kb= (KeyBlock*)m_mesh->key->block.first; kb; kb= (KeyBlock*)kb->next, kbindex++) + for (kbindex = 0, kb = (KeyBlock *)m_mesh->key->block.first; kb; kb = kb->next, kbindex++) { // first check the cases where the weight must be cleared if (kb->vgroup[0] == 0 || From 8e01b8959e65c4ec63433b7ef82130847caa8d39 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 14 Oct 2012 13:08:19 +0000 Subject: [PATCH 219/347] style cleanup --- source/blender/blenkernel/CMakeLists.txt | 2 +- source/blender/blenkernel/intern/armature.c | 8 +++++--- source/blender/blenkernel/intern/boids.c | 10 ++++++---- source/blender/blenkernel/intern/effect.c | 8 +++++--- source/blender/blenkernel/intern/pointcache.c | 5 +++-- source/blender/blenloader/intern/readfile.c | 8 +++++--- source/blender/blenloader/intern/writefile.c | 5 +++-- source/blender/editors/interface/interface.c | 20 +++++++++++-------- .../editors/interface/interface_handlers.c | 4 +++- .../editors/interface/interface_regions.c | 14 ++++++++----- .../editors/space_buttons/buttons_ops.c | 2 +- .../editors/space_outliner/outliner_tools.c | 19 +++++++++++------- .../editors/space_view3d/view3d_select.c | 7 ++++--- source/blender/editors/uvedit/uvedit_ops.c | 12 ++++++----- source/blender/gpu/intern/gpu_material.c | 4 +++- source/blender/makesdna/intern/makesdna.c | 4 +++- source/blender/makesrna/intern/makesrna.c | 11 ++++++---- source/blender/makesrna/intern/rna_access.c | 2 +- source/blender/modifiers/intern/MOD_wave.c | 2 +- .../intern/raytrace/rayobject_octree.cpp | 8 ++++++-- .../render/intern/source/convertblender.c | 8 +++++--- .../windowmanager/intern/wm_event_system.c | 5 +++-- .../Rasterizer/RAS_IPolygonMaterial.cpp | 16 ++++++++++----- 23 files changed, 116 insertions(+), 68 deletions(-) diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index f24b58658f6..d4e7f09b5f1 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -193,8 +193,8 @@ set(SRC BKE_lamp.h BKE_lattice.h BKE_library.h - BKE_mask.h BKE_main.h + BKE_mask.h BKE_material.h BKE_mball.h BKE_mesh.h diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index b87342f85fa..6eb1daa1e4f 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -534,10 +534,12 @@ Mat4 *b_bone_spline_setup(bPoseChannel *pchan, int rest) mul_m4_v3(imat, h2); /* if next bone is B-bone too, use average handle direction */ - if (next->bone->segments > 1) - ; - else + if (next->bone->segments > 1) { + /* pass */ + } + else { h2[1] -= length; + } normalize_v3(h2); /* find the next roll to interpolate as well */ diff --git a/source/blender/blenkernel/intern/boids.c b/source/blender/blenkernel/intern/boids.c index 79d5e092a10..aafc7fe89b4 100644 --- a/source/blender/blenkernel/intern/boids.c +++ b/source/blender/blenkernel/intern/boids.c @@ -101,13 +101,15 @@ static int rule_goal_avoid(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, break; } } - else if (rule->type == eBoidRuleType_Goal && eob == bpa->ground) - ; /* skip current object */ + else if (rule->type == eBoidRuleType_Goal && eob == bpa->ground) { + /* skip current object */ + } else if (pd->forcefield == PFIELD_BOID && mul * pd->f_strength > 0.0f && get_effector_data(cur, &cur_efd, &epoint, 0)) { float temp = mul * pd->f_strength * effector_falloff(cur, &cur_efd, &epoint, bbd->part->effector_weights); - if (temp == 0.0f) - ; /* do nothing */ + if (temp == 0.0f) { + /* do nothing */ + } else if (temp > priority) { priority = temp; eff = cur; diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c index a9571406b7e..7c0b43c24df 100644 --- a/source/blender/blenkernel/intern/effect.c +++ b/source/blender/blenkernel/intern/effect.c @@ -1013,10 +1013,12 @@ void pdDoEffectors(ListBase *effectors, ListBase *colliders, EffectorWeights *we if (efd.falloff > 0.0f) efd.falloff *= eff_calc_visibility(colliders, eff, &efd, point); - if (efd.falloff <= 0.0f) - ; /* don't do anything */ - else if (eff->pd->forcefield == PFIELD_TEXTURE) + if (efd.falloff <= 0.0f) { + /* don't do anything */ + } + else if (eff->pd->forcefield == PFIELD_TEXTURE) { do_texture_effector(eff, &efd, point, force); + } else { float temp1[3]={0, 0, 0}, temp2[3]; copy_v3_v3(temp1, force); diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index 6b90ec88362..84301972ddf 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -3328,8 +3328,9 @@ void BKE_ptcache_load_external(PTCacheID *pid) cache->endframe = end; cache->totpoint = 0; - if (pid->type == PTCACHE_TYPE_SMOKE_DOMAIN) - ; /*necessary info in every file*/ + if (pid->type == PTCACHE_TYPE_SMOKE_DOMAIN) { + /* necessary info in every file */ + } /* read totpoint from info file (frame 0) */ else if (info) { pf= ptcache_file_open(pid, PTCACHE_FILE_READ, 0); diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 1e14eb55dc0..884a6432dda 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -4319,10 +4319,12 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb) if (smd->domain->ptcaches[1].first || smd->domain->point_cache[1]) { if (smd->domain->point_cache[1]) { PointCache *cache = newdataadr(fd, smd->domain->point_cache[1]); - if (cache->flag & PTCACHE_FAKE_SMOKE) - ; /* Smoke was already saved in "new format" and this cache is a fake one. */ - else + if (cache->flag & PTCACHE_FAKE_SMOKE) { + /* Smoke was already saved in "new format" and this cache is a fake one. */ + } + else { printf("High resolution smoke cache not available due to pointcache update. Please reset the simulation.\n"); + } BKE_ptcache_free(cache); } smd->domain->ptcaches[1].first = NULL; diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index a825cf4ef98..b73485add3d 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -730,8 +730,9 @@ static void write_nodetree(WriteData *wd, bNodeTree *ntree) write_curvemapping(wd, node->storage); else if (ntree->type==NTREE_TEXTURE && (node->type==TEX_NODE_CURVE_RGB || node->type==TEX_NODE_CURVE_TIME) ) write_curvemapping(wd, node->storage); - else if (ntree->type==NTREE_COMPOSIT && node->type==CMP_NODE_MOVIEDISTORTION) - /* pass */; + else if (ntree->type==NTREE_COMPOSIT && node->type==CMP_NODE_MOVIEDISTORTION) { + /* pass */ + } else writestruct(wd, DATA, node->typeinfo->storagename, 1, node->storage); } diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index d442ce1b04b..fcde4186778 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -1528,7 +1528,9 @@ void ui_set_but_val(uiBut *but, double value) * so leave this unset */ value = UI_BUT_VALUE_UNSET; } - else if (but->pointype == 0) ; + else if (but->pointype == 0) { + /* pass */ + } else if (but->type == HSVSLI) { float *fp, hsv[3]; @@ -1721,8 +1723,9 @@ void ui_get_but_string(uiBut *but, char *str, size_t maxlen) BLI_strncpy(str, but->poin, maxlen); return; } - else if (ui_but_anim_expression_get(but, str, maxlen)) - ; /* driver expression */ + else if (ui_but_anim_expression_get(but, str, maxlen)) { + /* driver expression */ + } else { /* number editing */ double value; @@ -2480,7 +2483,9 @@ static void ui_block_do_align_but(uiBut *first, short nr) if (rows > 0) { uiBut *bt = but; while (bt && bt->alignnr == nr) { - if (bt->next && bt->next->alignnr == nr && buts_are_horiz(bt, bt->next) == 0) break; + if (bt->next && bt->next->alignnr == nr && buts_are_horiz(bt, bt->next) == 0) { + break; + } bt = bt->next; } if (bt == NULL || bt->alignnr != nr) flag = UI_BUT_ALIGN_TOP | UI_BUT_ALIGN_RIGHT; @@ -2714,9 +2719,8 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, const char *str, } /* keep track of UI_interface.h */ - if (ELEM7(but->type, BLOCK, BUT, LABEL, PULLDOWN, ROUNDBOX, LISTBOX, BUTM)) ; - else if (ELEM(but->type, SCROLL, SEPR /* , FTPREVIEW */ )) ; - else if (but->type >= SEARCH_MENU) ; + if (ELEM9(but->type, BLOCK, BUT, LABEL, PULLDOWN, ROUNDBOX, LISTBOX, BUTM, SCROLL, SEPR /* , FTPREVIEW */)) {} + else if (but->type >= SEARCH_MENU) {} else but->flag |= UI_BUT_UNDO; BLI_addtail(&block->buttons, but); @@ -2750,7 +2754,7 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, const char *str, static uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, const char *str, - int x, int y, short width, short height, + int x, int y, short width, short height, PointerRNA *ptr, PropertyRNA *prop, int index, float min, float max, float a1, float a2, const char *tip) { diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index f798f0b399b..80c15ad7b4b 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -6621,7 +6621,9 @@ static int ui_handle_menu_event(bContext *C, wmEvent *event, uiPopupBlockHandle } } - if (menu->menuretval) ; + if (menu->menuretval) { + /* pass */ + } else if (event->type == ESCKEY && event->val == KM_PRESS) { /* esc cancels this and all preceding menus */ menu->menuretval = UI_RETURN_CANCEL; diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index 4dafb4b2d4b..14cb1cbe85a 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -2674,14 +2674,18 @@ void uiPupMenuReports(bContext *C, ReportList *reports) ds = BLI_dynstr_new(); for (report = reports->list.first; report; report = report->next) { - if (report->type < reports->printlevel) - ; /* pass */ - else if (report->type >= RPT_ERROR) + if (report->type < reports->printlevel) { + /* pass */ + } + else if (report->type >= RPT_ERROR) { BLI_dynstr_appendf(ds, "Error %%i%d%%t|%s", ICON_ERROR, report->message); - else if (report->type >= RPT_WARNING) + } + else if (report->type >= RPT_WARNING) { BLI_dynstr_appendf(ds, "Warning %%i%d%%t|%s", ICON_ERROR, report->message); - else if (report->type >= RPT_INFO) + } + else if (report->type >= RPT_INFO) { BLI_dynstr_appendf(ds, "Info %%i%d%%t|%s", ICON_INFO, report->message); + } } str = BLI_dynstr_get_cstring(ds); diff --git a/source/blender/editors/space_buttons/buttons_ops.c b/source/blender/editors/space_buttons/buttons_ops.c index c8cf69e3e17..9a7284de660 100644 --- a/source/blender/editors/space_buttons/buttons_ops.c +++ b/source/blender/editors/space_buttons/buttons_ops.c @@ -207,7 +207,7 @@ static int file_browse_invoke(bContext *C, wmOperator *op, wmEvent *event) * user-prefs exception - campbell */ if (RNA_struct_find_property(op->ptr, "relative_path")) { if (!RNA_struct_property_is_set(op->ptr, "relative_path")) { - /* annoying exception!, if were dealign with the user prefs, default relative to be off */ + /* annoying exception!, if were dealing with the user prefs, default relative to be off */ RNA_boolean_set(op->ptr, "relative_path", U.flag & USER_RELPATHS && (ptr.data != &U)); } } diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c index 09df1d57b2b..9b689c359bc 100644 --- a/source/blender/editors/space_outliner/outliner_tools.c +++ b/source/blender/editors/space_outliner/outliner_tools.c @@ -1274,12 +1274,15 @@ static int do_outliner_operation_event(bContext *C, Scene *scene, ARegion *ar, S else { if (datalevel == TSE_ANIM_DATA) WM_operator_name_call(C, "OUTLINER_OT_animdata_operation", WM_OP_INVOKE_REGION_WIN, NULL); - else if (datalevel == TSE_DRIVER_BASE) - /* do nothing... no special ops needed yet */; - else if (ELEM3(datalevel, TSE_R_LAYER_BASE, TSE_R_LAYER, TSE_R_PASS)) - /*WM_operator_name_call(C, "OUTLINER_OT_renderdata_operation", WM_OP_INVOKE_REGION_WIN, NULL)*/; - else + else if (datalevel == TSE_DRIVER_BASE) { + /* do nothing... no special ops needed yet */ + } + else if (ELEM3(datalevel, TSE_R_LAYER_BASE, TSE_R_LAYER, TSE_R_PASS)) { + /*WM_operator_name_call(C, "OUTLINER_OT_renderdata_operation", WM_OP_INVOKE_REGION_WIN, NULL)*/ + } + else { WM_operator_name_call(C, "OUTLINER_OT_data_operation", WM_OP_INVOKE_REGION_WIN, NULL); + } } } @@ -1301,11 +1304,13 @@ static int outliner_operation(bContext *C, wmOperator *UNUSED(op), wmEvent *even SpaceOops *soops = CTX_wm_space_outliner(C); TreeElement *te; float fmval[2]; - + UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], fmval, fmval + 1); for (te = soops->tree.first; te; te = te->next) { - if (do_outliner_operation_event(C, scene, ar, soops, te, event, fmval)) break; + if (do_outliner_operation_event(C, scene, ar, soops, te, event, fmval)) { + break; + } } return OPERATOR_FINISHED; diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index 9fd7cfafae0..c30adf844a8 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -888,9 +888,10 @@ static void view3d_lasso_select(bContext *C, ViewContext *vc, do_lasso_select_paintface(vc, mcords, moves, extend, select); else if (paint_vertsel_test(ob)) do_lasso_select_paintvert(vc, mcords, moves, extend, select); - else if (ob && ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT)) - ; - else if (ob && ob->mode & OB_MODE_PARTICLE_EDIT) + else if (ob && (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT))) { + /* pass */ + } + else if (ob && (ob->mode & OB_MODE_PARTICLE_EDIT)) PE_lasso_select(C, mcords, moves, extend, select); else { do_lasso_select_objects(vc, mcords, moves, extend, select); diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c index e5826435197..6b69fc53162 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -772,13 +772,15 @@ static int nearest_uv_between(BMEditMesh *em, BMFace *efa, int UNUSED(nverts), i BM_ITER_ELEM (l, &iter, efa, BM_LOOPS_OF_FACE) { luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); - if (i == id1) + if (i == id1) { uv1 = luv->uv; - else if (i == id) - ; /* uv2 = luv->uv; */ /* UNUSED */ - else if (i == id2) + } + else if (i == id) { + /* uv2 = luv->uv; */ /* UNUSED */ + } + else if (i == id2) { uv3 = luv->uv; - + } i++; } diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index e035f1c3f5a..e5f08d38ce8 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -780,7 +780,9 @@ static void shade_one_light(GPUShadeInput *shi, GPUShadeResult *shr, GPULamp *la } } - if (mat->scene->gm.flag & GAME_GLSL_NO_SHADERS); + if (mat->scene->gm.flag & GAME_GLSL_NO_SHADERS) { + /* pass */ + } else if (!(lamp->mode & LA_NO_SPEC) && !(lamp->mode & LA_ONLYSHADOW) && (GPU_link_changed(shi->spec) || ma->spec != 0.0f)) { diff --git a/source/blender/makesdna/intern/makesdna.c b/source/blender/makesdna/intern/makesdna.c index 079f2768352..674a7d7a2fe 100644 --- a/source/blender/makesdna/intern/makesdna.c +++ b/source/blender/makesdna/intern/makesdna.c @@ -1094,7 +1094,9 @@ static int make_structDNA(char *baseDirectory, FILE *file) int a; fp = fopen("padding.c", "w"); - if (fp == NULL) ; + if (fp == NULL) { + /* pass */ + } else { /* add all include files defined in the global array */ diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c index 14c996800fc..fb4e739b8ab 100644 --- a/source/blender/makesrna/intern/makesrna.c +++ b/source/blender/makesrna/intern/makesrna.c @@ -1102,8 +1102,8 @@ static char *rna_def_property_lookup_int_func(FILE *f, StructRNA *srna, Property return NULL; /* only supported in case of standard next functions */ - if (strcmp(nextfunc, "rna_iterator_array_next") == 0) ; - else if (strcmp(nextfunc, "rna_iterator_listbase_next") == 0) ; + if (strcmp(nextfunc, "rna_iterator_array_next") == 0) {} + else if (strcmp(nextfunc, "rna_iterator_listbase_next") == 0) {} else return NULL; } @@ -1372,9 +1372,12 @@ static void rna_def_property_funcs(FILE *f, StructRNA *srna, PropertyDefRNA *dp) CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)prop; const char *nextfunc = (const char *)cprop->next; - if (dp->dnatype && strcmp(dp->dnatype, "ListBase") == 0) ; - else if (dp->dnalengthname || dp->dnalengthfixed) + if (dp->dnatype && strcmp(dp->dnatype, "ListBase") == 0) { + /* pass */ + } + else if (dp->dnalengthname || dp->dnalengthfixed) { cprop->length = (void *)rna_def_property_length_func(f, srna, prop, dp, (const char *)cprop->length); + } /* test if we can allow raw array access, if it is using our standard * array get/next function, we can be sure it is an actual array */ diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index c88944b4584..090fda15725 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -3606,7 +3606,7 @@ static char *rna_path_token(const char **path, char *fixedbuf, int fixedlen, int /* copy string, taking into account escaped ] */ if (bracket) { for (p = *path, i = 0, j = 0; i < len; i++, p++) { - if (*p == '\\' && *(p + 1) == quote) ; + if (*p == '\\' && *(p + 1) == quote) {} else buf[j++] = *p; } diff --git a/source/blender/modifiers/intern/MOD_wave.c b/source/blender/modifiers/intern/MOD_wave.c index 440d2c157fe..b713f56a4c2 100644 --- a/source/blender/modifiers/intern/MOD_wave.c +++ b/source/blender/modifiers/intern/MOD_wave.c @@ -186,7 +186,7 @@ static void waveModifier_do(WaveModifierData *md, const float falloff = wmd->falloff; float falloff_fac = 1.0f; /* when falloff == 0.0f this stays at 1.0f */ - if (wmd->flag & MOD_WAVE_NORM && ob->type == OB_MESH) + if ((wmd->flag & MOD_WAVE_NORM) && (ob->type == OB_MESH)) mvert = dm->getVertArray(dm); if (wmd->objectcenter) { diff --git a/source/blender/render/intern/raytrace/rayobject_octree.cpp b/source/blender/render/intern/raytrace/rayobject_octree.cpp index 5ae716ac942..77e9dc9d8fd 100644 --- a/source/blender/render/intern/raytrace/rayobject_octree.cpp +++ b/source/blender/render/intern/raytrace/rayobject_octree.cpp @@ -382,8 +382,12 @@ static void d2dda(Octree *oc, short b1, short b2, short c1, short c2, char *ocfa while (TRUE) { - if (x < 0 || y < 0 || x >= oc->ocres || y >= oc->ocres) ; - else ocface[oc->ocres * x + y] = 1; + if (x < 0 || y < 0 || x >= oc->ocres || y >= oc->ocres) { + /* pass*/ + } + else { + ocface[oc->ocres * x + y] = 1; + } labdao = labda; if (labdax == labday) { diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index 46ab3aeb21f..f23bc44d21f 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -4712,10 +4712,12 @@ void RE_Database_Free(Render *re) static int allow_render_object(Render *re, Object *ob, int nolamps, int onlyselected, Object *actob) { /* override not showing object when duplis are used with particles */ - if (ob->transflag & OB_DUPLIPARTS) - ; /* let particle system(s) handle showing vs. not showing */ - else if ((ob->transflag & OB_DUPLI) && !(ob->transflag & OB_DUPLIFRAMES)) + if (ob->transflag & OB_DUPLIPARTS) { + /* pass */ /* let particle system(s) handle showing vs. not showing */ + } + else if ((ob->transflag & OB_DUPLI) && !(ob->transflag & OB_DUPLIFRAMES)) { return 0; + } /* don't add non-basic meta objects, ends up having renderobjects with no geometry */ if (ob->type == OB_MBALL && ob!=BKE_mball_basis_find(re->scene, ob)) diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index ef9e25e0fef..8114eb651fb 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -887,8 +887,9 @@ static int wm_operator_invoke(bContext *C, wmOperatorType *ot, wmEvent *event, wm_operator_reports(C, op, retval, (reports != NULL)); } - if (retval & OPERATOR_HANDLED) - ; /* do nothing, wm_operator_exec() has been called somewhere */ + if (retval & OPERATOR_HANDLED) { + /* do nothing, wm_operator_exec() has been called somewhere */ + } else if (retval & OPERATOR_FINISHED) { if (!is_nested_call) { /* not called by py script */ WM_operator_last_properties_store(op); diff --git a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp index 4af1753c2da..ddadd97b567 100644 --- a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp +++ b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp @@ -254,12 +254,18 @@ bool RAS_IPolyMaterial::UsesLighting(RAS_IRasterizer *rasty) const { bool dolights = false; - if (m_flag & RAS_BLENDERMAT) - dolights = (m_flag &RAS_MULTILIGHT)!=0; - else if (rasty->GetDrawingMode() < RAS_IRasterizer::KX_SOLID); - else if (rasty->GetDrawingMode() == RAS_IRasterizer::KX_SHADOW); - else + if (m_flag & RAS_BLENDERMAT) { + dolights = (m_flag & RAS_MULTILIGHT) != 0; + } + else if (rasty->GetDrawingMode() < RAS_IRasterizer::KX_SOLID) { + /* pass */ + } + else if (rasty->GetDrawingMode() == RAS_IRasterizer::KX_SHADOW) { + /* pass */ + } + else { dolights = m_light; + } return dolights; } From 76d0ae0b3ebab1aee6afadc5f791ff85c3d2adec Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 14 Oct 2012 13:18:32 +0000 Subject: [PATCH 220/347] fix for incorrect initial boundbox with svbvh raytracing. (bad use of FLT_MIN) --- source/blender/render/intern/raytrace/svbvh.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/render/intern/raytrace/svbvh.h b/source/blender/render/intern/raytrace/svbvh.h index 2f4a337f0f9..4fdf3ac23e8 100644 --- a/source/blender/render/intern/raytrace/svbvh.h +++ b/source/blender/render/intern/raytrace/svbvh.h @@ -230,7 +230,7 @@ struct Reorganize_SVBVH { return node; } - void copy_bb(float *bb, const float *old_bb) + void copy_bb(float bb[6], const float old_bb[6]) { std::copy(old_bb, old_bb + 6, bb); } @@ -281,7 +281,7 @@ struct Reorganize_SVBVH { useless_bb += alloc_childs - nchilds; while (alloc_childs > nchilds) { - const static float def_bb[6] = { FLT_MAX, FLT_MAX, FLT_MAX, FLT_MIN, FLT_MIN, FLT_MIN }; + const static float def_bb[6] = {FLT_MAX, FLT_MAX, FLT_MAX, -FLT_MAX, -FLT_MAX, -FLT_MAX}; alloc_childs--; node->child[alloc_childs] = NULL; copy_bb(node->child_bb + alloc_childs * 6, def_bb); From 459a2b38e0e8a7e36032f0f691d9ea515971e4e5 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 14 Oct 2012 13:21:40 +0000 Subject: [PATCH 221/347] correct another misuse of FLT_MIN --- source/blender/makesrna/intern/rna_access.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index 090fda15725..7e832455618 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -996,7 +996,7 @@ void RNA_property_float_range(PointerRNA *ptr, PropertyRNA *prop, float *hardmin IDProperty *item; item = IDP_GetPropertyTypeFromGroup(idp_ui, "min", IDP_DOUBLE); - *hardmin = item ? (float)IDP_Double(item) : FLT_MIN; + *hardmin = item ? (float)IDP_Double(item) : -FLT_MAX; item = IDP_GetPropertyTypeFromGroup(idp_ui, "max", IDP_DOUBLE); *hardmax = item ? (float)IDP_Double(item) : FLT_MAX; From 7b8dc4be0d6eb68f6bf8439993aa0421112188cf Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Sun, 14 Oct 2012 14:18:30 +0000 Subject: [PATCH 222/347] Few minor fixes to i18n tools (mostly use ordered dicts too for "xgettexted" messages...). --- .../modules/bl_i18n_utils/update_pot.py | 36 ++++++++++--------- .../scripts/modules/bl_i18n_utils/utils.py | 8 +++-- 2 files changed, 25 insertions(+), 19 deletions(-) diff --git a/release/scripts/modules/bl_i18n_utils/update_pot.py b/release/scripts/modules/bl_i18n_utils/update_pot.py index f98fc5d7705..6a7efddda6c 100755 --- a/release/scripts/modules/bl_i18n_utils/update_pot.py +++ b/release/scripts/modules/bl_i18n_utils/update_pot.py @@ -117,28 +117,30 @@ def check_file(path, rel_path, messages): def py_xgettext(messages): + forbidden = set() + forced = set() with open(SRC_POTFILES) as src: - forbidden = set() - forced = set() for l in src: if l[0] == '-': forbidden.add(l[1:].rstrip('\n')) elif l[0] != '#': forced.add(l.rstrip('\n')) - for root, dirs, files in os.walk(POTFILES_DIR): - if "/.svn" in root: + for root, dirs, files in os.walk(POTFILES_DIR): + if "/.svn" in root: + continue + for fname in files: + if os.path.splitext(fname)[1] not in PYGETTEXT_ALLOWED_EXTS: continue - for fname in files: - if os.path.splitext(fname)[1] not in PYGETTEXT_ALLOWED_EXTS: - continue - path = os.path.join(root, fname) - rel_path = os.path.relpath(path, SOURCE_DIR) - if rel_path in forbidden | forced: - continue - check_file(path, rel_path, messages) - for path in forced: - if os.path.exists(path): - check_file(os.path.join(SOURCE_DIR, path), path, messages) + path = os.path.join(root, fname) + rel_path = os.path.relpath(path, SOURCE_DIR) + if rel_path in forbidden: + continue + elif rel_path in forced: + forced.remove(rel_path) + check_file(path, rel_path, messages) + for path in forced: + if os.path.exists(path): + check_file(os.path.join(SOURCE_DIR, path), path, messages) # Spell checking! @@ -250,7 +252,7 @@ def main(): print("Running fake py gettext…") # Not using any more xgettext, simpler to do it ourself! - messages = {} + messages = utils.new_messages() py_xgettext(messages) print("Finished, found {} messages.".format(len(messages))) @@ -268,7 +270,7 @@ def main(): # add messages collected automatically from RNA print("\tMerging RNA messages from {}…".format(FILE_NAME_MESSAGES)) - messages = {} + messages = utils.new_messages() with open(FILE_NAME_MESSAGES, encoding="utf-8") as f: srcs = [] context = "" diff --git a/release/scripts/modules/bl_i18n_utils/utils.py b/release/scripts/modules/bl_i18n_utils/utils.py index 25b9daa99e5..9481f750092 100644 --- a/release/scripts/modules/bl_i18n_utils/utils.py +++ b/release/scripts/modules/bl_i18n_utils/utils.py @@ -41,6 +41,10 @@ def is_tooltip(msgid): return len(msgid) > 30 +def new_messages(): + return getattr(collections, 'OrderedDict', dict)() + + def parse_messages(fname): """ Returns a tupple (messages, states, stats). @@ -78,7 +82,7 @@ def parse_messages(fname): msgctxt_lines = [] comment_lines = [] - messages = getattr(collections, 'OrderedDict', dict)() + messages = new_messages() translated_messages = set() fuzzy_messages = set() commented_messages = set() @@ -282,7 +286,7 @@ def gen_empty_messages(blender_rev, time_str, year_str): """Generate an empty messages & state data (only header if present!).""" header_key = ("", "") - messages = getattr(collections, 'OrderedDict', dict)() + messages = new_messages() messages[header_key] = { "msgid_lines": [""], "msgctxt_lines": [], From b7f4c69ef72a0aba489153541d3747ff6ef3b72a Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Sun, 14 Oct 2012 15:29:09 +0000 Subject: [PATCH 223/347] More UI messages and BKE_reportf->BKE_report fixes... --- .../blender/editors/interface/interface_ops.c | 18 +++++++----------- source/blender/editors/mesh/editmesh_rip.c | 2 +- source/blender/editors/object/object_bake.c | 2 +- source/blender/editors/object/object_hook.c | 2 +- .../blender/editors/object/object_transform.c | 7 ++++--- source/blender/editors/object/object_vgroup.c | 8 ++++---- source/blender/editors/space_image/image_ops.c | 2 +- .../editors/space_sequencer/sequencer_edit.c | 2 +- source/blender/python/intern/bpy_util.c | 8 +++++--- 9 files changed, 25 insertions(+), 26 deletions(-) diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c index f9a325944e4..017ffdcfb14 100644 --- a/source/blender/editors/interface/interface_ops.c +++ b/source/blender/editors/interface/interface_ops.c @@ -807,8 +807,7 @@ static int editsource_text_edit(bContext *C, wmOperator *op, } if (text == NULL) { - BKE_reportf(op->reports, RPT_WARNING, - "File: '%s' can't be opened", filepath); + BKE_reportf(op->reports, RPT_WARNING, "File: '%s' can't be opened", filepath); return OPERATOR_CANCELLED; } else { @@ -820,8 +819,7 @@ static int editsource_text_edit(bContext *C, wmOperator *op, st->text = text; } else { - BKE_reportf(op->reports, RPT_INFO, - "See '%s' in the text editor", text->id.name + 2); + BKE_reportf(op->reports, RPT_INFO, "See '%s' in the text editor", text->id.name + 2); } txt_move_toline(text, line - 1, FALSE); @@ -872,14 +870,12 @@ static int editsource_exec(bContext *C, wmOperator *op) but_store->py_dbg_ln); } else { - BKE_report(op->reports, RPT_ERROR, - "Active button isn't from a script, cant edit source."); + BKE_report(op->reports, RPT_ERROR, "Active button isn't from a script, cant edit source"); ret = OPERATOR_CANCELLED; } } else { - BKE_report(op->reports, RPT_ERROR, - "Active button match can't be found."); + BKE_report(op->reports, RPT_ERROR, "Active button match can't be found"); ret = OPERATOR_CANCELLED; } @@ -978,19 +974,19 @@ static int edittranslation_exec(bContext *C, wmOperator *op) if (!BLI_is_dir(root)) { BKE_report(op->reports, RPT_ERROR, "Please set your User Preferences' \"Translation Branches " - "Directory\" path to a valid directory."); + "Directory\" path to a valid directory"); return OPERATOR_CANCELLED; } if (!WM_operatortype_find(EDTSRC_I18N_OP_NAME, 0)) { BKE_reportf(op->reports, RPT_ERROR, "Could not find operator \"%s\"! Please enable ui_translate addon " - "in the User Preferences.", EDTSRC_I18N_OP_NAME); + "in the User Preferences", EDTSRC_I18N_OP_NAME); return OPERATOR_CANCELLED; } /* Try to find a valid po file for current language... */ edittranslation_find_po_file(root, uilng, popath, FILE_MAX); /* printf("po path: %s\n", popath);*/ if (popath[0] == '\0') { - BKE_reportf(op->reports, RPT_ERROR, "No valid po found for language '%s' under %s.", uilng, root); + BKE_reportf(op->reports, RPT_ERROR, "No valid po found for language '%s' under %s", uilng, root); return OPERATOR_CANCELLED; } diff --git a/source/blender/editors/mesh/editmesh_rip.c b/source/blender/editors/mesh/editmesh_rip.c index b8b8cd2aa4e..b5dfc070d71 100644 --- a/source/blender/editors/mesh/editmesh_rip.c +++ b/source/blender/editors/mesh/editmesh_rip.c @@ -1062,5 +1062,5 @@ void MESH_OT_rip(wmOperatorType *ot) /* to give to transform */ Transform_Properties(ot, P_PROPORTIONAL); RNA_def_boolean(ot->srna, "mirror", FALSE, "Mirror Editing", ""); - RNA_def_boolean(ot->srna, "use_fill", FALSE, "Fill", "Fille the ripped region"); + RNA_def_boolean(ot->srna, "use_fill", FALSE, "Fill", "Fill the ripped region"); } diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c index 9af0eda880a..bc5d289d04c 100644 --- a/source/blender/editors/object/object_bake.c +++ b/source/blender/editors/object/object_bake.c @@ -937,7 +937,7 @@ static int multiresbake_check(bContext *C, wmOperator *op) ob = base->object; if (ob->type != OB_MESH) { - BKE_report(op->reports, RPT_ERROR, "Basking of multires data only works with active object which is a mesh"); + BKE_report(op->reports, RPT_ERROR, "Baking of multires data only works with an active mesh object"); ok = 0; break; diff --git a/source/blender/editors/object/object_hook.c b/source/blender/editors/object/object_hook.c index a6afe6b2d04..8bc249974f2 100644 --- a/source/blender/editors/object/object_hook.c +++ b/source/blender/editors/object/object_hook.c @@ -442,7 +442,7 @@ static int add_hook_object(Main *bmain, Scene *scene, Object *obedit, Object *ob ok = object_hook_index_array(scene, obedit, &tot, &indexar, name, cent); if (!ok) { - BKE_report(reports, RPT_ERROR, "Requires selected vertices or active Vertex Group"); + BKE_report(reports, RPT_ERROR, "Requires selected vertices or active vertex group"); return FALSE; } diff --git a/source/blender/editors/object/object_transform.c b/source/blender/editors/object/object_transform.c index 3b508f1d3c6..4c95884a51a 100644 --- a/source/blender/editors/object/object_transform.c +++ b/source/blender/editors/object/object_transform.c @@ -417,7 +417,8 @@ static int apply_objects_internal(bContext *C, ReportList *reports, int apply_lo cu = ob->data; if (!(cu->flag & CU_3D) && (apply_rot || apply_loc)) { - BKE_report(reports, RPT_ERROR, "Neither rotation nor location could be applied to a 2d curve, doing nothing"); + BKE_report(reports, RPT_ERROR, + "Neither rotation nor location could be applied to a 2D curve, doing nothing"); change = 0; } if (cu->key) { @@ -961,9 +962,9 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) /* Warn if any errors occurred */ if (tot_lib_error + tot_multiuser_arm_error) { - BKE_reportf(op->reports, RPT_WARNING, "%i Object(s) Not Centered, %i Changed:", tot_lib_error + tot_multiuser_arm_error, tot_change); + BKE_reportf(op->reports, RPT_WARNING, "%i object(s) not centered, %i changed:", tot_lib_error + tot_multiuser_arm_error, tot_change); if (tot_lib_error) - BKE_reportf(op->reports, RPT_WARNING, "|%i linked library objects", tot_lib_error); + BKE_reportf(op->reports, RPT_WARNING, "|%i linked library object(s)", tot_lib_error); if (tot_multiuser_arm_error) BKE_reportf(op->reports, RPT_WARNING, "|%i multiuser armature object(s)", tot_multiuser_arm_error); } diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 95be54814f0..1be09847ef2 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -482,7 +482,7 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou /* sanity check */ if (!me_src->dvert) { - BKE_reportf(op->reports, RPT_ERROR, "Transfer failed. Source mesh does not have any vertex groups"); + BKE_report(op->reports, RPT_ERROR, "Transfer failed (source mesh does not have any vertex groups)"); return 0; } @@ -528,7 +528,7 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou if (dv_array_src) MEM_freeN(dv_array_src); if (dv_array_dst) MEM_freeN(dv_array_dst); dmesh_src->release(dmesh_src); - BKE_reportf(op->reports, RPT_ERROR, "Transfer failed. Indices are not matching"); + BKE_report(op->reports, RPT_ERROR, "Transfer failed (indices are not matching)"); return 0; } @@ -3126,7 +3126,7 @@ static int vertex_group_limit_total_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } else { - BKE_reportf(op->reports, RPT_WARNING, "No vertex groups limited"); + BKE_report(op->reports, RPT_WARNING, "No vertex groups limited"); /* note, would normally return cancelled, except we want the redo * UI to show up for users to change */ @@ -3248,7 +3248,7 @@ static int vertex_group_copy_to_selected_exec(bContext *C, wmOperator *op) if ((change == 0 && fail == 0) || fail) { BKE_reportf(op->reports, RPT_ERROR, - "Copy to VGroups to Selected warning done %d, failed %d, object data must have matching indices", + "Copy VGroups to Selected warning, %d done, %d failed (object data must have matching indices)", change, fail); } diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index a66e6d6a6b8..4793f995d98 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -1558,7 +1558,7 @@ static int image_save_sequence_exec(bContext *C, wmOperator *op) BLI_strncpy(di, ibuf->name, FILE_MAX); BLI_splitdirstring(di, fi); - BKE_reportf(op->reports, RPT_INFO, "%d Image(s) will be saved in %s", tot, di); + BKE_reportf(op->reports, RPT_INFO, "%d image(s) will be saved in %s", tot, di); for (ibuf = sima->image->ibufs.first; ibuf; ibuf = ibuf->next) { if (ibuf->userflags & IB_BITMAPDIRTY) { diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index 0bce990788a..82d08be4da2 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -2742,7 +2742,7 @@ static int sequencer_swap_data_exec(bContext *C, wmOperator *op) const char *error_msg; if (BKE_sequencer_active_get_pair(scene, &seq_act, &seq_other) == 0) { - BKE_report(op->reports, RPT_ERROR, "Must select 2 strips"); + BKE_report(op->reports, RPT_ERROR, "Please select two strips"); return OPERATOR_CANCELLED; } diff --git a/source/blender/python/intern/bpy_util.c b/source/blender/python/intern/bpy_util.c index 53d0e10a01e..6c61d7540ab 100644 --- a/source/blender/python/intern/bpy_util.c +++ b/source/blender/python/intern/bpy_util.c @@ -35,6 +35,8 @@ #include "BKE_report.h" #include "BKE_context.h" +#include "BLF_translation.h" + #include "../generic/py_capi_utils.h" static bContext *__py_context = NULL; @@ -98,7 +100,7 @@ short BPy_errors_to_report(ReportList *reports) pystring = PyC_ExceptionBuffer(); if (pystring == NULL) { - BKE_report(reports, RPT_ERROR, "unknown py-exception, couldn't convert"); + BKE_report(reports, RPT_ERROR, "Unknown py-exception, couldn't convert"); return 0; } @@ -111,12 +113,12 @@ short BPy_errors_to_report(ReportList *reports) #if 0 // ARG!. workaround for a bug in blenders use of vsnprintf BKE_reportf(reports, RPT_ERROR, "%s\nlocation:%s:%d\n", cstring, filename, lineno); #else - pystring_format = PyUnicode_FromFormat("%s\nlocation:%s:%d\n", cstring, filename, lineno); + pystring_format = PyUnicode_FromFormat(TIP_("%s\nlocation:%s:%d\n"), cstring, filename, lineno); cstring = _PyUnicode_AsString(pystring_format); BKE_report(reports, RPT_ERROR, cstring); #endif - fprintf(stderr, "%s\nlocation:%s:%d\n", cstring, filename, lineno); // not exactly needed. just for testing + fprintf(stderr, TIP_("%s\nlocation:%s:%d\n"), cstring, filename, lineno); // not exactly needed. just for testing Py_DECREF(pystring); Py_DECREF(pystring_format); // workaround From 36c53ec9c3450f250fe8ab9e351a53455792498c Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Sun, 14 Oct 2012 19:38:27 +0000 Subject: [PATCH 224/347] Adding Estonian new language. --- source/blender/blenfont/intern/blf_lang.c | 1 + source/blender/makesrna/intern/rna_userdef.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/source/blender/blenfont/intern/blf_lang.c b/source/blender/blenfont/intern/blf_lang.c index b694f1fafa7..1a1eff6a48c 100644 --- a/source/blender/blenfont/intern/blf_lang.c +++ b/source/blender/blenfont/intern/blf_lang.c @@ -109,6 +109,7 @@ static const char *locales[] = { "hungarian", "hu_HU", "portuguese-brazilian", "pt_BR", "hebrew", "he_IL", + "estonian", "et_EE", }; void BLF_lang_init(void) diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index e1cf7a13f59..98045137c43 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -2987,7 +2987,7 @@ static void rna_def_userdef_system(BlenderRNA *brna) /* locale according to http://www.roseindia.net/tutorials/I18N/locales-list.shtml */ /* if you edit here, please also edit the source/blender/blenfont/intern/blf_lang.c 's locales */ /* Note: As this list is in alphabetical order, and not defined order, - * here is the highest define currently in use: 33 (Hebrew). */ + * here is the highest define currently in use: 34 (Estonian). */ static EnumPropertyItem language_items[] = { { 0, "", 0, N_("Nearly Done"), ""}, { 0, "DEFAULT", 0, "Default (Default)", ""}, @@ -3010,6 +3010,7 @@ static void rna_def_userdef_system(BlenderRNA *brna) {16, "CROATIAN", 0, "Croatian (Hrvatski)", "hr_HR"}, {11, "CZECH", 0, "Czech (Český)", "cs_CZ"}, { 3, "DUTCH", 0, "Dutch (Nederlandse taal)", "nl_NL"}, + {34, "ESTONIAN", 0, "Estonian (Eestlane)", "et_EE"}, { 6, "FINNISH", 0, "Finnish (Suomi)", "fi_FI"}, { 5, "GERMAN", 0, "German (Deutsch)", "de_DE"}, {23, "GREEK", 0, "Greek (Ελληνικά)", "el_GR"}, From 1086069fb32acab7267192b1a2995440e6f4697f Mon Sep 17 00:00:00 2001 From: "Sv. Lockal" Date: Sun, 14 Oct 2012 19:57:49 +0000 Subject: [PATCH 225/347] Fix for misplaced cursor in wrapped console prompt, also fixes newline for single wrap when input line width equals console width --- source/blender/editors/space_console/console_draw.c | 13 ++++++++----- source/blender/editors/space_info/textview.c | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/source/blender/editors/space_console/console_draw.c b/source/blender/editors/space_console/console_draw.c index 4c2f0ac73d4..c4a5c2a0154 100644 --- a/source/blender/editors/space_console/console_draw.c +++ b/source/blender/editors/space_console/console_draw.c @@ -94,12 +94,14 @@ void console_scrollback_prompt_begin(struct SpaceConsole *sc, ConsoleLine *cl_du { /* fake the edit line being in the scroll buffer */ ConsoleLine *cl = sc->history.last; + int prompt_len = strlen(sc->prompt); + cl_dummy->type = CONSOLE_LINE_INPUT; - cl_dummy->len = cl_dummy->len_alloc = strlen(sc->prompt) + cl->len; + cl_dummy->len = prompt_len + cl->len; cl_dummy->len_alloc = cl_dummy->len + 1; cl_dummy->line = MEM_mallocN(cl_dummy->len_alloc, "cl_dummy"); - memcpy(cl_dummy->line, sc->prompt, (cl_dummy->len_alloc - cl->len)); - memcpy(cl_dummy->line + ((cl_dummy->len_alloc - cl->len)) - 1, cl->line, cl->len + 1); + memcpy(cl_dummy->line, sc->prompt, prompt_len); + memcpy(cl_dummy->line + prompt_len, cl->line, cl->len + 1); BLI_addtail(&sc->scrollback, cl_dummy); } void console_scrollback_prompt_end(struct SpaceConsole *sc, ConsoleLine *cl_dummy) @@ -158,12 +160,13 @@ static int console_textview_line_color(struct TextViewContext *tvc, unsigned cha const ConsoleLine *cl = (ConsoleLine *)sc->history.last; const int prompt_len = strlen(sc->prompt); const int cursor_loc = cl->cursor + prompt_len; + const int line_len = cl->len + prompt_len; int xy[2] = {CONSOLE_DRAW_MARGIN, CONSOLE_DRAW_MARGIN}; int pen[2]; xy[1] += tvc->lheight / 6; /* account for wrapping */ - if (cl->len < tvc->console_width) { + if (line_len < tvc->console_width) { /* simple case, no wrapping */ pen[0] = tvc->cwidth * cursor_loc; pen[1] = -2; @@ -171,7 +174,7 @@ static int console_textview_line_color(struct TextViewContext *tvc, unsigned cha else { /* wrap */ pen[0] = tvc->cwidth * (cursor_loc % tvc->console_width); - pen[1] = -2 + (((cl->len / tvc->console_width) - (cursor_loc / tvc->console_width)) * tvc->lheight); + pen[1] = -2 + (((line_len / tvc->console_width) - (cursor_loc / tvc->console_width)) * tvc->lheight); } /* cursor */ diff --git a/source/blender/editors/space_info/textview.c b/source/blender/editors/space_info/textview.c index 4ba196276da..cfab2542756 100644 --- a/source/blender/editors/space_info/textview.c +++ b/source/blender/editors/space_info/textview.c @@ -128,7 +128,7 @@ static int console_draw_string(ConsoleDrawContext *cdc, const char *str, int str return 1; } - if (str_len > cdc->console_width) { /* wrap? */ + if (tot_lines > 1) { /* wrap? */ const int initial_offset = ((tot_lines - 1) * cdc->console_width); const char *line_stride = str + initial_offset; /* advance to the last line and draw it first */ From 18bf8993f756f1dfcc83b185811a0f0c1f827d75 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 14 Oct 2012 21:27:08 +0000 Subject: [PATCH 226/347] fix for py-console ctrl+backspace/del changing the selection. --- source/blender/editors/space_console/console_ops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/space_console/console_ops.c b/source/blender/editors/space_console/console_ops.c index 7efcbcceb3c..ecd9e316cef 100644 --- a/source/blender/editors/space_console/console_ops.c +++ b/source/blender/editors/space_console/console_ops.c @@ -580,7 +580,7 @@ static int console_delete_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } else { - console_select_offset(sc, -1); + console_select_offset(sc, -stride); } console_textview_update_rect(sc, ar); From 977aaeb95c2946f2c8d83dd6a15979424a869eda Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Mon, 15 Oct 2012 02:01:39 +0000 Subject: [PATCH 227/347] Streamlinining Bone Groups menu (Ctrl G) The Ctrl-G menu for managing Bone Groups has always been a bit clunky, especially when compared to the Hooks menu (Ctrl-H). This was because the old menu was more data-orientated (Bone Group Management, Membership to these groups) whereas this new arrangement should be a bit more task-orientated (Add to new group, Add to active group, Remove from all groups, Remove active group). --- release/scripts/startup/bl_ui/space_view3d.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index e7ad1c5ff37..f0ee965aa54 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -1530,13 +1530,20 @@ class VIEW3D_MT_pose_group(Menu): def draw(self, context): layout = self.layout - layout.operator("pose.group_add") - layout.operator("pose.group_remove") + + pose = context.active_object.pose - layout.separator() + layout.operator_context = 'EXEC_AREA' + layout.operator("pose.group_assign", text="Assign to New Group").type = 0 + if pose.bone_groups: + active_group = pose.bone_groups.active_index + 1 + layout.operator("pose.group_assign", text="Assign to Group").type = active_group - layout.operator("pose.group_assign") - layout.operator("pose.group_unassign") + layout.separator() + + #layout.operator_context = 'INVOKE_AREA' + layout.operator("pose.group_unassign") + layout.operator("pose.group_remove") class VIEW3D_MT_pose_ik(Menu): From 4d4664d98f49cfb171a43bd6ae6bb002b5f3c34b Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 15 Oct 2012 02:15:07 +0000 Subject: [PATCH 228/347] code cleanup: check for msvc directly when using warning pragma's. --- intern/ghost/GHOST_Types.h | 2 +- intern/ghost/intern/GHOST_Debug.h | 4 +- intern/ghost/test/multitest/MultiTest.c | 5 +- release/windows/contrib/vfapi/vfapi-plugin.c | 21 +++---- source/blender/blenlib/intern/freetypefont.c | 4 +- source/blender/blenlib/intern/noise.c | 6 +- source/blender/blenlib/intern/rand.c | 2 +- source/blender/blenloader/intern/writefile.c | 7 ++- .../BlenderRoutines/BL_KetsjiEmbedStart.cpp | 52 ++++++++--------- .../BlenderRoutines/KX_BlenderInputDevice.h | 4 +- .../KX_BlenderKeyboardDevice.cpp | 6 +- .../BlenderRoutines/KX_BlenderMouseDevice.cpp | 7 +-- .../BlenderRoutines/KX_BlenderRenderTools.h | 6 +- .../BlenderRoutines/KX_BlenderSystem.cpp | 6 +- .../Converter/BL_ArmatureActuator.h | 14 ++--- .../Converter/BL_BlenderDataConversion.cpp | 4 +- .../Converter/BL_DeformableGameObject.h | 6 +- .../gameengine/Converter/BL_MeshDeformer.cpp | 9 ++- source/gameengine/Converter/BL_MeshDeformer.h | 6 +- .../Converter/BL_ModifierDeformer.cpp | 9 +-- .../Converter/BL_ModifierDeformer.h | 49 ++++++++-------- .../gameengine/Converter/BL_ShapeDeformer.cpp | 9 +-- .../gameengine/Converter/BL_ShapeDeformer.h | 6 +- .../gameengine/Converter/BL_SkinDeformer.cpp | 7 +-- source/gameengine/Converter/BL_SkinDeformer.h | 25 ++++---- .../Converter/KX_BlenderSceneConverter.cpp | 5 +- .../Converter/KX_ConvertActuators.cpp | 7 +-- .../Converter/KX_ConvertSensors.cpp | 10 ++-- source/gameengine/Converter/KX_IpoConvert.cpp | 7 +-- .../Converter/KX_SoftBodyDeformer.cpp | 4 +- .../Converter/KX_SoftBodyDeformer.h | 6 +- source/gameengine/Expressions/Value.h | 6 +- source/gameengine/Expressions/VectorValue.cpp | 4 +- .../gameengine/GameLogic/SCA_AlwaysSensor.cpp | 9 ++- .../gameengine/GameLogic/SCA_DelaySensor.cpp | 9 ++- .../gameengine/GameLogic/SCA_LogicManager.h | 4 +- .../gameengine/GameLogic/SCA_MouseManager.cpp | 8 +-- .../GameLogic/SCA_TimeEventManager.cpp | 9 ++- .../GamePlayer/common/GPC_KeyboardDevice.h | 2 +- .../GamePlayer/common/GPC_MouseDevice.h | 2 +- .../gameengine/GamePlayer/ghost/GPG_Canvas.h | 2 +- .../GamePlayer/ghost/GPG_KeyboardDevice.h | 2 +- .../Ketsji/KX_ConvertPhysicsObjects.cpp | 4 +- source/gameengine/Ketsji/KX_GameObject.cpp | 12 ++-- source/gameengine/Ketsji/KX_GameObject.h | 10 ++-- .../gameengine/Ketsji/KX_IPO_SGController.cpp | 8 +-- source/gameengine/Ketsji/KX_KetsjiEngine.cpp | 7 +-- source/gameengine/Ketsji/KX_Light.cpp | 10 ++-- .../gameengine/Ketsji/KX_MouseFocusSensor.cpp | 25 ++++---- source/gameengine/Ketsji/KX_PyMath.cpp | 6 +- source/gameengine/Ketsji/KX_PythonInit.cpp | 58 +++++++++---------- source/gameengine/Ketsji/KX_Scene.cpp | 6 +- .../gameengine/Ketsji/KX_TimeCategoryLogger.h | 4 +- source/gameengine/Ketsji/KX_TimeLogger.h | 6 +- .../Physics/Bullet/CcdPhysicsController.cpp | 30 +++++----- .../Rasterizer/RAS_BucketManager.cpp | 7 +-- source/gameengine/Rasterizer/RAS_Deformer.h | 6 +- .../gameengine/Rasterizer/RAS_IRasterizer.h | 4 +- .../Rasterizer/RAS_MaterialBucket.cpp | 4 +- source/gameengine/Rasterizer/RAS_MeshObject.h | 6 +- .../RAS_OpenGLRasterizer.h | 4 +- source/gameengine/Rasterizer/RAS_Polygon.cpp | 5 +- 62 files changed, 280 insertions(+), 314 deletions(-) diff --git a/intern/ghost/GHOST_Types.h b/intern/ghost/GHOST_Types.h index c6d364c361c..9b563ef7e55 100644 --- a/intern/ghost/GHOST_Types.h +++ b/intern/ghost/GHOST_Types.h @@ -50,7 +50,7 @@ typedef unsigned short GHOST_TUns16; typedef int GHOST_TInt32; typedef unsigned int GHOST_TUns32; -#if defined(WIN32) && !defined(FREE_WINDOWS) +#ifdef _MSC_VER typedef __int64 GHOST_TInt64; typedef unsigned __int64 GHOST_TUns64; #else diff --git a/intern/ghost/intern/GHOST_Debug.h b/intern/ghost/intern/GHOST_Debug.h index c364f1d26a4..f0db1b3de8d 100644 --- a/intern/ghost/intern/GHOST_Debug.h +++ b/intern/ghost/intern/GHOST_Debug.h @@ -33,12 +33,12 @@ #ifndef __GHOST_DEBUG_H__ #define __GHOST_DEBUG_H__ -#if defined(WIN32) && !defined(FREE_WINDOWS) +#ifdef _MSC_VER # ifdef DEBUG # pragma warning (disable:4786) // suppress stl-MSVC debug info warning // #define GHOST_DEBUG # endif // DEBUG -#endif // WIN32 +#endif // _MSC_VER #ifdef WITH_GHOST_DEBUG # define GHOST_DEBUG // spit ghost events to stdout diff --git a/intern/ghost/test/multitest/MultiTest.c b/intern/ghost/test/multitest/MultiTest.c index 5d207dafaaf..2d0afcf671c 100644 --- a/intern/ghost/test/multitest/MultiTest.c +++ b/intern/ghost/test/multitest/MultiTest.c @@ -26,9 +26,8 @@ */ #define FALSE 0 -#ifdef WIN32 - -#pragma warning(disable: 4244 4305) +#ifdef _MSC_VER +# pragma warning(disable: 4244 4305) #endif #include diff --git a/release/windows/contrib/vfapi/vfapi-plugin.c b/release/windows/contrib/vfapi/vfapi-plugin.c index 8d63baa0ce4..0af96d14d6f 100644 --- a/release/windows/contrib/vfapi/vfapi-plugin.c +++ b/release/windows/contrib/vfapi/vfapi-plugin.c @@ -15,7 +15,6 @@ * */ - #include #include #include @@ -83,16 +82,16 @@ typedef struct { } VF_ReadData_Audio,*LPVF_ReadData_Audio; typedef struct { - DWORD dwSize; - HRESULT (__stdcall *OpenFile)( - char *lpFileName, LPVF_FileHandle lpFileHandle ); + DWORD dwSize; + HRESULT (__stdcall *OpenFile)( + char *lpFileName, LPVF_FileHandle lpFileHandle ); HRESULT (__stdcall *CloseFile)( VF_FileHandle hFileHandle ); HRESULT (__stdcall *GetFileInfo)( VF_FileHandle hFileHandle, - LPVF_FileInfo lpFileInfo ); + LPVF_FileInfo lpFileInfo ); HRESULT (__stdcall *GetStreamInfo)( VF_FileHandle hFileHandle, - DWORD dwStream,void *lpStreamInfo ); + DWORD dwStream,void *lpStreamInfo ); HRESULT (__stdcall *ReadData)( VF_FileHandle hFileHandle, - DWORD dwStream,void *lpData ); + DWORD dwStream,void *lpData ); } VF_PluginFunc,*LPVF_PluginFunc; __declspec(dllexport) HRESULT vfGetPluginInfo( @@ -117,8 +116,9 @@ static unsigned long getipaddress(const char * ipaddr) struct hostent *host; unsigned long ip; - if (((ip = inet_addr(ipaddr)) == INADDR_NONE) - && strcmp(ipaddr, "255.255.255.255") != 0) { + if (((ip = inet_addr(ipaddr)) == INADDR_NONE) && + strcmp(ipaddr, "255.255.255.255") != 0) + { if ((host = gethostbyname(ipaddr)) != NULL) { memcpy(&ip, host->h_addr, sizeof(ip)); } @@ -419,6 +419,3 @@ __declspec(dllexport) HRESULT vfGetPluginFunc( return VF_OK; } - - - diff --git a/source/blender/blenlib/intern/freetypefont.c b/source/blender/blenlib/intern/freetypefont.c index 85239270541..daedd39d693 100644 --- a/source/blender/blenlib/intern/freetypefont.c +++ b/source/blender/blenlib/intern/freetypefont.c @@ -33,8 +33,8 @@ */ -#ifdef WIN32 -#pragma warning (disable:4244) +#ifdef _MSC_VER +# pragma warning (disable:4244) #endif #include diff --git a/source/blender/blenlib/intern/noise.c b/source/blender/blenlib/intern/noise.c index 792bf929182..124624ca137 100644 --- a/source/blender/blenlib/intern/noise.c +++ b/source/blender/blenlib/intern/noise.c @@ -31,9 +31,9 @@ */ -#ifdef _WIN32 -#pragma warning (disable : 4244) // "conversion from double to float" -#pragma warning (disable : 4305) // "truncation from const double to float" +#ifdef _MSC_VER +# pragma warning (disable:4244) /* "conversion from double to float" */ +# pragma warning (disable:4305) /* "truncation from const double to float" */ #endif #include diff --git a/source/blender/blenlib/intern/rand.c b/source/blender/blenlib/intern/rand.c index 4435e9ce09c..3c22d73d113 100644 --- a/source/blender/blenlib/intern/rand.c +++ b/source/blender/blenlib/intern/rand.c @@ -40,7 +40,7 @@ #include "BLI_threads.h" #include "BLI_rand.h" -#if defined(WIN32) && !defined(FREE_WINDOWS) +#ifdef _MSC_VER typedef unsigned __int64 r_uint64; #define MULTIPLIER 0x5DEECE66Di64 diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index b73485add3d..ab7f5d46f8b 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -777,13 +777,16 @@ typedef struct RenderInfo { char scene_name[MAX_ID_NAME - 2]; } RenderInfo; -static void write_renderinfo(WriteData *wd, Main *mainvar) /* for renderdeamon */ +/* was for historic render-deamon feature, + * now write because it can be easily extracted without + * reading the whole blend file */ +static void write_renderinfo(WriteData *wd, Main *mainvar) { bScreen *curscreen; Scene *sce; RenderInfo data; - /* XXX in future, handle multiple windows with multiple screnes? */ + /* XXX in future, handle multiple windows with multiple screens? */ current_screen_compat(mainvar, &curscreen); for (sce= mainvar->scene.first; sce; sce= sce->id.next) { diff --git a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp index 5cfa97e2e7e..6807f531f0a 100644 --- a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp +++ b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp @@ -35,9 +35,9 @@ #include #include -#if defined(WIN32) && !defined(FREE_WINDOWS) -// don't show stl-warnings -#pragma warning (disable:4786) +#ifdef _MSC_VER + /* don't show stl-warnings */ +# pragma warning (disable:4786) #endif #include "GL/glew.h" @@ -69,37 +69,33 @@ #include "Value.h" - -#ifdef __cplusplus extern "C" { -#endif - /***/ -#include "DNA_view3d_types.h" -#include "DNA_screen_types.h" -#include "DNA_userdef_types.h" -#include "DNA_windowmanager_types.h" -#include "BKE_global.h" -#include "BKE_report.h" + #include "DNA_view3d_types.h" + #include "DNA_screen_types.h" + #include "DNA_userdef_types.h" + #include "DNA_scene_types.h" + #include "DNA_windowmanager_types.h" -#include "MEM_guardedalloc.h" + #include "BKE_global.h" + #include "BKE_report.h" + #include "BKE_ipo.h" + #include "BKE_main.h" + #include "BKE_context.h" -/* #include "BKE_screen.h" */ /* cant include this because of 'new' function name */ -extern float BKE_screen_view3d_zoom_to_fac(float camzoom); + /* avoid c++ conflict with 'new' */ + #define new _new + #include "BKE_screen.h" + #undef new -#include "BKE_main.h" -#include "BLI_blenlib.h" -#include "BLO_readfile.h" -#include "DNA_scene_types.h" -#include "BKE_ipo.h" - /***/ + #include "MEM_guardedalloc.h" -#include "BKE_context.h" -#include "../../blender/windowmanager/WM_types.h" -#include "../../blender/windowmanager/wm_window.h" -#include "../../blender/windowmanager/wm_event_system.h" -#ifdef __cplusplus + #include "BLI_blenlib.h" + #include "BLO_readfile.h" + + #include "../../blender/windowmanager/WM_types.h" + #include "../../blender/windowmanager/wm_window.h" + #include "../../blender/windowmanager/wm_event_system.h" } -#endif #ifdef WITH_AUDASPACE # include "AUD_C-API.h" diff --git a/source/gameengine/BlenderRoutines/KX_BlenderInputDevice.h b/source/gameengine/BlenderRoutines/KX_BlenderInputDevice.h index bb476ed497a..a183d4059f8 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderInputDevice.h +++ b/source/gameengine/BlenderRoutines/KX_BlenderInputDevice.h @@ -32,8 +32,8 @@ #ifndef __KX_BLENDERINPUTDEVICE_H__ #define __KX_BLENDERINPUTDEVICE_H__ -#if defined(WIN32) && !defined(FREE_WINDOWS) -#pragma warning(disable : 4786) // shut off 255 char limit debug template warning +#ifdef _MSC_VER +# pragma warning(disable:4786) // shut off 255 char limit debug template warning #endif #include diff --git a/source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.cpp b/source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.cpp index 54c60096812..f4e325eabb8 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.cpp +++ b/source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.cpp @@ -30,9 +30,9 @@ */ -#if defined(WIN32) && !defined(FREE_WINDOWS) -// annoying warnings about truncated STL debug info -#pragma warning (disable :4786) +#ifdef _MSC_VER + /* annoying warnings about truncated STL debug info */ +# pragma warning (disable:4786) #endif #include "KX_BlenderKeyboardDevice.h" diff --git a/source/gameengine/BlenderRoutines/KX_BlenderMouseDevice.cpp b/source/gameengine/BlenderRoutines/KX_BlenderMouseDevice.cpp index 5cd2038163c..aa2392ded08 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderMouseDevice.cpp +++ b/source/gameengine/BlenderRoutines/KX_BlenderMouseDevice.cpp @@ -29,10 +29,9 @@ * \ingroup blroutines */ - -#if defined(WIN32) && !defined(FREE_WINDOWS) -// annoying warnings about truncated STL debug info -#pragma warning (disable :4786) +#ifdef _MSC_VER + /* annoying warnings about truncated STL debug info */ +# pragma warning (disable:4786) #endif #include "KX_BlenderMouseDevice.h" diff --git a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h index 17c9f6bfb1a..adfaf7e3eea 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h +++ b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h @@ -32,9 +32,9 @@ #ifndef __KX_BLENDERRENDERTOOLS_H__ #define __KX_BLENDERRENDERTOOLS_H__ -#if defined(WIN32) && !defined(FREE_WINDOWS) -// don't show stl-warnings -#pragma warning (disable:4786) +#ifdef _MSC_VER + /* don't show stl-warnings */ +# pragma warning (disable:4786) #endif #include "RAS_IRenderTools.h" diff --git a/source/gameengine/BlenderRoutines/KX_BlenderSystem.cpp b/source/gameengine/BlenderRoutines/KX_BlenderSystem.cpp index d7d8c5121a2..0582e79d269 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderSystem.cpp +++ b/source/gameengine/BlenderRoutines/KX_BlenderSystem.cpp @@ -32,9 +32,9 @@ #include "KX_ISystem.h" -#if defined(WIN32) && !defined(FREE_WINDOWS) -#pragma warning (disable :4786) -#endif //WIN32 +#ifdef _MSC_VER +# pragma warning (disable:4786) +#endif #ifdef WIN32 #include diff --git a/source/gameengine/Converter/BL_ArmatureActuator.h b/source/gameengine/Converter/BL_ArmatureActuator.h index a5af2bc9c09..ba02c5aa362 100644 --- a/source/gameengine/Converter/BL_ArmatureActuator.h +++ b/source/gameengine/Converter/BL_ArmatureActuator.h @@ -49,13 +49,13 @@ class BL_ArmatureActuator : public SCA_IActuator Py_Header public: BL_ArmatureActuator(SCA_IObject* gameobj, - int type, - const char *posechannel, - const char *constraintname, - KX_GameObject* targetobj, - KX_GameObject* subtargetobj, - float weight, - float influence); + int type, + const char *posechannel, + const char *constraintname, + KX_GameObject* targetobj, + KX_GameObject* subtargetobj, + float weight, + float influence); virtual ~BL_ArmatureActuator(); diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index 6ffdea9f90e..912e2126874 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -30,8 +30,8 @@ * \ingroup bgeconv */ -#if defined(WIN32) && !defined(FREE_WINDOWS) -#pragma warning (disable : 4786) +#ifdef _MSC_VER +# pragma warning (disable:4786) #endif #include diff --git a/source/gameengine/Converter/BL_DeformableGameObject.h b/source/gameengine/Converter/BL_DeformableGameObject.h index 6653311d496..95e3b7c517d 100644 --- a/source/gameengine/Converter/BL_DeformableGameObject.h +++ b/source/gameengine/Converter/BL_DeformableGameObject.h @@ -32,9 +32,9 @@ #ifndef __BL_DEFORMABLEGAMEOBJECT_H__ #define __BL_DEFORMABLEGAMEOBJECT_H__ -#if defined(WIN32) && !defined(FREE_WINDOWS) -#pragma warning (disable:4786) // get rid of stupid stl-visual compiler debug warning -#endif /* WIN32 */ +#ifdef _MSC_VER +# pragma warning (disable:4786) // get rid of stupid stl-visual compiler debug warning +#endif #include "DNA_mesh_types.h" #include "KX_GameObject.h" diff --git a/source/gameengine/Converter/BL_MeshDeformer.cpp b/source/gameengine/Converter/BL_MeshDeformer.cpp index b8002d05f18..0d3c0d269fc 100644 --- a/source/gameengine/Converter/BL_MeshDeformer.cpp +++ b/source/gameengine/Converter/BL_MeshDeformer.cpp @@ -30,11 +30,10 @@ * \ingroup bgeconv */ - -#if defined(WIN32) && !defined(FREE_WINDOWS) -// This warning tells us about truncation of __long__ stl-generated names. -// It can occasionally cause DevStudio to have internal compiler warnings. -#pragma warning( disable : 4786 ) +#ifdef _MSC_VER + /* This warning tells us about truncation of __long__ stl-generated names. + * It can occasionally cause DevStudio to have internal compiler warnings. */ +# pragma warning( disable:4786 ) #endif #include "RAS_IPolygonMaterial.h" diff --git a/source/gameengine/Converter/BL_MeshDeformer.h b/source/gameengine/Converter/BL_MeshDeformer.h index 7bee55bd119..6e84cdf03f8 100644 --- a/source/gameengine/Converter/BL_MeshDeformer.h +++ b/source/gameengine/Converter/BL_MeshDeformer.h @@ -38,9 +38,9 @@ #include "MT_Point3.h" #include -#if defined(WIN32) && !defined(FREE_WINDOWS) -#pragma warning (disable:4786) // get rid of stupid stl-visual compiler debug warning -#endif /* WIN32 */ +#ifdef _MSC_VER +# pragma warning (disable:4786) /* get rid of stupid stl-visual compiler debug warning */ +#endif class BL_DeformableGameObject; diff --git a/source/gameengine/Converter/BL_ModifierDeformer.cpp b/source/gameengine/Converter/BL_ModifierDeformer.cpp index 22f62975f2c..53755deefe1 100644 --- a/source/gameengine/Converter/BL_ModifierDeformer.cpp +++ b/source/gameengine/Converter/BL_ModifierDeformer.cpp @@ -29,10 +29,9 @@ * \ingroup bgeconv */ - -#if defined(WIN32) && !defined(FREE_WINDOWS) -#pragma warning (disable : 4786) -#endif //WIN32 +#ifdef _MSC_VER +# pragma warning (disable:4786) +#endif #include "MEM_guardedalloc.h" #include "BL_ModifierDeformer.h" @@ -42,7 +41,6 @@ #include "RAS_MeshObject.h" #include "PHY_IGraphicController.h" -//#include "BL_ArmatureController.h" #include "DNA_armature_types.h" #include "DNA_action_types.h" #include "DNA_key_types.h" @@ -65,7 +63,6 @@ extern "C"{ #include "BKE_lattice.h" #include "BKE_modifier.h" } - #include "BLI_blenlib.h" #include "BLI_math.h" diff --git a/source/gameengine/Converter/BL_ModifierDeformer.h b/source/gameengine/Converter/BL_ModifierDeformer.h index f04b41df3fc..4efe4ca5bfc 100644 --- a/source/gameengine/Converter/BL_ModifierDeformer.h +++ b/source/gameengine/Converter/BL_ModifierDeformer.h @@ -32,9 +32,9 @@ #ifndef __BL_MODIFIERDEFORMER_H__ #define __BL_MODIFIERDEFORMER_H__ -#if defined(WIN32) && !defined(FREE_WINDOWS) -#pragma warning (disable:4786) // get rid of stupid stl-visual compiler debug warning -#endif /* WIN32 */ +#ifdef _MSC_VER +# pragma warning (disable:4786) /* get rid of stupid stl-visual compiler debug warning */ +#endif #include "BL_ShapeDeformer.h" #include "BL_DeformableGameObject.h" @@ -51,33 +51,34 @@ public: BL_ModifierDeformer(BL_DeformableGameObject *gameobj, - Scene *scene, - Object *bmeshobj, - RAS_MeshObject *mesh) - : - BL_ShapeDeformer(gameobj,bmeshobj, mesh), - m_lastModifierUpdate(-1), - m_scene(scene), - m_dm(NULL) + Scene *scene, + Object *bmeshobj, + RAS_MeshObject *mesh) + : + BL_ShapeDeformer(gameobj,bmeshobj, mesh), + m_lastModifierUpdate(-1), + m_scene(scene), + m_dm(NULL) { m_recalcNormal = false; - }; + } /* this second constructor is needed for making a mesh deformable on the fly. */ BL_ModifierDeformer(BL_DeformableGameObject *gameobj, - struct Scene *scene, - struct Object *bmeshobj_old, - struct Object *bmeshobj_new, - class RAS_MeshObject *mesh, - bool release_object, - BL_ArmatureObject* arma = NULL) - : - BL_ShapeDeformer(gameobj, bmeshobj_old, bmeshobj_new, mesh, release_object, false, arma), - m_lastModifierUpdate(-1), - m_scene(scene), - m_dm(NULL) + struct Scene *scene, + struct Object *bmeshobj_old, + struct Object *bmeshobj_new, + class RAS_MeshObject *mesh, + bool release_object, + BL_ArmatureObject* arma = NULL) + : + BL_ShapeDeformer(gameobj, bmeshobj_old, bmeshobj_new, mesh, release_object, false, arma), + m_lastModifierUpdate(-1), + m_scene(scene), + m_dm(NULL) { - }; + /* pass */ + } virtual void ProcessReplica(); virtual RAS_Deformer *GetReplica(); diff --git a/source/gameengine/Converter/BL_ShapeDeformer.cpp b/source/gameengine/Converter/BL_ShapeDeformer.cpp index f8941e16ed2..f262532e7e2 100644 --- a/source/gameengine/Converter/BL_ShapeDeformer.cpp +++ b/source/gameengine/Converter/BL_ShapeDeformer.cpp @@ -29,10 +29,9 @@ * \ingroup bgeconv */ - -#if defined(WIN32) && !defined(FREE_WINDOWS) -#pragma warning (disable : 4786) -#endif //WIN32 +#ifdef _MSC_VER +# pragma warning (disable:4786) +#endif #include "MEM_guardedalloc.h" #include "BL_ShapeDeformer.h" @@ -41,7 +40,6 @@ #include "RAS_IPolygonMaterial.h" #include "RAS_MeshObject.h" -//#include "BL_ArmatureController.h" #include "DNA_anim_types.h" #include "DNA_armature_types.h" #include "DNA_action_types.h" @@ -60,7 +58,6 @@ extern "C"{ #include "BKE_lattice.h" #include "BKE_animsys.h" } - #include "BLI_blenlib.h" #include "BLI_math.h" diff --git a/source/gameengine/Converter/BL_ShapeDeformer.h b/source/gameengine/Converter/BL_ShapeDeformer.h index ff5d1e33348..60f27c85e4f 100644 --- a/source/gameengine/Converter/BL_ShapeDeformer.h +++ b/source/gameengine/Converter/BL_ShapeDeformer.h @@ -32,9 +32,9 @@ #ifndef __BL_SHAPEDEFORMER_H__ #define __BL_SHAPEDEFORMER_H__ -#if defined(WIN32) && !defined(FREE_WINDOWS) -#pragma warning (disable:4786) // get rid of stupid stl-visual compiler debug warning -#endif /* WIN32 */ +#ifdef _MSC_VER +# pragma warning (disable:4786) /* get rid of stupid stl-visual compiler debug warning */ +#endif #include "BL_SkinDeformer.h" #include "BL_DeformableGameObject.h" diff --git a/source/gameengine/Converter/BL_SkinDeformer.cpp b/source/gameengine/Converter/BL_SkinDeformer.cpp index 2dc6e302f4f..e068a91bf7e 100644 --- a/source/gameengine/Converter/BL_SkinDeformer.cpp +++ b/source/gameengine/Converter/BL_SkinDeformer.cpp @@ -29,10 +29,9 @@ * \ingroup bgeconv */ - -#if defined(WIN32) && !defined(FREE_WINDOWS) -#pragma warning (disable : 4786) -#endif //WIN32 +#ifdef _MSC_VER +# pragma warning (disable:4786) +#endif // Eigen3 stuff used for BGEDeformVerts #include diff --git a/source/gameengine/Converter/BL_SkinDeformer.h b/source/gameengine/Converter/BL_SkinDeformer.h index f1e1e51dd9b..7495deb2257 100644 --- a/source/gameengine/Converter/BL_SkinDeformer.h +++ b/source/gameengine/Converter/BL_SkinDeformer.h @@ -32,8 +32,8 @@ #ifndef __BL_SKINDEFORMER_H__ #define __BL_SKINDEFORMER_H__ -#if defined(WIN32) && !defined(FREE_WINDOWS) -#pragma warning (disable:4786) // get rid of stupid stl-visual compiler debug warning +#ifdef _MSC_VER +# pragma warning (disable:4786) /* get rid of stupid stl-visual compiler debug warning */ #endif /* WIN32 */ #include "CTR_HashedPtr.h" @@ -56,18 +56,18 @@ public: void SetArmature (class BL_ArmatureObject *armobj); BL_SkinDeformer(BL_DeformableGameObject *gameobj, - struct Object *bmeshobj, - class RAS_MeshObject *mesh, - BL_ArmatureObject* arma = NULL); + struct Object *bmeshobj, + class RAS_MeshObject *mesh, + BL_ArmatureObject* arma = NULL); /* this second constructor is needed for making a mesh deformable on the fly. */ BL_SkinDeformer(BL_DeformableGameObject *gameobj, - struct Object *bmeshobj_old, - struct Object *bmeshobj_new, - class RAS_MeshObject *mesh, - bool release_object, - bool recalc_normal, - BL_ArmatureObject* arma = NULL); + struct Object *bmeshobj_old, + struct Object *bmeshobj_new, + class RAS_MeshObject *mesh, + bool release_object, + bool recalc_normal, + BL_ArmatureObject* arma = NULL); virtual RAS_Deformer *GetReplica(); virtual void ProcessReplica(); @@ -120,5 +120,4 @@ protected: #endif }; -#endif - +#endif /* __BL_SKINDEFORMER_H__ */ diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp index 9020720eaeb..34af4038c4e 100644 --- a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp +++ b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp @@ -29,9 +29,8 @@ * \ingroup bgeconv */ - -#if defined(WIN32) && !defined(FREE_WINDOWS) -#pragma warning (disable:4786) // suppress stl-MSVC debug info warning +#ifdef _MSC_VER +# pragma warning (disable:4786) /* suppress stl-MSVC debug info warning */ #endif #include "KX_Scene.h" diff --git a/source/gameengine/Converter/KX_ConvertActuators.cpp b/source/gameengine/Converter/KX_ConvertActuators.cpp index 287be3b8359..cc5bf4ccbbc 100644 --- a/source/gameengine/Converter/KX_ConvertActuators.cpp +++ b/source/gameengine/Converter/KX_ConvertActuators.cpp @@ -30,10 +30,9 @@ * \ingroup bgeconv */ - -#if defined(WIN32) && !defined(FREE_WINDOWS) -#pragma warning (disable : 4786) -#endif //WIN32 +#ifdef _MSC_VER +# pragma warning (disable:4786) +#endif #include diff --git a/source/gameengine/Converter/KX_ConvertSensors.cpp b/source/gameengine/Converter/KX_ConvertSensors.cpp index 3d4f3ae08f2..859257e192d 100644 --- a/source/gameengine/Converter/KX_ConvertSensors.cpp +++ b/source/gameengine/Converter/KX_ConvertSensors.cpp @@ -33,17 +33,17 @@ #include -#if defined(WIN32) && !defined(FREE_WINDOWS) -#pragma warning (disable : 4786) -#endif //WIN32 +#ifdef _MSC_VER +# pragma warning (disable:4786) +#endif #include "wm_event_types.h" #include "KX_BlenderSceneConverter.h" #include "KX_ConvertSensors.h" /* This little block needed for linking to Blender... */ -#if defined(WIN32) && !defined(FREE_WINDOWS) -#include "BLI_winstuff.h" +#ifdef _MSC_VER +# include "BLI_winstuff.h" #endif #include "DNA_object_types.h" diff --git a/source/gameengine/Converter/KX_IpoConvert.cpp b/source/gameengine/Converter/KX_IpoConvert.cpp index 12f88251805..4fc0b0ad3ec 100644 --- a/source/gameengine/Converter/KX_IpoConvert.cpp +++ b/source/gameengine/Converter/KX_IpoConvert.cpp @@ -29,10 +29,9 @@ * \ingroup bgeconv */ - -#if defined(WIN32) && !defined(FREE_WINDOWS) -// don't show stl-warnings -#pragma warning (disable:4786) +#ifdef _MSC_VER + /* don't show stl-warnings */ +# pragma warning (disable:4786) #endif #include "BKE_material.h" /* give_current_material */ diff --git a/source/gameengine/Converter/KX_SoftBodyDeformer.cpp b/source/gameengine/Converter/KX_SoftBodyDeformer.cpp index e3c12c2b966..72d0c8733f2 100644 --- a/source/gameengine/Converter/KX_SoftBodyDeformer.cpp +++ b/source/gameengine/Converter/KX_SoftBodyDeformer.cpp @@ -30,8 +30,8 @@ */ -#if defined(WIN32) && !defined(FREE_WINDOWS) -#pragma warning (disable : 4786) +#ifdef _MSC_VER +# pragma warning (disable:4786) #endif //WIN32 #include "MT_assert.h" diff --git a/source/gameengine/Converter/KX_SoftBodyDeformer.h b/source/gameengine/Converter/KX_SoftBodyDeformer.h index de533f1c5ed..d7bc088e1c0 100644 --- a/source/gameengine/Converter/KX_SoftBodyDeformer.h +++ b/source/gameengine/Converter/KX_SoftBodyDeformer.h @@ -32,9 +32,9 @@ #ifndef __KX_SOFTBODYDEFORMER_H__ #define __KX_SOFTBODYDEFORMER_H__ -#if defined(WIN32) && !defined(FREE_WINDOWS) -#pragma warning (disable:4786) // get rid of stupid stl-visual compiler debug warning -#endif /* WIN32 */ +#ifdef _MSC_VER +# pragma warning (disable:4786) /* get rid of stupid stl-visual compiler debug warning */ +#endif #include "RAS_Deformer.h" #include "BL_DeformableGameObject.h" diff --git a/source/gameengine/Expressions/Value.h b/source/gameengine/Expressions/Value.h index 92b5e20543c..c4af3255f4a 100644 --- a/source/gameengine/Expressions/Value.h +++ b/source/gameengine/Expressions/Value.h @@ -19,9 +19,9 @@ #ifndef __VALUE_H__ #define __VALUE_H__ -#if defined(WIN32) && !defined(FREE_WINDOWS) -#pragma warning (disable:4786) -#endif /* WIN32 */ +#ifdef _MSC_VER +# pragma warning (disable:4786) +#endif #include // array functionality for the propertylist #include "STR_String.h" // STR_String class diff --git a/source/gameengine/Expressions/VectorValue.cpp b/source/gameengine/Expressions/VectorValue.cpp index 65f5d7d3d22..ed13b0c8639 100644 --- a/source/gameengine/Expressions/VectorValue.cpp +++ b/source/gameengine/Expressions/VectorValue.cpp @@ -15,8 +15,8 @@ * */ -#if defined(WIN32) && !defined(FREE_WINDOWS) -#pragma warning (disable:4786) +#ifdef _MSC_VER +# pragma warning (disable:4786) #endif #include "Value.h" diff --git a/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp b/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp index 6b697f4f15b..1a6a82a33eb 100644 --- a/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp +++ b/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp @@ -32,11 +32,10 @@ * \ingroup gamelogic */ - -#if defined(WIN32) && !defined(FREE_WINDOWS) -// This warning tells us about truncation of __long__ stl-generated names. -// It can occasionally cause DevStudio to have internal compiler warnings. -#pragma warning( disable : 4786 ) +#ifdef _MSC_VER + /* This warning tells us about truncation of __long__ stl-generated names. + * It can occasionally cause DevStudio to have internal compiler warnings. */ +# pragma warning( disable:4786 ) #endif #include "SCA_AlwaysSensor.h" diff --git a/source/gameengine/GameLogic/SCA_DelaySensor.cpp b/source/gameengine/GameLogic/SCA_DelaySensor.cpp index f2bcd67e652..af751cffc2e 100644 --- a/source/gameengine/GameLogic/SCA_DelaySensor.cpp +++ b/source/gameengine/GameLogic/SCA_DelaySensor.cpp @@ -32,11 +32,10 @@ * \ingroup gamelogic */ - -#if defined(WIN32) && !defined(FREE_WINDOWS) -// This warning tells us about truncation of __long__ stl-generated names. -// It can occasionally cause DevStudio to have internal compiler warnings. -#pragma warning( disable : 4786 ) +#ifdef _MSC_VER + /* This warning tells us about truncation of __long__ stl-generated names. + * It can occasionally cause DevStudio to have internal compiler warnings. */ +# pragma warning( disable:4786 ) #endif #include diff --git a/source/gameengine/GameLogic/SCA_LogicManager.h b/source/gameengine/GameLogic/SCA_LogicManager.h index f3d02cccf26..690930196b3 100644 --- a/source/gameengine/GameLogic/SCA_LogicManager.h +++ b/source/gameengine/GameLogic/SCA_LogicManager.h @@ -31,8 +31,8 @@ #ifndef __SCA_LOGICMANAGER_H__ #define __SCA_LOGICMANAGER_H__ -#if defined(WIN32) && !defined(FREE_WINDOWS) -#pragma warning (disable:4786) +#ifdef _MSC_VER +# pragma warning (disable:4786) #endif #include diff --git a/source/gameengine/GameLogic/SCA_MouseManager.cpp b/source/gameengine/GameLogic/SCA_MouseManager.cpp index a067b9c4d5b..6d05b862c2d 100644 --- a/source/gameengine/GameLogic/SCA_MouseManager.cpp +++ b/source/gameengine/GameLogic/SCA_MouseManager.cpp @@ -34,10 +34,10 @@ */ -#if defined(WIN32) && !defined(FREE_WINDOWS) -// This warning tells us about truncation of __long__ stl-generated names. -// It can occasionally cause DevStudio to have internal compiler warnings. -#pragma warning( disable : 4786 ) +#ifdef _MSC_VER + /* This warning tells us about truncation of __long__ stl-generated names. + * It can occasionally cause DevStudio to have internal compiler warnings. */ +# pragma warning( disable:4786 ) #endif #include "BoolValue.h" diff --git a/source/gameengine/GameLogic/SCA_TimeEventManager.cpp b/source/gameengine/GameLogic/SCA_TimeEventManager.cpp index e8a6289a98e..5aa6fdc8625 100644 --- a/source/gameengine/GameLogic/SCA_TimeEventManager.cpp +++ b/source/gameengine/GameLogic/SCA_TimeEventManager.cpp @@ -29,11 +29,10 @@ * \ingroup gamelogic */ - -#if defined(WIN32) && !defined(FREE_WINDOWS) -// This warning tells us about truncation of __long__ stl-generated names. -// It can occasionally cause DevStudio to have internal compiler warnings. -#pragma warning( disable : 4786 ) +#ifdef _MSC_VER + /* This warning tells us about truncation of __long__ stl-generated names. + * It can occasionally cause DevStudio to have internal compiler warnings. */ +# pragma warning(disable:4786) #endif #include "SCA_TimeEventManager.h" diff --git a/source/gameengine/GamePlayer/common/GPC_KeyboardDevice.h b/source/gameengine/GamePlayer/common/GPC_KeyboardDevice.h index afe7f921a61..c082bc1b82f 100644 --- a/source/gameengine/GamePlayer/common/GPC_KeyboardDevice.h +++ b/source/gameengine/GamePlayer/common/GPC_KeyboardDevice.h @@ -33,7 +33,7 @@ #define __GPC_KEYBOARDDEVICE_H__ #ifdef WIN32 -#pragma warning (disable : 4786) +#pragma warning (disable:4786) #endif /* WIN32 */ #include "SCA_IInputDevice.h" diff --git a/source/gameengine/GamePlayer/common/GPC_MouseDevice.h b/source/gameengine/GamePlayer/common/GPC_MouseDevice.h index 7699a9e3eae..b092fbd21dd 100644 --- a/source/gameengine/GamePlayer/common/GPC_MouseDevice.h +++ b/source/gameengine/GamePlayer/common/GPC_MouseDevice.h @@ -33,7 +33,7 @@ #define __GPC_MOUSEDEVICE_H__ #ifdef WIN32 -#pragma warning (disable : 4786) +#pragma warning (disable:4786) #endif /* WIN32 */ #include "SCA_IInputDevice.h" diff --git a/source/gameengine/GamePlayer/ghost/GPG_Canvas.h b/source/gameengine/GamePlayer/ghost/GPG_Canvas.h index f2d7ec267f3..440fd2bba27 100644 --- a/source/gameengine/GamePlayer/ghost/GPG_Canvas.h +++ b/source/gameengine/GamePlayer/ghost/GPG_Canvas.h @@ -33,7 +33,7 @@ #define __GPG_CANVAS_H__ #ifdef WIN32 -#pragma warning (disable : 4786) +#pragma warning (disable:4786) #endif /* WIN32 */ #include "GPC_Canvas.h" diff --git a/source/gameengine/GamePlayer/ghost/GPG_KeyboardDevice.h b/source/gameengine/GamePlayer/ghost/GPG_KeyboardDevice.h index 4c6b8205a42..ff8d56db40a 100644 --- a/source/gameengine/GamePlayer/ghost/GPG_KeyboardDevice.h +++ b/source/gameengine/GamePlayer/ghost/GPG_KeyboardDevice.h @@ -34,7 +34,7 @@ #define __GPG_KEYBOARDDEVICE_H__ #ifdef WIN32 -#pragma warning (disable : 4786) +#pragma warning (disable:4786) #endif /* WIN32 */ #include "GHOST_Types.h" diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp index 776953206fe..daa74ca14c0 100644 --- a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp +++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp @@ -29,8 +29,8 @@ * \ingroup ketsji */ -#if defined(WIN32) && !defined(FREE_WINDOWS) -#pragma warning (disable : 4786) +#ifdef _MSC_VER +# pragma warning (disable:4786) #endif #include "MT_assert.h" diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index 3cfb670d227..dfc8073303e 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -30,6 +30,11 @@ * \ingroup ketsji */ +#ifdef _MSC_VER + /* This warning tells us about truncation of __long__ stl-generated names. + * It can occasionally cause DevStudio to have internal compiler warnings. */ +# pragma warning( disable:4786 ) +#endif #if defined(_WIN64) && !defined(FREE_WINDOWS64) typedef unsigned __int64 uint_ptr; @@ -37,13 +42,6 @@ typedef unsigned __int64 uint_ptr; typedef unsigned long uint_ptr; #endif -#if defined(WIN32) && !defined(FREE_WINDOWS) -// This warning tells us about truncation of __long__ stl-generated names. -// It can occasionally cause DevStudio to have internal compiler warnings. -#pragma warning( disable : 4786 ) -#endif - - #define KX_INERTIA_INFINITE 10000 #include "RAS_IPolygonMaterial.h" #include "KX_BlenderMaterial.h" diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h index 52fc3da5465..157e282b557 100644 --- a/source/gameengine/Ketsji/KX_GameObject.h +++ b/source/gameengine/Ketsji/KX_GameObject.h @@ -33,9 +33,9 @@ #ifndef __KX_GAMEOBJECT_H__ #define __KX_GAMEOBJECT_H__ -#if defined(WIN32) && !defined(FREE_WINDOWS) -// get rid of this stupid "warning 'this' used in initialiser list", generated by VC when including Solid/Sumo -#pragma warning (disable : 4355) +#ifdef _MSC_VER + /* get rid of this stupid "warning 'this' used in initialiser list", generated by VC when including Solid/Sumo */ +# pragma warning (disable:4355) #endif #include @@ -116,11 +116,11 @@ protected: KX_ObstacleSimulation* m_pObstacleSimulation; - CListValue* m_pInstanceObjects; + CListValue* m_pInstanceObjects; KX_GameObject* m_pDupliGroupObject; // The action manager is used to play/stop/update actions - BL_ActionManager* m_actionManager; + BL_ActionManager* m_actionManager; BL_ActionManager* GetActionManager(); diff --git a/source/gameengine/Ketsji/KX_IPO_SGController.cpp b/source/gameengine/Ketsji/KX_IPO_SGController.cpp index 950e3c88a9e..60821fb5aab 100644 --- a/source/gameengine/Ketsji/KX_IPO_SGController.cpp +++ b/source/gameengine/Ketsji/KX_IPO_SGController.cpp @@ -37,10 +37,10 @@ typedef unsigned __int64 uint_ptr; typedef unsigned long uint_ptr; #endif -#if defined(WIN32) && !defined(FREE_WINDOWS) -// This warning tells us about truncation of __long__ stl-generated names. -// It can occasionally cause DevStudio to have internal compiler warnings. -#pragma warning( disable : 4786 ) +#ifdef _MSC_VER + /* This warning tells us about truncation of __long__ stl-generated names. + * It can occasionally cause DevStudio to have internal compiler warnings. */ +# pragma warning(disable:4786) #endif #include "KX_IPO_SGController.h" diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp index e446e5338bc..bf5504f8a2a 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp @@ -30,10 +30,9 @@ * \ingroup ketsji */ - -#if defined(WIN32) && !defined(FREE_WINDOWS) -#pragma warning (disable : 4786) -#endif //WIN32 +#ifdef _MSC_VER +# pragma warning (disable:4786) +#endif #include #include diff --git a/source/gameengine/Ketsji/KX_Light.cpp b/source/gameengine/Ketsji/KX_Light.cpp index 8b80daa75d3..0e45684d2d0 100644 --- a/source/gameengine/Ketsji/KX_Light.cpp +++ b/source/gameengine/Ketsji/KX_Light.cpp @@ -29,8 +29,8 @@ * \ingroup ketsji */ -#if defined(WIN32) && !defined(FREE_WINDOWS) -#pragma warning (disable : 4786) +#ifdef _MSC_VER +# pragma warning (disable:4786) #endif #include @@ -50,9 +50,9 @@ #include "GPU_material.h" KX_LightObject::KX_LightObject(void* sgReplicationInfo,SG_Callbacks callbacks, - class RAS_IRenderTools* rendertools, - const RAS_LightObject& lightobj, - bool glsl) + class RAS_IRenderTools* rendertools, + const RAS_LightObject& lightobj, + bool glsl) : KX_GameObject(sgReplicationInfo,callbacks), m_rendertools(rendertools) { diff --git a/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp b/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp index 3251cc4af46..f7dbbe5a86b 100644 --- a/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp +++ b/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp @@ -30,11 +30,10 @@ * \ingroup ketsji */ - -#if defined(WIN32) && !defined(FREE_WINDOWS) -// This warning tells us about truncation of __long__ stl-generated names. -// It can occasionally cause DevStudio to have internal compiler warnings. -#pragma warning( disable : 4786 ) +#ifdef _MSC_VER + /* This warning tells us about truncation of __long__ stl-generated names. + * It can occasionally cause DevStudio to have internal compiler warnings. */ +# pragma warning(disable:4786) #endif #include "MT_Point3.h" @@ -60,14 +59,14 @@ /* ------------------------------------------------------------------------- */ KX_MouseFocusSensor::KX_MouseFocusSensor(SCA_MouseManager* eventmgr, - int startx, - int starty, - short int mousemode, - int focusmode, - bool bTouchPulse, - KX_Scene* kxscene, - KX_KetsjiEngine *kxengine, - SCA_IObject* gameobj) + int startx, + int starty, + short int mousemode, + int focusmode, + bool bTouchPulse, + KX_Scene* kxscene, + KX_KetsjiEngine *kxengine, + SCA_IObject* gameobj) : SCA_MouseSensor(eventmgr, startx, starty, mousemode, gameobj), m_focusmode(focusmode), m_bTouchPulse(bTouchPulse), diff --git a/source/gameengine/Ketsji/KX_PyMath.cpp b/source/gameengine/Ketsji/KX_PyMath.cpp index bc324c3b140..85303b143bd 100644 --- a/source/gameengine/Ketsji/KX_PyMath.cpp +++ b/source/gameengine/Ketsji/KX_PyMath.cpp @@ -31,9 +31,9 @@ */ -#if defined(WIN32) && !defined(FREE_WINDOWS) -#pragma warning (disable : 4786) -#endif //WIN32 +#ifdef _MSC_VER +# pragma warning (disable:4786) +#endif #ifdef WITH_PYTHON diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp index 43fca40f2da..89799d065a4 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.cpp +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -30,54 +30,48 @@ * \ingroup ketsji */ - #include "GL/glew.h" -#if defined(WIN32) && !defined(FREE_WINDOWS) -#pragma warning (disable : 4786) -#endif //WIN32 +#ifdef _MSC_VER +# pragma warning (disable:4786) +#endif #ifdef WITH_PYTHON - -#ifdef _POSIX_C_SOURCE -#undef _POSIX_C_SOURCE -#endif - -#ifdef _XOPEN_SOURCE -#undef _XOPEN_SOURCE -#endif - -#if defined(__sun) || defined(sun) -#if defined(_XPG4) -#undef _XPG4 -#endif -#endif - -#include +# ifdef _POSIX_C_SOURCE +# undef _POSIX_C_SOURCE +# endif +# ifdef _XOPEN_SOURCE +# undef _XOPEN_SOURCE +# endif +# if defined(__sun) || defined(sun) +# if defined(_XPG4) +# undef _XPG4 +# endif +# endif +# include extern "C" { - #include "bpy_internal_import.h" /* from the blender python api, but we want to import text too! */ - #include "py_capi_utils.h" - #include "mathutils.h" // 'mathutils' module copied here so the blenderlayer can use. - #include "bgl.h" - #include "blf_py_api.h" + # include "bpy_internal_import.h" /* from the blender python api, but we want to import text too! */ + # include "py_capi_utils.h" + # include "mathutils.h" // 'mathutils' module copied here so the blenderlayer can use. + # include "bgl.h" + # include "blf_py_api.h" - #include "marshal.h" /* python header for loading/saving dicts */ + # include "marshal.h" /* python header for loading/saving dicts */ } - #include "AUD_PyInit.h" -#endif +#endif /* WITH_PYTHON */ #include "KX_PythonInit.h" // directory header for py function getBlendFileList #ifndef WIN32 - #include - #include +# include +# include #else - #include - #include "BLI_winstuff.h" +# include +# include "BLI_winstuff.h" #endif //python physics binding diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp index f6ab9af261e..75605fb8fd1 100644 --- a/source/gameengine/Ketsji/KX_Scene.cpp +++ b/source/gameengine/Ketsji/KX_Scene.cpp @@ -31,9 +31,9 @@ */ -#if defined(WIN32) && !defined(FREE_WINDOWS) -#pragma warning (disable : 4786) -#endif //WIN32 +#ifdef _MSC_VER +# pragma warning (disable:4786) +#endif #include "KX_Scene.h" #include "KX_PythonInit.h" diff --git a/source/gameengine/Ketsji/KX_TimeCategoryLogger.h b/source/gameengine/Ketsji/KX_TimeCategoryLogger.h index d167d0addfe..e097454fca7 100644 --- a/source/gameengine/Ketsji/KX_TimeCategoryLogger.h +++ b/source/gameengine/Ketsji/KX_TimeCategoryLogger.h @@ -32,8 +32,8 @@ #ifndef __KX_TIMECATEGORYLOGGER_H__ #define __KX_TIMECATEGORYLOGGER_H__ -#if defined(WIN32) && !defined(FREE_WINDOWS) -#pragma warning (disable:4786) // suppress stl-MSVC debug info warning +#ifdef _MSC_VER +# pragma warning (disable:4786) /* suppress stl-MSVC debug info warning */ #endif #include diff --git a/source/gameengine/Ketsji/KX_TimeLogger.h b/source/gameengine/Ketsji/KX_TimeLogger.h index bafc27b504c..59d7bdc84e3 100644 --- a/source/gameengine/Ketsji/KX_TimeLogger.h +++ b/source/gameengine/Ketsji/KX_TimeLogger.h @@ -32,14 +32,14 @@ #ifndef __KX_TIMELOGGER_H__ #define __KX_TIMELOGGER_H__ -#if defined(WIN32) && !defined(FREE_WINDOWS) -#pragma warning (disable:4786) // suppress stl-MSVC debug info warning +#ifdef _MSC_VER +# pragma warning (disable:4786) /* suppress stl-MSVC debug info warning */ #endif #include #ifdef WITH_CXX_GUARDEDALLOC -#include "MEM_guardedalloc.h" +# include "MEM_guardedalloc.h" #endif /** diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp index 240bda811f0..29a9b6481e9 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp +++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp @@ -215,8 +215,7 @@ bool CcdPhysicsController::CreateSoftbody() btSoftBody* psb = 0; btSoftBodyWorldInfo& worldInfo = m_cci.m_physicsEnv->getDynamicsWorld()->getWorldInfo(); - if (m_cci.m_collisionShape->getShapeType() == CONVEX_HULL_SHAPE_PROXYTYPE) - { + if (m_cci.m_collisionShape->getShapeType() == CONVEX_HULL_SHAPE_PROXYTYPE) { btConvexHullShape* convexHull = (btConvexHullShape* )m_cci.m_collisionShape; { int nvertices = convexHull->getNumPoints(); @@ -224,26 +223,25 @@ bool CcdPhysicsController::CreateSoftbody() HullDesc hdsc(QF_TRIANGLES,nvertices,vertices); HullResult hres; - HullLibrary hlib;/*??*/ + HullLibrary hlib; /*??*/ hdsc.mMaxVertices=nvertices; hlib.CreateConvexHull(hdsc,hres); - psb=new btSoftBody(&worldInfo,(int)hres.mNumOutputVertices, - &hres.m_OutputVertices[0],0); - for (int i=0;i<(int)hres.mNumFaces;++i) - { - const int idx[]={ hres.m_Indices[i*3+0], - hres.m_Indices[i*3+1], - hres.m_Indices[i*3+2]}; - if (idx[0]appendLink( idx[0],idx[1]); - if (idx[1]appendLink( idx[1],idx[2]); - if (idx[2]appendLink( idx[2],idx[0]); - psb->appendFace(idx[0],idx[1],idx[2]); + psb = new btSoftBody(&worldInfo, (int)hres.mNumOutputVertices, + &hres.m_OutputVertices[0], 0); + for (int i = 0; i < (int)hres.mNumFaces; ++i) { + const int idx[3] = {hres.m_Indices[i * 3 + 0], + hres.m_Indices[i * 3 + 1], + hres.m_Indices[i * 3 + 2]}; + if (idx[0] < idx[1]) psb->appendLink(idx[0], idx[1]); + if (idx[1] < idx[2]) psb->appendLink(idx[1], idx[2]); + if (idx[2] < idx[0]) psb->appendLink(idx[2], idx[0]); + psb->appendFace(idx[0], idx[1], idx[2]); } hlib.ReleaseResult(hres); } - } else - { + } + else { int numtris = 0; if (m_cci.m_collisionShape->getShapeType() ==SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE) { diff --git a/source/gameengine/Rasterizer/RAS_BucketManager.cpp b/source/gameengine/Rasterizer/RAS_BucketManager.cpp index 457fd0ad90c..3c49d6e5289 100644 --- a/source/gameengine/Rasterizer/RAS_BucketManager.cpp +++ b/source/gameengine/Rasterizer/RAS_BucketManager.cpp @@ -29,10 +29,9 @@ * \ingroup bgerast */ - -#if defined(WIN32) && !defined(FREE_WINDOWS) -// don't show these anoying STL warnings -#pragma warning (disable:4786) +#ifdef _MSC_VER + /* don't show these anoying STL warnings */ +# pragma warning (disable:4786) #endif #include "CTR_Map.h" diff --git a/source/gameengine/Rasterizer/RAS_Deformer.h b/source/gameengine/Rasterizer/RAS_Deformer.h index 6042a7dc4b5..058f2304f3d 100644 --- a/source/gameengine/Rasterizer/RAS_Deformer.h +++ b/source/gameengine/Rasterizer/RAS_Deformer.h @@ -32,9 +32,9 @@ #ifndef __RAS_DEFORMER_H__ #define __RAS_DEFORMER_H__ -#if defined(WIN32) && !defined(FREE_WINDOWS) -#pragma warning (disable:4786) // get rid of stupid stl-visual compiler debug warning -#endif /* WIN32 */ +#ifdef _MSC_VER +# pragma warning (disable:4786) /* get rid of stupid stl-visual compiler debug warning */ +#endif #include #include "CTR_Map.h" diff --git a/source/gameengine/Rasterizer/RAS_IRasterizer.h b/source/gameengine/Rasterizer/RAS_IRasterizer.h index f212b1e6e0b..e6948025999 100644 --- a/source/gameengine/Rasterizer/RAS_IRasterizer.h +++ b/source/gameengine/Rasterizer/RAS_IRasterizer.h @@ -32,8 +32,8 @@ #ifndef __RAS_IRASTERIZER_H__ #define __RAS_IRASTERIZER_H__ -#if defined(WIN32) && !defined(FREE_WINDOWS) -#pragma warning (disable:4786) +#ifdef _MSC_VER +# pragma warning (disable:4786) #endif #include "STR_HashedString.h" diff --git a/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp b/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp index c890f0c3dc5..0cb6bc7439a 100644 --- a/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp +++ b/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp @@ -32,8 +32,8 @@ #include "RAS_MaterialBucket.h" -#if defined(WIN32) && !defined(FREE_WINDOWS) -#pragma warning (disable:4786) +#ifdef _MSC_VER +# pragma warning (disable:4786) #endif #ifdef WIN32 diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.h b/source/gameengine/Rasterizer/RAS_MeshObject.h index 99ed59f6057..281eae8734a 100644 --- a/source/gameengine/Rasterizer/RAS_MeshObject.h +++ b/source/gameengine/Rasterizer/RAS_MeshObject.h @@ -32,9 +32,9 @@ #ifndef __RAS_MESHOBJECT_H__ #define __RAS_MESHOBJECT_H__ -#if defined(WIN32) && !defined(FREE_WINDOWS) -// disable the STL warnings ("debug information length > 255") -#pragma warning (disable:4786) +#ifdef _MSC_VER + /* disable the STL warnings ("debug information length > 255") */ +# pragma warning (disable:4786) #endif #include diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h index e6d16378bcf..88bb0be531b 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h @@ -32,8 +32,8 @@ #ifndef __RAS_OPENGLRASTERIZER_H__ #define __RAS_OPENGLRASTERIZER_H__ -#if defined(WIN32) && !defined(FREE_WINDOWS) -#pragma warning (disable:4786) +#ifdef _MSC_VER +# pragma warning (disable:4786) #endif #include "MT_CmMatrix4x4.h" diff --git a/source/gameengine/Rasterizer/RAS_Polygon.cpp b/source/gameengine/Rasterizer/RAS_Polygon.cpp index a6912c0997d..f454d1c0204 100644 --- a/source/gameengine/Rasterizer/RAS_Polygon.cpp +++ b/source/gameengine/Rasterizer/RAS_Polygon.cpp @@ -29,9 +29,8 @@ * \ingroup bgerast */ - -#if defined(WIN32) && !defined(FREE_WINDOWS) -#pragma warning (disable:4786) +#ifdef _MSC_VER +# pragma warning (disable:4786) #endif #include "RAS_Polygon.h" From 2babbb59b931f13fb37692b8a84c12febc4b5a07 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Mon, 15 Oct 2012 03:00:27 +0000 Subject: [PATCH 229/347] Unparenting objects from armatures/curves/lattices now removes the corresponding modifiers now This makes it harder for users to unwittingly create multiple deform modifiers by parenting and unparenting a number of times, with the net result being that "Clear Parent" is now the true inverse operation of "Make Parent". --- .../blender/editors/object/object_relations.c | 89 ++++++++++++++++--- 1 file changed, 76 insertions(+), 13 deletions(-) diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index 446c0a51ed5..9e6cce7fee9 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -423,29 +423,92 @@ void OBJECT_OT_proxy_make(wmOperatorType *ot) /********************** Clear Parent Operator ******************* */ +typedef enum eObClearParentTypes { + CLEAR_PARENT_ALL = 0, + CLEAR_PARENT_KEEP_TRANSFORM, + CLEAR_PARENT_INVERSE +} eObClearParentTypes; + EnumPropertyItem prop_clear_parent_types[] = { - {0, "CLEAR", 0, "Clear Parent", ""}, - {1, "CLEAR_KEEP_TRANSFORM", 0, "Clear and Keep Transformation", ""}, - {2, "CLEAR_INVERSE", 0, "Clear Parent Inverse", ""}, + {CLEAR_PARENT_ALL, "CLEAR", 0, "Clear Parent", ""}, + {CLEAR_PARENT_KEEP_TRANSFORM, "CLEAR_KEEP_TRANSFORM", 0, "Clear and Keep Transformation", ""}, + {CLEAR_PARENT_INVERSE, "CLEAR_INVERSE", 0, "Clear Parent Inverse", ""}, {0, NULL, 0, NULL, NULL} }; +/* Helper for ED_object_parent_clear() - Remove deform-modifiers associated with parent */ +static void object_remove_parent_deform_modifiers(Object *ob, const Object *par) +{ + if (ELEM3(par->type, OB_ARMATURE, OB_LATTICE, OB_CURVE)) { + ModifierData *md, *mdn; + + /* assume that we only need to remove the first instance of matching deform modifier here */ + for (md = ob->modifiers.first; md; md = mdn) { + short free = FALSE; + + mdn = md->next; + + /* need to match types (modifier + parent) and references */ + if ((md->type == eModifierType_Armature) && (par->type == OB_ARMATURE)) { + ArmatureModifierData *amd = (ArmatureModifierData *)md; + if (amd->object == par) { + free = TRUE; + } + } + else if ((md->type == eModifierType_Lattice) && (par->type == OB_LATTICE)) { + LatticeModifierData *lmd = (LatticeModifierData *)md; + if (lmd->object == par) { + free = TRUE; + } + } + else if ((md->type == eModifierType_Curve) && (par->type == OB_CURVE)) { + CurveModifierData *cmd = (CurveModifierData *)md; + if (cmd->object == par) { + free = TRUE; + } + } + + /* free modifier if match */ + if (free) { + BLI_remlink(&ob->modifiers, md); + modifier_free(md); + } + } + } +} + void ED_object_parent_clear(Object *ob, int type) { - if (ob->parent == NULL) return; + + switch (type) { + case CLEAR_PARENT_ALL: + { + /* for deformers, remove corresponding modifiers to prevent a large number of modifiers building up */ + object_remove_parent_deform_modifiers(ob, ob->parent); + + /* clear parenting relationship completely */ + ob->parent = NULL; + } + break; - if (type == 0) { - ob->parent = NULL; - } - else if (type == 1) { - ob->parent = NULL; - BKE_object_apply_mat4(ob, ob->obmat, TRUE, FALSE); - } - else if (type == 2) - unit_m4(ob->parentinv); + case CLEAR_PARENT_KEEP_TRANSFORM: + { + /* remove parent, and apply the parented transform result as object's local transforms */ + ob->parent = NULL; + BKE_object_apply_mat4(ob, ob->obmat, TRUE, FALSE); + } + break; + case CLEAR_PARENT_INVERSE: + { + /* object stays parented, but the parent inverse (i.e. offset from parent to retain binding state) is cleared */ + unit_m4(ob->parentinv); + } + break; + } + ob->recalc |= OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME; } From 04f063de84efde869fe712d4533361d687a66980 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Mon, 15 Oct 2012 03:16:38 +0000 Subject: [PATCH 230/347] Parenting an object to a deformer (armature/curve/lattice) will now attempt to check if the object is already parented to said deformer before trying to add a new modifier This should help reduce the number of cases where users inadvertantly end up creating multiple deform modifiers pointing to the same object, which has been known to be a cause of "double-transform" artifacts. Note that this is only able to detect these cases by checking if the parent object is selected, so this will only really work for the Ctrl-P shortcut where you have to select both objects first. However, it shouldn't be a problem either in the Outliner (drag and drop), as the object probably won't be a child of its parent already if you're doing this. --- source/blender/blenkernel/BKE_modifier.h | 1 + source/blender/blenkernel/intern/modifier.c | 32 +++++++++++++++---- .../blender/editors/object/object_relations.c | 23 +++++++++---- 3 files changed, 43 insertions(+), 13 deletions(-) diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h index 3b675f3b620..7ee1c85d0de 100644 --- a/source/blender/blenkernel/BKE_modifier.h +++ b/source/blender/blenkernel/BKE_modifier.h @@ -352,6 +352,7 @@ int modifiers_isParticleEnabled(struct Object *ob); struct Object *modifiers_isDeformedByArmature(struct Object *ob); struct Object *modifiers_isDeformedByLattice(struct Object *ob); +struct Object *modifiers_isDeformedByCurve(struct Object *ob); int modifiers_usesArmature(struct Object *ob, struct bArmature *arm); int modifiers_isCorrectableDeformed(struct Object *ob); void modifier_freeTemporaryData(struct ModifierData *md); diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index f072ed4009e..0afd048e7f2 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -494,8 +494,8 @@ ModifierData *modifiers_getVirtualModifierList(Object *ob) return md; } -/* Takes an object and returns its first selected armature, else just its - * armature + +/* Takes an object and returns its first selected armature, else just its armature * This should work for multiple armatures per object */ Object *modifiers_isDeformedByArmature(Object *ob) @@ -518,9 +518,8 @@ Object *modifiers_isDeformedByArmature(Object *ob) return NULL; } -/* Takes an object and returns its first selected lattice, else just its - * lattice - * This should work for multiple lattics per object +/* Takes an object and returns its first selected lattice, else just its lattice + * This should work for multiple lattices per object */ Object *modifiers_isDeformedByLattice(Object *ob) { @@ -542,7 +541,28 @@ Object *modifiers_isDeformedByLattice(Object *ob) return NULL; } - +/* Takes an object and returns its first selected curve, else just its curve + * This should work for multiple curves per object + */ +Object *modifiers_isDeformedByCurve(Object *ob) +{ + ModifierData *md = modifiers_getVirtualModifierList(ob); + CurveModifierData *cmd = NULL; + + /* return the first selected curve, this lets us use multiple curves */ + for (; md; md = md->next) { + if (md->type == eModifierType_Curve) { + cmd = (CurveModifierData *) md; + if (cmd->object && (cmd->object->flag & SELECT)) + return cmd->object; + } + } + + if (cmd) /* if were still here then return the last curve */ + return cmd->object; + + return NULL; +} int modifiers_usesArmature(Object *ob, bArmature *arm) { diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index 9e6cce7fee9..b7efe9189d8 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -669,23 +669,32 @@ int ED_object_parent_set(ReportList *reports, Main *bmain, Scene *scene, Object ob->partype = PAROBJECT; /* note, dna define, not operator property */ //ob->partype= PARSKEL; /* note, dna define, not operator property */ - /* BUT, to keep the deforms, we need a modifier, and then we need to set the object that it uses */ + /* BUT, to keep the deforms, we need a modifier, and then we need to set the object that it uses + * - We need to ensure that the modifier we're adding doesn't already exist, so we check this by + * assuming that the parent is selected too... + */ // XXX currently this should only happen for meshes, curves, surfaces, and lattices - this stuff isn't available for metas yet if (ELEM5(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_LATTICE)) { ModifierData *md; switch (partype) { case PAR_CURVE: /* curve deform */ - md = ED_object_modifier_add(reports, bmain, scene, ob, NULL, eModifierType_Curve); - ((CurveModifierData *)md)->object = par; + if (modifiers_isDeformedByCurve(ob) != par) { + md = ED_object_modifier_add(reports, bmain, scene, ob, NULL, eModifierType_Curve); + ((CurveModifierData *)md)->object = par; + } break; case PAR_LATTICE: /* lattice deform */ - md = ED_object_modifier_add(reports, bmain, scene, ob, NULL, eModifierType_Lattice); - ((LatticeModifierData *)md)->object = par; + if (modifiers_isDeformedByLattice(ob) != par) { + md = ED_object_modifier_add(reports, bmain, scene, ob, NULL, eModifierType_Lattice); + ((LatticeModifierData *)md)->object = par; + } break; default: /* armature deform */ - md = ED_object_modifier_add(reports, bmain, scene, ob, NULL, eModifierType_Armature); - ((ArmatureModifierData *)md)->object = par; + if (modifiers_isDeformedByArmature(ob) != par) { + md = ED_object_modifier_add(reports, bmain, scene, ob, NULL, eModifierType_Armature); + ((ArmatureModifierData *)md)->object = par; + } break; } } From ab86e9593bb8916f07a0fed740b89c3cd61ba719 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 15 Oct 2012 03:17:10 +0000 Subject: [PATCH 231/347] add missing redraw notifier for separate UV operator, also some style cleanup and remove unused define. --- source/blender/blenkernel/BKE_scene.h | 7 ++++++- source/blender/editors/uvedit/uvedit_ops.c | 1 + source/gameengine/Ketsji/KX_KetsjiEngine.cpp | 1 - 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h index c12e913be45..9927c7a42ed 100644 --- a/source/blender/blenkernel/BKE_scene.h +++ b/source/blender/blenkernel/BKE_scene.h @@ -55,7 +55,12 @@ struct Text; #define SCE_COPY_LINK_DATA 3 #define SCE_COPY_FULL 4 -#define SETLOOPER(_sce_basis, _sce_iter, _base) _sce_iter = _sce_basis, _base = _setlooper_base_step(&_sce_iter, NULL); _base; _base = _setlooper_base_step(&_sce_iter, _base) +/* Use as the contents of a 'for' loop: for (SETLOOPER(...)) { ... */ +#define SETLOOPER(_sce_basis, _sce_iter, _base) \ + _sce_iter = _sce_basis, _base = _setlooper_base_step(&_sce_iter, NULL); \ + _base; \ + _base = _setlooper_base_step(&_sce_iter, _base) + struct Base *_setlooper_base_step(struct Scene **sce_iter, struct Base *base); void free_avicodecdata(struct AviCodecData *acd); diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c index 6b69fc53162..77e264c40e3 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -2283,6 +2283,7 @@ static int select_split_exec(bContext *C, wmOperator *op) } if (change) { + WM_event_add_notifier(C, NC_SPACE | ND_SPACE_IMAGE, NULL); return OPERATOR_FINISHED; } else { diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp index bf5504f8a2a..479e63a1f24 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp @@ -45,7 +45,6 @@ #include "BoolValue.h" #include "FloatValue.h" -#define KX_NUM_ITERATIONS 4 #include "RAS_BucketManager.h" #include "RAS_Rect.h" #include "RAS_IRasterizer.h" From 8ebe1e4afeda1d15fb236d179ba626546e8cac73 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 15 Oct 2012 03:27:05 +0000 Subject: [PATCH 232/347] code cleanup: remove redundant pointer indirection. --- source/blender/editors/mesh/editmesh_rip.c | 19 ++++++++++++------- source/blender/editors/uvedit/uvedit_ops.c | 7 +++++-- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/source/blender/editors/mesh/editmesh_rip.c b/source/blender/editors/mesh/editmesh_rip.c index b5dfc070d71..212ef10392a 100644 --- a/source/blender/editors/mesh/editmesh_rip.c +++ b/source/blender/editors/mesh/editmesh_rip.c @@ -387,6 +387,11 @@ static void edbm_ripsel_deselect_helper(BMesh *bm, EdgeLoopPair *eloop_pairs, /** * return an un-ordered array of loop pairs * use for rebuilding face-fill + * + * \note the method currenly used fails for edges with 3+ face users and gives + * nasty holes in the mesh, there isnt a good way of knowing ahead of time + * which loops will be split apart (its possible to figure out but quite involved). + * So for now this is a known limitation of current rip-fill option. */ typedef struct UnorderedLoopPair { @@ -562,7 +567,7 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, wmEvent *event) ED_view3d_ob_project_mat_get(rv3d, obedit, projectMat); /* find selected vert - same some time and check history first */ - if (BM_select_history_active_get(em->bm, &ese) && ese.htype == BM_VERT) { + if (BM_select_history_active_get(bm, &ese) && ese.htype == BM_VERT) { v = (BMVert *)ese.ele; } else { @@ -669,7 +674,7 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, wmEvent *event) int vi_best = 0; if (ese.ele) { - BM_select_history_remove(em->bm, ese.ele); + BM_select_history_remove(bm, ese.ele); } dist = FLT_MAX; @@ -717,7 +722,7 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, wmEvent *event) BM_vert_select_set(bm, v, TRUE); if (ese.ele) { - BM_select_history_store(em->bm, v); + BM_select_history_store(bm, v); } /* splice all others back together */ @@ -806,7 +811,7 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, wmEvent *event) float scale; dist = FLT_MAX; - BM_ITER_MESH (v, &iter, em->bm, BM_VERTS_OF_MESH) { + BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(v, BM_ELEM_SELECT)) { /* disable by default, re-enable winner at end */ BM_vert_select_set(bm, v, FALSE); @@ -836,7 +841,7 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, wmEvent *event) if (v_best) { BM_vert_select_set(bm, v_best, TRUE); if (ese.ele) { - BM_select_history_store(em->bm, v_best); + BM_select_history_store(bm, v_best); } } } @@ -997,7 +1002,7 @@ static int edbm_rip_invoke(bContext *C, wmOperator *op, wmEvent *event) int ret; /* running in face mode hardly makes sense, so convert to region loop and rip */ - if (em->bm->totfacesel) { + if (bm->totfacesel) { /* highly nifty but hard to support since the operator can fail and we're left * with modified selection */ // WM_operator_name_call(C, "MESH_OT_region_to_loop", WM_OP_INVOKE_DEFAULT, NULL); @@ -1017,7 +1022,7 @@ static int edbm_rip_invoke(bContext *C, wmOperator *op, wmEvent *event) */ /* BM_ELEM_SELECT --> BM_ELEM_TAG */ - BM_ITER_MESH (e, &iter, em->bm, BM_EDGES_OF_MESH) { + BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { BM_elem_flag_set(e, BM_ELEM_TAG, BM_elem_flag_test(e, BM_ELEM_SELECT)); } diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c index 77e264c40e3..59273ee66b3 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -2492,13 +2492,16 @@ static void uv_faces_do_sticky(SpaceImage *sima, Scene *scene, Object *obedit, s break; if (efa_index != vlist_iter->f) { + BMLoop *l_other; efa_vlist = EDBM_face_at_index(em, vlist_iter->f); /* tf_vlist = CustomData_bmesh_get(&em->bm->pdata, efa_vlist->head.data, CD_MTEXPOLY); */ /* UNUSED */ + l_other = BM_iter_at_index(em->bm, BM_LOOPS_OF_FACE, efa_vlist, vlist_iter->tfindex); + if (select) - uvedit_uv_select_enable(em, scene, BM_iter_at_index(em->bm, BM_LOOPS_OF_FACE, efa_vlist, vlist_iter->tfindex), FALSE); + uvedit_uv_select_enable(em, scene, l_other, FALSE); else - uvedit_uv_select_disable(em, scene, BM_iter_at_index(em->bm, BM_LOOPS_OF_FACE, efa_vlist, vlist_iter->tfindex)); + uvedit_uv_select_disable(em, scene, l_other); } vlist_iter = vlist_iter->next; } From 75198e98bba86dd7471883e8f9ec388486404cd4 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 15 Oct 2012 03:36:22 +0000 Subject: [PATCH 233/347] fix for error in filled rip copying customdata (new triangles were flipped across the edges of the empty space they spanned) only noticeable when the customdata on either size of the rip didnt match. --- source/blender/editors/mesh/editmesh_rip.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/blender/editors/mesh/editmesh_rip.c b/source/blender/editors/mesh/editmesh_rip.c index 212ef10392a..8fe2aa4b1a7 100644 --- a/source/blender/editors/mesh/editmesh_rip.c +++ b/source/blender/editors/mesh/editmesh_rip.c @@ -505,12 +505,12 @@ static void edbm_tagged_loop_pairs_do_fill_faces(BMesh *bm, UnorderedLoopPair *u if (v_shared == f_verts[0]) { BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[0]->e, ulp->l_pair[0]->next), l_iter); l_iter = l_iter->next; BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[0]->e, ulp->l_pair[0]), l_iter); l_iter = l_iter->next; - BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[1]->e, ulp->l_pair[1]->next), l_iter); l_iter = l_iter->next; + BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[1]->e, ulp->l_pair[1]->next), l_iter); } else { - BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[1]->e, ulp->l_pair[1]), l_iter); l_iter = l_iter->next; - BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[0]->e, ulp->l_pair[0]), l_iter); l_iter = l_iter->next; BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[0]->e, ulp->l_pair[0]->next), l_iter); l_iter = l_iter->next; + BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[0]->e, ulp->l_pair[0]), l_iter); l_iter = l_iter->next; + BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[1]->e, ulp->l_pair[1]), l_iter); } } From c483a54207d78acea785566e82f54145457466ec Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Mon, 15 Oct 2012 03:52:27 +0000 Subject: [PATCH 234/347] Making "Jump to Keyframes" operator (for Action/Graph Editors) more obvious This operator used to be called "Jump to Frame". It basically takes the midpoint (frame number and/or value) of selected keyframes, and positions the current frame (or2d-cursor in Graph Editor) at this point. The hotkey for this is now Ctrl-G (i.e. as it's similar to a "Goto Frame" feature). It is also now in the Key menu instead of in the relatively obscure View menu, even though it doesn't actually result in any keyframe edits taking place. (Also, fixed a typo/grammer issue with one of Remove Bone Group operator) --- release/scripts/startup/bl_ui/space_dopesheet.py | 4 +++- release/scripts/startup/bl_ui/space_graph.py | 4 +++- source/blender/editors/armature/poseobject.c | 2 +- source/blender/editors/space_action/action_edit.c | 4 ++-- source/blender/editors/space_action/action_ops.c | 5 ++--- source/blender/editors/space_graph/graph_edit.c | 4 ++-- source/blender/editors/space_graph/graph_ops.c | 5 ++--- 7 files changed, 15 insertions(+), 13 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_dopesheet.py b/release/scripts/startup/bl_ui/space_dopesheet.py index 8a47a631e82..a81553a8257 100644 --- a/release/scripts/startup/bl_ui/space_dopesheet.py +++ b/release/scripts/startup/bl_ui/space_dopesheet.py @@ -165,7 +165,6 @@ class DOPESHEET_MT_view(Menu): layout.operator("action.previewrange_set") layout.separator() - layout.operator("action.frame_jump") layout.operator("action.view_all") layout.operator("action.view_selected") @@ -275,6 +274,9 @@ class DOPESHEET_MT_key(Menu): layout.separator() layout.operator("action.keyframe_insert") + layout.separator() + layout.operator("action.frame_jump") + layout.separator() layout.operator("action.duplicate_move") layout.operator("action.delete") diff --git a/release/scripts/startup/bl_ui/space_graph.py b/release/scripts/startup/bl_ui/space_graph.py index 972b4ebe721..e89bd78a84f 100644 --- a/release/scripts/startup/bl_ui/space_graph.py +++ b/release/scripts/startup/bl_ui/space_graph.py @@ -96,7 +96,6 @@ class GRAPH_MT_view(Menu): layout.operator("graph.previewrange_set") layout.separator() - layout.operator("graph.frame_jump") layout.operator("graph.view_all") layout.operator("graph.view_selected") @@ -198,6 +197,9 @@ class GRAPH_MT_key(Menu): layout.operator("graph.fmodifier_add") layout.operator("graph.sound_bake") + layout.separator() + layout.operator("graph.frame_jump") + layout.separator() layout.operator("graph.duplicate_move") layout.operator("graph.delete") diff --git a/source/blender/editors/armature/poseobject.c b/source/blender/editors/armature/poseobject.c index 365500a517b..0e5daea6f16 100644 --- a/source/blender/editors/armature/poseobject.c +++ b/source/blender/editors/armature/poseobject.c @@ -1399,7 +1399,7 @@ void POSE_OT_group_remove(wmOperatorType *ot) /* identifiers */ ot->name = "Remove Bone Group"; ot->idname = "POSE_OT_group_remove"; - ot->description = "Removes the active bone group"; + ot->description = "Remove the active bone group"; /* api callbacks */ ot->exec = pose_group_remove_exec; diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c index cd036d7cb50..78277cb8199 100644 --- a/source/blender/editors/space_action/action_edit.c +++ b/source/blender/editors/space_action/action_edit.c @@ -1353,9 +1353,9 @@ static int actkeys_framejump_exec(bContext *C, wmOperator *UNUSED(op)) void ACTION_OT_frame_jump(wmOperatorType *ot) { /* identifiers */ - ot->name = "Jump to Frame"; + ot->name = "Jump to Keyframes"; ot->idname = "ACTION_OT_frame_jump"; - ot->description = "Set the current frame to the average frame of the selected keyframes"; + ot->description = "Set the current frame to the average frame value of selected keyframes"; /* api callbacks */ ot->exec = actkeys_framejump_exec; diff --git a/source/blender/editors/space_action/action_ops.c b/source/blender/editors/space_action/action_ops.c index e4a161e3e22..cca71bb1331 100644 --- a/source/blender/editors/space_action/action_ops.c +++ b/source/blender/editors/space_action/action_ops.c @@ -168,9 +168,8 @@ static void action_keymap_keyframes(wmKeyConfig *keyconf, wmKeyMap *keymap) /* action_edit.c */ - /* snap - current frame to selected keys */ - // TODO: maybe since this is called jump, we're better to have it on -J? - WM_keymap_add_item(keymap, "ACTION_OT_frame_jump", SKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0); + /* jump to selected keyframes */ + WM_keymap_add_item(keymap, "ACTION_OT_frame_jump", GKEY, KM_PRESS, KM_CTRL, 0); /* menu + single-step transform */ WM_keymap_add_item(keymap, "ACTION_OT_snap", SKEY, KM_PRESS, KM_SHIFT, 0); diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c index c5fa64d3a70..f16f37df443 100644 --- a/source/blender/editors/space_graph/graph_edit.c +++ b/source/blender/editors/space_graph/graph_edit.c @@ -1808,9 +1808,9 @@ static int graphkeys_framejump_exec(bContext *C, wmOperator *UNUSED(op)) void GRAPH_OT_frame_jump(wmOperatorType *ot) { /* identifiers */ - ot->name = "Jump to Frame"; + ot->name = "Jump to Keyframes"; ot->idname = "GRAPH_OT_frame_jump"; - ot->description = "Set the current frame to the average frame of the selected keyframes"; + ot->description = "Place the cursor on the midpoint of selected keyframes"; /* api callbacks */ ot->exec = graphkeys_framejump_exec; diff --git a/source/blender/editors/space_graph/graph_ops.c b/source/blender/editors/space_graph/graph_ops.c index 08b13b49f55..9b031c015a9 100644 --- a/source/blender/editors/space_graph/graph_ops.c +++ b/source/blender/editors/space_graph/graph_ops.c @@ -346,9 +346,8 @@ static void graphedit_keymap_keyframes(wmKeyConfig *keyconf, wmKeyMap *keymap) /* graph_edit.c */ - /* snap - current frame to selected keys */ - // TODO: maybe since this is called jump, we're better to have it on -J? - WM_keymap_add_item(keymap, "GRAPH_OT_frame_jump", SKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0); + /* jump to selected keyframes */ + WM_keymap_add_item(keymap, "GRAPH_OT_frame_jump", GKEY, KM_PRESS, KM_CTRL, 0); /* menu + single-step transform */ WM_keymap_add_item(keymap, "GRAPH_OT_snap", SKEY, KM_PRESS, KM_SHIFT, 0); From 0093ea2a79648c56a30fe65494134a09f91054b7 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 15 Oct 2012 03:56:01 +0000 Subject: [PATCH 235/347] safety NULL check for r51327, don't assume ED_object_modifier_add() succeeds. --- source/blender/editors/object/object_relations.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index b7efe9189d8..447ba29e203 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -679,21 +679,27 @@ int ED_object_parent_set(ReportList *reports, Main *bmain, Scene *scene, Object switch (partype) { case PAR_CURVE: /* curve deform */ - if (modifiers_isDeformedByCurve(ob) != par) { + if ( modifiers_isDeformedByCurve(ob) != par) { md = ED_object_modifier_add(reports, bmain, scene, ob, NULL, eModifierType_Curve); - ((CurveModifierData *)md)->object = par; + if (md) { + ((CurveModifierData *)md)->object = par; + } } break; case PAR_LATTICE: /* lattice deform */ if (modifiers_isDeformedByLattice(ob) != par) { md = ED_object_modifier_add(reports, bmain, scene, ob, NULL, eModifierType_Lattice); - ((LatticeModifierData *)md)->object = par; + if (md) { + ((LatticeModifierData *)md)->object = par; + } } break; default: /* armature deform */ if (modifiers_isDeformedByArmature(ob) != par) { md = ED_object_modifier_add(reports, bmain, scene, ob, NULL, eModifierType_Armature); - ((ArmatureModifierData *)md)->object = par; + if (md) { + ((ArmatureModifierData *)md)->object = par; + } } break; } From 504180674ec920392c0cc0cb0aa2af001b3ae166 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 15 Oct 2012 04:16:34 +0000 Subject: [PATCH 236/347] style cleanup: bge --- .../render/intern/source/shadeoutput.c | 7 +- .../Converter/KX_ConvertActuators.cpp | 357 +++++++++--------- .../Converter/KX_ConvertActuators.h | 18 +- source/gameengine/Ketsji/KX_Scene.cpp | 22 +- 4 files changed, 205 insertions(+), 199 deletions(-) diff --git a/source/blender/render/intern/source/shadeoutput.c b/source/blender/render/intern/source/shadeoutput.c index 873657ec6ba..31743b22c75 100644 --- a/source/blender/render/intern/source/shadeoutput.c +++ b/source/blender/render/intern/source/shadeoutput.c @@ -468,9 +468,10 @@ static float area_lamp_energy(float (*area)[3], const float co[3], const float v /* cross product */ #define CROSS(dest, a, b) \ - { dest[0]= a[1] * b[2] - a[2] * b[1]; \ - dest[1]= a[2] * b[0] - a[0] * b[2]; \ - dest[2]= a[0] * b[1] - a[1] * b[0]; \ + { \ + dest[0]= a[1] * b[2] - a[2] * b[1]; \ + dest[1]= a[2] * b[0] - a[0] * b[2]; \ + dest[2]= a[0] * b[1] - a[1] * b[0]; \ } (void)0 CROSS(cross[0], vec[0], vec[1]); diff --git a/source/gameengine/Converter/KX_ConvertActuators.cpp b/source/gameengine/Converter/KX_ConvertActuators.cpp index cc5bf4ccbbc..ea2b85f8c5e 100644 --- a/source/gameengine/Converter/KX_ConvertActuators.cpp +++ b/source/gameengine/Converter/KX_ConvertActuators.cpp @@ -104,22 +104,25 @@ #include "BL_BlenderDataConversion.h" /** - * KX_BLENDERTRUNC needed to round 'almost' zero values to zero, else velocities etc. are incorrectly set + * KX_flt_trunc needed to round 'almost' zero values to zero, else velocities etc. are incorrectly set */ -#define KX_BLENDERTRUNC(x) (( x < 0.0001f && x > -0.0001f ) ? 0.0f : x) +BLI_INLINE float KX_flt_trunc(const float x) +{ + return ( x < 0.0001f && x > -0.0001f ) ? 0.0f : x; +} void BL_ConvertActuators(const char* maggiename, - struct Object* blenderobject, - KX_GameObject* gameobj, - SCA_LogicManager* logicmgr, - KX_Scene* scene, - KX_KetsjiEngine* ketsjiEngine, - int activeLayerBitInfo, - bool isInActiveLayer, - RAS_IRenderTools* rendertools, - KX_BlenderSceneConverter* converter - ) + struct Object* blenderobject, + KX_GameObject* gameobj, + SCA_LogicManager* logicmgr, + KX_Scene* scene, + KX_KetsjiEngine* ketsjiEngine, + int activeLayerBitInfo, + bool isInActiveLayer, + RAS_IRenderTools* rendertools, + KX_BlenderSceneConverter* converter + ) { int uniqueint = 0; @@ -145,20 +148,23 @@ void BL_ConvertActuators(const char* maggiename, { bObjectActuator* obact = (bObjectActuator*) bact->data; KX_GameObject* obref = NULL; - MT_Vector3 forcevec(KX_BLENDERTRUNC(obact->forceloc[0]), - KX_BLENDERTRUNC(obact->forceloc[1]), - KX_BLENDERTRUNC(obact->forceloc[2])); - MT_Vector3 torquevec(obact->forcerot[0],obact->forcerot[1],obact->forcerot[2]); - MT_Vector3 dlocvec ( KX_BLENDERTRUNC(obact->dloc[0]), - KX_BLENDERTRUNC(obact->dloc[1]), - KX_BLENDERTRUNC(obact->dloc[2])); - MT_Vector3 drotvec ( KX_BLENDERTRUNC(obact->drot[0]),obact->drot[1],obact->drot[2]); - MT_Vector3 linvelvec ( KX_BLENDERTRUNC(obact->linearvelocity[0]), - KX_BLENDERTRUNC(obact->linearvelocity[1]), - KX_BLENDERTRUNC(obact->linearvelocity[2])); - MT_Vector3 angvelvec ( KX_BLENDERTRUNC(obact->angularvelocity[0]), - KX_BLENDERTRUNC(obact->angularvelocity[1]), - KX_BLENDERTRUNC(obact->angularvelocity[2])); + MT_Vector3 forcevec(KX_flt_trunc(obact->forceloc[0]), + KX_flt_trunc(obact->forceloc[1]), + KX_flt_trunc(obact->forceloc[2])); + MT_Vector3 torquevec(obact->forcerot[0], + obact->forcerot[1], + obact->forcerot[2]); + MT_Vector3 dlocvec(KX_flt_trunc(obact->dloc[0]), + KX_flt_trunc(obact->dloc[1]), + KX_flt_trunc(obact->dloc[2])); + MT_Vector3 drotvec(KX_flt_trunc(obact->drot[0]), + obact->drot[1],obact->drot[2]); + MT_Vector3 linvelvec(KX_flt_trunc(obact->linearvelocity[0]), + KX_flt_trunc(obact->linearvelocity[1]), + KX_flt_trunc(obact->linearvelocity[2])); + MT_Vector3 angvelvec(KX_flt_trunc(obact->angularvelocity[0]), + KX_flt_trunc(obact->angularvelocity[1]), + KX_flt_trunc(obact->angularvelocity[2])); short damping = obact->damping; /* Blender uses a bit vector internally for the local-flags. In */ @@ -180,17 +186,17 @@ void BL_ConvertActuators(const char* maggiename, obref = converter->FindGameObject(obact->reference); } - KX_ObjectActuator* tmpbaseact = new KX_ObjectActuator(gameobj, - obref, - forcevec.getValue(), - torquevec.getValue(), - dlocvec.getValue(), - drotvec.getValue(), - linvelvec.getValue(), - angvelvec.getValue(), - damping, - bitLocalFlag - ); + KX_ObjectActuator* tmpbaseact = new KX_ObjectActuator( + gameobj, + obref, + forcevec.getValue(), + torquevec.getValue(), + dlocvec.getValue(), + drotvec.getValue(), + linvelvec.getValue(), + angvelvec.getValue(), + damping, + bitLocalFlag); baseact = tmpbaseact; break; } @@ -209,22 +215,22 @@ void BL_ConvertActuators(const char* maggiename, if (actact->flag & ACT_IPOCHILD) ipo_flags |= BL_Action::ACT_IPOFLAG_CHILD; BL_ActionActuator* tmpbaseact = new BL_ActionActuator( - gameobj, - propname, - propframe, - actact->sta, - actact->end, - actact->act, - actact->type, // + 1, because Blender starts to count at zero, - actact->blendin, - actact->priority, - actact->layer, - actact->layer_weight, - ipo_flags, - actact->end_reset, - actact->stridelength - // Ketsji at 1, because zero is reserved for "NoDef" - ); + gameobj, + propname, + propframe, + actact->sta, + actact->end, + actact->act, + actact->type, // + 1, because Blender starts to count at zero, + actact->blendin, + actact->priority, + actact->layer, + actact->layer_weight, + ipo_flags, + actact->end_reset, + actact->stridelength + // Ketsji at 1, because zero is reserved for "NoDef" + ); baseact= tmpbaseact; break; } @@ -236,18 +242,17 @@ void BL_ConvertActuators(const char* maggiename, STR_String propframe = (actact->frameProp ? actact->frameProp : ""); BL_ShapeActionActuator* tmpbaseact = new BL_ShapeActionActuator( - gameobj, - propname, - propframe, - actact->sta, - actact->end, - actact->act, - actact->type, // + 1, because Blender starts to count at zero, - actact->blendin, - actact->priority, - actact->stridelength - // Ketsji at 1, because zero is reserved for "NoDef" - ); + gameobj, + propname, + propframe, + actact->sta, + actact->end, + actact->act, + actact->type, // + 1, because Blender starts to count at zero, + actact->blendin, + actact->priority, + actact->stridelength); + // Ketsji at 1, because zero is reserved for "NoDef" baseact= tmpbaseact; break; } @@ -266,17 +271,17 @@ void BL_ConvertActuators(const char* maggiename, bool ipo_add = (ipoact->flag & ACT_IPOADD); KX_IpoActuator* tmpbaseact = new KX_IpoActuator( - gameobj, - propname , - frameProp, - ipoact->sta, - ipoact->end, - ipochild, - ipoact->type + 1, // + 1, because Blender starts to count at zero, - // Ketsji at 1, because zero is reserved for "NoDef" - ipo_as_force, - ipo_add, - local); + gameobj, + propname , + frameProp, + ipoact->sta, + ipoact->end, + ipochild, + ipoact->type + 1, // + 1, because Blender starts to count at zero, + // Ketsji at 1, because zero is reserved for "NoDef" + ipo_as_force, + ipo_add, + local); baseact = tmpbaseact; break; } @@ -292,14 +297,14 @@ void BL_ConvertActuators(const char* maggiename, /* visifac, fac and axis are not copied from the struct... */ /* that's some internal state... */ - KX_CameraActuator *tmpcamact - = new KX_CameraActuator(gameobj, - tmpgob, - camact->height, - camact->min, - camact->max, - camact->axis, - camact->damping); + KX_CameraActuator *tmpcamact = new KX_CameraActuator( + gameobj, + tmpgob, + camact->height, + camact->min, + camact->max, + camact->axis, + camact->damping); baseact = tmpcamact; } break; @@ -332,14 +337,13 @@ void BL_ConvertActuators(const char* maggiename, ? (char*) msgAct->body : ""); - KX_NetworkMessageActuator *tmpmsgact = - new KX_NetworkMessageActuator( - gameobj, // actuator controlling object - scene->GetNetworkScene(), // needed for replication - toPropName, - subject, - bodyType, - body); + KX_NetworkMessageActuator *tmpmsgact = new KX_NetworkMessageActuator( + gameobj, // actuator controlling object + scene->GetNetworkScene(), // needed for replication + toPropName, + subject, + bodyType, + body); baseact = tmpmsgact; break; } @@ -456,11 +460,11 @@ void BL_ConvertActuators(const char* maggiename, destinationObj = converter->FindGameObject(propact->ob); SCA_PropertyActuator* tmppropact = new SCA_PropertyActuator( - gameobj, - destinationObj, - propact->name, - propact->value, - propact->type+1); // + 1 because Ketsji Logic starts + gameobj, + destinationObj, + propact->name, + propact->value, + propact->type + 1); // + 1 because Ketsji Logic starts // with 0 for KX_ACT_PROP_NODEF baseact = tmppropact; break; @@ -490,18 +494,16 @@ void BL_ConvertActuators(const char* maggiename, } } - KX_SCA_AddObjectActuator* tmpaddact = - new KX_SCA_AddObjectActuator( - gameobj, - originalval, - editobact->time, - scene, - editobact->linVelocity, - (editobact->localflag & ACT_EDOB_LOCAL_LINV)!=0, - editobact->angVelocity, - (editobact->localflag & ACT_EDOB_LOCAL_ANGV)!=0 - ); - + KX_SCA_AddObjectActuator* tmpaddact = new KX_SCA_AddObjectActuator( + gameobj, + originalval, + editobact->time, + scene, + editobact->linVelocity, + (editobact->localflag & ACT_EDOB_LOCAL_LINV) != 0, + editobact->angVelocity, + (editobact->localflag & ACT_EDOB_LOCAL_ANGV) != 0); + //editobact->ob to gameobj baseact = tmpaddact; } @@ -518,23 +520,20 @@ void BL_ConvertActuators(const char* maggiename, RAS_MeshObject *tmpmesh = NULL; if (editobact->me) tmpmesh = BL_ConvertMesh( - editobact->me, - blenderobject, - scene, - converter - ); + editobact->me, + blenderobject, + scene, + converter + ); - KX_SCA_ReplaceMeshActuator* tmpreplaceact - = new KX_SCA_ReplaceMeshActuator( - gameobj, - tmpmesh, - scene, - (editobact->flag & ACT_EDOB_REPLACE_MESH_NOGFX)==0, - (editobact->flag & ACT_EDOB_REPLACE_MESH_PHYS)!=0 - - ); - - baseact = tmpreplaceact; + KX_SCA_ReplaceMeshActuator* tmpreplaceact = new KX_SCA_ReplaceMeshActuator( + gameobj, + tmpmesh, + scene, + (editobact->flag & ACT_EDOB_REPLACE_MESH_NOGFX) == 0, + (editobact->flag & ACT_EDOB_REPLACE_MESH_PHYS) != 0); + + baseact = tmpreplaceact; } break; case ACT_EDOB_TRACK_TO: @@ -543,25 +542,23 @@ void BL_ConvertActuators(const char* maggiename, if (editobact->ob) originalval = converter->FindGameObject(editobact->ob); - KX_TrackToActuator* tmptrackact - = new KX_TrackToActuator(gameobj, - originalval, - editobact->time, - editobact->flag, - blenderobject->trackflag, - blenderobject->upflag - ); - baseact = tmptrackact; + KX_TrackToActuator* tmptrackact = new KX_TrackToActuator( + gameobj, + originalval, + editobact->time, + editobact->flag, + blenderobject->trackflag, + blenderobject->upflag); + baseact = tmptrackact; break; } case ACT_EDOB_DYNAMICS: { - KX_SCA_DynamicActuator* tmpdynact - = new KX_SCA_DynamicActuator(gameobj, - editobact->dyn_operation, - editobact->mass - ); - baseact = tmpdynact; + KX_SCA_DynamicActuator* tmpdynact = new KX_SCA_DynamicActuator( + gameobj, + editobact->dyn_operation, + editobact->mass); + baseact = tmpdynact; } } break; @@ -693,17 +690,17 @@ void BL_ConvertActuators(const char* maggiename, ; /* error */ } } - KX_ConstraintActuator *tmpconact - = new KX_ConstraintActuator(gameobj, - conact->damp, - conact->rotdamp, - min, - max, - conact->maxrot, - locrot, - conact->time, - conact->flag, - prop); + KX_ConstraintActuator *tmpconact = new KX_ConstraintActuator( + gameobj, + conact->damp, + conact->rotdamp, + min, + max, + conact->maxrot, + locrot, + conact->time, + conact->flag, + prop); baseact = tmpconact; break; } @@ -776,13 +773,14 @@ void BL_ConvertActuators(const char* maggiename, default: ; /* flag error */ } - tmpsceneact = new KX_SceneActuator(gameobj, - mode, - scene, - ketsjiEngine, - nextSceneName, - cam); - baseact = tmpsceneact; + tmpsceneact = new KX_SceneActuator( + gameobj, + mode, + scene, + ketsjiEngine, + nextSceneName, + cam); + baseact = tmpsceneact; break; } case ACT_GAME: @@ -831,13 +829,14 @@ void BL_ConvertActuators(const char* maggiename, default: ; /* flag error */ } - tmpgameact = new KX_GameActuator(gameobj, - mode, - filename, - loadinganimationname, - scene, - ketsjiEngine); - baseact = tmpgameact; + tmpgameact = new KX_GameActuator( + gameobj, + mode, + filename, + loadinganimationname, + scene, + ketsjiEngine); + baseact = tmpgameact; break; } @@ -904,12 +903,13 @@ void BL_ConvertActuators(const char* maggiename, default: ; /* error */ } - tmprandomact = new SCA_RandomActuator(gameobj, - seedArg, - modeArg, - paraArg1, - paraArg2, - randAct->propname); + tmprandomact = new SCA_RandomActuator( + gameobj, + seedArg, + modeArg, + paraArg1, + paraArg2, + randAct->propname); baseact = tmprandomact; } break; @@ -998,8 +998,9 @@ void BL_ConvertActuators(const char* maggiename, break; } - tmp = new SCA_2DFilterActuator(gameobj, filtermode, _2dfilter->flag, - _2dfilter->float_arg,_2dfilter->int_arg,ketsjiEngine->GetRasterizer(),scene); + tmp = new SCA_2DFilterActuator(gameobj, filtermode, _2dfilter->flag, + _2dfilter->float_arg, _2dfilter->int_arg, + ketsjiEngine->GetRasterizer(), scene); if (_2dfilter->text) { @@ -1054,7 +1055,15 @@ void BL_ConvertActuators(const char* maggiename, bArmatureActuator* armAct = (bArmatureActuator*) bact->data; KX_GameObject *tmpgob = converter->FindGameObject(armAct->target); KX_GameObject *subgob = converter->FindGameObject(armAct->subtarget); - BL_ArmatureActuator* tmparmact = new BL_ArmatureActuator(gameobj, armAct->type, armAct->posechannel, armAct->constraint, tmpgob, subgob, armAct->weight, armAct->influence); + BL_ArmatureActuator* tmparmact = new BL_ArmatureActuator( + gameobj, + armAct->type, + armAct->posechannel, + armAct->constraint, + tmpgob, + subgob, + armAct->weight, + armAct->influence); baseact = tmparmact; break; } diff --git a/source/gameengine/Converter/KX_ConvertActuators.h b/source/gameengine/Converter/KX_ConvertActuators.h index 596c8cab936..385d274bf89 100644 --- a/source/gameengine/Converter/KX_ConvertActuators.h +++ b/source/gameengine/Converter/KX_ConvertActuators.h @@ -33,14 +33,14 @@ #define __KX_CONVERTACTUATORS_H__ void BL_ConvertActuators(const char* maggiename, - struct Object* blenderobject, - class KX_GameObject* gameobj, - class SCA_LogicManager* logicmgr, - class KX_Scene* scene, - class KX_KetsjiEngine* ketsjiEngine, - int activeLayerBitInfo, - bool isInActiveLayer, - class RAS_IRenderTools* rendertools, - class KX_BlenderSceneConverter* converter); + struct Object* blenderobject, + class KX_GameObject* gameobj, + class SCA_LogicManager* logicmgr, + class KX_Scene* scene, + class KX_KetsjiEngine* ketsjiEngine, + int activeLayerBitInfo, + bool isInActiveLayer, + class RAS_IRenderTools* rendertools, + class KX_BlenderSceneConverter* converter); #endif /* __KX_CONVERTACTUATORS_H__ */ diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp index 75605fb8fd1..a6b7ed3f732 100644 --- a/source/gameengine/Ketsji/KX_Scene.cpp +++ b/source/gameengine/Ketsji/KX_Scene.cpp @@ -1254,9 +1254,9 @@ KX_FontObject* KX_Scene::FindFont(KX_FontObject* font) { list::iterator it = m_fonts.begin(); - while ( (it != m_fonts.end()) - && ((*it) != font) ) { - ++it; + while ((it != m_fonts.end()) && ((*it) != font)) + { + ++it; } return ((it == m_fonts.end()) ? NULL : (*it)); @@ -1268,9 +1268,7 @@ KX_Camera* KX_Scene::FindCamera(KX_Camera* cam) { list::iterator it = m_cameras.begin(); - while ( (it != m_cameras.end()) - && ((*it) != cam) ) - { + while ((it != m_cameras.end()) && ((*it) != cam)) { it++; } @@ -1282,9 +1280,7 @@ KX_Camera* KX_Scene::FindCamera(STR_String& name) { list::iterator it = m_cameras.begin(); - while ( (it != m_cameras.end()) - && ((*it)->GetName() != name) ) - { + while ((it != m_cameras.end()) && ((*it)->GetName() != name)) { it++; } @@ -1509,8 +1505,8 @@ void KX_Scene::CalculateVisibleMeshes(RAS_IRasterizer* rasty,KX_Camera* cam, int cam->GetProjectionMatrix().getValue(pmat); dbvt_culling = m_physicsEnvironment->cullingTest(PhysicsCullingCallback,&info,planes,5,m_dbvt_occlusion_res, - KX_GetActiveEngine()->GetCanvas()->GetViewPort(), - mvmat, pmat); + KX_GetActiveEngine()->GetCanvas()->GetViewPort(), + mvmat, pmat); } if (!dbvt_culling) { // the physics engine couldn't help us, do it the hard way @@ -1639,8 +1635,8 @@ RAS_MaterialBucket* KX_Scene::FindBucket(class RAS_IPolyMaterial* polymat, bool void KX_Scene::RenderBuckets(const MT_Transform & cameratransform, - class RAS_IRasterizer* rasty, - class RAS_IRenderTools* rendertools) + class RAS_IRasterizer* rasty, + class RAS_IRenderTools* rendertools) { m_bucketmanager->Renderbuckets(cameratransform,rasty,rendertools); KX_BlenderMaterial::EndFrame(); From fe53fc8315e47a88107f27b173b087569af3d2d6 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Mon, 15 Oct 2012 04:17:29 +0000 Subject: [PATCH 237/347] Adding some descriptions/tooltips for more keyframe editing operations --- source/blender/editors/space_action/action_edit.c | 4 ++-- source/blender/editors/space_graph/graph_edit.c | 4 ++-- source/blender/makesrna/intern/rna_curve.c | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c index 78277cb8199..eeb297b7f57 100644 --- a/source/blender/editors/space_action/action_edit.c +++ b/source/blender/editors/space_action/action_edit.c @@ -976,8 +976,8 @@ void ACTION_OT_sample(wmOperatorType *ot) /* defines for set extrapolation-type for selected keyframes tool */ static EnumPropertyItem prop_actkeys_expo_types[] = { - {FCURVE_EXTRAPOLATE_CONSTANT, "CONSTANT", 0, "Constant Extrapolation", ""}, - {FCURVE_EXTRAPOLATE_LINEAR, "LINEAR", 0, "Linear Extrapolation", ""}, + {FCURVE_EXTRAPOLATE_CONSTANT, "CONSTANT", 0, "Constant Extrapolation", "Values on endpoint keyframes are held"}, + {FCURVE_EXTRAPOLATE_LINEAR, "LINEAR", 0, "Linear Extrapolation", "Straight-line slope of end segments are extended past the endpoint keyframes"}, {MAKE_CYCLIC_EXPO, "MAKE_CYCLIC", 0, "Make Cyclic (F-Modifier)", "Add Cycles F-Modifier if one doesn't exist already"}, {CLEAR_CYCLIC_EXPO, "CLEAR_CYCLIC", 0, "Clear Cyclic (F-Modifier)", "Remove Cycles F-Modifier if not needed anymore"}, diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c index f16f37df443..30ec32ec0aa 100644 --- a/source/blender/editors/space_graph/graph_edit.c +++ b/source/blender/editors/space_graph/graph_edit.c @@ -1309,8 +1309,8 @@ void GRAPH_OT_sample(wmOperatorType *ot) /* defines for set extrapolation-type for selected keyframes tool */ static EnumPropertyItem prop_graphkeys_expo_types[] = { - {FCURVE_EXTRAPOLATE_CONSTANT, "CONSTANT", 0, "Constant Extrapolation", ""}, - {FCURVE_EXTRAPOLATE_LINEAR, "LINEAR", 0, "Linear Extrapolation", ""}, + {FCURVE_EXTRAPOLATE_CONSTANT, "CONSTANT", 0, "Constant Extrapolation", "Values on endpoint keyframes are held"}, + {FCURVE_EXTRAPOLATE_LINEAR, "LINEAR", 0, "Linear Extrapolation", "Straight-line slope of end segments are extended past the endpoint keyframes"}, {MAKE_CYCLIC_EXPO, "MAKE_CYCLIC", 0, "Make Cyclic (F-Modifier)", "Add Cycles F-Modifier if one doesn't exist already"}, {CLEAR_CYCLIC_EXPO, "CLEAR_CYCLIC", 0, "Clear Cyclic (F-Modifier)", "Remove Cycles F-Modifier if not needed anymore"}, diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c index d7e59f3b9dd..fa4c6fcc650 100644 --- a/source/blender/makesrna/intern/rna_curve.c +++ b/source/blender/makesrna/intern/rna_curve.c @@ -62,9 +62,9 @@ EnumPropertyItem keyframe_handle_type_items[] = { }; EnumPropertyItem beztriple_interpolation_mode_items[] = { - {BEZT_IPO_CONST, "CONSTANT", 0, "Constant", ""}, - {BEZT_IPO_LIN, "LINEAR", 0, "Linear", ""}, - {BEZT_IPO_BEZ, "BEZIER", 0, "Bezier", ""}, + {BEZT_IPO_CONST, "CONSTANT", 0, "Constant", "No interpolation. Value of A gets held until B is encountered"}, + {BEZT_IPO_LIN, "LINEAR", 0, "Linear", "Straight-line interpolation between A and B (i.e. no ease in/out)"}, + {BEZT_IPO_BEZ, "BEZIER", 0, "Bezier", "Smooth interpolation between A and B, with some control over curve shape"}, {0, NULL, 0, NULL, NULL} }; From 27564ed24a8d87a969d66161c487dde2ea9f578b Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 15 Oct 2012 06:12:05 +0000 Subject: [PATCH 238/347] fix for own mistake using freed memory with menus. --- source/blender/editors/interface/interface_handlers.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 80c15ad7b4b..c4440cf07ed 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -6775,9 +6775,13 @@ static int ui_handle_menus_recursive(bContext *C, wmEvent *event, uiPopupBlockHa /* now handle events for our own menu */ if (retval == WM_UI_HANDLER_CONTINUE || event->type == TIMER) { if (submenu && submenu->menuretval) { + int do_ret_out_parent = (submenu->menuretval & UI_RETURN_OUT_PARENT); retval = ui_handle_menu_return_submenu(C, event, menu); - /* we may wan't to quit the submenu and handle the even in this menu */ - if ((retval == WM_UI_HANDLER_BREAK) && (submenu->menuretval & UI_RETURN_OUT_PARENT)) { + submenu = NULL; /* hint not to use this, it may be freed by call above */ + (void)submenu; + /* we may wan't to quit the submenu and handle the even in this menu, + * if its important to use it, check 'data->menu' first */ + if ((retval == WM_UI_HANDLER_BREAK) && do_ret_out_parent) { retval = ui_handle_menu_event(C, event, menu, level); } } From abff7cac7e0c682bba013036418cc3ea384d74de Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 15 Oct 2012 07:47:38 +0000 Subject: [PATCH 239/347] Color Management: remove unused function and get rid of unneeded float->byte conversion --- source/blender/blenkernel/BKE_colortools.h | 1 - source/blender/blenkernel/intern/colortools.c | 58 ------------------- source/blender/blenkernel/intern/tracking.c | 8 +-- .../blender/makesrna/intern/rna_image_api.c | 5 +- 4 files changed, 8 insertions(+), 64 deletions(-) diff --git a/source/blender/blenkernel/BKE_colortools.h b/source/blender/blenkernel/BKE_colortools.h index 728f88b3c16..f30cc57bde4 100644 --- a/source/blender/blenkernel/BKE_colortools.h +++ b/source/blender/blenkernel/BKE_colortools.h @@ -88,7 +88,6 @@ int curvemapping_RGBA_does_something(const struct CurveMapping * void curvemapping_table_RGBA(const struct CurveMapping *cumap, float **array, int *size); /* non-const, these modify the curve */ -void curvemapping_do_ibuf(struct CurveMapping *cumap, struct ImBuf *ibuf); void curvemapping_premultiply(struct CurveMapping *cumap, int restore); diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c index 1bd5786debd..d5d6d31b1e1 100644 --- a/source/blender/blenkernel/intern/colortools.c +++ b/source/blender/blenkernel/intern/colortools.c @@ -835,64 +835,6 @@ void curvemapping_evaluate_premulRGB(const CurveMapping *cumap, unsigned char ve vecout_byte[2] = FTOCHAR(vecout[2]); } - -/* only used for image editor curves */ -void curvemapping_do_ibuf(CurveMapping *cumap, ImBuf *ibuf) -{ - ImBuf *tmpbuf; - int pixel; - float *pix_in; - float col[3]; - int stride = 4; - float *pix_out; - - if (ibuf == NULL) - return; - if (ibuf->rect_float == NULL) - IMB_float_from_rect(ibuf); - else if (ibuf->rect == NULL) - imb_addrectImBuf(ibuf); - - if (!ibuf->rect || !ibuf->rect_float) - return; - - /* work on a temp buffer, so can color manage afterwards. - * No worse off memory wise than comp nodes */ - tmpbuf = IMB_dupImBuf(ibuf); - - curvemapping_premultiply(cumap, 0); - - pix_in = ibuf->rect_float; - pix_out = tmpbuf->rect_float; - - if (ibuf->channels) - stride = ibuf->channels; - - for (pixel = ibuf->x * ibuf->y; pixel > 0; pixel--, pix_in += stride, pix_out += stride) { - if (stride < 3) { - col[0] = curvemap_evaluateF(cumap->cm, *pix_in); - - pix_out[1] = pix_out[2] = pix_out[3] = pix_out[0] = col[0]; - } - else { - curvemapping_evaluate_premulRGBF(cumap, col, pix_in); - pix_out[0] = col[0]; - pix_out[1] = col[1]; - pix_out[2] = col[2]; - if (stride > 3) - pix_out[3] = pix_in[3]; - else - pix_out[3] = 1.f; - } - } - - IMB_rect_from_float(tmpbuf); - SWAP(unsigned int *, tmpbuf->rect, ibuf->rect); - IMB_freeImBuf(tmpbuf); - - curvemapping_premultiply(cumap, 1); -} - int curvemapping_RGBA_does_something(const CurveMapping *cumap) { int a; diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index 7d2fd520c37..89d577201b0 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -1494,7 +1494,8 @@ ImBuf *BKE_tracking_distortion_exec(MovieDistortion *distortion, MovieTracking * ibuf->x, ibuf->y, overscan, ibuf->channels); } - resibuf->userflags |= IB_RECT_INVALID; + if (ibuf->rect) + imb_freerectImBuf(ibuf); } else { if (undistort) { @@ -1512,9 +1513,8 @@ ImBuf *BKE_tracking_distortion_exec(MovieDistortion *distortion, MovieTracking * (void) overscan; (void) undistort; - if (ibuf->rect_float) { - resibuf->userflags |= IB_RECT_INVALID; - } + if (ibuf->rect_float && ibuf->rect) + imb_freerectImBuf(ibuf); #endif return resibuf; diff --git a/source/blender/makesrna/intern/rna_image_api.c b/source/blender/makesrna/intern/rna_image_api.c index ab501909052..d8ae579cd6b 100644 --- a/source/blender/makesrna/intern/rna_image_api.c +++ b/source/blender/makesrna/intern/rna_image_api.c @@ -184,7 +184,10 @@ static void rna_Image_update(Image *image, ReportList *reports) return; } - IMB_rect_from_float(ibuf); + if (ibuf->rect) + IMB_rect_from_float(ibuf); + + ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID; } static void rna_Image_scale(Image *image, ReportList *reports, int width, int height) From da9394f596acba3e93c77479a9906580cddf45d1 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 15 Oct 2012 09:11:17 +0000 Subject: [PATCH 240/347] code cleanup: define sizes of vectors for function args and use C style comments --- source/blender/blenkernel/BKE_armature.h | 2 +- source/blender/blenkernel/BKE_curve.h | 2 +- source/blender/blenkernel/BKE_lattice.h | 2 +- source/blender/blenkernel/BKE_mesh.h | 2 +- source/blender/blenkernel/intern/armature.c | 11 +- source/blender/blenkernel/intern/lattice.c | 14 +- .../blenkernel/intern/navmesh_conversion.c | 330 +++++++++--------- source/blender/bmesh/intern/bmesh_core.c | 6 +- source/blender/bmesh/intern/bmesh_mesh.c | 2 +- source/blender/bmesh/operators/bmo_bevel.c | 2 +- source/blender/bmesh/operators/bmo_utils.c | 15 +- source/blender/python/bmesh/bmesh_py_types.c | 2 +- .../python/bmesh/bmesh_py_types_select.c | 2 +- .../blender/python/intern/bpy_app_handlers.c | 2 +- source/blender/python/intern/bpy_driver.c | 2 +- source/blender/python/intern/bpy_interface.c | 8 +- source/blender/python/intern/bpy_util.c | 13 +- source/blender/render/intern/include/sunsky.h | 2 +- .../render/intern/include/texture_ocean.h | 7 +- .../render/intern/include/volume_precache.h | 4 +- source/blender/render/intern/source/sunsky.c | 2 +- .../render/intern/source/texture_ocean.c | 2 +- .../render/intern/source/volume_precache.c | 6 +- 23 files changed, 223 insertions(+), 217 deletions(-) diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h index 6b9de47836e..b0f372e0bac 100644 --- a/source/blender/blenkernel/BKE_armature.h +++ b/source/blender/blenkernel/BKE_armature.h @@ -99,7 +99,7 @@ void BKE_pose_where_is_bone_tail(struct bPoseChannel *pchan); /* get_objectspace_bone_matrix has to be removed still */ void get_objectspace_bone_matrix(struct Bone *bone, float M_accumulatedMatrix[][4], int root, int posed); void vec_roll_to_mat3(const float vec[3], const float roll, float mat[][3]); -void mat3_to_vec_roll(float mat[][3], float *vec, float *roll); +void mat3_to_vec_roll(float mat[][3], float r_vec[3], float *r_roll); /* Common Conversions Between Co-ordinate Spaces */ void BKE_armature_mat_world_to_pose(struct Object *ob, float inmat[][4], float outmat[][4]); diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h index e6161cebf54..536bbecb79b 100644 --- a/source/blender/blenkernel/BKE_curve.h +++ b/source/blender/blenkernel/BKE_curve.h @@ -108,7 +108,7 @@ void BKE_nurb_free(struct Nurb *nu); struct Nurb *BKE_nurb_duplicate(struct Nurb *nu); void BKE_nurb_test2D(struct Nurb *nu); -void BKE_nurb_minmax(struct Nurb *nu, float *min, float *max); +void BKE_nurb_minmax(struct Nurb *nu, float min[3], float max[3]); void BKE_nurb_makeFaces(struct Nurb *nu, float *coord_array, int rowstride, int resolu, int resolv); void BKE_nurb_makeCurve(struct Nurb *nu, float *coord_array, float *tilt_array, float *radius_array, float *weight_array, int resolu, int stride); diff --git a/source/blender/blenkernel/BKE_lattice.h b/source/blender/blenkernel/BKE_lattice.h index 31626ef4a58..34baa48dbe2 100644 --- a/source/blender/blenkernel/BKE_lattice.h +++ b/source/blender/blenkernel/BKE_lattice.h @@ -46,7 +46,7 @@ struct Lattice *BKE_lattice_add(const char *name); struct Lattice *BKE_lattice_copy(struct Lattice *lt); void BKE_lattice_free(struct Lattice *lt); void BKE_lattice_make_local(struct Lattice *lt); -void calc_lat_fudu(int flag, int res, float *fu, float *du); +void calc_lat_fudu(int flag, int res, float *r_fu, float *r_du); void init_latt_deform(struct Object *oblatt, struct Object *ob); void calc_latt_deform(struct Object *, float co[3], float weight); diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index c14085a559a..9fffb71785b 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -130,7 +130,7 @@ struct Mesh *BKE_mesh_copy(struct Mesh *me); void mesh_update_customdata_pointers(struct Mesh *me, const short do_ensure_tess_cd); void BKE_mesh_make_local(struct Mesh *me); -void BKE_mesh_boundbox_calc(struct Mesh *me, float *loc, float *size); +void BKE_mesh_boundbox_calc(struct Mesh *me, float r_loc[3], float r_size[3]); void BKE_mesh_texspace_calc(struct Mesh *me); float *BKE_mesh_orco_verts_get(struct Object *ob); void BKE_mesh_orco_verts_transform(struct Mesh *me, float (*orco)[3], int totvert, int invert); diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index 6eb1daa1e4f..f5c7cab6019 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -1425,19 +1425,20 @@ void BKE_rotMode_change_values(float quat[4], float eul[3], float axis[3], float * *************************************************************************** */ /* Computes vector and roll based on a rotation. * "mat" must contain only a rotation, and no scaling. */ -void mat3_to_vec_roll(float mat[][3], float vec[3], float *roll) +void mat3_to_vec_roll(float mat[][3], float r_vec[3], float *r_roll) { - if (vec) - copy_v3_v3(vec, mat[1]); + if (r_vec) { + copy_v3_v3(r_vec, mat[1]); + } - if (roll) { + if (r_roll) { float vecmat[3][3], vecmatinv[3][3], rollmat[3][3]; vec_roll_to_mat3(mat[1], 0.0f, vecmat); invert_m3_m3(vecmatinv, vecmat); mul_m3_m3m3(rollmat, vecmatinv, mat); - *roll = (float)atan2(rollmat[2][0], rollmat[2][2]); + *r_roll = atan2f(rollmat[2][0], rollmat[2][2]); } } diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c index bb871f0cfd4..5382ea453eb 100644 --- a/source/blender/blenkernel/intern/lattice.c +++ b/source/blender/blenkernel/intern/lattice.c @@ -64,19 +64,19 @@ #include "BKE_deform.h" -void calc_lat_fudu(int flag, int res, float *fu, float *du) +void calc_lat_fudu(int flag, int res, float *r_fu, float *r_du) { if (res == 1) { - *fu = 0.0; - *du = 0.0; + *r_fu = 0.0; + *r_du = 0.0; } else if (flag & LT_GRID) { - *fu = -0.5f * (res - 1); - *du = 1.0f; + *r_fu = -0.5f * (res - 1); + *r_du = 1.0f; } else { - *fu = -1.0f; - *du = 2.0f / (res - 1); + *r_fu = -1.0f; + *r_du = 2.0f / (res - 1); } } diff --git a/source/blender/blenkernel/intern/navmesh_conversion.c b/source/blender/blenkernel/intern/navmesh_conversion.c index a21878d1d7d..5fe4f8e90ba 100644 --- a/source/blender/blenkernel/intern/navmesh_conversion.c +++ b/source/blender/blenkernel/intern/navmesh_conversion.c @@ -44,36 +44,36 @@ #include "recast-capi.h" -BLI_INLINE float area2(const float* a, const float* b, const float* c) +BLI_INLINE float area2(const float *a, const float *b, const float *c) { return (b[0] - a[0]) * (c[2] - a[2]) - (c[0] - a[0]) * (b[2] - a[2]); } -BLI_INLINE int left(const float* a, const float* b, const float* c) +BLI_INLINE int left(const float *a, const float *b, const float *c) { return area2(a, b, c) < 0; } -int polyNumVerts(const unsigned short* p, const int vertsPerPoly) +int polyNumVerts(const unsigned short *p, const int vertsPerPoly) { int i, nv = 0; - for (i=0; i 0) + if (d > 0.0f) t /= d; - if (t < 0) - t = 0; - else if (t > 1) - t = 1; - dx[0] = a[0] + t*abx[0] - point[0]; - dx[2] = a[2] + t*abx[2] - point[2]; + if (t < 0.0f) + t = 0.0f; + else if (t > 1.0f) + t = 1.0f; + dx[0] = a[0] + t * abx[0] - point[0]; + dx[2] = a[2] + t * abx[2] - point[2]; - return dx[0]*dx[0] + dx[2]*dx[2]; + return dx[0] * dx[0] + dx[2] * dx[2]; } -int buildRawVertIndicesData(DerivedMesh* dm, int *nverts_r, float **verts_r, - int *ntris_r, unsigned short **tris_r, int **trisToFacesMap_r, - int **recastData) +int buildRawVertIndicesData(DerivedMesh *dm, int *nverts_r, float **verts_r, + int *ntris_r, unsigned short **tris_r, int **trisToFacesMap_r, + int **recastData) { int vi, fi, triIdx; int nverts, ntris; @@ -117,49 +118,49 @@ int buildRawVertIndicesData(DerivedMesh* dm, int *nverts_r, float **verts_r, MFace *faces; nverts = dm->getNumVerts(dm); - if (nverts>=0xffff) { + if (nverts >= 0xffff) { printf("Converting navmesh: Error! Too many vertices. Max number of vertices %d\n", 0xffff); return 0; } - verts = MEM_callocN(sizeof(float)*3*nverts, "buildRawVertIndicesData verts"); + verts = MEM_callocN(sizeof(float) * 3 * nverts, "buildRawVertIndicesData verts"); dm->getVertCos(dm, (float(*)[3])verts); - //flip coordinates - for (vi=0; vigetNumTessFaces(dm); faces = dm->getTessFaceArray(dm); ntris = nfaces; - for (fi=0; fiv4) ntris++; } - //copy and transform to triangles (reorder on the run) - trisToFacesMap = MEM_callocN(sizeof(int)*ntris, "buildRawVertIndicesData trisToFacesMap"); - tris = MEM_callocN(sizeof(unsigned short)*3*ntris, "buildRawVertIndicesData tris"); + /* copy and transform to triangles (reorder on the run) */ + trisToFacesMap = MEM_callocN(sizeof(int) * ntris, "buildRawVertIndicesData trisToFacesMap"); + tris = MEM_callocN(sizeof(unsigned short) * 3 * ntris, "buildRawVertIndicesData tris"); tri = tris; triIdx = 0; - for (fi=0; fiv1; - tri[3*triIdx+1] = (unsigned short) face->v3; - tri[3*triIdx+2] = (unsigned short) face->v2; - trisToFacesMap[triIdx++]=fi; + for (fi = 0; fi < nfaces; fi++) { + MFace *face = &faces[fi]; + tri[3 * triIdx + 0] = (unsigned short) face->v1; + tri[3 * triIdx + 1] = (unsigned short) face->v3; + tri[3 * triIdx + 2] = (unsigned short) face->v2; + trisToFacesMap[triIdx++] = fi; if (face->v4) { - tri[3*triIdx+0] = (unsigned short) face->v1; - tri[3*triIdx+1] = (unsigned short) face->v4; - tri[3*triIdx+2] = (unsigned short) face->v3; - trisToFacesMap[triIdx++]=fi; + tri[3 * triIdx + 0] = (unsigned short) face->v1; + tri[3 * triIdx + 1] = (unsigned short) face->v4; + tri[3 * triIdx + 2] = (unsigned short) face->v3; + trisToFacesMap[triIdx++] = fi; } } - //carefully, recast data is just reference to data in derived mesh - *recastData = (int*)CustomData_get_layer(&dm->polyData, CD_RECAST); + /* carefully, recast data is just reference to data in derived mesh */ + *recastData = (int *)CustomData_get_layer(&dm->polyData, CD_RECAST); *nverts_r = nverts; *verts_r = verts; @@ -170,122 +171,122 @@ int buildRawVertIndicesData(DerivedMesh* dm, int *nverts_r, float **verts_r, return 1; } -int buildPolygonsByDetailedMeshes(const int vertsPerPoly, const int npolys, - unsigned short* polys, const unsigned short* dmeshes, - const float* verts, const unsigned short* dtris, - const int* dtrisToPolysMap) +int buildPolygonsByDetailedMeshes(const int vertsPerPoly, const int npolys, + unsigned short *polys, const unsigned short *dmeshes, + const float *verts, const unsigned short *dtris, + const int *dtrisToPolysMap) { int polyidx; int capacity = vertsPerPoly; - unsigned short* newPoly = MEM_callocN(sizeof(unsigned short)*capacity, "buildPolygonsByDetailedMeshes newPoly"); - memset(newPoly, 0xff, sizeof(unsigned short)*capacity); + unsigned short *newPoly = MEM_callocN(sizeof(unsigned short) * capacity, "buildPolygonsByDetailedMeshes newPoly"); + memset(newPoly, 0xff, sizeof(unsigned short) * capacity); - for (polyidx=0; polyidxtolerance) + if (distSq > tolerance) adjustedPoly[adjustedNv++] = cur; } - memcpy(newPoly, adjustedPoly, adjustedNv*sizeof(unsigned short)); + memcpy(newPoly, adjustedPoly, adjustedNv * sizeof(unsigned short)); MEM_freeN(adjustedPoly); nv = adjustedNv; allBorderTraversed = 1; - for (i=0; irecastData[((struct SortContext *)ctx)->trisToFacesMap[*(int*)a]] - - ((struct SortContext *)ctx)->recastData[((struct SortContext *)ctx)->trisToFacesMap[*(int*)b]] ); + return (((struct SortContext *)ctx)->recastData[((struct SortContext *)ctx)->trisToFacesMap[*(int *)a]] - + ((struct SortContext *)ctx)->recastData[((struct SortContext *)ctx)->trisToFacesMap[*(int *)b]]); } -int buildNavMeshData(const int nverts, const float* verts, +int buildNavMeshData(const int nverts, const float *verts, const int ntris, const unsigned short *tris, - const int* recastData, const int* trisToFacesMap, + const int *recastData, const int *trisToFacesMap, int *ndtris_r, unsigned short **dtris_r, int *npolys_r, unsigned short **dmeshes_r, unsigned short **polys_r, int *vertsPerPoly_r, int **dtrisToPolysMap_r, int **dtrisToTrisMap_r) @@ -333,86 +333,86 @@ int buildNavMeshData(const int nverts, const float* verts, return 0; } - trisMapping = MEM_callocN(sizeof(int)*ntris, "buildNavMeshData trisMapping"); + trisMapping = MEM_callocN(sizeof(int) * ntris, "buildNavMeshData trisMapping"); - //sort the triangles by polygon idx - for (i=0; i0) { + for (i = 0; i < ntris; i++) { + if (recastData[trisToFacesMap[trisMapping[i]]] > 0) { validTriStart = i; break; } } - if (validTriStart<0) { + if (validTriStart < 0) { printf("Converting navmesh: Error! No valid polygons in mesh\n"); MEM_freeN(trisMapping); return 0; } - ndtris = ntris-validTriStart; - //fill dtris to faces mapping - dtrisToTrisMap = MEM_callocN(sizeof(int)*ndtris, "buildNavMeshData dtrisToTrisMap"); - memcpy(dtrisToTrisMap, &trisMapping[validTriStart], ndtris*sizeof(int)); + ndtris = ntris - validTriStart; + /* fill dtris to faces mapping */ + dtrisToTrisMap = MEM_callocN(sizeof(int) * ndtris, "buildNavMeshData dtrisToTrisMap"); + memcpy(dtrisToTrisMap, &trisMapping[validTriStart], ndtris * sizeof(int)); MEM_freeN(trisMapping); - //create detailed mesh triangles - copy only valid triangles - //and reserve memory for adjacency info - dtris = MEM_callocN(sizeof(unsigned short)*3*2*ndtris, "buildNavMeshData dtris"); - memset(dtris, 0xffff, sizeof(unsigned short)*3*2*ndtris); - for (i=0; iloops.first); + return bm_loop_reverse_loop(bm, f, f->loops.first); #else return bm_loop_reverse_loop(bm, f); #endif @@ -1186,13 +1186,15 @@ BMFace *bmesh_sfme(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, { #ifdef USE_BMESH_HOLES BMLoopList *lst, *lst2; +#else + int first_loop_f1; #endif BMFace *f2; BMLoop *l_iter, *l_first; BMLoop *v1loop = NULL, *v2loop = NULL, *f1loop = NULL, *f2loop = NULL; BMEdge *e; - int i, len, f1len, f2len, first_loop_f1; + int i, len, f1len, f2len; /* verify that v1 and v2 are in face */ len = f->len; diff --git a/source/blender/bmesh/intern/bmesh_mesh.c b/source/blender/bmesh/intern/bmesh_mesh.c index 0d072da5327..360e2c93de3 100644 --- a/source/blender/bmesh/intern/bmesh_mesh.c +++ b/source/blender/bmesh/intern/bmesh_mesh.c @@ -57,7 +57,7 @@ static void bm_mempool_init(BMesh *bm, const BMAllocTemplate *allocsize) bm_mesh_chunksize_default.totface, BLI_MEMPOOL_ALLOW_ITER); #ifdef USE_BMESH_HOLES - bm->looplistpool = BLI_mempool_create(sizeof(BMLoopList), allocsize[3], allocsize[3], FALSE, FALSE); + bm->looplistpool = BLI_mempool_create(sizeof(BMLoopList), 512, 512, 0); #endif /* allocate one flag pool that we don't get rid of. */ diff --git a/source/blender/bmesh/operators/bmo_bevel.c b/source/blender/bmesh/operators/bmo_bevel.c index 10a9d511c77..e31df2e4444 100644 --- a/source/blender/bmesh/operators/bmo_bevel.c +++ b/source/blender/bmesh/operators/bmo_bevel.c @@ -233,7 +233,7 @@ void bmo_bevel_exec(BMesh *bm, BMOperator *op) } #if 0 - //a bit of cleaner code that, alas, doens't work. + /* a bit of cleaner code that, alas, doens't work. */ /* build edge tag */ BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { if (BMO_elem_flag_test(bm, e->v1, BEVEL_FLAG) || BMO_elem_flag_test(bm, e->v2, BEVEL_FLAG)) { diff --git a/source/blender/bmesh/operators/bmo_utils.c b/source/blender/bmesh/operators/bmo_utils.c index 88ed1250264..7562d7e1da2 100644 --- a/source/blender/bmesh/operators/bmo_utils.c +++ b/source/blender/bmesh/operators/bmo_utils.c @@ -1019,10 +1019,9 @@ void bmo_similar_verts_exec(BMesh *bm, BMOperator *op) void bmo_rotate_uvs_exec(BMesh *bm, BMOperator *op) { - BMOIter fs_iter; /* selected faces iterator */ - BMFace *fs; /* current face */ - BMIter l_iter; /* iteration loop */ - // int n; + BMOIter fs_iter; /* selected faces iterator */ + BMFace *fs; /* current face */ + BMIter l_iter; /* iteration loop */ int dir = BMO_slot_int_get(op, "dir"); @@ -1077,7 +1076,6 @@ void bmo_rotate_uvs_exec(BMesh *bm, BMOperator *op) } } } - } /**************************************************************************** * @@ -1126,10 +1124,9 @@ void bmo_reverse_uvs_exec(BMesh *bm, BMOperator *op) void bmo_rotate_colors_exec(BMesh *bm, BMOperator *op) { - BMOIter fs_iter; /* selected faces iterator */ - BMFace *fs; /* current face */ - BMIter l_iter; /* iteration loop */ - // int n; + BMOIter fs_iter; /* selected faces iterator */ + BMFace *fs; /* current face */ + BMIter l_iter; /* iteration loop */ int dir = BMO_slot_int_get(op, "dir"); diff --git a/source/blender/python/bmesh/bmesh_py_types.c b/source/blender/python/bmesh/bmesh_py_types.c index fd5fa63647b..2cae10101d1 100644 --- a/source/blender/python/bmesh/bmesh_py_types.c +++ b/source/blender/python/bmesh/bmesh_py_types.c @@ -645,7 +645,7 @@ static PyGetSetDef bpy_bmface_getseters[] = { static PyGetSetDef bpy_bmloop_getseters[] = { /* generic */ - // flags are available but not used for loops. + /* flags are available but not used for loops. */ // {(char *)"select", (getter)bpy_bm_elem_hflag_get, (setter)bpy_bm_elem_hflag_set, (char *)bpy_bm_elem_select_doc, (void *)BM_ELEM_SELECT}, // {(char *)"hide", (getter)bpy_bm_elem_hflag_get, (setter)bpy_bm_elem_hflag_set, (char *)bpy_bm_elem_hide_doc, (void *)BM_ELEM_HIDDEN}, {(char *)"tag", (getter)bpy_bm_elem_hflag_get, (setter)bpy_bm_elem_hflag_set, (char *)bpy_bm_elem_tag_doc, (void *)BM_ELEM_TAG}, diff --git a/source/blender/python/bmesh/bmesh_py_types_select.c b/source/blender/python/bmesh/bmesh_py_types_select.c index 85095596a4e..2ff731559d1 100644 --- a/source/blender/python/bmesh/bmesh_py_types_select.c +++ b/source/blender/python/bmesh/bmesh_py_types_select.c @@ -387,7 +387,7 @@ void BPy_BM_init_types_select(void) BPy_BMEditSelSeq_Type.tp_name = "BMEditSelSeq"; BPy_BMEditSelIter_Type.tp_name = "BMEditSelIter"; - BPy_BMEditSelSeq_Type.tp_doc = NULL; // todo + BPy_BMEditSelSeq_Type.tp_doc = NULL; /* todo */ BPy_BMEditSelIter_Type.tp_doc = NULL; BPy_BMEditSelSeq_Type.tp_repr = (reprfunc)NULL; diff --git a/source/blender/python/intern/bpy_app_handlers.c b/source/blender/python/intern/bpy_app_handlers.c index 4d7f2080bbc..90a0444ceae 100644 --- a/source/blender/python/intern/bpy_app_handlers.c +++ b/source/blender/python/intern/bpy_app_handlers.c @@ -284,7 +284,7 @@ void bpy_app_generic_callback(struct Main *UNUSED(main), struct ID *id, void *ar if (PyList_GET_SIZE(cb_list) > 0) { PyGILState_STATE gilstate = PyGILState_Ensure(); - PyObject *args = PyTuple_New(1); // save python creating each call + PyObject *args = PyTuple_New(1); /* save python creating each call */ PyObject *func; PyObject *ret; Py_ssize_t pos; diff --git a/source/blender/python/intern/bpy_driver.c b/source/blender/python/intern/bpy_driver.c index de23b3bf109..9a79616c23b 100644 --- a/source/blender/python/intern/bpy_driver.c +++ b/source/blender/python/intern/bpy_driver.c @@ -280,7 +280,7 @@ float BPY_driver_exec(ChannelDriver *driver, const float evaltime) } -#if 0 // slow, with this can avoid all Py_CompileString above. +#if 0 /* slow, with this can avoid all Py_CompileString above. */ /* execute expression to get a value */ retval = PyRun_String(expr, Py_eval_input, bpy_pydriver_Dict, driver_vars); #else diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c index b628f42e759..f6ab100ca1a 100644 --- a/source/blender/python/intern/bpy_interface.c +++ b/source/blender/python/intern/bpy_interface.c @@ -69,7 +69,7 @@ #include "BPY_extern.h" -#include "../generic/bpy_internal_import.h" // our own imports +#include "../generic/bpy_internal_import.h" /* our own imports */ #include "../generic/py_capi_utils.h" /* inittab initialization functions */ @@ -180,10 +180,10 @@ void BPY_text_free_code(Text *text) void BPY_modules_update(bContext *C) { -#if 0 // slow, this runs all the time poll, draw etc 100's of time a sec. +#if 0 /* slow, this runs all the time poll, draw etc 100's of time a sec. */ PyObject *mod = PyImport_ImportModuleLevel("bpy", NULL, NULL, NULL, 0); PyModule_AddObject(mod, "data", BPY_rna_module()); - PyModule_AddObject(mod, "types", BPY_rna_types()); // atm this does not need updating + PyModule_AddObject(mod, "types", BPY_rna_types()); /* atm this does not need updating */ #endif /* refreshes the main struct */ @@ -268,7 +268,7 @@ void BPY_python_start(int argc, const char **argv) Py_Initialize(); - // PySys_SetArgv(argc, argv); // broken in py3, not a huge deal + // PySys_SetArgv(argc, argv); /* broken in py3, not a huge deal */ /* sigh, why do python guys not have a (char **) version anymore? */ { int i; diff --git a/source/blender/python/intern/bpy_util.c b/source/blender/python/intern/bpy_util.c index 6c61d7540ab..30b6806a796 100644 --- a/source/blender/python/intern/bpy_util.c +++ b/source/blender/python/intern/bpy_util.c @@ -81,7 +81,7 @@ short BPy_reports_to_error(ReportList *reports, PyObject *exception, const short short BPy_errors_to_report(ReportList *reports) { PyObject *pystring; - PyObject *pystring_format = NULL; // workaround, see below + PyObject *pystring_format = NULL; /* workaround, see below */ char *cstring; const char *filename; @@ -110,17 +110,18 @@ short BPy_errors_to_report(ReportList *reports) cstring = _PyUnicode_AsString(pystring); -#if 0 // ARG!. workaround for a bug in blenders use of vsnprintf +#if 0 /* ARG!. workaround for a bug in blenders use of vsnprintf */ BKE_reportf(reports, RPT_ERROR, "%s\nlocation:%s:%d\n", cstring, filename, lineno); #else pystring_format = PyUnicode_FromFormat(TIP_("%s\nlocation:%s:%d\n"), cstring, filename, lineno); cstring = _PyUnicode_AsString(pystring_format); BKE_report(reports, RPT_ERROR, cstring); #endif - - fprintf(stderr, TIP_("%s\nlocation:%s:%d\n"), cstring, filename, lineno); // not exactly needed. just for testing - + + /* not exactly needed. just for testing */ + fprintf(stderr, TIP_("%s\nlocation:%s:%d\n"), cstring, filename, lineno); + Py_DECREF(pystring); - Py_DECREF(pystring_format); // workaround + Py_DECREF(pystring_format); /* workaround */ return 1; } diff --git a/source/blender/render/intern/include/sunsky.h b/source/blender/render/intern/include/sunsky.h index 74e42109be5..04aff810bbb 100644 --- a/source/blender/render/intern/include/sunsky.h +++ b/source/blender/render/intern/include/sunsky.h @@ -69,7 +69,7 @@ typedef struct SunSky { float atm_BetaRM[3]; } SunSky; -void InitSunSky(struct SunSky *sunsky, float turb, float *toSun, float horizon_brightness, +void InitSunSky(struct SunSky *sunsky, float turb, const float toSun[3], float horizon_brightness, float spread, float sun_brightness, float sun_size, float back_scatter, float skyblendfac, short skyblendtype, float sky_exposure, float sky_colorspace); diff --git a/source/blender/render/intern/include/texture_ocean.h b/source/blender/render/intern/include/texture_ocean.h index 7d4110aadf3..121142aa0b0 100644 --- a/source/blender/render/intern/include/texture_ocean.h +++ b/source/blender/render/intern/include/texture_ocean.h @@ -23,4 +23,9 @@ * ***** END GPL LICENSE BLOCK ***** */ -int ocean_texture(struct Tex *tex, float *texvec, struct TexResult *texres); +#ifndef __TEXTURE_OCEAN_H__ +#define __TEXTURE_OCEAN_H__ + +int ocean_texture(struct Tex *tex, const float texvec[2], struct TexResult *texres); + +#endif /* __TEXTURE_OCEAN_H__ */ diff --git a/source/blender/render/intern/include/volume_precache.h b/source/blender/render/intern/include/volume_precache.h index 8e402bc5418..9aa280d8276 100644 --- a/source/blender/render/intern/include/volume_precache.h +++ b/source/blender/render/intern/include/volume_precache.h @@ -30,8 +30,8 @@ */ -void global_bounds_obi(Render *re, ObjectInstanceRen *obi, float *bbmin, float *bbmax); -int point_inside_volume_objectinstance(Render *re, ObjectInstanceRen *obi, float *co); +void global_bounds_obi(Render *re, ObjectInstanceRen *obi, float bbmin[3], float bbmax[3]); +int point_inside_volume_objectinstance(Render *re, ObjectInstanceRen *obi, const float co[3]); void volume_precache(Render *re); void free_volume_precache(Render *re); diff --git a/source/blender/render/intern/source/sunsky.c b/source/blender/render/intern/source/sunsky.c index 94e94b98d26..1288b0305b1 100644 --- a/source/blender/render/intern/source/sunsky.c +++ b/source/blender/render/intern/source/sunsky.c @@ -146,7 +146,7 @@ static float PerezFunction(struct SunSky *sunsky, const float *lam, float theta, * sun_size, controls sun's size * back_scatter, controls back scatter light * */ -void InitSunSky(struct SunSky *sunsky, float turb, float *toSun, float horizon_brightness, +void InitSunSky(struct SunSky *sunsky, float turb, const float toSun[3], float horizon_brightness, float spread, float sun_brightness, float sun_size, float back_scatter, float skyblendfac, short skyblendtype, float sky_exposure, float sky_colorspace) { diff --git a/source/blender/render/intern/source/texture_ocean.c b/source/blender/render/intern/source/texture_ocean.c index b2bc635cba7..a7547479093 100644 --- a/source/blender/render/intern/source/texture_ocean.c +++ b/source/blender/render/intern/source/texture_ocean.c @@ -55,7 +55,7 @@ extern struct Render R; /* ***** actual texture sampling ***** */ -int ocean_texture(Tex *tex, float *texvec, TexResult *texres) +int ocean_texture(Tex *tex, const float texvec[2], TexResult *texres) { OceanTex *ot = tex->ot; ModifierData *md; diff --git a/source/blender/render/intern/source/volume_precache.c b/source/blender/render/intern/source/volume_precache.c index 8a92695a15e..fb7ea38ef68 100644 --- a/source/blender/render/intern/source/volume_precache.c +++ b/source/blender/render/intern/source/volume_precache.c @@ -92,7 +92,7 @@ static int intersect_outside_volume(RayObject *tree, Isect *isect, float *offset } /* Uses ray tracing to check if a point is inside or outside an ObjectInstanceRen */ -static int point_inside_obi(RayObject *tree, ObjectInstanceRen *UNUSED(obi), float *co) +static int point_inside_obi(RayObject *tree, ObjectInstanceRen *UNUSED(obi), const float co[3]) { Isect isect= {{0}}; float dir[3] = {0.0f, 0.0f, 1.0f}; @@ -118,7 +118,7 @@ static int point_inside_obi(RayObject *tree, ObjectInstanceRen *UNUSED(obi), flo } /* find the bounding box of an objectinstance in global space */ -void global_bounds_obi(Render *re, ObjectInstanceRen *obi, float *bbmin, float *bbmax) +void global_bounds_obi(Render *re, ObjectInstanceRen *obi, float bbmin[3], float bbmax[3]) { ObjectRen *obr = obi->obr; VolumePrecache *vp = obi->volume_precache; @@ -826,7 +826,7 @@ void free_volume_precache(Render *re) BLI_freelistN(&re->volumes); } -int point_inside_volume_objectinstance(Render *re, ObjectInstanceRen *obi, float *co) +int point_inside_volume_objectinstance(Render *re, ObjectInstanceRen *obi, const float co[3]) { RayObject *tree; int inside=0; From c5300c638c966d2a0e5d59d1905341c9dd9f3780 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 15 Oct 2012 09:25:03 +0000 Subject: [PATCH 241/347] Solve some issues with smoke when using strict compile flags - Mark some functions as static - ifdef-ed currently unused functions from spectrum.cpp - Fixed missing prototype for smectrum() function --- intern/smoke/intern/spectrum.cpp | 49 +++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 17 deletions(-) diff --git a/intern/smoke/intern/spectrum.cpp b/intern/smoke/intern/spectrum.cpp index 34725c12c92..359f3ab73a9 100644 --- a/intern/smoke/intern/spectrum.cpp +++ b/intern/smoke/intern/spectrum.cpp @@ -35,13 +35,14 @@ #include #include +#include "spectrum.h" /* A colour system is defined by the CIE x and y coordinates of its three primary illuminants and the x and y coordinates of the white point. */ struct colourSystem { - char *name; /* Colour system name */ + const char *name; /* Colour system name */ double xRed, yRed, /* Red x, y */ xGreen, yGreen, /* Green x, y */ xBlue, yBlue, /* Blue x, y */ @@ -68,12 +69,18 @@ struct colourSystem { static struct colourSystem /* Name xRed yRed xGreen yGreen xBlue yBlue White point Gamma */ +#if 0 /* UNUSED */ NTSCsystem = { "NTSC", 0.67, 0.33, 0.21, 0.71, 0.14, 0.08, IlluminantC, GAMMA_REC709 }, EBUsystem = { "EBU (PAL/SECAM)", 0.64, 0.33, 0.29, 0.60, 0.15, 0.06, IlluminantD65, GAMMA_REC709 }, SMPTEsystem = { "SMPTE", 0.630, 0.340, 0.310, 0.595, 0.155, 0.070, IlluminantD65, GAMMA_REC709 }, HDTVsystem = { "HDTV", 0.670, 0.330, 0.210, 0.710, 0.150, 0.060, IlluminantD65, GAMMA_REC709 }, - CIEsystem = { "CIE", 0.7355, 0.2645, 0.2658, 0.7243, 0.1669, 0.0085, IlluminantE, GAMMA_REC709 }, +#endif + + CIEsystem = { "CIE", 0.7355, 0.2645, 0.2658, 0.7243, 0.1669, 0.0085, IlluminantE, GAMMA_REC709 }; + +#if 0 /* UNUSED */ Rec709system = { "CIE REC 709", 0.64, 0.33, 0.30, 0.60, 0.15, 0.06, IlluminantD65, GAMMA_REC709 }; +#endif /* UPVP_TO_XY @@ -81,11 +88,13 @@ static struct colourSystem */ -void upvp_to_xy(double up, double vp, double *xc, double *yc) +#if 0 /* UNUSED */ +static void upvp_to_xy(double up, double vp, double *xc, double *yc) { *xc = (9 * up) / ((6 * up) - (16 * vp) + 12); *yc = (4 * vp) / ((6 * up) - (16 * vp) + 12); } +#endif /* XY_TO_UPVP @@ -93,11 +102,13 @@ void upvp_to_xy(double up, double vp, double *xc, double *yc) */ -void xy_to_upvp(double xc, double yc, double *up, double *vp) +#if 0 /* UNUSED */ +static void xy_to_upvp(double xc, double yc, double *up, double *vp) { *up = (4 * xc) / ((-2 * xc) + (12 * yc) + 3); *vp = (9 * yc) / ((-2 * xc) + (12 * yc) + 3); } +#endif /* XYZ_TO_RGB @@ -117,9 +128,9 @@ void xy_to_upvp(double xc, double yc, double *up, double *vp) */ -void xyz_to_rgb(struct colourSystem *cs, - double xc, double yc, double zc, - double *r, double *g, double *b) +static void xyz_to_rgb(struct colourSystem *cs, + double xc, double yc, double zc, + double *r, double *g, double *b) { double xr, yr, zr, xg, yg, zg, xb, yb, zb; double xw, yw, zw; @@ -165,10 +176,12 @@ void xyz_to_rgb(struct colourSystem *cs, system. This amounts simply to testing whether all the primary weights are non-negative. */ -int inside_gamut(double r, double g, double b) +#if 0 /* UNUSED */ +static int inside_gamut(double r, double g, double b) { return (r >= 0) && (g >= 0) && (b >= 0); } +#endif /* CONSTRAIN_RGB @@ -181,7 +194,7 @@ int inside_gamut(double r, double g, double b) */ -int constrain_rgb(double *r, double *g, double *b) +static int constrain_rgb(double *r, double *g, double *b) { double w; @@ -214,7 +227,8 @@ int constrain_rgb(double *r, double *g, double *b) http://www.poynton.com/GammaFAQ.html */ -void gamma_correct(const struct colourSystem *cs, double *c) +#if 0 /* UNUSED */ +static void gamma_correct(const struct colourSystem *cs, double *c) { double gamma; @@ -235,12 +249,13 @@ void gamma_correct(const struct colourSystem *cs, double *c) } } -void gamma_correct_rgb(const struct colourSystem *cs, double *r, double *g, double *b) +static void gamma_correct_rgb(const struct colourSystem *cs, double *r, double *g, double *b) { gamma_correct(cs, r); gamma_correct(cs, g); gamma_correct(cs, b); } +#endif /* NORM_RGB @@ -249,7 +264,7 @@ void gamma_correct_rgb(const struct colourSystem *cs, double *r, double *g, doub */ -void norm_rgb(double *r, double *g, double *b) +static void norm_rgb(double *r, double *g, double *b) { #define Max(a, b) (((a) > (b)) ? (a) : (b)) double greatest = Max(*r, Max(*g, *b)); @@ -276,8 +291,8 @@ void norm_rgb(double *r, double *g, double *b) x + y + z = 1. */ -void spectrum_to_xyz(double (*spec_intens)(double wavelength), - double *x, double *y, double *z) +static void spectrum_to_xyz(double (*spec_intens)(double wavelength), + double *x, double *y, double *z) { int i; double lambda, X = 0, Y = 0, Z = 0, XYZ; @@ -348,7 +363,7 @@ void spectrum_to_xyz(double (*spec_intens)(double wavelength), double bbTemp = 5000; /* Hidden temperature argument to BB_SPECTRUM. */ -double bb_spectrum(double wavelength) +static double bb_spectrum(double wavelength) { double wlm = wavelength * 1e-9; /* Wavelength in meters */ @@ -356,14 +371,14 @@ double bb_spectrum(double wavelength) (exp(1.4388e-2 / (wlm * bbTemp)) - 1.0); } -void xyz_to_lms(double x, double y, double z, double* l, double* m, double* s) +static void xyz_to_lms(double x, double y, double z, double* l, double* m, double* s) { *l = 0.3897*x + 0.6890*y - 0.0787*z; *m = -0.2298*x + 1.1834*y + 0.0464*z; *s = z; } -void lms_to_xyz(double l, double m, double s, double* x, double *y, double* z) +static void lms_to_xyz(double l, double m, double s, double* x, double *y, double* z) { *x = 1.9102*l - 1.1121*m + 0.2019*s; *y = 0.3709*l + 0.6290*m + 0.0000*s; From c84802f51cfaab85efcb867d9608fe8a58d41f04 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 15 Oct 2012 10:43:10 +0000 Subject: [PATCH 242/347] Motion Tracking: fixed dopesheet left in incorrect state after joining tracks --- source/blender/blenkernel/BKE_tracking.h | 2 +- source/blender/blenkernel/intern/tracking.c | 4 +++- source/blender/editors/space_clip/tracking_ops.c | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/source/blender/blenkernel/BKE_tracking.h b/source/blender/blenkernel/BKE_tracking.h index c14476a3b59..167f7bd831a 100644 --- a/source/blender/blenkernel/BKE_tracking.h +++ b/source/blender/blenkernel/BKE_tracking.h @@ -80,7 +80,7 @@ int BKE_tracking_track_has_marker_at_frame(struct MovieTrackingTrack *track, int int BKE_tracking_track_has_enabled_marker_at_frame(struct MovieTrackingTrack *track, int framenr); void BKE_tracking_track_path_clear(struct MovieTrackingTrack *track, int ref_frame, int action); -void BKE_tracking_tracks_join(struct MovieTrackingTrack *dst_track, struct MovieTrackingTrack *src_track); +void BKE_tracking_tracks_join(struct MovieTracking *tracking, struct MovieTrackingTrack *dst_track, struct MovieTrackingTrack *src_track); struct MovieTrackingTrack *BKE_tracking_track_get_named(struct MovieTracking *tracking, struct MovieTrackingObject *object, diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index 89d577201b0..0d304482060 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -631,7 +631,7 @@ void BKE_tracking_track_path_clear(MovieTrackingTrack *track, int ref_frame, int } } -void BKE_tracking_tracks_join(MovieTrackingTrack *dst_track, MovieTrackingTrack *src_track) +void BKE_tracking_tracks_join(MovieTracking *tracking, MovieTrackingTrack *dst_track, MovieTrackingTrack *src_track) { int i = 0, a = 0, b = 0, tot; MovieTrackingMarker *markers; @@ -734,6 +734,8 @@ void BKE_tracking_tracks_join(MovieTrackingTrack *dst_track, MovieTrackingTrack dst_track->markersnr = i; MEM_freeN(markers); + + BKE_tracking_dopesheet_tag_update(tracking); } MovieTrackingTrack *BKE_tracking_track_get_named(MovieTracking *tracking, MovieTrackingObject *object, const char *name) diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c index 1af6237689c..857d88a9a79 100644 --- a/source/blender/editors/space_clip/tracking_ops.c +++ b/source/blender/editors/space_clip/tracking_ops.c @@ -2766,7 +2766,7 @@ static int join_tracks_exec(bContext *C, wmOperator *op) next = track->next; if (TRACK_VIEW_SELECTED(sc, track) && track != act_track) { - BKE_tracking_tracks_join(act_track, track); + BKE_tracking_tracks_join(tracking, act_track, track); if (tracking->stabilization.rot_track == track) tracking->stabilization.rot_track = act_track; From 0325f5e7369a4d8d2d8b057fab35c20f2ddcfb28 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 15 Oct 2012 11:16:54 +0000 Subject: [PATCH 243/347] Fix #32858: Image appears too dark in Image Editor No need to linearize byte buffer when converting to display space which is data space. --- source/blender/imbuf/intern/colormanagement.c | 42 +++++++++++-------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c index de9cf09e036..ff474d85a8c 100644 --- a/source/blender/imbuf/intern/colormanagement.c +++ b/source/blender/imbuf/intern/colormanagement.c @@ -99,6 +99,7 @@ static pthread_mutex_t processor_lock = BLI_MUTEX_INITIALIZER; typedef struct ColormanageProcessor { OCIO_ConstProcessorRcPtr *processor; CurveMapping *curve_mapping; + int is_data_result; } ColormanageProcessor; /*********************** Color managed cache *************************/ @@ -1207,6 +1208,7 @@ static void *display_buffer_apply_get_linear_buffer(DisplayBufferThread *handle) int predivide = handle->predivide; int is_data = handle->is_data; + int is_data_display = handle->cm_processor->is_data_result; linear_buffer = MEM_callocN(buffer_size * sizeof(float), "color conversion linear buffer"); @@ -1228,7 +1230,7 @@ static void *display_buffer_apply_get_linear_buffer(DisplayBufferThread *handle) *fp = (float)(*cp) / 255.0f; } - if (!is_data) { + if (!is_data && !is_data_display) { /* convert float buffer to scene linear space */ IMB_colormanagement_transform(linear_buffer, width, height, channels, from_colorspace, to_colorspace, predivide); @@ -2347,7 +2349,6 @@ static void partial_buffer_update_rect(ImBuf *ibuf, unsigned char *display_buffe } else if (byte_buffer) { rgba_uchar_to_float(pixel, byte_buffer + linear_index); - IMB_colormanagement_colorspace_to_scene_linear_v3(pixel, rect_colorspace); } @@ -2449,28 +2450,29 @@ ColormanageProcessor *IMB_colormanagement_display_processor_new(const ColorManag const ColorManagedDisplaySettings *display_settings) { ColormanageProcessor *cm_processor; + ColorManagedViewSettings default_view_settings; + const ColorManagedViewSettings *applied_view_settings; + ColorSpace *display_space; cm_processor = MEM_callocN(sizeof(ColormanageProcessor), "colormanagement processor"); - { - ColorManagedViewSettings default_view_settings; - const ColorManagedViewSettings *applied_view_settings; + if (view_settings) { + applied_view_settings = view_settings; + } + else { + init_default_view_settings(display_settings, &default_view_settings); + applied_view_settings = &default_view_settings; + } - if (view_settings) { - applied_view_settings = view_settings; - } - else { - init_default_view_settings(display_settings, &default_view_settings); - applied_view_settings = &default_view_settings; - } + display_space = display_transform_get_colorspace(applied_view_settings, display_settings); + cm_processor->is_data_result = display_space->is_data; - cm_processor->processor = create_display_buffer_processor(applied_view_settings->view_transform, display_settings->display_device, - applied_view_settings->exposure, applied_view_settings->gamma); + cm_processor->processor = create_display_buffer_processor(applied_view_settings->view_transform, display_settings->display_device, + applied_view_settings->exposure, applied_view_settings->gamma); - if (applied_view_settings->flag & COLORMANAGE_VIEW_USE_CURVES) { - cm_processor->curve_mapping = curvemapping_copy(applied_view_settings->curve_mapping); - curvemapping_premultiply(cm_processor->curve_mapping, FALSE); - } + if (applied_view_settings->flag & COLORMANAGE_VIEW_USE_CURVES) { + cm_processor->curve_mapping = curvemapping_copy(applied_view_settings->curve_mapping); + curvemapping_premultiply(cm_processor->curve_mapping, FALSE); } return cm_processor; @@ -2479,9 +2481,13 @@ ColormanageProcessor *IMB_colormanagement_display_processor_new(const ColorManag ColormanageProcessor *IMB_colormanagement_colorspace_processor_new(const char *from_colorspace, const char *to_colorspace) { ColormanageProcessor *cm_processor; + ColorSpace *color_space; cm_processor = MEM_callocN(sizeof(ColormanageProcessor), "colormanagement processor"); + color_space = colormanage_colorspace_get_named(to_colorspace); + cm_processor->is_data_result = color_space->is_data; + cm_processor->processor = create_colorspace_transform_processor(from_colorspace, to_colorspace); return cm_processor; From f5cc313d9da08a3425cc0e4248f71d6b79364390 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 15 Oct 2012 12:54:12 +0000 Subject: [PATCH 244/347] Clamp minimal tile size with Save Buffers and FSAA enabled That was an old check whether tiled EXRs are used during rendering since version 2.42 where there indeed was a special check for tile size in EXR tile code. Now it seems EXR could handle tiles with non-equal size and no extra tile size check happens for EXR. Anyway EXR tile initialization happens after initparts, so clamping size in initparts should be safe for EXR tiles as well. --- .../blender/render/intern/source/initrender.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/source/blender/render/intern/source/initrender.c b/source/blender/render/intern/source/initrender.c index 88c64b44b64..2b564a09024 100644 --- a/source/blender/render/intern/source/initrender.c +++ b/source/blender/render/intern/source/initrender.c @@ -558,20 +558,19 @@ void initparts(Render *re, int do_crop) xparts = re->r.xparts; yparts = re->r.yparts; - /* mininum part size, but for exr tile saving it was checked already */ - if (!(re->r.scemode & (R_EXR_TILE_FILE | R_FULL_SAMPLE))) { - if (re->r.mode & R_PANORAMA) { - if (ceil(re->rectx / (float)xparts) < 8) - xparts = 1 + re->rectx / 8; - } - else + /* minimum part size */ + if (re->r.mode & R_PANORAMA) { + if (ceil(re->rectx / (float)xparts) < 8) + xparts = 1 + re->rectx / 8; + } + else { if (ceil(re->rectx / (float)xparts) < 64) xparts = 1 + re->rectx / 64; - - if (ceil(re->recty / (float)yparts) < 64) - yparts = 1 + re->recty / 64; } + if (ceil(re->recty / (float)yparts) < 64) + yparts = 1 + re->recty / 64; + /* part size */ partx = ceil(re->rectx / (float)xparts); party = ceil(re->recty / (float)yparts); From 3c56c1f68d20365d3afc1065ded3e4889cdcd53f Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 15 Oct 2012 13:02:11 +0000 Subject: [PATCH 245/347] Forget this in svn rev51336 --- source/blender/blenkernel/intern/movieclip.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c index 0aa1f9e0822..6f1c8d952de 100644 --- a/source/blender/blenkernel/intern/movieclip.c +++ b/source/blender/blenkernel/intern/movieclip.c @@ -616,11 +616,6 @@ static ImBuf *get_undistorted_ibuf(MovieClip *clip, struct MovieDistortion *dist else undistibuf = BKE_tracking_undistort_frame(&clip->tracking, ibuf, ibuf->x, ibuf->y, 0.0f); - if (undistibuf->userflags & IB_RECT_INVALID) { - ibuf->userflags &= ~IB_RECT_INVALID; - IMB_rect_from_float(undistibuf); - } - IMB_scaleImBuf(undistibuf, ibuf->x, ibuf->y); return undistibuf; From c2ba1324fb2ee5e18bb0a2bf77b125b0d5caeaf3 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 15 Oct 2012 14:11:30 +0000 Subject: [PATCH 246/347] add support for using ninja to extract build info for qtcreator/netbeans/error-checkers. --- build_files/cmake/project_source_info.py | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/build_files/cmake/project_source_info.py b/build_files/cmake/project_source_info.py index 17a9327a358..d80145b989c 100644 --- a/build_files/cmake/project_source_info.py +++ b/build_files/cmake/project_source_info.py @@ -82,10 +82,20 @@ def makefile_log(): import subprocess import time - print("running make with --dry-run ...") - process = subprocess.Popen(["make", "--always-make", "--dry-run", "--keep-going", "VERBOSE=1"], - stdout=subprocess.PIPE, - ) + # support both make and ninja + make_exe = cmake_cache_var("CMAKE_MAKE_PROGRAM") + make_exe_basename = os.path.basename(make_exe) + + if make_exe_basename.startswith("make"): + print("running 'make' with --dry-run ...") + process = subprocess.Popen([make_exe, "--always-make", "--dry-run", "--keep-going", "VERBOSE=1"], + stdout=subprocess.PIPE, + ) + elif make_exe_basename.startswith("ninja"): + print("running 'ninja' with -t commands ...") + process = subprocess.Popen([make_exe, "-t", "commands"], + stdout=subprocess.PIPE, + ) while process.poll(): time.sleep(1) @@ -145,6 +155,12 @@ def build_info(use_c=True, use_cxx=True, ignore_prefix_list=None): source.append((c, inc_dirs, defs)) + # make relative includes absolute + # not totally essential but useful + for i, f in enumerate(inc_dirs): + if not os.path.isabs(f): + inc_dirs[i] = os.path.abspath(os.path.join(CMAKE_DIR, f)) + # safety check that our includes are ok for f in inc_dirs: if not os.path.exists(f): From e3ea7187cedfb92741dc6667a604a873a56670e7 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 15 Oct 2012 14:26:14 +0000 Subject: [PATCH 247/347] another change needed for qtcreator project generator to work with ninja. --- build_files/cmake/project_info.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/build_files/cmake/project_info.py b/build_files/cmake/project_info.py index a80ae623eb9..7536e93b6ce 100755 --- a/build_files/cmake/project_info.py +++ b/build_files/cmake/project_info.py @@ -133,12 +133,20 @@ def cmake_advanced_info(): """ Extracr includes and defines from cmake. """ + make_exe = cmake_cache_var("CMAKE_MAKE_PROGRAM") + make_exe_basename = os.path.basename(make_exe) + def create_eclipse_project(): print("CMAKE_DIR %r" % CMAKE_DIR) if sys.platform == "win32": cmd = 'cmake "%s" -G"Eclipse CDT4 - MinGW Makefiles"' % CMAKE_DIR else: - cmd = 'cmake "%s" -G"Eclipse CDT4 - Unix Makefiles"' % CMAKE_DIR + if make_exe_basename.startswith("make"): + cmd = 'cmake "%s" -G"Eclipse CDT4 - Unix Makefiles"' % CMAKE_DIR + elif make_exe_basename.startswith("ninja"): + cmd = 'cmake "%s" -G"Eclipse CDT4 - Ninja"' % CMAKE_DIR + else: + raise Exception("Unknown make program %r" % make_exe) os.system(cmd) From 827c70abd8c81089af13c4738e0586bf44e501ea Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Mon, 15 Oct 2012 16:29:23 +0000 Subject: [PATCH 248/347] Update to stable Eigen 3.1.1 - Fixes several bugs within the Eigen library: http://eigen.tuxfamily.org/index.php?title=ChangeLog#Eigen_3.1.1 --- extern/Eigen3/Eigen/Cholesky | 7 +- extern/Eigen3/Eigen/CholmodSupport | 45 + extern/Eigen3/Eigen/Core | 60 +- extern/Eigen3/Eigen/Eigen2Support | 46 +- extern/Eigen3/Eigen/Eigenvalues | 10 +- extern/Eigen3/Eigen/Geometry | 4 - extern/Eigen3/Eigen/Householder | 4 - extern/Eigen3/Eigen/IterativeLinearSolvers | 40 + extern/Eigen3/Eigen/Jacobi | 4 - extern/Eigen3/Eigen/LU | 7 +- extern/Eigen3/Eigen/LeastSquares | 4 - extern/Eigen3/Eigen/OrderingMethods | 23 + extern/Eigen3/Eigen/PaStiXSupport | 46 + extern/Eigen3/Eigen/PardisoSupport | 30 + extern/Eigen3/Eigen/QR | 8 +- extern/Eigen3/Eigen/SVD | 7 +- extern/Eigen3/Eigen/Sparse | 66 +- extern/Eigen3/Eigen/SparseCholesky | 30 + extern/Eigen3/Eigen/SparseCore | 66 + extern/Eigen3/Eigen/StdDeque | 21 +- extern/Eigen3/Eigen/StdList | 21 +- extern/Eigen3/Eigen/StdVector | 21 +- extern/Eigen3/Eigen/SuperLUSupport | 59 + extern/Eigen3/Eigen/UmfPackSupport | 36 + extern/Eigen3/Eigen/src/Cholesky/LDLT.h | 172 ++- extern/Eigen3/Eigen/src/Cholesky/LLT.h | 172 ++- extern/Eigen3/Eigen/src/Cholesky/LLT_MKL.h | 102 ++ .../Eigen/src/CholmodSupport/CholmodSupport.h | 579 +++++++++ extern/Eigen3/Eigen/src/Core/Array.h | 24 +- extern/Eigen3/Eigen/src/Core/ArrayBase.h | 31 +- extern/Eigen3/Eigen/src/Core/ArrayWrapper.h | 53 +- extern/Eigen3/Eigen/src/Core/Assign.h | 132 +- extern/Eigen3/Eigen/src/Core/Assign_MKL.h | 224 ++++ extern/Eigen3/Eigen/src/Core/BandMatrix.h | 26 +- extern/Eigen3/Eigen/src/Core/Block.h | 46 +- extern/Eigen3/Eigen/src/Core/BooleanRedux.h | 37 +- .../Eigen3/Eigen/src/Core/CommaInitializer.h | 25 +- extern/Eigen3/Eigen/src/Core/CwiseBinaryOp.h | 29 +- extern/Eigen3/Eigen/src/Core/CwiseNullaryOp.h | 49 +- extern/Eigen3/Eigen/src/Core/CwiseUnaryOp.h | 27 +- extern/Eigen3/Eigen/src/Core/CwiseUnaryView.h | 27 +- extern/Eigen3/Eigen/src/Core/DenseBase.h | 28 +- .../Eigen3/Eigen/src/Core/DenseCoeffsBase.h | 33 +- extern/Eigen3/Eigen/src/Core/DenseStorage.h | 47 +- extern/Eigen3/Eigen/src/Core/Diagonal.h | 59 +- extern/Eigen3/Eigen/src/Core/DiagonalMatrix.h | 31 +- .../Eigen3/Eigen/src/Core/DiagonalProduct.h | 28 +- extern/Eigen3/Eigen/src/Core/Dot.h | 33 +- extern/Eigen3/Eigen/src/Core/EigenBase.h | 24 +- extern/Eigen3/Eigen/src/Core/Flagged.h | 25 +- .../Eigen/src/Core/ForceAlignedAccess.h | 25 +- extern/Eigen3/Eigen/src/Core/Functors.h | 115 +- extern/Eigen3/Eigen/src/Core/Fuzzy.h | 29 +- extern/Eigen3/Eigen/src/Core/GeneralProduct.h | 613 +++++++++ .../Eigen3/Eigen/src/Core/GenericPacketMath.h | 27 +- .../Eigen3/Eigen/src/Core/GlobalFunctions.h | 48 +- extern/Eigen3/Eigen/src/Core/IO.h | 27 +- extern/Eigen3/Eigen/src/Core/Map.h | 25 +- extern/Eigen3/Eigen/src/Core/MapBase.h | 23 +- extern/Eigen3/Eigen/src/Core/MathFunctions.h | 41 +- extern/Eigen3/Eigen/src/Core/Matrix.h | 44 +- extern/Eigen3/Eigen/src/Core/MatrixBase.h | 36 +- extern/Eigen3/Eigen/src/Core/NestByValue.h | 25 +- extern/Eigen3/Eigen/src/Core/NoAlias.h | 25 +- extern/Eigen3/Eigen/src/Core/NumTraits.h | 41 +- .../Eigen3/Eigen/src/Core/PermutationMatrix.h | 31 +- .../Eigen3/Eigen/src/Core/PlainObjectBase.h | 103 +- extern/Eigen3/Eigen/src/Core/Product.h | 647 +--------- extern/Eigen3/Eigen/src/Core/ProductBase.h | 32 +- extern/Eigen3/Eigen/src/Core/Random.h | 25 +- extern/Eigen3/Eigen/src/Core/Redux.h | 64 +- extern/Eigen3/Eigen/src/Core/Replicate.h | 33 +- extern/Eigen3/Eigen/src/Core/ReturnByValue.h | 25 +- extern/Eigen3/Eigen/src/Core/Reverse.h | 32 +- extern/Eigen3/Eigen/src/Core/Select.h | 46 +- .../Eigen3/Eigen/src/Core/SelfAdjointView.h | 41 +- .../Eigen3/Eigen/src/Core/SelfCwiseBinaryOp.h | 35 +- .../Eigen3/Eigen/src/Core/SolveTriangular.h | 47 +- extern/Eigen3/Eigen/src/Core/StableNorm.h | 31 +- extern/Eigen3/Eigen/src/Core/Stride.h | 25 +- extern/Eigen3/Eigen/src/Core/Swap.h | 36 +- extern/Eigen3/Eigen/src/Core/Transpose.h | 31 +- extern/Eigen3/Eigen/src/Core/Transpositions.h | 27 +- .../Eigen3/Eigen/src/Core/TriangularMatrix.h | 57 +- extern/Eigen3/Eigen/src/Core/VectorBlock.h | 24 +- extern/Eigen3/Eigen/src/Core/VectorwiseOp.h | 109 +- extern/Eigen3/Eigen/src/Core/Visitor.h | 31 +- .../Eigen/src/Core/arch/AltiVec/Complex.h | 27 +- .../Eigen/src/Core/arch/AltiVec/PacketMath.h | 29 +- .../Eigen/src/Core/arch/Default/Settings.h | 21 +- .../Eigen3/Eigen/src/Core/arch/NEON/Complex.h | 25 +- .../Eigen/src/Core/arch/NEON/PacketMath.h | 28 +- .../Eigen3/Eigen/src/Core/arch/SSE/Complex.h | 31 +- .../Eigen/src/Core/arch/SSE/MathFunctions.h | 29 +- .../Eigen/src/Core/arch/SSE/PacketMath.h | 52 +- .../src/Core/products/CoeffBasedProduct.h | 63 +- .../Core/products/GeneralBlockPanelKernel.h | 275 ++-- .../src/Core/products/GeneralMatrixMatrix.h | 43 +- .../products/GeneralMatrixMatrixTriangular.h | 41 +- .../GeneralMatrixMatrixTriangular_MKL.h | 146 +++ .../Core/products/GeneralMatrixMatrix_MKL.h | 118 ++ .../src/Core/products/GeneralMatrixVector.h | 41 +- .../Core/products/GeneralMatrixVector_MKL.h | 131 ++ .../Eigen/src/Core/products/Parallelizer.h | 47 +- .../Core/products/SelfadjointMatrixMatrix.h | 29 +- .../products/SelfadjointMatrixMatrix_MKL.h | 295 +++++ .../Core/products/SelfadjointMatrixVector.h | 50 +- .../products/SelfadjointMatrixVector_MKL.h | 114 ++ .../src/Core/products/SelfadjointProduct.h | 31 +- .../Core/products/SelfadjointRank2Update.h | 29 +- .../Core/products/TriangularMatrixMatrix.h | 112 +- .../products/TriangularMatrixMatrix_MKL.h | 309 +++++ .../Core/products/TriangularMatrixVector.h | 101 +- .../products/TriangularMatrixVector_MKL.h | 247 ++++ .../Core/products/TriangularSolverMatrix.h | 114 +- .../products/TriangularSolverMatrix_MKL.h | 155 +++ .../Core/products/TriangularSolverVector.h | 25 +- extern/Eigen3/Eigen/src/Core/util/BlasUtil.h | 47 +- extern/Eigen3/Eigen/src/Core/util/Constants.h | 78 +- .../src/Core/util/DisableStupidWarnings.h | 4 +- .../Eigen/src/Core/util/ForwardDeclarations.h | 27 +- .../Eigen3/Eigen/src/Core/util/MKL_support.h | 109 ++ extern/Eigen3/Eigen/src/Core/util/Macros.h | 44 +- extern/Eigen3/Eigen/src/Core/util/Memory.h | 105 +- extern/Eigen3/Eigen/src/Core/util/Meta.h | 42 +- extern/Eigen3/Eigen/src/Core/util/NonMPL2.h | 3 + .../Eigen3/Eigen/src/Core/util/StaticAssert.h | 45 +- extern/Eigen3/Eigen/src/Core/util/XprHelper.h | 60 +- extern/Eigen3/Eigen/src/Eigen2Support/Block.h | 25 +- extern/Eigen3/Eigen/src/Eigen2Support/Cwise.h | 25 +- .../Eigen/src/Eigen2Support/CwiseOperators.h | 25 +- .../src/Eigen2Support/Geometry/AlignedBox.h | 33 +- .../Eigen/src/Eigen2Support/Geometry/All.h | 2 +- .../src/Eigen2Support/Geometry/AngleAxis.h | 24 +- .../src/Eigen2Support/Geometry/Hyperplane.h | 25 +- .../Eigen2Support/Geometry/ParametrizedLine.h | 24 +- .../src/Eigen2Support/Geometry/Quaternion.h | 43 +- .../src/Eigen2Support/Geometry/Rotation2D.h | 24 +- .../src/Eigen2Support/Geometry/RotationBase.h | 31 +- .../src/Eigen2Support/Geometry/Scaling.h | 24 +- .../src/Eigen2Support/Geometry/Transform.h | 24 +- .../src/Eigen2Support/Geometry/Translation.h | 24 +- extern/Eigen3/Eigen/src/Eigen2Support/LU.h | 25 +- extern/Eigen3/Eigen/src/Eigen2Support/Lazy.h | 25 +- .../Eigen/src/Eigen2Support/LeastSquares.h | 24 +- .../Eigen3/Eigen/src/Eigen2Support/Macros.h | 21 +- .../Eigen/src/Eigen2Support/MathFunctions.h | 25 +- .../Eigen3/Eigen/src/Eigen2Support/Memory.h | 25 +- extern/Eigen3/Eigen/src/Eigen2Support/Meta.h | 25 +- extern/Eigen3/Eigen/src/Eigen2Support/Minor.h | 25 +- extern/Eigen3/Eigen/src/Eigen2Support/QR.h | 24 +- extern/Eigen3/Eigen/src/Eigen2Support/SVD.h | 27 +- .../src/Eigen2Support/TriangularSolver.h | 25 +- .../Eigen/src/Eigen2Support/VectorBlock.h | 25 +- .../src/Eigenvalues/ComplexEigenSolver.h | 25 +- .../Eigen/src/Eigenvalues/ComplexSchur.h | 72 +- .../Eigen/src/Eigenvalues/ComplexSchur_MKL.h | 94 ++ .../Eigen/src/Eigenvalues/EigenSolver.h | 32 +- .../Eigen/src/Eigenvalues/EigenvaluesCommon.h | 31 - .../GeneralizedSelfAdjointEigenSolver.h | 26 +- .../src/Eigenvalues/HessenbergDecomposition.h | 27 +- .../src/Eigenvalues/MatrixBaseEigenvalues.h | 25 +- .../Eigen3/Eigen/src/Eigenvalues/RealSchur.h | 92 +- .../Eigen/src/Eigenvalues/RealSchur_MKL.h | 83 ++ .../src/Eigenvalues/SelfAdjointEigenSolver.h | 327 ++++- .../Eigenvalues/SelfAdjointEigenSolver_MKL.h | 92 ++ .../src/Eigenvalues/Tridiagonalization.h | 33 +- extern/Eigen3/Eigen/src/Geometry/AlignedBox.h | 67 +- extern/Eigen3/Eigen/src/Geometry/AngleAxis.h | 27 +- .../Eigen3/Eigen/src/Geometry/EulerAngles.h | 24 +- .../Eigen3/Eigen/src/Geometry/Homogeneous.h | 39 +- extern/Eigen3/Eigen/src/Geometry/Hyperplane.h | 25 +- .../Eigen3/Eigen/src/Geometry/OrthoMethods.h | 39 +- .../Eigen/src/Geometry/ParametrizedLine.h | 67 +- extern/Eigen3/Eigen/src/Geometry/Quaternion.h | 77 +- extern/Eigen3/Eigen/src/Geometry/Rotation2D.h | 27 +- .../Eigen3/Eigen/src/Geometry/RotationBase.h | 37 +- extern/Eigen3/Eigen/src/Geometry/Scaling.h | 40 +- extern/Eigen3/Eigen/src/Geometry/Transform.h | 115 +- .../Eigen3/Eigen/src/Geometry/Translation.h | 31 +- extern/Eigen3/Eigen/src/Geometry/Umeyama.h | 25 +- .../Eigen/src/Geometry/arch/Geometry_SSE.h | 31 +- .../Eigen/src/Householder/BlockHouseholder.h | 27 +- .../Eigen/src/Householder/Householder.h | 73 +- .../src/Householder/HouseholderSequence.h | 74 +- .../BasicPreconditioners.h | 149 +++ .../src/IterativeLinearSolvers/BiCGSTAB.h | 254 ++++ .../ConjugateGradient.h | 251 ++++ .../IterativeLinearSolvers/IncompleteLUT.h | 466 +++++++ .../IterativeSolverBase.h | 254 ++++ extern/Eigen3/Eigen/src/Jacobi/Jacobi.h | 32 +- extern/Eigen3/Eigen/src/LU/Determinant.h | 25 +- extern/Eigen3/Eigen/src/LU/FullPivLU.h | 26 +- extern/Eigen3/Eigen/src/LU/Inverse.h | 27 +- extern/Eigen3/Eigen/src/LU/PartialPivLU.h | 25 +- extern/Eigen3/Eigen/src/LU/PartialPivLU_MKL.h | 85 ++ extern/Eigen3/Eigen/src/LU/arch/Inverse_SSE.h | 27 +- extern/Eigen3/Eigen/src/OrderingMethods/Amd.h | 439 +++++++ .../Eigen/src/PaStiXSupport/PaStiXSupport.h | 742 +++++++++++ .../Eigen/src/PardisoSupport/PardisoSupport.h | 614 +++++++++ .../Eigen3/Eigen/src/QR/ColPivHouseholderQR.h | 24 +- .../Eigen/src/QR/ColPivHouseholderQR_MKL.h | 98 ++ .../Eigen/src/QR/FullPivHouseholderQR.h | 122 +- extern/Eigen3/Eigen/src/QR/HouseholderQR.h | 24 +- .../Eigen3/Eigen/src/QR/HouseholderQR_MKL.h | 69 + extern/Eigen3/Eigen/src/SVD/JacobiSVD.h | 294 +++-- extern/Eigen3/Eigen/src/SVD/JacobiSVD_MKL.h | 92 ++ .../Eigen/src/SVD/UpperBidiagonalization.h | 25 +- .../Eigen/src/Sparse/DynamicSparseMatrix.h | 346 ----- .../Eigen/src/Sparse/SparseCwiseUnaryOp.h | 146 --- extern/Eigen3/Eigen/src/Sparse/SparseFuzzy.h | 41 - extern/Eigen3/Eigen/src/Sparse/SparseMatrix.h | 651 ---------- .../Eigen/src/Sparse/SparseSparseProduct.h | 401 ------ .../Eigen/src/Sparse/SparseTriangularView.h | 100 -- .../src/SparseCholesky/SimplicialCholesky.h | 873 +++++++++++++ .../src/{Sparse => SparseCore}/AmbiVector.h | 32 +- .../CompressedStorage.h | 36 +- .../ConservativeSparseSparseProduct.h | 245 ++++ .../{Sparse => SparseCore}/CoreIterators.h | 28 +- .../MappedSparseMatrix.h | 88 +- .../src/{Sparse => SparseCore}/SparseAssign.h | 0 .../src/{Sparse => SparseCore}/SparseBlock.h | 212 +--- .../SparseCwiseBinaryOp.h | 87 +- .../Eigen/src/SparseCore/SparseCwiseUnaryOp.h | 163 +++ .../SparseDenseProduct.h | 147 ++- .../SparseDiagonalProduct.h | 25 +- .../src/{Sparse => SparseCore}/SparseDot.h | 41 +- .../Eigen3/Eigen/src/SparseCore/SparseFuzzy.h | 26 + .../Eigen/src/SparseCore/SparseMatrix.h | 1116 +++++++++++++++++ .../{Sparse => SparseCore}/SparseMatrixBase.h | 440 ++----- .../Eigen/src/SparseCore/SparsePermutation.h | 148 +++ .../{Sparse => SparseCore}/SparseProduct.h | 103 +- .../src/{Sparse => SparseCore}/SparseRedux.h | 27 +- .../SparseSelfAdjointView.h | 176 +-- .../SparseSparseProductWithPruning.h | 149 +++ .../{Sparse => SparseCore}/SparseTranspose.h | 41 +- .../src/SparseCore/SparseTriangularView.h | 164 +++ .../src/{Sparse => SparseCore}/SparseUtil.h | 109 +- .../src/{Sparse => SparseCore}/SparseVector.h | 205 ++- .../src/{Sparse => SparseCore}/SparseView.h | 37 +- .../{Sparse => SparseCore}/TriangularSolver.h | 69 +- extern/Eigen3/Eigen/src/StlSupport/StdDeque.h | 21 +- extern/Eigen3/Eigen/src/StlSupport/StdList.h | 21 +- .../Eigen3/Eigen/src/StlSupport/StdVector.h | 21 +- extern/Eigen3/Eigen/src/StlSupport/details.h | 21 +- .../Eigen/src/SuperLUSupport/SuperLUSupport.h | 1025 +++++++++++++++ .../Eigen/src/UmfPackSupport/UmfPackSupport.h | 431 +++++++ extern/Eigen3/Eigen/src/misc/Image.h | 25 +- extern/Eigen3/Eigen/src/misc/Kernel.h | 25 +- extern/Eigen3/Eigen/src/misc/Solve.h | 27 +- extern/Eigen3/Eigen/src/misc/SparseSolve.h | 111 ++ extern/Eigen3/Eigen/src/misc/blas.h | 658 ++++++++++ .../Eigen/src/plugins/ArrayCwiseBinaryOps.h | 56 + .../Eigen3/Eigen/src/plugins/BlockMethods.h | 21 +- .../Eigen/src/plugins/CommonCwiseBinaryOps.h | 21 +- .../Eigen/src/plugins/CommonCwiseUnaryOps.h | 21 +- .../Eigen/src/plugins/MatrixCwiseBinaryOps.h | 42 +- .../Eigen/src/plugins/MatrixCwiseUnaryOps.h | 21 +- intern/itasc/CMakeLists.txt | 430 ++++--- 259 files changed, 17107 insertions(+), 7706 deletions(-) create mode 100644 extern/Eigen3/Eigen/CholmodSupport create mode 100644 extern/Eigen3/Eigen/IterativeLinearSolvers create mode 100644 extern/Eigen3/Eigen/OrderingMethods create mode 100644 extern/Eigen3/Eigen/PaStiXSupport create mode 100644 extern/Eigen3/Eigen/PardisoSupport create mode 100644 extern/Eigen3/Eigen/SparseCholesky create mode 100644 extern/Eigen3/Eigen/SparseCore create mode 100644 extern/Eigen3/Eigen/SuperLUSupport create mode 100644 extern/Eigen3/Eigen/UmfPackSupport create mode 100644 extern/Eigen3/Eigen/src/Cholesky/LLT_MKL.h create mode 100644 extern/Eigen3/Eigen/src/CholmodSupport/CholmodSupport.h create mode 100644 extern/Eigen3/Eigen/src/Core/Assign_MKL.h create mode 100644 extern/Eigen3/Eigen/src/Core/GeneralProduct.h create mode 100644 extern/Eigen3/Eigen/src/Core/products/GeneralMatrixMatrixTriangular_MKL.h create mode 100644 extern/Eigen3/Eigen/src/Core/products/GeneralMatrixMatrix_MKL.h create mode 100644 extern/Eigen3/Eigen/src/Core/products/GeneralMatrixVector_MKL.h create mode 100644 extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixMatrix_MKL.h create mode 100644 extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixVector_MKL.h create mode 100644 extern/Eigen3/Eigen/src/Core/products/TriangularMatrixMatrix_MKL.h create mode 100644 extern/Eigen3/Eigen/src/Core/products/TriangularMatrixVector_MKL.h create mode 100644 extern/Eigen3/Eigen/src/Core/products/TriangularSolverMatrix_MKL.h create mode 100644 extern/Eigen3/Eigen/src/Core/util/MKL_support.h create mode 100644 extern/Eigen3/Eigen/src/Core/util/NonMPL2.h create mode 100644 extern/Eigen3/Eigen/src/Eigenvalues/ComplexSchur_MKL.h delete mode 100644 extern/Eigen3/Eigen/src/Eigenvalues/EigenvaluesCommon.h create mode 100644 extern/Eigen3/Eigen/src/Eigenvalues/RealSchur_MKL.h create mode 100644 extern/Eigen3/Eigen/src/Eigenvalues/SelfAdjointEigenSolver_MKL.h create mode 100644 extern/Eigen3/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h create mode 100644 extern/Eigen3/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h create mode 100644 extern/Eigen3/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h create mode 100644 extern/Eigen3/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h create mode 100644 extern/Eigen3/Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h create mode 100644 extern/Eigen3/Eigen/src/LU/PartialPivLU_MKL.h create mode 100644 extern/Eigen3/Eigen/src/OrderingMethods/Amd.h create mode 100644 extern/Eigen3/Eigen/src/PaStiXSupport/PaStiXSupport.h create mode 100644 extern/Eigen3/Eigen/src/PardisoSupport/PardisoSupport.h create mode 100644 extern/Eigen3/Eigen/src/QR/ColPivHouseholderQR_MKL.h create mode 100644 extern/Eigen3/Eigen/src/QR/HouseholderQR_MKL.h create mode 100644 extern/Eigen3/Eigen/src/SVD/JacobiSVD_MKL.h delete mode 100644 extern/Eigen3/Eigen/src/Sparse/DynamicSparseMatrix.h delete mode 100644 extern/Eigen3/Eigen/src/Sparse/SparseCwiseUnaryOp.h delete mode 100644 extern/Eigen3/Eigen/src/Sparse/SparseFuzzy.h delete mode 100644 extern/Eigen3/Eigen/src/Sparse/SparseMatrix.h delete mode 100644 extern/Eigen3/Eigen/src/Sparse/SparseSparseProduct.h delete mode 100644 extern/Eigen3/Eigen/src/Sparse/SparseTriangularView.h create mode 100644 extern/Eigen3/Eigen/src/SparseCholesky/SimplicialCholesky.h rename extern/Eigen3/Eigen/src/{Sparse => SparseCore}/AmbiVector.h (89%) rename extern/Eigen3/Eigen/src/{Sparse => SparseCore}/CompressedStorage.h (84%) create mode 100644 extern/Eigen3/Eigen/src/SparseCore/ConservativeSparseSparseProduct.h rename extern/Eigen3/Eigen/src/{Sparse => SparseCore}/CoreIterators.h (62%) rename extern/Eigen3/Eigen/src/{Sparse => SparseCore}/MappedSparseMatrix.h (68%) rename extern/Eigen3/Eigen/src/{Sparse => SparseCore}/SparseAssign.h (100%) rename extern/Eigen3/Eigen/src/{Sparse => SparseCore}/SparseBlock.h (66%) rename extern/Eigen3/Eigen/src/{Sparse => SparseCore}/SparseCwiseBinaryOp.h (77%) create mode 100644 extern/Eigen3/Eigen/src/SparseCore/SparseCwiseUnaryOp.h rename extern/Eigen3/Eigen/src/{Sparse => SparseCore}/SparseDenseProduct.h (56%) rename extern/Eigen3/Eigen/src/{Sparse => SparseCore}/SparseDiagonalProduct.h (87%) rename extern/Eigen3/Eigen/src/{Sparse => SparseCore}/SparseDot.h (67%) create mode 100644 extern/Eigen3/Eigen/src/SparseCore/SparseFuzzy.h create mode 100644 extern/Eigen3/Eigen/src/SparseCore/SparseMatrix.h rename extern/Eigen3/Eigen/src/{Sparse => SparseCore}/SparseMatrixBase.h (52%) create mode 100644 extern/Eigen3/Eigen/src/SparseCore/SparsePermutation.h rename extern/Eigen3/Eigen/src/{Sparse => SparseCore}/SparseProduct.h (62%) rename extern/Eigen3/Eigen/src/{Sparse => SparseCore}/SparseRedux.h (56%) rename extern/Eigen3/Eigen/src/{Sparse => SparseCore}/SparseSelfAdjointView.h (75%) create mode 100644 extern/Eigen3/Eigen/src/SparseCore/SparseSparseProductWithPruning.h rename extern/Eigen3/Eigen/src/{Sparse => SparseCore}/SparseTranspose.h (53%) create mode 100644 extern/Eigen3/Eigen/src/SparseCore/SparseTriangularView.h rename extern/Eigen3/Eigen/src/{Sparse => SparseCore}/SparseUtil.h (60%) rename extern/Eigen3/Eigen/src/{Sparse => SparseCore}/SparseVector.h (63%) rename extern/Eigen3/Eigen/src/{Sparse => SparseCore}/SparseView.h (64%) rename extern/Eigen3/Eigen/src/{Sparse => SparseCore}/TriangularSolver.h (83%) create mode 100644 extern/Eigen3/Eigen/src/SuperLUSupport/SuperLUSupport.h create mode 100644 extern/Eigen3/Eigen/src/UmfPackSupport/UmfPackSupport.h create mode 100644 extern/Eigen3/Eigen/src/misc/SparseSolve.h create mode 100644 extern/Eigen3/Eigen/src/misc/blas.h diff --git a/extern/Eigen3/Eigen/Cholesky b/extern/Eigen3/Eigen/Cholesky index 53f7bf911a4..f727f5d89c0 100644 --- a/extern/Eigen3/Eigen/Cholesky +++ b/extern/Eigen3/Eigen/Cholesky @@ -5,8 +5,6 @@ #include "src/Core/util/DisableStupidWarnings.h" -namespace Eigen { - /** \defgroup Cholesky_Module Cholesky module * * @@ -24,8 +22,9 @@ namespace Eigen { #include "src/misc/Solve.h" #include "src/Cholesky/LLT.h" #include "src/Cholesky/LDLT.h" - -} // namespace Eigen +#ifdef EIGEN_USE_LAPACKE +#include "src/Cholesky/LLT_MKL.h" +#endif #include "src/Core/util/ReenableStupidWarnings.h" diff --git a/extern/Eigen3/Eigen/CholmodSupport b/extern/Eigen3/Eigen/CholmodSupport new file mode 100644 index 00000000000..745b884e74d --- /dev/null +++ b/extern/Eigen3/Eigen/CholmodSupport @@ -0,0 +1,45 @@ +#ifndef EIGEN_CHOLMODSUPPORT_MODULE_H +#define EIGEN_CHOLMODSUPPORT_MODULE_H + +#include "SparseCore" + +#include "src/Core/util/DisableStupidWarnings.h" + +extern "C" { + #include +} + +/** \ingroup Support_modules + * \defgroup CholmodSupport_Module CholmodSupport module + * + * This module provides an interface to the Cholmod library which is part of the
suitesparse package. + * It provides the two following main factorization classes: + * - class CholmodSupernodalLLT: a supernodal LLT Cholesky factorization. + * - class CholmodDecomposiiton: a general L(D)LT Cholesky factorization with automatic or explicit runtime selection of the underlying factorization method (supernodal or simplicial). + * + * For the sake of completeness, this module also propose the two following classes: + * - class CholmodSimplicialLLT + * - class CholmodSimplicialLDLT + * Note that these classes does not bring any particular advantage compared to the built-in + * SimplicialLLT and SimplicialLDLT factorization classes. + * + * \code + * #include + * \endcode + * + * In order to use this module, the cholmod headers must be accessible from the include paths, and your binary must be linked to the cholmod library and its dependencies. + * The dependencies depend on how cholmod has been compiled. + * For a cmake based project, you can use our FindCholmod.cmake module to help you in this task. + * + */ + +#include "src/misc/Solve.h" +#include "src/misc/SparseSolve.h" + +#include "src/CholmodSupport/CholmodSupport.h" + + +#include "src/Core/util/ReenableStupidWarnings.h" + +#endif // EIGEN_CHOLMODSUPPORT_MODULE_H + diff --git a/extern/Eigen3/Eigen/Core b/extern/Eigen3/Eigen/Core index a5025e37ead..d4801702261 100644 --- a/extern/Eigen3/Eigen/Core +++ b/extern/Eigen3/Eigen/Core @@ -4,24 +4,9 @@ // Copyright (C) 2008 Gael Guennebaud // Copyright (C) 2007-2011 Benoit Jacob // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_CORE_H #define EIGEN_CORE_H @@ -34,6 +19,12 @@ // defined e.g. EIGEN_DONT_ALIGN) so it needs to be done before we do anything with vectorization. #include "src/Core/util/Macros.h" +#include + +// this include file manages BLAS and MKL related macros +// and inclusion of their respective header files +#include "src/Core/util/MKL_support.h" + // if alignment is disabled, then disable vectorization. Note: EIGEN_ALIGN is the proper check, it takes into // account both the user's will (EIGEN_DONT_ALIGN) and our own platform checks #if !EIGEN_ALIGN @@ -136,7 +127,7 @@ #endif // MSVC for windows mobile does not have the errno.h file -#if !(defined(_MSC_VER) && defined(_WIN32_WCE)) +#if !(defined(_MSC_VER) && defined(_WIN32_WCE)) && !defined(__ARMCC_VERSION) #define EIGEN_HAS_ERRNO #endif @@ -146,7 +137,6 @@ #include #include #include -#include #include #include #include @@ -175,9 +165,6 @@ #include #endif -// defined in bits/termios.h -#undef B0 - /** \brief Namespace containing all symbols from the %Eigen library. */ namespace Eigen { @@ -201,6 +188,8 @@ inline static const char *SimdInstructionSetsInUse(void) { #endif } +} // end namespace Eigen + #define STAGE10_FULL_EIGEN2_API 10 #define STAGE20_RESOLVE_API_CONFLICTS 20 #define STAGE30_FULL_EIGEN3_API 30 @@ -247,6 +236,10 @@ using std::ptrdiff_t; * \endcode */ +/** \defgroup Support_modules Support modules [category] + * Category of modules which add support for external libraries. + */ + #include "src/Core/util/Constants.h" #include "src/Core/util/ForwardDeclarations.h" #include "src/Core/util/Meta.h" @@ -318,15 +311,15 @@ using std::ptrdiff_t; #include "src/Core/CommaInitializer.h" #include "src/Core/Flagged.h" #include "src/Core/ProductBase.h" -#include "src/Core/Product.h" +#include "src/Core/GeneralProduct.h" #include "src/Core/TriangularMatrix.h" #include "src/Core/SelfAdjointView.h" -#include "src/Core/SolveTriangular.h" +#include "src/Core/products/GeneralBlockPanelKernel.h" #include "src/Core/products/Parallelizer.h" #include "src/Core/products/CoeffBasedProduct.h" -#include "src/Core/products/GeneralBlockPanelKernel.h" #include "src/Core/products/GeneralMatrixVector.h" #include "src/Core/products/GeneralMatrixMatrix.h" +#include "src/Core/SolveTriangular.h" #include "src/Core/products/GeneralMatrixMatrixTriangular.h" #include "src/Core/products/SelfadjointMatrixVector.h" #include "src/Core/products/SelfadjointMatrixMatrix.h" @@ -347,7 +340,20 @@ using std::ptrdiff_t; #include "src/Core/ArrayBase.h" #include "src/Core/ArrayWrapper.h" -} // namespace Eigen +#ifdef EIGEN_USE_BLAS +#include "src/Core/products/GeneralMatrixMatrix_MKL.h" +#include "src/Core/products/GeneralMatrixVector_MKL.h" +#include "src/Core/products/GeneralMatrixMatrixTriangular_MKL.h" +#include "src/Core/products/SelfadjointMatrixMatrix_MKL.h" +#include "src/Core/products/SelfadjointMatrixVector_MKL.h" +#include "src/Core/products/TriangularMatrixMatrix_MKL.h" +#include "src/Core/products/TriangularMatrixVector_MKL.h" +#include "src/Core/products/TriangularSolverMatrix_MKL.h" +#endif // EIGEN_USE_BLAS + +#ifdef EIGEN_USE_MKL_VML +#include "src/Core/Assign_MKL.h" +#endif #include "src/Core/GlobalFunctions.h" diff --git a/extern/Eigen3/Eigen/Eigen2Support b/extern/Eigen3/Eigen/Eigen2Support index d96592a8de9..36156d29a92 100644 --- a/extern/Eigen3/Eigen/Eigen2Support +++ b/extern/Eigen3/Eigen/Eigen2Support @@ -3,24 +3,9 @@ // // Copyright (C) 2009 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN2SUPPORT_H #define EIGEN2SUPPORT_H @@ -31,9 +16,8 @@ #include "src/Core/util/DisableStupidWarnings.h" -namespace Eigen { - -/** \defgroup Eigen2Support_Module Eigen2 support module +/** \ingroup Support_modules + * \defgroup Eigen2Support_Module Eigen2 support module * This module provides a couple of deprecated functions improving the compatibility with Eigen2. * * To use it, define EIGEN2_SUPPORT before including any Eigen header @@ -56,13 +40,29 @@ namespace Eigen { #include "src/Eigen2Support/MathFunctions.h" -} // namespace Eigen - #include "src/Core/util/ReenableStupidWarnings.h" // Eigen2 used to include iostream #include +#define EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, SizeSuffix) \ +using Eigen::Matrix##SizeSuffix##TypeSuffix; \ +using Eigen::Vector##SizeSuffix##TypeSuffix; \ +using Eigen::RowVector##SizeSuffix##TypeSuffix; + +#define EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE(TypeSuffix) \ +EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 2) \ +EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 3) \ +EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 4) \ +EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, X) \ + +#define EIGEN_USING_MATRIX_TYPEDEFS \ +EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE(i) \ +EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE(f) \ +EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE(d) \ +EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE(cf) \ +EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE(cd) + #define USING_PART_OF_NAMESPACE_EIGEN \ EIGEN_USING_MATRIX_TYPEDEFS \ using Eigen::Matrix; \ diff --git a/extern/Eigen3/Eigen/Eigenvalues b/extern/Eigen3/Eigen/Eigenvalues index 250c0f46652..af99ccd1fab 100644 --- a/extern/Eigen3/Eigen/Eigenvalues +++ b/extern/Eigen3/Eigen/Eigenvalues @@ -9,8 +9,7 @@ #include "Jacobi" #include "Householder" #include "LU" - -namespace Eigen { +#include "Geometry" /** \defgroup Eigenvalues_Module Eigenvalues module * @@ -35,8 +34,11 @@ namespace Eigen { #include "src/Eigenvalues/ComplexSchur.h" #include "src/Eigenvalues/ComplexEigenSolver.h" #include "src/Eigenvalues/MatrixBaseEigenvalues.h" - -} // namespace Eigen +#ifdef EIGEN_USE_LAPACKE +#include "src/Eigenvalues/RealSchur_MKL.h" +#include "src/Eigenvalues/ComplexSchur_MKL.h" +#include "src/Eigenvalues/SelfAdjointEigenSolver_MKL.h" +#endif #include "src/Core/util/ReenableStupidWarnings.h" diff --git a/extern/Eigen3/Eigen/Geometry b/extern/Eigen3/Eigen/Geometry index 78277c0c560..efd9d4504cb 100644 --- a/extern/Eigen3/Eigen/Geometry +++ b/extern/Eigen3/Eigen/Geometry @@ -13,8 +13,6 @@ #define M_PI 3.14159265358979323846 #endif -namespace Eigen { - /** \defgroup Geometry_Module Geometry module * * @@ -58,8 +56,6 @@ namespace Eigen { #include "src/Eigen2Support/Geometry/All.h" #endif -} // namespace Eigen - #include "src/Core/util/ReenableStupidWarnings.h" #endif // EIGEN_GEOMETRY_MODULE_H diff --git a/extern/Eigen3/Eigen/Householder b/extern/Eigen3/Eigen/Householder index 6b86cf65c55..6e348db5c43 100644 --- a/extern/Eigen3/Eigen/Householder +++ b/extern/Eigen3/Eigen/Householder @@ -5,8 +5,6 @@ #include "src/Core/util/DisableStupidWarnings.h" -namespace Eigen { - /** \defgroup Householder_Module Householder module * This module provides Householder transformations. * @@ -19,8 +17,6 @@ namespace Eigen { #include "src/Householder/HouseholderSequence.h" #include "src/Householder/BlockHouseholder.h" -} // namespace Eigen - #include "src/Core/util/ReenableStupidWarnings.h" #endif // EIGEN_HOUSEHOLDER_MODULE_H diff --git a/extern/Eigen3/Eigen/IterativeLinearSolvers b/extern/Eigen3/Eigen/IterativeLinearSolvers new file mode 100644 index 00000000000..315c2dd1ee7 --- /dev/null +++ b/extern/Eigen3/Eigen/IterativeLinearSolvers @@ -0,0 +1,40 @@ +#ifndef EIGEN_ITERATIVELINEARSOLVERS_MODULE_H +#define EIGEN_ITERATIVELINEARSOLVERS_MODULE_H + +#include "SparseCore" +#include "OrderingMethods" + +#include "src/Core/util/DisableStupidWarnings.h" + +/** \ingroup Sparse_modules + * \defgroup IterativeLinearSolvers_Module IterativeLinearSolvers module + * + * This module currently provides iterative methods to solve problems of the form \c A \c x = \c b, where \c A is a squared matrix, usually very large and sparse. + * Those solvers are accessible via the following classes: + * - ConjugateGradient for selfadjoint (hermitian) matrices, + * - BiCGSTAB for general square matrices. + * + * These iterative solvers are associated with some preconditioners: + * - IdentityPreconditioner - not really useful + * - DiagonalPreconditioner - also called JAcobi preconditioner, work very well on diagonal dominant matrices. + * - IncompleteILUT - incomplete LU factorization with dual thresholding + * + * Such problems can also be solved using the direct sparse decomposition modules: SparseCholesky, CholmodSupport, UmfPackSupport, SuperLUSupport. + * + * \code + * #include + * \endcode + */ + +#include "src/misc/Solve.h" +#include "src/misc/SparseSolve.h" + +#include "src/IterativeLinearSolvers/IterativeSolverBase.h" +#include "src/IterativeLinearSolvers/BasicPreconditioners.h" +#include "src/IterativeLinearSolvers/ConjugateGradient.h" +#include "src/IterativeLinearSolvers/BiCGSTAB.h" +#include "src/IterativeLinearSolvers/IncompleteLUT.h" + +#include "src/Core/util/ReenableStupidWarnings.h" + +#endif // EIGEN_ITERATIVELINEARSOLVERS_MODULE_H diff --git a/extern/Eigen3/Eigen/Jacobi b/extern/Eigen3/Eigen/Jacobi index afa67681379..ba8a4dc36a5 100644 --- a/extern/Eigen3/Eigen/Jacobi +++ b/extern/Eigen3/Eigen/Jacobi @@ -5,8 +5,6 @@ #include "src/Core/util/DisableStupidWarnings.h" -namespace Eigen { - /** \defgroup Jacobi_Module Jacobi module * This module provides Jacobi and Givens rotations. * @@ -21,8 +19,6 @@ namespace Eigen { #include "src/Jacobi/Jacobi.h" -} // namespace Eigen - #include "src/Core/util/ReenableStupidWarnings.h" #endif // EIGEN_JACOBI_MODULE_H diff --git a/extern/Eigen3/Eigen/LU b/extern/Eigen3/Eigen/LU index 226f88ca38a..db579550448 100644 --- a/extern/Eigen3/Eigen/LU +++ b/extern/Eigen3/Eigen/LU @@ -5,8 +5,6 @@ #include "src/Core/util/DisableStupidWarnings.h" -namespace Eigen { - /** \defgroup LU_Module LU module * This module includes %LU decomposition and related notions such as matrix inversion and determinant. * This module defines the following MatrixBase methods: @@ -23,6 +21,9 @@ namespace Eigen { #include "src/misc/Image.h" #include "src/LU/FullPivLU.h" #include "src/LU/PartialPivLU.h" +#ifdef EIGEN_USE_LAPACKE +#include "src/LU/PartialPivLU_MKL.h" +#endif #include "src/LU/Determinant.h" #include "src/LU/Inverse.h" @@ -34,8 +35,6 @@ namespace Eigen { #include "src/Eigen2Support/LU.h" #endif -} // namespace Eigen - #include "src/Core/util/ReenableStupidWarnings.h" #endif // EIGEN_LU_MODULE_H diff --git a/extern/Eigen3/Eigen/LeastSquares b/extern/Eigen3/Eigen/LeastSquares index 93a6302dcd9..35137c25db0 100644 --- a/extern/Eigen3/Eigen/LeastSquares +++ b/extern/Eigen3/Eigen/LeastSquares @@ -15,8 +15,6 @@ #include "Eigenvalues" #include "Geometry" -namespace Eigen { - /** \defgroup LeastSquares_Module LeastSquares module * This module provides linear regression and related features. * @@ -27,8 +25,6 @@ namespace Eigen { #include "src/Eigen2Support/LeastSquares.h" -} // namespace Eigen - #include "src/Core/util/ReenableStupidWarnings.h" #endif // EIGEN2_SUPPORT diff --git a/extern/Eigen3/Eigen/OrderingMethods b/extern/Eigen3/Eigen/OrderingMethods new file mode 100644 index 00000000000..1e2d87452e5 --- /dev/null +++ b/extern/Eigen3/Eigen/OrderingMethods @@ -0,0 +1,23 @@ +#ifndef EIGEN_ORDERINGMETHODS_MODULE_H +#define EIGEN_ORDERINGMETHODS_MODULE_H + +#include "SparseCore" + +#include "src/Core/util/DisableStupidWarnings.h" + +/** \ingroup Sparse_modules + * \defgroup OrderingMethods_Module OrderingMethods module + * + * This module is currently for internal use only. + * + * + * \code + * #include + * \endcode + */ + +#include "src/OrderingMethods/Amd.h" + +#include "src/Core/util/ReenableStupidWarnings.h" + +#endif // EIGEN_ORDERINGMETHODS_MODULE_H diff --git a/extern/Eigen3/Eigen/PaStiXSupport b/extern/Eigen3/Eigen/PaStiXSupport new file mode 100644 index 00000000000..7c616ee5eac --- /dev/null +++ b/extern/Eigen3/Eigen/PaStiXSupport @@ -0,0 +1,46 @@ +#ifndef EIGEN_PASTIXSUPPORT_MODULE_H +#define EIGEN_PASTIXSUPPORT_MODULE_H + +#include "SparseCore" + +#include "src/Core/util/DisableStupidWarnings.h" + +#include +extern "C" { +#include +#include +} + +#ifdef complex +#undef complex +#endif + +/** \ingroup Support_modules + * \defgroup PaStiXSupport_Module PaStiXSupport module + * + * This module provides an interface to the PaSTiX library. + * PaSTiX is a general \b supernodal, \b parallel and \b opensource sparse solver. + * It provides the two following main factorization classes: + * - class PastixLLT : a supernodal, parallel LLt Cholesky factorization. + * - class PastixLDLT: a supernodal, parallel LDLt Cholesky factorization. + * - class PastixLU : a supernodal, parallel LU factorization (optimized for a symmetric pattern). + * + * \code + * #include + * \endcode + * + * In order to use this module, the PaSTiX headers must be accessible from the include paths, and your binary must be linked to the PaSTiX library and its dependencies. + * The dependencies depend on how PaSTiX has been compiled. + * For a cmake based project, you can use our FindPaSTiX.cmake module to help you in this task. + * + */ + +#include "src/misc/Solve.h" +#include "src/misc/SparseSolve.h" + +#include "src/PaStiXSupport/PaStiXSupport.h" + + +#include "src/Core/util/ReenableStupidWarnings.h" + +#endif // EIGEN_PASTIXSUPPORT_MODULE_H diff --git a/extern/Eigen3/Eigen/PardisoSupport b/extern/Eigen3/Eigen/PardisoSupport new file mode 100644 index 00000000000..99330ce7a7d --- /dev/null +++ b/extern/Eigen3/Eigen/PardisoSupport @@ -0,0 +1,30 @@ +#ifndef EIGEN_PARDISOSUPPORT_MODULE_H +#define EIGEN_PARDISOSUPPORT_MODULE_H + +#include "SparseCore" + +#include "src/Core/util/DisableStupidWarnings.h" + +#include + +#include + +/** \ingroup Support_modules + * \defgroup PardisoSupport_Module PardisoSupport module + * + * This module brings support for the Intel(R) MKL PARDISO direct sparse solvers. + * + * \code + * #include + * \endcode + * + * In order to use this module, the MKL headers must be accessible from the include paths, and your binary must be linked to the MKL library and its dependencies. + * See this \ref TopicUsingIntelMKL "page" for more information on MKL-Eigen integration. + * + */ + +#include "src/PardisoSupport/PardisoSupport.h" + +#include "src/Core/util/ReenableStupidWarnings.h" + +#endif // EIGEN_PARDISOSUPPORT_MODULE_H diff --git a/extern/Eigen3/Eigen/QR b/extern/Eigen3/Eigen/QR index 97c1788ee30..ac5b0269354 100644 --- a/extern/Eigen3/Eigen/QR +++ b/extern/Eigen3/Eigen/QR @@ -9,8 +9,6 @@ #include "Jacobi" #include "Householder" -namespace Eigen { - /** \defgroup QR_Module QR module * * @@ -28,13 +26,15 @@ namespace Eigen { #include "src/QR/HouseholderQR.h" #include "src/QR/FullPivHouseholderQR.h" #include "src/QR/ColPivHouseholderQR.h" +#ifdef EIGEN_USE_LAPACKE +#include "src/QR/HouseholderQR_MKL.h" +#include "src/QR/ColPivHouseholderQR_MKL.h" +#endif #ifdef EIGEN2_SUPPORT #include "src/Eigen2Support/QR.h" #endif -} // namespace Eigen - #include "src/Core/util/ReenableStupidWarnings.h" #ifdef EIGEN2_SUPPORT diff --git a/extern/Eigen3/Eigen/SVD b/extern/Eigen3/Eigen/SVD index 7c987a9dd36..fd310017ad1 100644 --- a/extern/Eigen3/Eigen/SVD +++ b/extern/Eigen3/Eigen/SVD @@ -7,8 +7,6 @@ #include "src/Core/util/DisableStupidWarnings.h" -namespace Eigen { - /** \defgroup SVD_Module SVD module * * @@ -24,14 +22,15 @@ namespace Eigen { #include "src/misc/Solve.h" #include "src/SVD/JacobiSVD.h" +#if defined(EIGEN_USE_LAPACKE) && !defined(EIGEN_USE_LAPACKE_STRICT) +#include "src/SVD/JacobiSVD_MKL.h" +#endif #include "src/SVD/UpperBidiagonalization.h" #ifdef EIGEN2_SUPPORT #include "src/Eigen2Support/SVD.h" #endif -} // namespace Eigen - #include "src/Core/util/ReenableStupidWarnings.h" #endif // EIGEN_SVD_MODULE_H diff --git a/extern/Eigen3/Eigen/Sparse b/extern/Eigen3/Eigen/Sparse index 7425b3a412a..2d1757172eb 100644 --- a/extern/Eigen3/Eigen/Sparse +++ b/extern/Eigen3/Eigen/Sparse @@ -1,69 +1,23 @@ #ifndef EIGEN_SPARSE_MODULE_H #define EIGEN_SPARSE_MODULE_H -#include "Core" - -#include "src/Core/util/DisableStupidWarnings.h" - -#include -#include -#include -#include -#include - -#ifdef EIGEN2_SUPPORT -#define EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET -#endif - -#ifndef EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET -#error The sparse module API is not stable yet. To use it anyway, please define the EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET preprocessor token. -#endif - -namespace Eigen { - -/** \defgroup Sparse_Module Sparse module +/** \defgroup Sparse_modules Sparse modules * - * - * - * See the \ref TutorialSparse "Sparse tutorial" + * Meta-module including all related modules: + * - SparseCore + * - OrderingMethods + * - SparseCholesky + * - IterativeLinearSolvers * * \code * #include * \endcode */ -/** The type used to identify a general sparse storage. */ -struct Sparse {}; - -#include "src/Sparse/SparseUtil.h" -#include "src/Sparse/SparseMatrixBase.h" -#include "src/Sparse/CompressedStorage.h" -#include "src/Sparse/AmbiVector.h" -#include "src/Sparse/SparseMatrix.h" -#include "src/Sparse/DynamicSparseMatrix.h" -#include "src/Sparse/MappedSparseMatrix.h" -#include "src/Sparse/SparseVector.h" -#include "src/Sparse/CoreIterators.h" -#include "src/Sparse/SparseBlock.h" -#include "src/Sparse/SparseTranspose.h" -#include "src/Sparse/SparseCwiseUnaryOp.h" -#include "src/Sparse/SparseCwiseBinaryOp.h" -#include "src/Sparse/SparseDot.h" -#include "src/Sparse/SparseAssign.h" -#include "src/Sparse/SparseRedux.h" -#include "src/Sparse/SparseFuzzy.h" -#include "src/Sparse/SparseProduct.h" -#include "src/Sparse/SparseSparseProduct.h" -#include "src/Sparse/SparseDenseProduct.h" -#include "src/Sparse/SparseDiagonalProduct.h" -#include "src/Sparse/SparseTriangularView.h" -#include "src/Sparse/SparseSelfAdjointView.h" -#include "src/Sparse/TriangularSolver.h" -#include "src/Sparse/SparseView.h" - -} // namespace Eigen - -#include "src/Core/util/ReenableStupidWarnings.h" +#include "SparseCore" +#include "OrderingMethods" +#include "SparseCholesky" +#include "IterativeLinearSolvers" #endif // EIGEN_SPARSE_MODULE_H diff --git a/extern/Eigen3/Eigen/SparseCholesky b/extern/Eigen3/Eigen/SparseCholesky new file mode 100644 index 00000000000..5f82742f7d8 --- /dev/null +++ b/extern/Eigen3/Eigen/SparseCholesky @@ -0,0 +1,30 @@ +#ifndef EIGEN_SPARSECHOLESKY_MODULE_H +#define EIGEN_SPARSECHOLESKY_MODULE_H + +#include "SparseCore" + +#include "src/Core/util/DisableStupidWarnings.h" + +/** \ingroup Sparse_modules + * \defgroup SparseCholesky_Module SparseCholesky module + * + * This module currently provides two variants of the direct sparse Cholesky decomposition for selfadjoint (hermitian) matrices. + * Those decompositions are accessible via the following classes: + * - SimplicialLLt, + * - SimplicialLDLt + * + * Such problems can also be solved using the ConjugateGradient solver from the IterativeLinearSolvers module. + * + * \code + * #include + * \endcode + */ + +#include "src/misc/Solve.h" +#include "src/misc/SparseSolve.h" + +#include "src/SparseCholesky/SimplicialCholesky.h" + +#include "src/Core/util/ReenableStupidWarnings.h" + +#endif // EIGEN_SPARSECHOLESKY_MODULE_H diff --git a/extern/Eigen3/Eigen/SparseCore b/extern/Eigen3/Eigen/SparseCore new file mode 100644 index 00000000000..41d28c92824 --- /dev/null +++ b/extern/Eigen3/Eigen/SparseCore @@ -0,0 +1,66 @@ +#ifndef EIGEN_SPARSECORE_MODULE_H +#define EIGEN_SPARSECORE_MODULE_H + +#include "Core" + +#include "src/Core/util/DisableStupidWarnings.h" + +#include +#include +#include +#include +#include + +/** \ingroup Sparse_modules + * \defgroup SparseCore_Module SparseCore module + * + * This module provides a sparse matrix representation, and basic associatd matrix manipulations + * and operations. + * + * See the \ref TutorialSparse "Sparse tutorial" + * + * \code + * #include + * \endcode + * + * This module depends on: Core. + */ + +namespace Eigen { + +/** The type used to identify a general sparse storage. */ +struct Sparse {}; + +} + +#include "src/SparseCore/SparseUtil.h" +#include "src/SparseCore/SparseMatrixBase.h" +#include "src/SparseCore/CompressedStorage.h" +#include "src/SparseCore/AmbiVector.h" +#include "src/SparseCore/SparseMatrix.h" +#include "src/SparseCore/MappedSparseMatrix.h" +#include "src/SparseCore/SparseVector.h" +#include "src/SparseCore/CoreIterators.h" +#include "src/SparseCore/SparseBlock.h" +#include "src/SparseCore/SparseTranspose.h" +#include "src/SparseCore/SparseCwiseUnaryOp.h" +#include "src/SparseCore/SparseCwiseBinaryOp.h" +#include "src/SparseCore/SparseDot.h" +#include "src/SparseCore/SparsePermutation.h" +#include "src/SparseCore/SparseAssign.h" +#include "src/SparseCore/SparseRedux.h" +#include "src/SparseCore/SparseFuzzy.h" +#include "src/SparseCore/ConservativeSparseSparseProduct.h" +#include "src/SparseCore/SparseSparseProductWithPruning.h" +#include "src/SparseCore/SparseProduct.h" +#include "src/SparseCore/SparseDenseProduct.h" +#include "src/SparseCore/SparseDiagonalProduct.h" +#include "src/SparseCore/SparseTriangularView.h" +#include "src/SparseCore/SparseSelfAdjointView.h" +#include "src/SparseCore/TriangularSolver.h" +#include "src/SparseCore/SparseView.h" + +#include "src/Core/util/ReenableStupidWarnings.h" + +#endif // EIGEN_SPARSECORE_MODULE_H + diff --git a/extern/Eigen3/Eigen/StdDeque b/extern/Eigen3/Eigen/StdDeque index a4f96232d8c..f27234778f4 100644 --- a/extern/Eigen3/Eigen/StdDeque +++ b/extern/Eigen3/Eigen/StdDeque @@ -4,24 +4,9 @@ // Copyright (C) 2009 Gael Guennebaud // Copyright (C) 2009 Hauke Heibel // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_STDDEQUE_MODULE_H #define EIGEN_STDDEQUE_MODULE_H diff --git a/extern/Eigen3/Eigen/StdList b/extern/Eigen3/Eigen/StdList index d914ded4f93..225c1e18f8e 100644 --- a/extern/Eigen3/Eigen/StdList +++ b/extern/Eigen3/Eigen/StdList @@ -3,24 +3,9 @@ // // Copyright (C) 2009 Hauke Heibel // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_STDLIST_MODULE_H #define EIGEN_STDLIST_MODULE_H diff --git a/extern/Eigen3/Eigen/StdVector b/extern/Eigen3/Eigen/StdVector index 3d8995e5aae..6b22627f6f6 100644 --- a/extern/Eigen3/Eigen/StdVector +++ b/extern/Eigen3/Eigen/StdVector @@ -4,24 +4,9 @@ // Copyright (C) 2009 Gael Guennebaud // Copyright (C) 2009 Hauke Heibel // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_STDVECTOR_MODULE_H #define EIGEN_STDVECTOR_MODULE_H diff --git a/extern/Eigen3/Eigen/SuperLUSupport b/extern/Eigen3/Eigen/SuperLUSupport new file mode 100644 index 00000000000..575e14fbc29 --- /dev/null +++ b/extern/Eigen3/Eigen/SuperLUSupport @@ -0,0 +1,59 @@ +#ifndef EIGEN_SUPERLUSUPPORT_MODULE_H +#define EIGEN_SUPERLUSUPPORT_MODULE_H + +#include "SparseCore" + +#include "src/Core/util/DisableStupidWarnings.h" + +#ifdef EMPTY +#define EIGEN_EMPTY_WAS_ALREADY_DEFINED +#endif + +typedef int int_t; +#include +#include +#include + +// slu_util.h defines a preprocessor token named EMPTY which is really polluting, +// so we remove it in favor of a SUPERLU_EMPTY token. +// If EMPTY was already defined then we don't undef it. + +#if defined(EIGEN_EMPTY_WAS_ALREADY_DEFINED) +# undef EIGEN_EMPTY_WAS_ALREADY_DEFINED +#elif defined(EMPTY) +# undef EMPTY +#endif + +#define SUPERLU_EMPTY (-1) + +namespace Eigen { struct SluMatrix; } + +/** \ingroup Support_modules + * \defgroup SuperLUSupport_Module SuperLUSupport module + * + * This module provides an interface to the SuperLU library. + * It provides the following factorization class: + * - class SuperLU: a supernodal sequential LU factorization. + * - class SuperILU: a supernodal sequential incomplete LU factorization (to be used as a preconditioner for iterative methods). + * + * \warning When including this module, you have to use SUPERLU_EMPTY instead of EMPTY which is no longer defined because it is too polluting. + * + * \code + * #include + * \endcode + * + * In order to use this module, the superlu headers must be accessible from the include paths, and your binary must be linked to the superlu library and its dependencies. + * The dependencies depend on how superlu has been compiled. + * For a cmake based project, you can use our FindSuperLU.cmake module to help you in this task. + * + */ + +#include "src/misc/Solve.h" +#include "src/misc/SparseSolve.h" + +#include "src/SuperLUSupport/SuperLUSupport.h" + + +#include "src/Core/util/ReenableStupidWarnings.h" + +#endif // EIGEN_SUPERLUSUPPORT_MODULE_H diff --git a/extern/Eigen3/Eigen/UmfPackSupport b/extern/Eigen3/Eigen/UmfPackSupport new file mode 100644 index 00000000000..984f64a8419 --- /dev/null +++ b/extern/Eigen3/Eigen/UmfPackSupport @@ -0,0 +1,36 @@ +#ifndef EIGEN_UMFPACKSUPPORT_MODULE_H +#define EIGEN_UMFPACKSUPPORT_MODULE_H + +#include "SparseCore" + +#include "src/Core/util/DisableStupidWarnings.h" + +extern "C" { +#include +} + +/** \ingroup Support_modules + * \defgroup UmfPackSupport_Module UmfPackSupport module + * + * This module provides an interface to the UmfPack library which is part of the suitesparse package. + * It provides the following factorization class: + * - class UmfPackLU: a multifrontal sequential LU factorization. + * + * \code + * #include + * \endcode + * + * In order to use this module, the umfpack headers must be accessible from the include paths, and your binary must be linked to the umfpack library and its dependencies. + * The dependencies depend on how umfpack has been compiled. + * For a cmake based project, you can use our FindUmfPack.cmake module to help you in this task. + * + */ + +#include "src/misc/Solve.h" +#include "src/misc/SparseSolve.h" + +#include "src/UmfPackSupport/UmfPackSupport.h" + +#include "src/Core/util/ReenableStupidWarnings.h" + +#endif // EIGEN_UMFPACKSUPPORT_MODULE_H diff --git a/extern/Eigen3/Eigen/src/Cholesky/LDLT.h b/extern/Eigen3/Eigen/src/Cholesky/LDLT.h index a19e947a4c6..68e54b1d4ad 100644 --- a/extern/Eigen3/Eigen/src/Cholesky/LDLT.h +++ b/extern/Eigen3/Eigen/src/Cholesky/LDLT.h @@ -1,43 +1,33 @@ // This file is part of Eigen, a lightweight C++ template library // for linear algebra. // -// Copyright (C) 2008-2010 Gael Guennebaud +// Copyright (C) 2008-2011 Gael Guennebaud // Copyright (C) 2009 Keir Mierle // Copyright (C) 2009 Benoit Jacob +// Copyright (C) 2011 Timothy E. Holy // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_LDLT_H #define EIGEN_LDLT_H +namespace Eigen { + namespace internal { template struct LDLT_Traits; } -/** \ingroup cholesky_Module +/** \ingroup Cholesky_Module * * \class LDLT * * \brief Robust Cholesky decomposition of a matrix with pivoting * * \param MatrixType the type of the matrix of which to compute the LDL^T Cholesky decomposition + * \param UpLo the triangular part that will be used for the decompositon: Lower (default) or Upper. + * The other triangular part won't be read. * * Perform a robust Cholesky decomposition of a positive semidefinite or negative semidefinite * matrix \f$ A \f$ such that \f$ A = P^TLDL^*P \f$, where P is a permutation matrix, L @@ -48,14 +38,10 @@ template struct LDLT_Traits; * on D also stabilizes the computation. * * Remember that Cholesky decompositions are not rank-revealing. Also, do not use a Cholesky - * decomposition to determine whether a system of equations has a solution. + * decomposition to determine whether a system of equations has a solution. * * \sa MatrixBase::ldlt(), class LLT */ - /* THIS PART OF THE DOX IS CURRENTLY DISABLED BECAUSE INACCURATE BECAUSE OF BUG IN THE DECOMPOSITION CODE - * Note that during the decomposition, only the upper triangular part of A is considered. Therefore, - * the strict lower part does not have to store correct values. - */ template class LDLT { public: @@ -98,6 +84,11 @@ template class LDLT m_isInitialized(false) {} + /** \brief Constructor with decomposition + * + * This calculates the decomposition for the input \a matrix. + * \sa LDLT(Index size) + */ LDLT(const MatrixType& matrix) : m_matrix(matrix.rows(), matrix.cols()), m_transpositions(matrix.rows()), @@ -107,6 +98,14 @@ template class LDLT compute(matrix); } + /** Clear any existing decomposition + * \sa rankUpdate(w,sigma) + */ + void setZero() + { + m_isInitialized = false; + } + /** \returns a view of the upper triangular matrix U */ inline typename Traits::MatrixU matrixU() const { @@ -130,14 +129,14 @@ template class LDLT } /** \returns the coefficients of the diagonal matrix D */ - inline Diagonal vectorD(void) const + inline Diagonal vectorD() const { eigen_assert(m_isInitialized && "LDLT is not initialized."); return m_matrix.diagonal(); } /** \returns true if the matrix is positive (semidefinite) */ - inline bool isPositive(void) const + inline bool isPositive() const { eigen_assert(m_isInitialized && "LDLT is not initialized."); return m_sign == 1; @@ -196,6 +195,9 @@ template class LDLT LDLT& compute(const MatrixType& matrix); + template + LDLT& rankUpdate(const MatrixBase& w,RealScalar alpha=1); + /** \returns the internal LDLT decomposition matrix * * TODO: document the storage layout @@ -211,6 +213,17 @@ template class LDLT inline Index rows() const { return m_matrix.rows(); } inline Index cols() const { return m_matrix.cols(); } + /** \brief Reports whether previous computation was successful. + * + * \returns \c Success if computation was succesful, + * \c NumericalIssue if the matrix.appears to be negative. + */ + ComputationInfo info() const + { + eigen_assert(m_isInitialized && "LDLT is not initialized."); + return Success; + } + protected: /** \internal @@ -249,7 +262,7 @@ template<> struct ldlt_inplace return true; } - RealScalar cutoff = 0, biggest_in_corner; + RealScalar cutoff(0), biggest_in_corner; for (Index k = 0; k < size; ++k) { @@ -317,6 +330,61 @@ template<> struct ldlt_inplace return true; } + + // Reference for the algorithm: Davis and Hager, "Multiple Rank + // Modifications of a Sparse Cholesky Factorization" (Algorithm 1) + // Trivial rearrangements of their computations (Timothy E. Holy) + // allow their algorithm to work for rank-1 updates even if the + // original matrix is not of full rank. + // Here only rank-1 updates are implemented, to reduce the + // requirement for intermediate storage and improve accuracy + template + static bool updateInPlace(MatrixType& mat, MatrixBase& w, typename MatrixType::RealScalar sigma=1) + { + using internal::isfinite; + typedef typename MatrixType::Scalar Scalar; + typedef typename MatrixType::RealScalar RealScalar; + typedef typename MatrixType::Index Index; + + const Index size = mat.rows(); + eigen_assert(mat.cols() == size && w.size()==size); + + RealScalar alpha = 1; + + // Apply the update + for (Index j = 0; j < size; j++) + { + // Check for termination due to an original decomposition of low-rank + if (!(isfinite)(alpha)) + break; + + // Update the diagonal terms + RealScalar dj = real(mat.coeff(j,j)); + Scalar wj = w.coeff(j); + RealScalar swj2 = sigma*abs2(wj); + RealScalar gamma = dj*alpha + swj2; + + mat.coeffRef(j,j) += swj2/alpha; + alpha += swj2/dj; + + + // Update the terms of L + Index rs = size-j-1; + w.tail(rs) -= wj * mat.col(j).tail(rs); + if(gamma != 0) + mat.col(j).tail(rs) += (sigma*conj(wj)/gamma)*w.tail(rs); + } + return true; + } + + template + static bool update(MatrixType& mat, const TranspositionType& transpositions, Workspace& tmp, const WType& w, typename MatrixType::RealScalar sigma=1) + { + // Apply the permutation to the input w + tmp = transpositions * w; + + return ldlt_inplace::updateInPlace(mat,tmp,sigma); + } }; template<> struct ldlt_inplace @@ -327,22 +395,29 @@ template<> struct ldlt_inplace Transpose matt(mat); return ldlt_inplace::unblocked(matt, transpositions, temp, sign); } + + template + static EIGEN_STRONG_INLINE bool update(MatrixType& mat, TranspositionType& transpositions, Workspace& tmp, WType& w, typename MatrixType::RealScalar sigma=1) + { + Transpose matt(mat); + return ldlt_inplace::update(matt, transpositions, tmp, w.conjugate(), sigma); + } }; template struct LDLT_Traits { typedef const TriangularView MatrixL; typedef const TriangularView MatrixU; - inline static MatrixL getL(const MatrixType& m) { return m; } - inline static MatrixU getU(const MatrixType& m) { return m.adjoint(); } + static inline MatrixL getL(const MatrixType& m) { return m; } + static inline MatrixU getU(const MatrixType& m) { return m.adjoint(); } }; template struct LDLT_Traits { typedef const TriangularView MatrixL; typedef const TriangularView MatrixU; - inline static MatrixL getL(const MatrixType& m) { return m.adjoint(); } - inline static MatrixU getU(const MatrixType& m) { return m; } + static inline MatrixL getL(const MatrixType& m) { return m.adjoint(); } + static inline MatrixU getU(const MatrixType& m) { return m; } }; } // end namespace internal @@ -367,6 +442,37 @@ LDLT& LDLT::compute(const MatrixType& a) return *this; } +/** Update the LDLT decomposition: given A = L D L^T, efficiently compute the decomposition of A + sigma w w^T. + * \param w a vector to be incorporated into the decomposition. + * \param sigma a scalar, +1 for updates and -1 for "downdates," which correspond to removing previously-added column vectors. Optional; default value is +1. + * \sa setZero() + */ +template +template +LDLT& LDLT::rankUpdate(const MatrixBase& w,typename NumTraits::Real sigma) +{ + const Index size = w.rows(); + if (m_isInitialized) + { + eigen_assert(m_matrix.rows()==size); + } + else + { + m_matrix.resize(size,size); + m_matrix.setZero(); + m_transpositions.resize(size); + for (Index i = 0; i < size; i++) + m_transpositions.coeffRef(i) = i; + m_temporary.resize(size); + m_sign = sigma>=0 ? 1 : -1; + m_isInitialized = true; + } + + internal::ldlt_inplace::update(m_matrix, m_transpositions, m_temporary, w, sigma); + + return *this; +} + namespace internal { template struct solve_retval, Rhs> @@ -481,4 +587,6 @@ MatrixBase::ldlt() const return LDLT(derived()); } +} // end namespace Eigen + #endif // EIGEN_LDLT_H diff --git a/extern/Eigen3/Eigen/src/Cholesky/LLT.h b/extern/Eigen3/Eigen/src/Cholesky/LLT.h index 3bb76b5787f..41d14e532f1 100644 --- a/extern/Eigen3/Eigen/src/Cholesky/LLT.h +++ b/extern/Eigen3/Eigen/src/Cholesky/LLT.h @@ -3,39 +3,28 @@ // // Copyright (C) 2008 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_LLT_H #define EIGEN_LLT_H +namespace Eigen { + namespace internal{ template struct LLT_Traits; } -/** \ingroup cholesky_Module +/** \ingroup Cholesky_Module * * \class LLT * * \brief Standard Cholesky decomposition (LL^T) of a matrix and associated features * * \param MatrixType the type of the matrix of which we are computing the LL^T Cholesky decomposition + * \param UpLo the triangular part that will be used for the decompositon: Lower (default) or Upper. + * The other triangular part won't be read. * * This class performs a LL^T Cholesky decomposition of a symmetric, positive definite * matrix A such that A = LL^* = U^*U, where L is lower triangular. @@ -49,6 +38,9 @@ template struct LLT_Traits; * use LDLT instead for the semidefinite case. Also, do not use a Cholesky decomposition to determine whether a system of equations * has a solution. * + * Example: \include LLT_example.cpp + * Output: \verbinclude LLT_example.out + * * \sa MatrixBase::llt(), class LDLT */ /* HEY THIS DOX IS DISABLED BECAUSE THERE's A BUG EITHER HERE OR IN LDLT ABOUT THAT (OR BOTH) @@ -178,6 +170,9 @@ template class LLT inline Index rows() const { return m_matrix.rows(); } inline Index cols() const { return m_matrix.cols(); } + template + LLT rankUpdate(const VectorType& vec, const RealScalar& sigma = 1); + protected: /** \internal * Used to compute and store L @@ -190,16 +185,85 @@ template class LLT namespace internal { -template struct llt_inplace; +template struct llt_inplace; -template<> struct llt_inplace +template +static typename MatrixType::Index llt_rank_update_lower(MatrixType& mat, const VectorType& vec, const typename MatrixType::RealScalar& sigma) { + typedef typename MatrixType::Scalar Scalar; + typedef typename MatrixType::RealScalar RealScalar; + typedef typename MatrixType::Index Index; + typedef typename MatrixType::ColXpr ColXpr; + typedef typename internal::remove_all::type ColXprCleaned; + typedef typename ColXprCleaned::SegmentReturnType ColXprSegment; + typedef Matrix TempVectorType; + typedef typename TempVectorType::SegmentReturnType TempVecSegment; + + int n = mat.cols(); + eigen_assert(mat.rows()==n && vec.size()==n); + + TempVectorType temp; + + if(sigma>0) + { + // This version is based on Givens rotations. + // It is faster than the other one below, but only works for updates, + // i.e., for sigma > 0 + temp = sqrt(sigma) * vec; + + for(int i=0; i g; + g.makeGivens(mat(i,i), -temp(i), &mat(i,i)); + + int rs = n-i-1; + if(rs>0) + { + ColXprSegment x(mat.col(i).tail(rs)); + TempVecSegment y(temp.tail(rs)); + apply_rotation_in_the_plane(x, y, g); + } + } + } + else + { + temp = vec; + RealScalar beta = 1; + for(int j=0; j struct llt_inplace +{ + typedef typename NumTraits::Real RealScalar; template static typename MatrixType::Index unblocked(MatrixType& mat) { typedef typename MatrixType::Index Index; - typedef typename MatrixType::Scalar Scalar; - typedef typename MatrixType::RealScalar RealScalar; eigen_assert(mat.rows()==mat.cols()); const Index size = mat.rows(); @@ -254,21 +318,35 @@ template<> struct llt_inplace } return -1; } -}; -template<> struct llt_inplace + template + static typename MatrixType::Index rankUpdate(MatrixType& mat, const VectorType& vec, const RealScalar& sigma) + { + return Eigen::internal::llt_rank_update_lower(mat, vec, sigma); + } +}; + +template struct llt_inplace { + typedef typename NumTraits::Real RealScalar; + template static EIGEN_STRONG_INLINE typename MatrixType::Index unblocked(MatrixType& mat) { Transpose matt(mat); - return llt_inplace::unblocked(matt); + return llt_inplace::unblocked(matt); } template static EIGEN_STRONG_INLINE typename MatrixType::Index blocked(MatrixType& mat) { Transpose matt(mat); - return llt_inplace::blocked(matt); + return llt_inplace::blocked(matt); + } + template + static typename MatrixType::Index rankUpdate(MatrixType& mat, const VectorType& vec, const RealScalar& sigma) + { + Transpose matt(mat); + return llt_inplace::rankUpdate(matt, vec.conjugate(), sigma); } }; @@ -276,33 +354,35 @@ template struct LLT_Traits { typedef const TriangularView MatrixL; typedef const TriangularView MatrixU; - inline static MatrixL getL(const MatrixType& m) { return m; } - inline static MatrixU getU(const MatrixType& m) { return m.adjoint(); } + static inline MatrixL getL(const MatrixType& m) { return m; } + static inline MatrixU getU(const MatrixType& m) { return m.adjoint(); } static bool inplace_decomposition(MatrixType& m) - { return llt_inplace::blocked(m)==-1; } + { return llt_inplace::blocked(m)==-1; } }; template struct LLT_Traits { typedef const TriangularView MatrixL; typedef const TriangularView MatrixU; - inline static MatrixL getL(const MatrixType& m) { return m.adjoint(); } - inline static MatrixU getU(const MatrixType& m) { return m; } + static inline MatrixL getL(const MatrixType& m) { return m.adjoint(); } + static inline MatrixU getU(const MatrixType& m) { return m; } static bool inplace_decomposition(MatrixType& m) - { return llt_inplace::blocked(m)==-1; } + { return llt_inplace::blocked(m)==-1; } }; } // end namespace internal /** Computes / recomputes the Cholesky decomposition A = LL^* = U^*U of \a matrix - * * * \returns a reference to *this + * + * Example: \include TutorialLinAlgComputeTwice.cpp + * Output: \verbinclude TutorialLinAlgComputeTwice.out */ template LLT& LLT::compute(const MatrixType& a) { - assert(a.rows()==a.cols()); + eigen_assert(a.rows()==a.cols()); const Index size = a.rows(); m_matrix.resize(size, size); m_matrix = a; @@ -314,6 +394,26 @@ LLT& LLT::compute(const MatrixType& a) return *this; } +/** Performs a rank one update (or dowdate) of the current decomposition. + * If A = LL^* before the rank one update, + * then after it we have LL^* = A + sigma * v v^* where \a v must be a vector + * of same dimension. + */ +template +template +LLT<_MatrixType,_UpLo> LLT<_MatrixType,_UpLo>::rankUpdate(const VectorType& v, const RealScalar& sigma) +{ + EIGEN_STATIC_ASSERT_VECTOR_ONLY(VectorType); + eigen_assert(v.size()==m_matrix.cols()); + eigen_assert(m_isInitialized); + if(internal::llt_inplace::rankUpdate(m_matrix,v,sigma)>=0) + m_info = NumericalIssue; + else + m_info = Success; + + return *this; +} + namespace internal { template struct solve_retval, Rhs> @@ -383,4 +483,6 @@ SelfAdjointView::llt() const return LLT(m_matrix); } +} // end namespace Eigen + #endif // EIGEN_LLT_H diff --git a/extern/Eigen3/Eigen/src/Cholesky/LLT_MKL.h b/extern/Eigen3/Eigen/src/Cholesky/LLT_MKL.h new file mode 100644 index 00000000000..64daa445cf7 --- /dev/null +++ b/extern/Eigen3/Eigen/src/Cholesky/LLT_MKL.h @@ -0,0 +1,102 @@ +/* + Copyright (c) 2011, Intel Corporation. All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of Intel Corporation nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ******************************************************************************** + * Content : Eigen bindings to Intel(R) MKL + * LLt decomposition based on LAPACKE_?potrf function. + ******************************************************************************** +*/ + +#ifndef EIGEN_LLT_MKL_H +#define EIGEN_LLT_MKL_H + +#include "Eigen/src/Core/util/MKL_support.h" +#include + +namespace Eigen { + +namespace internal { + +template struct mkl_llt; + +#define EIGEN_MKL_LLT(EIGTYPE, MKLTYPE, MKLPREFIX) \ +template<> struct mkl_llt \ +{ \ + template \ + static inline typename MatrixType::Index potrf(MatrixType& m, char uplo) \ + { \ + lapack_int matrix_order; \ + lapack_int size, lda, info, StorageOrder; \ + EIGTYPE* a; \ + eigen_assert(m.rows()==m.cols()); \ + /* Set up parameters for ?potrf */ \ + size = m.rows(); \ + StorageOrder = MatrixType::Flags&RowMajorBit?RowMajor:ColMajor; \ + matrix_order = StorageOrder==RowMajor ? LAPACK_ROW_MAJOR : LAPACK_COL_MAJOR; \ + a = &(m.coeffRef(0,0)); \ + lda = m.outerStride(); \ +\ + info = LAPACKE_##MKLPREFIX##potrf( matrix_order, uplo, size, (MKLTYPE*)a, lda ); \ + info = (info==0) ? Success : NumericalIssue; \ + return info; \ + } \ +}; \ +template<> struct llt_inplace \ +{ \ + template \ + static typename MatrixType::Index blocked(MatrixType& m) \ + { \ + return mkl_llt::potrf(m, 'L'); \ + } \ + template \ + static typename MatrixType::Index rankUpdate(MatrixType& mat, const VectorType& vec, const typename MatrixType::RealScalar& sigma) \ + { return Eigen::internal::llt_rank_update_lower(mat, vec, sigma); } \ +}; \ +template<> struct llt_inplace \ +{ \ + template \ + static typename MatrixType::Index blocked(MatrixType& m) \ + { \ + return mkl_llt::potrf(m, 'U'); \ + } \ + template \ + static typename MatrixType::Index rankUpdate(MatrixType& mat, const VectorType& vec, const typename MatrixType::RealScalar& sigma) \ + { \ + Transpose matt(mat); \ + return llt_inplace::rankUpdate(matt, vec.conjugate(), sigma); \ + } \ +}; + +EIGEN_MKL_LLT(double, double, d) +EIGEN_MKL_LLT(float, float, s) +EIGEN_MKL_LLT(dcomplex, MKL_Complex16, z) +EIGEN_MKL_LLT(scomplex, MKL_Complex8, c) + +} // end namespace internal + +} // end namespace Eigen + +#endif // EIGEN_LLT_MKL_H diff --git a/extern/Eigen3/Eigen/src/CholmodSupport/CholmodSupport.h b/extern/Eigen3/Eigen/src/CholmodSupport/CholmodSupport.h new file mode 100644 index 00000000000..37f142150ff --- /dev/null +++ b/extern/Eigen3/Eigen/src/CholmodSupport/CholmodSupport.h @@ -0,0 +1,579 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008-2010 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_CHOLMODSUPPORT_H +#define EIGEN_CHOLMODSUPPORT_H + +namespace Eigen { + +namespace internal { + +template +void cholmod_configure_matrix(CholmodType& mat) +{ + if (internal::is_same::value) + { + mat.xtype = CHOLMOD_REAL; + mat.dtype = CHOLMOD_SINGLE; + } + else if (internal::is_same::value) + { + mat.xtype = CHOLMOD_REAL; + mat.dtype = CHOLMOD_DOUBLE; + } + else if (internal::is_same >::value) + { + mat.xtype = CHOLMOD_COMPLEX; + mat.dtype = CHOLMOD_SINGLE; + } + else if (internal::is_same >::value) + { + mat.xtype = CHOLMOD_COMPLEX; + mat.dtype = CHOLMOD_DOUBLE; + } + else + { + eigen_assert(false && "Scalar type not supported by CHOLMOD"); + } +} + +} // namespace internal + +/** Wraps the Eigen sparse matrix \a mat into a Cholmod sparse matrix object. + * Note that the data are shared. + */ +template +cholmod_sparse viewAsCholmod(SparseMatrix<_Scalar,_Options,_Index>& mat) +{ + typedef SparseMatrix<_Scalar,_Options,_Index> MatrixType; + cholmod_sparse res; + res.nzmax = mat.nonZeros(); + res.nrow = mat.rows();; + res.ncol = mat.cols(); + res.p = mat.outerIndexPtr(); + res.i = mat.innerIndexPtr(); + res.x = mat.valuePtr(); + res.sorted = 1; + if(mat.isCompressed()) + { + res.packed = 1; + } + else + { + res.packed = 0; + res.nz = mat.innerNonZeroPtr(); + } + + res.dtype = 0; + res.stype = -1; + + if (internal::is_same<_Index,int>::value) + { + res.itype = CHOLMOD_INT; + } + else + { + eigen_assert(false && "Index type different than int is not supported yet"); + } + + // setup res.xtype + internal::cholmod_configure_matrix<_Scalar>(res); + + res.stype = 0; + + return res; +} + +template +const cholmod_sparse viewAsCholmod(const SparseMatrix<_Scalar,_Options,_Index>& mat) +{ + cholmod_sparse res = viewAsCholmod(mat.const_cast_derived()); + return res; +} + +/** Returns a view of the Eigen sparse matrix \a mat as Cholmod sparse matrix. + * The data are not copied but shared. */ +template +cholmod_sparse viewAsCholmod(const SparseSelfAdjointView, UpLo>& mat) +{ + cholmod_sparse res = viewAsCholmod(mat.matrix().const_cast_derived()); + + if(UpLo==Upper) res.stype = 1; + if(UpLo==Lower) res.stype = -1; + + return res; +} + +/** Returns a view of the Eigen \b dense matrix \a mat as Cholmod dense matrix. + * The data are not copied but shared. */ +template +cholmod_dense viewAsCholmod(MatrixBase& mat) +{ + EIGEN_STATIC_ASSERT((internal::traits::Flags&RowMajorBit)==0,THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES); + typedef typename Derived::Scalar Scalar; + + cholmod_dense res; + res.nrow = mat.rows(); + res.ncol = mat.cols(); + res.nzmax = res.nrow * res.ncol; + res.d = Derived::IsVectorAtCompileTime ? mat.derived().size() : mat.derived().outerStride(); + res.x = mat.derived().data(); + res.z = 0; + + internal::cholmod_configure_matrix(res); + + return res; +} + +/** Returns a view of the Cholmod sparse matrix \a cm as an Eigen sparse matrix. + * The data are not copied but shared. */ +template +MappedSparseMatrix viewAsEigen(cholmod_sparse& cm) +{ + return MappedSparseMatrix + (cm.nrow, cm.ncol, reinterpret_cast(cm.p)[cm.ncol], + reinterpret_cast(cm.p), reinterpret_cast(cm.i),reinterpret_cast(cm.x) ); +} + +enum CholmodMode { + CholmodAuto, CholmodSimplicialLLt, CholmodSupernodalLLt, CholmodLDLt +}; + + +/** \ingroup CholmodSupport_Module + * \class CholmodBase + * \brief The base class for the direct Cholesky factorization of Cholmod + * \sa class CholmodSupernodalLLT, class CholmodSimplicialLDLT, class CholmodSimplicialLLT + */ +template +class CholmodBase : internal::noncopyable +{ + public: + typedef _MatrixType MatrixType; + enum { UpLo = _UpLo }; + typedef typename MatrixType::Scalar Scalar; + typedef typename MatrixType::RealScalar RealScalar; + typedef MatrixType CholMatrixType; + typedef typename MatrixType::Index Index; + + public: + + CholmodBase() + : m_cholmodFactor(0), m_info(Success), m_isInitialized(false) + { + cholmod_start(&m_cholmod); + } + + CholmodBase(const MatrixType& matrix) + : m_cholmodFactor(0), m_info(Success), m_isInitialized(false) + { + cholmod_start(&m_cholmod); + compute(matrix); + } + + ~CholmodBase() + { + if(m_cholmodFactor) + cholmod_free_factor(&m_cholmodFactor, &m_cholmod); + cholmod_finish(&m_cholmod); + } + + inline Index cols() const { return m_cholmodFactor->n; } + inline Index rows() const { return m_cholmodFactor->n; } + + Derived& derived() { return *static_cast(this); } + const Derived& derived() const { return *static_cast(this); } + + /** \brief Reports whether previous computation was successful. + * + * \returns \c Success if computation was succesful, + * \c NumericalIssue if the matrix.appears to be negative. + */ + ComputationInfo info() const + { + eigen_assert(m_isInitialized && "Decomposition is not initialized."); + return m_info; + } + + /** Computes the sparse Cholesky decomposition of \a matrix */ + Derived& compute(const MatrixType& matrix) + { + analyzePattern(matrix); + factorize(matrix); + return derived(); + } + + /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A. + * + * \sa compute() + */ + template + inline const internal::solve_retval + solve(const MatrixBase& b) const + { + eigen_assert(m_isInitialized && "LLT is not initialized."); + eigen_assert(rows()==b.rows() + && "CholmodDecomposition::solve(): invalid number of rows of the right hand side matrix b"); + return internal::solve_retval(*this, b.derived()); + } + + /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A. + * + * \sa compute() + */ + template + inline const internal::sparse_solve_retval + solve(const SparseMatrixBase& b) const + { + eigen_assert(m_isInitialized && "LLT is not initialized."); + eigen_assert(rows()==b.rows() + && "CholmodDecomposition::solve(): invalid number of rows of the right hand side matrix b"); + return internal::sparse_solve_retval(*this, b.derived()); + } + + /** Performs a symbolic decomposition on the sparcity of \a matrix. + * + * This function is particularly useful when solving for several problems having the same structure. + * + * \sa factorize() + */ + void analyzePattern(const MatrixType& matrix) + { + if(m_cholmodFactor) + { + cholmod_free_factor(&m_cholmodFactor, &m_cholmod); + m_cholmodFactor = 0; + } + cholmod_sparse A = viewAsCholmod(matrix.template selfadjointView()); + m_cholmodFactor = cholmod_analyze(&A, &m_cholmod); + + this->m_isInitialized = true; + this->m_info = Success; + m_analysisIsOk = true; + m_factorizationIsOk = false; + } + + /** Performs a numeric decomposition of \a matrix + * + * The given matrix must has the same sparcity than the matrix on which the symbolic decomposition has been performed. + * + * \sa analyzePattern() + */ + void factorize(const MatrixType& matrix) + { + eigen_assert(m_analysisIsOk && "You must first call analyzePattern()"); + cholmod_sparse A = viewAsCholmod(matrix.template selfadjointView()); + cholmod_factorize(&A, m_cholmodFactor, &m_cholmod); + + this->m_info = Success; + m_factorizationIsOk = true; + } + + /** Returns a reference to the Cholmod's configuration structure to get a full control over the performed operations. + * See the Cholmod user guide for details. */ + cholmod_common& cholmod() { return m_cholmod; } + + #ifndef EIGEN_PARSED_BY_DOXYGEN + /** \internal */ + template + void _solve(const MatrixBase &b, MatrixBase &dest) const + { + eigen_assert(m_factorizationIsOk && "The decomposition is not in a valid state for solving, you must first call either compute() or symbolic()/numeric()"); + const Index size = m_cholmodFactor->n; + eigen_assert(size==b.rows()); + + // note: cd stands for Cholmod Dense + cholmod_dense b_cd = viewAsCholmod(b.const_cast_derived()); + cholmod_dense* x_cd = cholmod_solve(CHOLMOD_A, m_cholmodFactor, &b_cd, &m_cholmod); + if(!x_cd) + { + this->m_info = NumericalIssue; + } + // TODO optimize this copy by swapping when possible (be carreful with alignment, etc.) + dest = Matrix::Map(reinterpret_cast(x_cd->x),b.rows(),b.cols()); + cholmod_free_dense(&x_cd, &m_cholmod); + } + + /** \internal */ + template + void _solve(const SparseMatrix &b, SparseMatrix &dest) const + { + eigen_assert(m_factorizationIsOk && "The decomposition is not in a valid state for solving, you must first call either compute() or symbolic()/numeric()"); + const Index size = m_cholmodFactor->n; + eigen_assert(size==b.rows()); + + // note: cs stands for Cholmod Sparse + cholmod_sparse b_cs = viewAsCholmod(b); + cholmod_sparse* x_cs = cholmod_spsolve(CHOLMOD_A, m_cholmodFactor, &b_cs, &m_cholmod); + if(!x_cs) + { + this->m_info = NumericalIssue; + } + // TODO optimize this copy by swapping when possible (be carreful with alignment, etc.) + dest = viewAsEigen(*x_cs); + cholmod_free_sparse(&x_cs, &m_cholmod); + } + #endif // EIGEN_PARSED_BY_DOXYGEN + + template + void dumpMemory(Stream& s) + {} + + protected: + mutable cholmod_common m_cholmod; + cholmod_factor* m_cholmodFactor; + mutable ComputationInfo m_info; + bool m_isInitialized; + int m_factorizationIsOk; + int m_analysisIsOk; +}; + +/** \ingroup CholmodSupport_Module + * \class CholmodSimplicialLLT + * \brief A simplicial direct Cholesky (LLT) factorization and solver based on Cholmod + * + * This class allows to solve for A.X = B sparse linear problems via a simplicial LL^T Cholesky factorization + * using the Cholmod library. + * This simplicial variant is equivalent to Eigen's built-in SimplicialLLT class. Thefore, it has little practical interest. + * The sparse matrix A must be selfajoint and positive definite. The vectors or matrices + * X and B can be either dense or sparse. + * + * \tparam _MatrixType the type of the sparse matrix A, it must be a SparseMatrix<> + * \tparam _UpLo the triangular part that will be used for the computations. It can be Lower + * or Upper. Default is Lower. + * + * This class supports all kind of SparseMatrix<>: row or column major; upper, lower, or both; compressed or non compressed. + * + * \sa \ref TutorialSparseDirectSolvers, class CholmodSupernodalLLT, class SimplicialLLT + */ +template +class CholmodSimplicialLLT : public CholmodBase<_MatrixType, _UpLo, CholmodSimplicialLLT<_MatrixType, _UpLo> > +{ + typedef CholmodBase<_MatrixType, _UpLo, CholmodSimplicialLLT> Base; + using Base::m_cholmod; + + public: + + typedef _MatrixType MatrixType; + + CholmodSimplicialLLT() : Base() { init(); } + + CholmodSimplicialLLT(const MatrixType& matrix) : Base() + { + init(); + compute(matrix); + } + + ~CholmodSimplicialLLT() {} + protected: + void init() + { + m_cholmod.final_asis = 0; + m_cholmod.supernodal = CHOLMOD_SIMPLICIAL; + m_cholmod.final_ll = 1; + } +}; + + +/** \ingroup CholmodSupport_Module + * \class CholmodSimplicialLDLT + * \brief A simplicial direct Cholesky (LDLT) factorization and solver based on Cholmod + * + * This class allows to solve for A.X = B sparse linear problems via a simplicial LDL^T Cholesky factorization + * using the Cholmod library. + * This simplicial variant is equivalent to Eigen's built-in SimplicialLDLT class. Thefore, it has little practical interest. + * The sparse matrix A must be selfajoint and positive definite. The vectors or matrices + * X and B can be either dense or sparse. + * + * \tparam _MatrixType the type of the sparse matrix A, it must be a SparseMatrix<> + * \tparam _UpLo the triangular part that will be used for the computations. It can be Lower + * or Upper. Default is Lower. + * + * This class supports all kind of SparseMatrix<>: row or column major; upper, lower, or both; compressed or non compressed. + * + * \sa \ref TutorialSparseDirectSolvers, class CholmodSupernodalLLT, class SimplicialLDLT + */ +template +class CholmodSimplicialLDLT : public CholmodBase<_MatrixType, _UpLo, CholmodSimplicialLDLT<_MatrixType, _UpLo> > +{ + typedef CholmodBase<_MatrixType, _UpLo, CholmodSimplicialLDLT> Base; + using Base::m_cholmod; + + public: + + typedef _MatrixType MatrixType; + + CholmodSimplicialLDLT() : Base() { init(); } + + CholmodSimplicialLDLT(const MatrixType& matrix) : Base() + { + init(); + compute(matrix); + } + + ~CholmodSimplicialLDLT() {} + protected: + void init() + { + m_cholmod.final_asis = 1; + m_cholmod.supernodal = CHOLMOD_SIMPLICIAL; + } +}; + +/** \ingroup CholmodSupport_Module + * \class CholmodSupernodalLLT + * \brief A supernodal Cholesky (LLT) factorization and solver based on Cholmod + * + * This class allows to solve for A.X = B sparse linear problems via a supernodal LL^T Cholesky factorization + * using the Cholmod library. + * This supernodal variant performs best on dense enough problems, e.g., 3D FEM, or very high order 2D FEM. + * The sparse matrix A must be selfajoint and positive definite. The vectors or matrices + * X and B can be either dense or sparse. + * + * \tparam _MatrixType the type of the sparse matrix A, it must be a SparseMatrix<> + * \tparam _UpLo the triangular part that will be used for the computations. It can be Lower + * or Upper. Default is Lower. + * + * This class supports all kind of SparseMatrix<>: row or column major; upper, lower, or both; compressed or non compressed. + * + * \sa \ref TutorialSparseDirectSolvers + */ +template +class CholmodSupernodalLLT : public CholmodBase<_MatrixType, _UpLo, CholmodSupernodalLLT<_MatrixType, _UpLo> > +{ + typedef CholmodBase<_MatrixType, _UpLo, CholmodSupernodalLLT> Base; + using Base::m_cholmod; + + public: + + typedef _MatrixType MatrixType; + + CholmodSupernodalLLT() : Base() { init(); } + + CholmodSupernodalLLT(const MatrixType& matrix) : Base() + { + init(); + compute(matrix); + } + + ~CholmodSupernodalLLT() {} + protected: + void init() + { + m_cholmod.final_asis = 1; + m_cholmod.supernodal = CHOLMOD_SUPERNODAL; + } +}; + +/** \ingroup CholmodSupport_Module + * \class CholmodDecomposition + * \brief A general Cholesky factorization and solver based on Cholmod + * + * This class allows to solve for A.X = B sparse linear problems via a LL^T or LDL^T Cholesky factorization + * using the Cholmod library. The sparse matrix A must be selfajoint and positive definite. The vectors or matrices + * X and B can be either dense or sparse. + * + * This variant permits to change the underlying Cholesky method at runtime. + * On the other hand, it does not provide access to the result of the factorization. + * The default is to let Cholmod automatically choose between a simplicial and supernodal factorization. + * + * \tparam _MatrixType the type of the sparse matrix A, it must be a SparseMatrix<> + * \tparam _UpLo the triangular part that will be used for the computations. It can be Lower + * or Upper. Default is Lower. + * + * This class supports all kind of SparseMatrix<>: row or column major; upper, lower, or both; compressed or non compressed. + * + * \sa \ref TutorialSparseDirectSolvers + */ +template +class CholmodDecomposition : public CholmodBase<_MatrixType, _UpLo, CholmodDecomposition<_MatrixType, _UpLo> > +{ + typedef CholmodBase<_MatrixType, _UpLo, CholmodDecomposition> Base; + using Base::m_cholmod; + + public: + + typedef _MatrixType MatrixType; + + CholmodDecomposition() : Base() { init(); } + + CholmodDecomposition(const MatrixType& matrix) : Base() + { + init(); + compute(matrix); + } + + ~CholmodDecomposition() {} + + void setMode(CholmodMode mode) + { + switch(mode) + { + case CholmodAuto: + m_cholmod.final_asis = 1; + m_cholmod.supernodal = CHOLMOD_AUTO; + break; + case CholmodSimplicialLLt: + m_cholmod.final_asis = 0; + m_cholmod.supernodal = CHOLMOD_SIMPLICIAL; + m_cholmod.final_ll = 1; + break; + case CholmodSupernodalLLt: + m_cholmod.final_asis = 1; + m_cholmod.supernodal = CHOLMOD_SUPERNODAL; + break; + case CholmodLDLt: + m_cholmod.final_asis = 1; + m_cholmod.supernodal = CHOLMOD_SIMPLICIAL; + break; + default: + break; + } + } + protected: + void init() + { + m_cholmod.final_asis = 1; + m_cholmod.supernodal = CHOLMOD_AUTO; + } +}; + +namespace internal { + +template +struct solve_retval, Rhs> + : solve_retval_base, Rhs> +{ + typedef CholmodBase<_MatrixType,_UpLo,Derived> Dec; + EIGEN_MAKE_SOLVE_HELPERS(Dec,Rhs) + + template void evalTo(Dest& dst) const + { + dec()._solve(rhs(),dst); + } +}; + +template +struct sparse_solve_retval, Rhs> + : sparse_solve_retval_base, Rhs> +{ + typedef CholmodBase<_MatrixType,_UpLo,Derived> Dec; + EIGEN_MAKE_SPARSE_SOLVE_HELPERS(Dec,Rhs) + + template void evalTo(Dest& dst) const + { + dec()._solve(rhs(),dst); + } +}; + +} // end namespace internal + +} // end namespace Eigen + +#endif // EIGEN_CHOLMODSUPPORT_H diff --git a/extern/Eigen3/Eigen/src/Core/Array.h b/extern/Eigen3/Eigen/src/Core/Array.h index a11fb1b53d5..aaa38997838 100644 --- a/extern/Eigen3/Eigen/src/Core/Array.h +++ b/extern/Eigen3/Eigen/src/Core/Array.h @@ -3,28 +3,15 @@ // // Copyright (C) 2009 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_ARRAY_H #define EIGEN_ARRAY_H +namespace Eigen { + /** \class Array * \ingroup Core_Module * @@ -316,5 +303,6 @@ EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(d) \ EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(cf) \ EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(cd) +} // end namespace Eigen #endif // EIGEN_ARRAY_H diff --git a/extern/Eigen3/Eigen/src/Core/ArrayBase.h b/extern/Eigen3/Eigen/src/Core/ArrayBase.h index 9399ac3d15c..004b117c933 100644 --- a/extern/Eigen3/Eigen/src/Core/ArrayBase.h +++ b/extern/Eigen3/Eigen/src/Core/ArrayBase.h @@ -3,28 +3,15 @@ // // Copyright (C) 2009 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_ARRAYBASE_H #define EIGEN_ARRAYBASE_H +namespace Eigen { + template class MatrixWrapper; /** \class ArrayBase @@ -159,7 +146,7 @@ template class ArrayBase /** \returns an \link MatrixBase Matrix \endlink expression of this array * \sa MatrixBase::array() */ MatrixWrapper matrix() { return derived(); } - const MatrixWrapper matrix() const { return derived(); } + const MatrixWrapper matrix() const { return derived(); } // template // inline void evalTo(Dest& dst) const { dst = matrix(); } @@ -174,10 +161,10 @@ template class ArrayBase protected: // mixing arrays and matrices is not legal template Derived& operator+=(const MatrixBase& ) - {EIGEN_STATIC_ASSERT(sizeof(typename OtherDerived::Scalar)==-1,YOU_CANNOT_MIX_ARRAYS_AND_MATRICES);} + {EIGEN_STATIC_ASSERT(std::ptrdiff_t(sizeof(typename OtherDerived::Scalar))==-1,YOU_CANNOT_MIX_ARRAYS_AND_MATRICES); return *this;} // mixing arrays and matrices is not legal template Derived& operator-=(const MatrixBase& ) - {EIGEN_STATIC_ASSERT(sizeof(typename OtherDerived::Scalar)==-1,YOU_CANNOT_MIX_ARRAYS_AND_MATRICES);} + {EIGEN_STATIC_ASSERT(std::ptrdiff_t(sizeof(typename OtherDerived::Scalar))==-1,YOU_CANNOT_MIX_ARRAYS_AND_MATRICES); return *this;} }; /** replaces \c *this by \c *this - \a other. @@ -236,4 +223,6 @@ ArrayBase::operator/=(const ArrayBase& other) return derived(); } +} // end namespace Eigen + #endif // EIGEN_ARRAYBASE_H diff --git a/extern/Eigen3/Eigen/src/Core/ArrayWrapper.h b/extern/Eigen3/Eigen/src/Core/ArrayWrapper.h index 07f082e1edc..87af7fda937 100644 --- a/extern/Eigen3/Eigen/src/Core/ArrayWrapper.h +++ b/extern/Eigen3/Eigen/src/Core/ArrayWrapper.h @@ -3,28 +3,15 @@ // // Copyright (C) 2009-2010 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_ARRAYWRAPPER_H #define EIGEN_ARRAYWRAPPER_H +namespace Eigen { + /** \class ArrayWrapper * \ingroup Core_Module * @@ -61,7 +48,7 @@ class ArrayWrapper : public ArrayBase > typedef typename internal::nested::type NestedExpressionType; - inline ArrayWrapper(const ExpressionType& matrix) : m_expression(matrix) {} + inline ArrayWrapper(ExpressionType& matrix) : m_expression(matrix) {} inline Index rows() const { return m_expression.rows(); } inline Index cols() const { return m_expression.cols(); } @@ -71,7 +58,7 @@ class ArrayWrapper : public ArrayBase > inline ScalarWithConstIfNotLvalue* data() { return m_expression.data(); } inline const Scalar* data() const { return m_expression.data(); } - inline const CoeffReturnType coeff(Index row, Index col) const + inline CoeffReturnType coeff(Index row, Index col) const { return m_expression.coeff(row, col); } @@ -86,7 +73,7 @@ class ArrayWrapper : public ArrayBase > return m_expression.const_cast_derived().coeffRef(row, col); } - inline const CoeffReturnType coeff(Index index) const + inline CoeffReturnType coeff(Index index) const { return m_expression.coeff(index); } @@ -128,8 +115,14 @@ class ArrayWrapper : public ArrayBase > template inline void evalTo(Dest& dst) const { dst = m_expression; } + const typename internal::remove_all::type& + nestedExpression() const + { + return m_expression; + } + protected: - const NestedExpressionType m_expression; + NestedExpressionType m_expression; }; /** \class MatrixWrapper @@ -168,7 +161,7 @@ class MatrixWrapper : public MatrixBase > typedef typename internal::nested::type NestedExpressionType; - inline MatrixWrapper(const ExpressionType& matrix) : m_expression(matrix) {} + inline MatrixWrapper(ExpressionType& matrix) : m_expression(matrix) {} inline Index rows() const { return m_expression.rows(); } inline Index cols() const { return m_expression.cols(); } @@ -178,7 +171,7 @@ class MatrixWrapper : public MatrixBase > inline ScalarWithConstIfNotLvalue* data() { return m_expression.data(); } inline const Scalar* data() const { return m_expression.data(); } - inline const CoeffReturnType coeff(Index row, Index col) const + inline CoeffReturnType coeff(Index row, Index col) const { return m_expression.coeff(row, col); } @@ -193,7 +186,7 @@ class MatrixWrapper : public MatrixBase > return m_expression.derived().coeffRef(row, col); } - inline const CoeffReturnType coeff(Index index) const + inline CoeffReturnType coeff(Index index) const { return m_expression.coeff(index); } @@ -232,8 +225,16 @@ class MatrixWrapper : public MatrixBase > m_expression.const_cast_derived().template writePacket(index, x); } + const typename internal::remove_all::type& + nestedExpression() const + { + return m_expression; + } + protected: - const NestedExpressionType m_expression; + NestedExpressionType m_expression; }; +} // end namespace Eigen + #endif // EIGEN_ARRAYWRAPPER_H diff --git a/extern/Eigen3/Eigen/src/Core/Assign.h b/extern/Eigen3/Eigen/src/Core/Assign.h index 3a17152f043..cd29a88f0da 100644 --- a/extern/Eigen3/Eigen/src/Core/Assign.h +++ b/extern/Eigen3/Eigen/src/Core/Assign.h @@ -5,28 +5,15 @@ // Copyright (C) 2006-2010 Benoit Jacob // Copyright (C) 2008 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_ASSIGN_H #define EIGEN_ASSIGN_H +namespace Eigen { + namespace internal { /*************************************************************************** @@ -152,7 +139,7 @@ struct assign_DefaultTraversal_CompleteUnrolling inner = Index % Derived1::InnerSizeAtCompileTime }; - EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src) + static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src) { dst.copyCoeffByOuterInner(outer, inner, src); assign_DefaultTraversal_CompleteUnrolling::run(dst, src); @@ -162,13 +149,13 @@ struct assign_DefaultTraversal_CompleteUnrolling template struct assign_DefaultTraversal_CompleteUnrolling { - EIGEN_STRONG_INLINE static void run(Derived1 &, const Derived2 &) {} + static EIGEN_STRONG_INLINE void run(Derived1 &, const Derived2 &) {} }; template struct assign_DefaultTraversal_InnerUnrolling { - EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src, int outer) + static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src, int outer) { dst.copyCoeffByOuterInner(outer, Index, src); assign_DefaultTraversal_InnerUnrolling::run(dst, src, outer); @@ -178,7 +165,7 @@ struct assign_DefaultTraversal_InnerUnrolling template struct assign_DefaultTraversal_InnerUnrolling { - EIGEN_STRONG_INLINE static void run(Derived1 &, const Derived2 &, int) {} + static EIGEN_STRONG_INLINE void run(Derived1 &, const Derived2 &, int) {} }; /*********************** @@ -188,7 +175,7 @@ struct assign_DefaultTraversal_InnerUnrolling template struct assign_LinearTraversal_CompleteUnrolling { - EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src) + static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src) { dst.copyCoeff(Index, src); assign_LinearTraversal_CompleteUnrolling::run(dst, src); @@ -198,7 +185,7 @@ struct assign_LinearTraversal_CompleteUnrolling template struct assign_LinearTraversal_CompleteUnrolling { - EIGEN_STRONG_INLINE static void run(Derived1 &, const Derived2 &) {} + static EIGEN_STRONG_INLINE void run(Derived1 &, const Derived2 &) {} }; /************************** @@ -214,7 +201,7 @@ struct assign_innervec_CompleteUnrolling JointAlignment = assign_traits::JointAlignment }; - EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src) + static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src) { dst.template copyPacketByOuterInner(outer, inner, src); assign_innervec_CompleteUnrolling struct assign_innervec_CompleteUnrolling { - EIGEN_STRONG_INLINE static void run(Derived1 &, const Derived2 &) {} + static EIGEN_STRONG_INLINE void run(Derived1 &, const Derived2 &) {} }; template struct assign_innervec_InnerUnrolling { - EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src, int outer) + static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src, int outer) { dst.template copyPacketByOuterInner(outer, Index, src); assign_innervec_InnerUnrolling struct assign_innervec_InnerUnrolling { - EIGEN_STRONG_INLINE static void run(Derived1 &, const Derived2 &, int) {} + static EIGEN_STRONG_INLINE void run(Derived1 &, const Derived2 &, int) {} }; /*************************************************************************** @@ -251,24 +238,25 @@ struct assign_innervec_InnerUnrolling template::Traversal, - int Unrolling = assign_traits::Unrolling> + int Unrolling = assign_traits::Unrolling, + int Version = Specialized> struct assign_impl; /************************ *** Default traversal *** ************************/ -template -struct assign_impl +template +struct assign_impl { - inline static void run(Derived1 &, const Derived2 &) { } + static inline void run(Derived1 &, const Derived2 &) { } }; -template -struct assign_impl +template +struct assign_impl { typedef typename Derived1::Index Index; - inline static void run(Derived1 &dst, const Derived2 &src) + static inline void run(Derived1 &dst, const Derived2 &src) { const Index innerSize = dst.innerSize(); const Index outerSize = dst.outerSize(); @@ -278,21 +266,21 @@ struct assign_impl } }; -template -struct assign_impl +template +struct assign_impl { - EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src) + static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src) { assign_DefaultTraversal_CompleteUnrolling ::run(dst, src); } }; -template -struct assign_impl +template +struct assign_impl { typedef typename Derived1::Index Index; - EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src) + static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src) { const Index outerSize = dst.outerSize(); for(Index outer = 0; outer < outerSize; ++outer) @@ -305,11 +293,11 @@ struct assign_impl *** Linear traversal *** ***********************/ -template -struct assign_impl +template +struct assign_impl { typedef typename Derived1::Index Index; - inline static void run(Derived1 &dst, const Derived2 &src) + static inline void run(Derived1 &dst, const Derived2 &src) { const Index size = dst.size(); for(Index i = 0; i < size; ++i) @@ -317,10 +305,10 @@ struct assign_impl } }; -template -struct assign_impl +template +struct assign_impl { - EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src) + static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src) { assign_LinearTraversal_CompleteUnrolling ::run(dst, src); @@ -331,11 +319,11 @@ struct assign_impl *** Inner vectorization *** **************************/ -template -struct assign_impl +template +struct assign_impl { typedef typename Derived1::Index Index; - inline static void run(Derived1 &dst, const Derived2 &src) + static inline void run(Derived1 &dst, const Derived2 &src) { const Index innerSize = dst.innerSize(); const Index outerSize = dst.outerSize(); @@ -346,21 +334,21 @@ struct assign_impl } }; -template -struct assign_impl +template +struct assign_impl { - EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src) + static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src) { assign_innervec_CompleteUnrolling ::run(dst, src); } }; -template -struct assign_impl +template +struct assign_impl { typedef typename Derived1::Index Index; - EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src) + static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src) { const Index outerSize = dst.outerSize(); for(Index outer = 0; outer < outerSize; ++outer) @@ -398,11 +386,11 @@ struct unaligned_assign_impl } }; -template -struct assign_impl +template +struct assign_impl { typedef typename Derived1::Index Index; - EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src) + static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src) { const Index size = dst.size(); typedef packet_traits PacketTraits; @@ -412,7 +400,7 @@ struct assign_impl srcAlignment = assign_traits::JointAlignment }; const Index alignedStart = assign_traits::DstIsAligned ? 0 - : first_aligned(&dst.coeffRef(0), size); + : internal::first_aligned(&dst.coeffRef(0), size); const Index alignedEnd = alignedStart + ((size-alignedStart)/packetSize)*packetSize; unaligned_assign_impl::DstIsAligned!=0>::run(src,dst,0,alignedStart); @@ -426,11 +414,11 @@ struct assign_impl } }; -template -struct assign_impl +template +struct assign_impl { typedef typename Derived1::Index Index; - EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src) + static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src) { enum { size = Derived1::SizeAtCompileTime, packetSize = packet_traits::size, @@ -445,11 +433,11 @@ struct assign_impl -struct assign_impl +template +struct assign_impl { typedef typename Derived1::Index Index; - inline static void run(Derived1 &dst, const Derived2 &src) + static inline void run(Derived1 &dst, const Derived2 &src) { typedef packet_traits PacketTraits; enum { @@ -463,7 +451,7 @@ struct assign_impl const Index outerSize = dst.outerSize(); const Index alignedStep = alignable ? (packetSize - dst.outerStride() % packetSize) & packetAlignedMask : 0; Index alignedStart = ((!alignable) || assign_traits::DstIsAligned) ? 0 - : first_aligned(&dst.coeffRef(0,0), innerSize); + : internal::first_aligned(&dst.coeffRef(0,0), innerSize); for(Index outer = 0; outer < outerSize; ++outer) { @@ -531,19 +519,19 @@ struct assign_selector; template struct assign_selector { - EIGEN_STRONG_INLINE static Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.derived()); } + static EIGEN_STRONG_INLINE Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.derived()); } }; template struct assign_selector { - EIGEN_STRONG_INLINE static Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.eval()); } + static EIGEN_STRONG_INLINE Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.eval()); } }; template struct assign_selector { - EIGEN_STRONG_INLINE static Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.transpose()); } + static EIGEN_STRONG_INLINE Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.transpose()); } }; template struct assign_selector { - EIGEN_STRONG_INLINE static Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.transpose().eval()); } + static EIGEN_STRONG_INLINE Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.transpose().eval()); } }; } // end namespace internal @@ -590,4 +578,6 @@ EIGEN_STRONG_INLINE Derived& MatrixBase::operator=(const ReturnByValue< return derived(); } +} // end namespace Eigen + #endif // EIGEN_ASSIGN_H diff --git a/extern/Eigen3/Eigen/src/Core/Assign_MKL.h b/extern/Eigen3/Eigen/src/Core/Assign_MKL.h new file mode 100644 index 00000000000..428c6367b92 --- /dev/null +++ b/extern/Eigen3/Eigen/src/Core/Assign_MKL.h @@ -0,0 +1,224 @@ +/* + Copyright (c) 2011, Intel Corporation. All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of Intel Corporation nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ******************************************************************************** + * Content : Eigen bindings to Intel(R) MKL + * MKL VML support for coefficient-wise unary Eigen expressions like a=b.sin() + ******************************************************************************** +*/ + +#ifndef EIGEN_ASSIGN_VML_H +#define EIGEN_ASSIGN_VML_H + +namespace Eigen { + +namespace internal { + +template struct vml_call +{ enum { IsSupported = 0 }; }; + +template +class vml_assign_traits +{ + private: + enum { + DstHasDirectAccess = Dst::Flags & DirectAccessBit, + SrcHasDirectAccess = Src::Flags & DirectAccessBit, + + StorageOrdersAgree = (int(Dst::IsRowMajor) == int(Src::IsRowMajor)), + InnerSize = int(Dst::IsVectorAtCompileTime) ? int(Dst::SizeAtCompileTime) + : int(Dst::Flags)&RowMajorBit ? int(Dst::ColsAtCompileTime) + : int(Dst::RowsAtCompileTime), + InnerMaxSize = int(Dst::IsVectorAtCompileTime) ? int(Dst::MaxSizeAtCompileTime) + : int(Dst::Flags)&RowMajorBit ? int(Dst::MaxColsAtCompileTime) + : int(Dst::MaxRowsAtCompileTime), + MaxSizeAtCompileTime = Dst::SizeAtCompileTime, + + MightEnableVml = vml_call::IsSupported && StorageOrdersAgree && DstHasDirectAccess && SrcHasDirectAccess + && Src::InnerStrideAtCompileTime==1 && Dst::InnerStrideAtCompileTime==1, + MightLinearize = MightEnableVml && (int(Dst::Flags) & int(Src::Flags) & LinearAccessBit), + VmlSize = MightLinearize ? MaxSizeAtCompileTime : InnerMaxSize, + LargeEnough = VmlSize==Dynamic || VmlSize>=EIGEN_MKL_VML_THRESHOLD, + MayEnableVml = MightEnableVml && LargeEnough, + MayLinearize = MayEnableVml && MightLinearize + }; + public: + enum { + Traversal = MayLinearize ? LinearVectorizedTraversal + : MayEnableVml ? InnerVectorizedTraversal + : DefaultTraversal + }; +}; + +template::Traversal > +struct vml_assign_impl + : assign_impl,Traversal,Unrolling,BuiltIn> +{ +}; + +template +struct vml_assign_impl +{ + typedef typename Derived1::Scalar Scalar; + typedef typename Derived1::Index Index; + static inline void run(Derived1& dst, const CwiseUnaryOp& src) + { + // in case we want to (or have to) skip VML at runtime we can call: + // assign_impl,Traversal,Unrolling,BuiltIn>::run(dst,src); + const Index innerSize = dst.innerSize(); + const Index outerSize = dst.outerSize(); + for(Index outer = 0; outer < outerSize; ++outer) { + const Scalar *src_ptr = src.IsRowMajor ? &(src.nestedExpression().coeffRef(outer,0)) : + &(src.nestedExpression().coeffRef(0, outer)); + Scalar *dst_ptr = dst.IsRowMajor ? &(dst.coeffRef(outer,0)) : &(dst.coeffRef(0, outer)); + vml_call::run(src.functor(), innerSize, src_ptr, dst_ptr ); + } + } +}; + +template +struct vml_assign_impl +{ + static inline void run(Derived1& dst, const CwiseUnaryOp& src) + { + // in case we want to (or have to) skip VML at runtime we can call: + // assign_impl,Traversal,Unrolling,BuiltIn>::run(dst,src); + vml_call::run(src.functor(), dst.size(), src.nestedExpression().data(), dst.data() ); + } +}; + +// Macroses + +#define EIGEN_MKL_VML_SPECIALIZE_ASSIGN(TRAVERSAL,UNROLLING) \ + template \ + struct assign_impl, TRAVERSAL, UNROLLING, Specialized> { \ + static inline void run(Derived1 &dst, const Eigen::CwiseUnaryOp &src) { \ + vml_assign_impl::run(dst, src); \ + } \ + }; + +EIGEN_MKL_VML_SPECIALIZE_ASSIGN(DefaultTraversal,NoUnrolling) +EIGEN_MKL_VML_SPECIALIZE_ASSIGN(DefaultTraversal,CompleteUnrolling) +EIGEN_MKL_VML_SPECIALIZE_ASSIGN(DefaultTraversal,InnerUnrolling) +EIGEN_MKL_VML_SPECIALIZE_ASSIGN(LinearTraversal,NoUnrolling) +EIGEN_MKL_VML_SPECIALIZE_ASSIGN(LinearTraversal,CompleteUnrolling) +EIGEN_MKL_VML_SPECIALIZE_ASSIGN(InnerVectorizedTraversal,NoUnrolling) +EIGEN_MKL_VML_SPECIALIZE_ASSIGN(InnerVectorizedTraversal,CompleteUnrolling) +EIGEN_MKL_VML_SPECIALIZE_ASSIGN(InnerVectorizedTraversal,InnerUnrolling) +EIGEN_MKL_VML_SPECIALIZE_ASSIGN(LinearVectorizedTraversal,CompleteUnrolling) +EIGEN_MKL_VML_SPECIALIZE_ASSIGN(LinearVectorizedTraversal,NoUnrolling) +EIGEN_MKL_VML_SPECIALIZE_ASSIGN(SliceVectorizedTraversal,NoUnrolling) + + +#if !defined (EIGEN_FAST_MATH) || (EIGEN_FAST_MATH != 1) +#define EIGEN_MKL_VML_MODE VML_HA +#else +#define EIGEN_MKL_VML_MODE VML_LA +#endif + +#define EIGEN_MKL_VML_DECLARE_UNARY_CALL(EIGENOP, VMLOP, EIGENTYPE, VMLTYPE) \ + template<> struct vml_call< scalar_##EIGENOP##_op > { \ + enum { IsSupported = 1 }; \ + static inline void run( const scalar_##EIGENOP##_op& /*func*/, \ + int size, const EIGENTYPE* src, EIGENTYPE* dst) { \ + VMLOP(size, (const VMLTYPE*)src, (VMLTYPE*)dst); \ + } \ + }; + +#define EIGEN_MKL_VML_DECLARE_UNARY_CALL_LA(EIGENOP, VMLOP, EIGENTYPE, VMLTYPE) \ + template<> struct vml_call< scalar_##EIGENOP##_op > { \ + enum { IsSupported = 1 }; \ + static inline void run( const scalar_##EIGENOP##_op& /*func*/, \ + int size, const EIGENTYPE* src, EIGENTYPE* dst) { \ + MKL_INT64 vmlMode = EIGEN_MKL_VML_MODE; \ + VMLOP(size, (const VMLTYPE*)src, (VMLTYPE*)dst, vmlMode); \ + } \ + }; + +#define EIGEN_MKL_VML_DECLARE_POW_CALL(EIGENOP, VMLOP, EIGENTYPE, VMLTYPE) \ + template<> struct vml_call< scalar_##EIGENOP##_op > { \ + enum { IsSupported = 1 }; \ + static inline void run( const scalar_##EIGENOP##_op& func, \ + int size, const EIGENTYPE* src, EIGENTYPE* dst) { \ + EIGENTYPE exponent = func.m_exponent; \ + MKL_INT64 vmlMode = EIGEN_MKL_VML_MODE; \ + VMLOP(&size, (const VMLTYPE*)src, (const VMLTYPE*)&exponent, \ + (VMLTYPE*)dst, &vmlMode); \ + } \ + }; + +#define EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL(EIGENOP, VMLOP) \ + EIGEN_MKL_VML_DECLARE_UNARY_CALL(EIGENOP, vs##VMLOP, float, float) \ + EIGEN_MKL_VML_DECLARE_UNARY_CALL(EIGENOP, vd##VMLOP, double, double) + +#define EIGEN_MKL_VML_DECLARE_UNARY_CALLS_COMPLEX(EIGENOP, VMLOP) \ + EIGEN_MKL_VML_DECLARE_UNARY_CALL(EIGENOP, vc##VMLOP, scomplex, MKL_Complex8) \ + EIGEN_MKL_VML_DECLARE_UNARY_CALL(EIGENOP, vz##VMLOP, dcomplex, MKL_Complex16) + +#define EIGEN_MKL_VML_DECLARE_UNARY_CALLS(EIGENOP, VMLOP) \ + EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL(EIGENOP, VMLOP) \ + EIGEN_MKL_VML_DECLARE_UNARY_CALLS_COMPLEX(EIGENOP, VMLOP) + + +#define EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL_LA(EIGENOP, VMLOP) \ + EIGEN_MKL_VML_DECLARE_UNARY_CALL_LA(EIGENOP, vms##VMLOP, float, float) \ + EIGEN_MKL_VML_DECLARE_UNARY_CALL_LA(EIGENOP, vmd##VMLOP, double, double) + +#define EIGEN_MKL_VML_DECLARE_UNARY_CALLS_COMPLEX_LA(EIGENOP, VMLOP) \ + EIGEN_MKL_VML_DECLARE_UNARY_CALL_LA(EIGENOP, vmc##VMLOP, scomplex, MKL_Complex8) \ + EIGEN_MKL_VML_DECLARE_UNARY_CALL_LA(EIGENOP, vmz##VMLOP, dcomplex, MKL_Complex16) + +#define EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(EIGENOP, VMLOP) \ + EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL_LA(EIGENOP, VMLOP) \ + EIGEN_MKL_VML_DECLARE_UNARY_CALLS_COMPLEX_LA(EIGENOP, VMLOP) + + +EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(sin, Sin) +EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(asin, Asin) +EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(cos, Cos) +EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(acos, Acos) +EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(tan, Tan) +//EIGEN_MKL_VML_DECLARE_UNARY_CALLS(abs, Abs) +EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(exp, Exp) +EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(log, Ln) +EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(sqrt, Sqrt) + +EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL(square, Sqr) + +// The vm*powx functions are not avaibale in the windows version of MKL. +#ifdef _WIN32 +EIGEN_MKL_VML_DECLARE_POW_CALL(pow, vmspowx_, float, float) +EIGEN_MKL_VML_DECLARE_POW_CALL(pow, vmdpowx_, double, double) +EIGEN_MKL_VML_DECLARE_POW_CALL(pow, vmcpowx_, scomplex, MKL_Complex8) +EIGEN_MKL_VML_DECLARE_POW_CALL(pow, vmzpowx_, dcomplex, MKL_Complex16) +#endif + +} // end namespace internal + +} // end namespace Eigen + +#endif // EIGEN_ASSIGN_VML_H diff --git a/extern/Eigen3/Eigen/src/Core/BandMatrix.h b/extern/Eigen3/Eigen/src/Core/BandMatrix.h index 2570d7b559f..ffd7fe8b301 100644 --- a/extern/Eigen3/Eigen/src/Core/BandMatrix.h +++ b/extern/Eigen3/Eigen/src/Core/BandMatrix.h @@ -3,30 +3,16 @@ // // Copyright (C) 2009 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_BANDMATRIX_H #define EIGEN_BANDMATRIX_H -namespace internal { +namespace Eigen { +namespace internal { template class BandMatrixBase : public EigenBase @@ -343,4 +329,6 @@ class TridiagonalMatrix : public BandMatrix // Copyright (C) 2006-2010 Benoit Jacob // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_BLOCK_H #define EIGEN_BLOCK_H +namespace Eigen { + /** \class Block * \ingroup Core_Module * @@ -242,6 +229,21 @@ template::type& nestedExpression() const + { + return m_xpr; + } + + Index startRow() const + { + return m_startRow.value(); + } + + Index startCol() const + { + return m_startCol.value(); + } + protected: const typename XprType::Nested m_xpr; @@ -304,6 +306,11 @@ class Block init(); } + const typename internal::remove_all::type& nestedExpression() const + { + return m_xpr; + } + /** \sa MapBase::innerStride() */ inline Index innerStride() const { @@ -341,9 +348,10 @@ class Block : m_xpr.innerStride(); } - const typename XprType::Nested m_xpr; + typename XprType::Nested m_xpr; Index m_outerStride; }; +} // end namespace Eigen #endif // EIGEN_BLOCK_H diff --git a/extern/Eigen3/Eigen/src/Core/BooleanRedux.h b/extern/Eigen3/Eigen/src/Core/BooleanRedux.h index 5c3444a57c9..57efd8e6953 100644 --- a/extern/Eigen3/Eigen/src/Core/BooleanRedux.h +++ b/extern/Eigen3/Eigen/src/Core/BooleanRedux.h @@ -3,28 +3,15 @@ // // Copyright (C) 2008 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_ALLANDANY_H #define EIGEN_ALLANDANY_H +namespace Eigen { + namespace internal { template @@ -35,7 +22,7 @@ struct all_unroller row = (UnrollCount-1) % Derived::RowsAtCompileTime }; - inline static bool run(const Derived &mat) + static inline bool run(const Derived &mat) { return all_unroller::run(mat) && mat.coeff(row, col); } @@ -44,13 +31,13 @@ struct all_unroller template struct all_unroller { - inline static bool run(const Derived &mat) { return mat.coeff(0, 0); } + static inline bool run(const Derived &mat) { return mat.coeff(0, 0); } }; template struct all_unroller { - inline static bool run(const Derived &) { return false; } + static inline bool run(const Derived &) { return false; } }; template @@ -61,7 +48,7 @@ struct any_unroller row = (UnrollCount-1) % Derived::RowsAtCompileTime }; - inline static bool run(const Derived &mat) + static inline bool run(const Derived &mat) { return any_unroller::run(mat) || mat.coeff(row, col); } @@ -70,13 +57,13 @@ struct any_unroller template struct any_unroller { - inline static bool run(const Derived &mat) { return mat.coeff(0, 0); } + static inline bool run(const Derived &mat) { return mat.coeff(0, 0); } }; template struct any_unroller { - inline static bool run(const Derived &) { return false; } + static inline bool run(const Derived &) { return false; } }; } // end namespace internal @@ -146,4 +133,6 @@ inline typename DenseBase::Index DenseBase::count() const return derived().template cast().template cast().sum(); } +} // end namespace Eigen + #endif // EIGEN_ALLANDANY_H diff --git a/extern/Eigen3/Eigen/src/Core/CommaInitializer.h b/extern/Eigen3/Eigen/src/Core/CommaInitializer.h index 92422bf2fa0..4adce64143c 100644 --- a/extern/Eigen3/Eigen/src/Core/CommaInitializer.h +++ b/extern/Eigen3/Eigen/src/Core/CommaInitializer.h @@ -4,28 +4,15 @@ // Copyright (C) 2008 Gael Guennebaud // Copyright (C) 2006-2008 Benoit Jacob // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_COMMAINITIALIZER_H #define EIGEN_COMMAINITIALIZER_H +namespace Eigen { + /** \class CommaInitializer * \ingroup Core_Module * @@ -147,4 +134,6 @@ DenseBase::operator<<(const DenseBase& other) return CommaInitializer(*static_cast(this), other); } +} // end namespace Eigen + #endif // EIGEN_COMMAINITIALIZER_H diff --git a/extern/Eigen3/Eigen/src/Core/CwiseBinaryOp.h b/extern/Eigen3/Eigen/src/Core/CwiseBinaryOp.h index 7386b2e1843..1b93af31b60 100644 --- a/extern/Eigen3/Eigen/src/Core/CwiseBinaryOp.h +++ b/extern/Eigen3/Eigen/src/Core/CwiseBinaryOp.h @@ -4,28 +4,15 @@ // Copyright (C) 2008-2009 Gael Guennebaud // Copyright (C) 2006-2008 Benoit Jacob // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_CWISE_BINARY_OP_H #define EIGEN_CWISE_BINARY_OP_H +namespace Eigen { + /** \class CwiseBinaryOp * \ingroup Core_Module * @@ -167,8 +154,8 @@ class CwiseBinaryOp : internal::no_assignment_operator, const BinaryOp& functor() const { return m_functor; } protected: - const LhsNested m_lhs; - const RhsNested m_rhs; + LhsNested m_lhs; + RhsNested m_rhs; const BinaryOp m_functor; }; @@ -237,4 +224,6 @@ MatrixBase::operator+=(const MatrixBase& other) return derived(); } +} // end namespace Eigen + #endif // EIGEN_CWISE_BINARY_OP_H diff --git a/extern/Eigen3/Eigen/src/Core/CwiseNullaryOp.h b/extern/Eigen3/Eigen/src/Core/CwiseNullaryOp.h index c616e7ae13d..2635a62b07b 100644 --- a/extern/Eigen3/Eigen/src/Core/CwiseNullaryOp.h +++ b/extern/Eigen3/Eigen/src/Core/CwiseNullaryOp.h @@ -3,28 +3,15 @@ // // Copyright (C) 2008-2010 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_CWISE_NULLARY_OP_H #define EIGEN_CWISE_NULLARY_OP_H +namespace Eigen { + /** \class CwiseNullaryOp * \ingroup Core_Module * @@ -101,6 +88,9 @@ class CwiseNullaryOp : internal::no_assignment_operator, return m_functor.packetOp(index); } + /** \returns the functor representing the nullary operation */ + const NullaryOp& functor() const { return m_functor; } + protected: const internal::variable_if_dynamic m_rows; const internal::variable_if_dynamic m_cols; @@ -238,6 +228,8 @@ DenseBase::Constant(const Scalar& value) * assumed to be a(0), a(1), ..., a(size). This assumption allows for better vectorization * and yields faster code than the random access version. * + * When size is set to 1, a vector of length 1 containing 'high' is returned. + * * \only_for_vectors * * Example: \include DenseBase_LinSpaced_seq.cpp @@ -270,6 +262,7 @@ DenseBase::LinSpaced(Sequential_t, const Scalar& low, const Scalar& hig * \brief Sets a linearly space vector. * * The function generates 'size' equally spaced values in the closed interval [low,high]. + * When size is set to 1, a vector of length 1 containing 'high' is returned. * * \only_for_vectors * @@ -381,6 +374,7 @@ PlainObjectBase::setConstant(Index rows, Index cols, const Scalar& valu * \brief Sets a linearly space vector. * * The function generates 'size' equally spaced values in the closed interval [low,high]. + * When size is set to 1, a vector of length 1 containing 'high' is returned. * * \only_for_vectors * @@ -396,6 +390,23 @@ EIGEN_STRONG_INLINE Derived& DenseBase::setLinSpaced(Index size, const return derived() = Derived::NullaryExpr(size, internal::linspaced_op(low,high,size)); } +/** + * \brief Sets a linearly space vector. + * + * The function fill *this with equally spaced values in the closed interval [low,high]. + * When size is set to 1, a vector of length 1 containing 'high' is returned. + * + * \only_for_vectors + * + * \sa setLinSpaced(Index, const Scalar&, const Scalar&), CwiseNullaryOp + */ +template +EIGEN_STRONG_INLINE Derived& DenseBase::setLinSpaced(const Scalar& low, const Scalar& high) +{ + EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) + return setLinSpaced(size(), low, high); +} + // zero: /** \returns an expression of a zero matrix. @@ -848,4 +859,6 @@ template EIGEN_STRONG_INLINE const typename MatrixBase::BasisReturnType MatrixBase::UnitW() { return Derived::Unit(3); } +} // end namespace Eigen + #endif // EIGEN_CWISE_NULLARY_OP_H diff --git a/extern/Eigen3/Eigen/src/Core/CwiseUnaryOp.h b/extern/Eigen3/Eigen/src/Core/CwiseUnaryOp.h index 958571d64bf..063355ae521 100644 --- a/extern/Eigen3/Eigen/src/Core/CwiseUnaryOp.h +++ b/extern/Eigen3/Eigen/src/Core/CwiseUnaryOp.h @@ -4,28 +4,15 @@ // Copyright (C) 2008-2010 Gael Guennebaud // Copyright (C) 2006-2008 Benoit Jacob // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_CWISE_UNARY_OP_H #define EIGEN_CWISE_UNARY_OP_H +namespace Eigen { + /** \class CwiseUnaryOp * \ingroup Core_Module * @@ -95,7 +82,7 @@ class CwiseUnaryOp : internal::no_assignment_operator, nestedExpression() { return m_xpr.const_cast_derived(); } protected: - const typename XprType::Nested m_xpr; + typename XprType::Nested m_xpr; const UnaryOp m_functor; }; @@ -134,4 +121,6 @@ class CwiseUnaryOpImpl } }; +} // end namespace Eigen + #endif // EIGEN_CWISE_UNARY_OP_H diff --git a/extern/Eigen3/Eigen/src/Core/CwiseUnaryView.h b/extern/Eigen3/Eigen/src/Core/CwiseUnaryView.h index d24ef037314..66f73a9505b 100644 --- a/extern/Eigen3/Eigen/src/Core/CwiseUnaryView.h +++ b/extern/Eigen3/Eigen/src/Core/CwiseUnaryView.h @@ -3,28 +3,15 @@ // // Copyright (C) 2009-2010 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_CWISE_UNARY_VIEW_H #define EIGEN_CWISE_UNARY_VIEW_H +namespace Eigen { + /** \class CwiseUnaryView * \ingroup Core_Module * @@ -97,7 +84,7 @@ class CwiseUnaryView : internal::no_assignment_operator, protected: // FIXME changed from MatrixType::Nested because of a weird compilation error with sun CC - const typename internal::nested::type m_matrix; + typename internal::nested::type m_matrix; ViewOp m_functor; }; @@ -143,6 +130,6 @@ class CwiseUnaryViewImpl } }; - +} // end namespace Eigen #endif // EIGEN_CWISE_UNARY_VIEW_H diff --git a/extern/Eigen3/Eigen/src/Core/DenseBase.h b/extern/Eigen3/Eigen/src/Core/DenseBase.h index 920904f243a..1cc0314ef0b 100644 --- a/extern/Eigen3/Eigen/src/Core/DenseBase.h +++ b/extern/Eigen3/Eigen/src/Core/DenseBase.h @@ -4,28 +4,15 @@ // Copyright (C) 2007-2010 Benoit Jacob // Copyright (C) 2008-2010 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_DENSEBASE_H #define EIGEN_DENSEBASE_H +namespace Eigen { + /** \class DenseBase * \ingroup Core_Module * @@ -376,12 +363,13 @@ template class DenseBase inline Derived& operator*=(const Scalar& other); inline Derived& operator/=(const Scalar& other); + typedef typename internal::add_const_on_value_type::type>::type EvalReturnType; /** \returns the matrix or vector obtained by evaluating this expression. * * Notice that in the case of a plain matrix or vector (not an expression) this function just returns * a const reference, in order to avoid a useless copy. */ - EIGEN_STRONG_INLINE const typename internal::eval::type eval() const + EIGEN_STRONG_INLINE EvalReturnType eval() const { // Even though MSVC does not honor strong inlining when the return type // is a dynamic matrix, we desperately need strong inlining for fixed @@ -540,4 +528,6 @@ template class DenseBase template explicit DenseBase(const DenseBase&); }; +} // end namespace Eigen + #endif // EIGEN_DENSEBASE_H diff --git a/extern/Eigen3/Eigen/src/Core/DenseCoeffsBase.h b/extern/Eigen3/Eigen/src/Core/DenseCoeffsBase.h index e45238fb584..72704c2d79f 100644 --- a/extern/Eigen3/Eigen/src/Core/DenseCoeffsBase.h +++ b/extern/Eigen3/Eigen/src/Core/DenseCoeffsBase.h @@ -3,28 +3,15 @@ // // Copyright (C) 2006-2010 Benoit Jacob // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_DENSECOEFFSBASE_H #define EIGEN_DENSECOEFFSBASE_H +namespace Eigen { + namespace internal { template struct add_const_on_value_type_if_arithmetic { @@ -710,16 +697,16 @@ namespace internal { template struct first_aligned_impl { - inline static typename Derived::Index run(const Derived&) + static inline typename Derived::Index run(const Derived&) { return 0; } }; template struct first_aligned_impl { - inline static typename Derived::Index run(const Derived& m) + static inline typename Derived::Index run(const Derived& m) { - return first_aligned(&m.const_cast_derived().coeffRef(0,0), m.size()); + return internal::first_aligned(&m.const_cast_derived().coeffRef(0,0), m.size()); } }; @@ -729,7 +716,7 @@ struct first_aligned_impl * documentation. */ template -inline static typename Derived::Index first_aligned(const Derived& m) +static inline typename Derived::Index first_aligned(const Derived& m) { return first_aligned_impl @@ -762,4 +749,6 @@ struct outer_stride_at_compile_time } // end namespace internal +} // end namespace Eigen + #endif // EIGEN_DENSECOEFFSBASE_H diff --git a/extern/Eigen3/Eigen/src/Core/DenseStorage.h b/extern/Eigen3/Eigen/src/Core/DenseStorage.h index 813053b00dd..1fc2daf2c40 100644 --- a/extern/Eigen3/Eigen/src/Core/DenseStorage.h +++ b/extern/Eigen3/Eigen/src/Core/DenseStorage.h @@ -5,24 +5,9 @@ // Copyright (C) 2006-2009 Benoit Jacob // Copyright (C) 2010 Hauke Heibel // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_MATRIXSTORAGE_H #define EIGEN_MATRIXSTORAGE_H @@ -33,6 +18,8 @@ #define EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN #endif +namespace Eigen { + namespace internal { struct constructor_without_unaligned_array_assert {}; @@ -104,8 +91,8 @@ template class DenseSt : m_data(internal::constructor_without_unaligned_array_assert()) {} inline DenseStorage(DenseIndex,DenseIndex,DenseIndex) {} inline void swap(DenseStorage& other) { std::swap(m_data,other.m_data); } - inline static DenseIndex rows(void) {return _Rows;} - inline static DenseIndex cols(void) {return _Cols;} + static inline DenseIndex rows(void) {return _Rows;} + static inline DenseIndex cols(void) {return _Cols;} inline void conservativeResize(DenseIndex,DenseIndex,DenseIndex) {} inline void resize(DenseIndex,DenseIndex,DenseIndex) {} inline const T *data() const { return m_data.array; } @@ -120,14 +107,24 @@ template class DenseStorage class DenseStorage +: public DenseStorage { }; + +template class DenseStorage +: public DenseStorage { }; + +template class DenseStorage +: public DenseStorage { }; + // dynamic-size matrix with fixed-size storage template class DenseStorage { @@ -241,7 +238,7 @@ template class DenseStorage(m_data, _Rows*m_cols); } inline void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_cols,other.m_cols); } - inline static DenseIndex rows(void) {return _Rows;} + static inline DenseIndex rows(void) {return _Rows;} inline DenseIndex cols(void) const {return m_cols;} inline void conservativeResize(DenseIndex size, DenseIndex, DenseIndex cols) { @@ -278,7 +275,7 @@ template class DenseStorage(m_data, _Cols*m_rows); } inline void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); } inline DenseIndex rows(void) const {return m_rows;} - inline static DenseIndex cols(void) {return _Cols;} + static inline DenseIndex cols(void) {return _Cols;} inline void conservativeResize(DenseIndex size, DenseIndex rows, DenseIndex) { m_data = internal::conditional_aligned_realloc_new_auto(m_data, size, m_rows*_Cols); @@ -301,4 +298,6 @@ template class DenseStorage +// Copyright (C) 2009-2010 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_DIAGONAL_H #define EIGEN_DIAGONAL_H +namespace Eigen { + /** \class Diagonal * \ingroup Core_Module * @@ -53,16 +41,15 @@ struct traits > typedef typename remove_reference::type _MatrixTypeNested; typedef typename MatrixType::StorageKind StorageKind; enum { - AbsDiagIndex = DiagIndex<0 ? -DiagIndex : DiagIndex, // only used if DiagIndex != Dynamic - // FIXME these computations are broken in the case where the matrix is rectangular and DiagIndex!=0 RowsAtCompileTime = (int(DiagIndex) == Dynamic || int(MatrixType::SizeAtCompileTime) == Dynamic) ? Dynamic - : (EIGEN_SIZE_MIN_PREFER_DYNAMIC(MatrixType::RowsAtCompileTime, - MatrixType::ColsAtCompileTime) - AbsDiagIndex), + : (EIGEN_PLAIN_ENUM_MIN(MatrixType::RowsAtCompileTime - EIGEN_PLAIN_ENUM_MAX(-DiagIndex, 0), + MatrixType::ColsAtCompileTime - EIGEN_PLAIN_ENUM_MAX( DiagIndex, 0))), ColsAtCompileTime = 1, MaxRowsAtCompileTime = int(MatrixType::MaxSizeAtCompileTime) == Dynamic ? Dynamic : DiagIndex == Dynamic ? EIGEN_SIZE_MIN_PREFER_FIXED(MatrixType::MaxRowsAtCompileTime, - MatrixType::MaxColsAtCompileTime) - : (EIGEN_SIZE_MIN_PREFER_FIXED(MatrixType::MaxRowsAtCompileTime, MatrixType::MaxColsAtCompileTime) - AbsDiagIndex), + MatrixType::MaxColsAtCompileTime) + : (EIGEN_PLAIN_ENUM_MIN(MatrixType::MaxRowsAtCompileTime - EIGEN_PLAIN_ENUM_MAX(-DiagIndex, 0), + MatrixType::MaxColsAtCompileTime - EIGEN_PLAIN_ENUM_MAX( DiagIndex, 0))), MaxColsAtCompileTime = 1, MaskLvalueBit = is_lvalue::value ? LvalueBit : 0, Flags = (unsigned int)_MatrixTypeNested::Flags & (HereditaryBits | LinearAccessBit | MaskLvalueBit | DirectAccessBit) & ~RowMajorBit, @@ -101,6 +88,15 @@ template class Diagonal return 0; } + typedef typename internal::conditional< + internal::is_lvalue::value, + Scalar, + const Scalar + >::type ScalarWithConstIfNotLvalue; + + inline ScalarWithConstIfNotLvalue* data() { return &(m_matrix.const_cast_derived().coeffRef(rowOffset(), colOffset())); } + inline const Scalar* data() const { return &(m_matrix.const_cast_derived().coeffRef(rowOffset(), colOffset())); } + inline Scalar& coeffRef(Index row, Index) { EIGEN_STATIC_ASSERT_LVALUE(MatrixType) @@ -133,8 +129,19 @@ template class Diagonal return m_matrix.coeff(index+rowOffset(), index+colOffset()); } + const typename internal::remove_all::type& + nestedExpression() const + { + return m_matrix; + } + + int index() const + { + return m_index.value(); + } + protected: - const typename MatrixType::Nested m_matrix; + typename MatrixType::Nested m_matrix; const internal::variable_if_dynamic m_index; private: @@ -224,4 +231,6 @@ MatrixBase::diagonal() const return derived(); } +} // end namespace Eigen + #endif // EIGEN_DIAGONAL_H diff --git a/extern/Eigen3/Eigen/src/Core/DiagonalMatrix.h b/extern/Eigen3/Eigen/src/Core/DiagonalMatrix.h index f41a74bfae7..88190da684d 100644 --- a/extern/Eigen3/Eigen/src/Core/DiagonalMatrix.h +++ b/extern/Eigen3/Eigen/src/Core/DiagonalMatrix.h @@ -4,28 +4,15 @@ // Copyright (C) 2009 Gael Guennebaud // Copyright (C) 2007-2009 Benoit Jacob // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_DIAGONALMATRIX_H #define EIGEN_DIAGONALMATRIX_H +namespace Eigen { + #ifndef EIGEN_PARSED_BY_DOXYGEN template class DiagonalBase : public EigenBase @@ -72,7 +59,7 @@ class DiagonalBase : public EigenBase const DiagonalProduct operator*(const MatrixBase &matrix) const; - inline const DiagonalWrapper, const DiagonalVectorType> > + inline const DiagonalWrapper, const DiagonalVectorType> > inverse() const { return diagonal().cwiseInverse(); @@ -251,13 +238,13 @@ class DiagonalWrapper #endif /** Constructor from expression of diagonal coefficients to wrap. */ - inline DiagonalWrapper(const DiagonalVectorType& diagonal) : m_diagonal(diagonal) {} + inline DiagonalWrapper(DiagonalVectorType& diagonal) : m_diagonal(diagonal) {} /** \returns a const reference to the wrapped expression of diagonal coefficients. */ const DiagonalVectorType& diagonal() const { return m_diagonal; } protected: - const typename DiagonalVectorType::Nested m_diagonal; + typename DiagonalVectorType::Nested m_diagonal; }; /** \returns a pseudo-expression of a diagonal matrix with *this as vector of diagonal coefficients @@ -303,4 +290,6 @@ bool MatrixBase::isDiagonal(RealScalar prec) const return true; } +} // end namespace Eigen + #endif // EIGEN_DIAGONALMATRIX_H diff --git a/extern/Eigen3/Eigen/src/Core/DiagonalProduct.h b/extern/Eigen3/Eigen/src/Core/DiagonalProduct.h index de0c6ed11b7..598c6b3e19a 100644 --- a/extern/Eigen3/Eigen/src/Core/DiagonalProduct.h +++ b/extern/Eigen3/Eigen/src/Core/DiagonalProduct.h @@ -4,28 +4,15 @@ // Copyright (C) 2008 Gael Guennebaud // Copyright (C) 2007-2009 Benoit Jacob // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_DIAGONALPRODUCT_H #define EIGEN_DIAGONALPRODUCT_H +namespace Eigen { + namespace internal { template struct traits > @@ -107,8 +94,8 @@ class DiagonalProduct : internal::no_assignment_operator, m_diagonal.diagonal().template packet(id)); } - const typename MatrixType::Nested m_matrix; - const typename DiagonalType::Nested m_diagonal; + typename MatrixType::Nested m_matrix; + typename DiagonalType::Nested m_diagonal; }; /** \returns the diagonal matrix product of \c *this by the diagonal matrix \a diagonal. @@ -131,5 +118,6 @@ DiagonalBase::operator*(const MatrixBase &matrix return DiagonalProduct(matrix.derived(), derived()); } +} // end namespace Eigen #endif // EIGEN_DIAGONALPRODUCT_H diff --git a/extern/Eigen3/Eigen/src/Core/Dot.h b/extern/Eigen3/Eigen/src/Core/Dot.h index 42da7849896..ae9274e36dd 100644 --- a/extern/Eigen3/Eigen/src/Core/Dot.h +++ b/extern/Eigen3/Eigen/src/Core/Dot.h @@ -3,28 +3,15 @@ // // Copyright (C) 2006-2008, 2010 Benoit Jacob // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_DOT_H #define EIGEN_DOT_H +namespace Eigen { + namespace internal { // helper function for dot(). The problem is that if we put that in the body of dot(), then upon calling dot @@ -176,7 +163,7 @@ template struct lpNorm_selector { typedef typename NumTraits::Scalar>::Real RealScalar; - inline static RealScalar run(const MatrixBase& m) + static inline RealScalar run(const MatrixBase& m) { return pow(m.cwiseAbs().array().pow(p).sum(), RealScalar(1)/p); } @@ -185,7 +172,7 @@ struct lpNorm_selector template struct lpNorm_selector { - inline static typename NumTraits::Scalar>::Real run(const MatrixBase& m) + static inline typename NumTraits::Scalar>::Real run(const MatrixBase& m) { return m.cwiseAbs().sum(); } @@ -194,7 +181,7 @@ struct lpNorm_selector template struct lpNorm_selector { - inline static typename NumTraits::Scalar>::Real run(const MatrixBase& m) + static inline typename NumTraits::Scalar>::Real run(const MatrixBase& m) { return m.norm(); } @@ -203,7 +190,7 @@ struct lpNorm_selector template struct lpNorm_selector { - inline static typename NumTraits::Scalar>::Real run(const MatrixBase& m) + static inline typename NumTraits::Scalar>::Real run(const MatrixBase& m) { return m.cwiseAbs().maxCoeff(); } @@ -269,4 +256,6 @@ bool MatrixBase::isUnitary(RealScalar prec) const return true; } +} // end namespace Eigen + #endif // EIGEN_DOT_H diff --git a/extern/Eigen3/Eigen/src/Core/EigenBase.h b/extern/Eigen3/Eigen/src/Core/EigenBase.h index 0472539af33..0bbd28bec21 100644 --- a/extern/Eigen3/Eigen/src/Core/EigenBase.h +++ b/extern/Eigen3/Eigen/src/Core/EigenBase.h @@ -4,28 +4,14 @@ // Copyright (C) 2009 Benoit Jacob // Copyright (C) 2009 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_EIGENBASE_H #define EIGEN_EIGENBASE_H +namespace Eigen { /** Common base class for all classes T such that MatrixBase has an operator=(T) and a constructor MatrixBase(T). * @@ -169,4 +155,6 @@ inline void MatrixBase::applyOnTheLeft(const EigenBase &o other.derived().applyThisOnTheLeft(derived()); } +} // end namespace Eigen + #endif // EIGEN_EIGENBASE_H diff --git a/extern/Eigen3/Eigen/src/Core/Flagged.h b/extern/Eigen3/Eigen/src/Core/Flagged.h index 458213ab553..1f2955fc1de 100644 --- a/extern/Eigen3/Eigen/src/Core/Flagged.h +++ b/extern/Eigen3/Eigen/src/Core/Flagged.h @@ -3,28 +3,15 @@ // // Copyright (C) 2008 Benoit Jacob // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_FLAGGED_H #define EIGEN_FLAGGED_H +namespace Eigen { + /** \class Flagged * \ingroup Core_Module * @@ -148,4 +135,6 @@ DenseBase::flagged() const return derived(); } +} // end namespace Eigen + #endif // EIGEN_FLAGGED_H diff --git a/extern/Eigen3/Eigen/src/Core/ForceAlignedAccess.h b/extern/Eigen3/Eigen/src/Core/ForceAlignedAccess.h index 11c1f8f709a..807c7a29346 100644 --- a/extern/Eigen3/Eigen/src/Core/ForceAlignedAccess.h +++ b/extern/Eigen3/Eigen/src/Core/ForceAlignedAccess.h @@ -3,28 +3,15 @@ // // Copyright (C) 2009-2010 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_FORCEALIGNEDACCESS_H #define EIGEN_FORCEALIGNEDACCESS_H +namespace Eigen { + /** \class ForceAlignedAccess * \ingroup Core_Module * @@ -154,4 +141,6 @@ MatrixBase::forceAlignedAccessIf() return derived(); } +} // end namespace Eigen + #endif // EIGEN_FORCEALIGNEDACCESS_H diff --git a/extern/Eigen3/Eigen/src/Core/Functors.h b/extern/Eigen3/Eigen/src/Core/Functors.h index 54636e0d459..278c46c6b61 100644 --- a/extern/Eigen3/Eigen/src/Core/Functors.h +++ b/extern/Eigen3/Eigen/src/Core/Functors.h @@ -3,28 +3,15 @@ // // Copyright (C) 2008-2010 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_FUNCTORS_H #define EIGEN_FUNCTORS_H +namespace Eigen { + namespace internal { // associative functors: @@ -178,6 +165,18 @@ struct functor_traits > { enum { Cost = 5 * NumTraits::MulCost, PacketAccess=0 }; }; +/** \internal + * \brief Template functor to compute the pow of two scalars + */ +template struct scalar_binary_pow_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_binary_pow_op) + inline Scalar operator() (const Scalar& a, const OtherScalar& b) const { return internal::pow(a, b); } +}; +template +struct functor_traits > { + enum { Cost = 5 * NumTraits::MulCost, PacketAccess = false }; +}; + // other binary functors: /** \internal @@ -220,6 +219,38 @@ struct functor_traits > { }; }; +/** \internal + * \brief Template functor to compute the and of two booleans + * + * \sa class CwiseBinaryOp, ArrayBase::operator&& + */ +struct scalar_boolean_and_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_boolean_and_op) + EIGEN_STRONG_INLINE bool operator() (const bool& a, const bool& b) const { return a && b; } +}; +template<> struct functor_traits { + enum { + Cost = NumTraits::AddCost, + PacketAccess = false + }; +}; + +/** \internal + * \brief Template functor to compute the or of two booleans + * + * \sa class CwiseBinaryOp, ArrayBase::operator|| + */ +struct scalar_boolean_or_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_boolean_or_op) + EIGEN_STRONG_INLINE bool operator() (const bool& a, const bool& b) const { return a || b; } +}; +template<> struct functor_traits { + enum { + Cost = NumTraits::AddCost, + PacketAccess = false + }; +}; + // unary functors: /** \internal @@ -249,7 +280,7 @@ struct functor_traits > template struct scalar_abs_op { EIGEN_EMPTY_STRUCT_CTOR(scalar_abs_op) typedef typename NumTraits::Real result_type; - EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { return abs(a); } + EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { return internal::abs(a); } template EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const { return internal::pabs(a); } @@ -271,7 +302,7 @@ struct functor_traits > template struct scalar_abs2_op { EIGEN_EMPTY_STRUCT_CTOR(scalar_abs2_op) typedef typename NumTraits::Real result_type; - EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { return abs2(a); } + EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { return internal::abs2(a); } template EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const { return internal::pmul(a,a); } @@ -287,7 +318,7 @@ struct functor_traits > */ template struct scalar_conjugate_op { EIGEN_EMPTY_STRUCT_CTOR(scalar_conjugate_op) - EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { return conj(a); } + EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { return internal::conj(a); } template EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const { return internal::pconj(a); } }; @@ -324,7 +355,7 @@ template struct scalar_real_op { EIGEN_EMPTY_STRUCT_CTOR(scalar_real_op) typedef typename NumTraits::Real result_type; - EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return real(a); } + EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return internal::real(a); } }; template struct functor_traits > @@ -339,7 +370,7 @@ template struct scalar_imag_op { EIGEN_EMPTY_STRUCT_CTOR(scalar_imag_op) typedef typename NumTraits::Real result_type; - EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return imag(a); } + EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return internal::imag(a); } }; template struct functor_traits > @@ -354,7 +385,7 @@ template struct scalar_real_ref_op { EIGEN_EMPTY_STRUCT_CTOR(scalar_real_ref_op) typedef typename NumTraits::Real result_type; - EIGEN_STRONG_INLINE result_type& operator() (const Scalar& a) const { return real_ref(*const_cast(&a)); } + EIGEN_STRONG_INLINE result_type& operator() (const Scalar& a) const { return internal::real_ref(*const_cast(&a)); } }; template struct functor_traits > @@ -369,7 +400,7 @@ template struct scalar_imag_ref_op { EIGEN_EMPTY_STRUCT_CTOR(scalar_imag_ref_op) typedef typename NumTraits::Real result_type; - EIGEN_STRONG_INLINE result_type& operator() (const Scalar& a) const { return imag_ref(*const_cast(&a)); } + EIGEN_STRONG_INLINE result_type& operator() (const Scalar& a) const { return internal::imag_ref(*const_cast(&a)); } }; template struct functor_traits > @@ -383,7 +414,7 @@ struct functor_traits > */ template struct scalar_exp_op { EIGEN_EMPTY_STRUCT_CTOR(scalar_exp_op) - inline const Scalar operator() (const Scalar& a) const { return exp(a); } + inline const Scalar operator() (const Scalar& a) const { return internal::exp(a); } typedef typename packet_traits::type Packet; inline Packet packetOp(const Packet& a) const { return internal::pexp(a); } }; @@ -399,7 +430,7 @@ struct functor_traits > */ template struct scalar_log_op { EIGEN_EMPTY_STRUCT_CTOR(scalar_log_op) - inline const Scalar operator() (const Scalar& a) const { return log(a); } + inline const Scalar operator() (const Scalar& a) const { return internal::log(a); } typedef typename packet_traits::type Packet; inline Packet packetOp(const Packet& a) const { return internal::plog(a); } }; @@ -584,7 +615,7 @@ template struct functor_traits< linspaced_o template struct linspaced_op { typedef typename packet_traits::type Packet; - linspaced_op(Scalar low, Scalar high, int num_steps) : impl(low, (high-low)/(num_steps-1)) {} + linspaced_op(Scalar low, Scalar high, int num_steps) : impl((num_steps==1 ? high : low), (num_steps==1 ? Scalar() : (high-low)/(num_steps-1))) {} template EIGEN_STRONG_INLINE const Scalar operator() (Index i) const { return impl(i); } @@ -657,7 +688,7 @@ struct functor_traits > */ template struct scalar_sqrt_op { EIGEN_EMPTY_STRUCT_CTOR(scalar_sqrt_op) - inline const Scalar operator() (const Scalar& a) const { return sqrt(a); } + inline const Scalar operator() (const Scalar& a) const { return internal::sqrt(a); } typedef typename packet_traits::type Packet; inline Packet packetOp(const Packet& a) const { return internal::psqrt(a); } }; @@ -675,7 +706,7 @@ struct functor_traits > */ template struct scalar_cos_op { EIGEN_EMPTY_STRUCT_CTOR(scalar_cos_op) - inline Scalar operator() (const Scalar& a) const { return cos(a); } + inline Scalar operator() (const Scalar& a) const { return internal::cos(a); } typedef typename packet_traits::type Packet; inline Packet packetOp(const Packet& a) const { return internal::pcos(a); } }; @@ -694,7 +725,7 @@ struct functor_traits > */ template struct scalar_sin_op { EIGEN_EMPTY_STRUCT_CTOR(scalar_sin_op) - inline const Scalar operator() (const Scalar& a) const { return sin(a); } + inline const Scalar operator() (const Scalar& a) const { return internal::sin(a); } typedef typename packet_traits::type Packet; inline Packet packetOp(const Packet& a) const { return internal::psin(a); } }; @@ -714,7 +745,7 @@ struct functor_traits > */ template struct scalar_tan_op { EIGEN_EMPTY_STRUCT_CTOR(scalar_tan_op) - inline const Scalar operator() (const Scalar& a) const { return tan(a); } + inline const Scalar operator() (const Scalar& a) const { return internal::tan(a); } typedef typename packet_traits::type Packet; inline Packet packetOp(const Packet& a) const { return internal::ptan(a); } }; @@ -733,7 +764,7 @@ struct functor_traits > */ template struct scalar_acos_op { EIGEN_EMPTY_STRUCT_CTOR(scalar_acos_op) - inline const Scalar operator() (const Scalar& a) const { return acos(a); } + inline const Scalar operator() (const Scalar& a) const { return internal::acos(a); } typedef typename packet_traits::type Packet; inline Packet packetOp(const Packet& a) const { return internal::pacos(a); } }; @@ -752,7 +783,7 @@ struct functor_traits > */ template struct scalar_asin_op { EIGEN_EMPTY_STRUCT_CTOR(scalar_asin_op) - inline const Scalar operator() (const Scalar& a) const { return asin(a); } + inline const Scalar operator() (const Scalar& a) const { return internal::asin(a); } typedef typename packet_traits::type Packet; inline Packet packetOp(const Packet& a) const { return internal::pasin(a); } }; @@ -781,6 +812,20 @@ template struct functor_traits > { enum { Cost = 5 * NumTraits::MulCost, PacketAccess = false }; }; +/** \internal + * \brief Template functor to compute the quotient between a scalar and array entries. + * \sa class CwiseUnaryOp, Cwise::inverse() + */ +template +struct scalar_inverse_mult_op { + scalar_inverse_mult_op(const Scalar& other) : m_other(other) {} + inline Scalar operator() (const Scalar& a) const { return m_other / a; } + template + inline const Packet packetOp(const Packet& a) const + { return internal::pdiv(pset1(m_other),a); } + Scalar m_other; +}; + /** \internal * \brief Template functor to compute the inverse of a scalar * \sa class CwiseUnaryOp, Cwise::inverse() @@ -939,4 +984,6 @@ struct functor_traits > } // end namespace internal +} // end namespace Eigen + #endif // EIGEN_FUNCTORS_H diff --git a/extern/Eigen3/Eigen/src/Core/Fuzzy.h b/extern/Eigen3/Eigen/src/Core/Fuzzy.h index d266eed0ac6..d74edcfdb9d 100644 --- a/extern/Eigen3/Eigen/src/Core/Fuzzy.h +++ b/extern/Eigen3/Eigen/src/Core/Fuzzy.h @@ -4,28 +4,15 @@ // Copyright (C) 2006-2008 Benoit Jacob // Copyright (C) 2008 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_FUZZY_H #define EIGEN_FUZZY_H +namespace Eigen { + namespace internal { @@ -35,8 +22,8 @@ struct isApprox_selector static bool run(const Derived& x, const OtherDerived& y, typename Derived::RealScalar prec) { using std::min; - const typename internal::nested::type nested(x); - const typename internal::nested::type otherNested(y); + typename internal::nested::type nested(x); + typename internal::nested::type otherNested(y); return (nested - otherNested).cwiseAbs2().sum() <= prec * prec * (min)(nested.cwiseAbs2().sum(), otherNested.cwiseAbs2().sum()); } }; @@ -158,4 +145,6 @@ bool DenseBase::isMuchSmallerThan( return internal::isMuchSmallerThan_object_selector::run(derived(), other.derived(), prec); } +} // end namespace Eigen + #endif // EIGEN_FUZZY_H diff --git a/extern/Eigen3/Eigen/src/Core/GeneralProduct.h b/extern/Eigen3/Eigen/src/Core/GeneralProduct.h new file mode 100644 index 00000000000..bfc2a67b12f --- /dev/null +++ b/extern/Eigen3/Eigen/src/Core/GeneralProduct.h @@ -0,0 +1,613 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2006-2008 Benoit Jacob +// Copyright (C) 2008-2011 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_GENERAL_PRODUCT_H +#define EIGEN_GENERAL_PRODUCT_H + +namespace Eigen { + +/** \class GeneralProduct + * \ingroup Core_Module + * + * \brief Expression of the product of two general matrices or vectors + * + * \param LhsNested the type used to store the left-hand side + * \param RhsNested the type used to store the right-hand side + * \param ProductMode the type of the product + * + * This class represents an expression of the product of two general matrices. + * We call a general matrix, a dense matrix with full storage. For instance, + * This excludes triangular, selfadjoint, and sparse matrices. + * It is the return type of the operator* between general matrices. Its template + * arguments are determined automatically by ProductReturnType. Therefore, + * GeneralProduct should never be used direclty. To determine the result type of a + * function which involves a matrix product, use ProductReturnType::Type. + * + * \sa ProductReturnType, MatrixBase::operator*(const MatrixBase&) + */ +template::value> +class GeneralProduct; + +enum { + Large = 2, + Small = 3 +}; + +namespace internal { + +template struct product_type_selector; + +template struct product_size_category +{ + enum { is_large = MaxSize == Dynamic || + Size >= EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD, + value = is_large ? Large + : Size == 1 ? 1 + : Small + }; +}; + +template struct product_type +{ + typedef typename remove_all::type _Lhs; + typedef typename remove_all::type _Rhs; + enum { + MaxRows = _Lhs::MaxRowsAtCompileTime, + Rows = _Lhs::RowsAtCompileTime, + MaxCols = _Rhs::MaxColsAtCompileTime, + Cols = _Rhs::ColsAtCompileTime, + MaxDepth = EIGEN_SIZE_MIN_PREFER_FIXED(_Lhs::MaxColsAtCompileTime, + _Rhs::MaxRowsAtCompileTime), + Depth = EIGEN_SIZE_MIN_PREFER_FIXED(_Lhs::ColsAtCompileTime, + _Rhs::RowsAtCompileTime), + LargeThreshold = EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD + }; + + // the splitting into different lines of code here, introducing the _select enums and the typedef below, + // is to work around an internal compiler error with gcc 4.1 and 4.2. +private: + enum { + rows_select = product_size_category::value, + cols_select = product_size_category::value, + depth_select = product_size_category::value + }; + typedef product_type_selector selector; + +public: + enum { + value = selector::ret + }; +#ifdef EIGEN_DEBUG_PRODUCT + static void debug() + { + EIGEN_DEBUG_VAR(Rows); + EIGEN_DEBUG_VAR(Cols); + EIGEN_DEBUG_VAR(Depth); + EIGEN_DEBUG_VAR(rows_select); + EIGEN_DEBUG_VAR(cols_select); + EIGEN_DEBUG_VAR(depth_select); + EIGEN_DEBUG_VAR(value); + } +#endif +}; + + +/* The following allows to select the kind of product at compile time + * based on the three dimensions of the product. + * This is a compile time mapping from {1,Small,Large}^3 -> {product types} */ +// FIXME I'm not sure the current mapping is the ideal one. +template struct product_type_selector { enum { ret = OuterProduct }; }; +template struct product_type_selector<1, 1, Depth> { enum { ret = InnerProduct }; }; +template<> struct product_type_selector<1, 1, 1> { enum { ret = InnerProduct }; }; +template<> struct product_type_selector { enum { ret = CoeffBasedProductMode }; }; +template<> struct product_type_selector<1, Small,Small> { enum { ret = CoeffBasedProductMode }; }; +template<> struct product_type_selector { enum { ret = CoeffBasedProductMode }; }; +template<> struct product_type_selector { enum { ret = LazyCoeffBasedProductMode }; }; +template<> struct product_type_selector { enum { ret = LazyCoeffBasedProductMode }; }; +template<> struct product_type_selector { enum { ret = LazyCoeffBasedProductMode }; }; +template<> struct product_type_selector<1, Large,Small> { enum { ret = CoeffBasedProductMode }; }; +template<> struct product_type_selector<1, Large,Large> { enum { ret = GemvProduct }; }; +template<> struct product_type_selector<1, Small,Large> { enum { ret = CoeffBasedProductMode }; }; +template<> struct product_type_selector { enum { ret = CoeffBasedProductMode }; }; +template<> struct product_type_selector { enum { ret = GemvProduct }; }; +template<> struct product_type_selector { enum { ret = CoeffBasedProductMode }; }; +template<> struct product_type_selector { enum { ret = GemmProduct }; }; +template<> struct product_type_selector { enum { ret = GemmProduct }; }; +template<> struct product_type_selector { enum { ret = GemmProduct }; }; +template<> struct product_type_selector { enum { ret = GemmProduct }; }; +template<> struct product_type_selector { enum { ret = GemmProduct }; }; +template<> struct product_type_selector { enum { ret = GemmProduct }; }; +template<> struct product_type_selector { enum { ret = GemmProduct }; }; + +} // end namespace internal + +/** \class ProductReturnType + * \ingroup Core_Module + * + * \brief Helper class to get the correct and optimized returned type of operator* + * + * \param Lhs the type of the left-hand side + * \param Rhs the type of the right-hand side + * \param ProductMode the type of the product (determined automatically by internal::product_mode) + * + * This class defines the typename Type representing the optimized product expression + * between two matrix expressions. In practice, using ProductReturnType::Type + * is the recommended way to define the result type of a function returning an expression + * which involve a matrix product. The class Product should never be + * used directly. + * + * \sa class Product, MatrixBase::operator*(const MatrixBase&) + */ +template +struct ProductReturnType +{ + // TODO use the nested type to reduce instanciations ???? +// typedef typename internal::nested::type LhsNested; +// typedef typename internal::nested::type RhsNested; + + typedef GeneralProduct Type; +}; + +template +struct ProductReturnType +{ + typedef typename internal::nested::type >::type LhsNested; + typedef typename internal::nested::type >::type RhsNested; + typedef CoeffBasedProduct Type; +}; + +template +struct ProductReturnType +{ + typedef typename internal::nested::type >::type LhsNested; + typedef typename internal::nested::type >::type RhsNested; + typedef CoeffBasedProduct Type; +}; + +// this is a workaround for sun CC +template +struct LazyProductReturnType : public ProductReturnType +{}; + +/*********************************************************************** +* Implementation of Inner Vector Vector Product +***********************************************************************/ + +// FIXME : maybe the "inner product" could return a Scalar +// instead of a 1x1 matrix ?? +// Pro: more natural for the user +// Cons: this could be a problem if in a meta unrolled algorithm a matrix-matrix +// product ends up to a row-vector times col-vector product... To tackle this use +// case, we could have a specialization for Block with: operator=(Scalar x); + +namespace internal { + +template +struct traits > + : traits::ReturnType,1,1> > +{}; + +} + +template +class GeneralProduct + : internal::no_assignment_operator, + public Matrix::ReturnType,1,1> +{ + typedef Matrix::ReturnType,1,1> Base; + public: + GeneralProduct(const Lhs& lhs, const Rhs& rhs) + { + EIGEN_STATIC_ASSERT((internal::is_same::value), + YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) + + Base::coeffRef(0,0) = (lhs.transpose().cwiseProduct(rhs)).sum(); + } + + /** Convertion to scalar */ + operator const typename Base::Scalar() const { + return Base::coeff(0,0); + } +}; + +/*********************************************************************** +* Implementation of Outer Vector Vector Product +***********************************************************************/ + +namespace internal { +template struct outer_product_selector; + +template +struct traits > + : traits, Lhs, Rhs> > +{}; + +} + +template +class GeneralProduct + : public ProductBase, Lhs, Rhs> +{ + public: + EIGEN_PRODUCT_PUBLIC_INTERFACE(GeneralProduct) + + GeneralProduct(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs) + { + EIGEN_STATIC_ASSERT((internal::is_same::value), + YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) + } + + template void scaleAndAddTo(Dest& dest, Scalar alpha) const + { + internal::outer_product_selector<(int(Dest::Flags)&RowMajorBit) ? RowMajor : ColMajor>::run(*this, dest, alpha); + } +}; + +namespace internal { + +template<> struct outer_product_selector { + template + static EIGEN_DONT_INLINE void run(const ProductType& prod, Dest& dest, typename ProductType::Scalar alpha) { + typedef typename Dest::Index Index; + // FIXME make sure lhs is sequentially stored + // FIXME not very good if rhs is real and lhs complex while alpha is real too + const Index cols = dest.cols(); + for (Index j=0; j struct outer_product_selector { + template + static EIGEN_DONT_INLINE void run(const ProductType& prod, Dest& dest, typename ProductType::Scalar alpha) { + typedef typename Dest::Index Index; + // FIXME make sure rhs is sequentially stored + // FIXME not very good if lhs is real and rhs complex while alpha is real too + const Index rows = dest.rows(); + for (Index i=0; i call fast BLAS-like colmajor routine + * 2 - the matrix is row-major, BLAS compatible and N is large => call fast BLAS-like rowmajor routine + * 3 - all other cases are handled using a simple loop along the outer-storage direction. + * Therefore we need a lower level meta selector. + * Furthermore, if the matrix is the rhs, then the product has to be transposed. + */ +namespace internal { + +template +struct traits > + : traits, Lhs, Rhs> > +{}; + +template +struct gemv_selector; + +} // end namespace internal + +template +class GeneralProduct + : public ProductBase, Lhs, Rhs> +{ + public: + EIGEN_PRODUCT_PUBLIC_INTERFACE(GeneralProduct) + + typedef typename Lhs::Scalar LhsScalar; + typedef typename Rhs::Scalar RhsScalar; + + GeneralProduct(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs) + { +// EIGEN_STATIC_ASSERT((internal::is_same::value), +// YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) + } + + enum { Side = Lhs::IsVectorAtCompileTime ? OnTheLeft : OnTheRight }; + typedef typename internal::conditional::type MatrixType; + + template void scaleAndAddTo(Dest& dst, Scalar alpha) const + { + eigen_assert(m_lhs.rows() == dst.rows() && m_rhs.cols() == dst.cols()); + internal::gemv_selector::HasUsableDirectAccess)>::run(*this, dst, alpha); + } +}; + +namespace internal { + +// The vector is on the left => transposition +template +struct gemv_selector +{ + template + static void run(const ProductType& prod, Dest& dest, typename ProductType::Scalar alpha) + { + Transpose destT(dest); + enum { OtherStorageOrder = StorageOrder == RowMajor ? ColMajor : RowMajor }; + gemv_selector + ::run(GeneralProduct,Transpose, GemvProduct> + (prod.rhs().transpose(), prod.lhs().transpose()), destT, alpha); + } +}; + +template struct gemv_static_vector_if; + +template +struct gemv_static_vector_if +{ + EIGEN_STRONG_INLINE Scalar* data() { eigen_internal_assert(false && "should never be called"); return 0; } +}; + +template +struct gemv_static_vector_if +{ + EIGEN_STRONG_INLINE Scalar* data() { return 0; } +}; + +template +struct gemv_static_vector_if +{ + #if EIGEN_ALIGN_STATICALLY + internal::plain_array m_data; + EIGEN_STRONG_INLINE Scalar* data() { return m_data.array; } + #else + // Some architectures cannot align on the stack, + // => let's manually enforce alignment by allocating more data and return the address of the first aligned element. + enum { + ForceAlignment = internal::packet_traits::Vectorizable, + PacketSize = internal::packet_traits::size + }; + internal::plain_array m_data; + EIGEN_STRONG_INLINE Scalar* data() { + return ForceAlignment + ? reinterpret_cast((reinterpret_cast(m_data.array) & ~(size_t(15))) + 16) + : m_data.array; + } + #endif +}; + +template<> struct gemv_selector +{ + template + static inline void run(const ProductType& prod, Dest& dest, typename ProductType::Scalar alpha) + { + typedef typename ProductType::Index Index; + typedef typename ProductType::LhsScalar LhsScalar; + typedef typename ProductType::RhsScalar RhsScalar; + typedef typename ProductType::Scalar ResScalar; + typedef typename ProductType::RealScalar RealScalar; + typedef typename ProductType::ActualLhsType ActualLhsType; + typedef typename ProductType::ActualRhsType ActualRhsType; + typedef typename ProductType::LhsBlasTraits LhsBlasTraits; + typedef typename ProductType::RhsBlasTraits RhsBlasTraits; + typedef Map, Aligned> MappedDest; + + ActualLhsType actualLhs = LhsBlasTraits::extract(prod.lhs()); + ActualRhsType actualRhs = RhsBlasTraits::extract(prod.rhs()); + + ResScalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(prod.lhs()) + * RhsBlasTraits::extractScalarFactor(prod.rhs()); + + enum { + // FIXME find a way to allow an inner stride on the result if packet_traits::size==1 + // on, the other hand it is good for the cache to pack the vector anyways... + EvalToDestAtCompileTime = Dest::InnerStrideAtCompileTime==1, + ComplexByReal = (NumTraits::IsComplex) && (!NumTraits::IsComplex), + MightCannotUseDest = (Dest::InnerStrideAtCompileTime!=1) || ComplexByReal + }; + + gemv_static_vector_if static_dest; + + bool alphaIsCompatible = (!ComplexByReal) || (imag(actualAlpha)==RealScalar(0)); + bool evalToDest = EvalToDestAtCompileTime && alphaIsCompatible; + + RhsScalar compatibleAlpha = get_factor::run(actualAlpha); + + ei_declare_aligned_stack_constructed_variable(ResScalar,actualDestPtr,dest.size(), + evalToDest ? dest.data() : static_dest.data()); + + if(!evalToDest) + { + #ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN + int size = dest.size(); + EIGEN_DENSE_STORAGE_CTOR_PLUGIN + #endif + if(!alphaIsCompatible) + { + MappedDest(actualDestPtr, dest.size()).setZero(); + compatibleAlpha = RhsScalar(1); + } + else + MappedDest(actualDestPtr, dest.size()) = dest; + } + + general_matrix_vector_product + ::run( + actualLhs.rows(), actualLhs.cols(), + actualLhs.data(), actualLhs.outerStride(), + actualRhs.data(), actualRhs.innerStride(), + actualDestPtr, 1, + compatibleAlpha); + + if (!evalToDest) + { + if(!alphaIsCompatible) + dest += actualAlpha * MappedDest(actualDestPtr, dest.size()); + else + dest = MappedDest(actualDestPtr, dest.size()); + } + } +}; + +template<> struct gemv_selector +{ + template + static void run(const ProductType& prod, Dest& dest, typename ProductType::Scalar alpha) + { + typedef typename ProductType::LhsScalar LhsScalar; + typedef typename ProductType::RhsScalar RhsScalar; + typedef typename ProductType::Scalar ResScalar; + typedef typename ProductType::Index Index; + typedef typename ProductType::ActualLhsType ActualLhsType; + typedef typename ProductType::ActualRhsType ActualRhsType; + typedef typename ProductType::_ActualRhsType _ActualRhsType; + typedef typename ProductType::LhsBlasTraits LhsBlasTraits; + typedef typename ProductType::RhsBlasTraits RhsBlasTraits; + + typename add_const::type actualLhs = LhsBlasTraits::extract(prod.lhs()); + typename add_const::type actualRhs = RhsBlasTraits::extract(prod.rhs()); + + ResScalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(prod.lhs()) + * RhsBlasTraits::extractScalarFactor(prod.rhs()); + + enum { + // FIXME find a way to allow an inner stride on the result if packet_traits::size==1 + // on, the other hand it is good for the cache to pack the vector anyways... + DirectlyUseRhs = _ActualRhsType::InnerStrideAtCompileTime==1 + }; + + gemv_static_vector_if static_rhs; + + ei_declare_aligned_stack_constructed_variable(RhsScalar,actualRhsPtr,actualRhs.size(), + DirectlyUseRhs ? const_cast(actualRhs.data()) : static_rhs.data()); + + if(!DirectlyUseRhs) + { + #ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN + int size = actualRhs.size(); + EIGEN_DENSE_STORAGE_CTOR_PLUGIN + #endif + Map(actualRhsPtr, actualRhs.size()) = actualRhs; + } + + general_matrix_vector_product + ::run( + actualLhs.rows(), actualLhs.cols(), + actualLhs.data(), actualLhs.outerStride(), + actualRhsPtr, 1, + dest.data(), dest.innerStride(), + actualAlpha); + } +}; + +template<> struct gemv_selector +{ + template + static void run(const ProductType& prod, Dest& dest, typename ProductType::Scalar alpha) + { + typedef typename Dest::Index Index; + // TODO makes sure dest is sequentially stored in memory, otherwise use a temp + const Index size = prod.rhs().rows(); + for(Index k=0; k struct gemv_selector +{ + template + static void run(const ProductType& prod, Dest& dest, typename ProductType::Scalar alpha) + { + typedef typename Dest::Index Index; + // TODO makes sure rhs is sequentially stored in memory, otherwise use a temp + const Index rows = prod.rows(); + for(Index i=0; i +template +inline const typename ProductReturnType::Type +MatrixBase::operator*(const MatrixBase &other) const +{ + // A note regarding the function declaration: In MSVC, this function will sometimes + // not be inlined since DenseStorage is an unwindable object for dynamic + // matrices and product types are holding a member to store the result. + // Thus it does not help tagging this function with EIGEN_STRONG_INLINE. + enum { + ProductIsValid = Derived::ColsAtCompileTime==Dynamic + || OtherDerived::RowsAtCompileTime==Dynamic + || int(Derived::ColsAtCompileTime)==int(OtherDerived::RowsAtCompileTime), + AreVectors = Derived::IsVectorAtCompileTime && OtherDerived::IsVectorAtCompileTime, + SameSizes = EIGEN_PREDICATE_SAME_MATRIX_SIZE(Derived,OtherDerived) + }; + // note to the lost user: + // * for a dot product use: v1.dot(v2) + // * for a coeff-wise product use: v1.cwiseProduct(v2) + EIGEN_STATIC_ASSERT(ProductIsValid || !(AreVectors && SameSizes), + INVALID_VECTOR_VECTOR_PRODUCT__IF_YOU_WANTED_A_DOT_OR_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTIONS) + EIGEN_STATIC_ASSERT(ProductIsValid || !(SameSizes && !AreVectors), + INVALID_MATRIX_PRODUCT__IF_YOU_WANTED_A_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTION) + EIGEN_STATIC_ASSERT(ProductIsValid || SameSizes, INVALID_MATRIX_PRODUCT) +#ifdef EIGEN_DEBUG_PRODUCT + internal::product_type::debug(); +#endif + return typename ProductReturnType::Type(derived(), other.derived()); +} + +/** \returns an expression of the matrix product of \c *this and \a other without implicit evaluation. + * + * The returned product will behave like any other expressions: the coefficients of the product will be + * computed once at a time as requested. This might be useful in some extremely rare cases when only + * a small and no coherent fraction of the result's coefficients have to be computed. + * + * \warning This version of the matrix product can be much much slower. So use it only if you know + * what you are doing and that you measured a true speed improvement. + * + * \sa operator*(const MatrixBase&) + */ +template +template +const typename LazyProductReturnType::Type +MatrixBase::lazyProduct(const MatrixBase &other) const +{ + enum { + ProductIsValid = Derived::ColsAtCompileTime==Dynamic + || OtherDerived::RowsAtCompileTime==Dynamic + || int(Derived::ColsAtCompileTime)==int(OtherDerived::RowsAtCompileTime), + AreVectors = Derived::IsVectorAtCompileTime && OtherDerived::IsVectorAtCompileTime, + SameSizes = EIGEN_PREDICATE_SAME_MATRIX_SIZE(Derived,OtherDerived) + }; + // note to the lost user: + // * for a dot product use: v1.dot(v2) + // * for a coeff-wise product use: v1.cwiseProduct(v2) + EIGEN_STATIC_ASSERT(ProductIsValid || !(AreVectors && SameSizes), + INVALID_VECTOR_VECTOR_PRODUCT__IF_YOU_WANTED_A_DOT_OR_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTIONS) + EIGEN_STATIC_ASSERT(ProductIsValid || !(SameSizes && !AreVectors), + INVALID_MATRIX_PRODUCT__IF_YOU_WANTED_A_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTION) + EIGEN_STATIC_ASSERT(ProductIsValid || SameSizes, INVALID_MATRIX_PRODUCT) + + return typename LazyProductReturnType::Type(derived(), other.derived()); +} + +} // end namespace Eigen + +#endif // EIGEN_PRODUCT_H diff --git a/extern/Eigen3/Eigen/src/Core/GenericPacketMath.h b/extern/Eigen3/Eigen/src/Core/GenericPacketMath.h index 8ed83532712..858fb243ec8 100644 --- a/extern/Eigen3/Eigen/src/Core/GenericPacketMath.h +++ b/extern/Eigen3/Eigen/src/Core/GenericPacketMath.h @@ -4,28 +4,15 @@ // Copyright (C) 2008 Gael Guennebaud // Copyright (C) 2006-2008 Benoit Jacob // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_GENERIC_PACKET_MATH_H #define EIGEN_GENERIC_PACKET_MATH_H +namespace Eigen { + namespace internal { /** \internal @@ -312,7 +299,7 @@ template struct palign_impl { // by default data are aligned, so there is nothing to be done :) - inline static void run(PacketType&, const PacketType&) {} + static inline void run(PacketType&, const PacketType&) {} }; /** \internal update \a first using the concatenation of the \a Offset last elements @@ -335,5 +322,7 @@ template<> inline std::complex pmul(const std::complex& a, const } // end namespace internal +} // end namespace Eigen + #endif // EIGEN_GENERIC_PACKET_MATH_H diff --git a/extern/Eigen3/Eigen/src/Core/GlobalFunctions.h b/extern/Eigen3/Eigen/src/Core/GlobalFunctions.h index 144145a955c..e63726c4735 100644 --- a/extern/Eigen3/Eigen/src/Core/GlobalFunctions.h +++ b/extern/Eigen3/Eigen/src/Core/GlobalFunctions.h @@ -4,24 +4,9 @@ // Copyright (C) 2010 Gael Guennebaud // Copyright (C) 2010 Benoit Jacob // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_GLOBAL_FUNCTIONS_H #define EIGEN_GLOBAL_FUNCTIONS_H @@ -66,13 +51,36 @@ namespace std template inline const Eigen::CwiseUnaryOp, const Derived> - pow(const Eigen::ArrayBase& x, const typename Derived::Scalar& exponent) { \ - return x.derived().pow(exponent); \ + pow(const Eigen::ArrayBase& x, const typename Derived::Scalar& exponent) { + return x.derived().pow(exponent); + } + + template + inline const Eigen::CwiseBinaryOp, const Derived, const Derived> + pow(const Eigen::ArrayBase& x, const Eigen::ArrayBase& exponents) + { + return Eigen::CwiseBinaryOp, const Derived, const Derived>( + x.derived(), + exponents.derived() + ); } } namespace Eigen { + /** + * \brief Component-wise division of a scalar by array elements. + **/ + template + inline const Eigen::CwiseUnaryOp, const Derived> + operator/(typename Derived::Scalar s, const Eigen::ArrayBase& a) + { + return Eigen::CwiseUnaryOp, const Derived>( + a.derived(), + Eigen::internal::scalar_inverse_mult_op(s) + ); + } + namespace internal { EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(real,scalar_real_op) diff --git a/extern/Eigen3/Eigen/src/Core/IO.h b/extern/Eigen3/Eigen/src/Core/IO.h index f3cfcdbf4a3..cc8e18a0076 100644 --- a/extern/Eigen3/Eigen/src/Core/IO.h +++ b/extern/Eigen3/Eigen/src/Core/IO.h @@ -4,28 +4,15 @@ // Copyright (C) 2006-2008 Benoit Jacob // Copyright (C) 2008 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_IO_H #define EIGEN_IO_H +namespace Eigen { + enum { DontAlignCols = 1 }; enum { StreamPrecision = -1, FullPrecision = -2 }; @@ -171,7 +158,7 @@ std::ostream & print_matrix(std::ostream & s, const Derived& _m, const IOFormat& return s; } - const typename Derived::Nested m = _m; + typename Derived::Nested m = _m; typedef typename Derived::Scalar Scalar; typedef typename Derived::Index Index; @@ -257,4 +244,6 @@ std::ostream & operator << return internal::print_matrix(s, m.eval(), EIGEN_DEFAULT_IO_FORMAT); } +} // end namespace Eigen + #endif // EIGEN_IO_H diff --git a/extern/Eigen3/Eigen/src/Core/Map.h b/extern/Eigen3/Eigen/src/Core/Map.h index 2bf80b3af3d..15a19226e29 100644 --- a/extern/Eigen3/Eigen/src/Core/Map.h +++ b/extern/Eigen3/Eigen/src/Core/Map.h @@ -4,28 +4,15 @@ // Copyright (C) 2007-2010 Benoit Jacob // Copyright (C) 2008 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_MAP_H #define EIGEN_MAP_H +namespace Eigen { + /** \class Map * \ingroup Core_Module * @@ -200,4 +187,6 @@ inline Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> this->_set_noalias(Eigen::Map(data)); } +} // end namespace Eigen + #endif // EIGEN_MAP_H diff --git a/extern/Eigen3/Eigen/src/Core/MapBase.h b/extern/Eigen3/Eigen/src/Core/MapBase.h index 9426e2d24dd..a388d61ea92 100644 --- a/extern/Eigen3/Eigen/src/Core/MapBase.h +++ b/extern/Eigen3/Eigen/src/Core/MapBase.h @@ -4,24 +4,9 @@ // Copyright (C) 2007-2010 Benoit Jacob // Copyright (C) 2008 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_MAPBASE_H #define EIGEN_MAPBASE_H @@ -30,6 +15,7 @@ EIGEN_STATIC_ASSERT((int(internal::traits::Flags) & LinearAccessBit) || Derived::IsVectorAtCompileTime, \ YOU_ARE_TRYING_TO_USE_AN_INDEX_BASED_ACCESSOR_ON_AN_EXPRESSION_THAT_DOES_NOT_SUPPORT_THAT) +namespace Eigen { /** \class MapBase * \ingroup Core_Module @@ -251,5 +237,6 @@ template class MapBase using Base::Base::operator=; }; +} // end namespace Eigen #endif // EIGEN_MAPBASE_H diff --git a/extern/Eigen3/Eigen/src/Core/MathFunctions.h b/extern/Eigen3/Eigen/src/Core/MathFunctions.h index 2b454db21e9..05e913f2fec 100644 --- a/extern/Eigen3/Eigen/src/Core/MathFunctions.h +++ b/extern/Eigen3/Eigen/src/Core/MathFunctions.h @@ -3,28 +3,15 @@ // // Copyright (C) 2006-2010 Benoit Jacob // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_MATHFUNCTIONS_H #define EIGEN_MATHFUNCTIONS_H +namespace Eigen { + namespace internal { /** \internal \struct global_math_functions_filtering_base @@ -309,8 +296,7 @@ struct abs2_impl > { static inline RealScalar run(const std::complex& x) { - using std::norm; - return norm(x); + return real(x)*real(x) + imag(x)*imag(x); } }; @@ -553,7 +539,7 @@ struct pow_default_impl { static inline Scalar run(Scalar x, Scalar y) { - Scalar res = 1; + Scalar res(1); eigen_assert(!NumTraits::IsSigned || y >= 0); if(y & 1) res *= x; y >>= 1; @@ -838,6 +824,19 @@ template<> struct scalar_fuzzy_impl }; +/**************************************************************************** +* Special functions * +****************************************************************************/ + +// std::isfinite is non standard, so let's define our own version, +// even though it is not very efficient. +template bool (isfinite)(const T& x) +{ + return x::highest() && x>NumTraits::lowest(); +} + } // end namespace internal +} // end namespace Eigen + #endif // EIGEN_MATHFUNCTIONS_H diff --git a/extern/Eigen3/Eigen/src/Core/Matrix.h b/extern/Eigen3/Eigen/src/Core/Matrix.h index 982c9256af0..99160b591b0 100644 --- a/extern/Eigen3/Eigen/src/Core/Matrix.h +++ b/extern/Eigen3/Eigen/src/Core/Matrix.h @@ -4,28 +4,15 @@ // Copyright (C) 2006-2010 Benoit Jacob // Copyright (C) 2008-2009 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_MATRIX_H #define EIGEN_MATRIX_H +namespace Eigen { + /** \class Matrix * \ingroup Core_Module * @@ -411,25 +398,8 @@ EIGEN_MAKE_TYPEDEFS_ALL_SIZES(std::complex, cd) #undef EIGEN_MAKE_TYPEDEFS_ALL_SIZES #undef EIGEN_MAKE_TYPEDEFS +#undef EIGEN_MAKE_FIXED_TYPEDEFS -#undef EIGEN_MAKE_TYPEDEFS_LARGE - -#define EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, SizeSuffix) \ -using Eigen::Matrix##SizeSuffix##TypeSuffix; \ -using Eigen::Vector##SizeSuffix##TypeSuffix; \ -using Eigen::RowVector##SizeSuffix##TypeSuffix; - -#define EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE(TypeSuffix) \ -EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 2) \ -EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 3) \ -EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 4) \ -EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, X) \ - -#define EIGEN_USING_MATRIX_TYPEDEFS \ -EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE(i) \ -EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE(f) \ -EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE(d) \ -EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE(cf) \ -EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE(cd) +} // end namespace Eigen #endif // EIGEN_MATRIX_H diff --git a/extern/Eigen3/Eigen/src/Core/MatrixBase.h b/extern/Eigen3/Eigen/src/Core/MatrixBase.h index 62877bce09e..c1e0ed132cc 100644 --- a/extern/Eigen3/Eigen/src/Core/MatrixBase.h +++ b/extern/Eigen3/Eigen/src/Core/MatrixBase.h @@ -4,28 +4,15 @@ // Copyright (C) 2006-2009 Benoit Jacob // Copyright (C) 2008 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_MATRIXBASE_H #define EIGEN_MATRIXBASE_H +namespace Eigen { + /** \class MatrixBase * \ingroup Core_Module * @@ -250,8 +237,7 @@ template class MatrixBase // huuuge hack. make Eigen2's matrix.part() work in eigen3. Problem: Diagonal is now a class template instead // of an integer constant. Solution: overload the part() method template wrt template parameters list. - // Note: replacing next line by "template class U>" produces a mysterious error C2082 in MSVC. - template class U> + template class U> const DiagonalWrapper part() const { return diagonal().asDiagonal(); } #endif // EIGEN2_SUPPORT @@ -331,7 +317,7 @@ template class MatrixBase /** \returns an \link ArrayBase Array \endlink expression of this matrix * \sa ArrayBase::matrix() */ ArrayWrapper array() { return derived(); } - const ArrayWrapper array() const { return derived(); } + const ArrayWrapper array() const { return derived(); } /////////// LU module /////////// @@ -466,6 +452,8 @@ template class MatrixBase const MatrixFunctionReturnValue sinh() const; const MatrixFunctionReturnValue cos() const; const MatrixFunctionReturnValue sin() const; + const MatrixSquareRootReturnValue sqrt() const; + const MatrixLogarithmReturnValue log() const; #ifdef EIGEN2_SUPPORT template @@ -512,10 +500,12 @@ template class MatrixBase protected: // mixing arrays and matrices is not legal template Derived& operator+=(const ArrayBase& ) - {EIGEN_STATIC_ASSERT(sizeof(typename OtherDerived::Scalar)==-1,YOU_CANNOT_MIX_ARRAYS_AND_MATRICES);} + {EIGEN_STATIC_ASSERT(std::ptrdiff_t(sizeof(typename OtherDerived::Scalar))==-1,YOU_CANNOT_MIX_ARRAYS_AND_MATRICES); return *this;} // mixing arrays and matrices is not legal template Derived& operator-=(const ArrayBase& ) - {EIGEN_STATIC_ASSERT(sizeof(typename OtherDerived::Scalar)==-1,YOU_CANNOT_MIX_ARRAYS_AND_MATRICES);} + {EIGEN_STATIC_ASSERT(std::ptrdiff_t(sizeof(typename OtherDerived::Scalar))==-1,YOU_CANNOT_MIX_ARRAYS_AND_MATRICES); return *this;} }; +} // end namespace Eigen + #endif // EIGEN_MATRIXBASE_H diff --git a/extern/Eigen3/Eigen/src/Core/NestByValue.h b/extern/Eigen3/Eigen/src/Core/NestByValue.h index a6104d2a426..a893b1761b5 100644 --- a/extern/Eigen3/Eigen/src/Core/NestByValue.h +++ b/extern/Eigen3/Eigen/src/Core/NestByValue.h @@ -4,28 +4,15 @@ // Copyright (C) 2008 Gael Guennebaud // Copyright (C) 2006-2008 Benoit Jacob // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_NESTBYVALUE_H #define EIGEN_NESTBYVALUE_H +namespace Eigen { + /** \class NestByValue * \ingroup Core_Module * @@ -119,4 +106,6 @@ DenseBase::nestByValue() const return NestByValue(derived()); } +} // end namespace Eigen + #endif // EIGEN_NESTBYVALUE_H diff --git a/extern/Eigen3/Eigen/src/Core/NoAlias.h b/extern/Eigen3/Eigen/src/Core/NoAlias.h index da64affcf9a..ecb3fa2850e 100644 --- a/extern/Eigen3/Eigen/src/Core/NoAlias.h +++ b/extern/Eigen3/Eigen/src/Core/NoAlias.h @@ -3,28 +3,15 @@ // // Copyright (C) 2009 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_NOALIAS_H #define EIGEN_NOALIAS_H +namespace Eigen { + /** \class NoAlias * \ingroup Core_Module * @@ -133,4 +120,6 @@ NoAlias MatrixBase::noalias() return derived(); } +} // end namespace Eigen + #endif // EIGEN_NOALIAS_H diff --git a/extern/Eigen3/Eigen/src/Core/NumTraits.h b/extern/Eigen3/Eigen/src/Core/NumTraits.h index 73ef05dfe7a..c94ef026b42 100644 --- a/extern/Eigen3/Eigen/src/Core/NumTraits.h +++ b/extern/Eigen3/Eigen/src/Core/NumTraits.h @@ -3,28 +3,15 @@ // // Copyright (C) 2006-2010 Benoit Jacob // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_NUMTRAITS_H #define EIGEN_NUMTRAITS_H +namespace Eigen { + /** \class NumTraits * \ingroup Core_Module * @@ -81,14 +68,14 @@ template struct GenericNumTraits >::type NonInteger; typedef T Nested; - inline static Real epsilon() { return std::numeric_limits::epsilon(); } - inline static Real dummy_precision() + static inline Real epsilon() { return std::numeric_limits::epsilon(); } + static inline Real dummy_precision() { // make sure to override this for floating-point types return Real(0); } - inline static T highest() { return (std::numeric_limits::max)(); } - inline static T lowest() { return IsInteger ? (std::numeric_limits::min)() : (-(std::numeric_limits::max)()); } + static inline T highest() { return (std::numeric_limits::max)(); } + static inline T lowest() { return IsInteger ? (std::numeric_limits::min)() : (-(std::numeric_limits::max)()); } #ifdef EIGEN2_SUPPORT enum { @@ -104,12 +91,12 @@ template struct NumTraits : GenericNumTraits template<> struct NumTraits : GenericNumTraits { - inline static float dummy_precision() { return 1e-5f; } + static inline float dummy_precision() { return 1e-5f; } }; template<> struct NumTraits : GenericNumTraits { - inline static double dummy_precision() { return 1e-12; } + static inline double dummy_precision() { return 1e-12; } }; template<> struct NumTraits @@ -130,8 +117,8 @@ template struct NumTraits > MulCost = 4 * NumTraits::MulCost + 2 * NumTraits::AddCost }; - inline static Real epsilon() { return NumTraits::epsilon(); } - inline static Real dummy_precision() { return NumTraits::dummy_precision(); } + static inline Real epsilon() { return NumTraits::epsilon(); } + static inline Real dummy_precision() { return NumTraits::dummy_precision(); } }; template @@ -155,6 +142,6 @@ struct NumTraits > }; }; - +} // end namespace Eigen #endif // EIGEN_NUMTRAITS_H diff --git a/extern/Eigen3/Eigen/src/Core/PermutationMatrix.h b/extern/Eigen3/Eigen/src/Core/PermutationMatrix.h index a064e053e51..bc29f814205 100644 --- a/extern/Eigen3/Eigen/src/Core/PermutationMatrix.h +++ b/extern/Eigen3/Eigen/src/Core/PermutationMatrix.h @@ -4,28 +4,15 @@ // Copyright (C) 2009 Benoit Jacob // Copyright (C) 2009-2011 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_PERMUTATIONMATRIX_H #define EIGEN_PERMUTATIONMATRIX_H +namespace Eigen { + template class PermutedImpl; /** \class PermutationBase @@ -56,6 +43,8 @@ namespace internal { template struct permut_matrix_product_retval; +template +struct permut_sparsematrix_product_retval; enum PermPermProduct_t {PermPermProduct}; } // end namespace internal @@ -511,7 +500,7 @@ class PermutationWrapper : public PermutationBase MatrixBase::asPermutation() con return derived(); } +} // end namespace Eigen + #endif // EIGEN_PERMUTATIONMATRIX_H diff --git a/extern/Eigen3/Eigen/src/Core/PlainObjectBase.h b/extern/Eigen3/Eigen/src/Core/PlainObjectBase.h index 612254e9da9..71c74309acc 100644 --- a/extern/Eigen3/Eigen/src/Core/PlainObjectBase.h +++ b/extern/Eigen3/Eigen/src/Core/PlainObjectBase.h @@ -4,24 +4,9 @@ // Copyright (C) 2008-2009 Gael Guennebaud // Copyright (C) 2006-2008 Benoit Jacob // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_DENSESTORAGEBASE_H #define EIGEN_DENSESTORAGEBASE_H @@ -32,6 +17,8 @@ # define EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED #endif +namespace Eigen { + namespace internal { template @@ -47,13 +34,13 @@ EIGEN_ALWAYS_INLINE void check_rows_cols_for_overflow(Index rows, Index cols) throw_std_bad_alloc(); } -template (Derived::IsVectorAtCompileTime)> struct conservative_resize_like_impl; +template struct conservative_resize_like_impl; template struct matrix_swap_impl; } // end namespace internal -/** +/** \class PlainObjectBase * \brief %Dense storage base class for matrices and arrays. * * This class can be extended with the help of the plugin mechanism described on the page @@ -61,8 +48,29 @@ template struct m * * \sa \ref TopicClassHierarchy */ +#ifdef EIGEN_PARSED_BY_DOXYGEN +namespace internal { + +// this is a warkaround to doxygen not being able to understand the inheritence logic +// when it is hidden by the dense_xpr_base helper struct. +template struct dense_xpr_base_dispatcher_for_doxygen;// : public MatrixBase {}; +/** This class is just a workaround for Doxygen and it does not not actually exist. */ +template +struct dense_xpr_base_dispatcher_for_doxygen > + : public MatrixBase > {}; +/** This class is just a workaround for Doxygen and it does not not actually exist. */ +template +struct dense_xpr_base_dispatcher_for_doxygen > + : public ArrayBase > {}; + +} // namespace internal + +template +class PlainObjectBase : public internal::dense_xpr_base_dispatcher_for_doxygen +#else template class PlainObjectBase : public internal::dense_xpr_base::type +#endif { public: enum { Options = internal::traits::Options }; @@ -443,68 +451,68 @@ class PlainObjectBase : public internal::dense_xpr_base::type * \see class Map */ //@{ - inline static ConstMapType Map(const Scalar* data) + static inline ConstMapType Map(const Scalar* data) { return ConstMapType(data); } - inline static MapType Map(Scalar* data) + static inline MapType Map(Scalar* data) { return MapType(data); } - inline static ConstMapType Map(const Scalar* data, Index size) + static inline ConstMapType Map(const Scalar* data, Index size) { return ConstMapType(data, size); } - inline static MapType Map(Scalar* data, Index size) + static inline MapType Map(Scalar* data, Index size) { return MapType(data, size); } - inline static ConstMapType Map(const Scalar* data, Index rows, Index cols) + static inline ConstMapType Map(const Scalar* data, Index rows, Index cols) { return ConstMapType(data, rows, cols); } - inline static MapType Map(Scalar* data, Index rows, Index cols) + static inline MapType Map(Scalar* data, Index rows, Index cols) { return MapType(data, rows, cols); } - inline static ConstAlignedMapType MapAligned(const Scalar* data) + static inline ConstAlignedMapType MapAligned(const Scalar* data) { return ConstAlignedMapType(data); } - inline static AlignedMapType MapAligned(Scalar* data) + static inline AlignedMapType MapAligned(Scalar* data) { return AlignedMapType(data); } - inline static ConstAlignedMapType MapAligned(const Scalar* data, Index size) + static inline ConstAlignedMapType MapAligned(const Scalar* data, Index size) { return ConstAlignedMapType(data, size); } - inline static AlignedMapType MapAligned(Scalar* data, Index size) + static inline AlignedMapType MapAligned(Scalar* data, Index size) { return AlignedMapType(data, size); } - inline static ConstAlignedMapType MapAligned(const Scalar* data, Index rows, Index cols) + static inline ConstAlignedMapType MapAligned(const Scalar* data, Index rows, Index cols) { return ConstAlignedMapType(data, rows, cols); } - inline static AlignedMapType MapAligned(Scalar* data, Index rows, Index cols) + static inline AlignedMapType MapAligned(Scalar* data, Index rows, Index cols) { return AlignedMapType(data, rows, cols); } template - inline static typename StridedConstMapType >::type Map(const Scalar* data, const Stride& stride) + static inline typename StridedConstMapType >::type Map(const Scalar* data, const Stride& stride) { return typename StridedConstMapType >::type(data, stride); } template - inline static typename StridedMapType >::type Map(Scalar* data, const Stride& stride) + static inline typename StridedMapType >::type Map(Scalar* data, const Stride& stride) { return typename StridedMapType >::type(data, stride); } template - inline static typename StridedConstMapType >::type Map(const Scalar* data, Index size, const Stride& stride) + static inline typename StridedConstMapType >::type Map(const Scalar* data, Index size, const Stride& stride) { return typename StridedConstMapType >::type(data, size, stride); } template - inline static typename StridedMapType >::type Map(Scalar* data, Index size, const Stride& stride) + static inline typename StridedMapType >::type Map(Scalar* data, Index size, const Stride& stride) { return typename StridedMapType >::type(data, size, stride); } template - inline static typename StridedConstMapType >::type Map(const Scalar* data, Index rows, Index cols, const Stride& stride) + static inline typename StridedConstMapType >::type Map(const Scalar* data, Index rows, Index cols, const Stride& stride) { return typename StridedConstMapType >::type(data, rows, cols, stride); } template - inline static typename StridedMapType >::type Map(Scalar* data, Index rows, Index cols, const Stride& stride) + static inline typename StridedMapType >::type Map(Scalar* data, Index rows, Index cols, const Stride& stride) { return typename StridedMapType >::type(data, rows, cols, stride); } template - inline static typename StridedConstAlignedMapType >::type MapAligned(const Scalar* data, const Stride& stride) + static inline typename StridedConstAlignedMapType >::type MapAligned(const Scalar* data, const Stride& stride) { return typename StridedConstAlignedMapType >::type(data, stride); } template - inline static typename StridedAlignedMapType >::type MapAligned(Scalar* data, const Stride& stride) + static inline typename StridedAlignedMapType >::type MapAligned(Scalar* data, const Stride& stride) { return typename StridedAlignedMapType >::type(data, stride); } template - inline static typename StridedConstAlignedMapType >::type MapAligned(const Scalar* data, Index size, const Stride& stride) + static inline typename StridedConstAlignedMapType >::type MapAligned(const Scalar* data, Index size, const Stride& stride) { return typename StridedConstAlignedMapType >::type(data, size, stride); } template - inline static typename StridedAlignedMapType >::type MapAligned(Scalar* data, Index size, const Stride& stride) + static inline typename StridedAlignedMapType >::type MapAligned(Scalar* data, Index size, const Stride& stride) { return typename StridedAlignedMapType >::type(data, size, stride); } template - inline static typename StridedConstAlignedMapType >::type MapAligned(const Scalar* data, Index rows, Index cols, const Stride& stride) + static inline typename StridedConstAlignedMapType >::type MapAligned(const Scalar* data, Index rows, Index cols, const Stride& stride) { return typename StridedConstAlignedMapType >::type(data, rows, cols, stride); } template - inline static typename StridedAlignedMapType >::type MapAligned(Scalar* data, Index rows, Index cols, const Stride& stride) + static inline typename StridedAlignedMapType >::type MapAligned(Scalar* data, Index rows, Index cols, const Stride& stride) { return typename StridedAlignedMapType >::type(data, rows, cols, stride); } //@} @@ -594,6 +602,9 @@ class PlainObjectBase : public internal::dense_xpr_base::type template EIGEN_STRONG_INLINE void _init2(Index rows, Index cols, typename internal::enable_if::type* = 0) { + EIGEN_STATIC_ASSERT(bool(NumTraits::IsInteger) && + bool(NumTraits::IsInteger), + FLOATING_POINT_ARGUMENT_PASSED__INTEGER_WAS_EXPECTED) eigen_assert(rows >= 0 && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows) && cols >= 0 && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols)); internal::check_rows_cols_for_overflow(rows, cols); @@ -623,7 +634,7 @@ class PlainObjectBase : public internal::dense_xpr_base::type public: #ifndef EIGEN_PARSED_BY_DOXYGEN - EIGEN_STRONG_INLINE static void _check_template_params() + static EIGEN_STRONG_INLINE void _check_template_params() { EIGEN_STATIC_ASSERT((EIGEN_IMPLIES(MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1, (Options&RowMajor)==RowMajor) && EIGEN_IMPLIES(MaxColsAtCompileTime==1 && MaxRowsAtCompileTime!=1, (Options&RowMajor)==0) @@ -751,4 +762,6 @@ struct matrix_swap_impl } // end namespace internal +} // end namespace Eigen + #endif // EIGEN_DENSESTORAGEBASE_H diff --git a/extern/Eigen3/Eigen/src/Core/Product.h b/extern/Eigen3/Eigen/src/Core/Product.h index e2035b242b1..30aa8943b4c 100644 --- a/extern/Eigen3/Eigen/src/Core/Product.h +++ b/extern/Eigen3/Eigen/src/Core/Product.h @@ -1,625 +1,98 @@ // This file is part of Eigen, a lightweight C++ template library // for linear algebra. // -// Copyright (C) 2006-2008 Benoit Jacob -// Copyright (C) 2008 Gael Guennebaud +// Copyright (C) 2008-2011 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_PRODUCT_H #define EIGEN_PRODUCT_H -/** \class GeneralProduct +template class Product; +template class ProductImpl; + +/** \class Product * \ingroup Core_Module * - * \brief Expression of the product of two general matrices or vectors + * \brief Expression of the product of two arbitrary matrices or vectors * - * \param LhsNested the type used to store the left-hand side - * \param RhsNested the type used to store the right-hand side - * \param ProductMode the type of the product + * \param Lhs the type of the left-hand side expression + * \param Rhs the type of the right-hand side expression * - * This class represents an expression of the product of two general matrices. - * We call a general matrix, a dense matrix with full storage. For instance, - * This excludes triangular, selfadjoint, and sparse matrices. - * It is the return type of the operator* between general matrices. Its template - * arguments are determined automatically by ProductReturnType. Therefore, - * GeneralProduct should never be used direclty. To determine the result type of a - * function which involves a matrix product, use ProductReturnType::Type. + * This class represents an expression of the product of two arbitrary matrices. * - * \sa ProductReturnType, MatrixBase::operator*(const MatrixBase&) */ -template::value> -class GeneralProduct; - -enum { - Large = 2, - Small = 3 -}; namespace internal { - -template struct product_type_selector; - -template struct product_size_category +template +struct traits > { - enum { is_large = MaxSize == Dynamic || - Size >= EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD, - value = is_large ? Large - : Size == 1 ? 1 - : Small + typedef MatrixXpr XprKind; + typedef typename remove_all::type LhsCleaned; + typedef typename remove_all::type RhsCleaned; + typedef typename scalar_product_traits::Scalar, typename traits::Scalar>::ReturnType Scalar; + typedef typename promote_storage_type::StorageKind, + typename traits::StorageKind>::ret StorageKind; + typedef typename promote_index_type::Index, + typename traits::Index>::type Index; + enum { + RowsAtCompileTime = LhsCleaned::RowsAtCompileTime, + ColsAtCompileTime = RhsCleaned::ColsAtCompileTime, + MaxRowsAtCompileTime = LhsCleaned::MaxRowsAtCompileTime, + MaxColsAtCompileTime = RhsCleaned::MaxColsAtCompileTime, + Flags = (MaxRowsAtCompileTime==1 ? RowMajorBit : 0), // TODO should be no storage order + CoeffReadCost = 0 // TODO CoeffReadCost should not be part of the expression traits }; }; - -template struct product_type -{ - typedef typename remove_all::type _Lhs; - typedef typename remove_all::type _Rhs; - enum { - MaxRows = _Lhs::MaxRowsAtCompileTime, - Rows = _Lhs::RowsAtCompileTime, - MaxCols = _Rhs::MaxColsAtCompileTime, - Cols = _Rhs::ColsAtCompileTime, - MaxDepth = EIGEN_SIZE_MIN_PREFER_FIXED(_Lhs::MaxColsAtCompileTime, - _Rhs::MaxRowsAtCompileTime), - Depth = EIGEN_SIZE_MIN_PREFER_FIXED(_Lhs::ColsAtCompileTime, - _Rhs::RowsAtCompileTime), - LargeThreshold = EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD - }; - - // the splitting into different lines of code here, introducing the _select enums and the typedef below, - // is to work around an internal compiler error with gcc 4.1 and 4.2. -private: - enum { - rows_select = product_size_category::value, - cols_select = product_size_category::value, - depth_select = product_size_category::value - }; - typedef product_type_selector selector; - -public: - enum { - value = selector::ret - }; -#ifdef EIGEN_DEBUG_PRODUCT - static void debug() - { - EIGEN_DEBUG_VAR(Rows); - EIGEN_DEBUG_VAR(Cols); - EIGEN_DEBUG_VAR(Depth); - EIGEN_DEBUG_VAR(rows_select); - EIGEN_DEBUG_VAR(cols_select); - EIGEN_DEBUG_VAR(depth_select); - EIGEN_DEBUG_VAR(value); - } -#endif -}; - - -/* The following allows to select the kind of product at compile time - * based on the three dimensions of the product. - * This is a compile time mapping from {1,Small,Large}^3 -> {product types} */ -// FIXME I'm not sure the current mapping is the ideal one. -template struct product_type_selector { enum { ret = OuterProduct }; }; -template struct product_type_selector<1, 1, Depth> { enum { ret = InnerProduct }; }; -template<> struct product_type_selector<1, 1, 1> { enum { ret = InnerProduct }; }; -template<> struct product_type_selector { enum { ret = CoeffBasedProductMode }; }; -template<> struct product_type_selector<1, Small,Small> { enum { ret = CoeffBasedProductMode }; }; -template<> struct product_type_selector { enum { ret = CoeffBasedProductMode }; }; -template<> struct product_type_selector { enum { ret = LazyCoeffBasedProductMode }; }; -template<> struct product_type_selector { enum { ret = LazyCoeffBasedProductMode }; }; -template<> struct product_type_selector { enum { ret = LazyCoeffBasedProductMode }; }; -template<> struct product_type_selector<1, Large,Small> { enum { ret = CoeffBasedProductMode }; }; -template<> struct product_type_selector<1, Large,Large> { enum { ret = GemvProduct }; }; -template<> struct product_type_selector<1, Small,Large> { enum { ret = CoeffBasedProductMode }; }; -template<> struct product_type_selector { enum { ret = CoeffBasedProductMode }; }; -template<> struct product_type_selector { enum { ret = GemvProduct }; }; -template<> struct product_type_selector { enum { ret = CoeffBasedProductMode }; }; -template<> struct product_type_selector { enum { ret = GemmProduct }; }; -template<> struct product_type_selector { enum { ret = GemmProduct }; }; -template<> struct product_type_selector { enum { ret = GemmProduct }; }; -template<> struct product_type_selector { enum { ret = GemmProduct }; }; -template<> struct product_type_selector { enum { ret = GemmProduct }; }; -template<> struct product_type_selector { enum { ret = GemmProduct }; }; -template<> struct product_type_selector { enum { ret = GemmProduct }; }; - } // end namespace internal -/** \class ProductReturnType - * \ingroup Core_Module - * - * \brief Helper class to get the correct and optimized returned type of operator* - * - * \param Lhs the type of the left-hand side - * \param Rhs the type of the right-hand side - * \param ProductMode the type of the product (determined automatically by internal::product_mode) - * - * This class defines the typename Type representing the optimized product expression - * between two matrix expressions. In practice, using ProductReturnType::Type - * is the recommended way to define the result type of a function returning an expression - * which involve a matrix product. The class Product should never be - * used directly. - * - * \sa class Product, MatrixBase::operator*(const MatrixBase&) - */ -template -struct ProductReturnType -{ - // TODO use the nested type to reduce instanciations ???? -// typedef typename internal::nested::type LhsNested; -// typedef typename internal::nested::type RhsNested; - - typedef GeneralProduct Type; -}; template -struct ProductReturnType -{ - typedef typename internal::nested::type >::type LhsNested; - typedef typename internal::nested::type >::type RhsNested; - typedef CoeffBasedProduct Type; -}; - -template -struct ProductReturnType -{ - typedef typename internal::nested::type >::type LhsNested; - typedef typename internal::nested::type >::type RhsNested; - typedef CoeffBasedProduct Type; -}; - -// this is a workaround for sun CC -template -struct LazyProductReturnType : public ProductReturnType -{}; - -/*********************************************************************** -* Implementation of Inner Vector Vector Product -***********************************************************************/ - -// FIXME : maybe the "inner product" could return a Scalar -// instead of a 1x1 matrix ?? -// Pro: more natural for the user -// Cons: this could be a problem if in a meta unrolled algorithm a matrix-matrix -// product ends up to a row-vector times col-vector product... To tackle this use -// case, we could have a specialization for Block with: operator=(Scalar x); - -namespace internal { - -template -struct traits > - : traits::ReturnType,1,1> > -{}; - -} - -template -class GeneralProduct - : internal::no_assignment_operator, - public Matrix::ReturnType,1,1> -{ - typedef Matrix::ReturnType,1,1> Base; - public: - GeneralProduct(const Lhs& lhs, const Rhs& rhs) - { - EIGEN_STATIC_ASSERT((internal::is_same::value), - YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) - - Base::coeffRef(0,0) = (lhs.transpose().cwiseProduct(rhs)).sum(); - } - - /** Convertion to scalar */ - operator const typename Base::Scalar() const { - return Base::coeff(0,0); - } -}; - -/*********************************************************************** -* Implementation of Outer Vector Vector Product -***********************************************************************/ - -namespace internal { -template struct outer_product_selector; - -template -struct traits > - : traits, Lhs, Rhs> > -{}; - -} - -template -class GeneralProduct - : public ProductBase, Lhs, Rhs> +class Product : public ProductImpl::StorageKind, + typename internal::traits::StorageKind>::ret> { public: - EIGEN_PRODUCT_PUBLIC_INTERFACE(GeneralProduct) - - GeneralProduct(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs) - { - EIGEN_STATIC_ASSERT((internal::is_same::value), - YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) - } - - template void scaleAndAddTo(Dest& dest, Scalar alpha) const - { - internal::outer_product_selector<(int(Dest::Flags)&RowMajorBit) ? RowMajor : ColMajor>::run(*this, dest, alpha); - } -}; - -namespace internal { - -template<> struct outer_product_selector { - template - static EIGEN_DONT_INLINE void run(const ProductType& prod, Dest& dest, typename ProductType::Scalar alpha) { - typedef typename Dest::Index Index; - // FIXME make sure lhs is sequentially stored - // FIXME not very good if rhs is real and lhs complex while alpha is real too - const Index cols = dest.cols(); - for (Index j=0; j struct outer_product_selector { - template - static EIGEN_DONT_INLINE void run(const ProductType& prod, Dest& dest, typename ProductType::Scalar alpha) { - typedef typename Dest::Index Index; - // FIXME make sure rhs is sequentially stored - // FIXME not very good if lhs is real and rhs complex while alpha is real too - const Index rows = dest.rows(); - for (Index i=0; i call fast BLAS-like colmajor routine - * 2 - the matrix is row-major, BLAS compatible and N is large => call fast BLAS-like rowmajor routine - * 3 - all other cases are handled using a simple loop along the outer-storage direction. - * Therefore we need a lower level meta selector. - * Furthermore, if the matrix is the rhs, then the product has to be transposed. - */ -namespace internal { - -template -struct traits > - : traits, Lhs, Rhs> > -{}; - -template -struct gemv_selector; - -} // end namespace internal - -template -class GeneralProduct - : public ProductBase, Lhs, Rhs> -{ - public: - EIGEN_PRODUCT_PUBLIC_INTERFACE(GeneralProduct) - - typedef typename Lhs::Scalar LhsScalar; - typedef typename Rhs::Scalar RhsScalar; - - GeneralProduct(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs) - { -// EIGEN_STATIC_ASSERT((internal::is_same::value), -// YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) - } - - enum { Side = Lhs::IsVectorAtCompileTime ? OnTheLeft : OnTheRight }; - typedef typename internal::conditional::type MatrixType; - - template void scaleAndAddTo(Dest& dst, Scalar alpha) const - { - eigen_assert(m_lhs.rows() == dst.rows() && m_rhs.cols() == dst.cols()); - internal::gemv_selector::HasUsableDirectAccess)>::run(*this, dst, alpha); - } -}; - -namespace internal { - -// The vector is on the left => transposition -template -struct gemv_selector -{ - template - static void run(const ProductType& prod, Dest& dest, typename ProductType::Scalar alpha) - { - Transpose destT(dest); - enum { OtherStorageOrder = StorageOrder == RowMajor ? ColMajor : RowMajor }; - gemv_selector - ::run(GeneralProduct,Transpose, GemvProduct> - (prod.rhs().transpose(), prod.lhs().transpose()), destT, alpha); - } -}; - -template struct gemv_static_vector_if; - -template -struct gemv_static_vector_if -{ - EIGEN_STRONG_INLINE Scalar* data() { eigen_internal_assert(false && "should never be called"); return 0; } -}; - -template -struct gemv_static_vector_if -{ - EIGEN_STRONG_INLINE Scalar* data() { return 0; } -}; - -template -struct gemv_static_vector_if -{ - #if EIGEN_ALIGN_STATICALLY - internal::plain_array m_data; - EIGEN_STRONG_INLINE Scalar* data() { return m_data.array; } - #else - // Some architectures cannot align on the stack, - // => let's manually enforce alignment by allocating more data and return the address of the first aligned element. - enum { - ForceAlignment = internal::packet_traits::Vectorizable, - PacketSize = internal::packet_traits::size - }; - internal::plain_array m_data; - EIGEN_STRONG_INLINE Scalar* data() { - return ForceAlignment - ? reinterpret_cast((reinterpret_cast(m_data.array) & ~(size_t(15))) + 16) - : m_data.array; - } - #endif -}; - -template<> struct gemv_selector -{ - template - static inline void run(const ProductType& prod, Dest& dest, typename ProductType::Scalar alpha) - { - typedef typename ProductType::Index Index; - typedef typename ProductType::LhsScalar LhsScalar; - typedef typename ProductType::RhsScalar RhsScalar; - typedef typename ProductType::Scalar ResScalar; - typedef typename ProductType::RealScalar RealScalar; - typedef typename ProductType::ActualLhsType ActualLhsType; - typedef typename ProductType::ActualRhsType ActualRhsType; - typedef typename ProductType::LhsBlasTraits LhsBlasTraits; - typedef typename ProductType::RhsBlasTraits RhsBlasTraits; - typedef Map, Aligned> MappedDest; - - const ActualLhsType actualLhs = LhsBlasTraits::extract(prod.lhs()); - const ActualRhsType actualRhs = RhsBlasTraits::extract(prod.rhs()); - - ResScalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(prod.lhs()) - * RhsBlasTraits::extractScalarFactor(prod.rhs()); - - enum { - // FIXME find a way to allow an inner stride on the result if packet_traits::size==1 - // on, the other hand it is good for the cache to pack the vector anyways... - EvalToDestAtCompileTime = Dest::InnerStrideAtCompileTime==1, - ComplexByReal = (NumTraits::IsComplex) && (!NumTraits::IsComplex), - MightCannotUseDest = (Dest::InnerStrideAtCompileTime!=1) || ComplexByReal - }; - - gemv_static_vector_if static_dest; - - // this is written like this (i.e., with a ?:) to workaround an ICE with ICC 12 - bool alphaIsCompatible = (!ComplexByReal) ? true : (imag(actualAlpha)==RealScalar(0)); - bool evalToDest = EvalToDestAtCompileTime && alphaIsCompatible; - RhsScalar compatibleAlpha = get_factor::run(actualAlpha); + typedef typename ProductImpl< + Lhs, Rhs, + typename internal::promote_storage_type::ret>::Base Base; + EIGEN_GENERIC_PUBLIC_INTERFACE(Product) - ei_declare_aligned_stack_constructed_variable(ResScalar,actualDestPtr,dest.size(), - evalToDest ? dest.data() : static_dest.data()); - - if(!evalToDest) + typedef typename Lhs::Nested LhsNested; + typedef typename Rhs::Nested RhsNested; + typedef typename internal::remove_all::type LhsNestedCleaned; + typedef typename internal::remove_all::type RhsNestedCleaned; + + Product(const Lhs& lhs, const Rhs& rhs) : m_lhs(lhs), m_rhs(rhs) { - #ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN - int size = dest.size(); - EIGEN_DENSE_STORAGE_CTOR_PLUGIN - #endif - if(!alphaIsCompatible) - { - MappedDest(actualDestPtr, dest.size()).setZero(); - compatibleAlpha = RhsScalar(1); - } - else - MappedDest(actualDestPtr, dest.size()) = dest; + eigen_assert(lhs.cols() == rhs.rows() + && "invalid matrix product" + && "if you wanted a coeff-wise or a dot product use the respective explicit functions"); } - general_matrix_vector_product - ::run( - actualLhs.rows(), actualLhs.cols(), - &actualLhs.coeffRef(0,0), actualLhs.outerStride(), - actualRhs.data(), actualRhs.innerStride(), - actualDestPtr, 1, - compatibleAlpha); + inline Index rows() const { return m_lhs.rows(); } + inline Index cols() const { return m_rhs.cols(); } - if (!evalToDest) - { - if(!alphaIsCompatible) - dest += actualAlpha * MappedDest(actualDestPtr, dest.size()); - else - dest = MappedDest(actualDestPtr, dest.size()); - } - } + const LhsNestedCleaned& lhs() const { return m_lhs; } + const RhsNestedCleaned& rhs() const { return m_rhs; } + + protected: + + const LhsNested m_lhs; + const RhsNested m_rhs; }; -template<> struct gemv_selector +template +class ProductImpl : public internal::dense_xpr_base >::type { - template - static void run(const ProductType& prod, Dest& dest, typename ProductType::Scalar alpha) - { - typedef typename ProductType::LhsScalar LhsScalar; - typedef typename ProductType::RhsScalar RhsScalar; - typedef typename ProductType::Scalar ResScalar; - typedef typename ProductType::Index Index; - typedef typename ProductType::ActualLhsType ActualLhsType; - typedef typename ProductType::ActualRhsType ActualRhsType; - typedef typename ProductType::_ActualRhsType _ActualRhsType; - typedef typename ProductType::LhsBlasTraits LhsBlasTraits; - typedef typename ProductType::RhsBlasTraits RhsBlasTraits; + typedef Product Derived; + public: - typename add_const::type actualLhs = LhsBlasTraits::extract(prod.lhs()); - typename add_const::type actualRhs = RhsBlasTraits::extract(prod.rhs()); - - ResScalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(prod.lhs()) - * RhsBlasTraits::extractScalarFactor(prod.rhs()); - - enum { - // FIXME find a way to allow an inner stride on the result if packet_traits::size==1 - // on, the other hand it is good for the cache to pack the vector anyways... - DirectlyUseRhs = _ActualRhsType::InnerStrideAtCompileTime==1 - }; - - gemv_static_vector_if static_rhs; - - ei_declare_aligned_stack_constructed_variable(RhsScalar,actualRhsPtr,actualRhs.size(), - DirectlyUseRhs ? const_cast(actualRhs.data()) : static_rhs.data()); - - if(!DirectlyUseRhs) - { - #ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN - int size = actualRhs.size(); - EIGEN_DENSE_STORAGE_CTOR_PLUGIN - #endif - Map(actualRhsPtr, actualRhs.size()) = actualRhs; - } - - general_matrix_vector_product - ::run( - actualLhs.rows(), actualLhs.cols(), - &actualLhs.coeffRef(0,0), actualLhs.outerStride(), - actualRhsPtr, 1, - &dest.coeffRef(0,0), dest.innerStride(), - actualAlpha); - } + typedef typename internal::dense_xpr_base >::type Base; + EIGEN_DENSE_PUBLIC_INTERFACE(Derived) }; -template<> struct gemv_selector -{ - template - static void run(const ProductType& prod, Dest& dest, typename ProductType::Scalar alpha) - { - typedef typename Dest::Index Index; - // TODO makes sure dest is sequentially stored in memory, otherwise use a temp - const Index size = prod.rhs().rows(); - for(Index k=0; k struct gemv_selector -{ - template - static void run(const ProductType& prod, Dest& dest, typename ProductType::Scalar alpha) - { - typedef typename Dest::Index Index; - // TODO makes sure rhs is sequentially stored in memory, otherwise use a temp - const Index rows = prod.rows(); - for(Index i=0; i -template -inline const typename ProductReturnType::Type -MatrixBase::operator*(const MatrixBase &other) const -{ - // A note regarding the function declaration: In MSVC, this function will sometimes - // not be inlined since DenseStorage is an unwindable object for dynamic - // matrices and product types are holding a member to store the result. - // Thus it does not help tagging this function with EIGEN_STRONG_INLINE. - enum { - ProductIsValid = Derived::ColsAtCompileTime==Dynamic - || OtherDerived::RowsAtCompileTime==Dynamic - || int(Derived::ColsAtCompileTime)==int(OtherDerived::RowsAtCompileTime), - AreVectors = Derived::IsVectorAtCompileTime && OtherDerived::IsVectorAtCompileTime, - SameSizes = EIGEN_PREDICATE_SAME_MATRIX_SIZE(Derived,OtherDerived) - }; - // note to the lost user: - // * for a dot product use: v1.dot(v2) - // * for a coeff-wise product use: v1.cwiseProduct(v2) - EIGEN_STATIC_ASSERT(ProductIsValid || !(AreVectors && SameSizes), - INVALID_VECTOR_VECTOR_PRODUCT__IF_YOU_WANTED_A_DOT_OR_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTIONS) - EIGEN_STATIC_ASSERT(ProductIsValid || !(SameSizes && !AreVectors), - INVALID_MATRIX_PRODUCT__IF_YOU_WANTED_A_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTION) - EIGEN_STATIC_ASSERT(ProductIsValid || SameSizes, INVALID_MATRIX_PRODUCT) -#ifdef EIGEN_DEBUG_PRODUCT - internal::product_type::debug(); -#endif - return typename ProductReturnType::Type(derived(), other.derived()); -} - -/** \returns an expression of the matrix product of \c *this and \a other without implicit evaluation. - * - * The returned product will behave like any other expressions: the coefficients of the product will be - * computed once at a time as requested. This might be useful in some extremely rare cases when only - * a small and no coherent fraction of the result's coefficients have to be computed. - * - * \warning This version of the matrix product can be much much slower. So use it only if you know - * what you are doing and that you measured a true speed improvement. - * - * \sa operator*(const MatrixBase&) - */ -template -template -const typename LazyProductReturnType::Type -MatrixBase::lazyProduct(const MatrixBase &other) const -{ - enum { - ProductIsValid = Derived::ColsAtCompileTime==Dynamic - || OtherDerived::RowsAtCompileTime==Dynamic - || int(Derived::ColsAtCompileTime)==int(OtherDerived::RowsAtCompileTime), - AreVectors = Derived::IsVectorAtCompileTime && OtherDerived::IsVectorAtCompileTime, - SameSizes = EIGEN_PREDICATE_SAME_MATRIX_SIZE(Derived,OtherDerived) - }; - // note to the lost user: - // * for a dot product use: v1.dot(v2) - // * for a coeff-wise product use: v1.cwiseProduct(v2) - EIGEN_STATIC_ASSERT(ProductIsValid || !(AreVectors && SameSizes), - INVALID_VECTOR_VECTOR_PRODUCT__IF_YOU_WANTED_A_DOT_OR_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTIONS) - EIGEN_STATIC_ASSERT(ProductIsValid || !(SameSizes && !AreVectors), - INVALID_MATRIX_PRODUCT__IF_YOU_WANTED_A_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTION) - EIGEN_STATIC_ASSERT(ProductIsValid || SameSizes, INVALID_MATRIX_PRODUCT) - - return typename LazyProductReturnType::Type(derived(), other.derived()); -} - #endif // EIGEN_PRODUCT_H diff --git a/extern/Eigen3/Eigen/src/Core/ProductBase.h b/extern/Eigen3/Eigen/src/Core/ProductBase.h index 91975880fdc..ec12e5c9f6b 100644 --- a/extern/Eigen3/Eigen/src/Core/ProductBase.h +++ b/extern/Eigen3/Eigen/src/Core/ProductBase.h @@ -3,28 +3,15 @@ // // Copyright (C) 2009-2010 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_PRODUCTBASE_H #define EIGEN_PRODUCTBASE_H +namespace Eigen { + /** \class ProductBase * \ingroup Core_Module * @@ -115,10 +102,10 @@ class ProductBase : public MatrixBase inline void evalTo(Dest& dst) const { dst.setZero(); scaleAndAddTo(dst,Scalar(1)); } template - inline void addTo(Dest& dst) const { scaleAndAddTo(dst,1); } + inline void addTo(Dest& dst) const { scaleAndAddTo(dst,Scalar(1)); } template - inline void subTo(Dest& dst) const { scaleAndAddTo(dst,-1); } + inline void subTo(Dest& dst) const { scaleAndAddTo(dst,Scalar(-1)); } template inline void scaleAndAddTo(Dest& dst,Scalar alpha) const { derived().scaleAndAddTo(dst,alpha); } @@ -181,8 +168,8 @@ class ProductBase : public MatrixBase protected: - const LhsNested m_lhs; - const RhsNested m_rhs; + LhsNested m_lhs; + RhsNested m_rhs; mutable PlainObject m_result; }; @@ -286,5 +273,6 @@ Derived& MatrixBase::lazyAssign(const ProductBase // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_RANDOM_H #define EIGEN_RANDOM_H +namespace Eigen { + namespace internal { template struct scalar_random_op { @@ -160,4 +147,6 @@ PlainObjectBase::setRandom(Index rows, Index cols) return setRandom(); } +} // end namespace Eigen + #endif // EIGEN_RANDOM_H diff --git a/extern/Eigen3/Eigen/src/Core/Redux.h b/extern/Eigen3/Eigen/src/Core/Redux.h index f9f5a95d546..b7ce7c658a2 100644 --- a/extern/Eigen3/Eigen/src/Core/Redux.h +++ b/extern/Eigen3/Eigen/src/Core/Redux.h @@ -4,28 +4,15 @@ // Copyright (C) 2008 Gael Guennebaud // Copyright (C) 2006-2008 Benoit Jacob // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_REDUX_H #define EIGEN_REDUX_H +namespace Eigen { + namespace internal { // TODO @@ -95,7 +82,7 @@ struct redux_novec_unroller typedef typename Derived::Scalar Scalar; - EIGEN_STRONG_INLINE static Scalar run(const Derived &mat, const Func& func) + static EIGEN_STRONG_INLINE Scalar run(const Derived &mat, const Func& func) { return func(redux_novec_unroller::run(mat,func), redux_novec_unroller::run(mat,func)); @@ -112,7 +99,7 @@ struct redux_novec_unroller typedef typename Derived::Scalar Scalar; - EIGEN_STRONG_INLINE static Scalar run(const Derived &mat, const Func&) + static EIGEN_STRONG_INLINE Scalar run(const Derived &mat, const Func&) { return mat.coeffByOuterInner(outer, inner); } @@ -125,7 +112,7 @@ template struct redux_novec_unroller { typedef typename Derived::Scalar Scalar; - EIGEN_STRONG_INLINE static Scalar run(const Derived&, const Func&) { return Scalar(); } + static EIGEN_STRONG_INLINE Scalar run(const Derived&, const Func&) { return Scalar(); } }; /*** vectorization ***/ @@ -141,7 +128,7 @@ struct redux_vec_unroller typedef typename Derived::Scalar Scalar; typedef typename packet_traits::type PacketScalar; - EIGEN_STRONG_INLINE static PacketScalar run(const Derived &mat, const Func& func) + static EIGEN_STRONG_INLINE PacketScalar run(const Derived &mat, const Func& func) { return func.packetOp( redux_vec_unroller::run(mat,func), @@ -162,7 +149,7 @@ struct redux_vec_unroller typedef typename Derived::Scalar Scalar; typedef typename packet_traits::type PacketScalar; - EIGEN_STRONG_INLINE static PacketScalar run(const Derived &mat, const Func&) + static EIGEN_STRONG_INLINE PacketScalar run(const Derived &mat, const Func&) { return mat.template packetByOuterInner(outer, inner); } @@ -214,20 +201,33 @@ struct redux_impl const Index size = mat.size(); eigen_assert(size && "you are using an empty matrix"); const Index packetSize = packet_traits::size; - const Index alignedStart = first_aligned(mat); + const Index alignedStart = internal::first_aligned(mat); enum { alignment = bool(Derived::Flags & DirectAccessBit) || bool(Derived::Flags & AlignedBit) ? Aligned : Unaligned }; - const Index alignedSize = ((size-alignedStart)/packetSize)*packetSize; - const Index alignedEnd = alignedStart + alignedSize; + const Index alignedSize2 = ((size-alignedStart)/(2*packetSize))*(2*packetSize); + const Index alignedSize = ((size-alignedStart)/(packetSize))*(packetSize); + const Index alignedEnd2 = alignedStart + alignedSize2; + const Index alignedEnd = alignedStart + alignedSize; Scalar res; if(alignedSize) { - PacketScalar packet_res = mat.template packet(alignedStart); - for(Index index = alignedStart + packetSize; index < alignedEnd; index += packetSize) - packet_res = func.packetOp(packet_res, mat.template packet(index)); - res = func.predux(packet_res); + PacketScalar packet_res0 = mat.template packet(alignedStart); + if(alignedSize>packetSize) // we have at least two packets to partly unroll the loop + { + PacketScalar packet_res1 = mat.template packet(alignedStart+packetSize); + for(Index index = alignedStart + 2*packetSize; index < alignedEnd2; index += 2*packetSize) + { + packet_res0 = func.packetOp(packet_res0, mat.template packet(index)); + packet_res1 = func.packetOp(packet_res1, mat.template packet(index+packetSize)); + } + + packet_res0 = func.packetOp(packet_res0,packet_res1); + if(alignedEnd>alignedEnd2) + packet_res0 = func.packetOp(packet_res0, mat.template packet(alignedEnd2)); + } + res = func.predux(packet_res0); for(Index index = 0; index < alignedStart; ++index) res = func(res,mat.coeff(index)); @@ -296,7 +296,7 @@ struct redux_impl Size = Derived::SizeAtCompileTime, VectorizedSize = (Size / PacketSize) * PacketSize }; - EIGEN_STRONG_INLINE static Scalar run(const Derived& mat, const Func& func) + static EIGEN_STRONG_INLINE Scalar run(const Derived& mat, const Func& func) { eigen_assert(mat.rows()>0 && mat.cols()>0 && "you are using an empty matrix"); Scalar res = func.predux(redux_vec_unroller::run(mat,func)); @@ -401,4 +401,6 @@ MatrixBase::trace() const return derived().diagonal().sum(); } +} // end namespace Eigen + #endif // EIGEN_REDUX_H diff --git a/extern/Eigen3/Eigen/src/Core/Replicate.h b/extern/Eigen3/Eigen/src/Core/Replicate.h index 4c171f8d580..b61fdc29e2f 100644 --- a/extern/Eigen3/Eigen/src/Core/Replicate.h +++ b/extern/Eigen3/Eigen/src/Core/Replicate.h @@ -3,28 +3,15 @@ // // Copyright (C) 2009-2010 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_REPLICATE_H #define EIGEN_REPLICATE_H +namespace Eigen { + /** * \class Replicate * \ingroup Core_Module @@ -92,7 +79,7 @@ template class Replicate } template - inline Replicate(const OriginalMatrixType& matrix, int rowFactor, int colFactor) + inline Replicate(const OriginalMatrixType& matrix, Index rowFactor, Index colFactor) : m_matrix(matrix), m_rowFactor(rowFactor), m_colFactor(colFactor) { EIGEN_STATIC_ASSERT((internal::is_same::type,OriginalMatrixType>::value), @@ -127,9 +114,13 @@ template class Replicate return m_matrix.template packet(actual_row, actual_col); } + const _MatrixTypeNested& nestedExpression() const + { + return m_matrix; + } protected: - const MatrixTypeNested m_matrix; + MatrixTypeNested m_matrix; const internal::variable_if_dynamic m_rowFactor; const internal::variable_if_dynamic m_colFactor; }; @@ -181,4 +172,6 @@ VectorwiseOp::replicate(Index factor) const (_expression(),Direction==Vertical?factor:1,Direction==Horizontal?factor:1); } +} // end namespace Eigen + #endif // EIGEN_REPLICATE_H diff --git a/extern/Eigen3/Eigen/src/Core/ReturnByValue.h b/extern/Eigen3/Eigen/src/Core/ReturnByValue.h index 24c5a4e215d..613912ffa8c 100644 --- a/extern/Eigen3/Eigen/src/Core/ReturnByValue.h +++ b/extern/Eigen3/Eigen/src/Core/ReturnByValue.h @@ -4,28 +4,15 @@ // Copyright (C) 2009-2010 Gael Guennebaud // Copyright (C) 2009-2010 Benoit Jacob // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_RETURNBYVALUE_H #define EIGEN_RETURNBYVALUE_H +namespace Eigen { + /** \class ReturnByValue * \ingroup Core_Module * @@ -96,4 +83,6 @@ Derived& DenseBase::operator=(const ReturnByValue& other) return derived(); } +} // end namespace Eigen + #endif // EIGEN_RETURNBYVALUE_H diff --git a/extern/Eigen3/Eigen/src/Core/Reverse.h b/extern/Eigen3/Eigen/src/Core/Reverse.h index 600744ae758..e30ae3d281b 100644 --- a/extern/Eigen3/Eigen/src/Core/Reverse.h +++ b/extern/Eigen3/Eigen/src/Core/Reverse.h @@ -5,28 +5,15 @@ // Copyright (C) 2009 Ricard Marxer // Copyright (C) 2009-2010 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_REVERSE_H #define EIGEN_REVERSE_H +namespace Eigen { + /** \class Reverse * \ingroup Core_Module * @@ -183,8 +170,14 @@ template class Reverse m_matrix.const_cast_derived().template writePacket(m_matrix.size() - index - PacketSize, internal::preverse(x)); } + const typename internal::remove_all::type& + nestedExpression() const + { + return m_matrix; + } + protected: - const typename MatrixType::Nested m_matrix; + typename MatrixType::Nested m_matrix; }; /** \returns an expression of the reverse of *this. @@ -226,5 +219,6 @@ inline void DenseBase::reverseInPlace() derived() = derived().reverse().eval(); } +} // end namespace Eigen #endif // EIGEN_REVERSE_H diff --git a/extern/Eigen3/Eigen/src/Core/Select.h b/extern/Eigen3/Eigen/src/Core/Select.h index d0cd66a261a..2bf6e91d0aa 100644 --- a/extern/Eigen3/Eigen/src/Core/Select.h +++ b/extern/Eigen3/Eigen/src/Core/Select.h @@ -3,28 +3,15 @@ // // Copyright (C) 2008-2010 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_SELECT_H #define EIGEN_SELECT_H +namespace Eigen { + /** \class Select * \ingroup Core_Module * @@ -101,10 +88,25 @@ class Select : internal::no_assignment_operator, return m_else.coeff(i); } + const ConditionMatrixType& conditionMatrix() const + { + return m_condition; + } + + const ThenMatrixType& thenMatrix() const + { + return m_then; + } + + const ElseMatrixType& elseMatrix() const + { + return m_else; + } + protected: - const typename ConditionMatrixType::Nested m_condition; - const typename ThenMatrixType::Nested m_then; - const typename ElseMatrixType::Nested m_else; + typename ConditionMatrixType::Nested m_condition; + typename ThenMatrixType::Nested m_then; + typename ElseMatrixType::Nested m_else; }; @@ -155,4 +157,6 @@ DenseBase::select(typename ElseDerived::Scalar thenScalar, derived(), ElseDerived::Constant(rows(),cols(),thenScalar), elseMatrix.derived()); } +} // end namespace Eigen + #endif // EIGEN_SELECT_H diff --git a/extern/Eigen3/Eigen/src/Core/SelfAdjointView.h b/extern/Eigen3/Eigen/src/Core/SelfAdjointView.h index 4bb68755eee..82cc4da736a 100644 --- a/extern/Eigen3/Eigen/src/Core/SelfAdjointView.h +++ b/extern/Eigen3/Eigen/src/Core/SelfAdjointView.h @@ -3,28 +3,15 @@ // // Copyright (C) 2009 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_SELFADJOINTMATRIX_H #define EIGEN_SELFADJOINTMATRIX_H +namespace Eigen { + /** \class SelfAdjointView * \ingroup Core_Module * @@ -82,7 +69,7 @@ template class SelfAdjointView }; typedef typename MatrixType::PlainObject PlainObject; - inline SelfAdjointView(const MatrixType& matrix) : m_matrix(matrix) + inline SelfAdjointView(MatrixType& matrix) : m_matrix(matrix) {} inline Index rows() const { return m_matrix.rows(); } @@ -199,7 +186,7 @@ template class SelfAdjointView #endif protected: - const MatrixTypeNested m_matrix; + MatrixTypeNested m_matrix; }; @@ -222,7 +209,7 @@ struct triangular_assignment_selector::run(dst, src); @@ -236,7 +223,7 @@ struct triangular_assignment_selector struct triangular_assignment_selector { - inline static void run(Derived1 &, const Derived2 &) {} + static inline void run(Derived1 &, const Derived2 &) {} }; template @@ -247,7 +234,7 @@ struct triangular_assignment_selector::run(dst, src); @@ -261,14 +248,14 @@ struct triangular_assignment_selector struct triangular_assignment_selector { - inline static void run(Derived1 &, const Derived2 &) {} + static inline void run(Derived1 &, const Derived2 &) {} }; template struct triangular_assignment_selector { typedef typename Derived1::Index Index; - inline static void run(Derived1 &dst, const Derived2 &src) + static inline void run(Derived1 &dst, const Derived2 &src) { for(Index j = 0; j < dst.cols(); ++j) { @@ -285,7 +272,7 @@ struct triangular_assignment_selector struct triangular_assignment_selector { - inline static void run(Derived1 &dst, const Derived2 &src) + static inline void run(Derived1 &dst, const Derived2 &src) { typedef typename Derived1::Index Index; for(Index i = 0; i < dst.rows(); ++i) @@ -322,4 +309,6 @@ MatrixBase::selfadjointView() return derived(); } +} // end namespace Eigen + #endif // EIGEN_SELFADJOINTMATRIX_H diff --git a/extern/Eigen3/Eigen/src/Core/SelfCwiseBinaryOp.h b/extern/Eigen3/Eigen/src/Core/SelfCwiseBinaryOp.h index 4e9ca88745d..0caf2bab1d8 100644 --- a/extern/Eigen3/Eigen/src/Core/SelfCwiseBinaryOp.h +++ b/extern/Eigen3/Eigen/src/Core/SelfCwiseBinaryOp.h @@ -3,28 +3,15 @@ // // Copyright (C) 2009-2010 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_SELFCWISEBINARYOP_H #define EIGEN_SELFCWISEBINARYOP_H +namespace Eigen { + /** \class SelfCwiseBinaryOp * \ingroup Core_Module * @@ -163,6 +150,16 @@ template class SelfCwiseBinaryOp return Base::operator=(rhs); } + Lhs& expression() const + { + return m_matrix; + } + + const BinaryOp& functor() const + { + return m_functor; + } + protected: Lhs& m_matrix; const BinaryOp& m_functor; @@ -192,4 +189,6 @@ inline Derived& DenseBase::operator/=(const Scalar& other) return derived(); } +} // end namespace Eigen + #endif // EIGEN_SELFCWISEBINARYOP_H diff --git a/extern/Eigen3/Eigen/src/Core/SolveTriangular.h b/extern/Eigen3/Eigen/src/Core/SolveTriangular.h index a23014a343f..ef17f288e29 100644 --- a/extern/Eigen3/Eigen/src/Core/SolveTriangular.h +++ b/extern/Eigen3/Eigen/src/Core/SolveTriangular.h @@ -3,28 +3,15 @@ // // Copyright (C) 2008-2009 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_SOLVETRIANGULAR_H #define EIGEN_SOLVETRIANGULAR_H +namespace Eigen { + namespace internal { // Forward declarations: @@ -98,12 +85,22 @@ struct triangular_solver_selector typedef typename Rhs::Index Index; typedef blas_traits LhsProductTraits; typedef typename LhsProductTraits::DirectLinearAccessType ActualLhsType; + static void run(const Lhs& lhs, Rhs& rhs) { - const ActualLhsType actualLhs = LhsProductTraits::extract(lhs); + typename internal::add_const_on_value_type::type actualLhs = LhsProductTraits::extract(lhs); + + const Index size = lhs.rows(); + const Index othersize = Side==OnTheLeft? rhs.cols() : rhs.rows(); + + typedef internal::gemm_blocking_space<(Rhs::Flags&RowMajorBit) ? RowMajor : ColMajor,Scalar,Scalar, + Rhs::MaxRowsAtCompileTime, Rhs::MaxColsAtCompileTime, Lhs::MaxRowsAtCompileTime,4> BlockingType; + + BlockingType blocking(rhs.rows(), rhs.cols(), size); + triangular_solve_matrix - ::run(lhs.rows(), Side==OnTheLeft? rhs.cols() : rhs.rows(), &actualLhs.coeffRef(0,0), actualLhs.outerStride(), &rhs.coeffRef(0,0), rhs.outerStride()); + ::run(size, othersize, &actualLhs.coeffRef(0,0), actualLhs.outerStride(), &rhs.coeffRef(0,0), rhs.outerStride(), blocking); } }; @@ -177,10 +174,8 @@ template void TriangularView::solveInPlace(const MatrixBase& _other) const { OtherDerived& other = _other.const_cast_derived(); - eigen_assert(cols() == rows()); - eigen_assert( (Side==OnTheLeft && cols() == other.rows()) || (Side==OnTheRight && cols() == other.cols()) ); - eigen_assert(!(Mode & ZeroDiag)); - eigen_assert((Mode & (Upper|Lower)) != 0); + eigen_assert( cols() == rows() && ((Side==OnTheLeft && cols() == other.rows()) || (Side==OnTheRight && cols() == other.cols())) ); + eigen_assert((!(Mode & ZeroDiag)) && bool(Mode & (Upper|Lower))); enum { copy = internal::traits::Flags & RowMajorBit && OtherDerived::IsVectorAtCompileTime }; typedef typename internal::conditional struct triangular_solv protected: const TriangularType& m_triangularMatrix; - const typename Rhs::Nested m_rhs; + typename Rhs::Nested m_rhs; }; } // namespace internal +} // end namespace Eigen + #endif // EIGEN_SOLVETRIANGULAR_H diff --git a/extern/Eigen3/Eigen/src/Core/StableNorm.h b/extern/Eigen3/Eigen/src/Core/StableNorm.h index f667272e4a4..d8bf7db70e4 100644 --- a/extern/Eigen3/Eigen/src/Core/StableNorm.h +++ b/extern/Eigen3/Eigen/src/Core/StableNorm.h @@ -3,28 +3,15 @@ // // Copyright (C) 2009 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_STABLENORM_H #define EIGEN_STABLENORM_H +namespace Eigen { + namespace internal { template inline void stable_norm_kernel(const ExpressionType& bl, Scalar& ssq, Scalar& scale, Scalar& invScale) @@ -58,9 +45,9 @@ MatrixBase::stableNorm() const { using std::min; const Index blockSize = 4096; - RealScalar scale = 0; - RealScalar invScale = 1; - RealScalar ssq = 0; // sum of square + RealScalar scale(0); + RealScalar invScale(1); + RealScalar ssq(0); // sum of square enum { Alignment = (int(Flags)&DirectAccessBit) || (int(Flags)&AlignedBit) ? 1 : 0 }; @@ -187,4 +174,6 @@ MatrixBase::hypotNorm() const return this->cwiseAbs().redux(internal::scalar_hypot_op()); } +} // end namespace Eigen + #endif // EIGEN_STABLENORM_H diff --git a/extern/Eigen3/Eigen/src/Core/Stride.h b/extern/Eigen3/Eigen/src/Core/Stride.h index 0430f111627..1e3f5fe9fff 100644 --- a/extern/Eigen3/Eigen/src/Core/Stride.h +++ b/extern/Eigen3/Eigen/src/Core/Stride.h @@ -3,28 +3,15 @@ // // Copyright (C) 2010 Benoit Jacob // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_STRIDE_H #define EIGEN_STRIDE_H +namespace Eigen { + /** \class Stride * \ingroup Core_Module * @@ -116,4 +103,6 @@ class OuterStride : public Stride OuterStride(Index v) : Base(v,0) {} }; +} // end namespace Eigen + #endif // EIGEN_STRIDE_H diff --git a/extern/Eigen3/Eigen/src/Core/Swap.h b/extern/Eigen3/Eigen/src/Core/Swap.h index 5fb03286675..fd73cf3ad7e 100644 --- a/extern/Eigen3/Eigen/src/Core/Swap.h +++ b/extern/Eigen3/Eigen/src/Core/Swap.h @@ -3,28 +3,15 @@ // // Copyright (C) 2006-2008 Benoit Jacob // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_SWAP_H #define EIGEN_SWAP_H +namespace Eigen { + /** \class SwapWrapper * \ingroup Core_Module * @@ -52,6 +39,15 @@ template class SwapWrapper inline Index cols() const { return m_expression.cols(); } inline Index outerStride() const { return m_expression.outerStride(); } inline Index innerStride() const { return m_expression.innerStride(); } + + typedef typename internal::conditional< + internal::is_lvalue::value, + Scalar, + const Scalar + >::type ScalarWithConstIfNotLvalue; + + inline ScalarWithConstIfNotLvalue* data() { return m_expression.data(); } + inline const Scalar* data() const { return m_expression.data(); } inline Scalar& coeffRef(Index row, Index col) { @@ -119,8 +115,12 @@ template class SwapWrapper _other.template writePacket(index, tmp); } + ExpressionType& expression() const { return m_expression; } + protected: ExpressionType& m_expression; }; +} // end namespace Eigen + #endif // EIGEN_SWAP_H diff --git a/extern/Eigen3/Eigen/src/Core/Transpose.h b/extern/Eigen3/Eigen/src/Core/Transpose.h index 3f7c7df6ee1..045a1cce671 100644 --- a/extern/Eigen3/Eigen/src/Core/Transpose.h +++ b/extern/Eigen3/Eigen/src/Core/Transpose.h @@ -4,28 +4,15 @@ // Copyright (C) 2006-2008 Benoit Jacob // Copyright (C) 2009-2010 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_TRANSPOSE_H #define EIGEN_TRANSPOSE_H +namespace Eigen { + /** \class Transpose * \ingroup Core_Module * @@ -91,7 +78,7 @@ template class Transpose nestedExpression() { return m_matrix.const_cast_derived(); } protected: - const typename MatrixType::Nested m_matrix; + typename MatrixType::Nested m_matrix; }; namespace internal { @@ -152,12 +139,12 @@ template class TransposeImpl return derived().nestedExpression().coeffRef(index); } - inline const CoeffReturnType coeff(Index row, Index col) const + inline CoeffReturnType coeff(Index row, Index col) const { return derived().nestedExpression().coeff(col, row); } - inline const CoeffReturnType coeff(Index index) const + inline CoeffReturnType coeff(Index index) const { return derived().nestedExpression().coeff(index); } @@ -422,4 +409,6 @@ void DenseBase::checkTransposeAliasing(const OtherDerived& other) const } #endif +} // end namespace Eigen + #endif // EIGEN_TRANSPOSE_H diff --git a/extern/Eigen3/Eigen/src/Core/Transpositions.h b/extern/Eigen3/Eigen/src/Core/Transpositions.h index 88fdfb2226f..2cd268a5fa0 100644 --- a/extern/Eigen3/Eigen/src/Core/Transpositions.h +++ b/extern/Eigen3/Eigen/src/Core/Transpositions.h @@ -3,28 +3,15 @@ // // Copyright (C) 2010-2011 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_TRANSPOSITIONS_H #define EIGEN_TRANSPOSITIONS_H +namespace Eigen { + /** \class Transpositions * \ingroup Core_Module * @@ -404,7 +391,7 @@ struct transposition_matrix_product_retval protected: const TranspositionType& m_transpositions; - const typename MatrixType::Nested m_matrix; + typename MatrixType::Nested m_matrix; }; } // end namespace internal @@ -444,4 +431,6 @@ class Transpose > const TranspositionType& m_transpositions; }; +} // end namespace Eigen + #endif // EIGEN_TRANSPOSITIONS_H diff --git a/extern/Eigen3/Eigen/src/Core/TriangularMatrix.h b/extern/Eigen3/Eigen/src/Core/TriangularMatrix.h index 033e81036f3..de9540063c2 100644 --- a/extern/Eigen3/Eigen/src/Core/TriangularMatrix.h +++ b/extern/Eigen3/Eigen/src/Core/TriangularMatrix.h @@ -4,28 +4,15 @@ // Copyright (C) 2008 Benoit Jacob // Copyright (C) 2008-2009 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_TRIANGULARMATRIX_H #define EIGEN_TRIANGULARMATRIX_H +namespace Eigen { + namespace internal { template struct triangular_solve_retval; @@ -273,11 +260,8 @@ template class TriangularView inline const TriangularView conjugate() const { return m_matrix.conjugate(); } - /** \sa MatrixBase::adjoint() */ - inline TriangularView adjoint() - { return m_matrix.adjoint(); } /** \sa MatrixBase::adjoint() const */ - inline const TriangularView adjoint() const + inline const TriangularView adjoint() const { return m_matrix.adjoint(); } /** \sa MatrixBase::transpose() */ @@ -288,11 +272,13 @@ template class TriangularView } /** \sa MatrixBase::transpose() const */ inline const TriangularView,TransposeMode> transpose() const - { return m_matrix.transpose(); } + { + return m_matrix.transpose(); + } /** Efficient triangular matrix times vector/matrix product */ template - TriangularProduct + TriangularProduct operator*(const MatrixBase& rhs) const { return TriangularProduct @@ -375,7 +361,8 @@ template class TriangularView template void swap(MatrixBase const & other) { - TriangularView,Mode>(const_cast(m_matrix)).lazyAssign(other.derived()); + SwapWrapper swaper(const_cast(m_matrix)); + TriangularView,Mode>(swaper).lazyAssign(other.derived()); } Scalar determinant() const @@ -433,7 +420,7 @@ template class TriangularView template EIGEN_STRONG_INLINE TriangularView& assignProduct(const ProductBase& prod, const Scalar& alpha); - const MatrixTypeNested m_matrix; + MatrixTypeNested m_matrix; }; /*************************************************************************** @@ -452,7 +439,7 @@ struct triangular_assignment_selector typedef typename Derived1::Scalar Scalar; - inline static void run(Derived1 &dst, const Derived2 &src) + static inline void run(Derived1 &dst, const Derived2 &src) { triangular_assignment_selector::run(dst, src); @@ -480,7 +467,7 @@ struct triangular_assignment_selector template struct triangular_assignment_selector { - inline static void run(Derived1 &, const Derived2 &) {} + static inline void run(Derived1 &, const Derived2 &) {} }; template @@ -488,7 +475,7 @@ struct triangular_assignment_selector struct triangular_assignment_selector { typedef typename Derived1::Index Index; - inline static void run(Derived1 &dst, const Derived2 &src) + static inline void run(Derived1 &dst, const Derived2 &src) { for(Index j = 0; j < dst.cols(); ++j) { @@ -524,7 +511,7 @@ template struct triangular_assignment_selector { typedef typename Derived1::Index Index; - inline static void run(Derived1 &dst, const Derived2 &src) + static inline void run(Derived1 &dst, const Derived2 &src) { for(Index j = 0; j < dst.cols(); ++j) { @@ -542,7 +529,7 @@ template struct triangular_assignment_selector { typedef typename Derived1::Index Index; - inline static void run(Derived1 &dst, const Derived2 &src) + static inline void run(Derived1 &dst, const Derived2 &src) { for(Index j = 0; j < dst.cols(); ++j) { @@ -560,7 +547,7 @@ template struct triangular_assignment_selector { typedef typename Derived1::Index Index; - inline static void run(Derived1 &dst, const Derived2 &src) + static inline void run(Derived1 &dst, const Derived2 &src) { for(Index j = 0; j < dst.cols(); ++j) { @@ -580,7 +567,7 @@ template struct triangular_assignment_selector { typedef typename Derived1::Index Index; - inline static void run(Derived1 &dst, const Derived2 &src) + static inline void run(Derived1 &dst, const Derived2 &src) { for(Index j = 0; j < dst.cols(); ++j) { @@ -835,4 +822,6 @@ bool MatrixBase::isLowerTriangular(RealScalar prec) const return true; } +} // end namespace Eigen + #endif // EIGEN_TRIANGULARMATRIX_H diff --git a/extern/Eigen3/Eigen/src/Core/VectorBlock.h b/extern/Eigen3/Eigen/src/Core/VectorBlock.h index 858e4c7865a..6f4effca055 100644 --- a/extern/Eigen3/Eigen/src/Core/VectorBlock.h +++ b/extern/Eigen3/Eigen/src/Core/VectorBlock.h @@ -4,28 +4,15 @@ // Copyright (C) 2008-2010 Gael Guennebaud // Copyright (C) 2006-2008 Benoit Jacob // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_VECTORBLOCK_H #define EIGEN_VECTORBLOCK_H +namespace Eigen { + /** \class VectorBlock * \ingroup Core_Module * @@ -292,5 +279,6 @@ DenseBase::tail() const return typename ConstFixedSegmentReturnType::Type(derived(), size() - Size); } +} // end namespace Eigen #endif // EIGEN_VECTORBLOCK_H diff --git a/extern/Eigen3/Eigen/src/Core/VectorwiseOp.h b/extern/Eigen3/Eigen/src/Core/VectorwiseOp.h index 20f6881575b..862c0f33608 100644 --- a/extern/Eigen3/Eigen/src/Core/VectorwiseOp.h +++ b/extern/Eigen3/Eigen/src/Core/VectorwiseOp.h @@ -4,28 +4,15 @@ // Copyright (C) 2008-2010 Gael Guennebaud // Copyright (C) 2006-2008 Benoit Jacob // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_PARTIAL_REDUX_H #define EIGEN_PARTIAL_REDUX_H +namespace Eigen { + /** \class PartialReduxExpr * \ingroup Core_Module * @@ -110,7 +97,7 @@ class PartialReduxExpr : internal::no_assignment_operator, } protected: - const MatrixTypeNested m_matrix; + MatrixTypeNested m_matrix; const MemberOp m_functor; }; @@ -237,7 +224,10 @@ template class VectorwiseOp typename ExtendedType::Type extendedTo(const DenseBase& other) const { - EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived); + EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(Direction==Vertical, OtherDerived::MaxColsAtCompileTime==1), + YOU_PASSED_A_ROW_VECTOR_BUT_A_COLUMN_VECTOR_WAS_EXPECTED) + EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(Direction==Horizontal, OtherDerived::MaxRowsAtCompileTime==1), + YOU_PASSED_A_COLUMN_VECTOR_BUT_A_ROW_VECTOR_WAS_EXPECTED) return typename ExtendedType::Type (other.derived(), Direction==Vertical ? 1 : m_matrix.rows(), @@ -418,10 +408,9 @@ template class VectorwiseOp ExpressionType& operator=(const DenseBase& other) { EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived) + EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived) //eigen_assert((m_matrix.isNull()) == (other.isNull())); FIXME - for(Index j=0; j(m_matrix); + return const_cast(m_matrix = extendedTo(other.derived())); } /** Adds the vector \a other to each subvector of \c *this */ @@ -429,9 +418,8 @@ template class VectorwiseOp ExpressionType& operator+=(const DenseBase& other) { EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived) - for(Index j=0; j(m_matrix); + EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived) + return const_cast(m_matrix += extendedTo(other.derived())); } /** Substracts the vector \a other to each subvector of \c *this */ @@ -439,8 +427,29 @@ template class VectorwiseOp ExpressionType& operator-=(const DenseBase& other) { EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived) - for(Index j=0; j(m_matrix -= extendedTo(other.derived())); + } + + /** Multiples each subvector of \c *this by the vector \a other */ + template + ExpressionType& operator*=(const DenseBase& other) + { + EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived) + EIGEN_STATIC_ASSERT_ARRAYXPR(ExpressionType) + EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived) + m_matrix *= extendedTo(other.derived()); + return const_cast(m_matrix); + } + + /** Divides each subvector of \c *this by the vector \a other */ + template + ExpressionType& operator/=(const DenseBase& other) + { + EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived) + EIGEN_STATIC_ASSERT_ARRAYXPR(ExpressionType) + EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived) + m_matrix /= extendedTo(other.derived()); return const_cast(m_matrix); } @@ -451,7 +460,8 @@ template class VectorwiseOp const typename ExtendedType::Type> operator+(const DenseBase& other) const { - EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived); + EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived) + EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived) return m_matrix + extendedTo(other.derived()); } @@ -462,10 +472,39 @@ template class VectorwiseOp const typename ExtendedType::Type> operator-(const DenseBase& other) const { - EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived); + EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived) + EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived) return m_matrix - extendedTo(other.derived()); } + /** Returns the expression where each subvector is the product of the vector \a other + * by the corresponding subvector of \c *this */ + template EIGEN_STRONG_INLINE + CwiseBinaryOp, + const ExpressionTypeNestedCleaned, + const typename ExtendedType::Type> + operator*(const DenseBase& other) const + { + EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived) + EIGEN_STATIC_ASSERT_ARRAYXPR(ExpressionType) + EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived) + return m_matrix * extendedTo(other.derived()); + } + + /** Returns the expression where each subvector is the quotient of the corresponding + * subvector of \c *this by the vector \a other */ + template + CwiseBinaryOp, + const ExpressionTypeNestedCleaned, + const typename ExtendedType::Type> + operator/(const DenseBase& other) const + { + EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived) + EIGEN_STATIC_ASSERT_ARRAYXPR(ExpressionType) + EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived) + return m_matrix / extendedTo(other.derived()); + } + /////////// Geometry module /////////// #if EIGEN2_SUPPORT_STAGE > STAGE20_RESOLVE_API_CONFLICTS @@ -509,7 +548,7 @@ template class VectorwiseOp * Example: \include MatrixBase_colwise.cpp * Output: \verbinclude MatrixBase_colwise.out * - * \sa rowwise(), class VectorwiseOp + * \sa rowwise(), class VectorwiseOp, \ref TutorialReductionsVisitorsBroadcasting */ template inline const typename DenseBase::ConstColwiseReturnType @@ -520,7 +559,7 @@ DenseBase::colwise() const /** \returns a writable VectorwiseOp wrapper of *this providing additional partial reduction operations * - * \sa rowwise(), class VectorwiseOp + * \sa rowwise(), class VectorwiseOp, \ref TutorialReductionsVisitorsBroadcasting */ template inline typename DenseBase::ColwiseReturnType @@ -534,7 +573,7 @@ DenseBase::colwise() * Example: \include MatrixBase_rowwise.cpp * Output: \verbinclude MatrixBase_rowwise.out * - * \sa colwise(), class VectorwiseOp + * \sa colwise(), class VectorwiseOp, \ref TutorialReductionsVisitorsBroadcasting */ template inline const typename DenseBase::ConstRowwiseReturnType @@ -545,7 +584,7 @@ DenseBase::rowwise() const /** \returns a writable VectorwiseOp wrapper of *this providing additional partial reduction operations * - * \sa colwise(), class VectorwiseOp + * \sa colwise(), class VectorwiseOp, \ref TutorialReductionsVisitorsBroadcasting */ template inline typename DenseBase::RowwiseReturnType @@ -554,4 +593,6 @@ DenseBase::rowwise() return derived(); } +} // end namespace Eigen + #endif // EIGEN_PARTIAL_REDUX_H diff --git a/extern/Eigen3/Eigen/src/Core/Visitor.h b/extern/Eigen3/Eigen/src/Core/Visitor.h index 378ebcba174..916bfd096a9 100644 --- a/extern/Eigen3/Eigen/src/Core/Visitor.h +++ b/extern/Eigen3/Eigen/src/Core/Visitor.h @@ -3,28 +3,15 @@ // // Copyright (C) 2008 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_VISITOR_H #define EIGEN_VISITOR_H +namespace Eigen { + namespace internal { template @@ -35,7 +22,7 @@ struct visitor_impl row = (UnrollCount-1) % Derived::RowsAtCompileTime }; - inline static void run(const Derived &mat, Visitor& visitor) + static inline void run(const Derived &mat, Visitor& visitor) { visitor_impl::run(mat, visitor); visitor(mat.coeff(row, col), row, col); @@ -45,7 +32,7 @@ struct visitor_impl template struct visitor_impl { - inline static void run(const Derived &mat, Visitor& visitor) + static inline void run(const Derived &mat, Visitor& visitor) { return visitor.init(mat.coeff(0, 0), 0, 0); } @@ -55,7 +42,7 @@ template struct visitor_impl { typedef typename Derived::Index Index; - inline static void run(const Derived& mat, Visitor& visitor) + static inline void run(const Derived& mat, Visitor& visitor) { visitor.init(mat.coeff(0,0), 0, 0); for(Index i = 1; i < mat.rows(); ++i) @@ -245,4 +232,6 @@ DenseBase::maxCoeff(IndexType* index) const return maxVisitor.res; } +} // end namespace Eigen + #endif // EIGEN_VISITOR_H diff --git a/extern/Eigen3/Eigen/src/Core/arch/AltiVec/Complex.h b/extern/Eigen3/Eigen/src/Core/arch/AltiVec/Complex.h index f8adf1b6385..68d9a2bff8d 100644 --- a/extern/Eigen3/Eigen/src/Core/arch/AltiVec/Complex.h +++ b/extern/Eigen3/Eigen/src/Core/arch/AltiVec/Complex.h @@ -3,28 +3,15 @@ // // Copyright (C) 2010 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_COMPLEX_ALTIVEC_H #define EIGEN_COMPLEX_ALTIVEC_H +namespace Eigen { + namespace internal { static Packet4ui p4ui_CONJ_XOR = vec_mergeh((Packet4ui)p4i_ZERO, (Packet4ui)p4f_ZERO_);//{ 0x00000000, 0x80000000, 0x00000000, 0x80000000 }; @@ -168,7 +155,7 @@ template<> EIGEN_STRONG_INLINE std::complex predux_mul(const P template struct palign_impl { - EIGEN_STRONG_INLINE static void run(Packet2cf& first, const Packet2cf& second) + static EIGEN_STRONG_INLINE void run(Packet2cf& first, const Packet2cf& second) { if (Offset==1) { @@ -225,4 +212,6 @@ template<> EIGEN_STRONG_INLINE Packet2cf pcplxflip(const Packet2cf& x } // end namespace internal +} // end namespace Eigen + #endif // EIGEN_COMPLEX_ALTIVEC_H diff --git a/extern/Eigen3/Eigen/src/Core/arch/AltiVec/PacketMath.h b/extern/Eigen3/Eigen/src/Core/arch/AltiVec/PacketMath.h index dc34ebbd660..75de1931198 100644 --- a/extern/Eigen3/Eigen/src/Core/arch/AltiVec/PacketMath.h +++ b/extern/Eigen3/Eigen/src/Core/arch/AltiVec/PacketMath.h @@ -3,28 +3,15 @@ // // Copyright (C) 2008 Konstantinos Margaritis // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_PACKET_MATH_ALTIVEC_H #define EIGEN_PACKET_MATH_ALTIVEC_H +namespace Eigen { + namespace internal { #ifndef EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD @@ -487,7 +474,7 @@ template<> EIGEN_STRONG_INLINE int predux_max(const Packet4i& a) template struct palign_impl { - EIGEN_STRONG_INLINE static void run(Packet4f& first, const Packet4f& second) + static EIGEN_STRONG_INLINE void run(Packet4f& first, const Packet4f& second) { if (Offset!=0) first = vec_sld(first, second, Offset*4); @@ -497,7 +484,7 @@ struct palign_impl template struct palign_impl { - EIGEN_STRONG_INLINE static void run(Packet4i& first, const Packet4i& second) + static EIGEN_STRONG_INLINE void run(Packet4i& first, const Packet4i& second) { if (Offset!=0) first = vec_sld(first, second, Offset*4); @@ -506,4 +493,6 @@ struct palign_impl } // end namespace internal +} // end namespace Eigen + #endif // EIGEN_PACKET_MATH_ALTIVEC_H diff --git a/extern/Eigen3/Eigen/src/Core/arch/Default/Settings.h b/extern/Eigen3/Eigen/src/Core/arch/Default/Settings.h index 957adc8fe42..097373c84dc 100644 --- a/extern/Eigen3/Eigen/src/Core/arch/Default/Settings.h +++ b/extern/Eigen3/Eigen/src/Core/arch/Default/Settings.h @@ -4,24 +4,9 @@ // Copyright (C) 2008-2010 Gael Guennebaud // Copyright (C) 2006-2008 Benoit Jacob // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. /* All the parameters defined in this file can be specialized in the diff --git a/extern/Eigen3/Eigen/src/Core/arch/NEON/Complex.h b/extern/Eigen3/Eigen/src/Core/arch/NEON/Complex.h index 212887184c2..795b4be7303 100644 --- a/extern/Eigen3/Eigen/src/Core/arch/NEON/Complex.h +++ b/extern/Eigen3/Eigen/src/Core/arch/NEON/Complex.h @@ -3,28 +3,15 @@ // // Copyright (C) 2010 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_COMPLEX_NEON_H #define EIGEN_COMPLEX_NEON_H +namespace Eigen { + namespace internal { static uint32x4_t p4ui_CONJ_XOR = EIGEN_INIT_NEON_PACKET4(0x00000000, 0x80000000, 0x00000000, 0x80000000); @@ -267,4 +254,6 @@ template<> EIGEN_STRONG_INLINE Packet2cf pdiv(const Packet2cf& a, con } // end namespace internal +} // end namespace Eigen + #endif // EIGEN_COMPLEX_NEON_H diff --git a/extern/Eigen3/Eigen/src/Core/arch/NEON/PacketMath.h b/extern/Eigen3/Eigen/src/Core/arch/NEON/PacketMath.h index 6c7cd159097..a20250f7c65 100644 --- a/extern/Eigen3/Eigen/src/Core/arch/NEON/PacketMath.h +++ b/extern/Eigen3/Eigen/src/Core/arch/NEON/PacketMath.h @@ -5,28 +5,15 @@ // Copyright (C) 2010 Konstantinos Margaritis // Heavily based on Gael's SSE version. // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_PACKET_MATH_NEON_H #define EIGEN_PACKET_MATH_NEON_H +namespace Eigen { + namespace internal { #ifndef EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD @@ -158,7 +145,8 @@ template<> EIGEN_STRONG_INLINE Packet4i pdiv(const Packet4i& /*a*/, co } // for some weird raisons, it has to be overloaded for packet of integers -template<> EIGEN_STRONG_INLINE Packet4i pmadd(const Packet4i& a, const Packet4i& b, const Packet4i& c) { return padd(pmul(a,b), c); } +template<> EIGEN_STRONG_INLINE Packet4f pmadd(const Packet4f& a, const Packet4f& b, const Packet4f& c) { return vmlaq_f32(c,a,b); } +template<> EIGEN_STRONG_INLINE Packet4i pmadd(const Packet4i& a, const Packet4i& b, const Packet4i& c) { return vmlaq_s32(c,a,b); } template<> EIGEN_STRONG_INLINE Packet4f pmin(const Packet4f& a, const Packet4f& b) { return vminq_f32(a,b); } template<> EIGEN_STRONG_INLINE Packet4i pmin(const Packet4i& a, const Packet4i& b) { return vminq_s32(a,b); } @@ -431,4 +419,6 @@ PALIGN_NEON(3,Packet4i,vextq_s32) } // end namespace internal +} // end namespace Eigen + #endif // EIGEN_PACKET_MATH_NEON_H diff --git a/extern/Eigen3/Eigen/src/Core/arch/SSE/Complex.h b/extern/Eigen3/Eigen/src/Core/arch/SSE/Complex.h index c352bb3e6cf..12df987754c 100644 --- a/extern/Eigen3/Eigen/src/Core/arch/SSE/Complex.h +++ b/extern/Eigen3/Eigen/src/Core/arch/SSE/Complex.h @@ -3,28 +3,15 @@ // // Copyright (C) 2010 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_COMPLEX_SSE_H #define EIGEN_COMPLEX_SSE_H +namespace Eigen { + namespace internal { //---------- float ---------- @@ -102,7 +89,7 @@ template<> EIGEN_STRONG_INLINE Packet2cf pset1(const std::complex(&from)); #else res.v = _mm_loadl_pi(res.v, (const __m64*)&from); #endif @@ -151,7 +138,7 @@ template<> EIGEN_STRONG_INLINE std::complex predux_mul(const P template struct palign_impl { - EIGEN_STRONG_INLINE static void run(Packet2cf& first, const Packet2cf& second) + static EIGEN_STRONG_INLINE void run(Packet2cf& first, const Packet2cf& second) { if (Offset==1) { @@ -350,7 +337,7 @@ template<> EIGEN_STRONG_INLINE std::complex predux_mul(const template struct palign_impl { - EIGEN_STRONG_INLINE static void run(Packet1cd& /*first*/, const Packet1cd& /*second*/) + static EIGEN_STRONG_INLINE void run(Packet1cd& /*first*/, const Packet1cd& /*second*/) { // FIXME is it sure we never have to align a Packet1cd? // Even though a std::complex has 16 bytes, it is not necessarily aligned on a 16 bytes boundary... @@ -444,4 +431,6 @@ EIGEN_STRONG_INLINE Packet1cd pcplxflip/**/(const Packet1cd& x) } // end namespace internal +} // end namespace Eigen + #endif // EIGEN_COMPLEX_SSE_H diff --git a/extern/Eigen3/Eigen/src/Core/arch/SSE/MathFunctions.h b/extern/Eigen3/Eigen/src/Core/arch/SSE/MathFunctions.h index 9d56d82180b..3f41a4e2600 100644 --- a/extern/Eigen3/Eigen/src/Core/arch/SSE/MathFunctions.h +++ b/extern/Eigen3/Eigen/src/Core/arch/SSE/MathFunctions.h @@ -4,24 +4,9 @@ // Copyright (C) 2007 Julien Pommier // Copyright (C) 2009 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. /* The sin, cos, exp, and log functions of this file come from * Julien Pommier's sse math library: http://gruntthepeon.free.fr/ssemath/ @@ -30,6 +15,8 @@ #ifndef EIGEN_MATH_FUNCTIONS_SSE_H #define EIGEN_MATH_FUNCTIONS_SSE_H +namespace Eigen { + namespace internal { template<> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED @@ -121,7 +108,7 @@ Packet4f pexp(const Packet4f& _x) _EIGEN_DECLARE_CONST_Packet4i(0x7f, 0x7f); - _EIGEN_DECLARE_CONST_Packet4f(exp_hi, 88.3762626647949f); + _EIGEN_DECLARE_CONST_Packet4f(exp_hi, 88.3762626647950f); _EIGEN_DECLARE_CONST_Packet4f(exp_lo, -88.3762626647949f); _EIGEN_DECLARE_CONST_Packet4f(cephes_LOG2EF, 1.44269504088896341f); @@ -168,7 +155,7 @@ Packet4f pexp(const Packet4f& _x) y = pmadd(y, z, x); y = padd(y, p4f_1); - /* build 2^n */ + // build 2^n emm0 = _mm_cvttps_epi32(fx); emm0 = _mm_add_epi32(emm0, p4i_0x7f); emm0 = _mm_slli_epi32(emm0, 23); @@ -392,4 +379,6 @@ Packet4f psqrt(const Packet4f& _x) } // end namespace internal +} // end namespace Eigen + #endif // EIGEN_MATH_FUNCTIONS_SSE_H diff --git a/extern/Eigen3/Eigen/src/Core/arch/SSE/PacketMath.h b/extern/Eigen3/Eigen/src/Core/arch/SSE/PacketMath.h index 908e27368e8..10d9182190f 100644 --- a/extern/Eigen3/Eigen/src/Core/arch/SSE/PacketMath.h +++ b/extern/Eigen3/Eigen/src/Core/arch/SSE/PacketMath.h @@ -3,28 +3,15 @@ // // Copyright (C) 2008-2009 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_PACKET_MATH_SSE_H #define EIGEN_PACKET_MATH_SSE_H +namespace Eigen { + namespace internal { #ifndef EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD @@ -110,9 +97,18 @@ template<> struct unpacket_traits { typedef float type; enum {size=4} template<> struct unpacket_traits { typedef double type; enum {size=2}; }; template<> struct unpacket_traits { typedef int type; enum {size=4}; }; +#if defined(_MSC_VER) && (_MSC_VER==1500) +// Workaround MSVC 9 internal compiler error. +// TODO: It has been detected with win64 builds (amd64), so let's check whether it also happens in 32bits+SSE mode +// TODO: let's check whether there does not exist a better fix, like adding a pset0() function. (it crashed on pset1(0)). +template<> EIGEN_STRONG_INLINE Packet4f pset1(const float& from) { return _mm_set_ps(from,from,from,from); } +template<> EIGEN_STRONG_INLINE Packet2d pset1(const double& from) { return _mm_set_pd(from,from); } +template<> EIGEN_STRONG_INLINE Packet4i pset1(const int& from) { return _mm_set_epi32(from,from,from,from); } +#else template<> EIGEN_STRONG_INLINE Packet4f pset1(const float& from) { return _mm_set1_ps(from); } template<> EIGEN_STRONG_INLINE Packet2d pset1(const double& from) { return _mm_set1_pd(from); } template<> EIGEN_STRONG_INLINE Packet4i pset1(const int& from) { return _mm_set1_epi32(from); } +#endif template<> EIGEN_STRONG_INLINE Packet4f plset(const float& a) { return _mm_add_ps(pset1(a), _mm_set_ps(3,2,1,0)); } template<> EIGEN_STRONG_INLINE Packet2d plset(const double& a) { return _mm_add_pd(pset1(a),_mm_set_pd(1,0)); } @@ -282,7 +278,7 @@ template<> EIGEN_STRONG_INLINE Packet4i ploadu(const int* from) template<> EIGEN_STRONG_INLINE Packet4f ploaddup(const float* from) { - return vec4f_swizzle1(_mm_castpd_ps(_mm_load_sd((const double*)from)), 0, 0, 1, 1); + return vec4f_swizzle1(_mm_castpd_ps(_mm_load_sd(reinterpret_cast(from))), 0, 0, 1, 1); } template<> EIGEN_STRONG_INLINE Packet2d ploaddup(const double* from) { return pset1(from[0]); } @@ -302,8 +298,8 @@ template<> EIGEN_STRONG_INLINE void pstoreu(double* to, const Packet2d& _mm_storel_pd((to), from); _mm_storeh_pd((to+1), from); } -template<> EIGEN_STRONG_INLINE void pstoreu(float* to, const Packet4f& from) { EIGEN_DEBUG_UNALIGNED_STORE pstoreu((double*)to, _mm_castps_pd(from)); } -template<> EIGEN_STRONG_INLINE void pstoreu(int* to, const Packet4i& from) { EIGEN_DEBUG_UNALIGNED_STORE pstoreu((double*)to, _mm_castsi128_pd(from)); } +template<> EIGEN_STRONG_INLINE void pstoreu(float* to, const Packet4f& from) { EIGEN_DEBUG_UNALIGNED_STORE pstoreu(reinterpret_cast(to), _mm_castps_pd(from)); } +template<> EIGEN_STRONG_INLINE void pstoreu(int* to, const Packet4i& from) { EIGEN_DEBUG_UNALIGNED_STORE pstoreu(reinterpret_cast(to), _mm_castsi128_pd(from)); } // some compilers might be tempted to perform multiple moves instead of using a vector path. template<> EIGEN_STRONG_INLINE void pstore1(float* to, const float& a) @@ -541,7 +537,7 @@ template<> EIGEN_STRONG_INLINE int predux_max(const Packet4i& a) template struct palign_impl { - EIGEN_STRONG_INLINE static void run(Packet4f& first, const Packet4f& second) + static EIGEN_STRONG_INLINE void run(Packet4f& first, const Packet4f& second) { if (Offset!=0) first = _mm_castsi128_ps(_mm_alignr_epi8(_mm_castps_si128(second), _mm_castps_si128(first), Offset*4)); @@ -551,7 +547,7 @@ struct palign_impl template struct palign_impl { - EIGEN_STRONG_INLINE static void run(Packet4i& first, const Packet4i& second) + static EIGEN_STRONG_INLINE void run(Packet4i& first, const Packet4i& second) { if (Offset!=0) first = _mm_alignr_epi8(second,first, Offset*4); @@ -561,7 +557,7 @@ struct palign_impl template struct palign_impl { - EIGEN_STRONG_INLINE static void run(Packet2d& first, const Packet2d& second) + static EIGEN_STRONG_INLINE void run(Packet2d& first, const Packet2d& second) { if (Offset==1) first = _mm_castsi128_pd(_mm_alignr_epi8(_mm_castpd_si128(second), _mm_castpd_si128(first), 8)); @@ -572,7 +568,7 @@ struct palign_impl template struct palign_impl { - EIGEN_STRONG_INLINE static void run(Packet4f& first, const Packet4f& second) + static EIGEN_STRONG_INLINE void run(Packet4f& first, const Packet4f& second) { if (Offset==1) { @@ -595,7 +591,7 @@ struct palign_impl template struct palign_impl { - EIGEN_STRONG_INLINE static void run(Packet4i& first, const Packet4i& second) + static EIGEN_STRONG_INLINE void run(Packet4i& first, const Packet4i& second) { if (Offset==1) { @@ -618,7 +614,7 @@ struct palign_impl template struct palign_impl { - EIGEN_STRONG_INLINE static void run(Packet2d& first, const Packet2d& second) + static EIGEN_STRONG_INLINE void run(Packet2d& first, const Packet2d& second) { if (Offset==1) { @@ -631,4 +627,6 @@ struct palign_impl } // end namespace internal +} // end namespace Eigen + #endif // EIGEN_PACKET_MATH_SSE_H diff --git a/extern/Eigen3/Eigen/src/Core/products/CoeffBasedProduct.h b/extern/Eigen3/Eigen/src/Core/products/CoeffBasedProduct.h index dc20f7e1e29..403d25fa9eb 100644 --- a/extern/Eigen3/Eigen/src/Core/products/CoeffBasedProduct.h +++ b/extern/Eigen3/Eigen/src/Core/products/CoeffBasedProduct.h @@ -4,28 +4,15 @@ // Copyright (C) 2006-2008 Benoit Jacob // Copyright (C) 2008-2010 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_COEFFBASED_PRODUCT_H #define EIGEN_COEFFBASED_PRODUCT_H +namespace Eigen { + namespace internal { /********************************************************************************* @@ -224,8 +211,8 @@ class CoeffBasedProduct { return reinterpret_cast(*this).diagonal(index); } protected: - const LhsNested m_lhs; - const RhsNested m_rhs; + typename internal::add_const_on_value_type::type m_lhs; + typename internal::add_const_on_value_type::type m_rhs; mutable PlainObject m_result; }; @@ -252,7 +239,7 @@ template struct product_coeff_impl { typedef typename Lhs::Index Index; - EIGEN_STRONG_INLINE static void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, RetScalar &res) + static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, RetScalar &res) { product_coeff_impl::run(row, col, lhs, rhs, res); res += lhs.coeff(row, UnrollingIndex) * rhs.coeff(UnrollingIndex, col); @@ -263,7 +250,7 @@ template struct product_coeff_impl { typedef typename Lhs::Index Index; - EIGEN_STRONG_INLINE static void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, RetScalar &res) + static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, RetScalar &res) { res = lhs.coeff(row, 0) * rhs.coeff(0, col); } @@ -273,7 +260,7 @@ template struct product_coeff_impl { typedef typename Lhs::Index Index; - EIGEN_STRONG_INLINE static void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, RetScalar& res) + static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, RetScalar& res) { eigen_assert(lhs.cols()>0 && "you are using a non initialized matrix"); res = lhs.coeff(row, 0) * rhs.coeff(0, col); @@ -291,7 +278,7 @@ struct product_coeff_vectorized_unroller { typedef typename Lhs::Index Index; enum { PacketSize = packet_traits::size }; - EIGEN_STRONG_INLINE static void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, typename Lhs::PacketScalar &pres) + static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, typename Lhs::PacketScalar &pres) { product_coeff_vectorized_unroller::run(row, col, lhs, rhs, pres); pres = padd(pres, pmul( lhs.template packet(row, UnrollingIndex) , rhs.template packet(UnrollingIndex, col) )); @@ -302,7 +289,7 @@ template struct product_coeff_vectorized_unroller<0, Lhs, Rhs, Packet> { typedef typename Lhs::Index Index; - EIGEN_STRONG_INLINE static void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, typename Lhs::PacketScalar &pres) + static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, typename Lhs::PacketScalar &pres) { pres = pmul(lhs.template packet(row, 0) , rhs.template packet(0, col)); } @@ -314,7 +301,7 @@ struct product_coeff_impl::size }; - EIGEN_STRONG_INLINE static void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, RetScalar &res) + static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, RetScalar &res) { Packet pres; product_coeff_vectorized_unroller::run(row, col, lhs, rhs, pres); @@ -327,7 +314,7 @@ template struct product_coeff_vectorized_dyn_selector { typedef typename Lhs::Index Index; - EIGEN_STRONG_INLINE static void run(Index /*row*/, Index col, const Lhs& lhs, const Rhs& rhs, typename Lhs::Scalar &res) + static EIGEN_STRONG_INLINE void run(Index /*row*/, Index col, const Lhs& lhs, const Rhs& rhs, typename Lhs::Scalar &res) { res = lhs.transpose().cwiseProduct(rhs.col(col)).sum(); } @@ -349,7 +336,7 @@ template struct product_coeff_vectorized_dyn_selector { typedef typename Lhs::Index Index; - EIGEN_STRONG_INLINE static void run(Index row, Index /*col*/, const Lhs& lhs, const Rhs& rhs, typename Lhs::Scalar &res) + static EIGEN_STRONG_INLINE void run(Index row, Index /*col*/, const Lhs& lhs, const Rhs& rhs, typename Lhs::Scalar &res) { res = lhs.row(row).transpose().cwiseProduct(rhs).sum(); } @@ -359,7 +346,7 @@ template struct product_coeff_vectorized_dyn_selector { typedef typename Lhs::Index Index; - EIGEN_STRONG_INLINE static void run(Index /*row*/, Index /*col*/, const Lhs& lhs, const Rhs& rhs, typename Lhs::Scalar &res) + static EIGEN_STRONG_INLINE void run(Index /*row*/, Index /*col*/, const Lhs& lhs, const Rhs& rhs, typename Lhs::Scalar &res) { res = lhs.transpose().cwiseProduct(rhs).sum(); } @@ -369,7 +356,7 @@ template struct product_coeff_impl { typedef typename Lhs::Index Index; - EIGEN_STRONG_INLINE static void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, typename Lhs::Scalar &res) + static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, typename Lhs::Scalar &res) { product_coeff_vectorized_dyn_selector::run(row, col, lhs, rhs, res); } @@ -383,7 +370,7 @@ template { typedef typename Lhs::Index Index; - EIGEN_STRONG_INLINE static void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Packet &res) + static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Packet &res) { product_packet_impl::run(row, col, lhs, rhs, res); res = pmadd(pset1(lhs.coeff(row, UnrollingIndex)), rhs.template packet(UnrollingIndex, col), res); @@ -394,7 +381,7 @@ template { typedef typename Lhs::Index Index; - EIGEN_STRONG_INLINE static void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Packet &res) + static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Packet &res) { product_packet_impl::run(row, col, lhs, rhs, res); res = pmadd(lhs.template packet(row, UnrollingIndex), pset1(rhs.coeff(UnrollingIndex, col)), res); @@ -405,7 +392,7 @@ template struct product_packet_impl { typedef typename Lhs::Index Index; - EIGEN_STRONG_INLINE static void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Packet &res) + static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Packet &res) { res = pmul(pset1(lhs.coeff(row, 0)),rhs.template packet(0, col)); } @@ -415,7 +402,7 @@ template struct product_packet_impl { typedef typename Lhs::Index Index; - EIGEN_STRONG_INLINE static void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Packet &res) + static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Packet &res) { res = pmul(lhs.template packet(row, 0), pset1(rhs.coeff(0, col))); } @@ -425,7 +412,7 @@ template struct product_packet_impl { typedef typename Lhs::Index Index; - EIGEN_STRONG_INLINE static void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Packet& res) + static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Packet& res) { eigen_assert(lhs.cols()>0 && "you are using a non initialized matrix"); res = pmul(pset1(lhs.coeff(row, 0)),rhs.template packet(0, col)); @@ -438,7 +425,7 @@ template struct product_packet_impl { typedef typename Lhs::Index Index; - EIGEN_STRONG_INLINE static void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Packet& res) + static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Packet& res) { eigen_assert(lhs.cols()>0 && "you are using a non initialized matrix"); res = pmul(lhs.template packet(row, 0), pset1(rhs.coeff(0, col))); @@ -449,4 +436,6 @@ struct product_packet_impl } // end namespace internal +} // end namespace Eigen + #endif // EIGEN_COEFFBASED_PRODUCT_H diff --git a/extern/Eigen3/Eigen/src/Core/products/GeneralBlockPanelKernel.h b/extern/Eigen3/Eigen/src/Core/products/GeneralBlockPanelKernel.h index cd1c37c780e..5eb03c98ccf 100644 --- a/extern/Eigen3/Eigen/src/Core/products/GeneralBlockPanelKernel.h +++ b/extern/Eigen3/Eigen/src/Core/products/GeneralBlockPanelKernel.h @@ -3,34 +3,23 @@ // // Copyright (C) 2008-2009 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_GENERAL_BLOCK_PANEL_H #define EIGEN_GENERAL_BLOCK_PANEL_H +namespace Eigen { + namespace internal { template class gebp_traits; -inline std::ptrdiff_t manage_caching_sizes_second_if_negative(std::ptrdiff_t a, std::ptrdiff_t b) + +/** \internal \returns b if a<=0, and returns a otherwise. */ +inline std::ptrdiff_t manage_caching_sizes_helper(std::ptrdiff_t a, std::ptrdiff_t b) { return a<=0 ? b : a; } @@ -38,9 +27,14 @@ inline std::ptrdiff_t manage_caching_sizes_second_if_negative(std::ptrdiff_t a, /** \internal */ inline void manage_caching_sizes(Action action, std::ptrdiff_t* l1=0, std::ptrdiff_t* l2=0) { - static std::ptrdiff_t m_l1CacheSize = manage_caching_sizes_second_if_negative(queryL1CacheSize(),8 * 1024); - static std::ptrdiff_t m_l2CacheSize = manage_caching_sizes_second_if_negative(queryTopLevelCacheSize(),1*1024*1024); - + static std::ptrdiff_t m_l1CacheSize = 0; + static std::ptrdiff_t m_l2CacheSize = 0; + if(m_l2CacheSize==0) + { + m_l1CacheSize = manage_caching_sizes_helper(queryL1CacheSize(),8 * 1024); + m_l2CacheSize = manage_caching_sizes_helper(queryTopLevelCacheSize(),1*1024*1024); + } + if(action==SetAction) { // set the cpu cache size and cache all block sizes from a global cache size in byte @@ -533,7 +527,7 @@ struct gebp_kernel ResPacketSize = Traits::ResPacketSize }; - EIGEN_FLATTEN_ATTRIB + EIGEN_DONT_INLINE EIGEN_FLATTEN_ATTRIB void operator()(ResScalar* res, Index resStride, const LhsScalar* blockA, const RhsScalar* blockB, Index rows, Index depth, Index cols, ResScalar alpha, Index strideA=-1, Index strideB=-1, Index offsetA=0, Index offsetB=0, RhsScalar* unpackedB = 0) { @@ -595,64 +589,64 @@ struct gebp_kernel if(nr==2) { LhsPacket A0, A1; - RhsPacket B0; + RhsPacket B_0; RhsPacket T0; EIGEN_ASM_COMMENT("mybegin2"); traits.loadLhs(&blA[0*LhsProgress], A0); traits.loadLhs(&blA[1*LhsProgress], A1); - traits.loadRhs(&blB[0*RhsProgress], B0); - traits.madd(A0,B0,C0,T0); - traits.madd(A1,B0,C4,B0); - traits.loadRhs(&blB[1*RhsProgress], B0); - traits.madd(A0,B0,C1,T0); - traits.madd(A1,B0,C5,B0); + traits.loadRhs(&blB[0*RhsProgress], B_0); + traits.madd(A0,B_0,C0,T0); + traits.madd(A1,B_0,C4,B_0); + traits.loadRhs(&blB[1*RhsProgress], B_0); + traits.madd(A0,B_0,C1,T0); + traits.madd(A1,B_0,C5,B_0); traits.loadLhs(&blA[2*LhsProgress], A0); traits.loadLhs(&blA[3*LhsProgress], A1); - traits.loadRhs(&blB[2*RhsProgress], B0); - traits.madd(A0,B0,C0,T0); - traits.madd(A1,B0,C4,B0); - traits.loadRhs(&blB[3*RhsProgress], B0); - traits.madd(A0,B0,C1,T0); - traits.madd(A1,B0,C5,B0); + traits.loadRhs(&blB[2*RhsProgress], B_0); + traits.madd(A0,B_0,C0,T0); + traits.madd(A1,B_0,C4,B_0); + traits.loadRhs(&blB[3*RhsProgress], B_0); + traits.madd(A0,B_0,C1,T0); + traits.madd(A1,B_0,C5,B_0); traits.loadLhs(&blA[4*LhsProgress], A0); traits.loadLhs(&blA[5*LhsProgress], A1); - traits.loadRhs(&blB[4*RhsProgress], B0); - traits.madd(A0,B0,C0,T0); - traits.madd(A1,B0,C4,B0); - traits.loadRhs(&blB[5*RhsProgress], B0); - traits.madd(A0,B0,C1,T0); - traits.madd(A1,B0,C5,B0); + traits.loadRhs(&blB[4*RhsProgress], B_0); + traits.madd(A0,B_0,C0,T0); + traits.madd(A1,B_0,C4,B_0); + traits.loadRhs(&blB[5*RhsProgress], B_0); + traits.madd(A0,B_0,C1,T0); + traits.madd(A1,B_0,C5,B_0); traits.loadLhs(&blA[6*LhsProgress], A0); traits.loadLhs(&blA[7*LhsProgress], A1); - traits.loadRhs(&blB[6*RhsProgress], B0); - traits.madd(A0,B0,C0,T0); - traits.madd(A1,B0,C4,B0); - traits.loadRhs(&blB[7*RhsProgress], B0); - traits.madd(A0,B0,C1,T0); - traits.madd(A1,B0,C5,B0); + traits.loadRhs(&blB[6*RhsProgress], B_0); + traits.madd(A0,B_0,C0,T0); + traits.madd(A1,B_0,C4,B_0); + traits.loadRhs(&blB[7*RhsProgress], B_0); + traits.madd(A0,B_0,C1,T0); + traits.madd(A1,B_0,C5,B_0); EIGEN_ASM_COMMENT("myend"); } else { EIGEN_ASM_COMMENT("mybegin4"); LhsPacket A0, A1; - RhsPacket B0, B1, B2, B3; + RhsPacket B_0, B1, B2, B3; RhsPacket T0; traits.loadLhs(&blA[0*LhsProgress], A0); traits.loadLhs(&blA[1*LhsProgress], A1); - traits.loadRhs(&blB[0*RhsProgress], B0); + traits.loadRhs(&blB[0*RhsProgress], B_0); traits.loadRhs(&blB[1*RhsProgress], B1); - traits.madd(A0,B0,C0,T0); + traits.madd(A0,B_0,C0,T0); traits.loadRhs(&blB[2*RhsProgress], B2); - traits.madd(A1,B0,C4,B0); + traits.madd(A1,B_0,C4,B_0); traits.loadRhs(&blB[3*RhsProgress], B3); - traits.loadRhs(&blB[4*RhsProgress], B0); + traits.loadRhs(&blB[4*RhsProgress], B_0); traits.madd(A0,B1,C1,T0); traits.madd(A1,B1,C5,B1); traits.loadRhs(&blB[5*RhsProgress], B1); @@ -664,9 +658,9 @@ EIGEN_ASM_COMMENT("mybegin4"); traits.madd(A1,B3,C7,B3); traits.loadLhs(&blA[3*LhsProgress], A1); traits.loadRhs(&blB[7*RhsProgress], B3); - traits.madd(A0,B0,C0,T0); - traits.madd(A1,B0,C4,B0); - traits.loadRhs(&blB[8*RhsProgress], B0); + traits.madd(A0,B_0,C0,T0); + traits.madd(A1,B_0,C4,B_0); + traits.loadRhs(&blB[8*RhsProgress], B_0); traits.madd(A0,B1,C1,T0); traits.madd(A1,B1,C5,B1); traits.loadRhs(&blB[9*RhsProgress], B1); @@ -679,9 +673,9 @@ EIGEN_ASM_COMMENT("mybegin4"); traits.loadLhs(&blA[5*LhsProgress], A1); traits.loadRhs(&blB[11*RhsProgress], B3); - traits.madd(A0,B0,C0,T0); - traits.madd(A1,B0,C4,B0); - traits.loadRhs(&blB[12*RhsProgress], B0); + traits.madd(A0,B_0,C0,T0); + traits.madd(A1,B_0,C4,B_0); + traits.loadRhs(&blB[12*RhsProgress], B_0); traits.madd(A0,B1,C1,T0); traits.madd(A1,B1,C5,B1); traits.loadRhs(&blB[13*RhsProgress], B1); @@ -693,8 +687,8 @@ EIGEN_ASM_COMMENT("mybegin4"); traits.madd(A1,B3,C7,B3); traits.loadLhs(&blA[7*LhsProgress], A1); traits.loadRhs(&blB[15*RhsProgress], B3); - traits.madd(A0,B0,C0,T0); - traits.madd(A1,B0,C4,B0); + traits.madd(A0,B_0,C0,T0); + traits.madd(A1,B_0,C4,B_0); traits.madd(A0,B1,C1,T0); traits.madd(A1,B1,C5,B1); traits.madd(A0,B2,C2,T0); @@ -712,32 +706,32 @@ EIGEN_ASM_COMMENT("mybegin4"); if(nr==2) { LhsPacket A0, A1; - RhsPacket B0; + RhsPacket B_0; RhsPacket T0; traits.loadLhs(&blA[0*LhsProgress], A0); traits.loadLhs(&blA[1*LhsProgress], A1); - traits.loadRhs(&blB[0*RhsProgress], B0); - traits.madd(A0,B0,C0,T0); - traits.madd(A1,B0,C4,B0); - traits.loadRhs(&blB[1*RhsProgress], B0); - traits.madd(A0,B0,C1,T0); - traits.madd(A1,B0,C5,B0); + traits.loadRhs(&blB[0*RhsProgress], B_0); + traits.madd(A0,B_0,C0,T0); + traits.madd(A1,B_0,C4,B_0); + traits.loadRhs(&blB[1*RhsProgress], B_0); + traits.madd(A0,B_0,C1,T0); + traits.madd(A1,B_0,C5,B_0); } else { LhsPacket A0, A1; - RhsPacket B0, B1, B2, B3; + RhsPacket B_0, B1, B2, B3; RhsPacket T0; traits.loadLhs(&blA[0*LhsProgress], A0); traits.loadLhs(&blA[1*LhsProgress], A1); - traits.loadRhs(&blB[0*RhsProgress], B0); + traits.loadRhs(&blB[0*RhsProgress], B_0); traits.loadRhs(&blB[1*RhsProgress], B1); - traits.madd(A0,B0,C0,T0); + traits.madd(A0,B_0,C0,T0); traits.loadRhs(&blB[2*RhsProgress], B2); - traits.madd(A1,B0,C4,B0); + traits.madd(A1,B_0,C4,B_0); traits.loadRhs(&blB[3*RhsProgress], B3); traits.madd(A0,B1,C1,T0); traits.madd(A1,B1,C5,B1); @@ -824,42 +818,42 @@ EIGEN_ASM_COMMENT("mybegin4"); if(nr==2) { LhsPacket A0; - RhsPacket B0, B1; + RhsPacket B_0, B1; traits.loadLhs(&blA[0*LhsProgress], A0); - traits.loadRhs(&blB[0*RhsProgress], B0); + traits.loadRhs(&blB[0*RhsProgress], B_0); traits.loadRhs(&blB[1*RhsProgress], B1); - traits.madd(A0,B0,C0,B0); - traits.loadRhs(&blB[2*RhsProgress], B0); + traits.madd(A0,B_0,C0,B_0); + traits.loadRhs(&blB[2*RhsProgress], B_0); traits.madd(A0,B1,C1,B1); traits.loadLhs(&blA[1*LhsProgress], A0); traits.loadRhs(&blB[3*RhsProgress], B1); - traits.madd(A0,B0,C0,B0); - traits.loadRhs(&blB[4*RhsProgress], B0); + traits.madd(A0,B_0,C0,B_0); + traits.loadRhs(&blB[4*RhsProgress], B_0); traits.madd(A0,B1,C1,B1); traits.loadLhs(&blA[2*LhsProgress], A0); traits.loadRhs(&blB[5*RhsProgress], B1); - traits.madd(A0,B0,C0,B0); - traits.loadRhs(&blB[6*RhsProgress], B0); + traits.madd(A0,B_0,C0,B_0); + traits.loadRhs(&blB[6*RhsProgress], B_0); traits.madd(A0,B1,C1,B1); traits.loadLhs(&blA[3*LhsProgress], A0); traits.loadRhs(&blB[7*RhsProgress], B1); - traits.madd(A0,B0,C0,B0); + traits.madd(A0,B_0,C0,B_0); traits.madd(A0,B1,C1,B1); } else { LhsPacket A0; - RhsPacket B0, B1, B2, B3; + RhsPacket B_0, B1, B2, B3; traits.loadLhs(&blA[0*LhsProgress], A0); - traits.loadRhs(&blB[0*RhsProgress], B0); + traits.loadRhs(&blB[0*RhsProgress], B_0); traits.loadRhs(&blB[1*RhsProgress], B1); - traits.madd(A0,B0,C0,B0); + traits.madd(A0,B_0,C0,B_0); traits.loadRhs(&blB[2*RhsProgress], B2); traits.loadRhs(&blB[3*RhsProgress], B3); - traits.loadRhs(&blB[4*RhsProgress], B0); + traits.loadRhs(&blB[4*RhsProgress], B_0); traits.madd(A0,B1,C1,B1); traits.loadRhs(&blB[5*RhsProgress], B1); traits.madd(A0,B2,C2,B2); @@ -867,8 +861,8 @@ EIGEN_ASM_COMMENT("mybegin4"); traits.madd(A0,B3,C3,B3); traits.loadLhs(&blA[1*LhsProgress], A0); traits.loadRhs(&blB[7*RhsProgress], B3); - traits.madd(A0,B0,C0,B0); - traits.loadRhs(&blB[8*RhsProgress], B0); + traits.madd(A0,B_0,C0,B_0); + traits.loadRhs(&blB[8*RhsProgress], B_0); traits.madd(A0,B1,C1,B1); traits.loadRhs(&blB[9*RhsProgress], B1); traits.madd(A0,B2,C2,B2); @@ -877,8 +871,8 @@ EIGEN_ASM_COMMENT("mybegin4"); traits.loadLhs(&blA[2*LhsProgress], A0); traits.loadRhs(&blB[11*RhsProgress], B3); - traits.madd(A0,B0,C0,B0); - traits.loadRhs(&blB[12*RhsProgress], B0); + traits.madd(A0,B_0,C0,B_0); + traits.loadRhs(&blB[12*RhsProgress], B_0); traits.madd(A0,B1,C1,B1); traits.loadRhs(&blB[13*RhsProgress], B1); traits.madd(A0,B2,C2,B2); @@ -887,7 +881,7 @@ EIGEN_ASM_COMMENT("mybegin4"); traits.loadLhs(&blA[3*LhsProgress], A0); traits.loadRhs(&blB[15*RhsProgress], B3); - traits.madd(A0,B0,C0,B0); + traits.madd(A0,B_0,C0,B_0); traits.madd(A0,B1,C1,B1); traits.madd(A0,B2,C2,B2); traits.madd(A0,B3,C3,B3); @@ -902,26 +896,26 @@ EIGEN_ASM_COMMENT("mybegin4"); if(nr==2) { LhsPacket A0; - RhsPacket B0, B1; + RhsPacket B_0, B1; traits.loadLhs(&blA[0*LhsProgress], A0); - traits.loadRhs(&blB[0*RhsProgress], B0); + traits.loadRhs(&blB[0*RhsProgress], B_0); traits.loadRhs(&blB[1*RhsProgress], B1); - traits.madd(A0,B0,C0,B0); + traits.madd(A0,B_0,C0,B_0); traits.madd(A0,B1,C1,B1); } else { LhsPacket A0; - RhsPacket B0, B1, B2, B3; + RhsPacket B_0, B1, B2, B3; traits.loadLhs(&blA[0*LhsProgress], A0); - traits.loadRhs(&blB[0*RhsProgress], B0); + traits.loadRhs(&blB[0*RhsProgress], B_0); traits.loadRhs(&blB[1*RhsProgress], B1); traits.loadRhs(&blB[2*RhsProgress], B2); traits.loadRhs(&blB[3*RhsProgress], B3); - traits.madd(A0,B0,C0,B0); + traits.madd(A0,B_0,C0,B_0); traits.madd(A0,B1,C1,B1); traits.madd(A0,B2,C2,B2); traits.madd(A0,B3,C3,B3); @@ -968,26 +962,26 @@ EIGEN_ASM_COMMENT("mybegin4"); if(nr==2) { LhsScalar A0; - RhsScalar B0, B1; + RhsScalar B_0, B1; A0 = blA[k]; - B0 = blB[0]; + B_0 = blB[0]; B1 = blB[1]; - MADD(cj,A0,B0,C0,B0); + MADD(cj,A0,B_0,C0,B_0); MADD(cj,A0,B1,C1,B1); } else { LhsScalar A0; - RhsScalar B0, B1, B2, B3; + RhsScalar B_0, B1, B2, B3; A0 = blA[k]; - B0 = blB[0]; + B_0 = blB[0]; B1 = blB[1]; B2 = blB[2]; B3 = blB[3]; - MADD(cj,A0,B0,C0,B0); + MADD(cj,A0,B_0,C0,B_0); MADD(cj,A0,B1,C1,B1); MADD(cj,A0,B2,C2,B2); MADD(cj,A0,B3,C3,B3); @@ -1024,14 +1018,14 @@ EIGEN_ASM_COMMENT("mybegin4"); for(Index k=0; k struct gemm_pack_lhs { - void operator()(Scalar* blockA, const Scalar* EIGEN_RESTRICT _lhs, Index lhsStride, Index depth, Index rows, + EIGEN_DONT_INLINE void operator()(Scalar* blockA, const Scalar* EIGEN_RESTRICT _lhs, Index lhsStride, Index depth, Index rows, Index stride=0, Index offset=0) { -// enum { PacketSize = packet_traits::size }; + typedef typename packet_traits::type Packet; + enum { PacketSize = packet_traits::size }; + + EIGEN_ASM_COMMENT("EIGEN PRODUCT PACK LHS"); eigen_assert(((!PanelMode) && stride==0 && offset==0) || (PanelMode && stride>=depth && offset<=stride)); + eigen_assert( (StorageOrder==RowMajor) || ((Pack1%PacketSize)==0 && Pack1<=4*PacketSize) ); conj_if::IsComplex && Conjugate> cj; const_blas_data_mapper lhs(_lhs,lhsStride); Index count = 0; @@ -1128,9 +1126,44 @@ struct gemm_pack_lhs for(Index i=0; i=1*PacketSize) A = ploadu(&lhs(i+0*PacketSize, k)); + if(Pack1>=2*PacketSize) B = ploadu(&lhs(i+1*PacketSize, k)); + if(Pack1>=3*PacketSize) C = ploadu(&lhs(i+2*PacketSize, k)); + if(Pack1>=4*PacketSize) D = ploadu(&lhs(i+3*PacketSize, k)); + if(Pack1>=1*PacketSize) { pstore(blockA+count, cj.pconj(A)); count+=PacketSize; } + if(Pack1>=2*PacketSize) { pstore(blockA+count, cj.pconj(B)); count+=PacketSize; } + if(Pack1>=3*PacketSize) { pstore(blockA+count, cj.pconj(C)); count+=PacketSize; } + if(Pack1>=4*PacketSize) { pstore(blockA+count, cj.pconj(D)); count+=PacketSize; } + } + } + else + { + for(Index k=0; k=Pack2) @@ -1164,9 +1197,10 @@ struct gemm_pack_rhs { typedef typename packet_traits::type Packet; enum { PacketSize = packet_traits::size }; - void operator()(Scalar* blockB, const Scalar* rhs, Index rhsStride, Index depth, Index cols, + EIGEN_DONT_INLINE void operator()(Scalar* blockB, const Scalar* rhs, Index rhsStride, Index depth, Index cols, Index stride=0, Index offset=0) { + EIGEN_ASM_COMMENT("EIGEN PRODUCT PACK RHS COLMAJOR"); eigen_assert(((!PanelMode) && stride==0 && offset==0) || (PanelMode && stride>=depth && offset<=stride)); conj_if::IsComplex && Conjugate> cj; Index packet_cols = (cols/nr) * nr; @@ -1211,9 +1245,10 @@ template { enum { PacketSize = packet_traits::size }; - void operator()(Scalar* blockB, const Scalar* rhs, Index rhsStride, Index depth, Index cols, + EIGEN_DONT_INLINE void operator()(Scalar* blockB, const Scalar* rhs, Index rhsStride, Index depth, Index cols, Index stride=0, Index offset=0) { + EIGEN_ASM_COMMENT("EIGEN PRODUCT PACK RHS ROWMAJOR"); eigen_assert(((!PanelMode) && stride==0 && offset==0) || (PanelMode && stride>=depth && offset<=stride)); conj_if::IsComplex && Conjugate> cj; Index packet_cols = (cols/nr) * nr; @@ -1279,4 +1314,6 @@ inline void setCpuCacheSizes(std::ptrdiff_t l1, std::ptrdiff_t l2) internal::manage_caching_sizes(SetAction, &l1, &l2); } +} // end namespace Eigen + #endif // EIGEN_GENERAL_BLOCK_PANEL_H diff --git a/extern/Eigen3/Eigen/src/Core/products/GeneralMatrixMatrix.h b/extern/Eigen3/Eigen/src/Core/products/GeneralMatrixMatrix.h index ae94a27953b..73a465ec5ee 100644 --- a/extern/Eigen3/Eigen/src/Core/products/GeneralMatrixMatrix.h +++ b/extern/Eigen3/Eigen/src/Core/products/GeneralMatrixMatrix.h @@ -3,28 +3,15 @@ // // Copyright (C) 2008-2009 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_GENERAL_MATRIX_MATRIX_H #define EIGEN_GENERAL_MATRIX_MATRIX_H +namespace Eigen { + namespace internal { template class level3_blocking; @@ -77,7 +64,7 @@ static void run(Index rows, Index cols, Index depth, typedef gebp_traits Traits; - Index kc = blocking.kc(); // cache block size along the K direction + Index kc = blocking.kc(); // cache block size along the K direction Index mc = (std::min)(rows,blocking.mc()); // cache block size along the M direction //Index nc = blocking.nc(); // cache block size along the N direction @@ -247,7 +234,7 @@ struct gemm_functor BlockingType& m_blocking; }; -template class gemm_blocking_space; template @@ -280,8 +267,8 @@ class level3_blocking inline RhsScalar* blockW() { return m_blockW; } }; -template -class gemm_blocking_space +template +class gemm_blocking_space : public level3_blocking< typename conditional::type, typename conditional::type> @@ -322,8 +309,8 @@ class gemm_blocking_space -class gemm_blocking_space +template +class gemm_blocking_space : public level3_blocking< typename conditional::type, typename conditional::type> @@ -347,7 +334,7 @@ class gemm_blocking_spacem_nc = Transpose ? rows : cols; this->m_kc = depth; - computeProductBlockingSizes(this->m_kc, this->m_mc, this->m_nc); + computeProductBlockingSizes(this->m_kc, this->m_mc, this->m_nc); m_sizeA = this->m_mc * this->m_kc; m_sizeB = this->m_kc * this->m_nc; m_sizeW = this->m_kc*Traits::WorkSpaceFactor; @@ -412,8 +399,8 @@ class GeneralProduct { eigen_assert(dst.rows()==m_lhs.rows() && dst.cols()==m_rhs.cols()); - const ActualLhsType lhs = LhsBlasTraits::extract(m_lhs); - const ActualRhsType rhs = RhsBlasTraits::extract(m_rhs); + typename internal::add_const_on_value_type::type lhs = LhsBlasTraits::extract(m_lhs); + typename internal::add_const_on_value_type::type rhs = RhsBlasTraits::extract(m_rhs); Scalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(m_lhs) * RhsBlasTraits::extractScalarFactor(m_rhs); @@ -436,4 +423,6 @@ class GeneralProduct } }; +} // end namespace Eigen + #endif // EIGEN_GENERAL_MATRIX_MATRIX_H diff --git a/extern/Eigen3/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h b/extern/Eigen3/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h index 5043b64fe2e..432d3a9dc84 100644 --- a/extern/Eigen3/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h +++ b/extern/Eigen3/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h @@ -3,28 +3,15 @@ // // Copyright (C) 2009-2010 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_GENERAL_MATRIX_MATRIX_TRIANGULAR_H #define EIGEN_GENERAL_MATRIX_MATRIX_TRIANGULAR_H +namespace Eigen { + namespace internal { /********************************************************************** @@ -42,14 +29,14 @@ struct tribb_kernel; template + int ResStorageOrder, int UpLo, int Version = Specialized> struct general_matrix_matrix_triangular_product; // as usual if the result is row major => we transpose the product template -struct general_matrix_matrix_triangular_product -{ + typename RhsScalar, int RhsStorageOrder, bool ConjugateRhs, int UpLo, int Version> +struct general_matrix_matrix_triangular_product +{ typedef typename scalar_product_traits::ReturnType ResScalar; static EIGEN_STRONG_INLINE void run(Index size, Index depth,const LhsScalar* lhs, Index lhsStride, const RhsScalar* rhs, Index rhsStride, ResScalar* res, Index resStride, ResScalar alpha) @@ -63,8 +50,8 @@ struct general_matrix_matrix_triangular_product -struct general_matrix_matrix_triangular_product + typename RhsScalar, int RhsStorageOrder, bool ConjugateRhs, int UpLo, int Version> +struct general_matrix_matrix_triangular_product { typedef typename scalar_product_traits::ReturnType ResScalar; static EIGEN_STRONG_INLINE void run(Index size, Index depth,const LhsScalar* _lhs, Index lhsStride, @@ -201,13 +188,13 @@ TriangularView& TriangularView::assignProduct( typedef internal::blas_traits LhsBlasTraits; typedef typename LhsBlasTraits::DirectLinearAccessType ActualLhs; typedef typename internal::remove_all::type _ActualLhs; - const ActualLhs actualLhs = LhsBlasTraits::extract(prod.lhs()); + typename internal::add_const_on_value_type::type actualLhs = LhsBlasTraits::extract(prod.lhs()); typedef typename internal::remove_all::type Rhs; typedef internal::blas_traits RhsBlasTraits; typedef typename RhsBlasTraits::DirectLinearAccessType ActualRhs; typedef typename internal::remove_all::type _ActualRhs; - const ActualRhs actualRhs = RhsBlasTraits::extract(prod.rhs()); + typename internal::add_const_on_value_type::type actualRhs = RhsBlasTraits::extract(prod.rhs()); typename ProductDerived::Scalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(prod.lhs().derived()) * RhsBlasTraits::extractScalarFactor(prod.rhs().derived()); @@ -222,4 +209,6 @@ TriangularView& TriangularView::assignProduct( return *this; } +} // end namespace Eigen + #endif // EIGEN_GENERAL_MATRIX_MATRIX_TRIANGULAR_H diff --git a/extern/Eigen3/Eigen/src/Core/products/GeneralMatrixMatrixTriangular_MKL.h b/extern/Eigen3/Eigen/src/Core/products/GeneralMatrixMatrixTriangular_MKL.h new file mode 100644 index 00000000000..3deed068e39 --- /dev/null +++ b/extern/Eigen3/Eigen/src/Core/products/GeneralMatrixMatrixTriangular_MKL.h @@ -0,0 +1,146 @@ +/* + Copyright (c) 2011, Intel Corporation. All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of Intel Corporation nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ******************************************************************************** + * Content : Eigen bindings to Intel(R) MKL + * Level 3 BLAS SYRK/HERK implementation. + ******************************************************************************** +*/ + +#ifndef EIGEN_GENERAL_MATRIX_MATRIX_TRIANGULAR_MKL_H +#define EIGEN_GENERAL_MATRIX_MATRIX_TRIANGULAR_MKL_H + +namespace Eigen { + +namespace internal { + +template +struct general_matrix_matrix_rankupdate : + general_matrix_matrix_triangular_product< + Index,Scalar,AStorageOrder,ConjugateA,Scalar,AStorageOrder,ConjugateA,ResStorageOrder,UpLo,BuiltIn> {}; + + +// try to go to BLAS specialization +#define EIGEN_MKL_RANKUPDATE_SPECIALIZE(Scalar) \ +template \ +struct general_matrix_matrix_triangular_product { \ + static EIGEN_STRONG_INLINE void run(Index size, Index depth,const Scalar* lhs, Index lhsStride, \ + const Scalar* rhs, Index rhsStride, Scalar* res, Index resStride, Scalar alpha) \ + { \ + if (lhs==rhs) { \ + general_matrix_matrix_rankupdate \ + ::run(size,depth,lhs,lhsStride,rhs,rhsStride,res,resStride,alpha); \ + } else { \ + general_matrix_matrix_triangular_product \ + ::run(size,depth,lhs,lhsStride,rhs,rhsStride,res,resStride,alpha); \ + } \ + } \ +}; + +EIGEN_MKL_RANKUPDATE_SPECIALIZE(double) +//EIGEN_MKL_RANKUPDATE_SPECIALIZE(dcomplex) +EIGEN_MKL_RANKUPDATE_SPECIALIZE(float) +//EIGEN_MKL_RANKUPDATE_SPECIALIZE(scomplex) + +// SYRK for float/double +#define EIGEN_MKL_RANKUPDATE_R(EIGTYPE, MKLTYPE, MKLFUNC) \ +template \ +struct general_matrix_matrix_rankupdate { \ + enum { \ + IsLower = (UpLo&Lower) == Lower, \ + LowUp = IsLower ? Lower : Upper, \ + conjA = ((AStorageOrder==ColMajor) && ConjugateA) ? 1 : 0 \ + }; \ + static EIGEN_STRONG_INLINE void run(Index size, Index depth,const EIGTYPE* lhs, Index lhsStride, \ + const EIGTYPE* rhs, Index rhsStride, EIGTYPE* res, Index resStride, EIGTYPE alpha) \ + { \ + /* typedef Matrix MatrixRhs;*/ \ +\ + MKL_INT lda=lhsStride, ldc=resStride, n=size, k=depth; \ + char uplo=(IsLower) ? 'L' : 'U', trans=(AStorageOrder==RowMajor) ? 'T':'N'; \ + MKLTYPE alpha_, beta_; \ +\ +/* Set alpha_ & beta_ */ \ + assign_scalar_eig2mkl(alpha_, alpha); \ + assign_scalar_eig2mkl(beta_, EIGTYPE(1)); \ + MKLFUNC(&uplo, &trans, &n, &k, &alpha_, lhs, &lda, &beta_, res, &ldc); \ + } \ +}; + +// HERK for complex data +#define EIGEN_MKL_RANKUPDATE_C(EIGTYPE, MKLTYPE, RTYPE, MKLFUNC) \ +template \ +struct general_matrix_matrix_rankupdate { \ + enum { \ + IsLower = (UpLo&Lower) == Lower, \ + LowUp = IsLower ? Lower : Upper, \ + conjA = (((AStorageOrder==ColMajor) && ConjugateA) || ((AStorageOrder==RowMajor) && !ConjugateA)) ? 1 : 0 \ + }; \ + static EIGEN_STRONG_INLINE void run(Index size, Index depth,const EIGTYPE* lhs, Index lhsStride, \ + const EIGTYPE* rhs, Index rhsStride, EIGTYPE* res, Index resStride, EIGTYPE alpha) \ + { \ + typedef Matrix MatrixType; \ +\ + MKL_INT lda=lhsStride, ldc=resStride, n=size, k=depth; \ + char uplo=(IsLower) ? 'L' : 'U', trans=(AStorageOrder==RowMajor) ? 'C':'N'; \ + RTYPE alpha_, beta_; \ + const EIGTYPE* a_ptr; \ +\ +/* Set alpha_ & beta_ */ \ +/* assign_scalar_eig2mkl(alpha_, alpha); */\ +/* assign_scalar_eig2mkl(beta_, EIGTYPE(1));*/ \ + alpha_ = alpha.real(); \ + beta_ = 1.0; \ +/* Copy with conjugation in some cases*/ \ + MatrixType a; \ + if (conjA) { \ + Map > mapA(lhs,n,k,OuterStride<>(lhsStride)); \ + a = mapA.conjugate(); \ + lda = a.outerStride(); \ + a_ptr = a.data(); \ + } else a_ptr=lhs; \ + MKLFUNC(&uplo, &trans, &n, &k, &alpha_, (MKLTYPE*)a_ptr, &lda, &beta_, (MKLTYPE*)res, &ldc); \ + } \ +}; + + +EIGEN_MKL_RANKUPDATE_R(double, double, dsyrk) +EIGEN_MKL_RANKUPDATE_R(float, float, ssyrk) + +//EIGEN_MKL_RANKUPDATE_C(dcomplex, MKL_Complex16, double, zherk) +//EIGEN_MKL_RANKUPDATE_C(scomplex, MKL_Complex8, double, cherk) + + +} // end namespace internal + +} // end namespace Eigen + +#endif // EIGEN_GENERAL_MATRIX_MATRIX_TRIANGULAR_MKL_H diff --git a/extern/Eigen3/Eigen/src/Core/products/GeneralMatrixMatrix_MKL.h b/extern/Eigen3/Eigen/src/Core/products/GeneralMatrixMatrix_MKL.h new file mode 100644 index 00000000000..060af328ebe --- /dev/null +++ b/extern/Eigen3/Eigen/src/Core/products/GeneralMatrixMatrix_MKL.h @@ -0,0 +1,118 @@ +/* + Copyright (c) 2011, Intel Corporation. All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of Intel Corporation nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ******************************************************************************** + * Content : Eigen bindings to Intel(R) MKL + * General matrix-matrix product functionality based on ?GEMM. + ******************************************************************************** +*/ + +#ifndef EIGEN_GENERAL_MATRIX_MATRIX_MKL_H +#define EIGEN_GENERAL_MATRIX_MATRIX_MKL_H + +namespace Eigen { + +namespace internal { + +/********************************************************************** +* This file implements general matrix-matrix multiplication using BLAS +* gemm function via partial specialization of +* general_matrix_matrix_product::run(..) method for float, double, +* std::complex and std::complex types +**********************************************************************/ + +// gemm specialization + +#define GEMM_SPECIALIZATION(EIGTYPE, EIGPREFIX, MKLTYPE, MKLPREFIX) \ +template< \ + typename Index, \ + int LhsStorageOrder, bool ConjugateLhs, \ + int RhsStorageOrder, bool ConjugateRhs> \ +struct general_matrix_matrix_product \ +{ \ +static void run(Index rows, Index cols, Index depth, \ + const EIGTYPE* _lhs, Index lhsStride, \ + const EIGTYPE* _rhs, Index rhsStride, \ + EIGTYPE* res, Index resStride, \ + EIGTYPE alpha, \ + level3_blocking& /*blocking*/, \ + GemmParallelInfo* /*info = 0*/) \ +{ \ + using std::conj; \ +\ + char transa, transb; \ + MKL_INT m, n, k, lda, ldb, ldc; \ + const EIGTYPE *a, *b; \ + MKLTYPE alpha_, beta_; \ + MatrixX##EIGPREFIX a_tmp, b_tmp; \ + EIGTYPE myone(1);\ +\ +/* Set transpose options */ \ + transa = (LhsStorageOrder==RowMajor) ? ((ConjugateLhs) ? 'C' : 'T') : 'N'; \ + transb = (RhsStorageOrder==RowMajor) ? ((ConjugateRhs) ? 'C' : 'T') : 'N'; \ +\ +/* Set m, n, k */ \ + m = (MKL_INT)rows; \ + n = (MKL_INT)cols; \ + k = (MKL_INT)depth; \ +\ +/* Set alpha_ & beta_ */ \ + assign_scalar_eig2mkl(alpha_, alpha); \ + assign_scalar_eig2mkl(beta_, myone); \ +\ +/* Set lda, ldb, ldc */ \ + lda = (MKL_INT)lhsStride; \ + ldb = (MKL_INT)rhsStride; \ + ldc = (MKL_INT)resStride; \ +\ +/* Set a, b, c */ \ + if ((LhsStorageOrder==ColMajor) && (ConjugateLhs)) { \ + Map > lhs(_lhs,m,k,OuterStride<>(lhsStride)); \ + a_tmp = lhs.conjugate(); \ + a = a_tmp.data(); \ + lda = a_tmp.outerStride(); \ + } else a = _lhs; \ +\ + if ((RhsStorageOrder==ColMajor) && (ConjugateRhs)) { \ + Map > rhs(_rhs,k,n,OuterStride<>(rhsStride)); \ + b_tmp = rhs.conjugate(); \ + b = b_tmp.data(); \ + ldb = b_tmp.outerStride(); \ + } else b = _rhs; \ +\ + MKLPREFIX##gemm(&transa, &transb, &m, &n, &k, &alpha_, (const MKLTYPE*)a, &lda, (const MKLTYPE*)b, &ldb, &beta_, (MKLTYPE*)res, &ldc); \ +}}; + +GEMM_SPECIALIZATION(double, d, double, d) +GEMM_SPECIALIZATION(float, f, float, s) +GEMM_SPECIALIZATION(dcomplex, cd, MKL_Complex16, z) +GEMM_SPECIALIZATION(scomplex, cf, MKL_Complex8, c) + +} // end namespase internal + +} // end namespace Eigen + +#endif // EIGEN_GENERAL_MATRIX_MATRIX_MKL_H diff --git a/extern/Eigen3/Eigen/src/Core/products/GeneralMatrixVector.h b/extern/Eigen3/Eigen/src/Core/products/GeneralMatrixVector.h index e0e2cbf8f62..ba1f73957db 100644 --- a/extern/Eigen3/Eigen/src/Core/products/GeneralMatrixVector.h +++ b/extern/Eigen3/Eigen/src/Core/products/GeneralMatrixVector.h @@ -3,28 +3,15 @@ // // Copyright (C) 2008-2009 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_GENERAL_MATRIX_VECTOR_H #define EIGEN_GENERAL_MATRIX_VECTOR_H +namespace Eigen { + namespace internal { /* Optimized col-major matrix * vector product: @@ -40,8 +27,8 @@ namespace internal { * |cplx |real |cplx | invalid, the caller has to do tmp: = A * B; C += alpha*tmp * |cplx |real |real | optimal case, vectorization possible via real-cplx mul */ -template -struct general_matrix_vector_product +template +struct general_matrix_vector_product { typedef typename scalar_product_traits::ReturnType ResScalar; @@ -99,7 +86,7 @@ EIGEN_DONT_INLINE static void run( // How many coeffs of the result do we have to skip to be aligned. // Here we assume data are at least aligned on the base scalar type. - Index alignedStart = first_aligned(res,size); + Index alignedStart = internal::first_aligned(res,size); Index alignedSize = ResPacketSize>1 ? alignedStart + ((size-alignedStart) & ~ResPacketAlignedMask) : 0; const Index peeledSize = peels>1 ? alignedStart + ((alignedSize-alignedStart) & ~PeelAlignedMask) : alignedStart; @@ -109,7 +96,7 @@ EIGEN_DONT_INLINE static void run( : FirstAligned; // we cannot assume the first element is aligned because of sub-matrices - const Index lhsAlignmentOffset = first_aligned(lhs,size); + const Index lhsAlignmentOffset = internal::first_aligned(lhs,size); // find how many columns do we have to skip to be aligned with the result (if possible) Index skipColumns = 0; @@ -296,8 +283,8 @@ EIGEN_DONT_INLINE static void run( * - alpha is always a complex (or converted to a complex) * - no vectorization */ -template -struct general_matrix_vector_product +template +struct general_matrix_vector_product { typedef typename scalar_product_traits::ReturnType ResScalar; @@ -351,7 +338,7 @@ EIGEN_DONT_INLINE static void run( // How many coeffs of the result do we have to skip to be aligned. // Here we assume data are at least aligned on the base scalar type // if that's not the case then vectorization is discarded, see below. - Index alignedStart = first_aligned(rhs, depth); + Index alignedStart = internal::first_aligned(rhs, depth); Index alignedSize = RhsPacketSize>1 ? alignedStart + ((depth-alignedStart) & ~RhsPacketAlignedMask) : 0; const Index peeledSize = peels>1 ? alignedStart + ((alignedSize-alignedStart) & ~PeelAlignedMask) : alignedStart; @@ -361,7 +348,7 @@ EIGEN_DONT_INLINE static void run( : FirstAligned; // we cannot assume the first element is aligned because of sub-matrices - const Index lhsAlignmentOffset = first_aligned(lhs,depth); + const Index lhsAlignmentOffset = internal::first_aligned(lhs,depth); // find how many rows do we have to skip to be aligned with rhs (if possible) Index skipRows = 0; @@ -556,4 +543,6 @@ EIGEN_DONT_INLINE static void run( } // end namespace internal +} // end namespace Eigen + #endif // EIGEN_GENERAL_MATRIX_VECTOR_H diff --git a/extern/Eigen3/Eigen/src/Core/products/GeneralMatrixVector_MKL.h b/extern/Eigen3/Eigen/src/Core/products/GeneralMatrixVector_MKL.h new file mode 100644 index 00000000000..e9de6af3ed1 --- /dev/null +++ b/extern/Eigen3/Eigen/src/Core/products/GeneralMatrixVector_MKL.h @@ -0,0 +1,131 @@ +/* + Copyright (c) 2011, Intel Corporation. All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of Intel Corporation nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ******************************************************************************** + * Content : Eigen bindings to Intel(R) MKL + * General matrix-vector product functionality based on ?GEMV. + ******************************************************************************** +*/ + +#ifndef EIGEN_GENERAL_MATRIX_VECTOR_MKL_H +#define EIGEN_GENERAL_MATRIX_VECTOR_MKL_H + +namespace Eigen { + +namespace internal { + +/********************************************************************** +* This file implements general matrix-vector multiplication using BLAS +* gemv function via partial specialization of +* general_matrix_vector_product::run(..) method for float, double, +* std::complex and std::complex types +**********************************************************************/ + +// gemv specialization + +template +struct general_matrix_vector_product_gemv : + general_matrix_vector_product {}; + +#define EIGEN_MKL_GEMV_SPECIALIZE(Scalar) \ +template \ +struct general_matrix_vector_product { \ +static EIGEN_DONT_INLINE void run( \ + Index rows, Index cols, \ + const Scalar* lhs, Index lhsStride, \ + const Scalar* rhs, Index rhsIncr, \ + Scalar* res, Index resIncr, Scalar alpha) \ +{ \ + if (ConjugateLhs) { \ + general_matrix_vector_product::run( \ + rows, cols, lhs, lhsStride, rhs, rhsIncr, res, resIncr, alpha); \ + } else { \ + general_matrix_vector_product_gemv::run( \ + rows, cols, lhs, lhsStride, rhs, rhsIncr, res, resIncr, alpha); \ + } \ +} \ +}; \ +template \ +struct general_matrix_vector_product { \ +static EIGEN_DONT_INLINE void run( \ + Index rows, Index cols, \ + const Scalar* lhs, Index lhsStride, \ + const Scalar* rhs, Index rhsIncr, \ + Scalar* res, Index resIncr, Scalar alpha) \ +{ \ + general_matrix_vector_product_gemv::run( \ + rows, cols, lhs, lhsStride, rhs, rhsIncr, res, resIncr, alpha); \ +} \ +}; \ + +EIGEN_MKL_GEMV_SPECIALIZE(double) +EIGEN_MKL_GEMV_SPECIALIZE(float) +EIGEN_MKL_GEMV_SPECIALIZE(dcomplex) +EIGEN_MKL_GEMV_SPECIALIZE(scomplex) + +#define EIGEN_MKL_GEMV_SPECIALIZATION(EIGTYPE,MKLTYPE,MKLPREFIX) \ +template \ +struct general_matrix_vector_product_gemv \ +{ \ +typedef Matrix GEMVVector;\ +\ +static EIGEN_DONT_INLINE void run( \ + Index rows, Index cols, \ + const EIGTYPE* lhs, Index lhsStride, \ + const EIGTYPE* rhs, Index rhsIncr, \ + EIGTYPE* res, Index resIncr, EIGTYPE alpha) \ +{ \ + MKL_INT m=rows, n=cols, lda=lhsStride, incx=rhsIncr, incy=resIncr; \ + MKLTYPE alpha_, beta_; \ + const EIGTYPE *x_ptr, myone(1); \ + char trans=(LhsStorageOrder==ColMajor) ? 'N' : (ConjugateLhs) ? 'C' : 'T'; \ + if (LhsStorageOrder==RowMajor) { \ + m=cols; \ + n=rows; \ + }\ + assign_scalar_eig2mkl(alpha_, alpha); \ + assign_scalar_eig2mkl(beta_, myone); \ + GEMVVector x_tmp; \ + if (ConjugateRhs) { \ + Map > map_x(rhs,cols,1,InnerStride<>(incx)); \ + x_tmp=map_x.conjugate(); \ + x_ptr=x_tmp.data(); \ + incx=1; \ + } else x_ptr=rhs; \ + MKLPREFIX##gemv(&trans, &m, &n, &alpha_, (const MKLTYPE*)lhs, &lda, (const MKLTYPE*)x_ptr, &incx, &beta_, (MKLTYPE*)res, &incy); \ +}\ +}; + +EIGEN_MKL_GEMV_SPECIALIZATION(double, double, d) +EIGEN_MKL_GEMV_SPECIALIZATION(float, float, s) +EIGEN_MKL_GEMV_SPECIALIZATION(dcomplex, MKL_Complex16, z) +EIGEN_MKL_GEMV_SPECIALIZATION(scomplex, MKL_Complex8, c) + +} // end namespase internal + +} // end namespace Eigen + +#endif // EIGEN_GENERAL_MATRIX_VECTOR_MKL_H diff --git a/extern/Eigen3/Eigen/src/Core/products/Parallelizer.h b/extern/Eigen3/Eigen/src/Core/products/Parallelizer.h index ecdedc363ce..5c3e9b7ac15 100644 --- a/extern/Eigen3/Eigen/src/Core/products/Parallelizer.h +++ b/extern/Eigen3/Eigen/src/Core/products/Parallelizer.h @@ -3,28 +3,15 @@ // // Copyright (C) 2010 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_PARALLELIZER_H #define EIGEN_PARALLELIZER_H +namespace Eigen { + namespace internal { /** \internal */ @@ -55,12 +42,23 @@ inline void manage_multi_threading(Action action, int* v) } } +} + +/** Must be call first when calling Eigen from multiple threads */ +inline void initParallel() +{ + int nbt; + internal::manage_multi_threading(GetAction, &nbt); + std::ptrdiff_t l1, l2; + internal::manage_caching_sizes(GetAction, &l1, &l2); +} + /** \returns the max number of threads reserved for Eigen * \sa setNbThreads */ inline int nbThreads() { int ret; - manage_multi_threading(GetAction, &ret); + internal::manage_multi_threading(GetAction, &ret); return ret; } @@ -68,9 +66,11 @@ inline int nbThreads() * \sa nbThreads */ inline void setNbThreads(int v) { - manage_multi_threading(SetAction, &v); + internal::manage_multi_threading(SetAction, &v); } +namespace internal { + template struct GemmParallelInfo { GemmParallelInfo() : sync(-1), users(0), rhs_start(0), rhs_length(0) {} @@ -85,7 +85,9 @@ template struct GemmParallelInfo template void parallelize_gemm(const Functor& func, Index rows, Index cols, bool transpose) { -#ifndef EIGEN_HAS_OPENMP + // TODO when EIGEN_USE_BLAS is defined, + // we should still enable OMP for other scalar types +#if !(defined (EIGEN_HAS_OPENMP)) || defined (EIGEN_USE_BLAS) // FIXME the transpose variable is only needed to properly split // the matrix product when multithreading is enabled. This is a temporary // fix to support row-major destination matrices. This whole @@ -117,6 +119,7 @@ void parallelize_gemm(const Functor& func, Index rows, Index cols, bool transpos if(threads==1) return func(0,rows, 0,cols); + Eigen::initParallel(); func.initParallelSession(); if(transpose) @@ -151,4 +154,6 @@ void parallelize_gemm(const Functor& func, Index rows, Index cols, bool transpos } // end namespace internal +} // end namespace Eigen + #endif // EIGEN_PARALLELIZER_H diff --git a/extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixMatrix.h b/extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixMatrix.h index ccd757cfaf8..48209636eed 100644 --- a/extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixMatrix.h +++ b/extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixMatrix.h @@ -3,28 +3,15 @@ // // Copyright (C) 2009 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_SELFADJOINT_MATRIX_MATRIX_H #define EIGEN_SELFADJOINT_MATRIX_MATRIX_H +namespace Eigen { + namespace internal { // pack a selfadjoint block diagonal for use with the gebp_kernel @@ -400,8 +387,8 @@ struct SelfadjointProductMatrix { eigen_assert(dst.rows()==m_lhs.rows() && dst.cols()==m_rhs.cols()); - const ActualLhsType lhs = LhsBlasTraits::extract(m_lhs); - const ActualRhsType rhs = RhsBlasTraits::extract(m_rhs); + typename internal::add_const_on_value_type::type lhs = LhsBlasTraits::extract(m_lhs); + typename internal::add_const_on_value_type::type rhs = RhsBlasTraits::extract(m_rhs); Scalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(m_lhs) * RhsBlasTraits::extractScalarFactor(m_rhs); @@ -424,4 +411,6 @@ struct SelfadjointProductMatrix } }; +} // end namespace Eigen + #endif // EIGEN_SELFADJOINT_MATRIX_MATRIX_H diff --git a/extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixMatrix_MKL.h b/extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixMatrix_MKL.h new file mode 100644 index 00000000000..4e5c4125c01 --- /dev/null +++ b/extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixMatrix_MKL.h @@ -0,0 +1,295 @@ +/* + Copyright (c) 2011, Intel Corporation. All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of Intel Corporation nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ******************************************************************************** + * Content : Eigen bindings to Intel(R) MKL + * Self adjoint matrix * matrix product functionality based on ?SYMM/?HEMM. + ******************************************************************************** +*/ + +#ifndef EIGEN_SELFADJOINT_MATRIX_MATRIX_MKL_H +#define EIGEN_SELFADJOINT_MATRIX_MATRIX_MKL_H + +namespace Eigen { + +namespace internal { + + +/* Optimized selfadjoint matrix * matrix (?SYMM/?HEMM) product */ + +#define EIGEN_MKL_SYMM_L(EIGTYPE, MKLTYPE, EIGPREFIX, MKLPREFIX) \ +template \ +struct product_selfadjoint_matrix \ +{\ +\ + static EIGEN_DONT_INLINE void run( \ + Index rows, Index cols, \ + const EIGTYPE* _lhs, Index lhsStride, \ + const EIGTYPE* _rhs, Index rhsStride, \ + EIGTYPE* res, Index resStride, \ + EIGTYPE alpha) \ + { \ + char side='L', uplo='L'; \ + MKL_INT m, n, lda, ldb, ldc; \ + const EIGTYPE *a, *b; \ + MKLTYPE alpha_, beta_; \ + MatrixX##EIGPREFIX b_tmp; \ + EIGTYPE myone(1);\ +\ +/* Set transpose options */ \ +/* Set m, n, k */ \ + m = (MKL_INT)rows; \ + n = (MKL_INT)cols; \ +\ +/* Set alpha_ & beta_ */ \ + assign_scalar_eig2mkl(alpha_, alpha); \ + assign_scalar_eig2mkl(beta_, myone); \ +\ +/* Set lda, ldb, ldc */ \ + lda = (MKL_INT)lhsStride; \ + ldb = (MKL_INT)rhsStride; \ + ldc = (MKL_INT)resStride; \ +\ +/* Set a, b, c */ \ + if (LhsStorageOrder==RowMajor) uplo='U'; \ + a = _lhs; \ +\ + if (RhsStorageOrder==RowMajor) { \ + Map > rhs(_rhs,n,m,OuterStride<>(rhsStride)); \ + b_tmp = rhs.adjoint(); \ + b = b_tmp.data(); \ + ldb = b_tmp.outerStride(); \ + } else b = _rhs; \ +\ + MKLPREFIX##symm(&side, &uplo, &m, &n, &alpha_, (const MKLTYPE*)a, &lda, (const MKLTYPE*)b, &ldb, &beta_, (MKLTYPE*)res, &ldc); \ +\ + } \ +}; + + +#define EIGEN_MKL_HEMM_L(EIGTYPE, MKLTYPE, EIGPREFIX, MKLPREFIX) \ +template \ +struct product_selfadjoint_matrix \ +{\ + static EIGEN_DONT_INLINE void run( \ + Index rows, Index cols, \ + const EIGTYPE* _lhs, Index lhsStride, \ + const EIGTYPE* _rhs, Index rhsStride, \ + EIGTYPE* res, Index resStride, \ + EIGTYPE alpha) \ + { \ + char side='L', uplo='L'; \ + MKL_INT m, n, lda, ldb, ldc; \ + const EIGTYPE *a, *b; \ + MKLTYPE alpha_, beta_; \ + MatrixX##EIGPREFIX b_tmp; \ + Matrix a_tmp; \ + EIGTYPE myone(1); \ +\ +/* Set transpose options */ \ +/* Set m, n, k */ \ + m = (MKL_INT)rows; \ + n = (MKL_INT)cols; \ +\ +/* Set alpha_ & beta_ */ \ + assign_scalar_eig2mkl(alpha_, alpha); \ + assign_scalar_eig2mkl(beta_, myone); \ +\ +/* Set lda, ldb, ldc */ \ + lda = (MKL_INT)lhsStride; \ + ldb = (MKL_INT)rhsStride; \ + ldc = (MKL_INT)resStride; \ +\ +/* Set a, b, c */ \ + if (((LhsStorageOrder==ColMajor) && ConjugateLhs) || ((LhsStorageOrder==RowMajor) && (!ConjugateLhs))) { \ + Map, 0, OuterStride<> > lhs(_lhs,m,m,OuterStride<>(lhsStride)); \ + a_tmp = lhs.conjugate(); \ + a = a_tmp.data(); \ + lda = a_tmp.outerStride(); \ + } else a = _lhs; \ + if (LhsStorageOrder==RowMajor) uplo='U'; \ +\ + if (RhsStorageOrder==ColMajor && (!ConjugateRhs)) { \ + b = _rhs; } \ + else { \ + if (RhsStorageOrder==ColMajor && ConjugateRhs) { \ + Map > rhs(_rhs,m,n,OuterStride<>(rhsStride)); \ + b_tmp = rhs.conjugate(); \ + } else \ + if (ConjugateRhs) { \ + Map > rhs(_rhs,n,m,OuterStride<>(rhsStride)); \ + b_tmp = rhs.adjoint(); \ + } else { \ + Map > rhs(_rhs,n,m,OuterStride<>(rhsStride)); \ + b_tmp = rhs.transpose(); \ + } \ + b = b_tmp.data(); \ + ldb = b_tmp.outerStride(); \ + } \ +\ + MKLPREFIX##hemm(&side, &uplo, &m, &n, &alpha_, (const MKLTYPE*)a, &lda, (const MKLTYPE*)b, &ldb, &beta_, (MKLTYPE*)res, &ldc); \ +\ + } \ +}; + +EIGEN_MKL_SYMM_L(double, double, d, d) +EIGEN_MKL_SYMM_L(float, float, f, s) +EIGEN_MKL_HEMM_L(dcomplex, MKL_Complex16, cd, z) +EIGEN_MKL_HEMM_L(scomplex, MKL_Complex8, cf, c) + + +/* Optimized matrix * selfadjoint matrix (?SYMM/?HEMM) product */ + +#define EIGEN_MKL_SYMM_R(EIGTYPE, MKLTYPE, EIGPREFIX, MKLPREFIX) \ +template \ +struct product_selfadjoint_matrix \ +{\ +\ + static EIGEN_DONT_INLINE void run( \ + Index rows, Index cols, \ + const EIGTYPE* _lhs, Index lhsStride, \ + const EIGTYPE* _rhs, Index rhsStride, \ + EIGTYPE* res, Index resStride, \ + EIGTYPE alpha) \ + { \ + char side='R', uplo='L'; \ + MKL_INT m, n, lda, ldb, ldc; \ + const EIGTYPE *a, *b; \ + MKLTYPE alpha_, beta_; \ + MatrixX##EIGPREFIX b_tmp; \ + EIGTYPE myone(1);\ +\ +/* Set m, n, k */ \ + m = (MKL_INT)rows; \ + n = (MKL_INT)cols; \ +\ +/* Set alpha_ & beta_ */ \ + assign_scalar_eig2mkl(alpha_, alpha); \ + assign_scalar_eig2mkl(beta_, myone); \ +\ +/* Set lda, ldb, ldc */ \ + lda = (MKL_INT)rhsStride; \ + ldb = (MKL_INT)lhsStride; \ + ldc = (MKL_INT)resStride; \ +\ +/* Set a, b, c */ \ + if (RhsStorageOrder==RowMajor) uplo='U'; \ + a = _rhs; \ +\ + if (LhsStorageOrder==RowMajor) { \ + Map > lhs(_lhs,n,m,OuterStride<>(rhsStride)); \ + b_tmp = lhs.adjoint(); \ + b = b_tmp.data(); \ + ldb = b_tmp.outerStride(); \ + } else b = _lhs; \ +\ + MKLPREFIX##symm(&side, &uplo, &m, &n, &alpha_, (const MKLTYPE*)a, &lda, (const MKLTYPE*)b, &ldb, &beta_, (MKLTYPE*)res, &ldc); \ +\ + } \ +}; + + +#define EIGEN_MKL_HEMM_R(EIGTYPE, MKLTYPE, EIGPREFIX, MKLPREFIX) \ +template \ +struct product_selfadjoint_matrix \ +{\ + static EIGEN_DONT_INLINE void run( \ + Index rows, Index cols, \ + const EIGTYPE* _lhs, Index lhsStride, \ + const EIGTYPE* _rhs, Index rhsStride, \ + EIGTYPE* res, Index resStride, \ + EIGTYPE alpha) \ + { \ + char side='R', uplo='L'; \ + MKL_INT m, n, lda, ldb, ldc; \ + const EIGTYPE *a, *b; \ + MKLTYPE alpha_, beta_; \ + MatrixX##EIGPREFIX b_tmp; \ + Matrix a_tmp; \ + EIGTYPE myone(1); \ +\ +/* Set m, n, k */ \ + m = (MKL_INT)rows; \ + n = (MKL_INT)cols; \ +\ +/* Set alpha_ & beta_ */ \ + assign_scalar_eig2mkl(alpha_, alpha); \ + assign_scalar_eig2mkl(beta_, myone); \ +\ +/* Set lda, ldb, ldc */ \ + lda = (MKL_INT)rhsStride; \ + ldb = (MKL_INT)lhsStride; \ + ldc = (MKL_INT)resStride; \ +\ +/* Set a, b, c */ \ + if (((RhsStorageOrder==ColMajor) && ConjugateRhs) || ((RhsStorageOrder==RowMajor) && (!ConjugateRhs))) { \ + Map, 0, OuterStride<> > rhs(_rhs,n,n,OuterStride<>(rhsStride)); \ + a_tmp = rhs.conjugate(); \ + a = a_tmp.data(); \ + lda = a_tmp.outerStride(); \ + } else a = _rhs; \ + if (RhsStorageOrder==RowMajor) uplo='U'; \ +\ + if (LhsStorageOrder==ColMajor && (!ConjugateLhs)) { \ + b = _lhs; } \ + else { \ + if (LhsStorageOrder==ColMajor && ConjugateLhs) { \ + Map > lhs(_lhs,m,n,OuterStride<>(lhsStride)); \ + b_tmp = lhs.conjugate(); \ + } else \ + if (ConjugateLhs) { \ + Map > lhs(_lhs,n,m,OuterStride<>(lhsStride)); \ + b_tmp = lhs.adjoint(); \ + } else { \ + Map > lhs(_lhs,n,m,OuterStride<>(lhsStride)); \ + b_tmp = lhs.transpose(); \ + } \ + b = b_tmp.data(); \ + ldb = b_tmp.outerStride(); \ + } \ +\ + MKLPREFIX##hemm(&side, &uplo, &m, &n, &alpha_, (const MKLTYPE*)a, &lda, (const MKLTYPE*)b, &ldb, &beta_, (MKLTYPE*)res, &ldc); \ + } \ +}; + +EIGEN_MKL_SYMM_R(double, double, d, d) +EIGEN_MKL_SYMM_R(float, float, f, s) +EIGEN_MKL_HEMM_R(dcomplex, MKL_Complex16, cd, z) +EIGEN_MKL_HEMM_R(scomplex, MKL_Complex8, cf, c) + +} // end namespace internal + +} // end namespace Eigen + +#endif // EIGEN_SELFADJOINT_MATRIX_MATRIX_MKL_H diff --git a/extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixVector.h b/extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixVector.h index d6121fc07bd..c3145c69a5f 100644 --- a/extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixVector.h +++ b/extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixVector.h @@ -3,28 +3,15 @@ // // Copyright (C) 2008-2009 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_SELFADJOINT_MATRIX_VECTOR_H #define EIGEN_SELFADJOINT_MATRIX_VECTOR_H +namespace Eigen { + namespace internal { /* Optimized selfadjoint matrix * vector product: @@ -32,8 +19,15 @@ namespace internal { * the number of load/stores of the result by a factor 2 and to reduce * the instruction dependency. */ -template -static EIGEN_DONT_INLINE void product_selfadjoint_vector( + +template +struct selfadjoint_matrix_vector_product; + +template +struct selfadjoint_matrix_vector_product + +{ +static EIGEN_DONT_INLINE void run( Index size, const Scalar* lhs, Index lhsStride, const Scalar* _rhs, Index rhsIncr, @@ -85,14 +79,14 @@ static EIGEN_DONT_INLINE void product_selfadjoint_vector( Scalar t1 = cjAlpha * rhs[j+1]; Packet ptmp1 = pset1(t1); - Scalar t2 = 0; + Scalar t2(0); Packet ptmp2 = pset1(t2); - Scalar t3 = 0; + Scalar t3(0); Packet ptmp3 = pset1(t3); size_t starti = FirstTriangular ? 0 : j+2; size_t endi = FirstTriangular ? j : size; - size_t alignedStart = (starti) + first_aligned(&res[starti], endi-starti); + size_t alignedStart = (starti) + internal::first_aligned(&res[starti], endi-starti); size_t alignedEnd = alignedStart + ((endi-alignedStart)/(PacketSize))*(PacketSize); // TODO make sure this product is a real * complex and that the rhs is properly conjugated if needed @@ -148,7 +142,7 @@ static EIGEN_DONT_INLINE void product_selfadjoint_vector( register const Scalar* EIGEN_RESTRICT A0 = lhs + j*lhsStride; Scalar t1 = cjAlpha * rhs[j]; - Scalar t2 = 0; + Scalar t2(0); // TODO make sure this product is a real * complex and that the rhs is properly conjugated if needed res[j] += cjd.pmul(internal::real(A0[j]), t1); for (Index i=FirstTriangular ? 0 : j+1; i<(FirstTriangular ? j : size); i++) @@ -159,6 +153,7 @@ static EIGEN_DONT_INLINE void product_selfadjoint_vector( res[j] += alpha * t2; } } +}; } // end namespace internal @@ -193,8 +188,8 @@ struct SelfadjointProductMatrix eigen_assert(dest.rows()==m_lhs.rows() && dest.cols()==m_rhs.cols()); - const ActualLhsType lhs = LhsBlasTraits::extract(m_lhs); - const ActualRhsType rhs = RhsBlasTraits::extract(m_rhs); + typename internal::add_const_on_value_type::type lhs = LhsBlasTraits::extract(m_lhs); + typename internal::add_const_on_value_type::type rhs = RhsBlasTraits::extract(m_rhs); Scalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(m_lhs) * RhsBlasTraits::extractScalarFactor(m_rhs); @@ -232,7 +227,7 @@ struct SelfadjointProductMatrix } - internal::product_selfadjoint_vector::Flags&RowMajorBit) ? RowMajor : ColMajor, int(LhsUpLo), bool(LhsBlasTraits::NeedToConjugate), bool(RhsBlasTraits::NeedToConjugate)> + internal::selfadjoint_matrix_vector_product::Flags&RowMajorBit) ? RowMajor : ColMajor, int(LhsUpLo), bool(LhsBlasTraits::NeedToConjugate), bool(RhsBlasTraits::NeedToConjugate)>::run ( lhs.rows(), // size &lhs.coeffRef(0,0), lhs.outerStride(), // lhs info @@ -274,5 +269,6 @@ struct SelfadjointProductMatrix } }; +} // end namespace Eigen #endif // EIGEN_SELFADJOINT_MATRIX_VECTOR_H diff --git a/extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixVector_MKL.h b/extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixVector_MKL.h new file mode 100644 index 00000000000..f88d483b653 --- /dev/null +++ b/extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixVector_MKL.h @@ -0,0 +1,114 @@ +/* + Copyright (c) 2011, Intel Corporation. All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of Intel Corporation nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ******************************************************************************** + * Content : Eigen bindings to Intel(R) MKL + * Selfadjoint matrix-vector product functionality based on ?SYMV/HEMV. + ******************************************************************************** +*/ + +#ifndef EIGEN_SELFADJOINT_MATRIX_VECTOR_MKL_H +#define EIGEN_SELFADJOINT_MATRIX_VECTOR_MKL_H + +namespace Eigen { + +namespace internal { + +/********************************************************************** +* This file implements selfadjoint matrix-vector multiplication using BLAS +**********************************************************************/ + +// symv/hemv specialization + +template +struct selfadjoint_matrix_vector_product_symv : + selfadjoint_matrix_vector_product {}; + +#define EIGEN_MKL_SYMV_SPECIALIZE(Scalar) \ +template \ +struct selfadjoint_matrix_vector_product { \ +static EIGEN_DONT_INLINE void run( \ + Index size, const Scalar* lhs, Index lhsStride, \ + const Scalar* _rhs, Index rhsIncr, Scalar* res, Scalar alpha) { \ + enum {\ + IsColMajor = StorageOrder==ColMajor \ + }; \ + if (IsColMajor == ConjugateLhs) {\ + selfadjoint_matrix_vector_product::run( \ + size, lhs, lhsStride, _rhs, rhsIncr, res, alpha); \ + } else {\ + selfadjoint_matrix_vector_product_symv::run( \ + size, lhs, lhsStride, _rhs, rhsIncr, res, alpha); \ + }\ + } \ +}; \ + +EIGEN_MKL_SYMV_SPECIALIZE(double) +EIGEN_MKL_SYMV_SPECIALIZE(float) +EIGEN_MKL_SYMV_SPECIALIZE(dcomplex) +EIGEN_MKL_SYMV_SPECIALIZE(scomplex) + +#define EIGEN_MKL_SYMV_SPECIALIZATION(EIGTYPE,MKLTYPE,MKLFUNC) \ +template \ +struct selfadjoint_matrix_vector_product_symv \ +{ \ +typedef Matrix SYMVVector;\ +\ +static EIGEN_DONT_INLINE void run( \ +Index size, const EIGTYPE* lhs, Index lhsStride, \ +const EIGTYPE* _rhs, Index rhsIncr, EIGTYPE* res, EIGTYPE alpha) \ +{ \ + enum {\ + IsRowMajor = StorageOrder==RowMajor ? 1 : 0, \ + IsLower = UpLo == Lower ? 1 : 0 \ + }; \ + MKL_INT n=size, lda=lhsStride, incx=rhsIncr, incy=1; \ + MKLTYPE alpha_, beta_; \ + const EIGTYPE *x_ptr, myone(1); \ + char uplo=(IsRowMajor) ? (IsLower ? 'U' : 'L') : (IsLower ? 'L' : 'U'); \ + assign_scalar_eig2mkl(alpha_, alpha); \ + assign_scalar_eig2mkl(beta_, myone); \ + SYMVVector x_tmp; \ + if (ConjugateRhs) { \ + Map > map_x(_rhs,size,1,InnerStride<>(incx)); \ + x_tmp=map_x.conjugate(); \ + x_ptr=x_tmp.data(); \ + incx=1; \ + } else x_ptr=_rhs; \ + MKLFUNC(&uplo, &n, &alpha_, (const MKLTYPE*)lhs, &lda, (const MKLTYPE*)x_ptr, &incx, &beta_, (MKLTYPE*)res, &incy); \ +}\ +}; + +EIGEN_MKL_SYMV_SPECIALIZATION(double, double, dsymv) +EIGEN_MKL_SYMV_SPECIALIZATION(float, float, ssymv) +EIGEN_MKL_SYMV_SPECIALIZATION(dcomplex, MKL_Complex16, zhemv) +EIGEN_MKL_SYMV_SPECIALIZATION(scomplex, MKL_Complex8, chemv) + +} // end namespace internal + +} // end namespace Eigen + +#endif // EIGEN_SELFADJOINT_MATRIX_VECTOR_MKL_H diff --git a/extern/Eigen3/Eigen/src/Core/products/SelfadjointProduct.h b/extern/Eigen3/Eigen/src/Core/products/SelfadjointProduct.h index 3a4523fa4a9..6a55f3d7715 100644 --- a/extern/Eigen3/Eigen/src/Core/products/SelfadjointProduct.h +++ b/extern/Eigen3/Eigen/src/Core/products/SelfadjointProduct.h @@ -3,24 +3,9 @@ // // Copyright (C) 2009 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_SELFADJOINT_PRODUCT_H #define EIGEN_SELFADJOINT_PRODUCT_H @@ -31,6 +16,8 @@ * It corresponds to the level 3 SYRK and level 2 SYR Blas routines. **********************************************************************/ +namespace Eigen { + template struct selfadjoint_rank1_update; @@ -72,7 +59,7 @@ struct selfadjoint_product_selector typedef internal::blas_traits OtherBlasTraits; typedef typename OtherBlasTraits::DirectLinearAccessType ActualOtherType; typedef typename internal::remove_all::type _ActualOtherType; - const ActualOtherType actualOther = OtherBlasTraits::extract(other.derived()); + typename internal::add_const_on_value_type::type actualOther = OtherBlasTraits::extract(other.derived()); Scalar actualAlpha = alpha * OtherBlasTraits::extractScalarFactor(other.derived()); @@ -105,12 +92,12 @@ struct selfadjoint_product_selector typedef internal::blas_traits OtherBlasTraits; typedef typename OtherBlasTraits::DirectLinearAccessType ActualOtherType; typedef typename internal::remove_all::type _ActualOtherType; - const ActualOtherType actualOther = OtherBlasTraits::extract(other.derived()); + typename internal::add_const_on_value_type::type actualOther = OtherBlasTraits::extract(other.derived()); Scalar actualAlpha = alpha * OtherBlasTraits::extractScalarFactor(other.derived()); enum { IsRowMajor = (internal::traits::Flags&RowMajorBit) ? 1 : 0 }; - + internal::general_matrix_matrix_triangular_product::IsComplex, Scalar, _ActualOtherType::Flags&RowMajorBit ? ColMajor : RowMajor, (!OtherBlasTraits::NeedToConjugate) && NumTraits::IsComplex, @@ -133,4 +120,6 @@ SelfAdjointView& SelfAdjointView return *this; } +} // end namespace Eigen + #endif // EIGEN_SELFADJOINT_PRODUCT_H diff --git a/extern/Eigen3/Eigen/src/Core/products/SelfadjointRank2Update.h b/extern/Eigen3/Eigen/src/Core/products/SelfadjointRank2Update.h index 9f8b8438a5d..57a98cc2de9 100644 --- a/extern/Eigen3/Eigen/src/Core/products/SelfadjointRank2Update.h +++ b/extern/Eigen3/Eigen/src/Core/products/SelfadjointRank2Update.h @@ -3,28 +3,15 @@ // // Copyright (C) 2009 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_SELFADJOINTRANK2UPTADE_H #define EIGEN_SELFADJOINTRANK2UPTADE_H +namespace Eigen { + namespace internal { /* Optimized selfadjoint matrix += alpha * uv' + conj(alpha)*vu' @@ -76,12 +63,12 @@ SelfAdjointView& SelfAdjointView typedef internal::blas_traits UBlasTraits; typedef typename UBlasTraits::DirectLinearAccessType ActualUType; typedef typename internal::remove_all::type _ActualUType; - const ActualUType actualU = UBlasTraits::extract(u.derived()); + typename internal::add_const_on_value_type::type actualU = UBlasTraits::extract(u.derived()); typedef internal::blas_traits VBlasTraits; typedef typename VBlasTraits::DirectLinearAccessType ActualVType; typedef typename internal::remove_all::type _ActualVType; - const ActualVType actualV = VBlasTraits::extract(v.derived()); + typename internal::add_const_on_value_type::type actualV = VBlasTraits::extract(v.derived()); // If MatrixType is row major, then we use the routine for lower triangular in the upper triangular case and // vice versa, and take the complex conjugate of all coefficients and vector entries. @@ -101,4 +88,6 @@ SelfAdjointView& SelfAdjointView return *this; } +} // end namespace Eigen + #endif // EIGEN_SELFADJOINTRANK2UPTADE_H diff --git a/extern/Eigen3/Eigen/src/Core/products/TriangularMatrixMatrix.h b/extern/Eigen3/Eigen/src/Core/products/TriangularMatrixMatrix.h index 0c48d2efb75..92cba66f615 100644 --- a/extern/Eigen3/Eigen/src/Core/products/TriangularMatrixMatrix.h +++ b/extern/Eigen3/Eigen/src/Core/products/TriangularMatrixMatrix.h @@ -3,28 +3,15 @@ // // Copyright (C) 2009 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_TRIANGULAR_MATRIX_MATRIX_H #define EIGEN_TRIANGULAR_MATRIX_MATRIX_H +namespace Eigen { + namespace internal { // template @@ -58,23 +45,23 @@ template + int ResStorageOrder, int Version = Specialized> struct product_triangular_matrix_matrix; template + int RhsStorageOrder, bool ConjugateRhs, int Version> struct product_triangular_matrix_matrix + RhsStorageOrder,ConjugateRhs,RowMajor,Version> { static EIGEN_STRONG_INLINE void run( Index rows, Index cols, Index depth, const Scalar* lhs, Index lhsStride, const Scalar* rhs, Index rhsStride, Scalar* res, Index resStride, - Scalar alpha) + Scalar alpha, level3_blocking& blocking) { product_triangular_matrix_matrix - ::run(cols, rows, depth, rhs, rhsStride, lhs, lhsStride, res, resStride, alpha); + ::run(cols, rows, depth, rhs, rhsStride, lhs, lhsStride, res, resStride, alpha, blocking); } }; // implements col-major += alpha * op(triangular) * op(general) template + int RhsStorageOrder, bool ConjugateRhs, int Version> struct product_triangular_matrix_matrix + RhsStorageOrder,ConjugateRhs,ColMajor,Version> { typedef gebp_traits Traits; enum { - SmallPanelWidth = EIGEN_PLAIN_ENUM_MAX(Traits::mr,Traits::nr), + SmallPanelWidth = 2 * EIGEN_PLAIN_ENUM_MAX(Traits::mr,Traits::nr), IsLower = (Mode&Lower) == Lower, SetDiag = (Mode&(ZeroDiag|UnitDiag)) ? 0 : 1 }; @@ -109,7 +96,7 @@ struct product_triangular_matrix_matrix& blocking) { // strip zeros Index diagSize = (std::min)(_rows,_depth); @@ -120,15 +107,16 @@ struct product_triangular_matrix_matrix lhs(_lhs,lhsStride); const_blas_data_mapper rhs(_rhs,rhsStride); - Index kc = depth; // cache block size along the K direction - Index mc = rows; // cache block size along the M direction - Index nc = cols; // cache block size along the N direction - computeProductBlockingSizes(kc, mc, nc); + Index kc = blocking.kc(); // cache block size along the K direction + Index mc = (std::min)(rows,blocking.mc()); // cache block size along the M direction + + std::size_t sizeA = kc*mc; + std::size_t sizeB = kc*cols; std::size_t sizeW = kc*Traits::WorkSpaceFactor; - std::size_t sizeB = sizeW + kc*cols; - ei_declare_aligned_stack_constructed_variable(Scalar, blockA, kc*mc, 0); - ei_declare_aligned_stack_constructed_variable(Scalar, allocatedBlockB, sizeB, 0); - Scalar* blockB = allocatedBlockB + sizeW; + + ei_declare_aligned_stack_constructed_variable(Scalar, blockA, sizeA, blocking.blockA()); + ei_declare_aligned_stack_constructed_variable(Scalar, blockB, sizeB, blocking.blockB()); + ei_declare_aligned_stack_constructed_variable(Scalar, blockW, sizeW, blocking.blockW()); Matrix triangularBuffer; triangularBuffer.setZero(); @@ -186,7 +174,7 @@ struct product_triangular_matrix_matrix0) @@ -196,7 +184,7 @@ struct product_triangular_matrix_matrix() (blockA, &lhs(i2, actual_k2), lhsStride, actual_kc, actual_mc); - gebp_kernel(res+i2, resStride, blockA, blockB, actual_mc, actual_kc, cols, alpha); + gebp_kernel(res+i2, resStride, blockA, blockB, actual_mc, actual_kc, cols, alpha, -1, -1, 0, 0, blockW); } } } @@ -220,10 +208,10 @@ struct product_triangular_matrix_matrix + int RhsStorageOrder, bool ConjugateRhs, int Version> struct product_triangular_matrix_matrix + RhsStorageOrder,ConjugateRhs,ColMajor,Version> { typedef gebp_traits Traits; enum { @@ -237,7 +225,7 @@ struct product_triangular_matrix_matrix& blocking) { // strip zeros Index diagSize = (std::min)(_cols,_depth); @@ -248,16 +236,16 @@ struct product_triangular_matrix_matrix lhs(_lhs,lhsStride); const_blas_data_mapper rhs(_rhs,rhsStride); - Index kc = depth; // cache block size along the K direction - Index mc = rows; // cache block size along the M direction - Index nc = cols; // cache block size along the N direction - computeProductBlockingSizes(kc, mc, nc); + Index kc = blocking.kc(); // cache block size along the K direction + Index mc = (std::min)(rows,blocking.mc()); // cache block size along the M direction + std::size_t sizeA = kc*mc; + std::size_t sizeB = kc*cols; std::size_t sizeW = kc*Traits::WorkSpaceFactor; - std::size_t sizeB = sizeW + kc*cols; - ei_declare_aligned_stack_constructed_variable(Scalar, blockA, kc*mc, 0); - ei_declare_aligned_stack_constructed_variable(Scalar, allocatedBlockB, sizeB, 0); - Scalar* blockB = allocatedBlockB + sizeW; + + ei_declare_aligned_stack_constructed_variable(Scalar, blockA, sizeA, blocking.blockA()); + ei_declare_aligned_stack_constructed_variable(Scalar, blockB, sizeB, blocking.blockB()); + ei_declare_aligned_stack_constructed_variable(Scalar, blockW, sizeW, blocking.blockW()); Matrix triangularBuffer; triangularBuffer.setZero(); @@ -345,13 +333,13 @@ struct product_triangular_matrix_matrix template void scaleAndAddTo(Dest& dst, Scalar alpha) const { - const ActualLhsType lhs = LhsBlasTraits::extract(m_lhs); - const ActualRhsType rhs = RhsBlasTraits::extract(m_rhs); + typename internal::add_const_on_value_type::type lhs = LhsBlasTraits::extract(m_lhs); + typename internal::add_const_on_value_type::type rhs = RhsBlasTraits::extract(m_rhs); Scalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(m_lhs) * RhsBlasTraits::extractScalarFactor(m_rhs); + typedef internal::gemm_blocking_space<(Dest::Flags&RowMajorBit) ? RowMajor : ColMajor,Scalar,Scalar, + Lhs::MaxRowsAtCompileTime, Rhs::MaxColsAtCompileTime, Lhs::MaxColsAtCompileTime,4> BlockingType; + + enum { IsLower = (Mode&Lower) == Lower }; + Index stripedRows = ((!LhsIsTriangular) || (IsLower)) ? lhs.rows() : (std::min)(lhs.rows(),lhs.cols()); + Index stripedCols = ((LhsIsTriangular) || (!IsLower)) ? rhs.cols() : (std::min)(rhs.cols(),rhs.rows()); + Index stripedDepth = LhsIsTriangular ? ((!IsLower) ? lhs.cols() : (std::min)(lhs.cols(),lhs.rows())) + : ((IsLower) ? rhs.rows() : (std::min)(rhs.rows(),rhs.cols())); + + BlockingType blocking(stripedRows, stripedCols, stripedDepth); + internal::product_triangular_matrix_matrix::Flags&RowMajorBit) ? RowMajor : ColMajor, LhsBlasTraits::NeedToConjugate, (internal::traits<_ActualRhsType>::Flags&RowMajorBit) ? RowMajor : ColMajor, RhsBlasTraits::NeedToConjugate, (internal::traits::Flags&RowMajorBit) ? RowMajor : ColMajor> ::run( - lhs.rows(), rhs.cols(), lhs.cols(),// LhsIsTriangular ? rhs.cols() : lhs.rows(), // sizes + stripedRows, stripedCols, stripedDepth, // sizes &lhs.coeffRef(0,0), lhs.outerStride(), // lhs info &rhs.coeffRef(0,0), rhs.outerStride(), // rhs info - &dst.coeffRef(0,0), dst.outerStride(), // result info - actualAlpha // alpha + &dst.coeffRef(0,0), dst.outerStride(), // result info + actualAlpha, blocking ); } }; +} // end namespace Eigen #endif // EIGEN_TRIANGULAR_MATRIX_MATRIX_H diff --git a/extern/Eigen3/Eigen/src/Core/products/TriangularMatrixMatrix_MKL.h b/extern/Eigen3/Eigen/src/Core/products/TriangularMatrixMatrix_MKL.h new file mode 100644 index 00000000000..8173da5bb6d --- /dev/null +++ b/extern/Eigen3/Eigen/src/Core/products/TriangularMatrixMatrix_MKL.h @@ -0,0 +1,309 @@ +/* + Copyright (c) 2011, Intel Corporation. All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of Intel Corporation nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ******************************************************************************** + * Content : Eigen bindings to Intel(R) MKL + * Triangular matrix * matrix product functionality based on ?TRMM. + ******************************************************************************** +*/ + +#ifndef EIGEN_TRIANGULAR_MATRIX_MATRIX_MKL_H +#define EIGEN_TRIANGULAR_MATRIX_MATRIX_MKL_H + +namespace Eigen { + +namespace internal { + + +template +struct product_triangular_matrix_matrix_trmm : + product_triangular_matrix_matrix {}; + + +// try to go to BLAS specialization +#define EIGEN_MKL_TRMM_SPECIALIZE(Scalar, LhsIsTriangular) \ +template \ +struct product_triangular_matrix_matrix { \ + static inline void run(Index _rows, Index _cols, Index _depth, const Scalar* _lhs, Index lhsStride,\ + const Scalar* _rhs, Index rhsStride, Scalar* res, Index resStride, Scalar alpha) { \ + product_triangular_matrix_matrix_trmm::run( \ + _rows, _cols, _depth, _lhs, lhsStride, _rhs, rhsStride, res, resStride, alpha); \ + } \ +}; + +EIGEN_MKL_TRMM_SPECIALIZE(double, true) +EIGEN_MKL_TRMM_SPECIALIZE(double, false) +EIGEN_MKL_TRMM_SPECIALIZE(dcomplex, true) +EIGEN_MKL_TRMM_SPECIALIZE(dcomplex, false) +EIGEN_MKL_TRMM_SPECIALIZE(float, true) +EIGEN_MKL_TRMM_SPECIALIZE(float, false) +EIGEN_MKL_TRMM_SPECIALIZE(scomplex, true) +EIGEN_MKL_TRMM_SPECIALIZE(scomplex, false) + +// implements col-major += alpha * op(triangular) * op(general) +#define EIGEN_MKL_TRMM_L(EIGTYPE, MKLTYPE, EIGPREFIX, MKLPREFIX) \ +template \ +struct product_triangular_matrix_matrix_trmm \ +{ \ + enum { \ + IsLower = (Mode&Lower) == Lower, \ + SetDiag = (Mode&(ZeroDiag|UnitDiag)) ? 0 : 1, \ + IsUnitDiag = (Mode&UnitDiag) ? 1 : 0, \ + IsZeroDiag = (Mode&ZeroDiag) ? 1 : 0, \ + LowUp = IsLower ? Lower : Upper, \ + conjA = ((LhsStorageOrder==ColMajor) && ConjugateLhs) ? 1 : 0 \ + }; \ +\ + static EIGEN_DONT_INLINE void run( \ + Index _rows, Index _cols, Index _depth, \ + const EIGTYPE* _lhs, Index lhsStride, \ + const EIGTYPE* _rhs, Index rhsStride, \ + EIGTYPE* res, Index resStride, \ + EIGTYPE alpha) \ + { \ + Index diagSize = (std::min)(_rows,_depth); \ + Index rows = IsLower ? _rows : diagSize; \ + Index depth = IsLower ? diagSize : _depth; \ + Index cols = _cols; \ +\ + typedef Matrix MatrixLhs; \ + typedef Matrix MatrixRhs; \ +\ +/* Non-square case - doesn't fit to MKL ?TRMM. Fall to default triangular product or call MKL ?GEMM*/ \ + if (rows != depth) { \ +\ + int nthr = mkl_domain_get_max_threads(MKL_BLAS); \ +\ + if (((nthr==1) && (((std::max)(rows,depth)-diagSize)/(double)diagSize < 0.5))) { \ + /* Most likely no benefit to call TRMM or GEMM from MKL*/ \ + product_triangular_matrix_matrix::run( \ + _rows, _cols, _depth, _lhs, lhsStride, _rhs, rhsStride, res, resStride, alpha); \ + /*std::cout << "TRMM_L: A is not square! Go to Eigen TRMM implementation!\n";*/ \ + } else { \ + /* Make sense to call GEMM */ \ + Map > lhsMap(_lhs,rows,depth,OuterStride<>(lhsStride)); \ + MatrixLhs aa_tmp=lhsMap.template triangularView(); \ + MKL_INT aStride = aa_tmp.outerStride(); \ + gemm_blocking_space blocking(_rows,_cols,_depth); \ + general_matrix_matrix_product::run( \ + rows, cols, depth, aa_tmp.data(), aStride, _rhs, rhsStride, res, resStride, alpha, blocking, 0); \ +\ + /*std::cout << "TRMM_L: A is not square! Go to MKL GEMM implementation! " << nthr<<" \n";*/ \ + } \ + return; \ + } \ + char side = 'L', transa, uplo, diag = 'N'; \ + EIGTYPE *b; \ + const EIGTYPE *a; \ + MKL_INT m, n, lda, ldb; \ + MKLTYPE alpha_; \ +\ +/* Set alpha_*/ \ + assign_scalar_eig2mkl(alpha_, alpha); \ +\ +/* Set m, n */ \ + m = (MKL_INT)diagSize; \ + n = (MKL_INT)cols; \ +\ +/* Set trans */ \ + transa = (LhsStorageOrder==RowMajor) ? ((ConjugateLhs) ? 'C' : 'T') : 'N'; \ +\ +/* Set b, ldb */ \ + Map > rhs(_rhs,depth,cols,OuterStride<>(rhsStride)); \ + MatrixX##EIGPREFIX b_tmp; \ +\ + if (ConjugateRhs) b_tmp = rhs.conjugate(); else b_tmp = rhs; \ + b = b_tmp.data(); \ + ldb = b_tmp.outerStride(); \ +\ +/* Set uplo */ \ + uplo = IsLower ? 'L' : 'U'; \ + if (LhsStorageOrder==RowMajor) uplo = (uplo == 'L') ? 'U' : 'L'; \ +/* Set a, lda */ \ + Map > lhs(_lhs,rows,depth,OuterStride<>(lhsStride)); \ + MatrixLhs a_tmp; \ +\ + if ((conjA!=0) || (SetDiag==0)) { \ + if (conjA) a_tmp = lhs.conjugate(); else a_tmp = lhs; \ + if (IsZeroDiag) \ + a_tmp.diagonal().setZero(); \ + else if (IsUnitDiag) \ + a_tmp.diagonal().setOnes();\ + a = a_tmp.data(); \ + lda = a_tmp.outerStride(); \ + } else { \ + a = _lhs; \ + lda = lhsStride; \ + } \ + /*std::cout << "TRMM_L: A is square! Go to MKL TRMM implementation! \n";*/ \ +/* call ?trmm*/ \ + MKLPREFIX##trmm(&side, &uplo, &transa, &diag, &m, &n, &alpha_, (const MKLTYPE*)a, &lda, (MKLTYPE*)b, &ldb); \ +\ +/* Add op(a_triangular)*b into res*/ \ + Map > res_tmp(res,rows,cols,OuterStride<>(resStride)); \ + res_tmp=res_tmp+b_tmp; \ + } \ +}; + +EIGEN_MKL_TRMM_L(double, double, d, d) +EIGEN_MKL_TRMM_L(dcomplex, MKL_Complex16, cd, z) +EIGEN_MKL_TRMM_L(float, float, f, s) +EIGEN_MKL_TRMM_L(scomplex, MKL_Complex8, cf, c) + +// implements col-major += alpha * op(general) * op(triangular) +#define EIGEN_MKL_TRMM_R(EIGTYPE, MKLTYPE, EIGPREFIX, MKLPREFIX) \ +template \ +struct product_triangular_matrix_matrix_trmm \ +{ \ + enum { \ + IsLower = (Mode&Lower) == Lower, \ + SetDiag = (Mode&(ZeroDiag|UnitDiag)) ? 0 : 1, \ + IsUnitDiag = (Mode&UnitDiag) ? 1 : 0, \ + IsZeroDiag = (Mode&ZeroDiag) ? 1 : 0, \ + LowUp = IsLower ? Lower : Upper, \ + conjA = ((RhsStorageOrder==ColMajor) && ConjugateRhs) ? 1 : 0 \ + }; \ +\ + static EIGEN_DONT_INLINE void run( \ + Index _rows, Index _cols, Index _depth, \ + const EIGTYPE* _lhs, Index lhsStride, \ + const EIGTYPE* _rhs, Index rhsStride, \ + EIGTYPE* res, Index resStride, \ + EIGTYPE alpha) \ + { \ + Index diagSize = (std::min)(_cols,_depth); \ + Index rows = _rows; \ + Index depth = IsLower ? _depth : diagSize; \ + Index cols = IsLower ? diagSize : _cols; \ +\ + typedef Matrix MatrixLhs; \ + typedef Matrix MatrixRhs; \ +\ +/* Non-square case - doesn't fit to MKL ?TRMM. Fall to default triangular product or call MKL ?GEMM*/ \ + if (cols != depth) { \ +\ + int nthr = mkl_domain_get_max_threads(MKL_BLAS); \ +\ + if ((nthr==1) && (((std::max)(cols,depth)-diagSize)/(double)diagSize < 0.5)) { \ + /* Most likely no benefit to call TRMM or GEMM from MKL*/ \ + product_triangular_matrix_matrix::run( \ + _rows, _cols, _depth, _lhs, lhsStride, _rhs, rhsStride, res, resStride, alpha); \ + /*std::cout << "TRMM_R: A is not square! Go to Eigen TRMM implementation!\n";*/ \ + } else { \ + /* Make sense to call GEMM */ \ + Map > rhsMap(_rhs,depth,cols, OuterStride<>(rhsStride)); \ + MatrixRhs aa_tmp=rhsMap.template triangularView(); \ + MKL_INT aStride = aa_tmp.outerStride(); \ + gemm_blocking_space blocking(_rows,_cols,_depth); \ + general_matrix_matrix_product::run( \ + rows, cols, depth, _lhs, lhsStride, aa_tmp.data(), aStride, res, resStride, alpha, blocking, 0); \ +\ + /*std::cout << "TRMM_R: A is not square! Go to MKL GEMM implementation! " << nthr<<" \n";*/ \ + } \ + return; \ + } \ + char side = 'R', transa, uplo, diag = 'N'; \ + EIGTYPE *b; \ + const EIGTYPE *a; \ + MKL_INT m, n, lda, ldb; \ + MKLTYPE alpha_; \ +\ +/* Set alpha_*/ \ + assign_scalar_eig2mkl(alpha_, alpha); \ +\ +/* Set m, n */ \ + m = (MKL_INT)rows; \ + n = (MKL_INT)diagSize; \ +\ +/* Set trans */ \ + transa = (RhsStorageOrder==RowMajor) ? ((ConjugateRhs) ? 'C' : 'T') : 'N'; \ +\ +/* Set b, ldb */ \ + Map > lhs(_lhs,rows,depth,OuterStride<>(lhsStride)); \ + MatrixX##EIGPREFIX b_tmp; \ +\ + if (ConjugateLhs) b_tmp = lhs.conjugate(); else b_tmp = lhs; \ + b = b_tmp.data(); \ + ldb = b_tmp.outerStride(); \ +\ +/* Set uplo */ \ + uplo = IsLower ? 'L' : 'U'; \ + if (RhsStorageOrder==RowMajor) uplo = (uplo == 'L') ? 'U' : 'L'; \ +/* Set a, lda */ \ + Map > rhs(_rhs,depth,cols, OuterStride<>(rhsStride)); \ + MatrixRhs a_tmp; \ +\ + if ((conjA!=0) || (SetDiag==0)) { \ + if (conjA) a_tmp = rhs.conjugate(); else a_tmp = rhs; \ + if (IsZeroDiag) \ + a_tmp.diagonal().setZero(); \ + else if (IsUnitDiag) \ + a_tmp.diagonal().setOnes();\ + a = a_tmp.data(); \ + lda = a_tmp.outerStride(); \ + } else { \ + a = _rhs; \ + lda = rhsStride; \ + } \ + /*std::cout << "TRMM_R: A is square! Go to MKL TRMM implementation! \n";*/ \ +/* call ?trmm*/ \ + MKLPREFIX##trmm(&side, &uplo, &transa, &diag, &m, &n, &alpha_, (const MKLTYPE*)a, &lda, (MKLTYPE*)b, &ldb); \ +\ +/* Add op(a_triangular)*b into res*/ \ + Map > res_tmp(res,rows,cols,OuterStride<>(resStride)); \ + res_tmp=res_tmp+b_tmp; \ + } \ +}; + +EIGEN_MKL_TRMM_R(double, double, d, d) +EIGEN_MKL_TRMM_R(dcomplex, MKL_Complex16, cd, z) +EIGEN_MKL_TRMM_R(float, float, f, s) +EIGEN_MKL_TRMM_R(scomplex, MKL_Complex8, cf, c) + +} // end namespace internal + +} // end namespace Eigen + +#endif // EIGEN_TRIANGULAR_MATRIX_MATRIX_MKL_H diff --git a/extern/Eigen3/Eigen/src/Core/products/TriangularMatrixVector.h b/extern/Eigen3/Eigen/src/Core/products/TriangularMatrixVector.h index 71b4a52ab80..b1c10c201c5 100644 --- a/extern/Eigen3/Eigen/src/Core/products/TriangularMatrixVector.h +++ b/extern/Eigen3/Eigen/src/Core/products/TriangularMatrixVector.h @@ -3,45 +3,36 @@ // // Copyright (C) 2009 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_TRIANGULARMATRIXVECTOR_H #define EIGEN_TRIANGULARMATRIXVECTOR_H +namespace Eigen { + namespace internal { -template -struct product_triangular_matrix_vector; +template +struct triangular_matrix_vector_product; -template -struct product_triangular_matrix_vector +template +struct triangular_matrix_vector_product { typedef typename scalar_product_traits::ReturnType ResScalar; enum { IsLower = ((Mode&Lower)==Lower), - HasUnitDiag = (Mode & UnitDiag)==UnitDiag + HasUnitDiag = (Mode & UnitDiag)==UnitDiag, + HasZeroDiag = (Mode & ZeroDiag)==ZeroDiag }; - static EIGEN_DONT_INLINE void run(Index rows, Index cols, const LhsScalar* _lhs, Index lhsStride, + static EIGEN_DONT_INLINE void run(Index _rows, Index _cols, const LhsScalar* _lhs, Index lhsStride, const RhsScalar* _rhs, Index rhsIncr, ResScalar* _res, Index resIncr, ResScalar alpha) { static const Index PanelWidth = EIGEN_TUNE_TRIANGULAR_PANEL_WIDTH; + Index size = (std::min)(_rows,_cols); + Index rows = IsLower ? _rows : (std::min)(_rows,_cols); + Index cols = IsLower ? (std::min)(_rows,_cols) : _cols; typedef Map, 0, OuterStride<> > LhsMap; const LhsMap lhs(_lhs,rows,cols,OuterStride<>(lhsStride)); @@ -54,45 +45,57 @@ struct product_triangular_matrix_vector > ResMap; ResMap res(_res,rows); - for (Index pi=0; pi0) + if ((!(HasUnitDiag||HasZeroDiag)) || (--r)>0) res.segment(s,r) += (alpha * cjRhs.coeff(i)) * cjLhs.col(i).segment(s,r); if (HasUnitDiag) res.coeffRef(i) += alpha * cjRhs.coeff(i); } - Index r = IsLower ? cols - pi - actualPanelWidth : pi; + Index r = IsLower ? rows - pi - actualPanelWidth : pi; if (r>0) { Index s = IsLower ? pi+actualPanelWidth : 0; - general_matrix_vector_product::run( + general_matrix_vector_product::run( r, actualPanelWidth, &lhs.coeffRef(s,pi), lhsStride, &rhs.coeffRef(pi), rhsIncr, &res.coeffRef(s), resIncr, alpha); } } + if((!IsLower) && cols>size) + { + general_matrix_vector_product::run( + rows, cols-size, + &lhs.coeffRef(0,size), lhsStride, + &rhs.coeffRef(size), rhsIncr, + _res, resIncr, alpha); + } } }; -template -struct product_triangular_matrix_vector +template +struct triangular_matrix_vector_product { typedef typename scalar_product_traits::ReturnType ResScalar; enum { IsLower = ((Mode&Lower)==Lower), - HasUnitDiag = (Mode & UnitDiag)==UnitDiag + HasUnitDiag = (Mode & UnitDiag)==UnitDiag, + HasZeroDiag = (Mode & ZeroDiag)==ZeroDiag }; - static void run(Index rows, Index cols, const LhsScalar* _lhs, Index lhsStride, + static void run(Index _rows, Index _cols, const LhsScalar* _lhs, Index lhsStride, const RhsScalar* _rhs, Index rhsIncr, ResScalar* _res, Index resIncr, ResScalar alpha) { static const Index PanelWidth = EIGEN_TUNE_TRIANGULAR_PANEL_WIDTH; + Index diagSize = (std::min)(_rows,_cols); + Index rows = IsLower ? _rows : diagSize; + Index cols = IsLower ? diagSize : _cols; typedef Map, 0, OuterStride<> > LhsMap; const LhsMap lhs(_lhs,rows,cols,OuterStride<>(lhsStride)); @@ -105,15 +108,15 @@ struct product_triangular_matrix_vector, 0, InnerStride<> > ResMap; ResMap res(_res,rows,InnerStride<>(resIncr)); - for (Index pi=0; pi0) + if ((!(HasUnitDiag||HasZeroDiag)) || (--r)>0) res.coeffRef(i) += alpha * (cjLhs.row(i).segment(s,r).cwiseProduct(cjRhs.segment(s,r).transpose())).sum(); if (HasUnitDiag) res.coeffRef(i) += alpha * cjRhs.coeff(i); @@ -122,13 +125,21 @@ struct product_triangular_matrix_vector0) { Index s = IsLower ? 0 : pi + actualPanelWidth; - general_matrix_vector_product::run( + general_matrix_vector_product::run( actualPanelWidth, r, &lhs.coeffRef(pi,s), lhsStride, &rhs.coeffRef(s), rhsIncr, &res.coeffRef(pi), resIncr, alpha); } } + if(IsLower && rows>diagSize) + { + general_matrix_vector_product::run( + rows-diagSize, cols, + &lhs.coeffRef(diagSize,0), lhsStride, + &rhs.coeffRef(0), rhsIncr, + &res.coeffRef(diagSize), resIncr, alpha); + } } }; @@ -180,7 +191,7 @@ struct TriangularProduct { eigen_assert(dst.rows()==m_lhs.rows() && dst.cols()==m_rhs.cols()); - typedef TriangularProduct<(Mode & UnitDiag) | ((Mode & Lower) ? Upper : Lower),true,Transpose,false,Transpose,true> TriangularProductTranspose; + typedef TriangularProduct<(Mode & (UnitDiag|ZeroDiag)) | ((Mode & Lower) ? Upper : Lower),true,Transpose,false,Transpose,true> TriangularProductTranspose; Transpose dstT(dst); internal::trmv_selector<(int(internal::traits::Flags)&RowMajorBit) ? ColMajor : RowMajor>::run( TriangularProductTranspose(m_rhs.transpose(),m_lhs.transpose()), dstT, alpha); @@ -208,8 +219,8 @@ template<> struct trmv_selector typedef typename ProductType::RhsBlasTraits RhsBlasTraits; typedef Map, Aligned> MappedDest; - const ActualLhsType actualLhs = LhsBlasTraits::extract(prod.lhs()); - const ActualRhsType actualRhs = RhsBlasTraits::extract(prod.rhs()); + typename internal::add_const_on_value_type::type actualLhs = LhsBlasTraits::extract(prod.lhs()); + typename internal::add_const_on_value_type::type actualRhs = RhsBlasTraits::extract(prod.rhs()); ResScalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(prod.lhs()) * RhsBlasTraits::extractScalarFactor(prod.rhs()); @@ -247,7 +258,7 @@ template<> struct trmv_selector MappedDest(actualDestPtr, dest.size()) = dest; } - internal::product_triangular_matrix_vector + internal::triangular_matrix_vector_product struct trmv_selector Map(actualRhsPtr, actualRhs.size()) = actualRhs; } - internal::product_triangular_matrix_vector + internal::triangular_matrix_vector_product struct trmv_selector } // end namespace internal +} // end namespace Eigen + #endif // EIGEN_TRIANGULARMATRIXVECTOR_H diff --git a/extern/Eigen3/Eigen/src/Core/products/TriangularMatrixVector_MKL.h b/extern/Eigen3/Eigen/src/Core/products/TriangularMatrixVector_MKL.h new file mode 100644 index 00000000000..3589b8c5ef6 --- /dev/null +++ b/extern/Eigen3/Eigen/src/Core/products/TriangularMatrixVector_MKL.h @@ -0,0 +1,247 @@ +/* + Copyright (c) 2011, Intel Corporation. All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of Intel Corporation nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ******************************************************************************** + * Content : Eigen bindings to Intel(R) MKL + * Triangular matrix-vector product functionality based on ?TRMV. + ******************************************************************************** +*/ + +#ifndef EIGEN_TRIANGULAR_MATRIX_VECTOR_MKL_H +#define EIGEN_TRIANGULAR_MATRIX_VECTOR_MKL_H + +namespace Eigen { + +namespace internal { + +/********************************************************************** +* This file implements triangular matrix-vector multiplication using BLAS +**********************************************************************/ + +// trmv/hemv specialization + +template +struct triangular_matrix_vector_product_trmv : + triangular_matrix_vector_product {}; + +#define EIGEN_MKL_TRMV_SPECIALIZE(Scalar) \ +template \ +struct triangular_matrix_vector_product { \ + static EIGEN_DONT_INLINE void run(Index _rows, Index _cols, const Scalar* _lhs, Index lhsStride, \ + const Scalar* _rhs, Index rhsIncr, Scalar* _res, Index resIncr, Scalar alpha) { \ + triangular_matrix_vector_product_trmv::run( \ + _rows, _cols, _lhs, lhsStride, _rhs, rhsIncr, _res, resIncr, alpha); \ + } \ +}; \ +template \ +struct triangular_matrix_vector_product { \ + static EIGEN_DONT_INLINE void run(Index _rows, Index _cols, const Scalar* _lhs, Index lhsStride, \ + const Scalar* _rhs, Index rhsIncr, Scalar* _res, Index resIncr, Scalar alpha) { \ + triangular_matrix_vector_product_trmv::run( \ + _rows, _cols, _lhs, lhsStride, _rhs, rhsIncr, _res, resIncr, alpha); \ + } \ +}; + +EIGEN_MKL_TRMV_SPECIALIZE(double) +EIGEN_MKL_TRMV_SPECIALIZE(float) +EIGEN_MKL_TRMV_SPECIALIZE(dcomplex) +EIGEN_MKL_TRMV_SPECIALIZE(scomplex) + +// implements col-major: res += alpha * op(triangular) * vector +#define EIGEN_MKL_TRMV_CM(EIGTYPE, MKLTYPE, EIGPREFIX, MKLPREFIX) \ +template \ +struct triangular_matrix_vector_product_trmv { \ + enum { \ + IsLower = (Mode&Lower) == Lower, \ + SetDiag = (Mode&(ZeroDiag|UnitDiag)) ? 0 : 1, \ + IsUnitDiag = (Mode&UnitDiag) ? 1 : 0, \ + IsZeroDiag = (Mode&ZeroDiag) ? 1 : 0, \ + LowUp = IsLower ? Lower : Upper \ + }; \ + static EIGEN_DONT_INLINE void run(Index _rows, Index _cols, const EIGTYPE* _lhs, Index lhsStride, \ + const EIGTYPE* _rhs, Index rhsIncr, EIGTYPE* _res, Index resIncr, EIGTYPE alpha, level3_blocking& blocking) \ + { \ + if (ConjLhs || IsZeroDiag) { \ + triangular_matrix_vector_product::run( \ + _rows, _cols, _lhs, lhsStride, _rhs, rhsIncr, _res, resIncr, alpha, blocking); \ + return; \ + }\ + Index size = (std::min)(_rows,_cols); \ + Index rows = IsLower ? _rows : size; \ + Index cols = IsLower ? size : _cols; \ +\ + typedef VectorX##EIGPREFIX VectorRhs; \ + EIGTYPE *x, *y;\ +\ +/* Set x*/ \ + Map > rhs(_rhs,cols,InnerStride<>(rhsIncr)); \ + VectorRhs x_tmp; \ + if (ConjRhs) x_tmp = rhs.conjugate(); else x_tmp = rhs; \ + x = x_tmp.data(); \ +\ +/* Square part handling */\ +\ + char trans, uplo, diag; \ + MKL_INT m, n, lda, incx, incy; \ + EIGTYPE const *a; \ + MKLTYPE alpha_, beta_; \ + assign_scalar_eig2mkl(alpha_, alpha); \ + assign_scalar_eig2mkl(beta_, EIGTYPE(1)); \ +\ +/* Set m, n */ \ + n = (MKL_INT)size; \ + lda = lhsStride; \ + incx = 1; \ + incy = resIncr; \ +\ +/* Set uplo, trans and diag*/ \ + trans = 'N'; \ + uplo = IsLower ? 'L' : 'U'; \ + diag = IsUnitDiag ? 'U' : 'N'; \ +\ +/* call ?TRMV*/ \ + MKLPREFIX##trmv(&uplo, &trans, &diag, &n, (const MKLTYPE*)_lhs, &lda, (MKLTYPE*)x, &incx); \ +\ +/* Add op(a_tr)rhs into res*/ \ + MKLPREFIX##axpy(&n, &alpha_,(const MKLTYPE*)x, &incx, (MKLTYPE*)_res, &incy); \ +/* Non-square case - doesn't fit to MKL ?TRMV. Fall to default triangular product*/ \ + if (size<(std::max)(rows,cols)) { \ + typedef Matrix MatrixLhs; \ + if (ConjRhs) x_tmp = rhs.conjugate(); else x_tmp = rhs; \ + x = x_tmp.data(); \ + if (size \ +struct triangular_matrix_vector_product_trmv { \ + enum { \ + IsLower = (Mode&Lower) == Lower, \ + SetDiag = (Mode&(ZeroDiag|UnitDiag)) ? 0 : 1, \ + IsUnitDiag = (Mode&UnitDiag) ? 1 : 0, \ + IsZeroDiag = (Mode&ZeroDiag) ? 1 : 0, \ + LowUp = IsLower ? Lower : Upper \ + }; \ + static EIGEN_DONT_INLINE void run(Index _rows, Index _cols, const EIGTYPE* _lhs, Index lhsStride, \ + const EIGTYPE* _rhs, Index rhsIncr, EIGTYPE* _res, Index resIncr, EIGTYPE alpha, level3_blocking& blocking) \ + { \ + if (IsZeroDiag) { \ + triangular_matrix_vector_product::run( \ + _rows, _cols, _lhs, lhsStride, _rhs, rhsIncr, _res, resIncr, alpha, blocking); \ + return; \ + }\ + Index size = (std::min)(_rows,_cols); \ + Index rows = IsLower ? _rows : size; \ + Index cols = IsLower ? size : _cols; \ +\ + typedef VectorX##EIGPREFIX VectorRhs; \ + EIGTYPE *x, *y;\ +\ +/* Set x*/ \ + Map > rhs(_rhs,cols,InnerStride<>(rhsIncr)); \ + VectorRhs x_tmp; \ + if (ConjRhs) x_tmp = rhs.conjugate(); else x_tmp = rhs; \ + x = x_tmp.data(); \ +\ +/* Square part handling */\ +\ + char trans, uplo, diag; \ + MKL_INT m, n, lda, incx, incy; \ + EIGTYPE const *a; \ + MKLTYPE alpha_, beta_; \ + assign_scalar_eig2mkl(alpha_, alpha); \ + assign_scalar_eig2mkl(beta_, EIGTYPE(1)); \ +\ +/* Set m, n */ \ + n = (MKL_INT)size; \ + lda = lhsStride; \ + incx = 1; \ + incy = resIncr; \ +\ +/* Set uplo, trans and diag*/ \ + trans = ConjLhs ? 'C' : 'T'; \ + uplo = IsLower ? 'U' : 'L'; \ + diag = IsUnitDiag ? 'U' : 'N'; \ +\ +/* call ?TRMV*/ \ + MKLPREFIX##trmv(&uplo, &trans, &diag, &n, (const MKLTYPE*)_lhs, &lda, (MKLTYPE*)x, &incx); \ +\ +/* Add op(a_tr)rhs into res*/ \ + MKLPREFIX##axpy(&n, &alpha_,(const MKLTYPE*)x, &incx, (MKLTYPE*)_res, &incy); \ +/* Non-square case - doesn't fit to MKL ?TRMV. Fall to default triangular product*/ \ + if (size<(std::max)(rows,cols)) { \ + typedef Matrix MatrixLhs; \ + if (ConjRhs) x_tmp = rhs.conjugate(); else x_tmp = rhs; \ + x = x_tmp.data(); \ + if (size // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_TRIANGULAR_SOLVER_MATRIX_H #define EIGEN_TRIANGULAR_SOLVER_MATRIX_H +namespace Eigen { + namespace internal { // if the rhs is row major, let's transpose the product @@ -34,14 +21,15 @@ struct triangular_solve_matrix& blocking) { triangular_solve_matrix< Scalar, Index, Side==OnTheLeft?OnTheRight:OnTheLeft, (Mode&UnitDiag) | ((Mode&Upper) ? Lower : Upper), NumTraits::IsComplex && Conjugate, TriStorageOrder==RowMajor ? ColMajor : RowMajor, ColMajor> - ::run(size, cols, tri, triStride, _other, otherStride); + ::run(size, cols, tri, triStride, _other, otherStride, blocking); } }; @@ -53,7 +41,8 @@ struct triangular_solve_matrix& blocking) { Index cols = otherSize; const_blas_data_mapper tri(_tri,triStride); @@ -65,22 +54,29 @@ struct triangular_solve_matrix(kc, mc, nc); + Index kc = blocking.kc(); // cache block size along the K direction + Index mc = (std::min)(size,blocking.mc()); // cache block size along the M direction + std::size_t sizeA = kc*mc; + std::size_t sizeB = kc*cols; std::size_t sizeW = kc*Traits::WorkSpaceFactor; - std::size_t sizeB = sizeW + kc*cols; - ei_declare_aligned_stack_constructed_variable(Scalar, blockA, kc*mc, 0); - ei_declare_aligned_stack_constructed_variable(Scalar, allocatedBlockB, sizeB, 0); - Scalar* blockB = allocatedBlockB + sizeW; + + ei_declare_aligned_stack_constructed_variable(Scalar, blockA, sizeA, blocking.blockA()); + ei_declare_aligned_stack_constructed_variable(Scalar, blockB, sizeB, blocking.blockB()); + ei_declare_aligned_stack_constructed_variable(Scalar, blockW, sizeW, blocking.blockW()); conj_if conj; gebp_kernel gebp_kernel; gemm_pack_lhs pack_lhs; gemm_pack_rhs pack_rhs; + // the goal here is to subdivise the Rhs panels such that we keep some cache + // coherence when accessing the rhs elements + std::ptrdiff_t l1, l2; + manage_caching_sizes(GetAction, &l1, &l2); + Index subcols = cols>0 ? l2/(4 * sizeof(Scalar) * otherStride) : 0; + subcols = std::max((subcols/Traits::nr)*Traits::nr, Traits::nr); + for(Index k2=IsLower ? 0 : size; IsLower ? k20; IsLower ? k2+=kc : k2-=kc) @@ -92,16 +88,18 @@ struct triangular_solve_matrix general block copy (done during the next step) - // - R1 = L1^-1 B => tricky part + // - R1 = A11^-1 B => tricky part // - update B from the new R1 => actually this has to be performed continuously during the above step - // - R2 = L2 * B => GEPP + // - R2 -= A21 * B => GEPP - // The tricky part: compute R1 = L1^-1 B while updating B from R1 - // The idea is to split L1 into multiple small vertical panels. - // Each panel can be split into a small triangular part A1 which is processed without optimization, - // and the remaining small part A2 which is processed using gebp with appropriate block strides + // The tricky part: compute R1 = A11^-1 B while updating B from R1 + // The idea is to split A11 into multiple small vertical panels. + // Each panel can be split into a small triangular part T1k which is processed without optimization, + // and the remaining small part T2k which is processed using gebp with appropriate block strides + for(Index j2=0; j2(actual_kc-k1, SmallPanelWidth); @@ -114,11 +112,11 @@ struct triangular_solve_matrix0) @@ -152,13 +150,13 @@ struct triangular_solve_matrix GEPP + + // R2 -= A21 * B => GEPP { Index start = IsLower ? k2+kc : 0; Index end = IsLower ? size : k2-kc; @@ -169,7 +167,7 @@ struct triangular_solve_matrix& blocking) { Index rows = otherSize; const_blas_data_mapper rhs(_tri,triStride); @@ -198,19 +197,16 @@ struct triangular_solve_matrix(Traits::Max_kc/4,size); // cache block size along the K direction -// Index mc = std::min(Traits::Max_mc,size); // cache block size along the M direction - // check that !!!! - Index kc = size; // cache block size along the K direction - Index mc = size; // cache block size along the M direction - Index nc = rows; // cache block size along the N direction - computeProductBlockingSizes(kc, mc, nc); + Index kc = blocking.kc(); // cache block size along the K direction + Index mc = (std::min)(rows,blocking.mc()); // cache block size along the M direction + std::size_t sizeA = kc*mc; + std::size_t sizeB = kc*size; std::size_t sizeW = kc*Traits::WorkSpaceFactor; - std::size_t sizeB = sizeW + kc*size; - ei_declare_aligned_stack_constructed_variable(Scalar, blockA, kc*mc, 0); - ei_declare_aligned_stack_constructed_variable(Scalar, allocatedBlockB, sizeB, 0); - Scalar* blockB = allocatedBlockB + sizeW; + + ei_declare_aligned_stack_constructed_variable(Scalar, blockA, sizeA, blocking.blockA()); + ei_declare_aligned_stack_constructed_variable(Scalar, blockB, sizeB, blocking.blockB()); + ei_declare_aligned_stack_constructed_variable(Scalar, blockW, sizeW, blocking.blockW()); conj_if conj; gebp_kernel gebp_kernel; @@ -277,7 +273,7 @@ struct triangular_solve_matrix0) gebp_kernel(_other+i2+startPanel*otherStride, otherStride, blockA, geb, actual_mc, actual_kc, rs, Scalar(-1), - -1, -1, 0, 0, allocatedBlockB); + -1, -1, 0, 0, blockW); } } } @@ -316,4 +312,6 @@ struct triangular_solve_matrix \ +struct triangular_solve_matrix \ +{ \ + enum { \ + IsLower = (Mode&Lower) == Lower, \ + IsUnitDiag = (Mode&UnitDiag) ? 1 : 0, \ + IsZeroDiag = (Mode&ZeroDiag) ? 1 : 0, \ + conjA = ((TriStorageOrder==ColMajor) && Conjugate) ? 1 : 0 \ + }; \ + static EIGEN_DONT_INLINE void run( \ + Index size, Index otherSize, \ + const EIGTYPE* _tri, Index triStride, \ + EIGTYPE* _other, Index otherStride, level3_blocking& /*blocking*/) \ + { \ + MKL_INT m = size, n = otherSize, lda, ldb; \ + char side = 'L', uplo, diag='N', transa; \ + /* Set alpha_ */ \ + MKLTYPE alpha; \ + EIGTYPE myone(1); \ + assign_scalar_eig2mkl(alpha, myone); \ + ldb = otherStride;\ +\ + const EIGTYPE *a; \ +/* Set trans */ \ + transa = (TriStorageOrder==RowMajor) ? ((Conjugate) ? 'C' : 'T') : 'N'; \ +/* Set uplo */ \ + uplo = IsLower ? 'L' : 'U'; \ + if (TriStorageOrder==RowMajor) uplo = (uplo == 'L') ? 'U' : 'L'; \ +/* Set a, lda */ \ + typedef Matrix MatrixTri; \ + Map > tri(_tri,size,size,OuterStride<>(triStride)); \ + MatrixTri a_tmp; \ +\ + if (conjA) { \ + a_tmp = tri.conjugate(); \ + a = a_tmp.data(); \ + lda = a_tmp.outerStride(); \ + } else { \ + a = _tri; \ + lda = triStride; \ + } \ + if (IsUnitDiag) diag='U'; \ +/* call ?trsm*/ \ + MKLPREFIX##trsm(&side, &uplo, &transa, &diag, &m, &n, &alpha, (const MKLTYPE*)a, &lda, (MKLTYPE*)_other, &ldb); \ + } \ +}; + +EIGEN_MKL_TRSM_L(double, double, d) +EIGEN_MKL_TRSM_L(dcomplex, MKL_Complex16, z) +EIGEN_MKL_TRSM_L(float, float, s) +EIGEN_MKL_TRSM_L(scomplex, MKL_Complex8, c) + + +// implements RightSide general * op(triangular)^-1 +#define EIGEN_MKL_TRSM_R(EIGTYPE, MKLTYPE, MKLPREFIX) \ +template \ +struct triangular_solve_matrix \ +{ \ + enum { \ + IsLower = (Mode&Lower) == Lower, \ + IsUnitDiag = (Mode&UnitDiag) ? 1 : 0, \ + IsZeroDiag = (Mode&ZeroDiag) ? 1 : 0, \ + conjA = ((TriStorageOrder==ColMajor) && Conjugate) ? 1 : 0 \ + }; \ + static EIGEN_DONT_INLINE void run( \ + Index size, Index otherSize, \ + const EIGTYPE* _tri, Index triStride, \ + EIGTYPE* _other, Index otherStride, level3_blocking& /*blocking*/) \ + { \ + MKL_INT m = otherSize, n = size, lda, ldb; \ + char side = 'R', uplo, diag='N', transa; \ + /* Set alpha_ */ \ + MKLTYPE alpha; \ + EIGTYPE myone(1); \ + assign_scalar_eig2mkl(alpha, myone); \ + ldb = otherStride;\ +\ + const EIGTYPE *a; \ +/* Set trans */ \ + transa = (TriStorageOrder==RowMajor) ? ((Conjugate) ? 'C' : 'T') : 'N'; \ +/* Set uplo */ \ + uplo = IsLower ? 'L' : 'U'; \ + if (TriStorageOrder==RowMajor) uplo = (uplo == 'L') ? 'U' : 'L'; \ +/* Set a, lda */ \ + typedef Matrix MatrixTri; \ + Map > tri(_tri,size,size,OuterStride<>(triStride)); \ + MatrixTri a_tmp; \ +\ + if (conjA) { \ + a_tmp = tri.conjugate(); \ + a = a_tmp.data(); \ + lda = a_tmp.outerStride(); \ + } else { \ + a = _tri; \ + lda = triStride; \ + } \ + if (IsUnitDiag) diag='U'; \ +/* call ?trsm*/ \ + MKLPREFIX##trsm(&side, &uplo, &transa, &diag, &m, &n, &alpha, (const MKLTYPE*)a, &lda, (MKLTYPE*)_other, &ldb); \ + /*std::cout << "TRMS_L specialization!\n";*/ \ + } \ +}; + +EIGEN_MKL_TRSM_R(double, double, d) +EIGEN_MKL_TRSM_R(dcomplex, MKL_Complex16, z) +EIGEN_MKL_TRSM_R(float, float, s) +EIGEN_MKL_TRSM_R(scomplex, MKL_Complex8, c) + + +} // end namespace internal + +} // end namespace Eigen + +#endif // EIGEN_TRIANGULAR_SOLVER_MATRIX_MKL_H diff --git a/extern/Eigen3/Eigen/src/Core/products/TriangularSolverVector.h b/extern/Eigen3/Eigen/src/Core/products/TriangularSolverVector.h index 639d4a5b476..ce4d1008801 100644 --- a/extern/Eigen3/Eigen/src/Core/products/TriangularSolverVector.h +++ b/extern/Eigen3/Eigen/src/Core/products/TriangularSolverVector.h @@ -3,28 +3,15 @@ // // Copyright (C) 2008-2010 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_TRIANGULAR_SOLVER_VECTOR_H #define EIGEN_TRIANGULAR_SOLVER_VECTOR_H +namespace Eigen { + namespace internal { template @@ -147,4 +134,6 @@ struct triangular_solve_vector // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_BLASUTIL_H #define EIGEN_BLASUTIL_H @@ -28,6 +13,8 @@ // This file contains many lightweight helper classes used to // implement and control fast level 2 and level 3 BLAS-like routines. +namespace Eigen { + namespace internal { // forward declarations @@ -47,7 +34,7 @@ template< int ResStorageOrder> struct general_matrix_matrix_product; -template +template struct general_matrix_vector_product; @@ -56,11 +43,15 @@ template struct conj_if; template<> struct conj_if { template inline T operator()(const T& x) { return conj(x); } + template + inline T pconj(const T& x) { return internal::pconj(x); } }; template<> struct conj_if { template inline const T& operator()(const T& x) { return x; } + template + inline const T& pconj(const T& x) { return x; } }; template struct conj_helper @@ -118,11 +109,11 @@ template struct conj_helper struct get_factor { - EIGEN_STRONG_INLINE static To run(const From& x) { return x; } + static EIGEN_STRONG_INLINE To run(const From& x) { return x; } }; template struct get_factor::Real> { - EIGEN_STRONG_INLINE static typename NumTraits::Real run(const Scalar& x) { return real(x); } + static EIGEN_STRONG_INLINE typename NumTraits::Real run(const Scalar& x) { return real(x); } }; // Lightweight helper class to access matrix coefficients. @@ -175,7 +166,7 @@ template struct blas_traits ExtractType, typename _ExtractType::PlainObject >::type DirectLinearAccessType; - static inline const ExtractType extract(const XprType& x) { return x; } + static inline ExtractType extract(const XprType& x) { return x; } static inline const Scalar extractScalarFactor(const XprType&) { return Scalar(1); } }; @@ -192,7 +183,7 @@ struct blas_traits, NestedXpr> > IsComplex = NumTraits::IsComplex, NeedToConjugate = Base::NeedToConjugate ? 0 : IsComplex }; - static inline const ExtractType extract(const XprType& x) { return Base::extract(x.nestedExpression()); } + static inline ExtractType extract(const XprType& x) { return Base::extract(x.nestedExpression()); } static inline Scalar extractScalarFactor(const XprType& x) { return conj(Base::extractScalarFactor(x.nestedExpression())); } }; @@ -204,7 +195,7 @@ struct blas_traits, NestedXpr> > typedef blas_traits Base; typedef CwiseUnaryOp, NestedXpr> XprType; typedef typename Base::ExtractType ExtractType; - static inline const ExtractType extract(const XprType& x) { return Base::extract(x.nestedExpression()); } + static inline ExtractType extract(const XprType& x) { return Base::extract(x.nestedExpression()); } static inline Scalar extractScalarFactor(const XprType& x) { return x.functor().m_other * Base::extractScalarFactor(x.nestedExpression()); } }; @@ -217,7 +208,7 @@ struct blas_traits, NestedXpr> > typedef blas_traits Base; typedef CwiseUnaryOp, NestedXpr> XprType; typedef typename Base::ExtractType ExtractType; - static inline const ExtractType extract(const XprType& x) { return Base::extract(x.nestedExpression()); } + static inline ExtractType extract(const XprType& x) { return Base::extract(x.nestedExpression()); } static inline Scalar extractScalarFactor(const XprType& x) { return - Base::extractScalarFactor(x.nestedExpression()); } }; @@ -239,7 +230,7 @@ struct blas_traits > enum { IsTransposed = Base::IsTransposed ? 0 : 1 }; - static inline const ExtractType extract(const XprType& x) { return Base::extract(x.nestedExpression()); } + static inline ExtractType extract(const XprType& x) { return Base::extract(x.nestedExpression()); } static inline Scalar extractScalarFactor(const XprType& x) { return Base::extractScalarFactor(x.nestedExpression()); } }; @@ -252,7 +243,7 @@ template::HasUsableDirectA struct extract_data_selector { static const typename T::Scalar* run(const T& m) { - return const_cast(&blas_traits::extract(m).coeffRef(0,0)); // FIXME this should be .data() + return blas_traits::extract(m).data(); } }; @@ -268,4 +259,6 @@ template const typename T::Scalar* extract_data(const T& m) } // end namespace internal +} // end namespace Eigen + #endif // EIGEN_BLASUTIL_H diff --git a/extern/Eigen3/Eigen/src/Core/util/Constants.h b/extern/Eigen3/Eigen/src/Core/util/Constants.h index c3dd3a09d00..3fd45e84f8e 100644 --- a/extern/Eigen3/Eigen/src/Core/util/Constants.h +++ b/extern/Eigen3/Eigen/src/Core/util/Constants.h @@ -4,28 +4,15 @@ // Copyright (C) 2008-2009 Gael Guennebaud // Copyright (C) 2007-2009 Benoit Jacob // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_CONSTANTS_H #define EIGEN_CONSTANTS_H +namespace Eigen { + /** This value means that a quantity is not known at compile-time, and that instead the value is * stored in some runtime variable. * @@ -188,7 +175,9 @@ enum { /** View matrix as an upper triangular matrix with zeros on the diagonal. */ StrictlyUpper=ZeroDiag|Upper, /** Used in BandMatrix and SelfAdjointView to indicate that the matrix is self-adjoint. */ - SelfAdjoint=0x10 + SelfAdjoint=0x10, + /** Used to support symmetric, non-selfadjoint, complex matrices. */ + Symmetric=0x20 }; /** \ingroup enums @@ -200,8 +189,6 @@ enum { Aligned=1 }; -enum { ConditionalJumpCost = 5 }; - /** \ingroup enums * Enum used by DenseBase::corner() in Eigen2 compatibility mode. */ // FIXME after the corner() API change, this was not needed anymore, except by AlignedBox @@ -223,8 +210,6 @@ enum DirectionType { BothDirections }; -enum ProductEvaluationMode { NormalProduct, CacheFriendlyProduct }; - /** \internal \ingroup enums * Enum to specify how to traverse the entries of a matrix. */ enum { @@ -257,6 +242,13 @@ enum { CompleteUnrolling }; +/** \internal \ingroup enums + * Enum to specify whether to use the default (built-in) implementation or the specialization. */ +enum { + Specialized, + BuiltIn +}; + /** \ingroup enums * Enum containing possible values for the \p _Options template parameter of * Matrix, Array and BandMatrix. */ @@ -280,26 +272,21 @@ enum { OnTheRight = 2 }; -/* the following could as well be written: - * enum NoChange_t { NoChange }; - * but it feels dangerous to disambiguate overloaded functions on enum/integer types. - * If on some platform it is really impossible to get rid of "unused variable" warnings, then - * we can always come back to that solution. +/* the following used to be written as: + * + * struct NoChange_t {}; + * namespace { + * EIGEN_UNUSED NoChange_t NoChange; + * } + * + * on the ground that it feels dangerous to disambiguate overloaded functions on enum/integer types. + * However, this leads to "variable declared but never referenced" warnings on Intel Composer XE, + * and we do not know how to get rid of them (bug 450). */ -struct NoChange_t {}; -namespace { - EIGEN_UNUSED NoChange_t NoChange; -} -struct Sequential_t {}; -namespace { - EIGEN_UNUSED Sequential_t Sequential; -} - -struct Default_t {}; -namespace { - EIGEN_UNUSED Default_t Default; -} +enum NoChange_t { NoChange }; +enum Sequential_t { Sequential }; +enum Default_t { Default }; /** \internal \ingroup enums * Used in AmbiVector. */ @@ -375,7 +362,7 @@ enum QRPreconditioners { #error The preprocessor symbol 'Success' is defined, possibly by the X11 header file X.h #endif -/** \ingroups enums +/** \ingroup enums * Enum for reporting the status of a computation. */ enum ComputationInfo { /** Computation was successful. */ @@ -383,7 +370,10 @@ enum ComputationInfo { /** The provided data did not satisfy the prerequisites. */ NumericalIssue = 1, /** Iterative procedure did not converge. */ - NoConvergence = 2 + NoConvergence = 2, + /** The inputs are invalid, or the algorithm has been improperly called. + * When assertions are enabled, such errors trigger an assert. */ + InvalidInput = 3 }; /** \ingroup enums @@ -436,4 +426,6 @@ struct MatrixXpr {}; /** The type used to identify an array expression */ struct ArrayXpr {}; +} // end namespace Eigen + #endif // EIGEN_CONSTANTS_H diff --git a/extern/Eigen3/Eigen/src/Core/util/DisableStupidWarnings.h b/extern/Eigen3/Eigen/src/Core/util/DisableStupidWarnings.h index 00730524b26..6a0bf0629c5 100644 --- a/extern/Eigen3/Eigen/src/Core/util/DisableStupidWarnings.h +++ b/extern/Eigen3/Eigen/src/Core/util/DisableStupidWarnings.h @@ -21,15 +21,13 @@ #elif defined __INTEL_COMPILER // 2196 - routine is both "inline" and "noinline" ("noinline" assumed) // ICC 12 generates this warning even without any inline keyword, when defining class methods 'inline' i.e. inside of class body - // 2536 - type qualifiers are meaningless here - // ICC 12 generates this warning when a function return type is const qualified, even if that type is a template-parameter-dependent // typedef that may be a reference type. // 279 - controlling expression is constant // ICC 12 generates this warning on assert(constant_expression_depending_on_template_params) and frankly this is a legitimate use case. #ifndef EIGEN_PERMANENTLY_DISABLE_STUPID_WARNINGS #pragma warning push #endif - #pragma warning disable 2196 2536 279 + #pragma warning disable 2196 279 #elif defined __clang__ // -Wconstant-logical-operand - warning: use of logical && with constant operand; switch to bitwise & or remove constant // this is really a stupid warning as it warns on compile-time expressions involving enums diff --git a/extern/Eigen3/Eigen/src/Core/util/ForwardDeclarations.h b/extern/Eigen3/Eigen/src/Core/util/ForwardDeclarations.h index 7fbccf98c2b..bcdfe3914e3 100644 --- a/extern/Eigen3/Eigen/src/Core/util/ForwardDeclarations.h +++ b/extern/Eigen3/Eigen/src/Core/util/ForwardDeclarations.h @@ -4,28 +4,14 @@ // Copyright (C) 2007-2010 Benoit Jacob // Copyright (C) 2008-2009 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_FORWARDDECLARATIONS_H #define EIGEN_FORWARDDECLARATIONS_H +namespace Eigen { namespace internal { template struct traits; @@ -133,6 +119,7 @@ template class WithFormat; template struct CommaInitializer; template class ReturnByValue; template class ArrayWrapper; +template class MatrixWrapper; namespace internal { template struct solve_retval_base; @@ -282,6 +269,8 @@ template class Homogeneous; // MatrixFunctions module template struct MatrixExponentialReturnValue; template class MatrixFunctionReturnValue; +template class MatrixSquareRootReturnValue; +template class MatrixLogarithmReturnValue; namespace internal { template @@ -304,4 +293,6 @@ template struct eigen2_part_return_type; } #endif +} // end namespace Eigen + #endif // EIGEN_FORWARDDECLARATIONS_H diff --git a/extern/Eigen3/Eigen/src/Core/util/MKL_support.h b/extern/Eigen3/Eigen/src/Core/util/MKL_support.h new file mode 100644 index 00000000000..1e6e355d626 --- /dev/null +++ b/extern/Eigen3/Eigen/src/Core/util/MKL_support.h @@ -0,0 +1,109 @@ +/* + Copyright (c) 2011, Intel Corporation. All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of Intel Corporation nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ******************************************************************************** + * Content : Eigen bindings to Intel(R) MKL + * Include file with common MKL declarations + ******************************************************************************** +*/ + +#ifndef EIGEN_MKL_SUPPORT_H +#define EIGEN_MKL_SUPPORT_H + +#ifdef EIGEN_USE_MKL_ALL + #ifndef EIGEN_USE_BLAS + #define EIGEN_USE_BLAS + #endif + #ifndef EIGEN_USE_LAPACKE + #define EIGEN_USE_LAPACKE + #endif + #ifndef EIGEN_USE_MKL_VML + #define EIGEN_USE_MKL_VML + #endif +#endif + +#ifdef EIGEN_USE_LAPACKE_STRICT + #define EIGEN_USE_LAPACKE +#endif + +#if defined(EIGEN_USE_BLAS) || defined(EIGEN_USE_LAPACKE) || defined(EIGEN_USE_MKL_VML) + #define EIGEN_USE_MKL +#endif + +#if defined EIGEN_USE_MKL + +#include +#include +#define EIGEN_MKL_VML_THRESHOLD 128 + +namespace Eigen { + +typedef std::complex dcomplex; +typedef std::complex scomplex; + +namespace internal { + +template +static inline void assign_scalar_eig2mkl(MKLType& mklScalar, const EigenType& eigenScalar) { + mklScalar=eigenScalar; +} + +template +static inline void assign_conj_scalar_eig2mkl(MKLType& mklScalar, const EigenType& eigenScalar) { + mklScalar=eigenScalar; +} + +template <> +inline void assign_scalar_eig2mkl(MKL_Complex16& mklScalar, const dcomplex& eigenScalar) { + mklScalar.real=eigenScalar.real(); + mklScalar.imag=eigenScalar.imag(); +} + +template <> +inline void assign_scalar_eig2mkl(MKL_Complex8& mklScalar, const scomplex& eigenScalar) { + mklScalar.real=eigenScalar.real(); + mklScalar.imag=eigenScalar.imag(); +} + +template <> +inline void assign_conj_scalar_eig2mkl(MKL_Complex16& mklScalar, const dcomplex& eigenScalar) { + mklScalar.real=eigenScalar.real(); + mklScalar.imag=-eigenScalar.imag(); +} + +template <> +inline void assign_conj_scalar_eig2mkl(MKL_Complex8& mklScalar, const scomplex& eigenScalar) { + mklScalar.real=eigenScalar.real(); + mklScalar.imag=-eigenScalar.imag(); +} + +} // end namespace internal + +} // end namespace Eigen + +#endif + +#endif // EIGEN_MKL_SUPPORT_H diff --git a/extern/Eigen3/Eigen/src/Core/util/Macros.h b/extern/Eigen3/Eigen/src/Core/util/Macros.h index b7c2b79af92..d973a68372f 100644 --- a/extern/Eigen3/Eigen/src/Core/util/Macros.h +++ b/extern/Eigen3/Eigen/src/Core/util/Macros.h @@ -1,35 +1,19 @@ - // This file is part of Eigen, a lightweight C++ template library // for linear algebra. // // Copyright (C) 2008-2010 Gael Guennebaud // Copyright (C) 2006-2008 Benoit Jacob // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_MACROS_H #define EIGEN_MACROS_H #define EIGEN_WORLD_VERSION 3 -#define EIGEN_MAJOR_VERSION 0 -#define EIGEN_MINOR_VERSION 5 +#define EIGEN_MAJOR_VERSION 1 +#define EIGEN_MINOR_VERSION 1 #define EIGEN_VERSION_AT_LEAST(x,y,z) (EIGEN_WORLD_VERSION>x || (EIGEN_WORLD_VERSION>=x && \ (EIGEN_MAJOR_VERSION>y || (EIGEN_MAJOR_VERSION>=y && \ @@ -235,12 +219,16 @@ #define EIGEN_ONLY_USED_FOR_DEBUG(x) #endif -#if (defined __GNUC__) -#define EIGEN_DEPRECATED __attribute__((deprecated)) -#elif (defined _MSC_VER) -#define EIGEN_DEPRECATED __declspec(deprecated) +#ifndef EIGEN_NO_DEPRECATED_WARNING + #if (defined __GNUC__) + #define EIGEN_DEPRECATED __attribute__((deprecated)) + #elif (defined _MSC_VER) + #define EIGEN_DEPRECATED __declspec(deprecated) + #else + #define EIGEN_DEPRECATED + #endif #else -#define EIGEN_DEPRECATED + #define EIGEN_DEPRECATED #endif #if (defined __GNUC__) @@ -252,7 +240,7 @@ // Suppresses 'unused variable' warnings. #define EIGEN_UNUSED_VARIABLE(var) (void)var; -#if (defined __GNUC__) +#if !defined(EIGEN_ASM_COMMENT) && (defined __GNUC__) #define EIGEN_ASM_COMMENT(X) asm("#" X) #else #define EIGEN_ASM_COMMENT(X) @@ -265,7 +253,7 @@ * If we made alignment depend on whether or not EIGEN_VECTORIZE is defined, it would be impossible to link * vectorized and non-vectorized code. */ -#if (defined __GNUC__) || (defined __PGI) || (defined __IBMCPP__) +#if (defined __GNUC__) || (defined __PGI) || (defined __IBMCPP__) || (defined __ARMCC_VERSION) #define EIGEN_ALIGN_TO_BOUNDARY(n) __attribute__((aligned(n))) #elif (defined _MSC_VER) #define EIGEN_ALIGN_TO_BOUNDARY(n) __declspec(align(n)) diff --git a/extern/Eigen3/Eigen/src/Core/util/Memory.h b/extern/Eigen3/Eigen/src/Core/util/Memory.h index 023716dc9e0..6e06ace44a0 100644 --- a/extern/Eigen3/Eigen/src/Core/util/Memory.h +++ b/extern/Eigen3/Eigen/src/Core/util/Memory.h @@ -7,24 +7,9 @@ // Copyright (C) 2010 Hauke Heibel // Copyright (C) 2010 Thomas Capricelli // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. /***************************************************************************** @@ -80,6 +65,8 @@ #define EIGEN_HAS_MM_MALLOC 0 #endif +namespace Eigen { + namespace internal { inline void throw_std_bad_alloc() @@ -457,7 +444,7 @@ template inline void conditional_aligned_delete_auto(T * * There is also the variant first_aligned(const MatrixBase&) defined in DenseCoeffsBase.h. */ template -inline static Index first_aligned(const Scalar* array, Index size) +static inline Index first_aligned(const Scalar* array, Index size) { typedef typename packet_traits::type Packet; enum { PacketSize = packet_traits::size, @@ -483,7 +470,26 @@ inline static Index first_aligned(const Scalar* array, Index size) } } -} // end namespace internal + +// std::copy is much slower than memcpy, so let's introduce a smart_copy which +// use memcpy on trivial types, i.e., on types that does not require an initialization ctor. +template struct smart_copy_helper; + +template void smart_copy(const T* start, const T* end, T* target) +{ + smart_copy_helper::RequireInitialization>::run(start, end, target); +} + +template struct smart_copy_helper { + static inline void run(const T* start, const T* end, T* target) + { memcpy(target, start, std::ptrdiff_t(end)-std::ptrdiff_t(start)); } +}; + +template struct smart_copy_helper { + static inline void run(const T* start, const T* end, T* target) + { std::copy(start, end, target); } +}; + /***************************************************************************** *** Implementation of runtime stack allocation (falling back to malloc) *** @@ -499,8 +505,6 @@ inline static Index first_aligned(const Scalar* array, Index size) #endif #endif -namespace internal { - // This helper class construct the allocated memory, and takes care of destructing and freeing the handled data // at destruction time. In practice this helper class is mainly useful to avoid memory leak in case of exceptions. template class aligned_stack_memory_handler @@ -531,14 +535,14 @@ template class aligned_stack_memory_handler bool m_deallocate; }; -} +} // end namespace internal /** \internal * Declares, allocates and construct an aligned buffer named NAME of SIZE elements of type TYPE on the stack * if SIZE is smaller than EIGEN_STACK_ALLOCATION_LIMIT, and if stack allocation is supported by the platform * (currently, this is Linux and Visual Studio only). Otherwise the memory is allocated on the heap. * The allocated buffer is automatically deleted when exiting the scope of this declaration. - * If BUFFER is non nul, then the declared variable is simply an alias for BUFFER, and no allocation/deletion occurs. + * If BUFFER is non null, then the declared variable is simply an alias for BUFFER, and no allocation/deletion occurs. * Here is an example: * \code * { @@ -619,7 +623,7 @@ template class aligned_stack_memory_handler #define EIGEN_MAKE_ALIGNED_OPERATOR_NEW EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(true) #define EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(Scalar,Size) \ - EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(((Size)!=Eigen::Dynamic) && ((sizeof(Scalar)*(Size))%16==0)) + EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(bool(((Size)!=Eigen::Dynamic) && ((sizeof(Scalar)*(Size))%16==0))) /****************************************************************************/ @@ -667,24 +671,24 @@ public: return &value; } - aligned_allocator() throw() + aligned_allocator() { } - aligned_allocator( const aligned_allocator& ) throw() + aligned_allocator( const aligned_allocator& ) { } template - aligned_allocator( const aligned_allocator& ) throw() + aligned_allocator( const aligned_allocator& ) { } - ~aligned_allocator() throw() + ~aligned_allocator() { } - size_type max_size() const throw() + size_type max_size() const { return (std::numeric_limits::max)(); } @@ -701,6 +705,15 @@ public: ::new( p ) T( value ); } + // Support for c++11 +#if (__cplusplus >= 201103L) + template + void construct(pointer p, Args&&... args) + { + ::new(p) T(std::forward(args)...); + } +#endif + void destroy( pointer p ) { p->~T(); @@ -720,19 +733,21 @@ public: //---------- Cache sizes ---------- -#if defined(__GNUC__) && ( defined(__i386__) || defined(__x86_64__) ) -# if defined(__PIC__) && defined(__i386__) - // Case for x86 with PIC -# define EIGEN_CPUID(abcd,func,id) \ - __asm__ __volatile__ ("xchgl %%ebx, %%esi;cpuid; xchgl %%ebx,%%esi": "=a" (abcd[0]), "=S" (abcd[1]), "=c" (abcd[2]), "=d" (abcd[3]) : "a" (func), "c" (id)); -# else - // Case for x86_64 or x86 w/o PIC -# define EIGEN_CPUID(abcd,func,id) \ - __asm__ __volatile__ ("cpuid": "=a" (abcd[0]), "=b" (abcd[1]), "=c" (abcd[2]), "=d" (abcd[3]) : "a" (func), "c" (id) ); -# endif -#elif defined(_MSC_VER) -# if (_MSC_VER > 1500) -# define EIGEN_CPUID(abcd,func,id) __cpuidex((int*)abcd,func,id) +#if !defined(EIGEN_NO_CPUID) +# if defined(__GNUC__) && ( defined(__i386__) || defined(__x86_64__) ) +# if defined(__PIC__) && defined(__i386__) + // Case for x86 with PIC +# define EIGEN_CPUID(abcd,func,id) \ + __asm__ __volatile__ ("xchgl %%ebx, %%esi;cpuid; xchgl %%ebx,%%esi": "=a" (abcd[0]), "=S" (abcd[1]), "=c" (abcd[2]), "=d" (abcd[3]) : "a" (func), "c" (id)); +# else + // Case for x86_64 or x86 w/o PIC +# define EIGEN_CPUID(abcd,func,id) \ + __asm__ __volatile__ ("cpuid": "=a" (abcd[0]), "=b" (abcd[1]), "=c" (abcd[2]), "=d" (abcd[3]) : "a" (func), "c" (id) ); +# endif +# elif defined(_MSC_VER) +# if (_MSC_VER > 1500) +# define EIGEN_CPUID(abcd,func,id) __cpuidex((int*)abcd,func,id) +# endif # endif #endif @@ -742,7 +757,7 @@ namespace internal { inline bool cpuid_is_vendor(int abcd[4], const char* vendor) { - return abcd[1]==((int*)(vendor))[0] && abcd[3]==((int*)(vendor))[1] && abcd[2]==((int*)(vendor))[2]; + return abcd[1]==(reinterpret_cast(vendor))[0] && abcd[3]==(reinterpret_cast(vendor))[1] && abcd[2]==(reinterpret_cast(vendor))[2]; } inline void queryCacheSizes_intel_direct(int& l1, int& l2, int& l3) @@ -932,4 +947,6 @@ inline int queryTopLevelCacheSize() } // end namespace internal +} // end namespace Eigen + #endif // EIGEN_MEMORY_H diff --git a/extern/Eigen3/Eigen/src/Core/util/Meta.h b/extern/Eigen3/Eigen/src/Core/util/Meta.h index 4518261efef..a5f31164d15 100644 --- a/extern/Eigen3/Eigen/src/Core/util/Meta.h +++ b/extern/Eigen3/Eigen/src/Core/util/Meta.h @@ -4,28 +4,15 @@ // Copyright (C) 2008-2009 Gael Guennebaud // Copyright (C) 2006-2008 Benoit Jacob // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_META_H #define EIGEN_META_H +namespace Eigen { + namespace internal { /** \internal @@ -80,8 +67,6 @@ template<> struct is_arithmetic { enum { value = true }; }; template<> struct is_arithmetic { enum { value = true }; }; template<> struct is_arithmetic { enum { value = true }; }; template<> struct is_arithmetic { enum { value = true }; }; -template<> struct is_arithmetic { enum { value = true }; }; -template<> struct is_arithmetic { enum { value = true }; }; template struct add_const { typedef const T type; }; template struct add_const { typedef T& type; }; @@ -103,6 +88,21 @@ template struct enable_if; template struct enable_if { typedef T type; }; + + +/** \internal + * A base class do disable default copy ctor and copy assignement operator. + */ +class noncopyable +{ + noncopyable(const noncopyable&); + const noncopyable& operator=(const noncopyable&); +protected: + noncopyable() {} + ~noncopyable() {} +}; + + /** \internal * Convenient struct to get the result type of a unary or binary functor. * @@ -226,4 +226,6 @@ template struct is_diagonal > } // end namespace internal +} // end namespace Eigen + #endif // EIGEN_META_H diff --git a/extern/Eigen3/Eigen/src/Core/util/NonMPL2.h b/extern/Eigen3/Eigen/src/Core/util/NonMPL2.h new file mode 100644 index 00000000000..1af67cf18c7 --- /dev/null +++ b/extern/Eigen3/Eigen/src/Core/util/NonMPL2.h @@ -0,0 +1,3 @@ +#ifdef EIGEN_MPL2_ONLY +#error Including non-MPL2 code in EIGEN_MPL2_ONLY mode +#endif diff --git a/extern/Eigen3/Eigen/src/Core/util/StaticAssert.h b/extern/Eigen3/Eigen/src/Core/util/StaticAssert.h index 99c7c9972f0..b46a75b3783 100644 --- a/extern/Eigen3/Eigen/src/Core/util/StaticAssert.h +++ b/extern/Eigen3/Eigen/src/Core/util/StaticAssert.h @@ -4,24 +4,9 @@ // Copyright (C) 2008 Gael Guennebaud // Copyright (C) 2008 Benoit Jacob // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_STATIC_ASSERT_H #define EIGEN_STATIC_ASSERT_H @@ -48,6 +33,8 @@ #else // not CXX0X + namespace Eigen { + namespace internal { template @@ -70,6 +57,7 @@ YOU_CALLED_A_DYNAMIC_SIZE_METHOD_ON_A_FIXED_SIZE_MATRIX_OR_VECTOR, UNALIGNED_LOAD_AND_STORE_OPERATIONS_UNIMPLEMENTED_ON_ALTIVEC, THIS_FUNCTION_IS_NOT_FOR_INTEGER_NUMERIC_TYPES, + FLOATING_POINT_ARGUMENT_PASSED__INTEGER_WAS_EXPECTED, NUMERIC_TYPE_MUST_BE_REAL, COEFFICIENT_WRITE_ACCESS_TO_SELFADJOINT_NOT_SUPPORTED, WRITING_TO_TRIANGULAR_PART_WITH_UNIT_DIAGONAL_IS_NOT_SUPPORTED, @@ -95,12 +83,20 @@ YOU_PERFORMED_AN_INVALID_TRANSFORMATION_CONVERSION, THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY, YOU_ARE_TRYING_TO_USE_AN_INDEX_BASED_ACCESSOR_ON_AN_EXPRESSION_THAT_DOES_NOT_SUPPORT_THAT, - THIS_METHOD_IS_ONLY_FOR_1x1_EXPRESSIONS + THIS_METHOD_IS_ONLY_FOR_1x1_EXPRESSIONS, + THIS_METHOD_IS_ONLY_FOR_EXPRESSIONS_OF_BOOL, + THIS_METHOD_IS_ONLY_FOR_ARRAYS_NOT_MATRICES, + YOU_PASSED_A_ROW_VECTOR_BUT_A_COLUMN_VECTOR_WAS_EXPECTED, + YOU_PASSED_A_COLUMN_VECTOR_BUT_A_ROW_VECTOR_WAS_EXPECTED, + THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE, + THE_STORAGE_ORDER_OF_BOTH_SIDES_MUST_MATCH }; }; } // end namespace internal + } // end namespace Eigen + // Specialized implementation for MSVC to avoid "conditional // expression is constant" warnings. This implementation doesn't // appear to work under GCC, hence the multiple implementations. @@ -195,4 +191,15 @@ EIGEN_STATIC_ASSERT(internal::is_lvalue::value, \ THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY) +#define EIGEN_STATIC_ASSERT_ARRAYXPR(Derived) \ + EIGEN_STATIC_ASSERT((internal::is_same::XprKind, ArrayXpr>::value), \ + THIS_METHOD_IS_ONLY_FOR_ARRAYS_NOT_MATRICES) + +#define EIGEN_STATIC_ASSERT_SAME_XPR_KIND(Derived1, Derived2) \ + EIGEN_STATIC_ASSERT((internal::is_same::XprKind, \ + typename internal::traits::XprKind \ + >::value), \ + YOU_CANNOT_MIX_ARRAYS_AND_MATRICES) + + #endif // EIGEN_STATIC_ASSERT_H diff --git a/extern/Eigen3/Eigen/src/Core/util/XprHelper.h b/extern/Eigen3/Eigen/src/Core/util/XprHelper.h index c2078f13786..2a65c7cbfa4 100644 --- a/extern/Eigen3/Eigen/src/Core/util/XprHelper.h +++ b/extern/Eigen3/Eigen/src/Core/util/XprHelper.h @@ -4,24 +4,9 @@ // Copyright (C) 2008 Gael Guennebaud // Copyright (C) 2006-2008 Benoit Jacob // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_XPRHELPER_H #define EIGEN_XPRHELPER_H @@ -37,6 +22,8 @@ #define EIGEN_EMPTY_STRUCT_CTOR(X) #endif +namespace Eigen { + typedef EIGEN_DEFAULT_DENSE_INDEX_TYPE DenseIndex; namespace internal { @@ -260,30 +247,27 @@ template struct plain_matrix_type_row_major // we should be able to get rid of this one too template struct must_nest_by_value { enum { ret = false }; }; -template -struct is_reference -{ - enum { ret = false }; -}; - -template -struct is_reference -{ - enum { ret = true }; -}; - -/** -* \internal The reference selector for template expressions. The idea is that we don't -* need to use references for expressions since they are light weight proxy -* objects which should generate no copying overhead. -**/ +/** \internal The reference selector for template expressions. The idea is that we don't + * need to use references for expressions since they are light weight proxy + * objects which should generate no copying overhead. */ template struct ref_selector { typedef typename conditional< bool(traits::Flags & NestByRefBit), T const&, - T + const T + >::type type; +}; + +/** \internal Adds the const qualifier on the value-type of T2 if and only if T1 is a const type */ +template +struct transfer_constness +{ + typedef typename conditional< + bool(internal::is_const::value), + typename internal::add_const_on_value_type::type, + T2 >::type type; }; @@ -297,6 +281,8 @@ struct ref_selector * \param T the type of the expression being nested * \param n the number of coefficient accesses in the nested expression for each coefficient access in the bigger expression. * + * Note that if no evaluation occur, then the constness of T is preserved. + * * Example. Suppose that a, b, and c are of type Matrix3d. The user forms the expression a*(b+c). * b+c is an expression "sum of matrices", which we will denote by S. In order to determine how to nest it, * the Product expression uses: nested::ret, which turns out to be Matrix3d because the internal logic of @@ -456,4 +442,6 @@ struct is_lvalue } // end namespace internal +} // end namespace Eigen + #endif // EIGEN_XPRHELPER_H diff --git a/extern/Eigen3/Eigen/src/Eigen2Support/Block.h b/extern/Eigen3/Eigen/src/Eigen2Support/Block.h index bc28051e017..604456f40e7 100644 --- a/extern/Eigen3/Eigen/src/Eigen2Support/Block.h +++ b/extern/Eigen3/Eigen/src/Eigen2Support/Block.h @@ -4,28 +4,15 @@ // Copyright (C) 2008-2009 Gael Guennebaud // Copyright (C) 2006-2008 Benoit Jacob // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_BLOCK2_H #define EIGEN_BLOCK2_H +namespace Eigen { + /** \returns a dynamic-size expression of a corner of *this. * * \param type the type of corner. Can be \a Eigen::TopLeft, \a Eigen::TopRight, @@ -134,4 +121,6 @@ DenseBase::corner(CornerType type) const } } +} // end namespace Eigen + #endif // EIGEN_BLOCK2_H diff --git a/extern/Eigen3/Eigen/src/Eigen2Support/Cwise.h b/extern/Eigen3/Eigen/src/Eigen2Support/Cwise.h index 2dc83b6a7dd..d95009b6e29 100644 --- a/extern/Eigen3/Eigen/src/Eigen2Support/Cwise.h +++ b/extern/Eigen3/Eigen/src/Eigen2Support/Cwise.h @@ -4,28 +4,15 @@ // Copyright (C) 2008 Gael Guennebaud // Copyright (C) 2008 Benoit Jacob // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_CWISE_H #define EIGEN_CWISE_H +namespace Eigen { + /** \internal * convenient macro to defined the return type of a cwise binary operation */ #define EIGEN_CWISE_BINOP_RETURN_TYPE(OP) \ @@ -200,4 +187,6 @@ inline Cwise MatrixBase::cwise() return derived(); } +} // end namespace Eigen + #endif // EIGEN_CWISE_H diff --git a/extern/Eigen3/Eigen/src/Eigen2Support/CwiseOperators.h b/extern/Eigen3/Eigen/src/Eigen2Support/CwiseOperators.h index 9c28559c329..482f3064856 100644 --- a/extern/Eigen3/Eigen/src/Eigen2Support/CwiseOperators.h +++ b/extern/Eigen3/Eigen/src/Eigen2Support/CwiseOperators.h @@ -3,28 +3,15 @@ // // Copyright (C) 2008 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_ARRAY_CWISE_OPERATORS_H #define EIGEN_ARRAY_CWISE_OPERATORS_H +namespace Eigen { + /*************************************************************************** * The following functions were defined in Core ***************************************************************************/ @@ -306,4 +293,6 @@ inline ExpressionType& Cwise::operator-=(const Scalar& scalar) return m_matrix.const_cast_derived() = *this - scalar; } +} // end namespace Eigen + #endif // EIGEN_ARRAY_CWISE_OPERATORS_H diff --git a/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/AlignedBox.h b/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/AlignedBox.h index 78df29d408a..5c928e8fc2d 100644 --- a/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/AlignedBox.h +++ b/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/AlignedBox.h @@ -3,27 +3,14 @@ // // Copyright (C) 2008 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. // no include guard, we'll include this twice from All.h from Eigen2Support, and it's internal anyway +namespace Eigen { + /** \geometry_module \ingroup Geometry_Module * \nonstableyet * @@ -63,7 +50,7 @@ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_AmbientDim== ~AlignedBox() {} /** \returns the dimension in which the box holds */ - inline int dim() const { return AmbientDimAtCompileTime==Dynamic ? m_min.size()-1 : int(AmbientDimAtCompileTime); } + inline int dim() const { return AmbientDimAtCompileTime==Dynamic ? m_min.size()-1 : AmbientDimAtCompileTime; } /** \returns true if the box is null, i.e, empty. */ inline bool isNull() const { return (m_min.cwise() > m_max).any(); } @@ -157,14 +144,16 @@ protected: template inline Scalar AlignedBox::squaredExteriorDistance(const VectorType& p) const { - Scalar dist2 = 0.; + Scalar dist2(0); Scalar aux; for (int k=0; k // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. // no include guard, we'll include this twice from All.h from Eigen2Support, and it's internal anyway +namespace Eigen { /** \geometry_module \ingroup Geometry_Module * @@ -224,3 +210,5 @@ AngleAxis::toRotationMatrix(void) const return res; } + +} // end namespace Eigen diff --git a/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Hyperplane.h b/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Hyperplane.h index 81c4f55b173..19cc1bfd883 100644 --- a/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Hyperplane.h +++ b/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Hyperplane.h @@ -4,27 +4,14 @@ // Copyright (C) 2008 Gael Guennebaud // Copyright (C) 2008 Benoit Jacob // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. // no include guard, we'll include this twice from All.h from Eigen2Support, and it's internal anyway +namespace Eigen { + /** \geometry_module \ingroup Geometry_Module * * \class Hyperplane @@ -263,3 +250,5 @@ protected: Coefficients m_coeffs; }; + +} // end namespace Eigen diff --git a/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/ParametrizedLine.h b/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/ParametrizedLine.h index 411c4b57079..6e4a168a8cd 100644 --- a/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/ParametrizedLine.h +++ b/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/ParametrizedLine.h @@ -4,27 +4,13 @@ // Copyright (C) 2008 Gael Guennebaud // Copyright (C) 2008 Benoit Jacob // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. // no include guard, we'll include this twice from All.h from Eigen2Support, and it's internal anyway +namespace Eigen { /** \geometry_module \ingroup Geometry_Module * @@ -151,3 +137,5 @@ inline _Scalar ParametrizedLine<_Scalar, _AmbientDim>::intersection(const Hyperp return -(hyperplane.offset()+origin().eigen2_dot(hyperplane.normal())) /(direction().eigen2_dot(hyperplane.normal())); } + +} // end namespace Eigen diff --git a/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Quaternion.h b/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Quaternion.h index a75fa42aeac..ec87da054d6 100644 --- a/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Quaternion.h +++ b/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Quaternion.h @@ -3,27 +3,14 @@ // // Copyright (C) 2008 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. // no include guard, we'll include this twice from All.h from Eigen2Support, and it's internal anyway +namespace Eigen { + template @@ -143,7 +130,7 @@ public: /** \returns a quaternion representing an identity rotation * \sa MatrixBase::Identity() */ - inline static Quaternion Identity() { return Quaternion(1, 0, 0, 0); } + static inline Quaternion Identity() { return Quaternion(1, 0, 0, 0); } /** \sa Quaternion::Identity(), MatrixBase::setIdentity() */ @@ -314,9 +301,9 @@ Quaternion::toRotationMatrix(void) const // it has to be inlined, and so the return by value is not an issue Matrix3 res; - const Scalar tx = 2*this->x(); - const Scalar ty = 2*this->y(); - const Scalar tz = 2*this->z(); + const Scalar tx = Scalar(2)*this->x(); + const Scalar ty = Scalar(2)*this->y(); + const Scalar tz = Scalar(2)*this->z(); const Scalar twx = tx*this->w(); const Scalar twy = ty*this->w(); const Scalar twz = tz*this->w(); @@ -327,15 +314,15 @@ Quaternion::toRotationMatrix(void) const const Scalar tyz = tz*this->y(); const Scalar tzz = tz*this->z(); - res.coeffRef(0,0) = 1-(tyy+tzz); + res.coeffRef(0,0) = Scalar(1)-(tyy+tzz); res.coeffRef(0,1) = txy-twz; res.coeffRef(0,2) = txz+twy; res.coeffRef(1,0) = txy+twz; - res.coeffRef(1,1) = 1-(txx+tzz); + res.coeffRef(1,1) = Scalar(1)-(txx+tzz); res.coeffRef(1,2) = tyz-twx; res.coeffRef(2,0) = txz-twy; res.coeffRef(2,1) = tyz+twx; - res.coeffRef(2,2) = 1-(txx+tyy); + res.coeffRef(2,2) = Scalar(1)-(txx+tyy); return res; } @@ -460,7 +447,7 @@ template struct ei_quaternion_assign_impl { typedef typename Other::Scalar Scalar; - inline static void run(Quaternion& q, const Other& mat) + static inline void run(Quaternion& q, const Other& mat) { // This algorithm comes from "Quaternion Calculus and Fast Animation", // Ken Shoemake, 1987 SIGGRAPH course notes @@ -499,8 +486,10 @@ template struct ei_quaternion_assign_impl { typedef typename Other::Scalar Scalar; - inline static void run(Quaternion& q, const Other& vec) + static inline void run(Quaternion& q, const Other& vec) { q.coeffs() = vec; } }; + +} // end namespace Eigen diff --git a/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Rotation2D.h b/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Rotation2D.h index ee7c80e7eaa..3e02b7a4fd1 100644 --- a/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Rotation2D.h +++ b/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Rotation2D.h @@ -3,27 +3,13 @@ // // Copyright (C) 2008 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. // no include guard, we'll include this twice from All.h from Eigen2Support, and it's internal anyway +namespace Eigen { /** \geometry_module \ingroup Geometry_Module * @@ -155,3 +141,5 @@ Rotation2D::toRotationMatrix(void) const Scalar cosA = ei_cos(m_angle); return (Matrix2() << cosA, -sinA, sinA, cosA).finished(); } + +} // end namespace Eigen diff --git a/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/RotationBase.h b/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/RotationBase.h index 2f494f198bd..78ad73b60ad 100644 --- a/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/RotationBase.h +++ b/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/RotationBase.h @@ -3,27 +3,14 @@ // // Copyright (C) 2008 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. // no include guard, we'll include this twice from All.h from Eigen2Support, and it's internal anyway +namespace Eigen { + // this file aims to contains the various representations of rotation/orientation // in 2D and 3D space excepted Matrix and Quaternion. @@ -113,22 +100,24 @@ Matrix<_Scalar, _Rows, _Cols, _Storage, _MaxRows, _MaxCols> * \sa class Transform, class Rotation2D, class Quaternion, class AngleAxis */ template -inline static Matrix ei_toRotationMatrix(const Scalar& s) +static inline Matrix ei_toRotationMatrix(const Scalar& s) { EIGEN_STATIC_ASSERT(Dim==2,YOU_MADE_A_PROGRAMMING_MISTAKE) return Rotation2D(s).toRotationMatrix(); } template -inline static Matrix ei_toRotationMatrix(const RotationBase& r) +static inline Matrix ei_toRotationMatrix(const RotationBase& r) { return r.toRotationMatrix(); } template -inline static const MatrixBase& ei_toRotationMatrix(const MatrixBase& mat) +static inline const MatrixBase& ei_toRotationMatrix(const MatrixBase& mat) { EIGEN_STATIC_ASSERT(OtherDerived::RowsAtCompileTime==Dim && OtherDerived::ColsAtCompileTime==Dim, YOU_MADE_A_PROGRAMMING_MISTAKE) return mat; } + +} // end namespace Eigen diff --git a/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Scaling.h b/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Scaling.h index 108e6d7d58f..a07c1c7c762 100644 --- a/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Scaling.h +++ b/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Scaling.h @@ -3,27 +3,13 @@ // // Copyright (C) 2008 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. // no include guard, we'll include this twice from All.h from Eigen2Support, and it's internal anyway +namespace Eigen { /** \geometry_module \ingroup Geometry_Module * @@ -177,3 +163,5 @@ Scaling::operator* (const TransformType& t) const res.prescale(m_coeffs); return res; } + +} // end namespace Eigen diff --git a/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Transform.h b/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Transform.h index 88956c86c73..dceb8020383 100644 --- a/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Transform.h +++ b/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Transform.h @@ -4,27 +4,13 @@ // Copyright (C) 2008 Gael Guennebaud // Copyright (C) 2009 Benoit Jacob // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. // no include guard, we'll include this twice from All.h from Eigen2Support, and it's internal anyway +namespace Eigen { // Note that we have to pass Dim and HDim because it is not allowed to use a template // parameter to define a template specialization. To be more precise, in the following @@ -796,3 +782,5 @@ struct ei_transform_product_impl { return ((tr.linear() * other) + tr.translation()) * (Scalar(1) / ( (tr.matrix().template block<1,Dim>(Dim,0) * other).coeff(0) + tr.matrix().coeff(Dim,Dim))); } }; + +} // end namespace Eigen diff --git a/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Translation.h b/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Translation.h index e651e310212..0fb9a9f9a5a 100644 --- a/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Translation.h +++ b/extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Translation.h @@ -3,27 +3,13 @@ // // Copyright (C) 2008 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. // no include guard, we'll include this twice from All.h from Eigen2Support, and it's internal anyway +namespace Eigen { /** \geometry_module \ingroup Geometry_Module * @@ -194,3 +180,5 @@ Translation::operator* (const TransformType& t) const res.pretranslate(m_coeffs); return res; } + +} // end namespace Eigen diff --git a/extern/Eigen3/Eigen/src/Eigen2Support/LU.h b/extern/Eigen3/Eigen/src/Eigen2Support/LU.h index c23c11baa72..49f19ad76e3 100644 --- a/extern/Eigen3/Eigen/src/Eigen2Support/LU.h +++ b/extern/Eigen3/Eigen/src/Eigen2Support/LU.h @@ -3,28 +3,15 @@ // // Copyright (C) 2011 Benoit Jacob // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN2_LU_H #define EIGEN2_LU_H +namespace Eigen { + template class LU : public FullPivLU { @@ -57,7 +44,6 @@ class LU : public FullPivLU > ImageResultType; typedef FullPivLU Base; - LU() : Base() {} template explicit LU(const T& t) : Base(t), m_originalMatrix(t) {} @@ -129,5 +115,6 @@ MatrixBase::eigen2_lu() const } #endif +} // end namespace Eigen #endif // EIGEN2_LU_H diff --git a/extern/Eigen3/Eigen/src/Eigen2Support/Lazy.h b/extern/Eigen3/Eigen/src/Eigen2Support/Lazy.h index c4288ede2ef..593fc78e6de 100644 --- a/extern/Eigen3/Eigen/src/Eigen2Support/Lazy.h +++ b/extern/Eigen3/Eigen/src/Eigen2Support/Lazy.h @@ -3,28 +3,15 @@ // // Copyright (C) 2008 Benoit Jacob // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_LAZY_H #define EIGEN_LAZY_H +namespace Eigen { + /** \deprecated it is only used by lazy() which is deprecated * * \returns an expression of *this with added flags @@ -79,4 +66,6 @@ Derived& MatrixBase::operator-=(const Flagged // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN2_LEASTSQUARES_H #define EIGEN2_LEASTSQUARES_H +namespace Eigen { + /** \ingroup LeastSquares_Module * * \leastsquares_module @@ -178,5 +165,6 @@ void fitHyperplane(int numPoints, result->offset() = - (result->normal().cwise()* mean).sum(); } +} // end namespace Eigen #endif // EIGEN2_LEASTSQUARES_H diff --git a/extern/Eigen3/Eigen/src/Eigen2Support/Macros.h b/extern/Eigen3/Eigen/src/Eigen2Support/Macros.h index 77e85a41e3d..351c32afb60 100644 --- a/extern/Eigen3/Eigen/src/Eigen2Support/Macros.h +++ b/extern/Eigen3/Eigen/src/Eigen2Support/Macros.h @@ -3,24 +3,9 @@ // // Copyright (C) 2011 Benoit Jacob // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN2_MACROS_H #define EIGEN2_MACROS_H diff --git a/extern/Eigen3/Eigen/src/Eigen2Support/MathFunctions.h b/extern/Eigen3/Eigen/src/Eigen2Support/MathFunctions.h index caa44e63f32..3a8a9ca8146 100644 --- a/extern/Eigen3/Eigen/src/Eigen2Support/MathFunctions.h +++ b/extern/Eigen3/Eigen/src/Eigen2Support/MathFunctions.h @@ -3,28 +3,15 @@ // // Copyright (C) 2010 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN2_MATH_FUNCTIONS_H #define EIGEN2_MATH_FUNCTIONS_H +namespace Eigen { + template inline typename NumTraits::Real ei_real(const T& x) { return internal::real(x); } template inline typename NumTraits::Real ei_imag(const T& x) { return internal::imag(x); } template inline T ei_conj(const T& x) { return internal::conj(x); } @@ -65,4 +52,6 @@ inline bool ei_isApproxOrLessThan(const Scalar& x, const Scalar& y, return internal::isApproxOrLessThan(x, y, precision); } +} // end namespace Eigen + #endif // EIGEN2_MATH_FUNCTIONS_H diff --git a/extern/Eigen3/Eigen/src/Eigen2Support/Memory.h b/extern/Eigen3/Eigen/src/Eigen2Support/Memory.h index 0283475419e..f86372b6b56 100644 --- a/extern/Eigen3/Eigen/src/Eigen2Support/Memory.h +++ b/extern/Eigen3/Eigen/src/Eigen2Support/Memory.h @@ -3,28 +3,15 @@ // // Copyright (C) 2011 Benoit Jacob // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN2_MEMORY_H #define EIGEN2_MEMORY_H +namespace Eigen { + inline void* ei_aligned_malloc(size_t size) { return internal::aligned_malloc(size); } inline void ei_aligned_free(void *ptr) { internal::aligned_free(ptr); } inline void* ei_aligned_realloc(void *ptr, size_t new_size, size_t old_size) { return internal::aligned_realloc(ptr, new_size, old_size); } @@ -53,6 +40,6 @@ template inline void ei_aligned_delete(T *ptr, size_t size) return internal::aligned_delete(ptr, size); } - +} // end namespace Eigen #endif // EIGEN2_MACROS_H diff --git a/extern/Eigen3/Eigen/src/Eigen2Support/Meta.h b/extern/Eigen3/Eigen/src/Eigen2Support/Meta.h index 6e500b79a2e..fa37cfc961e 100644 --- a/extern/Eigen3/Eigen/src/Eigen2Support/Meta.h +++ b/extern/Eigen3/Eigen/src/Eigen2Support/Meta.h @@ -3,28 +3,15 @@ // // Copyright (C) 2011 Benoit Jacob // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN2_META_H #define EIGEN2_META_H +namespace Eigen { + template struct ei_traits : internal::traits {}; @@ -83,4 +70,6 @@ class ei_meta_sqrt template class ei_meta_sqrt { public: enum { ret = (SupX*SupX <= Y) ? SupX : InfX }; }; +} // end namespace Eigen + #endif // EIGEN2_META_H diff --git a/extern/Eigen3/Eigen/src/Eigen2Support/Minor.h b/extern/Eigen3/Eigen/src/Eigen2Support/Minor.h index eda91cc32be..4cded5734fa 100644 --- a/extern/Eigen3/Eigen/src/Eigen2Support/Minor.h +++ b/extern/Eigen3/Eigen/src/Eigen2Support/Minor.h @@ -3,28 +3,15 @@ // // Copyright (C) 2006-2009 Benoit Jacob // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_MINOR_H #define EIGEN_MINOR_H +namespace Eigen { + /** * \class Minor * @@ -125,4 +112,6 @@ MatrixBase::minor(Index row, Index col) const return Minor(derived(), row, col); } +} // end namespace Eigen + #endif // EIGEN_MINOR_H diff --git a/extern/Eigen3/Eigen/src/Eigen2Support/QR.h b/extern/Eigen3/Eigen/src/Eigen2Support/QR.h index 64f5d5ccb30..2042c98510a 100644 --- a/extern/Eigen3/Eigen/src/Eigen2Support/QR.h +++ b/extern/Eigen3/Eigen/src/Eigen2Support/QR.h @@ -4,28 +4,15 @@ // Copyright (C) 2008 Gael Guennebaud // Copyright (C) 2011 Benoit Jacob // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN2_QR_H #define EIGEN2_QR_H +namespace Eigen { + template class QR : public HouseholderQR { @@ -75,5 +62,6 @@ MatrixBase::qr() const return QR(eval()); } +} // end namespace Eigen #endif // EIGEN2_QR_H diff --git a/extern/Eigen3/Eigen/src/Eigen2Support/SVD.h b/extern/Eigen3/Eigen/src/Eigen2Support/SVD.h index 16b4b488f0c..3d2eeb44586 100644 --- a/extern/Eigen3/Eigen/src/Eigen2Support/SVD.h +++ b/extern/Eigen3/Eigen/src/Eigen2Support/SVD.h @@ -3,28 +3,15 @@ // // Copyright (C) 2008 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN2_SVD_H #define EIGEN2_SVD_H +namespace Eigen { + /** \ingroup SVD_Module * \nonstableyet * @@ -390,7 +377,7 @@ void SVD::compute(const MatrixType& matrix) Scalar ek = e[k]/scale; Scalar b = ((spm1 + sp)*(spm1 - sp) + epm1*epm1)/Scalar(2); Scalar c = (sp*epm1)*(sp*epm1); - Scalar shift = 0.0; + Scalar shift(0); if ((b != 0.0) || (c != 0.0)) { shift = ei_sqrt(b*b + c); @@ -646,4 +633,6 @@ MatrixBase::svd() const return SVD(derived()); } +} // end namespace Eigen + #endif // EIGEN2_SVD_H diff --git a/extern/Eigen3/Eigen/src/Eigen2Support/TriangularSolver.h b/extern/Eigen3/Eigen/src/Eigen2Support/TriangularSolver.h index e94e47a5093..ebbeb3b4958 100644 --- a/extern/Eigen3/Eigen/src/Eigen2Support/TriangularSolver.h +++ b/extern/Eigen3/Eigen/src/Eigen2Support/TriangularSolver.h @@ -3,28 +3,15 @@ // // Copyright (C) 2010 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_TRIANGULAR_SOLVER2_H #define EIGEN_TRIANGULAR_SOLVER2_H +namespace Eigen { + const unsigned int UnitDiagBit = UnitDiag; const unsigned int SelfAdjointBit = SelfAdjoint; const unsigned int UpperTriangularBit = Upper; @@ -49,5 +36,7 @@ void Flagged::solveTriangularInPlace(const MatrixB { m_matrix.template triangularView().solveInPlace(other.derived()); } + +} // end namespace Eigen #endif // EIGEN_TRIANGULAR_SOLVER2_H diff --git a/extern/Eigen3/Eigen/src/Eigen2Support/VectorBlock.h b/extern/Eigen3/Eigen/src/Eigen2Support/VectorBlock.h index 010031d1971..71a8080a9fc 100644 --- a/extern/Eigen3/Eigen/src/Eigen2Support/VectorBlock.h +++ b/extern/Eigen3/Eigen/src/Eigen2Support/VectorBlock.h @@ -4,28 +4,15 @@ // Copyright (C) 2008-2009 Gael Guennebaud // Copyright (C) 2006-2008 Benoit Jacob // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN2_VECTORBLOCK_H #define EIGEN2_VECTORBLOCK_H +namespace Eigen { + /** \deprecated use DenseMase::head(Index) */ template inline VectorBlock @@ -102,4 +89,6 @@ MatrixBase::end() const return VectorBlock(derived(), size() - Size); } +} // end namespace Eigen + #endif // EIGEN2_VECTORBLOCK_H diff --git a/extern/Eigen3/Eigen/src/Eigenvalues/ComplexEigenSolver.h b/extern/Eigen3/Eigen/src/Eigenvalues/ComplexEigenSolver.h index 57e00227d72..c4b8a308cee 100644 --- a/extern/Eigen3/Eigen/src/Eigenvalues/ComplexEigenSolver.h +++ b/extern/Eigen3/Eigen/src/Eigenvalues/ComplexEigenSolver.h @@ -5,31 +5,17 @@ // Copyright (C) 2009 Gael Guennebaud // Copyright (C) 2010 Jitse Niesen // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_COMPLEX_EIGEN_SOLVER_H #define EIGEN_COMPLEX_EIGEN_SOLVER_H -#include "./EigenvaluesCommon.h" #include "./ComplexSchur.h" +namespace Eigen { + /** \eigenvalues_module \ingroup Eigenvalues_Module * * @@ -328,5 +314,6 @@ void ComplexEigenSolver::sortEigenvalues(bool computeEigenvectors) } } +} // end namespace Eigen #endif // EIGEN_COMPLEX_EIGEN_SOLVER_H diff --git a/extern/Eigen3/Eigen/src/Eigenvalues/ComplexSchur.h b/extern/Eigen3/Eigen/src/Eigenvalues/ComplexSchur.h index ec93af2e58a..16a9a03d219 100644 --- a/extern/Eigen3/Eigen/src/Eigenvalues/ComplexSchur.h +++ b/extern/Eigen3/Eigen/src/Eigenvalues/ComplexSchur.h @@ -5,31 +5,17 @@ // Copyright (C) 2009 Gael Guennebaud // Copyright (C) 2010 Jitse Niesen // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_COMPLEX_SCHUR_H #define EIGEN_COMPLEX_SCHUR_H -#include "./EigenvaluesCommon.h" #include "./HessenbergDecomposition.h" +namespace Eigen { + namespace internal { template struct complex_schur_reduce_to_hessenberg; } @@ -227,46 +213,6 @@ template class ComplexSchur friend struct internal::complex_schur_reduce_to_hessenberg::IsComplex>; }; -namespace internal { - -/** Computes the principal value of the square root of the complex \a z. */ -template -std::complex sqrt(const std::complex &z) -{ - RealScalar t, tre, tim; - - t = abs(z); - - if (abs(real(z)) <= abs(imag(z))) - { - // No cancellation in these formulas - tre = sqrt(RealScalar(0.5)*(t + real(z))); - tim = sqrt(RealScalar(0.5)*(t - real(z))); - } - else - { - // Stable computation of the above formulas - if (z.real() > RealScalar(0)) - { - tre = t + z.real(); - tim = abs(imag(z))*sqrt(RealScalar(0.5)/tre); - tre = sqrt(RealScalar(0.5)*tre); - } - else - { - tim = t - z.real(); - tre = abs(imag(z))*sqrt(RealScalar(0.5)/tim); - tim = sqrt(RealScalar(0.5)*tim); - } - } - if(z.imag() < RealScalar(0)) - tim = -tim; - - return (std::complex(tre,tim)); -} -} // end namespace internal - - /** If m_matT(i+1,i) is neglegible in floating point arithmetic * compared to m_matT(i,i) and m_matT(j,j), then set it to zero and * return true, else return false. */ @@ -302,7 +248,7 @@ typename ComplexSchur::ComplexScalar ComplexSchur::compu ComplexScalar b = t.coeff(0,1) * t.coeff(1,0); ComplexScalar c = t.coeff(0,0) - t.coeff(1,1); - ComplexScalar disc = internal::sqrt(c*c + RealScalar(4)*b); + ComplexScalar disc = sqrt(c*c + RealScalar(4)*b); ComplexScalar det = t.coeff(0,0) * t.coeff(1,1) - b; ComplexScalar trace = t.coeff(0,0) + t.coeff(1,1); ComplexScalar eival1 = (trace + disc) / RealScalar(2); @@ -406,7 +352,7 @@ void ComplexSchur::reduceToTriangularForm(bool computeU) // if we spent too many iterations on the current element, we give up iter++; - if(iter > m_maxIterations) break; + if(iter > m_maxIterations * m_matT.cols()) break; // find il, the top row of the active submatrix il = iu-1; @@ -436,7 +382,7 @@ void ComplexSchur::reduceToTriangularForm(bool computeU) } } - if(iter <= m_maxIterations) + if(iter <= m_maxIterations * m_matT.cols()) m_info = Success; else m_info = NoConvergence; @@ -445,4 +391,6 @@ void ComplexSchur::reduceToTriangularForm(bool computeU) m_matUisUptodate = computeU; } +} // end namespace Eigen + #endif // EIGEN_COMPLEX_SCHUR_H diff --git a/extern/Eigen3/Eigen/src/Eigenvalues/ComplexSchur_MKL.h b/extern/Eigen3/Eigen/src/Eigenvalues/ComplexSchur_MKL.h new file mode 100644 index 00000000000..aa18e696352 --- /dev/null +++ b/extern/Eigen3/Eigen/src/Eigenvalues/ComplexSchur_MKL.h @@ -0,0 +1,94 @@ +/* + Copyright (c) 2011, Intel Corporation. All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of Intel Corporation nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ******************************************************************************** + * Content : Eigen bindings to Intel(R) MKL + * Complex Schur needed to complex unsymmetrical eigenvalues/eigenvectors. + ******************************************************************************** +*/ + +#ifndef EIGEN_COMPLEX_SCHUR_MKL_H +#define EIGEN_COMPLEX_SCHUR_MKL_H + +#include "Eigen/src/Core/util/MKL_support.h" + +namespace Eigen { + +/** \internal Specialization for the data types supported by MKL */ + +#define EIGEN_MKL_SCHUR_COMPLEX(EIGTYPE, MKLTYPE, MKLPREFIX, MKLPREFIX_U, EIGCOLROW, MKLCOLROW) \ +template<> inline\ +ComplexSchur >& \ +ComplexSchur >::compute(const Matrix& matrix, bool computeU) \ +{ \ + typedef Matrix MatrixType; \ + typedef MatrixType::Scalar Scalar; \ + typedef MatrixType::RealScalar RealScalar; \ + typedef std::complex ComplexScalar; \ +\ + assert(matrix.cols() == matrix.rows()); \ +\ + m_matUisUptodate = false; \ + if(matrix.cols() == 1) \ + { \ + m_matT = matrix.cast(); \ + if(computeU) m_matU = ComplexMatrixType::Identity(1,1); \ + m_info = Success; \ + m_isInitialized = true; \ + m_matUisUptodate = computeU; \ + return *this; \ + } \ + lapack_int n = matrix.cols(), sdim, info; \ + lapack_int lda = matrix.outerStride(); \ + lapack_int matrix_order = MKLCOLROW; \ + char jobvs, sort='N'; \ + LAPACK_##MKLPREFIX_U##_SELECT1 select = 0; \ + jobvs = (computeU) ? 'V' : 'N'; \ + m_matU.resize(n, n); \ + lapack_int ldvs = m_matU.outerStride(); \ + m_matT = matrix; \ + Matrix w; \ + w.resize(n, 1);\ + info = LAPACKE_##MKLPREFIX##gees( matrix_order, jobvs, sort, select, n, (MKLTYPE*)m_matT.data(), lda, &sdim, (MKLTYPE*)w.data(), (MKLTYPE*)m_matU.data(), ldvs ); \ + if(info == 0) \ + m_info = Success; \ + else \ + m_info = NoConvergence; \ +\ + m_isInitialized = true; \ + m_matUisUptodate = computeU; \ + return *this; \ +\ +} + +EIGEN_MKL_SCHUR_COMPLEX(dcomplex, MKL_Complex16, z, Z, ColMajor, LAPACK_COL_MAJOR) +EIGEN_MKL_SCHUR_COMPLEX(scomplex, MKL_Complex8, c, C, ColMajor, LAPACK_COL_MAJOR) +EIGEN_MKL_SCHUR_COMPLEX(dcomplex, MKL_Complex16, z, Z, RowMajor, LAPACK_ROW_MAJOR) +EIGEN_MKL_SCHUR_COMPLEX(scomplex, MKL_Complex8, c, C, RowMajor, LAPACK_ROW_MAJOR) + +} // end namespace Eigen + +#endif // EIGEN_COMPLEX_SCHUR_MKL_H diff --git a/extern/Eigen3/Eigen/src/Eigenvalues/EigenSolver.h b/extern/Eigen3/Eigen/src/Eigenvalues/EigenSolver.h index f57353c065f..c16ff2b74e2 100644 --- a/extern/Eigen3/Eigen/src/Eigenvalues/EigenSolver.h +++ b/extern/Eigen3/Eigen/src/Eigenvalues/EigenSolver.h @@ -4,31 +4,17 @@ // Copyright (C) 2008 Gael Guennebaud // Copyright (C) 2010 Jitse Niesen // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_EIGENSOLVER_H #define EIGEN_EIGENSOLVER_H -#include "./EigenvaluesCommon.h" #include "./RealSchur.h" +namespace Eigen { + /** \eigenvalues_module \ingroup Eigenvalues_Module * * @@ -432,7 +418,7 @@ void EigenSolver::doComputeEigenvectors() const Scalar eps = NumTraits::epsilon(); // inefficient! this is already computed in RealSchur - Scalar norm = 0.0; + Scalar norm(0); for (Index j = 0; j < size; ++j) { norm += m_matT.row(j).segment((std::max)(j-1,Index(0)), size-(std::max)(j-1,Index(0))).cwiseAbs().sum(); @@ -452,7 +438,7 @@ void EigenSolver::doComputeEigenvectors() // Scalar vector if (q == Scalar(0)) { - Scalar lastr=0, lastw=0; + Scalar lastr(0), lastw(0); Index l = n; m_matT.coeffRef(n,n) = 1.0; @@ -498,7 +484,7 @@ void EigenSolver::doComputeEigenvectors() } else if (q < Scalar(0) && n > 0) // Complex vector { - Scalar lastra=0, lastsa=0, lastw=0; + Scalar lastra(0), lastsa(0), lastw(0); Index l = n-1; // Last vector component imaginary so matrix is triangular @@ -588,4 +574,6 @@ void EigenSolver::doComputeEigenvectors() } } +} // end namespace Eigen + #endif // EIGEN_EIGENSOLVER_H diff --git a/extern/Eigen3/Eigen/src/Eigenvalues/EigenvaluesCommon.h b/extern/Eigen3/Eigen/src/Eigenvalues/EigenvaluesCommon.h deleted file mode 100644 index 749bea79500..00000000000 --- a/extern/Eigen3/Eigen/src/Eigenvalues/EigenvaluesCommon.h +++ /dev/null @@ -1,31 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2010 Jitse Niesen -// -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . - -#ifndef EIGEN_EIGENVALUES_COMMON_H -#define EIGEN_EIGENVALUES_COMMON_H - - - -#endif // EIGEN_EIGENVALUES_COMMON_H - diff --git a/extern/Eigen3/Eigen/src/Eigenvalues/GeneralizedSelfAdjointEigenSolver.h b/extern/Eigen3/Eigen/src/Eigenvalues/GeneralizedSelfAdjointEigenSolver.h index 980af14ce71..07bf1ea0956 100644 --- a/extern/Eigen3/Eigen/src/Eigenvalues/GeneralizedSelfAdjointEigenSolver.h +++ b/extern/Eigen3/Eigen/src/Eigenvalues/GeneralizedSelfAdjointEigenSolver.h @@ -4,31 +4,17 @@ // Copyright (C) 2008-2010 Gael Guennebaud // Copyright (C) 2010 Jitse Niesen // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_GENERALIZEDSELFADJOINTEIGENSOLVER_H #define EIGEN_GENERALIZEDSELFADJOINTEIGENSOLVER_H -#include "./EigenvaluesCommon.h" #include "./Tridiagonalization.h" +namespace Eigen { + /** \eigenvalues_module \ingroup Eigenvalues_Module * * @@ -236,4 +222,6 @@ compute(const MatrixType& matA, const MatrixType& matB, int options) return *this; } +} // end namespace Eigen + #endif // EIGEN_GENERALIZEDSELFADJOINTEIGENSOLVER_H diff --git a/extern/Eigen3/Eigen/src/Eigenvalues/HessenbergDecomposition.h b/extern/Eigen3/Eigen/src/Eigenvalues/HessenbergDecomposition.h index c17f155a59b..b8378b08a09 100644 --- a/extern/Eigen3/Eigen/src/Eigenvalues/HessenbergDecomposition.h +++ b/extern/Eigen3/Eigen/src/Eigenvalues/HessenbergDecomposition.h @@ -4,28 +4,15 @@ // Copyright (C) 2008-2009 Gael Guennebaud // Copyright (C) 2010 Jitse Niesen // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_HESSENBERGDECOMPOSITION_H #define EIGEN_HESSENBERGDECOMPOSITION_H +namespace Eigen { + namespace internal { template struct HessenbergDecompositionMatrixHReturnType; @@ -379,6 +366,8 @@ template struct HessenbergDecompositionMatrixHReturnType const HessenbergDecomposition& m_hess; }; -} +} // end namespace internal + +} // end namespace Eigen #endif // EIGEN_HESSENBERGDECOMPOSITION_H diff --git a/extern/Eigen3/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h b/extern/Eigen3/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h index 5591519fb75..6af481c75f6 100644 --- a/extern/Eigen3/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h +++ b/extern/Eigen3/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h @@ -4,28 +4,15 @@ // Copyright (C) 2008 Gael Guennebaud // Copyright (C) 2010 Jitse Niesen // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_MATRIXBASEEIGENVALUES_H #define EIGEN_MATRIXBASEEIGENVALUES_H +namespace Eigen { + namespace internal { template @@ -167,4 +154,6 @@ SelfAdjointView::operatorNorm() const return eigenvalues().cwiseAbs().maxCoeff(); } +} // end namespace Eigen + #endif diff --git a/extern/Eigen3/Eigen/src/Eigenvalues/RealSchur.h b/extern/Eigen3/Eigen/src/Eigenvalues/RealSchur.h index cc9af11c117..781692eccd3 100644 --- a/extern/Eigen3/Eigen/src/Eigenvalues/RealSchur.h +++ b/extern/Eigen3/Eigen/src/Eigenvalues/RealSchur.h @@ -4,31 +4,17 @@ // Copyright (C) 2008 Gael Guennebaud // Copyright (C) 2010 Jitse Niesen // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_REAL_SCHUR_H #define EIGEN_REAL_SCHUR_H -#include "./EigenvaluesCommon.h" #include "./HessenbergDecomposition.h" +namespace Eigen { + /** \eigenvalues_module \ingroup Eigenvalues_Module * * @@ -235,42 +221,44 @@ RealSchur& RealSchur::compute(const MatrixType& matrix, // Rows iu+1,...,end are already brought in triangular form. Index iu = m_matT.cols() - 1; Index iter = 0; // iteration count - Scalar exshift = 0.0; // sum of exceptional shifts + Scalar exshift(0); // sum of exceptional shifts Scalar norm = computeNormOfT(); - while (iu >= 0) + if(norm!=0) { - Index il = findSmallSubdiagEntry(iu, norm); + while (iu >= 0) + { + Index il = findSmallSubdiagEntry(iu, norm); - // Check for convergence - if (il == iu) // One root found - { - m_matT.coeffRef(iu,iu) = m_matT.coeff(iu,iu) + exshift; - if (iu > 0) - m_matT.coeffRef(iu, iu-1) = Scalar(0); - iu--; - iter = 0; + // Check for convergence + if (il == iu) // One root found + { + m_matT.coeffRef(iu,iu) = m_matT.coeff(iu,iu) + exshift; + if (iu > 0) + m_matT.coeffRef(iu, iu-1) = Scalar(0); + iu--; + iter = 0; + } + else if (il == iu-1) // Two roots found + { + splitOffTwoRows(iu, computeU, exshift); + iu -= 2; + iter = 0; + } + else // No convergence yet + { + // The firstHouseholderVector vector has to be initialized to something to get rid of a silly GCC warning (-O1 -Wall -DNDEBUG ) + Vector3s firstHouseholderVector(0,0,0), shiftInfo; + computeShift(iu, iter, exshift, shiftInfo); + iter = iter + 1; + if (iter > m_maxIterations * m_matT.cols()) break; + Index im; + initFrancisQRStep(il, iu, shiftInfo, im, firstHouseholderVector); + performFrancisQRStep(il, im, iu, computeU, firstHouseholderVector, workspace); + } } - else if (il == iu-1) // Two roots found - { - splitOffTwoRows(iu, computeU, exshift); - iu -= 2; - iter = 0; - } - else // No convergence yet - { - // The firstHouseholderVector vector has to be initialized to something to get rid of a silly GCC warning (-O1 -Wall -DNDEBUG ) - Vector3s firstHouseholderVector(0,0,0), shiftInfo; - computeShift(iu, iter, exshift, shiftInfo); - iter = iter + 1; - if (iter > m_maxIterations) break; - Index im; - initFrancisQRStep(il, iu, shiftInfo, im, firstHouseholderVector); - performFrancisQRStep(il, im, iu, computeU, firstHouseholderVector, workspace); - } - } - - if(iter <= m_maxIterations) + } + if(iter <= m_maxIterations * m_matT.cols()) m_info = Success; else m_info = NoConvergence; @@ -288,7 +276,7 @@ inline typename MatrixType::Scalar RealSchur::computeNormOfT() // FIXME to be efficient the following would requires a triangular reduxion code // Scalar norm = m_matT.upper().cwiseAbs().sum() // + m_matT.bottomLeftCorner(size-1,size-1).diagonal().cwiseAbs().sum(); - Scalar norm = 0.0; + Scalar norm(0); for (Index j = 0; j < size; ++j) norm += m_matT.row(j).segment((std::max)(j-1,Index(0)), size-(std::max)(j-1,Index(0))).cwiseAbs().sum(); return norm; @@ -471,4 +459,6 @@ inline void RealSchur::performFrancisQRStep(Index il, Index im, Inde } } +} // end namespace Eigen + #endif // EIGEN_REAL_SCHUR_H diff --git a/extern/Eigen3/Eigen/src/Eigenvalues/RealSchur_MKL.h b/extern/Eigen3/Eigen/src/Eigenvalues/RealSchur_MKL.h new file mode 100644 index 00000000000..960ec3c764a --- /dev/null +++ b/extern/Eigen3/Eigen/src/Eigenvalues/RealSchur_MKL.h @@ -0,0 +1,83 @@ +/* + Copyright (c) 2011, Intel Corporation. All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of Intel Corporation nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ******************************************************************************** + * Content : Eigen bindings to Intel(R) MKL + * Real Schur needed to real unsymmetrical eigenvalues/eigenvectors. + ******************************************************************************** +*/ + +#ifndef EIGEN_REAL_SCHUR_MKL_H +#define EIGEN_REAL_SCHUR_MKL_H + +#include "Eigen/src/Core/util/MKL_support.h" + +namespace Eigen { + +/** \internal Specialization for the data types supported by MKL */ + +#define EIGEN_MKL_SCHUR_REAL(EIGTYPE, MKLTYPE, MKLPREFIX, MKLPREFIX_U, EIGCOLROW, MKLCOLROW) \ +template<> inline \ +RealSchur >& \ +RealSchur >::compute(const Matrix& matrix, bool computeU) \ +{ \ + typedef Matrix MatrixType; \ + typedef MatrixType::Scalar Scalar; \ + typedef MatrixType::RealScalar RealScalar; \ +\ + assert(matrix.cols() == matrix.rows()); \ +\ + lapack_int n = matrix.cols(), sdim, info; \ + lapack_int lda = matrix.outerStride(); \ + lapack_int matrix_order = MKLCOLROW; \ + char jobvs, sort='N'; \ + LAPACK_##MKLPREFIX_U##_SELECT2 select = 0; \ + jobvs = (computeU) ? 'V' : 'N'; \ + m_matU.resize(n, n); \ + lapack_int ldvs = m_matU.outerStride(); \ + m_matT = matrix; \ + Matrix wr, wi; \ + wr.resize(n, 1); wi.resize(n, 1); \ + info = LAPACKE_##MKLPREFIX##gees( matrix_order, jobvs, sort, select, n, (MKLTYPE*)m_matT.data(), lda, &sdim, (MKLTYPE*)wr.data(), (MKLTYPE*)wi.data(), (MKLTYPE*)m_matU.data(), ldvs ); \ + if(info == 0) \ + m_info = Success; \ + else \ + m_info = NoConvergence; \ +\ + m_isInitialized = true; \ + m_matUisUptodate = computeU; \ + return *this; \ +\ +} + +EIGEN_MKL_SCHUR_REAL(double, double, d, D, ColMajor, LAPACK_COL_MAJOR) +EIGEN_MKL_SCHUR_REAL(float, float, s, S, ColMajor, LAPACK_COL_MAJOR) +EIGEN_MKL_SCHUR_REAL(double, double, d, D, RowMajor, LAPACK_ROW_MAJOR) +EIGEN_MKL_SCHUR_REAL(float, float, s, S, RowMajor, LAPACK_ROW_MAJOR) + +} // end namespace Eigen + +#endif // EIGEN_REAL_SCHUR_MKL_H diff --git a/extern/Eigen3/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h b/extern/Eigen3/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h index ad107c63282..acc5576feb1 100644 --- a/extern/Eigen3/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h +++ b/extern/Eigen3/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h @@ -4,34 +4,24 @@ // Copyright (C) 2008-2010 Gael Guennebaud // Copyright (C) 2010 Jitse Niesen // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_SELFADJOINTEIGENSOLVER_H #define EIGEN_SELFADJOINTEIGENSOLVER_H -#include "./EigenvaluesCommon.h" #include "./Tridiagonalization.h" +namespace Eigen { + template class GeneralizedSelfAdjointEigenSolver; +namespace internal { +template struct direct_selfadjoint_eigenvalues; +} + /** \eigenvalues_module \ingroup Eigenvalues_Module * * @@ -86,7 +76,7 @@ template class SelfAdjointEigenSolver Options = MatrixType::Options, MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime }; - + /** \brief Scalar type for matrices of type \p _MatrixType. */ typedef typename MatrixType::Scalar Scalar; typedef typename MatrixType::Index Index; @@ -98,6 +88,8 @@ template class SelfAdjointEigenSolver * complex. */ typedef typename NumTraits::Real RealScalar; + + friend struct internal::direct_selfadjoint_eigenvalues::IsComplex>; /** \brief Type for vector of eigenvalues as returned by eigenvalues(). * @@ -198,6 +190,22 @@ template class SelfAdjointEigenSolver * \sa SelfAdjointEigenSolver(const MatrixType&, int) */ SelfAdjointEigenSolver& compute(const MatrixType& matrix, int options = ComputeEigenvectors); + + /** \brief Computes eigendecomposition of given matrix using a direct algorithm + * + * This is a variant of compute(const MatrixType&, int options) which + * directly solves the underlying polynomial equation. + * + * Currently only 3x3 matrices for which the sizes are known at compile time are supported (e.g., Matrix3d). + * + * This method is usually significantly faster than the QR algorithm + * but it might also be less accurate. It is also worth noting that + * for 3x3 matrices it involves trigonometric operations which are + * not necessarily available for all scalar types. + * + * \sa compute(const MatrixType&, int options) + */ + SelfAdjointEigenSolver& computeDirect(const MatrixType& matrix, int options = ComputeEigenvectors); /** \brief Returns the eigenvectors of given matrix. * @@ -401,7 +409,7 @@ SelfAdjointEigenSolver& SelfAdjointEigenSolver // map the matrix coefficients to [-1:1] to avoid over- and underflow. RealScalar scale = matrix.cwiseAbs().maxCoeff(); - if(scale==Scalar(0)) scale = 1; + if(scale==RealScalar(0)) scale = RealScalar(1); mat = matrix / scale; m_subdiag.resize(n-1); internal::tridiagonalization_inplace(mat, diag, m_subdiag, computeEigenvectors); @@ -466,19 +474,277 @@ SelfAdjointEigenSolver& SelfAdjointEigenSolver return *this; } + +namespace internal { + +template struct direct_selfadjoint_eigenvalues +{ + static inline void run(SolverType& eig, const typename SolverType::MatrixType& A, int options) + { eig.compute(A,options); } +}; + +template struct direct_selfadjoint_eigenvalues +{ + typedef typename SolverType::MatrixType MatrixType; + typedef typename SolverType::RealVectorType VectorType; + typedef typename SolverType::Scalar Scalar; + + static inline void computeRoots(const MatrixType& m, VectorType& roots) + { + using std::sqrt; + using std::atan2; + using std::cos; + using std::sin; + const Scalar s_inv3 = Scalar(1.0)/Scalar(3.0); + const Scalar s_sqrt3 = sqrt(Scalar(3.0)); + + // The characteristic equation is x^3 - c2*x^2 + c1*x - c0 = 0. The + // eigenvalues are the roots to this equation, all guaranteed to be + // real-valued, because the matrix is symmetric. + Scalar c0 = m(0,0)*m(1,1)*m(2,2) + Scalar(2)*m(1,0)*m(2,0)*m(2,1) - m(0,0)*m(2,1)*m(2,1) - m(1,1)*m(2,0)*m(2,0) - m(2,2)*m(1,0)*m(1,0); + Scalar c1 = m(0,0)*m(1,1) - m(1,0)*m(1,0) + m(0,0)*m(2,2) - m(2,0)*m(2,0) + m(1,1)*m(2,2) - m(2,1)*m(2,1); + Scalar c2 = m(0,0) + m(1,1) + m(2,2); + + // Construct the parameters used in classifying the roots of the equation + // and in solving the equation for the roots in closed form. + Scalar c2_over_3 = c2*s_inv3; + Scalar a_over_3 = (c1 - c2*c2_over_3)*s_inv3; + if (a_over_3 > Scalar(0)) + a_over_3 = Scalar(0); + + Scalar half_b = Scalar(0.5)*(c0 + c2_over_3*(Scalar(2)*c2_over_3*c2_over_3 - c1)); + + Scalar q = half_b*half_b + a_over_3*a_over_3*a_over_3; + if (q > Scalar(0)) + q = Scalar(0); + + // Compute the eigenvalues by solving for the roots of the polynomial. + Scalar rho = sqrt(-a_over_3); + Scalar theta = atan2(sqrt(-q),half_b)*s_inv3; + Scalar cos_theta = cos(theta); + Scalar sin_theta = sin(theta); + roots(0) = c2_over_3 + Scalar(2)*rho*cos_theta; + roots(1) = c2_over_3 - rho*(cos_theta + s_sqrt3*sin_theta); + roots(2) = c2_over_3 - rho*(cos_theta - s_sqrt3*sin_theta); + + // Sort in increasing order. + if (roots(0) >= roots(1)) + std::swap(roots(0),roots(1)); + if (roots(1) >= roots(2)) + { + std::swap(roots(1),roots(2)); + if (roots(0) >= roots(1)) + std::swap(roots(0),roots(1)); + } + } + + static inline void run(SolverType& solver, const MatrixType& mat, int options) + { + using std::sqrt; + eigen_assert(mat.cols() == 3 && mat.cols() == mat.rows()); + eigen_assert((options&~(EigVecMask|GenEigMask))==0 + && (options&EigVecMask)!=EigVecMask + && "invalid option parameter"); + bool computeEigenvectors = (options&ComputeEigenvectors)==ComputeEigenvectors; + + MatrixType& eivecs = solver.m_eivec; + VectorType& eivals = solver.m_eivalues; + + // map the matrix coefficients to [-1:1] to avoid over- and underflow. + Scalar scale = mat.cwiseAbs().maxCoeff(); + MatrixType scaledMat = mat / scale; + + // compute the eigenvalues + computeRoots(scaledMat,eivals); + + // compute the eigen vectors + if(computeEigenvectors) + { + Scalar safeNorm2 = Eigen::NumTraits::epsilon(); + safeNorm2 *= safeNorm2; + if((eivals(2)-eivals(0))<=Eigen::NumTraits::epsilon()) + { + eivecs.setIdentity(); + } + else + { + scaledMat = scaledMat.template selfadjointView(); + MatrixType tmp; + tmp = scaledMat; + + Scalar d0 = eivals(2) - eivals(1); + Scalar d1 = eivals(1) - eivals(0); + int k = d0 > d1 ? 2 : 0; + d0 = d0 > d1 ? d1 : d0; + + tmp.diagonal().array () -= eivals(k); + VectorType cross; + Scalar n; + n = (cross = tmp.row(0).cross(tmp.row(1))).squaredNorm(); + + if(n>safeNorm2) + eivecs.col(k) = cross / sqrt(n); + else + { + n = (cross = tmp.row(0).cross(tmp.row(2))).squaredNorm(); + + if(n>safeNorm2) + eivecs.col(k) = cross / sqrt(n); + else + { + n = (cross = tmp.row(1).cross(tmp.row(2))).squaredNorm(); + + if(n>safeNorm2) + eivecs.col(k) = cross / sqrt(n); + else + { + // the input matrix and/or the eigenvaues probably contains some inf/NaN, + // => exit + // scale back to the original size. + eivals *= scale; + + solver.m_info = NumericalIssue; + solver.m_isInitialized = true; + solver.m_eigenvectorsOk = computeEigenvectors; + return; + } + } + } + + tmp = scaledMat; + tmp.diagonal().array() -= eivals(1); + + if(d0<=Eigen::NumTraits::epsilon()) + eivecs.col(1) = eivecs.col(k).unitOrthogonal(); + else + { + n = (cross = eivecs.col(k).cross(tmp.row(0).normalized())).squaredNorm(); + if(n>safeNorm2) + eivecs.col(1) = cross / sqrt(n); + else + { + n = (cross = eivecs.col(k).cross(tmp.row(1))).squaredNorm(); + if(n>safeNorm2) + eivecs.col(1) = cross / sqrt(n); + else + { + n = (cross = eivecs.col(k).cross(tmp.row(2))).squaredNorm(); + if(n>safeNorm2) + eivecs.col(1) = cross / sqrt(n); + else + { + // we should never reach this point, + // if so the last two eigenvalues are likely to ve very closed to each other + eivecs.col(1) = eivecs.col(k).unitOrthogonal(); + } + } + } + + // make sure that eivecs[1] is orthogonal to eivecs[2] + Scalar d = eivecs.col(1).dot(eivecs.col(k)); + eivecs.col(1) = (eivecs.col(1) - d * eivecs.col(k)).normalized(); + } + + eivecs.col(k==2 ? 0 : 2) = eivecs.col(k).cross(eivecs.col(1)).normalized(); + } + } + // Rescale back to the original size. + eivals *= scale; + + solver.m_info = Success; + solver.m_isInitialized = true; + solver.m_eigenvectorsOk = computeEigenvectors; + } +}; + +// 2x2 direct eigenvalues decomposition, code from Hauke Heibel +template struct direct_selfadjoint_eigenvalues +{ + typedef typename SolverType::MatrixType MatrixType; + typedef typename SolverType::RealVectorType VectorType; + typedef typename SolverType::Scalar Scalar; + + static inline void computeRoots(const MatrixType& m, VectorType& roots) + { + using std::sqrt; + const Scalar t0 = Scalar(0.5) * sqrt( abs2(m(0,0)-m(1,1)) + Scalar(4)*m(1,0)*m(1,0)); + const Scalar t1 = Scalar(0.5) * (m(0,0) + m(1,1)); + roots(0) = t1 - t0; + roots(1) = t1 + t0; + } + + static inline void run(SolverType& solver, const MatrixType& mat, int options) + { + eigen_assert(mat.cols() == 2 && mat.cols() == mat.rows()); + eigen_assert((options&~(EigVecMask|GenEigMask))==0 + && (options&EigVecMask)!=EigVecMask + && "invalid option parameter"); + bool computeEigenvectors = (options&ComputeEigenvectors)==ComputeEigenvectors; + + MatrixType& eivecs = solver.m_eivec; + VectorType& eivals = solver.m_eivalues; + + // map the matrix coefficients to [-1:1] to avoid over- and underflow. + Scalar scale = mat.cwiseAbs().maxCoeff(); + scale = (std::max)(scale,Scalar(1)); + MatrixType scaledMat = mat / scale; + + // Compute the eigenvalues + computeRoots(scaledMat,eivals); + + // compute the eigen vectors + if(computeEigenvectors) + { + scaledMat.diagonal().array () -= eivals(1); + Scalar a2 = abs2(scaledMat(0,0)); + Scalar c2 = abs2(scaledMat(1,1)); + Scalar b2 = abs2(scaledMat(1,0)); + if(a2>c2) + { + eivecs.col(1) << -scaledMat(1,0), scaledMat(0,0); + eivecs.col(1) /= sqrt(a2+b2); + } + else + { + eivecs.col(1) << -scaledMat(1,1), scaledMat(1,0); + eivecs.col(1) /= sqrt(c2+b2); + } + + eivecs.col(0) << eivecs.col(1).unitOrthogonal(); + } + + // Rescale back to the original size. + eivals *= scale; + + solver.m_info = Success; + solver.m_isInitialized = true; + solver.m_eigenvectorsOk = computeEigenvectors; + } +}; + +} + +template +SelfAdjointEigenSolver& SelfAdjointEigenSolver +::computeDirect(const MatrixType& matrix, int options) +{ + internal::direct_selfadjoint_eigenvalues::IsComplex>::run(*this,matrix,options); + return *this; +} + namespace internal { template static void tridiagonal_qr_step(RealScalar* diag, RealScalar* subdiag, Index start, Index end, Scalar* matrixQ, Index n) { - // NOTE this version avoids over & underflow, however since the matrix is prescaled, overflow cannot occur, - // and underflows should be meaningless anyway. So I don't any reason to enable this version, but I keep - // it here for reference: -// RealScalar td = (diag[end-1] - diag[end])*RealScalar(0.5); -// RealScalar e = subdiag[end-1]; -// RealScalar mu = diag[end] - (e / (td + (td>0 ? 1 : -1))) * (e / hypot(td,e)); RealScalar td = (diag[end-1] - diag[end])*RealScalar(0.5); - RealScalar e2 = abs2(subdiag[end-1]); - RealScalar mu = diag[end] - e2 / (td + (td>0 ? 1 : -1) * sqrt(td*td + e2)); + RealScalar e = subdiag[end-1]; + // Note that thanks to scaling, e^2 or td^2 cannot overflow, however they can still + // underflow thus leading to inf/NaN values when using the following commented code: +// RealScalar e2 = abs2(subdiag[end-1]); +// RealScalar mu = diag[end] - e2 / (td + (td>0 ? 1 : -1) * sqrt(td*td + e2)); + // This explain the following, somewhat more complicated, version: + RealScalar mu = diag[end] - (e / (td + (td>0 ? 1 : -1))) * (e / hypot(td,e)); + RealScalar x = diag[start] - mu; RealScalar z = subdiag[start]; for (Index k = start; k < end; ++k) @@ -515,6 +781,9 @@ static void tridiagonal_qr_step(RealScalar* diag, RealScalar* subdiag, Index sta } } } + } // end namespace internal +} // end namespace Eigen + #endif // EIGEN_SELFADJOINTEIGENSOLVER_H diff --git a/extern/Eigen3/Eigen/src/Eigenvalues/SelfAdjointEigenSolver_MKL.h b/extern/Eigen3/Eigen/src/Eigenvalues/SelfAdjointEigenSolver_MKL.h new file mode 100644 index 00000000000..9380956b5f9 --- /dev/null +++ b/extern/Eigen3/Eigen/src/Eigenvalues/SelfAdjointEigenSolver_MKL.h @@ -0,0 +1,92 @@ +/* + Copyright (c) 2011, Intel Corporation. All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of Intel Corporation nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ******************************************************************************** + * Content : Eigen bindings to Intel(R) MKL + * Self-adjoint eigenvalues/eigenvectors. + ******************************************************************************** +*/ + +#ifndef EIGEN_SAEIGENSOLVER_MKL_H +#define EIGEN_SAEIGENSOLVER_MKL_H + +#include "Eigen/src/Core/util/MKL_support.h" + +namespace Eigen { + +/** \internal Specialization for the data types supported by MKL */ + +#define EIGEN_MKL_EIG_SELFADJ(EIGTYPE, MKLTYPE, MKLRTYPE, MKLNAME, EIGCOLROW, MKLCOLROW ) \ +template<> inline\ +SelfAdjointEigenSolver >& \ +SelfAdjointEigenSolver >::compute(const Matrix& matrix, int options) \ +{ \ + eigen_assert(matrix.cols() == matrix.rows()); \ + eigen_assert((options&~(EigVecMask|GenEigMask))==0 \ + && (options&EigVecMask)!=EigVecMask \ + && "invalid option parameter"); \ + bool computeEigenvectors = (options&ComputeEigenvectors)==ComputeEigenvectors; \ + lapack_int n = matrix.cols(), lda, matrix_order, info; \ + m_eivalues.resize(n,1); \ + m_subdiag.resize(n-1); \ + m_eivec = matrix; \ +\ + if(n==1) \ + { \ + m_eivalues.coeffRef(0,0) = internal::real(matrix.coeff(0,0)); \ + if(computeEigenvectors) m_eivec.setOnes(n,n); \ + m_info = Success; \ + m_isInitialized = true; \ + m_eigenvectorsOk = computeEigenvectors; \ + return *this; \ + } \ +\ + lda = matrix.outerStride(); \ + matrix_order=MKLCOLROW; \ + char jobz, uplo='L'/*, range='A'*/; \ + jobz = computeEigenvectors ? 'V' : 'N'; \ +\ + info = LAPACKE_##MKLNAME( matrix_order, jobz, uplo, n, (MKLTYPE*)m_eivec.data(), lda, (MKLRTYPE*)m_eivalues.data() ); \ + m_info = (info==0) ? Success : NoConvergence; \ + m_isInitialized = true; \ + m_eigenvectorsOk = computeEigenvectors; \ + return *this; \ +} + + +EIGEN_MKL_EIG_SELFADJ(double, double, double, dsyev, ColMajor, LAPACK_COL_MAJOR) +EIGEN_MKL_EIG_SELFADJ(float, float, float, ssyev, ColMajor, LAPACK_COL_MAJOR) +EIGEN_MKL_EIG_SELFADJ(dcomplex, MKL_Complex16, double, zheev, ColMajor, LAPACK_COL_MAJOR) +EIGEN_MKL_EIG_SELFADJ(scomplex, MKL_Complex8, float, cheev, ColMajor, LAPACK_COL_MAJOR) + +EIGEN_MKL_EIG_SELFADJ(double, double, double, dsyev, RowMajor, LAPACK_ROW_MAJOR) +EIGEN_MKL_EIG_SELFADJ(float, float, float, ssyev, RowMajor, LAPACK_ROW_MAJOR) +EIGEN_MKL_EIG_SELFADJ(dcomplex, MKL_Complex16, double, zheev, RowMajor, LAPACK_ROW_MAJOR) +EIGEN_MKL_EIG_SELFADJ(scomplex, MKL_Complex8, float, cheev, RowMajor, LAPACK_ROW_MAJOR) + +} // end namespace Eigen + +#endif // EIGEN_SAEIGENSOLVER_H diff --git a/extern/Eigen3/Eigen/src/Eigenvalues/Tridiagonalization.h b/extern/Eigen3/Eigen/src/Eigenvalues/Tridiagonalization.h index ae4cdce7aeb..c34b7b3b801 100644 --- a/extern/Eigen3/Eigen/src/Eigenvalues/Tridiagonalization.h +++ b/extern/Eigen3/Eigen/src/Eigenvalues/Tridiagonalization.h @@ -4,28 +4,15 @@ // Copyright (C) 2008 Gael Guennebaud // Copyright (C) 2010 Jitse Niesen // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_TRIDIAGONALIZATION_H #define EIGEN_TRIDIAGONALIZATION_H +namespace Eigen { + namespace internal { template struct TridiagonalizationMatrixTReturnType; @@ -97,13 +84,13 @@ template class Tridiagonalization typedef internal::TridiagonalizationMatrixTReturnType MatrixTReturnType; typedef typename internal::conditional::IsComplex, - const typename Diagonal::RealReturnType, + typename internal::add_const_on_value_type::RealReturnType>::type, const Diagonal >::type DiagonalReturnType; typedef typename internal::conditional::IsComplex, - const typename Diagonal< - Block >::RealReturnType, + typename internal::add_const_on_value_type >::RealReturnType>::type, const Diagonal< Block > >::type SubDiagonalReturnType; @@ -560,9 +547,11 @@ template struct TridiagonalizationMatrixTReturnType Index cols() const { return m_matrix.cols(); } protected: - const typename MatrixType::Nested m_matrix; + typename MatrixType::Nested m_matrix; }; } // end namespace internal +} // end namespace Eigen + #endif // EIGEN_TRIDIAGONALIZATION_H diff --git a/extern/Eigen3/Eigen/src/Geometry/AlignedBox.h b/extern/Eigen3/Eigen/src/Geometry/AlignedBox.h index b51deb3f3c3..5830fcd35fc 100644 --- a/extern/Eigen3/Eigen/src/Geometry/AlignedBox.h +++ b/extern/Eigen3/Eigen/src/Geometry/AlignedBox.h @@ -3,28 +3,15 @@ // // Copyright (C) 2008 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_ALIGNEDBOX_H #define EIGEN_ALIGNEDBOX_H +namespace Eigen { + /** \geometry_module \ingroup Geometry_Module * * @@ -190,7 +177,7 @@ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_AmbientDim) template inline bool contains(const MatrixBase& a_p) const { - const typename internal::nested::type p(a_p.derived()); + typename internal::nested::type p(a_p.derived()); return (m_min.array()<=p.array()).all() && (p.array()<=m_max.array()).all(); } @@ -202,7 +189,7 @@ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_AmbientDim) template inline AlignedBox& extend(const MatrixBase& a_p) { - const typename internal::nested::type p(a_p.derived()); + typename internal::nested::type p(a_p.derived()); m_min = m_min.cwiseMin(p); m_max = m_max.cwiseMax(p); return *this; @@ -310,7 +297,7 @@ template inline Scalar AlignedBox::squaredExteriorDistance(const MatrixBase& a_p) const { const typename internal::nested::type p(a_p.derived()); - Scalar dist2 = 0.; + Scalar dist2(0); Scalar aux; for (Index k=0; k::squaredExteriorDistance(const Matri template inline Scalar AlignedBox::squaredExteriorDistance(const AlignedBox& b) const { - Scalar dist2 = 0.; + Scalar dist2(0); Scalar aux; for (Index k=0; k::squaredExteriorDistance(const Align return dist2; } +/** \defgroup alignedboxtypedefs Global aligned box typedefs + * + * \ingroup Geometry_Module + * + * Eigen defines several typedef shortcuts for most common aligned box types. + * + * The general patterns are the following: + * + * \c AlignedBoxSizeType where \c Size can be \c 1, \c 2,\c 3,\c 4 for fixed size boxes or \c X for dynamic size, + * and where \c Type can be \c i for integer, \c f for float, \c d for double. + * + * For example, \c AlignedBox3d is a fixed-size 3x3 aligned box type of doubles, and \c AlignedBoxXf is a dynamic-size aligned box of floats. + * + * \sa class AlignedBox + */ + +#define EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, Size, SizeSuffix) \ +/** \ingroup alignedboxtypedefs */ \ +typedef AlignedBox AlignedBox##SizeSuffix##TypeSuffix; + +#define EIGEN_MAKE_TYPEDEFS_ALL_SIZES(Type, TypeSuffix) \ +EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, 1, 1) \ +EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, 2, 2) \ +EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, 3, 3) \ +EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, 4, 4) \ +EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, Dynamic, X) + +EIGEN_MAKE_TYPEDEFS_ALL_SIZES(int, i) +EIGEN_MAKE_TYPEDEFS_ALL_SIZES(float, f) +EIGEN_MAKE_TYPEDEFS_ALL_SIZES(double, d) + +#undef EIGEN_MAKE_TYPEDEFS_ALL_SIZES +#undef EIGEN_MAKE_TYPEDEFS + +} // end namespace Eigen + #endif // EIGEN_ALIGNEDBOX_H diff --git a/extern/Eigen3/Eigen/src/Geometry/AngleAxis.h b/extern/Eigen3/Eigen/src/Geometry/AngleAxis.h index 0ec4624cf98..67197ac78c3 100644 --- a/extern/Eigen3/Eigen/src/Geometry/AngleAxis.h +++ b/extern/Eigen3/Eigen/src/Geometry/AngleAxis.h @@ -3,28 +3,15 @@ // // Copyright (C) 2008 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_ANGLEAXIS_H #define EIGEN_ANGLEAXIS_H +namespace Eigen { + /** \geometry_module \ingroup Geometry_Module * * \class AngleAxis @@ -144,7 +131,7 @@ public: m_angle = Scalar(other.angle()); } - inline static const AngleAxis Identity() { return AngleAxis(0, Vector3::UnitX()); } + static inline const AngleAxis Identity() { return AngleAxis(0, Vector3::UnitX()); } /** \returns \c true if \c *this is approximately equal to \a other, within the precision * determined by \a prec. @@ -238,4 +225,6 @@ AngleAxis::toRotationMatrix(void) const return res; } +} // end namespace Eigen + #endif // EIGEN_ANGLEAXIS_H diff --git a/extern/Eigen3/Eigen/src/Geometry/EulerAngles.h b/extern/Eigen3/Eigen/src/Geometry/EulerAngles.h index d246a6ebf4a..e424d240604 100644 --- a/extern/Eigen3/Eigen/src/Geometry/EulerAngles.h +++ b/extern/Eigen3/Eigen/src/Geometry/EulerAngles.h @@ -3,28 +3,15 @@ // // Copyright (C) 2008 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_EULERANGLES_H #define EIGEN_EULERANGLES_H +namespace Eigen { + /** \geometry_module \ingroup Geometry_Module * * @@ -92,5 +79,6 @@ MatrixBase::eulerAngles(Index a0, Index a1, Index a2) const return res; } +} // end namespace Eigen #endif // EIGEN_EULERANGLES_H diff --git a/extern/Eigen3/Eigen/src/Geometry/Homogeneous.h b/extern/Eigen3/Eigen/src/Geometry/Homogeneous.h index 2bc4f7e87e3..df03feb55c6 100644 --- a/extern/Eigen3/Eigen/src/Geometry/Homogeneous.h +++ b/extern/Eigen3/Eigen/src/Geometry/Homogeneous.h @@ -3,28 +3,15 @@ // // Copyright (C) 2009-2010 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_HOMOGENEOUS_H #define EIGEN_HOMOGENEOUS_H +namespace Eigen { + /** \geometry_module \ingroup Geometry_Module * * \class Homogeneous @@ -121,7 +108,7 @@ template class Homogeneous } protected: - const typename MatrixType::Nested m_matrix; + typename MatrixType::Nested m_matrix; }; /** \geometry_module @@ -216,8 +203,8 @@ template struct take_matrix_for_product > { typedef Transform TransformType; - typedef typename TransformType::ConstAffinePart type; - static const type run (const TransformType& x) { return x.affine(); } + typedef typename internal::add_const::type type; + static type run (const TransformType& x) { return x.affine(); } }; template @@ -270,8 +257,8 @@ struct homogeneous_left_product_impl,Lhs> .template replicate(m_rhs.cols()); } - const typename LhsMatrixTypeCleaned::Nested m_lhs; - const typename MatrixType::Nested m_rhs; + typename LhsMatrixTypeCleaned::Nested m_lhs; + typename MatrixType::Nested m_rhs; }; template @@ -309,10 +296,12 @@ struct homogeneous_right_product_impl,Rhs> .template replicate(m_lhs.rows()); } - const typename MatrixType::Nested m_lhs; - const typename Rhs::Nested m_rhs; + typename MatrixType::Nested m_lhs; + typename Rhs::Nested m_rhs; }; } // end namespace internal +} // end namespace Eigen + #endif // EIGEN_HOMOGENEOUS_H diff --git a/extern/Eigen3/Eigen/src/Geometry/Hyperplane.h b/extern/Eigen3/Eigen/src/Geometry/Hyperplane.h index d85d3e553f8..1b7c7c78c80 100644 --- a/extern/Eigen3/Eigen/src/Geometry/Hyperplane.h +++ b/extern/Eigen3/Eigen/src/Geometry/Hyperplane.h @@ -4,28 +4,15 @@ // Copyright (C) 2008 Gael Guennebaud // Copyright (C) 2008 Benoit Jacob // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_HYPERPLANE_H #define EIGEN_HYPERPLANE_H +namespace Eigen { + /** \geometry_module \ingroup Geometry_Module * * \class Hyperplane @@ -277,4 +264,6 @@ protected: Coefficients m_coeffs; }; +} // end namespace Eigen + #endif // EIGEN_HYPERPLANE_H diff --git a/extern/Eigen3/Eigen/src/Geometry/OrthoMethods.h b/extern/Eigen3/Eigen/src/Geometry/OrthoMethods.h index 52b46988196..11ad5829cda 100644 --- a/extern/Eigen3/Eigen/src/Geometry/OrthoMethods.h +++ b/extern/Eigen3/Eigen/src/Geometry/OrthoMethods.h @@ -4,28 +4,15 @@ // Copyright (C) 2008-2009 Gael Guennebaud // Copyright (C) 2006-2008 Benoit Jacob // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_ORTHOMETHODS_H #define EIGEN_ORTHOMETHODS_H +namespace Eigen { + /** \geometry_module * * \returns the cross product of \c *this and \a other @@ -43,8 +30,8 @@ MatrixBase::cross(const MatrixBase& other) const // Note that there is no need for an expression here since the compiler // optimize such a small temporary very well (even within a complex expression) - const typename internal::nested::type lhs(derived()); - const typename internal::nested::type rhs(other.derived()); + typename internal::nested::type lhs(derived()); + typename internal::nested::type rhs(other.derived()); return typename cross_product_return_type::type( internal::conj(lhs.coeff(1) * rhs.coeff(2) - lhs.coeff(2) * rhs.coeff(1)), internal::conj(lhs.coeff(2) * rhs.coeff(0) - lhs.coeff(0) * rhs.coeff(2)), @@ -56,9 +43,9 @@ namespace internal { template< int Arch,typename VectorLhs,typename VectorRhs, typename Scalar = typename VectorLhs::Scalar, - bool Vectorizable = (VectorLhs::Flags&VectorRhs::Flags)&PacketAccessBit> + bool Vectorizable = bool((VectorLhs::Flags&VectorRhs::Flags)&PacketAccessBit)> struct cross3_impl { - inline static typename internal::plain_matrix_type::type + static inline typename internal::plain_matrix_type::type run(const VectorLhs& lhs, const VectorRhs& rhs) { return typename internal::plain_matrix_type::type( @@ -145,7 +132,7 @@ struct unitOrthogonal_selector typedef typename NumTraits::Real RealScalar; typedef typename Derived::Index Index; typedef Matrix Vector2; - inline static VectorType run(const Derived& src) + static inline VectorType run(const Derived& src) { VectorType perp = VectorType::Zero(src.size()); Index maxi = 0; @@ -167,7 +154,7 @@ struct unitOrthogonal_selector typedef typename plain_matrix_type::type VectorType; typedef typename traits::Scalar Scalar; typedef typename NumTraits::Real RealScalar; - inline static VectorType run(const Derived& src) + static inline VectorType run(const Derived& src) { VectorType perp; /* Let us compute the crossed product of *this with a vector @@ -205,7 +192,7 @@ template struct unitOrthogonal_selector { typedef typename plain_matrix_type::type VectorType; - inline static VectorType run(const Derived& src) + static inline VectorType run(const Derived& src) { return VectorType(-conj(src.y()), conj(src.x())).normalized(); } }; @@ -226,4 +213,6 @@ MatrixBase::unitOrthogonal() const return internal::unitOrthogonal_selector::run(derived()); } +} // end namespace Eigen + #endif // EIGEN_ORTHOMETHODS_H diff --git a/extern/Eigen3/Eigen/src/Geometry/ParametrizedLine.h b/extern/Eigen3/Eigen/src/Geometry/ParametrizedLine.h index b90f9c088a2..719a904413d 100644 --- a/extern/Eigen3/Eigen/src/Geometry/ParametrizedLine.h +++ b/extern/Eigen3/Eigen/src/Geometry/ParametrizedLine.h @@ -4,28 +4,15 @@ // Copyright (C) 2008 Gael Guennebaud // Copyright (C) 2008 Benoit Jacob // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_PARAMETRIZEDLINE_H #define EIGEN_PARAMETRIZEDLINE_H +namespace Eigen { + /** \geometry_module \ingroup Geometry_Module * * \class ParametrizedLine @@ -106,8 +93,16 @@ public: VectorType projection(const VectorType& p) const { return origin() + direction().dot(p-origin()) * direction(); } + VectorType pointAt( Scalar t ) const; + + template + Scalar intersectionParameter(const Hyperplane<_Scalar, _AmbientDim, OtherOptions>& hyperplane) const; + template Scalar intersection(const Hyperplane<_Scalar, _AmbientDim, OtherOptions>& hyperplane) const; + + template + VectorType intersectionPoint(const Hyperplane<_Scalar, _AmbientDim, OtherOptions>& hyperplane) const; /** \returns \c *this with scalar type casted to \a NewScalarType * @@ -155,14 +150,46 @@ inline ParametrizedLine<_Scalar, _AmbientDim,_Options>::ParametrizedLine(const H origin() = -hyperplane.normal()*hyperplane.offset(); } -/** \returns the parameter value of the intersection between \c *this and the given hyperplane +/** \returns the point at \a t along this line + */ +template +inline typename ParametrizedLine<_Scalar, _AmbientDim,_Options>::VectorType +ParametrizedLine<_Scalar, _AmbientDim,_Options>::pointAt( _Scalar t ) const +{ + return origin() + (direction()*t); +} + +/** \returns the parameter value of the intersection between \c *this and the given \a hyperplane */ template template -inline _Scalar ParametrizedLine<_Scalar, _AmbientDim,_Options>::intersection(const Hyperplane<_Scalar, _AmbientDim, OtherOptions>& hyperplane) const +inline _Scalar ParametrizedLine<_Scalar, _AmbientDim,_Options>::intersectionParameter(const Hyperplane<_Scalar, _AmbientDim, OtherOptions>& hyperplane) const { return -(hyperplane.offset()+hyperplane.normal().dot(origin())) / hyperplane.normal().dot(direction()); } + +/** \deprecated use intersectionParameter() + * \returns the parameter value of the intersection between \c *this and the given \a hyperplane + */ +template +template +inline _Scalar ParametrizedLine<_Scalar, _AmbientDim,_Options>::intersection(const Hyperplane<_Scalar, _AmbientDim, OtherOptions>& hyperplane) const +{ + return intersectionParameter(hyperplane); +} + +/** \returns the point of the intersection between \c *this and the given hyperplane + */ +template +template +inline typename ParametrizedLine<_Scalar, _AmbientDim,_Options>::VectorType +ParametrizedLine<_Scalar, _AmbientDim,_Options>::intersectionPoint(const Hyperplane<_Scalar, _AmbientDim, OtherOptions>& hyperplane) const +{ + return pointAt(intersectionParameter(hyperplane)); +} + +} // end namespace Eigen + #endif // EIGEN_PARAMETRIZEDLINE_H diff --git a/extern/Eigen3/Eigen/src/Geometry/Quaternion.h b/extern/Eigen3/Eigen/src/Geometry/Quaternion.h index 9180db67d84..8792e2da2ae 100644 --- a/extern/Eigen3/Eigen/src/Geometry/Quaternion.h +++ b/extern/Eigen3/Eigen/src/Geometry/Quaternion.h @@ -4,27 +4,14 @@ // Copyright (C) 2008-2010 Gael Guennebaud // Copyright (C) 2009 Mathieu Gautier // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_QUATERNION_H #define EIGEN_QUATERNION_H +namespace Eigen { + /*************************************************************************** * Definition of QuaternionBase @@ -38,6 +25,12 @@ template class QuaternionBase : public RotationBase { @@ -109,7 +102,7 @@ public: /** \returns a quaternion representing an identity rotation * \sa MatrixBase::Identity() */ - inline static Quaternion Identity() { return Quaternion(1, 0, 0, 0); } + static inline Quaternion Identity() { return Quaternion(1, 0, 0, 0); } /** \sa QuaternionBase::Identity(), MatrixBase::setIdentity() */ @@ -278,6 +271,9 @@ public: explicit inline Quaternion(const Quaternion& other) { m_coeffs = other.coeffs().template cast(); } + template + static Quaternion FromTwoVectors(const MatrixBase& a, const MatrixBase& b); + inline Coefficients& coeffs() { return m_coeffs;} inline const Coefficients& coeffs() const { return m_coeffs;} @@ -287,7 +283,7 @@ protected: Coefficients m_coeffs; #ifndef EIGEN_PARSED_BY_DOXYGEN - EIGEN_STRONG_INLINE static void _check_template_params() + static EIGEN_STRONG_INLINE void _check_template_params() { EIGEN_STATIC_ASSERT( (_Options & DontAlign) == _Options, INVALID_MATRIX_TEMPLATE_PARAMETERS) @@ -434,7 +430,7 @@ typedef Map, Aligned> QuaternionMapAlignedd; namespace internal { template struct quat_product { - EIGEN_STRONG_INLINE static Quaternion run(const QuaternionBase& a, const QuaternionBase& b){ + static EIGEN_STRONG_INLINE Quaternion run(const QuaternionBase& a, const QuaternionBase& b){ return Quaternion ( a.w() * b.w() - a.x() * b.x() - a.y() * b.y() - a.z() * b.z(), @@ -544,9 +540,9 @@ QuaternionBase::toRotationMatrix(void) const // it has to be inlined, and so the return by value is not an issue Matrix3 res; - const Scalar tx = 2*this->x(); - const Scalar ty = 2*this->y(); - const Scalar tz = 2*this->z(); + const Scalar tx = Scalar(2)*this->x(); + const Scalar ty = Scalar(2)*this->y(); + const Scalar tz = Scalar(2)*this->z(); const Scalar twx = tx*this->w(); const Scalar twy = ty*this->w(); const Scalar twz = tz*this->w(); @@ -557,15 +553,15 @@ QuaternionBase::toRotationMatrix(void) const const Scalar tyz = tz*this->y(); const Scalar tzz = tz*this->z(); - res.coeffRef(0,0) = 1-(tyy+tzz); + res.coeffRef(0,0) = Scalar(1)-(tyy+tzz); res.coeffRef(0,1) = txy-twz; res.coeffRef(0,2) = txz+twy; res.coeffRef(1,0) = txy+twz; - res.coeffRef(1,1) = 1-(txx+tzz); + res.coeffRef(1,1) = Scalar(1)-(txx+tzz); res.coeffRef(1,2) = tyz-twx; res.coeffRef(2,0) = txz-twy; res.coeffRef(2,1) = tyz+twx; - res.coeffRef(2,2) = 1-(txx+tyy); + res.coeffRef(2,2) = Scalar(1)-(txx+tyy); return res; } @@ -618,6 +614,27 @@ inline Derived& QuaternionBase::setFromTwoVectors(const MatrixBase +template +Quaternion Quaternion::FromTwoVectors(const MatrixBase& a, const MatrixBase& b) +{ + Quaternion quat; + quat.setFromTwoVectors(a, b); + return quat; +} + + /** \returns the multiplicative inverse of \c *this * Note that in most cases, i.e., if you simply want the opposite rotation, * and/or the quaternion is normalized, then it is enough to use the conjugate. @@ -709,7 +726,7 @@ struct quaternionbase_assign_impl { typedef typename Other::Scalar Scalar; typedef DenseIndex Index; - template inline static void run(QuaternionBase& q, const Other& mat) + template static inline void run(QuaternionBase& q, const Other& mat) { // This algorithm comes from "Quaternion Calculus and Fast Animation", // Ken Shoemake, 1987 SIGGRAPH course notes @@ -748,7 +765,7 @@ template struct quaternionbase_assign_impl { typedef typename Other::Scalar Scalar; - template inline static void run(QuaternionBase& q, const Other& vec) + template static inline void run(QuaternionBase& q, const Other& vec) { q.coeffs() = vec; } @@ -756,4 +773,6 @@ struct quaternionbase_assign_impl } // end namespace internal +} // end namespace Eigen + #endif // EIGEN_QUATERNION_H diff --git a/extern/Eigen3/Eigen/src/Geometry/Rotation2D.h b/extern/Eigen3/Eigen/src/Geometry/Rotation2D.h index cf36da1c50c..868e2ef312f 100644 --- a/extern/Eigen3/Eigen/src/Geometry/Rotation2D.h +++ b/extern/Eigen3/Eigen/src/Geometry/Rotation2D.h @@ -3,28 +3,15 @@ // // Copyright (C) 2008 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_ROTATION2D_H #define EIGEN_ROTATION2D_H +namespace Eigen { + /** \geometry_module \ingroup Geometry_Module * * \class Rotation2D @@ -121,7 +108,7 @@ public: m_angle = Scalar(other.angle()); } - inline static Rotation2D Identity() { return Rotation2D(0); } + static inline Rotation2D Identity() { return Rotation2D(0); } /** \returns \c true if \c *this is approximately equal to \a other, within the precision * determined by \a prec. @@ -162,4 +149,6 @@ Rotation2D::toRotationMatrix(void) const return (Matrix2() << cosA, -sinA, sinA, cosA).finished(); } +} // end namespace Eigen + #endif // EIGEN_ROTATION2D_H diff --git a/extern/Eigen3/Eigen/src/Geometry/RotationBase.h b/extern/Eigen3/Eigen/src/Geometry/RotationBase.h index 1abf06bb640..b88661de6b1 100644 --- a/extern/Eigen3/Eigen/src/Geometry/RotationBase.h +++ b/extern/Eigen3/Eigen/src/Geometry/RotationBase.h @@ -3,28 +3,15 @@ // // Copyright (C) 2008 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_ROTATIONBASE_H #define EIGEN_ROTATIONBASE_H +namespace Eigen { + // forward declaration namespace internal { template @@ -115,7 +102,7 @@ struct rotation_base_generic_product_selector { enum { Dim = RotationDerived::Dim }; typedef Matrix ReturnType; - inline static ReturnType run(const RotationDerived& r, const MatrixType& m) + static inline ReturnType run(const RotationDerived& r, const MatrixType& m) { return r.toRotationMatrix() * m; } }; @@ -123,7 +110,7 @@ template struct rotation_base_generic_product_selector< RotationDerived, DiagonalMatrix, false > { typedef Transform ReturnType; - inline static ReturnType run(const RotationDerived& r, const DiagonalMatrix& m) + static inline ReturnType run(const RotationDerived& r, const DiagonalMatrix& m) { ReturnType res(r); res.linear() *= m; @@ -136,7 +123,7 @@ struct rotation_base_generic_product_selector ReturnType; - EIGEN_STRONG_INLINE static ReturnType run(const RotationDerived& r, const OtherVectorType& v) + static EIGEN_STRONG_INLINE ReturnType run(const RotationDerived& r, const OtherVectorType& v) { return r._transformVector(v); } @@ -192,20 +179,20 @@ namespace internal { * \sa class Transform, class Rotation2D, class Quaternion, class AngleAxis */ template -inline static Matrix toRotationMatrix(const Scalar& s) +static inline Matrix toRotationMatrix(const Scalar& s) { EIGEN_STATIC_ASSERT(Dim==2,YOU_MADE_A_PROGRAMMING_MISTAKE) return Rotation2D(s).toRotationMatrix(); } template -inline static Matrix toRotationMatrix(const RotationBase& r) +static inline Matrix toRotationMatrix(const RotationBase& r) { return r.toRotationMatrix(); } template -inline static const MatrixBase& toRotationMatrix(const MatrixBase& mat) +static inline const MatrixBase& toRotationMatrix(const MatrixBase& mat) { EIGEN_STATIC_ASSERT(OtherDerived::RowsAtCompileTime==Dim && OtherDerived::ColsAtCompileTime==Dim, YOU_MADE_A_PROGRAMMING_MISTAKE) @@ -214,4 +201,6 @@ inline static const MatrixBase& toRotationMatrix(const MatrixBase< } // end namespace internal +} // end namespace Eigen + #endif // EIGEN_ROTATIONBASE_H diff --git a/extern/Eigen3/Eigen/src/Geometry/Scaling.h b/extern/Eigen3/Eigen/src/Geometry/Scaling.h index c911d13e1d3..8edcac31c74 100644 --- a/extern/Eigen3/Eigen/src/Geometry/Scaling.h +++ b/extern/Eigen3/Eigen/src/Geometry/Scaling.h @@ -3,28 +3,15 @@ // // Copyright (C) 2008 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_SCALING_H #define EIGEN_SCALING_H +namespace Eigen { + /** \geometry_module \ingroup Geometry_Module * * \class Scaling @@ -73,7 +60,12 @@ public: /** Concatenates a uniform scaling and an affine transformation */ template - inline Transform operator* (const Transform& t) const; + inline Transform operator* (const Transform& t) const + { + Transform res = t; + res.prescale(factor()); + return res; +} /** Concatenates a uniform scaling and a linear transformation matrix */ // TODO returns an expression @@ -169,14 +161,6 @@ UniformScaling::operator* (const Translation& t) const return res; } -template -template -inline Transform -UniformScaling::operator* (const Transform& t) const -{ - Transform res = t; - res.prescale(factor()); - return res; -} +} // end namespace Eigen #endif // EIGEN_SCALING_H diff --git a/extern/Eigen3/Eigen/src/Geometry/Transform.h b/extern/Eigen3/Eigen/src/Geometry/Transform.h index a694673ebed..4c1ef8eaade 100644 --- a/extern/Eigen3/Eigen/src/Geometry/Transform.h +++ b/extern/Eigen3/Eigen/src/Geometry/Transform.h @@ -5,28 +5,15 @@ // Copyright (C) 2009 Benoit Jacob // Copyright (C) 2010 Hauke Heibel // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_TRANSFORM_H #define EIGEN_TRANSFORM_H +namespace Eigen { + namespace internal { template @@ -37,7 +24,7 @@ struct transform_traits Dim = Transform::Dim, HDim = Transform::HDim, Mode = Transform::Mode, - IsProjective = (Mode==Projective) + IsProjective = (int(Mode)==int(Projective)) }; }; @@ -207,9 +194,9 @@ public: /** type of the matrix used to represent the linear part of the transformation */ typedef Matrix LinearMatrixType; /** type of read/write reference to the linear part of the transformation */ - typedef Block LinearPart; + typedef Block LinearPart; /** type of read reference to the linear part of the transformation */ - typedef const Block ConstLinearPart; + typedef const Block ConstLinearPart; /** type of read/write reference to the affine part of the transformation */ typedef typename internal::conditional VectorType; /** type of a read/write reference to the translation part of the rotation */ - typedef Block TranslationPart; + typedef Block TranslationPart; /** type of a read reference to the translation part of the rotation */ - typedef const Block ConstTranslationPart; + typedef const Block ConstTranslationPart; /** corresponding translation type */ typedef Translation TranslationType; @@ -279,6 +266,9 @@ public: template inline explicit Transform(const EigenBase& other) { + EIGEN_STATIC_ASSERT((internal::is_same::value), + YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY); + check_template_params(); internal::transform_construct_from_matrix::run(this, other.derived()); } @@ -287,6 +277,9 @@ public: template inline Transform& operator=(const EigenBase& other) { + EIGEN_STATIC_ASSERT((internal::is_same::value), + YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY); + internal::transform_construct_from_matrix::run(this, other.derived()); return *this; } @@ -376,9 +369,9 @@ public: inline MatrixType& matrix() { return m_matrix; } /** \returns a read-only expression of the linear part of the transformation */ - inline ConstLinearPart linear() const { return m_matrix.template block(0,0); } + inline ConstLinearPart linear() const { return ConstLinearPart(m_matrix,0,0); } /** \returns a writable expression of the linear part of the transformation */ - inline LinearPart linear() { return m_matrix.template block(0,0); } + inline LinearPart linear() { return LinearPart(m_matrix,0,0); } /** \returns a read-only expression of the Dim x HDim affine part of the transformation */ inline ConstAffinePart affine() const { return take_affine_part::run(m_matrix); } @@ -386,9 +379,9 @@ public: inline AffinePart affine() { return take_affine_part::run(m_matrix); } /** \returns a read-only expression of the translation vector of the transformation */ - inline ConstTranslationPart translation() const { return m_matrix.template block(0,Dim); } + inline ConstTranslationPart translation() const { return ConstTranslationPart(m_matrix,0,Dim); } /** \returns a writable expression of the translation vector of the transformation */ - inline TranslationPart translation() { return m_matrix.template block(0,Dim); } + inline TranslationPart translation() { return TranslationPart(m_matrix,0,Dim); } /** \returns an expression of the product between the transform \c *this and a matrix expression \a other * @@ -460,15 +453,40 @@ public: { return internal::transform_transform_product_impl::run(*this,other); } - + + #ifdef __INTEL_COMPILER +private: + // this intermediate structure permits to workaround a bug in ICC 11: + // error: template instantiation resulted in unexpected function type of "Eigen::Transform + // (const Eigen::Transform &) const" + // (the meaning of a name may have changed since the template declaration -- the type of the template is: + // "Eigen::internal::transform_transform_product_impl, + // Eigen::Transform, >::ResultType (const Eigen::Transform &) const") + // + template struct icc_11_workaround + { + typedef internal::transform_transform_product_impl > ProductType; + typedef typename ProductType::ResultType ResultType; + }; + +public: /** Concatenates two different transformations */ template - inline const typename internal::transform_transform_product_impl< - Transform,Transform >::ResultType + inline typename icc_11_workaround::ResultType + operator * (const Transform& other) const + { + typedef typename icc_11_workaround::ProductType ProductType; + return ProductType::run(*this,other); + } + #else + /** Concatenates two different transformations */ + template + inline typename internal::transform_transform_product_impl >::ResultType operator * (const Transform& other) const { return internal::transform_transform_product_impl >::run(*this,other); } + #endif /** \sa MatrixBase::setIdentity() */ void setIdentity() { m_matrix.setIdentity(); } @@ -512,7 +530,12 @@ public: inline Transform& operator=(const UniformScaling& t); inline Transform& operator*=(const UniformScaling& s) { return scale(s.factor()); } - inline Transform operator*(const UniformScaling& s) const; + inline Transform operator*(const UniformScaling& s) const + { + Transform res = *this; + res.scale(s.factor()); + return res; + } inline Transform& operator*=(const DiagonalMatrix& s) { linear() *= s; return *this; } @@ -571,7 +594,7 @@ public: if(int(Mode)!=int(AffineCompact)) { matrix().template block<1,Dim>(Dim,0).setZero(); - matrix().coeffRef(Dim,Dim) = 1; + matrix().coeffRef(Dim,Dim) = Scalar(1); } } @@ -608,7 +631,7 @@ public: protected: #ifndef EIGEN_PARSED_BY_DOXYGEN - EIGEN_STRONG_INLINE static void check_template_params() + static EIGEN_STRONG_INLINE void check_template_params() { EIGEN_STATIC_ASSERT((Options & (DontAlign|RowMajor)) == Options, INVALID_MATRIX_TEMPLATE_PARAMETERS) } @@ -940,14 +963,6 @@ inline Transform& Transform::o return *this; } -template -inline Transform Transform::operator*(const UniformScaling& s) const -{ - Transform res = *this; - res.scale(s.factor()); - return res; -} - template template inline Transform& Transform::operator=(const RotationBase& r) @@ -1219,7 +1234,7 @@ struct transform_right_product_impl< TransformType, MatrixType, 0 > { typedef typename MatrixType::PlainObject ResultType; - EIGEN_STRONG_INLINE static ResultType run(const TransformType& T, const MatrixType& other) + static EIGEN_STRONG_INLINE ResultType run(const TransformType& T, const MatrixType& other) { return T.matrix() * other; } @@ -1237,11 +1252,11 @@ struct transform_right_product_impl< TransformType, MatrixType, 1 > typedef typename MatrixType::PlainObject ResultType; - EIGEN_STRONG_INLINE static ResultType run(const TransformType& T, const MatrixType& other) + static EIGEN_STRONG_INLINE ResultType run(const TransformType& T, const MatrixType& other) { EIGEN_STATIC_ASSERT(OtherRows==HDim, YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES); - typedef Block TopLeftLhs; + typedef Block TopLeftLhs; ResultType res(other.rows(),other.cols()); TopLeftLhs(res, 0, 0, Dim, other.cols()).noalias() = T.affine() * other; @@ -1263,15 +1278,13 @@ struct transform_right_product_impl< TransformType, MatrixType, 2 > typedef typename MatrixType::PlainObject ResultType; - EIGEN_STRONG_INLINE static ResultType run(const TransformType& T, const MatrixType& other) + static EIGEN_STRONG_INLINE ResultType run(const TransformType& T, const MatrixType& other) { EIGEN_STATIC_ASSERT(OtherRows==Dim, YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES); - typedef Block TopLeftLhs; - - ResultType res(other.rows(),other.cols()); - TopLeftLhs(res, 0, 0, Dim, other.cols()).noalias() = T.linear() * other; - TopLeftLhs(res, 0, 0, Dim, other.cols()).colwise() += T.translation(); + typedef Block TopLeftLhs; + ResultType res(Replicate(T.translation(),1,other.cols())); + TopLeftLhs(res, 0, 0, Dim, other.cols()).noalias() += T.linear() * other; return res; } @@ -1422,4 +1435,6 @@ struct transform_transform_product_impl // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_TRANSLATION_H #define EIGEN_TRANSLATION_H +namespace Eigen { + /** \geometry_module \ingroup Geometry_Module * * \class Translation @@ -54,6 +41,8 @@ public: typedef Matrix LinearMatrixType; /** corresponding affine transformation type */ typedef Transform AffineTransformType; + /** corresponding isometric transformation type */ + typedef Transform IsometryTransformType; protected: @@ -114,8 +103,8 @@ public: /** Concatenates a translation and a rotation */ template - inline AffineTransformType operator*(const RotationBase& r) const - { return *this * r.toRotationMatrix(); } + inline IsometryTransformType operator*(const RotationBase& r) const + { return *this * IsometryTransformType(r); } /** \returns the concatenation of a linear transformation \a l with the translation \a t */ // its a nightmare to define a templated friend function outside its declaration @@ -212,4 +201,6 @@ Translation::operator* (const EigenBase& linear) const return res; } +} // end namespace Eigen + #endif // EIGEN_TRANSLATION_H diff --git a/extern/Eigen3/Eigen/src/Geometry/Umeyama.h b/extern/Eigen3/Eigen/src/Geometry/Umeyama.h index b50f461730e..ac0939cde52 100644 --- a/extern/Eigen3/Eigen/src/Geometry/Umeyama.h +++ b/extern/Eigen3/Eigen/src/Geometry/Umeyama.h @@ -3,24 +3,9 @@ // // Copyright (C) 2009 Hauke Heibel // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_UMEYAMA_H #define EIGEN_UMEYAMA_H @@ -31,6 +16,8 @@ // * Eigen/SVD // * Eigen/Array +namespace Eigen { + #ifndef EIGEN_PARSED_BY_DOXYGEN // These helpers are required since it allows to use mixed types as parameters @@ -180,4 +167,6 @@ umeyama(const MatrixBase& src, const MatrixBase& dst, boo return Rt; } +} // end namespace Eigen + #endif // EIGEN_UMEYAMA_H diff --git a/extern/Eigen3/Eigen/src/Geometry/arch/Geometry_SSE.h b/extern/Eigen3/Eigen/src/Geometry/arch/Geometry_SSE.h index 2af32678d1c..3d8284f2d0c 100644 --- a/extern/Eigen3/Eigen/src/Geometry/arch/Geometry_SSE.h +++ b/extern/Eigen3/Eigen/src/Geometry/arch/Geometry_SSE.h @@ -4,34 +4,21 @@ // Copyright (C) 2009 Rohit Garg // Copyright (C) 2009-2010 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_GEOMETRY_SSE_H #define EIGEN_GEOMETRY_SSE_H +namespace Eigen { + namespace internal { template struct quat_product { - inline static Quaternion run(const QuaternionBase& _a, const QuaternionBase& _b) + static inline Quaternion run(const QuaternionBase& _a, const QuaternionBase& _b) { const __m128 mask = _mm_castsi128_ps(_mm_setr_epi32(0,0,0,0x80000000)); Quaternion res; @@ -53,7 +40,7 @@ struct quat_product template struct cross3_impl { - inline static typename plain_matrix_type::type + static inline typename plain_matrix_type::type run(const VectorLhs& lhs, const VectorRhs& rhs) { __m128 a = lhs.template packet(0); @@ -72,7 +59,7 @@ struct cross3_impl template struct quat_product { - inline static Quaternion run(const QuaternionBase& _a, const QuaternionBase& _b) + static inline Quaternion run(const QuaternionBase& _a, const QuaternionBase& _b) { const Packet2d mask = _mm_castsi128_pd(_mm_set_epi32(0x0,0x0,0x80000000,0x0)); @@ -123,4 +110,6 @@ struct quat_product } // end namespace internal +} // end namespace Eigen + #endif // EIGEN_GEOMETRY_SSE_H diff --git a/extern/Eigen3/Eigen/src/Householder/BlockHouseholder.h b/extern/Eigen3/Eigen/src/Householder/BlockHouseholder.h index 23ce1bfbd46..1991c652738 100644 --- a/extern/Eigen3/Eigen/src/Householder/BlockHouseholder.h +++ b/extern/Eigen3/Eigen/src/Householder/BlockHouseholder.h @@ -4,30 +4,17 @@ // Copyright (C) 2010 Vincent Lejeune // Copyright (C) 2010 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_BLOCK_HOUSEHOLDER_H #define EIGEN_BLOCK_HOUSEHOLDER_H // This file contains some helper function to deal with block householder reflectors +namespace Eigen { + namespace internal { /** \internal */ @@ -64,7 +51,7 @@ void apply_block_householder_on_the_left(MatrixType& mat, const VectorsType& vec Matrix T(nbVecs,nbVecs); make_block_householder_triangular_factor(T, vectors, hCoeffs); - const TriangularView& V(vectors); + const TriangularView& V(vectors); // A -= V T V^* A Matrix // Copyright (C) 2009 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_HOUSEHOLDER_H #define EIGEN_HOUSEHOLDER_H +namespace Eigen { + namespace internal { template struct decrement_size { @@ -35,6 +22,22 @@ template struct decrement_size }; } +/** Computes the elementary reflector H such that: + * \f$ H *this = [ beta 0 ... 0]^T \f$ + * where the transformation H is: + * \f$ H = I - tau v v^*\f$ + * and the vector v is: + * \f$ v^T = [1 essential^T] \f$ + * + * The essential part of the vector \c v is stored in *this. + * + * On output: + * \param tau the scaling factor of the Householder transformation + * \param beta the result of H * \c *this + * + * \sa MatrixBase::makeHouseholder(), MatrixBase::applyHouseholderOnTheLeft(), + * MatrixBase::applyHouseholderOnTheRight() + */ template void MatrixBase::makeHouseholderInPlace(Scalar& tau, RealScalar& beta) { @@ -51,7 +54,7 @@ void MatrixBase::makeHouseholderInPlace(Scalar& tau, RealScalar& beta) * * On output: * \param essential the essential part of the vector \c v - * \param tau the scaling factor of the householder transformation + * \param tau the scaling factor of the Householder transformation * \param beta the result of H * \c *this * * \sa MatrixBase::makeHouseholderInPlace(), MatrixBase::applyHouseholderOnTheLeft(), @@ -86,6 +89,21 @@ void MatrixBase::makeHouseholder( } } +/** Apply the elementary reflector H given by + * \f$ H = I - tau v v^*\f$ + * with + * \f$ v^T = [1 essential^T] \f$ + * from the left to a vector or matrix. + * + * On input: + * \param essential the essential part of the vector \c v + * \param tau the scaling factor of the Householder transformation + * \param workspace a pointer to working space with at least + * this->cols() * essential.size() entries + * + * \sa MatrixBase::makeHouseholder(), MatrixBase::makeHouseholderInPlace(), + * MatrixBase::applyHouseholderOnTheRight() + */ template template void MatrixBase::applyHouseholderOnTheLeft( @@ -108,6 +126,21 @@ void MatrixBase::applyHouseholderOnTheLeft( } } +/** Apply the elementary reflector H given by + * \f$ H = I - tau v v^*\f$ + * with + * \f$ v^T = [1 essential^T] \f$ + * from the right to a vector or matrix. + * + * On input: + * \param essential the essential part of the vector \c v + * \param tau the scaling factor of the Householder transformation + * \param workspace a pointer to working space with at least + * this->cols() * essential.size() entries + * + * \sa MatrixBase::makeHouseholder(), MatrixBase::makeHouseholderInPlace(), + * MatrixBase::applyHouseholderOnTheLeft() + */ template template void MatrixBase::applyHouseholderOnTheRight( @@ -130,4 +163,6 @@ void MatrixBase::applyHouseholderOnTheRight( } } +} // end namespace Eigen + #endif // EIGEN_HOUSEHOLDER_H diff --git a/extern/Eigen3/Eigen/src/Householder/HouseholderSequence.h b/extern/Eigen3/Eigen/src/Householder/HouseholderSequence.h index 717f29c99e9..1e71e16a785 100644 --- a/extern/Eigen3/Eigen/src/Householder/HouseholderSequence.h +++ b/extern/Eigen3/Eigen/src/Householder/HouseholderSequence.h @@ -4,28 +4,15 @@ // Copyright (C) 2009 Gael Guennebaud // Copyright (C) 2010 Benoit Jacob // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_HOUSEHOLDER_SEQUENCE_H #define EIGEN_HOUSEHOLDER_SEQUENCE_H +namespace Eigen { + /** \ingroup Householder_Module * \householder_module * \class HouseholderSequence @@ -237,13 +224,20 @@ template class HouseholderS ConjugateReturnType inverse() const { return adjoint(); } /** \internal */ - template void evalTo(DestType& dst) const + template inline void evalTo(DestType& dst) const { - Index vecs = m_length; - // FIXME find a way to pass this temporary if the user wants to Matrix temp(rows()); - if( internal::is_same::type,DestType>::value + AutoAlign|ColMajor, DestType::MaxRowsAtCompileTime, 1> workspace(rows()); + evalTo(dst, workspace); + } + + /** \internal */ + template + void evalTo(Dest& dst, Workspace& workspace) const + { + workspace.resize(rows()); + Index vecs = m_length; + if( internal::is_same::type,Dest>::value && internal::extract_data(dst) == internal::extract_data(m_vectors)) { // in-place @@ -254,10 +248,10 @@ template class HouseholderS Index cornerSize = rows() - k - m_shift; if(m_trans) dst.bottomRightCorner(cornerSize, cornerSize) - .applyHouseholderOnTheRight(essentialVector(k), m_coeffs.coeff(k), &temp.coeffRef(0)); + .applyHouseholderOnTheRight(essentialVector(k), m_coeffs.coeff(k), workspace.data()); else dst.bottomRightCorner(cornerSize, cornerSize) - .applyHouseholderOnTheLeft(essentialVector(k), m_coeffs.coeff(k), &temp.coeffRef(0)); + .applyHouseholderOnTheLeft(essentialVector(k), m_coeffs.coeff(k), workspace.data()); // clear the off diagonal vector dst.col(k).tail(rows()-k-1).setZero(); @@ -274,10 +268,10 @@ template class HouseholderS Index cornerSize = rows() - k - m_shift; if(m_trans) dst.bottomRightCorner(cornerSize, cornerSize) - .applyHouseholderOnTheRight(essentialVector(k), m_coeffs.coeff(k), &temp.coeffRef(0)); + .applyHouseholderOnTheRight(essentialVector(k), m_coeffs.coeff(k), &workspace.coeffRef(0)); else dst.bottomRightCorner(cornerSize, cornerSize) - .applyHouseholderOnTheLeft(essentialVector(k), m_coeffs.coeff(k), &temp.coeffRef(0)); + .applyHouseholderOnTheLeft(essentialVector(k), m_coeffs.coeff(k), &workspace.coeffRef(0)); } } } @@ -285,24 +279,40 @@ template class HouseholderS /** \internal */ template inline void applyThisOnTheRight(Dest& dst) const { - Matrix temp(dst.rows()); + Matrix workspace(dst.rows()); + applyThisOnTheRight(dst, workspace); + } + + /** \internal */ + template + inline void applyThisOnTheRight(Dest& dst, Workspace& workspace) const + { + workspace.resize(dst.rows()); for(Index k = 0; k < m_length; ++k) { Index actual_k = m_trans ? m_length-k-1 : k; dst.rightCols(rows()-m_shift-actual_k) - .applyHouseholderOnTheRight(essentialVector(actual_k), m_coeffs.coeff(actual_k), &temp.coeffRef(0)); + .applyHouseholderOnTheRight(essentialVector(actual_k), m_coeffs.coeff(actual_k), workspace.data()); } } /** \internal */ template inline void applyThisOnTheLeft(Dest& dst) const { - Matrix temp(dst.cols()); + Matrix workspace(dst.cols()); + applyThisOnTheLeft(dst, workspace); + } + + /** \internal */ + template + inline void applyThisOnTheLeft(Dest& dst, Workspace& workspace) const + { + workspace.resize(dst.cols()); for(Index k = 0; k < m_length; ++k) { Index actual_k = m_trans ? k : m_length-k-1; dst.bottomRows(rows()-m_shift-actual_k) - .applyHouseholderOnTheLeft(essentialVector(actual_k), m_coeffs.coeff(actual_k), &temp.coeffRef(0)); + .applyHouseholderOnTheLeft(essentialVector(actual_k), m_coeffs.coeff(actual_k), workspace.data()); } } @@ -426,4 +436,6 @@ HouseholderSequence rightHouseholderSequence( return HouseholderSequence(v, h); } +} // end namespace Eigen + #endif // EIGEN_HOUSEHOLDER_SEQUENCE_H diff --git a/extern/Eigen3/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h b/extern/Eigen3/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h new file mode 100644 index 00000000000..73ca9bfde6a --- /dev/null +++ b/extern/Eigen3/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h @@ -0,0 +1,149 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2011 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_BASIC_PRECONDITIONERS_H +#define EIGEN_BASIC_PRECONDITIONERS_H + +namespace Eigen { + +/** \ingroup IterativeLinearSolvers_Module + * \brief A preconditioner based on the digonal entries + * + * This class allows to approximately solve for A.x = b problems assuming A is a diagonal matrix. + * In other words, this preconditioner neglects all off diagonal entries and, in Eigen's language, solves for: + * \code + * A.diagonal().asDiagonal() . x = b + * \endcode + * + * \tparam _Scalar the type of the scalar. + * + * This preconditioner is suitable for both selfadjoint and general problems. + * The diagonal entries are pre-inverted and stored into a dense vector. + * + * \note A variant that has yet to be implemented would attempt to preserve the norm of each column. + * + */ +template +class DiagonalPreconditioner +{ + typedef _Scalar Scalar; + typedef Matrix Vector; + typedef typename Vector::Index Index; + + public: + // this typedef is only to export the scalar type and compile-time dimensions to solve_retval + typedef Matrix MatrixType; + + DiagonalPreconditioner() : m_isInitialized(false) {} + + template + DiagonalPreconditioner(const MatType& mat) : m_invdiag(mat.cols()) + { + compute(mat); + } + + Index rows() const { return m_invdiag.size(); } + Index cols() const { return m_invdiag.size(); } + + template + DiagonalPreconditioner& analyzePattern(const MatType& ) + { + return *this; + } + + template + DiagonalPreconditioner& factorize(const MatType& mat) + { + m_invdiag.resize(mat.cols()); + for(int j=0; j + DiagonalPreconditioner& compute(const MatType& mat) + { + return factorize(mat); + } + + template + void _solve(const Rhs& b, Dest& x) const + { + x = m_invdiag.array() * b.array() ; + } + + template inline const internal::solve_retval + solve(const MatrixBase& b) const + { + eigen_assert(m_isInitialized && "DiagonalPreconditioner is not initialized."); + eigen_assert(m_invdiag.size()==b.rows() + && "DiagonalPreconditioner::solve(): invalid number of rows of the right hand side matrix b"); + return internal::solve_retval(*this, b.derived()); + } + + protected: + Vector m_invdiag; + bool m_isInitialized; +}; + +namespace internal { + +template +struct solve_retval, Rhs> + : solve_retval_base, Rhs> +{ + typedef DiagonalPreconditioner<_MatrixType> Dec; + EIGEN_MAKE_SOLVE_HELPERS(Dec,Rhs) + + template void evalTo(Dest& dst) const + { + dec()._solve(rhs(),dst); + } +}; + +} + +/** \ingroup IterativeLinearSolvers_Module + * \brief A naive preconditioner which approximates any matrix as the identity matrix + * + * \sa class DiagonalPreconditioner + */ +class IdentityPreconditioner +{ + public: + + IdentityPreconditioner() {} + + template + IdentityPreconditioner(const MatrixType& ) {} + + template + IdentityPreconditioner& analyzePattern(const MatrixType& ) { return *this; } + + template + IdentityPreconditioner& factorize(const MatrixType& ) { return *this; } + + template + IdentityPreconditioner& compute(const MatrixType& ) { return *this; } + + template + inline const Rhs& solve(const Rhs& b) const { return b; } +}; + +} // end namespace Eigen + +#endif // EIGEN_BASIC_PRECONDITIONERS_H diff --git a/extern/Eigen3/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h b/extern/Eigen3/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h new file mode 100644 index 00000000000..126341be8d8 --- /dev/null +++ b/extern/Eigen3/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h @@ -0,0 +1,254 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2011 Gael Guennebaud +// Copyright (C) 2012 Désiré Nuentsa-Wakam +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_BICGSTAB_H +#define EIGEN_BICGSTAB_H + +namespace Eigen { + +namespace internal { + +/** \internal Low-level bi conjugate gradient stabilized algorithm + * \param mat The matrix A + * \param rhs The right hand side vector b + * \param x On input and initial solution, on output the computed solution. + * \param precond A preconditioner being able to efficiently solve for an + * approximation of Ax=b (regardless of b) + * \param iters On input the max number of iteration, on output the number of performed iterations. + * \param tol_error On input the tolerance error, on output an estimation of the relative error. + * \return false in the case of numerical issue, for example a break down of BiCGSTAB. + */ +template +bool bicgstab(const MatrixType& mat, const Rhs& rhs, Dest& x, + const Preconditioner& precond, int& iters, + typename Dest::RealScalar& tol_error) +{ + using std::sqrt; + using std::abs; + typedef typename Dest::RealScalar RealScalar; + typedef typename Dest::Scalar Scalar; + typedef Matrix VectorType; + RealScalar tol = tol_error; + int maxIters = iters; + + int n = mat.cols(); + VectorType r = rhs - mat * x; + VectorType r0 = r; + + RealScalar r0_sqnorm = r0.squaredNorm(); + Scalar rho = 1; + Scalar alpha = 1; + Scalar w = 1; + + VectorType v = VectorType::Zero(n), p = VectorType::Zero(n); + VectorType y(n), z(n); + VectorType kt(n), ks(n); + + VectorType s(n), t(n); + + RealScalar tol2 = tol*tol; + int i = 0; + + while ( r.squaredNorm()/r0_sqnorm > tol2 && i > +class BiCGSTAB; + +namespace internal { + +template< typename _MatrixType, typename _Preconditioner> +struct traits > +{ + typedef _MatrixType MatrixType; + typedef _Preconditioner Preconditioner; +}; + +} + +/** \ingroup IterativeLinearSolvers_Module + * \brief A bi conjugate gradient stabilized solver for sparse square problems + * + * This class allows to solve for A.x = b sparse linear problems using a bi conjugate gradient + * stabilized algorithm. The vectors x and b can be either dense or sparse. + * + * \tparam _MatrixType the type of the sparse matrix A, can be a dense or a sparse matrix. + * \tparam _Preconditioner the type of the preconditioner. Default is DiagonalPreconditioner + * + * The maximal number of iterations and tolerance value can be controlled via the setMaxIterations() + * and setTolerance() methods. The defaults are the size of the problem for the maximal number of iterations + * and NumTraits::epsilon() for the tolerance. + * + * This class can be used as the direct solver classes. Here is a typical usage example: + * \code + * int n = 10000; + * VectorXd x(n), b(n); + * SparseMatrix A(n,n); + * // fill A and b + * BiCGSTAB > solver; + * solver(A); + * x = solver.solve(b); + * std::cout << "#iterations: " << solver.iterations() << std::endl; + * std::cout << "estimated error: " << solver.error() << std::endl; + * // update b, and solve again + * x = solver.solve(b); + * \endcode + * + * By default the iterations start with x=0 as an initial guess of the solution. + * One can control the start using the solveWithGuess() method. Here is a step by + * step execution example starting with a random guess and printing the evolution + * of the estimated error: + * * \code + * x = VectorXd::Random(n); + * solver.setMaxIterations(1); + * int i = 0; + * do { + * x = solver.solveWithGuess(b,x); + * std::cout << i << " : " << solver.error() << std::endl; + * ++i; + * } while (solver.info()!=Success && i<100); + * \endcode + * Note that such a step by step excution is slightly slower. + * + * \sa class SimplicialCholesky, DiagonalPreconditioner, IdentityPreconditioner + */ +template< typename _MatrixType, typename _Preconditioner> +class BiCGSTAB : public IterativeSolverBase > +{ + typedef IterativeSolverBase Base; + using Base::mp_matrix; + using Base::m_error; + using Base::m_iterations; + using Base::m_info; + using Base::m_isInitialized; +public: + typedef _MatrixType MatrixType; + typedef typename MatrixType::Scalar Scalar; + typedef typename MatrixType::Index Index; + typedef typename MatrixType::RealScalar RealScalar; + typedef _Preconditioner Preconditioner; + +public: + + /** Default constructor. */ + BiCGSTAB() : Base() {} + + /** Initialize the solver with matrix \a A for further \c Ax=b solving. + * + * This constructor is a shortcut for the default constructor followed + * by a call to compute(). + * + * \warning this class stores a reference to the matrix A as well as some + * precomputed values that depend on it. Therefore, if \a A is changed + * this class becomes invalid. Call compute() to update it with the new + * matrix A, or modify a copy of A. + */ + BiCGSTAB(const MatrixType& A) : Base(A) {} + + ~BiCGSTAB() {} + + /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A + * \a x0 as an initial solution. + * + * \sa compute() + */ + template + inline const internal::solve_retval_with_guess + solveWithGuess(const MatrixBase& b, const Guess& x0) const + { + eigen_assert(m_isInitialized && "BiCGSTAB is not initialized."); + eigen_assert(Base::rows()==b.rows() + && "BiCGSTAB::solve(): invalid number of rows of the right hand side matrix b"); + return internal::solve_retval_with_guess + (*this, b.derived(), x0); + } + + /** \internal */ + template + void _solveWithGuess(const Rhs& b, Dest& x) const + { + bool failed = false; + for(int j=0; j + void _solve(const Rhs& b, Dest& x) const + { + x.setZero(); + _solveWithGuess(b,x); + } + +protected: + +}; + + +namespace internal { + + template +struct solve_retval, Rhs> + : solve_retval_base, Rhs> +{ + typedef BiCGSTAB<_MatrixType, _Preconditioner> Dec; + EIGEN_MAKE_SOLVE_HELPERS(Dec,Rhs) + + template void evalTo(Dest& dst) const + { + dec()._solve(rhs(),dst); + } +}; + +} // end namespace internal + +} // end namespace Eigen + +#endif // EIGEN_BICGSTAB_H diff --git a/extern/Eigen3/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h b/extern/Eigen3/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h new file mode 100644 index 00000000000..f64f2534d28 --- /dev/null +++ b/extern/Eigen3/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h @@ -0,0 +1,251 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2011 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_CONJUGATE_GRADIENT_H +#define EIGEN_CONJUGATE_GRADIENT_H + +namespace Eigen { + +namespace internal { + +/** \internal Low-level conjugate gradient algorithm + * \param mat The matrix A + * \param rhs The right hand side vector b + * \param x On input and initial solution, on output the computed solution. + * \param precond A preconditioner being able to efficiently solve for an + * approximation of Ax=b (regardless of b) + * \param iters On input the max number of iteration, on output the number of performed iterations. + * \param tol_error On input the tolerance error, on output an estimation of the relative error. + */ +template +EIGEN_DONT_INLINE +void conjugate_gradient(const MatrixType& mat, const Rhs& rhs, Dest& x, + const Preconditioner& precond, int& iters, + typename Dest::RealScalar& tol_error) +{ + using std::sqrt; + using std::abs; + typedef typename Dest::RealScalar RealScalar; + typedef typename Dest::Scalar Scalar; + typedef Matrix VectorType; + + RealScalar tol = tol_error; + int maxIters = iters; + + int n = mat.cols(); + + VectorType residual = rhs - mat * x; //initial residual + VectorType p(n); + + p = precond.solve(residual); //initial search direction + + VectorType z(n), tmp(n); + RealScalar absNew = internal::real(residual.dot(p)); // the square of the absolute value of r scaled by invM + RealScalar rhsNorm2 = rhs.squaredNorm(); + RealScalar residualNorm2 = 0; + RealScalar threshold = tol*tol*rhsNorm2; + int i = 0; + while(i < maxIters) + { + tmp.noalias() = mat * p; // the bottleneck of the algorithm + + Scalar alpha = absNew / p.dot(tmp); // the amount we travel on dir + x += alpha * p; // update solution + residual -= alpha * tmp; // update residue + + residualNorm2 = residual.squaredNorm(); + if(residualNorm2 < threshold) + break; + + z = precond.solve(residual); // approximately solve for "A z = residual" + + RealScalar absOld = absNew; + absNew = internal::real(residual.dot(z)); // update the absolute value of r + RealScalar beta = absNew / absOld; // calculate the Gram-Schmidt value used to create the new search direction + p = z + beta * p; // update search direction + i++; + } + tol_error = sqrt(residualNorm2 / rhsNorm2); + iters = i; +} + +} + +template< typename _MatrixType, int _UpLo=Lower, + typename _Preconditioner = DiagonalPreconditioner > +class ConjugateGradient; + +namespace internal { + +template< typename _MatrixType, int _UpLo, typename _Preconditioner> +struct traits > +{ + typedef _MatrixType MatrixType; + typedef _Preconditioner Preconditioner; +}; + +} + +/** \ingroup IterativeLinearSolvers_Module + * \brief A conjugate gradient solver for sparse self-adjoint problems + * + * This class allows to solve for A.x = b sparse linear problems using a conjugate gradient algorithm. + * The sparse matrix A must be selfadjoint. The vectors x and b can be either dense or sparse. + * + * \tparam _MatrixType the type of the sparse matrix A, can be a dense or a sparse matrix. + * \tparam _UpLo the triangular part that will be used for the computations. It can be Lower + * or Upper. Default is Lower. + * \tparam _Preconditioner the type of the preconditioner. Default is DiagonalPreconditioner + * + * The maximal number of iterations and tolerance value can be controlled via the setMaxIterations() + * and setTolerance() methods. The defaults are the size of the problem for the maximal number of iterations + * and NumTraits::epsilon() for the tolerance. + * + * This class can be used as the direct solver classes. Here is a typical usage example: + * \code + * int n = 10000; + * VectorXd x(n), b(n); + * SparseMatrix A(n,n); + * // fill A and b + * ConjugateGradient > cg; + * cg.compute(A); + * x = cg.solve(b); + * std::cout << "#iterations: " << cg.iterations() << std::endl; + * std::cout << "estimated error: " << cg.error() << std::endl; + * // update b, and solve again + * x = cg.solve(b); + * \endcode + * + * By default the iterations start with x=0 as an initial guess of the solution. + * One can control the start using the solveWithGuess() method. Here is a step by + * step execution example starting with a random guess and printing the evolution + * of the estimated error: + * * \code + * x = VectorXd::Random(n); + * cg.setMaxIterations(1); + * int i = 0; + * do { + * x = cg.solveWithGuess(b,x); + * std::cout << i << " : " << cg.error() << std::endl; + * ++i; + * } while (cg.info()!=Success && i<100); + * \endcode + * Note that such a step by step excution is slightly slower. + * + * \sa class SimplicialCholesky, DiagonalPreconditioner, IdentityPreconditioner + */ +template< typename _MatrixType, int _UpLo, typename _Preconditioner> +class ConjugateGradient : public IterativeSolverBase > +{ + typedef IterativeSolverBase Base; + using Base::mp_matrix; + using Base::m_error; + using Base::m_iterations; + using Base::m_info; + using Base::m_isInitialized; +public: + typedef _MatrixType MatrixType; + typedef typename MatrixType::Scalar Scalar; + typedef typename MatrixType::Index Index; + typedef typename MatrixType::RealScalar RealScalar; + typedef _Preconditioner Preconditioner; + + enum { + UpLo = _UpLo + }; + +public: + + /** Default constructor. */ + ConjugateGradient() : Base() {} + + /** Initialize the solver with matrix \a A for further \c Ax=b solving. + * + * This constructor is a shortcut for the default constructor followed + * by a call to compute(). + * + * \warning this class stores a reference to the matrix A as well as some + * precomputed values that depend on it. Therefore, if \a A is changed + * this class becomes invalid. Call compute() to update it with the new + * matrix A, or modify a copy of A. + */ + ConjugateGradient(const MatrixType& A) : Base(A) {} + + ~ConjugateGradient() {} + + /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A + * \a x0 as an initial solution. + * + * \sa compute() + */ + template + inline const internal::solve_retval_with_guess + solveWithGuess(const MatrixBase& b, const Guess& x0) const + { + eigen_assert(m_isInitialized && "ConjugateGradient is not initialized."); + eigen_assert(Base::rows()==b.rows() + && "ConjugateGradient::solve(): invalid number of rows of the right hand side matrix b"); + return internal::solve_retval_with_guess + (*this, b.derived(), x0); + } + + /** \internal */ + template + void _solveWithGuess(const Rhs& b, Dest& x) const + { + m_iterations = Base::maxIterations(); + m_error = Base::m_tolerance; + + for(int j=0; jtemplate selfadjointView(), b.col(j), xj, + Base::m_preconditioner, m_iterations, m_error); + } + + m_isInitialized = true; + m_info = m_error <= Base::m_tolerance ? Success : NoConvergence; + } + + /** \internal */ + template + void _solve(const Rhs& b, Dest& x) const + { + x.setOnes(); + _solveWithGuess(b,x); + } + +protected: + +}; + + +namespace internal { + +template +struct solve_retval, Rhs> + : solve_retval_base, Rhs> +{ + typedef ConjugateGradient<_MatrixType,_UpLo,_Preconditioner> Dec; + EIGEN_MAKE_SOLVE_HELPERS(Dec,Rhs) + + template void evalTo(Dest& dst) const + { + dec()._solve(rhs(),dst); + } +}; + +} // end namespace internal + +} // end namespace Eigen + +#endif // EIGEN_CONJUGATE_GRADIENT_H diff --git a/extern/Eigen3/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h b/extern/Eigen3/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h new file mode 100644 index 00000000000..224304f0eb8 --- /dev/null +++ b/extern/Eigen3/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h @@ -0,0 +1,466 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2012 Désiré Nuentsa-Wakam +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_INCOMPLETE_LUT_H +#define EIGEN_INCOMPLETE_LUT_H + +namespace Eigen { + +/** + * \brief Incomplete LU factorization with dual-threshold strategy + * During the numerical factorization, two dropping rules are used : + * 1) any element whose magnitude is less than some tolerance is dropped. + * This tolerance is obtained by multiplying the input tolerance @p droptol + * by the average magnitude of all the original elements in the current row. + * 2) After the elimination of the row, only the @p fill largest elements in + * the L part and the @p fill largest elements in the U part are kept + * (in addition to the diagonal element ). Note that @p fill is computed from + * the input parameter @p fillfactor which is used the ratio to control the fill_in + * relatively to the initial number of nonzero elements. + * + * The two extreme cases are when @p droptol=0 (to keep all the @p fill*2 largest elements) + * and when @p fill=n/2 with @p droptol being different to zero. + * + * References : Yousef Saad, ILUT: A dual threshold incomplete LU factorization, + * Numerical Linear Algebra with Applications, 1(4), pp 387-402, 1994. + * + * NOTE : The following implementation is derived from the ILUT implementation + * in the SPARSKIT package, Copyright (C) 2005, the Regents of the University of Minnesota + * released under the terms of the GNU LGPL: + * http://www-users.cs.umn.edu/~saad/software/SPARSKIT/README + * However, Yousef Saad gave us permission to relicense his ILUT code to MPL2. + * See the Eigen mailing list archive, thread: ILUT, date: July 8, 2012: + * http://listengine.tuxfamily.org/lists.tuxfamily.org/eigen/2012/07/msg00064.html + * alternatively, on GMANE: + * http://comments.gmane.org/gmane.comp.lib.eigen/3302 + */ +template +class IncompleteLUT : internal::noncopyable +{ + typedef _Scalar Scalar; + typedef typename NumTraits::Real RealScalar; + typedef Matrix Vector; + typedef SparseMatrix FactorType; + typedef SparseMatrix PermutType; + typedef typename FactorType::Index Index; + + public: + typedef Matrix MatrixType; + + IncompleteLUT() + : m_droptol(NumTraits::dummy_precision()), m_fillfactor(10), + m_analysisIsOk(false), m_factorizationIsOk(false), m_isInitialized(false) + {} + + template + IncompleteLUT(const MatrixType& mat, RealScalar droptol=NumTraits::dummy_precision(), int fillfactor = 10) + : m_droptol(droptol),m_fillfactor(fillfactor), + m_analysisIsOk(false),m_factorizationIsOk(false),m_isInitialized(false) + { + eigen_assert(fillfactor != 0); + compute(mat); + } + + Index rows() const { return m_lu.rows(); } + + Index cols() const { return m_lu.cols(); } + + /** \brief Reports whether previous computation was successful. + * + * \returns \c Success if computation was succesful, + * \c NumericalIssue if the matrix.appears to be negative. + */ + ComputationInfo info() const + { + eigen_assert(m_isInitialized && "IncompleteLUT is not initialized."); + return m_info; + } + + template + void analyzePattern(const MatrixType& amat); + + template + void factorize(const MatrixType& amat); + + /** + * Compute an incomplete LU factorization with dual threshold on the matrix mat + * No pivoting is done in this version + * + **/ + template + IncompleteLUT& compute(const MatrixType& amat) + { + analyzePattern(amat); + factorize(amat); + eigen_assert(m_factorizationIsOk == true); + m_isInitialized = true; + return *this; + } + + void setDroptol(RealScalar droptol); + void setFillfactor(int fillfactor); + + template + void _solve(const Rhs& b, Dest& x) const + { + x = m_Pinv * b; + x = m_lu.template triangularView().solve(x); + x = m_lu.template triangularView().solve(x); + x = m_P * x; + } + + template inline const internal::solve_retval + solve(const MatrixBase& b) const + { + eigen_assert(m_isInitialized && "IncompleteLUT is not initialized."); + eigen_assert(cols()==b.rows() + && "IncompleteLUT::solve(): invalid number of rows of the right hand side matrix b"); + return internal::solve_retval(*this, b.derived()); + } + +protected: + + template + int QuickSplit(VectorV &row, VectorI &ind, int ncut); + + + /** keeps off-diagonal entries; drops diagonal entries */ + struct keep_diag { + inline bool operator() (const Index& row, const Index& col, const Scalar&) const + { + return row!=col; + } + }; + +protected: + + FactorType m_lu; + RealScalar m_droptol; + int m_fillfactor; + bool m_analysisIsOk; + bool m_factorizationIsOk; + bool m_isInitialized; + ComputationInfo m_info; + PermutationMatrix m_P; // Fill-reducing permutation + PermutationMatrix m_Pinv; // Inverse permutation +}; + +/** + * Set control parameter droptol + * \param droptol Drop any element whose magnitude is less than this tolerance + **/ +template +void IncompleteLUT::setDroptol(RealScalar droptol) +{ + this->m_droptol = droptol; +} + +/** + * Set control parameter fillfactor + * \param fillfactor This is used to compute the number @p fill_in of largest elements to keep on each row. + **/ +template +void IncompleteLUT::setFillfactor(int fillfactor) +{ + this->m_fillfactor = fillfactor; +} + + +/** + * Compute a quick-sort split of a vector + * On output, the vector row is permuted such that its elements satisfy + * abs(row(i)) >= abs(row(ncut)) if incut + * \param row The vector of values + * \param ind The array of index for the elements in @p row + * \param ncut The number of largest elements to keep + **/ +template +template +int IncompleteLUT::QuickSplit(VectorV &row, VectorI &ind, int ncut) +{ + using std::swap; + int mid; + int n = row.size(); /* length of the vector */ + int first, last ; + + ncut--; /* to fit the zero-based indices */ + first = 0; + last = n-1; + if (ncut < first || ncut > last ) return 0; + + do { + mid = first; + RealScalar abskey = std::abs(row(mid)); + for (int j = first + 1; j <= last; j++) { + if ( std::abs(row(j)) > abskey) { + ++mid; + swap(row(mid), row(j)); + swap(ind(mid), ind(j)); + } + } + /* Interchange for the pivot element */ + swap(row(mid), row(first)); + swap(ind(mid), ind(first)); + + if (mid > ncut) last = mid - 1; + else if (mid < ncut ) first = mid + 1; + } while (mid != ncut ); + + return 0; /* mid is equal to ncut */ +} + +template +template +void IncompleteLUT::analyzePattern(const _MatrixType& amat) +{ + // Compute the Fill-reducing permutation + SparseMatrix mat1 = amat; + SparseMatrix mat2 = amat.transpose(); + // Symmetrize the pattern + // FIXME for a matrix with nearly symmetric pattern, mat2+mat1 is the appropriate choice. + // on the other hand for a really non-symmetric pattern, mat2*mat1 should be prefered... + SparseMatrix AtA = mat2 + mat1; + AtA.prune(keep_diag()); + internal::minimum_degree_ordering(AtA, m_P); // Then compute the AMD ordering... + + m_Pinv = m_P.inverse(); // ... and the inverse permutation + + m_analysisIsOk = true; +} + +template +template +void IncompleteLUT::factorize(const _MatrixType& amat) +{ + using std::sqrt; + using std::swap; + using std::abs; + + eigen_assert((amat.rows() == amat.cols()) && "The factorization should be done on a square matrix"); + int n = amat.cols(); // Size of the matrix + m_lu.resize(n,n); + // Declare Working vectors and variables + Vector u(n) ; // real values of the row -- maximum size is n -- + VectorXi ju(n); // column position of the values in u -- maximum size is n + VectorXi jr(n); // Indicate the position of the nonzero elements in the vector u -- A zero location is indicated by -1 + + // Apply the fill-reducing permutation + eigen_assert(m_analysisIsOk && "You must first call analyzePattern()"); + SparseMatrix mat; + mat = amat.twistedBy(m_Pinv); + + // Initialization + jr.fill(-1); + ju.fill(0); + u.fill(0); + + // number of largest elements to keep in each row: + int fill_in = static_cast (amat.nonZeros()*m_fillfactor)/n+1; + if (fill_in > n) fill_in = n; + + // number of largest nonzero elements to keep in the L and the U part of the current row: + int nnzL = fill_in/2; + int nnzU = nnzL; + m_lu.reserve(n * (nnzL + nnzU + 1)); + + // global loop over the rows of the sparse matrix + for (int ii = 0; ii < n; ii++) + { + // 1 - copy the lower and the upper part of the row i of mat in the working vector u + + int sizeu = 1; // number of nonzero elements in the upper part of the current row + int sizel = 0; // number of nonzero elements in the lower part of the current row + ju(ii) = ii; + u(ii) = 0; + jr(ii) = ii; + RealScalar rownorm = 0; + + typename FactorType::InnerIterator j_it(mat, ii); // Iterate through the current row ii + for (; j_it; ++j_it) + { + int k = j_it.index(); + if (k < ii) + { + // copy the lower part + ju(sizel) = k; + u(sizel) = j_it.value(); + jr(k) = sizel; + ++sizel; + } + else if (k == ii) + { + u(ii) = j_it.value(); + } + else + { + // copy the upper part + int jpos = ii + sizeu; + ju(jpos) = k; + u(jpos) = j_it.value(); + jr(k) = jpos; + ++sizeu; + } + rownorm += internal::abs2(j_it.value()); + } + + // 2 - detect possible zero row + if(rownorm==0) + { + m_info = NumericalIssue; + return; + } + // Take the 2-norm of the current row as a relative tolerance + rownorm = sqrt(rownorm); + + // 3 - eliminate the previous nonzero rows + int jj = 0; + int len = 0; + while (jj < sizel) + { + // In order to eliminate in the correct order, + // we must select first the smallest column index among ju(jj:sizel) + int k; + int minrow = ju.segment(jj,sizel-jj).minCoeff(&k); // k is relative to the segment + k += jj; + if (minrow != ju(jj)) + { + // swap the two locations + int j = ju(jj); + swap(ju(jj), ju(k)); + jr(minrow) = jj; jr(j) = k; + swap(u(jj), u(k)); + } + // Reset this location + jr(minrow) = -1; + + // Start elimination + typename FactorType::InnerIterator ki_it(m_lu, minrow); + while (ki_it && ki_it.index() < minrow) ++ki_it; + eigen_internal_assert(ki_it && ki_it.col()==minrow); + Scalar fact = u(jj) / ki_it.value(); + + // drop too small elements + if(abs(fact) <= m_droptol) + { + jj++; + continue; + } + + // linear combination of the current row ii and the row minrow + ++ki_it; + for (; ki_it; ++ki_it) + { + Scalar prod = fact * ki_it.value(); + int j = ki_it.index(); + int jpos = jr(j); + if (jpos == -1) // fill-in element + { + int newpos; + if (j >= ii) // dealing with the upper part + { + newpos = ii + sizeu; + sizeu++; + eigen_internal_assert(sizeu<=n); + } + else // dealing with the lower part + { + newpos = sizel; + sizel++; + eigen_internal_assert(sizel<=ii); + } + ju(newpos) = j; + u(newpos) = -prod; + jr(j) = newpos; + } + else + u(jpos) -= prod; + } + // store the pivot element + u(len) = fact; + ju(len) = minrow; + ++len; + + jj++; + } // end of the elimination on the row ii + + // reset the upper part of the pointer jr to zero + for(int k = 0; k m_droptol * rownorm ) + { + ++len; + u(ii + len) = u(ii + k); + ju(ii + len) = ju(ii + k); + } + } + sizeu = len + 1; // +1 to take into account the diagonal element + len = (std::min)(sizeu, nnzU); + typename Vector::SegmentReturnType uu(u.segment(ii+1, sizeu-1)); + typename VectorXi::SegmentReturnType juu(ju.segment(ii+1, sizeu-1)); + QuickSplit(uu, juu, len); + + // store the largest elements of the U part + for(int k = ii + 1; k < ii + len; k++) + m_lu.insertBackByOuterInnerUnordered(ii,ju(k)) = u(k); + } + + m_lu.finalize(); + m_lu.makeCompressed(); + + m_factorizationIsOk = true; + m_info = Success; +} + +namespace internal { + +template +struct solve_retval, Rhs> + : solve_retval_base, Rhs> +{ + typedef IncompleteLUT<_MatrixType> Dec; + EIGEN_MAKE_SOLVE_HELPERS(Dec,Rhs) + + template void evalTo(Dest& dst) const + { + dec()._solve(rhs(),dst); + } +}; + +} // end namespace internal + +} // end namespace Eigen + +#endif // EIGEN_INCOMPLETE_LUT_H + diff --git a/extern/Eigen3/Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h b/extern/Eigen3/Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h new file mode 100644 index 00000000000..11706cebabd --- /dev/null +++ b/extern/Eigen3/Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h @@ -0,0 +1,254 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2011 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_ITERATIVE_SOLVER_BASE_H +#define EIGEN_ITERATIVE_SOLVER_BASE_H + +namespace Eigen { + +/** \ingroup IterativeLinearSolvers_Module + * \brief Base class for linear iterative solvers + * + * \sa class SimplicialCholesky, DiagonalPreconditioner, IdentityPreconditioner + */ +template< typename Derived> +class IterativeSolverBase : internal::noncopyable +{ +public: + typedef typename internal::traits::MatrixType MatrixType; + typedef typename internal::traits::Preconditioner Preconditioner; + typedef typename MatrixType::Scalar Scalar; + typedef typename MatrixType::Index Index; + typedef typename MatrixType::RealScalar RealScalar; + +public: + + Derived& derived() { return *static_cast(this); } + const Derived& derived() const { return *static_cast(this); } + + /** Default constructor. */ + IterativeSolverBase() + : mp_matrix(0) + { + init(); + } + + /** Initialize the solver with matrix \a A for further \c Ax=b solving. + * + * This constructor is a shortcut for the default constructor followed + * by a call to compute(). + * + * \warning this class stores a reference to the matrix A as well as some + * precomputed values that depend on it. Therefore, if \a A is changed + * this class becomes invalid. Call compute() to update it with the new + * matrix A, or modify a copy of A. + */ + IterativeSolverBase(const MatrixType& A) + { + init(); + compute(A); + } + + ~IterativeSolverBase() {} + + /** Initializes the iterative solver for the sparcity pattern of the matrix \a A for further solving \c Ax=b problems. + * + * Currently, this function mostly call analyzePattern on the preconditioner. In the future + * we might, for instance, implement column reodering for faster matrix vector products. + */ + Derived& analyzePattern(const MatrixType& A) + { + m_preconditioner.analyzePattern(A); + m_isInitialized = true; + m_analysisIsOk = true; + m_info = Success; + return derived(); + } + + /** Initializes the iterative solver with the numerical values of the matrix \a A for further solving \c Ax=b problems. + * + * Currently, this function mostly call factorize on the preconditioner. + * + * \warning this class stores a reference to the matrix A as well as some + * precomputed values that depend on it. Therefore, if \a A is changed + * this class becomes invalid. Call compute() to update it with the new + * matrix A, or modify a copy of A. + */ + Derived& factorize(const MatrixType& A) + { + eigen_assert(m_analysisIsOk && "You must first call analyzePattern()"); + mp_matrix = &A; + m_preconditioner.factorize(A); + m_factorizationIsOk = true; + m_info = Success; + return derived(); + } + + /** Initializes the iterative solver with the matrix \a A for further solving \c Ax=b problems. + * + * Currently, this function mostly initialized/compute the preconditioner. In the future + * we might, for instance, implement column reodering for faster matrix vector products. + * + * \warning this class stores a reference to the matrix A as well as some + * precomputed values that depend on it. Therefore, if \a A is changed + * this class becomes invalid. Call compute() to update it with the new + * matrix A, or modify a copy of A. + */ + Derived& compute(const MatrixType& A) + { + mp_matrix = &A; + m_preconditioner.compute(A); + m_isInitialized = true; + m_analysisIsOk = true; + m_factorizationIsOk = true; + m_info = Success; + return derived(); + } + + /** \internal */ + Index rows() const { return mp_matrix ? mp_matrix->rows() : 0; } + /** \internal */ + Index cols() const { return mp_matrix ? mp_matrix->cols() : 0; } + + /** \returns the tolerance threshold used by the stopping criteria */ + RealScalar tolerance() const { return m_tolerance; } + + /** Sets the tolerance threshold used by the stopping criteria */ + Derived& setTolerance(RealScalar tolerance) + { + m_tolerance = tolerance; + return derived(); + } + + /** \returns a read-write reference to the preconditioner for custom configuration. */ + Preconditioner& preconditioner() { return m_preconditioner; } + + /** \returns a read-only reference to the preconditioner. */ + const Preconditioner& preconditioner() const { return m_preconditioner; } + + /** \returns the max number of iterations */ + int maxIterations() const + { + return (mp_matrix && m_maxIterations<0) ? mp_matrix->cols() : m_maxIterations; + } + + /** Sets the max number of iterations */ + Derived& setMaxIterations(int maxIters) + { + m_maxIterations = maxIters; + return derived(); + } + + /** \returns the number of iterations performed during the last solve */ + int iterations() const + { + eigen_assert(m_isInitialized && "ConjugateGradient is not initialized."); + return m_iterations; + } + + /** \returns the tolerance error reached during the last solve */ + RealScalar error() const + { + eigen_assert(m_isInitialized && "ConjugateGradient is not initialized."); + return m_error; + } + + /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A. + * + * \sa compute() + */ + template inline const internal::solve_retval + solve(const MatrixBase& b) const + { + eigen_assert(m_isInitialized && "IterativeSolverBase is not initialized."); + eigen_assert(rows()==b.rows() + && "IterativeSolverBase::solve(): invalid number of rows of the right hand side matrix b"); + return internal::solve_retval(derived(), b.derived()); + } + + /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A. + * + * \sa compute() + */ + template + inline const internal::sparse_solve_retval + solve(const SparseMatrixBase& b) const + { + eigen_assert(m_isInitialized && "IterativeSolverBase is not initialized."); + eigen_assert(rows()==b.rows() + && "IterativeSolverBase::solve(): invalid number of rows of the right hand side matrix b"); + return internal::sparse_solve_retval(*this, b.derived()); + } + + /** \returns Success if the iterations converged, and NoConvergence otherwise. */ + ComputationInfo info() const + { + eigen_assert(m_isInitialized && "IterativeSolverBase is not initialized."); + return m_info; + } + + /** \internal */ + template + void _solve_sparse(const Rhs& b, SparseMatrix &dest) const + { + eigen_assert(rows()==b.rows()); + + int rhsCols = b.cols(); + int size = b.rows(); + Eigen::Matrix tb(size); + Eigen::Matrix tx(size); + for(int k=0; k::epsilon(); + } + const MatrixType* mp_matrix; + Preconditioner m_preconditioner; + + int m_maxIterations; + RealScalar m_tolerance; + + mutable RealScalar m_error; + mutable int m_iterations; + mutable ComputationInfo m_info; + mutable bool m_isInitialized, m_analysisIsOk, m_factorizationIsOk; +}; + +namespace internal { + +template +struct sparse_solve_retval, Rhs> + : sparse_solve_retval_base, Rhs> +{ + typedef IterativeSolverBase Dec; + EIGEN_MAKE_SPARSE_SOLVE_HELPERS(Dec,Rhs) + + template void evalTo(Dest& dst) const + { + dec().derived()._solve_sparse(rhs(),dst); + } +}; + +} // end namespace internal + +} // end namespace Eigen + +#endif // EIGEN_ITERATIVE_SOLVER_BASE_H diff --git a/extern/Eigen3/Eigen/src/Jacobi/Jacobi.h b/extern/Eigen3/Eigen/src/Jacobi/Jacobi.h index 98dea6800bc..a9c17dcdf19 100644 --- a/extern/Eigen3/Eigen/src/Jacobi/Jacobi.h +++ b/extern/Eigen3/Eigen/src/Jacobi/Jacobi.h @@ -4,28 +4,15 @@ // Copyright (C) 2009 Benoit Jacob // Copyright (C) 2009 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_JACOBI_H #define EIGEN_JACOBI_H +namespace Eigen { + /** \ingroup Jacobi_Module * \jacobi_module * \class JacobiRotation @@ -326,7 +313,7 @@ void /*EIGEN_DONT_INLINE*/ apply_rotation_in_the_plane(VectorX& _x, VectorY& _y, // both vectors are sequentially stored in memory => vectorization enum { Peeling = 2 }; - Index alignedStart = first_aligned(y, size); + Index alignedStart = internal::first_aligned(y, size); Index alignedEnd = alignedStart + ((size-alignedStart)/PacketSize)*PacketSize; const Packet pc = pset1(j.c()); @@ -344,7 +331,7 @@ void /*EIGEN_DONT_INLINE*/ apply_rotation_in_the_plane(VectorX& _x, VectorY& _y, Scalar* EIGEN_RESTRICT px = x + alignedStart; Scalar* EIGEN_RESTRICT py = y + alignedStart; - if(first_aligned(x, size)==alignedStart) + if(internal::first_aligned(x, size)==alignedStart) { for(Index i=alignedStart; i // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_DETERMINANT_H #define EIGEN_DETERMINANT_H +namespace Eigen { + namespace internal { template @@ -109,4 +96,6 @@ inline typename internal::traits::Scalar MatrixBase::determina return internal::determinant_impl::type>::run(derived()); } +} // end namespace Eigen + #endif // EIGEN_DETERMINANT_H diff --git a/extern/Eigen3/Eigen/src/LU/FullPivLU.h b/extern/Eigen3/Eigen/src/LU/FullPivLU.h index 46ae7d651c8..e23f96cdcf1 100644 --- a/extern/Eigen3/Eigen/src/LU/FullPivLU.h +++ b/extern/Eigen3/Eigen/src/LU/FullPivLU.h @@ -3,28 +3,15 @@ // // Copyright (C) 2006-2009 Benoit Jacob // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_LU_H #define EIGEN_LU_H +namespace Eigen { + /** \ingroup LU_Module * * \class FullPivLU @@ -282,6 +269,7 @@ template class FullPivLU FullPivLU& setThreshold(Default_t) { m_usePrescribedThreshold = false; + return *this; } /** Returns the threshold that will be used by certain methods such as rank(). @@ -743,4 +731,6 @@ MatrixBase::fullPivLu() const return FullPivLU(eval()); } +} // end namespace Eigen + #endif // EIGEN_LU_H diff --git a/extern/Eigen3/Eigen/src/LU/Inverse.h b/extern/Eigen3/Eigen/src/LU/Inverse.h index 2d3e6d10529..39b8cdbc8dc 100644 --- a/extern/Eigen3/Eigen/src/LU/Inverse.h +++ b/extern/Eigen3/Eigen/src/LU/Inverse.h @@ -3,28 +3,15 @@ // // Copyright (C) 2008-2010 Benoit Jacob // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_INVERSE_H #define EIGEN_INVERSE_H +namespace Eigen { + namespace internal { /********************************** @@ -286,7 +273,7 @@ struct inverse_impl : public ReturnByValue > typedef typename MatrixType::Index Index; typedef typename internal::eval::type MatrixTypeNested; typedef typename remove_all::type MatrixTypeNestedCleaned; - const MatrixTypeNested m_matrix; + MatrixTypeNested m_matrix; inverse_impl(const MatrixType& matrix) : m_matrix(matrix) @@ -404,4 +391,6 @@ inline void MatrixBase::computeInverseWithCheck( computeInverseAndDetWithCheck(inverse,determinant,invertible,absDeterminantThreshold); } +} // end namespace Eigen + #endif // EIGEN_INVERSE_H diff --git a/extern/Eigen3/Eigen/src/LU/PartialPivLU.h b/extern/Eigen3/Eigen/src/LU/PartialPivLU.h index 09394b01f5b..c9ff9dd5a36 100644 --- a/extern/Eigen3/Eigen/src/LU/PartialPivLU.h +++ b/extern/Eigen3/Eigen/src/LU/PartialPivLU.h @@ -4,28 +4,15 @@ // Copyright (C) 2006-2009 Benoit Jacob // Copyright (C) 2009 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_PARTIALLU_H #define EIGEN_PARTIALLU_H +namespace Eigen { + /** \ingroup LU_Module * * \class PartialPivLU @@ -506,4 +493,6 @@ MatrixBase::lu() const } #endif +} // end namespace Eigen + #endif // EIGEN_PARTIALLU_H diff --git a/extern/Eigen3/Eigen/src/LU/PartialPivLU_MKL.h b/extern/Eigen3/Eigen/src/LU/PartialPivLU_MKL.h new file mode 100644 index 00000000000..9035953c82f --- /dev/null +++ b/extern/Eigen3/Eigen/src/LU/PartialPivLU_MKL.h @@ -0,0 +1,85 @@ +/* + Copyright (c) 2011, Intel Corporation. All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of Intel Corporation nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ******************************************************************************** + * Content : Eigen bindings to Intel(R) MKL + * LU decomposition with partial pivoting based on LAPACKE_?getrf function. + ******************************************************************************** +*/ + +#ifndef EIGEN_PARTIALLU_LAPACK_H +#define EIGEN_PARTIALLU_LAPACK_H + +#include "Eigen/src/Core/util/MKL_support.h" + +namespace Eigen { + +namespace internal { + +/** \internal Specialization for the data types supported by MKL */ + +#define EIGEN_MKL_LU_PARTPIV(EIGTYPE, MKLTYPE, MKLPREFIX) \ +template \ +struct partial_lu_impl \ +{ \ + /* \internal performs the LU decomposition in-place of the matrix represented */ \ + static lapack_int blocked_lu(lapack_int rows, lapack_int cols, EIGTYPE* lu_data, lapack_int luStride, lapack_int* row_transpositions, lapack_int& nb_transpositions, lapack_int maxBlockSize=256) \ + { \ + EIGEN_UNUSED_VARIABLE(maxBlockSize);\ + lapack_int matrix_order, first_zero_pivot; \ + lapack_int m, n, lda, *ipiv, info; \ + EIGTYPE* a; \ +/* Set up parameters for ?getrf */ \ + matrix_order = StorageOrder==RowMajor ? LAPACK_ROW_MAJOR : LAPACK_COL_MAJOR; \ + lda = luStride; \ + a = lu_data; \ + ipiv = row_transpositions; \ + m = rows; \ + n = cols; \ + nb_transpositions = 0; \ +\ + info = LAPACKE_##MKLPREFIX##getrf( matrix_order, m, n, (MKLTYPE*)a, lda, ipiv ); \ +\ + for(int i=0;i= 0); \ +/* something should be done with nb_transpositions */ \ +\ + first_zero_pivot = info; \ + return first_zero_pivot; \ + } \ +}; + +EIGEN_MKL_LU_PARTPIV(double, double, d) +EIGEN_MKL_LU_PARTPIV(float, float, s) +EIGEN_MKL_LU_PARTPIV(dcomplex, MKL_Complex16, z) +EIGEN_MKL_LU_PARTPIV(scomplex, MKL_Complex8, c) + +} // end namespace internal + +} // end namespace Eigen + +#endif // EIGEN_PARTIALLU_LAPACK_H diff --git a/extern/Eigen3/Eigen/src/LU/arch/Inverse_SSE.h b/extern/Eigen3/Eigen/src/LU/arch/Inverse_SSE.h index 4c6153f0aff..60b7a23763e 100644 --- a/extern/Eigen3/Eigen/src/LU/arch/Inverse_SSE.h +++ b/extern/Eigen3/Eigen/src/LU/arch/Inverse_SSE.h @@ -5,24 +5,9 @@ // Copyright (C) 2010 Gael Guennebaud // Copyright (C) 2009 Benoit Jacob // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. // The SSE code for the 4x4 float and double matrix inverse in this file // comes from the following Intel's library: @@ -42,6 +27,8 @@ #ifndef EIGEN_INVERSE_SSE_H #define EIGEN_INVERSE_SSE_H +namespace Eigen { + namespace internal { template @@ -335,6 +322,8 @@ struct compute_inverse_size4 } }; -} +} // end namespace internal + +} // end namespace Eigen #endif // EIGEN_INVERSE_SSE_H diff --git a/extern/Eigen3/Eigen/src/OrderingMethods/Amd.h b/extern/Eigen3/Eigen/src/OrderingMethods/Amd.h new file mode 100644 index 00000000000..ce04852b872 --- /dev/null +++ b/extern/Eigen3/Eigen/src/OrderingMethods/Amd.h @@ -0,0 +1,439 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2010 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +/* + +NOTE: this routine has been adapted from the CSparse library: + +Copyright (c) 2006, Timothy A. Davis. +http://www.cise.ufl.edu/research/sparse/CSparse + +CSparse is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +CSparse is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this Module; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +*/ + +#include "../Core/util/NonMPL2.h" + +#ifndef EIGEN_SPARSE_AMD_H +#define EIGEN_SPARSE_AMD_H + +namespace Eigen { + +namespace internal { + +template inline T amd_flip(const T& i) { return -i-2; } +template inline T amd_unflip(const T& i) { return i<0 ? amd_flip(i) : i; } +template inline bool amd_marked(const T0* w, const T1& j) { return w[j]<0; } +template inline void amd_mark(const T0* w, const T1& j) { return w[j] = amd_flip(w[j]); } + +/* clear w */ +template +static int cs_wclear (Index mark, Index lemax, Index *w, Index n) +{ + Index k; + if(mark < 2 || (mark + lemax < 0)) + { + for(k = 0; k < n; k++) + if(w[k] != 0) + w[k] = 1; + mark = 2; + } + return (mark); /* at this point, w[0..n-1] < mark holds */ +} + +/* depth-first search and postorder of a tree rooted at node j */ +template +Index cs_tdfs(Index j, Index k, Index *head, const Index *next, Index *post, Index *stack) +{ + int i, p, top = 0; + if(!head || !next || !post || !stack) return (-1); /* check inputs */ + stack[0] = j; /* place j on the stack */ + while (top >= 0) /* while (stack is not empty) */ + { + p = stack[top]; /* p = top of stack */ + i = head[p]; /* i = youngest child of p */ + if(i == -1) + { + top--; /* p has no unordered children left */ + post[k++] = p; /* node p is the kth postordered node */ + } + else + { + head[p] = next[i]; /* remove i from children of p */ + stack[++top] = i; /* start dfs on child node i */ + } + } + return k; +} + + +/** \internal + * Approximate minimum degree ordering algorithm. + * \returns the permutation P reducing the fill-in of the input matrix \a C + * The input matrix \a C must be a selfadjoint compressed column major SparseMatrix object. Both the upper and lower parts have to be stored, but the diagonal entries are optional. + * On exit the values of C are destroyed */ +template +void minimum_degree_ordering(SparseMatrix& C, PermutationMatrix& perm) +{ + using std::sqrt; + typedef SparseMatrix CCS; + + int d, dk, dext, lemax = 0, e, elenk, eln, i, j, k, k1, + k2, k3, jlast, ln, dense, nzmax, mindeg = 0, nvi, nvj, nvk, mark, wnvi, + ok, nel = 0, p, p1, p2, p3, p4, pj, pk, pk1, pk2, pn, q, t; + unsigned int h; + + Index n = C.cols(); + dense = std::max (16, Index(10 * sqrt(double(n)))); /* find dense threshold */ + dense = std::min (n-2, dense); + + Index cnz = C.nonZeros(); + perm.resize(n+1); + t = cnz + cnz/5 + 2*n; /* add elbow room to C */ + C.resizeNonZeros(t); + + Index* W = new Index[8*(n+1)]; /* get workspace */ + Index* len = W; + Index* nv = W + (n+1); + Index* next = W + 2*(n+1); + Index* head = W + 3*(n+1); + Index* elen = W + 4*(n+1); + Index* degree = W + 5*(n+1); + Index* w = W + 6*(n+1); + Index* hhead = W + 7*(n+1); + Index* last = perm.indices().data(); /* use P as workspace for last */ + + /* --- Initialize quotient graph ---------------------------------------- */ + Index* Cp = C.outerIndexPtr(); + Index* Ci = C.innerIndexPtr(); + for(k = 0; k < n; k++) + len[k] = Cp[k+1] - Cp[k]; + len[n] = 0; + nzmax = t; + + for(i = 0; i <= n; i++) + { + head[i] = -1; // degree list i is empty + last[i] = -1; + next[i] = -1; + hhead[i] = -1; // hash list i is empty + nv[i] = 1; // node i is just one node + w[i] = 1; // node i is alive + elen[i] = 0; // Ek of node i is empty + degree[i] = len[i]; // degree of node i + } + mark = internal::cs_wclear(0, 0, w, n); /* clear w */ + elen[n] = -2; /* n is a dead element */ + Cp[n] = -1; /* n is a root of assembly tree */ + w[n] = 0; /* n is a dead element */ + + /* --- Initialize degree lists ------------------------------------------ */ + for(i = 0; i < n; i++) + { + d = degree[i]; + if(d == 0) /* node i is empty */ + { + elen[i] = -2; /* element i is dead */ + nel++; + Cp[i] = -1; /* i is a root of assembly tree */ + w[i] = 0; + } + else if(d > dense) /* node i is dense */ + { + nv[i] = 0; /* absorb i into element n */ + elen[i] = -1; /* node i is dead */ + nel++; + Cp[i] = amd_flip (n); + nv[n]++; + } + else + { + if(head[d] != -1) last[head[d]] = i; + next[i] = head[d]; /* put node i in degree list d */ + head[d] = i; + } + } + + while (nel < n) /* while (selecting pivots) do */ + { + /* --- Select node of minimum approximate degree -------------------- */ + for(k = -1; mindeg < n && (k = head[mindeg]) == -1; mindeg++) {} + if(next[k] != -1) last[next[k]] = -1; + head[mindeg] = next[k]; /* remove k from degree list */ + elenk = elen[k]; /* elenk = |Ek| */ + nvk = nv[k]; /* # of nodes k represents */ + nel += nvk; /* nv[k] nodes of A eliminated */ + + /* --- Garbage collection ------------------------------------------- */ + if(elenk > 0 && cnz + mindeg >= nzmax) + { + for(j = 0; j < n; j++) + { + if((p = Cp[j]) >= 0) /* j is a live node or element */ + { + Cp[j] = Ci[p]; /* save first entry of object */ + Ci[p] = amd_flip (j); /* first entry is now amd_flip(j) */ + } + } + for(q = 0, p = 0; p < cnz; ) /* scan all of memory */ + { + if((j = amd_flip (Ci[p++])) >= 0) /* found object j */ + { + Ci[q] = Cp[j]; /* restore first entry of object */ + Cp[j] = q++; /* new pointer to object j */ + for(k3 = 0; k3 < len[j]-1; k3++) Ci[q++] = Ci[p++]; + } + } + cnz = q; /* Ci[cnz...nzmax-1] now free */ + } + + /* --- Construct new element ---------------------------------------- */ + dk = 0; + nv[k] = -nvk; /* flag k as in Lk */ + p = Cp[k]; + pk1 = (elenk == 0) ? p : cnz; /* do in place if elen[k] == 0 */ + pk2 = pk1; + for(k1 = 1; k1 <= elenk + 1; k1++) + { + if(k1 > elenk) + { + e = k; /* search the nodes in k */ + pj = p; /* list of nodes starts at Ci[pj]*/ + ln = len[k] - elenk; /* length of list of nodes in k */ + } + else + { + e = Ci[p++]; /* search the nodes in e */ + pj = Cp[e]; + ln = len[e]; /* length of list of nodes in e */ + } + for(k2 = 1; k2 <= ln; k2++) + { + i = Ci[pj++]; + if((nvi = nv[i]) <= 0) continue; /* node i dead, or seen */ + dk += nvi; /* degree[Lk] += size of node i */ + nv[i] = -nvi; /* negate nv[i] to denote i in Lk*/ + Ci[pk2++] = i; /* place i in Lk */ + if(next[i] != -1) last[next[i]] = last[i]; + if(last[i] != -1) /* remove i from degree list */ + { + next[last[i]] = next[i]; + } + else + { + head[degree[i]] = next[i]; + } + } + if(e != k) + { + Cp[e] = amd_flip (k); /* absorb e into k */ + w[e] = 0; /* e is now a dead element */ + } + } + if(elenk != 0) cnz = pk2; /* Ci[cnz...nzmax] is free */ + degree[k] = dk; /* external degree of k - |Lk\i| */ + Cp[k] = pk1; /* element k is in Ci[pk1..pk2-1] */ + len[k] = pk2 - pk1; + elen[k] = -2; /* k is now an element */ + + /* --- Find set differences ----------------------------------------- */ + mark = internal::cs_wclear(mark, lemax, w, n); /* clear w if necessary */ + for(pk = pk1; pk < pk2; pk++) /* scan 1: find |Le\Lk| */ + { + i = Ci[pk]; + if((eln = elen[i]) <= 0) continue;/* skip if elen[i] empty */ + nvi = -nv[i]; /* nv[i] was negated */ + wnvi = mark - nvi; + for(p = Cp[i]; p <= Cp[i] + eln - 1; p++) /* scan Ei */ + { + e = Ci[p]; + if(w[e] >= mark) + { + w[e] -= nvi; /* decrement |Le\Lk| */ + } + else if(w[e] != 0) /* ensure e is a live element */ + { + w[e] = degree[e] + wnvi; /* 1st time e seen in scan 1 */ + } + } + } + + /* --- Degree update ------------------------------------------------ */ + for(pk = pk1; pk < pk2; pk++) /* scan2: degree update */ + { + i = Ci[pk]; /* consider node i in Lk */ + p1 = Cp[i]; + p2 = p1 + elen[i] - 1; + pn = p1; + for(h = 0, d = 0, p = p1; p <= p2; p++) /* scan Ei */ + { + e = Ci[p]; + if(w[e] != 0) /* e is an unabsorbed element */ + { + dext = w[e] - mark; /* dext = |Le\Lk| */ + if(dext > 0) + { + d += dext; /* sum up the set differences */ + Ci[pn++] = e; /* keep e in Ei */ + h += e; /* compute the hash of node i */ + } + else + { + Cp[e] = amd_flip (k); /* aggressive absorb. e->k */ + w[e] = 0; /* e is a dead element */ + } + } + } + elen[i] = pn - p1 + 1; /* elen[i] = |Ei| */ + p3 = pn; + p4 = p1 + len[i]; + for(p = p2 + 1; p < p4; p++) /* prune edges in Ai */ + { + j = Ci[p]; + if((nvj = nv[j]) <= 0) continue; /* node j dead or in Lk */ + d += nvj; /* degree(i) += |j| */ + Ci[pn++] = j; /* place j in node list of i */ + h += j; /* compute hash for node i */ + } + if(d == 0) /* check for mass elimination */ + { + Cp[i] = amd_flip (k); /* absorb i into k */ + nvi = -nv[i]; + dk -= nvi; /* |Lk| -= |i| */ + nvk += nvi; /* |k| += nv[i] */ + nel += nvi; + nv[i] = 0; + elen[i] = -1; /* node i is dead */ + } + else + { + degree[i] = std::min (degree[i], d); /* update degree(i) */ + Ci[pn] = Ci[p3]; /* move first node to end */ + Ci[p3] = Ci[p1]; /* move 1st el. to end of Ei */ + Ci[p1] = k; /* add k as 1st element in of Ei */ + len[i] = pn - p1 + 1; /* new len of adj. list of node i */ + h %= n; /* finalize hash of i */ + next[i] = hhead[h]; /* place i in hash bucket */ + hhead[h] = i; + last[i] = h; /* save hash of i in last[i] */ + } + } /* scan2 is done */ + degree[k] = dk; /* finalize |Lk| */ + lemax = std::max(lemax, dk); + mark = internal::cs_wclear(mark+lemax, lemax, w, n); /* clear w */ + + /* --- Supernode detection ------------------------------------------ */ + for(pk = pk1; pk < pk2; pk++) + { + i = Ci[pk]; + if(nv[i] >= 0) continue; /* skip if i is dead */ + h = last[i]; /* scan hash bucket of node i */ + i = hhead[h]; + hhead[h] = -1; /* hash bucket will be empty */ + for(; i != -1 && next[i] != -1; i = next[i], mark++) + { + ln = len[i]; + eln = elen[i]; + for(p = Cp[i]+1; p <= Cp[i] + ln-1; p++) w[Ci[p]] = mark; + jlast = i; + for(j = next[i]; j != -1; ) /* compare i with all j */ + { + ok = (len[j] == ln) && (elen[j] == eln); + for(p = Cp[j] + 1; ok && p <= Cp[j] + ln - 1; p++) + { + if(w[Ci[p]] != mark) ok = 0; /* compare i and j*/ + } + if(ok) /* i and j are identical */ + { + Cp[j] = amd_flip (i); /* absorb j into i */ + nv[i] += nv[j]; + nv[j] = 0; + elen[j] = -1; /* node j is dead */ + j = next[j]; /* delete j from hash bucket */ + next[jlast] = j; + } + else + { + jlast = j; /* j and i are different */ + j = next[j]; + } + } + } + } + + /* --- Finalize new element------------------------------------------ */ + for(p = pk1, pk = pk1; pk < pk2; pk++) /* finalize Lk */ + { + i = Ci[pk]; + if((nvi = -nv[i]) <= 0) continue;/* skip if i is dead */ + nv[i] = nvi; /* restore nv[i] */ + d = degree[i] + dk - nvi; /* compute external degree(i) */ + d = std::min (d, n - nel - nvi); + if(head[d] != -1) last[head[d]] = i; + next[i] = head[d]; /* put i back in degree list */ + last[i] = -1; + head[d] = i; + mindeg = std::min (mindeg, d); /* find new minimum degree */ + degree[i] = d; + Ci[p++] = i; /* place i in Lk */ + } + nv[k] = nvk; /* # nodes absorbed into k */ + if((len[k] = p-pk1) == 0) /* length of adj list of element k*/ + { + Cp[k] = -1; /* k is a root of the tree */ + w[k] = 0; /* k is now a dead element */ + } + if(elenk != 0) cnz = p; /* free unused space in Lk */ + } + + /* --- Postordering ----------------------------------------------------- */ + for(i = 0; i < n; i++) Cp[i] = amd_flip (Cp[i]);/* fix assembly tree */ + for(j = 0; j <= n; j++) head[j] = -1; + for(j = n; j >= 0; j--) /* place unordered nodes in lists */ + { + if(nv[j] > 0) continue; /* skip if j is an element */ + next[j] = head[Cp[j]]; /* place j in list of its parent */ + head[Cp[j]] = j; + } + for(e = n; e >= 0; e--) /* place elements in lists */ + { + if(nv[e] <= 0) continue; /* skip unless e is an element */ + if(Cp[e] != -1) + { + next[e] = head[Cp[e]]; /* place e in list of its parent */ + head[Cp[e]] = e; + } + } + for(k = 0, i = 0; i <= n; i++) /* postorder the assembly tree */ + { + if(Cp[i] == -1) k = internal::cs_tdfs(i, k, head, next, perm.indices().data(), w); + } + + perm.indices().conservativeResize(n); + + delete[] W; +} + +} // namespace internal + +} // end namespace Eigen + +#endif // EIGEN_SPARSE_AMD_H diff --git a/extern/Eigen3/Eigen/src/PaStiXSupport/PaStiXSupport.h b/extern/Eigen3/Eigen/src/PaStiXSupport/PaStiXSupport.h new file mode 100644 index 00000000000..82e137c645a --- /dev/null +++ b/extern/Eigen3/Eigen/src/PaStiXSupport/PaStiXSupport.h @@ -0,0 +1,742 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2012 Désiré Nuentsa-Wakam +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_PASTIXSUPPORT_H +#define EIGEN_PASTIXSUPPORT_H + +namespace Eigen { + +/** \ingroup PaStiXSupport_Module + * \brief Interface to the PaStix solver + * + * This class is used to solve the linear systems A.X = B via the PaStix library. + * The matrix can be either real or complex, symmetric or not. + * + * \sa TutorialSparseDirectSolvers + */ +template class PastixLU; +template class PastixLLT; +template class PastixLDLT; + +namespace internal +{ + + template struct pastix_traits; + + template + struct pastix_traits< PastixLU<_MatrixType> > + { + typedef _MatrixType MatrixType; + typedef typename _MatrixType::Scalar Scalar; + typedef typename _MatrixType::RealScalar RealScalar; + typedef typename _MatrixType::Index Index; + }; + + template + struct pastix_traits< PastixLLT<_MatrixType,Options> > + { + typedef _MatrixType MatrixType; + typedef typename _MatrixType::Scalar Scalar; + typedef typename _MatrixType::RealScalar RealScalar; + typedef typename _MatrixType::Index Index; + }; + + template + struct pastix_traits< PastixLDLT<_MatrixType,Options> > + { + typedef _MatrixType MatrixType; + typedef typename _MatrixType::Scalar Scalar; + typedef typename _MatrixType::RealScalar RealScalar; + typedef typename _MatrixType::Index Index; + }; + + void eigen_pastix(pastix_data_t **pastix_data, int pastix_comm, int n, int *ptr, int *idx, float *vals, int *perm, int * invp, float *x, int nbrhs, int *iparm, double *dparm) + { + if (n == 0) { ptr = NULL; idx = NULL; vals = NULL; } + if (nbrhs == 0) {x = NULL; nbrhs=1;} + s_pastix(pastix_data, pastix_comm, n, ptr, idx, vals, perm, invp, x, nbrhs, iparm, dparm); + } + + void eigen_pastix(pastix_data_t **pastix_data, int pastix_comm, int n, int *ptr, int *idx, double *vals, int *perm, int * invp, double *x, int nbrhs, int *iparm, double *dparm) + { + if (n == 0) { ptr = NULL; idx = NULL; vals = NULL; } + if (nbrhs == 0) {x = NULL; nbrhs=1;} + d_pastix(pastix_data, pastix_comm, n, ptr, idx, vals, perm, invp, x, nbrhs, iparm, dparm); + } + + void eigen_pastix(pastix_data_t **pastix_data, int pastix_comm, int n, int *ptr, int *idx, std::complex *vals, int *perm, int * invp, std::complex *x, int nbrhs, int *iparm, double *dparm) + { + if (n == 0) { ptr = NULL; idx = NULL; vals = NULL; } + if (nbrhs == 0) {x = NULL; nbrhs=1;} + c_pastix(pastix_data, pastix_comm, n, ptr, idx, reinterpret_cast(vals), perm, invp, reinterpret_cast(x), nbrhs, iparm, dparm); + } + + void eigen_pastix(pastix_data_t **pastix_data, int pastix_comm, int n, int *ptr, int *idx, std::complex *vals, int *perm, int * invp, std::complex *x, int nbrhs, int *iparm, double *dparm) + { + if (n == 0) { ptr = NULL; idx = NULL; vals = NULL; } + if (nbrhs == 0) {x = NULL; nbrhs=1;} + z_pastix(pastix_data, pastix_comm, n, ptr, idx, reinterpret_cast(vals), perm, invp, reinterpret_cast(x), nbrhs, iparm, dparm); + } + + // Convert the matrix to Fortran-style Numbering + template + void c_to_fortran_numbering (MatrixType& mat) + { + if ( !(mat.outerIndexPtr()[0]) ) + { + int i; + for(i = 0; i <= mat.rows(); ++i) + ++mat.outerIndexPtr()[i]; + for(i = 0; i < mat.nonZeros(); ++i) + ++mat.innerIndexPtr()[i]; + } + } + + // Convert to C-style Numbering + template + void fortran_to_c_numbering (MatrixType& mat) + { + // Check the Numbering + if ( mat.outerIndexPtr()[0] == 1 ) + { // Convert to C-style numbering + int i; + for(i = 0; i <= mat.rows(); ++i) + --mat.outerIndexPtr()[i]; + for(i = 0; i < mat.nonZeros(); ++i) + --mat.innerIndexPtr()[i]; + } + } +} + +// This is the base class to interface with PaStiX functions. +// Users should not used this class directly. +template +class PastixBase : internal::noncopyable +{ + public: + typedef typename internal::pastix_traits::MatrixType _MatrixType; + typedef _MatrixType MatrixType; + typedef typename MatrixType::Scalar Scalar; + typedef typename MatrixType::RealScalar RealScalar; + typedef typename MatrixType::Index Index; + typedef Matrix Vector; + typedef SparseMatrix ColSpMatrix; + + public: + + PastixBase() : m_initisOk(false), m_analysisIsOk(false), m_factorizationIsOk(false), m_isInitialized(false), m_pastixdata(0), m_size(0) + { + init(); + } + + ~PastixBase() + { + clean(); + } + + /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A. + * + * \sa compute() + */ + template + inline const internal::solve_retval + solve(const MatrixBase& b) const + { + eigen_assert(m_isInitialized && "Pastix solver is not initialized."); + eigen_assert(rows()==b.rows() + && "PastixBase::solve(): invalid number of rows of the right hand side matrix b"); + return internal::solve_retval(*this, b.derived()); + } + + template + bool _solve (const MatrixBase &b, MatrixBase &x) const; + + /** \internal */ + template + void _solve_sparse(const Rhs& b, SparseMatrix &dest) const + { + eigen_assert(m_factorizationIsOk && "The decomposition is not in a valid state for solving, you must first call either compute() or symbolic()/numeric()"); + eigen_assert(rows()==b.rows()); + + // we process the sparse rhs per block of NbColsAtOnce columns temporarily stored into a dense matrix. + static const int NbColsAtOnce = 1; + int rhsCols = b.cols(); + int size = b.rows(); + Eigen::Matrix tmp(size,rhsCols); + for(int k=0; k(rhsCols-k, NbColsAtOnce); + tmp.leftCols(actualCols) = b.middleCols(k,actualCols); + tmp.leftCols(actualCols) = derived().solve(tmp.leftCols(actualCols)); + dest.middleCols(k,actualCols) = tmp.leftCols(actualCols).sparseView(); + } + } + + Derived& derived() + { + return *static_cast(this); + } + const Derived& derived() const + { + return *static_cast(this); + } + + /** Returns a reference to the integer vector IPARM of PaStiX parameters + * to modify the default parameters. + * The statistics related to the different phases of factorization and solve are saved here as well + * \sa analyzePattern() factorize() + */ + Array& iparm() + { + return m_iparm; + } + + /** Return a reference to a particular index parameter of the IPARM vector + * \sa iparm() + */ + + int& iparm(int idxparam) + { + return m_iparm(idxparam); + } + + /** Returns a reference to the double vector DPARM of PaStiX parameters + * The statistics related to the different phases of factorization and solve are saved here as well + * \sa analyzePattern() factorize() + */ + Array& dparm() + { + return m_dparm; + } + + + /** Return a reference to a particular index parameter of the DPARM vector + * \sa dparm() + */ + double& dparm(int idxparam) + { + return m_dparm(idxparam); + } + + inline Index cols() const { return m_size; } + inline Index rows() const { return m_size; } + + /** \brief Reports whether previous computation was successful. + * + * \returns \c Success if computation was succesful, + * \c NumericalIssue if the PaStiX reports a problem + * \c InvalidInput if the input matrix is invalid + * + * \sa iparm() + */ + ComputationInfo info() const + { + eigen_assert(m_isInitialized && "Decomposition is not initialized."); + return m_info; + } + + /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A. + * + * \sa compute() + */ + template + inline const internal::sparse_solve_retval + solve(const SparseMatrixBase& b) const + { + eigen_assert(m_isInitialized && "Pastix LU, LLT or LDLT is not initialized."); + eigen_assert(rows()==b.rows() + && "PastixBase::solve(): invalid number of rows of the right hand side matrix b"); + return internal::sparse_solve_retval(*this, b.derived()); + } + + protected: + + // Initialize the Pastix data structure, check the matrix + void init(); + + // Compute the ordering and the symbolic factorization + void analyzePattern(ColSpMatrix& mat); + + // Compute the numerical factorization + void factorize(ColSpMatrix& mat); + + // Free all the data allocated by Pastix + void clean() + { + eigen_assert(m_initisOk && "The Pastix structure should be allocated first"); + m_iparm(IPARM_START_TASK) = API_TASK_CLEAN; + m_iparm(IPARM_END_TASK) = API_TASK_CLEAN; + internal::eigen_pastix(&m_pastixdata, MPI_COMM_WORLD, 0, 0, 0, (Scalar*)0, + m_perm.data(), m_invp.data(), 0, 0, m_iparm.data(), m_dparm.data()); + } + + void compute(ColSpMatrix& mat); + + int m_initisOk; + int m_analysisIsOk; + int m_factorizationIsOk; + bool m_isInitialized; + mutable ComputationInfo m_info; + mutable pastix_data_t *m_pastixdata; // Data structure for pastix + mutable int m_comm; // The MPI communicator identifier + mutable Matrix m_iparm; // integer vector for the input parameters + mutable Matrix m_dparm; // Scalar vector for the input parameters + mutable Matrix m_perm; // Permutation vector + mutable Matrix m_invp; // Inverse permutation vector + mutable int m_size; // Size of the matrix +}; + + /** Initialize the PaStiX data structure. + *A first call to this function fills iparm and dparm with the default PaStiX parameters + * \sa iparm() dparm() + */ +template +void PastixBase::init() +{ + m_size = 0; + m_iparm.setZero(IPARM_SIZE); + m_dparm.setZero(DPARM_SIZE); + + m_iparm(IPARM_MODIFY_PARAMETER) = API_NO; + pastix(&m_pastixdata, MPI_COMM_WORLD, + 0, 0, 0, 0, + 0, 0, 0, 1, m_iparm.data(), m_dparm.data()); + + m_iparm[IPARM_MATRIX_VERIFICATION] = API_NO; + m_iparm[IPARM_VERBOSE] = 2; + m_iparm[IPARM_ORDERING] = API_ORDER_SCOTCH; + m_iparm[IPARM_INCOMPLETE] = API_NO; + m_iparm[IPARM_OOC_LIMIT] = 2000; + m_iparm[IPARM_RHS_MAKING] = API_RHS_B; + m_iparm(IPARM_MATRIX_VERIFICATION) = API_NO; + + m_iparm(IPARM_START_TASK) = API_TASK_INIT; + m_iparm(IPARM_END_TASK) = API_TASK_INIT; + internal::eigen_pastix(&m_pastixdata, MPI_COMM_WORLD, 0, 0, 0, (Scalar*)0, + 0, 0, 0, 0, m_iparm.data(), m_dparm.data()); + + // Check the returned error + if(m_iparm(IPARM_ERROR_NUMBER)) { + m_info = InvalidInput; + m_initisOk = false; + } + else { + m_info = Success; + m_initisOk = true; + } +} + +template +void PastixBase::compute(ColSpMatrix& mat) +{ + eigen_assert(mat.rows() == mat.cols() && "The input matrix should be squared"); + + analyzePattern(mat); + factorize(mat); + + m_iparm(IPARM_MATRIX_VERIFICATION) = API_NO; + m_isInitialized = m_factorizationIsOk; +} + + +template +void PastixBase::analyzePattern(ColSpMatrix& mat) +{ + eigen_assert(m_initisOk && "The initialization of PaSTiX failed"); + + // clean previous calls + if(m_size>0) + clean(); + + m_size = mat.rows(); + m_perm.resize(m_size); + m_invp.resize(m_size); + + m_iparm(IPARM_START_TASK) = API_TASK_ORDERING; + m_iparm(IPARM_END_TASK) = API_TASK_ANALYSE; + internal::eigen_pastix(&m_pastixdata, MPI_COMM_WORLD, m_size, mat.outerIndexPtr(), mat.innerIndexPtr(), + mat.valuePtr(), m_perm.data(), m_invp.data(), 0, 0, m_iparm.data(), m_dparm.data()); + + // Check the returned error + if(m_iparm(IPARM_ERROR_NUMBER)) + { + m_info = NumericalIssue; + m_analysisIsOk = false; + } + else + { + m_info = Success; + m_analysisIsOk = true; + } +} + +template +void PastixBase::factorize(ColSpMatrix& mat) +{ +// if(&m_cpyMat != &mat) m_cpyMat = mat; + eigen_assert(m_analysisIsOk && "The analysis phase should be called before the factorization phase"); + m_iparm(IPARM_START_TASK) = API_TASK_NUMFACT; + m_iparm(IPARM_END_TASK) = API_TASK_NUMFACT; + m_size = mat.rows(); + + internal::eigen_pastix(&m_pastixdata, MPI_COMM_WORLD, m_size, mat.outerIndexPtr(), mat.innerIndexPtr(), + mat.valuePtr(), m_perm.data(), m_invp.data(), 0, 0, m_iparm.data(), m_dparm.data()); + + // Check the returned error + if(m_iparm(IPARM_ERROR_NUMBER)) + { + m_info = NumericalIssue; + m_factorizationIsOk = false; + m_isInitialized = false; + } + else + { + m_info = Success; + m_factorizationIsOk = true; + m_isInitialized = true; + } +} + +/* Solve the system */ +template +template +bool PastixBase::_solve (const MatrixBase &b, MatrixBase &x) const +{ + eigen_assert(m_isInitialized && "The matrix should be factorized first"); + EIGEN_STATIC_ASSERT((Dest::Flags&RowMajorBit)==0, + THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES); + int rhs = 1; + + x = b; /* on return, x is overwritten by the computed solution */ + + for (int i = 0; i < b.cols(); i++){ + m_iparm[IPARM_START_TASK] = API_TASK_SOLVE; + m_iparm[IPARM_END_TASK] = API_TASK_REFINE; + + internal::eigen_pastix(&m_pastixdata, MPI_COMM_WORLD, x.rows(), 0, 0, 0, + m_perm.data(), m_invp.data(), &x(0, i), rhs, m_iparm.data(), m_dparm.data()); + } + + // Check the returned error + m_info = m_iparm(IPARM_ERROR_NUMBER)==0 ? Success : NumericalIssue; + + return m_iparm(IPARM_ERROR_NUMBER)==0; +} + +/** \ingroup PaStiXSupport_Module + * \class PastixLU + * \brief Sparse direct LU solver based on PaStiX library + * + * This class is used to solve the linear systems A.X = B with a supernodal LU + * factorization in the PaStiX library. The matrix A should be squared and nonsingular + * PaStiX requires that the matrix A has a symmetric structural pattern. + * This interface can symmetrize the input matrix otherwise. + * The vectors or matrices X and B can be either dense or sparse. + * + * \tparam _MatrixType the type of the sparse matrix A, it must be a SparseMatrix<> + * \tparam IsStrSym Indicates if the input matrix has a symmetric pattern, default is false + * NOTE : Note that if the analysis and factorization phase are called separately, + * the input matrix will be symmetrized at each call, hence it is advised to + * symmetrize the matrix in a end-user program and set \p IsStrSym to true + * + * \sa \ref TutorialSparseDirectSolvers + * + */ +template +class PastixLU : public PastixBase< PastixLU<_MatrixType> > +{ + public: + typedef _MatrixType MatrixType; + typedef PastixBase > Base; + typedef typename Base::ColSpMatrix ColSpMatrix; + typedef typename MatrixType::Index Index; + + public: + PastixLU() : Base() + { + init(); + } + + PastixLU(const MatrixType& matrix):Base() + { + init(); + compute(matrix); + } + /** Compute the LU supernodal factorization of \p matrix. + * iparm and dparm can be used to tune the PaStiX parameters. + * see the PaStiX user's manual + * \sa analyzePattern() factorize() + */ + void compute (const MatrixType& matrix) + { + m_structureIsUptodate = false; + ColSpMatrix temp; + grabMatrix(matrix, temp); + Base::compute(temp); + } + /** Compute the LU symbolic factorization of \p matrix using its sparsity pattern. + * Several ordering methods can be used at this step. See the PaStiX user's manual. + * The result of this operation can be used with successive matrices having the same pattern as \p matrix + * \sa factorize() + */ + void analyzePattern(const MatrixType& matrix) + { + m_structureIsUptodate = false; + ColSpMatrix temp; + grabMatrix(matrix, temp); + Base::analyzePattern(temp); + } + + /** Compute the LU supernodal factorization of \p matrix + * WARNING The matrix \p matrix should have the same structural pattern + * as the same used in the analysis phase. + * \sa analyzePattern() + */ + void factorize(const MatrixType& matrix) + { + ColSpMatrix temp; + grabMatrix(matrix, temp); + Base::factorize(temp); + } + protected: + + void init() + { + m_structureIsUptodate = false; + m_iparm(IPARM_SYM) = API_SYM_NO; + m_iparm(IPARM_FACTORIZATION) = API_FACT_LU; + } + + void grabMatrix(const MatrixType& matrix, ColSpMatrix& out) + { + if(IsStrSym) + out = matrix; + else + { + if(!m_structureIsUptodate) + { + // update the transposed structure + m_transposedStructure = matrix.transpose(); + + // Set the elements of the matrix to zero + for (Index j=0; j + * \tparam UpLo The part of the matrix to use : Lower or Upper. The default is Lower as required by PaStiX + * + * \sa \ref TutorialSparseDirectSolvers + */ +template +class PastixLLT : public PastixBase< PastixLLT<_MatrixType, _UpLo> > +{ + public: + typedef _MatrixType MatrixType; + typedef PastixBase > Base; + typedef typename Base::ColSpMatrix ColSpMatrix; + + public: + enum { UpLo = _UpLo }; + PastixLLT() : Base() + { + init(); + } + + PastixLLT(const MatrixType& matrix):Base() + { + init(); + compute(matrix); + } + + /** Compute the L factor of the LL^T supernodal factorization of \p matrix + * \sa analyzePattern() factorize() + */ + void compute (const MatrixType& matrix) + { + ColSpMatrix temp; + grabMatrix(matrix, temp); + Base::compute(temp); + } + + /** Compute the LL^T symbolic factorization of \p matrix using its sparsity pattern + * The result of this operation can be used with successive matrices having the same pattern as \p matrix + * \sa factorize() + */ + void analyzePattern(const MatrixType& matrix) + { + ColSpMatrix temp; + grabMatrix(matrix, temp); + Base::analyzePattern(temp); + } + /** Compute the LL^T supernodal numerical factorization of \p matrix + * \sa analyzePattern() + */ + void factorize(const MatrixType& matrix) + { + ColSpMatrix temp; + grabMatrix(matrix, temp); + Base::factorize(temp); + } + protected: + using Base::m_iparm; + + void init() + { + m_iparm(IPARM_SYM) = API_SYM_YES; + m_iparm(IPARM_FACTORIZATION) = API_FACT_LLT; + } + + void grabMatrix(const MatrixType& matrix, ColSpMatrix& out) + { + // Pastix supports only lower, column-major matrices + out.template selfadjointView() = matrix.template selfadjointView(); + internal::c_to_fortran_numbering(out); + } +}; + +/** \ingroup PaStiXSupport_Module + * \class PastixLDLT + * \brief A sparse direct supernodal Cholesky (LLT) factorization and solver based on the PaStiX library + * + * This class is used to solve the linear systems A.X = B via a LDL^T supernodal Cholesky factorization + * available in the PaStiX library. The matrix A should be symmetric and positive definite + * WARNING Selfadjoint complex matrices are not supported in the current version of PaStiX + * The vectors or matrices X and B can be either dense or sparse + * + * \tparam MatrixType the type of the sparse matrix A, it must be a SparseMatrix<> + * \tparam UpLo The part of the matrix to use : Lower or Upper. The default is Lower as required by PaStiX + * + * \sa \ref TutorialSparseDirectSolvers + */ +template +class PastixLDLT : public PastixBase< PastixLDLT<_MatrixType, _UpLo> > +{ + public: + typedef _MatrixType MatrixType; + typedef PastixBase > Base; + typedef typename Base::ColSpMatrix ColSpMatrix; + + public: + enum { UpLo = _UpLo }; + PastixLDLT():Base() + { + init(); + } + + PastixLDLT(const MatrixType& matrix):Base() + { + init(); + compute(matrix); + } + + /** Compute the L and D factors of the LDL^T factorization of \p matrix + * \sa analyzePattern() factorize() + */ + void compute (const MatrixType& matrix) + { + ColSpMatrix temp; + grabMatrix(matrix, temp); + Base::compute(temp); + } + + /** Compute the LDL^T symbolic factorization of \p matrix using its sparsity pattern + * The result of this operation can be used with successive matrices having the same pattern as \p matrix + * \sa factorize() + */ + void analyzePattern(const MatrixType& matrix) + { + ColSpMatrix temp; + grabMatrix(matrix, temp); + Base::analyzePattern(temp); + } + /** Compute the LDL^T supernodal numerical factorization of \p matrix + * + */ + void factorize(const MatrixType& matrix) + { + ColSpMatrix temp; + grabMatrix(matrix, temp); + Base::factorize(temp); + } + + protected: + using Base::m_iparm; + + void init() + { + m_iparm(IPARM_SYM) = API_SYM_YES; + m_iparm(IPARM_FACTORIZATION) = API_FACT_LDLT; + } + + void grabMatrix(const MatrixType& matrix, ColSpMatrix& out) + { + // Pastix supports only lower, column-major matrices + out.template selfadjointView() = matrix.template selfadjointView(); + internal::c_to_fortran_numbering(out); + } +}; + +namespace internal { + +template +struct solve_retval, Rhs> + : solve_retval_base, Rhs> +{ + typedef PastixBase<_MatrixType> Dec; + EIGEN_MAKE_SOLVE_HELPERS(Dec,Rhs) + + template void evalTo(Dest& dst) const + { + dec()._solve(rhs(),dst); + } +}; + +template +struct sparse_solve_retval, Rhs> + : sparse_solve_retval_base, Rhs> +{ + typedef PastixBase<_MatrixType> Dec; + EIGEN_MAKE_SPARSE_SOLVE_HELPERS(Dec,Rhs) + + template void evalTo(Dest& dst) const + { + dec()._solve_sparse(rhs(),dst); + } +}; + +} // end namespace internal + +} // end namespace Eigen + +#endif diff --git a/extern/Eigen3/Eigen/src/PardisoSupport/PardisoSupport.h b/extern/Eigen3/Eigen/src/PardisoSupport/PardisoSupport.h new file mode 100644 index 00000000000..e6defc8c39e --- /dev/null +++ b/extern/Eigen3/Eigen/src/PardisoSupport/PardisoSupport.h @@ -0,0 +1,614 @@ +/* + Copyright (c) 2011, Intel Corporation. All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of Intel Corporation nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ******************************************************************************** + * Content : Eigen bindings to Intel(R) MKL PARDISO + ******************************************************************************** +*/ + +#ifndef EIGEN_PARDISOSUPPORT_H +#define EIGEN_PARDISOSUPPORT_H + +namespace Eigen { + +template class PardisoLU; +template class PardisoLLT; +template class PardisoLDLT; + +namespace internal +{ + template + struct pardiso_run_selector + { + static Index run( _MKL_DSS_HANDLE_t pt, Index maxfct, Index mnum, Index type, Index phase, Index n, void *a, + Index *ia, Index *ja, Index *perm, Index nrhs, Index *iparm, Index msglvl, void *b, void *x) + { + Index error = 0; + ::pardiso(pt, &maxfct, &mnum, &type, &phase, &n, a, ia, ja, perm, &nrhs, iparm, &msglvl, b, x, &error); + return error; + } + }; + template<> + struct pardiso_run_selector + { + typedef long long int Index; + static Index run( _MKL_DSS_HANDLE_t pt, Index maxfct, Index mnum, Index type, Index phase, Index n, void *a, + Index *ia, Index *ja, Index *perm, Index nrhs, Index *iparm, Index msglvl, void *b, void *x) + { + Index error = 0; + ::pardiso_64(pt, &maxfct, &mnum, &type, &phase, &n, a, ia, ja, perm, &nrhs, iparm, &msglvl, b, x, &error); + return error; + } + }; + + template struct pardiso_traits; + + template + struct pardiso_traits< PardisoLU<_MatrixType> > + { + typedef _MatrixType MatrixType; + typedef typename _MatrixType::Scalar Scalar; + typedef typename _MatrixType::RealScalar RealScalar; + typedef typename _MatrixType::Index Index; + }; + + template + struct pardiso_traits< PardisoLLT<_MatrixType, Options> > + { + typedef _MatrixType MatrixType; + typedef typename _MatrixType::Scalar Scalar; + typedef typename _MatrixType::RealScalar RealScalar; + typedef typename _MatrixType::Index Index; + }; + + template + struct pardiso_traits< PardisoLDLT<_MatrixType, Options> > + { + typedef _MatrixType MatrixType; + typedef typename _MatrixType::Scalar Scalar; + typedef typename _MatrixType::RealScalar RealScalar; + typedef typename _MatrixType::Index Index; + }; + +} + +template +class PardisoImpl +{ + typedef internal::pardiso_traits Traits; + public: + typedef typename Traits::MatrixType MatrixType; + typedef typename Traits::Scalar Scalar; + typedef typename Traits::RealScalar RealScalar; + typedef typename Traits::Index Index; + typedef SparseMatrix SparseMatrixType; + typedef Matrix VectorType; + typedef Matrix IntRowVectorType; + typedef Matrix IntColVectorType; + enum { + ScalarIsComplex = NumTraits::IsComplex + }; + + PardisoImpl() + { + eigen_assert((sizeof(Index) >= sizeof(_INTEGER_t) && sizeof(Index) <= 8) && "Non-supported index type"); + m_iparm.setZero(); + m_msglvl = 0; // No output + m_initialized = false; + } + + ~PardisoImpl() + { + pardisoRelease(); + } + + inline Index cols() const { return m_size; } + inline Index rows() const { return m_size; } + + /** \brief Reports whether previous computation was successful. + * + * \returns \c Success if computation was succesful, + * \c NumericalIssue if the matrix appears to be negative. + */ + ComputationInfo info() const + { + eigen_assert(m_initialized && "Decomposition is not initialized."); + return m_info; + } + + /** \warning for advanced usage only. + * \returns a reference to the parameter array controlling PARDISO. + * See the PARDISO manual to know how to use it. */ + Array& pardisoParameterArray() + { + return m_iparm; + } + + /** Performs a symbolic decomposition on the sparcity of \a matrix. + * + * This function is particularly useful when solving for several problems having the same structure. + * + * \sa factorize() + */ + Derived& analyzePattern(const MatrixType& matrix); + + /** Performs a numeric decomposition of \a matrix + * + * The given matrix must has the same sparcity than the matrix on which the symbolic decomposition has been performed. + * + * \sa analyzePattern() + */ + Derived& factorize(const MatrixType& matrix); + + Derived& compute(const MatrixType& matrix); + + /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A. + * + * \sa compute() + */ + template + inline const internal::solve_retval + solve(const MatrixBase& b) const + { + eigen_assert(m_initialized && "Pardiso solver is not initialized."); + eigen_assert(rows()==b.rows() + && "PardisoImpl::solve(): invalid number of rows of the right hand side matrix b"); + return internal::solve_retval(*this, b.derived()); + } + + /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A. + * + * \sa compute() + */ + template + inline const internal::sparse_solve_retval + solve(const SparseMatrixBase& b) const + { + eigen_assert(m_initialized && "Pardiso solver is not initialized."); + eigen_assert(rows()==b.rows() + && "PardisoImpl::solve(): invalid number of rows of the right hand side matrix b"); + return internal::sparse_solve_retval(*this, b.derived()); + } + + Derived& derived() + { + return *static_cast(this); + } + const Derived& derived() const + { + return *static_cast(this); + } + + template + bool _solve(const MatrixBase &b, MatrixBase& x) const; + + /** \internal */ + template + void _solve_sparse(const Rhs& b, SparseMatrix &dest) const + { + eigen_assert(m_size==b.rows()); + + // we process the sparse rhs per block of NbColsAtOnce columns temporarily stored into a dense matrix. + static const int NbColsAtOnce = 4; + int rhsCols = b.cols(); + int size = b.rows(); + // Pardiso cannot solve in-place, + // so we need two temporaries + Eigen::Matrix tmp_rhs(size,rhsCols); + Eigen::Matrix tmp_res(size,rhsCols); + for(int k=0; k(rhsCols-k, NbColsAtOnce); + tmp_rhs.leftCols(actualCols) = b.middleCols(k,actualCols); + tmp_res.leftCols(actualCols) = derived().solve(tmp_rhs.leftCols(actualCols)); + dest.middleCols(k,actualCols) = tmp_res.leftCols(actualCols).sparseView(); + } + } + + protected: + void pardisoRelease() + { + if(m_initialized) // Factorization ran at least once + { + internal::pardiso_run_selector::run(m_pt, 1, 1, m_type, -1, m_size, 0, 0, 0, m_perm.data(), 0, + m_iparm.data(), m_msglvl, 0, 0); + } + } + + void pardisoInit(int type) + { + m_type = type; + bool symmetric = abs(m_type) < 10; + m_iparm[0] = 1; // No solver default + m_iparm[1] = 3; // use Metis for the ordering + m_iparm[2] = 1; // Numbers of processors, value of OMP_NUM_THREADS + m_iparm[3] = 0; // No iterative-direct algorithm + m_iparm[4] = 0; // No user fill-in reducing permutation + m_iparm[5] = 0; // Write solution into x + m_iparm[6] = 0; // Not in use + m_iparm[7] = 2; // Max numbers of iterative refinement steps + m_iparm[8] = 0; // Not in use + m_iparm[9] = 13; // Perturb the pivot elements with 1E-13 + m_iparm[10] = symmetric ? 0 : 1; // Use nonsymmetric permutation and scaling MPS + m_iparm[11] = 0; // Not in use + m_iparm[12] = symmetric ? 0 : 1; // Maximum weighted matching algorithm is switched-off (default for symmetric). + // Try m_iparm[12] = 1 in case of inappropriate accuracy + m_iparm[13] = 0; // Output: Number of perturbed pivots + m_iparm[14] = 0; // Not in use + m_iparm[15] = 0; // Not in use + m_iparm[16] = 0; // Not in use + m_iparm[17] = -1; // Output: Number of nonzeros in the factor LU + m_iparm[18] = -1; // Output: Mflops for LU factorization + m_iparm[19] = 0; // Output: Numbers of CG Iterations + + m_iparm[20] = 0; // 1x1 pivoting + m_iparm[26] = 0; // No matrix checker + m_iparm[27] = (sizeof(RealScalar) == 4) ? 1 : 0; + m_iparm[34] = 1; // C indexing + m_iparm[59] = 1; // Automatic switch between In-Core and Out-of-Core modes + } + + protected: + // cached data to reduce reallocation, etc. + + void manageErrorCode(Index error) + { + switch(error) + { + case 0: + m_info = Success; + break; + case -4: + case -7: + m_info = NumericalIssue; + break; + default: + m_info = InvalidInput; + } + } + + mutable SparseMatrixType m_matrix; + ComputationInfo m_info; + bool m_initialized, m_analysisIsOk, m_factorizationIsOk; + Index m_type, m_msglvl; + mutable void *m_pt[64]; + mutable Array m_iparm; + mutable IntColVectorType m_perm; + Index m_size; + + private: + PardisoImpl(PardisoImpl &) {} +}; + +template +Derived& PardisoImpl::compute(const MatrixType& a) +{ + m_size = a.rows(); + eigen_assert(a.rows() == a.cols()); + + pardisoRelease(); + memset(m_pt, 0, sizeof(m_pt)); + m_perm.setZero(m_size); + derived().getMatrix(a); + + Index error; + error = internal::pardiso_run_selector::run(m_pt, 1, 1, m_type, 12, m_size, + m_matrix.valuePtr(), m_matrix.outerIndexPtr(), m_matrix.innerIndexPtr(), + m_perm.data(), 0, m_iparm.data(), m_msglvl, NULL, NULL); + + manageErrorCode(error); + m_analysisIsOk = true; + m_factorizationIsOk = true; + m_initialized = true; + return derived(); +} + +template +Derived& PardisoImpl::analyzePattern(const MatrixType& a) +{ + m_size = a.rows(); + eigen_assert(m_size == a.cols()); + + pardisoRelease(); + memset(m_pt, 0, sizeof(m_pt)); + m_perm.setZero(m_size); + derived().getMatrix(a); + + Index error; + error = internal::pardiso_run_selector::run(m_pt, 1, 1, m_type, 11, m_size, + m_matrix.valuePtr(), m_matrix.outerIndexPtr(), m_matrix.innerIndexPtr(), + m_perm.data(), 0, m_iparm.data(), m_msglvl, NULL, NULL); + + manageErrorCode(error); + m_analysisIsOk = true; + m_factorizationIsOk = false; + m_initialized = true; + return derived(); +} + +template +Derived& PardisoImpl::factorize(const MatrixType& a) +{ + eigen_assert(m_analysisIsOk && "You must first call analyzePattern()"); + eigen_assert(m_size == a.rows() && m_size == a.cols()); + + derived().getMatrix(a); + + Index error; + error = internal::pardiso_run_selector::run(m_pt, 1, 1, m_type, 22, m_size, + m_matrix.valuePtr(), m_matrix.outerIndexPtr(), m_matrix.innerIndexPtr(), + m_perm.data(), 0, m_iparm.data(), m_msglvl, NULL, NULL); + + manageErrorCode(error); + m_factorizationIsOk = true; + return derived(); +} + +template +template +bool PardisoImpl::_solve(const MatrixBase &b, MatrixBase& x) const +{ + if(m_iparm[0] == 0) // Factorization was not computed + return false; + + //Index n = m_matrix.rows(); + Index nrhs = Index(b.cols()); + eigen_assert(m_size==b.rows()); + eigen_assert(((MatrixBase::Flags & RowMajorBit) == 0 || nrhs == 1) && "Row-major right hand sides are not supported"); + eigen_assert(((MatrixBase::Flags & RowMajorBit) == 0 || nrhs == 1) && "Row-major matrices of unknowns are not supported"); + eigen_assert(((nrhs == 1) || b.outerStride() == b.rows())); + + +// switch (transposed) { +// case SvNoTrans : m_iparm[11] = 0 ; break; +// case SvTranspose : m_iparm[11] = 2 ; break; +// case SvAdjoint : m_iparm[11] = 1 ; break; +// default: +// //std::cerr << "Eigen: transposition option \"" << transposed << "\" not supported by the PARDISO backend\n"; +// m_iparm[11] = 0; +// } + + Scalar* rhs_ptr = const_cast(b.derived().data()); + Matrix tmp; + + // Pardiso cannot solve in-place + if(rhs_ptr == x.derived().data()) + { + tmp = b; + rhs_ptr = tmp.data(); + } + + Index error; + error = internal::pardiso_run_selector::run(m_pt, 1, 1, m_type, 33, m_size, + m_matrix.valuePtr(), m_matrix.outerIndexPtr(), m_matrix.innerIndexPtr(), + m_perm.data(), nrhs, m_iparm.data(), m_msglvl, + rhs_ptr, x.derived().data()); + + return error==0; +} + + +/** \ingroup PardisoSupport_Module + * \class PardisoLU + * \brief A sparse direct LU factorization and solver based on the PARDISO library + * + * This class allows to solve for A.X = B sparse linear problems via a direct LU factorization + * using the Intel MKL PARDISO library. The sparse matrix A must be squared and invertible. + * The vectors or matrices X and B can be either dense or sparse. + * + * \tparam _MatrixType the type of the sparse matrix A, it must be a SparseMatrix<> + * + * \sa \ref TutorialSparseDirectSolvers + */ +template +class PardisoLU : public PardisoImpl< PardisoLU > +{ + protected: + typedef PardisoImpl< PardisoLU > Base; + typedef typename Base::Scalar Scalar; + typedef typename Base::RealScalar RealScalar; + using Base::pardisoInit; + using Base::m_matrix; + friend class PardisoImpl< PardisoLU >; + + public: + + using Base::compute; + using Base::solve; + + PardisoLU() + : Base() + { + pardisoInit(Base::ScalarIsComplex ? 13 : 11); + } + + PardisoLU(const MatrixType& matrix) + : Base() + { + pardisoInit(Base::ScalarIsComplex ? 13 : 11); + compute(matrix); + } + protected: + void getMatrix(const MatrixType& matrix) + { + m_matrix = matrix; + } + + private: + PardisoLU(PardisoLU& ) {} +}; + +/** \ingroup PardisoSupport_Module + * \class PardisoLLT + * \brief A sparse direct Cholesky (LLT) factorization and solver based on the PARDISO library + * + * This class allows to solve for A.X = B sparse linear problems via a LL^T Cholesky factorization + * using the Intel MKL PARDISO library. The sparse matrix A must be selfajoint and positive definite. + * The vectors or matrices X and B can be either dense or sparse. + * + * \tparam MatrixType the type of the sparse matrix A, it must be a SparseMatrix<> + * \tparam UpLo can be any bitwise combination of Upper, Lower. The default is Upper, meaning only the upper triangular part has to be used. + * Upper|Lower can be used to tell both triangular parts can be used as input. + * + * \sa \ref TutorialSparseDirectSolvers + */ +template +class PardisoLLT : public PardisoImpl< PardisoLLT > +{ + protected: + typedef PardisoImpl< PardisoLLT > Base; + typedef typename Base::Scalar Scalar; + typedef typename Base::Index Index; + typedef typename Base::RealScalar RealScalar; + using Base::pardisoInit; + using Base::m_matrix; + friend class PardisoImpl< PardisoLLT >; + + public: + + enum { UpLo = _UpLo }; + using Base::compute; + using Base::solve; + + PardisoLLT() + : Base() + { + pardisoInit(Base::ScalarIsComplex ? 4 : 2); + } + + PardisoLLT(const MatrixType& matrix) + : Base() + { + pardisoInit(Base::ScalarIsComplex ? 4 : 2); + compute(matrix); + } + + protected: + + void getMatrix(const MatrixType& matrix) + { + // PARDISO supports only upper, row-major matrices + PermutationMatrix p_null; + m_matrix.resize(matrix.rows(), matrix.cols()); + m_matrix.template selfadjointView() = matrix.template selfadjointView().twistedBy(p_null); + } + + private: + PardisoLLT(PardisoLLT& ) {} +}; + +/** \ingroup PardisoSupport_Module + * \class PardisoLDLT + * \brief A sparse direct Cholesky (LDLT) factorization and solver based on the PARDISO library + * + * This class allows to solve for A.X = B sparse linear problems via a LDL^T Cholesky factorization + * using the Intel MKL PARDISO library. The sparse matrix A is assumed to be selfajoint and positive definite. + * For complex matrices, A can also be symmetric only, see the \a Options template parameter. + * The vectors or matrices X and B can be either dense or sparse. + * + * \tparam MatrixType the type of the sparse matrix A, it must be a SparseMatrix<> + * \tparam Options can be any bitwise combination of Upper, Lower, and Symmetric. The default is Upper, meaning only the upper triangular part has to be used. + * Symmetric can be used for symmetric, non-selfadjoint complex matrices, the default being to assume a selfadjoint matrix. + * Upper|Lower can be used to tell both triangular parts can be used as input. + * + * \sa \ref TutorialSparseDirectSolvers + */ +template +class PardisoLDLT : public PardisoImpl< PardisoLDLT > +{ + protected: + typedef PardisoImpl< PardisoLDLT > Base; + typedef typename Base::Scalar Scalar; + typedef typename Base::Index Index; + typedef typename Base::RealScalar RealScalar; + using Base::pardisoInit; + using Base::m_matrix; + friend class PardisoImpl< PardisoLDLT >; + + public: + + using Base::compute; + using Base::solve; + enum { UpLo = Options&(Upper|Lower) }; + + PardisoLDLT() + : Base() + { + pardisoInit(Base::ScalarIsComplex ? ( bool(Options&Symmetric) ? 6 : -4 ) : -2); + } + + PardisoLDLT(const MatrixType& matrix) + : Base() + { + pardisoInit(Base::ScalarIsComplex ? ( bool(Options&Symmetric) ? 6 : -4 ) : -2); + compute(matrix); + } + + void getMatrix(const MatrixType& matrix) + { + // PARDISO supports only upper, row-major matrices + PermutationMatrix p_null; + m_matrix.resize(matrix.rows(), matrix.cols()); + m_matrix.template selfadjointView() = matrix.template selfadjointView().twistedBy(p_null); + } + + private: + PardisoLDLT(PardisoLDLT& ) {} +}; + +namespace internal { + +template +struct solve_retval, Rhs> + : solve_retval_base, Rhs> +{ + typedef PardisoImpl<_Derived> Dec; + EIGEN_MAKE_SOLVE_HELPERS(Dec,Rhs) + + template void evalTo(Dest& dst) const + { + dec()._solve(rhs(),dst); + } +}; + +template +struct sparse_solve_retval, Rhs> + : sparse_solve_retval_base, Rhs> +{ + typedef PardisoImpl Dec; + EIGEN_MAKE_SPARSE_SOLVE_HELPERS(Dec,Rhs) + + template void evalTo(Dest& dst) const + { + dec().derived()._solve_sparse(rhs(),dst); + } +}; + +} // end namespace internal + +} // end namespace Eigen + +#endif // EIGEN_PARDISOSUPPORT_H diff --git a/extern/Eigen3/Eigen/src/QR/ColPivHouseholderQR.h b/extern/Eigen3/Eigen/src/QR/ColPivHouseholderQR.h index f04c6038d6a..2daa23cc354 100644 --- a/extern/Eigen3/Eigen/src/QR/ColPivHouseholderQR.h +++ b/extern/Eigen3/Eigen/src/QR/ColPivHouseholderQR.h @@ -4,28 +4,15 @@ // Copyright (C) 2008-2009 Gael Guennebaud // Copyright (C) 2009 Benoit Jacob // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_COLPIVOTINGHOUSEHOLDERQR_H #define EIGEN_COLPIVOTINGHOUSEHOLDERQR_H +namespace Eigen { + /** \ingroup QR_Module * * \class ColPivHouseholderQR @@ -528,5 +515,6 @@ MatrixBase::colPivHouseholderQr() const return ColPivHouseholderQR(eval()); } +} // end namespace Eigen #endif // EIGEN_COLPIVOTINGHOUSEHOLDERQR_H diff --git a/extern/Eigen3/Eigen/src/QR/ColPivHouseholderQR_MKL.h b/extern/Eigen3/Eigen/src/QR/ColPivHouseholderQR_MKL.h new file mode 100644 index 00000000000..745ecf8be98 --- /dev/null +++ b/extern/Eigen3/Eigen/src/QR/ColPivHouseholderQR_MKL.h @@ -0,0 +1,98 @@ +/* + Copyright (c) 2011, Intel Corporation. All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of Intel Corporation nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ******************************************************************************** + * Content : Eigen bindings to Intel(R) MKL + * Householder QR decomposition of a matrix with column pivoting based on + * LAPACKE_?geqp3 function. + ******************************************************************************** +*/ + +#ifndef EIGEN_COLPIVOTINGHOUSEHOLDERQR_MKL_H +#define EIGEN_COLPIVOTINGHOUSEHOLDERQR_MKL_H + +#include "Eigen/src/Core/util/MKL_support.h" + +namespace Eigen { + +/** \internal Specialization for the data types supported by MKL */ + +#define EIGEN_MKL_QR_COLPIV(EIGTYPE, MKLTYPE, MKLPREFIX, EIGCOLROW, MKLCOLROW) \ +template<> inline\ +ColPivHouseholderQR >& \ +ColPivHouseholderQR >::compute( \ + const Matrix& matrix) \ +\ +{ \ + typedef Matrix MatrixType; \ + typedef MatrixType::Scalar Scalar; \ + typedef MatrixType::RealScalar RealScalar; \ + Index rows = matrix.rows();\ + Index cols = matrix.cols();\ + Index size = matrix.diagonalSize();\ +\ + m_qr = matrix;\ + m_hCoeffs.resize(size);\ +\ + m_colsTranspositions.resize(cols);\ + /*Index number_of_transpositions = 0;*/ \ +\ + m_nonzero_pivots = 0; \ + m_maxpivot = RealScalar(0);\ + m_colsPermutation.resize(cols); \ + m_colsPermutation.indices().setZero(); \ +\ + lapack_int lda = m_qr.outerStride(), i; \ + lapack_int matrix_order = MKLCOLROW; \ + LAPACKE_##MKLPREFIX##geqp3( matrix_order, rows, cols, (MKLTYPE*)m_qr.data(), lda, (lapack_int*)m_colsPermutation.indices().data(), (MKLTYPE*)m_hCoeffs.data()); \ + m_isInitialized = true; \ + m_maxpivot=m_qr.diagonal().cwiseAbs().maxCoeff(); \ + m_hCoeffs.adjointInPlace(); \ + RealScalar premultiplied_threshold = internal::abs(m_maxpivot) * threshold(); \ + lapack_int *perm = m_colsPermutation.indices().data(); \ + for(i=0;i premultiplied_threshold);\ + } \ + for(i=0;i // Copyright (C) 2009 Benoit Jacob // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_FULLPIVOTINGHOUSEHOLDERQR_H #define EIGEN_FULLPIVOTINGHOUSEHOLDERQR_H +namespace Eigen { + +namespace internal { + +template struct FullPivHouseholderQRMatrixQReturnType; + +template +struct traits > +{ + typedef typename MatrixType::PlainObject ReturnType; +}; + +} + /** \ingroup QR_Module * * \class FullPivHouseholderQR @@ -62,7 +61,7 @@ template class FullPivHouseholderQR typedef typename MatrixType::Scalar Scalar; typedef typename MatrixType::RealScalar RealScalar; typedef typename MatrixType::Index Index; - typedef Matrix MatrixQType; + typedef internal::FullPivHouseholderQRMatrixQReturnType MatrixQReturnType; typedef typename internal::plain_diag_type::type HCoeffsType; typedef Matrix IntRowVectorType; typedef PermutationMatrix PermutationType; @@ -139,7 +138,9 @@ template class FullPivHouseholderQR return internal::solve_retval(*this, b.derived()); } - MatrixQType matrixQ(void) const; + /** \returns Expression object representing the matrix Q + */ + MatrixQReturnType matrixQ(void) const; /** \returns a reference to the matrix where the Householder QR decomposition is stored */ @@ -508,28 +509,73 @@ struct solve_retval, Rhs> } }; +/** \ingroup QR_Module + * + * \brief Expression type for return value of FullPivHouseholderQR::matrixQ() + * + * \tparam MatrixType type of underlying dense matrix + */ +template struct FullPivHouseholderQRMatrixQReturnType + : public ReturnByValue > +{ +public: + typedef typename MatrixType::Index Index; + typedef typename internal::plain_col_type::type IntColVectorType; + typedef typename internal::plain_diag_type::type HCoeffsType; + typedef Matrix WorkVectorType; + + FullPivHouseholderQRMatrixQReturnType(const MatrixType& qr, + const HCoeffsType& hCoeffs, + const IntColVectorType& rowsTranspositions) + : m_qr(qr), + m_hCoeffs(hCoeffs), + m_rowsTranspositions(rowsTranspositions) + {} + + template + void evalTo(ResultType& result) const + { + const Index rows = m_qr.rows(); + WorkVectorType workspace(rows); + evalTo(result, workspace); + } + + template + void evalTo(ResultType& result, WorkVectorType& workspace) const + { + // compute the product H'_0 H'_1 ... H'_n-1, + // where H_k is the k-th Householder transformation I - h_k v_k v_k' + // and v_k is the k-th Householder vector [1,m_qr(k+1,k), m_qr(k+2,k), ...] + const Index rows = m_qr.rows(); + const Index cols = m_qr.cols(); + const Index size = (std::min)(rows, cols); + workspace.resize(rows); + result.setIdentity(rows, rows); + for (Index k = size-1; k >= 0; k--) + { + result.block(k, k, rows-k, rows-k) + .applyHouseholderOnTheLeft(m_qr.col(k).tail(rows-k-1), internal::conj(m_hCoeffs.coeff(k)), &workspace.coeffRef(k)); + result.row(k).swap(result.row(m_rowsTranspositions.coeff(k))); + } + } + + Index rows() const { return m_qr.rows(); } + Index cols() const { return m_qr.rows(); } + +protected: + typename MatrixType::Nested m_qr; + typename HCoeffsType::Nested m_hCoeffs; + typename IntColVectorType::Nested m_rowsTranspositions; +}; + } // end namespace internal -/** \returns the matrix Q */ template -typename FullPivHouseholderQR::MatrixQType FullPivHouseholderQR::matrixQ() const +inline typename FullPivHouseholderQR::MatrixQReturnType FullPivHouseholderQR::matrixQ() const { eigen_assert(m_isInitialized && "FullPivHouseholderQR is not initialized."); - // compute the product H'_0 H'_1 ... H'_n-1, - // where H_k is the k-th Householder transformation I - h_k v_k v_k' - // and v_k is the k-th Householder vector [1,m_qr(k+1,k), m_qr(k+2,k), ...] - Index rows = m_qr.rows(); - Index cols = m_qr.cols(); - Index size = (std::min)(rows,cols); - MatrixQType res = MatrixQType::Identity(rows, rows); - Matrix temp(rows); - for (Index k = size-1; k >= 0; k--) - { - res.block(k, k, rows-k, rows-k) - .applyHouseholderOnTheLeft(m_qr.col(k).tail(rows-k-1), internal::conj(m_hCoeffs.coeff(k)), &temp.coeffRef(k)); - res.row(k).swap(res.row(m_rows_transpositions.coeff(k))); - } - return res; + return MatrixQReturnType(m_qr, m_hCoeffs, m_rows_transpositions); } /** \return the full-pivoting Householder QR decomposition of \c *this. @@ -543,4 +589,6 @@ MatrixBase::fullPivHouseholderQr() const return FullPivHouseholderQR(eval()); } +} // end namespace Eigen + #endif // EIGEN_FULLPIVOTINGHOUSEHOLDERQR_H diff --git a/extern/Eigen3/Eigen/src/QR/HouseholderQR.h b/extern/Eigen3/Eigen/src/QR/HouseholderQR.h index 9ee96de2680..5bcb32c1e18 100644 --- a/extern/Eigen3/Eigen/src/QR/HouseholderQR.h +++ b/extern/Eigen3/Eigen/src/QR/HouseholderQR.h @@ -5,28 +5,15 @@ // Copyright (C) 2009 Benoit Jacob // Copyright (C) 2010 Vincent Lejeune // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_QR_H #define EIGEN_QR_H +namespace Eigen { + /** \ingroup QR_Module * * @@ -351,5 +338,6 @@ MatrixBase::householderQr() const return HouseholderQR(eval()); } +} // end namespace Eigen #endif // EIGEN_QR_H diff --git a/extern/Eigen3/Eigen/src/QR/HouseholderQR_MKL.h b/extern/Eigen3/Eigen/src/QR/HouseholderQR_MKL.h new file mode 100644 index 00000000000..5313de604d2 --- /dev/null +++ b/extern/Eigen3/Eigen/src/QR/HouseholderQR_MKL.h @@ -0,0 +1,69 @@ +/* + Copyright (c) 2011, Intel Corporation. All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of Intel Corporation nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ******************************************************************************** + * Content : Eigen bindings to Intel(R) MKL + * Householder QR decomposition of a matrix w/o pivoting based on + * LAPACKE_?geqrf function. + ******************************************************************************** +*/ + +#ifndef EIGEN_QR_MKL_H +#define EIGEN_QR_MKL_H + +#include "Eigen/src/Core/util/MKL_support.h" + +namespace Eigen { + +namespace internal { + +/** \internal Specialization for the data types supported by MKL */ + +#define EIGEN_MKL_QR_NOPIV(EIGTYPE, MKLTYPE, MKLPREFIX) \ +template \ +void householder_qr_inplace_blocked(MatrixQR& mat, HCoeffs& hCoeffs, \ + typename MatrixQR::Index maxBlockSize=32, \ + EIGTYPE* tempData = 0) \ +{ \ + lapack_int m = mat.rows(); \ + lapack_int n = mat.cols(); \ + lapack_int lda = mat.outerStride(); \ + lapack_int matrix_order = (MatrixQR::IsRowMajor) ? LAPACK_ROW_MAJOR : LAPACK_COL_MAJOR; \ + LAPACKE_##MKLPREFIX##geqrf( matrix_order, m, n, (MKLTYPE*)mat.data(), lda, (MKLTYPE*)hCoeffs.data()); \ + hCoeffs.adjointInPlace(); \ +\ +} + +EIGEN_MKL_QR_NOPIV(double, double, d) +EIGEN_MKL_QR_NOPIV(float, float, s) +EIGEN_MKL_QR_NOPIV(dcomplex, MKL_Complex16, z) +EIGEN_MKL_QR_NOPIV(scomplex, MKL_Complex8, c) + +} // end namespace internal + +} // end namespace Eigen + +#endif // EIGEN_QR_MKL_H diff --git a/extern/Eigen3/Eigen/src/SVD/JacobiSVD.h b/extern/Eigen3/Eigen/src/SVD/JacobiSVD.h index 3c423095c31..a7dbf073766 100644 --- a/extern/Eigen3/Eigen/src/SVD/JacobiSVD.h +++ b/extern/Eigen3/Eigen/src/SVD/JacobiSVD.h @@ -3,28 +3,15 @@ // // Copyright (C) 2009-2010 Benoit Jacob // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_JACOBISVD_H #define EIGEN_JACOBISVD_H +namespace Eigen { + namespace internal { // forward declaration (needed by ICC) // the empty body is required by MSVC @@ -61,9 +48,12 @@ template struct qr_preconditioner_impl {}; template -struct qr_preconditioner_impl +class qr_preconditioner_impl { - static bool run(JacobiSVD&, const MatrixType&) +public: + typedef typename MatrixType::Index Index; + void allocate(const JacobiSVD&) {} + bool run(JacobiSVD&, const MatrixType&) { return false; } @@ -72,134 +62,279 @@ struct qr_preconditioner_impl /*** preconditioner using FullPivHouseholderQR ***/ template -struct qr_preconditioner_impl +class qr_preconditioner_impl { - static bool run(JacobiSVD& svd, const MatrixType& matrix) +public: + typedef typename MatrixType::Index Index; + typedef typename MatrixType::Scalar Scalar; + enum + { + RowsAtCompileTime = MatrixType::RowsAtCompileTime, + MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime + }; + typedef Matrix WorkspaceType; + + void allocate(const JacobiSVD& svd) + { + if (svd.rows() != m_qr.rows() || svd.cols() != m_qr.cols()) + { + m_qr = FullPivHouseholderQR(svd.rows(), svd.cols()); + } + if (svd.m_computeFullU) m_workspace.resize(svd.rows()); + } + + bool run(JacobiSVD& svd, const MatrixType& matrix) { if(matrix.rows() > matrix.cols()) { - FullPivHouseholderQR qr(matrix); - svd.m_workMatrix = qr.matrixQR().block(0,0,matrix.cols(),matrix.cols()).template triangularView(); - if(svd.m_computeFullU) svd.m_matrixU = qr.matrixQ(); - if(svd.computeV()) svd.m_matrixV = qr.colsPermutation(); + m_qr.compute(matrix); + svd.m_workMatrix = m_qr.matrixQR().block(0,0,matrix.cols(),matrix.cols()).template triangularView(); + if(svd.m_computeFullU) m_qr.matrixQ().evalTo(svd.m_matrixU, m_workspace); + if(svd.computeV()) svd.m_matrixV = m_qr.colsPermutation(); return true; } return false; } +private: + FullPivHouseholderQR m_qr; + WorkspaceType m_workspace; }; template -struct qr_preconditioner_impl +class qr_preconditioner_impl { - static bool run(JacobiSVD& svd, const MatrixType& matrix) +public: + typedef typename MatrixType::Index Index; + typedef typename MatrixType::Scalar Scalar; + enum + { + RowsAtCompileTime = MatrixType::RowsAtCompileTime, + ColsAtCompileTime = MatrixType::ColsAtCompileTime, + MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime, + MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime, + Options = MatrixType::Options + }; + typedef Matrix + TransposeTypeWithSameStorageOrder; + + void allocate(const JacobiSVD& svd) + { + if (svd.cols() != m_qr.rows() || svd.rows() != m_qr.cols()) + { + m_qr = FullPivHouseholderQR(svd.cols(), svd.rows()); + } + m_adjoint.resize(svd.cols(), svd.rows()); + if (svd.m_computeFullV) m_workspace.resize(svd.cols()); + } + + bool run(JacobiSVD& svd, const MatrixType& matrix) { if(matrix.cols() > matrix.rows()) { - typedef Matrix - TransposeTypeWithSameStorageOrder; - FullPivHouseholderQR qr(matrix.adjoint()); - svd.m_workMatrix = qr.matrixQR().block(0,0,matrix.rows(),matrix.rows()).template triangularView().adjoint(); - if(svd.m_computeFullV) svd.m_matrixV = qr.matrixQ(); - if(svd.computeU()) svd.m_matrixU = qr.colsPermutation(); + m_adjoint = matrix.adjoint(); + m_qr.compute(m_adjoint); + svd.m_workMatrix = m_qr.matrixQR().block(0,0,matrix.rows(),matrix.rows()).template triangularView().adjoint(); + if(svd.m_computeFullV) m_qr.matrixQ().evalTo(svd.m_matrixV, m_workspace); + if(svd.computeU()) svd.m_matrixU = m_qr.colsPermutation(); return true; } else return false; } +private: + FullPivHouseholderQR m_qr; + TransposeTypeWithSameStorageOrder m_adjoint; + typename internal::plain_row_type::type m_workspace; }; /*** preconditioner using ColPivHouseholderQR ***/ template -struct qr_preconditioner_impl +class qr_preconditioner_impl { - static bool run(JacobiSVD& svd, const MatrixType& matrix) +public: + typedef typename MatrixType::Index Index; + + void allocate(const JacobiSVD& svd) + { + if (svd.rows() != m_qr.rows() || svd.cols() != m_qr.cols()) + { + m_qr = ColPivHouseholderQR(svd.rows(), svd.cols()); + } + if (svd.m_computeFullU) m_workspace.resize(svd.rows()); + else if (svd.m_computeThinU) m_workspace.resize(svd.cols()); + } + + bool run(JacobiSVD& svd, const MatrixType& matrix) { if(matrix.rows() > matrix.cols()) { - ColPivHouseholderQR qr(matrix); - svd.m_workMatrix = qr.matrixQR().block(0,0,matrix.cols(),matrix.cols()).template triangularView(); - if(svd.m_computeFullU) svd.m_matrixU = qr.householderQ(); - else if(svd.m_computeThinU) { + m_qr.compute(matrix); + svd.m_workMatrix = m_qr.matrixQR().block(0,0,matrix.cols(),matrix.cols()).template triangularView(); + if(svd.m_computeFullU) m_qr.householderQ().evalTo(svd.m_matrixU, m_workspace); + else if(svd.m_computeThinU) + { svd.m_matrixU.setIdentity(matrix.rows(), matrix.cols()); - qr.householderQ().applyThisOnTheLeft(svd.m_matrixU); + m_qr.householderQ().applyThisOnTheLeft(svd.m_matrixU, m_workspace); } - if(svd.computeV()) svd.m_matrixV = qr.colsPermutation(); + if(svd.computeV()) svd.m_matrixV = m_qr.colsPermutation(); return true; } return false; } + +private: + ColPivHouseholderQR m_qr; + typename internal::plain_col_type::type m_workspace; }; template -struct qr_preconditioner_impl +class qr_preconditioner_impl { - static bool run(JacobiSVD& svd, const MatrixType& matrix) +public: + typedef typename MatrixType::Index Index; + typedef typename MatrixType::Scalar Scalar; + enum + { + RowsAtCompileTime = MatrixType::RowsAtCompileTime, + ColsAtCompileTime = MatrixType::ColsAtCompileTime, + MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime, + MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime, + Options = MatrixType::Options + }; + + typedef Matrix + TransposeTypeWithSameStorageOrder; + + void allocate(const JacobiSVD& svd) + { + if (svd.cols() != m_qr.rows() || svd.rows() != m_qr.cols()) + { + m_qr = ColPivHouseholderQR(svd.cols(), svd.rows()); + } + if (svd.m_computeFullV) m_workspace.resize(svd.cols()); + else if (svd.m_computeThinV) m_workspace.resize(svd.rows()); + m_adjoint.resize(svd.cols(), svd.rows()); + } + + bool run(JacobiSVD& svd, const MatrixType& matrix) { if(matrix.cols() > matrix.rows()) { - typedef Matrix - TransposeTypeWithSameStorageOrder; - ColPivHouseholderQR qr(matrix.adjoint()); - svd.m_workMatrix = qr.matrixQR().block(0,0,matrix.rows(),matrix.rows()).template triangularView().adjoint(); - if(svd.m_computeFullV) svd.m_matrixV = qr.householderQ(); - else if(svd.m_computeThinV) { + m_adjoint = matrix.adjoint(); + m_qr.compute(m_adjoint); + + svd.m_workMatrix = m_qr.matrixQR().block(0,0,matrix.rows(),matrix.rows()).template triangularView().adjoint(); + if(svd.m_computeFullV) m_qr.householderQ().evalTo(svd.m_matrixV, m_workspace); + else if(svd.m_computeThinV) + { svd.m_matrixV.setIdentity(matrix.cols(), matrix.rows()); - qr.householderQ().applyThisOnTheLeft(svd.m_matrixV); + m_qr.householderQ().applyThisOnTheLeft(svd.m_matrixV, m_workspace); } - if(svd.computeU()) svd.m_matrixU = qr.colsPermutation(); + if(svd.computeU()) svd.m_matrixU = m_qr.colsPermutation(); return true; } else return false; } + +private: + ColPivHouseholderQR m_qr; + TransposeTypeWithSameStorageOrder m_adjoint; + typename internal::plain_row_type::type m_workspace; }; /*** preconditioner using HouseholderQR ***/ template -struct qr_preconditioner_impl +class qr_preconditioner_impl { - static bool run(JacobiSVD& svd, const MatrixType& matrix) +public: + typedef typename MatrixType::Index Index; + + void allocate(const JacobiSVD& svd) + { + if (svd.rows() != m_qr.rows() || svd.cols() != m_qr.cols()) + { + m_qr = HouseholderQR(svd.rows(), svd.cols()); + } + if (svd.m_computeFullU) m_workspace.resize(svd.rows()); + else if (svd.m_computeThinU) m_workspace.resize(svd.cols()); + } + + bool run(JacobiSVD& svd, const MatrixType& matrix) { if(matrix.rows() > matrix.cols()) { - HouseholderQR qr(matrix); - svd.m_workMatrix = qr.matrixQR().block(0,0,matrix.cols(),matrix.cols()).template triangularView(); - if(svd.m_computeFullU) svd.m_matrixU = qr.householderQ(); - else if(svd.m_computeThinU) { + m_qr.compute(matrix); + svd.m_workMatrix = m_qr.matrixQR().block(0,0,matrix.cols(),matrix.cols()).template triangularView(); + if(svd.m_computeFullU) m_qr.householderQ().evalTo(svd.m_matrixU, m_workspace); + else if(svd.m_computeThinU) + { svd.m_matrixU.setIdentity(matrix.rows(), matrix.cols()); - qr.householderQ().applyThisOnTheLeft(svd.m_matrixU); + m_qr.householderQ().applyThisOnTheLeft(svd.m_matrixU, m_workspace); } if(svd.computeV()) svd.m_matrixV.setIdentity(matrix.cols(), matrix.cols()); return true; } return false; } +private: + HouseholderQR m_qr; + typename internal::plain_col_type::type m_workspace; }; template -struct qr_preconditioner_impl +class qr_preconditioner_impl { - static bool run(JacobiSVD& svd, const MatrixType& matrix) +public: + typedef typename MatrixType::Index Index; + typedef typename MatrixType::Scalar Scalar; + enum + { + RowsAtCompileTime = MatrixType::RowsAtCompileTime, + ColsAtCompileTime = MatrixType::ColsAtCompileTime, + MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime, + MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime, + Options = MatrixType::Options + }; + + typedef Matrix + TransposeTypeWithSameStorageOrder; + + void allocate(const JacobiSVD& svd) + { + if (svd.cols() != m_qr.rows() || svd.rows() != m_qr.cols()) + { + m_qr = HouseholderQR(svd.cols(), svd.rows()); + } + if (svd.m_computeFullV) m_workspace.resize(svd.cols()); + else if (svd.m_computeThinV) m_workspace.resize(svd.rows()); + m_adjoint.resize(svd.cols(), svd.rows()); + } + + bool run(JacobiSVD& svd, const MatrixType& matrix) { if(matrix.cols() > matrix.rows()) { - typedef Matrix - TransposeTypeWithSameStorageOrder; - HouseholderQR qr(matrix.adjoint()); - svd.m_workMatrix = qr.matrixQR().block(0,0,matrix.rows(),matrix.rows()).template triangularView().adjoint(); - if(svd.m_computeFullV) svd.m_matrixV = qr.householderQ(); - else if(svd.m_computeThinV) { + m_adjoint = matrix.adjoint(); + m_qr.compute(m_adjoint); + + svd.m_workMatrix = m_qr.matrixQR().block(0,0,matrix.rows(),matrix.rows()).template triangularView().adjoint(); + if(svd.m_computeFullV) m_qr.householderQ().evalTo(svd.m_matrixV, m_workspace); + else if(svd.m_computeThinV) + { svd.m_matrixV.setIdentity(matrix.cols(), matrix.rows()); - qr.householderQ().applyThisOnTheLeft(svd.m_matrixV); + m_qr.householderQ().applyThisOnTheLeft(svd.m_matrixV, m_workspace); } if(svd.computeU()) svd.m_matrixU.setIdentity(matrix.rows(), matrix.rows()); return true; } else return false; } + +private: + HouseholderQR m_qr; + TransposeTypeWithSameStorageOrder m_adjoint; + typename internal::plain_row_type::type m_workspace; }; /*** 2x2 SVD implementation @@ -316,7 +451,7 @@ void real_2x2_jacobi_svd(const MatrixType& matrix, Index p, Index q, * Here's an example demonstrating basic usage: * \include JacobiSVD_basic.cpp * Output: \verbinclude JacobiSVD_basic.out - * + * * This JacobiSVD class is a two-sided Jacobi R-SVD decomposition, ensuring optimal reliability and accuracy. The downside is that it's slower than * bidiagonalizing SVD algorithms for large square matrices; however its complexity is still \f$ O(n^2p) \f$ where \a n is the smaller dimension and * \a p is the greater dimension, meaning that it is still of the same order of complexity as the faster bidiagonalizing R-SVD algorithms. @@ -324,7 +459,7 @@ void real_2x2_jacobi_svd(const MatrixType& matrix, Index p, Index q, * * If the input matrix has inf or nan coefficients, the result of the computation is undefined, but the computation is guaranteed to * terminate in finite (and reasonable) time. - * + * * The possible values for QRPreconditioner are: * \li ColPivHouseholderQRPreconditioner is the default. In practice it's very safe. It uses column-pivoting QR. * \li FullPivHouseholderQRPreconditioner, is the safest and slowest. It uses full-pivoting QR. @@ -494,7 +629,7 @@ template class JacobiSVD * \param b the right-hand-side of the equation to solve. * * \note Solving requires both U and V to be computed. Thin U and V are enough, there is no need for full U or V. - * + * * \note SVD solving is implicitly least-squares. Thus, this method serves both purposes of exact solving and least-squares solving. * In other words, the returned solution is guaranteed to minimize the Euclidean norm \f$ \Vert A x - b \Vert \f$. */ @@ -535,6 +670,9 @@ template class JacobiSVD friend struct internal::svd_precondition_2x2_block_to_be_real; template friend struct internal::qr_preconditioner_impl; + + internal::qr_preconditioner_impl m_qr_precond_morecols; + internal::qr_preconditioner_impl m_qr_precond_morerows; }; template @@ -578,6 +716,9 @@ void JacobiSVD::allocate(Index rows, Index cols, u : m_computeThinV ? m_diagSize : 0); m_workMatrix.resize(m_diagSize, m_diagSize); + + if(m_cols>m_rows) m_qr_precond_morecols.allocate(*this); + if(m_rows>m_cols) m_qr_precond_morerows.allocate(*this); } template @@ -595,8 +736,7 @@ JacobiSVD::compute(const MatrixType& matrix, unsig /*** step 1. The R-SVD step: we use a QR decomposition to reduce to the case of a square matrix */ - if(!internal::qr_preconditioner_impl::run(*this, matrix) - && !internal::qr_preconditioner_impl::run(*this, matrix)) + if(!m_qr_precond_morecols.run(*this, matrix) && !m_qr_precond_morerows.run(*this, matrix)) { m_workMatrix = matrix.block(0,0,m_diagSize,m_diagSize); if(m_computeFullU) m_matrixU.setIdentity(m_rows,m_rows); @@ -722,6 +862,6 @@ MatrixBase::jacobiSvd(unsigned int computationOptions) const return JacobiSVD(*this, computationOptions); } - +} // end namespace Eigen #endif // EIGEN_JACOBISVD_H diff --git a/extern/Eigen3/Eigen/src/SVD/JacobiSVD_MKL.h b/extern/Eigen3/Eigen/src/SVD/JacobiSVD_MKL.h new file mode 100644 index 00000000000..4d479f6b26e --- /dev/null +++ b/extern/Eigen3/Eigen/src/SVD/JacobiSVD_MKL.h @@ -0,0 +1,92 @@ +/* + Copyright (c) 2011, Intel Corporation. All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of Intel Corporation nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ******************************************************************************** + * Content : Eigen bindings to Intel(R) MKL + * Singular Value Decomposition - SVD. + ******************************************************************************** +*/ + +#ifndef EIGEN_JACOBISVD_MKL_H +#define EIGEN_JACOBISVD_MKL_H + +#include "Eigen/src/Core/util/MKL_support.h" + +namespace Eigen { + +/** \internal Specialization for the data types supported by MKL */ + +#define EIGEN_MKL_SVD(EIGTYPE, MKLTYPE, MKLRTYPE, MKLPREFIX, EIGCOLROW, MKLCOLROW) \ +template<> inline\ +JacobiSVD, ColPivHouseholderQRPreconditioner>& \ +JacobiSVD, ColPivHouseholderQRPreconditioner>::compute(const Matrix& matrix, unsigned int computationOptions) \ +{ \ + typedef Matrix MatrixType; \ + typedef MatrixType::Scalar Scalar; \ + typedef MatrixType::RealScalar RealScalar; \ + allocate(matrix.rows(), matrix.cols(), computationOptions); \ +\ + /*const RealScalar precision = RealScalar(2) * NumTraits::epsilon();*/ \ + m_nonzeroSingularValues = m_diagSize; \ +\ + lapack_int lda = matrix.outerStride(), ldu, ldvt; \ + lapack_int matrix_order = MKLCOLROW; \ + char jobu, jobvt; \ + MKLTYPE *u, *vt, dummy; \ + jobu = (m_computeFullU) ? 'A' : (m_computeThinU) ? 'S' : 'N'; \ + jobvt = (m_computeFullV) ? 'A' : (m_computeThinV) ? 'S' : 'N'; \ + if (computeU()) { \ + ldu = m_matrixU.outerStride(); \ + u = (MKLTYPE*)m_matrixU.data(); \ + } else { ldu=1; u=&dummy; }\ + MatrixType localV; \ + ldvt = (m_computeFullV) ? m_cols : (m_computeThinV) ? m_diagSize : 1; \ + if (computeV()) { \ + localV.resize(ldvt, m_cols); \ + vt = (MKLTYPE*)localV.data(); \ + } else { ldvt=1; vt=&dummy; }\ + Matrix superb; superb.resize(m_diagSize, 1); \ + MatrixType m_temp; m_temp = matrix; \ + LAPACKE_##MKLPREFIX##gesvd( matrix_order, jobu, jobvt, m_rows, m_cols, (MKLTYPE*)m_temp.data(), lda, (MKLRTYPE*)m_singularValues.data(), u, ldu, vt, ldvt, superb.data()); \ + if (computeV()) m_matrixV = localV.adjoint(); \ + /* for(int i=0;i // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_BIDIAGONALIZATION_H #define EIGEN_BIDIAGONALIZATION_H +namespace Eigen { + namespace internal { // UpperBidiagonalization will probably be replaced by a Bidiagonalization class, don't want to make it stable API. // At the same time, it's useful to keep for now as it's about the only thing that is testing the BandMatrix class. @@ -156,4 +143,6 @@ MatrixBase::bidiagonalization() const } // end namespace internal +} // end namespace Eigen + #endif // EIGEN_BIDIAGONALIZATION_H diff --git a/extern/Eigen3/Eigen/src/Sparse/DynamicSparseMatrix.h b/extern/Eigen3/Eigen/src/Sparse/DynamicSparseMatrix.h deleted file mode 100644 index 93e75f4c601..00000000000 --- a/extern/Eigen3/Eigen/src/Sparse/DynamicSparseMatrix.h +++ /dev/null @@ -1,346 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008-2009 Gael Guennebaud -// -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . - -#ifndef EIGEN_DYNAMIC_SPARSEMATRIX_H -#define EIGEN_DYNAMIC_SPARSEMATRIX_H - -/** \class DynamicSparseMatrix - * - * \brief A sparse matrix class designed for matrix assembly purpose - * - * \param _Scalar the scalar type, i.e. the type of the coefficients - * - * Unlike SparseMatrix, this class provides a much higher degree of flexibility. In particular, it allows - * random read/write accesses in log(rho*outer_size) where \c rho is the probability that a coefficient is - * nonzero and outer_size is the number of columns if the matrix is column-major and the number of rows - * otherwise. - * - * Internally, the data are stored as a std::vector of compressed vector. The performances of random writes might - * decrease as the number of nonzeros per inner-vector increase. In practice, we observed very good performance - * till about 100 nonzeros/vector, and the performance remains relatively good till 500 nonzeros/vectors. - * - * \see SparseMatrix - */ - -namespace internal { -template -struct traits > -{ - typedef _Scalar Scalar; - typedef _Index Index; - typedef Sparse StorageKind; - typedef MatrixXpr XprKind; - enum { - RowsAtCompileTime = Dynamic, - ColsAtCompileTime = Dynamic, - MaxRowsAtCompileTime = Dynamic, - MaxColsAtCompileTime = Dynamic, - Flags = _Options | NestByRefBit | LvalueBit, - CoeffReadCost = NumTraits::ReadCost, - SupportedAccessPatterns = OuterRandomAccessPattern - }; -}; -} - -template -class DynamicSparseMatrix - : public SparseMatrixBase > -{ - public: - EIGEN_SPARSE_PUBLIC_INTERFACE(DynamicSparseMatrix) - // FIXME: why are these operator already alvailable ??? - // EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(DynamicSparseMatrix, +=) - // EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(DynamicSparseMatrix, -=) - typedef MappedSparseMatrix Map; - using Base::IsRowMajor; - using Base::operator=; - enum { - Options = _Options - }; - - protected: - - typedef DynamicSparseMatrix TransposedSparseMatrix; - - Index m_innerSize; - std::vector > m_data; - - public: - - inline Index rows() const { return IsRowMajor ? outerSize() : m_innerSize; } - inline Index cols() const { return IsRowMajor ? m_innerSize : outerSize(); } - inline Index innerSize() const { return m_innerSize; } - inline Index outerSize() const { return static_cast(m_data.size()); } - inline Index innerNonZeros(Index j) const { return m_data[j].size(); } - - std::vector >& _data() { return m_data; } - const std::vector >& _data() const { return m_data; } - - /** \returns the coefficient value at given position \a row, \a col - * This operation involes a log(rho*outer_size) binary search. - */ - inline Scalar coeff(Index row, Index col) const - { - const Index outer = IsRowMajor ? row : col; - const Index inner = IsRowMajor ? col : row; - return m_data[outer].at(inner); - } - - /** \returns a reference to the coefficient value at given position \a row, \a col - * This operation involes a log(rho*outer_size) binary search. If the coefficient does not - * exist yet, then a sorted insertion into a sequential buffer is performed. - */ - inline Scalar& coeffRef(Index row, Index col) - { - const Index outer = IsRowMajor ? row : col; - const Index inner = IsRowMajor ? col : row; - return m_data[outer].atWithInsertion(inner); - } - - class InnerIterator; - - void setZero() - { - for (Index j=0; j(m_data[j].size()); - return res; - } - - - - void reserve(Index reserveSize = 1000) - { - if (outerSize()>0) - { - Index reserveSizePerVector = (std::max)(reserveSize/outerSize(),Index(4)); - for (Index j=0; j(m_data[outer].size()) - 1; - m_data[outer].resize(id+2,1); - - while ( (id >= startId) && (m_data[outer].index(id) > inner) ) - { - m_data[outer].index(id+1) = m_data[outer].index(id); - m_data[outer].value(id+1) = m_data[outer].value(id); - --id; - } - m_data[outer].index(id+1) = inner; - m_data[outer].value(id+1) = 0; - return m_data[outer].value(id+1); - } - - /** Does nothing: provided for compatibility with SparseMatrix */ - inline void finalize() {} - - /** Suppress all nonzeros which are smaller than \a reference under the tolerence \a epsilon */ - void prune(Scalar reference, RealScalar epsilon = NumTraits::dummy_precision()) - { - for (Index j=0; jinnerSize) - { - // remove all coefficients with innerCoord>=innerSize - // TODO - //std::cerr << "not implemented yet\n"; - exit(2); - } - if (m_data.size() != outerSize) - { - m_data.resize(outerSize); - } - } - - inline DynamicSparseMatrix() - : m_innerSize(0), m_data(0) - { - eigen_assert(innerSize()==0 && outerSize()==0); - } - - inline DynamicSparseMatrix(Index rows, Index cols) - : m_innerSize(0) - { - resize(rows, cols); - } - - template - explicit inline DynamicSparseMatrix(const SparseMatrixBase& other) - : m_innerSize(0) - { - Base::operator=(other.derived()); - } - - inline DynamicSparseMatrix(const DynamicSparseMatrix& other) - : Base(), m_innerSize(0) - { - *this = other.derived(); - } - - inline void swap(DynamicSparseMatrix& other) - { - //EIGEN_DBG_SPARSE(std::cout << "SparseMatrix:: swap\n"); - std::swap(m_innerSize, other.m_innerSize); - //std::swap(m_outerSize, other.m_outerSize); - m_data.swap(other.m_data); - } - - inline DynamicSparseMatrix& operator=(const DynamicSparseMatrix& other) - { - if (other.isRValue()) - { - swap(other.const_cast_derived()); - } - else - { - resize(other.rows(), other.cols()); - m_data = other.m_data; - } - return *this; - } - - /** Destructor */ - inline ~DynamicSparseMatrix() {} - - public: - - /** \deprecated - * Set the matrix to zero and reserve the memory for \a reserveSize nonzero coefficients. */ - EIGEN_DEPRECATED void startFill(Index reserveSize = 1000) - { - setZero(); - reserve(reserveSize); - } - - /** \deprecated use insert() - * inserts a nonzero coefficient at given coordinates \a row, \a col and returns its reference assuming that: - * 1 - the coefficient does not exist yet - * 2 - this the coefficient with greater inner coordinate for the given outer coordinate. - * In other words, assuming \c *this is column-major, then there must not exists any nonzero coefficient of coordinates - * \c i \c x \a col such that \c i >= \a row. Otherwise the matrix is invalid. - * - * \see fillrand(), coeffRef() - */ - EIGEN_DEPRECATED Scalar& fill(Index row, Index col) - { - const Index outer = IsRowMajor ? row : col; - const Index inner = IsRowMajor ? col : row; - return insertBack(outer,inner); - } - - /** \deprecated use insert() - * Like fill() but with random inner coordinates. - * Compared to the generic coeffRef(), the unique limitation is that we assume - * the coefficient does not exist yet. - */ - EIGEN_DEPRECATED Scalar& fillrand(Index row, Index col) - { - return insert(row,col); - } - - /** \deprecated use finalize() - * Does nothing. Provided for compatibility with SparseMatrix. */ - EIGEN_DEPRECATED void endFill() {} - -# ifdef EIGEN_DYNAMICSPARSEMATRIX_PLUGIN -# include EIGEN_DYNAMICSPARSEMATRIX_PLUGIN -# endif -}; - -template -class DynamicSparseMatrix::InnerIterator : public SparseVector::InnerIterator -{ - typedef typename SparseVector::InnerIterator Base; - public: - InnerIterator(const DynamicSparseMatrix& mat, Index outer) - : Base(mat.m_data[outer]), m_outer(outer) - {} - - inline Index row() const { return IsRowMajor ? m_outer : Base::index(); } - inline Index col() const { return IsRowMajor ? Base::index() : m_outer; } - - protected: - const Index m_outer; -}; - -#endif // EIGEN_DYNAMIC_SPARSEMATRIX_H diff --git a/extern/Eigen3/Eigen/src/Sparse/SparseCwiseUnaryOp.h b/extern/Eigen3/Eigen/src/Sparse/SparseCwiseUnaryOp.h deleted file mode 100644 index aa068835fbb..00000000000 --- a/extern/Eigen3/Eigen/src/Sparse/SparseCwiseUnaryOp.h +++ /dev/null @@ -1,146 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008-2010 Gael Guennebaud -// -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . - -#ifndef EIGEN_SPARSE_CWISE_UNARY_OP_H -#define EIGEN_SPARSE_CWISE_UNARY_OP_H - -// template -// struct internal::traits > : internal::traits -// { -// typedef typename internal::result_of< -// UnaryOp(typename MatrixType::Scalar) -// >::type Scalar; -// typedef typename MatrixType::Nested MatrixTypeNested; -// typedef typename internal::remove_reference::type _MatrixTypeNested; -// enum { -// CoeffReadCost = _MatrixTypeNested::CoeffReadCost + internal::functor_traits::Cost -// }; -// }; - -template -class CwiseUnaryOpImpl - : public SparseMatrixBase > -{ - public: - - class InnerIterator; -// typedef typename internal::remove_reference::type _LhsNested; - - typedef CwiseUnaryOp Derived; - EIGEN_SPARSE_PUBLIC_INTERFACE(Derived) -}; - -template -class CwiseUnaryOpImpl::InnerIterator -{ - typedef typename CwiseUnaryOpImpl::Scalar Scalar; - typedef typename internal::traits::_XprTypeNested _MatrixTypeNested; - typedef typename _MatrixTypeNested::InnerIterator MatrixTypeIterator; - typedef typename MatrixType::Index Index; - public: - - EIGEN_STRONG_INLINE InnerIterator(const CwiseUnaryOpImpl& unaryOp, Index outer) - : m_iter(unaryOp.derived().nestedExpression(),outer), m_functor(unaryOp.derived().functor()) - {} - - EIGEN_STRONG_INLINE InnerIterator& operator++() - { ++m_iter; return *this; } - - EIGEN_STRONG_INLINE Scalar value() const { return m_functor(m_iter.value()); } - - EIGEN_STRONG_INLINE Index index() const { return m_iter.index(); } - EIGEN_STRONG_INLINE Index row() const { return m_iter.row(); } - EIGEN_STRONG_INLINE Index col() const { return m_iter.col(); } - - EIGEN_STRONG_INLINE operator bool() const { return m_iter; } - - protected: - MatrixTypeIterator m_iter; - const UnaryOp m_functor; -}; - -template -class CwiseUnaryViewImpl - : public SparseMatrixBase > -{ - public: - - class InnerIterator; -// typedef typename internal::remove_reference::type _LhsNested; - - typedef CwiseUnaryView Derived; - EIGEN_SPARSE_PUBLIC_INTERFACE(Derived) -}; - -template -class CwiseUnaryViewImpl::InnerIterator -{ - typedef typename CwiseUnaryViewImpl::Scalar Scalar; - typedef typename internal::traits::_MatrixTypeNested _MatrixTypeNested; - typedef typename _MatrixTypeNested::InnerIterator MatrixTypeIterator; - typedef typename MatrixType::Index Index; - public: - - EIGEN_STRONG_INLINE InnerIterator(const CwiseUnaryViewImpl& unaryView, Index outer) - : m_iter(unaryView.derived().nestedExpression(),outer), m_functor(unaryView.derived().functor()) - {} - - EIGEN_STRONG_INLINE InnerIterator& operator++() - { ++m_iter; return *this; } - - EIGEN_STRONG_INLINE Scalar value() const { return m_functor(m_iter.value()); } - EIGEN_STRONG_INLINE Scalar& valueRef() { return m_functor(m_iter.valueRef()); } - - EIGEN_STRONG_INLINE Index index() const { return m_iter.index(); } - EIGEN_STRONG_INLINE Index row() const { return m_iter.row(); } - EIGEN_STRONG_INLINE Index col() const { return m_iter.col(); } - - EIGEN_STRONG_INLINE operator bool() const { return m_iter; } - - protected: - MatrixTypeIterator m_iter; - const ViewOp m_functor; -}; - -template -EIGEN_STRONG_INLINE Derived& -SparseMatrixBase::operator*=(const Scalar& other) -{ - for (Index j=0; j -EIGEN_STRONG_INLINE Derived& -SparseMatrixBase::operator/=(const Scalar& other) -{ - for (Index j=0; j -// -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . - -#ifndef EIGEN_SPARSE_FUZZY_H -#define EIGEN_SPARSE_FUZZY_H - -// template -// template -// bool SparseMatrixBase::isApprox( -// const OtherDerived& other, -// typename NumTraits::Real prec -// ) const -// { -// const typename internal::nested::type nested(derived()); -// const typename internal::nested::type otherNested(other.derived()); -// return (nested - otherNested).cwise().abs2().sum() -// <= prec * prec * (std::min)(nested.cwise().abs2().sum(), otherNested.cwise().abs2().sum()); -// } - -#endif // EIGEN_SPARSE_FUZZY_H diff --git a/extern/Eigen3/Eigen/src/Sparse/SparseMatrix.h b/extern/Eigen3/Eigen/src/Sparse/SparseMatrix.h deleted file mode 100644 index 0e175ec6e71..00000000000 --- a/extern/Eigen3/Eigen/src/Sparse/SparseMatrix.h +++ /dev/null @@ -1,651 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008-2010 Gael Guennebaud -// -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . - -#ifndef EIGEN_SPARSEMATRIX_H -#define EIGEN_SPARSEMATRIX_H - -/** \ingroup Sparse_Module - * - * \class SparseMatrix - * - * \brief The main sparse matrix class - * - * This class implements a sparse matrix using the very common compressed row/column storage - * scheme. - * - * \tparam _Scalar the scalar type, i.e. the type of the coefficients - * \tparam _Options Union of bit flags controlling the storage scheme. Currently the only possibility - * is RowMajor. The default is 0 which means column-major. - * \tparam _Index the type of the indices. Default is \c int. - * - * See http://www.netlib.org/linalg/html_templates/node91.html for details on the storage scheme. - * - * This class can be extended with the help of the plugin mechanism described on the page - * \ref TopicCustomizingEigen by defining the preprocessor symbol \c EIGEN_SPARSEMATRIX_PLUGIN. - */ - -namespace internal { -template -struct traits > -{ - typedef _Scalar Scalar; - typedef _Index Index; - typedef Sparse StorageKind; - typedef MatrixXpr XprKind; - enum { - RowsAtCompileTime = Dynamic, - ColsAtCompileTime = Dynamic, - MaxRowsAtCompileTime = Dynamic, - MaxColsAtCompileTime = Dynamic, - Flags = _Options | NestByRefBit | LvalueBit, - CoeffReadCost = NumTraits::ReadCost, - SupportedAccessPatterns = InnerRandomAccessPattern - }; -}; - -} // end namespace internal - -template -class SparseMatrix - : public SparseMatrixBase > -{ - public: - EIGEN_SPARSE_PUBLIC_INTERFACE(SparseMatrix) -// using Base::operator=; - EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(SparseMatrix, +=) - EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(SparseMatrix, -=) - // FIXME: why are these operator already alvailable ??? - // EIGEN_SPARSE_INHERIT_SCALAR_ASSIGNMENT_OPERATOR(SparseMatrix, *=) - // EIGEN_SPARSE_INHERIT_SCALAR_ASSIGNMENT_OPERATOR(SparseMatrix, /=) - - typedef MappedSparseMatrix Map; - using Base::IsRowMajor; - typedef CompressedStorage Storage; - enum { - Options = _Options - }; - - protected: - - typedef SparseMatrix TransposedSparseMatrix; - - Index m_outerSize; - Index m_innerSize; - Index* m_outerIndex; - CompressedStorage m_data; - - public: - - inline Index rows() const { return IsRowMajor ? m_outerSize : m_innerSize; } - inline Index cols() const { return IsRowMajor ? m_innerSize : m_outerSize; } - - inline Index innerSize() const { return m_innerSize; } - inline Index outerSize() const { return m_outerSize; } - inline Index innerNonZeros(Index j) const { return m_outerIndex[j+1]-m_outerIndex[j]; } - - inline const Scalar* _valuePtr() const { return &m_data.value(0); } - inline Scalar* _valuePtr() { return &m_data.value(0); } - - inline const Index* _innerIndexPtr() const { return &m_data.index(0); } - inline Index* _innerIndexPtr() { return &m_data.index(0); } - - inline const Index* _outerIndexPtr() const { return m_outerIndex; } - inline Index* _outerIndexPtr() { return m_outerIndex; } - - inline Storage& data() { return m_data; } - inline const Storage& data() const { return m_data; } - - inline Scalar coeff(Index row, Index col) const - { - const Index outer = IsRowMajor ? row : col; - const Index inner = IsRowMajor ? col : row; - return m_data.atInRange(m_outerIndex[outer], m_outerIndex[outer+1], inner); - } - - inline Scalar& coeffRef(Index row, Index col) - { - const Index outer = IsRowMajor ? row : col; - const Index inner = IsRowMajor ? col : row; - - Index start = m_outerIndex[outer]; - Index end = m_outerIndex[outer+1]; - eigen_assert(end>=start && "you probably called coeffRef on a non finalized matrix"); - eigen_assert(end>start && "coeffRef cannot be called on a zero coefficient"); - const Index p = m_data.searchLowerIndex(start,end-1,inner); - eigen_assert((p(m_data.size()); } - - /** Preallocates \a reserveSize non zeros */ - inline void reserve(Index reserveSize) - { - m_data.reserve(reserveSize); - } - - //--- low level purely coherent filling --- - - /** \returns a reference to the non zero coefficient at position \a row, \a col assuming that: - * - the nonzero does not already exist - * - the new coefficient is the last one according to the storage order - * - * Before filling a given inner vector you must call the statVec(Index) function. - * - * After an insertion session, you should call the finalize() function. - * - * \sa insert, insertBackByOuterInner, startVec */ - inline Scalar& insertBack(Index row, Index col) - { - return insertBackByOuterInner(IsRowMajor?row:col, IsRowMajor?col:row); - } - - /** \sa insertBack, startVec */ - inline Scalar& insertBackByOuterInner(Index outer, Index inner) - { - eigen_assert(size_t(m_outerIndex[outer+1]) == m_data.size() && "Invalid ordered insertion (invalid outer index)"); - eigen_assert( (m_outerIndex[outer+1]-m_outerIndex[outer]==0 || m_data.index(m_data.size()-1)=0 && m_outerIndex[previousOuter]==0) - { - m_outerIndex[previousOuter] = static_cast(m_data.size()); - --previousOuter; - } - m_outerIndex[outer+1] = m_outerIndex[outer]; - } - - // here we have to handle the tricky case where the outerIndex array - // starts with: [ 0 0 0 0 0 1 ...] and we are inserting in, e.g., - // the 2nd inner vector... - bool isLastVec = (!(previousOuter==-1 && m_data.size()!=0)) - && (size_t(m_outerIndex[outer+1]) == m_data.size()); - - size_t startId = m_outerIndex[outer]; - // FIXME let's make sure sizeof(long int) == sizeof(size_t) - size_t p = m_outerIndex[outer+1]; - ++m_outerIndex[outer+1]; - - float reallocRatio = 1; - if (m_data.allocatedSize()<=m_data.size()) - { - // if there is no preallocated memory, let's reserve a minimum of 32 elements - if (m_data.size()==0) - { - m_data.reserve(32); - } - else - { - // we need to reallocate the data, to reduce multiple reallocations - // we use a smart resize algorithm based on the current filling ratio - // in addition, we use float to avoid integers overflows - float nnzEstimate = float(m_outerIndex[outer])*float(m_outerSize)/float(outer+1); - reallocRatio = (nnzEstimate-float(m_data.size()))/float(m_data.size()); - // furthermore we bound the realloc ratio to: - // 1) reduce multiple minor realloc when the matrix is almost filled - // 2) avoid to allocate too much memory when the matrix is almost empty - reallocRatio = (std::min)((std::max)(reallocRatio,1.5f),8.f); - } - } - m_data.resize(m_data.size()+1,reallocRatio); - - if (!isLastVec) - { - if (previousOuter==-1) - { - // oops wrong guess. - // let's correct the outer offsets - for (Index k=0; k<=(outer+1); ++k) - m_outerIndex[k] = 0; - Index k=outer+1; - while(m_outerIndex[k]==0) - m_outerIndex[k++] = 1; - while (k<=m_outerSize && m_outerIndex[k]!=0) - m_outerIndex[k++]++; - p = 0; - --k; - k = m_outerIndex[k]-1; - while (k>0) - { - m_data.index(k) = m_data.index(k-1); - m_data.value(k) = m_data.value(k-1); - k--; - } - } - else - { - // we are not inserting into the last inner vec - // update outer indices: - Index j = outer+2; - while (j<=m_outerSize && m_outerIndex[j]!=0) - m_outerIndex[j++]++; - --j; - // shift data of last vecs: - Index k = m_outerIndex[j]-1; - while (k>=Index(p)) - { - m_data.index(k) = m_data.index(k-1); - m_data.value(k) = m_data.value(k-1); - k--; - } - } - } - - while ( (p > startId) && (m_data.index(p-1) > inner) ) - { - m_data.index(p) = m_data.index(p-1); - m_data.value(p) = m_data.value(p-1); - --p; - } - - m_data.index(p) = inner; - return (m_data.value(p) = 0); - } - - - - - /** Must be called after inserting a set of non zero entries. - */ - inline void finalize() - { - Index size = static_cast(m_data.size()); - Index i = m_outerSize; - // find the last filled column - while (i>=0 && m_outerIndex[i]==0) - --i; - ++i; - while (i<=m_outerSize) - { - m_outerIndex[i] = size; - ++i; - } - } - - /** Suppress all nonzeros which are smaller than \a reference under the tolerence \a epsilon */ - void prune(Scalar reference, RealScalar epsilon = NumTraits::dummy_precision()) - { - prune(default_prunning_func(reference,epsilon)); - } - - /** Suppress all nonzeros which do not satisfy the predicate \a keep. - * The functor type \a KeepFunc must implement the following function: - * \code - * bool operator() (const Index& row, const Index& col, const Scalar& value) const; - * \endcode - * \sa prune(Scalar,RealScalar) - */ - template - void prune(const KeepFunc& keep = KeepFunc()) - { - Index k = 0; - for(Index j=0; j - inline SparseMatrix(const SparseMatrixBase& other) - : m_outerSize(0), m_innerSize(0), m_outerIndex(0) - { - *this = other.derived(); - } - - /** Copy constructor */ - inline SparseMatrix(const SparseMatrix& other) - : Base(), m_outerSize(0), m_innerSize(0), m_outerIndex(0) - { - *this = other.derived(); - } - - /** Swap the content of two sparse matrices of same type (optimization) */ - inline void swap(SparseMatrix& other) - { - //EIGEN_DBG_SPARSE(std::cout << "SparseMatrix:: swap\n"); - std::swap(m_outerIndex, other.m_outerIndex); - std::swap(m_innerSize, other.m_innerSize); - std::swap(m_outerSize, other.m_outerSize); - m_data.swap(other.m_data); - } - - inline SparseMatrix& operator=(const SparseMatrix& other) - { -// std::cout << "SparseMatrix& operator=(const SparseMatrix& other)\n"; - if (other.isRValue()) - { - swap(other.const_cast_derived()); - } - else - { - resize(other.rows(), other.cols()); - memcpy(m_outerIndex, other.m_outerIndex, (m_outerSize+1)*sizeof(Index)); - m_data = other.m_data; - } - return *this; - } - - #ifndef EIGEN_PARSED_BY_DOXYGEN - template - inline SparseMatrix& operator=(const SparseSparseProduct& product) - { return Base::operator=(product); } - - template - inline SparseMatrix& operator=(const ReturnByValue& other) - { return Base::operator=(other); } - - template - inline SparseMatrix& operator=(const EigenBase& other) - { return Base::operator=(other); } - #endif - - template - EIGEN_DONT_INLINE SparseMatrix& operator=(const SparseMatrixBase& other) - { - const bool needToTranspose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit); - if (needToTranspose) - { - // two passes algorithm: - // 1 - compute the number of coeffs per dest inner vector - // 2 - do the actual copy/eval - // Since each coeff of the rhs has to be evaluated twice, let's evaluate it if needed - typedef typename internal::nested::type OtherCopy; - typedef typename internal::remove_all::type _OtherCopy; - OtherCopy otherCopy(other.derived()); - - resize(other.rows(), other.cols()); - Eigen::Map > (m_outerIndex,outerSize()).setZero(); - // pass 1 - // FIXME the above copy could be merged with that pass - for (Index j=0; j::operator=(other.derived()); - } - } - - friend std::ostream & operator << (std::ostream & s, const SparseMatrix& m) - { - EIGEN_DBG_SPARSE( - s << "Nonzero entries:\n"; - for (Index i=0; i&>(m); - return s; - } - - /** Destructor */ - inline ~SparseMatrix() - { - delete[] m_outerIndex; - } - - /** Overloaded for performance */ - Scalar sum() const; - - public: - - /** \deprecated use setZero() and reserve() - * Initializes the filling process of \c *this. - * \param reserveSize approximate number of nonzeros - * Note that the matrix \c *this is zero-ed. - */ - EIGEN_DEPRECATED void startFill(Index reserveSize = 1000) - { - setZero(); - m_data.reserve(reserveSize); - } - - /** \deprecated use insert() - * Like fill() but with random inner coordinates. - */ - EIGEN_DEPRECATED Scalar& fillrand(Index row, Index col) - { - return insert(row,col); - } - - /** \deprecated use insert() - */ - EIGEN_DEPRECATED Scalar& fill(Index row, Index col) - { - const Index outer = IsRowMajor ? row : col; - const Index inner = IsRowMajor ? col : row; - - if (m_outerIndex[outer+1]==0) - { - // we start a new inner vector - Index i = outer; - while (i>=0 && m_outerIndex[i]==0) - { - m_outerIndex[i] = m_data.size(); - --i; - } - m_outerIndex[outer+1] = m_outerIndex[outer]; - } - else - { - eigen_assert(m_data.index(m_data.size()-1) -class SparseMatrix::InnerIterator -{ - public: - InnerIterator(const SparseMatrix& mat, Index outer) - : m_values(mat._valuePtr()), m_indices(mat._innerIndexPtr()), m_outer(outer), m_id(mat.m_outerIndex[outer]), m_end(mat.m_outerIndex[outer+1]) - {} - - inline InnerIterator& operator++() { m_id++; return *this; } - - inline const Scalar& value() const { return m_values[m_id]; } - inline Scalar& valueRef() { return const_cast(m_values[m_id]); } - - inline Index index() const { return m_indices[m_id]; } - inline Index outer() const { return m_outer; } - inline Index row() const { return IsRowMajor ? m_outer : index(); } - inline Index col() const { return IsRowMajor ? index() : m_outer; } - - inline operator bool() const { return (m_id < m_end); } - - protected: - const Scalar* m_values; - const Index* m_indices; - const Index m_outer; - Index m_id; - const Index m_end; -}; - -#endif // EIGEN_SPARSEMATRIX_H diff --git a/extern/Eigen3/Eigen/src/Sparse/SparseSparseProduct.h b/extern/Eigen3/Eigen/src/Sparse/SparseSparseProduct.h deleted file mode 100644 index 19abcd1f8e4..00000000000 --- a/extern/Eigen3/Eigen/src/Sparse/SparseSparseProduct.h +++ /dev/null @@ -1,401 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008-2010 Gael Guennebaud -// -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . - -#ifndef EIGEN_SPARSESPARSEPRODUCT_H -#define EIGEN_SPARSESPARSEPRODUCT_H - -namespace internal { - -template -static void sparse_product_impl2(const Lhs& lhs, const Rhs& rhs, ResultType& res) -{ - typedef typename remove_all::type::Scalar Scalar; - typedef typename remove_all::type::Index Index; - - // make sure to call innerSize/outerSize since we fake the storage order. - Index rows = lhs.innerSize(); - Index cols = rhs.outerSize(); - eigen_assert(lhs.outerSize() == rhs.innerSize()); - - std::vector mask(rows,false); - Matrix values(rows); - Matrix indices(rows); - - // estimate the number of non zero entries - float ratioLhs = float(lhs.nonZeros())/(float(lhs.rows())*float(lhs.cols())); - float avgNnzPerRhsColumn = float(rhs.nonZeros())/float(cols); - float ratioRes = (std::min)(ratioLhs * avgNnzPerRhsColumn, 1.f); - -// int t200 = rows/(log2(200)*1.39); -// int t = (rows*100)/139; - - res.resize(rows, cols); - res.reserve(Index(ratioRes*rows*cols)); - // we compute each column of the result, one after the other - for (Index j=0; j use a quick sort - // otherwise => loop through the entire vector - // In order to avoid to perform an expensive log2 when the - // result is clearly very sparse we use a linear bound up to 200. -// if((nnz<200 && nnz1) std::sort(indices.data(),indices.data()+nnz); -// for(int k=0; k -static void sparse_product_impl(const Lhs& lhs, const Rhs& rhs, ResultType& res) -{ -// return sparse_product_impl2(lhs,rhs,res); - - typedef typename remove_all::type::Scalar Scalar; - typedef typename remove_all::type::Index Index; - - // make sure to call innerSize/outerSize since we fake the storage order. - Index rows = lhs.innerSize(); - Index cols = rhs.outerSize(); - //int size = lhs.outerSize(); - eigen_assert(lhs.outerSize() == rhs.innerSize()); - - // allocate a temporary buffer - AmbiVector tempVector(rows); - - // estimate the number of non zero entries - float ratioLhs = float(lhs.nonZeros())/(float(lhs.rows())*float(lhs.cols())); - float avgNnzPerRhsColumn = float(rhs.nonZeros())/float(cols); - float ratioRes = (std::min)(ratioLhs * avgNnzPerRhsColumn, 1.f); - - // mimics a resizeByInnerOuter: - if(ResultType::IsRowMajor) - res.resize(cols, rows); - else - res.resize(rows, cols); - - res.reserve(Index(ratioRes*rows*cols)); - for (Index j=0; j::Iterator it(tempVector); it; ++it) - res.insertBackByOuterInner(j,it.index()) = it.value(); - } - res.finalize(); -} - -template::Flags&RowMajorBit, - int RhsStorageOrder = traits::Flags&RowMajorBit, - int ResStorageOrder = traits::Flags&RowMajorBit> -struct sparse_product_selector; - -template -struct sparse_product_selector -{ - typedef typename traits::type>::Scalar Scalar; - - static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res) - { -// std::cerr << __LINE__ << "\n"; - typename remove_all::type _res(res.rows(), res.cols()); - sparse_product_impl(lhs, rhs, _res); - res.swap(_res); - } -}; - -template -struct sparse_product_selector -{ - static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res) - { -// std::cerr << __LINE__ << "\n"; - // we need a col-major matrix to hold the result - typedef SparseMatrix SparseTemporaryType; - SparseTemporaryType _res(res.rows(), res.cols()); - sparse_product_impl(lhs, rhs, _res); - res = _res; - } -}; - -template -struct sparse_product_selector -{ - static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res) - { -// std::cerr << __LINE__ << "\n"; - // let's transpose the product to get a column x column product - typename remove_all::type _res(res.rows(), res.cols()); - sparse_product_impl(rhs, lhs, _res); - res.swap(_res); - } -}; - -template -struct sparse_product_selector -{ - static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res) - { -// std::cerr << "here...\n"; - typedef SparseMatrix ColMajorMatrix; - ColMajorMatrix colLhs(lhs); - ColMajorMatrix colRhs(rhs); -// std::cerr << "more...\n"; - sparse_product_impl(colLhs, colRhs, res); -// std::cerr << "OK.\n"; - - // let's transpose the product to get a column x column product - -// typedef SparseMatrix SparseTemporaryType; -// SparseTemporaryType _res(res.cols(), res.rows()); -// sparse_product_impl(rhs, lhs, _res); -// res = _res.transpose(); - } -}; - -// NOTE the 2 others cases (col row *) must never occur since they are caught -// by ProductReturnType which transforms it to (col col *) by evaluating rhs. - -} // end namespace internal - -// sparse = sparse * sparse -template -template -inline Derived& SparseMatrixBase::operator=(const SparseSparseProduct& product) -{ -// std::cerr << "there..." << typeid(Lhs).name() << " " << typeid(Lhs).name() << " " << (Derived::Flags&&RowMajorBit) << "\n"; - internal::sparse_product_selector< - typename internal::remove_all::type, - typename internal::remove_all::type, - Derived>::run(product.lhs(),product.rhs(),derived()); - return derived(); -} - -namespace internal { - -template::Flags&RowMajorBit, - int RhsStorageOrder = traits::Flags&RowMajorBit, - int ResStorageOrder = traits::Flags&RowMajorBit> -struct sparse_product_selector2; - -template -struct sparse_product_selector2 -{ - typedef typename traits::type>::Scalar Scalar; - - static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res) - { - sparse_product_impl2(lhs, rhs, res); - } -}; - -template -struct sparse_product_selector2 -{ - static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res) - { - // prevent warnings until the code is fixed - EIGEN_UNUSED_VARIABLE(lhs); - EIGEN_UNUSED_VARIABLE(rhs); - EIGEN_UNUSED_VARIABLE(res); - -// typedef SparseMatrix RowMajorMatrix; -// RowMajorMatrix rhsRow = rhs; -// RowMajorMatrix resRow(res.rows(), res.cols()); -// sparse_product_impl2(rhsRow, lhs, resRow); -// res = resRow; - } -}; - -template -struct sparse_product_selector2 -{ - static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res) - { - typedef SparseMatrix RowMajorMatrix; - RowMajorMatrix lhsRow = lhs; - RowMajorMatrix resRow(res.rows(), res.cols()); - sparse_product_impl2(rhs, lhsRow, resRow); - res = resRow; - } -}; - -template -struct sparse_product_selector2 -{ - static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res) - { - typedef SparseMatrix RowMajorMatrix; - RowMajorMatrix resRow(res.rows(), res.cols()); - sparse_product_impl2(rhs, lhs, resRow); - res = resRow; - } -}; - - -template -struct sparse_product_selector2 -{ - typedef typename traits::type>::Scalar Scalar; - - static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res) - { - typedef SparseMatrix ColMajorMatrix; - ColMajorMatrix resCol(res.rows(), res.cols()); - sparse_product_impl2(lhs, rhs, resCol); - res = resCol; - } -}; - -template -struct sparse_product_selector2 -{ - static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res) - { - typedef SparseMatrix ColMajorMatrix; - ColMajorMatrix lhsCol = lhs; - ColMajorMatrix resCol(res.rows(), res.cols()); - sparse_product_impl2(lhsCol, rhs, resCol); - res = resCol; - } -}; - -template -struct sparse_product_selector2 -{ - static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res) - { - typedef SparseMatrix ColMajorMatrix; - ColMajorMatrix rhsCol = rhs; - ColMajorMatrix resCol(res.rows(), res.cols()); - sparse_product_impl2(lhs, rhsCol, resCol); - res = resCol; - } -}; - -template -struct sparse_product_selector2 -{ - static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res) - { - typedef SparseMatrix ColMajorMatrix; -// ColMajorMatrix lhsTr(lhs); -// ColMajorMatrix rhsTr(rhs); -// ColMajorMatrix aux(res.rows(), res.cols()); -// sparse_product_impl2(rhs, lhs, aux); -// // ColMajorMatrix aux2 = aux.transpose(); -// res = aux; - typedef SparseMatrix ColMajorMatrix; - ColMajorMatrix lhsCol(lhs); - ColMajorMatrix rhsCol(rhs); - ColMajorMatrix resCol(res.rows(), res.cols()); - sparse_product_impl2(lhsCol, rhsCol, resCol); - res = resCol; - } -}; - -} // end namespace internal - -template -template -inline void SparseMatrixBase::_experimentalNewProduct(const Lhs& lhs, const Rhs& rhs) -{ - //derived().resize(lhs.rows(), rhs.cols()); - internal::sparse_product_selector2< - typename internal::remove_all::type, - typename internal::remove_all::type, - Derived>::run(lhs,rhs,derived()); -} - -// sparse * sparse -template -template -inline const typename SparseSparseProductReturnType::Type -SparseMatrixBase::operator*(const SparseMatrixBase &other) const -{ - return typename SparseSparseProductReturnType::Type(derived(), other.derived()); -} - -#endif // EIGEN_SPARSESPARSEPRODUCT_H diff --git a/extern/Eigen3/Eigen/src/Sparse/SparseTriangularView.h b/extern/Eigen3/Eigen/src/Sparse/SparseTriangularView.h deleted file mode 100644 index 319eaf06638..00000000000 --- a/extern/Eigen3/Eigen/src/Sparse/SparseTriangularView.h +++ /dev/null @@ -1,100 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2009 Gael Guennebaud -// -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . - -#ifndef EIGEN_SPARSE_TRIANGULARVIEW_H -#define EIGEN_SPARSE_TRIANGULARVIEW_H - -namespace internal { - -template -struct traits > -: public traits -{}; - -} // namespace internal - -template class SparseTriangularView - : public SparseMatrixBase > -{ - enum { SkipFirst = (Mode==Lower && !(MatrixType::Flags&RowMajorBit)) - || (Mode==Upper && (MatrixType::Flags&RowMajorBit)) }; - public: - - EIGEN_SPARSE_PUBLIC_INTERFACE(SparseTriangularView) - - class InnerIterator; - - inline Index rows() const { return m_matrix.rows(); } - inline Index cols() const { return m_matrix.cols(); } - - typedef typename internal::conditional::ret, - MatrixType, const MatrixType&>::type MatrixTypeNested; - - inline SparseTriangularView(const MatrixType& matrix) : m_matrix(matrix) {} - - /** \internal */ - inline const MatrixType& nestedExpression() const { return m_matrix; } - - template - typename internal::plain_matrix_type_column_major::type - solve(const MatrixBase& other) const; - - template void solveInPlace(MatrixBase& other) const; - template void solveInPlace(SparseMatrixBase& other) const; - - protected: - MatrixTypeNested m_matrix; -}; - -template -class SparseTriangularView::InnerIterator : public MatrixType::InnerIterator -{ - typedef typename MatrixType::InnerIterator Base; - public: - - EIGEN_STRONG_INLINE InnerIterator(const SparseTriangularView& view, Index outer) - : Base(view.nestedExpression(), outer) - { - if(SkipFirst) - while((*this) && this->index()index() <= this->outer()); - } -}; - -template -template -inline const SparseTriangularView -SparseMatrixBase::triangularView() const -{ - return derived(); -} - -#endif // EIGEN_SPARSE_TRIANGULARVIEW_H diff --git a/extern/Eigen3/Eigen/src/SparseCholesky/SimplicialCholesky.h b/extern/Eigen3/Eigen/src/SparseCholesky/SimplicialCholesky.h new file mode 100644 index 00000000000..9bf38ab2d91 --- /dev/null +++ b/extern/Eigen3/Eigen/src/SparseCholesky/SimplicialCholesky.h @@ -0,0 +1,873 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008-2010 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +/* + +NOTE: the _symbolic, and _numeric functions has been adapted from + the LDL library: + +LDL Copyright (c) 2005 by Timothy A. Davis. All Rights Reserved. + +LDL License: + + Your use or distribution of LDL or any modified version of + LDL implies that you agree to this License. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 + USA + + Permission is hereby granted to use or copy this program under the + terms of the GNU LGPL, provided that the Copyright, this License, + and the Availability of the original version is retained on all copies. + User documentation of any code that uses this code or any modified + version of this code must cite the Copyright, this License, the + Availability note, and "Used by permission." Permission to modify + the code and to distribute modified code is granted, provided the + Copyright, this License, and the Availability note are retained, + and a notice that the code was modified is included. + */ + +#include "../Core/util/NonMPL2.h" + +#ifndef EIGEN_SIMPLICIAL_CHOLESKY_H +#define EIGEN_SIMPLICIAL_CHOLESKY_H + +namespace Eigen { + +enum SimplicialCholeskyMode { + SimplicialCholeskyLLT, + SimplicialCholeskyLDLT +}; + +/** \ingroup SparseCholesky_Module + * \brief A direct sparse Cholesky factorizations + * + * These classes provide LL^T and LDL^T Cholesky factorizations of sparse matrices that are + * selfadjoint and positive definite. The factorization allows for solving A.X = B where + * X and B can be either dense or sparse. + * + * In order to reduce the fill-in, a symmetric permutation P is applied prior to the factorization + * such that the factorized matrix is P A P^-1. + * + * \tparam _MatrixType the type of the sparse matrix A, it must be a SparseMatrix<> + * \tparam _UpLo the triangular part that will be used for the computations. It can be Lower + * or Upper. Default is Lower. + * + */ +template +class SimplicialCholeskyBase : internal::noncopyable +{ + public: + typedef typename internal::traits::MatrixType MatrixType; + enum { UpLo = internal::traits::UpLo }; + typedef typename MatrixType::Scalar Scalar; + typedef typename MatrixType::RealScalar RealScalar; + typedef typename MatrixType::Index Index; + typedef SparseMatrix CholMatrixType; + typedef Matrix VectorType; + + public: + + /** Default constructor */ + SimplicialCholeskyBase() + : m_info(Success), m_isInitialized(false), m_shiftOffset(0), m_shiftScale(1) + {} + + SimplicialCholeskyBase(const MatrixType& matrix) + : m_info(Success), m_isInitialized(false), m_shiftOffset(0), m_shiftScale(1) + { + derived().compute(matrix); + } + + ~SimplicialCholeskyBase() + { + } + + Derived& derived() { return *static_cast(this); } + const Derived& derived() const { return *static_cast(this); } + + inline Index cols() const { return m_matrix.cols(); } + inline Index rows() const { return m_matrix.rows(); } + + /** \brief Reports whether previous computation was successful. + * + * \returns \c Success if computation was succesful, + * \c NumericalIssue if the matrix.appears to be negative. + */ + ComputationInfo info() const + { + eigen_assert(m_isInitialized && "Decomposition is not initialized."); + return m_info; + } + + /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A. + * + * \sa compute() + */ + template + inline const internal::solve_retval + solve(const MatrixBase& b) const + { + eigen_assert(m_isInitialized && "Simplicial LLT or LDLT is not initialized."); + eigen_assert(rows()==b.rows() + && "SimplicialCholeskyBase::solve(): invalid number of rows of the right hand side matrix b"); + return internal::solve_retval(*this, b.derived()); + } + + /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A. + * + * \sa compute() + */ + template + inline const internal::sparse_solve_retval + solve(const SparseMatrixBase& b) const + { + eigen_assert(m_isInitialized && "Simplicial LLT or LDLT is not initialized."); + eigen_assert(rows()==b.rows() + && "SimplicialCholesky::solve(): invalid number of rows of the right hand side matrix b"); + return internal::sparse_solve_retval(*this, b.derived()); + } + + /** \returns the permutation P + * \sa permutationPinv() */ + const PermutationMatrix& permutationP() const + { return m_P; } + + /** \returns the inverse P^-1 of the permutation P + * \sa permutationP() */ + const PermutationMatrix& permutationPinv() const + { return m_Pinv; } + + /** Sets the shift parameters that will be used to adjust the diagonal coefficients during the numerical factorization. + * + * During the numerical factorization, the diagonal coefficients are transformed by the following linear model:\n + * \c d_ii = \a offset + \a scale * \c d_ii + * + * The default is the identity transformation with \a offset=0, and \a scale=1. + * + * \returns a reference to \c *this. + */ + Derived& setShift(const RealScalar& offset, const RealScalar& scale = 1) + { + m_shiftOffset = offset; + m_shiftScale = scale; + return derived(); + } + +#ifndef EIGEN_PARSED_BY_DOXYGEN + /** \internal */ + template + void dumpMemory(Stream& s) + { + int total = 0; + s << " L: " << ((total+=(m_matrix.cols()+1) * sizeof(int) + m_matrix.nonZeros()*(sizeof(int)+sizeof(Scalar))) >> 20) << "Mb" << "\n"; + s << " diag: " << ((total+=m_diag.size() * sizeof(Scalar)) >> 20) << "Mb" << "\n"; + s << " tree: " << ((total+=m_parent.size() * sizeof(int)) >> 20) << "Mb" << "\n"; + s << " nonzeros: " << ((total+=m_nonZerosPerCol.size() * sizeof(int)) >> 20) << "Mb" << "\n"; + s << " perm: " << ((total+=m_P.size() * sizeof(int)) >> 20) << "Mb" << "\n"; + s << " perm^-1: " << ((total+=m_Pinv.size() * sizeof(int)) >> 20) << "Mb" << "\n"; + s << " TOTAL: " << (total>> 20) << "Mb" << "\n"; + } + + /** \internal */ + template + void _solve(const MatrixBase &b, MatrixBase &dest) const + { + eigen_assert(m_factorizationIsOk && "The decomposition is not in a valid state for solving, you must first call either compute() or symbolic()/numeric()"); + eigen_assert(m_matrix.rows()==b.rows()); + + if(m_info!=Success) + return; + + if(m_P.size()>0) + dest = m_P * b; + else + dest = b; + + if(m_matrix.nonZeros()>0) // otherwise L==I + derived().matrixL().solveInPlace(dest); + + if(m_diag.size()>0) + dest = m_diag.asDiagonal().inverse() * dest; + + if (m_matrix.nonZeros()>0) // otherwise U==I + derived().matrixU().solveInPlace(dest); + + if(m_P.size()>0) + dest = m_Pinv * dest; + } + + /** \internal */ + template + void _solve_sparse(const Rhs& b, SparseMatrix &dest) const + { + eigen_assert(m_factorizationIsOk && "The decomposition is not in a valid state for solving, you must first call either compute() or symbolic()/numeric()"); + eigen_assert(m_matrix.rows()==b.rows()); + + // we process the sparse rhs per block of NbColsAtOnce columns temporarily stored into a dense matrix. + static const int NbColsAtOnce = 4; + int rhsCols = b.cols(); + int size = b.rows(); + Eigen::Matrix tmp(size,rhsCols); + for(int k=0; k(rhsCols-k, NbColsAtOnce); + tmp.leftCols(actualCols) = b.middleCols(k,actualCols); + tmp.leftCols(actualCols) = derived().solve(tmp.leftCols(actualCols)); + dest.middleCols(k,actualCols) = tmp.leftCols(actualCols).sparseView(); + } + } + +#endif // EIGEN_PARSED_BY_DOXYGEN + + protected: + + /** Computes the sparse Cholesky decomposition of \a matrix */ + template + void compute(const MatrixType& matrix) + { + eigen_assert(matrix.rows()==matrix.cols()); + Index size = matrix.cols(); + CholMatrixType ap(size,size); + ordering(matrix, ap); + analyzePattern_preordered(ap, DoLDLT); + factorize_preordered(ap); + } + + template + void factorize(const MatrixType& a) + { + eigen_assert(a.rows()==a.cols()); + int size = a.cols(); + CholMatrixType ap(size,size); + ap.template selfadjointView() = a.template selfadjointView().twistedBy(m_P); + factorize_preordered(ap); + } + + template + void factorize_preordered(const CholMatrixType& a); + + void analyzePattern(const MatrixType& a, bool doLDLT) + { + eigen_assert(a.rows()==a.cols()); + int size = a.cols(); + CholMatrixType ap(size,size); + ordering(a, ap); + analyzePattern_preordered(ap,doLDLT); + } + void analyzePattern_preordered(const CholMatrixType& a, bool doLDLT); + + void ordering(const MatrixType& a, CholMatrixType& ap); + + /** keeps off-diagonal entries; drops diagonal entries */ + struct keep_diag { + inline bool operator() (const Index& row, const Index& col, const Scalar&) const + { + return row!=col; + } + }; + + mutable ComputationInfo m_info; + bool m_isInitialized; + bool m_factorizationIsOk; + bool m_analysisIsOk; + + CholMatrixType m_matrix; + VectorType m_diag; // the diagonal coefficients (LDLT mode) + VectorXi m_parent; // elimination tree + VectorXi m_nonZerosPerCol; + PermutationMatrix m_P; // the permutation + PermutationMatrix m_Pinv; // the inverse permutation + + RealScalar m_shiftOffset; + RealScalar m_shiftScale; +}; + +template class SimplicialLLT; +template class SimplicialLDLT; +template class SimplicialCholesky; + +namespace internal { + +template struct traits > +{ + typedef _MatrixType MatrixType; + enum { UpLo = _UpLo }; + typedef typename MatrixType::Scalar Scalar; + typedef typename MatrixType::Index Index; + typedef SparseMatrix CholMatrixType; + typedef SparseTriangularView MatrixL; + typedef SparseTriangularView MatrixU; + static inline MatrixL getL(const MatrixType& m) { return m; } + static inline MatrixU getU(const MatrixType& m) { return m.adjoint(); } +}; + +template struct traits > +{ + typedef _MatrixType MatrixType; + enum { UpLo = _UpLo }; + typedef typename MatrixType::Scalar Scalar; + typedef typename MatrixType::Index Index; + typedef SparseMatrix CholMatrixType; + typedef SparseTriangularView MatrixL; + typedef SparseTriangularView MatrixU; + static inline MatrixL getL(const MatrixType& m) { return m; } + static inline MatrixU getU(const MatrixType& m) { return m.adjoint(); } +}; + +template struct traits > +{ + typedef _MatrixType MatrixType; + enum { UpLo = _UpLo }; +}; + +} + +/** \ingroup SparseCholesky_Module + * \class SimplicialLLT + * \brief A direct sparse LLT Cholesky factorizations + * + * This class provides a LL^T Cholesky factorizations of sparse matrices that are + * selfadjoint and positive definite. The factorization allows for solving A.X = B where + * X and B can be either dense or sparse. + * + * In order to reduce the fill-in, a symmetric permutation P is applied prior to the factorization + * such that the factorized matrix is P A P^-1. + * + * \tparam _MatrixType the type of the sparse matrix A, it must be a SparseMatrix<> + * \tparam _UpLo the triangular part that will be used for the computations. It can be Lower + * or Upper. Default is Lower. + * + * \sa class SimplicialLDLT + */ +template + class SimplicialLLT : public SimplicialCholeskyBase > +{ +public: + typedef _MatrixType MatrixType; + enum { UpLo = _UpLo }; + typedef SimplicialCholeskyBase Base; + typedef typename MatrixType::Scalar Scalar; + typedef typename MatrixType::RealScalar RealScalar; + typedef typename MatrixType::Index Index; + typedef SparseMatrix CholMatrixType; + typedef Matrix VectorType; + typedef internal::traits Traits; + typedef typename Traits::MatrixL MatrixL; + typedef typename Traits::MatrixU MatrixU; +public: + /** Default constructor */ + SimplicialLLT() : Base() {} + /** Constructs and performs the LLT factorization of \a matrix */ + SimplicialLLT(const MatrixType& matrix) + : Base(matrix) {} + + /** \returns an expression of the factor L */ + inline const MatrixL matrixL() const { + eigen_assert(Base::m_factorizationIsOk && "Simplicial LLT not factorized"); + return Traits::getL(Base::m_matrix); + } + + /** \returns an expression of the factor U (= L^*) */ + inline const MatrixU matrixU() const { + eigen_assert(Base::m_factorizationIsOk && "Simplicial LLT not factorized"); + return Traits::getU(Base::m_matrix); + } + + /** Computes the sparse Cholesky decomposition of \a matrix */ + SimplicialLLT& compute(const MatrixType& matrix) + { + Base::template compute(matrix); + return *this; + } + + /** Performs a symbolic decomposition on the sparcity of \a matrix. + * + * This function is particularly useful when solving for several problems having the same structure. + * + * \sa factorize() + */ + void analyzePattern(const MatrixType& a) + { + Base::analyzePattern(a, false); + } + + /** Performs a numeric decomposition of \a matrix + * + * The given matrix must has the same sparcity than the matrix on which the symbolic decomposition has been performed. + * + * \sa analyzePattern() + */ + void factorize(const MatrixType& a) + { + Base::template factorize(a); + } + + /** \returns the determinant of the underlying matrix from the current factorization */ + Scalar determinant() const + { + Scalar detL = Base::m_matrix.diagonal().prod(); + return internal::abs2(detL); + } +}; + +/** \ingroup SparseCholesky_Module + * \class SimplicialLDLT + * \brief A direct sparse LDLT Cholesky factorizations without square root. + * + * This class provides a LDL^T Cholesky factorizations without square root of sparse matrices that are + * selfadjoint and positive definite. The factorization allows for solving A.X = B where + * X and B can be either dense or sparse. + * + * In order to reduce the fill-in, a symmetric permutation P is applied prior to the factorization + * such that the factorized matrix is P A P^-1. + * + * \tparam _MatrixType the type of the sparse matrix A, it must be a SparseMatrix<> + * \tparam _UpLo the triangular part that will be used for the computations. It can be Lower + * or Upper. Default is Lower. + * + * \sa class SimplicialLLT + */ +template + class SimplicialLDLT : public SimplicialCholeskyBase > +{ +public: + typedef _MatrixType MatrixType; + enum { UpLo = _UpLo }; + typedef SimplicialCholeskyBase Base; + typedef typename MatrixType::Scalar Scalar; + typedef typename MatrixType::RealScalar RealScalar; + typedef typename MatrixType::Index Index; + typedef SparseMatrix CholMatrixType; + typedef Matrix VectorType; + typedef internal::traits Traits; + typedef typename Traits::MatrixL MatrixL; + typedef typename Traits::MatrixU MatrixU; +public: + /** Default constructor */ + SimplicialLDLT() : Base() {} + + /** Constructs and performs the LLT factorization of \a matrix */ + SimplicialLDLT(const MatrixType& matrix) + : Base(matrix) {} + + /** \returns a vector expression of the diagonal D */ + inline const VectorType vectorD() const { + eigen_assert(Base::m_factorizationIsOk && "Simplicial LDLT not factorized"); + return Base::m_diag; + } + /** \returns an expression of the factor L */ + inline const MatrixL matrixL() const { + eigen_assert(Base::m_factorizationIsOk && "Simplicial LDLT not factorized"); + return Traits::getL(Base::m_matrix); + } + + /** \returns an expression of the factor U (= L^*) */ + inline const MatrixU matrixU() const { + eigen_assert(Base::m_factorizationIsOk && "Simplicial LDLT not factorized"); + return Traits::getU(Base::m_matrix); + } + + /** Computes the sparse Cholesky decomposition of \a matrix */ + SimplicialLDLT& compute(const MatrixType& matrix) + { + Base::template compute(matrix); + return *this; + } + + /** Performs a symbolic decomposition on the sparcity of \a matrix. + * + * This function is particularly useful when solving for several problems having the same structure. + * + * \sa factorize() + */ + void analyzePattern(const MatrixType& a) + { + Base::analyzePattern(a, true); + } + + /** Performs a numeric decomposition of \a matrix + * + * The given matrix must has the same sparcity than the matrix on which the symbolic decomposition has been performed. + * + * \sa analyzePattern() + */ + void factorize(const MatrixType& a) + { + Base::template factorize(a); + } + + /** \returns the determinant of the underlying matrix from the current factorization */ + Scalar determinant() const + { + return Base::m_diag.prod(); + } +}; + +/** \deprecated use SimplicialLDLT or class SimplicialLLT + * \ingroup SparseCholesky_Module + * \class SimplicialCholesky + * + * \sa class SimplicialLDLT, class SimplicialLLT + */ +template + class SimplicialCholesky : public SimplicialCholeskyBase > +{ +public: + typedef _MatrixType MatrixType; + enum { UpLo = _UpLo }; + typedef SimplicialCholeskyBase Base; + typedef typename MatrixType::Scalar Scalar; + typedef typename MatrixType::RealScalar RealScalar; + typedef typename MatrixType::Index Index; + typedef SparseMatrix CholMatrixType; + typedef Matrix VectorType; + typedef internal::traits Traits; + typedef internal::traits > LDLTTraits; + typedef internal::traits > LLTTraits; + public: + SimplicialCholesky() : Base(), m_LDLT(true) {} + + SimplicialCholesky(const MatrixType& matrix) + : Base(), m_LDLT(true) + { + compute(matrix); + } + + SimplicialCholesky& setMode(SimplicialCholeskyMode mode) + { + switch(mode) + { + case SimplicialCholeskyLLT: + m_LDLT = false; + break; + case SimplicialCholeskyLDLT: + m_LDLT = true; + break; + default: + break; + } + + return *this; + } + + inline const VectorType vectorD() const { + eigen_assert(Base::m_factorizationIsOk && "Simplicial Cholesky not factorized"); + return Base::m_diag; + } + inline const CholMatrixType rawMatrix() const { + eigen_assert(Base::m_factorizationIsOk && "Simplicial Cholesky not factorized"); + return Base::m_matrix; + } + + /** Computes the sparse Cholesky decomposition of \a matrix */ + SimplicialCholesky& compute(const MatrixType& matrix) + { + if(m_LDLT) + Base::template compute(matrix); + else + Base::template compute(matrix); + return *this; + } + + /** Performs a symbolic decomposition on the sparcity of \a matrix. + * + * This function is particularly useful when solving for several problems having the same structure. + * + * \sa factorize() + */ + void analyzePattern(const MatrixType& a) + { + Base::analyzePattern(a, m_LDLT); + } + + /** Performs a numeric decomposition of \a matrix + * + * The given matrix must has the same sparcity than the matrix on which the symbolic decomposition has been performed. + * + * \sa analyzePattern() + */ + void factorize(const MatrixType& a) + { + if(m_LDLT) + Base::template factorize(a); + else + Base::template factorize(a); + } + + /** \internal */ + template + void _solve(const MatrixBase &b, MatrixBase &dest) const + { + eigen_assert(Base::m_factorizationIsOk && "The decomposition is not in a valid state for solving, you must first call either compute() or symbolic()/numeric()"); + eigen_assert(Base::m_matrix.rows()==b.rows()); + + if(Base::m_info!=Success) + return; + + if(Base::m_P.size()>0) + dest = Base::m_P * b; + else + dest = b; + + if(Base::m_matrix.nonZeros()>0) // otherwise L==I + { + if(m_LDLT) + LDLTTraits::getL(Base::m_matrix).solveInPlace(dest); + else + LLTTraits::getL(Base::m_matrix).solveInPlace(dest); + } + + if(Base::m_diag.size()>0) + dest = Base::m_diag.asDiagonal().inverse() * dest; + + if (Base::m_matrix.nonZeros()>0) // otherwise I==I + { + if(m_LDLT) + LDLTTraits::getU(Base::m_matrix).solveInPlace(dest); + else + LLTTraits::getU(Base::m_matrix).solveInPlace(dest); + } + + if(Base::m_P.size()>0) + dest = Base::m_Pinv * dest; + } + + Scalar determinant() const + { + if(m_LDLT) + { + return Base::m_diag.prod(); + } + else + { + Scalar detL = Diagonal(Base::m_matrix).prod(); + return internal::abs2(detL); + } + } + + protected: + bool m_LDLT; +}; + +template +void SimplicialCholeskyBase::ordering(const MatrixType& a, CholMatrixType& ap) +{ + eigen_assert(a.rows()==a.cols()); + const Index size = a.rows(); + // TODO allows to configure the permutation + // Note that amd compute the inverse permutation + { + CholMatrixType C; + C = a.template selfadjointView(); + // remove diagonal entries: + // seems not to be needed + // C.prune(keep_diag()); + internal::minimum_degree_ordering(C, m_Pinv); + } + + if(m_Pinv.size()>0) + m_P = m_Pinv.inverse(); + else + m_P.resize(0); + + ap.resize(size,size); + ap.template selfadjointView() = a.template selfadjointView().twistedBy(m_P); +} + +template +void SimplicialCholeskyBase::analyzePattern_preordered(const CholMatrixType& ap, bool doLDLT) +{ + const Index size = ap.rows(); + m_matrix.resize(size, size); + m_parent.resize(size); + m_nonZerosPerCol.resize(size); + + ei_declare_aligned_stack_constructed_variable(Index, tags, size, 0); + + for(Index k = 0; k < size; ++k) + { + /* L(k,:) pattern: all nodes reachable in etree from nz in A(0:k-1,k) */ + m_parent[k] = -1; /* parent of k is not yet known */ + tags[k] = k; /* mark node k as visited */ + m_nonZerosPerCol[k] = 0; /* count of nonzeros in column k of L */ + for(typename CholMatrixType::InnerIterator it(ap,k); it; ++it) + { + Index i = it.index(); + if(i < k) + { + /* follow path from i to root of etree, stop at flagged node */ + for(; tags[i] != k; i = m_parent[i]) + { + /* find parent of i if not yet determined */ + if (m_parent[i] == -1) + m_parent[i] = k; + m_nonZerosPerCol[i]++; /* L (k,i) is nonzero */ + tags[i] = k; /* mark i as visited */ + } + } + } + } + + /* construct Lp index array from m_nonZerosPerCol column counts */ + Index* Lp = m_matrix.outerIndexPtr(); + Lp[0] = 0; + for(Index k = 0; k < size; ++k) + Lp[k+1] = Lp[k] + m_nonZerosPerCol[k] + (doLDLT ? 0 : 1); + + m_matrix.resizeNonZeros(Lp[size]); + + m_isInitialized = true; + m_info = Success; + m_analysisIsOk = true; + m_factorizationIsOk = false; +} + + +template +template +void SimplicialCholeskyBase::factorize_preordered(const CholMatrixType& ap) +{ + eigen_assert(m_analysisIsOk && "You must first call analyzePattern()"); + eigen_assert(ap.rows()==ap.cols()); + const Index size = ap.rows(); + eigen_assert(m_parent.size()==size); + eigen_assert(m_nonZerosPerCol.size()==size); + + const Index* Lp = m_matrix.outerIndexPtr(); + Index* Li = m_matrix.innerIndexPtr(); + Scalar* Lx = m_matrix.valuePtr(); + + ei_declare_aligned_stack_constructed_variable(Scalar, y, size, 0); + ei_declare_aligned_stack_constructed_variable(Index, pattern, size, 0); + ei_declare_aligned_stack_constructed_variable(Index, tags, size, 0); + + bool ok = true; + m_diag.resize(DoLDLT ? size : 0); + + for(Index k = 0; k < size; ++k) + { + // compute nonzero pattern of kth row of L, in topological order + y[k] = 0.0; // Y(0:k) is now all zero + Index top = size; // stack for pattern is empty + tags[k] = k; // mark node k as visited + m_nonZerosPerCol[k] = 0; // count of nonzeros in column k of L + for(typename MatrixType::InnerIterator it(ap,k); it; ++it) + { + Index i = it.index(); + if(i <= k) + { + y[i] += internal::conj(it.value()); /* scatter A(i,k) into Y (sum duplicates) */ + Index len; + for(len = 0; tags[i] != k; i = m_parent[i]) + { + pattern[len++] = i; /* L(k,i) is nonzero */ + tags[i] = k; /* mark i as visited */ + } + while(len > 0) + pattern[--top] = pattern[--len]; + } + } + + /* compute numerical values kth row of L (a sparse triangular solve) */ + + RealScalar d = internal::real(y[k]) * m_shiftScale + m_shiftOffset; // get D(k,k), apply the shift function, and clear Y(k) + y[k] = 0.0; + for(; top < size; ++top) + { + Index i = pattern[top]; /* pattern[top:n-1] is pattern of L(:,k) */ + Scalar yi = y[i]; /* get and clear Y(i) */ + y[i] = 0.0; + + /* the nonzero entry L(k,i) */ + Scalar l_ki; + if(DoLDLT) + l_ki = yi / m_diag[i]; + else + yi = l_ki = yi / Lx[Lp[i]]; + + Index p2 = Lp[i] + m_nonZerosPerCol[i]; + Index p; + for(p = Lp[i] + (DoLDLT ? 0 : 1); p < p2; ++p) + y[Li[p]] -= internal::conj(Lx[p]) * yi; + d -= internal::real(l_ki * internal::conj(yi)); + Li[p] = k; /* store L(k,i) in column form of L */ + Lx[p] = l_ki; + ++m_nonZerosPerCol[i]; /* increment count of nonzeros in col i */ + } + if(DoLDLT) + { + m_diag[k] = d; + if(d == RealScalar(0)) + { + ok = false; /* failure, D(k,k) is zero */ + break; + } + } + else + { + Index p = Lp[k] + m_nonZerosPerCol[k]++; + Li[p] = k ; /* store L(k,k) = sqrt (d) in column k */ + if(d <= RealScalar(0)) { + ok = false; /* failure, matrix is not positive definite */ + break; + } + Lx[p] = internal::sqrt(d) ; + } + } + + m_info = ok ? Success : NumericalIssue; + m_factorizationIsOk = true; +} + +namespace internal { + +template +struct solve_retval, Rhs> + : solve_retval_base, Rhs> +{ + typedef SimplicialCholeskyBase Dec; + EIGEN_MAKE_SOLVE_HELPERS(Dec,Rhs) + + template void evalTo(Dest& dst) const + { + dec().derived()._solve(rhs(),dst); + } +}; + +template +struct sparse_solve_retval, Rhs> + : sparse_solve_retval_base, Rhs> +{ + typedef SimplicialCholeskyBase Dec; + EIGEN_MAKE_SPARSE_SOLVE_HELPERS(Dec,Rhs) + + template void evalTo(Dest& dst) const + { + dec().derived()._solve_sparse(rhs(),dst); + } +}; + +} // end namespace internal + +} // end namespace Eigen + +#endif // EIGEN_SIMPLICIAL_CHOLESKY_H diff --git a/extern/Eigen3/Eigen/src/Sparse/AmbiVector.h b/extern/Eigen3/Eigen/src/SparseCore/AmbiVector.h similarity index 89% rename from extern/Eigen3/Eigen/src/Sparse/AmbiVector.h rename to extern/Eigen3/Eigen/src/SparseCore/AmbiVector.h index 2ea8ba3096b..6cfaadbaa9a 100644 --- a/extern/Eigen3/Eigen/src/Sparse/AmbiVector.h +++ b/extern/Eigen3/Eigen/src/SparseCore/AmbiVector.h @@ -3,28 +3,17 @@ // // Copyright (C) 2008 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_AMBIVECTOR_H #define EIGEN_AMBIVECTOR_H +namespace Eigen { + +namespace internal { + /** \internal * Hybrid sparse/dense vector class designed for intensive read-write operations. * @@ -299,7 +288,7 @@ class AmbiVector<_Scalar,_Index>::Iterator * In practice, all coefficients having a magnitude smaller than \a epsilon * are skipped. */ - Iterator(const AmbiVector& vec, RealScalar epsilon = RealScalar(0.1)*NumTraits::dummy_precision()) + Iterator(const AmbiVector& vec, RealScalar epsilon = 0) : m_vector(vec) { m_epsilon = epsilon; @@ -315,7 +304,7 @@ class AmbiVector<_Scalar,_Index>::Iterator { ListEl* EIGEN_RESTRICT llElements = reinterpret_cast(m_vector.m_buffer); m_currentEl = m_vector.m_llStart; - while (m_currentEl>=0 && internal::abs(llElements[m_currentEl].value)=0 && internal::abs(llElements[m_currentEl].value)<=m_epsilon) m_currentEl = llElements[m_currentEl].next; if (m_currentEl<0) { @@ -375,5 +364,8 @@ class AmbiVector<_Scalar,_Index>::Iterator bool m_isDense; // mode of the vector }; +} // end namespace internal + +} // end namespace Eigen #endif // EIGEN_AMBIVECTOR_H diff --git a/extern/Eigen3/Eigen/src/Sparse/CompressedStorage.h b/extern/Eigen3/Eigen/src/SparseCore/CompressedStorage.h similarity index 84% rename from extern/Eigen3/Eigen/src/Sparse/CompressedStorage.h rename to extern/Eigen3/Eigen/src/SparseCore/CompressedStorage.h index b3bde272ec2..85a998aff10 100644 --- a/extern/Eigen3/Eigen/src/Sparse/CompressedStorage.h +++ b/extern/Eigen3/Eigen/src/SparseCore/CompressedStorage.h @@ -3,29 +3,19 @@ // // Copyright (C) 2008 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_COMPRESSED_STORAGE_H #define EIGEN_COMPRESSED_STORAGE_H -/** Stores a sparse set of values as a list of values and a list of indices. +namespace Eigen { + +namespace internal { + +/** \internal + * Stores a sparse set of values as a list of values and a list of indices. * */ template @@ -218,8 +208,8 @@ class CompressedStorage Index* newIndices = new Index[size]; size_t copySize = (std::min)(size, m_size); // copy - memcpy(newValues, m_values, copySize * sizeof(Scalar)); - memcpy(newIndices, m_indices, copySize * sizeof(Index)); + internal::smart_copy(m_values, m_values+copySize, newValues); + internal::smart_copy(m_indices, m_indices+copySize, newIndices); // delete old stuff delete[] m_values; delete[] m_indices; @@ -236,4 +226,8 @@ class CompressedStorage }; +} // end namespace internal + +} // end namespace Eigen + #endif // EIGEN_COMPRESSED_STORAGE_H diff --git a/extern/Eigen3/Eigen/src/SparseCore/ConservativeSparseSparseProduct.h b/extern/Eigen3/Eigen/src/SparseCore/ConservativeSparseSparseProduct.h new file mode 100644 index 00000000000..16b5e1dba6c --- /dev/null +++ b/extern/Eigen3/Eigen/src/SparseCore/ConservativeSparseSparseProduct.h @@ -0,0 +1,245 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008-2011 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_CONSERVATIVESPARSESPARSEPRODUCT_H +#define EIGEN_CONSERVATIVESPARSESPARSEPRODUCT_H + +namespace Eigen { + +namespace internal { + +template +static void conservative_sparse_sparse_product_impl(const Lhs& lhs, const Rhs& rhs, ResultType& res) +{ + typedef typename remove_all::type::Scalar Scalar; + typedef typename remove_all::type::Index Index; + + // make sure to call innerSize/outerSize since we fake the storage order. + Index rows = lhs.innerSize(); + Index cols = rhs.outerSize(); + eigen_assert(lhs.outerSize() == rhs.innerSize()); + + std::vector mask(rows,false); + Matrix values(rows); + Matrix indices(rows); + + // estimate the number of non zero entries + // given a rhs column containing Y non zeros, we assume that the respective Y columns + // of the lhs differs in average of one non zeros, thus the number of non zeros for + // the product of a rhs column with the lhs is X+Y where X is the average number of non zero + // per column of the lhs. + // Therefore, we have nnz(lhs*rhs) = nnz(lhs) + nnz(rhs) + Index estimated_nnz_prod = lhs.nonZeros() + rhs.nonZeros(); + + res.setZero(); + res.reserve(Index(estimated_nnz_prod)); + // we compute each column of the result, one after the other + for (Index j=0; j use a quick sort + // otherwise => loop through the entire vector + // In order to avoid to perform an expensive log2 when the + // result is clearly very sparse we use a linear bound up to 200. + //if((nnz<200 && nnz1) std::sort(indices.data(),indices.data()+nnz); + for(int k=0; k::Flags&RowMajorBit, + int RhsStorageOrder = traits::Flags&RowMajorBit, + int ResStorageOrder = traits::Flags&RowMajorBit> +struct conservative_sparse_sparse_product_selector; + +template +struct conservative_sparse_sparse_product_selector +{ + typedef typename remove_all::type LhsCleaned; + typedef typename LhsCleaned::Scalar Scalar; + + static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res) + { + typedef SparseMatrix RowMajorMatrix; + typedef SparseMatrix ColMajorMatrix; + ColMajorMatrix resCol(lhs.rows(),rhs.cols()); + internal::conservative_sparse_sparse_product_impl(lhs, rhs, resCol); + // sort the non zeros: + RowMajorMatrix resRow(resCol); + res = resRow; + } +}; + +template +struct conservative_sparse_sparse_product_selector +{ + static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res) + { + typedef SparseMatrix RowMajorMatrix; + RowMajorMatrix rhsRow = rhs; + RowMajorMatrix resRow(lhs.rows(), rhs.cols()); + internal::conservative_sparse_sparse_product_impl(rhsRow, lhs, resRow); + res = resRow; + } +}; + +template +struct conservative_sparse_sparse_product_selector +{ + static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res) + { + typedef SparseMatrix RowMajorMatrix; + RowMajorMatrix lhsRow = lhs; + RowMajorMatrix resRow(lhs.rows(), rhs.cols()); + internal::conservative_sparse_sparse_product_impl(rhs, lhsRow, resRow); + res = resRow; + } +}; + +template +struct conservative_sparse_sparse_product_selector +{ + static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res) + { + typedef SparseMatrix RowMajorMatrix; + RowMajorMatrix resRow(lhs.rows(), rhs.cols()); + internal::conservative_sparse_sparse_product_impl(rhs, lhs, resRow); + res = resRow; + } +}; + + +template +struct conservative_sparse_sparse_product_selector +{ + typedef typename traits::type>::Scalar Scalar; + + static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res) + { + typedef SparseMatrix ColMajorMatrix; + ColMajorMatrix resCol(lhs.rows(), rhs.cols()); + internal::conservative_sparse_sparse_product_impl(lhs, rhs, resCol); + res = resCol; + } +}; + +template +struct conservative_sparse_sparse_product_selector +{ + static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res) + { + typedef SparseMatrix ColMajorMatrix; + ColMajorMatrix lhsCol = lhs; + ColMajorMatrix resCol(lhs.rows(), rhs.cols()); + internal::conservative_sparse_sparse_product_impl(lhsCol, rhs, resCol); + res = resCol; + } +}; + +template +struct conservative_sparse_sparse_product_selector +{ + static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res) + { + typedef SparseMatrix ColMajorMatrix; + ColMajorMatrix rhsCol = rhs; + ColMajorMatrix resCol(lhs.rows(), rhs.cols()); + internal::conservative_sparse_sparse_product_impl(lhs, rhsCol, resCol); + res = resCol; + } +}; + +template +struct conservative_sparse_sparse_product_selector +{ + static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res) + { + typedef SparseMatrix RowMajorMatrix; + typedef SparseMatrix ColMajorMatrix; + RowMajorMatrix resRow(lhs.rows(),rhs.cols()); + internal::conservative_sparse_sparse_product_impl(rhs, lhs, resRow); + // sort the non zeros: + ColMajorMatrix resCol(resRow); + res = resCol; + } +}; + +} // end namespace internal + +} // end namespace Eigen + +#endif // EIGEN_CONSERVATIVESPARSESPARSEPRODUCT_H diff --git a/extern/Eigen3/Eigen/src/Sparse/CoreIterators.h b/extern/Eigen3/Eigen/src/SparseCore/CoreIterators.h similarity index 62% rename from extern/Eigen3/Eigen/src/Sparse/CoreIterators.h rename to extern/Eigen3/Eigen/src/SparseCore/CoreIterators.h index b4beaeee69e..6da4683d2c2 100644 --- a/extern/Eigen3/Eigen/src/Sparse/CoreIterators.h +++ b/extern/Eigen3/Eigen/src/SparseCore/CoreIterators.h @@ -3,32 +3,20 @@ // // Copyright (C) 2008-2010 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_COREITERATORS_H #define EIGEN_COREITERATORS_H +namespace Eigen { + /* This file contains the respective InnerIterator definition of the expressions defined in Eigen/Core */ -/** \class InnerIterator +/** \ingroup SparseCore_Module + * \class InnerIterator * \brief An InnerIterator allows to loop over the element of a sparse (or dense) matrix or expression * * todo @@ -68,4 +56,6 @@ template class DenseBase::InnerIterator const Index m_end; }; +} // end namespace Eigen + #endif // EIGEN_COREITERATORS_H diff --git a/extern/Eigen3/Eigen/src/Sparse/MappedSparseMatrix.h b/extern/Eigen3/Eigen/src/SparseCore/MappedSparseMatrix.h similarity index 68% rename from extern/Eigen3/Eigen/src/Sparse/MappedSparseMatrix.h rename to extern/Eigen3/Eigen/src/SparseCore/MappedSparseMatrix.h index 31a431fb224..93cd4832dea 100644 --- a/extern/Eigen3/Eigen/src/Sparse/MappedSparseMatrix.h +++ b/extern/Eigen3/Eigen/src/SparseCore/MappedSparseMatrix.h @@ -3,28 +3,15 @@ // // Copyright (C) 2008 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_MAPPED_SPARSEMATRIX_H #define EIGEN_MAPPED_SPARSEMATRIX_H +namespace Eigen { + /** \class MappedSparseMatrix * * \brief Sparse matrix @@ -46,9 +33,9 @@ class MappedSparseMatrix { public: EIGEN_SPARSE_PUBLIC_INTERFACE(MappedSparseMatrix) + enum { IsRowMajor = Base::IsRowMajor }; protected: - enum { IsRowMajor = Base::IsRowMajor }; Index m_outerSize; Index m_innerSize; @@ -63,18 +50,17 @@ class MappedSparseMatrix inline Index cols() const { return IsRowMajor ? m_innerSize : m_outerSize; } inline Index innerSize() const { return m_innerSize; } inline Index outerSize() const { return m_outerSize; } - inline Index innerNonZeros(Index j) const { return m_outerIndex[j+1]-m_outerIndex[j]; } //---------------------------------------- // direct access interface - inline const Scalar* _valuePtr() const { return m_values; } - inline Scalar* _valuePtr() { return m_values; } + inline const Scalar* valuePtr() const { return m_values; } + inline Scalar* valuePtr() { return m_values; } - inline const Index* _innerIndexPtr() const { return m_innerIndices; } - inline Index* _innerIndexPtr() { return m_innerIndices; } + inline const Index* innerIndexPtr() const { return m_innerIndices; } + inline Index* innerIndexPtr() { return m_innerIndices; } - inline const Index* _outerIndexPtr() const { return m_outerIndex; } - inline Index* _outerIndexPtr() { return m_outerIndex; } + inline const Index* outerIndexPtr() const { return m_outerIndex; } + inline Index* outerIndexPtr() { return m_outerIndex; } //---------------------------------------- inline Scalar coeff(Index row, Index col) const @@ -112,6 +98,7 @@ class MappedSparseMatrix } class InnerIterator; + class ReverseInnerIterator; /** \returns the number of non zero coefficients */ inline Index nonZeros() const { return m_nnz; } @@ -132,23 +119,17 @@ class MappedSparseMatrix::InnerIterator InnerIterator(const MappedSparseMatrix& mat, Index outer) : m_matrix(mat), m_outer(outer), - m_id(mat._outerIndexPtr()[outer]), + m_id(mat.outerIndexPtr()[outer]), m_start(m_id), - m_end(mat._outerIndexPtr()[outer+1]) - {} - - template - InnerIterator(const Flagged& mat, Index outer) - : m_matrix(mat._expression()), m_id(m_matrix._outerIndexPtr()[outer]), - m_start(m_id), m_end(m_matrix._outerIndexPtr()[outer+1]) + m_end(mat.outerIndexPtr()[outer+1]) {} inline InnerIterator& operator++() { m_id++; return *this; } - inline Scalar value() const { return m_matrix._valuePtr()[m_id]; } - inline Scalar& valueRef() { return const_cast(m_matrix._valuePtr()[m_id]); } + inline Scalar value() const { return m_matrix.valuePtr()[m_id]; } + inline Scalar& valueRef() { return const_cast(m_matrix.valuePtr()[m_id]); } - inline Index index() const { return m_matrix._innerIndexPtr()[m_id]; } + inline Index index() const { return m_matrix.innerIndexPtr()[m_id]; } inline Index row() const { return IsRowMajor ? m_outer : index(); } inline Index col() const { return IsRowMajor ? index() : m_outer; } @@ -162,4 +143,37 @@ class MappedSparseMatrix::InnerIterator const Index m_end; }; +template +class MappedSparseMatrix::ReverseInnerIterator +{ + public: + ReverseInnerIterator(const MappedSparseMatrix& mat, Index outer) + : m_matrix(mat), + m_outer(outer), + m_id(mat.outerIndexPtr()[outer+1]), + m_start(mat.outerIndexPtr()[outer]), + m_end(m_id) + {} + + inline ReverseInnerIterator& operator--() { m_id--; return *this; } + + inline Scalar value() const { return m_matrix.valuePtr()[m_id-1]; } + inline Scalar& valueRef() { return const_cast(m_matrix.valuePtr()[m_id-1]); } + + inline Index index() const { return m_matrix.innerIndexPtr()[m_id-1]; } + inline Index row() const { return IsRowMajor ? m_outer : index(); } + inline Index col() const { return IsRowMajor ? index() : m_outer; } + + inline operator bool() const { return (m_id <= m_end) && (m_id>m_start); } + + protected: + const MappedSparseMatrix& m_matrix; + const Index m_outer; + Index m_id; + const Index m_start; + const Index m_end; +}; + +} // end namespace Eigen + #endif // EIGEN_MAPPED_SPARSEMATRIX_H diff --git a/extern/Eigen3/Eigen/src/Sparse/SparseAssign.h b/extern/Eigen3/Eigen/src/SparseCore/SparseAssign.h similarity index 100% rename from extern/Eigen3/Eigen/src/Sparse/SparseAssign.h rename to extern/Eigen3/Eigen/src/SparseCore/SparseAssign.h diff --git a/extern/Eigen3/Eigen/src/Sparse/SparseBlock.h b/extern/Eigen3/Eigen/src/SparseCore/SparseBlock.h similarity index 66% rename from extern/Eigen3/Eigen/src/Sparse/SparseBlock.h rename to extern/Eigen3/Eigen/src/SparseCore/SparseBlock.h index 8079c999994..eefd8070251 100644 --- a/extern/Eigen3/Eigen/src/Sparse/SparseBlock.h +++ b/extern/Eigen3/Eigen/src/SparseCore/SparseBlock.h @@ -3,28 +3,15 @@ // // Copyright (C) 2008-2009 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_SPARSE_BLOCK_H #define EIGEN_SPARSE_BLOCK_H +namespace Eigen { + namespace internal { template struct traits > @@ -65,6 +52,17 @@ class SparseInnerVectorSet : internal::no_assignment_operator, protected: Index m_outer; }; + class ReverseInnerIterator: public MatrixType::ReverseInnerIterator + { + public: + inline ReverseInnerIterator(const SparseInnerVectorSet& xpr, Index outer) + : MatrixType::ReverseInnerIterator(xpr.m_matrix, xpr.m_outerStart + outer), m_outer(outer) + {} + inline Index row() const { return IsRowMajor ? m_outer : this->index(); } + inline Index col() const { return IsRowMajor ? this->index() : m_outer; } + protected: + Index m_outer; + }; inline SparseInnerVectorSet(const MatrixType& matrix, Index outerStart, Index outerSize) : m_matrix(matrix), m_outerStart(outerStart), m_outerSize(outerSize) @@ -101,15 +99,16 @@ class SparseInnerVectorSet : internal::no_assignment_operator, const internal::variable_if_dynamic m_outerSize; }; + /*************************************************************************** -* specialisation for DynamicSparseMatrix +* specialisation for SparseMatrix ***************************************************************************/ -template -class SparseInnerVectorSet, Size> - : public SparseMatrixBase, Size> > +template +class SparseInnerVectorSet, Size> + : public SparseMatrixBase, Size> > { - typedef DynamicSparseMatrix<_Scalar, _Options> MatrixType; + typedef SparseMatrix<_Scalar, _Options, _Index> MatrixType; public: enum { IsRowMajor = internal::traits::IsRowMajor }; @@ -126,98 +125,11 @@ class SparseInnerVectorSet, Size> protected: Index m_outer; }; - - inline SparseInnerVectorSet(const MatrixType& matrix, Index outerStart, Index outerSize) - : m_matrix(matrix), m_outerStart(outerStart), m_outerSize(outerSize) - { - eigen_assert( (outerStart>=0) && ((outerStart+outerSize)<=matrix.outerSize()) ); - } - - inline SparseInnerVectorSet(const MatrixType& matrix, Index outer) - : m_matrix(matrix), m_outerStart(outer), m_outerSize(Size) - { - eigen_assert(Size!=Dynamic); - eigen_assert( (outer>=0) && (outer - inline SparseInnerVectorSet& operator=(const SparseMatrixBase& other) - { - if (IsRowMajor != ((OtherDerived::Flags&RowMajorBit)==RowMajorBit)) - { - // need to transpose => perform a block evaluation followed by a big swap - DynamicSparseMatrix aux(other); - *this = aux.markAsRValue(); - } - else - { - // evaluate/copy vector per vector - for (Index j=0; j aux(other.innerVector(j)); - m_matrix.const_cast_derived()._data()[m_outerStart+j].swap(aux._data()); - } - } - return *this; - } - - inline SparseInnerVectorSet& operator=(const SparseInnerVectorSet& other) - { - return operator=(other); - } - - Index nonZeros() const - { - Index count = 0; - for (Index j=0; j0); - return m_matrix.data()[m_outerStart].vale(m_matrix.data()[m_outerStart].size()-1); - } - -// template -// inline SparseInnerVectorSet& operator=(const SparseMatrixBase& other) -// { -// return *this; -// } - - EIGEN_STRONG_INLINE Index rows() const { return IsRowMajor ? m_outerSize.value() : m_matrix.rows(); } - EIGEN_STRONG_INLINE Index cols() const { return IsRowMajor ? m_matrix.cols() : m_outerSize.value(); } - - protected: - - const typename MatrixType::Nested m_matrix; - Index m_outerStart; - const internal::variable_if_dynamic m_outerSize; - -}; - - -/*************************************************************************** -* specialisation for SparseMatrix -***************************************************************************/ - -template -class SparseInnerVectorSet, Size> - : public SparseMatrixBase, Size> > -{ - typedef SparseMatrix<_Scalar, _Options> MatrixType; - public: - - enum { IsRowMajor = internal::traits::IsRowMajor }; - - EIGEN_SPARSE_PUBLIC_INTERFACE(SparseInnerVectorSet) - class InnerIterator: public MatrixType::InnerIterator + class ReverseInnerIterator: public MatrixType::ReverseInnerIterator { public: - inline InnerIterator(const SparseInnerVectorSet& xpr, Index outer) - : MatrixType::InnerIterator(xpr.m_matrix, xpr.m_outerStart + outer), m_outer(outer) + inline ReverseInnerIterator(const SparseInnerVectorSet& xpr, Index outer) + : MatrixType::ReverseInnerIterator(xpr.m_matrix, xpr.m_outerStart + outer), m_outer(outer) {} inline Index row() const { return IsRowMajor ? m_outer : this->index(); } inline Index col() const { return IsRowMajor ? this->index() : m_outer; } @@ -243,19 +155,19 @@ class SparseInnerVectorSet, Size> { typedef typename internal::remove_all::type _NestedMatrixType; _NestedMatrixType& matrix = const_cast<_NestedMatrixType&>(m_matrix);; - // This assignement is slow if this vector set not empty + // This assignement is slow if this vector set is not empty // and/or it is not at the end of the nonzeros of the underlying matrix. // 1 - eval to a temporary to avoid transposition and/or aliasing issues SparseMatrix tmp(other); // 2 - let's check whether there is enough allocated memory - Index nnz = tmp.nonZeros(); - Index nnz_previous = nonZeros(); - Index free_size = matrix.data().allocatedSize() - nnz_previous; - std::size_t nnz_head = m_outerStart==0 ? 0 : matrix._outerIndexPtr()[m_outerStart]; - std::size_t tail = m_matrix._outerIndexPtr()[m_outerStart+m_outerSize.value()]; - std::size_t nnz_tail = matrix.nonZeros() - tail; + Index nnz = tmp.nonZeros(); + Index nnz_previous = nonZeros(); + Index free_size = Index(matrix.data().allocatedSize()) + nnz_previous; + Index nnz_head = m_outerStart==0 ? 0 : matrix.outerIndexPtr()[m_outerStart]; + Index tail = m_matrix.outerIndexPtr()[m_outerStart+m_outerSize.value()]; + Index nnz_tail = matrix.nonZeros() - tail; if(nnz>free_size) { @@ -298,15 +210,15 @@ class SparseInnerVectorSet, Size> // update outer index pointers Index p = nnz_head; - for(Index k=1; k, Size> return operator=(other); } - inline const Scalar* _valuePtr() const - { return m_matrix._valuePtr() + m_matrix._outerIndexPtr()[m_outerStart]; } - inline Scalar* _valuePtr() - { return m_matrix.const_cast_derived()._valuePtr() + m_matrix._outerIndexPtr()[m_outerStart]; } + inline const Scalar* valuePtr() const + { return m_matrix.valuePtr() + m_matrix.outerIndexPtr()[m_outerStart]; } + inline Scalar* valuePtr() + { return m_matrix.const_cast_derived().valuePtr() + m_matrix.outerIndexPtr()[m_outerStart]; } - inline const Index* _innerIndexPtr() const - { return m_matrix._innerIndexPtr() + m_matrix._outerIndexPtr()[m_outerStart]; } - inline Index* _innerIndexPtr() - { return m_matrix.const_cast_derived()._innerIndexPtr() + m_matrix._outerIndexPtr()[m_outerStart]; } + inline const Index* innerIndexPtr() const + { return m_matrix.innerIndexPtr() + m_matrix.outerIndexPtr()[m_outerStart]; } + inline Index* innerIndexPtr() + { return m_matrix.const_cast_derived().innerIndexPtr() + m_matrix.outerIndexPtr()[m_outerStart]; } - inline const Index* _outerIndexPtr() const - { return m_matrix._outerIndexPtr() + m_outerStart; } - inline Index* _outerIndexPtr() - { return m_matrix.const_cast_derived()._outerIndexPtr() + m_outerStart; } + inline const Index* outerIndexPtr() const + { return m_matrix.outerIndexPtr() + m_outerStart; } + inline Index* outerIndexPtr() + { return m_matrix.const_cast_derived().outerIndexPtr() + m_outerStart; } Index nonZeros() const { - return std::size_t(m_matrix._outerIndexPtr()[m_outerStart+m_outerSize.value()]) - - std::size_t(m_matrix._outerIndexPtr()[m_outerStart]); + if(m_matrix.isCompressed()) + return std::size_t(m_matrix.outerIndexPtr()[m_outerStart+m_outerSize.value()]) + - std::size_t(m_matrix.outerIndexPtr()[m_outerStart]); + else if(m_outerSize.value()==0) + return 0; + else + return Map >(m_matrix.innerNonZeroPtr()+m_outerStart, m_outerSize.value()).sum(); } const Scalar& lastCoeff() const { EIGEN_STATIC_ASSERT_VECTOR_ONLY(SparseInnerVectorSet); eigen_assert(nonZeros()>0); - return m_matrix._valuePtr()[m_matrix._outerIndexPtr()[m_outerStart+1]-1]; + if(m_matrix.isCompressed()) + return m_matrix.valuePtr()[m_matrix.outerIndexPtr()[m_outerStart+1]-1]; + else + return m_matrix.valuePtr()[m_matrix.outerIndexPtr()[m_outerStart]+m_matrix.innerNonZeroPtr()[m_outerStart]-1]; } // template @@ -356,7 +276,7 @@ class SparseInnerVectorSet, Size> protected: - const typename MatrixType::Nested m_matrix; + typename MatrixType::Nested m_matrix; Index m_outerStart; const internal::variable_if_dynamic m_outerSize; @@ -412,11 +332,9 @@ template const SparseInnerVectorSet SparseMatrixBase::innerVector(Index outer) const { return SparseInnerVectorSet(derived(), outer); } -//---------- - /** \returns the i-th row of the matrix \c *this. For row-major matrix only. */ template -SparseInnerVectorSet SparseMatrixBase::subrows(Index start, Index size) +SparseInnerVectorSet SparseMatrixBase::middleRows(Index start, Index size) { EIGEN_STATIC_ASSERT(IsRowMajor,THIS_METHOD_IS_ONLY_FOR_ROW_MAJOR_MATRICES); return innerVectors(start, size); @@ -425,7 +343,7 @@ SparseInnerVectorSet SparseMatrixBase::subrows(Index s /** \returns the i-th row of the matrix \c *this. For row-major matrix only. * (read-only version) */ template -const SparseInnerVectorSet SparseMatrixBase::subrows(Index start, Index size) const +const SparseInnerVectorSet SparseMatrixBase::middleRows(Index start, Index size) const { EIGEN_STATIC_ASSERT(IsRowMajor,THIS_METHOD_IS_ONLY_FOR_ROW_MAJOR_MATRICES); return innerVectors(start, size); @@ -433,7 +351,7 @@ const SparseInnerVectorSet SparseMatrixBase::subrows(I /** \returns the i-th column of the matrix \c *this. For column-major matrix only. */ template -SparseInnerVectorSet SparseMatrixBase::subcols(Index start, Index size) +SparseInnerVectorSet SparseMatrixBase::middleCols(Index start, Index size) { EIGEN_STATIC_ASSERT(!IsRowMajor,THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES); return innerVectors(start, size); @@ -442,12 +360,14 @@ SparseInnerVectorSet SparseMatrixBase::subcols(Index s /** \returns the i-th column of the matrix \c *this. For column-major matrix only. * (read-only version) */ template -const SparseInnerVectorSet SparseMatrixBase::subcols(Index start, Index size) const +const SparseInnerVectorSet SparseMatrixBase::middleCols(Index start, Index size) const { EIGEN_STATIC_ASSERT(!IsRowMajor,THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES); return innerVectors(start, size); } + + /** \returns the \a outer -th column (resp. row) of the matrix \c *this if \c *this * is col-major (resp. row-major). */ @@ -462,4 +382,6 @@ template const SparseInnerVectorSet SparseMatrixBase::innerVectors(Index outerStart, Index outerSize) const { return SparseInnerVectorSet(derived(), outerStart, outerSize); } +} // end namespace Eigen + #endif // EIGEN_SPARSE_BLOCK_H diff --git a/extern/Eigen3/Eigen/src/Sparse/SparseCwiseBinaryOp.h b/extern/Eigen3/Eigen/src/SparseCore/SparseCwiseBinaryOp.h similarity index 77% rename from extern/Eigen3/Eigen/src/Sparse/SparseCwiseBinaryOp.h rename to extern/Eigen3/Eigen/src/SparseCore/SparseCwiseBinaryOp.h index cde5bbc0300..d5f97f78fc9 100644 --- a/extern/Eigen3/Eigen/src/Sparse/SparseCwiseBinaryOp.h +++ b/extern/Eigen3/Eigen/src/SparseCore/SparseCwiseBinaryOp.h @@ -3,28 +3,15 @@ // // Copyright (C) 2008 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_SPARSE_CWISE_BINARY_OP_H #define EIGEN_SPARSE_CWISE_BINARY_OP_H +namespace Eigen { + // Here we have to handle 3 cases: // 1 - sparse op dense // 2 - dense op sparse @@ -63,8 +50,18 @@ class CwiseBinaryOpImpl { public: class InnerIterator; + class ReverseInnerIterator; typedef CwiseBinaryOp Derived; EIGEN_SPARSE_PUBLIC_INTERFACE(Derived) + CwiseBinaryOpImpl() + { + typedef typename internal::traits::StorageKind LhsStorageKind; + typedef typename internal::traits::StorageKind RhsStorageKind; + EIGEN_STATIC_ASSERT(( + (!internal::is_same::value) + || ((Lhs::Flags&RowMajorBit) == (Rhs::Flags&RowMajorBit))), + THE_STORAGE_ORDER_OF_BOTH_SIDES_MUST_MATCH); + } }; template @@ -76,7 +73,7 @@ class CwiseBinaryOpImpl::InnerIterator typedef internal::sparse_cwise_binary_op_inner_iterator_selector< BinaryOp,Lhs,Rhs, InnerIterator> Base; - EIGEN_STRONG_INLINE InnerIterator(const CwiseBinaryOpImpl& binOp, Index outer) + EIGEN_STRONG_INLINE InnerIterator(const CwiseBinaryOpImpl& binOp, typename CwiseBinaryOpImpl::Index outer) : Base(binOp.derived(),outer) {} }; @@ -246,7 +243,7 @@ class sparse_cwise_binary_op_inner_iterator_selector, Lhs, EIGEN_STRONG_INLINE operator bool() const { return m_lhsIter; } protected: - const RhsNested m_rhs; + RhsNested m_rhs; LhsIterator m_lhsIter; const BinaryFunc m_functor; const Index m_outer; @@ -298,16 +295,6 @@ class sparse_cwise_binary_op_inner_iterator_selector, Lhs, * Implementation of SparseMatrixBase and SparseCwise functions/operators ***************************************************************************/ -// template -// template -// EIGEN_STRONG_INLINE const CwiseBinaryOp::Scalar>, -// Derived, OtherDerived> -// SparseMatrixBase::operator-(const SparseMatrixBase &other) const -// { -// return CwiseBinaryOp, -// Derived, OtherDerived>(derived(), other.derived()); -// } - template template EIGEN_STRONG_INLINE Derived & @@ -316,14 +303,6 @@ SparseMatrixBase::operator-=(const SparseMatrixBase &othe return *this = derived() - other.derived(); } -// template -// template -// EIGEN_STRONG_INLINE const CwiseBinaryOp::Scalar>, Derived, OtherDerived> -// SparseMatrixBase::operator+(const SparseMatrixBase &other) const -// { -// return CwiseBinaryOp, Derived, OtherDerived>(derived(), other.derived()); -// } - template template EIGEN_STRONG_INLINE Derived & @@ -332,14 +311,6 @@ SparseMatrixBase::operator+=(const SparseMatrixBase& othe return *this = derived() + other.derived(); } -// template -// template -// EIGEN_STRONG_INLINE const EIGEN_SPARSE_CWISE_PRODUCT_RETURN_TYPE -// SparseCwise::operator*(const SparseMatrixBase &other) const -// { -// return EIGEN_SPARSE_CWISE_PRODUCT_RETURN_TYPE(_expression(), other.derived()); -// } - template template EIGEN_STRONG_INLINE const EIGEN_SPARSE_CWISE_PRODUCT_RETURN_TYPE @@ -348,28 +319,6 @@ SparseMatrixBase::cwiseProduct(const MatrixBase &other) c return EIGEN_SPARSE_CWISE_PRODUCT_RETURN_TYPE(derived(), other.derived()); } -// template -// template -// EIGEN_STRONG_INLINE const EIGEN_SPARSE_CWISE_BINOP_RETURN_TYPE(internal::scalar_quotient_op) -// SparseCwise::operator/(const SparseMatrixBase &other) const -// { -// return EIGEN_SPARSE_CWISE_BINOP_RETURN_TYPE(internal::scalar_quotient_op)(_expression(), other.derived()); -// } -// -// template -// template -// EIGEN_STRONG_INLINE const EIGEN_SPARSE_CWISE_BINOP_RETURN_TYPE(internal::scalar_quotient_op) -// SparseCwise::operator/(const MatrixBase &other) const -// { -// return EIGEN_SPARSE_CWISE_BINOP_RETURN_TYPE(internal::scalar_quotient_op)(_expression(), other.derived()); -// } - -// template -// template -// inline ExpressionType& SparseCwise::operator*=(const SparseMatrixBase &other) -// { -// return m_matrix.const_cast_derived() = _expression() * other.derived(); -// } - +} // end namespace Eigen #endif // EIGEN_SPARSE_CWISE_BINARY_OP_H diff --git a/extern/Eigen3/Eigen/src/SparseCore/SparseCwiseUnaryOp.h b/extern/Eigen3/Eigen/src/SparseCore/SparseCwiseUnaryOp.h new file mode 100644 index 00000000000..5a50c780303 --- /dev/null +++ b/extern/Eigen3/Eigen/src/SparseCore/SparseCwiseUnaryOp.h @@ -0,0 +1,163 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008-2010 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_SPARSE_CWISE_UNARY_OP_H +#define EIGEN_SPARSE_CWISE_UNARY_OP_H + +namespace Eigen { + +template +class CwiseUnaryOpImpl + : public SparseMatrixBase > +{ + public: + + class InnerIterator; + class ReverseInnerIterator; + + typedef CwiseUnaryOp Derived; + EIGEN_SPARSE_PUBLIC_INTERFACE(Derived) + + protected: + typedef typename internal::traits::_XprTypeNested _MatrixTypeNested; + typedef typename _MatrixTypeNested::InnerIterator MatrixTypeIterator; + typedef typename _MatrixTypeNested::ReverseInnerIterator MatrixTypeReverseIterator; +}; + +template +class CwiseUnaryOpImpl::InnerIterator + : public CwiseUnaryOpImpl::MatrixTypeIterator +{ + typedef typename CwiseUnaryOpImpl::Scalar Scalar; + typedef typename CwiseUnaryOpImpl::MatrixTypeIterator Base; + public: + + EIGEN_STRONG_INLINE InnerIterator(const CwiseUnaryOpImpl& unaryOp, typename CwiseUnaryOpImpl::Index outer) + : Base(unaryOp.derived().nestedExpression(),outer), m_functor(unaryOp.derived().functor()) + {} + + EIGEN_STRONG_INLINE InnerIterator& operator++() + { Base::operator++(); return *this; } + + EIGEN_STRONG_INLINE typename CwiseUnaryOpImpl::Scalar value() const { return m_functor(Base::value()); } + + protected: + const UnaryOp m_functor; + private: + typename CwiseUnaryOpImpl::Scalar& valueRef(); +}; + +template +class CwiseUnaryOpImpl::ReverseInnerIterator + : public CwiseUnaryOpImpl::MatrixTypeReverseIterator +{ + typedef typename CwiseUnaryOpImpl::Scalar Scalar; + typedef typename CwiseUnaryOpImpl::MatrixTypeReverseIterator Base; + public: + + EIGEN_STRONG_INLINE ReverseInnerIterator(const CwiseUnaryOpImpl& unaryOp, typename CwiseUnaryOpImpl::Index outer) + : Base(unaryOp.derived().nestedExpression(),outer), m_functor(unaryOp.derived().functor()) + {} + + EIGEN_STRONG_INLINE ReverseInnerIterator& operator--() + { Base::operator--(); return *this; } + + EIGEN_STRONG_INLINE typename CwiseUnaryOpImpl::Scalar value() const { return m_functor(Base::value()); } + + protected: + const UnaryOp m_functor; + private: + typename CwiseUnaryOpImpl::Scalar& valueRef(); +}; + +template +class CwiseUnaryViewImpl + : public SparseMatrixBase > +{ + public: + + class InnerIterator; + class ReverseInnerIterator; + + typedef CwiseUnaryView Derived; + EIGEN_SPARSE_PUBLIC_INTERFACE(Derived) + + protected: + typedef typename internal::traits::_MatrixTypeNested _MatrixTypeNested; + typedef typename _MatrixTypeNested::InnerIterator MatrixTypeIterator; + typedef typename _MatrixTypeNested::ReverseInnerIterator MatrixTypeReverseIterator; +}; + +template +class CwiseUnaryViewImpl::InnerIterator + : public CwiseUnaryViewImpl::MatrixTypeIterator +{ + typedef typename CwiseUnaryViewImpl::Scalar Scalar; + typedef typename CwiseUnaryViewImpl::MatrixTypeIterator Base; + public: + + EIGEN_STRONG_INLINE InnerIterator(const CwiseUnaryViewImpl& unaryOp, typename CwiseUnaryViewImpl::Index outer) + : Base(unaryOp.derived().nestedExpression(),outer), m_functor(unaryOp.derived().functor()) + {} + + EIGEN_STRONG_INLINE InnerIterator& operator++() + { Base::operator++(); return *this; } + + EIGEN_STRONG_INLINE typename CwiseUnaryViewImpl::Scalar value() const { return m_functor(Base::value()); } + EIGEN_STRONG_INLINE typename CwiseUnaryViewImpl::Scalar& valueRef() { return m_functor(Base::valueRef()); } + + protected: + const ViewOp m_functor; +}; + +template +class CwiseUnaryViewImpl::ReverseInnerIterator + : public CwiseUnaryViewImpl::MatrixTypeReverseIterator +{ + typedef typename CwiseUnaryViewImpl::Scalar Scalar; + typedef typename CwiseUnaryViewImpl::MatrixTypeReverseIterator Base; + public: + + EIGEN_STRONG_INLINE ReverseInnerIterator(const CwiseUnaryViewImpl& unaryOp, typename CwiseUnaryViewImpl::Index outer) + : Base(unaryOp.derived().nestedExpression(),outer), m_functor(unaryOp.derived().functor()) + {} + + EIGEN_STRONG_INLINE ReverseInnerIterator& operator--() + { Base::operator--(); return *this; } + + EIGEN_STRONG_INLINE typename CwiseUnaryViewImpl::Scalar value() const { return m_functor(Base::value()); } + EIGEN_STRONG_INLINE typename CwiseUnaryViewImpl::Scalar& valueRef() { return m_functor(Base::valueRef()); } + + protected: + const ViewOp m_functor; +}; + +template +EIGEN_STRONG_INLINE Derived& +SparseMatrixBase::operator*=(const Scalar& other) +{ + for (Index j=0; j +EIGEN_STRONG_INLINE Derived& +SparseMatrixBase::operator/=(const Scalar& other) +{ + for (Index j=0; j // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_SPARSEDENSEPRODUCT_H #define EIGEN_SPARSEDENSEPRODUCT_H +namespace Eigen { + template struct SparseDenseProductReturnType { typedef SparseTimeDenseProduct Type; @@ -149,6 +136,102 @@ struct traits > typedef Dense StorageKind; typedef MatrixXpr XprKind; }; + +template +struct sparse_time_dense_product_impl; + +template +struct sparse_time_dense_product_impl +{ + typedef typename internal::remove_all::type Lhs; + typedef typename internal::remove_all::type Rhs; + typedef typename internal::remove_all::type Res; + typedef typename Lhs::Index Index; + typedef typename Lhs::InnerIterator LhsInnerIterator; + static void run(const SparseLhsType& lhs, const DenseRhsType& rhs, DenseResType& res, typename Res::Scalar alpha) + { + for(Index c=0; c +struct sparse_time_dense_product_impl +{ + typedef typename internal::remove_all::type Lhs; + typedef typename internal::remove_all::type Rhs; + typedef typename internal::remove_all::type Res; + typedef typename Lhs::InnerIterator LhsInnerIterator; + typedef typename Lhs::Index Index; + static void run(const SparseLhsType& lhs, const DenseRhsType& rhs, DenseResType& res, typename Res::Scalar alpha) + { + for(Index c=0; c +struct sparse_time_dense_product_impl +{ + typedef typename internal::remove_all::type Lhs; + typedef typename internal::remove_all::type Rhs; + typedef typename internal::remove_all::type Res; + typedef typename Lhs::InnerIterator LhsInnerIterator; + typedef typename Lhs::Index Index; + static void run(const SparseLhsType& lhs, const DenseRhsType& rhs, DenseResType& res, typename Res::Scalar alpha) + { + for(Index j=0; j +struct sparse_time_dense_product_impl +{ + typedef typename internal::remove_all::type Lhs; + typedef typename internal::remove_all::type Rhs; + typedef typename internal::remove_all::type Res; + typedef typename Lhs::InnerIterator LhsInnerIterator; + typedef typename Lhs::Index Index; + static void run(const SparseLhsType& lhs, const DenseRhsType& rhs, DenseResType& res, typename Res::Scalar alpha) + { + for(Index j=0; j +inline void sparse_time_dense_product(const SparseLhsType& lhs, const DenseRhsType& rhs, DenseResType& res, const AlphaType& alpha) +{ + sparse_time_dense_product_impl::run(lhs, rhs, res, alpha); +} + } // end namespace internal template @@ -163,21 +246,7 @@ class SparseTimeDenseProduct template void scaleAndAddTo(Dest& dest, Scalar alpha) const { - typedef typename internal::remove_all::type _Lhs; - typedef typename internal::remove_all::type _Rhs; - typedef typename _Lhs::InnerIterator LhsInnerIterator; - enum { LhsIsRowMajor = (_Lhs::Flags&RowMajorBit)==RowMajorBit }; - for(Index j=0; j void scaleAndAddTo(Dest& dest, Scalar alpha) const { - typedef typename internal::remove_all::type _Rhs; - typedef typename _Rhs::InnerIterator RhsInnerIterator; - enum { RhsIsRowMajor = (_Rhs::Flags&RowMajorBit)==RowMajorBit }; - for(Index j=0; j lhs_t(m_lhs); + Transpose rhs_t(m_rhs); + Transpose dest_t(dest); + internal::sparse_time_dense_product(rhs_t, lhs_t, dest_t, alpha); } private: @@ -228,4 +295,6 @@ SparseMatrixBase::operator*(const MatrixBase &other) cons return typename SparseDenseProductReturnType::Type(derived(), other.derived()); } +} // end namespace Eigen + #endif // EIGEN_SPARSEDENSEPRODUCT_H diff --git a/extern/Eigen3/Eigen/src/Sparse/SparseDiagonalProduct.h b/extern/Eigen3/Eigen/src/SparseCore/SparseDiagonalProduct.h similarity index 87% rename from extern/Eigen3/Eigen/src/Sparse/SparseDiagonalProduct.h rename to extern/Eigen3/Eigen/src/SparseCore/SparseDiagonalProduct.h index fb9a29c051b..095bf6863fc 100644 --- a/extern/Eigen3/Eigen/src/Sparse/SparseDiagonalProduct.h +++ b/extern/Eigen3/Eigen/src/SparseCore/SparseDiagonalProduct.h @@ -3,28 +3,15 @@ // // Copyright (C) 2009 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_SPARSE_DIAGONAL_PRODUCT_H #define EIGEN_SPARSE_DIAGONAL_PRODUCT_H +namespace Eigen { + // The product of a diagonal matrix with a sparse matrix can be easily // implemented using expression template. // We have two consider very different cases: @@ -192,4 +179,6 @@ SparseMatrixBase::operator*(const DiagonalBase &other) co return SparseDiagonalProduct(this->derived(), other.derived()); } +} // end namespace Eigen + #endif // EIGEN_SPARSE_DIAGONAL_PRODUCT_H diff --git a/extern/Eigen3/Eigen/src/Sparse/SparseDot.h b/extern/Eigen3/Eigen/src/SparseCore/SparseDot.h similarity index 67% rename from extern/Eigen3/Eigen/src/Sparse/SparseDot.h rename to extern/Eigen3/Eigen/src/SparseCore/SparseDot.h index 1f10f71a402..5c4a593dc01 100644 --- a/extern/Eigen3/Eigen/src/Sparse/SparseDot.h +++ b/extern/Eigen3/Eigen/src/SparseCore/SparseDot.h @@ -3,28 +3,15 @@ // // Copyright (C) 2008 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_SPARSE_DOT_H #define EIGEN_SPARSE_DOT_H +namespace Eigen { + template template typename internal::traits::Scalar @@ -40,7 +27,7 @@ SparseMatrixBase::dot(const MatrixBase& other) const eigen_assert(other.size()>0 && "you are using a non initialized vector"); typename Derived::InnerIterator i(derived(),0); - Scalar res = 0; + Scalar res(0); while (i) { res += internal::conj(i.value()) * other.coeff(i.index()); @@ -62,9 +49,17 @@ SparseMatrixBase::dot(const SparseMatrixBase& other) cons eigen_assert(size() == other.size()); - typename Derived::InnerIterator i(derived(),0); - typename OtherDerived::InnerIterator j(other.derived(),0); - Scalar res = 0; + typedef typename Derived::Nested Nested; + typedef typename OtherDerived::Nested OtherNested; + typedef typename internal::remove_all::type NestedCleaned; + typedef typename internal::remove_all::type OtherNestedCleaned; + + const Nested nthis(derived()); + const OtherNested nother(other.derived()); + + typename NestedCleaned::InnerIterator i(nthis,0); + typename OtherNestedCleaned::InnerIterator j(nother,0); + Scalar res(0); while (i && j) { if (i.index()==j.index()) @@ -94,4 +89,6 @@ SparseMatrixBase::norm() const return internal::sqrt(squaredNorm()); } +} // end namespace Eigen + #endif // EIGEN_SPARSE_DOT_H diff --git a/extern/Eigen3/Eigen/src/SparseCore/SparseFuzzy.h b/extern/Eigen3/Eigen/src/SparseCore/SparseFuzzy.h new file mode 100644 index 00000000000..45f36e9eb90 --- /dev/null +++ b/extern/Eigen3/Eigen/src/SparseCore/SparseFuzzy.h @@ -0,0 +1,26 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_SPARSE_FUZZY_H +#define EIGEN_SPARSE_FUZZY_H + +// template +// template +// bool SparseMatrixBase::isApprox( +// const OtherDerived& other, +// typename NumTraits::Real prec +// ) const +// { +// const typename internal::nested::type nested(derived()); +// const typename internal::nested::type otherNested(other.derived()); +// return (nested - otherNested).cwise().abs2().sum() +// <= prec * prec * (std::min)(nested.cwise().abs2().sum(), otherNested.cwise().abs2().sum()); +// } + +#endif // EIGEN_SPARSE_FUZZY_H diff --git a/extern/Eigen3/Eigen/src/SparseCore/SparseMatrix.h b/extern/Eigen3/Eigen/src/SparseCore/SparseMatrix.h new file mode 100644 index 00000000000..efb774f031b --- /dev/null +++ b/extern/Eigen3/Eigen/src/SparseCore/SparseMatrix.h @@ -0,0 +1,1116 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008-2010 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_SPARSEMATRIX_H +#define EIGEN_SPARSEMATRIX_H + +namespace Eigen { + +/** \ingroup SparseCore_Module + * + * \class SparseMatrix + * + * \brief A versatible sparse matrix representation + * + * This class implements a more versatile variants of the common \em compressed row/column storage format. + * Each colmun's (resp. row) non zeros are stored as a pair of value with associated row (resp. colmiun) index. + * All the non zeros are stored in a single large buffer. Unlike the \em compressed format, there might be extra + * space inbetween the nonzeros of two successive colmuns (resp. rows) such that insertion of new non-zero + * can be done with limited memory reallocation and copies. + * + * A call to the function makeCompressed() turns the matrix into the standard \em compressed format + * compatible with many library. + * + * More details on this storage sceheme are given in the \ref TutorialSparse "manual pages". + * + * \tparam _Scalar the scalar type, i.e. the type of the coefficients + * \tparam _Options Union of bit flags controlling the storage scheme. Currently the only possibility + * is RowMajor. The default is 0 which means column-major. + * \tparam _Index the type of the indices. It has to be a \b signed type (e.g., short, int, std::ptrdiff_t). Default is \c int. + * + * This class can be extended with the help of the plugin mechanism described on the page + * \ref TopicCustomizingEigen by defining the preprocessor symbol \c EIGEN_SPARSEMATRIX_PLUGIN. + */ + +namespace internal { +template +struct traits > +{ + typedef _Scalar Scalar; + typedef _Index Index; + typedef Sparse StorageKind; + typedef MatrixXpr XprKind; + enum { + RowsAtCompileTime = Dynamic, + ColsAtCompileTime = Dynamic, + MaxRowsAtCompileTime = Dynamic, + MaxColsAtCompileTime = Dynamic, + Flags = _Options | NestByRefBit | LvalueBit, + CoeffReadCost = NumTraits::ReadCost, + SupportedAccessPatterns = InnerRandomAccessPattern + }; +}; + +template +struct traits, DiagIndex> > +{ + typedef SparseMatrix<_Scalar, _Options, _Index> MatrixType; + typedef typename nested::type MatrixTypeNested; + typedef typename remove_reference::type _MatrixTypeNested; + + typedef _Scalar Scalar; + typedef Dense StorageKind; + typedef _Index Index; + typedef MatrixXpr XprKind; + + enum { + RowsAtCompileTime = Dynamic, + ColsAtCompileTime = 1, + MaxRowsAtCompileTime = Dynamic, + MaxColsAtCompileTime = 1, + Flags = 0, + CoeffReadCost = _MatrixTypeNested::CoeffReadCost*10 + }; +}; + +} // end namespace internal + +template +class SparseMatrix + : public SparseMatrixBase > +{ + public: + EIGEN_SPARSE_PUBLIC_INTERFACE(SparseMatrix) + EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(SparseMatrix, +=) + EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(SparseMatrix, -=) + + typedef MappedSparseMatrix Map; + using Base::IsRowMajor; + typedef internal::CompressedStorage Storage; + enum { + Options = _Options + }; + + protected: + + typedef SparseMatrix TransposedSparseMatrix; + + Index m_outerSize; + Index m_innerSize; + Index* m_outerIndex; + Index* m_innerNonZeros; // optional, if null then the data is compressed + Storage m_data; + + Eigen::Map > innerNonZeros() { return Eigen::Map >(m_innerNonZeros, m_innerNonZeros?m_outerSize:0); } + const Eigen::Map > innerNonZeros() const { return Eigen::Map >(m_innerNonZeros, m_innerNonZeros?m_outerSize:0); } + + public: + + /** \returns whether \c *this is in compressed form. */ + inline bool isCompressed() const { return m_innerNonZeros==0; } + + /** \returns the number of rows of the matrix */ + inline Index rows() const { return IsRowMajor ? m_outerSize : m_innerSize; } + /** \returns the number of columns of the matrix */ + inline Index cols() const { return IsRowMajor ? m_innerSize : m_outerSize; } + + /** \returns the number of rows (resp. columns) of the matrix if the storage order column major (resp. row major) */ + inline Index innerSize() const { return m_innerSize; } + /** \returns the number of columns (resp. rows) of the matrix if the storage order column major (resp. row major) */ + inline Index outerSize() const { return m_outerSize; } + + /** \returns a const pointer to the array of values. + * This function is aimed at interoperability with other libraries. + * \sa innerIndexPtr(), outerIndexPtr() */ + inline const Scalar* valuePtr() const { return &m_data.value(0); } + /** \returns a non-const pointer to the array of values. + * This function is aimed at interoperability with other libraries. + * \sa innerIndexPtr(), outerIndexPtr() */ + inline Scalar* valuePtr() { return &m_data.value(0); } + + /** \returns a const pointer to the array of inner indices. + * This function is aimed at interoperability with other libraries. + * \sa valuePtr(), outerIndexPtr() */ + inline const Index* innerIndexPtr() const { return &m_data.index(0); } + /** \returns a non-const pointer to the array of inner indices. + * This function is aimed at interoperability with other libraries. + * \sa valuePtr(), outerIndexPtr() */ + inline Index* innerIndexPtr() { return &m_data.index(0); } + + /** \returns a const pointer to the array of the starting positions of the inner vectors. + * This function is aimed at interoperability with other libraries. + * \sa valuePtr(), innerIndexPtr() */ + inline const Index* outerIndexPtr() const { return m_outerIndex; } + /** \returns a non-const pointer to the array of the starting positions of the inner vectors. + * This function is aimed at interoperability with other libraries. + * \sa valuePtr(), innerIndexPtr() */ + inline Index* outerIndexPtr() { return m_outerIndex; } + + /** \returns a const pointer to the array of the number of non zeros of the inner vectors. + * This function is aimed at interoperability with other libraries. + * \warning it returns the null pointer 0 in compressed mode */ + inline const Index* innerNonZeroPtr() const { return m_innerNonZeros; } + /** \returns a non-const pointer to the array of the number of non zeros of the inner vectors. + * This function is aimed at interoperability with other libraries. + * \warning it returns the null pointer 0 in compressed mode */ + inline Index* innerNonZeroPtr() { return m_innerNonZeros; } + + /** \internal */ + inline Storage& data() { return m_data; } + /** \internal */ + inline const Storage& data() const { return m_data; } + + /** \returns the value of the matrix at position \a i, \a j + * This function returns Scalar(0) if the element is an explicit \em zero */ + inline Scalar coeff(Index row, Index col) const + { + const Index outer = IsRowMajor ? row : col; + const Index inner = IsRowMajor ? col : row; + Index end = m_innerNonZeros ? m_outerIndex[outer] + m_innerNonZeros[outer] : m_outerIndex[outer+1]; + return m_data.atInRange(m_outerIndex[outer], end, inner); + } + + /** \returns a non-const reference to the value of the matrix at position \a i, \a j + * + * If the element does not exist then it is inserted via the insert(Index,Index) function + * which itself turns the matrix into a non compressed form if that was not the case. + * + * This is a O(log(nnz_j)) operation (binary search) plus the cost of insert(Index,Index) + * function if the element does not already exist. + */ + inline Scalar& coeffRef(Index row, Index col) + { + const Index outer = IsRowMajor ? row : col; + const Index inner = IsRowMajor ? col : row; + + Index start = m_outerIndex[outer]; + Index end = m_innerNonZeros ? m_outerIndex[outer] + m_innerNonZeros[outer] : m_outerIndex[outer+1]; + eigen_assert(end>=start && "you probably called coeffRef on a non finalized matrix"); + if(end<=start) + return insert(row,col); + const Index p = m_data.searchLowerIndex(start,end-1,inner); + if((p(m_data.size()); + } + + /** Preallocates \a reserveSize non zeros. + * + * Precondition: the matrix must be in compressed mode. */ + inline void reserve(Index reserveSize) + { + eigen_assert(isCompressed() && "This function does not make sense in non compressed mode."); + m_data.reserve(reserveSize); + } + + #ifdef EIGEN_PARSED_BY_DOXYGEN + /** Preallocates \a reserveSize[\c j] non zeros for each column (resp. row) \c j. + * + * This function turns the matrix in non-compressed mode */ + template + inline void reserve(const SizesType& reserveSizes); + #else + template + inline void reserve(const SizesType& reserveSizes, const typename SizesType::value_type& enableif = typename SizesType::value_type()) + { + EIGEN_UNUSED_VARIABLE(enableif); + reserveInnerVectors(reserveSizes); + } + template + inline void reserve(const SizesType& reserveSizes, const typename SizesType::Scalar& enableif = + #if (!defined(_MSC_VER)) || (_MSC_VER>=1500) // MSVC 2005 fails to compile with this typename + typename + #endif + SizesType::Scalar()) + { + EIGEN_UNUSED_VARIABLE(enableif); + reserveInnerVectors(reserveSizes); + } + #endif // EIGEN_PARSED_BY_DOXYGEN + protected: + template + inline void reserveInnerVectors(const SizesType& reserveSizes) + { + + if(isCompressed()) + { + std::size_t totalReserveSize = 0; + // turn the matrix into non-compressed mode + m_innerNonZeros = new Index[m_outerSize]; + + // temporarily use m_innerSizes to hold the new starting points. + Index* newOuterIndex = m_innerNonZeros; + + Index count = 0; + for(Index j=0; j=0; --j) + { + ptrdiff_t innerNNZ = previousOuterIndex - m_outerIndex[j]; + for(std::ptrdiff_t i=innerNNZ-1; i>=0; --i) + { + m_data.index(newOuterIndex[j]+i) = m_data.index(m_outerIndex[j]+i); + m_data.value(newOuterIndex[j]+i) = m_data.value(m_outerIndex[j]+i); + } + previousOuterIndex = m_outerIndex[j]; + m_outerIndex[j] = newOuterIndex[j]; + m_innerNonZeros[j] = innerNNZ; + } + m_outerIndex[m_outerSize] = m_outerIndex[m_outerSize-1] + m_innerNonZeros[m_outerSize-1] + reserveSizes[m_outerSize-1]; + + m_data.resize(m_outerIndex[m_outerSize]); + } + else + { + Index* newOuterIndex = new Index[m_outerSize+1]; + Index count = 0; + for(Index j=0; j(reserveSizes[j], alreadyReserved); + count += toReserve + m_innerNonZeros[j]; + } + newOuterIndex[m_outerSize] = count; + + m_data.resize(count); + for(ptrdiff_t j=m_outerSize-1; j>=0; --j) + { + std::ptrdiff_t offset = newOuterIndex[j] - m_outerIndex[j]; + if(offset>0) + { + std::ptrdiff_t innerNNZ = m_innerNonZeros[j]; + for(std::ptrdiff_t i=innerNNZ-1; i>=0; --i) + { + m_data.index(newOuterIndex[j]+i) = m_data.index(m_outerIndex[j]+i); + m_data.value(newOuterIndex[j]+i) = m_data.value(m_outerIndex[j]+i); + } + } + } + + std::swap(m_outerIndex, newOuterIndex); + delete[] newOuterIndex; + } + + } + public: + + //--- low level purely coherent filling --- + + /** \internal + * \returns a reference to the non zero coefficient at position \a row, \a col assuming that: + * - the nonzero does not already exist + * - the new coefficient is the last one according to the storage order + * + * Before filling a given inner vector you must call the statVec(Index) function. + * + * After an insertion session, you should call the finalize() function. + * + * \sa insert, insertBackByOuterInner, startVec */ + inline Scalar& insertBack(Index row, Index col) + { + return insertBackByOuterInner(IsRowMajor?row:col, IsRowMajor?col:row); + } + + /** \internal + * \sa insertBack, startVec */ + inline Scalar& insertBackByOuterInner(Index outer, Index inner) + { + eigen_assert(size_t(m_outerIndex[outer+1]) == m_data.size() && "Invalid ordered insertion (invalid outer index)"); + eigen_assert( (m_outerIndex[outer+1]-m_outerIndex[outer]==0 || m_data.index(m_data.size()-1)(m_data.size()); + Index i = m_outerSize; + // find the last filled column + while (i>=0 && m_outerIndex[i]==0) + --i; + ++i; + while (i<=m_outerSize) + { + m_outerIndex[i] = size; + ++i; + } + } + } + + //--- + + template + void setFromTriplets(const InputIterators& begin, const InputIterators& end); + + void sumupDuplicates(); + + //--- + + /** \internal + * same as insert(Index,Index) except that the indices are given relative to the storage order */ + EIGEN_DONT_INLINE Scalar& insertByOuterInner(Index j, Index i) + { + return insert(IsRowMajor ? j : i, IsRowMajor ? i : j); + } + + /** Turns the matrix into the \em compressed format. + */ + void makeCompressed() + { + if(isCompressed()) + return; + + Index oldStart = m_outerIndex[1]; + m_outerIndex[1] = m_innerNonZeros[0]; + for(Index j=1; j0) + { + for(Index k=0; k::dummy_precision()) + { + prune(default_prunning_func(reference,epsilon)); + } + + /** Turns the matrix into compressed format, and suppresses all nonzeros which do not satisfy the predicate \a keep. + * The functor type \a KeepFunc must implement the following function: + * \code + * bool operator() (const Index& row, const Index& col, const Scalar& value) const; + * \endcode + * \sa prune(Scalar,RealScalar) + */ + template + void prune(const KeepFunc& keep = KeepFunc()) + { + // TODO optimize the uncompressed mode to avoid moving and allocating the data twice + // TODO also implement a unit test + makeCompressed(); + + Index k = 0; + for(Index j=0; j diagonal() const { return *this; } + + /** Default constructor yielding an empty \c 0 \c x \c 0 matrix */ + inline SparseMatrix() + : m_outerSize(-1), m_innerSize(0), m_outerIndex(0), m_innerNonZeros(0) + { + check_template_parameters(); + resize(0, 0); + } + + /** Constructs a \a rows \c x \a cols empty matrix */ + inline SparseMatrix(Index rows, Index cols) + : m_outerSize(0), m_innerSize(0), m_outerIndex(0), m_innerNonZeros(0) + { + check_template_parameters(); + resize(rows, cols); + } + + /** Constructs a sparse matrix from the sparse expression \a other */ + template + inline SparseMatrix(const SparseMatrixBase& other) + : m_outerSize(0), m_innerSize(0), m_outerIndex(0), m_innerNonZeros(0) + { + check_template_parameters(); + *this = other.derived(); + } + + /** Copy constructor (it performs a deep copy) */ + inline SparseMatrix(const SparseMatrix& other) + : Base(), m_outerSize(0), m_innerSize(0), m_outerIndex(0), m_innerNonZeros(0) + { + check_template_parameters(); + *this = other.derived(); + } + + /** Swaps the content of two sparse matrices of the same type. + * This is a fast operation that simply swaps the underlying pointers and parameters. */ + inline void swap(SparseMatrix& other) + { + //EIGEN_DBG_SPARSE(std::cout << "SparseMatrix:: swap\n"); + std::swap(m_outerIndex, other.m_outerIndex); + std::swap(m_innerSize, other.m_innerSize); + std::swap(m_outerSize, other.m_outerSize); + std::swap(m_innerNonZeros, other.m_innerNonZeros); + m_data.swap(other.m_data); + } + + inline SparseMatrix& operator=(const SparseMatrix& other) + { + if (other.isRValue()) + { + swap(other.const_cast_derived()); + } + else + { + initAssignment(other); + if(other.isCompressed()) + { + memcpy(m_outerIndex, other.m_outerIndex, (m_outerSize+1)*sizeof(Index)); + m_data = other.m_data; + } + else + { + Base::operator=(other); + } + } + return *this; + } + + #ifndef EIGEN_PARSED_BY_DOXYGEN + template + inline SparseMatrix& operator=(const SparseSparseProduct& product) + { return Base::operator=(product); } + + template + inline SparseMatrix& operator=(const ReturnByValue& other) + { return Base::operator=(other.derived()); } + + template + inline SparseMatrix& operator=(const EigenBase& other) + { return Base::operator=(other.derived()); } + #endif + + template + EIGEN_DONT_INLINE SparseMatrix& operator=(const SparseMatrixBase& other) + { + initAssignment(other.derived()); + const bool needToTranspose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit); + if (needToTranspose) + { + // two passes algorithm: + // 1 - compute the number of coeffs per dest inner vector + // 2 - do the actual copy/eval + // Since each coeff of the rhs has to be evaluated twice, let's evaluate it if needed + typedef typename internal::nested::type OtherCopy; + typedef typename internal::remove_all::type _OtherCopy; + OtherCopy otherCopy(other.derived()); + + Eigen::Map > (m_outerIndex,outerSize()).setZero(); + // pass 1 + // FIXME the above copy could be merged with that pass + for (Index j=0; j&>(m); + return s; + } + + /** Destructor */ + inline ~SparseMatrix() + { + delete[] m_outerIndex; + delete[] m_innerNonZeros; + } + +#ifndef EIGEN_PARSED_BY_DOXYGEN + /** Overloaded for performance */ + Scalar sum() const; +#endif + +# ifdef EIGEN_SPARSEMATRIX_PLUGIN +# include EIGEN_SPARSEMATRIX_PLUGIN +# endif + +protected: + + template + void initAssignment(const Other& other) + { + resize(other.rows(), other.cols()); + if(m_innerNonZeros) + { + delete[] m_innerNonZeros; + m_innerNonZeros = 0; + } + } + + /** \internal + * \sa insert(Index,Index) */ + EIGEN_DONT_INLINE Scalar& insertCompressed(Index row, Index col) + { + eigen_assert(isCompressed()); + + const Index outer = IsRowMajor ? row : col; + const Index inner = IsRowMajor ? col : row; + + Index previousOuter = outer; + if (m_outerIndex[outer+1]==0) + { + // we start a new inner vector + while (previousOuter>=0 && m_outerIndex[previousOuter]==0) + { + m_outerIndex[previousOuter] = static_cast(m_data.size()); + --previousOuter; + } + m_outerIndex[outer+1] = m_outerIndex[outer]; + } + + // here we have to handle the tricky case where the outerIndex array + // starts with: [ 0 0 0 0 0 1 ...] and we are inserted in, e.g., + // the 2nd inner vector... + bool isLastVec = (!(previousOuter==-1 && m_data.size()!=0)) + && (size_t(m_outerIndex[outer+1]) == m_data.size()); + + size_t startId = m_outerIndex[outer]; + // FIXME let's make sure sizeof(long int) == sizeof(size_t) + size_t p = m_outerIndex[outer+1]; + ++m_outerIndex[outer+1]; + + float reallocRatio = 1; + if (m_data.allocatedSize()<=m_data.size()) + { + // if there is no preallocated memory, let's reserve a minimum of 32 elements + if (m_data.size()==0) + { + m_data.reserve(32); + } + else + { + // we need to reallocate the data, to reduce multiple reallocations + // we use a smart resize algorithm based on the current filling ratio + // in addition, we use float to avoid integers overflows + float nnzEstimate = float(m_outerIndex[outer])*float(m_outerSize)/float(outer+1); + reallocRatio = (nnzEstimate-float(m_data.size()))/float(m_data.size()); + // furthermore we bound the realloc ratio to: + // 1) reduce multiple minor realloc when the matrix is almost filled + // 2) avoid to allocate too much memory when the matrix is almost empty + reallocRatio = (std::min)((std::max)(reallocRatio,1.5f),8.f); + } + } + m_data.resize(m_data.size()+1,reallocRatio); + + if (!isLastVec) + { + if (previousOuter==-1) + { + // oops wrong guess. + // let's correct the outer offsets + for (Index k=0; k<=(outer+1); ++k) + m_outerIndex[k] = 0; + Index k=outer+1; + while(m_outerIndex[k]==0) + m_outerIndex[k++] = 1; + while (k<=m_outerSize && m_outerIndex[k]!=0) + m_outerIndex[k++]++; + p = 0; + --k; + k = m_outerIndex[k]-1; + while (k>0) + { + m_data.index(k) = m_data.index(k-1); + m_data.value(k) = m_data.value(k-1); + k--; + } + } + else + { + // we are not inserting into the last inner vec + // update outer indices: + Index j = outer+2; + while (j<=m_outerSize && m_outerIndex[j]!=0) + m_outerIndex[j++]++; + --j; + // shift data of last vecs: + Index k = m_outerIndex[j]-1; + while (k>=Index(p)) + { + m_data.index(k) = m_data.index(k-1); + m_data.value(k) = m_data.value(k-1); + k--; + } + } + } + + while ( (p > startId) && (m_data.index(p-1) > inner) ) + { + m_data.index(p) = m_data.index(p-1); + m_data.value(p) = m_data.value(p-1); + --p; + } + + m_data.index(p) = inner; + return (m_data.value(p) = 0); + } + + /** \internal + * A vector object that is equal to 0 everywhere but v at the position i */ + class SingletonVector + { + Index m_index; + Index m_value; + public: + typedef Index value_type; + SingletonVector(Index i, Index v) + : m_index(i), m_value(v) + {} + + Index operator[](Index i) const { return i==m_index ? m_value : 0; } + }; + + /** \internal + * \sa insert(Index,Index) */ + EIGEN_DONT_INLINE Scalar& insertUncompressed(Index row, Index col) + { + eigen_assert(!isCompressed()); + + const Index outer = IsRowMajor ? row : col; + const Index inner = IsRowMajor ? col : row; + + std::ptrdiff_t room = m_outerIndex[outer+1] - m_outerIndex[outer]; + std::ptrdiff_t innerNNZ = m_innerNonZeros[outer]; + if(innerNNZ>=room) + { + // this inner vector is full, we need to reallocate the whole buffer :( + reserve(SingletonVector(outer,std::max(2,innerNNZ))); + } + + Index startId = m_outerIndex[outer]; + Index p = startId + m_innerNonZeros[outer]; + while ( (p > startId) && (m_data.index(p-1) > inner) ) + { + m_data.index(p) = m_data.index(p-1); + m_data.value(p) = m_data.value(p-1); + --p; + } + + m_innerNonZeros[outer]++; + + m_data.index(p) = inner; + return (m_data.value(p) = 0); + } + +public: + /** \internal + * \sa insert(Index,Index) */ + inline Scalar& insertBackUncompressed(Index row, Index col) + { + const Index outer = IsRowMajor ? row : col; + const Index inner = IsRowMajor ? col : row; + + eigen_assert(!isCompressed()); + eigen_assert(m_innerNonZeros[outer]<=(m_outerIndex[outer+1] - m_outerIndex[outer])); + + Index p = m_outerIndex[outer] + m_innerNonZeros[outer]; + m_innerNonZeros[outer]++; + m_data.index(p) = inner; + return (m_data.value(p) = 0); + } + +private: + static void check_template_parameters() + { + EIGEN_STATIC_ASSERT(NumTraits::IsSigned,THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE); + } + + struct default_prunning_func { + default_prunning_func(Scalar ref, RealScalar eps) : reference(ref), epsilon(eps) {} + inline bool operator() (const Index&, const Index&, const Scalar& value) const + { + return !internal::isMuchSmallerThan(value, reference, epsilon); + } + Scalar reference; + RealScalar epsilon; + }; +}; + +template +class SparseMatrix::InnerIterator +{ + public: + InnerIterator(const SparseMatrix& mat, Index outer) + : m_values(mat.valuePtr()), m_indices(mat.innerIndexPtr()), m_outer(outer), m_id(mat.m_outerIndex[outer]) + { + if(mat.isCompressed()) + m_end = mat.m_outerIndex[outer+1]; + else + m_end = m_id + mat.m_innerNonZeros[outer]; + } + + inline InnerIterator& operator++() { m_id++; return *this; } + + inline const Scalar& value() const { return m_values[m_id]; } + inline Scalar& valueRef() { return const_cast(m_values[m_id]); } + + inline Index index() const { return m_indices[m_id]; } + inline Index outer() const { return m_outer; } + inline Index row() const { return IsRowMajor ? m_outer : index(); } + inline Index col() const { return IsRowMajor ? index() : m_outer; } + + inline operator bool() const { return (m_id < m_end); } + + protected: + const Scalar* m_values; + const Index* m_indices; + const Index m_outer; + Index m_id; + Index m_end; +}; + +template +class SparseMatrix::ReverseInnerIterator +{ + public: + ReverseInnerIterator(const SparseMatrix& mat, Index outer) + : m_values(mat.valuePtr()), m_indices(mat.innerIndexPtr()), m_outer(outer), m_start(mat.m_outerIndex[outer]) + { + if(mat.isCompressed()) + m_id = mat.m_outerIndex[outer+1]; + else + m_id = m_start + mat.m_innerNonZeros[outer]; + } + + inline ReverseInnerIterator& operator--() { --m_id; return *this; } + + inline const Scalar& value() const { return m_values[m_id-1]; } + inline Scalar& valueRef() { return const_cast(m_values[m_id-1]); } + + inline Index index() const { return m_indices[m_id-1]; } + inline Index outer() const { return m_outer; } + inline Index row() const { return IsRowMajor ? m_outer : index(); } + inline Index col() const { return IsRowMajor ? index() : m_outer; } + + inline operator bool() const { return (m_id > m_start); } + + protected: + const Scalar* m_values; + const Index* m_indices; + const Index m_outer; + Index m_id; + const Index m_start; +}; + +namespace internal { + +template +void set_from_triplets(const InputIterator& begin, const InputIterator& end, SparseMatrixType& mat, int Options = 0) +{ + EIGEN_UNUSED_VARIABLE(Options); + enum { IsRowMajor = SparseMatrixType::IsRowMajor }; + typedef typename SparseMatrixType::Scalar Scalar; + typedef typename SparseMatrixType::Index Index; + SparseMatrix trMat(mat.rows(),mat.cols()); + + // pass 1: count the nnz per inner-vector + VectorXi wi(trMat.outerSize()); + wi.setZero(); + for(InputIterator it(begin); it!=end; ++it) + wi(IsRowMajor ? it->col() : it->row())++; + + // pass 2: insert all the elements into trMat + trMat.reserve(wi); + for(InputIterator it(begin); it!=end; ++it) + trMat.insertBackUncompressed(it->row(),it->col()) = it->value(); + + // pass 3: + trMat.sumupDuplicates(); + + // pass 4: transposed copy -> implicit sorting + mat = trMat; +} + +} + + +/** Fill the matrix \c *this with the list of \em triplets defined by the iterator range \a begin - \b. + * + * A \em triplet is a tuple (i,j,value) defining a non-zero element. + * The input list of triplets does not have to be sorted, and can contains duplicated elements. + * In any case, the result is a \b sorted and \b compressed sparse matrix where the duplicates have been summed up. + * This is a \em O(n) operation, with \em n the number of triplet elements. + * The initial contents of \c *this is destroyed. + * The matrix \c *this must be properly resized beforehand using the SparseMatrix(Index,Index) constructor, + * or the resize(Index,Index) method. The sizes are not extracted from the triplet list. + * + * The \a InputIterators value_type must provide the following interface: + * \code + * Scalar value() const; // the value + * Scalar row() const; // the row index i + * Scalar col() const; // the column index j + * \endcode + * See for instance the Eigen::Triplet template class. + * + * Here is a typical usage example: + * \code + typedef Triplet T; + std::vector tripletList; + triplets.reserve(estimation_of_entries); + for(...) + { + // ... + tripletList.push_back(T(i,j,v_ij)); + } + SparseMatrixType m(rows,cols); + m.setFromTriplets(tripletList.begin(), tripletList.end()); + // m is ready to go! + * \endcode + * + * \warning The list of triplets is read multiple times (at least twice). Therefore, it is not recommended to define + * an abstract iterator over a complex data-structure that would be expensive to evaluate. The triplets should rather + * be explicitely stored into a std::vector for instance. + */ +template +template +void SparseMatrix::setFromTriplets(const InputIterators& begin, const InputIterators& end) +{ + internal::set_from_triplets(begin, end, *this); +} + +/** \internal */ +template +void SparseMatrix::sumupDuplicates() +{ + eigen_assert(!isCompressed()); + // TODO, in practice we should be able to use m_innerNonZeros for that task + VectorXi wi(innerSize()); + wi.fill(-1); + Index count = 0; + // for each inner-vector, wi[inner_index] will hold the position of first element into the index/value buffers + for(int j=0; j=start) + { + // we already meet this entry => accumulate it + m_data.value(wi(i)) += m_data.value(k); + } + else + { + m_data.value(count) = m_data.value(k); + m_data.index(count) = m_data.index(k); + wi(i) = count; + ++count; + } + } + m_outerIndex[j] = start; + } + m_outerIndex[m_outerSize] = count; + + // turn the matrix into compressed form + delete[] m_innerNonZeros; + m_innerNonZeros = 0; + m_data.resize(m_outerIndex[m_outerSize]); +} + +} // end namespace Eigen + +#endif // EIGEN_SPARSEMATRIX_H diff --git a/extern/Eigen3/Eigen/src/Sparse/SparseMatrixBase.h b/extern/Eigen3/Eigen/src/SparseCore/SparseMatrixBase.h similarity index 52% rename from extern/Eigen3/Eigen/src/Sparse/SparseMatrixBase.h rename to extern/Eigen3/Eigen/src/SparseCore/SparseMatrixBase.h index c01981bc935..9a1258097fe 100644 --- a/extern/Eigen3/Eigen/src/Sparse/SparseMatrixBase.h +++ b/extern/Eigen3/Eigen/src/SparseCore/SparseMatrixBase.h @@ -1,31 +1,18 @@ // This file is part of Eigen, a lightweight C++ template library // for linear algebra. // -// Copyright (C) 2008-2009 Gael Guennebaud +// Copyright (C) 2008-2011 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_SPARSEMATRIXBASE_H #define EIGEN_SPARSEMATRIXBASE_H -/** \ingroup Sparse_Module +namespace Eigen { + +/** \ingroup SparseCore_Module * * \class SparseMatrixBase * @@ -44,6 +31,9 @@ template class SparseMatrixBase : public EigenBase typedef typename internal::packet_traits::type PacketScalar; typedef typename internal::traits::StorageKind StorageKind; typedef typename internal::traits::Index Index; + typedef typename internal::add_const_on_value_type_if_arithmetic< + typename internal::packet_traits::type + >::type PacketReturnType; typedef SparseMatrixBase StorageBaseType; typedef EigenBase Base; @@ -54,8 +44,6 @@ template class SparseMatrixBase : public EigenBase other.derived().evalTo(derived()); return derived(); } - -// using Base::operator=; enum { @@ -107,15 +95,6 @@ template class SparseMatrixBase : public EigenBase #endif }; - /* \internal the return type of MatrixBase::conjugate() */ -// typedef typename internal::conditional::IsComplex, -// const SparseCwiseUnaryOp, Derived>, -// const Derived& -// >::type ConjugateReturnType; - /* \internal the return type of MatrixBase::real() */ -// typedef SparseCwiseUnaryOp, Derived> RealReturnType; - /* \internal the return type of MatrixBase::imag() */ -// typedef SparseCwiseUnaryOp, Derived> ImagReturnType; /** \internal the return type of MatrixBase::adjoint() */ typedef typename internal::conditional::IsComplex, CwiseUnaryOp, Eigen::Transpose >, @@ -125,16 +104,6 @@ template class SparseMatrixBase : public EigenBase typedef SparseMatrix PlainObject; -#define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::SparseMatrixBase -# include "../plugins/CommonCwiseUnaryOps.h" -# include "../plugins/CommonCwiseBinaryOps.h" -# include "../plugins/MatrixCwiseUnaryOps.h" -# include "../plugins/MatrixCwiseBinaryOps.h" -# ifdef EIGEN_SPARSEMATRIXBASE_PLUGIN -# include EIGEN_SPARSEMATRIXBASE_PLUGIN -# endif -# undef EIGEN_CURRENT_STORAGE_BASE_CLASS -#undef EIGEN_CURRENT_STORAGE_BASE_CLASS #ifndef EIGEN_PARSED_BY_DOXYGEN /** This is the "real scalar" type; if the \a Scalar type is already real numbers @@ -162,12 +131,24 @@ template class SparseMatrixBase : public EigenBase { return *static_cast(const_cast(this)); } #endif // not EIGEN_PARSED_BY_DOXYGEN - /** \returns the number of rows. \sa cols(), RowsAtCompileTime */ +#define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::SparseMatrixBase +# include "../plugins/CommonCwiseUnaryOps.h" +# include "../plugins/CommonCwiseBinaryOps.h" +# include "../plugins/MatrixCwiseUnaryOps.h" +# include "../plugins/MatrixCwiseBinaryOps.h" +# ifdef EIGEN_SPARSEMATRIXBASE_PLUGIN +# include EIGEN_SPARSEMATRIXBASE_PLUGIN +# endif +# undef EIGEN_CURRENT_STORAGE_BASE_CLASS +#undef EIGEN_CURRENT_STORAGE_BASE_CLASS + + + /** \returns the number of rows. \sa cols() */ inline Index rows() const { return derived().rows(); } - /** \returns the number of columns. \sa rows(), ColsAtCompileTime*/ + /** \returns the number of columns. \sa rows() */ inline Index cols() const { return derived().cols(); } /** \returns the number of coefficients, which is \a rows()*cols(). - * \sa rows(), cols(), SizeAtCompileTime. */ + * \sa rows(), cols(). */ inline Index size() const { return rows() * cols(); } /** \returns the number of nonzero coefficients which is in practice the number * of stored coefficients. */ @@ -188,16 +169,7 @@ template class SparseMatrixBase : public EigenBase Derived& markAsRValue() { m_isRValue = true; return derived(); } SparseMatrixBase() : m_isRValue(false) { /* TODO check flags */ } - - inline Derived& operator=(const Derived& other) - { -// std::cout << "Derived& operator=(const Derived& other)\n"; -// if (other.isRValue()) -// derived().swap(other.const_cast_derived()); -// else - this->operator=(other); - return derived(); - } + template Derived& operator=(const ReturnByValue& other) @@ -207,10 +179,54 @@ template class SparseMatrixBase : public EigenBase } + template + inline Derived& operator=(const SparseMatrixBase& other) + { + return assign(other.derived()); + } + + inline Derived& operator=(const Derived& other) + { +// if (other.isRValue()) +// derived().swap(other.const_cast_derived()); +// else + return assign(other.derived()); + } + + protected: + + template + inline Derived& assign(const OtherDerived& other) + { + const bool transpose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit); + const Index outerSize = (int(OtherDerived::Flags) & RowMajorBit) ? other.rows() : other.cols(); + if ((!transpose) && other.isRValue()) + { + // eval without temporary + derived().resize(other.rows(), other.cols()); + derived().setZero(); + derived().reserve((std::max)(this->rows(),this->cols())*2); + for (Index j=0; j inline void assignGeneric(const OtherDerived& other) { -// std::cout << "Derived& operator=(const MatrixBase& other)\n"; //const bool transpose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit); eigen_assert(( ((internal::traits::SupportedAccessPatterns&OuterRandomAccessPattern)==OuterRandomAccessPattern) || (!((Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit)))) && @@ -230,8 +246,7 @@ template class SparseMatrixBase : public EigenBase for (typename OtherDerived::InnerIterator it(other.derived(), j); it; ++it) { Scalar v = it.value(); - if (v!=Scalar(0)) - temp.insertBackByOuterInner(Flip?it.index():j,Flip?j:it.index()) = v; + temp.insertBackByOuterInner(Flip?it.index():j,Flip?j:it.index()) = v; } } temp.finalize(); @@ -239,54 +254,23 @@ template class SparseMatrixBase : public EigenBase derived() = temp.markAsRValue(); } - - template - inline Derived& operator=(const SparseMatrixBase& other) - { -// std::cout << typeid(OtherDerived).name() << "\n"; -// std::cout << Flags << " " << OtherDerived::Flags << "\n"; - const bool transpose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit); -// std::cout << "eval transpose = " << transpose << "\n"; - const Index outerSize = (int(OtherDerived::Flags) & RowMajorBit) ? other.rows() : other.cols(); - if ((!transpose) && other.isRValue()) - { - // eval without temporary - derived().resize(other.rows(), other.cols()); - derived().setZero(); - derived().reserve((std::max)(this->rows(),this->cols())*2); - for (Index j=0; j inline Derived& operator=(const SparseSparseProduct& product); - template - inline void _experimentalNewProduct(const Lhs& lhs, const Rhs& rhs); - friend std::ostream & operator << (std::ostream & s, const SparseMatrixBase& m) { + typedef typename Derived::Nested Nested; + typedef typename internal::remove_all::type NestedCleaned; + if (Flags&RowMajorBit) { - for (Index row=0; row class SparseMatrixBase : public EigenBase } else { + const Nested nm(m.derived()); if (m.cols() == 1) { Index row = 0; - for (typename Derived::InnerIterator it(m.derived(), 0); it; ++it) + for (typename NestedCleaned::InnerIterator it(nm.derived(), 0); it; ++it) { for ( ; row class SparseMatrixBase : public EigenBase } else { - SparseMatrix trans = m.derived(); - s << trans; + SparseMatrix trans = m; + s << static_cast >&>(trans); } } return s; } -// const SparseCwiseUnaryOp::Scalar>,Derived> operator-() const; - -// template -// const CwiseBinaryOp::Scalar>, Derived, OtherDerived> -// operator+(const SparseMatrixBase &other) const; - -// template -// const CwiseBinaryOp::Scalar>, Derived, OtherDerived> -// operator-(const SparseMatrixBase &other) const; - template Derived& operator+=(const SparseMatrixBase& other); template Derived& operator-=(const SparseMatrixBase& other); -// template -// Derived& operator+=(const Flagged, 0, EvalBeforeNestingBit | EvalBeforeAssigningBit>& other); - Derived& operator*=(const Scalar& other); Derived& operator/=(const Scalar& other); @@ -358,16 +330,6 @@ template class SparseMatrixBase : public EigenBase EIGEN_STRONG_INLINE const EIGEN_SPARSE_CWISE_PRODUCT_RETURN_TYPE cwiseProduct(const MatrixBase &other) const; -// const SparseCwiseUnaryOp::Scalar>, Derived> -// operator*(const Scalar& scalar) const; -// const SparseCwiseUnaryOp::Scalar>, Derived> -// operator/(const Scalar& scalar) const; - -// inline friend const SparseCwiseUnaryOp::Scalar>, Derived> -// operator*(const Scalar& scalar, const SparseMatrixBase& matrix) -// { return matrix*scalar; } - - // sparse * sparse template const typename SparseSparseProductReturnType::Type @@ -394,6 +356,12 @@ template class SparseMatrixBase : public EigenBase template const typename SparseDenseProductReturnType::Type operator*(const MatrixBase &other) const; + + /** \returns an expression of P H P^-1 where H is the matrix represented by \c *this */ + SparseSymmetricPermutationProduct twistedBy(const PermutationMatrix& perm) const + { + return SparseSymmetricPermutationProduct(derived(), perm); + } template Derived& operator*=(const SparseMatrixBase& other); @@ -407,8 +375,6 @@ template class SparseMatrixBase : public EigenBase // deprecated template void solveTriangularInPlace(MatrixBase& other) const; -// template -// void solveTriangularInPlace(SparseMatrixBase& other) const; #endif // EIGEN2_SUPPORT template @@ -421,12 +387,9 @@ template class SparseMatrixBase : public EigenBase template Scalar dot(const SparseMatrixBase& other) const; RealScalar squaredNorm() const; RealScalar norm() const; -// const PlainObject normalized() const; -// void normalize(); Transpose transpose() { return derived(); } const Transpose transpose() const { return derived(); } - // void transposeInPlace(); const AdjointReturnType adjoint() const { return transpose(); } // sub-vector @@ -442,77 +405,14 @@ template class SparseMatrixBase : public EigenBase const SparseInnerVectorSet subrows(Index start, Index size) const; SparseInnerVectorSet subcols(Index start, Index size); const SparseInnerVectorSet subcols(Index start, Index size) const; + + SparseInnerVectorSet middleRows(Index start, Index size); + const SparseInnerVectorSet middleRows(Index start, Index size) const; + SparseInnerVectorSet middleCols(Index start, Index size); + const SparseInnerVectorSet middleCols(Index start, Index size) const; SparseInnerVectorSet innerVectors(Index outerStart, Index outerSize); const SparseInnerVectorSet innerVectors(Index outerStart, Index outerSize) const; -// typename BlockReturnType::Type block(int startRow, int startCol, int blockRows, int blockCols); -// const typename BlockReturnType::Type -// block(int startRow, int startCol, int blockRows, int blockCols) const; -// -// typename BlockReturnType::SubVectorType segment(int start, int size); -// const typename BlockReturnType::SubVectorType segment(int start, int size) const; -// -// typename BlockReturnType::SubVectorType start(int size); -// const typename BlockReturnType::SubVectorType start(int size) const; -// -// typename BlockReturnType::SubVectorType end(int size); -// const typename BlockReturnType::SubVectorType end(int size) const; -// -// template -// typename BlockReturnType::Type block(int startRow, int startCol); -// template -// const typename BlockReturnType::Type block(int startRow, int startCol) const; - -// template typename BlockReturnType::SubVectorType start(void); -// template const typename BlockReturnType::SubVectorType start() const; - -// template typename BlockReturnType::SubVectorType end(); -// template const typename BlockReturnType::SubVectorType end() const; - -// template typename BlockReturnType::SubVectorType segment(int start); -// template const typename BlockReturnType::SubVectorType segment(int start) const; - -// Diagonal diagonal(); -// const Diagonal diagonal() const; - -// template Part part(); -// template const Part part() const; - - -// static const ConstantReturnType Constant(int rows, int cols, const Scalar& value); -// static const ConstantReturnType Constant(int size, const Scalar& value); -// static const ConstantReturnType Constant(const Scalar& value); - -// template -// static const CwiseNullaryOp NullaryExpr(int rows, int cols, const CustomNullaryOp& func); -// template -// static const CwiseNullaryOp NullaryExpr(int size, const CustomNullaryOp& func); -// template -// static const CwiseNullaryOp NullaryExpr(const CustomNullaryOp& func); - -// static const ConstantReturnType Zero(int rows, int cols); -// static const ConstantReturnType Zero(int size); -// static const ConstantReturnType Zero(); -// static const ConstantReturnType Ones(int rows, int cols); -// static const ConstantReturnType Ones(int size); -// static const ConstantReturnType Ones(); -// static const IdentityReturnType Identity(); -// static const IdentityReturnType Identity(int rows, int cols); -// static const BasisReturnType Unit(int size, int i); -// static const BasisReturnType Unit(int i); -// static const BasisReturnType UnitX(); -// static const BasisReturnType UnitY(); -// static const BasisReturnType UnitZ(); -// static const BasisReturnType UnitW(); - -// const DiagonalMatrix asDiagonal() const; - -// Derived& setConstant(const Scalar& value); -// Derived& setZero(); -// Derived& setOnes(); -// Derived& setRandom(); -// Derived& setIdentity(); - /** \internal use operator= */ template void evalTo(MatrixBase& dst) const @@ -537,37 +437,6 @@ template class SparseMatrixBase : public EigenBase bool isApprox(const MatrixBase& other, RealScalar prec = NumTraits::dummy_precision()) const { return toDense().isApprox(other,prec); } -// bool isMuchSmallerThan(const RealScalar& other, -// RealScalar prec = NumTraits::dummy_precision()) const; -// template -// bool isMuchSmallerThan(const MatrixBase& other, -// RealScalar prec = NumTraits::dummy_precision()) const; - -// bool isApproxToConstant(const Scalar& value, RealScalar prec = NumTraits::dummy_precision()) const; -// bool isZero(RealScalar prec = NumTraits::dummy_precision()) const; -// bool isOnes(RealScalar prec = NumTraits::dummy_precision()) const; -// bool isIdentity(RealScalar prec = NumTraits::dummy_precision()) const; -// bool isDiagonal(RealScalar prec = NumTraits::dummy_precision()) const; - -// bool isUpper(RealScalar prec = NumTraits::dummy_precision()) const; -// bool isLower(RealScalar prec = NumTraits::dummy_precision()) const; - -// template -// bool isOrthogonal(const MatrixBase& other, -// RealScalar prec = NumTraits::dummy_precision()) const; -// bool isUnitary(RealScalar prec = NumTraits::dummy_precision()) const; - -// template -// inline bool operator==(const MatrixBase& other) const -// { return (cwise() == other).all(); } - -// template -// inline bool operator!=(const MatrixBase& other) const -// { return (cwise() != other).any(); } - - -// template -// const SparseCwiseUnaryOp::Scalar, NewType>, Derived> cast() const; /** \returns the matrix or vector obtained by evaluating this expression. * @@ -577,130 +446,13 @@ template class SparseMatrixBase : public EigenBase inline const typename internal::eval::type eval() const { return typename internal::eval::type(derived()); } -// template -// void swap(MatrixBase const & other); - -// template -// const SparseFlagged marked() const; -// const Flagged lazy() const; - - /** \returns number of elements to skip to pass from one row (resp. column) to another - * for a row-major (resp. column-major) matrix. - * Combined with coeffRef() and the \ref flags flags, it allows a direct access to the data - * of the underlying matrix. - */ -// inline int stride(void) const { return derived().stride(); } - -// FIXME -// ConjugateReturnType conjugate() const; -// const RealReturnType real() const; -// const ImagReturnType imag() const; - -// template -// const SparseCwiseUnaryOp unaryExpr(const CustomUnaryOp& func = CustomUnaryOp()) const; - -// template -// const CwiseBinaryOp -// binaryExpr(const MatrixBase &other, const CustomBinaryOp& func = CustomBinaryOp()) const; - - Scalar sum() const; -// Scalar trace() const; - -// typename internal::traits::Scalar minCoeff() const; -// typename internal::traits::Scalar maxCoeff() const; - -// typename internal::traits::Scalar minCoeff(int* row, int* col = 0) const; -// typename internal::traits::Scalar maxCoeff(int* row, int* col = 0) const; - -// template -// typename internal::result_of::Scalar)>::type -// redux(const BinaryOp& func) const; - -// template -// void visit(Visitor& func) const; - - -// const SparseCwise cwise() const; -// SparseCwise cwise(); - -// inline const WithFormat format(const IOFormat& fmt) const; - -/////////// Array module /////////// - /* - bool all(void) const; - bool any(void) const; - - const VectorwiseOp rowwise() const; - const VectorwiseOp colwise() const; - - static const CwiseNullaryOp,Derived> Random(int rows, int cols); - static const CwiseNullaryOp,Derived> Random(int size); - static const CwiseNullaryOp,Derived> Random(); - - template - const Select - select(const MatrixBase& thenMatrix, - const MatrixBase& elseMatrix) const; - - template - inline const Select - select(const MatrixBase& thenMatrix, typename ThenDerived::Scalar elseScalar) const; - - template - inline const Select - select(typename ElseDerived::Scalar thenScalar, const MatrixBase& elseMatrix) const; - - template RealScalar lpNorm() const; - */ - - -// template -// Scalar dot(const MatrixBase& other) const -// { -// EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) -// EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived) -// EIGEN_STATIC_ASSERT((internal::is_same::value), -// YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) -// -// eigen_assert(derived().size() == other.size()); -// // short version, but the assembly looks more complicated because -// // of the CwiseBinaryOp iterator complexity -// // return res = (derived().cwise() * other.derived().conjugate()).sum(); -// -// // optimized, generic version -// typename Derived::InnerIterator i(derived(),0); -// typename OtherDerived::InnerIterator j(other.derived(),0); -// Scalar res = 0; -// while (i && j) -// { -// if (i.index()==j.index()) -// { -// // std::cerr << i.value() << " * " << j.value() << "\n"; -// res += i.value() * internal::conj(j.value()); -// ++i; ++j; -// } -// else if (i.index() +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_SPARSE_PERMUTATION_H +#define EIGEN_SPARSE_PERMUTATION_H + +// This file implements sparse * permutation products + +namespace Eigen { + +namespace internal { + +template +struct traits > +{ + typedef typename remove_all::type MatrixTypeNestedCleaned; + typedef typename MatrixTypeNestedCleaned::Scalar Scalar; + typedef typename MatrixTypeNestedCleaned::Index Index; + enum { + SrcStorageOrder = MatrixTypeNestedCleaned::Flags&RowMajorBit ? RowMajor : ColMajor, + MoveOuter = SrcStorageOrder==RowMajor ? Side==OnTheLeft : Side==OnTheRight + }; + + typedef typename internal::conditional, + SparseMatrix >::type ReturnType; +}; + +template +struct permut_sparsematrix_product_retval + : public ReturnByValue > +{ + typedef typename remove_all::type MatrixTypeNestedCleaned; + typedef typename MatrixTypeNestedCleaned::Scalar Scalar; + typedef typename MatrixTypeNestedCleaned::Index Index; + + enum { + SrcStorageOrder = MatrixTypeNestedCleaned::Flags&RowMajorBit ? RowMajor : ColMajor, + MoveOuter = SrcStorageOrder==RowMajor ? Side==OnTheLeft : Side==OnTheRight + }; + + permut_sparsematrix_product_retval(const PermutationType& perm, const MatrixType& matrix) + : m_permutation(perm), m_matrix(matrix) + {} + + inline int rows() const { return m_matrix.rows(); } + inline int cols() const { return m_matrix.cols(); } + + template inline void evalTo(Dest& dst) const + { + if(MoveOuter) + { + SparseMatrix tmp(m_matrix.rows(), m_matrix.cols()); + VectorXi sizes(m_matrix.outerSize()); + for(Index j=0; j tmp(m_matrix.rows(), m_matrix.cols()); + VectorXi sizes(tmp.outerSize()); + sizes.setZero(); + PermutationMatrix perm; + if((Side==OnTheLeft) ^ Transposed) + perm = m_permutation; + else + perm = m_permutation.transpose(); + + for(Index j=0; j +inline const internal::permut_sparsematrix_product_retval, SparseDerived, OnTheRight, false> +operator*(const SparseMatrixBase& matrix, const PermutationBase& perm) +{ + return internal::permut_sparsematrix_product_retval, SparseDerived, OnTheRight, false>(perm, matrix.derived()); +} + +/** \returns the matrix with the permutation applied to the rows + */ +template +inline const internal::permut_sparsematrix_product_retval, SparseDerived, OnTheLeft, false> +operator*( const PermutationBase& perm, const SparseMatrixBase& matrix) +{ + return internal::permut_sparsematrix_product_retval, SparseDerived, OnTheLeft, false>(perm, matrix.derived()); +} + + + +/** \returns the matrix with the inverse permutation applied to the columns. + */ +template +inline const internal::permut_sparsematrix_product_retval, SparseDerived, OnTheRight, true> +operator*(const SparseMatrixBase& matrix, const Transpose >& tperm) +{ + return internal::permut_sparsematrix_product_retval, SparseDerived, OnTheRight, true>(tperm.nestedPermutation(), matrix.derived()); +} + +/** \returns the matrix with the inverse permutation applied to the rows. + */ +template +inline const internal::permut_sparsematrix_product_retval, SparseDerived, OnTheLeft, true> +operator*(const Transpose >& tperm, const SparseMatrixBase& matrix) +{ + return internal::permut_sparsematrix_product_retval, SparseDerived, OnTheLeft, true>(tperm.nestedPermutation(), matrix.derived()); +} + +} // end namespace Eigen + +#endif // EIGEN_SPARSE_SELFADJOINTVIEW_H diff --git a/extern/Eigen3/Eigen/src/Sparse/SparseProduct.h b/extern/Eigen3/Eigen/src/SparseCore/SparseProduct.h similarity index 62% rename from extern/Eigen3/Eigen/src/Sparse/SparseProduct.h rename to extern/Eigen3/Eigen/src/SparseCore/SparseProduct.h index 1c1f54706ac..6a555b83434 100644 --- a/extern/Eigen3/Eigen/src/Sparse/SparseProduct.h +++ b/extern/Eigen3/Eigen/src/SparseCore/SparseProduct.h @@ -3,28 +3,15 @@ // // Copyright (C) 2008-2010 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_SPARSEPRODUCT_H #define EIGEN_SPARSEPRODUCT_H +namespace Eigen { + template struct SparseSparseProductReturnType { @@ -38,11 +25,11 @@ struct SparseSparseProductReturnType typedef typename internal::conditional, - const typename internal::nested::type>::type LhsNested; + typename internal::nested::type>::type LhsNested; typedef typename internal::conditional, - const typename internal::nested::type>::type RhsNested; + typename internal::nested::type>::type RhsNested; typedef SparseSparseProduct Type; }; @@ -106,9 +93,42 @@ class SparseSparseProduct : internal::no_assignment_operator, template EIGEN_STRONG_INLINE SparseSparseProduct(const Lhs& lhs, const Rhs& rhs) - : m_lhs(lhs), m_rhs(rhs) + : m_lhs(lhs), m_rhs(rhs), m_tolerance(0), m_conservative(true) { - eigen_assert(lhs.cols() == rhs.rows()); + init(); + } + + template + EIGEN_STRONG_INLINE SparseSparseProduct(const Lhs& lhs, const Rhs& rhs, RealScalar tolerance) + : m_lhs(lhs), m_rhs(rhs), m_tolerance(tolerance), m_conservative(false) + { + init(); + } + + SparseSparseProduct pruned(Scalar reference = 0, RealScalar epsilon = NumTraits::dummy_precision()) const + { + return SparseSparseProduct(m_lhs,m_rhs,internal::abs(reference)*epsilon); + } + + template + void evalTo(Dest& result) const + { + if(m_conservative) + internal::conservative_sparse_sparse_product_selector<_LhsNested, _RhsNested, Dest>::run(lhs(),rhs(),result); + else + internal::sparse_sparse_product_with_pruning_selector<_LhsNested, _RhsNested, Dest>::run(lhs(),rhs(),result,m_tolerance); + } + + EIGEN_STRONG_INLINE Index rows() const { return m_lhs.rows(); } + EIGEN_STRONG_INLINE Index cols() const { return m_rhs.cols(); } + + EIGEN_STRONG_INLINE const _LhsNested& lhs() const { return m_lhs; } + EIGEN_STRONG_INLINE const _RhsNested& rhs() const { return m_rhs; } + + protected: + void init() + { + eigen_assert(m_lhs.cols() == m_rhs.rows()); enum { ProductIsValid = _LhsNested::ColsAtCompileTime==Dynamic @@ -127,15 +147,40 @@ class SparseSparseProduct : internal::no_assignment_operator, EIGEN_STATIC_ASSERT(ProductIsValid || SameSizes, INVALID_MATRIX_PRODUCT) } - EIGEN_STRONG_INLINE Index rows() const { return m_lhs.rows(); } - EIGEN_STRONG_INLINE Index cols() const { return m_rhs.cols(); } - - EIGEN_STRONG_INLINE const _LhsNested& lhs() const { return m_lhs; } - EIGEN_STRONG_INLINE const _RhsNested& rhs() const { return m_rhs; } - - protected: LhsNested m_lhs; RhsNested m_rhs; + RealScalar m_tolerance; + bool m_conservative; }; +// sparse = sparse * sparse +template +template +inline Derived& SparseMatrixBase::operator=(const SparseSparseProduct& product) +{ + product.evalTo(derived()); + return derived(); +} + +/** \returns an expression of the product of two sparse matrices. + * By default a conservative product preserving the symbolic non zeros is performed. + * The automatic pruning of the small values can be achieved by calling the pruned() function + * in which case a totally different product algorithm is employed: + * \code + * C = (A*B).pruned(); // supress numerical zeros (exact) + * C = (A*B).pruned(ref); + * C = (A*B).pruned(ref,epsilon); + * \endcode + * where \c ref is a meaningful non zero reference value. + * */ +template +template +inline const typename SparseSparseProductReturnType::Type +SparseMatrixBase::operator*(const SparseMatrixBase &other) const +{ + return typename SparseSparseProductReturnType::Type(derived(), other.derived()); +} + +} // end namespace Eigen + #endif // EIGEN_SPARSEPRODUCT_H diff --git a/extern/Eigen3/Eigen/src/Sparse/SparseRedux.h b/extern/Eigen3/Eigen/src/SparseCore/SparseRedux.h similarity index 56% rename from extern/Eigen3/Eigen/src/Sparse/SparseRedux.h rename to extern/Eigen3/Eigen/src/SparseCore/SparseRedux.h index afc49de7aad..f3da93a71d4 100644 --- a/extern/Eigen3/Eigen/src/Sparse/SparseRedux.h +++ b/extern/Eigen3/Eigen/src/SparseCore/SparseRedux.h @@ -3,34 +3,21 @@ // // Copyright (C) 2008 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_SPARSEREDUX_H #define EIGEN_SPARSEREDUX_H +namespace Eigen { + template typename internal::traits::Scalar SparseMatrixBase::sum() const { eigen_assert(rows()>0 && cols()>0 && "you are using a non initialized matrix"); - Scalar res = 0; + Scalar res(0); for (Index j=0; j::sum() const return Matrix::Map(&m_data.value(0), m_data.size()).sum(); } +} // end namespace Eigen + #endif // EIGEN_SPARSEREDUX_H diff --git a/extern/Eigen3/Eigen/src/Sparse/SparseSelfAdjointView.h b/extern/Eigen3/Eigen/src/SparseCore/SparseSelfAdjointView.h similarity index 75% rename from extern/Eigen3/Eigen/src/Sparse/SparseSelfAdjointView.h rename to extern/Eigen3/Eigen/src/SparseCore/SparseSelfAdjointView.h index d82044c789c..86ec0a6c5e2 100644 --- a/extern/Eigen3/Eigen/src/Sparse/SparseSelfAdjointView.h +++ b/extern/Eigen3/Eigen/src/SparseCore/SparseSelfAdjointView.h @@ -3,30 +3,17 @@ // // Copyright (C) 2009 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_SPARSE_SELFADJOINTVIEW_H #define EIGEN_SPARSE_SELFADJOINTVIEW_H -/** \class SparseSelfAdjointView - * +namespace Eigen { + +/** \ingroup SparseCore_Module + * \class SparseSelfAdjointView * * \brief Pseudo expression to manipulate a triangular sparse matrix as a selfadjoint matrix. * @@ -45,9 +32,6 @@ class SparseSelfAdjointTimeDenseProduct; template class DenseTimeSparseSelfAdjointProduct; -template -class SparseSymmetricPermutationProduct; - namespace internal { template @@ -106,9 +90,6 @@ template class SparseSelfAdjointView * * \returns a reference to \c *this * - * Note that it is faster to set alpha=0 than initializing the matrix to zero - * and then keep the default value alpha=1. - * * To perform \f$ this = this + \alpha ( u^* u ) \f$ you can simply * call this function with u.adjoint(). */ @@ -116,21 +97,21 @@ template class SparseSelfAdjointView SparseSelfAdjointView& rankUpdate(const SparseMatrixBase& u, Scalar alpha = Scalar(1)); /** \internal triggered by sparse_matrix = SparseSelfadjointView; */ - template void evalTo(SparseMatrix& _dest) const + template void evalTo(SparseMatrix& _dest) const { internal::permute_symm_to_fullsymm(m_matrix, _dest); } - template void evalTo(DynamicSparseMatrix& _dest) const + template void evalTo(DynamicSparseMatrix& _dest) const { // TODO directly evaluate into _dest; - SparseMatrix tmp(_dest.rows(),_dest.cols()); + SparseMatrix tmp(_dest.rows(),_dest.cols()); internal::permute_symm_to_fullsymm(m_matrix, tmp); _dest = tmp; } - /** \returns an expression of P^-1 H P */ - SparseSymmetricPermutationProduct<_MatrixTypeNested,UpLo> twistedBy(const PermutationMatrix& perm) const + /** \returns an expression of P H P^-1 */ + SparseSymmetricPermutationProduct<_MatrixTypeNested,UpLo> twistedBy(const PermutationMatrix& perm) const { return SparseSymmetricPermutationProduct<_MatrixTypeNested,UpLo>(m_matrix, perm); } @@ -141,6 +122,20 @@ template class SparseSelfAdjointView permutedMatrix.evalTo(*this); return *this; } + + + SparseSelfAdjointView& operator=(const SparseSelfAdjointView& src) + { + PermutationMatrix pnull; + return *this = src.twistedBy(pnull); + } + + template + SparseSelfAdjointView& operator=(const SparseSelfAdjointView& src) + { + PermutationMatrix pnull; + return *this = src.twistedBy(pnull); + } // const SparseLLT llt() const; @@ -148,7 +143,7 @@ template class SparseSelfAdjointView protected: - const typename MatrixType::Nested m_matrix; + typename MatrixType::Nested m_matrix; mutable VectorI m_countPerRow; mutable VectorI m_countPerCol; }; @@ -230,12 +225,15 @@ class SparseSelfAdjointTimeDenseProduct for (Index j=0; j dest_j(dest.row(LhsIsRowMajor ? j : 0)); for(; (ProcessFirstHalf ? i && i.index() < j : i) ; ++i) { Index a = LhsIsRowMajor ? j : i.index(); @@ -300,7 +298,7 @@ void permute_symm_to_fullsymm(const MatrixType& mat, SparseMatrixj) || (UpLo==Upper && ic) || ( UpLo==Upper && rj) || (UpLo==Upper && ic) || ( (UpLo&Upper)==Upper && r -void permute_symm_to_symm(const MatrixType& mat, SparseMatrix& _dest, const typename MatrixType::Index* perm) +template +void permute_symm_to_symm(const MatrixType& mat, SparseMatrix& _dest, const typename MatrixType::Index* perm) { typedef typename MatrixType::Index Index; typedef typename MatrixType::Scalar Scalar; - typedef SparseMatrix Dest; - Dest& dest(_dest.derived()); + SparseMatrix& dest(_dest.derived()); typedef Matrix VectorI; - //internal::conj_if cj; + enum { + SrcOrder = MatrixType::IsRowMajor ? RowMajor : ColMajor, + StorageOrderMatch = int(SrcOrder) == int(DstOrder), + DstUpLo = DstOrder==RowMajor ? (_DstUpLo==Upper ? Lower : Upper) : _DstUpLo, + SrcUpLo = SrcOrder==RowMajor ? (_SrcUpLo==Upper ? Lower : Upper) : _SrcUpLo + }; Index size = mat.rows(); VectorI count(size); @@ -379,37 +397,40 @@ void permute_symm_to_symm(const MatrixType& mat, SparseMatrixj)) + if((int(SrcUpLo)==int(Lower) && ij)) continue; Index ip = perm ? perm[i] : i; - count[DstUpLo==Lower ? (std::min)(ip,jp) : (std::max)(ip,jp)]++; + count[int(DstUpLo)==int(Lower) ? (std::min)(ip,jp) : (std::max)(ip,jp)]++; } } - dest._outerIndexPtr()[0] = 0; + dest.outerIndexPtr()[0] = 0; for(Index j=0; jj)) + if((int(SrcUpLo)==int(Lower) && ij)) continue; + Index jp = perm ? perm[j] : j; Index ip = perm? perm[i] : i; - Index k = count[DstUpLo==Lower ? (std::min)(ip,jp) : (std::max)(ip,jp)]++; - dest._innerIndexPtr()[k] = DstUpLo==Lower ? (std::max)(ip,jp) : (std::min)(ip,jp); - if((DstUpLo==Lower && ipjp)) - dest._valuePtr()[k] = conj(it.value()); + Index k = count[int(DstUpLo)==int(Lower) ? (std::min)(ip,jp) : (std::max)(ip,jp)]++; + dest.innerIndexPtr()[k] = int(DstUpLo)==int(Lower) ? (std::max)(ip,jp) : (std::min)(ip,jp); + + if(!StorageOrderMatch) std::swap(ip,jp); + if( ((int(DstUpLo)==int(Lower) && ipjp))) + dest.valuePtr()[k] = conj(it.value()); else - dest._valuePtr()[k] = it.value(); + dest.valuePtr()[k] = it.value(); } } } @@ -420,10 +441,12 @@ template class SparseSymmetricPermutationProduct : public EigenBase > { - typedef PermutationMatrix Perm; public: typedef typename MatrixType::Scalar Scalar; typedef typename MatrixType::Index Index; + protected: + typedef PermutationMatrix Perm; + public: typedef Matrix VectorI; typedef typename MatrixType::Nested MatrixTypeNested; typedef typename internal::remove_all::type _MatrixTypeNested; @@ -435,7 +458,8 @@ class SparseSymmetricPermutationProduct inline Index rows() const { return m_matrix.rows(); } inline Index cols() const { return m_matrix.cols(); } - template void evalTo(SparseMatrix& _dest) const + template + void evalTo(SparseMatrix& _dest) const { internal::permute_symm_to_fullsymm(m_matrix,_dest,m_perm.indices().data()); } @@ -446,9 +470,11 @@ class SparseSymmetricPermutationProduct } protected: - const MatrixTypeNested m_matrix; + MatrixTypeNested m_matrix; const Perm& m_perm; }; +} // end namespace Eigen + #endif // EIGEN_SPARSE_SELFADJOINTVIEW_H diff --git a/extern/Eigen3/Eigen/src/SparseCore/SparseSparseProductWithPruning.h b/extern/Eigen3/Eigen/src/SparseCore/SparseSparseProductWithPruning.h new file mode 100644 index 00000000000..2438ac573d0 --- /dev/null +++ b/extern/Eigen3/Eigen/src/SparseCore/SparseSparseProductWithPruning.h @@ -0,0 +1,149 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008-2011 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_SPARSESPARSEPRODUCTWITHPRUNING_H +#define EIGEN_SPARSESPARSEPRODUCTWITHPRUNING_H + +namespace Eigen { + +namespace internal { + + +// perform a pseudo in-place sparse * sparse product assuming all matrices are col major +template +static void sparse_sparse_product_with_pruning_impl(const Lhs& lhs, const Rhs& rhs, ResultType& res, typename ResultType::RealScalar tolerance) +{ + // return sparse_sparse_product_with_pruning_impl2(lhs,rhs,res); + + typedef typename remove_all::type::Scalar Scalar; + typedef typename remove_all::type::Index Index; + + // make sure to call innerSize/outerSize since we fake the storage order. + Index rows = lhs.innerSize(); + Index cols = rhs.outerSize(); + //int size = lhs.outerSize(); + eigen_assert(lhs.outerSize() == rhs.innerSize()); + + // allocate a temporary buffer + AmbiVector tempVector(rows); + + // estimate the number of non zero entries + // given a rhs column containing Y non zeros, we assume that the respective Y columns + // of the lhs differs in average of one non zeros, thus the number of non zeros for + // the product of a rhs column with the lhs is X+Y where X is the average number of non zero + // per column of the lhs. + // Therefore, we have nnz(lhs*rhs) = nnz(lhs) + nnz(rhs) + Index estimated_nnz_prod = lhs.nonZeros() + rhs.nonZeros(); + + // mimics a resizeByInnerOuter: + if(ResultType::IsRowMajor) + res.resize(cols, rows); + else + res.resize(rows, cols); + + res.reserve(estimated_nnz_prod); + double ratioColRes = double(estimated_nnz_prod)/double(lhs.rows()*rhs.cols()); + for (Index j=0; j::Iterator it(tempVector,tolerance); it; ++it) + res.insertBackByOuterInner(j,it.index()) = it.value(); + } + res.finalize(); +} + +template::Flags&RowMajorBit, + int RhsStorageOrder = traits::Flags&RowMajorBit, + int ResStorageOrder = traits::Flags&RowMajorBit> +struct sparse_sparse_product_with_pruning_selector; + +template +struct sparse_sparse_product_with_pruning_selector +{ + typedef typename traits::type>::Scalar Scalar; + typedef typename ResultType::RealScalar RealScalar; + + static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res, RealScalar tolerance) + { + typename remove_all::type _res(res.rows(), res.cols()); + internal::sparse_sparse_product_with_pruning_impl(lhs, rhs, _res, tolerance); + res.swap(_res); + } +}; + +template +struct sparse_sparse_product_with_pruning_selector +{ + typedef typename ResultType::RealScalar RealScalar; + static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res, RealScalar tolerance) + { + // we need a col-major matrix to hold the result + typedef SparseMatrix SparseTemporaryType; + SparseTemporaryType _res(res.rows(), res.cols()); + internal::sparse_sparse_product_with_pruning_impl(lhs, rhs, _res, tolerance); + res = _res; + } +}; + +template +struct sparse_sparse_product_with_pruning_selector +{ + typedef typename ResultType::RealScalar RealScalar; + static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res, RealScalar tolerance) + { + // let's transpose the product to get a column x column product + typename remove_all::type _res(res.rows(), res.cols()); + internal::sparse_sparse_product_with_pruning_impl(rhs, lhs, _res, tolerance); + res.swap(_res); + } +}; + +template +struct sparse_sparse_product_with_pruning_selector +{ + typedef typename ResultType::RealScalar RealScalar; + static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res, RealScalar tolerance) + { + typedef SparseMatrix ColMajorMatrix; + ColMajorMatrix colLhs(lhs); + ColMajorMatrix colRhs(rhs); + internal::sparse_sparse_product_with_pruning_impl(colLhs, colRhs, res, tolerance); + + // let's transpose the product to get a column x column product +// typedef SparseMatrix SparseTemporaryType; +// SparseTemporaryType _res(res.cols(), res.rows()); +// sparse_sparse_product_with_pruning_impl(rhs, lhs, _res); +// res = _res.transpose(); + } +}; + +// NOTE the 2 others cases (col row *) must never occur since they are caught +// by ProductReturnType which transforms it to (col col *) by evaluating rhs. + +} // end namespace internal + +} // end namespace Eigen + +#endif // EIGEN_SPARSESPARSEPRODUCTWITHPRUNING_H diff --git a/extern/Eigen3/Eigen/src/Sparse/SparseTranspose.h b/extern/Eigen3/Eigen/src/SparseCore/SparseTranspose.h similarity index 53% rename from extern/Eigen3/Eigen/src/Sparse/SparseTranspose.h rename to extern/Eigen3/Eigen/src/SparseCore/SparseTranspose.h index 2aea2fa32c7..273f9de688f 100644 --- a/extern/Eigen3/Eigen/src/Sparse/SparseTranspose.h +++ b/extern/Eigen3/Eigen/src/SparseCore/SparseTranspose.h @@ -3,28 +3,15 @@ // // Copyright (C) 2008-2009 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_SPARSETRANSPOSE_H #define EIGEN_SPARSETRANSPOSE_H +namespace Eigen { + template class TransposeImpl : public SparseMatrixBase > { @@ -39,17 +26,21 @@ template class TransposeImpl inline Index nonZeros() const { return derived().nestedExpression().nonZeros(); } }; +// NOTE: VC10 trigger an ICE if don't put typename TransposeImpl:: in front of Index, +// a typedef typename TransposeImpl::Index Index; +// does not fix the issue. +// An alternative is to define the nested class in the parent class itself. template class TransposeImpl::InnerIterator : public _MatrixTypeNested::InnerIterator { typedef typename _MatrixTypeNested::InnerIterator Base; public: - EIGEN_STRONG_INLINE InnerIterator(const TransposeImpl& trans, Index outer) + EIGEN_STRONG_INLINE InnerIterator(const TransposeImpl& trans, typename TransposeImpl::Index outer) : Base(trans.derived().nestedExpression(), outer) {} - inline Index row() const { return Base::col(); } - inline Index col() const { return Base::row(); } + inline typename TransposeImpl::Index row() const { return Base::col(); } + inline typename TransposeImpl::Index col() const { return Base::row(); } }; template class TransposeImpl::ReverseInnerIterator @@ -58,11 +49,13 @@ template class TransposeImpl::ReverseInn typedef typename _MatrixTypeNested::ReverseInnerIterator Base; public: - EIGEN_STRONG_INLINE ReverseInnerIterator(const TransposeImpl& xpr, Index outer) + EIGEN_STRONG_INLINE ReverseInnerIterator(const TransposeImpl& xpr, typename TransposeImpl::Index outer) : Base(xpr.derived().nestedExpression(), outer) {} - inline Index row() const { return Base::col(); } - inline Index col() const { return Base::row(); } + inline typename TransposeImpl::Index row() const { return Base::col(); } + inline typename TransposeImpl::Index col() const { return Base::row(); } }; +} // end namespace Eigen + #endif // EIGEN_SPARSETRANSPOSE_H diff --git a/extern/Eigen3/Eigen/src/SparseCore/SparseTriangularView.h b/extern/Eigen3/Eigen/src/SparseCore/SparseTriangularView.h new file mode 100644 index 00000000000..477e4bd94b0 --- /dev/null +++ b/extern/Eigen3/Eigen/src/SparseCore/SparseTriangularView.h @@ -0,0 +1,164 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2009 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_SPARSE_TRIANGULARVIEW_H +#define EIGEN_SPARSE_TRIANGULARVIEW_H + +namespace Eigen { + +namespace internal { + +template +struct traits > +: public traits +{}; + +} // namespace internal + +template class SparseTriangularView + : public SparseMatrixBase > +{ + enum { SkipFirst = ((Mode&Lower) && !(MatrixType::Flags&RowMajorBit)) + || ((Mode&Upper) && (MatrixType::Flags&RowMajorBit)), + SkipLast = !SkipFirst, + HasUnitDiag = (Mode&UnitDiag) ? 1 : 0 + }; + + public: + + EIGEN_SPARSE_PUBLIC_INTERFACE(SparseTriangularView) + + class InnerIterator; + class ReverseInnerIterator; + + inline Index rows() const { return m_matrix.rows(); } + inline Index cols() const { return m_matrix.cols(); } + + typedef typename MatrixType::Nested MatrixTypeNested; + typedef typename internal::remove_reference::type MatrixTypeNestedNonRef; + typedef typename internal::remove_all::type MatrixTypeNestedCleaned; + + inline SparseTriangularView(const MatrixType& matrix) : m_matrix(matrix) {} + + /** \internal */ + inline const MatrixTypeNestedCleaned& nestedExpression() const { return m_matrix; } + + template + typename internal::plain_matrix_type_column_major::type + solve(const MatrixBase& other) const; + + template void solveInPlace(MatrixBase& other) const; + template void solveInPlace(SparseMatrixBase& other) const; + + protected: + MatrixTypeNested m_matrix; +}; + +template +class SparseTriangularView::InnerIterator : public MatrixTypeNestedCleaned::InnerIterator +{ + typedef typename MatrixTypeNestedCleaned::InnerIterator Base; + public: + + EIGEN_STRONG_INLINE InnerIterator(const SparseTriangularView& view, Index outer) + : Base(view.nestedExpression(), outer), m_returnOne(false) + { + if(SkipFirst) + { + while((*this) && (HasUnitDiag ? this->index()<=outer : this->index()=Base::outer())) + { + if((!SkipFirst) && Base::operator bool()) + Base::operator++(); + m_returnOne = true; + } + } + + EIGEN_STRONG_INLINE InnerIterator& operator++() + { + if(HasUnitDiag && m_returnOne) + m_returnOne = false; + else + { + Base::operator++(); + if(HasUnitDiag && (!SkipFirst) && ((!Base::operator bool()) || Base::index()>=Base::outer())) + { + if((!SkipFirst) && Base::operator bool()) + Base::operator++(); + m_returnOne = true; + } + } + return *this; + } + + inline Index row() const { return Base::row(); } + inline Index col() const { return Base::col(); } + inline Index index() const + { + if(HasUnitDiag && m_returnOne) return Base::outer(); + else return Base::index(); + } + inline Scalar value() const + { + if(HasUnitDiag && m_returnOne) return Scalar(1); + else return Base::value(); + } + + EIGEN_STRONG_INLINE operator bool() const + { + if(HasUnitDiag && m_returnOne) + return true; + return (SkipFirst ? Base::operator bool() : (Base::operator bool() && this->index() <= this->outer())); + } + protected: + bool m_returnOne; +}; + +template +class SparseTriangularView::ReverseInnerIterator : public MatrixTypeNestedCleaned::ReverseInnerIterator +{ + typedef typename MatrixTypeNestedCleaned::ReverseInnerIterator Base; + public: + + EIGEN_STRONG_INLINE ReverseInnerIterator(const SparseTriangularView& view, Index outer) + : Base(view.nestedExpression(), outer) + { + eigen_assert((!HasUnitDiag) && "ReverseInnerIterator does not support yet triangular views with a unit diagonal"); + if(SkipLast) + while((*this) && this->index()>outer) + --(*this); + } + + EIGEN_STRONG_INLINE InnerIterator& operator--() + { Base::operator--(); return *this; } + + inline Index row() const { return Base::row(); } + inline Index col() const { return Base::col(); } + + EIGEN_STRONG_INLINE operator bool() const + { + return SkipLast ? Base::operator bool() : (Base::operator bool() && this->index() >= this->outer()); + } +}; + +template +template +inline const SparseTriangularView +SparseMatrixBase::triangularView() const +{ + return derived(); +} + +} // end namespace Eigen + +#endif // EIGEN_SPARSE_TRIANGULARVIEW_H diff --git a/extern/Eigen3/Eigen/src/Sparse/SparseUtil.h b/extern/Eigen3/Eigen/src/SparseCore/SparseUtil.h similarity index 60% rename from extern/Eigen3/Eigen/src/Sparse/SparseUtil.h rename to extern/Eigen3/Eigen/src/SparseCore/SparseUtil.h index db9ae98e7a0..6062a086ff7 100644 --- a/extern/Eigen3/Eigen/src/Sparse/SparseUtil.h +++ b/extern/Eigen3/Eigen/src/SparseCore/SparseUtil.h @@ -3,28 +3,15 @@ // // Copyright (C) 2008 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_SPARSEUTIL_H #define EIGEN_SPARSEUTIL_H +namespace Eigen { + #ifdef NDEBUG #define EIGEN_DBG_SPARSE(X) #else @@ -58,22 +45,22 @@ EIGEN_SPARSE_INHERIT_SCALAR_ASSIGNMENT_OPERATOR(Derived, /=) #define _EIGEN_SPARSE_PUBLIC_INTERFACE(Derived, BaseClass) \ typedef BaseClass Base; \ - typedef typename Eigen::internal::traits::Scalar Scalar; \ + typedef typename Eigen::internal::traits::Scalar Scalar; \ typedef typename Eigen::NumTraits::Real RealScalar; \ - typedef typename Eigen::internal::nested::type Nested; \ - typedef typename Eigen::internal::traits::StorageKind StorageKind; \ - typedef typename Eigen::internal::traits::Index Index; \ - enum { RowsAtCompileTime = Eigen::internal::traits::RowsAtCompileTime, \ - ColsAtCompileTime = Eigen::internal::traits::ColsAtCompileTime, \ - Flags = Eigen::internal::traits::Flags, \ - CoeffReadCost = Eigen::internal::traits::CoeffReadCost, \ + typedef typename Eigen::internal::nested::type Nested; \ + typedef typename Eigen::internal::traits::StorageKind StorageKind; \ + typedef typename Eigen::internal::traits::Index Index; \ + enum { RowsAtCompileTime = Eigen::internal::traits::RowsAtCompileTime, \ + ColsAtCompileTime = Eigen::internal::traits::ColsAtCompileTime, \ + Flags = Eigen::internal::traits::Flags, \ + CoeffReadCost = Eigen::internal::traits::CoeffReadCost, \ SizeAtCompileTime = Base::SizeAtCompileTime, \ IsVectorAtCompileTime = Base::IsVectorAtCompileTime }; \ using Base::derived; \ using Base::const_cast_derived; #define EIGEN_SPARSE_PUBLIC_INTERFACE(Derived) \ - _EIGEN_SPARSE_PUBLIC_INTERFACE(Derived, Eigen::SparseMatrixBase) + _EIGEN_SPARSE_PUBLIC_INTERFACE(Derived, Eigen::SparseMatrixBase) const int CoherentAccessPattern = 0x1; const int InnerRandomAccessPattern = 0x2 | CoherentAccessPattern; @@ -100,20 +87,43 @@ template class SparseDenseOuterProdu template struct SparseSparseProductReturnType; template::ColsAtCompileTime> struct DenseSparseProductReturnType; template::ColsAtCompileTime> struct SparseDenseProductReturnType; +template class SparseSymmetricPermutationProduct; namespace internal { -template struct eval -{ - typedef typename traits::Scalar _Scalar; - enum { - _Flags = traits::Flags - }; +template struct sparse_eval; +template struct eval + : public sparse_eval::RowsAtCompileTime,traits::ColsAtCompileTime> +{}; + +template struct sparse_eval { + typedef typename traits::Scalar _Scalar; + enum { _Flags = traits::Flags| RowMajorBit }; + public: + typedef SparseVector<_Scalar, _Flags> type; +}; + +template struct sparse_eval { + typedef typename traits::Scalar _Scalar; + enum { _Flags = traits::Flags & (~RowMajorBit) }; + public: + typedef SparseVector<_Scalar, _Flags> type; +}; + +template struct sparse_eval { + typedef typename traits::Scalar _Scalar; + enum { _Flags = traits::Flags }; public: typedef SparseMatrix<_Scalar, _Flags> type; }; +template struct sparse_eval { + typedef typename traits::Scalar _Scalar; + public: + typedef Matrix<_Scalar, 1, 1> type; +}; + template struct plain_matrix_type { typedef typename traits::Scalar _Scalar; @@ -127,4 +137,37 @@ template struct plain_matrix_type } // end namespace internal +/** \ingroup SparseCore_Module + * + * \class Triplet + * + * \brief A small structure to hold a non zero as a triplet (i,j,value). + * + * \sa SparseMatrix::setFromTriplets() + */ +template +class Triplet +{ +public: + Triplet() : m_row(0), m_col(0), m_value(0) {} + + Triplet(const Index& i, const Index& j, const Scalar& v = Scalar(0)) + : m_row(i), m_col(j), m_value(v) + {} + + /** \returns the row index of the element */ + const Index& row() const { return m_row; } + + /** \returns the column index of the element */ + const Index& col() const { return m_col; } + + /** \returns the value of the element */ + const Scalar& value() const { return m_value; } +protected: + Index m_row, m_col; + Scalar m_value; +}; + +} // end namespace Eigen + #endif // EIGEN_SPARSEUTIL_H diff --git a/extern/Eigen3/Eigen/src/Sparse/SparseVector.h b/extern/Eigen3/Eigen/src/SparseCore/SparseVector.h similarity index 63% rename from extern/Eigen3/Eigen/src/Sparse/SparseVector.h rename to extern/Eigen3/Eigen/src/SparseCore/SparseVector.h index ce4bb51a27e..c952f654038 100644 --- a/extern/Eigen3/Eigen/src/Sparse/SparseVector.h +++ b/extern/Eigen3/Eigen/src/SparseCore/SparseVector.h @@ -3,29 +3,17 @@ // // Copyright (C) 2008-2009 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_SPARSEVECTOR_H #define EIGEN_SPARSEVECTOR_H -/** \class SparseVector +namespace Eigen { + +/** \ingroup SparseCore_Module + * \class SparseVector * * \brief a sparse vector class * @@ -46,13 +34,13 @@ struct traits > typedef Sparse StorageKind; typedef MatrixXpr XprKind; enum { - IsColVector = _Options & RowMajorBit ? 0 : 1, + IsColVector = (_Options & RowMajorBit) ? 0 : 1, RowsAtCompileTime = IsColVector ? Dynamic : 1, ColsAtCompileTime = IsColVector ? 1 : Dynamic, MaxRowsAtCompileTime = RowsAtCompileTime, MaxColsAtCompileTime = ColsAtCompileTime, - Flags = _Options | NestByRefBit | LvalueBit, + Flags = _Options | NestByRefBit | LvalueBit | (IsColVector ? 0 : RowMajorBit), CoeffReadCost = NumTraits::ReadCost, SupportedAccessPatterns = InnerRandomAccessPattern }; @@ -67,7 +55,6 @@ class SparseVector EIGEN_SPARSE_PUBLIC_INTERFACE(SparseVector) EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(SparseVector, +=) EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(SparseVector, -=) -// EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(SparseVector, =) protected: public: @@ -79,11 +66,11 @@ class SparseVector Options = _Options }; - CompressedStorage m_data; + internal::CompressedStorage m_data; Index m_size; - CompressedStorage& _data() { return m_data; } - CompressedStorage& _data() const { return m_data; } + internal::CompressedStorage& _data() { return m_data; } + internal::CompressedStorage& _data() const { return m_data; } public: @@ -91,13 +78,12 @@ class SparseVector EIGEN_STRONG_INLINE Index cols() const { return IsColVector ? 1 : m_size; } EIGEN_STRONG_INLINE Index innerSize() const { return m_size; } EIGEN_STRONG_INLINE Index outerSize() const { return 1; } - EIGEN_STRONG_INLINE Index innerNonZeros(Index j) const { eigen_assert(j==0); return m_size; } - EIGEN_STRONG_INLINE const Scalar* _valuePtr() const { return &m_data.value(0); } - EIGEN_STRONG_INLINE Scalar* _valuePtr() { return &m_data.value(0); } + EIGEN_STRONG_INLINE const Scalar* valuePtr() const { return &m_data.value(0); } + EIGEN_STRONG_INLINE Scalar* valuePtr() { return &m_data.value(0); } - EIGEN_STRONG_INLINE const Index* _innerIndexPtr() const { return &m_data.index(0); } - EIGEN_STRONG_INLINE Index* _innerIndexPtr() { return &m_data.index(0); } + EIGEN_STRONG_INLINE const Index* innerIndexPtr() const { return &m_data.index(0); } + EIGEN_STRONG_INLINE Index* innerIndexPtr() { return &m_data.index(0); } inline Scalar coeff(Index row, Index col) const { @@ -126,6 +112,7 @@ class SparseVector public: class InnerIterator; + class ReverseInnerIterator; inline void setZero() { m_data.clear(); } @@ -134,11 +121,13 @@ class SparseVector inline void startVec(Index outer) { + EIGEN_UNUSED_VARIABLE(outer); eigen_assert(outer==0); } inline Scalar& insertBackByOuterInner(Index outer, Index inner) { + EIGEN_UNUSED_VARIABLE(outer); eigen_assert(outer==0); return insertBack(inner); } @@ -158,7 +147,7 @@ class SparseVector Scalar& insert(Index i) { Index startId = 0; - Index p = m_data.size() - 1; + Index p = Index(m_data.size()) - 1; // TODO smart realloc m_data.resize(p+2,1); @@ -205,13 +194,6 @@ class SparseVector inline SparseVector(Index rows, Index cols) : m_size(0) { resize(rows,cols); } - template - inline SparseVector(const MatrixBase& other) - : m_size(0) - { - *this = other.derived(); - } - template inline SparseVector(const SparseMatrixBase& other) : m_size(0) @@ -249,9 +231,9 @@ class SparseVector inline SparseVector& operator=(const SparseMatrixBase& other) { if (int(RowsAtCompileTime)!=int(OtherDerived::RowsAtCompileTime)) - return Base::operator=(other.transpose()); + return assign(other.transpose()); else - return Base::operator=(other); + return assign(other); } #ifndef EIGEN_PARSED_BY_DOXYGEN @@ -262,56 +244,6 @@ class SparseVector } #endif -// const bool needToTranspose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit); -// if (needToTranspose) -// { -// // two passes algorithm: -// // 1 - compute the number of coeffs per dest inner vector -// // 2 - do the actual copy/eval -// // Since each coeff of the rhs has to be evaluated twice, let's evauluate it if needed -// typedef typename internal::nested::type OtherCopy; -// OtherCopy otherCopy(other.derived()); -// typedef typename internal::remove_all::type _OtherCopy; -// -// resize(other.rows(), other.cols()); -// Eigen::Map(m_outerIndex,outerSize()).setZero(); -// // pass 1 -// // FIXME the above copy could be merged with that pass -// for (int j=0; j::operator=(other.derived()); -// } -// } - friend std::ostream & operator << (std::ostream & s, const SparseVector& m) { for (Index i=0; i + EIGEN_DONT_INLINE SparseVector& assign(const SparseMatrixBase& _other) + { + const OtherDerived& other(_other.derived()); + const bool needToTranspose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit); + if(needToTranspose) + { + Index size = other.size(); + Index nnz = other.nonZeros(); + resize(size); + reserve(nnz); + for(Index i=0; i @@ -399,18 +336,14 @@ class SparseVector::InnerIterator InnerIterator(const SparseVector& vec, Index outer=0) : m_data(vec.m_data), m_id(0), m_end(static_cast(m_data.size())) { + EIGEN_UNUSED_VARIABLE(outer); eigen_assert(outer==0); } - InnerIterator(const CompressedStorage& data) + InnerIterator(const internal::CompressedStorage& data) : m_data(data), m_id(0), m_end(static_cast(m_data.size())) {} - template - InnerIterator(const Flagged& vec, Index ) - : m_data(vec._expression().m_data), m_id(0), m_end(m_data.size()) - {} - inline InnerIterator& operator++() { m_id++; return *this; } inline Scalar value() const { return m_data.value(m_id); } @@ -423,9 +356,43 @@ class SparseVector::InnerIterator inline operator bool() const { return (m_id < m_end); } protected: - const CompressedStorage& m_data; + const internal::CompressedStorage& m_data; Index m_id; const Index m_end; }; +template +class SparseVector::ReverseInnerIterator +{ + public: + ReverseInnerIterator(const SparseVector& vec, Index outer=0) + : m_data(vec.m_data), m_id(static_cast(m_data.size())), m_start(0) + { + EIGEN_UNUSED_VARIABLE(outer); + eigen_assert(outer==0); + } + + ReverseInnerIterator(const internal::CompressedStorage& data) + : m_data(data), m_id(static_cast(m_data.size())), m_start(0) + {} + + inline ReverseInnerIterator& operator--() { m_id--; return *this; } + + inline Scalar value() const { return m_data.value(m_id-1); } + inline Scalar& valueRef() { return const_cast(m_data.value(m_id-1)); } + + inline Index index() const { return m_data.index(m_id-1); } + inline Index row() const { return IsColVector ? index() : 0; } + inline Index col() const { return IsColVector ? 0 : index(); } + + inline operator bool() const { return (m_id > m_start); } + + protected: + const internal::CompressedStorage& m_data; + Index m_id; + const Index m_start; +}; + +} // end namespace Eigen + #endif // EIGEN_SPARSEVECTOR_H diff --git a/extern/Eigen3/Eigen/src/Sparse/SparseView.h b/extern/Eigen3/Eigen/src/SparseCore/SparseView.h similarity index 64% rename from extern/Eigen3/Eigen/src/Sparse/SparseView.h rename to extern/Eigen3/Eigen/src/SparseCore/SparseView.h index 24306561098..8b0b9ea0304 100644 --- a/extern/Eigen3/Eigen/src/Sparse/SparseView.h +++ b/extern/Eigen3/Eigen/src/SparseCore/SparseView.h @@ -1,31 +1,18 @@ // This file is part of Eigen, a lightweight C++ template library // for linear algebra. // -// Copyright (C) 2010 Gael Guennebaud +// Copyright (C) 2011 Gael Guennebaud // Copyright (C) 2010 Daniel Lowengrub // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_SPARSEVIEW_H #define EIGEN_SPARSEVIEW_H +namespace Eigen { + namespace internal { template @@ -61,7 +48,7 @@ public: inline Index outerSize() const { return m_matrix.outerSize(); } protected: - const MatrixTypeNested m_matrix; + MatrixTypeNested m_matrix; Scalar m_reference; typename NumTraits::Real m_epsilon; }; @@ -92,10 +79,10 @@ protected: private: void incrementToNonZero() { - while(internal::isMuchSmallerThan(value(), m_view.m_reference, m_view.m_epsilon) && (bool(*this))) - { - IterBase::operator++(); - } + while((bool(*this)) && internal::isMuchSmallerThan(value(), m_view.m_reference, m_view.m_epsilon)) + { + IterBase::operator++(); + } } }; @@ -106,4 +93,6 @@ const SparseView MatrixBase::sparseView(const Scalar& m_refere return SparseView(derived(), m_reference, m_epsilon); } +} // end namespace Eigen + #endif diff --git a/extern/Eigen3/Eigen/src/Sparse/TriangularSolver.h b/extern/Eigen3/Eigen/src/SparseCore/TriangularSolver.h similarity index 83% rename from extern/Eigen3/Eigen/src/Sparse/TriangularSolver.h rename to extern/Eigen3/Eigen/src/SparseCore/TriangularSolver.h index 62bb8bb44c9..cb8ad82b4f6 100644 --- a/extern/Eigen3/Eigen/src/Sparse/TriangularSolver.h +++ b/extern/Eigen3/Eigen/src/SparseCore/TriangularSolver.h @@ -3,28 +3,15 @@ // // Copyright (C) 2008 Gael Guennebaud // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_SPARSETRIANGULARSOLVER_H #define EIGEN_SPARSETRIANGULARSOLVER_H +namespace Eigen { + namespace internal { template for(int i=0; i for(int i=lhs.rows()-1 ; i>=0 ; --i) { Scalar tmp = other.coeff(i,col); + Scalar l_ii = 0; typename Lhs::InnerIterator it(lhs, i); - if (it && it.index() == i) + while(it && it.index() if (Mode & UnitDiag) other.coeffRef(i,col) = tmp; else - { - typename Lhs::InnerIterator it(lhs, i); - eigen_assert(it && it.index() == i); - other.coeffRef(i,col) = tmp/it.value(); - } + other.coeffRef(i,col) = tmp/l_ii; } } } @@ -118,9 +110,11 @@ struct sparse_solve_triangular_selector if (tmp!=Scalar(0)) // optimization when other is actually sparse { typename Lhs::InnerIterator it(lhs, i); + while(it && it.index() { if(!(Mode & UnitDiag)) { - // FIXME lhs.coeff(i,i) might not be always efficient while it must simply be the - // last element of the column ! - other.coeffRef(i,col) /= lhs.innerVector(i).lastCoeff(); + // TODO replace this by a binary search. make sure the binary search is safe for partially sorted elements + typename Lhs::ReverseInnerIterator it(lhs, i); + while(it && it.index()!=i) + --it; + eigen_assert(it && it.index()==i); + other.coeffRef(i,col) /= it.value(); } typename Lhs::InnerIterator it(lhs, i); for(; it && it.index() template void SparseTriangularView::solveInPlace(MatrixBase& other) const { - eigen_assert(m_matrix.cols() == m_matrix.rows()); - eigen_assert(m_matrix.cols() == other.rows()); - eigen_assert(!(Mode & ZeroDiag)); - eigen_assert((Mode & (Upper|Lower)) != 0); + eigen_assert(m_matrix.cols() == m_matrix.rows() && m_matrix.cols() == other.rows()); + eigen_assert((!(Mode & ZeroDiag)) && bool(Mode & (Upper|Lower))); enum { copy = internal::traits::Flags & RowMajorBit }; @@ -295,10 +290,8 @@ template template void SparseTriangularView::solveInPlace(SparseMatrixBase& other) const { - eigen_assert(m_matrix.cols() == m_matrix.rows()); - eigen_assert(m_matrix.cols() == other.rows()); - eigen_assert(!(Mode & ZeroDiag)); - eigen_assert((Mode & (Upper|Lower)) != 0); + eigen_assert(m_matrix.cols() == m_matrix.rows() && m_matrix.cols() == other.rows()); + eigen_assert( (!(Mode & ZeroDiag)) && bool(Mode & (Upper|Lower))); // enum { copy = internal::traits::Flags & RowMajorBit }; @@ -336,4 +329,6 @@ SparseMatrixBase::solveTriangular(const MatrixBase& other } #endif // EIGEN2_SUPPORT +} // end namespace Eigen + #endif // EIGEN_SPARSETRIANGULARSOLVER_H diff --git a/extern/Eigen3/Eigen/src/StlSupport/StdDeque.h b/extern/Eigen3/Eigen/src/StlSupport/StdDeque.h index 6f12c106dbc..4ee8e5c10a5 100644 --- a/extern/Eigen3/Eigen/src/StlSupport/StdDeque.h +++ b/extern/Eigen3/Eigen/src/StlSupport/StdDeque.h @@ -4,24 +4,9 @@ // Copyright (C) 2009 Gael Guennebaud // Copyright (C) 2009 Hauke Heibel // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_STDDEQUE_H #define EIGEN_STDDEQUE_H diff --git a/extern/Eigen3/Eigen/src/StlSupport/StdList.h b/extern/Eigen3/Eigen/src/StlSupport/StdList.h index d329a0b2dc5..627381ecec0 100644 --- a/extern/Eigen3/Eigen/src/StlSupport/StdList.h +++ b/extern/Eigen3/Eigen/src/StlSupport/StdList.h @@ -3,24 +3,9 @@ // // Copyright (C) 2009 Hauke Heibel // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_STDLIST_H #define EIGEN_STDLIST_H diff --git a/extern/Eigen3/Eigen/src/StlSupport/StdVector.h b/extern/Eigen3/Eigen/src/StlSupport/StdVector.h index 27d6ab539f9..40a9abefa82 100644 --- a/extern/Eigen3/Eigen/src/StlSupport/StdVector.h +++ b/extern/Eigen3/Eigen/src/StlSupport/StdVector.h @@ -4,24 +4,9 @@ // Copyright (C) 2009 Gael Guennebaud // Copyright (C) 2009 Hauke Heibel // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_STDVECTOR_H #define EIGEN_STDVECTOR_H diff --git a/extern/Eigen3/Eigen/src/StlSupport/details.h b/extern/Eigen3/Eigen/src/StlSupport/details.h index 397c8ef8581..d8debc7c4f8 100644 --- a/extern/Eigen3/Eigen/src/StlSupport/details.h +++ b/extern/Eigen3/Eigen/src/StlSupport/details.h @@ -4,24 +4,9 @@ // Copyright (C) 2009 Gael Guennebaud // Copyright (C) 2009 Hauke Heibel // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_STL_DETAILS_H #define EIGEN_STL_DETAILS_H diff --git a/extern/Eigen3/Eigen/src/SuperLUSupport/SuperLUSupport.h b/extern/Eigen3/Eigen/src/SuperLUSupport/SuperLUSupport.h new file mode 100644 index 00000000000..11fb014dd93 --- /dev/null +++ b/extern/Eigen3/Eigen/src/SuperLUSupport/SuperLUSupport.h @@ -0,0 +1,1025 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008-2011 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_SUPERLUSUPPORT_H +#define EIGEN_SUPERLUSUPPORT_H + +namespace Eigen { + +#define DECL_GSSVX(PREFIX,FLOATTYPE,KEYTYPE) \ + extern "C" { \ + typedef struct { FLOATTYPE for_lu; FLOATTYPE total_needed; int expansions; } PREFIX##mem_usage_t; \ + extern void PREFIX##gssvx(superlu_options_t *, SuperMatrix *, int *, int *, int *, \ + char *, FLOATTYPE *, FLOATTYPE *, SuperMatrix *, SuperMatrix *, \ + void *, int, SuperMatrix *, SuperMatrix *, \ + FLOATTYPE *, FLOATTYPE *, FLOATTYPE *, FLOATTYPE *, \ + PREFIX##mem_usage_t *, SuperLUStat_t *, int *); \ + } \ + inline float SuperLU_gssvx(superlu_options_t *options, SuperMatrix *A, \ + int *perm_c, int *perm_r, int *etree, char *equed, \ + FLOATTYPE *R, FLOATTYPE *C, SuperMatrix *L, \ + SuperMatrix *U, void *work, int lwork, \ + SuperMatrix *B, SuperMatrix *X, \ + FLOATTYPE *recip_pivot_growth, \ + FLOATTYPE *rcond, FLOATTYPE *ferr, FLOATTYPE *berr, \ + SuperLUStat_t *stats, int *info, KEYTYPE) { \ + PREFIX##mem_usage_t mem_usage; \ + PREFIX##gssvx(options, A, perm_c, perm_r, etree, equed, R, C, L, \ + U, work, lwork, B, X, recip_pivot_growth, rcond, \ + ferr, berr, &mem_usage, stats, info); \ + return mem_usage.for_lu; /* bytes used by the factor storage */ \ + } + +DECL_GSSVX(s,float,float) +DECL_GSSVX(c,float,std::complex) +DECL_GSSVX(d,double,double) +DECL_GSSVX(z,double,std::complex) + +#ifdef MILU_ALPHA +#define EIGEN_SUPERLU_HAS_ILU +#endif + +#ifdef EIGEN_SUPERLU_HAS_ILU + +// similarly for the incomplete factorization using gsisx +#define DECL_GSISX(PREFIX,FLOATTYPE,KEYTYPE) \ + extern "C" { \ + extern void PREFIX##gsisx(superlu_options_t *, SuperMatrix *, int *, int *, int *, \ + char *, FLOATTYPE *, FLOATTYPE *, SuperMatrix *, SuperMatrix *, \ + void *, int, SuperMatrix *, SuperMatrix *, FLOATTYPE *, FLOATTYPE *, \ + PREFIX##mem_usage_t *, SuperLUStat_t *, int *); \ + } \ + inline float SuperLU_gsisx(superlu_options_t *options, SuperMatrix *A, \ + int *perm_c, int *perm_r, int *etree, char *equed, \ + FLOATTYPE *R, FLOATTYPE *C, SuperMatrix *L, \ + SuperMatrix *U, void *work, int lwork, \ + SuperMatrix *B, SuperMatrix *X, \ + FLOATTYPE *recip_pivot_growth, \ + FLOATTYPE *rcond, \ + SuperLUStat_t *stats, int *info, KEYTYPE) { \ + PREFIX##mem_usage_t mem_usage; \ + PREFIX##gsisx(options, A, perm_c, perm_r, etree, equed, R, C, L, \ + U, work, lwork, B, X, recip_pivot_growth, rcond, \ + &mem_usage, stats, info); \ + return mem_usage.for_lu; /* bytes used by the factor storage */ \ + } + +DECL_GSISX(s,float,float) +DECL_GSISX(c,float,std::complex) +DECL_GSISX(d,double,double) +DECL_GSISX(z,double,std::complex) + +#endif + +template +struct SluMatrixMapHelper; + +/** \internal + * + * A wrapper class for SuperLU matrices. It supports only compressed sparse matrices + * and dense matrices. Supernodal and other fancy format are not supported by this wrapper. + * + * This wrapper class mainly aims to avoids the need of dynamic allocation of the storage structure. + */ +struct SluMatrix : SuperMatrix +{ + SluMatrix() + { + Store = &storage; + } + + SluMatrix(const SluMatrix& other) + : SuperMatrix(other) + { + Store = &storage; + storage = other.storage; + } + + SluMatrix& operator=(const SluMatrix& other) + { + SuperMatrix::operator=(static_cast(other)); + Store = &storage; + storage = other.storage; + return *this; + } + + struct + { + union {int nnz;int lda;}; + void *values; + int *innerInd; + int *outerInd; + } storage; + + void setStorageType(Stype_t t) + { + Stype = t; + if (t==SLU_NC || t==SLU_NR || t==SLU_DN) + Store = &storage; + else + { + eigen_assert(false && "storage type not supported"); + Store = 0; + } + } + + template + void setScalarType() + { + if (internal::is_same::value) + Dtype = SLU_S; + else if (internal::is_same::value) + Dtype = SLU_D; + else if (internal::is_same >::value) + Dtype = SLU_C; + else if (internal::is_same >::value) + Dtype = SLU_Z; + else + { + eigen_assert(false && "Scalar type not supported by SuperLU"); + } + } + + template + static SluMatrix Map(MatrixBase& _mat) + { + MatrixType& mat(_mat.derived()); + eigen_assert( ((MatrixType::Flags&RowMajorBit)!=RowMajorBit) && "row-major dense matrices are not supported by SuperLU"); + SluMatrix res; + res.setStorageType(SLU_DN); + res.setScalarType(); + res.Mtype = SLU_GE; + + res.nrow = mat.rows(); + res.ncol = mat.cols(); + + res.storage.lda = MatrixType::IsVectorAtCompileTime ? mat.size() : mat.outerStride(); + res.storage.values = mat.data(); + return res; + } + + template + static SluMatrix Map(SparseMatrixBase& mat) + { + SluMatrix res; + if ((MatrixType::Flags&RowMajorBit)==RowMajorBit) + { + res.setStorageType(SLU_NR); + res.nrow = mat.cols(); + res.ncol = mat.rows(); + } + else + { + res.setStorageType(SLU_NC); + res.nrow = mat.rows(); + res.ncol = mat.cols(); + } + + res.Mtype = SLU_GE; + + res.storage.nnz = mat.nonZeros(); + res.storage.values = mat.derived().valuePtr(); + res.storage.innerInd = mat.derived().innerIndexPtr(); + res.storage.outerInd = mat.derived().outerIndexPtr(); + + res.setScalarType(); + + // FIXME the following is not very accurate + if (MatrixType::Flags & Upper) + res.Mtype = SLU_TRU; + if (MatrixType::Flags & Lower) + res.Mtype = SLU_TRL; + + eigen_assert(((MatrixType::Flags & SelfAdjoint)==0) && "SelfAdjoint matrix shape not supported by SuperLU"); + + return res; + } +}; + +template +struct SluMatrixMapHelper > +{ + typedef Matrix MatrixType; + static void run(MatrixType& mat, SluMatrix& res) + { + eigen_assert( ((Options&RowMajor)!=RowMajor) && "row-major dense matrices is not supported by SuperLU"); + res.setStorageType(SLU_DN); + res.setScalarType(); + res.Mtype = SLU_GE; + + res.nrow = mat.rows(); + res.ncol = mat.cols(); + + res.storage.lda = mat.outerStride(); + res.storage.values = mat.data(); + } +}; + +template +struct SluMatrixMapHelper > +{ + typedef Derived MatrixType; + static void run(MatrixType& mat, SluMatrix& res) + { + if ((MatrixType::Flags&RowMajorBit)==RowMajorBit) + { + res.setStorageType(SLU_NR); + res.nrow = mat.cols(); + res.ncol = mat.rows(); + } + else + { + res.setStorageType(SLU_NC); + res.nrow = mat.rows(); + res.ncol = mat.cols(); + } + + res.Mtype = SLU_GE; + + res.storage.nnz = mat.nonZeros(); + res.storage.values = mat.valuePtr(); + res.storage.innerInd = mat.innerIndexPtr(); + res.storage.outerInd = mat.outerIndexPtr(); + + res.setScalarType(); + + // FIXME the following is not very accurate + if (MatrixType::Flags & Upper) + res.Mtype = SLU_TRU; + if (MatrixType::Flags & Lower) + res.Mtype = SLU_TRL; + + eigen_assert(((MatrixType::Flags & SelfAdjoint)==0) && "SelfAdjoint matrix shape not supported by SuperLU"); + } +}; + +namespace internal { + +template +SluMatrix asSluMatrix(MatrixType& mat) +{ + return SluMatrix::Map(mat); +} + +/** View a Super LU matrix as an Eigen expression */ +template +MappedSparseMatrix map_superlu(SluMatrix& sluMat) +{ + eigen_assert((Flags&RowMajor)==RowMajor && sluMat.Stype == SLU_NR + || (Flags&ColMajor)==ColMajor && sluMat.Stype == SLU_NC); + + Index outerSize = (Flags&RowMajor)==RowMajor ? sluMat.ncol : sluMat.nrow; + + return MappedSparseMatrix( + sluMat.nrow, sluMat.ncol, sluMat.storage.outerInd[outerSize], + sluMat.storage.outerInd, sluMat.storage.innerInd, reinterpret_cast(sluMat.storage.values) ); +} + +} // end namespace internal + +/** \ingroup SuperLUSupport_Module + * \class SuperLUBase + * \brief The base class for the direct and incomplete LU factorization of SuperLU + */ +template +class SuperLUBase : internal::noncopyable +{ + public: + typedef _MatrixType MatrixType; + typedef typename MatrixType::Scalar Scalar; + typedef typename MatrixType::RealScalar RealScalar; + typedef typename MatrixType::Index Index; + typedef Matrix Vector; + typedef Matrix IntRowVectorType; + typedef Matrix IntColVectorType; + typedef SparseMatrix LUMatrixType; + + public: + + SuperLUBase() {} + + ~SuperLUBase() + { + clearFactors(); + } + + Derived& derived() { return *static_cast(this); } + const Derived& derived() const { return *static_cast(this); } + + inline Index rows() const { return m_matrix.rows(); } + inline Index cols() const { return m_matrix.cols(); } + + /** \returns a reference to the Super LU option object to configure the Super LU algorithms. */ + inline superlu_options_t& options() { return m_sluOptions; } + + /** \brief Reports whether previous computation was successful. + * + * \returns \c Success if computation was succesful, + * \c NumericalIssue if the matrix.appears to be negative. + */ + ComputationInfo info() const + { + eigen_assert(m_isInitialized && "Decomposition is not initialized."); + return m_info; + } + + /** Computes the sparse Cholesky decomposition of \a matrix */ + void compute(const MatrixType& matrix) + { + derived().analyzePattern(matrix); + derived().factorize(matrix); + } + + /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A. + * + * \sa compute() + */ + template + inline const internal::solve_retval solve(const MatrixBase& b) const + { + eigen_assert(m_isInitialized && "SuperLU is not initialized."); + eigen_assert(rows()==b.rows() + && "SuperLU::solve(): invalid number of rows of the right hand side matrix b"); + return internal::solve_retval(*this, b.derived()); + } + + /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A. + * + * \sa compute() + */ +// template +// inline const internal::sparse_solve_retval solve(const SparseMatrixBase& b) const +// { +// eigen_assert(m_isInitialized && "SuperLU is not initialized."); +// eigen_assert(rows()==b.rows() +// && "SuperLU::solve(): invalid number of rows of the right hand side matrix b"); +// return internal::sparse_solve_retval(*this, b.derived()); +// } + + /** Performs a symbolic decomposition on the sparcity of \a matrix. + * + * This function is particularly useful when solving for several problems having the same structure. + * + * \sa factorize() + */ + void analyzePattern(const MatrixType& /*matrix*/) + { + m_isInitialized = true; + m_info = Success; + m_analysisIsOk = true; + m_factorizationIsOk = false; + } + + template + void dumpMemory(Stream& s) + {} + + protected: + + void initFactorization(const MatrixType& a) + { + set_default_options(&this->m_sluOptions); + + const int size = a.rows(); + m_matrix = a; + + m_sluA = internal::asSluMatrix(m_matrix); + clearFactors(); + + m_p.resize(size); + m_q.resize(size); + m_sluRscale.resize(size); + m_sluCscale.resize(size); + m_sluEtree.resize(size); + + // set empty B and X + m_sluB.setStorageType(SLU_DN); + m_sluB.setScalarType(); + m_sluB.Mtype = SLU_GE; + m_sluB.storage.values = 0; + m_sluB.nrow = 0; + m_sluB.ncol = 0; + m_sluB.storage.lda = size; + m_sluX = m_sluB; + + m_extractedDataAreDirty = true; + } + + void init() + { + m_info = InvalidInput; + m_isInitialized = false; + m_sluL.Store = 0; + m_sluU.Store = 0; + } + + void extractData() const; + + void clearFactors() + { + if(m_sluL.Store) + Destroy_SuperNode_Matrix(&m_sluL); + if(m_sluU.Store) + Destroy_CompCol_Matrix(&m_sluU); + + m_sluL.Store = 0; + m_sluU.Store = 0; + + memset(&m_sluL,0,sizeof m_sluL); + memset(&m_sluU,0,sizeof m_sluU); + } + + // cached data to reduce reallocation, etc. + mutable LUMatrixType m_l; + mutable LUMatrixType m_u; + mutable IntColVectorType m_p; + mutable IntRowVectorType m_q; + + mutable LUMatrixType m_matrix; // copy of the factorized matrix + mutable SluMatrix m_sluA; + mutable SuperMatrix m_sluL, m_sluU; + mutable SluMatrix m_sluB, m_sluX; + mutable SuperLUStat_t m_sluStat; + mutable superlu_options_t m_sluOptions; + mutable std::vector m_sluEtree; + mutable Matrix m_sluRscale, m_sluCscale; + mutable Matrix m_sluFerr, m_sluBerr; + mutable char m_sluEqued; + + mutable ComputationInfo m_info; + bool m_isInitialized; + int m_factorizationIsOk; + int m_analysisIsOk; + mutable bool m_extractedDataAreDirty; + + private: + SuperLUBase(SuperLUBase& ) { } +}; + + +/** \ingroup SuperLUSupport_Module + * \class SuperLU + * \brief A sparse direct LU factorization and solver based on the SuperLU library + * + * This class allows to solve for A.X = B sparse linear problems via a direct LU factorization + * using the SuperLU library. The sparse matrix A must be squared and invertible. The vectors or matrices + * X and B can be either dense or sparse. + * + * \tparam _MatrixType the type of the sparse matrix A, it must be a SparseMatrix<> + * + * \sa \ref TutorialSparseDirectSolvers + */ +template +class SuperLU : public SuperLUBase<_MatrixType,SuperLU<_MatrixType> > +{ + public: + typedef SuperLUBase<_MatrixType,SuperLU> Base; + typedef _MatrixType MatrixType; + typedef typename Base::Scalar Scalar; + typedef typename Base::RealScalar RealScalar; + typedef typename Base::Index Index; + typedef typename Base::IntRowVectorType IntRowVectorType; + typedef typename Base::IntColVectorType IntColVectorType; + typedef typename Base::LUMatrixType LUMatrixType; + typedef TriangularView LMatrixType; + typedef TriangularView UMatrixType; + + public: + + SuperLU() : Base() { init(); } + + SuperLU(const MatrixType& matrix) : Base() + { + Base::init(); + compute(matrix); + } + + ~SuperLU() + { + } + + /** Performs a symbolic decomposition on the sparcity of \a matrix. + * + * This function is particularly useful when solving for several problems having the same structure. + * + * \sa factorize() + */ + void analyzePattern(const MatrixType& matrix) + { + m_info = InvalidInput; + m_isInitialized = false; + Base::analyzePattern(matrix); + } + + /** Performs a numeric decomposition of \a matrix + * + * The given matrix must has the same sparcity than the matrix on which the symbolic decomposition has been performed. + * + * \sa analyzePattern() + */ + void factorize(const MatrixType& matrix); + + #ifndef EIGEN_PARSED_BY_DOXYGEN + /** \internal */ + template + void _solve(const MatrixBase &b, MatrixBase &dest) const; + #endif // EIGEN_PARSED_BY_DOXYGEN + + inline const LMatrixType& matrixL() const + { + if (m_extractedDataAreDirty) this->extractData(); + return m_l; + } + + inline const UMatrixType& matrixU() const + { + if (m_extractedDataAreDirty) this->extractData(); + return m_u; + } + + inline const IntColVectorType& permutationP() const + { + if (m_extractedDataAreDirty) this->extractData(); + return m_p; + } + + inline const IntRowVectorType& permutationQ() const + { + if (m_extractedDataAreDirty) this->extractData(); + return m_q; + } + + Scalar determinant() const; + + protected: + + using Base::m_matrix; + using Base::m_sluOptions; + using Base::m_sluA; + using Base::m_sluB; + using Base::m_sluX; + using Base::m_p; + using Base::m_q; + using Base::m_sluEtree; + using Base::m_sluEqued; + using Base::m_sluRscale; + using Base::m_sluCscale; + using Base::m_sluL; + using Base::m_sluU; + using Base::m_sluStat; + using Base::m_sluFerr; + using Base::m_sluBerr; + using Base::m_l; + using Base::m_u; + + using Base::m_analysisIsOk; + using Base::m_factorizationIsOk; + using Base::m_extractedDataAreDirty; + using Base::m_isInitialized; + using Base::m_info; + + void init() + { + Base::init(); + + set_default_options(&this->m_sluOptions); + m_sluOptions.PrintStat = NO; + m_sluOptions.ConditionNumber = NO; + m_sluOptions.Trans = NOTRANS; + m_sluOptions.ColPerm = COLAMD; + } + + + private: + SuperLU(SuperLU& ) { } +}; + +template +void SuperLU::factorize(const MatrixType& a) +{ + eigen_assert(m_analysisIsOk && "You must first call analyzePattern()"); + if(!m_analysisIsOk) + { + m_info = InvalidInput; + return; + } + + this->initFactorization(a); + + int info = 0; + RealScalar recip_pivot_growth, rcond; + RealScalar ferr, berr; + + StatInit(&m_sluStat); + SuperLU_gssvx(&m_sluOptions, &m_sluA, m_q.data(), m_p.data(), &m_sluEtree[0], + &m_sluEqued, &m_sluRscale[0], &m_sluCscale[0], + &m_sluL, &m_sluU, + NULL, 0, + &m_sluB, &m_sluX, + &recip_pivot_growth, &rcond, + &ferr, &berr, + &m_sluStat, &info, Scalar()); + StatFree(&m_sluStat); + + m_extractedDataAreDirty = true; + + // FIXME how to better check for errors ??? + m_info = info == 0 ? Success : NumericalIssue; + m_factorizationIsOk = true; +} + +template +template +void SuperLU::_solve(const MatrixBase &b, MatrixBase& x) const +{ + eigen_assert(m_factorizationIsOk && "The decomposition is not in a valid state for solving, you must first call either compute() or analyzePattern()/factorize()"); + + const int size = m_matrix.rows(); + const int rhsCols = b.cols(); + eigen_assert(size==b.rows()); + + m_sluOptions.Trans = NOTRANS; + m_sluOptions.Fact = FACTORED; + m_sluOptions.IterRefine = NOREFINE; + + + m_sluFerr.resize(rhsCols); + m_sluBerr.resize(rhsCols); + m_sluB = SluMatrix::Map(b.const_cast_derived()); + m_sluX = SluMatrix::Map(x.derived()); + + typename Rhs::PlainObject b_cpy; + if(m_sluEqued!='N') + { + b_cpy = b; + m_sluB = SluMatrix::Map(b_cpy.const_cast_derived()); + } + + StatInit(&m_sluStat); + int info = 0; + RealScalar recip_pivot_growth, rcond; + SuperLU_gssvx(&m_sluOptions, &m_sluA, + m_q.data(), m_p.data(), + &m_sluEtree[0], &m_sluEqued, + &m_sluRscale[0], &m_sluCscale[0], + &m_sluL, &m_sluU, + NULL, 0, + &m_sluB, &m_sluX, + &recip_pivot_growth, &rcond, + &m_sluFerr[0], &m_sluBerr[0], + &m_sluStat, &info, Scalar()); + StatFree(&m_sluStat); + m_info = info==0 ? Success : NumericalIssue; +} + +// the code of this extractData() function has been adapted from the SuperLU's Matlab support code, +// +// Copyright (c) 1994 by Xerox Corporation. All rights reserved. +// +// THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY +// EXPRESSED OR IMPLIED. ANY USE IS AT YOUR OWN RISK. +// +template +void SuperLUBase::extractData() const +{ + eigen_assert(m_factorizationIsOk && "The decomposition is not in a valid state for extracting factors, you must first call either compute() or analyzePattern()/factorize()"); + if (m_extractedDataAreDirty) + { + int upper; + int fsupc, istart, nsupr; + int lastl = 0, lastu = 0; + SCformat *Lstore = static_cast(m_sluL.Store); + NCformat *Ustore = static_cast(m_sluU.Store); + Scalar *SNptr; + + const int size = m_matrix.rows(); + m_l.resize(size,size); + m_l.resizeNonZeros(Lstore->nnz); + m_u.resize(size,size); + m_u.resizeNonZeros(Ustore->nnz); + + int* Lcol = m_l.outerIndexPtr(); + int* Lrow = m_l.innerIndexPtr(); + Scalar* Lval = m_l.valuePtr(); + + int* Ucol = m_u.outerIndexPtr(); + int* Urow = m_u.innerIndexPtr(); + Scalar* Uval = m_u.valuePtr(); + + Ucol[0] = 0; + Ucol[0] = 0; + + /* for each supernode */ + for (int k = 0; k <= Lstore->nsuper; ++k) + { + fsupc = L_FST_SUPC(k); + istart = L_SUB_START(fsupc); + nsupr = L_SUB_START(fsupc+1) - istart; + upper = 1; + + /* for each column in the supernode */ + for (int j = fsupc; j < L_FST_SUPC(k+1); ++j) + { + SNptr = &((Scalar*)Lstore->nzval)[L_NZ_START(j)]; + + /* Extract U */ + for (int i = U_NZ_START(j); i < U_NZ_START(j+1); ++i) + { + Uval[lastu] = ((Scalar*)Ustore->nzval)[i]; + /* Matlab doesn't like explicit zero. */ + if (Uval[lastu] != 0.0) + Urow[lastu++] = U_SUB(i); + } + for (int i = 0; i < upper; ++i) + { + /* upper triangle in the supernode */ + Uval[lastu] = SNptr[i]; + /* Matlab doesn't like explicit zero. */ + if (Uval[lastu] != 0.0) + Urow[lastu++] = L_SUB(istart+i); + } + Ucol[j+1] = lastu; + + /* Extract L */ + Lval[lastl] = 1.0; /* unit diagonal */ + Lrow[lastl++] = L_SUB(istart + upper - 1); + for (int i = upper; i < nsupr; ++i) + { + Lval[lastl] = SNptr[i]; + /* Matlab doesn't like explicit zero. */ + if (Lval[lastl] != 0.0) + Lrow[lastl++] = L_SUB(istart+i); + } + Lcol[j+1] = lastl; + + ++upper; + } /* for j ... */ + + } /* for k ... */ + + // squeeze the matrices : + m_l.resizeNonZeros(lastl); + m_u.resizeNonZeros(lastu); + + m_extractedDataAreDirty = false; + } +} + +template +typename SuperLU::Scalar SuperLU::determinant() const +{ + eigen_assert(m_factorizationIsOk && "The decomposition is not in a valid state for computing the determinant, you must first call either compute() or analyzePattern()/factorize()"); + + if (m_extractedDataAreDirty) + this->extractData(); + + Scalar det = Scalar(1); + for (int j=0; j 0) + { + int lastId = m_u.outerIndexPtr()[j+1]-1; + eigen_assert(m_u.innerIndexPtr()[lastId]<=j); + if (m_u.innerIndexPtr()[lastId]==j) + det *= m_u.valuePtr()[lastId]; + } + } + if(m_sluEqued!='N') + return det/m_sluRscale.prod()/m_sluCscale.prod(); + else + return det; +} + +#ifdef EIGEN_PARSED_BY_DOXYGEN +#define EIGEN_SUPERLU_HAS_ILU +#endif + +#ifdef EIGEN_SUPERLU_HAS_ILU + +/** \ingroup SuperLUSupport_Module + * \class SuperILU + * \brief A sparse direct \b incomplete LU factorization and solver based on the SuperLU library + * + * This class allows to solve for an approximate solution of A.X = B sparse linear problems via an incomplete LU factorization + * using the SuperLU library. This class is aimed to be used as a preconditioner of the iterative linear solvers. + * + * \warning This class requires SuperLU 4 or later. + * + * \tparam _MatrixType the type of the sparse matrix A, it must be a SparseMatrix<> + * + * \sa \ref TutorialSparseDirectSolvers, class ConjugateGradient, class BiCGSTAB + */ + +template +class SuperILU : public SuperLUBase<_MatrixType,SuperILU<_MatrixType> > +{ + public: + typedef SuperLUBase<_MatrixType,SuperILU> Base; + typedef _MatrixType MatrixType; + typedef typename Base::Scalar Scalar; + typedef typename Base::RealScalar RealScalar; + typedef typename Base::Index Index; + + public: + + SuperILU() : Base() { init(); } + + SuperILU(const MatrixType& matrix) : Base() + { + init(); + compute(matrix); + } + + ~SuperILU() + { + } + + /** Performs a symbolic decomposition on the sparcity of \a matrix. + * + * This function is particularly useful when solving for several problems having the same structure. + * + * \sa factorize() + */ + void analyzePattern(const MatrixType& matrix) + { + Base::analyzePattern(matrix); + } + + /** Performs a numeric decomposition of \a matrix + * + * The given matrix must has the same sparcity than the matrix on which the symbolic decomposition has been performed. + * + * \sa analyzePattern() + */ + void factorize(const MatrixType& matrix); + + #ifndef EIGEN_PARSED_BY_DOXYGEN + /** \internal */ + template + void _solve(const MatrixBase &b, MatrixBase &dest) const; + #endif // EIGEN_PARSED_BY_DOXYGEN + + protected: + + using Base::m_matrix; + using Base::m_sluOptions; + using Base::m_sluA; + using Base::m_sluB; + using Base::m_sluX; + using Base::m_p; + using Base::m_q; + using Base::m_sluEtree; + using Base::m_sluEqued; + using Base::m_sluRscale; + using Base::m_sluCscale; + using Base::m_sluL; + using Base::m_sluU; + using Base::m_sluStat; + using Base::m_sluFerr; + using Base::m_sluBerr; + using Base::m_l; + using Base::m_u; + + using Base::m_analysisIsOk; + using Base::m_factorizationIsOk; + using Base::m_extractedDataAreDirty; + using Base::m_isInitialized; + using Base::m_info; + + void init() + { + Base::init(); + + ilu_set_default_options(&m_sluOptions); + m_sluOptions.PrintStat = NO; + m_sluOptions.ConditionNumber = NO; + m_sluOptions.Trans = NOTRANS; + m_sluOptions.ColPerm = MMD_AT_PLUS_A; + + // no attempt to preserve column sum + m_sluOptions.ILU_MILU = SILU; + // only basic ILU(k) support -- no direct control over memory consumption + // better to use ILU_DropRule = DROP_BASIC | DROP_AREA + // and set ILU_FillFactor to max memory growth + m_sluOptions.ILU_DropRule = DROP_BASIC; + m_sluOptions.ILU_DropTol = NumTraits::dummy_precision()*10; + } + + private: + SuperILU(SuperILU& ) { } +}; + +template +void SuperILU::factorize(const MatrixType& a) +{ + eigen_assert(m_analysisIsOk && "You must first call analyzePattern()"); + if(!m_analysisIsOk) + { + m_info = InvalidInput; + return; + } + + this->initFactorization(a); + + int info = 0; + RealScalar recip_pivot_growth, rcond; + + StatInit(&m_sluStat); + SuperLU_gsisx(&m_sluOptions, &m_sluA, m_q.data(), m_p.data(), &m_sluEtree[0], + &m_sluEqued, &m_sluRscale[0], &m_sluCscale[0], + &m_sluL, &m_sluU, + NULL, 0, + &m_sluB, &m_sluX, + &recip_pivot_growth, &rcond, + &m_sluStat, &info, Scalar()); + StatFree(&m_sluStat); + + // FIXME how to better check for errors ??? + m_info = info == 0 ? Success : NumericalIssue; + m_factorizationIsOk = true; +} + +template +template +void SuperILU::_solve(const MatrixBase &b, MatrixBase& x) const +{ + eigen_assert(m_factorizationIsOk && "The decomposition is not in a valid state for solving, you must first call either compute() or analyzePattern()/factorize()"); + + const int size = m_matrix.rows(); + const int rhsCols = b.cols(); + eigen_assert(size==b.rows()); + + m_sluOptions.Trans = NOTRANS; + m_sluOptions.Fact = FACTORED; + m_sluOptions.IterRefine = NOREFINE; + + m_sluFerr.resize(rhsCols); + m_sluBerr.resize(rhsCols); + m_sluB = SluMatrix::Map(b.const_cast_derived()); + m_sluX = SluMatrix::Map(x.derived()); + + typename Rhs::PlainObject b_cpy; + if(m_sluEqued!='N') + { + b_cpy = b; + m_sluB = SluMatrix::Map(b_cpy.const_cast_derived()); + } + + int info = 0; + RealScalar recip_pivot_growth, rcond; + + StatInit(&m_sluStat); + SuperLU_gsisx(&m_sluOptions, &m_sluA, + m_q.data(), m_p.data(), + &m_sluEtree[0], &m_sluEqued, + &m_sluRscale[0], &m_sluCscale[0], + &m_sluL, &m_sluU, + NULL, 0, + &m_sluB, &m_sluX, + &recip_pivot_growth, &rcond, + &m_sluStat, &info, Scalar()); + StatFree(&m_sluStat); + + m_info = info==0 ? Success : NumericalIssue; +} +#endif + +namespace internal { + +template +struct solve_retval, Rhs> + : solve_retval_base, Rhs> +{ + typedef SuperLUBase<_MatrixType,Derived> Dec; + EIGEN_MAKE_SOLVE_HELPERS(Dec,Rhs) + + template void evalTo(Dest& dst) const + { + dec().derived()._solve(rhs(),dst); + } +}; + +template +struct sparse_solve_retval, Rhs> + : sparse_solve_retval_base, Rhs> +{ + typedef SuperLUBase<_MatrixType,Derived> Dec; + EIGEN_MAKE_SPARSE_SOLVE_HELPERS(Dec,Rhs) + + template void evalTo(Dest& dst) const + { + dec().derived()._solve(rhs(),dst); + } +}; + +} // end namespace internal + +} // end namespace Eigen + +#endif // EIGEN_SUPERLUSUPPORT_H diff --git a/extern/Eigen3/Eigen/src/UmfPackSupport/UmfPackSupport.h b/extern/Eigen3/Eigen/src/UmfPackSupport/UmfPackSupport.h new file mode 100644 index 00000000000..f01720362de --- /dev/null +++ b/extern/Eigen3/Eigen/src/UmfPackSupport/UmfPackSupport.h @@ -0,0 +1,431 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008-2011 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_UMFPACKSUPPORT_H +#define EIGEN_UMFPACKSUPPORT_H + +namespace Eigen { + +/* TODO extract L, extract U, compute det, etc... */ + +// generic double/complex wrapper functions: + +inline void umfpack_free_numeric(void **Numeric, double) +{ umfpack_di_free_numeric(Numeric); *Numeric = 0; } + +inline void umfpack_free_numeric(void **Numeric, std::complex) +{ umfpack_zi_free_numeric(Numeric); *Numeric = 0; } + +inline void umfpack_free_symbolic(void **Symbolic, double) +{ umfpack_di_free_symbolic(Symbolic); *Symbolic = 0; } + +inline void umfpack_free_symbolic(void **Symbolic, std::complex) +{ umfpack_zi_free_symbolic(Symbolic); *Symbolic = 0; } + +inline int umfpack_symbolic(int n_row,int n_col, + const int Ap[], const int Ai[], const double Ax[], void **Symbolic, + const double Control [UMFPACK_CONTROL], double Info [UMFPACK_INFO]) +{ + return umfpack_di_symbolic(n_row,n_col,Ap,Ai,Ax,Symbolic,Control,Info); +} + +inline int umfpack_symbolic(int n_row,int n_col, + const int Ap[], const int Ai[], const std::complex Ax[], void **Symbolic, + const double Control [UMFPACK_CONTROL], double Info [UMFPACK_INFO]) +{ + return umfpack_zi_symbolic(n_row,n_col,Ap,Ai,&internal::real_ref(Ax[0]),0,Symbolic,Control,Info); +} + +inline int umfpack_numeric( const int Ap[], const int Ai[], const double Ax[], + void *Symbolic, void **Numeric, + const double Control[UMFPACK_CONTROL],double Info [UMFPACK_INFO]) +{ + return umfpack_di_numeric(Ap,Ai,Ax,Symbolic,Numeric,Control,Info); +} + +inline int umfpack_numeric( const int Ap[], const int Ai[], const std::complex Ax[], + void *Symbolic, void **Numeric, + const double Control[UMFPACK_CONTROL],double Info [UMFPACK_INFO]) +{ + return umfpack_zi_numeric(Ap,Ai,&internal::real_ref(Ax[0]),0,Symbolic,Numeric,Control,Info); +} + +inline int umfpack_solve( int sys, const int Ap[], const int Ai[], const double Ax[], + double X[], const double B[], void *Numeric, + const double Control[UMFPACK_CONTROL], double Info[UMFPACK_INFO]) +{ + return umfpack_di_solve(sys,Ap,Ai,Ax,X,B,Numeric,Control,Info); +} + +inline int umfpack_solve( int sys, const int Ap[], const int Ai[], const std::complex Ax[], + std::complex X[], const std::complex B[], void *Numeric, + const double Control[UMFPACK_CONTROL], double Info[UMFPACK_INFO]) +{ + return umfpack_zi_solve(sys,Ap,Ai,&internal::real_ref(Ax[0]),0,&internal::real_ref(X[0]),0,&internal::real_ref(B[0]),0,Numeric,Control,Info); +} + +inline int umfpack_get_lunz(int *lnz, int *unz, int *n_row, int *n_col, int *nz_udiag, void *Numeric, double) +{ + return umfpack_di_get_lunz(lnz,unz,n_row,n_col,nz_udiag,Numeric); +} + +inline int umfpack_get_lunz(int *lnz, int *unz, int *n_row, int *n_col, int *nz_udiag, void *Numeric, std::complex) +{ + return umfpack_zi_get_lunz(lnz,unz,n_row,n_col,nz_udiag,Numeric); +} + +inline int umfpack_get_numeric(int Lp[], int Lj[], double Lx[], int Up[], int Ui[], double Ux[], + int P[], int Q[], double Dx[], int *do_recip, double Rs[], void *Numeric) +{ + return umfpack_di_get_numeric(Lp,Lj,Lx,Up,Ui,Ux,P,Q,Dx,do_recip,Rs,Numeric); +} + +inline int umfpack_get_numeric(int Lp[], int Lj[], std::complex Lx[], int Up[], int Ui[], std::complex Ux[], + int P[], int Q[], std::complex Dx[], int *do_recip, double Rs[], void *Numeric) +{ + double& lx0_real = internal::real_ref(Lx[0]); + double& ux0_real = internal::real_ref(Ux[0]); + double& dx0_real = internal::real_ref(Dx[0]); + return umfpack_zi_get_numeric(Lp,Lj,Lx?&lx0_real:0,0,Up,Ui,Ux?&ux0_real:0,0,P,Q, + Dx?&dx0_real:0,0,do_recip,Rs,Numeric); +} + +inline int umfpack_get_determinant(double *Mx, double *Ex, void *NumericHandle, double User_Info [UMFPACK_INFO]) +{ + return umfpack_di_get_determinant(Mx,Ex,NumericHandle,User_Info); +} + +inline int umfpack_get_determinant(std::complex *Mx, double *Ex, void *NumericHandle, double User_Info [UMFPACK_INFO]) +{ + double& mx_real = internal::real_ref(*Mx); + return umfpack_zi_get_determinant(&mx_real,0,Ex,NumericHandle,User_Info); +} + +/** \ingroup UmfPackSupport_Module + * \brief A sparse LU factorization and solver based on UmfPack + * + * This class allows to solve for A.X = B sparse linear problems via a LU factorization + * using the UmfPack library. The sparse matrix A must be squared and full rank. + * The vectors or matrices X and B can be either dense or sparse. + * + * \WARNING The input matrix A should be in a \b compressed and \b column-major form. + * Otherwise an expensive copy will be made. You can call the inexpensive makeCompressed() to get a compressed matrix. + * \tparam _MatrixType the type of the sparse matrix A, it must be a SparseMatrix<> + * + * \sa \ref TutorialSparseDirectSolvers + */ +template +class UmfPackLU : internal::noncopyable +{ + public: + typedef _MatrixType MatrixType; + typedef typename MatrixType::Scalar Scalar; + typedef typename MatrixType::RealScalar RealScalar; + typedef typename MatrixType::Index Index; + typedef Matrix Vector; + typedef Matrix IntRowVectorType; + typedef Matrix IntColVectorType; + typedef SparseMatrix LUMatrixType; + typedef SparseMatrix UmfpackMatrixType; + + public: + + UmfPackLU() { init(); } + + UmfPackLU(const MatrixType& matrix) + { + init(); + compute(matrix); + } + + ~UmfPackLU() + { + if(m_symbolic) umfpack_free_symbolic(&m_symbolic,Scalar()); + if(m_numeric) umfpack_free_numeric(&m_numeric,Scalar()); + } + + inline Index rows() const { return m_copyMatrix.rows(); } + inline Index cols() const { return m_copyMatrix.cols(); } + + /** \brief Reports whether previous computation was successful. + * + * \returns \c Success if computation was succesful, + * \c NumericalIssue if the matrix.appears to be negative. + */ + ComputationInfo info() const + { + eigen_assert(m_isInitialized && "Decomposition is not initialized."); + return m_info; + } + + inline const LUMatrixType& matrixL() const + { + if (m_extractedDataAreDirty) extractData(); + return m_l; + } + + inline const LUMatrixType& matrixU() const + { + if (m_extractedDataAreDirty) extractData(); + return m_u; + } + + inline const IntColVectorType& permutationP() const + { + if (m_extractedDataAreDirty) extractData(); + return m_p; + } + + inline const IntRowVectorType& permutationQ() const + { + if (m_extractedDataAreDirty) extractData(); + return m_q; + } + + /** Computes the sparse Cholesky decomposition of \a matrix + * Note that the matrix should be column-major, and in compressed format for best performance. + * \sa SparseMatrix::makeCompressed(). + */ + void compute(const MatrixType& matrix) + { + analyzePattern(matrix); + factorize(matrix); + } + + /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A. + * + * \sa compute() + */ + template + inline const internal::solve_retval solve(const MatrixBase& b) const + { + eigen_assert(m_isInitialized && "UmfPackLU is not initialized."); + eigen_assert(rows()==b.rows() + && "UmfPackLU::solve(): invalid number of rows of the right hand side matrix b"); + return internal::solve_retval(*this, b.derived()); + } + + /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A. + * + * \sa compute() + */ +// template +// inline const internal::sparse_solve_retval solve(const SparseMatrixBase& b) const +// { +// eigen_assert(m_isInitialized && "UmfPAckLU is not initialized."); +// eigen_assert(rows()==b.rows() +// && "UmfPAckLU::solve(): invalid number of rows of the right hand side matrix b"); +// return internal::sparse_solve_retval(*this, b.derived()); +// } + + /** Performs a symbolic decomposition on the sparcity of \a matrix. + * + * This function is particularly useful when solving for several problems having the same structure. + * + * \sa factorize(), compute() + */ + void analyzePattern(const MatrixType& matrix) + { + if(m_symbolic) + umfpack_free_symbolic(&m_symbolic,Scalar()); + if(m_numeric) + umfpack_free_numeric(&m_numeric,Scalar()); + + grapInput(matrix); + + int errorCode = 0; + errorCode = umfpack_symbolic(matrix.rows(), matrix.cols(), m_outerIndexPtr, m_innerIndexPtr, m_valuePtr, + &m_symbolic, 0, 0); + + m_isInitialized = true; + m_info = errorCode ? InvalidInput : Success; + m_analysisIsOk = true; + m_factorizationIsOk = false; + } + + /** Performs a numeric decomposition of \a matrix + * + * The given matrix must has the same sparcity than the matrix on which the pattern anylysis has been performed. + * + * \sa analyzePattern(), compute() + */ + void factorize(const MatrixType& matrix) + { + eigen_assert(m_analysisIsOk && "UmfPackLU: you must first call analyzePattern()"); + if(m_numeric) + umfpack_free_numeric(&m_numeric,Scalar()); + + grapInput(matrix); + + int errorCode; + errorCode = umfpack_numeric(m_outerIndexPtr, m_innerIndexPtr, m_valuePtr, + m_symbolic, &m_numeric, 0, 0); + + m_info = errorCode ? NumericalIssue : Success; + m_factorizationIsOk = true; + } + + #ifndef EIGEN_PARSED_BY_DOXYGEN + /** \internal */ + template + bool _solve(const MatrixBase &b, MatrixBase &x) const; + #endif + + Scalar determinant() const; + + void extractData() const; + + protected: + + + void init() + { + m_info = InvalidInput; + m_isInitialized = false; + m_numeric = 0; + m_symbolic = 0; + m_outerIndexPtr = 0; + m_innerIndexPtr = 0; + m_valuePtr = 0; + } + + void grapInput(const MatrixType& mat) + { + m_copyMatrix.resize(mat.rows(), mat.cols()); + if( ((MatrixType::Flags&RowMajorBit)==RowMajorBit) || sizeof(typename MatrixType::Index)!=sizeof(int) || !mat.isCompressed() ) + { + // non supported input -> copy + m_copyMatrix = mat; + m_outerIndexPtr = m_copyMatrix.outerIndexPtr(); + m_innerIndexPtr = m_copyMatrix.innerIndexPtr(); + m_valuePtr = m_copyMatrix.valuePtr(); + } + else + { + m_outerIndexPtr = mat.outerIndexPtr(); + m_innerIndexPtr = mat.innerIndexPtr(); + m_valuePtr = mat.valuePtr(); + } + } + + // cached data to reduce reallocation, etc. + mutable LUMatrixType m_l; + mutable LUMatrixType m_u; + mutable IntColVectorType m_p; + mutable IntRowVectorType m_q; + + UmfpackMatrixType m_copyMatrix; + const Scalar* m_valuePtr; + const int* m_outerIndexPtr; + const int* m_innerIndexPtr; + void* m_numeric; + void* m_symbolic; + + mutable ComputationInfo m_info; + bool m_isInitialized; + int m_factorizationIsOk; + int m_analysisIsOk; + mutable bool m_extractedDataAreDirty; + + private: + UmfPackLU(UmfPackLU& ) { } +}; + + +template +void UmfPackLU::extractData() const +{ + if (m_extractedDataAreDirty) + { + // get size of the data + int lnz, unz, rows, cols, nz_udiag; + umfpack_get_lunz(&lnz, &unz, &rows, &cols, &nz_udiag, m_numeric, Scalar()); + + // allocate data + m_l.resize(rows,(std::min)(rows,cols)); + m_l.resizeNonZeros(lnz); + + m_u.resize((std::min)(rows,cols),cols); + m_u.resizeNonZeros(unz); + + m_p.resize(rows); + m_q.resize(cols); + + // extract + umfpack_get_numeric(m_l.outerIndexPtr(), m_l.innerIndexPtr(), m_l.valuePtr(), + m_u.outerIndexPtr(), m_u.innerIndexPtr(), m_u.valuePtr(), + m_p.data(), m_q.data(), 0, 0, 0, m_numeric); + + m_extractedDataAreDirty = false; + } +} + +template +typename UmfPackLU::Scalar UmfPackLU::determinant() const +{ + Scalar det; + umfpack_get_determinant(&det, 0, m_numeric, 0); + return det; +} + +template +template +bool UmfPackLU::_solve(const MatrixBase &b, MatrixBase &x) const +{ + const int rhsCols = b.cols(); + eigen_assert((BDerived::Flags&RowMajorBit)==0 && "UmfPackLU backend does not support non col-major rhs yet"); + eigen_assert((XDerived::Flags&RowMajorBit)==0 && "UmfPackLU backend does not support non col-major result yet"); + + int errorCode; + for (int j=0; j +struct solve_retval, Rhs> + : solve_retval_base, Rhs> +{ + typedef UmfPackLU<_MatrixType> Dec; + EIGEN_MAKE_SOLVE_HELPERS(Dec,Rhs) + + template void evalTo(Dest& dst) const + { + dec()._solve(rhs(),dst); + } +}; + +template +struct sparse_solve_retval, Rhs> + : sparse_solve_retval_base, Rhs> +{ + typedef UmfPackLU<_MatrixType> Dec; + EIGEN_MAKE_SPARSE_SOLVE_HELPERS(Dec,Rhs) + + template void evalTo(Dest& dst) const + { + dec()._solve(rhs(),dst); + } +}; + +} // end namespace internal + +} // end namespace Eigen + +#endif // EIGEN_UMFPACKSUPPORT_H diff --git a/extern/Eigen3/Eigen/src/misc/Image.h b/extern/Eigen3/Eigen/src/misc/Image.h index 19b3e08cbfd..75c5f433a8a 100644 --- a/extern/Eigen3/Eigen/src/misc/Image.h +++ b/extern/Eigen3/Eigen/src/misc/Image.h @@ -3,28 +3,15 @@ // // Copyright (C) 2009 Benoit Jacob // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_MISC_IMAGE_H #define EIGEN_MISC_IMAGE_H +namespace Eigen { + namespace internal { /** \class image_retval_base @@ -92,4 +79,6 @@ template struct image_retval_base image_retval(const DecompositionType& dec, const MatrixType& originalMatrix) \ : Base(dec, originalMatrix) {} +} // end namespace Eigen + #endif // EIGEN_MISC_IMAGE_H diff --git a/extern/Eigen3/Eigen/src/misc/Kernel.h b/extern/Eigen3/Eigen/src/misc/Kernel.h index 0115970e8eb..b9e1518fd49 100644 --- a/extern/Eigen3/Eigen/src/misc/Kernel.h +++ b/extern/Eigen3/Eigen/src/misc/Kernel.h @@ -3,28 +3,15 @@ // // Copyright (C) 2009 Benoit Jacob // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_MISC_KERNEL_H #define EIGEN_MISC_KERNEL_H +namespace Eigen { + namespace internal { /** \class kernel_retval_base @@ -89,4 +76,6 @@ template struct kernel_retval_base using Base::cols; \ kernel_retval(const DecompositionType& dec) : Base(dec) {} +} // end namespace Eigen + #endif // EIGEN_MISC_KERNEL_H diff --git a/extern/Eigen3/Eigen/src/misc/Solve.h b/extern/Eigen3/Eigen/src/misc/Solve.h index b7cbcadb392..7f70d60afbd 100644 --- a/extern/Eigen3/Eigen/src/misc/Solve.h +++ b/extern/Eigen3/Eigen/src/misc/Solve.h @@ -3,28 +3,15 @@ // // Copyright (C) 2009 Benoit Jacob // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_MISC_SOLVE_H #define EIGEN_MISC_SOLVE_H +namespace Eigen { + namespace internal { /** \class solve_retval_base @@ -66,7 +53,7 @@ template struct solve_retval_base protected: const DecompositionType& m_dec; - const typename Rhs::Nested m_rhs; + typename Rhs::Nested m_rhs; }; } // end namespace internal @@ -84,4 +71,6 @@ template struct solve_retval_base solve_retval(const DecompositionType& dec, const Rhs& rhs) \ : Base(dec, rhs) {} +} // end namespace Eigen + #endif // EIGEN_MISC_SOLVE_H diff --git a/extern/Eigen3/Eigen/src/misc/SparseSolve.h b/extern/Eigen3/Eigen/src/misc/SparseSolve.h new file mode 100644 index 00000000000..272c4a479d7 --- /dev/null +++ b/extern/Eigen3/Eigen/src/misc/SparseSolve.h @@ -0,0 +1,111 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2010 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_SPARSE_SOLVE_H +#define EIGEN_SPARSE_SOLVE_H + +namespace Eigen { + +namespace internal { + +template struct sparse_solve_retval_base; +template struct sparse_solve_retval; + +template +struct traits > +{ + typedef typename DecompositionType::MatrixType MatrixType; + typedef SparseMatrix ReturnType; +}; + +template struct sparse_solve_retval_base + : public ReturnByValue > +{ + typedef typename remove_all::type RhsNestedCleaned; + typedef _DecompositionType DecompositionType; + typedef ReturnByValue Base; + typedef typename Base::Index Index; + + sparse_solve_retval_base(const DecompositionType& dec, const Rhs& rhs) + : m_dec(dec), m_rhs(rhs) + {} + + inline Index rows() const { return m_dec.cols(); } + inline Index cols() const { return m_rhs.cols(); } + inline const DecompositionType& dec() const { return m_dec; } + inline const RhsNestedCleaned& rhs() const { return m_rhs; } + + template inline void evalTo(Dest& dst) const + { + static_cast*>(this)->evalTo(dst); + } + + protected: + const DecompositionType& m_dec; + typename Rhs::Nested m_rhs; +}; + +#define EIGEN_MAKE_SPARSE_SOLVE_HELPERS(DecompositionType,Rhs) \ + typedef typename DecompositionType::MatrixType MatrixType; \ + typedef typename MatrixType::Scalar Scalar; \ + typedef typename MatrixType::RealScalar RealScalar; \ + typedef typename MatrixType::Index Index; \ + typedef Eigen::internal::sparse_solve_retval_base Base; \ + using Base::dec; \ + using Base::rhs; \ + using Base::rows; \ + using Base::cols; \ + sparse_solve_retval(const DecompositionType& dec, const Rhs& rhs) \ + : Base(dec, rhs) {} + + + +template struct solve_retval_with_guess; + +template +struct traits > +{ + typedef typename DecompositionType::MatrixType MatrixType; + typedef Matrix ReturnType; +}; + +template struct solve_retval_with_guess + : public ReturnByValue > +{ + typedef typename DecompositionType::Index Index; + + solve_retval_with_guess(const DecompositionType& dec, const Rhs& rhs, const Guess& guess) + : m_dec(dec), m_rhs(rhs), m_guess(guess) + {} + + inline Index rows() const { return m_dec.cols(); } + inline Index cols() const { return m_rhs.cols(); } + + template inline void evalTo(Dest& dst) const + { + dst = m_guess; + m_dec._solveWithGuess(m_rhs,dst); + } + + protected: + const DecompositionType& m_dec; + const typename Rhs::Nested m_rhs; + const typename Guess::Nested m_guess; +}; + +} // namepsace internal + +} // end namespace Eigen + +#endif // EIGEN_SPARSE_SOLVE_H diff --git a/extern/Eigen3/Eigen/src/misc/blas.h b/extern/Eigen3/Eigen/src/misc/blas.h new file mode 100644 index 00000000000..6fce99ed5c4 --- /dev/null +++ b/extern/Eigen3/Eigen/src/misc/blas.h @@ -0,0 +1,658 @@ +#ifndef BLAS_H +#define BLAS_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +#define BLASFUNC(FUNC) FUNC##_ + +#ifdef __WIN64__ +typedef long long BLASLONG; +typedef unsigned long long BLASULONG; +#else +typedef long BLASLONG; +typedef unsigned long BLASULONG; +#endif + +int BLASFUNC(xerbla)(const char *, int *info, int); + +float BLASFUNC(sdot) (int *, float *, int *, float *, int *); +float BLASFUNC(sdsdot)(int *, float *, float *, int *, float *, int *); + +double BLASFUNC(dsdot) (int *, float *, int *, float *, int *); +double BLASFUNC(ddot) (int *, double *, int *, double *, int *); +double BLASFUNC(qdot) (int *, double *, int *, double *, int *); + +int BLASFUNC(cdotuw) (int *, float *, int *, float *, int *, float*); +int BLASFUNC(cdotcw) (int *, float *, int *, float *, int *, float*); +int BLASFUNC(zdotuw) (int *, double *, int *, double *, int *, double*); +int BLASFUNC(zdotcw) (int *, double *, int *, double *, int *, double*); + +int BLASFUNC(saxpy) (int *, float *, float *, int *, float *, int *); +int BLASFUNC(daxpy) (int *, double *, double *, int *, double *, int *); +int BLASFUNC(qaxpy) (int *, double *, double *, int *, double *, int *); +int BLASFUNC(caxpy) (int *, float *, float *, int *, float *, int *); +int BLASFUNC(zaxpy) (int *, double *, double *, int *, double *, int *); +int BLASFUNC(xaxpy) (int *, double *, double *, int *, double *, int *); +int BLASFUNC(caxpyc)(int *, float *, float *, int *, float *, int *); +int BLASFUNC(zaxpyc)(int *, double *, double *, int *, double *, int *); +int BLASFUNC(xaxpyc)(int *, double *, double *, int *, double *, int *); + +int BLASFUNC(scopy) (int *, float *, int *, float *, int *); +int BLASFUNC(dcopy) (int *, double *, int *, double *, int *); +int BLASFUNC(qcopy) (int *, double *, int *, double *, int *); +int BLASFUNC(ccopy) (int *, float *, int *, float *, int *); +int BLASFUNC(zcopy) (int *, double *, int *, double *, int *); +int BLASFUNC(xcopy) (int *, double *, int *, double *, int *); + +int BLASFUNC(sswap) (int *, float *, int *, float *, int *); +int BLASFUNC(dswap) (int *, double *, int *, double *, int *); +int BLASFUNC(qswap) (int *, double *, int *, double *, int *); +int BLASFUNC(cswap) (int *, float *, int *, float *, int *); +int BLASFUNC(zswap) (int *, double *, int *, double *, int *); +int BLASFUNC(xswap) (int *, double *, int *, double *, int *); + +float BLASFUNC(sasum) (int *, float *, int *); +float BLASFUNC(scasum)(int *, float *, int *); +double BLASFUNC(dasum) (int *, double *, int *); +double BLASFUNC(qasum) (int *, double *, int *); +double BLASFUNC(dzasum)(int *, double *, int *); +double BLASFUNC(qxasum)(int *, double *, int *); + +int BLASFUNC(isamax)(int *, float *, int *); +int BLASFUNC(idamax)(int *, double *, int *); +int BLASFUNC(iqamax)(int *, double *, int *); +int BLASFUNC(icamax)(int *, float *, int *); +int BLASFUNC(izamax)(int *, double *, int *); +int BLASFUNC(ixamax)(int *, double *, int *); + +int BLASFUNC(ismax) (int *, float *, int *); +int BLASFUNC(idmax) (int *, double *, int *); +int BLASFUNC(iqmax) (int *, double *, int *); +int BLASFUNC(icmax) (int *, float *, int *); +int BLASFUNC(izmax) (int *, double *, int *); +int BLASFUNC(ixmax) (int *, double *, int *); + +int BLASFUNC(isamin)(int *, float *, int *); +int BLASFUNC(idamin)(int *, double *, int *); +int BLASFUNC(iqamin)(int *, double *, int *); +int BLASFUNC(icamin)(int *, float *, int *); +int BLASFUNC(izamin)(int *, double *, int *); +int BLASFUNC(ixamin)(int *, double *, int *); + +int BLASFUNC(ismin)(int *, float *, int *); +int BLASFUNC(idmin)(int *, double *, int *); +int BLASFUNC(iqmin)(int *, double *, int *); +int BLASFUNC(icmin)(int *, float *, int *); +int BLASFUNC(izmin)(int *, double *, int *); +int BLASFUNC(ixmin)(int *, double *, int *); + +float BLASFUNC(samax) (int *, float *, int *); +double BLASFUNC(damax) (int *, double *, int *); +double BLASFUNC(qamax) (int *, double *, int *); +float BLASFUNC(scamax)(int *, float *, int *); +double BLASFUNC(dzamax)(int *, double *, int *); +double BLASFUNC(qxamax)(int *, double *, int *); + +float BLASFUNC(samin) (int *, float *, int *); +double BLASFUNC(damin) (int *, double *, int *); +double BLASFUNC(qamin) (int *, double *, int *); +float BLASFUNC(scamin)(int *, float *, int *); +double BLASFUNC(dzamin)(int *, double *, int *); +double BLASFUNC(qxamin)(int *, double *, int *); + +float BLASFUNC(smax) (int *, float *, int *); +double BLASFUNC(dmax) (int *, double *, int *); +double BLASFUNC(qmax) (int *, double *, int *); +float BLASFUNC(scmax) (int *, float *, int *); +double BLASFUNC(dzmax) (int *, double *, int *); +double BLASFUNC(qxmax) (int *, double *, int *); + +float BLASFUNC(smin) (int *, float *, int *); +double BLASFUNC(dmin) (int *, double *, int *); +double BLASFUNC(qmin) (int *, double *, int *); +float BLASFUNC(scmin) (int *, float *, int *); +double BLASFUNC(dzmin) (int *, double *, int *); +double BLASFUNC(qxmin) (int *, double *, int *); + +int BLASFUNC(sscal) (int *, float *, float *, int *); +int BLASFUNC(dscal) (int *, double *, double *, int *); +int BLASFUNC(qscal) (int *, double *, double *, int *); +int BLASFUNC(cscal) (int *, float *, float *, int *); +int BLASFUNC(zscal) (int *, double *, double *, int *); +int BLASFUNC(xscal) (int *, double *, double *, int *); +int BLASFUNC(csscal)(int *, float *, float *, int *); +int BLASFUNC(zdscal)(int *, double *, double *, int *); +int BLASFUNC(xqscal)(int *, double *, double *, int *); + +float BLASFUNC(snrm2) (int *, float *, int *); +float BLASFUNC(scnrm2)(int *, float *, int *); + +double BLASFUNC(dnrm2) (int *, double *, int *); +double BLASFUNC(qnrm2) (int *, double *, int *); +double BLASFUNC(dznrm2)(int *, double *, int *); +double BLASFUNC(qxnrm2)(int *, double *, int *); + +int BLASFUNC(srot) (int *, float *, int *, float *, int *, float *, float *); +int BLASFUNC(drot) (int *, double *, int *, double *, int *, double *, double *); +int BLASFUNC(qrot) (int *, double *, int *, double *, int *, double *, double *); +int BLASFUNC(csrot) (int *, float *, int *, float *, int *, float *, float *); +int BLASFUNC(zdrot) (int *, double *, int *, double *, int *, double *, double *); +int BLASFUNC(xqrot) (int *, double *, int *, double *, int *, double *, double *); + +int BLASFUNC(srotg) (float *, float *, float *, float *); +int BLASFUNC(drotg) (double *, double *, double *, double *); +int BLASFUNC(qrotg) (double *, double *, double *, double *); +int BLASFUNC(crotg) (float *, float *, float *, float *); +int BLASFUNC(zrotg) (double *, double *, double *, double *); +int BLASFUNC(xrotg) (double *, double *, double *, double *); + +int BLASFUNC(srotmg)(float *, float *, float *, float *, float *); +int BLASFUNC(drotmg)(double *, double *, double *, double *, double *); + +int BLASFUNC(srotm) (int *, float *, int *, float *, int *, float *); +int BLASFUNC(drotm) (int *, double *, int *, double *, int *, double *); +int BLASFUNC(qrotm) (int *, double *, int *, double *, int *, double *); + +/* Level 2 routines */ + +int BLASFUNC(sger)(int *, int *, float *, float *, int *, + float *, int *, float *, int *); +int BLASFUNC(dger)(int *, int *, double *, double *, int *, + double *, int *, double *, int *); +int BLASFUNC(qger)(int *, int *, double *, double *, int *, + double *, int *, double *, int *); +int BLASFUNC(cgeru)(int *, int *, float *, float *, int *, + float *, int *, float *, int *); +int BLASFUNC(cgerc)(int *, int *, float *, float *, int *, + float *, int *, float *, int *); +int BLASFUNC(zgeru)(int *, int *, double *, double *, int *, + double *, int *, double *, int *); +int BLASFUNC(zgerc)(int *, int *, double *, double *, int *, + double *, int *, double *, int *); +int BLASFUNC(xgeru)(int *, int *, double *, double *, int *, + double *, int *, double *, int *); +int BLASFUNC(xgerc)(int *, int *, double *, double *, int *, + double *, int *, double *, int *); + +int BLASFUNC(sgemv)(char *, int *, int *, float *, float *, int *, + float *, int *, float *, float *, int *); +int BLASFUNC(dgemv)(char *, int *, int *, double *, double *, int *, + double *, int *, double *, double *, int *); +int BLASFUNC(qgemv)(char *, int *, int *, double *, double *, int *, + double *, int *, double *, double *, int *); +int BLASFUNC(cgemv)(char *, int *, int *, float *, float *, int *, + float *, int *, float *, float *, int *); +int BLASFUNC(zgemv)(char *, int *, int *, double *, double *, int *, + double *, int *, double *, double *, int *); +int BLASFUNC(xgemv)(char *, int *, int *, double *, double *, int *, + double *, int *, double *, double *, int *); + +int BLASFUNC(strsv) (char *, char *, char *, int *, float *, int *, + float *, int *); +int BLASFUNC(dtrsv) (char *, char *, char *, int *, double *, int *, + double *, int *); +int BLASFUNC(qtrsv) (char *, char *, char *, int *, double *, int *, + double *, int *); +int BLASFUNC(ctrsv) (char *, char *, char *, int *, float *, int *, + float *, int *); +int BLASFUNC(ztrsv) (char *, char *, char *, int *, double *, int *, + double *, int *); +int BLASFUNC(xtrsv) (char *, char *, char *, int *, double *, int *, + double *, int *); + +int BLASFUNC(stpsv) (char *, char *, char *, int *, float *, float *, int *); +int BLASFUNC(dtpsv) (char *, char *, char *, int *, double *, double *, int *); +int BLASFUNC(qtpsv) (char *, char *, char *, int *, double *, double *, int *); +int BLASFUNC(ctpsv) (char *, char *, char *, int *, float *, float *, int *); +int BLASFUNC(ztpsv) (char *, char *, char *, int *, double *, double *, int *); +int BLASFUNC(xtpsv) (char *, char *, char *, int *, double *, double *, int *); + +int BLASFUNC(strmv) (char *, char *, char *, int *, float *, int *, + float *, int *); +int BLASFUNC(dtrmv) (char *, char *, char *, int *, double *, int *, + double *, int *); +int BLASFUNC(qtrmv) (char *, char *, char *, int *, double *, int *, + double *, int *); +int BLASFUNC(ctrmv) (char *, char *, char *, int *, float *, int *, + float *, int *); +int BLASFUNC(ztrmv) (char *, char *, char *, int *, double *, int *, + double *, int *); +int BLASFUNC(xtrmv) (char *, char *, char *, int *, double *, int *, + double *, int *); + +int BLASFUNC(stpmv) (char *, char *, char *, int *, float *, float *, int *); +int BLASFUNC(dtpmv) (char *, char *, char *, int *, double *, double *, int *); +int BLASFUNC(qtpmv) (char *, char *, char *, int *, double *, double *, int *); +int BLASFUNC(ctpmv) (char *, char *, char *, int *, float *, float *, int *); +int BLASFUNC(ztpmv) (char *, char *, char *, int *, double *, double *, int *); +int BLASFUNC(xtpmv) (char *, char *, char *, int *, double *, double *, int *); + +int BLASFUNC(stbmv) (char *, char *, char *, int *, int *, float *, int *, float *, int *); +int BLASFUNC(dtbmv) (char *, char *, char *, int *, int *, double *, int *, double *, int *); +int BLASFUNC(qtbmv) (char *, char *, char *, int *, int *, double *, int *, double *, int *); +int BLASFUNC(ctbmv) (char *, char *, char *, int *, int *, float *, int *, float *, int *); +int BLASFUNC(ztbmv) (char *, char *, char *, int *, int *, double *, int *, double *, int *); +int BLASFUNC(xtbmv) (char *, char *, char *, int *, int *, double *, int *, double *, int *); + +int BLASFUNC(stbsv) (char *, char *, char *, int *, int *, float *, int *, float *, int *); +int BLASFUNC(dtbsv) (char *, char *, char *, int *, int *, double *, int *, double *, int *); +int BLASFUNC(qtbsv) (char *, char *, char *, int *, int *, double *, int *, double *, int *); +int BLASFUNC(ctbsv) (char *, char *, char *, int *, int *, float *, int *, float *, int *); +int BLASFUNC(ztbsv) (char *, char *, char *, int *, int *, double *, int *, double *, int *); +int BLASFUNC(xtbsv) (char *, char *, char *, int *, int *, double *, int *, double *, int *); + +int BLASFUNC(ssymv) (char *, int *, float *, float *, int *, + float *, int *, float *, float *, int *); +int BLASFUNC(dsymv) (char *, int *, double *, double *, int *, + double *, int *, double *, double *, int *); +int BLASFUNC(qsymv) (char *, int *, double *, double *, int *, + double *, int *, double *, double *, int *); +int BLASFUNC(csymv) (char *, int *, float *, float *, int *, + float *, int *, float *, float *, int *); +int BLASFUNC(zsymv) (char *, int *, double *, double *, int *, + double *, int *, double *, double *, int *); +int BLASFUNC(xsymv) (char *, int *, double *, double *, int *, + double *, int *, double *, double *, int *); + +int BLASFUNC(sspmv) (char *, int *, float *, float *, + float *, int *, float *, float *, int *); +int BLASFUNC(dspmv) (char *, int *, double *, double *, + double *, int *, double *, double *, int *); +int BLASFUNC(qspmv) (char *, int *, double *, double *, + double *, int *, double *, double *, int *); +int BLASFUNC(cspmv) (char *, int *, float *, float *, + float *, int *, float *, float *, int *); +int BLASFUNC(zspmv) (char *, int *, double *, double *, + double *, int *, double *, double *, int *); +int BLASFUNC(xspmv) (char *, int *, double *, double *, + double *, int *, double *, double *, int *); + +int BLASFUNC(ssyr) (char *, int *, float *, float *, int *, + float *, int *); +int BLASFUNC(dsyr) (char *, int *, double *, double *, int *, + double *, int *); +int BLASFUNC(qsyr) (char *, int *, double *, double *, int *, + double *, int *); +int BLASFUNC(csyr) (char *, int *, float *, float *, int *, + float *, int *); +int BLASFUNC(zsyr) (char *, int *, double *, double *, int *, + double *, int *); +int BLASFUNC(xsyr) (char *, int *, double *, double *, int *, + double *, int *); + +int BLASFUNC(ssyr2) (char *, int *, float *, + float *, int *, float *, int *, float *, int *); +int BLASFUNC(dsyr2) (char *, int *, double *, + double *, int *, double *, int *, double *, int *); +int BLASFUNC(qsyr2) (char *, int *, double *, + double *, int *, double *, int *, double *, int *); +int BLASFUNC(csyr2) (char *, int *, float *, + float *, int *, float *, int *, float *, int *); +int BLASFUNC(zsyr2) (char *, int *, double *, + double *, int *, double *, int *, double *, int *); +int BLASFUNC(xsyr2) (char *, int *, double *, + double *, int *, double *, int *, double *, int *); + +int BLASFUNC(sspr) (char *, int *, float *, float *, int *, + float *); +int BLASFUNC(dspr) (char *, int *, double *, double *, int *, + double *); +int BLASFUNC(qspr) (char *, int *, double *, double *, int *, + double *); +int BLASFUNC(cspr) (char *, int *, float *, float *, int *, + float *); +int BLASFUNC(zspr) (char *, int *, double *, double *, int *, + double *); +int BLASFUNC(xspr) (char *, int *, double *, double *, int *, + double *); + +int BLASFUNC(sspr2) (char *, int *, float *, + float *, int *, float *, int *, float *); +int BLASFUNC(dspr2) (char *, int *, double *, + double *, int *, double *, int *, double *); +int BLASFUNC(qspr2) (char *, int *, double *, + double *, int *, double *, int *, double *); +int BLASFUNC(cspr2) (char *, int *, float *, + float *, int *, float *, int *, float *); +int BLASFUNC(zspr2) (char *, int *, double *, + double *, int *, double *, int *, double *); +int BLASFUNC(xspr2) (char *, int *, double *, + double *, int *, double *, int *, double *); + +int BLASFUNC(cher) (char *, int *, float *, float *, int *, + float *, int *); +int BLASFUNC(zher) (char *, int *, double *, double *, int *, + double *, int *); +int BLASFUNC(xher) (char *, int *, double *, double *, int *, + double *, int *); + +int BLASFUNC(chpr) (char *, int *, float *, float *, int *, float *); +int BLASFUNC(zhpr) (char *, int *, double *, double *, int *, double *); +int BLASFUNC(xhpr) (char *, int *, double *, double *, int *, double *); + +int BLASFUNC(cher2) (char *, int *, float *, + float *, int *, float *, int *, float *, int *); +int BLASFUNC(zher2) (char *, int *, double *, + double *, int *, double *, int *, double *, int *); +int BLASFUNC(xher2) (char *, int *, double *, + double *, int *, double *, int *, double *, int *); + +int BLASFUNC(chpr2) (char *, int *, float *, + float *, int *, float *, int *, float *); +int BLASFUNC(zhpr2) (char *, int *, double *, + double *, int *, double *, int *, double *); +int BLASFUNC(xhpr2) (char *, int *, double *, + double *, int *, double *, int *, double *); + +int BLASFUNC(chemv) (char *, int *, float *, float *, int *, + float *, int *, float *, float *, int *); +int BLASFUNC(zhemv) (char *, int *, double *, double *, int *, + double *, int *, double *, double *, int *); +int BLASFUNC(xhemv) (char *, int *, double *, double *, int *, + double *, int *, double *, double *, int *); + +int BLASFUNC(chpmv) (char *, int *, float *, float *, + float *, int *, float *, float *, int *); +int BLASFUNC(zhpmv) (char *, int *, double *, double *, + double *, int *, double *, double *, int *); +int BLASFUNC(xhpmv) (char *, int *, double *, double *, + double *, int *, double *, double *, int *); + +int BLASFUNC(snorm)(char *, int *, int *, float *, int *); +int BLASFUNC(dnorm)(char *, int *, int *, double *, int *); +int BLASFUNC(cnorm)(char *, int *, int *, float *, int *); +int BLASFUNC(znorm)(char *, int *, int *, double *, int *); + +int BLASFUNC(sgbmv)(char *, int *, int *, int *, int *, float *, float *, int *, + float *, int *, float *, float *, int *); +int BLASFUNC(dgbmv)(char *, int *, int *, int *, int *, double *, double *, int *, + double *, int *, double *, double *, int *); +int BLASFUNC(qgbmv)(char *, int *, int *, int *, int *, double *, double *, int *, + double *, int *, double *, double *, int *); +int BLASFUNC(cgbmv)(char *, int *, int *, int *, int *, float *, float *, int *, + float *, int *, float *, float *, int *); +int BLASFUNC(zgbmv)(char *, int *, int *, int *, int *, double *, double *, int *, + double *, int *, double *, double *, int *); +int BLASFUNC(xgbmv)(char *, int *, int *, int *, int *, double *, double *, int *, + double *, int *, double *, double *, int *); + +int BLASFUNC(ssbmv)(char *, int *, int *, float *, float *, int *, + float *, int *, float *, float *, int *); +int BLASFUNC(dsbmv)(char *, int *, int *, double *, double *, int *, + double *, int *, double *, double *, int *); +int BLASFUNC(qsbmv)(char *, int *, int *, double *, double *, int *, + double *, int *, double *, double *, int *); +int BLASFUNC(csbmv)(char *, int *, int *, float *, float *, int *, + float *, int *, float *, float *, int *); +int BLASFUNC(zsbmv)(char *, int *, int *, double *, double *, int *, + double *, int *, double *, double *, int *); +int BLASFUNC(xsbmv)(char *, int *, int *, double *, double *, int *, + double *, int *, double *, double *, int *); + +int BLASFUNC(chbmv)(char *, int *, int *, float *, float *, int *, + float *, int *, float *, float *, int *); +int BLASFUNC(zhbmv)(char *, int *, int *, double *, double *, int *, + double *, int *, double *, double *, int *); +int BLASFUNC(xhbmv)(char *, int *, int *, double *, double *, int *, + double *, int *, double *, double *, int *); + +/* Level 3 routines */ + +int BLASFUNC(sgemm)(char *, char *, int *, int *, int *, float *, + float *, int *, float *, int *, float *, float *, int *); +int BLASFUNC(dgemm)(char *, char *, int *, int *, int *, double *, + double *, int *, double *, int *, double *, double *, int *); +int BLASFUNC(qgemm)(char *, char *, int *, int *, int *, double *, + double *, int *, double *, int *, double *, double *, int *); +int BLASFUNC(cgemm)(char *, char *, int *, int *, int *, float *, + float *, int *, float *, int *, float *, float *, int *); +int BLASFUNC(zgemm)(char *, char *, int *, int *, int *, double *, + double *, int *, double *, int *, double *, double *, int *); +int BLASFUNC(xgemm)(char *, char *, int *, int *, int *, double *, + double *, int *, double *, int *, double *, double *, int *); + +int BLASFUNC(cgemm3m)(char *, char *, int *, int *, int *, float *, + float *, int *, float *, int *, float *, float *, int *); +int BLASFUNC(zgemm3m)(char *, char *, int *, int *, int *, double *, + double *, int *, double *, int *, double *, double *, int *); +int BLASFUNC(xgemm3m)(char *, char *, int *, int *, int *, double *, + double *, int *, double *, int *, double *, double *, int *); + +int BLASFUNC(sge2mm)(char *, char *, char *, int *, int *, + float *, float *, int *, float *, int *, + float *, float *, int *); +int BLASFUNC(dge2mm)(char *, char *, char *, int *, int *, + double *, double *, int *, double *, int *, + double *, double *, int *); +int BLASFUNC(cge2mm)(char *, char *, char *, int *, int *, + float *, float *, int *, float *, int *, + float *, float *, int *); +int BLASFUNC(zge2mm)(char *, char *, char *, int *, int *, + double *, double *, int *, double *, int *, + double *, double *, int *); + +int BLASFUNC(strsm)(char *, char *, char *, char *, int *, int *, + float *, float *, int *, float *, int *); +int BLASFUNC(dtrsm)(char *, char *, char *, char *, int *, int *, + double *, double *, int *, double *, int *); +int BLASFUNC(qtrsm)(char *, char *, char *, char *, int *, int *, + double *, double *, int *, double *, int *); +int BLASFUNC(ctrsm)(char *, char *, char *, char *, int *, int *, + float *, float *, int *, float *, int *); +int BLASFUNC(ztrsm)(char *, char *, char *, char *, int *, int *, + double *, double *, int *, double *, int *); +int BLASFUNC(xtrsm)(char *, char *, char *, char *, int *, int *, + double *, double *, int *, double *, int *); + +int BLASFUNC(strmm)(char *, char *, char *, char *, int *, int *, + float *, float *, int *, float *, int *); +int BLASFUNC(dtrmm)(char *, char *, char *, char *, int *, int *, + double *, double *, int *, double *, int *); +int BLASFUNC(qtrmm)(char *, char *, char *, char *, int *, int *, + double *, double *, int *, double *, int *); +int BLASFUNC(ctrmm)(char *, char *, char *, char *, int *, int *, + float *, float *, int *, float *, int *); +int BLASFUNC(ztrmm)(char *, char *, char *, char *, int *, int *, + double *, double *, int *, double *, int *); +int BLASFUNC(xtrmm)(char *, char *, char *, char *, int *, int *, + double *, double *, int *, double *, int *); + +int BLASFUNC(ssymm)(char *, char *, int *, int *, float *, float *, int *, + float *, int *, float *, float *, int *); +int BLASFUNC(dsymm)(char *, char *, int *, int *, double *, double *, int *, + double *, int *, double *, double *, int *); +int BLASFUNC(qsymm)(char *, char *, int *, int *, double *, double *, int *, + double *, int *, double *, double *, int *); +int BLASFUNC(csymm)(char *, char *, int *, int *, float *, float *, int *, + float *, int *, float *, float *, int *); +int BLASFUNC(zsymm)(char *, char *, int *, int *, double *, double *, int *, + double *, int *, double *, double *, int *); +int BLASFUNC(xsymm)(char *, char *, int *, int *, double *, double *, int *, + double *, int *, double *, double *, int *); + +int BLASFUNC(csymm3m)(char *, char *, int *, int *, float *, float *, int *, + float *, int *, float *, float *, int *); +int BLASFUNC(zsymm3m)(char *, char *, int *, int *, double *, double *, int *, + double *, int *, double *, double *, int *); +int BLASFUNC(xsymm3m)(char *, char *, int *, int *, double *, double *, int *, + double *, int *, double *, double *, int *); + +int BLASFUNC(ssyrk)(char *, char *, int *, int *, float *, float *, int *, + float *, float *, int *); +int BLASFUNC(dsyrk)(char *, char *, int *, int *, double *, double *, int *, + double *, double *, int *); +int BLASFUNC(qsyrk)(char *, char *, int *, int *, double *, double *, int *, + double *, double *, int *); +int BLASFUNC(csyrk)(char *, char *, int *, int *, float *, float *, int *, + float *, float *, int *); +int BLASFUNC(zsyrk)(char *, char *, int *, int *, double *, double *, int *, + double *, double *, int *); +int BLASFUNC(xsyrk)(char *, char *, int *, int *, double *, double *, int *, + double *, double *, int *); + +int BLASFUNC(ssyr2k)(char *, char *, int *, int *, float *, float *, int *, + float *, int *, float *, float *, int *); +int BLASFUNC(dsyr2k)(char *, char *, int *, int *, double *, double *, int *, + double*, int *, double *, double *, int *); +int BLASFUNC(qsyr2k)(char *, char *, int *, int *, double *, double *, int *, + double*, int *, double *, double *, int *); +int BLASFUNC(csyr2k)(char *, char *, int *, int *, float *, float *, int *, + float *, int *, float *, float *, int *); +int BLASFUNC(zsyr2k)(char *, char *, int *, int *, double *, double *, int *, + double*, int *, double *, double *, int *); +int BLASFUNC(xsyr2k)(char *, char *, int *, int *, double *, double *, int *, + double*, int *, double *, double *, int *); + +int BLASFUNC(chemm)(char *, char *, int *, int *, float *, float *, int *, + float *, int *, float *, float *, int *); +int BLASFUNC(zhemm)(char *, char *, int *, int *, double *, double *, int *, + double *, int *, double *, double *, int *); +int BLASFUNC(xhemm)(char *, char *, int *, int *, double *, double *, int *, + double *, int *, double *, double *, int *); + +int BLASFUNC(chemm3m)(char *, char *, int *, int *, float *, float *, int *, + float *, int *, float *, float *, int *); +int BLASFUNC(zhemm3m)(char *, char *, int *, int *, double *, double *, int *, + double *, int *, double *, double *, int *); +int BLASFUNC(xhemm3m)(char *, char *, int *, int *, double *, double *, int *, + double *, int *, double *, double *, int *); + +int BLASFUNC(cherk)(char *, char *, int *, int *, float *, float *, int *, + float *, float *, int *); +int BLASFUNC(zherk)(char *, char *, int *, int *, double *, double *, int *, + double *, double *, int *); +int BLASFUNC(xherk)(char *, char *, int *, int *, double *, double *, int *, + double *, double *, int *); + +int BLASFUNC(cher2k)(char *, char *, int *, int *, float *, float *, int *, + float *, int *, float *, float *, int *); +int BLASFUNC(zher2k)(char *, char *, int *, int *, double *, double *, int *, + double*, int *, double *, double *, int *); +int BLASFUNC(xher2k)(char *, char *, int *, int *, double *, double *, int *, + double*, int *, double *, double *, int *); +int BLASFUNC(cher2m)(char *, char *, char *, int *, int *, float *, float *, int *, + float *, int *, float *, float *, int *); +int BLASFUNC(zher2m)(char *, char *, char *, int *, int *, double *, double *, int *, + double*, int *, double *, double *, int *); +int BLASFUNC(xher2m)(char *, char *, char *, int *, int *, double *, double *, int *, + double*, int *, double *, double *, int *); + +int BLASFUNC(sgemt)(char *, int *, int *, float *, float *, int *, + float *, int *); +int BLASFUNC(dgemt)(char *, int *, int *, double *, double *, int *, + double *, int *); +int BLASFUNC(cgemt)(char *, int *, int *, float *, float *, int *, + float *, int *); +int BLASFUNC(zgemt)(char *, int *, int *, double *, double *, int *, + double *, int *); + +int BLASFUNC(sgema)(char *, char *, int *, int *, float *, + float *, int *, float *, float *, int *, float *, int *); +int BLASFUNC(dgema)(char *, char *, int *, int *, double *, + double *, int *, double*, double *, int *, double*, int *); +int BLASFUNC(cgema)(char *, char *, int *, int *, float *, + float *, int *, float *, float *, int *, float *, int *); +int BLASFUNC(zgema)(char *, char *, int *, int *, double *, + double *, int *, double*, double *, int *, double*, int *); + +int BLASFUNC(sgems)(char *, char *, int *, int *, float *, + float *, int *, float *, float *, int *, float *, int *); +int BLASFUNC(dgems)(char *, char *, int *, int *, double *, + double *, int *, double*, double *, int *, double*, int *); +int BLASFUNC(cgems)(char *, char *, int *, int *, float *, + float *, int *, float *, float *, int *, float *, int *); +int BLASFUNC(zgems)(char *, char *, int *, int *, double *, + double *, int *, double*, double *, int *, double*, int *); + +int BLASFUNC(sgetf2)(int *, int *, float *, int *, int *, int *); +int BLASFUNC(dgetf2)(int *, int *, double *, int *, int *, int *); +int BLASFUNC(qgetf2)(int *, int *, double *, int *, int *, int *); +int BLASFUNC(cgetf2)(int *, int *, float *, int *, int *, int *); +int BLASFUNC(zgetf2)(int *, int *, double *, int *, int *, int *); +int BLASFUNC(xgetf2)(int *, int *, double *, int *, int *, int *); + +int BLASFUNC(sgetrf)(int *, int *, float *, int *, int *, int *); +int BLASFUNC(dgetrf)(int *, int *, double *, int *, int *, int *); +int BLASFUNC(qgetrf)(int *, int *, double *, int *, int *, int *); +int BLASFUNC(cgetrf)(int *, int *, float *, int *, int *, int *); +int BLASFUNC(zgetrf)(int *, int *, double *, int *, int *, int *); +int BLASFUNC(xgetrf)(int *, int *, double *, int *, int *, int *); + +int BLASFUNC(slaswp)(int *, float *, int *, int *, int *, int *, int *); +int BLASFUNC(dlaswp)(int *, double *, int *, int *, int *, int *, int *); +int BLASFUNC(qlaswp)(int *, double *, int *, int *, int *, int *, int *); +int BLASFUNC(claswp)(int *, float *, int *, int *, int *, int *, int *); +int BLASFUNC(zlaswp)(int *, double *, int *, int *, int *, int *, int *); +int BLASFUNC(xlaswp)(int *, double *, int *, int *, int *, int *, int *); + +int BLASFUNC(sgetrs)(char *, int *, int *, float *, int *, int *, float *, int *, int *); +int BLASFUNC(dgetrs)(char *, int *, int *, double *, int *, int *, double *, int *, int *); +int BLASFUNC(qgetrs)(char *, int *, int *, double *, int *, int *, double *, int *, int *); +int BLASFUNC(cgetrs)(char *, int *, int *, float *, int *, int *, float *, int *, int *); +int BLASFUNC(zgetrs)(char *, int *, int *, double *, int *, int *, double *, int *, int *); +int BLASFUNC(xgetrs)(char *, int *, int *, double *, int *, int *, double *, int *, int *); + +int BLASFUNC(sgesv)(int *, int *, float *, int *, int *, float *, int *, int *); +int BLASFUNC(dgesv)(int *, int *, double *, int *, int *, double*, int *, int *); +int BLASFUNC(qgesv)(int *, int *, double *, int *, int *, double*, int *, int *); +int BLASFUNC(cgesv)(int *, int *, float *, int *, int *, float *, int *, int *); +int BLASFUNC(zgesv)(int *, int *, double *, int *, int *, double*, int *, int *); +int BLASFUNC(xgesv)(int *, int *, double *, int *, int *, double*, int *, int *); + +int BLASFUNC(spotf2)(char *, int *, float *, int *, int *); +int BLASFUNC(dpotf2)(char *, int *, double *, int *, int *); +int BLASFUNC(qpotf2)(char *, int *, double *, int *, int *); +int BLASFUNC(cpotf2)(char *, int *, float *, int *, int *); +int BLASFUNC(zpotf2)(char *, int *, double *, int *, int *); +int BLASFUNC(xpotf2)(char *, int *, double *, int *, int *); + +int BLASFUNC(spotrf)(char *, int *, float *, int *, int *); +int BLASFUNC(dpotrf)(char *, int *, double *, int *, int *); +int BLASFUNC(qpotrf)(char *, int *, double *, int *, int *); +int BLASFUNC(cpotrf)(char *, int *, float *, int *, int *); +int BLASFUNC(zpotrf)(char *, int *, double *, int *, int *); +int BLASFUNC(xpotrf)(char *, int *, double *, int *, int *); + +int BLASFUNC(slauu2)(char *, int *, float *, int *, int *); +int BLASFUNC(dlauu2)(char *, int *, double *, int *, int *); +int BLASFUNC(qlauu2)(char *, int *, double *, int *, int *); +int BLASFUNC(clauu2)(char *, int *, float *, int *, int *); +int BLASFUNC(zlauu2)(char *, int *, double *, int *, int *); +int BLASFUNC(xlauu2)(char *, int *, double *, int *, int *); + +int BLASFUNC(slauum)(char *, int *, float *, int *, int *); +int BLASFUNC(dlauum)(char *, int *, double *, int *, int *); +int BLASFUNC(qlauum)(char *, int *, double *, int *, int *); +int BLASFUNC(clauum)(char *, int *, float *, int *, int *); +int BLASFUNC(zlauum)(char *, int *, double *, int *, int *); +int BLASFUNC(xlauum)(char *, int *, double *, int *, int *); + +int BLASFUNC(strti2)(char *, char *, int *, float *, int *, int *); +int BLASFUNC(dtrti2)(char *, char *, int *, double *, int *, int *); +int BLASFUNC(qtrti2)(char *, char *, int *, double *, int *, int *); +int BLASFUNC(ctrti2)(char *, char *, int *, float *, int *, int *); +int BLASFUNC(ztrti2)(char *, char *, int *, double *, int *, int *); +int BLASFUNC(xtrti2)(char *, char *, int *, double *, int *, int *); + +int BLASFUNC(strtri)(char *, char *, int *, float *, int *, int *); +int BLASFUNC(dtrtri)(char *, char *, int *, double *, int *, int *); +int BLASFUNC(qtrtri)(char *, char *, int *, double *, int *, int *); +int BLASFUNC(ctrtri)(char *, char *, int *, float *, int *, int *); +int BLASFUNC(ztrtri)(char *, char *, int *, double *, int *, int *); +int BLASFUNC(xtrtri)(char *, char *, int *, double *, int *, int *); + +int BLASFUNC(spotri)(char *, int *, float *, int *, int *); +int BLASFUNC(dpotri)(char *, int *, double *, int *, int *); +int BLASFUNC(qpotri)(char *, int *, double *, int *, int *); +int BLASFUNC(cpotri)(char *, int *, float *, int *, int *); +int BLASFUNC(zpotri)(char *, int *, double *, int *, int *); +int BLASFUNC(xpotri)(char *, int *, double *, int *, int *); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/extern/Eigen3/Eigen/src/plugins/ArrayCwiseBinaryOps.h b/extern/Eigen3/Eigen/src/plugins/ArrayCwiseBinaryOps.h index 7d509e78f3a..5b979ebf89d 100644 --- a/extern/Eigen3/Eigen/src/plugins/ArrayCwiseBinaryOps.h +++ b/extern/Eigen3/Eigen/src/plugins/ArrayCwiseBinaryOps.h @@ -29,6 +29,16 @@ operator/(const EIGEN_CURRENT_STORAGE_BASE_CLASS &other) const */ EIGEN_MAKE_CWISE_BINARY_OP(min,internal::scalar_min_op) +/** \returns an expression of the coefficient-wise min of \c *this and scalar \a other + * + * \sa max() + */ +EIGEN_STRONG_INLINE const CwiseBinaryOp, const Derived, const ConstantReturnType> +(min)(const Scalar &other) const +{ + return (min)(Derived::PlainObject::Constant(rows(), cols(), other)); +} + /** \returns an expression of the coefficient-wise max of \c *this and \a other * * Example: \include Cwise_max.cpp @@ -38,6 +48,16 @@ EIGEN_MAKE_CWISE_BINARY_OP(min,internal::scalar_min_op) */ EIGEN_MAKE_CWISE_BINARY_OP(max,internal::scalar_max_op) +/** \returns an expression of the coefficient-wise max of \c *this and scalar \a other + * + * \sa min() + */ +EIGEN_STRONG_INLINE const CwiseBinaryOp, const Derived, const ConstantReturnType> +(max)(const Scalar &other) const +{ + return (max)(Derived::PlainObject::Constant(rows(), cols(), other)); +} + /** \returns an expression of the coefficient-wise \< operator of *this and \a other * * Example: \include Cwise_less.cpp @@ -141,3 +161,39 @@ operator-(const Scalar& scalar,const EIGEN_CURRENT_STORAGE_BASE_CLASS& { return (-other) + scalar; } + +/** \returns an expression of the coefficient-wise && operator of *this and \a other + * + * \warning this operator is for expression of bool only. + * + * Example: \include Cwise_boolean_and.cpp + * Output: \verbinclude Cwise_boolean_and.out + * + * \sa operator||(), select() + */ +template +inline const CwiseBinaryOp +operator&&(const EIGEN_CURRENT_STORAGE_BASE_CLASS &other) const +{ + EIGEN_STATIC_ASSERT((internal::is_same::value && internal::is_same::value), + THIS_METHOD_IS_ONLY_FOR_EXPRESSIONS_OF_BOOL); + return CwiseBinaryOp(derived(),other.derived()); +} + +/** \returns an expression of the coefficient-wise || operator of *this and \a other + * + * \warning this operator is for expression of bool only. + * + * Example: \include Cwise_boolean_or.cpp + * Output: \verbinclude Cwise_boolean_or.out + * + * \sa operator&&(), select() + */ +template +inline const CwiseBinaryOp +operator||(const EIGEN_CURRENT_STORAGE_BASE_CLASS &other) const +{ + EIGEN_STATIC_ASSERT((internal::is_same::value && internal::is_same::value), + THIS_METHOD_IS_ONLY_FOR_EXPRESSIONS_OF_BOOL); + return CwiseBinaryOp(derived(),other.derived()); +} diff --git a/extern/Eigen3/Eigen/src/plugins/BlockMethods.h b/extern/Eigen3/Eigen/src/plugins/BlockMethods.h index 4eba933388a..ef224001a54 100644 --- a/extern/Eigen3/Eigen/src/plugins/BlockMethods.h +++ b/extern/Eigen3/Eigen/src/plugins/BlockMethods.h @@ -4,24 +4,9 @@ // Copyright (C) 2008-2010 Gael Guennebaud // Copyright (C) 2006-2010 Benoit Jacob // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_BLOCKMETHODS_H #define EIGEN_BLOCKMETHODS_H diff --git a/extern/Eigen3/Eigen/src/plugins/CommonCwiseBinaryOps.h b/extern/Eigen3/Eigen/src/plugins/CommonCwiseBinaryOps.h index 8f7765e72bd..688d2244088 100644 --- a/extern/Eigen3/Eigen/src/plugins/CommonCwiseBinaryOps.h +++ b/extern/Eigen3/Eigen/src/plugins/CommonCwiseBinaryOps.h @@ -4,24 +4,9 @@ // Copyright (C) 2008-2009 Gael Guennebaud // Copyright (C) 2006-2008 Benoit Jacob // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. // This file is a base class plugin containing common coefficient wise functions. diff --git a/extern/Eigen3/Eigen/src/plugins/CommonCwiseUnaryOps.h b/extern/Eigen3/Eigen/src/plugins/CommonCwiseUnaryOps.h index 941d5153c59..08e931aaddd 100644 --- a/extern/Eigen3/Eigen/src/plugins/CommonCwiseUnaryOps.h +++ b/extern/Eigen3/Eigen/src/plugins/CommonCwiseUnaryOps.h @@ -4,24 +4,9 @@ // Copyright (C) 2008-2009 Gael Guennebaud // Copyright (C) 2006-2008 Benoit Jacob // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. // This file is a base class plugin containing common coefficient wise functions. diff --git a/extern/Eigen3/Eigen/src/plugins/MatrixCwiseBinaryOps.h b/extern/Eigen3/Eigen/src/plugins/MatrixCwiseBinaryOps.h index 35183f91f80..3a737df7b86 100644 --- a/extern/Eigen3/Eigen/src/plugins/MatrixCwiseBinaryOps.h +++ b/extern/Eigen3/Eigen/src/plugins/MatrixCwiseBinaryOps.h @@ -4,24 +4,9 @@ // Copyright (C) 2008-2009 Gael Guennebaud // Copyright (C) 2006-2008 Benoit Jacob // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. // This file is a base class plugin containing matrix specifics coefficient wise functions. @@ -91,6 +76,16 @@ cwiseMin(const EIGEN_CURRENT_STORAGE_BASE_CLASS &other) const return CwiseBinaryOp, const Derived, const OtherDerived>(derived(), other.derived()); } +/** \returns an expression of the coefficient-wise min of *this and scalar \a other + * + * \sa class CwiseBinaryOp, min() + */ +EIGEN_STRONG_INLINE const CwiseBinaryOp, const Derived, const ConstantReturnType> +cwiseMin(const Scalar &other) const +{ + return cwiseMin(Derived::PlainObject::Constant(rows(), cols(), other)); +} + /** \returns an expression of the coefficient-wise max of *this and \a other * * Example: \include MatrixBase_cwiseMax.cpp @@ -105,6 +100,17 @@ cwiseMax(const EIGEN_CURRENT_STORAGE_BASE_CLASS &other) const return CwiseBinaryOp, const Derived, const OtherDerived>(derived(), other.derived()); } +/** \returns an expression of the coefficient-wise max of *this and scalar \a other + * + * \sa class CwiseBinaryOp, min() + */ +EIGEN_STRONG_INLINE const CwiseBinaryOp, const Derived, const ConstantReturnType> +cwiseMax(const Scalar &other) const +{ + return cwiseMax(Derived::PlainObject::Constant(rows(), cols(), other)); +} + + /** \returns an expression of the coefficient-wise quotient of *this and \a other * * Example: \include MatrixBase_cwiseQuotient.cpp diff --git a/extern/Eigen3/Eigen/src/plugins/MatrixCwiseUnaryOps.h b/extern/Eigen3/Eigen/src/plugins/MatrixCwiseUnaryOps.h index a3d9a0e1465..0cf0640bae6 100644 --- a/extern/Eigen3/Eigen/src/plugins/MatrixCwiseUnaryOps.h +++ b/extern/Eigen3/Eigen/src/plugins/MatrixCwiseUnaryOps.h @@ -4,24 +4,9 @@ // Copyright (C) 2008-2009 Gael Guennebaud // Copyright (C) 2006-2008 Benoit Jacob // -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. // This file is a base class plugin containing matrix specifics coefficient wise functions. diff --git a/intern/itasc/CMakeLists.txt b/intern/itasc/CMakeLists.txt index ab2ed6d10eb..55879e85cdf 100644 --- a/intern/itasc/CMakeLists.txt +++ b/intern/itasc/CMakeLists.txt @@ -121,201 +121,245 @@ set(SRC kdl/framevel.inl # until we have another user... - ../../extern/Eigen3/Eigen/src/plugins/MatrixCwiseUnaryOps.h - ../../extern/Eigen3/Eigen/src/plugins/CommonCwiseUnaryOps.h - ../../extern/Eigen3/Eigen/src/plugins/MatrixCwiseBinaryOps.h - ../../extern/Eigen3/Eigen/src/plugins/BlockMethods.h - ../../extern/Eigen3/Eigen/src/plugins/ArrayCwiseUnaryOps.h - ../../extern/Eigen3/Eigen/src/plugins/ArrayCwiseBinaryOps.h - ../../extern/Eigen3/Eigen/src/plugins/CommonCwiseBinaryOps.h - ../../extern/Eigen3/Eigen/src/misc/Kernel.h - ../../extern/Eigen3/Eigen/src/misc/Image.h - ../../extern/Eigen3/Eigen/src/misc/Solve.h - ../../extern/Eigen3/Eigen/src/QR/HouseholderQR.h - ../../extern/Eigen3/Eigen/src/QR/ColPivHouseholderQR.h - ../../extern/Eigen3/Eigen/src/QR/FullPivHouseholderQR.h - ../../extern/Eigen3/Eigen/src/StlSupport/details.h - ../../extern/Eigen3/Eigen/src/StlSupport/StdList.h - ../../extern/Eigen3/Eigen/src/StlSupport/StdDeque.h - ../../extern/Eigen3/Eigen/src/StlSupport/StdVector.h - ../../extern/Eigen3/Eigen/src/SVD/UpperBidiagonalization.h - ../../extern/Eigen3/Eigen/src/SVD/JacobiSVD.h - ../../extern/Eigen3/Eigen/src/Eigenvalues/ComplexEigenSolver.h - ../../extern/Eigen3/Eigen/src/Eigenvalues/ComplexSchur.h - ../../extern/Eigen3/Eigen/src/Eigenvalues/HessenbergDecomposition.h - ../../extern/Eigen3/Eigen/src/Eigenvalues/Tridiagonalization.h - ../../extern/Eigen3/Eigen/src/Eigenvalues/GeneralizedSelfAdjointEigenSolver.h - ../../extern/Eigen3/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h - ../../extern/Eigen3/Eigen/src/Eigenvalues/RealSchur.h - ../../extern/Eigen3/Eigen/src/Eigenvalues/EigenvaluesCommon.h - ../../extern/Eigen3/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h - ../../extern/Eigen3/Eigen/src/Eigenvalues/EigenSolver.h - ../../extern/Eigen3/Eigen/src/Jacobi/Jacobi.h - ../../extern/Eigen3/Eigen/src/Householder/Householder.h - ../../extern/Eigen3/Eigen/src/Householder/BlockHouseholder.h - ../../extern/Eigen3/Eigen/src/Householder/HouseholderSequence.h - ../../extern/Eigen3/Eigen/src/Geometry/RotationBase.h - ../../extern/Eigen3/Eigen/src/Geometry/Rotation2D.h - ../../extern/Eigen3/Eigen/src/Geometry/Homogeneous.h - ../../extern/Eigen3/Eigen/src/Geometry/Hyperplane.h - ../../extern/Eigen3/Eigen/src/Geometry/EulerAngles.h - ../../extern/Eigen3/Eigen/src/Geometry/arch/Geometry_SSE.h - ../../extern/Eigen3/Eigen/src/Geometry/ParametrizedLine.h - ../../extern/Eigen3/Eigen/src/Geometry/OrthoMethods.h - ../../extern/Eigen3/Eigen/src/Geometry/AngleAxis.h - ../../extern/Eigen3/Eigen/src/Geometry/Umeyama.h - ../../extern/Eigen3/Eigen/src/Geometry/Scaling.h - ../../extern/Eigen3/Eigen/src/Geometry/Translation.h - ../../extern/Eigen3/Eigen/src/Geometry/AlignedBox.h - ../../extern/Eigen3/Eigen/src/Geometry/Transform.h - ../../extern/Eigen3/Eigen/src/Geometry/Quaternion.h - ../../extern/Eigen3/Eigen/src/LU/PartialPivLU.h - ../../extern/Eigen3/Eigen/src/LU/Determinant.h - ../../extern/Eigen3/Eigen/src/LU/arch/Inverse_SSE.h - ../../extern/Eigen3/Eigen/src/LU/FullPivLU.h - ../../extern/Eigen3/Eigen/src/LU/Inverse.h - ../../extern/Eigen3/Eigen/src/Sparse/SparseMatrixBase.h - ../../extern/Eigen3/Eigen/src/Sparse/SparseSelfAdjointView.h - ../../extern/Eigen3/Eigen/src/Sparse/SparseVector.h - ../../extern/Eigen3/Eigen/src/Sparse/SparseDiagonalProduct.h - ../../extern/Eigen3/Eigen/src/Sparse/TriangularSolver.h - ../../extern/Eigen3/Eigen/src/Sparse/AmbiVector.h - ../../extern/Eigen3/Eigen/src/Sparse/SparseDenseProduct.h - ../../extern/Eigen3/Eigen/src/Sparse/SparseBlock.h - ../../extern/Eigen3/Eigen/src/Sparse/SparseTriangularView.h - ../../extern/Eigen3/Eigen/src/Sparse/SparseCwiseBinaryOp.h - ../../extern/Eigen3/Eigen/src/Sparse/CoreIterators.h - ../../extern/Eigen3/Eigen/src/Sparse/SparseMatrix.h - ../../extern/Eigen3/Eigen/src/Sparse/SparseAssign.h - ../../extern/Eigen3/Eigen/src/Sparse/SparseSparseProduct.h - ../../extern/Eigen3/Eigen/src/Sparse/SparseDot.h - ../../extern/Eigen3/Eigen/src/Sparse/DynamicSparseMatrix.h - ../../extern/Eigen3/Eigen/src/Sparse/SparseRedux.h - ../../extern/Eigen3/Eigen/src/Sparse/SparseFuzzy.h - ../../extern/Eigen3/Eigen/src/Sparse/SparseCwiseUnaryOp.h - ../../extern/Eigen3/Eigen/src/Sparse/SparseView.h - ../../extern/Eigen3/Eigen/src/Sparse/MappedSparseMatrix.h - ../../extern/Eigen3/Eigen/src/Sparse/SparseUtil.h - ../../extern/Eigen3/Eigen/src/Sparse/SparseTranspose.h - ../../extern/Eigen3/Eigen/src/Sparse/SparseProduct.h - ../../extern/Eigen3/Eigen/src/Sparse/CompressedStorage.h - ../../extern/Eigen3/Eigen/src/Eigen2Support/Cwise.h - ../../extern/Eigen3/Eigen/src/Eigen2Support/TriangularSolver.h - ../../extern/Eigen3/Eigen/src/Eigen2Support/QR.h - ../../extern/Eigen3/Eigen/src/Eigen2Support/Lazy.h - ../../extern/Eigen3/Eigen/src/Eigen2Support/Memory.h - ../../extern/Eigen3/Eigen/src/Eigen2Support/SVD.h - ../../extern/Eigen3/Eigen/src/Eigen2Support/CwiseOperators.h - ../../extern/Eigen3/Eigen/src/Eigen2Support/VectorBlock.h - ../../extern/Eigen3/Eigen/src/Eigen2Support/Meta.h - ../../extern/Eigen3/Eigen/src/Eigen2Support/Macros.h - ../../extern/Eigen3/Eigen/src/Eigen2Support/LeastSquares.h - ../../extern/Eigen3/Eigen/src/Eigen2Support/LU.h - ../../extern/Eigen3/Eigen/src/Eigen2Support/Block.h - ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry/RotationBase.h - ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Rotation2D.h - ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Hyperplane.h - ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry/ParametrizedLine.h - ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry/AngleAxis.h - ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Scaling.h - ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry/All.h - ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Translation.h - ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry/AlignedBox.h - ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Transform.h - ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Quaternion.h - ../../extern/Eigen3/Eigen/src/Eigen2Support/Minor.h - ../../extern/Eigen3/Eigen/src/Eigen2Support/MathFunctions.h - ../../extern/Eigen3/Eigen/src/Core/SelfAdjointView.h - ../../extern/Eigen3/Eigen/src/Core/MatrixBase.h - ../../extern/Eigen3/Eigen/src/Core/Swap.h - ../../extern/Eigen3/Eigen/src/Core/DenseCoeffsBase.h - ../../extern/Eigen3/Eigen/src/Core/DenseBase.h - ../../extern/Eigen3/Eigen/src/Core/GlobalFunctions.h - ../../extern/Eigen3/Eigen/src/Core/ProductBase.h - ../../extern/Eigen3/Eigen/src/Core/CwiseBinaryOp.h - ../../extern/Eigen3/Eigen/src/Core/Stride.h - ../../extern/Eigen3/Eigen/src/Core/Matrix.h - ../../extern/Eigen3/Eigen/src/Core/Visitor.h - ../../extern/Eigen3/Eigen/src/Core/Array.h - ../../extern/Eigen3/Eigen/src/Core/ReturnByValue.h - ../../extern/Eigen3/Eigen/src/Core/SelfCwiseBinaryOp.h - ../../extern/Eigen3/Eigen/src/Core/EigenBase.h - ../../extern/Eigen3/Eigen/src/Core/Random.h - ../../extern/Eigen3/Eigen/src/Core/Redux.h - ../../extern/Eigen3/Eigen/src/Core/arch/Default/Settings.h - ../../extern/Eigen3/Eigen/src/Core/arch/AltiVec/PacketMath.h - ../../extern/Eigen3/Eigen/src/Core/arch/AltiVec/Complex.h - ../../extern/Eigen3/Eigen/src/Core/arch/NEON/PacketMath.h - ../../extern/Eigen3/Eigen/src/Core/arch/NEON/Complex.h - ../../extern/Eigen3/Eigen/src/Core/arch/SSE/PacketMath.h - ../../extern/Eigen3/Eigen/src/Core/arch/SSE/Complex.h - ../../extern/Eigen3/Eigen/src/Core/arch/SSE/MathFunctions.h - ../../extern/Eigen3/Eigen/src/Core/BooleanRedux.h - ../../extern/Eigen3/Eigen/src/Core/util/ReenableStupidWarnings.h - ../../extern/Eigen3/Eigen/src/Core/util/BlasUtil.h - ../../extern/Eigen3/Eigen/src/Core/util/Memory.h - ../../extern/Eigen3/Eigen/src/Core/util/Meta.h - ../../extern/Eigen3/Eigen/src/Core/util/Constants.h - ../../extern/Eigen3/Eigen/src/Core/util/Macros.h - ../../extern/Eigen3/Eigen/src/Core/util/ForwardDeclarations.h - ../../extern/Eigen3/Eigen/src/Core/util/StaticAssert.h - ../../extern/Eigen3/Eigen/src/Core/util/DisableStupidWarnings.h - ../../extern/Eigen3/Eigen/src/Core/util/XprHelper.h - ../../extern/Eigen3/Eigen/src/Core/VectorBlock.h - ../../extern/Eigen3/Eigen/src/Core/Transpositions.h - ../../extern/Eigen3/Eigen/src/Core/Select.h - ../../extern/Eigen3/Eigen/src/Core/BandMatrix.h - ../../extern/Eigen3/Eigen/src/Core/CwiseUnaryView.h - ../../extern/Eigen3/Eigen/src/Core/Dot.h - ../../extern/Eigen3/Eigen/src/Core/GenericPacketMath.h - ../../extern/Eigen3/Eigen/src/Core/Product.h - ../../extern/Eigen3/Eigen/src/Core/Transpose.h - ../../extern/Eigen3/Eigen/src/Core/Block.h - ../../extern/Eigen3/Eigen/src/Core/ArrayWrapper.h - ../../extern/Eigen3/Eigen/src/Core/MapBase.h - ../../extern/Eigen3/Eigen/src/Core/NoAlias.h - ../../extern/Eigen3/Eigen/src/Core/ForceAlignedAccess.h - ../../extern/Eigen3/Eigen/src/Core/PlainObjectBase.h - ../../extern/Eigen3/Eigen/src/Core/IO.h - ../../extern/Eigen3/Eigen/src/Core/DiagonalMatrix.h - ../../extern/Eigen3/Eigen/src/Core/CwiseUnaryOp.h - ../../extern/Eigen3/Eigen/src/Core/Reverse.h - ../../extern/Eigen3/Eigen/src/Core/Fuzzy.h - ../../extern/Eigen3/Eigen/src/Core/DenseStorage.h - ../../extern/Eigen3/Eigen/src/Core/StableNorm.h - ../../extern/Eigen3/Eigen/src/Core/NumTraits.h - ../../extern/Eigen3/Eigen/src/Core/Map.h - ../../extern/Eigen3/Eigen/src/Core/Functors.h - ../../extern/Eigen3/Eigen/src/Core/PermutationMatrix.h - ../../extern/Eigen3/Eigen/src/Core/ArrayBase.h - ../../extern/Eigen3/Eigen/src/Core/CwiseNullaryOp.h - ../../extern/Eigen3/Eigen/src/Core/SolveTriangular.h - ../../extern/Eigen3/Eigen/src/Core/NestByValue.h - ../../extern/Eigen3/Eigen/src/Core/DiagonalProduct.h - ../../extern/Eigen3/Eigen/src/Core/CommaInitializer.h - ../../extern/Eigen3/Eigen/src/Core/MathFunctions.h - ../../extern/Eigen3/Eigen/src/Core/Diagonal.h - ../../extern/Eigen3/Eigen/src/Core/Replicate.h - ../../extern/Eigen3/Eigen/src/Core/products/TriangularMatrixMatrix.h - ../../extern/Eigen3/Eigen/src/Core/products/SelfadjointProduct.h - ../../extern/Eigen3/Eigen/src/Core/products/GeneralMatrixVector.h - ../../extern/Eigen3/Eigen/src/Core/products/CoeffBasedProduct.h - ../../extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixVector.h - ../../extern/Eigen3/Eigen/src/Core/products/SelfadjointRank2Update.h - ../../extern/Eigen3/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h - ../../extern/Eigen3/Eigen/src/Core/products/GeneralMatrixMatrix.h - ../../extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixMatrix.h - ../../extern/Eigen3/Eigen/src/Core/products/Parallelizer.h - ../../extern/Eigen3/Eigen/src/Core/products/TriangularSolverMatrix.h - ../../extern/Eigen3/Eigen/src/Core/products/TriangularSolverVector.h - ../../extern/Eigen3/Eigen/src/Core/products/TriangularMatrixVector.h - ../../extern/Eigen3/Eigen/src/Core/products/GeneralBlockPanelKernel.h - ../../extern/Eigen3/Eigen/src/Core/TriangularMatrix.h - ../../extern/Eigen3/Eigen/src/Core/VectorwiseOp.h - ../../extern/Eigen3/Eigen/src/Core/Assign.h - ../../extern/Eigen3/Eigen/src/Core/Flagged.h ../../extern/Eigen3/Eigen/src/Cholesky/LDLT.h ../../extern/Eigen3/Eigen/src/Cholesky/LLT.h + ../../extern/Eigen3/Eigen/src/Cholesky/LLT_MKL.h + ../../extern/Eigen3/Eigen/src/CholmodSupport/CholmodSupport.h + ../../extern/Eigen3/Eigen/src/Core/arch + ../../extern/Eigen3/Eigen/src/Core/Array.h + ../../extern/Eigen3/Eigen/src/Core/ArrayBase.h + ../../extern/Eigen3/Eigen/src/Core/ArrayWrapper.h + ../../extern/Eigen3/Eigen/src/Core/Assign.h + ../../extern/Eigen3/Eigen/src/Core/Assign_MKL.h + ../../extern/Eigen3/Eigen/src/Core/BandMatrix.h + ../../extern/Eigen3/Eigen/src/Core/Block.h + ../../extern/Eigen3/Eigen/src/Core/BooleanRedux.h + ../../extern/Eigen3/Eigen/src/Core/CommaInitializer.h + ../../extern/Eigen3/Eigen/src/Core/CwiseBinaryOp.h + ../../extern/Eigen3/Eigen/src/Core/CwiseNullaryOp.h + ../../extern/Eigen3/Eigen/src/Core/CwiseUnaryOp.h + ../../extern/Eigen3/Eigen/src/Core/CwiseUnaryView.h + ../../extern/Eigen3/Eigen/src/Core/DenseBase.h + ../../extern/Eigen3/Eigen/src/Core/DenseCoeffsBase.h + ../../extern/Eigen3/Eigen/src/Core/DenseStorage.h + ../../extern/Eigen3/Eigen/src/Core/Diagonal.h + ../../extern/Eigen3/Eigen/src/Core/DiagonalMatrix.h + ../../extern/Eigen3/Eigen/src/Core/DiagonalProduct.h + ../../extern/Eigen3/Eigen/src/Core/Dot.h + ../../extern/Eigen3/Eigen/src/Core/EigenBase.h + ../../extern/Eigen3/Eigen/src/Core/Flagged.h + ../../extern/Eigen3/Eigen/src/Core/ForceAlignedAccess.h + ../../extern/Eigen3/Eigen/src/Core/Functors.h + ../../extern/Eigen3/Eigen/src/Core/Fuzzy.h + ../../extern/Eigen3/Eigen/src/Core/GeneralProduct.h + ../../extern/Eigen3/Eigen/src/Core/GenericPacketMath.h + ../../extern/Eigen3/Eigen/src/Core/GlobalFunctions.h + ../../extern/Eigen3/Eigen/src/Core/IO.h + ../../extern/Eigen3/Eigen/src/Core/Map.h + ../../extern/Eigen3/Eigen/src/Core/MapBase.h + ../../extern/Eigen3/Eigen/src/Core/MathFunctions.h + ../../extern/Eigen3/Eigen/src/Core/Matrix.h + ../../extern/Eigen3/Eigen/src/Core/MatrixBase.h + ../../extern/Eigen3/Eigen/src/Core/NestByValue.h + ../../extern/Eigen3/Eigen/src/Core/NoAlias.h + ../../extern/Eigen3/Eigen/src/Core/NumTraits.h + ../../extern/Eigen3/Eigen/src/Core/PermutationMatrix.h + ../../extern/Eigen3/Eigen/src/Core/PlainObjectBase.h + ../../extern/Eigen3/Eigen/src/Core/Product.h + ../../extern/Eigen3/Eigen/src/Core/ProductBase.h + ../../extern/Eigen3/Eigen/src/Core/products + ../../extern/Eigen3/Eigen/src/Core/Random.h + ../../extern/Eigen3/Eigen/src/Core/Redux.h + ../../extern/Eigen3/Eigen/src/Core/Replicate.h + ../../extern/Eigen3/Eigen/src/Core/ReturnByValue.h + ../../extern/Eigen3/Eigen/src/Core/Reverse.h + ../../extern/Eigen3/Eigen/src/Core/Select.h + ../../extern/Eigen3/Eigen/src/Core/SelfAdjointView.h + ../../extern/Eigen3/Eigen/src/Core/SelfCwiseBinaryOp.h + ../../extern/Eigen3/Eigen/src/Core/SolveTriangular.h + ../../extern/Eigen3/Eigen/src/Core/StableNorm.h + ../../extern/Eigen3/Eigen/src/Core/Stride.h + ../../extern/Eigen3/Eigen/src/Core/Swap.h + ../../extern/Eigen3/Eigen/src/Core/Transpose.h + ../../extern/Eigen3/Eigen/src/Core/Transpositions.h + ../../extern/Eigen3/Eigen/src/Core/TriangularMatrix.h + ../../extern/Eigen3/Eigen/src/Core/util + ../../extern/Eigen3/Eigen/src/Core/VectorBlock.h + ../../extern/Eigen3/Eigen/src/Core/VectorwiseOp.h + ../../extern/Eigen3/Eigen/src/Core/Visitor.h + ../../extern/Eigen3/Eigen/src/Core/arch/AltiVec + ../../extern/Eigen3/Eigen/src/Core/arch/Default + ../../extern/Eigen3/Eigen/src/Core/arch/NEON + ../../extern/Eigen3/Eigen/src/Core/arch/SSE + ../../extern/Eigen3/Eigen/src/Core/arch/AltiVec/Complex.h + ../../extern/Eigen3/Eigen/src/Core/arch/AltiVec/PacketMath.h + ../../extern/Eigen3/Eigen/src/Core/arch/Default/Settings.h + ../../extern/Eigen3/Eigen/src/Core/arch/NEON/Complex.h + ../../extern/Eigen3/Eigen/src/Core/arch/NEON/PacketMath.h + ../../extern/Eigen3/Eigen/src/Core/arch/SSE/Complex.h + ../../extern/Eigen3/Eigen/src/Core/arch/SSE/MathFunctions.h + ../../extern/Eigen3/Eigen/src/Core/arch/SSE/PacketMath.h + ../../extern/Eigen3/Eigen/src/Core/products/CoeffBasedProduct.h + ../../extern/Eigen3/Eigen/src/Core/products/GeneralBlockPanelKernel.h + ../../extern/Eigen3/Eigen/src/Core/products/GeneralMatrixMatrix.h + ../../extern/Eigen3/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h + ../../extern/Eigen3/Eigen/src/Core/products/GeneralMatrixMatrixTriangular_MKL.h + ../../extern/Eigen3/Eigen/src/Core/products/GeneralMatrixMatrix_MKL.h + ../../extern/Eigen3/Eigen/src/Core/products/GeneralMatrixVector.h + ../../extern/Eigen3/Eigen/src/Core/products/GeneralMatrixVector_MKL.h + ../../extern/Eigen3/Eigen/src/Core/products/Parallelizer.h + ../../extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixMatrix.h + ../../extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixMatrix_MKL.h + ../../extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixVector.h + ../../extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixVector_MKL.h + ../../extern/Eigen3/Eigen/src/Core/products/SelfadjointProduct.h + ../../extern/Eigen3/Eigen/src/Core/products/SelfadjointRank2Update.h + ../../extern/Eigen3/Eigen/src/Core/products/TriangularMatrixMatrix.h + ../../extern/Eigen3/Eigen/src/Core/products/TriangularMatrixMatrix_MKL.h + ../../extern/Eigen3/Eigen/src/Core/products/TriangularMatrixVector.h + ../../extern/Eigen3/Eigen/src/Core/products/TriangularMatrixVector_MKL.h + ../../extern/Eigen3/Eigen/src/Core/products/TriangularSolverMatrix.h + ../../extern/Eigen3/Eigen/src/Core/products/TriangularSolverMatrix_MKL.h + ../../extern/Eigen3/Eigen/src/Core/products/TriangularSolverVector.h + ../../extern/Eigen3/Eigen/src/Core/util/BlasUtil.h + ../../extern/Eigen3/Eigen/src/Core/util/Constants.h + ../../extern/Eigen3/Eigen/src/Core/util/DisableStupidWarnings.h + ../../extern/Eigen3/Eigen/src/Core/util/ForwardDeclarations.h + ../../extern/Eigen3/Eigen/src/Core/util/Macros.h + ../../extern/Eigen3/Eigen/src/Core/util/Memory.h + ../../extern/Eigen3/Eigen/src/Core/util/Meta.h + ../../extern/Eigen3/Eigen/src/Core/util/MKL_support.h + ../../extern/Eigen3/Eigen/src/Core/util/NonMPL2.h + ../../extern/Eigen3/Eigen/src/Core/util/ReenableStupidWarnings.h + ../../extern/Eigen3/Eigen/src/Core/util/StaticAssert.h + ../../extern/Eigen3/Eigen/src/Core/util/XprHelper.h + ../../extern/Eigen3/Eigen/src/Eigen2Support/Block.h + ../../extern/Eigen3/Eigen/src/Eigen2Support/Cwise.h + ../../extern/Eigen3/Eigen/src/Eigen2Support/CwiseOperators.h + ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry + ../../extern/Eigen3/Eigen/src/Eigen2Support/Lazy.h + ../../extern/Eigen3/Eigen/src/Eigen2Support/LeastSquares.h + ../../extern/Eigen3/Eigen/src/Eigen2Support/LU.h + ../../extern/Eigen3/Eigen/src/Eigen2Support/Macros.h + ../../extern/Eigen3/Eigen/src/Eigen2Support/MathFunctions.h + ../../extern/Eigen3/Eigen/src/Eigen2Support/Memory.h + ../../extern/Eigen3/Eigen/src/Eigen2Support/Meta.h + ../../extern/Eigen3/Eigen/src/Eigen2Support/Minor.h + ../../extern/Eigen3/Eigen/src/Eigen2Support/QR.h + ../../extern/Eigen3/Eigen/src/Eigen2Support/SVD.h + ../../extern/Eigen3/Eigen/src/Eigen2Support/TriangularSolver.h + ../../extern/Eigen3/Eigen/src/Eigen2Support/VectorBlock.h + ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry/AlignedBox.h + ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry/All.h + ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry/AngleAxis.h + ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Hyperplane.h + ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry/ParametrizedLine.h + ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Quaternion.h + ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Rotation2D.h + ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry/RotationBase.h + ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Scaling.h + ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Transform.h + ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Translation.h + ../../extern/Eigen3/Eigen/src/Eigenvalues/ComplexEigenSolver.h + ../../extern/Eigen3/Eigen/src/Eigenvalues/ComplexSchur.h + ../../extern/Eigen3/Eigen/src/Eigenvalues/ComplexSchur_MKL.h + ../../extern/Eigen3/Eigen/src/Eigenvalues/EigenSolver.h + ../../extern/Eigen3/Eigen/src/Eigenvalues/GeneralizedSelfAdjointEigenSolver.h + ../../extern/Eigen3/Eigen/src/Eigenvalues/HessenbergDecomposition.h + ../../extern/Eigen3/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h + ../../extern/Eigen3/Eigen/src/Eigenvalues/RealSchur.h + ../../extern/Eigen3/Eigen/src/Eigenvalues/RealSchur_MKL.h + ../../extern/Eigen3/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h + ../../extern/Eigen3/Eigen/src/Eigenvalues/SelfAdjointEigenSolver_MKL.h + ../../extern/Eigen3/Eigen/src/Eigenvalues/Tridiagonalization.h + ../../extern/Eigen3/Eigen/src/Geometry/AlignedBox.h + ../../extern/Eigen3/Eigen/src/Geometry/AngleAxis.h + ../../extern/Eigen3/Eigen/src/Geometry/arch + ../../extern/Eigen3/Eigen/src/Geometry/EulerAngles.h + ../../extern/Eigen3/Eigen/src/Geometry/Homogeneous.h + ../../extern/Eigen3/Eigen/src/Geometry/Hyperplane.h + ../../extern/Eigen3/Eigen/src/Geometry/OrthoMethods.h + ../../extern/Eigen3/Eigen/src/Geometry/ParametrizedLine.h + ../../extern/Eigen3/Eigen/src/Geometry/Quaternion.h + ../../extern/Eigen3/Eigen/src/Geometry/Rotation2D.h + ../../extern/Eigen3/Eigen/src/Geometry/RotationBase.h + ../../extern/Eigen3/Eigen/src/Geometry/Scaling.h + ../../extern/Eigen3/Eigen/src/Geometry/Transform.h + ../../extern/Eigen3/Eigen/src/Geometry/Translation.h + ../../extern/Eigen3/Eigen/src/Geometry/Umeyama.h + ../../extern/Eigen3/Eigen/src/Geometry/arch/Geometry_SSE.h + ../../extern/Eigen3/Eigen/src/Householder/BlockHouseholder.h + ../../extern/Eigen3/Eigen/src/Householder/Householder.h + ../../extern/Eigen3/Eigen/src/Householder/HouseholderSequence.h + ../../extern/Eigen3/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h + ../../extern/Eigen3/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h + ../../extern/Eigen3/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h + ../../extern/Eigen3/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h + ../../extern/Eigen3/Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h + ../../extern/Eigen3/Eigen/src/Jacobi/Jacobi.h + ../../extern/Eigen3/Eigen/src/LU/arch + ../../extern/Eigen3/Eigen/src/LU/Determinant.h + ../../extern/Eigen3/Eigen/src/LU/FullPivLU.h + ../../extern/Eigen3/Eigen/src/LU/Inverse.h + ../../extern/Eigen3/Eigen/src/LU/PartialPivLU.h + ../../extern/Eigen3/Eigen/src/LU/PartialPivLU_MKL.h + ../../extern/Eigen3/Eigen/src/LU/arch/Inverse_SSE.h + ../../extern/Eigen3/Eigen/src/misc/blas.h + ../../extern/Eigen3/Eigen/src/misc/Image.h + ../../extern/Eigen3/Eigen/src/misc/Kernel.h + ../../extern/Eigen3/Eigen/src/misc/Solve.h + ../../extern/Eigen3/Eigen/src/misc/SparseSolve.h + ../../extern/Eigen3/Eigen/src/OrderingMethods/Amd.h + ../../extern/Eigen3/Eigen/src/PardisoSupport/PardisoSupport.h + ../../extern/Eigen3/Eigen/src/PaStiXSupport/PaStiXSupport.h + ../../extern/Eigen3/Eigen/src/plugins/ArrayCwiseBinaryOps.h + ../../extern/Eigen3/Eigen/src/plugins/ArrayCwiseUnaryOps.h + ../../extern/Eigen3/Eigen/src/plugins/BlockMethods.h + ../../extern/Eigen3/Eigen/src/plugins/CommonCwiseBinaryOps.h + ../../extern/Eigen3/Eigen/src/plugins/CommonCwiseUnaryOps.h + ../../extern/Eigen3/Eigen/src/plugins/MatrixCwiseBinaryOps.h + ../../extern/Eigen3/Eigen/src/plugins/MatrixCwiseUnaryOps.h + ../../extern/Eigen3/Eigen/src/QR/ColPivHouseholderQR.h + ../../extern/Eigen3/Eigen/src/QR/ColPivHouseholderQR_MKL.h + ../../extern/Eigen3/Eigen/src/QR/FullPivHouseholderQR.h + ../../extern/Eigen3/Eigen/src/QR/HouseholderQR.h + ../../extern/Eigen3/Eigen/src/QR/HouseholderQR_MKL.h + ../../extern/Eigen3/Eigen/src/SparseCholesky/SimplicialCholesky.h + ../../extern/Eigen3/Eigen/src/SparseCore/AmbiVector.h + ../../extern/Eigen3/Eigen/src/SparseCore/CompressedStorage.h + ../../extern/Eigen3/Eigen/src/SparseCore/ConservativeSparseSparseProduct.h + ../../extern/Eigen3/Eigen/src/SparseCore/CoreIterators.h + ../../extern/Eigen3/Eigen/src/SparseCore/MappedSparseMatrix.h + ../../extern/Eigen3/Eigen/src/SparseCore/SparseAssign.h + ../../extern/Eigen3/Eigen/src/SparseCore/SparseBlock.h + ../../extern/Eigen3/Eigen/src/SparseCore/SparseCwiseBinaryOp.h + ../../extern/Eigen3/Eigen/src/SparseCore/SparseCwiseUnaryOp.h + ../../extern/Eigen3/Eigen/src/SparseCore/SparseDenseProduct.h + ../../extern/Eigen3/Eigen/src/SparseCore/SparseDiagonalProduct.h + ../../extern/Eigen3/Eigen/src/SparseCore/SparseDot.h + ../../extern/Eigen3/Eigen/src/SparseCore/SparseFuzzy.h + ../../extern/Eigen3/Eigen/src/SparseCore/SparseMatrix.h + ../../extern/Eigen3/Eigen/src/SparseCore/SparseMatrixBase.h + ../../extern/Eigen3/Eigen/src/SparseCore/SparsePermutation.h + ../../extern/Eigen3/Eigen/src/SparseCore/SparseProduct.h + ../../extern/Eigen3/Eigen/src/SparseCore/SparseRedux.h + ../../extern/Eigen3/Eigen/src/SparseCore/SparseSelfAdjointView.h + ../../extern/Eigen3/Eigen/src/SparseCore/SparseSparseProductWithPruning.h + ../../extern/Eigen3/Eigen/src/SparseCore/SparseTranspose.h + ../../extern/Eigen3/Eigen/src/SparseCore/SparseTriangularView.h + ../../extern/Eigen3/Eigen/src/SparseCore/SparseUtil.h + ../../extern/Eigen3/Eigen/src/SparseCore/SparseVector.h + ../../extern/Eigen3/Eigen/src/SparseCore/SparseView.h + ../../extern/Eigen3/Eigen/src/SparseCore/TriangularSolver.h + ../../extern/Eigen3/Eigen/src/StlSupport/details.h + ../../extern/Eigen3/Eigen/src/StlSupport/StdDeque.h + ../../extern/Eigen3/Eigen/src/StlSupport/StdList.h + ../../extern/Eigen3/Eigen/src/StlSupport/StdVector.h + ../../extern/Eigen3/Eigen/src/SuperLUSupport/SuperLUSupport.h + ../../extern/Eigen3/Eigen/src/SVD/JacobiSVD.h + ../../extern/Eigen3/Eigen/src/SVD/JacobiSVD_MKL.h + ../../extern/Eigen3/Eigen/src/SVD/UpperBidiagonalization.h + ../../extern/Eigen3/Eigen/src/UmfPackSupport/UmfPackSupport.h ) From d485fdcf34164a47488b000ffa4e3ef203af07a7 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Mon, 15 Oct 2012 17:48:33 +0000 Subject: [PATCH 249/347] Adding new Esperanto language. --- source/blender/blenfont/intern/blf_lang.c | 1 + source/blender/makesrna/intern/rna_userdef.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/source/blender/blenfont/intern/blf_lang.c b/source/blender/blenfont/intern/blf_lang.c index 1a1eff6a48c..ff574a71549 100644 --- a/source/blender/blenfont/intern/blf_lang.c +++ b/source/blender/blenfont/intern/blf_lang.c @@ -110,6 +110,7 @@ static const char *locales[] = { "portuguese-brazilian", "pt_BR", "hebrew", "he_IL", "estonian", "et_EE", + "esperanto", "eo", /* No country code for esperanto! ;) */ }; void BLF_lang_init(void) diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index 98045137c43..a2e3116fe6d 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -2987,7 +2987,7 @@ static void rna_def_userdef_system(BlenderRNA *brna) /* locale according to http://www.roseindia.net/tutorials/I18N/locales-list.shtml */ /* if you edit here, please also edit the source/blender/blenfont/intern/blf_lang.c 's locales */ /* Note: As this list is in alphabetical order, and not defined order, - * here is the highest define currently in use: 34 (Estonian). */ + * here is the highest define currently in use: 35 (Esperanto). */ static EnumPropertyItem language_items[] = { { 0, "", 0, N_("Nearly Done"), ""}, { 0, "DEFAULT", 0, "Default (Default)", ""}, @@ -3010,6 +3010,7 @@ static void rna_def_userdef_system(BlenderRNA *brna) {16, "CROATIAN", 0, "Croatian (Hrvatski)", "hr_HR"}, {11, "CZECH", 0, "Czech (Český)", "cs_CZ"}, { 3, "DUTCH", 0, "Dutch (Nederlandse taal)", "nl_NL"}, + {35, "ESPERANTO", 0, "Esperanto (Esperanto)", "eo"}, {34, "ESTONIAN", 0, "Estonian (Eestlane)", "et_EE"}, { 6, "FINNISH", 0, "Finnish (Suomi)", "fi_FI"}, { 5, "GERMAN", 0, "German (Deutsch)", "de_DE"}, From 45d6eb5dea6d865ff25e807535a5175a920b33fb Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Mon, 15 Oct 2012 17:52:09 +0000 Subject: [PATCH 250/347] Adding Estonian and Esperanto iso codes in allowed non-capitalized UI messages... --- release/scripts/modules/bl_i18n_utils/settings.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/release/scripts/modules/bl_i18n_utils/settings.py b/release/scripts/modules/bl_i18n_utils/settings.py index 6dd53b1fbc5..5db8f9c7c94 100644 --- a/release/scripts/modules/bl_i18n_utils/settings.py +++ b/release/scripts/modules/bl_i18n_utils/settings.py @@ -169,6 +169,8 @@ WARN_MSGID_NOT_CAPITALIZED_ALLOWED = { "uk_UA", "tr_TR", "hu_HU", + "et_EE", + "eo", "available with", # Is part of multi-line msg. "virtual parents", # Is part of multi-line msg. "description", # Addons' field. :/ From c10c6b1cea90fd863f56606adb87ab0261e03140 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 15 Oct 2012 17:56:40 +0000 Subject: [PATCH 251/347] Fix #32844: cycles camera motion blur producing completely blurred frames sometimes. --- intern/cycles/util/util_transform.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/intern/cycles/util/util_transform.h b/intern/cycles/util/util_transform.h index d93bbff5415..3d6aefed56d 100644 --- a/intern/cycles/util/util_transform.h +++ b/intern/cycles/util/util_transform.h @@ -304,10 +304,18 @@ __device_inline float4 quat_interpolate(float4 q1, float4 q2, float t) { float costheta = dot(q1, q2); + /* rotate around shortest angle */ + if(costheta < 0.0f) { + costheta = -costheta; + q1 = -q1; + } + if(costheta > 0.9995f) { + /* linear interpolation in degenerate case */ return normalize((1.0f - t)*q1 + t*q2); } else { + /* slerp */ float theta = acosf(clamp(costheta, -1.0f, 1.0f)); float thetap = theta * t; float4 qperp = normalize(q2 - q1 * costheta); From ff16453866933d5c166f58eeb54bd3bac72b1f16 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 15 Oct 2012 17:56:51 +0000 Subject: [PATCH 252/347] Fix for #32852: set uv unwrap default packing marging to 0.001. --- source/blender/blenkernel/intern/scene.c | 1 + .../blender/editors/uvedit/uvedit_unwrap_ops.c | 17 +++++++++++------ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 96e64f30156..39b404e23d4 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -446,6 +446,7 @@ Scene *BKE_scene_add(const char *name) sce->toolsettings->uvcalc_cubesize = 1.0f; sce->toolsettings->uvcalc_mapdir = 1; sce->toolsettings->uvcalc_mapalign = 1; + sce->toolsettings->uvcalc_margin = 0.001f; sce->toolsettings->unwrapper = 1; sce->toolsettings->select_thresh = 0.01f; sce->toolsettings->jointrilimit = 0.8f; diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c index 26f8641743e..decd94f77c8 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c @@ -729,12 +729,10 @@ static int pack_islands_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - if (RNA_struct_property_is_set(op->ptr, "margin")) { + if (RNA_struct_property_is_set(op->ptr, "margin")) scene->toolsettings->uvcalc_margin = RNA_float_get(op->ptr, "margin"); - } - else { + else RNA_float_set(op->ptr, "margin", scene->toolsettings->uvcalc_margin); - } handle = construct_param_handle(scene, em, implicit, 0, 1, 1); param_pack(handle, scene->toolsettings->uvcalc_margin); @@ -761,7 +759,7 @@ void UV_OT_pack_islands(wmOperatorType *ot) ot->poll = ED_operator_uvedit; /* properties */ - RNA_def_float_factor(ot->srna, "margin", 0.0f, 0.0f, 1.0f, "Margin", "Space between islands", 0.0f, 1.0f); + RNA_def_float_factor(ot->srna, "margin", 0.001f, 0.0f, 1.0f, "Margin", "Space between islands", 0.0f, 1.0f); } /* ******************** Average Islands Scale operator **************** */ @@ -1194,6 +1192,12 @@ static int unwrap_exec(bContext *C, wmOperator *op) else RNA_enum_set(op->ptr, "method", scene->toolsettings->unwrapper); + /* remember packing marging */ + if (RNA_struct_property_is_set(op->ptr, "margin")) + scene->toolsettings->uvcalc_margin = RNA_float_get(op->ptr, "margin"); + else + RNA_float_set(op->ptr, "margin", scene->toolsettings->uvcalc_margin); + scene->toolsettings->uv_subsurf_level = subsurf_level; if (fill_holes) scene->toolsettings->uvcalc_flag |= UVCALC_FILLHOLES; @@ -1241,8 +1245,9 @@ void UV_OT_unwrap(wmOperatorType *ot) "Map UVs taking image aspect ratio into account"); RNA_def_boolean(ot->srna, "use_subsurf_data", 0, "Use Subsurf Data", "Map UVs taking vertex position after subsurf into account"); - RNA_def_int(ot->srna, "uv_subsurf_level", 1, 1, 6, "SubSurf Target", + RNA_def_int(ot->srna, "uv_subsurf_level", 1, 1, 6, "Subsurf Target", "Number of times to subdivide before calculating UVs", 1, 6); + RNA_def_float_factor(ot->srna, "margin", 0.001f, 0.0f, 1.0f, "Margin", "Space between islands", 0.0f, 1.0f); } /**************** Project From View operator **************/ From fe47ae525de03bd6ebb1344e3d9c3d363960c8c8 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 15 Oct 2012 17:56:53 +0000 Subject: [PATCH 253/347] Cycles: tweak progressive refine tooltip to make it more clear --- intern/cycles/blender/addon/properties.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index f2a88f0d96c..f83a3996167 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -286,7 +286,7 @@ class CyclesRenderSettings(bpy.types.PropertyGroup): ) cls.use_progressive_refine = BoolProperty( name="Progressive Refine", - description="Instead of rendering each tile until it is finished, refine the whole image progressively so rendering can be stopped manually when the noise is low enough", + description="Instead of rendering each tile until it is finished, refine the whole image progressively. This renders somewhat slower, but time can be saved by manually stopping the render when the noise is low enough.", default=False, ) From 8a25e2d2b2214db32b1a337253f337b63eafdef3 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Mon, 15 Oct 2012 19:57:18 +0000 Subject: [PATCH 254/347] Smoke: Merge parts of Smoke2 branch New: ---------- Collision objects do cause vorticity when passing through smoke Part of my Smoke Development Project (milestone III) --- intern/smoke/intern/FLUID_3D.cpp | 78 ++++++++++++++++++++++++-------- 1 file changed, 58 insertions(+), 20 deletions(-) diff --git a/intern/smoke/intern/FLUID_3D.cpp b/intern/smoke/intern/FLUID_3D.cpp index b7b353352e2..4f8fa0710a0 100644 --- a/intern/smoke/intern/FLUID_3D.cpp +++ b/intern/smoke/intern/FLUID_3D.cpp @@ -1326,9 +1326,13 @@ void FLUID_3D::addBuoyancy(float *heat, float *density, float gravity[3], int zB } } + ////////////////////////////////////////////////////////////////////// // add vorticity to the force field ////////////////////////////////////////////////////////////////////// +#define VORT_VEL(i, j) \ + ((_obstacles[obpos[(i)]] & 8) ? ((abs(objvelocity[(j)][obpos[(i)]]) > FLT_EPSILON) ? objvelocity[(j)][obpos[(i)]] : velocity[(j)][index]) : velocity[(j)][obpos[(i)]]) + void FLUID_3D::addVorticity(int zBegin, int zEnd) { // set flame vorticity from RNA value @@ -1366,9 +1370,18 @@ void FLUID_3D::addVorticity(int zBegin, int zEnd) float gridSize = 0.5f / _dx; //index = _slabSize + _xRes + 1; + float *velocity[3]; + float *objvelocity[3]; + + velocity[0] = _xVelocity; + velocity[1] = _yVelocity; + velocity[2] = _zVelocity; + + objvelocity[0] = _xVelocityOb; + objvelocity[1] = _yVelocityOb; + objvelocity[2] = _zVelocityOb; size_t vIndex=_xRes + 1; - for (int z = zBegin + bb1; z < (zEnd - bt1); z++) { size_t index = index_ +(z-1)*_slabSize; @@ -1378,25 +1391,47 @@ void FLUID_3D::addVorticity(int zBegin, int zEnd) { for (int x = 1; x < _xRes - 1; x++, index++) { + if (!_obstacles[index]) + { + int obpos[6]; - int up = _obstacles[index + _xRes] ? index : index + _xRes; - int down = _obstacles[index - _xRes] ? index : index - _xRes; - float dy = (up == index || down == index) ? 1.0f / _dx : gridSize; - int out = _obstacles[index + _slabSize] ? index : index + _slabSize; - int in = _obstacles[index - _slabSize] ? index : index - _slabSize; - float dz = (out == index || in == index) ? 1.0f / _dx : gridSize; - int right = _obstacles[index + 1] ? index : index + 1; - int left = _obstacles[index - 1] ? index : index - 1; - float dx = (right == index || left == index) ? 1.0f / _dx : gridSize; + obpos[0] = (_obstacles[index + _xRes] == 1) ? index : index + _xRes; // up + obpos[1] = (_obstacles[index - _xRes] == 1) ? index : index - _xRes; // down + float dy = (obpos[0] == index || obpos[1] == index) ? 1.0f / _dx : gridSize; - _xVorticity[vIndex] = (_zVelocity[up] - _zVelocity[down]) * dy + (-_yVelocity[out] + _yVelocity[in]) * dz; - _yVorticity[vIndex] = (_xVelocity[out] - _xVelocity[in]) * dz + (-_zVelocity[right] + _zVelocity[left]) * dx; - _zVorticity[vIndex] = (_yVelocity[right] - _yVelocity[left]) * dx + (-_xVelocity[up] + _xVelocity[down])* dy; + obpos[2] = (_obstacles[index + _slabSize] == 1) ? index : index + _slabSize; // out + obpos[3] = (_obstacles[index - _slabSize] == 1) ? index : index - _slabSize; // in + float dz = (obpos[2] == index || obpos[3] == index) ? 1.0f / _dx : gridSize; - _vorticity[vIndex] = sqrtf(_xVorticity[vIndex] * _xVorticity[vIndex] + + obpos[4] = (_obstacles[index + 1] == 1) ? index : index + 1; // right + obpos[5] = (_obstacles[index - 1] == 1) ? index : index - 1; // left + float dx = (obpos[4] == index || obpos[5] == index) ? 1.0f / _dx : gridSize; + + float xV[2], yV[2], zV[2]; + + zV[1] = VORT_VEL(0, 2); + zV[0] = VORT_VEL(1, 2); + yV[1] = VORT_VEL(2, 1); + yV[0] = VORT_VEL(3, 1); + _xVorticity[vIndex] = (zV[1] - zV[0]) * dy + (-yV[1] + yV[0]) * dz; + + xV[1] = VORT_VEL(2, 0); + xV[0] = VORT_VEL(3, 0); + zV[1] = VORT_VEL(4, 2); + zV[0] = VORT_VEL(5, 2); + _yVorticity[vIndex] = (xV[1] - xV[0]) * dz + (-zV[1] + zV[0]) * dx; + + yV[1] = VORT_VEL(4, 1); + yV[0] = VORT_VEL(5, 1); + xV[1] = VORT_VEL(0, 0); + xV[0] = VORT_VEL(1, 0); + _zVorticity[vIndex] = (yV[1] - yV[0]) * dx + (-xV[1] + xV[0])* dy; + + _vorticity[vIndex] = sqrtf(_xVorticity[vIndex] * _xVorticity[vIndex] + _yVorticity[vIndex] * _yVorticity[vIndex] + _zVorticity[vIndex] * _zVorticity[vIndex]); + } vIndex++; } vIndex+=2; @@ -1425,15 +1460,18 @@ void FLUID_3D::addVorticity(int zBegin, int zEnd) { float N[3]; - int up = _obstacles[index + _xRes] ? vIndex : vIndex + _xRes; - int down = _obstacles[index - _xRes] ? vIndex : vIndex - _xRes; + int up = (_obstacles[index + _xRes] == 1) ? vIndex : vIndex + _xRes; + int down = (_obstacles[index - _xRes] == 1) ? vIndex : vIndex - _xRes; float dy = (up == vIndex || down == vIndex) ? 1.0f / _dx : gridSize; - int out = _obstacles[index + _slabSize] ? vIndex : vIndex + _slabSize; - int in = _obstacles[index - _slabSize] ? vIndex : vIndex - _slabSize; + + int out = (_obstacles[index + _slabSize] == 1) ? vIndex : vIndex + _slabSize; + int in = (_obstacles[index - _slabSize] == 1) ? vIndex : vIndex - _slabSize; float dz = (out == vIndex || in == vIndex) ? 1.0f / _dx : gridSize; - int right = _obstacles[index + 1] ? vIndex : vIndex + 1; - int left = _obstacles[index - 1] ? vIndex : vIndex - 1; + + int right = (_obstacles[index + 1] == 1) ? vIndex : vIndex + 1; + int left = (_obstacles[index - 1] == 1) ? vIndex : vIndex - 1; float dx = (right == vIndex || left == vIndex) ? 1.0f / _dx : gridSize; + N[0] = (_vorticity[right] - _vorticity[left]) * dx; N[1] = (_vorticity[up] - _vorticity[down]) * dy; N[2] = (_vorticity[out] - _vorticity[in]) * dz; From fe16b2620646708bae3286b9c1300eacbc4bc0da Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 15 Oct 2012 21:12:58 +0000 Subject: [PATCH 255/347] Cycles: fix some update issues with camera motion blur, and do some more work for getting object motion blur ready. --- intern/cycles/blender/blender_object.cpp | 6 + intern/cycles/blender/blender_sync.cpp | 6 + intern/cycles/kernel/CMakeLists.txt | 2 - intern/cycles/kernel/kernel_bvh.h | 172 +++++++- intern/cycles/kernel/kernel_light.h | 9 +- intern/cycles/kernel/kernel_mbvh.h | 394 ----------------- intern/cycles/kernel/kernel_object.h | 86 ++-- intern/cycles/kernel/kernel_qbvh.h | 413 ------------------ intern/cycles/kernel/kernel_shader.h | 36 +- intern/cycles/kernel/kernel_triangle.h | 4 +- intern/cycles/kernel/kernel_types.h | 18 +- intern/cycles/render/camera.cpp | 12 +- intern/cycles/render/camera.h | 1 + intern/cycles/render/mesh.cpp | 3 +- intern/cycles/render/object.cpp | 9 +- intern/cycles/render/scene.cpp | 4 +- intern/cycles/render/scene.h | 2 +- source/blender/editors/render/render_update.c | 9 + source/blender/makesrna/intern/rna_scene.c | 6 +- 19 files changed, 301 insertions(+), 891 deletions(-) delete mode 100644 intern/cycles/kernel/kernel_mbvh.h delete mode 100644 intern/cycles/kernel/kernel_qbvh.h diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp index 3d74c57288b..e10ffb3cf98 100644 --- a/intern/cycles/blender/blender_object.cpp +++ b/intern/cycles/blender/blender_object.cpp @@ -396,6 +396,8 @@ void BlenderSync::sync_motion(BL::SpaceView3D b_v3d, BL::Object b_override) if(b_override) b_cam = b_override; + Camera prevcam = *(scene->camera); + /* go back and forth one frame */ int frame = b_scene.frame_current(); @@ -411,6 +413,10 @@ void BlenderSync::sync_motion(BL::SpaceView3D b_v3d, BL::Object b_override) } scene_frame_set(b_scene, frame); + + /* tag camera for motion update */ + if(scene->camera->motion_modified(prevcam)) + scene->camera->tag_update(); } CCL_NAMESPACE_END diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp index 00130f357dd..6c63872333d 100644 --- a/intern/cycles/blender/blender_sync.cpp +++ b/intern/cycles/blender/blender_sync.cpp @@ -17,6 +17,7 @@ */ #include "background.h" +#include "camera.h" #include "film.h" #include "../render/filter.h" #include "graph.h" @@ -179,6 +180,11 @@ void BlenderSync::sync_integrator() integrator->sample_clamp = get_float(cscene, "sample_clamp"); #ifdef __CAMERA_MOTION__ + if(integrator->motion_blur != r.use_motion_blur()) { + scene->object_manager->tag_update(scene); + scene->camera->tag_update(); + } + integrator->motion_blur = (!preview && r.use_motion_blur()); #endif diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt index df8a9b1d5b4..ad1ce1df295 100644 --- a/intern/cycles/kernel/CMakeLists.txt +++ b/intern/cycles/kernel/CMakeLists.txt @@ -31,13 +31,11 @@ set(SRC_HEADERS kernel_globals.h kernel_light.h kernel_math.h - kernel_mbvh.h kernel_montecarlo.h kernel_object.h kernel_passes.h kernel_path.h kernel_projection.h - kernel_qbvh.h kernel_random.h kernel_shader.h kernel_textures.h diff --git a/intern/cycles/kernel/kernel_bvh.h b/intern/cycles/kernel/kernel_bvh.h index 90aec2e46b3..9d8ad6f3072 100644 --- a/intern/cycles/kernel/kernel_bvh.h +++ b/intern/cycles/kernel/kernel_bvh.h @@ -57,7 +57,7 @@ __device_inline float3 bvh_inverse_direction(float3 dir) __device_inline void bvh_instance_push(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *idir, float *t, const float tmax) { - Transform tfm = object_fetch_transform(kg, object, ray->time, OBJECT_INVERSE_TRANSFORM); + Transform tfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM); *P = transform_point(&tfm, ray->P); @@ -75,7 +75,7 @@ __device_inline void bvh_instance_push(KernelGlobals *kg, int object, const Ray __device_inline void bvh_instance_pop(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *idir, float *t, const float tmax) { if(*t != FLT_MAX) { - Transform tfm = object_fetch_transform(kg, object, ray->time, OBJECT_TRANSFORM); + Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM); *t *= len(transform_direction(&tfm, 1.0f/(*idir))); } @@ -83,6 +83,36 @@ __device_inline void bvh_instance_pop(KernelGlobals *kg, int object, const Ray * *idir = bvh_inverse_direction(ray->D); } +#ifdef __OBJECT_MOTION__ +__device_inline void bvh_instance_motion_push(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *idir, float *t, Transform *tfm, const float tmax) +{ + Transform itfm; + *tfm = object_fetch_transform_motion(kg, object, ray->time, &itfm); + + *P = transform_point(&itfm, ray->P); + + float3 dir = transform_direction(&itfm, ray->D); + + float len; + dir = normalize_len(dir, &len); + + *idir = bvh_inverse_direction(dir); + + if(*t != FLT_MAX) + *t *= len; +} + +__device_inline void bvh_instance_motion_pop(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *idir, float *t, Transform *tfm, const float tmax) +{ + if(*t != FLT_MAX) { + *t *= len(transform_direction(tfm, 1.0f/(*idir))); + } + + *P = ray->P; + *idir = bvh_inverse_direction(ray->D); +} +#endif + /* intersect two bounding boxes */ __device_inline void bvh_node_intersect(KernelGlobals *kg, bool *traverseChild0, bool *traverseChild1, @@ -133,7 +163,7 @@ __device_inline void bvh_node_intersect(KernelGlobals *kg, /* Sven Woop's algorithm */ __device_inline void bvh_triangle_intersect(KernelGlobals *kg, Intersection *isect, - float3 P, float3 idir, uint visibility, int object, int triAddr) + float3 P, float3 idir, uint visibility, int object, int triAddr, Transform *tfm) { /* compute and check intersection t-value */ float4 v00 = kernel_tex_fetch(__tri_woop, triAddr*TRI_NODE_SIZE+0); @@ -176,7 +206,7 @@ __device_inline void bvh_triangle_intersect(KernelGlobals *kg, Intersection *ise } } -__device_inline bool scene_intersect(KernelGlobals *kg, const Ray *ray, const uint visibility, Intersection *isect) +__device_inline bool bvh_intersect(KernelGlobals *kg, const Ray *ray, const uint visibility, Intersection *isect) { /* traversal stack in CUDA thread-local memory */ int traversalStack[BVH_STACK_SIZE]; @@ -255,7 +285,7 @@ __device_inline bool scene_intersect(KernelGlobals *kg, const Ray *ray, const ui /* triangle intersection */ while(primAddr < primAddr2) { /* intersect ray against triangle */ - bvh_triangle_intersect(kg, isect, P, idir, visibility, object, primAddr); + bvh_triangle_intersect(kg, isect, P, idir, visibility, object, primAddr, NULL); /* shadow ray early termination */ if(visibility == PATH_RAY_SHADOW_OPAQUE && isect->prim != ~0) @@ -268,7 +298,6 @@ __device_inline bool scene_intersect(KernelGlobals *kg, const Ray *ray, const ui else { /* instance push */ object = kernel_tex_fetch(__prim_object, -primAddr-1); - bvh_instance_push(kg, object, ray, &P, &idir, &isect->t, tmax); ++stackPtr; @@ -296,6 +325,133 @@ __device_inline bool scene_intersect(KernelGlobals *kg, const Ray *ray, const ui return (isect->prim != ~0); } +#ifdef __OBJECT_MOTION__ +__device_inline bool bvh_intersect_motion(KernelGlobals *kg, const Ray *ray, const uint visibility, Intersection *isect) +{ + /* traversal stack in CUDA thread-local memory */ + int traversalStack[BVH_STACK_SIZE]; + traversalStack[0] = ENTRYPOINT_SENTINEL; + + /* traversal variables in registers */ + int stackPtr = 0; + int nodeAddr = kernel_data.bvh.root; + + /* ray parameters in registers */ + const float tmax = ray->t; + float3 P = ray->P; + float3 idir = bvh_inverse_direction(ray->D); + int object = ~0; + + Transform ob_tfm; + + isect->t = tmax; + isect->object = ~0; + isect->prim = ~0; + isect->u = 0.0f; + isect->v = 0.0f; + + /* traversal loop */ + do { + do + { + /* traverse internal nodes */ + while(nodeAddr >= 0 && nodeAddr != ENTRYPOINT_SENTINEL) + { + bool traverseChild0, traverseChild1, closestChild1; + int nodeAddrChild1; + + bvh_node_intersect(kg, &traverseChild0, &traverseChild1, + &closestChild1, &nodeAddr, &nodeAddrChild1, + P, idir, isect->t, visibility, nodeAddr); + + if(traverseChild0 != traverseChild1) { + /* one child was intersected */ + if(traverseChild1) { + nodeAddr = nodeAddrChild1; + } + } + else { + if(!traverseChild0) { + /* neither child was intersected */ + nodeAddr = traversalStack[stackPtr]; + --stackPtr; + } + else { + /* both children were intersected, push the farther one */ + if(closestChild1) { + int tmp = nodeAddr; + nodeAddr = nodeAddrChild1; + nodeAddrChild1 = tmp; + } + + ++stackPtr; + traversalStack[stackPtr] = nodeAddrChild1; + } + } + } + + /* if node is leaf, fetch triangle list */ + if(nodeAddr < 0) { + float4 leaf = kernel_tex_fetch(__bvh_nodes, (-nodeAddr-1)*BVH_NODE_SIZE+(BVH_NODE_SIZE-1)); + int primAddr = __float_as_int(leaf.x); + + if(primAddr >= 0) { + int primAddr2 = __float_as_int(leaf.y); + + /* pop */ + nodeAddr = traversalStack[stackPtr]; + --stackPtr; + + /* triangle intersection */ + while(primAddr < primAddr2) { + /* intersect ray against triangle */ + bvh_triangle_intersect(kg, isect, P, idir, visibility, object, primAddr, &ob_tfm); + + /* shadow ray early termination */ + if(visibility == PATH_RAY_SHADOW_OPAQUE && isect->prim != ~0) + return true; + + primAddr++; + } + } + else { + /* instance push */ + object = kernel_tex_fetch(__prim_object, -primAddr-1); + bvh_instance_motion_push(kg, object, ray, &P, &idir, &isect->t, &ob_tfm, tmax); + + ++stackPtr; + traversalStack[stackPtr] = ENTRYPOINT_SENTINEL; + + nodeAddr = kernel_tex_fetch(__object_node, object); + } + } + } while(nodeAddr != ENTRYPOINT_SENTINEL); + + if(stackPtr >= 0) { + kernel_assert(object != ~0); + + /* instance pop */ + bvh_instance_motion_pop(kg, object, ray, &P, &idir, &isect->t, &ob_tfm, tmax); + object = ~0; + nodeAddr = traversalStack[stackPtr]; + --stackPtr; + } + } while(nodeAddr != ENTRYPOINT_SENTINEL); + + return (isect->prim != ~0); +} +#endif + +__device_inline bool scene_intersect(KernelGlobals *kg, const Ray *ray, const uint visibility, Intersection *isect) +{ +#ifdef __OBJECT_MOTION__ + if(kernel_data.bvh.have_motion) + return bvh_intersect_motion(kg, ray, visibility, isect); + else +#endif + return bvh_intersect(kg, ray, visibility, isect); +} + __device_inline float3 ray_offset(float3 P, float3 Ng) { #ifdef __INTERSECTION_REFINE__ @@ -352,7 +508,7 @@ __device_inline float3 bvh_triangle_refine(KernelGlobals *kg, ShaderData *sd, co #ifdef __OBJECT_MOTION__ Transform tfm = sd->ob_itfm; #else - Transform tfm = object_fetch_transform(kg, isect->object, ray->time, OBJECT_INVERSE_TRANSFORM); + Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_INVERSE_TRANSFORM); #endif P = transform_point(&tfm, P); @@ -373,7 +529,7 @@ __device_inline float3 bvh_triangle_refine(KernelGlobals *kg, ShaderData *sd, co #ifdef __OBJECT_MOTION__ Transform tfm = sd->ob_tfm; #else - Transform tfm = object_fetch_transform(kg, isect->object, ray->time, OBJECT_TRANSFORM); + Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_TRANSFORM); #endif P = transform_point(&tfm, P); diff --git a/intern/cycles/kernel/kernel_light.h b/intern/cycles/kernel/kernel_light.h index 1084415d0cf..4bb17c0bd5a 100644 --- a/intern/cycles/kernel/kernel_light.h +++ b/intern/cycles/kernel/kernel_light.h @@ -301,8 +301,13 @@ __device void triangle_light_sample(KernelGlobals *kg, int prim, int object, #ifdef __INSTANCING__ /* instance transform */ if(ls->object >= 0) { - Transform tfm = object_fetch_transform(kg, ls->object, time, OBJECT_TRANSFORM); - Transform itfm = object_fetch_transform(kg, ls->object, time, OBJECT_INVERSE_TRANSFORM); +#ifdef __OBJECT_MOTION__ + Transform itfm; + Transform tfm = object_fetch_transform_motion(kg, ls->object, time, &itfm); +#else + Transform tfm = object_fetch_transform(kg, ls->object, OBJECT_TRANSFORM); + Transform itfm = object_fetch_transform(kg, ls->object, OBJECT_INVERSE_TRANSFORM); +#endif ls->P = transform_point(&tfm, ls->P); ls->Ng = normalize(transform_direction_transposed(&itfm, ls->Ng)); diff --git a/intern/cycles/kernel/kernel_mbvh.h b/intern/cycles/kernel/kernel_mbvh.h deleted file mode 100644 index ccbd3d069b4..00000000000 --- a/intern/cycles/kernel/kernel_mbvh.h +++ /dev/null @@ -1,394 +0,0 @@ -/* - * Copyright 2011, Blender Foundation. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -CCL_NAMESPACE_BEGIN - -#define MBVH_OBJECT_SENTINEL 0x76543210 -#define MBVH_NODE_SIZE 8 -#define MBVH_STACK_SIZE 1024 -#define MBVH_RAY_STACK_SIZE 10000 - -typedef struct MBVHTask { - int node; - int index; - int num; - int object; -} MBVHTask; - -typedef struct MVBHRay { - float3 P; - float u; - float3 idir; - float v; - float t; - int index; - int object; - - float3 origP; - float3 origD; - float tmax; -} MBVHRay; - -__device float3 mbvh_inverse_direction(float3 dir) -{ - // Avoid divide by zero (ooeps = exp2f(-80.0f)) - float ooeps = 0.00000000000000000000000082718061255302767487140869206996285356581211090087890625f; - float3 idir; - - idir.x = 1.0f / (fabsf(dir.x) > ooeps ? dir.x : copysignf(ooeps, dir.x)); - idir.y = 1.0f / (fabsf(dir.y) > ooeps ? dir.y : copysignf(ooeps, dir.y)); - idir.z = 1.0f / (fabsf(dir.z) > ooeps ? dir.z : copysignf(ooeps, dir.z)); - - return idir; -} - -__device void mbvh_instance_push(KernelGlobals *kg, int object, MBVHRay *ray) -{ - Transform tfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM); - - ray->P = transform_point(&tfm, ray->origP); - - float3 dir = ray->origD; - - if(ray->t != ray->tmax) dir *= ray->t; - - dir = transform_direction(&tfm, dir); - ray->idir = mbvh_inverse_direction(normalize(dir)); - - if(ray->t != ray->tmax) ray->t = len(dir); -} - -__device void mbvh_instance_pop(KernelGlobals *kg, int object, MBVHRay *ray) -{ - Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM); - - if(ray->t != ray->tmax) - ray->t = len(transform_direction(&tfm, (1.0f/(ray->idir)) * (ray->t))); - - ray->P = ray->origP; - ray->idir = mbvh_inverse_direction(ray->origD); -} - -/* Sven Woop's algorithm */ -__device void mbvh_triangle_intersect(KernelGlobals *kg, MBVHRay *ray, int object, int triAddr) -{ - float3 P = ray->P; - float3 idir = ray->idir; - - /* compute and check intersection t-value */ - float4 v00 = kernel_tex_fetch(__tri_woop, triAddr*MBVH_NODE_SIZE+0); - float4 v11 = kernel_tex_fetch(__tri_woop, triAddr*MBVH_NODE_SIZE+1); - float3 dir = 1.0f/idir; - - float Oz = v00.w - P.x*v00.x - P.y*v00.y - P.z*v00.z; - float invDz = 1.0f/(dir.x*v00.x + dir.y*v00.y + dir.z*v00.z); - float t = Oz * invDz; - - if(t > 0.0f && t < ray->t) { - /* compute and check barycentric u */ - float Ox = v11.w + P.x*v11.x + P.y*v11.y + P.z*v11.z; - float Dx = dir.x*v11.x + dir.y*v11.y + dir.z*v11.z; - float u = Ox + t*Dx; - - if(u >= 0.0f) { - /* compute and check barycentric v */ - float4 v22 = kernel_tex_fetch(__tri_woop, triAddr*MBVH_NODE_SIZE+2); - float Oy = v22.w + P.x*v22.x + P.y*v22.y + P.z*v22.z; - float Dy = dir.x*v22.x + dir.y*v22.y + dir.z*v22.z; - float v = Oy + t*Dy; - - if(v >= 0.0f && u + v <= 1.0f) { - /* record intersection */ - ray->index = triAddr; - ray->object = object; - ray->u = u; - ray->v = v; - ray->t = t; - } - } - } -} - -__device void mbvh_node_intersect(KernelGlobals *kg, __m128 *traverseChild, - __m128 *tHit, float3 P, float3 idir, float t, int nodeAddr) -{ - /* X axis */ - const __m128 bminx = kernel_tex_fetch_m128(__bvh_nodes, nodeAddr*MBVH_NODE_SIZE+0); - const __m128 t0x = _mm_mul_ps(_mm_sub_ps(bminx, _mm_set_ps1(P.x)), _mm_set_ps1(idir.x)); - const __m128 bmaxx = kernel_tex_fetch_m128(__bvh_nodes, nodeAddr*MBVH_NODE_SIZE+1); - const __m128 t1x = _mm_mul_ps(_mm_sub_ps(bmaxx, _mm_set_ps1(P.x)), _mm_set_ps1(idir.x)); - - __m128 tmin = _mm_max_ps(_mm_min_ps(t0x, t1x), _mm_setzero_ps()); - __m128 tmax = _mm_min_ps(_mm_max_ps(t0x, t1x), _mm_set_ps1(t)); - - /* Y axis */ - const __m128 bminy = kernel_tex_fetch_m128(__bvh_nodes, nodeAddr*MBVH_NODE_SIZE+2); - const __m128 t0y = _mm_mul_ps(_mm_sub_ps(bminy, _mm_set_ps1(P.y)), _mm_set_ps1(idir.y)); - const __m128 bmaxy = kernel_tex_fetch_m128(__bvh_nodes, nodeAddr*MBVH_NODE_SIZE+3); - const __m128 t1y = _mm_mul_ps(_mm_sub_ps(bmaxy, _mm_set_ps1(P.y)), _mm_set_ps1(idir.y)); - - tmin = _mm_max_ps(_mm_min_ps(t0y, t1y), tmin); - tmax = _mm_min_ps(_mm_max_ps(t0y, t1y), tmax); - - /* Z axis */ - const __m128 bminz = kernel_tex_fetch_m128(__bvh_nodes, nodeAddr*MBVH_NODE_SIZE+4); - const __m128 t0z = _mm_mul_ps(_mm_sub_ps(bminz, _mm_set_ps1(P.z)), _mm_set_ps1(idir.z)); - const __m128 bmaxz = kernel_tex_fetch_m128(__bvh_nodes, nodeAddr*MBVH_NODE_SIZE+5); - const __m128 t1z = _mm_mul_ps(_mm_sub_ps(bmaxz, _mm_set_ps1(P.z)), _mm_set_ps1(idir.z)); - - tmin = _mm_max_ps(_mm_min_ps(t0z, t1z), tmin); - tmax = _mm_min_ps(_mm_max_ps(t0z, t1z), tmax); - - /* compare and get mask */ - *traverseChild = _mm_cmple_ps(tmin, tmax); - - /* get distance XXX probably wrong */ - *tHit = tmin; -} - -static void mbvh_sort_by_length(int id[4], float len[4]) -{ - for(int i = 1; i < 4; i++) { - int j = i - 1; - - while(j >= 0 && len[j] > len[j+1]) { - swap(len[j], len[j+1]); - swap(id[j], id[j+1]); - j--; - } - } -} - -__device void scene_intersect(KernelGlobals *kg, MBVHRay *rays, int numrays) -{ - /* traversal stacks */ - MBVHTask task_stack[MBVH_STACK_SIZE]; - int active_ray_stacks[4][MBVH_RAY_STACK_SIZE]; - int num_task, num_active[4] = {0, 0, 0, 0}; - __m128i one_mm = _mm_set1_epi32(1); - - /* push root node task on stack */ - task_stack[0].node = kernel_data.bvh.root; - task_stack[0].index = 0; - task_stack[0].num = numrays; - task_stack[0].object = ~0; - num_task = 1; - - /* push all rays in first SIMD lane */ - for(int i = 0; i < numrays; i++) - active_ray_stacks[0][i] = i; - num_active[0] = numrays; - - while(num_task >= 1) { - /* pop task */ - MBVHTask task = task_stack[--num_task]; - - if(task.node == MBVH_OBJECT_SENTINEL) { - /* instance pop */ - - /* pop rays from stack */ - num_active[task.index] -= task.num; - int ray_offset = num_active[task.index]; - - /* transform rays */ - for(int i = 0; i < task.num; i++) { - MBVHRay *ray = &rays[active_ray_stacks[task.index][ray_offset + i]]; - mbvh_instance_pop(kg, task.object, ray); - } - } - else if(task.node >= 0) { - /* inner node? */ - - /* pop rays from stack*/ - num_active[task.index] -= task.num; - int ray_offset = num_active[task.index]; - - /* initialze simd values */ - __m128i num_active_mm = _mm_load_si128((__m128i*)num_active); - __m128 len_mm = _mm_set_ps1(0.0f); - - for(int i = 0; i < task.num; i++) { - int rayid = active_ray_stacks[task.index][ray_offset + i]; - MVBHRay *ray = rays + rayid; - - /* intersect 4 QBVH node children */ - __m128 result; - __m128 thit; - - mbvh_node_intersect(kg, &result, &thit, ray->P, ray->idir, ray->t, task.node); - - /* update length for sorting */ - len_mm = _mm_add_ps(len_mm, _mm_and_ps(thit, result)); - - /* push rays on stack */ - for(int j = 0; j < 4; j++) - active_ray_stacks[j][num_active[j]] = rayid; - - /* update num active */ - __m128i resulti = _mm_and_si128(*((__m128i*)&result), one_mm); - num_active_mm = _mm_add_epi32(resulti, num_active_mm); - _mm_store_si128((__m128i*)num_active, num_active_mm); - } - - if(num_active[0] || num_active[1] || num_active[2] || num_active[3]) { - /* load child node addresses */ - float4 cnodes = kernel_tex_fetch(__bvh_nodes, task.node); - int child[4] = { - __float_as_int(cnodes.x), - __float_as_int(cnodes.y), - __float_as_int(cnodes.z), - __float_as_int(cnodes.w)}; - - /* sort nodes by average intersection distance */ - int ids[4] = {0, 1, 2, 3}; - float len[4]; - - _mm_store_ps(len, len_mm); - mbvh_sort_by_length(ids, len); - - /* push new tasks on stack */ - for(int j = 0; j < 4; j++) { - if(num_active[j]) { - int id = ids[j]; - - task_stack[num_task].node = child[id]; - task_stack[num_task].index = id; - task_stack[num_task].num = num_active[id]; - task_stack[num_task].object = task.object; - num_task++; - } - } - } - } - else { - /* fetch leaf node data */ - float4 leaf = kernel_tex_fetch(__bvh_nodes, (-task.node-1)*MBVH_NODE_SIZE+(MBVH_NODE_SIZE-2)); - int triAddr = __float_as_int(leaf.x); - int triAddr2 = __float_as_int(leaf.y); - - /* pop rays from stack*/ - num_active[task.index] -= task.num; - int ray_offset = num_active[task.index]; - - /* triangles */ - if(triAddr >= 0) { - int i, numq = (task.num >> 2) << 2; - - /* SIMD ray leaf intersection */ - for(i = 0; i < numq; i += 4) { - MBVHRay *ray4[4] = { - &rays[active_ray_stacks[task.index][ray_offset + i + 0]], - &rays[active_ray_stacks[task.index][ray_offset + i + 1]], - &rays[active_ray_stacks[task.index][ray_offset + i + 2]], - &rays[active_ray_stacks[task.index][ray_offset + i + 3]]}; - - /* load SoA */ - - while(triAddr < triAddr2) { - mbvh_triangle_intersect(ray4[0], task.object, task.node); - mbvh_triangle_intersect(ray4[1], task.object, task.node); - mbvh_triangle_intersect(ray4[2], task.object, task.node); - mbvh_triangle_intersect(ray4[3], task.object, task.node); - triAddr++; - - /* some shadow ray optim could be done by setting t=0 */ - } - - /* store AoS */ - } - - /* mono ray leaf intersection */ - for(; i < task.num; i++) { - MBVHRay *ray = &rays[active_ray_stacks[task.index][ray_offset + i]]; - - while(triAddr < triAddr2) { - mbvh_triangle_intersect(kg, ray, task.object, task.node); - triAddr++; - } - } - } - else { - /* instance push */ - int object = -triAddr-1; - int node = triAddr; - - /* push instance pop task */ - task_stack[num_task].node = MBVH_OBJECT_SENTINEL; - task_stack[num_task].index = task.index; - task_stack[num_task].num = task.num; - task_stack[num_task].object = object; - num_task++; - - num_active[task.index] += task.num; - - /* push node task */ - task_stack[num_task].node = node; - task_stack[num_task].index = task.index; - task_stack[num_task].num = task.num; - task_stack[num_task].object = object; - num_task++; - - for(int i = 0; i < task.num; i++) { - int rayid = active_ray_stacks[task.index][ray_offset + i]; - - /* push on stack for last task */ - active_ray_stacks[task.index][num_active[task.index]] = rayid; - num_active[task.index]++; - - /* transform ray */ - MBVHRay *ray = &rays[rayid]; - mbvh_instance_push(kg, object, ray); - } - } - } - } -} - -__device void mbvh_set_ray(MBVHRay *rays, int i, Ray *ray, float tmax) -{ - MBVHRay *mray = &rays[i]; - - /* ray parameters in registers */ - mray->P = ray->P; - mray->idir = mbvh_inverse_direction(ray->D); - mray->t = tmax; -} - -__device bool mbvh_get_intersection(MVBHRay *rays, int i, Intersection *isect, float tmax) -{ - MBVHRay *mray = &rays[i]; - - if(mray->t == tmax) - return false; - - isect->t = mray->t; - isect->u = mray->u; - isect->v = mray->v; - isect->index = mray->index; - isect->object = mray->object; - - return true; -} - -__device bool mbvh_get_shadow(MBVHRay *rays, int i, float tmax) -{ - return (rays[i].t == tmax); -} - -CCL_NAMESPACE_END - diff --git a/intern/cycles/kernel/kernel_object.h b/intern/cycles/kernel/kernel_object.h index ad43120146a..d8ea2cf9926 100644 --- a/intern/cycles/kernel/kernel_object.h +++ b/intern/cycles/kernel/kernel_object.h @@ -27,39 +27,11 @@ enum ObjectTransform { OBJECT_DUPLI = 16 }; -__device_inline Transform object_fetch_transform(KernelGlobals *kg, int object, float time, enum ObjectTransform type) +__device_inline Transform object_fetch_transform(KernelGlobals *kg, int object, enum ObjectTransform type) { - Transform tfm; - -#ifdef __OBJECT_MOTION__ - /* if we do motion blur */ - if(sd->flag & SD_OBJECT_MOTION) { - /* fetch motion transforms */ - MotionTransform motion; - - motion.pre.x = have_motion; - motion.pre.y = kernel_tex_fetch(__objects, offset + 1); - motion.pre.z = kernel_tex_fetch(__objects, offset + 2); - motion.pre.w = kernel_tex_fetch(__objects, offset + 3); - - motion.post.x = kernel_tex_fetch(__objects, offset + 4); - motion.post.y = kernel_tex_fetch(__objects, offset + 5); - motion.post.z = kernel_tex_fetch(__objects, offset + 6); - motion.post.w = kernel_tex_fetch(__objects, offset + 7); - - /* interpolate (todo: do only once per object) */ - transform_motion_interpolate(&tfm, &motion, time); - - /* invert */ - if(type == OBJECT_INVERSE_TRANSFORM) - tfm = transform_quick_inverse(tfm); - - return tfm; - } -#endif - int offset = object*OBJECT_SIZE + (int)type; + Transform tfm; tfm.x = kernel_tex_fetch(__objects, offset + 0); tfm.y = kernel_tex_fetch(__objects, offset + 1); tfm.z = kernel_tex_fetch(__objects, offset + 2); @@ -68,12 +40,54 @@ __device_inline Transform object_fetch_transform(KernelGlobals *kg, int object, return tfm; } +#ifdef __OBJECT_MOTION__ +__device_inline Transform object_fetch_transform_motion(KernelGlobals *kg, int object, float time, Transform *itfm) +{ + Transform tfm; + + int object_flag = kernel_tex_fetch(__object_flag, object); + + /* if we do motion blur */ + if(object_flag & SD_OBJECT_MOTION) { + /* fetch motion transforms */ + MotionTransform motion; + + int offset = object*OBJECT_SIZE + (int)OBJECT_TRANSFORM_MOTION_PRE; + + motion.pre.x = kernel_tex_fetch(__objects, offset + 0); + motion.pre.y = kernel_tex_fetch(__objects, offset + 1); + motion.pre.z = kernel_tex_fetch(__objects, offset + 2); + motion.pre.w = kernel_tex_fetch(__objects, offset + 3); + + + motion.post.x = kernel_tex_fetch(__objects, offset + 4); + motion.post.y = kernel_tex_fetch(__objects, offset + 5); + motion.post.z = kernel_tex_fetch(__objects, offset + 6); + motion.post.w = kernel_tex_fetch(__objects, offset + 7); + + transform_motion_interpolate(&tfm, &motion, time); + + /* invert */ + if(itfm) + *itfm = transform_quick_inverse(tfm); + } + else { + tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM); + + if(itfm) + *itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM); + } + + return tfm; +} +#endif + __device_inline void object_position_transform(KernelGlobals *kg, ShaderData *sd, float3 *P) { #ifdef __OBJECT_MOTION__ *P = transform_point(&sd->ob_tfm, *P); #else - Transform tfm = object_fetch_transform(kg, sd->object, TIME_INVALID, OBJECT_TRANSFORM); + Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM); *P = transform_point(&tfm, *P); #endif } @@ -83,7 +97,7 @@ __device_inline void object_inverse_position_transform(KernelGlobals *kg, Shader #ifdef __OBJECT_MOTION__ *P = transform_point(&sd->ob_itfm, *P); #else - Transform tfm = object_fetch_transform(kg, sd->object, TIME_INVALID, OBJECT_INVERSE_TRANSFORM); + Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_INVERSE_TRANSFORM); *P = transform_point(&tfm, *P); #endif } @@ -93,7 +107,7 @@ __device_inline void object_inverse_normal_transform(KernelGlobals *kg, ShaderDa #ifdef __OBJECT_MOTION__ *N = normalize(transform_direction_transposed(&sd->ob_tfm, *N)); #else - Transform tfm = object_fetch_transform(kg, sd->object, TIME_INVALID, OBJECT_TRANSFORM); + Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM); *N = normalize(transform_direction_transposed(&tfm, *N)); #endif } @@ -103,7 +117,7 @@ __device_inline void object_normal_transform(KernelGlobals *kg, ShaderData *sd, #ifdef __OBJECT_MOTION__ *N = normalize(transform_direction_transposed(&sd->ob_itfm, *N)); #else - Transform tfm = object_fetch_transform(kg, sd->object, TIME_INVALID, OBJECT_INVERSE_TRANSFORM); + Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_INVERSE_TRANSFORM); *N = normalize(transform_direction_transposed(&tfm, *N)); #endif } @@ -113,7 +127,7 @@ __device_inline void object_dir_transform(KernelGlobals *kg, ShaderData *sd, flo #ifdef __OBJECT_MOTION__ *D = transform_direction(&sd->ob_tfm, *D); #else - Transform tfm = object_fetch_transform(kg, sd->object, 0.0f, OBJECT_TRANSFORM); + Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM); *D = transform_direction(&tfm, *D); #endif } @@ -123,7 +137,7 @@ __device_inline float3 object_location(KernelGlobals *kg, ShaderData *sd) #ifdef __OBJECT_MOTION__ return make_float3(sd->ob_tfm.x.w, sd->ob_tfm.y.w, sd->ob_tfm.z.w); #else - Transform tfm = object_fetch_transform(kg, sd->object, 0.0f, OBJECT_TRANSFORM); + Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM); return make_float3(tfm.x.w, tfm.y.w, tfm.z.w); #endif } diff --git a/intern/cycles/kernel/kernel_qbvh.h b/intern/cycles/kernel/kernel_qbvh.h deleted file mode 100644 index 525b616921d..00000000000 --- a/intern/cycles/kernel/kernel_qbvh.h +++ /dev/null @@ -1,413 +0,0 @@ -/* - * Adapted from code Copyright 2009-2010 NVIDIA Corporation - * Modifications Copyright 2011, Blender Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -CCL_NAMESPACE_BEGIN - -/* - * "Persistent while-while kernel" used in: - * - * "Understanding the Efficiency of Ray Traversal on GPUs", - * Timo Aila and Samuli Laine, - * Proc. High-Performance Graphics 2009 - */ - -/* bottom-most stack entry, indicating the end of traversal */ - -#define ENTRYPOINT_SENTINEL 0x76543210 -/* 64 object BVH + 64 mesh BVH + 64 object node splitting */ -#define QBVH_STACK_SIZE 192 -#define QBVH_NODE_SIZE 8 -#define TRI_NODE_SIZE 3 - -__device_inline float3 qbvh_inverse_direction(float3 dir) -{ - // Avoid divide by zero (ooeps = exp2f(-80.0f)) - float ooeps = 0.00000000000000000000000082718061255302767487140869206996285356581211090087890625f; - float3 idir; - - idir.x = 1.0f/((fabsf(dir.x) > ooeps)? dir.x: copysignf(ooeps, dir.x)); - idir.y = 1.0f/((fabsf(dir.y) > ooeps)? dir.y: copysignf(ooeps, dir.y)); - idir.z = 1.0f/((fabsf(dir.z) > ooeps)? dir.z: copysignf(ooeps, dir.z)); - - return idir; -} - -__device_inline void qbvh_instance_push(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *idir, float *t, const float tmax) -{ - Transform tfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM); - - *P = transform_point(&tfm, ray->P); - - float3 dir = transform_direction(&tfm, ray->D); - - float len; - dir = normalize_len(dir, &len); - - *idir = qbvh_inverse_direction(dir); - - if(*t != FLT_MAX) - *t *= len; -} - -__device_inline void qbvh_instance_pop(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *idir, float *t, const float tmax) -{ - Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM); - - if(*t != FLT_MAX) - *t *= len(transform_direction(&tfm, 1.0f/(*idir))); - - *P = ray->P; - *idir = qbvh_inverse_direction(ray->D); -} - -#ifdef __KERNEL_CPU__ - -__device_inline void qbvh_node_intersect(KernelGlobals *kg, int *traverseChild, - int nodeAddrChild[4], float3 P, float3 idir, float t, int nodeAddr) -{ - /* X axis */ - const __m128 bminx = kernel_tex_fetch_m128(__bvh_nodes, nodeAddr*QBVH_NODE_SIZE+0); - const __m128 t0x = _mm_mul_ps(_mm_sub_ps(bminx, _mm_set_ps1(P.x)), _mm_set_ps1(idir.x)); - const __m128 bmaxx = kernel_tex_fetch_m128(__bvh_nodes, nodeAddr*QBVH_NODE_SIZE+1); - const __m128 t1x = _mm_mul_ps(_mm_sub_ps(bmaxx, _mm_set_ps1(P.x)), _mm_set_ps1(idir.x)); - - __m128 tmin = _mm_max_ps(_mm_min_ps(t0x, t1x), _mm_setzero_ps()); - __m128 tmax = _mm_min_ps(_mm_max_ps(t0x, t1x), _mm_set_ps1(t)); - - /* Y axis */ - const __m128 bminy = kernel_tex_fetch_m128(__bvh_nodes, nodeAddr*QBVH_NODE_SIZE+2); - const __m128 t0y = _mm_mul_ps(_mm_sub_ps(bminy, _mm_set_ps1(P.y)), _mm_set_ps1(idir.y)); - const __m128 bmaxy = kernel_tex_fetch_m128(__bvh_nodes, nodeAddr*QBVH_NODE_SIZE+3); - const __m128 t1y = _mm_mul_ps(_mm_sub_ps(bmaxy, _mm_set_ps1(P.y)), _mm_set_ps1(idir.y)); - - tmin = _mm_max_ps(_mm_min_ps(t0y, t1y), tmin); - tmax = _mm_min_ps(_mm_max_ps(t0y, t1y), tmax); - - /* Z axis */ - const __m128 bminz = kernel_tex_fetch_m128(__bvh_nodes, nodeAddr*QBVH_NODE_SIZE+4); - const __m128 t0z = _mm_mul_ps(_mm_sub_ps(bminz, _mm_set_ps1(P.z)), _mm_set_ps1(idir.z)); - const __m128 bmaxz = kernel_tex_fetch_m128(__bvh_nodes, nodeAddr*QBVH_NODE_SIZE+5); - const __m128 t1z = _mm_mul_ps(_mm_sub_ps(bmaxz, _mm_set_ps1(P.z)), _mm_set_ps1(idir.z)); - - tmin = _mm_max_ps(_mm_min_ps(t0z, t1z), tmin); - tmax = _mm_min_ps(_mm_max_ps(t0z, t1z), tmax); - - /* compare and get mask */ - *traverseChild = _mm_movemask_ps(_mm_cmple_ps(tmin, tmax)); - - /* get node addresses */ - float4 cnodes = kernel_tex_fetch(__bvh_nodes, nodeAddr*QBVH_NODE_SIZE+6); - - nodeAddrChild[0] = __float_as_int(cnodes.x); - nodeAddrChild[1] = __float_as_int(cnodes.y); - nodeAddrChild[2] = __float_as_int(cnodes.z); - nodeAddrChild[3] = __float_as_int(cnodes.w); -} - -#else - -__device_inline bool qbvh_bb_intersect(float3 bmin, float3 bmax, float3 P, float3 idir, float t) -{ - float t0x = (bmin.x - P.x)*idir.x; - float t1x = (bmax.x - P.x)*idir.x; - float t0y = (bmin.y - P.y)*idir.y; - float t1y = (bmax.y - P.y)*idir.y; - float t0z = (bmin.z - P.z)*idir.z; - float t1z = (bmax.z - P.z)*idir.z; - - float minx = min(t0x, t1x); - float maxx = max(t0x, t1x); - float miny = min(t0y, t1y); - float maxy = max(t0y, t1y); - float minz = min(t0z, t1z); - float maxz = max(t0z, t1z); - - float tmin = max4(0.0f, minx, miny, minz); - float tmax = min4(t, maxx, maxy, maxz); - - return (tmin <= tmax); -} - -/* intersect four bounding boxes */ -__device_inline void qbvh_node_intersect(KernelGlobals *kg, int *traverseChild, - int nodeAddrChild[4], float3 P, float3 idir, float t, int nodeAddr) -{ - /* fetch node data */ - float4 minx = kernel_tex_fetch(__bvh_nodes, nodeAddr*QBVH_NODE_SIZE+0); - float4 miny = kernel_tex_fetch(__bvh_nodes, nodeAddr*QBVH_NODE_SIZE+2); - float4 minz = kernel_tex_fetch(__bvh_nodes, nodeAddr*QBVH_NODE_SIZE+4); - float4 maxx = kernel_tex_fetch(__bvh_nodes, nodeAddr*QBVH_NODE_SIZE+1); - float4 maxy = kernel_tex_fetch(__bvh_nodes, nodeAddr*QBVH_NODE_SIZE+3); - float4 maxz = kernel_tex_fetch(__bvh_nodes, nodeAddr*QBVH_NODE_SIZE+5); - - /* intersect bounding boxes */ - bool traverseChild0 = qbvh_bb_intersect(make_float3(minx.x, miny.x, minz.x), make_float3(maxx.x, maxy.x, maxz.x), P, idir, t); - bool traverseChild1 = qbvh_bb_intersect(make_float3(minx.y, miny.y, minz.y), make_float3(maxx.y, maxy.y, maxz.y), P, idir, t); - bool traverseChild2 = qbvh_bb_intersect(make_float3(minx.z, miny.z, minz.z), make_float3(maxx.z, maxy.z, maxz.z), P, idir, t); - bool traverseChild3 = qbvh_bb_intersect(make_float3(minx.w, miny.w, minz.w), make_float3(maxx.w, maxy.w, maxz.w), P, idir, t); - - *traverseChild = 0; - if(traverseChild0) *traverseChild |= 1; - if(traverseChild1) *traverseChild |= 2; - if(traverseChild2) *traverseChild |= 4; - if(traverseChild3) *traverseChild |= 8; - - /* get node addresses */ - float4 cnodes = kernel_tex_fetch(__bvh_nodes, nodeAddr*QBVH_NODE_SIZE+6); - - nodeAddrChild[0] = __float_as_int(cnodes.x); - nodeAddrChild[1] = __float_as_int(cnodes.y); - nodeAddrChild[2] = __float_as_int(cnodes.z); - nodeAddrChild[3] = __float_as_int(cnodes.w); -} - -#endif - -/* Sven Woop's algorithm */ -__device_inline void qbvh_triangle_intersect(KernelGlobals *kg, Intersection *isect, float3 P, float3 idir, int object, int triAddr) -{ - /* compute and check intersection t-value */ - float4 v00 = kernel_tex_fetch(__tri_woop, triAddr*TRI_NODE_SIZE+0); - float4 v11 = kernel_tex_fetch(__tri_woop, triAddr*TRI_NODE_SIZE+1); - float3 dir = 1.0f/idir; - - float Oz = v00.w - P.x*v00.x - P.y*v00.y - P.z*v00.z; - float invDz = 1.0f/(dir.x*v00.x + dir.y*v00.y + dir.z*v00.z); - float t = Oz * invDz; - - if(t > 0.0f && t < isect->t) { - /* compute and check barycentric u */ - float Ox = v11.w + P.x*v11.x + P.y*v11.y + P.z*v11.z; - float Dx = dir.x*v11.x + dir.y*v11.y + dir.z*v11.z; - float u = Ox + t*Dx; - - if(u >= 0.0f) { - /* compute and check barycentric v */ - float4 v22 = kernel_tex_fetch(__tri_woop, triAddr*TRI_NODE_SIZE+2); - float Oy = v22.w + P.x*v22.x + P.y*v22.y + P.z*v22.z; - float Dy = dir.x*v22.x + dir.y*v22.y + dir.z*v22.z; - float v = Oy + t*Dy; - - if(v >= 0.0f && u + v <= 1.0f) { - /* record intersection */ - isect->prim = triAddr; - isect->object = object; - isect->u = u; - isect->v = v; - isect->t = t; - } - } - } -} - -__device_inline bool scene_intersect(KernelGlobals *kg, const Ray *ray, const bool isshadowray, Intersection *isect) -{ - /* traversal stack in CUDA thread-local memory */ - int traversalStack[QBVH_STACK_SIZE]; - traversalStack[0] = ENTRYPOINT_SENTINEL; - - /* traversal variables in registers */ - int stackPtr = 0; - int nodeAddr = kernel_data.bvh.root; - - /* ray parameters in registers */ - const float tmax = ray->t; - float3 P = ray->P; - float3 idir = qbvh_inverse_direction(ray->D); - int object = ~0; - - isect->t = tmax; - isect->object = ~0; - isect->prim = ~0; - isect->u = 0.0f; - isect->v = 0.0f; - - /* traversal loop */ - do { - do - { - /* traverse internal nodes */ - while(nodeAddr >= 0 && nodeAddr != ENTRYPOINT_SENTINEL) - { - int traverseChild, nodeAddrChild[4]; - - qbvh_node_intersect(kg, &traverseChild, nodeAddrChild, - P, idir, isect->t, nodeAddr); - - if(traverseChild & 1) { - ++stackPtr; - traversalStack[stackPtr] = nodeAddrChild[0]; - } - - if(traverseChild & 2) { - ++stackPtr; - traversalStack[stackPtr] = nodeAddrChild[1]; - } - if(traverseChild & 4) { - ++stackPtr; - traversalStack[stackPtr] = nodeAddrChild[2]; - } - - if(traverseChild & 8) { - ++stackPtr; - traversalStack[stackPtr] = nodeAddrChild[3]; - } - - nodeAddr = traversalStack[stackPtr]; - --stackPtr; - } - - /* if node is leaf, fetch triangle list */ - if(nodeAddr < 0) { - float4 leaf = kernel_tex_fetch(__bvh_nodes, (-nodeAddr-1)*QBVH_NODE_SIZE+(QBVH_NODE_SIZE-2)); - int primAddr = __float_as_int(leaf.x); - -#ifdef __INSTANCING__ - if(primAddr >= 0) { -#endif - int primAddr2 = __float_as_int(leaf.y); - - /* pop */ - nodeAddr = traversalStack[stackPtr]; - --stackPtr; - - /* triangle intersection */ - while(primAddr < primAddr2) { - /* intersect ray against triangle */ - qbvh_triangle_intersect(kg, isect, P, idir, object, primAddr); - - /* shadow ray early termination */ - if(isshadowray && isect->prim != ~0) - return true; - - primAddr++; - } -#ifdef __INSTANCING__ - } - else { - /* instance push */ - object = kernel_tex_fetch(__prim_object, -primAddr-1); - - qbvh_instance_push(kg, object, ray, &P, &idir, &isect->t, tmax); - - ++stackPtr; - traversalStack[stackPtr] = ENTRYPOINT_SENTINEL; - - nodeAddr = kernel_tex_fetch(__object_node, object); - } -#endif - } - } while(nodeAddr != ENTRYPOINT_SENTINEL); - -#ifdef __INSTANCING__ - if(stackPtr >= 0) { - kernel_assert(object != ~0); - - /* instance pop */ - qbvh_instance_pop(kg, object, ray, &P, &idir, &isect->t, tmax); - object = ~0; - nodeAddr = traversalStack[stackPtr]; - --stackPtr; - } -#endif - } while(nodeAddr != ENTRYPOINT_SENTINEL); - - return (isect->prim != ~0); -} - -__device_inline float3 ray_offset(float3 P, float3 Ng) -{ -#ifdef __INTERSECTION_REFINE__ - const float epsilon_f = 1e-5f; - const int epsilon_i = 32; - - float3 res; - - /* x component */ - if(fabsf(P.x) < epsilon_f) { - res.x = P.x + Ng.x*epsilon_f; - } - else { - uint ix = __float_as_uint(P.x); - ix += ((ix ^ __float_as_uint(Ng.x)) >> 31)? -epsilon_i: epsilon_i; - res.x = __uint_as_float(ix); - } - - /* y component */ - if(fabsf(P.y) < epsilon_f) { - res.y = P.y + Ng.y*epsilon_f; - } - else { - uint iy = __float_as_uint(P.y); - iy += ((iy ^ __float_as_uint(Ng.y)) >> 31)? -epsilon_i: epsilon_i; - res.y = __uint_as_float(iy); - } - - /* z component */ - if(fabsf(P.z) < epsilon_f) { - res.z = P.z + Ng.z*epsilon_f; - } - else { - uint iz = __float_as_uint(P.z); - iz += ((iz ^ __float_as_uint(Ng.z)) >> 31)? -epsilon_i: epsilon_i; - res.z = __uint_as_float(iz); - } - - return res; -#else - const float epsilon_f = 1e-4f; - return P + epsilon_f*Ng; -#endif -} - -__device_inline float3 bvh_triangle_refine(KernelGlobals *kg, const Intersection *isect, const Ray *ray) -{ - float3 P = ray->P; - float3 D = ray->D; - float t = isect->t; - -#ifdef __INTERSECTION_REFINE__ - if(isect->object != ~0) { - Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_INVERSE_TRANSFORM); - - P = transform_point(&tfm, P); - D = transform_direction(&tfm, D*t); - D = normalize_len(D, &t); - } - - P = P + D*t; - - float4 v00 = kernel_tex_fetch(__tri_woop, isect->prim*TRI_NODE_SIZE+0); - float Oz = v00.w - P.x*v00.x - P.y*v00.y - P.z*v00.z; - float invDz = 1.0f/(D.x*v00.x + D.y*v00.y + D.z*v00.z); - float rt = Oz * invDz; - - P = P + D*rt; - - if(isect->object != ~0) { - Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_TRANSFORM); - P = transform_point(&tfm, P); - } - - return P; -#else - return P + D*t; -#endif -} - -CCL_NAMESPACE_END - diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h index 1ed5e3d352c..2711012edef 100644 --- a/intern/cycles/kernel/kernel_shader.h +++ b/intern/cycles/kernel/kernel_shader.h @@ -67,10 +67,18 @@ __device_inline void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd, sd->v = isect->v; #endif + sd->flag = kernel_tex_fetch(__shader_flag, (shader & SHADER_MASK)*2); + sd->flag |= kernel_tex_fetch(__object_flag, sd->object); + /* matrices and time */ #ifdef __OBJECT_MOTION__ - sd->ob_tfm = object_fetch_transform(kg, sd->object, ray->time, OBJECT_TRANSFORM); - sd->ob_itfm = object_fetch_transform(kg, sd->object, ray->time, OBJECT_INVERSE_TRANSFORM); + if(sd->flag & SD_OBJECT_MOTION) { + sd->ob_tfm = object_fetch_transform_motion(kg, sd->object, time, &sd->ob_itfm); + } + else { + sd->ob_tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM); + sd->ob_itfm = object_fetch_transform(kg, sd->object, OBJECT_INVERSE_TRANSFORM); + } sd->time = ray->time; #endif @@ -87,9 +95,6 @@ __device_inline void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd, if(sd->shader & SHADER_SMOOTH_NORMAL) sd->N = triangle_smooth_normal(kg, sd->prim, sd->u, sd->v); - sd->flag = kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*2); - sd->flag |= kernel_tex_fetch(__object_flag, sd->object); - #ifdef __DPDU__ /* dPdu/dPdv */ triangle_dPdudv(kg, &sd->dPdu, &sd->dPdv, sd->prim); @@ -173,11 +178,20 @@ __device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd, } #endif -#ifdef __OBJECT_MOTION__ - sd->time = time; + sd->flag = kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*2); + if(sd->object != -1) + sd->flag |= kernel_tex_fetch(__object_flag, sd->object); - sd->ob_tfm = object_fetch_transform(kg, sd->object, time, OBJECT_TRANSFORM); - sd->ob_itfm = object_fetch_transform(kg, sd->object, time, OBJECT_INVERSE_TRANSFORM); +#ifdef __OBJECT_MOTION__ + if(sd->flag & SD_OBJECT_MOTION) { + sd->ob_tfm = object_fetch_transform_motion(kg, sd->object, time, &sd->ob_itfm); + } + else { + sd->ob_tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM); + sd->ob_itfm = object_fetch_transform(kg, sd->object, OBJECT_INVERSE_TRANSFORM); + } + + sd->time = time; #endif /* smooth normal */ @@ -190,10 +204,6 @@ __device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd, #endif } - sd->flag = kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*2); - if(sd->object != -1) - sd->flag |= kernel_tex_fetch(__object_flag, sd->object); - #ifdef __DPDU__ /* dPdu/dPdv */ if(sd->prim == ~0) { diff --git a/intern/cycles/kernel/kernel_triangle.h b/intern/cycles/kernel/kernel_triangle.h index f57c59a45eb..43cfa330724 100644 --- a/intern/cycles/kernel/kernel_triangle.h +++ b/intern/cycles/kernel/kernel_triangle.h @@ -201,10 +201,10 @@ __device float4 triangle_motion_vector(KernelGlobals *kg, ShaderData *sd) * transformation was set match the world/object space of motion_pre/post */ Transform tfm; - tfm = object_fetch_transform(kg, sd->object, TIME_INVALID, OBJECT_TRANSFORM_MOTION_PRE); + tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM_MOTION_PRE); motion_pre = transform_point(&tfm, motion_pre); - tfm = object_fetch_transform(kg, sd->object, TIME_INVALID, OBJECT_TRANSFORM_MOTION_POST); + tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM_MOTION_POST); motion_post = transform_point(&tfm, motion_post); float3 P; diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index be49aa54e47..2acea04838a 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -113,7 +113,6 @@ CCL_NAMESPACE_BEGIN #endif //#define __SOBOL_FULL_SCREEN__ -//#define __QBVH__ /* Shader Evaluation */ @@ -428,13 +427,6 @@ typedef struct ShaderData { /* length of the ray being shaded */ float ray_length; -#ifdef __OBJECT_MOTION__ - /* object <-> world space transformations, cached to avoid - * re-interpolating them constantly for shading */ - Transform ob_tfm; - Transform ob_itfm; -#endif - #ifdef __RAY_DIFFERENTIALS__ /* differential of P. these are orthogonal to Ng, not N */ differential3 dP; @@ -453,6 +445,13 @@ typedef struct ShaderData { float3 T; #endif +#ifdef __OBJECT_MOTION__ + /* object <-> world space transformations, cached to avoid + * re-interpolating them constantly for shading */ + Transform ob_tfm; + Transform ob_itfm; +#endif + #ifdef __MULTI_CLOSURE__ /* Closure data, we store a fixed array of closures */ ShaderClosure closure[MAX_CLOSURE]; @@ -632,7 +631,8 @@ typedef struct KernelBVH { /* root node */ int root; int attributes_map_stride; - int pad1, pad2; + int have_motion; + int pad2; } KernelBVH; typedef struct KernelData { diff --git a/intern/cycles/render/camera.cpp b/intern/cycles/render/camera.cpp index 441f17d90e9..727b9801d95 100644 --- a/intern/cycles/render/camera.cpp +++ b/intern/cycles/render/camera.cpp @@ -19,6 +19,8 @@ #include "camera.h" #include "scene.h" +#include "device.h" + #include "util_vector.h" CCL_NAMESPACE_BEGIN @@ -141,7 +143,7 @@ void Camera::update() void Camera::device_update(Device *device, DeviceScene *dscene, Scene *scene) { - Scene::MotionType need_motion = scene->need_motion(); + Scene::MotionType need_motion = scene->need_motion(device->info.advanced_shading); update(); @@ -274,13 +276,17 @@ bool Camera::modified(const Camera& cam) (border_bottom == cam.border_bottom) && (border_top == cam.border_top) && (matrix == cam.matrix) && - (motion == cam.motion) && - (use_motion == cam.use_motion) && (panorama_type == cam.panorama_type) && (fisheye_fov == cam.fisheye_fov) && (fisheye_lens == cam.fisheye_lens)); } +bool Camera::motion_modified(const Camera& cam) +{ + return !((motion == cam.motion) && + (use_motion == cam.use_motion)); +} + void Camera::tag_update() { need_update = true; diff --git a/intern/cycles/render/camera.h b/intern/cycles/render/camera.h index 82852bde5e0..1407c86e7c2 100644 --- a/intern/cycles/render/camera.h +++ b/intern/cycles/render/camera.h @@ -103,6 +103,7 @@ public: void device_free(Device *device, DeviceScene *dscene); bool modified(const Camera& cam); + bool motion_modified(const Camera& cam); void tag_update(); }; diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp index 014b78dec2b..3f2fe4ab093 100644 --- a/intern/cycles/render/mesh.cpp +++ b/intern/cycles/render/mesh.cpp @@ -723,7 +723,8 @@ void MeshManager::device_update(Device *device, DeviceScene *dscene, Scene *scen shader->need_update_attributes = false; #ifdef __OBJECT_MOTION__ - bool motion_blur = scene->need_motion() == Scene::MOTION_BLUR; + Scene::MotionType need_motion = scene->need_motion(device->info.advanced_shading); + bool motion_blur = need_motion == Scene::MOTION_BLUR; #else bool motion_blur = false; #endif diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp index 4a72dcc52f7..f5d78c080c8 100644 --- a/intern/cycles/render/object.cpp +++ b/intern/cycles/render/object.cpp @@ -151,7 +151,8 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene uint *object_flag = dscene->object_flag.resize(scene->objects.size()); int i = 0; map surface_area_map; - Scene::MotionType need_motion = scene->need_motion(); + Scene::MotionType need_motion = scene->need_motion(device->info.advanced_shading); + bool have_motion = false; foreach(Object *ob, scene->objects) { Mesh *mesh = ob->mesh; @@ -229,6 +230,7 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene transform_motion_decompose(&decomp, &ob->motion); memcpy(&objects[offset+8], &decomp, sizeof(float4)*8); flag |= SD_OBJECT_MOTION; + have_motion = true; } else { float4 no_motion = make_float4(FLT_MAX); @@ -253,6 +255,8 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene device->tex_alloc("__objects", dscene->objects); device->tex_alloc("__object_flag", dscene->object_flag); + + dscene->data.bvh.have_motion = have_motion; } void ObjectManager::device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress) @@ -300,7 +304,8 @@ void ObjectManager::apply_static_transforms(Scene *scene, Progress& progress) /* counter mesh users */ map mesh_users; #ifdef __OBJECT_MOTION__ - bool motion_blur = scene->need_motion() == Scene::MOTION_BLUR; + Scene::MotionType need_motion = scene->need_motion(); + bool motion_blur = need_motion == Scene::MOTION_BLUR; #else bool motion_blur = false; #endif diff --git a/intern/cycles/render/scene.cpp b/intern/cycles/render/scene.cpp index 071338d49c2..15031b9500c 100644 --- a/intern/cycles/render/scene.cpp +++ b/intern/cycles/render/scene.cpp @@ -183,10 +183,10 @@ void Scene::device_update(Device *device_, Progress& progress) device->const_copy_to("__data", &dscene.data, sizeof(dscene.data)); } -Scene::MotionType Scene::need_motion() +Scene::MotionType Scene::need_motion(bool advanced_shading) { if(integrator->motion_blur) - return MOTION_BLUR; + return (advanced_shading)? MOTION_BLUR: MOTION_NONE; else if(Pass::contains(film->passes, PASS_MOTION)) return MOTION_PASS; else diff --git a/intern/cycles/render/scene.h b/intern/cycles/render/scene.h index 09087fb2970..bd45c1c04e6 100644 --- a/intern/cycles/render/scene.h +++ b/intern/cycles/render/scene.h @@ -194,7 +194,7 @@ public: void need_global_attributes(AttributeRequestSet& attributes); enum MotionType { MOTION_NONE = 0, MOTION_PASS, MOTION_BLUR }; - MotionType need_motion(); + MotionType need_motion(bool advanced_shading = true); bool need_update(); bool need_reset(); diff --git a/source/blender/editors/render/render_update.c b/source/blender/editors/render/render_update.c index cd55b91cb6b..5b1c03f65df 100644 --- a/source/blender/editors/render/render_update.c +++ b/source/blender/editors/render/render_update.c @@ -74,12 +74,19 @@ void ED_render_scene_update(Main *bmain, Scene *scene, int updated) bScreen *sc; ScrArea *sa; ARegion *ar; + static int recursive_check = FALSE; /* don't do this render engine update if we're updating the scene from * other threads doing e.g. rendering or baking jobs */ if (!BLI_thread_is_main()) return; + /* don't call this recursively for frame updates */ + if(recursive_check) + return; + + recursive_check = TRUE; + C = CTX_create(); CTX_data_main_set(C, bmain); CTX_data_scene_set(C, scene); @@ -114,6 +121,8 @@ void ED_render_scene_update(Main *bmain, Scene *scene, int updated) } CTX_free(C); + + recursive_check = FALSE; } void ED_render_engine_area_exit(ScrArea *sa) diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index a3616e0845a..537dab73340 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -3600,14 +3600,14 @@ static void rna_def_scene_render_data(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "mode", R_MBLUR); RNA_def_property_ui_text(prop, "Motion Blur", "Use multi-sampled 3D scene motion blur"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); + RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_glsl_update"); prop = RNA_def_property(srna, "motion_blur_samples", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "mblur_samples"); RNA_def_property_range(prop, 1, 32); RNA_def_property_ui_text(prop, "Motion Samples", "Number of scene samples to take with motion blur"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); + RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_glsl_update"); prop = RNA_def_property(srna, "motion_blur_shutter", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "blurfac"); @@ -3615,7 +3615,7 @@ static void rna_def_scene_render_data(BlenderRNA *brna) RNA_def_property_ui_range(prop, 0.01, 2.0f, 1, 0); RNA_def_property_ui_text(prop, "Shutter", "Time taken in frames between shutter open and close"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); + RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_glsl_update"); /* border */ prop = RNA_def_property(srna, "use_border", PROP_BOOLEAN, PROP_NONE); From 59ea74fd6f5ac027d9b9e94132e2dd0a2bef7504 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 15 Oct 2012 22:45:47 +0000 Subject: [PATCH 256/347] dragging the playhead now uses continuous grab. --- source/blender/editors/animation/anim_ops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/animation/anim_ops.c b/source/blender/editors/animation/anim_ops.c index f2711ec3bb5..ca036a8540e 100644 --- a/source/blender/editors/animation/anim_ops.c +++ b/source/blender/editors/animation/anim_ops.c @@ -172,7 +172,7 @@ static void ANIM_OT_change_frame(wmOperatorType *ot) ot->poll = change_frame_poll; /* flags */ - ot->flag = OPTYPE_BLOCKING | OPTYPE_UNDO; + ot->flag = OPTYPE_BLOCKING | OPTYPE_UNDO | OPTYPE_GRAB_POINTER; /* rna */ RNA_def_int(ot->srna, "frame", 0, MINAFRAME, MAXFRAME, "Frame", "", MINAFRAME, MAXFRAME); From 92862f96dc537242f66a6b5ebe0fc3f835acada0 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 15 Oct 2012 23:11:59 +0000 Subject: [PATCH 257/347] code cleanup: use float sizes for function args. --- source/blender/blenkernel/BKE_node.h | 6 +- source/blender/blenkernel/intern/node.c | 2 +- source/blender/blenkernel/intern/smoke.c | 2 +- source/blender/blenlib/BLI_kdopbvh.h | 20 +- source/blender/blenlib/BLI_kdtree.h | 2 +- source/blender/blenlib/intern/BLI_kdopbvh.c | 8 +- source/blender/blenlib/intern/BLI_kdtree.c | 4 +- .../operations/COM_MathBaseOperation.h | 2 +- .../operations/COM_MixBaseOperation.h | 2 +- .../blender/makesdna/DNA_packedFile_types.h | 4 +- .../blender/nodes/texture/node_texture_tree.c | 28 +- .../blender/nodes/texture/node_texture_util.c | 22 +- .../blender/nodes/texture/node_texture_util.h | 6 +- .../nodes/texture/nodes/node_texture_bricks.c | 2 +- .../nodes/texture/nodes/node_texture_proc.c | 6 +- .../nodes/texture/nodes/node_texture_rotate.c | 2 +- .../texture/nodes/node_texture_valToNor.c | 2 +- .../python/mathutils/mathutils_Color.c | 2 +- .../python/mathutils/mathutils_Color.h | 2 +- .../render/extern/include/RE_shader_ext.h | 8 +- source/blender/render/intern/include/envmap.h | 2 +- .../render/intern/include/pointdensity.h | 2 +- .../blender/render/intern/include/shading.h | 2 +- source/blender/render/intern/source/envmap.c | 28 +- .../render/intern/source/pointdensity.c | 2 +- .../render/intern/source/render_texture.c | 288 +++++++++--------- .../BlenderRoutines/KX_BlenderRenderTools.h | 34 +-- 27 files changed, 251 insertions(+), 239 deletions(-) diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index 92c4f9c4842..4ee5c894b5c 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -349,7 +349,7 @@ struct bNodeSocket *nodeInsertSocket(struct bNodeTree *ntree, struct bNode *node void nodeRemoveSocket(struct bNodeTree *ntree, struct bNode *node, struct bNodeSocket *sock); void nodeRemoveAllSockets(struct bNodeTree *ntree, struct bNode *node); -void nodeAddToPreview(struct bNode *node, float col[4], int x, int y, int do_manage); +void nodeAddToPreview(struct bNode *node, const float col[4], int x, int y, int do_manage); struct bNode *nodeAddNode(struct bNodeTree *ntree, struct bNodeTemplate *ntemp); void nodeUnlinkNode(struct bNodeTree *ntree, struct bNode *node); @@ -785,7 +785,9 @@ void ntreeTexCheckCyclics(struct bNodeTree *ntree); struct bNodeTreeExec *ntreeTexBeginExecTree(struct bNodeTree *ntree, int use_tree_data); void ntreeTexEndExecTree(struct bNodeTreeExec *exec, int use_tree_data); -int ntreeTexExecTree(struct bNodeTree *ntree, struct TexResult *target, float *coord, float *dxt, float *dyt, int osatex, short thread, struct Tex *tex, short which_output, int cfra, int preview, struct ShadeInput *shi, struct MTex *mtex); +int ntreeTexExecTree(struct bNodeTree *ntree, struct TexResult *target, + float coord[3], float dxt[3], float dyt[3], int osatex, const short thread, + struct Tex *tex, short which_output, int cfra, int preview, struct ShadeInput *shi, struct MTex *mtex); /*************************************************/ diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index ab83bf4e5a4..0ff6b7abbca 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -889,7 +889,7 @@ void ntreeClearPreview(bNodeTree *ntree) /* hack warning! this function is only used for shader previews, and * since it gets called multiple times per pixel for Ztransp we only * add the color once. Preview gets cleared before it starts render though */ -void nodeAddToPreview(bNode *node, float col[4], int x, int y, int do_manage) +void nodeAddToPreview(bNode *node, const float col[4], int x, int y, int do_manage) { bNodePreview *preview = node->preview; if (preview) { diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c index 519c4008e0d..0724ac2711f 100644 --- a/source/blender/blenkernel/intern/smoke.c +++ b/source/blender/blenkernel/intern/smoke.c @@ -1054,7 +1054,7 @@ static void emit_from_particles(Object *flow_ob, SmokeDomainSettings *sds, Smoke } } -static void get_texture_value(Tex *texture, float *tex_co, TexResult *texres) +static void get_texture_value(Tex *texture, float tex_co[3], TexResult *texres) { int result_type; diff --git a/source/blender/blenlib/BLI_kdopbvh.h b/source/blender/blenlib/BLI_kdopbvh.h index c75334a2924..8d0d4943ebe 100644 --- a/source/blender/blenlib/BLI_kdopbvh.h +++ b/source/blender/blenlib/BLI_kdopbvh.h @@ -75,7 +75,7 @@ typedef struct BVHTreeRayHit { } BVHTreeRayHit; /* callback must update nearest in case it finds a nearest result */ -typedef void (*BVHTree_NearestPointCallback)(void *userdata, int index, const float *co, BVHTreeNearest *nearest); +typedef void (*BVHTree_NearestPointCallback)(void *userdata, int index, const float co[3], BVHTreeNearest *nearest); /* callback must update hit in case it finds a nearest successful hit */ typedef void (*BVHTree_RayCastCallback)(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit); @@ -87,11 +87,11 @@ BVHTree *BLI_bvhtree_new(int maxsize, float epsilon, char tree_type, char axis); void BLI_bvhtree_free(BVHTree *tree); /* construct: first insert points, then call balance */ -int BLI_bvhtree_insert(BVHTree *tree, int index, const float *co, int numpoints); +int BLI_bvhtree_insert(BVHTree *tree, int index, const float co[3], int numpoints); void BLI_bvhtree_balance(BVHTree *tree); /* update: first update points/nodes, then call update_tree to refit the bounding volumes */ -int BLI_bvhtree_update_node(BVHTree *tree, int index, const float *co, const float *co_moving, int numpoints); +int BLI_bvhtree_update_node(BVHTree *tree, int index, const float co[3], const float co_moving[3], int numpoints); void BLI_bvhtree_update_tree(BVHTree *tree); /* collision/overlap: check two trees if they overlap, alloc's *overlap with length of the int return value */ @@ -99,15 +99,19 @@ BVHTreeOverlap *BLI_bvhtree_overlap(BVHTree *tree1, BVHTree *tree2, unsigned int float BLI_bvhtree_getepsilon(BVHTree *tree); -/* find nearest node to the given coordinates (if nearest is given it will only search nodes where square distance is smaller than nearest->dist) */ -int BLI_bvhtree_find_nearest(BVHTree *tree, const float co[3], BVHTreeNearest *nearest, BVHTree_NearestPointCallback callback, void *userdata); +/* find nearest node to the given coordinates + * (if nearest is given it will only search nodes where square distance is smaller than nearest->dist) */ +int BLI_bvhtree_find_nearest(BVHTree *tree, const float co[3], BVHTreeNearest *nearest, + BVHTree_NearestPointCallback callback, void *userdata); -int BLI_bvhtree_ray_cast(BVHTree *tree, const float co[3], const float *dir, float radius, BVHTreeRayHit *hit, BVHTree_RayCastCallback callback, void *userdata); +int BLI_bvhtree_ray_cast(BVHTree *tree, const float co[3], const float dir[3], float radius, BVHTreeRayHit *hit, + BVHTree_RayCastCallback callback, void *userdata); -float BLI_bvhtree_bb_raycast(const float *bv, const float light_start[3], const float light_end[3], float pos[3]); +float BLI_bvhtree_bb_raycast(const float bv[6], const float light_start[3], const float light_end[3], float pos[3]); /* range query */ -int BLI_bvhtree_range_query(BVHTree *tree, const float co[3], float radius, BVHTree_RangeQuery callback, void *userdata); +int BLI_bvhtree_range_query(BVHTree *tree, const float co[3], float radius, + BVHTree_RangeQuery callback, void *userdata); #ifdef __cplusplus } diff --git a/source/blender/blenlib/BLI_kdtree.h b/source/blender/blenlib/BLI_kdtree.h index e90566408d4..f9b52f34102 100644 --- a/source/blender/blenlib/BLI_kdtree.h +++ b/source/blender/blenlib/BLI_kdtree.h @@ -56,7 +56,7 @@ void BLI_kdtree_balance(KDTree *tree); /* Find nearest returns index, and -1 if no node is found. * Find n nearest returns number of points found, with results in nearest. * Normal is optional, but if given will limit results to points in normal direction from co. */ -int BLI_kdtree_find_nearest(KDTree *tree, float *co, float *nor, KDTreeNearest *nearest); +int BLI_kdtree_find_nearest(KDTree *tree, const float co[3], const float nor[3], KDTreeNearest *nearest); int BLI_kdtree_find_n_nearest(KDTree *tree, int n, const float co[3], const float nor[3], KDTreeNearest *nearest); /* Range search returns number of points found, with results in nearest */ diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c index a86783f3450..46b0cfeaaac 100644 --- a/source/blender/blenlib/intern/BLI_kdopbvh.c +++ b/source/blender/blenlib/intern/BLI_kdopbvh.c @@ -921,7 +921,7 @@ void BLI_bvhtree_balance(BVHTree *tree) /* bvhtree_info(tree); */ } -int BLI_bvhtree_insert(BVHTree *tree, int index, const float *co, int numpoints) +int BLI_bvhtree_insert(BVHTree *tree, int index, const float co[3], int numpoints) { int i; BVHNode *node = NULL; @@ -952,7 +952,7 @@ int BLI_bvhtree_insert(BVHTree *tree, int index, const float *co, int numpoints) /* call before BLI_bvhtree_update_tree() */ -int BLI_bvhtree_update_node(BVHTree *tree, int index, const float *co, const float *co_moving, int numpoints) +int BLI_bvhtree_update_node(BVHTree *tree, int index, const float co[3], const float co_moving[3], int numpoints) { int i; BVHNode *node = NULL; @@ -1346,7 +1346,7 @@ int BLI_bvhtree_find_nearest(BVHTree *tree, const float co[3], BVHTreeNearest *n /* Determines the distance that the ray must travel to hit the bounding volume of the given node */ -static float ray_nearest_hit(BVHRayCastData *data, const float *bv) +static float ray_nearest_hit(BVHRayCastData *data, const float bv[6]) { int i; @@ -1524,7 +1524,7 @@ int BLI_bvhtree_ray_cast(BVHTree *tree, const float co[3], const float dir[3], f return data.hit.index; } -float BLI_bvhtree_bb_raycast(const float *bv, const float light_start[3], const float light_end[3], float pos[3]) +float BLI_bvhtree_bb_raycast(const float bv[6], const float light_start[3], const float light_end[3], float pos[3]) { BVHRayCastData data; float dist = 0.0; diff --git a/source/blender/blenlib/intern/BLI_kdtree.c b/source/blender/blenlib/intern/BLI_kdtree.c index 19985c56b84..900580317f2 100644 --- a/source/blender/blenlib/intern/BLI_kdtree.c +++ b/source/blender/blenlib/intern/BLI_kdtree.c @@ -132,7 +132,7 @@ void BLI_kdtree_balance(KDTree *tree) tree->root = kdtree_balance(tree->nodes, tree->totnode, 0); } -static float squared_distance(const float v2[3], const float v1[3], const float *UNUSED(n1), const float *n2) +static float squared_distance(const float v2[3], const float v1[3], const float UNUSED(n1[3]), const float n2[3]) { float d[3], dist; @@ -152,7 +152,7 @@ static float squared_distance(const float v2[3], const float v1[3], const float return dist; } -int BLI_kdtree_find_nearest(KDTree *tree, float *co, float *nor, KDTreeNearest *nearest) +int BLI_kdtree_find_nearest(KDTree *tree, const float co[3], const float nor[3], KDTreeNearest *nearest) { KDTreeNode *root, *node, *min_node; KDTreeNode **stack, *defaultstack[100]; diff --git a/source/blender/compositor/operations/COM_MathBaseOperation.h b/source/blender/compositor/operations/COM_MathBaseOperation.h index b492d06a697..febfa9662c6 100644 --- a/source/blender/compositor/operations/COM_MathBaseOperation.h +++ b/source/blender/compositor/operations/COM_MathBaseOperation.h @@ -45,7 +45,7 @@ protected: */ MathBaseOperation(); - void clampIfNeeded(float *color); + void clampIfNeeded(float color[4]); public: /** * the inner loop of this program diff --git a/source/blender/compositor/operations/COM_MixBaseOperation.h b/source/blender/compositor/operations/COM_MixBaseOperation.h index 4b466d193d6..88d1d00c2bf 100644 --- a/source/blender/compositor/operations/COM_MixBaseOperation.h +++ b/source/blender/compositor/operations/COM_MixBaseOperation.h @@ -40,7 +40,7 @@ protected: bool m_valueAlphaMultiply; bool m_useClamp; - inline void clampIfNeeded(float *color) + inline void clampIfNeeded(float color[4]) { if (m_useClamp) { CLAMP(color[0], 0.0f, 1.0f); diff --git a/source/blender/makesdna/DNA_packedFile_types.h b/source/blender/makesdna/DNA_packedFile_types.h index f01e89d18c9..4ec5866e8c3 100644 --- a/source/blender/makesdna/DNA_packedFile_types.h +++ b/source/blender/makesdna/DNA_packedFile_types.h @@ -45,7 +45,7 @@ enum PF_FileStatus PF_EQUAL = 0, PF_DIFFERS = 1, PF_NOFILE = 2, - + PF_WRITE_ORIGINAL = 3, PF_WRITE_LOCAL = 4, PF_USE_LOCAL = 5, @@ -53,7 +53,7 @@ enum PF_FileStatus PF_KEEP = 7, PF_REMOVE = 8, PF_NOOP = 9, - + PF_ASK = 10 }; diff --git a/source/blender/nodes/texture/node_texture_tree.c b/source/blender/nodes/texture/node_texture_tree.c index 9656d93f1b0..1bfd88d3af7 100644 --- a/source/blender/nodes/texture/node_texture_tree.c +++ b/source/blender/nodes/texture/node_texture_tree.c @@ -4,7 +4,7 @@ * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. + * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -240,19 +240,19 @@ void ntreeTexEndExecTree(bNodeTreeExec *exec, int use_tree_data) } int ntreeTexExecTree( - bNodeTree *nodes, - TexResult *texres, - float *co, - float *dxt, float *dyt, - int osatex, - short thread, - Tex *UNUSED(tex), - short which_output, - int cfra, - int preview, - ShadeInput *shi, - MTex *mtex -) { + bNodeTree *nodes, + TexResult *texres, + float co[3], + float dxt[3], float dyt[3], + int osatex, + const short thread, + Tex *UNUSED(tex), + short which_output, + int cfra, + int preview, + ShadeInput *shi, + MTex *mtex) +{ TexCallData data; float *nor = texres->nor; int retval = TEX_INT; diff --git a/source/blender/nodes/texture/node_texture_util.c b/source/blender/nodes/texture/node_texture_util.c index 5e58b74ac3a..06473d800d0 100644 --- a/source/blender/nodes/texture/node_texture_util.c +++ b/source/blender/nodes/texture/node_texture_util.c @@ -4,7 +4,7 @@ * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. + * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -29,7 +29,7 @@ * \ingroup nodes */ - + /* * HOW TEXTURE NODES WORK * @@ -112,13 +112,13 @@ void params_from_cdata(TexParams *out, TexCallData *in) out->mtex = in->mtex; } -void tex_do_preview(bNode *node, float *co, float *col) +void tex_do_preview(bNode *node, const float coord[2], const float col[4]) { - bNodePreview *preview= node->preview; + bNodePreview *preview = node->preview; if (preview) { - int xs= ((co[0] + 1.0f)*0.5f)*preview->xsize; - int ys= ((co[1] + 1.0f)*0.5f)*preview->ysize; + int xs = ((coord[0] + 1.0f) * 0.5f) * preview->xsize; + int ys = ((coord[1] + 1.0f) * 0.5f) * preview->ysize; nodeAddToPreview(node, col, xs, ys, 0); /* 0 = no color management */ } @@ -132,19 +132,19 @@ void tex_output(bNode *node, bNodeStack **in, bNodeStack *out, TexFn texfn, TexC dg = out->data = MEM_mallocN(sizeof(TexDelegate), "tex delegate"); else dg = out->data; - - dg->cdata= cdata; + + dg->cdata = cdata; dg->fn = texfn; dg->node = node; - memcpy(dg->in, in, MAX_SOCKET * sizeof(bNodeStack*)); + memcpy(dg->in, in, MAX_SOCKET * sizeof(bNodeStack *)); dg->type = out->sockettype; } void ntreeTexCheckCyclics(struct bNodeTree *ntree) { bNode *node; - for (node= ntree->nodes.first; node; node= node->next) { - + for (node = ntree->nodes.first; node; node = node->next) { + if (node->type == TEX_NODE_TEXTURE && node->id) { /* custom2 stops the node from rendering */ if (node->custom1) { diff --git a/source/blender/nodes/texture/node_texture_util.h b/source/blender/nodes/texture/node_texture_util.h index e938e6fc419..16dbc2f7bfb 100644 --- a/source/blender/nodes/texture/node_texture_util.h +++ b/source/blender/nodes/texture/node_texture_util.h @@ -79,8 +79,10 @@ typedef struct TexCallData { TexResult *target; + /* all float[3] */ float *co; float *dxt, *dyt; + int osatex; char do_preview; short thread; @@ -94,7 +96,7 @@ typedef struct TexCallData { typedef struct TexParams { float *co; float *dxt, *dyt; - float *previewco; + const float *previewco; int cfra; int osatex; @@ -119,7 +121,7 @@ void tex_input_vec(float *out, bNodeStack *in, TexParams *params, short thread); float tex_input_value(bNodeStack *in, TexParams *params, short thread); void tex_output(bNode *node, bNodeStack **in, bNodeStack *out, TexFn texfn, TexCallData *data); -void tex_do_preview(bNode *node, float *coord, float *col); +void tex_do_preview(bNode *node, const float coord[2], const float col[4]); void params_from_cdata(TexParams *out, TexCallData *in); diff --git a/source/blender/nodes/texture/nodes/node_texture_bricks.c b/source/blender/nodes/texture/nodes/node_texture_bricks.c index f6259962529..c575547b3ce 100644 --- a/source/blender/nodes/texture/nodes/node_texture_bricks.c +++ b/source/blender/nodes/texture/nodes/node_texture_bricks.c @@ -66,7 +66,7 @@ static float noise(int n) /* fast integer noise */ static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **in, short thread) { - float *co = p->co; + const float *co = p->co; float x = co[0]; float y = co[1]; diff --git a/source/blender/nodes/texture/nodes/node_texture_proc.c b/source/blender/nodes/texture/nodes/node_texture_proc.c index 102f6e1c428..1f724292661 100644 --- a/source/blender/nodes/texture/nodes/node_texture_proc.c +++ b/source/blender/nodes/texture/nodes/node_texture_proc.c @@ -57,7 +57,7 @@ static bNodeSocketTemplate outputs_color_only[]= { { SOCK_RGBA, 1, "Color 2", 1.0f, 1.0f, 1.0f, 1.0f } /* Calls multitex and copies the result to the outputs. Called by xxx_exec, which handles inputs. */ -static void do_proc(float *result, TexParams *p, float *col1, float *col2, char is_normal, Tex *tex, short thread) +static void do_proc(float *result, TexParams *p, const float col1[4], const float col2[4], char is_normal, Tex *tex, const short thread) { TexResult texres; int textype; @@ -69,7 +69,7 @@ static void do_proc(float *result, TexParams *p, float *col1, float *col2, char texres.nor = NULL; textype = multitex_nodes(tex, p->co, p->dxt, p->dyt, p->osatex, - &texres, thread, 0, p->shi, p->mtex); + &texres, thread, 0, p->shi, p->mtex); if (is_normal) return; @@ -83,7 +83,7 @@ static void do_proc(float *result, TexParams *p, float *col1, float *col2, char } } -typedef void (*MapFn) (Tex *tex, bNodeStack **in, TexParams *p, short thread); +typedef void (*MapFn) (Tex *tex, bNodeStack **in, TexParams *p, const short thread); static void texfn( float *result, diff --git a/source/blender/nodes/texture/nodes/node_texture_rotate.c b/source/blender/nodes/texture/nodes/node_texture_rotate.c index a7832c8c180..2f997d36e71 100644 --- a/source/blender/nodes/texture/nodes/node_texture_rotate.c +++ b/source/blender/nodes/texture/nodes/node_texture_rotate.c @@ -47,7 +47,7 @@ static bNodeSocketTemplate outputs[]= { { -1, 0, "" } }; -static void rotate(float new_co[3], float a, float ax[3], float co[3]) +static void rotate(float new_co[3], float a, float ax[3], const float co[3]) { float para[3]; float perp[3]; diff --git a/source/blender/nodes/texture/nodes/node_texture_valToNor.c b/source/blender/nodes/texture/nodes/node_texture_valToNor.c index 2d107b87578..73dcc72eb40 100644 --- a/source/blender/nodes/texture/nodes/node_texture_valToNor.c +++ b/source/blender/nodes/texture/nodes/node_texture_valToNor.c @@ -47,7 +47,7 @@ static bNodeSocketTemplate outputs[]= { static void normalfn(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack **in, short thread) { float new_co[3]; - float *co = p->co; + const float *co = p->co; float nabla = tex_input_value(in[1], p, thread); float val; diff --git a/source/blender/python/mathutils/mathutils_Color.c b/source/blender/python/mathutils/mathutils_Color.c index 8b5e39fbd27..c14b4a0686b 100644 --- a/source/blender/python/mathutils/mathutils_Color.c +++ b/source/blender/python/mathutils/mathutils_Color.c @@ -858,7 +858,7 @@ PyTypeObject color_Type = { * (i.e. it was allocated elsewhere by MEM_mallocN()) * pass Py_NEW - if vector is not a WRAPPER and managed by PYTHON * (i.e. it must be created here with PyMEM_malloc())*/ -PyObject *Color_CreatePyObject(float *col, int type, PyTypeObject *base_type) +PyObject *Color_CreatePyObject(float col[3], int type, PyTypeObject *base_type) { ColorObject *self; diff --git a/source/blender/python/mathutils/mathutils_Color.h b/source/blender/python/mathutils/mathutils_Color.h index eff09c25a99..d753b60d195 100644 --- a/source/blender/python/mathutils/mathutils_Color.h +++ b/source/blender/python/mathutils/mathutils_Color.h @@ -47,7 +47,7 @@ typedef struct { * blender (stored in blend_data). This is an either/or struct not both*/ //prototypes -PyObject *Color_CreatePyObject(float *col, int type, PyTypeObject *base_type); +PyObject *Color_CreatePyObject(float col[3], int type, PyTypeObject *base_type); PyObject *Color_CreatePyObject_cb(PyObject *cb_user, unsigned char cb_type, unsigned char cb_subtype); diff --git a/source/blender/render/extern/include/RE_shader_ext.h b/source/blender/render/extern/include/RE_shader_ext.h index 57fb80f11c0..10045a8f7e1 100644 --- a/source/blender/render/extern/include/RE_shader_ext.h +++ b/source/blender/render/extern/include/RE_shader_ext.h @@ -191,12 +191,12 @@ struct MTex; struct ImBuf; /* this one uses nodes */ -int multitex_ext(struct Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, struct TexResult *texres); +int multitex_ext(struct Tex *tex, float texvec[3], float dxt[3], float dyt[3], int osatex, struct TexResult *texres); /* nodes disabled */ -int multitex_ext_safe(struct Tex *tex, float *texvec, struct TexResult *texres); +int multitex_ext_safe(struct Tex *tex, float texvec[3], struct TexResult *texres); /* only for internal node usage */ -int multitex_nodes(struct Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, struct TexResult *texres, - short thread, short which_output, struct ShadeInput *shi, struct MTex *mtex); +int multitex_nodes(struct Tex *tex, float texvec[3], float dxt[3], float dyt[3], int osatex, struct TexResult *texres, + const short thread, short which_output, struct ShadeInput *shi, struct MTex *mtex); /* shaded view and bake */ struct Render; diff --git a/source/blender/render/intern/include/envmap.h b/source/blender/render/intern/include/envmap.h index 24138884cd2..d0f346f7402 100644 --- a/source/blender/render/intern/include/envmap.h +++ b/source/blender/render/intern/include/envmap.h @@ -46,7 +46,7 @@ struct Render; struct TexResult; void make_envmaps(struct Render *re); -int envmaptex(struct Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, struct TexResult *texres); +int envmaptex(struct Tex *tex, const float texvec[3], float dxt[3], float dyt[3], int osatex, struct TexResult *texres); #endif /* __ENVMAP_H__ */ diff --git a/source/blender/render/intern/include/pointdensity.h b/source/blender/render/intern/include/pointdensity.h index cc8fabda49c..e0c293e2473 100644 --- a/source/blender/render/intern/include/pointdensity.h +++ b/source/blender/render/intern/include/pointdensity.h @@ -43,7 +43,7 @@ struct TexResult; void cache_pointdensity(struct Render *re, struct Tex *tex); void make_pointdensities(struct Render *re); void free_pointdensities(struct Render *re); -int pointdensitytex(struct Tex *tex, float *texvec, struct TexResult *texres); +int pointdensitytex(struct Tex *tex, const float texvec[3], struct TexResult *texres); #endif /* __POINTDENSITY_H__ */ diff --git a/source/blender/render/intern/include/shading.h b/source/blender/render/intern/include/shading.h index a8519d8a7fb..4f6e005d742 100644 --- a/source/blender/render/intern/include/shading.h +++ b/source/blender/render/intern/include/shading.h @@ -60,7 +60,7 @@ void shade_material_loop(struct ShadeInput *shi, struct ShadeResult *shr); void shade_input_set_triangle_i(struct ShadeInput *shi, struct ObjectInstanceRen *obi, struct VlakRen *vlr, short i1, short i2, short i3); void shade_input_set_triangle(struct ShadeInput *shi, volatile int obi, volatile int facenr, int normal_flip); void shade_input_copy_triangle(struct ShadeInput *shi, struct ShadeInput *from); -void shade_input_calc_viewco(struct ShadeInput *shi, float x, float y, float z, float view[3], float *dxyview, float *co, float *dxco, float *dyco); +void shade_input_calc_viewco(struct ShadeInput *shi, float x, float y, float z, float view[3], float dxyview[2], float co[3], float dxco[3], float dyco[3]); void shade_input_set_viewco(struct ShadeInput *shi, float x, float y, float sx, float sy, float z); void shade_input_set_uv(struct ShadeInput *shi); void shade_input_set_normals(struct ShadeInput *shi); diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c index 96b33a0bf1a..910307f370b 100644 --- a/source/blender/render/intern/source/envmap.c +++ b/source/blender/render/intern/source/envmap.c @@ -643,31 +643,31 @@ static int envcube_isect(EnvMap *env, const float vec[3], float answ[2]) /* ------------------------------------------------------------------------- */ -static void set_dxtdyt(float *dxts, float *dyts, float *dxt, float *dyt, int face) +static void set_dxtdyt(float r_dxt[3], float r_dyt[3], const float dxt[3], const float dyt[3], int face) { if (face == 2 || face == 4) { - dxts[0] = dxt[0]; - dyts[0] = dyt[0]; - dxts[1] = dxt[2]; - dyts[1] = dyt[2]; + r_dxt[0] = dxt[0]; + r_dyt[0] = dyt[0]; + r_dxt[1] = dxt[2]; + r_dyt[1] = dyt[2]; } else if (face == 3 || face == 5) { - dxts[0] = dxt[1]; - dxts[1] = dxt[2]; - dyts[0] = dyt[1]; - dyts[1] = dyt[2]; + r_dxt[0] = dxt[1]; + r_dxt[1] = dxt[2]; + r_dyt[0] = dyt[1]; + r_dyt[1] = dyt[2]; } else { - dxts[0] = dxt[0]; - dyts[0] = dyt[0]; - dxts[1] = dxt[1]; - dyts[1] = dyt[1]; + r_dxt[0] = dxt[0]; + r_dyt[0] = dyt[0]; + r_dxt[1] = dxt[1]; + r_dyt[1] = dyt[1]; } } /* ------------------------------------------------------------------------- */ -int envmaptex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexResult *texres) +int envmaptex(Tex *tex, const float texvec[3], float dxt[3], float dyt[3], int osatex, TexResult *texres) { extern Render R; /* only in this call */ /* texvec should be the already reflected normal */ diff --git a/source/blender/render/intern/source/pointdensity.c b/source/blender/render/intern/source/pointdensity.c index ea92be6153c..f8462dcd888 100644 --- a/source/blender/render/intern/source/pointdensity.c +++ b/source/blender/render/intern/source/pointdensity.c @@ -406,7 +406,7 @@ static void init_pointdensityrangedata(PointDensity *pd, PointDensityRangeData * } -int pointdensitytex(Tex *tex, float *texvec, TexResult *texres) +int pointdensitytex(Tex *tex, const float texvec[3], TexResult *texres) { int retval = TEX_INT; PointDensity *pd = tex->pd; diff --git a/source/blender/render/intern/source/render_texture.c b/source/blender/render/intern/source/render_texture.c index 030b7d68163..91da5c50d01 100644 --- a/source/blender/render/intern/source/render_texture.c +++ b/source/blender/render/intern/source/render_texture.c @@ -185,7 +185,7 @@ static void tex_normal_derivate(Tex *tex, TexResult *texres) -static int blend(Tex *tex, float *texvec, TexResult *texres) +static int blend(Tex *tex, const float texvec[3], TexResult *texres) { float x, y, t; @@ -237,7 +237,7 @@ static int blend(Tex *tex, float *texvec, TexResult *texres) /* newnoise: all noisebased types now have different noisebases to choose from */ -static int clouds(Tex *tex, float *texvec, TexResult *texres) +static int clouds(Tex *tex, const float texvec[3], TexResult *texres) { int rv = TEX_INT; @@ -332,7 +332,7 @@ static float wood_int(Tex *tex, float x, float y, float z) return wi; } -static int wood(Tex *tex, float *texvec, TexResult *texres) +static int wood(Tex *tex, const float texvec[3], TexResult *texres) { int rv=TEX_INT; @@ -383,7 +383,7 @@ static float marble_int(Tex *tex, float x, float y, float z) return mi; } -static int marble(Tex *tex, float *texvec, TexResult *texres) +static int marble(Tex *tex, const float texvec[3], TexResult *texres) { int rv=TEX_INT; @@ -407,7 +407,7 @@ static int marble(Tex *tex, float *texvec, TexResult *texres) /* ------------------------------------------------------------------------- */ -static int magic(Tex *tex, float *texvec, TexResult *texres) +static int magic(Tex *tex, const float texvec[3], TexResult *texres) { float x, y, z, turb=1.0; int n; @@ -483,7 +483,7 @@ static int magic(Tex *tex, float *texvec, TexResult *texres) /* ------------------------------------------------------------------------- */ /* newnoise: stucci also modified to use different noisebasis */ -static int stucci(Tex *tex, float *texvec, TexResult *texres) +static int stucci(Tex *tex, const float texvec[3], TexResult *texres) { float nor[3], b2, ofs; int retval= TEX_INT; @@ -525,7 +525,7 @@ static int stucci(Tex *tex, float *texvec, TexResult *texres) /* ------------------------------------------------------------------------- */ /* newnoise: musgrave terrain noise types */ -static float mg_mFractalOrfBmTex(Tex *tex, float *texvec, TexResult *texres) +static float mg_mFractalOrfBmTex(Tex *tex, const float texvec[3], TexResult *texres) { int rv = TEX_INT; float (*mgravefunc)(float, float, float, float, float, float, int); @@ -555,7 +555,7 @@ static float mg_mFractalOrfBmTex(Tex *tex, float *texvec, TexResult *texres) } -static float mg_ridgedOrHybridMFTex(Tex *tex, float *texvec, TexResult *texres) +static float mg_ridgedOrHybridMFTex(Tex *tex, const float texvec[3], TexResult *texres) { int rv = TEX_INT; float (*mgravefunc)(float, float, float, float, float, float, float, float, int); @@ -586,7 +586,7 @@ static float mg_ridgedOrHybridMFTex(Tex *tex, float *texvec, TexResult *texres) } -static float mg_HTerrainTex(Tex *tex, float *texvec, TexResult *texres) +static float mg_HTerrainTex(Tex *tex, const float texvec[3], TexResult *texres) { int rv = TEX_INT; @@ -611,7 +611,7 @@ static float mg_HTerrainTex(Tex *tex, float *texvec, TexResult *texres) } -static float mg_distNoiseTex(Tex *tex, float *texvec, TexResult *texres) +static float mg_distNoiseTex(Tex *tex, const float texvec[3], TexResult *texres) { int rv = TEX_INT; @@ -640,7 +640,7 @@ static float mg_distNoiseTex(Tex *tex, float *texvec, TexResult *texres) /* ------------------------------------------------------------------------- */ /* newnoise: Voronoi texture type, probably the slowest, especially with minkovsky, bumpmapping, could be done another way */ -static float voronoiTex(Tex *tex, float *texvec, TexResult *texres) +static float voronoiTex(Tex *tex, const float texvec[3], TexResult *texres) { int rv = TEX_INT; float da[4], pa[12]; /* distance and point coordinate arrays of 4 nearest neighbors */ @@ -869,7 +869,7 @@ static int cubemap_ob(Object *ob, const float n[3], float x, float y, float z, f /* ------------------------------------------------------------------------- */ -static void do_2d_mapping(MTex *mtex, float *t, VlakRen *vlr, const float n[3], float *dxt, float *dyt) +static void do_2d_mapping(MTex *mtex, float texvec[3], VlakRen *vlr, const float n[3], float dxt[3], float dyt[3]) { Tex *tex; Object *ob= NULL; @@ -885,15 +885,15 @@ static void do_2d_mapping(MTex *mtex, float *t, VlakRen *vlr, const float n[3], if (R.osa==0) { if (wrap==MTEX_FLAT) { - fx = (t[0] + 1.0f) / 2.0f; - fy = (t[1] + 1.0f) / 2.0f; + fx = (texvec[0] + 1.0f) / 2.0f; + fy = (texvec[1] + 1.0f) / 2.0f; } - else if (wrap == MTEX_TUBE) map_to_tube( &fx, &fy, t[0], t[1], t[2]); - else if (wrap == MTEX_SPHERE) map_to_sphere(&fx, &fy, t[0], t[1], t[2]); + else if (wrap == MTEX_TUBE) map_to_tube( &fx, &fy, texvec[0], texvec[1], texvec[2]); + else if (wrap == MTEX_SPHERE) map_to_sphere(&fx, &fy, texvec[0], texvec[1], texvec[2]); else { - if (texco == TEXCO_OBJECT) cubemap_ob(ob, n, t[0], t[1], t[2], &fx, &fy); - else if (texco == TEXCO_GLOB) cubemap_glob(n, t[0], t[1], t[2], &fx, &fy); - else cubemap(mtex, vlr, n, t[0], t[1], t[2], &fx, &fy); + if (texco == TEXCO_OBJECT) cubemap_ob(ob, n, texvec[0], texvec[1], texvec[2], &fx, &fy); + else if (texco == TEXCO_GLOB) cubemap_glob(n, texvec[0], texvec[1], texvec[2], &fx, &fy); + else cubemap(mtex, vlr, n, texvec[0], texvec[1], texvec[2], &fx, &fy); } /* repeat */ @@ -933,14 +933,14 @@ static void do_2d_mapping(MTex *mtex, float *t, VlakRen *vlr, const float n[3], fy= tex->cropymin+ fy*fac1; } - t[0]= fx; - t[1]= fy; + texvec[0]= fx; + texvec[1]= fy; } else { if (wrap==MTEX_FLAT) { - fx= (t[0] + 1.0f) / 2.0f; - fy= (t[1] + 1.0f) / 2.0f; + fx= (texvec[0] + 1.0f) / 2.0f; + fy= (texvec[1] + 1.0f) / 2.0f; dxt[0]/= 2.0f; dxt[1]/= 2.0f; dxt[2]/= 2.0f; @@ -951,13 +951,13 @@ static void do_2d_mapping(MTex *mtex, float *t, VlakRen *vlr, const float n[3], else if (ELEM(wrap, MTEX_TUBE, MTEX_SPHERE)) { /* exception: the seam behind (y<0.0) */ ok= 1; - if (t[1]<=0.0f) { - fx= t[0]+dxt[0]; - fy= t[0]+dyt[0]; - if (fx>=0.0f && fy>=0.0f && t[0]>=0.0f) { + if (texvec[1]<=0.0f) { + fx= texvec[0]+dxt[0]; + fy= texvec[0]+dyt[0]; + if (fx>=0.0f && fy>=0.0f && texvec[0]>=0.0f) { /* pass */ } - else if (fx<=0.0f && fy<=0.0f && t[0]<=0.0f) { + else if (fx<=0.0f && fy<=0.0f && texvec[0]<=0.0f) { /* pass */ } else { @@ -967,20 +967,20 @@ static void do_2d_mapping(MTex *mtex, float *t, VlakRen *vlr, const float n[3], if (ok) { if (wrap==MTEX_TUBE) { - map_to_tube(area, area+1, t[0], t[1], t[2]); - map_to_tube(area + 2, area + 3, t[0] + dxt[0], t[1] + dxt[1], t[2] + dxt[2]); - map_to_tube(area + 4, area + 5, t[0] + dyt[0], t[1] + dyt[1], t[2] + dyt[2]); + map_to_tube(area, area+1, texvec[0], texvec[1], texvec[2]); + map_to_tube(area + 2, area + 3, texvec[0] + dxt[0], texvec[1] + dxt[1], texvec[2] + dxt[2]); + map_to_tube(area + 4, area + 5, texvec[0] + dyt[0], texvec[1] + dyt[1], texvec[2] + dyt[2]); } else { - map_to_sphere(area, area+1, t[0], t[1], t[2]); - map_to_sphere(area + 2, area + 3, t[0] + dxt[0], t[1] + dxt[1], t[2] + dxt[2]); - map_to_sphere(area + 4, area + 5, t[0] + dyt[0], t[1] + dyt[1], t[2] + dyt[2]); + map_to_sphere(area, area+1, texvec[0], texvec[1], texvec[2]); + map_to_sphere(area + 2, area + 3, texvec[0] + dxt[0], texvec[1] + dxt[1], texvec[2] + dxt[2]); + map_to_sphere(area + 4, area + 5, texvec[0] + dyt[0], texvec[1] + dyt[1], texvec[2] + dyt[2]); } areaflag= 1; } else { - if (wrap==MTEX_TUBE) map_to_tube( &fx, &fy, t[0], t[1], t[2]); - else map_to_sphere(&fx, &fy, t[0], t[1], t[2]); + if (wrap==MTEX_TUBE) map_to_tube( &fx, &fy, texvec[0], texvec[1], texvec[2]); + else map_to_sphere(&fx, &fy, texvec[0], texvec[1], texvec[2]); dxt[0]/= 2.0f; dxt[1]/= 2.0f; dyt[0]/= 2.0f; @@ -989,9 +989,9 @@ static void do_2d_mapping(MTex *mtex, float *t, VlakRen *vlr, const float n[3], } else { - if (texco==TEXCO_OBJECT) proj = cubemap_ob(ob, n, t[0], t[1], t[2], &fx, &fy); - else if (texco==TEXCO_GLOB) proj = cubemap_glob(n, t[0], t[1], t[2], &fx, &fy); - else proj = cubemap(mtex, vlr, n, t[0], t[1], t[2], &fx, &fy); + if (texco==TEXCO_OBJECT) proj = cubemap_ob(ob, n, texvec[0], texvec[1], texvec[2], &fx, &fy); + else if (texco==TEXCO_GLOB) proj = cubemap_glob(n, texvec[0], texvec[1], texvec[2], &fx, &fy); + else proj = cubemap(mtex, vlr, n, texvec[0], texvec[1], texvec[2], &fx, &fy); if (proj==1) { SWAP(float, dxt[1], dxt[2]); @@ -1091,111 +1091,111 @@ static void do_2d_mapping(MTex *mtex, float *t, VlakRen *vlr, const float n[3], dyt[1]*= fac1; } - t[0]= fx; - t[1]= fy; + texvec[0]= fx; + texvec[1]= fy; } } /* ************************************** */ -static int multitex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexResult *texres, short thread, short which_output) +static int multitex(Tex *tex, float texvec[3], float dxt[3], float dyt[3], int osatex, TexResult *texres, const short thread, short which_output) { float tmpvec[3]; - int retval=0; /* return value, int:0, col:1, nor:2, everything:3 */ + int retval = 0; /* return value, int:0, col:1, nor:2, everything:3 */ texres->talpha = FALSE; /* is set when image texture returns alpha (considered premul) */ if (tex->use_nodes && tex->nodetree) { retval = ntreeTexExecTree(tex->nodetree, texres, texvec, dxt, dyt, osatex, thread, - tex, which_output, R.r.cfra, (R.r.scemode & R_TEXNODE_PREVIEW) != 0, NULL, NULL); + tex, which_output, R.r.cfra, (R.r.scemode & R_TEXNODE_PREVIEW) != 0, NULL, NULL); } - else - switch (tex->type) { - - case 0: - texres->tin= 0.0f; - return 0; - case TEX_CLOUDS: - retval= clouds(tex, texvec, texres); - break; - case TEX_WOOD: - retval= wood(tex, texvec, texres); - break; - case TEX_MARBLE: - retval= marble(tex, texvec, texres); - break; - case TEX_MAGIC: - retval= magic(tex, texvec, texres); - break; - case TEX_BLEND: - retval= blend(tex, texvec, texres); - break; - case TEX_STUCCI: - retval= stucci(tex, texvec, texres); - break; - case TEX_NOISE: - retval= texnoise(tex, texres); - break; - case TEX_IMAGE: - if (osatex) retval= imagewraposa(tex, tex->ima, NULL, texvec, dxt, dyt, texres); - else retval= imagewrap(tex, tex->ima, NULL, texvec, texres); - BKE_image_tag_time(tex->ima); /* tag image as having being used */ - break; - case TEX_ENVMAP: - retval= envmaptex(tex, texvec, dxt, dyt, osatex, texres); - break; - case TEX_MUSGRAVE: - /* newnoise: musgrave types */ - - /* ton: added this, for Blender convention reason. - * artificer: added the use of tmpvec to avoid scaling texvec - */ - copy_v3_v3(tmpvec, texvec); - mul_v3_fl(tmpvec, 1.0f/tex->noisesize); - - switch (tex->stype) { - case TEX_MFRACTAL: - case TEX_FBM: - retval= mg_mFractalOrfBmTex(tex, tmpvec, texres); - break; - case TEX_RIDGEDMF: - case TEX_HYBRIDMF: - retval= mg_ridgedOrHybridMFTex(tex, tmpvec, texres); - break; - case TEX_HTERRAIN: - retval= mg_HTerrainTex(tex, tmpvec, texres); - break; + else { + switch (tex->type) { + case 0: + texres->tin= 0.0f; + return 0; + case TEX_CLOUDS: + retval = clouds(tex, texvec, texres); + break; + case TEX_WOOD: + retval = wood(tex, texvec, texres); + break; + case TEX_MARBLE: + retval = marble(tex, texvec, texres); + break; + case TEX_MAGIC: + retval = magic(tex, texvec, texres); + break; + case TEX_BLEND: + retval = blend(tex, texvec, texres); + break; + case TEX_STUCCI: + retval = stucci(tex, texvec, texres); + break; + case TEX_NOISE: + retval = texnoise(tex, texres); + break; + case TEX_IMAGE: + if (osatex) retval = imagewraposa(tex, tex->ima, NULL, texvec, dxt, dyt, texres); + else retval = imagewrap(tex, tex->ima, NULL, texvec, texres); + BKE_image_tag_time(tex->ima); /* tag image as having being used */ + break; + case TEX_ENVMAP: + retval = envmaptex(tex, texvec, dxt, dyt, osatex, texres); + break; + case TEX_MUSGRAVE: + /* newnoise: musgrave types */ + + /* ton: added this, for Blender convention reason. + * artificer: added the use of tmpvec to avoid scaling texvec + */ + copy_v3_v3(tmpvec, texvec); + mul_v3_fl(tmpvec, 1.0f / tex->noisesize); + + switch (tex->stype) { + case TEX_MFRACTAL: + case TEX_FBM: + retval = mg_mFractalOrfBmTex(tex, tmpvec, texres); + break; + case TEX_RIDGEDMF: + case TEX_HYBRIDMF: + retval = mg_ridgedOrHybridMFTex(tex, tmpvec, texres); + break; + case TEX_HTERRAIN: + retval = mg_HTerrainTex(tex, tmpvec, texres); + break; + } + break; + /* newnoise: voronoi type */ + case TEX_VORONOI: + /* ton: added this, for Blender convention reason. + * artificer: added the use of tmpvec to avoid scaling texvec + */ + copy_v3_v3(tmpvec, texvec); + mul_v3_fl(tmpvec, 1.0f / tex->noisesize); + + retval = voronoiTex(tex, tmpvec, texres); + break; + case TEX_DISTNOISE: + /* ton: added this, for Blender convention reason. + * artificer: added the use of tmpvec to avoid scaling texvec + */ + copy_v3_v3(tmpvec, texvec); + mul_v3_fl(tmpvec, 1.0f / tex->noisesize); + + retval = mg_distNoiseTex(tex, tmpvec, texres); + break; + case TEX_POINTDENSITY: + retval = pointdensitytex(tex, texvec, texres); + break; + case TEX_VOXELDATA: + retval = voxeldatatex(tex, texvec, texres); + break; + case TEX_OCEAN: + retval = ocean_texture(tex, texvec, texres); + break; } - break; - /* newnoise: voronoi type */ - case TEX_VORONOI: - /* ton: added this, for Blender convention reason. - * artificer: added the use of tmpvec to avoid scaling texvec - */ - copy_v3_v3(tmpvec, texvec); - mul_v3_fl(tmpvec, 1.0f/tex->noisesize); - - retval= voronoiTex(tex, tmpvec, texres); - break; - case TEX_DISTNOISE: - /* ton: added this, for Blender convention reason. - * artificer: added the use of tmpvec to avoid scaling texvec - */ - copy_v3_v3(tmpvec, texvec); - mul_v3_fl(tmpvec, 1.0f/tex->noisesize); - - retval= mg_distNoiseTex(tex, tmpvec, texres); - break; - case TEX_POINTDENSITY: - retval= pointdensitytex(tex, texvec, texres); - break; - case TEX_VOXELDATA: - retval= voxeldatatex(tex, texvec, texres); - break; - case TEX_OCEAN: - retval= ocean_texture(tex, texvec, texres); - break; } if (tex->flag & TEX_COLORBAND) { @@ -1213,7 +1213,8 @@ static int multitex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, } /* this is called from the shader and texture nodes */ -int multitex_nodes(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexResult *texres, short thread, short which_output, ShadeInput *shi, MTex *mtex) +int multitex_nodes(Tex *tex, float texvec[3], float dxt[3], float dyt[3], int osatex, TexResult *texres, + const short thread, short which_output, ShadeInput *shi, MTex *mtex) { if (tex==NULL) { memset(texres, 0, sizeof(TexResult)); @@ -1229,7 +1230,7 @@ int multitex_nodes(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, if (mtex) { /* we have mtex, use it for 2d mapping images only */ do_2d_mapping(mtex, texvec, shi->vlr, shi->facenor, dxt, dyt); - rgbnor= multitex(tex, texvec, dxt, dyt, osatex, texres, thread, which_output); + rgbnor = multitex(tex, texvec, dxt, dyt, osatex, texres, thread, which_output); if (mtex->mapto & (MAP_COL+MAP_COLSPEC+MAP_COLMIR)) { ImBuf *ibuf = BKE_image_get_ibuf(tex->ima, &tex->iuser); @@ -1265,12 +1266,13 @@ int multitex_nodes(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, return rgbnor; } - else + else { return multitex(tex, texvec, dxt, dyt, osatex, texres, thread, which_output); + } } /* this is called for surface shading */ -static int multitex_mtex(ShadeInput *shi, MTex *mtex, float *texvec, float *dxt, float *dyt, TexResult *texres) +static int multitex_mtex(ShadeInput *shi, MTex *mtex, float texvec[3], float dxt[3], float dyt[3], TexResult *texres) { Tex *tex = mtex->tex; @@ -1287,13 +1289,13 @@ static int multitex_mtex(ShadeInput *shi, MTex *mtex, float *texvec, float *dxt, /* Warning, if the texres's values are not declared zero, check the return value to be sure * the color values are set before using the r/g/b values, otherwise you may use uninitialized values - Campbell */ -int multitex_ext(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexResult *texres) +int multitex_ext(Tex *tex, float texvec[3], float dxt[3], float dyt[3], int osatex, TexResult *texres) { return multitex_nodes(tex, texvec, dxt, dyt, osatex, texres, 0, 0, NULL, NULL); } /* extern-tex doesn't support nodes (ntreeBeginExec() can't be called when rendering is going on) */ -int multitex_ext_safe(Tex *tex, float *texvec, TexResult *texres) +int multitex_ext_safe(Tex *tex, float texvec[3], TexResult *texres) { int use_nodes= tex->use_nodes, retval; @@ -1518,7 +1520,8 @@ float texture_value_blend(float tex, float out, float fact, float facg, int blen return in; } -static void texco_mapping(ShadeInput* shi, Tex* tex, MTex* mtex, float* co, float* dx, float* dy, float* texvec, float* dxt, float* dyt) +static void texco_mapping(ShadeInput* shi, Tex* tex, MTex* mtex, + const float co[3], const float dx[3], const float dy[3], float texvec[3], float dxt[3], float dyt[3]) { /* new: first swap coords, then map, then trans/scale */ if (tex->type == TEX_IMAGE) { @@ -1550,10 +1553,10 @@ static void texco_mapping(ShadeInput* shi, Tex* tex, MTex* mtex, float* co, floa texvec[0] = mtex->size[0]*(texvec[0] - 0.5f) + mtex->ofs[0] + 0.5f; texvec[1] = mtex->size[1]*(texvec[1] - 0.5f) + mtex->ofs[1] + 0.5f; if (shi->osatex) { - dxt[0] = mtex->size[0]*dxt[0]; - dxt[1] = mtex->size[1]*dxt[1]; - dyt[0] = mtex->size[0]*dyt[0]; - dyt[1] = mtex->size[1]*dyt[1]; + dxt[0] = mtex->size[0] * dxt[0]; + dxt[1] = mtex->size[1] * dxt[1]; + dyt[0] = mtex->size[0] * dyt[0]; + dyt[1] = mtex->size[1] * dyt[1]; } /* problem: repeat-mirror is not a 'repeat' but 'extend' in imagetexture.c */ @@ -1683,7 +1686,8 @@ static void compatible_bump_uv_derivs(CompatibleBump *compat_bump, ShadeInput *s } } -static int compatible_bump_compute(CompatibleBump *compat_bump, ShadeInput *shi, MTex *mtex, Tex *tex, TexResult *texres, float Tnor, float *co, float *dx, float *dy, float *texvec, float *dxt, float *dyt) +static int compatible_bump_compute(CompatibleBump *compat_bump, ShadeInput *shi, MTex *mtex, Tex *tex, TexResult *texres, + float Tnor, const float co[3], const float dx[3], const float dy[3], float texvec[3], float dxt[3], float dyt[3]) { TexResult ttexr = {0, 0, 0, 0, 0, texres->talpha, NULL}; /* temp TexResult */ float tco[3], texv[3], cd, ud, vd, du, dv, idu, idv; @@ -1839,7 +1843,7 @@ static void ntap_bump_init(NTapBump *ntap_bump) memset(ntap_bump, 0, sizeof(*ntap_bump)); } -static int ntap_bump_compute(NTapBump *ntap_bump, ShadeInput *shi, MTex *mtex, Tex *tex, TexResult *texres, float Tnor, float *co, float *dx, float *dy, float *texvec, float *dxt, float *dyt) +static int ntap_bump_compute(NTapBump *ntap_bump, ShadeInput *shi, MTex *mtex, Tex *tex, TexResult *texres, float Tnor, float *co, float *dx, float *dy, float texvec[3], float dxt[3], float dyt[3]) { TexResult ttexr = {0, 0, 0, 0, 0, texres->talpha, NULL}; /* temp TexResult */ diff --git a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h index adfaf7e3eea..7195524ceae 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h +++ b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h @@ -72,26 +72,26 @@ public: void ProcessLighting(RAS_IRasterizer *rasty, bool uselights, const MT_Transform& viewmat); void RenderText3D(int fontid, - const char* text, - int size, - int dpi, - float* color, - double* mat, - float aspect); + const char* text, + int size, + int dpi, + float* color, + double* mat, + float aspect); void RenderText2D(RAS_TEXT_RENDER_MODE mode, - const char* text, - int xco, - int yco, - int width, - int height); + const char* text, + int xco, + int yco, + int width, + int height); void RenderText(int mode, - class RAS_IPolyMaterial* polymat, - float v1[3], - float v2[3], - float v3[3], - float v4[3], - int glattrib); + class RAS_IPolyMaterial* polymat, + float v1[3], + float v2[3], + float v3[3], + float v4[3], + int glattrib); void applyTransform(RAS_IRasterizer* rasty, double* oglmatrix, int objectdrawmode); int applyLights(int objectlayer, const MT_Transform& viewmat); From 6533ebff28f2f7826f17280eeb7da09a63ba6429 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 15 Oct 2012 23:17:24 +0000 Subject: [PATCH 258/347] code cleanup: picky rna naming convention --- release/scripts/startup/bl_ui/space_userpref.py | 2 +- source/blender/makesrna/intern/rna_userdef.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py index d5dd07610b6..85ea4985715 100644 --- a/release/scripts/startup/bl_ui/space_userpref.py +++ b/release/scripts/startup/bl_ui/space_userpref.py @@ -248,7 +248,7 @@ class USERPREF_PT_interface(Panel): col.prop(view, "show_splash") if os.name == "nt": - col.prop(view, "quit_dialog") + col.prop(view, "use_quit_dialog") class USERPREF_PT_edit(Panel): diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index a2e3116fe6d..e98004db5b7 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -2510,7 +2510,7 @@ static void rna_def_userdef_view(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Sub Level Menu Open Delay", "Time delay in 1/10 seconds before automatically opening sub level menus"); - prop = RNA_def_property(srna, "quit_dialog", PROP_BOOLEAN, PROP_NONE); + prop = RNA_def_property(srna, "use_quit_dialog", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "uiflag", USER_QUIT_PROMPT); RNA_def_property_ui_text(prop, "Prompt Quit", "Asks for confirmation when quitting through the window close button"); @@ -2745,7 +2745,7 @@ static void rna_def_userdef_edit(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "autokey_flag", AUTOKEY_FLAG_INSERTAVAIL); RNA_def_property_ui_text(prop, "Auto Keyframe Insert Available", "Automatic keyframe insertion in available F-Curves"); - + prop = RNA_def_property(srna, "use_auto_keying_warning", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna(prop, NULL, "autokey_flag", AUTOKEY_FLAG_NOWARNING); RNA_def_property_ui_text(prop, "Show Auto Keying Warning", @@ -2783,7 +2783,7 @@ static void rna_def_userdef_edit(BlenderRNA *brna) RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", USER_NONEGFRAMES); RNA_def_property_ui_text(prop, "Allow Negative Frames", "Current frame number can be manually set to a negative value"); - + /* fcurve opacity */ prop = RNA_def_property(srna, "fcurve_unselected_alpha", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, NULL, "fcu_inactive_alpha"); From 1de76baf88c96184f579884d50e08b2b463d89eb Mon Sep 17 00:00:00 2001 From: Nicholas Bishop Date: Mon, 15 Oct 2012 23:50:09 +0000 Subject: [PATCH 259/347] Add BMesh and WM symmetrize operators * The symmetrize operation makes the input mesh elements symmetrical, but unlike mirroring it only copies in one direction. The edges and faces that cross the plane of symmetry are split as needed to enforce symmetry. * The symmetrize operator can be controlled with the "direction" property, which combines the choices of symmetry plane and positive-negative/negative-positive. The enum for this is BMO_SymmDirection. * Added menu items in the top-level Mesh menu and the WKEY specials menu. * Documentation: http://wiki.blender.org/index.php/User:Nicholasbishop/Symmetrize * Reviewed by Brecht: https://codereview.appspot.com/6618059 --- release/scripts/startup/bl_ui/space_view3d.py | 3 +- source/blender/bmesh/CMakeLists.txt | 1 + source/blender/bmesh/intern/bmesh_opdefines.c | 24 + .../blender/bmesh/intern/bmesh_operator_api.h | 10 + .../bmesh/intern/bmesh_operators_private.h | 1 + .../blender/bmesh/operators/bmo_symmetrize.c | 663 ++++++++++++++++++ source/blender/editors/mesh/editmesh_tools.c | 53 ++ source/blender/editors/mesh/mesh_intern.h | 2 + source/blender/editors/mesh/mesh_ops.c | 2 + 9 files changed, 758 insertions(+), 1 deletion(-) create mode 100644 source/blender/bmesh/operators/bmo_symmetrize.c diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index f0ee965aa54..e96bc696087 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -1668,7 +1668,7 @@ class VIEW3D_MT_edit_mesh(Menu): layout.menu("VIEW3D_MT_uv_map", text="UV Unwrap...") layout.separator() - + layout.operator("mesh.symmetrize") layout.operator("view3d.edit_mesh_extrude_move_normal", text="Extrude Region") layout.operator("view3d.edit_mesh_extrude_individual_move", text="Extrude Individual") layout.operator("mesh.duplicate_move") @@ -1719,6 +1719,7 @@ class VIEW3D_MT_edit_mesh_specials(Menu): layout.operator("mesh.shape_propagate_to_all") layout.operator("mesh.select_vertex_path") layout.operator("mesh.sort_elements") + layout.operator("mesh.symmetrize") class VIEW3D_MT_edit_mesh_select_mode(Menu): diff --git a/source/blender/bmesh/CMakeLists.txt b/source/blender/bmesh/CMakeLists.txt index 4bce7a6ff51..c23eb605614 100644 --- a/source/blender/bmesh/CMakeLists.txt +++ b/source/blender/bmesh/CMakeLists.txt @@ -52,6 +52,7 @@ set(SRC operators/bmo_mirror.c operators/bmo_primitive.c operators/bmo_removedoubles.c + operators/bmo_symmetrize.c operators/bmo_subdivide.c operators/bmo_subdivide.h operators/bmo_triangulate.c diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c index 362157ad71b..f50de0d6ee4 100644 --- a/source/blender/bmesh/intern/bmesh_opdefines.c +++ b/source/blender/bmesh/intern/bmesh_opdefines.c @@ -1182,6 +1182,29 @@ static BMOpDefine bmo_convex_hull_def = { 0 }; +/* + * Symmetrize + * + * Mekes the mesh elements in the "input" slot symmetrical. Unlike + * normal mirroring, it only copies in one direction, as specified by + * the "direction" slot. The edges and faces that cross the plane of + * symmetry are split as needed to enforce symmetry. + * + * All new vertices, edges, and faces are added to the "geomout" slot. + */ +static BMOpDefine bmo_symmetrize_def = { + "symmetrize", + {{BMO_OP_SLOT_ELEMENT_BUF, "input"}, + {BMO_OP_SLOT_INT, "direction"}, + + /* Outputs */ + {BMO_OP_SLOT_ELEMENT_BUF, "geomout"}, + + {0} /* null-terminating sentinel */}, + bmo_symmetrize_exec, + 0 +}; + BMOpDefine *opdefines[] = { &bmo_automerge_def, &bmo_average_vert_facedata_def, @@ -1246,6 +1269,7 @@ BMOpDefine *opdefines[] = { &bmo_split_def, &bmo_split_edges_def, &bmo_subdivide_edges_def, + &bmo_symmetrize_def, &bmo_transform_def, &bmo_translate_def, &bmo_triangle_fill_def, diff --git a/source/blender/bmesh/intern/bmesh_operator_api.h b/source/blender/bmesh/intern/bmesh_operator_api.h index 0674103162c..a2f4cdc8c6a 100644 --- a/source/blender/bmesh/intern/bmesh_operator_api.h +++ b/source/blender/bmesh/intern/bmesh_operator_api.h @@ -266,6 +266,16 @@ enum { DEL_ONLYTAGGED }; +typedef enum { + BMO_SYMMETRIZE_NEGATIVE_X, + BMO_SYMMETRIZE_NEGATIVE_Y, + BMO_SYMMETRIZE_NEGATIVE_Z, + + BMO_SYMMETRIZE_POSITIVE_X, + BMO_SYMMETRIZE_POSITIVE_Y, + BMO_SYMMETRIZE_POSITIVE_Z, +} BMO_SymmDirection; + void BMO_op_flag_enable(BMesh *bm, BMOperator *op, const int op_flag); void BMO_op_flag_disable(BMesh *bm, BMOperator *op, const int op_flag); diff --git a/source/blender/bmesh/intern/bmesh_operators_private.h b/source/blender/bmesh/intern/bmesh_operators_private.h index dc1bdaa4689..fa239bb6ceb 100644 --- a/source/blender/bmesh/intern/bmesh_operators_private.h +++ b/source/blender/bmesh/intern/bmesh_operators_private.h @@ -96,6 +96,7 @@ void bmo_spin_exec(BMesh *bm, BMOperator *op); void bmo_split_edges_exec(BMesh *bm, BMOperator *op); void bmo_split_exec(BMesh *bm, BMOperator *op); void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op); +void bmo_symmetrize_exec(BMesh *bm, BMOperator *op); void bmo_transform_exec(BMesh *bm, BMOperator *op); void bmo_translate_exec(BMesh *bm, BMOperator *op); void bmo_triangle_fill_exec(BMesh *bm, BMOperator *op); diff --git a/source/blender/bmesh/operators/bmo_symmetrize.c b/source/blender/bmesh/operators/bmo_symmetrize.c new file mode 100644 index 00000000000..2a1cc801316 --- /dev/null +++ b/source/blender/bmesh/operators/bmo_symmetrize.c @@ -0,0 +1,663 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Nicholas Bishop + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include "MEM_guardedalloc.h" + +#include "BLI_array.h" +#include "BLI_math.h" +#include "BLI_utildefines.h" + +#include "bmesh.h" +#include "intern/bmesh_operators_private.h" + +enum { + SYMM_OUTPUT_GEOM = (1 << 0) +}; + +/* Note: don't think there's much need to make these user-adjustable? */ +#define SYMM_AXIS_THRESHOLD 0.00002f +#define SYMM_VERT_THRESHOLD 0.00002f + +typedef enum { + /* Coordinate lies on the side being copied from */ + SYMM_SIDE_KEEP, + /* Coordinate lies on the side being copied from and within the + * axis threshold */ + SYMM_SIDE_AXIS, + /* Coordinate lies on the side being copied to */ + SYMM_SIDE_KILL +} SymmSide; + +typedef struct { + BMesh *bm; + BMOperator *op; + + int axis; + BMO_SymmDirection direction; + + /* Maps from input vertices to their mirrors. If the vertex + * doesn't have a mirror, it's not in this map. If the vertex is + * within the axis threshold, it's mapped to itself. */ + GHash *vert_symm_map; + + /* Edges that cross the symmetry plane and are asymmetric get + * split. This map goes from input edges to output vertices. If an + * edge is not split, it's not in this map. */ + GHash *edge_split_map; +} Symm; + +/* Return which side the coordinate lies on */ +static SymmSide symm_co_side(const Symm *symm, + const float *co) +{ + float comp = co[symm->axis]; + if (ELEM3(symm->direction, + BMO_SYMMETRIZE_NEGATIVE_X, + BMO_SYMMETRIZE_NEGATIVE_Y, + BMO_SYMMETRIZE_NEGATIVE_Z)) + { + comp = -comp; + } + + if (comp >= 0) { + if (comp < SYMM_AXIS_THRESHOLD) + return SYMM_SIDE_AXIS; + else + return SYMM_SIDE_KEEP; + } + else + return SYMM_SIDE_KILL; +} + +/* Output vertices and the vert_map array */ +static void symm_verts_mirror(Symm *symm) +{ + BMOIter oiter; + BMVert *src_v, *dst_v; + + symm->vert_symm_map = BLI_ghash_ptr_new(AT); + + BMO_ITER (src_v, &oiter, symm->bm, symm->op, "input", BM_VERT) { + SymmSide side = symm_co_side(symm, src_v->co); + float co[3]; + + switch (side) { + case SYMM_SIDE_KEEP: + /* The vertex is outside the axis area; output its mirror */ + copy_v3_v3(co, src_v->co); + co[symm->axis] = -co[symm->axis]; + + dst_v = BM_vert_create(symm->bm, co, src_v); + BMO_elem_flag_enable(symm->bm, dst_v, SYMM_OUTPUT_GEOM); + BLI_ghash_insert(symm->vert_symm_map, src_v, dst_v); + break; + + case SYMM_SIDE_AXIS: + /* The vertex is within the axis area, snap to center */ + src_v->co[symm->axis] = 0; + /* Vertex isn't copied, map to itself */ + BLI_ghash_insert(symm->vert_symm_map, src_v, src_v); + break; + + case SYMM_SIDE_KILL: + /* The vertex does not lie in the half-space being + * copied from, nothing to do */ + break; + } + } +} + +static int symm_edge_crosses_axis(const Symm *symm, const BMEdge *e) +{ + const int sides[2] = {symm_co_side(symm, e->v1->co), + symm_co_side(symm, e->v2->co)}; + + return ((sides[0] != SYMM_SIDE_AXIS) && + (sides[1] != SYMM_SIDE_AXIS) && + (sides[0] != sides[1])); +} + +/* Output edge split vertices for asymmetric edges and the edge_splits + * mapping array */ +static void symm_split_asymmetric_edges(Symm *symm) +{ + BMOIter oiter; + BMEdge *e; + + symm->edge_split_map = BLI_ghash_ptr_new(AT); + + BMO_ITER (e, &oiter, symm->bm, symm->op, "input", BM_EDGE) { + float flipped[3]; + + copy_v3_v3(flipped, e->v1->co); + flipped[symm->axis] = -flipped[symm->axis]; + + if (symm_edge_crosses_axis(symm, e) && + (!compare_v3v3(e->v2->co, flipped, SYMM_VERT_THRESHOLD))) + { + /* Endpoints lie on opposite sides and are asymmetric */ + + BMVert *v; + float lambda = 0, edge_dir[3], co[3]; + float plane_co[3][3][3] = { + /* axis == 0 */ + {{0, 0, 0}, {0, 1, 0}, {0, 0, 1}}, + /* axis == 1 */ + {{0, 0, 0}, {1, 0, 0}, {0, 0, 1}}, + /* axis == 2 */ + {{0, 0, 0}, {1, 0, 0}, {0, 1, 0}}, + }; + int r; + + /* Find intersection of edge with symmetry plane */ + sub_v3_v3v3(edge_dir, e->v2->co, e->v1->co); + normalize_v3(edge_dir); + r = isect_ray_plane_v3(e->v1->co, + edge_dir, + plane_co[symm->axis][0], + plane_co[symm->axis][1], + plane_co[symm->axis][2], + &lambda, TRUE); + BLI_assert(r); + + madd_v3_v3v3fl(co, e->v1->co, edge_dir, lambda); + co[symm->axis] = 0; + + /* Edge is asymmetric, split it with a new vertex */ + v = BM_vert_create(symm->bm, co, e->v1); + BMO_elem_flag_enable(symm->bm, v, SYMM_OUTPUT_GEOM); + BLI_ghash_insert(symm->edge_split_map, e, v); + } + } +} + +static void symm_mirror_edges(Symm *symm) +{ + BMOIter oiter; + BMEdge *e; + + BMO_ITER (e, &oiter, symm->bm, symm->op, "input", BM_EDGE) { + BMVert *v1 = NULL, *v2 = NULL; + BMEdge *e_new; + + v1 = BLI_ghash_lookup(symm->vert_symm_map, e->v1); + v2 = BLI_ghash_lookup(symm->vert_symm_map, e->v2); + + if (v1 && v2) { + e_new = BM_edge_create(symm->bm, v1, v2, e, TRUE); + BMO_elem_flag_enable(symm->bm, e_new, SYMM_OUTPUT_GEOM); + } + else if (v1 || v2) { + if (BLI_ghash_haskey(symm->edge_split_map, e)) { + BMVert *v_split = BLI_ghash_lookup(symm->edge_split_map, e); + + /* Output the keep side of the split edge */ + if (!v1) { + e_new = BM_edge_create(symm->bm, v_split, e->v2, e, TRUE); + BMO_elem_flag_enable(symm->bm, e_new, SYMM_OUTPUT_GEOM); + v1 = v_split; + } + else { + e_new = BM_edge_create(symm->bm, e->v1, v_split, e, TRUE); + BMO_elem_flag_enable(symm->bm, e_new, SYMM_OUTPUT_GEOM); + v2 = v_split; + } + + /* Output the kill side of the split edge */ + e_new = BM_edge_create(symm->bm, v1, v2, e, TRUE); + BMO_elem_flag_enable(symm->bm, e_new, SYMM_OUTPUT_GEOM); + } + } + } +} + +/****************************** SymmPoly ******************************/ + +typedef struct { + /* Indices into the source mvert array (or -1 if not in that array) */ + BMVert **src_verts; + /* Indices into the destination mvert array, these are vertices + * created by an edge split (-1 for vertices not created by edge + * split) */ + BMVert **edge_verts; + + /* Number of vertices in the polygon */ + int len; + + /* True only if none of the polygon's edges were split */ + int already_symmetric; +} SymmPoly; + +static void symm_poly_with_splits(const Symm *symm, + BMFace *f, + SymmPoly *out) +{ + BMIter iter; + BMLoop *l; + int i; + + /* Count vertices and check for edge splits */ + out->len = f->len; + out->already_symmetric = TRUE; + BM_ITER_ELEM (l, &iter, f, BM_LOOPS_OF_FACE) { + if (BLI_ghash_haskey(symm->edge_split_map, l->e)) { + out->len++; + out->already_symmetric = FALSE; + } + } + + i = 0; + BM_ITER_ELEM (l, &iter, f, BM_LOOPS_OF_FACE) { + BMVert *split = BLI_ghash_lookup(symm->edge_split_map, l->e); + + out->src_verts[i] = l->v; + out->edge_verts[i] = NULL; + i++; + + if (split) { + out->src_verts[i] = NULL; + out->edge_verts[i] = split; + i++; + } + } +} + +static const float *symm_poly_co(const SymmPoly *sp, int v) +{ + if (sp->src_verts[v]) + return sp->src_verts[v]->co; + else if (sp->edge_verts[v]) + return sp->edge_verts[v]->co; + else + return NULL; +} + +static SymmSide symm_poly_co_side(const Symm *symm, + const SymmPoly *sp, + int v) +{ + return symm_co_side(symm, symm_poly_co(sp, v)); +} + +/* Return the index of the vertex in the destination array at corner + * 'v' of the polygon, or -1 if not in that array */ +static BMVert *symm_poly_dst(const SymmPoly *sp, int v) +{ + if (sp->edge_verts[v]) + return sp->edge_verts[v]; + else if (sp->src_verts[v]) + return sp->src_verts[v]; + else + return NULL; +} + +/* Same as above, but returns the index of the mirror if available, or + * the same index if on the axis, or -1 otherwise */ +static BMVert *symm_poly_mirror_dst(const Symm *symm, + const SymmPoly *sp, + int v) +{ + if (sp->edge_verts[v]) + return sp->edge_verts[v]; + else if (sp->src_verts[v]) { + if (BLI_ghash_haskey(symm->vert_symm_map, sp->src_verts[v])) + return BLI_ghash_lookup(symm->vert_symm_map, sp->src_verts[v]); + else + return sp->src_verts[v]; + } + else + return NULL; +} + +static int symm_poly_next_crossing(const Symm *symm, + const SymmPoly *sp, + int start, + int *l1, + int *l2) +{ + int i; + + for (i = 0; i < sp->len; i++) { + (*l1) = (start + i) % sp->len; + (*l2) = ((*l1) + 1) % sp->len; + + if ((symm_poly_co_side(symm, sp, *l1) == SYMM_SIDE_KILL) ^ + (symm_poly_co_side(symm, sp, *l2) == SYMM_SIDE_KILL)) + { + return TRUE; + } + } + + BLI_assert(!"symm_poly_next_crossing failed"); + return FALSE; +} + +static BMFace *symm_face_create_v(BMesh *bm, BMVert **fv, BMEdge **fe, int len) +{ + BMFace *f_new; + int i; + + for (i = 0; i < len; i++) { + int j = (i + 1) % len; + fe[i] = BM_edge_exists(fv[i], fv[j]); + if (!fe[i]) { + fe[i] = BM_edge_create(bm, fv[i], fv[j], NULL, FALSE); + BMO_elem_flag_enable(bm, fe[i], SYMM_OUTPUT_GEOM); + } + } + f_new = BM_face_create(bm, fv, fe, len, TRUE); + BM_face_select_set(bm, f_new, TRUE); + BMO_elem_flag_enable(bm, f_new, SYMM_OUTPUT_GEOM); + return f_new; +} + +static void symm_mesh_output_poly_zero_splits(Symm *symm, + SymmPoly *sp, + BMVert **fv, + BMEdge **fe, + int segment_len, + int start) +{ + int i, j; + + j = 0; + + /* Output the keep side of the input polygon */ + for (i = 0; i < segment_len; i++) { + const int offset = (start + i) % sp->len; + BLI_assert(sp->src_verts[offset]); + fv[j++] = sp->src_verts[offset]; + } + + /* Output the kill side of the polygon */ + for (i = segment_len - 1; i >=0; i--) { + const int offset = (start + i) % sp->len; + + if (symm_poly_co_side(symm, sp, offset) == SYMM_SIDE_KEEP) { + BLI_assert(sp->src_verts[offset]); + fv[j++] = BLI_ghash_lookup(symm->vert_symm_map, + sp->src_verts[offset]); + } + } + + symm_face_create_v(symm->bm, fv, fe, j); +} + +static void symm_mesh_output_poly_with_splits(Symm *symm, + SymmPoly *sp, + BMVert **fv, + BMEdge **fe, + int segment_len, + int start) +{ + int i; + + /* Output the keep side of the input polygon */ + + for (i = 0; i < segment_len; i++) { + const int offset = (start + i) % sp->len; + BMVert *v = symm_poly_dst(sp, offset); + + BLI_assert(v); + + fv[i] = v; + } + + symm_face_create_v(symm->bm, fv, fe, segment_len); + + /* Output the kill side of the input polygon */ + + for (i = 0; i < segment_len; i++) { + const int offset = (start + i) % sp->len; + BMVert *v = symm_poly_mirror_dst(symm, sp, offset); + + fv[segment_len - i - 1] = v; + + } + + symm_face_create_v(symm->bm, fv, fe, segment_len); +} + +static void symm_mirror_polygons(Symm *symm) +{ + BMOIter oiter; + BMFace *f; + BMVert **pv = NULL; + BMVert **fv = NULL; + BMEdge **fe = NULL; + BLI_array_declare(pv); + BLI_array_declare(fv); + BLI_array_declare(fe); + + BMO_ITER (f, &oiter, symm->bm, symm->op, "input", BM_FACE) { + BMIter iter; + BMLoop *l; + int mirror_all = TRUE, ignore_all = TRUE; + + /* Check if entire polygon can be mirrored or ignored */ + BM_ITER_ELEM (l, &iter, f, BM_LOOPS_OF_FACE) { + const SymmSide side = symm_co_side(symm, l->v->co); + if (side == SYMM_SIDE_KILL) + mirror_all = FALSE; + else if (side == SYMM_SIDE_KEEP) + ignore_all = FALSE; + } + + if (mirror_all) { + int i; + + /* Make a mirrored copy of the polygon */ + + BLI_array_empty(fv); + BLI_array_empty(fe); + BLI_array_grow_items(fv, f->len); + BLI_array_grow_items(fe, f->len); + + i = f->len; + BM_ITER_ELEM (l, &iter, f, BM_LOOPS_OF_FACE) { + i--; + + if (symm_co_side(symm, l->v->co) == SYMM_SIDE_KEEP) + fv[i] = BLI_ghash_lookup(symm->vert_symm_map, l->v); + else + fv[i] = l->v; + } + + symm_face_create_v(symm->bm, fv, fe, f->len); + } + else if (ignore_all) { + BM_face_kill(symm->bm, f); + } + else { + SymmPoly sp; + int l1, l2, l3, l4; + int double_l2, double_l3; + int segment_len; + + BLI_array_empty(pv); + BLI_array_grow_items(pv, f->len * 4); + sp.src_verts = pv; + sp.edge_verts = pv + f->len * 2; + symm_poly_with_splits(symm, f, &sp); + + /* Find first loop edge crossing the axis */ + symm_poly_next_crossing(symm, &sp, 0, &l1, &l2); + + /* If crossing isn't kill to keep, find the next one */ + if (symm_poly_co_side(symm, &sp, l1) != SYMM_SIDE_KILL) { + symm_poly_next_crossing(symm, &sp, l2, &l1, &l2); + } + + /* Find next crossing (keep to kill) */ + symm_poly_next_crossing(symm, &sp, l2, &l3, &l4); + + if (l2 == l3) + segment_len = 0; + else if (l2 < l3) + segment_len = l3 - l2 + 1; + else + segment_len = (sp.len - l2 + 1) + l3; + + double_l2 = symm_poly_co_side(symm, &sp, l2) == SYMM_SIDE_KEEP; + double_l3 = symm_poly_co_side(symm, &sp, l3) == SYMM_SIDE_KEEP; + + /* Calculate number of new polygons/loops */ + if (segment_len == 0) { + } + else if (sp.already_symmetric) { + int new_loops; + + if (double_l2 && double_l3) + new_loops = segment_len * 2; + else if (!double_l2 && !double_l3) + new_loops = segment_len * 2 - 2; + else + new_loops = segment_len * 2 - 1; + + BLI_array_empty(fv); + BLI_array_empty(fe); + BLI_array_grow_items(fv, new_loops); + BLI_array_grow_items(fe, new_loops); + + symm_mesh_output_poly_zero_splits(symm, &sp, + fv, fe, + segment_len, l2); + BM_face_kill(symm->bm, f); + } + else if (!double_l2 && !double_l3) { + BLI_array_empty(fv); + BLI_array_empty(fe); + BLI_array_grow_items(fv, segment_len); + BLI_array_grow_items(fe, segment_len); + + symm_mesh_output_poly_with_splits(symm, &sp, + fv, fe, + segment_len, + l2); + + BM_face_kill(symm->bm, f); + } + else { + BLI_array_empty(fv); + BLI_array_empty(fe); + BLI_array_grow_items(fv, segment_len); + BLI_array_grow_items(fe, segment_len); + + symm_mesh_output_poly_with_splits(symm, &sp, + fv, fe, + segment_len, + l2); + + BM_face_kill(symm->bm, f); + + /* Output bridge triangle */ + + BLI_array_empty(fv); + BLI_array_empty(fe); + BLI_array_grow_items(fv, 3); + BLI_array_grow_items(fe, 3); + + if (double_l2) { + fv[0] = symm_poly_dst(&sp, l2); + fv[1] = symm_poly_mirror_dst(symm, &sp, l2); + fv[2] = symm_poly_dst(&sp, l3); + } + else if (double_l3) { + fv[0] = symm_poly_dst(&sp, l3); + fv[1] = symm_poly_mirror_dst(symm, &sp, l3); + fv[2] = symm_poly_dst(&sp, l2); + } + + BLI_assert(fv[0] && fv[1] && fv[2]); + + symm_face_create_v(symm->bm, fv, fe, 3); + } + } + } + + BLI_array_free(pv); + BLI_array_free(fv); + BLI_array_free(fe); +} + +/* Remove unused edges and vertices from the side being copied to */ +static void symm_kill_unused(Symm *symm) +{ + BMOIter oiter; + BMEdge *e; + BMVert *v; + + /* Kill unused edges */ + BMO_ITER (e, &oiter, symm->bm, symm->op, "input", BM_EDGE) { + const int crosses = symm_edge_crosses_axis(symm, e); + const int symmetric = (crosses && + (!BLI_ghash_haskey(symm->edge_split_map, e))); + + if (((symm_co_side(symm, e->v1->co) == SYMM_SIDE_KILL) || + (symm_co_side(symm, e->v2->co) == SYMM_SIDE_KILL)) && + !symmetric) + { + /* The edge might be used by a face outside the input set */ + if (BM_edge_face_count(e) == 0) + BM_edge_kill(symm->bm, e); + } + } + + /* Kill unused vertices */ + BMO_ITER (v, &oiter, symm->bm, symm->op, "input", BM_VERT) { + if (symm_co_side(symm, v->co) == SYMM_SIDE_KILL) { + if (BM_vert_edge_count(v) == 0) + BM_vert_kill(symm->bm, v); + } + } +} + +void bmo_symmetrize_exec(BMesh *bm, BMOperator *op) +{ + Symm symm; + BMO_SymmDirection direction = BMO_slot_int_get(op, "direction"); + + symm.bm = bm; + symm.op = op; + symm.axis = (ELEM(direction, + BMO_SYMMETRIZE_NEGATIVE_X, + BMO_SYMMETRIZE_POSITIVE_X) ? 0 : + ELEM(direction, + BMO_SYMMETRIZE_NEGATIVE_Y, + BMO_SYMMETRIZE_POSITIVE_Y) ? 1 : + ELEM(direction, + BMO_SYMMETRIZE_NEGATIVE_Z, + BMO_SYMMETRIZE_POSITIVE_Z) ? 2 : 0); + symm.direction = direction; + + symm_verts_mirror(&symm); + symm_split_asymmetric_edges(&symm); + symm_mirror_edges(&symm); + symm_mirror_polygons(&symm); + symm_kill_unused(&symm); + + BLI_ghash_free(symm.vert_symm_map, NULL, NULL); + BLI_ghash_free(symm.edge_split_map, NULL, NULL); + + BMO_slot_buffer_from_enabled_flag(bm, op, "geomout", BM_ALL, + SYMM_OUTPUT_GEOM); +} diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 69cfe79728e..d8dce98a009 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -41,6 +41,7 @@ #include "RNA_define.h" #include "RNA_access.h" +#include "BLI_array.h" #include "BLI_blenlib.h" #include "BLI_noise.h" #include "BLI_math.h" @@ -50,6 +51,7 @@ #include "BKE_context.h" #include "BKE_cdderivedmesh.h" #include "BKE_depsgraph.h" +#include "BKE_mesh.h" #include "BKE_object.h" #include "BKE_report.h" #include "BKE_texture.h" @@ -5393,3 +5395,54 @@ void MESH_OT_convex_hull(wmOperatorType *ot) join_triangle_props(ot); } + +static int mesh_symmetrize_exec(bContext *C, wmOperator *op) +{ + Object *obedit = CTX_data_edit_object(C); + BMEditMesh *em = BMEdit_FromObject(obedit); + BMOperator bmop; + + EDBM_op_init(em, &bmop, op, "symmetrize input=%hvef direction=%i", + BM_ELEM_SELECT, RNA_enum_get(op->ptr, "direction")); + BMO_op_exec(em->bm, &bmop); + + if (!EDBM_op_finish(em, &bmop, op, TRUE)) { + return OPERATOR_CANCELLED; + } + else { + EDBM_update_generic(C, em, TRUE); + EDBM_selectmode_flush(em); + return OPERATOR_FINISHED; + } +} + +void MESH_OT_symmetrize(struct wmOperatorType *ot) +{ + static EnumPropertyItem direction_items[] = { + {BMO_SYMMETRIZE_NEGATIVE_X, "NEGATIVE_X", 0, "-X to +X", ""}, + {BMO_SYMMETRIZE_POSITIVE_X, "POSITIVE_X", 0, "+X to -X", ""}, + + {BMO_SYMMETRIZE_NEGATIVE_Y, "NEGATIVE_Y", 0, "-Y to +Y", ""}, + {BMO_SYMMETRIZE_POSITIVE_Y, "POSITIVE_Y", 0, "+Y to -Y", ""}, + + {BMO_SYMMETRIZE_NEGATIVE_Z, "NEGATIVE_Z", 0, "-Z to +Z", ""}, + {BMO_SYMMETRIZE_POSITIVE_Z, "POSITIVE_Z", 0, "+Z to -Z", ""}, + {0, NULL, 0, NULL, NULL}, + }; + + /* identifiers */ + ot->name = "Symmetrize"; + ot->description = "Enforce symmetry (both form and topological) across an axis"; + ot->idname = "MESH_OT_symmetrize"; + + /* api callbacks */ + ot->exec = mesh_symmetrize_exec; + ot->poll = ED_operator_editmesh; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + ot->prop = RNA_def_enum(ot->srna, "direction", direction_items, + BMO_SYMMETRIZE_NEGATIVE_X, + "Direction", "Which sides to copy from and to"); +} diff --git a/source/blender/editors/mesh/mesh_intern.h b/source/blender/editors/mesh/mesh_intern.h index 2676316c66d..5fcf4fe4377 100644 --- a/source/blender/editors/mesh/mesh_intern.h +++ b/source/blender/editors/mesh/mesh_intern.h @@ -214,6 +214,8 @@ void MESH_OT_vert_slide(struct wmOperatorType *ot); void MESH_OT_convex_hull(struct wmOperatorType *ot); +void MESH_OT_symmetrize(struct wmOperatorType *ot); + /* ******************* mesh_navmesh.c */ void MESH_OT_navmesh_make(struct wmOperatorType *ot); void MESH_OT_navmesh_face_copy(struct wmOperatorType *ot); diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c index 8ba9b3fe4e7..8a575e57a60 100644 --- a/source/blender/editors/mesh/mesh_ops.c +++ b/source/blender/editors/mesh/mesh_ops.c @@ -166,6 +166,8 @@ void ED_operatortypes_mesh(void) WM_operatortype_append(MESH_OT_convex_hull); + WM_operatortype_append(MESH_OT_symmetrize); + #ifdef WITH_GAMEENGINE WM_operatortype_append(MESH_OT_navmesh_make); WM_operatortype_append(MESH_OT_navmesh_face_copy); From 5e1508528f3fe07a9316f325d85d7dbcdb8f59e2 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 16 Oct 2012 01:56:54 +0000 Subject: [PATCH 260/347] style cleanup --- .../blender/bmesh/operators/bmo_symmetrize.c | 110 +++++++++--------- 1 file changed, 55 insertions(+), 55 deletions(-) diff --git a/source/blender/bmesh/operators/bmo_symmetrize.c b/source/blender/bmesh/operators/bmo_symmetrize.c index 2a1cc801316..a428405fb8b 100644 --- a/source/blender/bmesh/operators/bmo_symmetrize.c +++ b/source/blender/bmesh/operators/bmo_symmetrize.c @@ -67,13 +67,13 @@ typedef struct { /* Return which side the coordinate lies on */ static SymmSide symm_co_side(const Symm *symm, - const float *co) + const float *co) { float comp = co[symm->axis]; if (ELEM3(symm->direction, - BMO_SYMMETRIZE_NEGATIVE_X, - BMO_SYMMETRIZE_NEGATIVE_Y, - BMO_SYMMETRIZE_NEGATIVE_Z)) + BMO_SYMMETRIZE_NEGATIVE_X, + BMO_SYMMETRIZE_NEGATIVE_Y, + BMO_SYMMETRIZE_NEGATIVE_Z)) { comp = -comp; } @@ -129,11 +129,11 @@ static void symm_verts_mirror(Symm *symm) static int symm_edge_crosses_axis(const Symm *symm, const BMEdge *e) { const int sides[2] = {symm_co_side(symm, e->v1->co), - symm_co_side(symm, e->v2->co)}; + symm_co_side(symm, e->v2->co)}; return ((sides[0] != SYMM_SIDE_AXIS) && - (sides[1] != SYMM_SIDE_AXIS) && - (sides[0] != sides[1])); + (sides[1] != SYMM_SIDE_AXIS) && + (sides[0] != sides[1])); } /* Output edge split vertices for asymmetric edges and the edge_splits @@ -152,7 +152,7 @@ static void symm_split_asymmetric_edges(Symm *symm) flipped[symm->axis] = -flipped[symm->axis]; if (symm_edge_crosses_axis(symm, e) && - (!compare_v3v3(e->v2->co, flipped, SYMM_VERT_THRESHOLD))) + (!compare_v3v3(e->v2->co, flipped, SYMM_VERT_THRESHOLD))) { /* Endpoints lie on opposite sides and are asymmetric */ @@ -172,11 +172,11 @@ static void symm_split_asymmetric_edges(Symm *symm) sub_v3_v3v3(edge_dir, e->v2->co, e->v1->co); normalize_v3(edge_dir); r = isect_ray_plane_v3(e->v1->co, - edge_dir, - plane_co[symm->axis][0], - plane_co[symm->axis][1], - plane_co[symm->axis][2], - &lambda, TRUE); + edge_dir, + plane_co[symm->axis][0], + plane_co[symm->axis][1], + plane_co[symm->axis][2], + &lambda, TRUE); BLI_assert(r); madd_v3_v3v3fl(co, e->v1->co, edge_dir, lambda); @@ -248,8 +248,8 @@ typedef struct { } SymmPoly; static void symm_poly_with_splits(const Symm *symm, - BMFace *f, - SymmPoly *out) + BMFace *f, + SymmPoly *out) { BMIter iter; BMLoop *l; @@ -292,8 +292,8 @@ static const float *symm_poly_co(const SymmPoly *sp, int v) } static SymmSide symm_poly_co_side(const Symm *symm, - const SymmPoly *sp, - int v) + const SymmPoly *sp, + int v) { return symm_co_side(symm, symm_poly_co(sp, v)); } @@ -313,8 +313,8 @@ static BMVert *symm_poly_dst(const SymmPoly *sp, int v) /* Same as above, but returns the index of the mirror if available, or * the same index if on the axis, or -1 otherwise */ static BMVert *symm_poly_mirror_dst(const Symm *symm, - const SymmPoly *sp, - int v) + const SymmPoly *sp, + int v) { if (sp->edge_verts[v]) return sp->edge_verts[v]; @@ -329,10 +329,10 @@ static BMVert *symm_poly_mirror_dst(const Symm *symm, } static int symm_poly_next_crossing(const Symm *symm, - const SymmPoly *sp, - int start, - int *l1, - int *l2) + const SymmPoly *sp, + int start, + int *l1, + int *l2) { int i; @@ -341,7 +341,7 @@ static int symm_poly_next_crossing(const Symm *symm, (*l2) = ((*l1) + 1) % sp->len; if ((symm_poly_co_side(symm, sp, *l1) == SYMM_SIDE_KILL) ^ - (symm_poly_co_side(symm, sp, *l2) == SYMM_SIDE_KILL)) + (symm_poly_co_side(symm, sp, *l2) == SYMM_SIDE_KILL)) { return TRUE; } @@ -371,11 +371,11 @@ static BMFace *symm_face_create_v(BMesh *bm, BMVert **fv, BMEdge **fe, int len) } static void symm_mesh_output_poly_zero_splits(Symm *symm, - SymmPoly *sp, - BMVert **fv, - BMEdge **fe, - int segment_len, - int start) + SymmPoly *sp, + BMVert **fv, + BMEdge **fe, + int segment_len, + int start) { int i, j; @@ -389,13 +389,13 @@ static void symm_mesh_output_poly_zero_splits(Symm *symm, } /* Output the kill side of the polygon */ - for (i = segment_len - 1; i >=0; i--) { + for (i = segment_len - 1; i >= 0; i--) { const int offset = (start + i) % sp->len; if (symm_poly_co_side(symm, sp, offset) == SYMM_SIDE_KEEP) { BLI_assert(sp->src_verts[offset]); fv[j++] = BLI_ghash_lookup(symm->vert_symm_map, - sp->src_verts[offset]); + sp->src_verts[offset]); } } @@ -403,11 +403,11 @@ static void symm_mesh_output_poly_zero_splits(Symm *symm, } static void symm_mesh_output_poly_with_splits(Symm *symm, - SymmPoly *sp, - BMVert **fv, - BMEdge **fe, - int segment_len, - int start) + SymmPoly *sp, + BMVert **fv, + BMEdge **fe, + int segment_len, + int start) { int i; @@ -539,8 +539,8 @@ static void symm_mirror_polygons(Symm *symm) BLI_array_grow_items(fe, new_loops); symm_mesh_output_poly_zero_splits(symm, &sp, - fv, fe, - segment_len, l2); + fv, fe, + segment_len, l2); BM_face_kill(symm->bm, f); } else if (!double_l2 && !double_l3) { @@ -550,9 +550,9 @@ static void symm_mirror_polygons(Symm *symm) BLI_array_grow_items(fe, segment_len); symm_mesh_output_poly_with_splits(symm, &sp, - fv, fe, - segment_len, - l2); + fv, fe, + segment_len, + l2); BM_face_kill(symm->bm, f); } @@ -563,9 +563,9 @@ static void symm_mirror_polygons(Symm *symm) BLI_array_grow_items(fe, segment_len); symm_mesh_output_poly_with_splits(symm, &sp, - fv, fe, - segment_len, - l2); + fv, fe, + segment_len, + l2); BM_face_kill(symm->bm, f); @@ -610,11 +610,11 @@ static void symm_kill_unused(Symm *symm) BMO_ITER (e, &oiter, symm->bm, symm->op, "input", BM_EDGE) { const int crosses = symm_edge_crosses_axis(symm, e); const int symmetric = (crosses && - (!BLI_ghash_haskey(symm->edge_split_map, e))); + (!BLI_ghash_haskey(symm->edge_split_map, e))); if (((symm_co_side(symm, e->v1->co) == SYMM_SIDE_KILL) || - (symm_co_side(symm, e->v2->co) == SYMM_SIDE_KILL)) && - !symmetric) + (symm_co_side(symm, e->v2->co) == SYMM_SIDE_KILL)) && + !symmetric) { /* The edge might be used by a face outside the input set */ if (BM_edge_face_count(e) == 0) @@ -639,14 +639,14 @@ void bmo_symmetrize_exec(BMesh *bm, BMOperator *op) symm.bm = bm; symm.op = op; symm.axis = (ELEM(direction, - BMO_SYMMETRIZE_NEGATIVE_X, - BMO_SYMMETRIZE_POSITIVE_X) ? 0 : - ELEM(direction, - BMO_SYMMETRIZE_NEGATIVE_Y, - BMO_SYMMETRIZE_POSITIVE_Y) ? 1 : - ELEM(direction, - BMO_SYMMETRIZE_NEGATIVE_Z, - BMO_SYMMETRIZE_POSITIVE_Z) ? 2 : 0); + BMO_SYMMETRIZE_NEGATIVE_X, + BMO_SYMMETRIZE_POSITIVE_X) ? 0 : + ELEM(direction, + BMO_SYMMETRIZE_NEGATIVE_Y, + BMO_SYMMETRIZE_POSITIVE_Y) ? 1 : + ELEM(direction, + BMO_SYMMETRIZE_NEGATIVE_Z, + BMO_SYMMETRIZE_POSITIVE_Z) ? 2 : 0); symm.direction = direction; symm_verts_mirror(&symm); From af6abc8c8040a993d6b4e4daf18b22e030a48d8a Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 16 Oct 2012 03:21:22 +0000 Subject: [PATCH 261/347] MESH_OT_vert_connect was missing select flush (newly created edges were not selected). also <120 line length for cycles property descriptions. --- intern/cycles/blender/addon/properties.py | 28 ++++++++++++++------ source/blender/editors/mesh/editmesh_tools.c | 9 ++++--- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index f83a3996167..5c68b7f2cb4 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -136,7 +136,8 @@ class CyclesRenderSettings(bpy.types.PropertyGroup): ) cls.blur_glossy = FloatProperty( name="Filter Glossy", - description="Adaptively blur glossy shaders after blurry bounces, to reduce noise at the cost of accuracy", + description="Adaptively blur glossy shaders after blurry bounces, " + "to reduce noise at the cost of accuracy", min=0.0, max=10.0, default=0.0, ) @@ -230,7 +231,9 @@ class CyclesRenderSettings(bpy.types.PropertyGroup): cls.sample_clamp = FloatProperty( name="Clamp", - description="If non-zero, the maximum value for a sample, higher values will be scaled down to avoid too much noise and slow convergence at the cost of accuracy", + description="If non-zero, the maximum value for a sample, " + "higher values will be scaled down to avoid too " + "much noise and slow convergence at the cost of accuracy", min=0.0, max=1e8, default=0.0, ) @@ -244,7 +247,8 @@ class CyclesRenderSettings(bpy.types.PropertyGroup): cls.preview_start_resolution = IntProperty( name="Start Resolution", - description="Resolution to start rendering preview at, progressively increasing it to the full viewport size", + description="Resolution to start rendering preview at, " + "progressively increasing it to the full viewport size", min=8, max=16384, default=64, ) @@ -286,7 +290,10 @@ class CyclesRenderSettings(bpy.types.PropertyGroup): ) cls.use_progressive_refine = BoolProperty( name="Progressive Refine", - description="Instead of rendering each tile until it is finished, refine the whole image progressively. This renders somewhat slower, but time can be saved by manually stopping the render when the noise is low enough.", + description="Instead of rendering each tile until it is finished, " + "refine the whole image progressively. " + "This renders somewhat slower, " + "but time can be saved by manually stopping the render when the noise is low enough", default=False, ) @@ -374,12 +381,15 @@ class CyclesMaterialSettings(bpy.types.PropertyGroup): ) cls.sample_as_light = BoolProperty( name="Sample as Lamp", - description="Use direct light sampling for this material, disabling may reduce overall noise for large objects that emit little light compared to other light sources", + description="Use direct light sampling for this material, " + "disabling may reduce overall noise for large " + "objects that emit little light compared to other light sources", default=True, ) cls.homogeneous_volume = BoolProperty( name="Homogeneous Volume", - description="When using volume rendering, assume volume has the same density everywhere, for faster rendering", + description="When using volume rendering, assume volume has the same density everywhere, " + "for faster rendering", default=False, ) @@ -423,12 +433,14 @@ class CyclesWorldSettings(bpy.types.PropertyGroup): ) cls.sample_as_light = BoolProperty( name="Sample as Lamp", - description="Use direct light sampling for the environment, enabling for non-solid colors is recommended", + description="Use direct light sampling for the environment, " + "enabling for non-solid colors is recommended", default=False, ) cls.sample_map_resolution = IntProperty( name="Map Resolution", - description="Importance map size is resolution x resolution; higher values potentially produce less noise, at the cost of memory and speed", + description="Importance map size is resolution x resolution; " + "higher values potentially produce less noise, at the cost of memory and speed", min=4, max=8096, default=256, ) diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index d8dce98a009..1507597feeb 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -1218,10 +1218,13 @@ static int edbm_vert_connect(bContext *C, wmOperator *op) if (!EDBM_op_finish(em, &bmop, op, TRUE)) { return OPERATOR_CANCELLED; } - - EDBM_update_generic(C, em, TRUE); + else { + EDBM_selectmode_flush(em); /* so newly created edges get the selection state from the vertex */ - return len ? OPERATOR_FINISHED : OPERATOR_CANCELLED; + EDBM_update_generic(C, em, TRUE); + + return len ? OPERATOR_FINISHED : OPERATOR_CANCELLED; + } } void MESH_OT_vert_connect(wmOperatorType *ot) From 64add7c9c79a8f32f0ca68484040bb749b0b728c Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Tue, 16 Oct 2012 07:53:10 +0000 Subject: [PATCH 262/347] More UI messages and BKE_reportf<->BKE_report fixes... --- source/blender/editors/io/io_collada.c | 4 ++-- .../blender/editors/object/object_modifier.c | 2 +- .../blender/editors/physics/dynamicpaint_ops.c | 16 ++++++---------- source/blender/editors/physics/particle_edit.c | 2 +- source/blender/editors/space_clip/clip_ops.c | 8 +++++--- .../blender/editors/space_clip/tracking_ops.c | 2 +- source/blender/editors/space_info/info_ops.c | 2 +- source/blender/editors/space_nla/nla_edit.c | 4 +++- .../editors/space_outliner/outliner_tools.c | 10 +++++----- .../editors/space_view3d/view3d_buttons.c | 2 +- .../blender/editors/space_view3d/view3d_edit.c | 2 +- source/blender/makesrna/intern/rna_main_api.c | 18 ++++++++++-------- 12 files changed, 37 insertions(+), 35 deletions(-) diff --git a/source/blender/editors/io/io_collada.c b/source/blender/editors/io/io_collada.c index 0ec99325752..ba93206e63a 100644 --- a/source/blender/editors/io/io_collada.c +++ b/source/blender/editors/io/io_collada.c @@ -143,7 +143,7 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } else { - BKE_report(op->reports, RPT_WARNING, "Export file not created."); + BKE_report(op->reports, RPT_WARNING, "Export file not created"); return OPERATOR_CANCELLED; } } @@ -307,7 +307,7 @@ static int wm_collada_import_exec(bContext *C, wmOperator *op) RNA_string_get(op->ptr, "filepath", filename); if (collada_import(C, filename)) return OPERATOR_FINISHED; - BKE_report(op->reports, RPT_ERROR, "Errors found during parsing COLLADA document. Please see console for error log."); + BKE_report(op->reports, RPT_ERROR, "Errors found during parsing COLLADA document (see console for details)"); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c index d75ef78fc4c..02070506937 100644 --- a/source/blender/editors/object/object_modifier.c +++ b/source/blender/editors/object/object_modifier.c @@ -1242,7 +1242,7 @@ static int multires_reshape_exec(bContext *C, wmOperator *op) CTX_DATA_END; if (!secondob) { - BKE_report(op->reports, RPT_ERROR, "Second selected mesh object require to copy shape from"); + BKE_report(op->reports, RPT_ERROR, "Second selected mesh object required to copy shape from"); return OPERATOR_CANCELLED; } diff --git a/source/blender/editors/physics/dynamicpaint_ops.c b/source/blender/editors/physics/dynamicpaint_ops.c index 5b69e6745c0..91f1c0b2730 100644 --- a/source/blender/editors/physics/dynamicpaint_ops.c +++ b/source/blender/editors/physics/dynamicpaint_ops.c @@ -346,7 +346,6 @@ static int dynamicPaint_initBake(struct bContext *C, struct wmOperator *op) Object *ob = ED_object_context(C); int status = 0; double timer = PIL_check_seconds_timer(); - char result_str[80]; DynamicPaintSurface *surface; /* @@ -354,14 +353,14 @@ static int dynamicPaint_initBake(struct bContext *C, struct wmOperator *op) */ pmd = (DynamicPaintModifierData *)modifiers_findByType(ob, eModifierType_DynamicPaint); if (!pmd) { - BKE_report(op->reports, RPT_ERROR, "Bake Failed: No Dynamic Paint modifier found."); + BKE_report(op->reports, RPT_ERROR, "Bake failed: no Dynamic Paint modifier found"); return 0; } /* Make sure we're dealing with a canvas */ canvas = pmd->canvas; if (!canvas) { - BKE_report(op->reports, RPT_ERROR, "Bake Failed: Invalid Canvas."); + BKE_report(op->reports, RPT_ERROR, "Bake failed: invalid canvas"); return 0; } surface = get_activeSurface(canvas); @@ -387,17 +386,14 @@ static int dynamicPaint_initBake(struct bContext *C, struct wmOperator *op) BLI_timestr(time, time_str); /* Show bake info */ - BLI_snprintf(result_str, sizeof(result_str), "Bake Complete! (%s)", time_str); - BKE_report(op->reports, RPT_INFO, result_str); + BKE_reportf(op->reports, RPT_INFO, "Bake complete! (%s)", time_str); } else { if (strlen(canvas->error)) { /* If an error occured */ - BLI_snprintf(result_str, sizeof(result_str), "Bake Failed: %s", canvas->error); - BKE_report(op->reports, RPT_ERROR, result_str); + BKE_reportf(op->reports, RPT_ERROR, "Bake failed: %s", canvas->error); } - else { /* User canceled the bake */ - BLI_strncpy(result_str, "Baking Cancelled!", sizeof(result_str)); - BKE_report(op->reports, RPT_WARNING, result_str); + else { /* User canceled the bake */ + BKE_report(op->reports, RPT_WARNING, "Baking cancelled!"); } } diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c index 1010c0efce4..7343a44470a 100644 --- a/source/blender/editors/physics/particle_edit.c +++ b/source/blender/editors/physics/particle_edit.c @@ -2414,7 +2414,7 @@ static int remove_doubles_exec(bContext *C, wmOperator *op) if (totremoved == 0) return OPERATOR_CANCELLED; - BKE_reportf(op->reports, RPT_INFO, "Remove %d double particles", totremoved); + BKE_reportf(op->reports, RPT_INFO, "Removed %d double particles", totremoved); DAG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_EDITED, ob); diff --git a/source/blender/editors/space_clip/clip_ops.c b/source/blender/editors/space_clip/clip_ops.c index c67ee5c8a81..37eb0bcb7c1 100644 --- a/source/blender/editors/space_clip/clip_ops.c +++ b/source/blender/editors/space_clip/clip_ops.c @@ -41,6 +41,8 @@ #include "BLI_math.h" #include "BLI_rect.h" +#include "BLF_translation.h" + #include "BKE_context.h" #include "BKE_global.h" #include "BKE_report.h" @@ -180,7 +182,7 @@ static int open_exec(bContext *C, wmOperator *op) BLI_join_dirfile(str, sizeof(str), dir_only, file_only); } else { - BKE_reportf(op->reports, RPT_ERROR, "No files selected to be opened"); + BKE_report(op->reports, RPT_ERROR, "No files selected to be opened"); return OPERATOR_CANCELLED; } @@ -195,8 +197,8 @@ static int open_exec(bContext *C, wmOperator *op) if (op->customdata) MEM_freeN(op->customdata); - BKE_reportf(op->reports, RPT_ERROR, "Can't read: \"%s\", %s.", str, - errno ? strerror(errno) : "Unsupported movie clip format"); + BKE_reportf(op->reports, RPT_ERROR, "Can't read \"%s\": %s", str, + errno ? strerror(errno) : TIP_("Unsupported movie clip format")); return OPERATOR_CANCELLED; } diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c index 857d88a9a79..c061125b4d5 100644 --- a/source/blender/editors/space_clip/tracking_ops.c +++ b/source/blender/editors/space_clip/tracking_ops.c @@ -1400,7 +1400,7 @@ static void solve_camera_freejob(void *scv) if (!solved) BKE_report(scj->reports, RPT_WARNING, "Some data failed to reconstruct, see console for details"); else - BKE_reportf(scj->reports, RPT_INFO, "Average re-projection error %.3f", tracking->reconstruction.error); + BKE_reportf(scj->reports, RPT_INFO, "Average re-projection error: %.3f", tracking->reconstruction.error); /* set currently solved clip as active for scene */ if (scene->clip) diff --git a/source/blender/editors/space_info/info_ops.c b/source/blender/editors/space_info/info_ops.c index fe36bc98144..bb2d55fa0f6 100644 --- a/source/blender/editors/space_info/info_ops.c +++ b/source/blender/editors/space_info/info_ops.c @@ -150,7 +150,7 @@ static int unpack_all_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event) count = countPackedFiles(bmain); if (!count) { - BKE_report(op->reports, RPT_WARNING, "No packed files. Auto-pack disabled"); + BKE_report(op->reports, RPT_WARNING, "No packed files (auto-pack disabled)"); G.fileflags &= ~G_AUTOPACK; return OPERATOR_CANCELLED; } diff --git a/source/blender/editors/space_nla/nla_edit.c b/source/blender/editors/space_nla/nla_edit.c index ebc4383d143..e0e5007aff0 100644 --- a/source/blender/editors/space_nla/nla_edit.c +++ b/source/blender/editors/space_nla/nla_edit.c @@ -405,7 +405,9 @@ static int nlaedit_add_actionclip_exec(bContext *C, wmOperator *op) else if (act->idroot == 0) { /* hopefully in this case (i.e. library of userless actions), the user knows what they're doing... */ BKE_reportf(op->reports, RPT_WARNING, - "Action '%s' does not specify what datablocks it can be used on. Try setting the 'ID Root Type' setting from the Datablocks Editor for this Action to avoid future problems", + "Action '%s' does not specify what datablocks it can be used on " + "(try setting the 'ID Root Type' setting from the Datablocks Editor " + "for this Action to avoid future problems)", act->id.name + 2); } diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c index 9b689c359bc..e4cd971dbd5 100644 --- a/source/blender/editors/space_outliner/outliner_tools.c +++ b/source/blender/editors/space_outliner/outliner_tools.c @@ -811,7 +811,7 @@ static int outliner_id_operation_exec(bContext *C, wmOperator *op) ED_undo_push(C, "Unlink world"); break; default: - BKE_report(op->reports, RPT_WARNING, "Not Yet"); + BKE_report(op->reports, RPT_WARNING, "Not yet"); break; } } @@ -844,7 +844,7 @@ static int outliner_id_operation_exec(bContext *C, wmOperator *op) break; default: - BKE_report(op->reports, RPT_WARNING, "Not Yet"); + BKE_report(op->reports, RPT_WARNING, "Not yet"); break; } } @@ -980,9 +980,9 @@ static int outliner_action_set_exec(bContext *C, wmOperator *op) else if (act->idroot == 0) { /* hopefully in this case (i.e. library of userless actions), the user knows what they're doing... */ BKE_reportf(op->reports, RPT_WARNING, - "Action '%s' does not specify what datablocks it can be used on. " - "Try setting the 'ID Root Type' setting from the Datablocks Editor " - "for this Action to avoid future problems", + "Action '%s' does not specify what datablocks it can be used on " + "(try setting the 'ID Root Type' setting from the Datablocks Editor " + "for this Action to avoid future problems)", act->id.name + 2); } diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c index 0a55df192ea..9755c7d1b7c 100644 --- a/source/blender/editors/space_view3d/view3d_buttons.c +++ b/source/blender/editors/space_view3d/view3d_buttons.c @@ -451,7 +451,7 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float but = uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Mean Tilt:"), 0, yi -= buth + but_margin, 200, buth, &(tfp->ve_median[C_TILT]), -M_PI * 2.0f, M_PI * 2.0f, 1, 3, - TIP_("Tilt (inclination) of curve control points")); + TIP_("Tilt of curve control points")); uiButSetUnitType(but, PROP_UNIT_ROTATION); } /* Lattice... */ diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 2ada1199cb3..2a210ef0ee4 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -2754,7 +2754,7 @@ static int view3d_zoom_border_exec(bContext *C, wmOperator *op) /* no depths to use, we cant do anything! */ if (depth_close == FLT_MAX) { - BKE_report(op->reports, RPT_ERROR, "Depth Too Large"); + BKE_report(op->reports, RPT_ERROR, "Depth too large"); return OPERATOR_CANCELLED; } /* convert border to 3d coordinates */ diff --git a/source/blender/makesrna/intern/rna_main_api.c b/source/blender/makesrna/intern/rna_main_api.c index be8f84fd2a4..d8f7d48a74f 100644 --- a/source/blender/makesrna/intern/rna_main_api.c +++ b/source/blender/makesrna/intern/rna_main_api.c @@ -97,6 +97,8 @@ #include "ED_screen.h" +#include "BLF_translation.h" + static Camera *rna_Main_cameras_new(Main *UNUSED(bmain), const char *name) { ID *id = BKE_camera_add(name); @@ -289,8 +291,8 @@ static Image *rna_Main_images_load(Main *UNUSED(bmain), ReportList *reports, con ima = BKE_image_load(filepath); if (!ima) - BKE_reportf(reports, RPT_ERROR, "Can't read: \"%s\", %s", filepath, - errno ? strerror(errno) : "Unsupported image format"); + BKE_reportf(reports, RPT_ERROR, "Can't read \"%s\": %s", filepath, + errno ? strerror(errno) : TIP_("Unsupported image format")); return ima; } @@ -358,8 +360,8 @@ static VFont *rna_Main_fonts_load(Main *bmain, ReportList *reports, const char * font = BKE_vfont_load(bmain, filepath); if (!font) - BKE_reportf(reports, RPT_ERROR, "Can't read: \"%s\", %s", filepath, - errno ? strerror(errno) : "Unsupported font format"); + BKE_reportf(reports, RPT_ERROR, "Can't read \"%s\": %s", filepath, + errno ? strerror(errno) : TIP_("Unsupported font format")); return font; @@ -468,8 +470,8 @@ static Text *rna_Main_texts_load(Main *bmain, ReportList *reports, const char *f txt = BKE_text_load(filepath, bmain->name); if (!txt) - BKE_reportf(reports, RPT_ERROR, "Can't read: \"%s\", %s", filepath, - errno ? strerror(errno) : "Unable to load text"); + BKE_reportf(reports, RPT_ERROR, "Can't read \"%s\": %s", filepath, + errno ? strerror(errno) : TIP_("Unable to load text")); return txt; } @@ -534,8 +536,8 @@ static MovieClip *rna_Main_movieclip_load(Main *UNUSED(bmain), ReportList *repor clip = BKE_movieclip_file_add(filepath); if (!clip) - BKE_reportf(reports, RPT_ERROR, "Can't read: \"%s\", %s.", filepath, - errno ? strerror(errno) : "Unable to load movie clip"); + BKE_reportf(reports, RPT_ERROR, "Can't read \"%s\": %s", filepath, + errno ? strerror(errno) : TIP_("Unable to load movie clip")); return clip; } From aacdd76c06ddffc8182dd1e1c1ffe1e9144ae7bf Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 16 Oct 2012 09:11:07 +0000 Subject: [PATCH 263/347] fix for 2 cases BM_disk_dissolve() could fail/assert. - when there was a vertex with 2 boundary edges and one manifold edge (vert at the boundary between 2 quads) it could assert. - when there is a vertex with 2 boundary verts connected that both use the same face, it would do nothing. --- source/blender/bmesh/intern/bmesh_mods.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/source/blender/bmesh/intern/bmesh_mods.c b/source/blender/bmesh/intern/bmesh_mods.c index 3195899ef01..91ca7124fc2 100644 --- a/source/blender/bmesh/intern/bmesh_mods.c +++ b/source/blender/bmesh/intern/bmesh_mods.c @@ -130,6 +130,7 @@ int BM_disk_dissolve(BMesh *bm, BMVert *v) /* this code for handling 2 and 3-valence verts * may be totally bad */ if (keepedge == NULL && len == 3) { +#if 0 /* handle specific case for three-valence. solve it by * increasing valence to four. this may be hackish. . */ BMLoop *loop = e->l; @@ -140,6 +141,13 @@ int BM_disk_dissolve(BMesh *bm, BMVert *v) if (!BM_disk_dissolve(bm, v)) { return FALSE; } +#else + BM_faces_join_pair(bm, e->l->f, e->l->radial_next->f, e, TRUE); + + if (!BM_vert_collapse_faces(bm, v->e, v, 1.0, FALSE, TRUE)) { + return FALSE; + } +#endif return TRUE; } else if (keepedge == NULL && len == 2) { @@ -188,8 +196,9 @@ int BM_disk_dissolve(BMesh *bm, BMVert *v) } while (e != v->e); } - /* collapse the verte */ - e = BM_vert_collapse_faces(bm, baseedge, v, 1.0, TRUE, TRUE); + /* collapse the vertex */ + /* note, the baseedge can be a boundary of manifold, use this as join_faces arg */ + e = BM_vert_collapse_faces(bm, baseedge, v, 1.0, !BM_edge_is_boundary(baseedge), TRUE); if (!e) { return FALSE; From 0ee9f123b2a53a23bc69b24358dfe915132d2de7 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 16 Oct 2012 10:29:34 +0000 Subject: [PATCH 264/347] Fix #32819: Crash when starting CUDA kernel compilation if UI translation is not "Default" Issue was caused by some boost filesystem routines accessing current locale and such an access failed in cases code page isn't specified for the current locale. Made it so UTF-8 locale name would be tried to be used first. --- source/blender/blenfont/intern/blf_lang.c | 72 ++++++++++++----------- 1 file changed, 39 insertions(+), 33 deletions(-) diff --git a/source/blender/blenfont/intern/blf_lang.c b/source/blender/blenfont/intern/blf_lang.c index ff574a71549..284983b346a 100644 --- a/source/blender/blenfont/intern/blf_lang.c +++ b/source/blender/blenfont/intern/blf_lang.c @@ -214,11 +214,33 @@ void BLF_lang_set(const char *str) get_language_variable("LANGUAGE", default_language, sizeof(default_language)); if (short_locale[0]) { - if (G.debug & G_DEBUG) - printf("Setting LANG= and LANGUAGE to %s\n", short_locale); + char *short_locale_utf8 = BLI_sprintfN("%s.UTF-8", short_locale); - BLI_setenv("LANG", short_locale); - BLI_setenv("LANGUAGE", short_locale); + if (G.debug & G_DEBUG) + printf("Setting LANG and LANGUAGE to %s\n", short_locale_utf8); + + locreturn = setlocale(LC_ALL, short_locale_utf8); + + if (locreturn != NULL) { + BLI_setenv("LANG", short_locale_utf8); + BLI_setenv("LANGUAGE", short_locale_utf8); + } + else { + if (G.debug & G_DEBUG) + printf("Setting LANG and LANGUAGE to %s\n", short_locale); + + locreturn = setlocale(LC_ALL, short_locale); + + if (locreturn != NULL) { + BLI_setenv("LANG", short_locale); + BLI_setenv("LANGUAGE", short_locale); + } + } + + if (G.debug & G_DEBUG && locreturn == NULL) + printf("Could not change locale to %s nor %s\n", short_locale, short_locale_utf8); + + MEM_freeN(short_locale_utf8); } else { if (G.debug & G_DEBUG) @@ -226,43 +248,27 @@ void BLF_lang_set(const char *str) BLI_setenv("LANG", default_lang); BLI_setenv("LANGUAGE", default_language); + locreturn = setlocale(LC_ALL, ""); + + if (G.debug & G_DEBUG && locreturn == NULL) + printf("Could not reset locale\n"); } - locreturn = setlocale(LC_ALL, short_locale); - if (locreturn == NULL) { - char *short_locale_utf8 = NULL; + char language[65]; - if (short_locale[0]) { - short_locale_utf8 = BLI_sprintfN("%s.UTF-8", short_locale); - locreturn = setlocale(LC_ALL, short_locale_utf8); - } + get_language(long_locale, default_lang, language, sizeof(language)); - if (locreturn == NULL) { - char language[65]; + if (G.debug & G_DEBUG) + printf("Fallback to LANG=%s and LANGUAGE=%s\n", default_lang, language); - get_language(long_locale, default_lang, language, sizeof(language)); + /* Fallback to default settings. */ + BLI_setenv("LANG", default_lang); + BLI_setenv("LANGUAGE", language); - if (G.debug & G_DEBUG) { - if (short_locale[0]) - printf("Could not change locale to %s nor %s\n", short_locale, short_locale_utf8); - else - printf("Could not reset locale\n"); + locreturn = setlocale(LC_ALL, ""); - printf("Fallback to LANG=%s and LANGUAGE=%s\n", default_lang, language); - } - - /* Fallback to default settings. */ - BLI_setenv("LANG", default_lang); - BLI_setenv("LANGUAGE", language); - - locreturn = setlocale(LC_ALL, ""); - - ok = 0; - } - - if (short_locale_utf8) - MEM_freeN(short_locale_utf8); + ok = 0; } } #endif From 7521ce083dfeb6297313df1172690a9c22b712ec Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 16 Oct 2012 10:48:19 +0000 Subject: [PATCH 265/347] Cycles: object motion blur enabled, so in addition to camera motion, moving objects in the scene will also cause motion blur. This change does come with a bit of a slow down to the CPU rendering kernel even with motion blur disabled, due to extra overhead in handling of object matrices. It's a few percentages on simpler scenes, not so noticeable on more complex ones. With motion blur enabled rendering is of course also slower as would be expected, though from testing especially GPU rendering handles it quite well. This does not support motion blur from deforming objects yet, only translation, scale and rotation. Deformation blur is probably for another release. --- intern/cycles/blender/addon/ui.py | 2 +- intern/cycles/kernel/kernel_shader.h | 2 +- intern/cycles/kernel/kernel_types.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index 93309f63a84..f125740efd5 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -131,7 +131,7 @@ class CyclesRender_PT_light_paths(CyclesButtonsPanel, Panel): class CyclesRender_PT_motion_blur(CyclesButtonsPanel, Panel): - bl_label = "Camera Motion Blur" + bl_label = "Motion Blur" bl_options = {'DEFAULT_CLOSED'} def draw_header(self, context): diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h index 2711012edef..02f7b9b193f 100644 --- a/intern/cycles/kernel/kernel_shader.h +++ b/intern/cycles/kernel/kernel_shader.h @@ -73,7 +73,7 @@ __device_inline void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd, /* matrices and time */ #ifdef __OBJECT_MOTION__ if(sd->flag & SD_OBJECT_MOTION) { - sd->ob_tfm = object_fetch_transform_motion(kg, sd->object, time, &sd->ob_itfm); + sd->ob_tfm = object_fetch_transform_motion(kg, sd->object, ray->time, &sd->ob_itfm); } else { sd->ob_tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM); diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index 2acea04838a..b8bbaae5c2b 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -109,7 +109,7 @@ CCL_NAMESPACE_BEGIN #define __BACKGROUND_MIS__ #define __AO__ #define __CAMERA_MOTION__ -//#define __OBJECT_MOTION__ +#define __OBJECT_MOTION__ #endif //#define __SOBOL_FULL_SCREEN__ From af537c283c968dc90a203f1aabdb4d261b7dfbb4 Mon Sep 17 00:00:00 2001 From: Lukas Toenne Date: Tue, 16 Oct 2012 10:59:35 +0000 Subject: [PATCH 266/347] Fix for (camera) motion blur changes in Cycles OSL. Compilation was broken due to changed object transform functions. Also added a few missing renderer service implementations for matrix callbacks. --- intern/cycles/kernel/osl/osl_services.cpp | 119 ++++++++++++++++++++-- intern/cycles/kernel/osl/osl_services.h | 3 + 2 files changed, 114 insertions(+), 8 deletions(-) diff --git a/intern/cycles/kernel/osl/osl_services.cpp b/intern/cycles/kernel/osl/osl_services.cpp index f1deaa9db9d..6393412855b 100644 --- a/intern/cycles/kernel/osl/osl_services.cpp +++ b/intern/cycles/kernel/osl/osl_services.cpp @@ -72,7 +72,11 @@ bool OSLRenderServices::get_matrix(OSL::Matrix44 &result, OSL::TransformationPtr int object = sd->object; if (object != ~0) { - Transform tfm = object_fetch_transform(kg, object, time, OBJECT_TRANSFORM); +#ifdef __OBJECT_MOTION__ + Transform tfm = object_fetch_transform_motion(kg, object, time, NULL); +#else + Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM); +#endif tfm = transform_transpose(tfm); result = TO_MATRIX44(tfm); @@ -93,9 +97,14 @@ bool OSLRenderServices::get_inverse_matrix(OSL::Matrix44 &result, OSL::Transform int object = sd->object; if (object != ~0) { - Transform tfm = object_fetch_transform(kg, object, time, OBJECT_INVERSE_TRANSFORM); - tfm = transform_transpose(tfm); - result = TO_MATRIX44(tfm); +#ifdef __OBJECT_MOTION__ + Transform itfm; + object_fetch_transform_motion(kg, object, time, &itfm); +#else + Transform itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM); +#endif + itfm = transform_transpose(itfm); + result = TO_MATRIX44(itfm); return true; } @@ -162,14 +171,108 @@ bool OSLRenderServices::get_inverse_matrix(OSL::Matrix44 &result, ustring to, fl bool OSLRenderServices::get_matrix(OSL::Matrix44 &result, OSL::TransformationPtr xform) { - // XXX implementation - return true; + /* this is only used for shader and object space, we don't really have + * a concept of shader space, so we just use object space for both. */ + if (xform) { + KernelGlobals *kg = kernel_globals; + const ShaderData *sd = (const ShaderData *)xform; + int object = sd->object; + + if (object != ~0) { +#ifdef __OBJECT_MOTION__ + Transform tfm = sd->ob_tfm; +#else + Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM); +#endif + tfm = transform_transpose(tfm); + result = TO_MATRIX44(tfm); + + return true; + } + } + + return false; +} + +bool OSLRenderServices::get_inverse_matrix(OSL::Matrix44 &result, OSL::TransformationPtr xform) +{ + /* this is only used for shader and object space, we don't really have + * a concept of shader space, so we just use object space for both. */ + if (xform) { + KernelGlobals *kg = kernel_globals; + const ShaderData *sd = (const ShaderData *)xform; + int object = sd->object; + + if (object != ~0) { +#ifdef __OBJECT_MOTION__ + Transform tfm = sd->ob_itfm; +#else + Transform tfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM); +#endif + tfm = transform_transpose(tfm); + result = TO_MATRIX44(tfm); + + return true; + } + } + + return false; } bool OSLRenderServices::get_matrix(OSL::Matrix44 &result, ustring from) { - // XXX implementation - return true; + KernelGlobals *kg = kernel_globals; + + if (from == u_ndc) { + Transform tfm = transform_transpose(kernel_data.cam.ndctoworld); + result = TO_MATRIX44(tfm); + return true; + } + else if (from == u_raster) { + Transform tfm = transform_transpose(kernel_data.cam.rastertoworld); + result = TO_MATRIX44(tfm); + return true; + } + else if (from == u_screen) { + Transform tfm = transform_transpose(kernel_data.cam.screentoworld); + result = TO_MATRIX44(tfm); + return true; + } + else if (from == u_camera) { + Transform tfm = transform_transpose(kernel_data.cam.cameratoworld); + result = TO_MATRIX44(tfm); + return true; + } + + return false; +} + +bool OSLRenderServices::get_inverse_matrix(OSL::Matrix44 &result, ustring to) +{ + KernelGlobals *kg = kernel_globals; + + if (to == u_ndc) { + Transform tfm = transform_transpose(kernel_data.cam.worldtondc); + result = TO_MATRIX44(tfm); + return true; + } + else if (to == u_raster) { + Transform tfm = transform_transpose(kernel_data.cam.worldtoraster); + result = TO_MATRIX44(tfm); + return true; + } + else if (to == u_screen) { + Transform tfm = transform_transpose(kernel_data.cam.worldtoscreen); + result = TO_MATRIX44(tfm); + return true; + } + else if (to == u_camera) { + Transform tfm = transform_transpose(kernel_data.cam.worldtocamera); + result = TO_MATRIX44(tfm); + return true; + } + + return false; } bool OSLRenderServices::get_array_attribute(void *renderstate, bool derivatives, diff --git a/intern/cycles/kernel/osl/osl_services.h b/intern/cycles/kernel/osl/osl_services.h index 790b02a8abc..fa32d47a89f 100644 --- a/intern/cycles/kernel/osl/osl_services.h +++ b/intern/cycles/kernel/osl/osl_services.h @@ -54,7 +54,10 @@ public: bool get_inverse_matrix(OSL::Matrix44 &result, ustring to, float time); bool get_matrix(OSL::Matrix44 &result, OSL::TransformationPtr xform); + bool get_inverse_matrix(OSL::Matrix44 &result, OSL::TransformationPtr xform); + bool get_matrix(OSL::Matrix44 &result, ustring from); + bool get_inverse_matrix(OSL::Matrix44 &result, ustring from); bool get_array_attribute(void *renderstate, bool derivatives, ustring object, TypeDesc type, ustring name, From 9be4c94204eaaddbfbbe4851eb517a684c853c54 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 16 Oct 2012 11:57:46 +0000 Subject: [PATCH 267/347] Cycles: non-camera viewport render border support This makes it possible to do a border render inside a viewport even when not looking through the camera. Render border could be defined by Ctrl-B shortcut (works for both camera render border and viewport render border). Camera render border could still be defined using Shift-B (so no muscule memory would be broken). Currently used a special flag of operator to do this, otherwise you'll need to either two operators with different poll callback or it could go into conflict with a border zoom, Border render of a viewport could be enabled/disabled in View panel using "Render Border" option. --- intern/cycles/blender/blender_camera.cpp | 32 ++++- intern/cycles/blender/blender_session.cpp | 10 +- intern/cycles/blender/blender_sync.h | 2 +- release/scripts/startup/bl_ui/space_view3d.py | 3 + source/blender/blenkernel/BKE_blender.h | 2 +- source/blender/blenloader/intern/readfile.c | 88 +++++++----- .../editors/space_view3d/view3d_draw.c | 39 +++++- .../editors/space_view3d/view3d_edit.c | 128 +++++++++++++----- .../editors/space_view3d/view3d_intern.h | 1 + .../blender/editors/space_view3d/view3d_ops.c | 9 +- source/blender/makesdna/DNA_view3d_types.h | 2 + source/blender/makesrna/intern/rna_space.c | 34 ++++- 12 files changed, 266 insertions(+), 84 deletions(-) diff --git a/intern/cycles/blender/blender_camera.cpp b/intern/cycles/blender/blender_camera.cpp index e16677336d5..000d412ab28 100644 --- a/intern/cycles/blender/blender_camera.cpp +++ b/intern/cycles/blender/blender_camera.cpp @@ -425,12 +425,26 @@ static void blender_camera_border(BlenderCamera *bcam, BL::Scene b_scene, BL::Sp BL::RegionView3D b_rv3d, int width, int height) { BL::RenderSettings r = b_scene.render(); - - if(!r.use_border()) - return; + bool is_camera_view; /* camera view? */ - if(!(b_rv3d && b_rv3d.view_perspective() == BL::RegionView3D::view_perspective_CAMERA)) + is_camera_view = b_rv3d.view_perspective() == BL::RegionView3D::view_perspective_CAMERA; + + if(!is_camera_view) { + /* for non-camera view check whether render border is enabled for viewport + * and if so use border from 3d viewport + * assume viewport has got correctly clamped border already + */ + if(b_v3d.use_render_border()) { + bcam->border_left = b_v3d.render_border_min_x(); + bcam->border_right = b_v3d.render_border_max_x(); + bcam->border_bottom = b_v3d.render_border_min_y(); + bcam->border_top = b_v3d.render_border_max_y(); + + return; + } + } + else if(!r.use_border()) return; BL::Object b_ob = (b_v3d.lock_camera_and_layers())? b_scene.camera(): b_v3d.camera(); @@ -504,14 +518,20 @@ void BlenderSync::sync_view(BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, int blender_camera_sync(scene->camera, &bcam, width, height); } -BufferParams BlenderSync::get_buffer_params(BL::Scene b_scene, Camera *cam, int width, int height) +BufferParams BlenderSync::get_buffer_params(BL::Scene b_scene, BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, Camera *cam, int width, int height) { BufferParams params; + bool use_border = false; params.full_width = width; params.full_height = height; - if(b_scene.render().use_border()) { + if(b_v3d && b_rv3d && b_rv3d.view_perspective() != BL::RegionView3D::view_perspective_CAMERA) + use_border = b_v3d.use_render_border(); + else + use_border = b_scene.render().use_border(); + + if(use_border) { /* border render */ params.full_x = cam->border_left*width; params.full_y = cam->border_bottom*height; diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp index 0a09102bd4f..3fdd4418eb6 100644 --- a/intern/cycles/blender/blender_session.cpp +++ b/intern/cycles/blender/blender_session.cpp @@ -105,7 +105,7 @@ void BlenderSession::create_session() sync->sync_camera(b_engine.camera_override(), width, height); /* set buffer parameters */ - BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, scene->camera, width, height); + BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, b_v3d, b_rv3d, scene->camera, width, height); session->reset(buffer_params, session_params.samples); } @@ -239,7 +239,7 @@ void BlenderSession::render() /* get buffer parameters */ SessionParams session_params = BlenderSync::get_session_params(b_engine, b_userpref, b_scene, background); - BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, scene->camera, width, height); + BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, b_v3d, b_rv3d, scene->camera, width, height); /* render each layer */ BL::RenderSettings r = b_scene.render(); @@ -399,7 +399,7 @@ void BlenderSession::synchronize() /* reset if needed */ if(scene->need_reset()) { - BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, scene->camera, width, height); + BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, b_v3d, b_rv3d, scene->camera, width, height); session->reset(buffer_params, session_params.samples); } } @@ -437,7 +437,7 @@ bool BlenderSession::draw(int w, int h) /* reset if requested */ if(reset) { SessionParams session_params = BlenderSync::get_session_params(b_engine, b_userpref, b_scene, background); - BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, scene->camera, w, h); + BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, b_v3d, b_rv3d, scene->camera, w, h); session->reset(buffer_params, session_params.samples); } @@ -447,7 +447,7 @@ bool BlenderSession::draw(int w, int h) update_status_progress(); /* draw */ - BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, scene->camera, width, height); + BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, b_v3d, b_rv3d, scene->camera, width, height); return !session->draw(buffer_params); } diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h index ce563087b4a..d7fcb014931 100644 --- a/intern/cycles/blender/blender_sync.h +++ b/intern/cycles/blender/blender_sync.h @@ -63,7 +63,7 @@ public: static SceneParams get_scene_params(BL::Scene b_scene, bool background); static SessionParams get_session_params(BL::RenderEngine b_engine, BL::UserPreferences b_userpref, BL::Scene b_scene, bool background); static bool get_session_pause(BL::Scene b_scene, bool background); - static BufferParams get_buffer_params(BL::Scene b_scene, Camera *cam, int width, int height); + static BufferParams get_buffer_params(BL::Scene b_scene, BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, Camera *cam, int width, int height); private: /* sync */ diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index e96bc696087..f787f18fad3 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -2312,6 +2312,9 @@ class VIEW3D_PT_view3d_properties(Panel): subcol.label(text="Local Camera:") subcol.prop(view, "camera", text="") + col = layout.column(align=True) + col.prop(view, "use_render_border") + class VIEW3D_PT_view3d_cursor(Panel): bl_space_type = 'VIEW_3D' diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index e1c79f8d6c1..95d41a86239 100644 --- a/source/blender/blenkernel/BKE_blender.h +++ b/source/blender/blenkernel/BKE_blender.h @@ -42,7 +42,7 @@ extern "C" { * and keep comment above the defines. * Use STRINGIFY() rather than defining with quotes */ #define BLENDER_VERSION 264 -#define BLENDER_SUBVERSION 2 +#define BLENDER_SUBVERSION 3 /* 262 was the last editmesh release but its has compatibility code for bmesh data, * so set the minversion to 2.61 */ diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 884a6432dda..35b6b400559 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -8046,40 +8046,63 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } } - /* WATCH IT!!!: pointers from libdata have not been converted yet here! */ - /* WATCH IT 2!: Userdef struct init has to be in editors/interface/resources.c! */ + if (main->versionfile < 264 || (main->versionfile == 264 && main->subversionfile < 3)) { + /* smoke branch */ + { + Object *ob; - { - Object *ob; - - for (ob = main->object.first; ob; ob = ob->id.next) { - ModifierData *md; - for (md = ob->modifiers.first; md; md = md->next) { - if (md->type == eModifierType_Smoke) { - SmokeModifierData *smd = (SmokeModifierData *)md; - if ((smd->type & MOD_SMOKE_TYPE_DOMAIN) && smd->domain) { - /* keep branch saves if possible */ - if (!smd->domain->flame_max_temp) { - smd->domain->burning_rate = 0.75f; - smd->domain->flame_smoke = 1.0f; - smd->domain->flame_vorticity = 0.5f; - smd->domain->flame_ignition = 1.25f; - smd->domain->flame_max_temp = 1.75f; - smd->domain->adapt_threshold = 0.02f; - smd->domain->adapt_margin = 4; - smd->domain->flame_smoke_color[0] = 0.7f; - smd->domain->flame_smoke_color[1] = 0.7f; - smd->domain->flame_smoke_color[2] = 0.7f; + for (ob = main->object.first; ob; ob = ob->id.next) { + ModifierData *md; + for (md = ob->modifiers.first; md; md = md->next) { + if (md->type == eModifierType_Smoke) { + SmokeModifierData *smd = (SmokeModifierData *)md; + if ((smd->type & MOD_SMOKE_TYPE_DOMAIN) && smd->domain) { + /* keep branch saves if possible */ + if (!smd->domain->flame_max_temp) { + smd->domain->burning_rate = 0.75f; + smd->domain->flame_smoke = 1.0f; + smd->domain->flame_vorticity = 0.5f; + smd->domain->flame_ignition = 1.25f; + smd->domain->flame_max_temp = 1.75f; + smd->domain->adapt_threshold = 0.02f; + smd->domain->adapt_margin = 4; + smd->domain->flame_smoke_color[0] = 0.7f; + smd->domain->flame_smoke_color[1] = 0.7f; + smd->domain->flame_smoke_color[2] = 0.7f; + } + } + else if ((smd->type & MOD_SMOKE_TYPE_FLOW) && smd->flow) { + if (!smd->flow->texture_size) { + smd->flow->fuel_amount = 1.0; + smd->flow->surface_distance = 1.5; + smd->flow->color[0] = 0.7f; + smd->flow->color[1] = 0.7f; + smd->flow->color[2] = 0.7f; + smd->flow->texture_size = 1.0f; + } } } - else if ((smd->type & MOD_SMOKE_TYPE_FLOW) && smd->flow) { - if (!smd->flow->texture_size) { - smd->flow->fuel_amount = 1.0; - smd->flow->surface_distance = 1.5; - smd->flow->color[0] = 0.7f; - smd->flow->color[1] = 0.7f; - smd->flow->color[2] = 0.7f; - smd->flow->texture_size = 1.0f; + } + } + } + + /* render border for viewport */ + { + bScreen *sc; + + for (sc = main->screen.first; sc; sc = sc->id.next) { + ScrArea *sa; + for (sa = sc->areabase.first; sa; sa = sa->next) { + SpaceLink *sl; + for (sl = sa->spacedata.first; sl; sl = sl->next) { + if (sl->spacetype == SPACE_VIEW3D) { + View3D *v3d = (View3D *)sl; + if (v3d->render_border.xmin == 0.0f && v3d->render_border.ymin == 0.0f && + v3d->render_border.xmax == 0.0f && v3d->render_border.ymax == 0.0f) + { + v3d->render_border.xmax = 1.0f; + v3d->render_border.ymax = 1.0f; + } } } } @@ -8087,6 +8110,9 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } } + /* WATCH IT!!!: pointers from libdata have not been converted yet here! */ + /* WATCH IT 2!: Userdef struct init has to be in editors/interface/resources.c! */ + /* don't forget to set version number in blender.c! */ } diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 88375c409b8..8e1b0716136 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -2878,12 +2878,20 @@ static int view3d_main_area_draw_engine(const bContext *C, ARegion *ar, int draw rctf viewborder; rcti cliprct; - ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &viewborder, FALSE); + if (rv3d->persp == RV3D_CAMOB) { + ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &viewborder, FALSE); - cliprct.xmin = viewborder.xmin + scene->r.border.xmin * BLI_rctf_size_x(&viewborder); - cliprct.ymin = viewborder.ymin + scene->r.border.ymin * BLI_rctf_size_y(&viewborder); - cliprct.xmax = viewborder.xmin + scene->r.border.xmax * BLI_rctf_size_x(&viewborder); - cliprct.ymax = viewborder.ymin + scene->r.border.ymax * BLI_rctf_size_y(&viewborder); + cliprct.xmin = viewborder.xmin + scene->r.border.xmin * BLI_rctf_size_x(&viewborder); + cliprct.ymin = viewborder.ymin + scene->r.border.ymin * BLI_rctf_size_y(&viewborder); + cliprct.xmax = viewborder.xmin + scene->r.border.xmax * BLI_rctf_size_x(&viewborder); + cliprct.ymax = viewborder.ymin + scene->r.border.ymax * BLI_rctf_size_y(&viewborder); + } + else { + cliprct.xmin = v3d->render_border.xmin * ar->winx; + cliprct.xmax = v3d->render_border.xmax * ar->winx; + cliprct.ymin = v3d->render_border.ymin * ar->winy; + cliprct.ymax = v3d->render_border.ymax * ar->winy; + } cliprct.xmin += ar->winrct.xmin; cliprct.xmax += ar->winrct.xmin; @@ -3129,8 +3137,20 @@ static void view3d_main_area_draw_info(const bContext *C, ARegion *ar, const cha Object *ob; - if (rv3d->persp == RV3D_CAMOB) + if (rv3d->persp == RV3D_CAMOB) { drawviewborder(scene, ar, v3d); + } + else if (v3d->flag2 & V3D_RENDER_BORDER) { + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + setlinestyle(3); + cpack(0x4040FF); + + glRectf(v3d->render_border.xmin * ar->winx, v3d->render_border.ymin * ar->winy, + v3d->render_border.xmax * ar->winx, v3d->render_border.ymax * ar->winy); + + setlinestyle(0); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + } if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { /* draw grease-pencil stuff - needed to get paint-buffer shown too (since it's 2D) */ @@ -3180,7 +3200,12 @@ void view3d_main_area_draw(const bContext *C, ARegion *ar) View3D *v3d = CTX_wm_view3d(C); RegionView3D *rv3d = CTX_wm_region_view3d(C); const char *grid_unit = NULL; - int draw_border = (rv3d->persp == RV3D_CAMOB && (scene->r.mode & R_BORDER)); + int draw_border = FALSE; + + if (rv3d->persp == RV3D_CAMOB) + draw_border = scene->r.mode & R_BORDER; + else + draw_border = v3d->flag2 & V3D_RENDER_BORDER; /* draw viewport using opengl */ if (v3d->drawtype != OB_RENDER || !view3d_main_area_do_render_draw(C) || draw_border) { diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 2a210ef0ee4..96264081f10 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -929,18 +929,6 @@ static int viewrotate_invoke(bContext *C, wmOperator *op, wmEvent *event) } } -static int view3d_camera_active_poll(bContext *C) -{ - if (ED_operator_view3d_active(C)) { - RegionView3D *rv3d = CTX_wm_region_view3d(C); - if (rv3d && rv3d->persp == RV3D_CAMOB) { - return 1; - } - } - - return 0; -} - /* test for unlocked camera view in quad view */ static int view3d_camera_user_poll(bContext *C) { @@ -2633,42 +2621,71 @@ static int render_border_exec(bContext *C, wmOperator *op) View3D *v3d = CTX_wm_view3d(C); ARegion *ar = CTX_wm_region(C); RegionView3D *rv3d = ED_view3d_context_rv3d(C); + Scene *scene = CTX_data_scene(C); rcti rect; - rctf vb; + rctf vb, border; + + int camera_only = RNA_boolean_get(op->ptr, "camera_only"); + + if (camera_only && rv3d->persp != RV3D_CAMOB) + return OPERATOR_PASS_THROUGH; /* get border select values using rna */ WM_operator_properties_border_to_rcti(op, &rect); /* calculate range */ - ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &vb, FALSE); - scene->r.border.xmin = ((float)rect.xmin - vb.xmin) / BLI_rctf_size_x(&vb); - scene->r.border.ymin = ((float)rect.ymin - vb.ymin) / BLI_rctf_size_y(&vb); - scene->r.border.xmax = ((float)rect.xmax - vb.xmin) / BLI_rctf_size_x(&vb); - scene->r.border.ymax = ((float)rect.ymax - vb.ymin) / BLI_rctf_size_y(&vb); + if (rv3d->persp == RV3D_CAMOB) { + ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &vb, FALSE); + } + else { + vb.xmin = 0; + vb.ymin = 0; + vb.xmax = ar->winx; + vb.ymax = ar->winy; + } + + border.xmin = ((float)rect.xmin - vb.xmin) / BLI_rctf_size_x(&vb); + border.ymin = ((float)rect.ymin - vb.ymin) / BLI_rctf_size_y(&vb); + border.xmax = ((float)rect.xmax - vb.xmin) / BLI_rctf_size_x(&vb); + border.ymax = ((float)rect.ymax - vb.ymin) / BLI_rctf_size_y(&vb); /* actually set border */ - CLAMP(scene->r.border.xmin, 0.0f, 1.0f); - CLAMP(scene->r.border.ymin, 0.0f, 1.0f); - CLAMP(scene->r.border.xmax, 0.0f, 1.0f); - CLAMP(scene->r.border.ymax, 0.0f, 1.0f); + CLAMP(border.xmin, 0.0f, 1.0f); + CLAMP(border.ymin, 0.0f, 1.0f); + CLAMP(border.xmax, 0.0f, 1.0f); + CLAMP(border.ymax, 0.0f, 1.0f); + + if (rv3d->persp == RV3D_CAMOB) { + scene->r.border = border; + + WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, NULL); + } + else { + v3d->render_border = border; + + WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, NULL); + } /* drawing a border surrounding the entire camera view switches off border rendering * or the border covers no pixels */ - if ((scene->r.border.xmin <= 0.0f && scene->r.border.xmax >= 1.0f && - scene->r.border.ymin <= 0.0f && scene->r.border.ymax >= 1.0f) || - (scene->r.border.xmin == scene->r.border.xmax || - scene->r.border.ymin == scene->r.border.ymax)) + if ((border.xmin <= 0.0f && border.xmax >= 1.0f && + border.ymin <= 0.0f && border.ymax >= 1.0f) || + (border.xmin == border.xmax || border.ymin == border.ymax)) { - scene->r.mode &= ~R_BORDER; + if (rv3d->persp == RV3D_CAMOB) + scene->r.mode &= ~R_BORDER; + else + v3d->flag2 &= ~V3D_RENDER_BORDER; } else { - scene->r.mode |= R_BORDER; + if (rv3d->persp == RV3D_CAMOB) + scene->r.mode |= R_BORDER; + else + v3d->flag2 |= V3D_RENDER_BORDER; } - - WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, NULL); return OPERATOR_FINISHED; @@ -2687,7 +2704,7 @@ void VIEW3D_OT_render_border(wmOperatorType *ot) ot->modal = WM_border_select_modal; ot->cancel = WM_border_select_cancel; - ot->poll = view3d_camera_active_poll; + ot->poll = ED_operator_view3d_active; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -2695,7 +2712,56 @@ void VIEW3D_OT_render_border(wmOperatorType *ot) /* rna */ WM_operator_properties_border(ot); + RNA_def_boolean(ot->srna, "camera_only", 0, "Camera Only", "Set render border for camera view and final render only"); } + +/* ********************* Set render border operator ****************** */ + +static int clear_render_border_exec(bContext *C, wmOperator *UNUSED(op)) +{ + View3D *v3d = CTX_wm_view3d(C); + RegionView3D *rv3d = ED_view3d_context_rv3d(C); + + Scene *scene = CTX_data_scene(C); + rctf *border = NULL; + + if (rv3d->persp == RV3D_CAMOB) { + scene->r.mode &= ~R_BORDER; + border = &scene->r.border; + + WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, NULL); + } + else { + v3d->flag2 &= ~V3D_RENDER_BORDER; + border = &v3d->render_border; + + WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, NULL); + } + + border->xmin = 0.0f; + border->ymin = 0.0f; + border->xmax = 1.0f; + border->ymax = 1.0f; + + return OPERATOR_FINISHED; + +} + +void VIEW3D_OT_clear_render_border(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Clear Render Border"; + ot->description = "Clear the boundaries of the border render and enables border render"; + ot->idname = "VIEW3D_OT_clear_render_border"; + + /* api callbacks */ + ot->exec = clear_render_border_exec; + ot->poll = ED_operator_view3d_active; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + /* ********************* Border Zoom operator ****************** */ static int view3d_zoom_border_exec(bContext *C, wmOperator *op) diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h index e364014c42f..8f7656a1f37 100644 --- a/source/blender/editors/space_view3d/view3d_intern.h +++ b/source/blender/editors/space_view3d/view3d_intern.h @@ -98,6 +98,7 @@ void VIEW3D_OT_cursor3d(struct wmOperatorType *ot); void VIEW3D_OT_manipulator(struct wmOperatorType *ot); void VIEW3D_OT_enable_manipulator(struct wmOperatorType *ot); void VIEW3D_OT_render_border(struct wmOperatorType *ot); +void VIEW3D_OT_clear_render_border(struct wmOperatorType *ot); void VIEW3D_OT_zoom_border(struct wmOperatorType *ot); void view3d_boxview_copy(ScrArea *sa, ARegion *ar); diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c index cb4f85430c5..73f1563417c 100644 --- a/source/blender/editors/space_view3d/view3d_ops.c +++ b/source/blender/editors/space_view3d/view3d_ops.c @@ -83,6 +83,7 @@ void view3d_operatortypes(void) WM_operatortype_append(VIEW3D_OT_select_circle); WM_operatortype_append(VIEW3D_OT_smoothview); WM_operatortype_append(VIEW3D_OT_render_border); + WM_operatortype_append(VIEW3D_OT_clear_render_border); WM_operatortype_append(VIEW3D_OT_zoom_border); WM_operatortype_append(VIEW3D_OT_manipulator); WM_operatortype_append(VIEW3D_OT_enable_manipulator); @@ -345,7 +346,13 @@ void view3d_keymap(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "VIEW3D_OT_clip_border", BKEY, KM_PRESS, KM_ALT, 0); WM_keymap_add_item(keymap, "VIEW3D_OT_zoom_border", BKEY, KM_PRESS, KM_SHIFT, 0); - WM_keymap_add_item(keymap, "VIEW3D_OT_render_border", BKEY, KM_PRESS, KM_SHIFT, 0); + + kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_render_border", BKEY, KM_PRESS, KM_SHIFT, 0); + RNA_boolean_set(kmi->ptr, "camera_only", TRUE); + kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_render_border", BKEY, KM_PRESS, KM_CTRL, 0); + RNA_boolean_set(kmi->ptr, "camera_only", FALSE); + + WM_keymap_add_item(keymap, "VIEW3D_OT_clear_render_border", BKEY, KM_PRESS, KM_CTRL | KM_ALT, 0); WM_keymap_add_item(keymap, "VIEW3D_OT_camera_to_view", PAD0, KM_PRESS, KM_ALT | KM_CTRL, 0); WM_keymap_add_item(keymap, "VIEW3D_OT_object_as_camera", PAD0, KM_PRESS, KM_CTRL, 0); diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h index 9da10381af0..c83b0bc366f 100644 --- a/source/blender/makesdna/DNA_view3d_types.h +++ b/source/blender/makesdna/DNA_view3d_types.h @@ -169,6 +169,7 @@ typedef struct View3D { short view DNA_DEPRECATED; struct Object *camera, *ob_centre; + rctf render_border; struct ListBase bgpicbase; struct BGpic *bgpic DNA_DEPRECATED; /* deprecated, use bgpicbase, only kept for do_versions(...) */ @@ -267,6 +268,7 @@ typedef struct View3D { #define V3D_SHOW_CAMERAPATH 256 #define V3D_SHOW_BUNDLENAME 512 #define V3D_BACKFACE_CULLING 1024 +#define V3D_RENDER_BORDER 2048 /* View3D->around */ #define V3D_CENTER 0 diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index bfd0f731626..13aa5557964 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -1494,7 +1494,39 @@ static void rna_def_space_view3d(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Camera", "Active camera used in this view (when unlocked from the scene's active camera)"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); - + + /* render border */ + prop = RNA_def_property(srna, "use_render_border", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag2", V3D_RENDER_BORDER); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_ui_text(prop, "Render Border", + "use a user-defined border region within the frame size for rendered viewport"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); + + prop = RNA_def_property(srna, "render_border_min_x", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "render_border.xmin"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Border Minimum X", "Minimum X value to for the render border"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); + + prop = RNA_def_property(srna, "render_border_min_y", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "render_border.ymin"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Border Minimum Y", "Minimum Y value for the render border"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); + + prop = RNA_def_property(srna, "render_border_max_x", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "render_border.xmax"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Border Maximum X", "Maximum X value for the render border"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); + + prop = RNA_def_property(srna, "render_border_max_y", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "render_border.ymax"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Border Maximum Y", "Maximum Y value for the render border"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); + prop = RNA_def_property(srna, "lock_object", PROP_POINTER, PROP_NONE); RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_pointer_sdna(prop, NULL, "ob_centre"); From 7680f88f18d43e8a49576081c7527b157131d409 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 16 Oct 2012 13:20:57 +0000 Subject: [PATCH 268/347] Fix object motion blur crash with lamp sampling(?), missed a check. Motion blur documentation is here: http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.65/Cycles#Motion_Blur --- intern/cycles/kernel/kernel_object.h | 3 +++ intern/cycles/kernel/kernel_shader.h | 17 ++++++++++------- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/intern/cycles/kernel/kernel_object.h b/intern/cycles/kernel/kernel_object.h index d8ea2cf9926..602574cb736 100644 --- a/intern/cycles/kernel/kernel_object.h +++ b/intern/cycles/kernel/kernel_object.h @@ -134,6 +134,9 @@ __device_inline void object_dir_transform(KernelGlobals *kg, ShaderData *sd, flo __device_inline float3 object_location(KernelGlobals *kg, ShaderData *sd) { + if(sd->object == ~0) + return make_float3(0.0f, 0.0f, 0.0f); + #ifdef __OBJECT_MOTION__ return make_float3(sd->ob_tfm.x.w, sd->ob_tfm.y.w, sd->ob_tfm.z.w); #else diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h index 02f7b9b193f..534f0941134 100644 --- a/intern/cycles/kernel/kernel_shader.h +++ b/intern/cycles/kernel/kernel_shader.h @@ -179,19 +179,22 @@ __device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd, #endif sd->flag = kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*2); - if(sd->object != -1) + if(sd->object != -1) { sd->flag |= kernel_tex_fetch(__object_flag, sd->object); #ifdef __OBJECT_MOTION__ - if(sd->flag & SD_OBJECT_MOTION) { - sd->ob_tfm = object_fetch_transform_motion(kg, sd->object, time, &sd->ob_itfm); - } - else { - sd->ob_tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM); - sd->ob_itfm = object_fetch_transform(kg, sd->object, OBJECT_INVERSE_TRANSFORM); + if(sd->flag & SD_OBJECT_MOTION) { + sd->ob_tfm = object_fetch_transform_motion(kg, sd->object, time, &sd->ob_itfm); + } + else { + sd->ob_tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM); + sd->ob_itfm = object_fetch_transform(kg, sd->object, OBJECT_INVERSE_TRANSFORM); + } } sd->time = time; +#else + } #endif /* smooth normal */ From eb771c78cd1199cd35af7ded4d4a13f8a62430c6 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 16 Oct 2012 14:35:37 +0000 Subject: [PATCH 269/347] fix for free NULL pointer in BM_vert_splice() and BM_iter_as_arrayN() failed with BM_VERTS_OF_MESH/BM_EDGES_OF_MESH/BM_FACES_OF_MESH. --- source/blender/bmesh/intern/bmesh_core.c | 8 +++++--- source/blender/bmesh/intern/bmesh_iterators.c | 16 ++++++++++++++++ 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c index 2836f2ce1d4..16c7f6f1539 100644 --- a/source/blender/bmesh/intern/bmesh_core.c +++ b/source/blender/bmesh/intern/bmesh_core.c @@ -1813,10 +1813,12 @@ int BM_vert_splice(BMesh *bm, BMVert *v, BMVert *vtarget) /* we can't modify the vert while iterating so first allocate an array of loops */ loops = BM_iter_as_arrayN(bm, BM_LOOPS_OF_VERT, v, &loops_tot); - for (i = 0; i < loops_tot; i++) { - loops[i]->v = vtarget; + if (loops) { + for (i = 0; i < loops_tot; i++) { + loops[i]->v = vtarget; + } + MEM_freeN(loops); } - MEM_freeN(loops); /* move all the edges from v's disk to vtarget's disk */ while ((e = v->e)) { diff --git a/source/blender/bmesh/intern/bmesh_iterators.c b/source/blender/bmesh/intern/bmesh_iterators.c index 726127fdcad..10f0df78fd0 100644 --- a/source/blender/bmesh/intern/bmesh_iterators.c +++ b/source/blender/bmesh/intern/bmesh_iterators.c @@ -120,6 +120,21 @@ void *BM_iter_as_arrayN(BMesh *bm, const char itype, void *data, int *r_len) { BMIter iter; + /* we can't rely on coun't being set */ + switch (itype) { + case BM_VERTS_OF_MESH: + iter.count = bm->totvert; + break; + case BM_EDGES_OF_MESH: + iter.count = bm->totedge; + break; + case BM_FACES_OF_MESH: + iter.count = bm->totface; + break; + default: + break; + } + if (BM_iter_init(&iter, bm, itype, data) && iter.count > 0) { BMElem *ele; BMElem **array = MEM_mallocN(sizeof(ele) * iter.count, __func__); @@ -229,6 +244,7 @@ void *bmiter__vert_of_mesh_step(BMIter *iter) void bmiter__edge_of_mesh_begin(BMIter *iter) { BLI_mempool_iternew(iter->bm->epool, &iter->pooliter); + iter->count = iter->bm->totedge; /* */ } void *bmiter__edge_of_mesh_step(BMIter *iter) From 66295d709cf271ec8d761763f2c3e757d86f02da Mon Sep 17 00:00:00 2001 From: Lukas Toenne Date: Tue, 16 Oct 2012 14:55:36 +0000 Subject: [PATCH 270/347] Fix/workaround #32846, dupli group + particle instances gets messed up in Cycles viewport rendering. Caused by modifier updates during dupli-list generation. The dupli-list generation temporarily changes the ob->obmat matrix, which in turn leads to wrong particle states if used for reset. Skip the particle update if no timestep is performed or initialization required. Proper solution for this problem would be to avoid changing the object data (= particles) state altogether in modifiers, which are usually only writing to DM data and not touching the object or base mesh. This would require a well designed physics framework and integrating it into current particles is close to impossible. --- .../blender/modifiers/intern/MOD_particlesystem.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/source/blender/modifiers/intern/MOD_particlesystem.c b/source/blender/modifiers/intern/MOD_particlesystem.c index 254c02b7672..c4db9375a4a 100644 --- a/source/blender/modifiers/intern/MOD_particlesystem.c +++ b/source/blender/modifiers/intern/MOD_particlesystem.c @@ -44,6 +44,7 @@ #include "BKE_material.h" #include "BKE_modifier.h" #include "BKE_particle.h" +#include "BKE_scene.h" #include "MOD_util.h" @@ -130,6 +131,7 @@ static void deformVerts(ModifierData *md, Object *ob, ParticleSystemModifierData *psmd = (ParticleSystemModifierData *) md; ParticleSystem *psys = NULL; int needsFree = 0; + float cfra = BKE_scene_frame_get(md->scene); if (ob->particlesystem.first) psys = psmd->psys; @@ -188,9 +190,16 @@ static void deformVerts(ModifierData *md, Object *ob, psmd->totdmface = psmd->dm->getNumTessFaces(psmd->dm); } - psmd->flag &= ~eParticleSystemFlag_psys_updated; - particle_system_update(md->scene, ob, psys); - psmd->flag |= eParticleSystemFlag_psys_updated; + /* skip the particle update if no timestep is performed or initialization required. + * XXX this is a workaround for bug #32846, which is caused by modifier updates + * during dupli-list generation (in cycles). The dupli-list generation can temporarily change + * the ob->obmat matrix, which in turn leads to wrong particle states if used for reset ... + */ + if (psys->cfra != cfra || psys->recalc) { + psmd->flag &= ~eParticleSystemFlag_psys_updated; + particle_system_update(md->scene, ob, psys); + psmd->flag |= eParticleSystemFlag_psys_updated; + } } /* disabled particles in editmode for now, until support for proper derivedmesh From 51fe26b78dbc685de2d16ff712945104e11b6683 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 16 Oct 2012 15:07:01 +0000 Subject: [PATCH 271/347] Fix #32891: Bake to Texture didn't use color management flag properly --- source/blender/render/intern/source/rendercore.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c index ee88706117f..fbf0ff2ea8a 100644 --- a/source/blender/render/intern/source/rendercore.c +++ b/source/blender/render/intern/source/rendercore.c @@ -59,6 +59,7 @@ #include "BKE_main.h" #include "BKE_node.h" #include "BKE_texture.h" +#include "BKE_scene.h" #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" @@ -2653,6 +2654,8 @@ int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_up Image *ima; int a, vdone = FALSE, use_mask = FALSE, result = BAKE_RESULT_OK; + re->scene_color_manage = BKE_scene_check_color_management_enabled(re->scene); + /* initialize render global */ R= *re; R.bakebuf= NULL; From 427a90d336144b4bdbff9f7ff72275d78005bcfd Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 16 Oct 2012 15:20:18 +0000 Subject: [PATCH 272/347] Color Management: texture baking should be correct when color management is disabled --- source/blender/render/intern/source/rendercore.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c index fbf0ff2ea8a..bad3b18919c 100644 --- a/source/blender/render/intern/source/rendercore.c +++ b/source/blender/render/intern/source/rendercore.c @@ -2224,7 +2224,8 @@ static void bake_shade(void *handle, Object *ob, ShadeInput *shi, int UNUSED(qua float rgb[3]; copy_v3_v3(rgb, shr.combined); - IMB_colormanagement_scene_linear_to_colorspace_v3(rgb, bs->rect_colorspace); + if (R.scene_color_manage) + IMB_colormanagement_scene_linear_to_colorspace_v3(rgb, bs->rect_colorspace); rgb_float_to_uchar(col, rgb); } else { From 617cdb4642019f57ee657105a2a1307dcceedbdf Mon Sep 17 00:00:00 2001 From: Lukas Toenne Date: Tue, 16 Oct 2012 15:38:52 +0000 Subject: [PATCH 273/347] Fix for second bug reported in #32846: Particle emitters are still shown for secondary instances with "show emitter" disabled. This requires checking the duplicator visibility on dupli objects themselves after generating the dupli-list. The emitter visibility option is messy design, it makes such checks unnecessarily complicated. A better approach would be to allow non-mesh objects to carry particle data, these objects would just be invisible anyway without having to care about extra settings. However, this conflicts with the simplistic particle design of "owner is the emitter" ... --- intern/cycles/blender/blender_object.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp index e10ffb3cf98..2c32c8ad83f 100644 --- a/intern/cycles/blender/blender_object.cpp +++ b/intern/cycles/blender/blender_object.cpp @@ -340,8 +340,19 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, int motion) Transform tfm = get_transform(b_dup->matrix()); BL::Object b_dup_ob = b_dup->object(); bool dup_hide = (b_v3d)? b_dup_ob.hide(): b_dup_ob.hide_render(); + bool emitter_hide = false; - if(!(b_dup->hide() || dup_hide)) { + if(b_dup_ob.is_duplicator()) { + emitter_hide = true; /* duplicators hidden by default */ + + /* check if we should render or hide particle emitter */ + BL::Object::particle_systems_iterator b_psys; + for(b_dup_ob.particle_systems.begin(b_psys); b_psys != b_dup_ob.particle_systems.end(); ++b_psys) + if(b_psys->settings().use_render_emitter()) + emitter_hide = false; + } + + if(!(b_dup->hide() || dup_hide || emitter_hide)) { sync_object(*b_ob, b_index, *b_dup, tfm, ob_layer, motion, b_dup->particle_index() + particle_offset); } From 12a8c19956815cda832c87761923f573a4d6b8d3 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 16 Oct 2012 16:04:12 +0000 Subject: [PATCH 274/347] un-subdivide bmesh operator, useful for making lower polygon versions of models, can give nicer results then edge collapsing which tends to give a lot of sharp triangles. works on edges and faces, has iteration option to further reduce the poly count. access from the edge menu, under subdivide. example: http://www.graphicall.org/ftp/ideasman42/bmesh_unsubdivide.png --- release/scripts/startup/bl_ui/space_view3d.py | 1 + source/blender/bmesh/CMakeLists.txt | 1 + source/blender/bmesh/intern/bmesh_core.c | 2 + source/blender/bmesh/intern/bmesh_iterators.h | 2 +- source/blender/bmesh/intern/bmesh_opdefines.c | 10 + .../bmesh/intern/bmesh_operators_private.h | 1 + .../blender/bmesh/operators/bmo_unsubdivide.c | 348 ++++++++++++++++++ source/blender/editors/mesh/editmesh_select.c | 14 +- source/blender/editors/mesh/editmesh_tools.c | 45 +++ source/blender/editors/mesh/mesh_intern.h | 1 + source/blender/editors/mesh/mesh_ops.c | 1 + 11 files changed, 422 insertions(+), 4 deletions(-) create mode 100644 source/blender/bmesh/operators/bmo_unsubdivide.c diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index f787f18fad3..ee40bf96a70 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -1821,6 +1821,7 @@ class VIEW3D_MT_edit_mesh_edges(Menu): layout.operator("mesh.edge_face_add") layout.operator("mesh.subdivide") + layout.operator("mesh.unsubdivide") layout.separator() diff --git a/source/blender/bmesh/CMakeLists.txt b/source/blender/bmesh/CMakeLists.txt index c23eb605614..20387684b66 100644 --- a/source/blender/bmesh/CMakeLists.txt +++ b/source/blender/bmesh/CMakeLists.txt @@ -56,6 +56,7 @@ set(SRC operators/bmo_subdivide.c operators/bmo_subdivide.h operators/bmo_triangulate.c + operators/bmo_unsubdivide.c operators/bmo_utils.c operators/bmo_wireframe.c diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c index 16c7f6f1539..413f480c60d 100644 --- a/source/blender/bmesh/intern/bmesh_core.c +++ b/source/blender/bmesh/intern/bmesh_core.c @@ -1143,6 +1143,8 @@ static BMFace *bm_face_create__sfme(BMesh *bm, BMFace *UNUSED(example)) /** * \brief Split Face Make Edge (SFME) * + * \warning this is a low level function, most likely you want to use #BM_face_split() + * * Takes as input two vertices in a single face. An edge is created which divides the original face * into two distinct regions. One of the regions is assigned to the original face and it is closed off. * The second region has a new face assigned to it. diff --git a/source/blender/bmesh/intern/bmesh_iterators.h b/source/blender/bmesh/intern/bmesh_iterators.h index 8d0eeca31ed..27e01f4eaf5 100644 --- a/source/blender/bmesh/intern/bmesh_iterators.h +++ b/source/blender/bmesh/intern/bmesh_iterators.h @@ -111,7 +111,7 @@ typedef struct BMIter { long l; float f; } filter; - int count; + int count; /* note, only some iterators set this, don't rely on it */ char itype; } BMIter; diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c index f50de0d6ee4..407e7caae0f 100644 --- a/source/blender/bmesh/intern/bmesh_opdefines.c +++ b/source/blender/bmesh/intern/bmesh_opdefines.c @@ -698,6 +698,15 @@ static BMOpDefine bmo_triangulate_def = { BMO_OP_FLAG_UNTAN_MULTIRES }; +static BMOpDefine bmo_unsubdivide_def = { + "unsubdivide", + {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertices */ + {BMO_OP_SLOT_INT, "iterations"}, + {0} /* null-terminating sentinel */}, + bmo_unsubdivide_exec, + BMO_OP_FLAG_UNTAN_MULTIRES +}; + static BMOpDefine bmo_subdivide_edges_def = { "subdivide_edges", {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, @@ -1274,6 +1283,7 @@ BMOpDefine *opdefines[] = { &bmo_translate_def, &bmo_triangle_fill_def, &bmo_triangulate_def, + &bmo_unsubdivide_def, &bmo_weld_verts_def, &bmo_wireframe_def, diff --git a/source/blender/bmesh/intern/bmesh_operators_private.h b/source/blender/bmesh/intern/bmesh_operators_private.h index fa239bb6ceb..d6135efe19a 100644 --- a/source/blender/bmesh/intern/bmesh_operators_private.h +++ b/source/blender/bmesh/intern/bmesh_operators_private.h @@ -101,6 +101,7 @@ void bmo_transform_exec(BMesh *bm, BMOperator *op); void bmo_translate_exec(BMesh *bm, BMOperator *op); void bmo_triangle_fill_exec(BMesh *bm, BMOperator *op); void bmo_triangulate_exec(BMesh *bm, BMOperator *op); +void bmo_unsubdivide_exec(BMesh *bm, BMOperator *op); void bmo_weld_verts_exec(BMesh *bm, BMOperator *op); void bmo_wireframe_exec(BMesh *bm, BMOperator *op); diff --git a/source/blender/bmesh/operators/bmo_unsubdivide.c b/source/blender/bmesh/operators/bmo_unsubdivide.c new file mode 100644 index 00000000000..01a9b6f8416 --- /dev/null +++ b/source/blender/bmesh/operators/bmo_unsubdivide.c @@ -0,0 +1,348 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Campbell Barton + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/bmesh/operators/bmo_unsubdivide.c + * \ingroup bmesh + */ + +#include "MEM_guardedalloc.h" + +#include "BLI_math.h" + +#include "bmesh.h" + +#include "intern/bmesh_operators_private.h" /* own include */ + + +static int bm_vert_dissolve_fan_test(BMVert *v) +{ + /* check if we should walk over these verts */ + BMIter iter; + BMEdge *e; + + unsigned int tot_edge = 0; + unsigned int tot_edge_boundary = 0; + unsigned int tot_edge_manifold = 0; + unsigned int tot_edge_wire = 0; + + BM_ITER_ELEM (e, &iter, v, BM_EDGES_OF_VERT) { + if (BM_edge_is_boundary(e)) { + tot_edge_boundary++; + } + else if (BM_edge_is_manifold(e)) { + tot_edge_manifold++; + } + else if (BM_edge_is_wire(e)) { + tot_edge_wire++; + } + tot_edge++; + } + + if ((tot_edge == 4) && (tot_edge_boundary == 0) && (tot_edge_manifold == 4)) { + return TRUE; + } + else if ((tot_edge == 3) && (tot_edge_boundary == 0) && (tot_edge_manifold == 3)) { + return TRUE; + } + else if ((tot_edge == 3) && (tot_edge_boundary == 2) && (tot_edge_manifold == 1)) { + return TRUE; + } + else if ((tot_edge == 2) && (tot_edge_wire == 2)) { + return TRUE; + } + return FALSE; +} + +static int bm_vert_dissolve_fan(BMesh *bm, BMVert *v) +{ + /* collapse under 2 conditions. + * - vert connects to 4 manifold edges (and 4 faces). + * - vert connecrs to 1 manifold edge, 2 boundary edges (and 2 faces). + * + * This covers boundary verts of a quad grid and center verts. + * note that surrounding faces dont have to be quads. + */ + + BMIter iter; + BMEdge *e; + + unsigned int tot_loop = 0; + unsigned int tot_edge = 0; + unsigned int tot_edge_boundary = 0; + unsigned int tot_edge_manifold = 0; + unsigned int tot_edge_wire = 0; + + BM_ITER_ELEM (e, &iter, v, BM_EDGES_OF_VERT) { + if (BM_edge_is_boundary(e)) { + tot_edge_boundary++; + } + else if (BM_edge_is_manifold(e)) { + tot_edge_manifold++; + } + else if (BM_edge_is_wire(e)) { + tot_edge_wire++; + } + tot_edge++; + } + + if (tot_edge == 2) { + /* check for 2 wire verts only */ + if (tot_edge_wire == 2) { + return (BM_vert_collapse_edge(bm, v->e, v, TRUE) != NULL); + } + } + else if (tot_edge == 4) { + /* check for 4 faces surrounding */ + if (tot_edge_boundary == 0 && tot_edge_manifold == 4) { + /* good to go! */ + tot_loop = 4; + } + } + else if (tot_edge == 3) { + /* check for 2 faces surrounding at a boundary */ + if (tot_edge_boundary == 2 && tot_edge_manifold == 1) { + /* good to go! */ + tot_loop = 2; + } + else if (tot_edge_boundary == 0 && tot_edge_manifold == 3) { + /* good to go! */ + tot_loop = 3; + } + } + + if (tot_loop) { + BMLoop *f_loop[4]; + unsigned int i; + + /* ensure there are exactly tot_loop loops */ + BLI_assert(BM_iter_at_index(bm, BM_LOOPS_OF_VERT, v, tot_loop) == NULL); + BM_iter_as_array(bm, BM_LOOPS_OF_VERT, v, (void **)f_loop, tot_loop); + + for (i = 0; i < tot_loop; i++) { + BMLoop *l = f_loop[i]; + if (l->f->len > 3) { + BLI_assert(l->prev->v != l->next->v); + BM_face_split(bm, l->f, l->prev->v, l->next->v, NULL, NULL, TRUE); + } + } + + return BM_vert_dissolve(bm, v); + } + + return FALSE; +} + +enum { + VERT_INDEX_DO_COLLAPSE = -1, + VERT_INDEX_INIT = 0, + VERT_INDEX_IGNORE = 1 +}; + +// #define USE_WALKER /* gives uneven results, disable for now */ +// #define USE_ALL_VERTS + +/* - BMVert.flag & BM_ELEM_TAG: shows we touched this vert + * - BMVert.index == -1: shows we will remove this vert + */ +void bmo_unsubdivide_exec(BMesh *bm, BMOperator *op) +{ +#ifdef USE_WALKER +# define ELE_VERT_TAG 1 +#else + BMVert **vert_seek_a = MEM_mallocN(sizeof(BMVert *) * bm->totvert, __func__); + BMVert **vert_seek_b = MEM_mallocN(sizeof(BMVert *) * bm->totvert, __func__); + unsigned vert_seek_a_tot = 0; + unsigned vert_seek_b_tot = 0; +#endif + + BMVert *v; + BMIter iter; + + const unsigned int offset = 0; + const unsigned int nth = 2; + + const int iterations = maxi(1, BMO_slot_int_get(op, "iterations")); + int iter_step; + +#ifdef USE_ALL_VERTS + (void)op; + BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { + BM_elem_flag_enable(v, BM_ELEM_TAG); + } +#else /* USE_ALL_VERTS */ + BMOpSlot *vinput = BMO_slot_get(op, "verts"); + BMVert **vinput_arr = (BMVert **)vinput->data.p; + int v_index; + + /* tag verts */ + BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { + BM_elem_flag_disable(v, BM_ELEM_TAG); + } + for (v_index = 0; v_index < vinput->len; v_index++) { + v = vinput_arr[v_index]; + BM_elem_flag_enable(v, BM_ELEM_TAG); + } +#endif /* USE_ALL_VERTS */ + + + for (iter_step = 0; iter_step < iterations; iter_step++) { + int iter_done; + + BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { + if (BM_elem_flag_test(v, BM_ELEM_TAG) && bm_vert_dissolve_fan_test(v)) { +#ifdef USE_WALKER + BMO_elem_flag_enable(bm, v, ELE_VERT_TAG); +#endif + BM_elem_index_set(v, VERT_INDEX_INIT); /* set_dirty! */ + } + else { + BM_elem_index_set(v, VERT_INDEX_IGNORE); /* set_dirty! */ + } + } + /* dont with selecting tagged verts */ + + + /* main loop, keep tagging until we can't tag any more islands */ + while (TRUE) { +#ifdef USE_WALKER + BMWalker walker; +#else + unsigned int depth = 1; + unsigned int i; +#endif + BMVert *v_first = NULL; + BMVert *v; + + /* we could avoid iterating from the start each time */ + BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { + if (v->e && (BM_elem_index_get(v) == VERT_INDEX_INIT)) { +#ifdef USE_WALKER + if (BMO_elem_flag_test(bm, v, ELE_VERT_TAG)) +#endif + { + /* check again incase the topology changed */ + if (bm_vert_dissolve_fan_test(v)) { + v_first = v; + } + break; + } + } + } + if (v_first == NULL) { + break; + } + +#ifdef USE_WALKER + /* Walk over selected elements starting at active */ + BMW_init(&walker, bm, BMW_CONNECTED_VERTEX, + ELE_VERT_TAG, BMW_MASK_NOP, BMW_MASK_NOP, + BMW_FLAG_NOP, /* don't use BMW_FLAG_TEST_HIDDEN here since we want to desel all */ + BMW_NIL_LAY); + + BLI_assert(walker.order == BMW_BREADTH_FIRST); + for (v = BMW_begin(&walker, v_first); v != NULL; v = BMW_step(&walker)) { + /* Deselect elements that aren't at "nth" depth from active */ + if (BM_elem_index_get(v) == VERT_INDEX_INIT) { + if ((offset + BMW_current_depth(&walker)) % nth) { + /* tag for removal */ + BM_elem_index_set(v, VERT_INDEX_DO_COLLAPSE); /* set_dirty! */ + } + else { + /* works better to allow these verts to be checked again */ + //BM_elem_index_set(v, VERT_INDEX_IGNORE); /* set_dirty! */ + } + } + } + BMW_end(&walker); +#else + + BM_elem_index_set(v_first, (offset + depth) % nth ? VERT_INDEX_IGNORE : VERT_INDEX_DO_COLLAPSE); /* set_dirty! */ + + vert_seek_b_tot = 0; + vert_seek_b[vert_seek_b_tot++] = v_first; + + while (TRUE) { + BMEdge *e; + + if ((offset + depth) % nth) { + vert_seek_a_tot = 0; + for (i = 0; i < vert_seek_b_tot; i++) { + v = vert_seek_b[i]; + BLI_assert(BM_elem_index_get(v) == VERT_INDEX_IGNORE); + BM_ITER_ELEM (e, &iter, v, BM_EDGES_OF_VERT) { + BMVert *v_other = BM_edge_other_vert(e, v); + if (BM_elem_index_get(v_other) == VERT_INDEX_INIT) { + BM_elem_index_set(v_other, VERT_INDEX_DO_COLLAPSE); /* set_dirty! */ + vert_seek_a[vert_seek_a_tot++] = v_other; + } + } + } + if (vert_seek_a_tot == 0) { + break; + } + } + else { + vert_seek_b_tot = 0; + for (i = 0; i < vert_seek_a_tot; i++) { + v = vert_seek_a[i]; + BLI_assert(BM_elem_index_get(v) == VERT_INDEX_DO_COLLAPSE); + BM_ITER_ELEM (e, &iter, v, BM_EDGES_OF_VERT) { + BMVert *v_other = BM_edge_other_vert(e, v); + if (BM_elem_index_get(v_other) == VERT_INDEX_INIT) { + BM_elem_index_set(v_other, VERT_INDEX_IGNORE); /* set_dirty! */ + vert_seek_b[vert_seek_b_tot++] = v_other; + } + } + } + if (vert_seek_b_tot == 0) { + break; + } + } + + depth++; + } +#endif /* USE_WALKER */ + + } + + /* now we tagged all verts -1 for removal, lets loop over and rebuild faces */ + iter_done = FALSE; + BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { + if (BM_elem_index_get(v) == VERT_INDEX_DO_COLLAPSE) { + iter_done |= bm_vert_dissolve_fan(bm, v); + } + } + + if (iter_done == FALSE) { + break; + } + } + + bm->elem_index_dirty |= BM_VERT; + +#ifndef USE_WALKER + MEM_freeN(vert_seek_a); + MEM_freeN(vert_seek_b); +#endif + +} + diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index fe3860de839..40132c697e6 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -2165,11 +2165,19 @@ static void walker_deselect_nth(BMEditMesh *em, int nth, int offset, BMHeader *h BMW_FLAG_NOP, /* don't use BMW_FLAG_TEST_HIDDEN here since we want to desel all */ BMW_NIL_LAY); + /* use tag to avoid touching the same verts twice */ + BM_ITER_MESH (ele, &iter, bm, itertype) { + BM_elem_flag_disable(ele, BM_ELEM_TAG); + } + BLI_assert(walker.order == BMW_BREADTH_FIRST); for (ele = BMW_begin(&walker, h_act); ele != NULL; ele = BMW_step(&walker)) { - /* Deselect elements that aren't at "nth" depth from active */ - if ((offset + BMW_current_depth(&walker)) % nth) { - BM_elem_select_set(bm, ele, FALSE); + if (!BM_elem_flag_test(ele, BM_ELEM_TAG)) { + /* Deselect elements that aren't at "nth" depth from active */ + if ((offset + BMW_current_depth(&walker)) % nth) { + BM_elem_select_set(bm, ele, FALSE); + } + BM_elem_flag_enable(ele, BM_ELEM_TAG); } } BMW_end(&walker); diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 1507597feeb..3255853442a 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -156,6 +156,51 @@ void MESH_OT_subdivide(wmOperatorType *ot) } +static int edbm_unsubdivide_exec(bContext *C, wmOperator *op) +{ + Object *obedit = CTX_data_edit_object(C); + BMEditMesh *em = BMEdit_FromObject(obedit); + BMOperator bmop; + + int iterations = RNA_int_get(op->ptr, "iterations"); + + EDBM_op_init(em, &bmop, op, + "unsubdivide verts=%hv iterations=%i", BM_ELEM_SELECT, iterations); + + BMO_op_exec(em->bm, &bmop); + + if (!EDBM_op_finish(em, &bmop, op, TRUE)) { + return 0; + } + + if ((em->selectmode & SCE_SELECT_VERTEX) == 0) { + EDBM_selectmode_flush_ex(em, SCE_SELECT_VERTEX); /* need to flush vert->face first */ + } + EDBM_selectmode_flush(em); + + EDBM_update_generic(C, em, TRUE); + + return OPERATOR_FINISHED; +} + +void MESH_OT_unsubdivide(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Un-Subdivide"; + ot->description = "UnSubdivide selected edges & faces"; + ot->idname = "MESH_OT_unsubdivide"; + + /* api callbacks */ + ot->exec = edbm_unsubdivide_exec; + ot->poll = ED_operator_editmesh; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* props */ + RNA_def_int(ot->srna, "iterations", 2, 1, INT_MAX, "Iterations", "Number of times to unsubdivide", 1, 100); +} + void EMBM_project_snap_verts(bContext *C, ARegion *ar, BMEditMesh *em) { Object *obedit = em->ob; diff --git a/source/blender/editors/mesh/mesh_intern.h b/source/blender/editors/mesh/mesh_intern.h index 5fcf4fe4377..5c782dc2266 100644 --- a/source/blender/editors/mesh/mesh_intern.h +++ b/source/blender/editors/mesh/mesh_intern.h @@ -144,6 +144,7 @@ extern struct EnumPropertyItem *corner_type_items; void MESH_OT_merge(struct wmOperatorType *ot); void MESH_OT_subdivide(struct wmOperatorType *ot); +void MESH_OT_unsubdivide(struct wmOperatorType *ot); void MESH_OT_remove_doubles(struct wmOperatorType *ot); void MESH_OT_spin(struct wmOperatorType *ot); void MESH_OT_screw(struct wmOperatorType *ot); diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c index 8a575e57a60..c4e8fd70989 100644 --- a/source/blender/editors/mesh/mesh_ops.c +++ b/source/blender/editors/mesh/mesh_ops.c @@ -74,6 +74,7 @@ void ED_operatortypes_mesh(void) WM_operatortype_append(MESH_OT_normals_make_consistent); WM_operatortype_append(MESH_OT_merge); WM_operatortype_append(MESH_OT_subdivide); + WM_operatortype_append(MESH_OT_unsubdivide); WM_operatortype_append(MESH_OT_faces_select_linked_flat); WM_operatortype_append(MESH_OT_edges_select_sharp); WM_operatortype_append(MESH_OT_primitive_plane_add); From c9fdf6e4960a01c3b42527a43b8ed7d325e6b95a Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Tue, 16 Oct 2012 17:01:22 +0000 Subject: [PATCH 275/347] Smoke: Animated collision objects do no longer block smoke. Smoke gets transfered velocity from moving collision object. Result: http://www.youtube.com/watch?v=KRtc8eAgaZA Part of my Blender Development Project Phase III, merged from Smoke2 branch WIP docs: http://wiki.blender.org/index.php/User:Genscher/Smoke_Development_Project_2012 --- intern/smoke/intern/FLUID_3D.cpp | 39 ++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/intern/smoke/intern/FLUID_3D.cpp b/intern/smoke/intern/FLUID_3D.cpp index 4f8fa0710a0..4eb11a46f5b 100644 --- a/intern/smoke/intern/FLUID_3D.cpp +++ b/intern/smoke/intern/FLUID_3D.cpp @@ -1047,21 +1047,52 @@ void FLUID_3D::project() setObstaclePressure(_pressure, 0, _zRes); // project out solution + // New idea for code from NVIDIA graphic gems 3 - DG float invDx = 1.0f / _dx; index = _slabSize + _xRes + 1; for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes) for (y = 1; y < _yRes - 1; y++, index += 2) for (x = 1; x < _xRes - 1; x++, index++) { + float vMask[3] = {1.0f, 1.0f, 1.0f}, vObst[3] = {0, 0, 0}; + float vR = 0.0f, vL = 0.0f, vT = 0.0f, vB = 0.0f, vD = 0.0f, vU = 0.0f; + + float pC = _pressure[index]; // center + float pR = _pressure[index + 1]; // right + float pL = _pressure[index - 1]; // left + float pU = _pressure[index + _xRes]; // Up + float pD = _pressure[index - _xRes]; // Down + float pT = _pressure[index + _slabSize]; // top + float pB = _pressure[index - _slabSize]; // bottom + if(!_obstacles[index]) { - _xVelocity[index] -= 0.5f * (_pressure[index + 1] - _pressure[index - 1]) * invDx; - _yVelocity[index] -= 0.5f * (_pressure[index + _xRes] - _pressure[index - _xRes]) * invDx; - _zVelocity[index] -= 0.5f * (_pressure[index + _slabSize] - _pressure[index - _slabSize]) * invDx; + // DG TODO: What if obstacle is left + right and one of them is moving? + if(_obstacles[index+1]) { pR = pC; vObst[0] = _xVelocityOb[index + 1]; vMask[0] = 0; } + if(_obstacles[index-1]) { pL = pC; vObst[0] = _xVelocityOb[index - 1]; vMask[0] = 0; } + if(_obstacles[index+_xRes]) { pU = pC; vObst[1] = _yVelocityOb[index + _xRes]; vMask[1] = 0; } + if(_obstacles[index-_xRes]) { pD = pC; vObst[1] = _yVelocityOb[index - _xRes]; vMask[1] = 0; } + if(_obstacles[index+_slabSize]) { pT = pC; vObst[2] = _zVelocityOb[index + _slabSize]; vMask[2] = 0; } + if(_obstacles[index-_slabSize]) { pB = pC; vObst[2] = _zVelocityOb[index - _slabSize]; vMask[2] = 0; } + + _xVelocity[index] -= 0.5f * (pR - pL) * invDx; + _yVelocity[index] -= 0.5f * (pU - pD) * invDx; + _zVelocity[index] -= 0.5f * (pT - pB) * invDx; + + _xVelocity[index] = (vMask[0] * _xVelocity[index]) + vObst[0]; + _yVelocity[index] = (vMask[1] * _yVelocity[index]) + vObst[1]; + _zVelocity[index] = (vMask[2] * _zVelocity[index]) + vObst[2]; + } + else + { + _xVelocity[index] = _xVelocityOb[index]; + _yVelocity[index] = _yVelocityOb[index]; + _zVelocity[index] = _zVelocityOb[index]; } } - setObstacleVelocity(0, _zRes); + // DG: was enabled in original code but now we do this later + // setObstacleVelocity(0, _zRes); if (_pressure) delete[] _pressure; if (_divergence) delete[] _divergence; From b4a83e1d0e524a165cef4d374b14ccebaf79b143 Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Tue, 16 Oct 2012 22:42:05 +0000 Subject: [PATCH 276/347] Cycles / OSL: * Ray Length is now available in OSL (via get_attribute) --- intern/cycles/kernel/osl/nodes/node_light_path.osl | 5 ++++- intern/cycles/kernel/osl/osl_services.cpp | 9 +++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/intern/cycles/kernel/osl/nodes/node_light_path.osl b/intern/cycles/kernel/osl/nodes/node_light_path.osl index 0ead20bf2bb..ca92a5e6553 100644 --- a/intern/cycles/kernel/osl/nodes/node_light_path.osl +++ b/intern/cycles/kernel/osl/nodes/node_light_path.osl @@ -25,7 +25,8 @@ shader node_light_path( output float IsGlossyRay = 0.0, output float IsSingularRay = 0.0, output float IsReflectionRay = 0.0, - output float IsTransmissionRay = 0.0) + output float IsTransmissionRay = 0.0, + output float RayLength = 0.0) { IsCameraRay = raytype("camera"); IsShadowRay = raytype("shadow"); @@ -34,5 +35,7 @@ shader node_light_path( IsSingularRay = raytype("singular"); IsReflectionRay = raytype("reflection"); IsTransmissionRay = raytype("refraction"); + + getattribute("std::ray_length", RayLength); } diff --git a/intern/cycles/kernel/osl/osl_services.cpp b/intern/cycles/kernel/osl/osl_services.cpp index 6393412855b..be5273b9ad3 100644 --- a/intern/cycles/kernel/osl/osl_services.cpp +++ b/intern/cycles/kernel/osl/osl_services.cpp @@ -459,6 +459,15 @@ static bool get_object_standard_attribute(KernelGlobals *kg, ShaderData *sd, ust set_attribute_float3(fval, type, derivatives, val); return true; } + + /* Ray Length */ + else if (name == "std::ray_length") { + float fval[3]; + fval[0] = sd->ray_length; + fval[1] = fval[2] = 0.0; /* derivates set to 0 */ + set_attribute_float(fval, type, derivatives, val); + return true; + } else return false; From a1af01249de4be5f212ff896075626630c453846 Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Wed, 17 Oct 2012 00:28:46 +0000 Subject: [PATCH 277/347] Cycles / OSL: * Add Light Falloff Node. --- intern/cycles/kernel/osl/nodes/CMakeLists.txt | 1 + .../kernel/osl/nodes/node_light_falloff.osl | 46 +++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 intern/cycles/kernel/osl/nodes/node_light_falloff.osl diff --git a/intern/cycles/kernel/osl/nodes/CMakeLists.txt b/intern/cycles/kernel/osl/nodes/CMakeLists.txt index 541076f84c9..cb965ac1530 100644 --- a/intern/cycles/kernel/osl/nodes/CMakeLists.txt +++ b/intern/cycles/kernel/osl/nodes/CMakeLists.txt @@ -30,6 +30,7 @@ set(SRC_OSL node_image_texture.osl node_invert.osl node_light_path.osl + node_light_falloff.osl node_magic_texture.osl node_mapping.osl node_math.osl diff --git a/intern/cycles/kernel/osl/nodes/node_light_falloff.osl b/intern/cycles/kernel/osl/nodes/node_light_falloff.osl new file mode 100644 index 00000000000..fd68594a1d8 --- /dev/null +++ b/intern/cycles/kernel/osl/nodes/node_light_falloff.osl @@ -0,0 +1,46 @@ +/* + * Copyright 2012, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "stdosl.h" + +shader node_light_falloff( + float Strength = 0.0, + float Smooth = 0.0, + output float Quadratic = 0.0, + output float Linear = 0.0, + output float Constant = 0.0) +{ + float ray_length = 0.0; + float strength = Strength; + getattribute("std::ray_length", ray_length); + + if(Smooth > 0.0) { + float squared = ray_length*ray_length; + strength *= squared/(Smooth + squared); + } + + /* Quadratic */ + Quadratic = strength; + + /* Linear */ + Linear = (strength*ray_length); + + /* Constant */ + Constant = (strength*ray_length*ray_length); +} + From aeda5142ef41ce69264166a5d7e31f2c110c0096 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 17 Oct 2012 01:47:37 +0000 Subject: [PATCH 278/347] style cleanup: make OSL follow our C style convention. http://wiki.blender.org/index.php/Dev:Doc/CodeStyle --- GNUmakefile | 60 ++++--- build_files/cmake/project_info.py | 2 +- build_files/cmake/project_source_info.py | 2 +- .../kernel/osl/nodes/node_attribute.osl | 4 +- .../kernel/osl/nodes/node_background.osl | 2 +- .../kernel/osl/nodes/node_blend_weight.osl | 6 +- .../kernel/osl/nodes/node_brick_texture.osl | 19 ++- .../kernel/osl/nodes/node_brightness.osl | 4 +- intern/cycles/kernel/osl/nodes/node_bump.osl | 4 +- .../kernel/osl/nodes/node_checker_texture.osl | 12 +- .../osl/nodes/node_convert_from_color.osl | 2 +- .../osl/nodes/node_convert_from_normal.osl | 2 +- .../osl/nodes/node_convert_from_point.osl | 2 +- .../osl/nodes/node_convert_from_vector.osl | 2 +- .../kernel/osl/nodes/node_diffuse_bsdf.osl | 2 +- .../cycles/kernel/osl/nodes/node_emission.osl | 6 +- .../osl/nodes/node_environment_texture.osl | 2 +- .../cycles/kernel/osl/nodes/node_fresnel.osl | 2 +- .../cycles/kernel/osl/nodes/node_geometry.osl | 4 +- .../kernel/osl/nodes/node_glass_bsdf.osl | 16 +- .../kernel/osl/nodes/node_glossy_bsdf.osl | 12 +- .../osl/nodes/node_gradient_texture.osl | 28 ++-- .../kernel/osl/nodes/node_image_texture.osl | 4 +- .../kernel/osl/nodes/node_magic_texture.osl | 50 +++--- intern/cycles/kernel/osl/nodes/node_math.osl | 46 +++--- intern/cycles/kernel/osl/nodes/node_mix.osl | 148 +++++++++--------- .../kernel/osl/nodes/node_mix_closure.osl | 2 +- .../osl/nodes/node_musgrave_texture.osl | 48 +++--- .../kernel/osl/nodes/node_noise_texture.osl | 6 +- .../osl/nodes/node_output_displacement.osl | 2 +- .../cycles/kernel/osl/nodes/node_rgb_ramp.osl | 6 +- .../kernel/osl/nodes/node_sky_texture.osl | 64 ++++---- intern/cycles/kernel/osl/nodes/node_texture.h | 14 +- .../osl/nodes/node_texture_coordinate.osl | 6 +- .../osl/nodes/node_translucent_bsdf.osl | 2 +- .../osl/nodes/node_transparent_bsdf.osl | 2 +- .../kernel/osl/nodes/node_vector_math.osl | 16 +- .../kernel/osl/nodes/node_velvet_bsdf.osl | 2 +- .../kernel/osl/nodes/node_voronoi_texture.osl | 6 +- .../kernel/osl/nodes/node_ward_bsdf.osl | 2 +- .../kernel/osl/nodes/node_wave_texture.osl | 14 +- 41 files changed, 326 insertions(+), 309 deletions(-) diff --git a/GNUmakefile b/GNUmakefile index 58707a03d75..f40f7490c62 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -163,12 +163,14 @@ help: @echo " * package_archive - build an archive package" @echo "" @echo "Testing Targets (not associated with building blender)" - @echo " * test - run ctest, currently tests import/export, operator execution and that python modules load" - @echo " * test_cmake - runs our own cmake file checker which detects errors in the cmake file list definitions" - @echo " * test_pep8 - checks all python script are pep8 which are tagged to use the stricter formatting" - @echo " * test_deprecated - checks for deprecation tags in our code which may need to be removed" - @echo " * test_style - checks C/C++ conforms with blenders style guide: http://wiki.blender.org/index.php/Dev:Doc/CodeStyle" - @echo " * test_style_qtc - same as test_style but outputs QtCreator tasks format" + @echo " * test - run ctest, currently tests import/export, operator execution and that python modules load" + @echo " * test_cmake - runs our own cmake file checker which detects errors in the cmake file list definitions" + @echo " * test_pep8 - checks all python script are pep8 which are tagged to use the stricter formatting" + @echo " * test_deprecated - checks for deprecation tags in our code which may need to be removed" + @echo " * test_style_c - checks C/C++ conforms with blenders style guide: http://wiki.blender.org/index.php/Dev:Doc/CodeStyle" + @echo " * test_style_c_qtc - same as test_style but outputs QtCreator tasks format" + @echo " * test_style_osl - checks OpenShadingLanguage conforms with blenders style guide: http://wiki.blender.org/index.php/Dev:Doc/CodeStyle" + @echo " * test_style_osl_qtc - checks OpenShadingLanguage conforms with blenders style guide: http://wiki.blender.org/index.php/Dev:Doc/CodeStyle" @echo "" @echo "Static Source Code Checking (not associated with building blender)" @echo " * check_cppcheck - run blender source through cppcheck (C & C++)" @@ -211,28 +213,40 @@ test: # run pep8 check check on scripts we distribute. test_pep8: - python3.2 source/tests/pep8.py > test_pep8.log 2>&1 + python3 source/tests/pep8.py > test_pep8.log 2>&1 @echo "written: test_pep8.log" # run some checks on our cmakefiles. test_cmake: - python3.2 build_files/cmake/cmake_consistency_check.py > test_cmake_consistency.log 2>&1 + python3 build_files/cmake/cmake_consistency_check.py > test_cmake_consistency.log 2>&1 @echo "written: test_cmake_consistency.log" # run deprecation tests, see if we have anything to remove. test_deprecated: - python3.2 source/tests/check_deprecated.py + python3 source/tests/check_deprecated.py -test_style: +test_style_c: # run our own checks on C/C++ style - PYTHONIOENCODING=utf_8 python3.2 $(BLENDER_DIR)/source/tools/check_style_c.py $(BLENDER_DIR)/source/blender $(BLENDER_DIR)/source/creator --no-length-check + PYTHONIOENCODING=utf_8 python3 $(BLENDER_DIR)/source/tools/check_style_c.py $(BLENDER_DIR)/source/blender $(BLENDER_DIR)/source/creator --no-length-check -test_style_qtc: +test_style_c_qtc: # run our own checks on C/C++ style USE_QTC_TASK=1 \ - PYTHONIOENCODING=utf_8 python3.2 $(BLENDER_DIR)/source/tools/check_style_c.py $(BLENDER_DIR)/source/blender $(BLENDER_DIR)/source/creator --no-length-check > \ + PYTHONIOENCODING=utf_8 python3 $(BLENDER_DIR)/source/tools/check_style_c.py $(BLENDER_DIR)/source/blender $(BLENDER_DIR)/source/creator --no-length-check > \ test_style.tasks + @echo "written: test_style.tasks" + +test_style_osl: + # run our own checks on C/C++ style + PYTHONIOENCODING=utf_8 python3 $(BLENDER_DIR)/source/tools/check_style_c.py $(BLENDER_DIR)/intern/cycles/kernel/osl + + +test_style_osl_qtc: + # run our own checks on C/C++ style + USE_QTC_TASK=1 \ + PYTHONIOENCODING=utf_8 python3 $(BLENDER_DIR)/source/tools/check_style_c.py $(BLENDER_DIR)/intern/cycles/kernel/osl > \ + test_style.tasks @echo "written: test_style.tasks" # ----------------------------------------------------------------------------- @@ -240,10 +254,10 @@ test_style_qtc: # project_qtcreator: - python3.2 build_files/cmake/cmake_qtcreator_project.py $(BUILD_DIR) + python3 build_files/cmake/cmake_qtcreator_project.py $(BUILD_DIR) project_netbeans: - python3.2 build_files/cmake/cmake_netbeans_project.py $(BUILD_DIR) + python3 build_files/cmake/cmake_netbeans_project.py $(BUILD_DIR) project_eclipse: cmake -G"Eclipse CDT4 - Unix Makefiles" -H$(BLENDER_DIR) -B$(BUILD_DIR) @@ -255,29 +269,29 @@ project_eclipse: check_cppcheck: $(CMAKE_CONFIG) - cd $(BUILD_DIR) ; python3.2 $(BLENDER_DIR)/build_files/cmake/cmake_static_check_cppcheck.py + cd $(BUILD_DIR) ; python3 $(BLENDER_DIR)/build_files/cmake/cmake_static_check_cppcheck.py check_clang_array: $(CMAKE_CONFIG) - cd $(BUILD_DIR) ; python3.2 $(BLENDER_DIR)/build_files/cmake/cmake_static_check_clang_array.py + cd $(BUILD_DIR) ; python3 $(BLENDER_DIR)/build_files/cmake/cmake_static_check_clang_array.py check_splint: $(CMAKE_CONFIG) - cd $(BUILD_DIR) ; python3.2 $(BLENDER_DIR)/build_files/cmake/cmake_static_check_splint.py + cd $(BUILD_DIR) ; python3 $(BLENDER_DIR)/build_files/cmake/cmake_static_check_splint.py check_sparse: $(CMAKE_CONFIG) - cd $(BUILD_DIR) ; python3.2 $(BLENDER_DIR)/build_files/cmake/cmake_static_check_sparse.py + cd $(BUILD_DIR) ; python3 $(BLENDER_DIR)/build_files/cmake/cmake_static_check_sparse.py check_smatch: $(CMAKE_CONFIG) - cd $(BUILD_DIR) ; python3.2 $(BLENDER_DIR)/build_files/cmake/cmake_static_check_smatch.py + cd $(BUILD_DIR) ; python3 $(BLENDER_DIR)/build_files/cmake/cmake_static_check_smatch.py check_spelling_py: - cd $(BUILD_DIR) ; PYTHONIOENCODING=utf_8 python3.2 $(BLENDER_DIR)/source/tools/spell_check_source.py $(BLENDER_DIR)/release/scripts + cd $(BUILD_DIR) ; PYTHONIOENCODING=utf_8 python3 $(BLENDER_DIR)/source/tools/spell_check_source.py $(BLENDER_DIR)/release/scripts check_spelling_c: - cd $(BUILD_DIR) ; PYTHONIOENCODING=utf_8 python3.2 $(BLENDER_DIR)/source/tools/spell_check_source.py $(BLENDER_DIR)/source + cd $(BUILD_DIR) ; PYTHONIOENCODING=utf_8 python3 $(BLENDER_DIR)/source/tools/spell_check_source.py $(BLENDER_DIR)/source # ----------------------------------------------------------------------------- @@ -310,7 +324,7 @@ doc_dna: @echo "docs written into: '$(BLENDER_DIR)/doc/blender_file_format/dna.html'" doc_man: - python3.2 doc/manpage/blender.1.py $(BUILD_DIR)/bin/blender + python3 doc/manpage/blender.1.py $(BUILD_DIR)/bin/blender clean: diff --git a/build_files/cmake/project_info.py b/build_files/cmake/project_info.py index 7536e93b6ce..b154d578144 100755 --- a/build_files/cmake/project_info.py +++ b/build_files/cmake/project_info.py @@ -112,7 +112,7 @@ def is_glsl(filename): def is_c(filename): ext = splitext(filename)[1] - return (ext in (".c", ".cpp", ".cxx", ".m", ".mm", ".rc", ".cc", ".inl")) + return (ext in {".c", ".cpp", ".cxx", ".m", ".mm", ".rc", ".cc", ".inl", ".osl"}) def is_c_any(filename): diff --git a/build_files/cmake/project_source_info.py b/build_files/cmake/project_source_info.py index d80145b989c..10bc36ba1a8 100644 --- a/build_files/cmake/project_source_info.py +++ b/build_files/cmake/project_source_info.py @@ -48,7 +48,7 @@ def is_c_header(filename): def is_c(filename): ext = os.path.splitext(filename)[1] - return (ext in (".c", ".cpp", ".cxx", ".m", ".mm", ".rc", ".cc", ".inl")) + return (ext in {".c", ".cpp", ".cxx", ".m", ".mm", ".rc", ".cc", ".inl", ".osl"}) def is_c_any(filename): diff --git a/intern/cycles/kernel/osl/nodes/node_attribute.osl b/intern/cycles/kernel/osl/nodes/node_attribute.osl index d273d0c68d7..8e7c846d1a3 100644 --- a/intern/cycles/kernel/osl/nodes/node_attribute.osl +++ b/intern/cycles/kernel/osl/nodes/node_attribute.osl @@ -29,12 +29,12 @@ shader node_attribute( Vector = point(Color); getattribute(name, Fac); - if(bump_offset == "dx") { + if (bump_offset == "dx") { Color += Dx(Color); Vector += Dx(Vector); Fac += Dx(Fac); } - else if(bump_offset == "dy") { + else if (bump_offset == "dy") { Color += Dy(Color); Vector += Dy(Vector); Fac += Dy(Fac); diff --git a/intern/cycles/kernel/osl/nodes/node_background.osl b/intern/cycles/kernel/osl/nodes/node_background.osl index 69f8d85a82e..b51a1685294 100644 --- a/intern/cycles/kernel/osl/nodes/node_background.osl +++ b/intern/cycles/kernel/osl/nodes/node_background.osl @@ -23,6 +23,6 @@ shader node_background( float Strength = 1.0, output closure color Background = background()) { - Background = Color*Strength*background(); + Background = Color * Strength * background(); } diff --git a/intern/cycles/kernel/osl/nodes/node_blend_weight.osl b/intern/cycles/kernel/osl/nodes/node_blend_weight.osl index d834819ef3a..836897fc5e3 100644 --- a/intern/cycles/kernel/osl/nodes/node_blend_weight.osl +++ b/intern/cycles/kernel/osl/nodes/node_blend_weight.osl @@ -26,13 +26,13 @@ shader node_blend_weight( output float Facing = 0.0) { float f = max(1.0 - Blend, 1e-5); - Fresnel = fresnel_dielectric(I, Normal, backfacing()? f: 1.0/f); + Fresnel = fresnel_dielectric(I, Normal, backfacing()? f: 1.0 / f); Facing = abs(dot(I, Normal)); - if(Blend != 0.5) { + if (Blend != 0.5) { Blend = clamp(Blend, 0.0, 1.0); - Blend = (Blend < 0.5)? 2.0*Blend: 0.5/(1.0 - Blend); + Blend = (Blend < 0.5)? 2.0 * Blend: 0.5 / (1.0 - Blend); Facing = powf(Facing, Blend); } diff --git a/intern/cycles/kernel/osl/nodes/node_brick_texture.osl b/intern/cycles/kernel/osl/nodes/node_brick_texture.osl index 4daceb4018e..d6af5a21ce1 100644 --- a/intern/cycles/kernel/osl/nodes/node_brick_texture.osl +++ b/intern/cycles/kernel/osl/nodes/node_brick_texture.osl @@ -40,21 +40,21 @@ float brick(point p, float mortar_size, float bias, rownum = (int)floor(p[1] / row_height); - if(offset_frequency && squash_frequency) { + if (offset_frequency && squash_frequency) { brick_width *= ((int)(rownum) % squash_frequency ) ? 1.0 : squash_amount; /* squash */ - offset = ((int)(rownum) % offset_frequency ) ? 0 : (brick_width*offset_amount); /* offset */ + offset = ((int)(rownum) % offset_frequency ) ? 0 : (brick_width * offset_amount); /* offset */ } - bricknum = (int)floor((p[0]+offset) / brick_width); + bricknum = (int)floor((p[0] + offset) / brick_width); - x = (p[0]+offset) - brick_width*bricknum; - y = p[1] - row_height*rownum; + x = (p[0] + offset) - brick_width * bricknum; + y = p[1] - row_height * rownum; tint = clamp((brick_noise((rownum << 16) + (bricknum & 65535)) + bias), 0.0, 1.0); return (x < mortar_size || y < mortar_size || - x > (brick_width - mortar_size) || - y > (row_height - mortar_size)) ? 1.0 : 0.0; + x > (brick_width - mortar_size) || + y > (row_height - mortar_size)) ? 1.0 : 0.0; } shader node_brick_texture( @@ -77,10 +77,10 @@ shader node_brick_texture( float tint = 0.0; color Col = Color1; - Fac = brick(Vector*Scale, MortarSize, Bias, BrickWidth, RowHeight, + Fac = brick(Vector * Scale, MortarSize, Bias, BrickWidth, RowHeight, Offset, OffsetFrequency, Squash, SquashFrequency, tint); - if(Fac != 1.0) { + if (Fac != 1.0) { float facm = 1.0 - tint; Col[0] = facm * (Color1[0]) + tint * Color2[0]; @@ -89,6 +89,5 @@ shader node_brick_texture( } Color = (Fac == 1.0) ? Mortar: Col; - } diff --git a/intern/cycles/kernel/osl/nodes/node_brightness.osl b/intern/cycles/kernel/osl/nodes/node_brightness.osl index 4f19a20f736..2074623e3ff 100644 --- a/intern/cycles/kernel/osl/nodes/node_brightness.osl +++ b/intern/cycles/kernel/osl/nodes/node_brightness.osl @@ -24,7 +24,7 @@ shader node_brightness( float Contrast = 0.0, output color ColorOut = color(0.8, 0.8, 0.8)) { - float delta = Contrast * (1.0/200.0); + float delta = Contrast * (1.0 / 200.0); float a = 1.0 - delta * 2.0; float b; @@ -38,7 +38,7 @@ shader node_brightness( */ if (Contrast > 0.0) { - a = (a < 0.0 ? 1.0/a : 0.0); + a = (a < 0.0 ? 1.0 / a : 0.0); b = a * (bright_factor - delta); } else { diff --git a/intern/cycles/kernel/osl/nodes/node_bump.osl b/intern/cycles/kernel/osl/nodes/node_bump.osl index a3849e70f98..2fda73dabd5 100644 --- a/intern/cycles/kernel/osl/nodes/node_bump.osl +++ b/intern/cycles/kernel/osl/nodes/node_bump.osl @@ -37,10 +37,10 @@ surface node_bump( vector Ry = cross(N, dPdx); float det = dot(dPdx, Rx); - vector surfgrad = dx*Rx + dy*Ry; + vector surfgrad = dx * Rx + dy * Ry; surfgrad *= 0.1; /* todo: remove this factor */ - Normal = normalize(abs(det)*N - sign(det)*surfgrad); + Normal = normalize(abs(det) * N - sign(det) * surfgrad); } diff --git a/intern/cycles/kernel/osl/nodes/node_checker_texture.osl b/intern/cycles/kernel/osl/nodes/node_checker_texture.osl index e92d7be34fc..577caf308ff 100644 --- a/intern/cycles/kernel/osl/nodes/node_checker_texture.osl +++ b/intern/cycles/kernel/osl/nodes/node_checker_texture.osl @@ -23,15 +23,15 @@ float checker(point p) { - p[0] = (p[0] + 0.00001)*0.9999; - p[1] = (p[1] + 0.00001)*0.9999; - p[2] = (p[2] + 0.00001)*0.9999; + p[0] = (p[0] + 0.00001) * 0.9999; + p[1] = (p[1] + 0.00001) * 0.9999; + p[2] = (p[2] + 0.00001) * 0.9999; int xi = (int)fabs(floor(p[0])); int yi = (int)fabs(floor(p[1])); int zi = (int)fabs(floor(p[2])); - if((xi % 2 == yi % 2) == (zi % 2)) { + if ((xi % 2 == yi % 2) == (zi % 2)) { return 1.0; } else { @@ -47,8 +47,8 @@ shader node_checker_texture( output float Fac = 0.0, output color Color = color(0.0, 0.0, 0.0)) { - Fac = checker(Vector*Scale); - if(Fac == 1.0) { + Fac = checker(Vector * Scale); + if (Fac == 1.0) { Color = Color1; } else { diff --git a/intern/cycles/kernel/osl/nodes/node_convert_from_color.osl b/intern/cycles/kernel/osl/nodes/node_convert_from_color.osl index 97356139c48..c55b0f811ff 100644 --- a/intern/cycles/kernel/osl/nodes/node_convert_from_color.osl +++ b/intern/cycles/kernel/osl/nodes/node_convert_from_color.osl @@ -25,7 +25,7 @@ shader node_convert_from_color( output point Point = point(0.0, 0.0, 0.0), output normal Normal = normal(0.0, 0.0, 0.0)) { - Val = Color[0]*0.2126 + Color[1]*0.7152 + Color[2]*0.0722; + Val = Color[0] * 0.2126 + Color[1] * 0.7152 + Color[2] * 0.0722; Vector = vector(Color[0], Color[1], Color[2]); Point = point(Color[0], Color[1], Color[2]); Normal = normal(Color[0], Color[1], Color[2]); diff --git a/intern/cycles/kernel/osl/nodes/node_convert_from_normal.osl b/intern/cycles/kernel/osl/nodes/node_convert_from_normal.osl index 0bb9092591d..b2c6c76661c 100644 --- a/intern/cycles/kernel/osl/nodes/node_convert_from_normal.osl +++ b/intern/cycles/kernel/osl/nodes/node_convert_from_normal.osl @@ -25,7 +25,7 @@ shader node_convert_from_normal( output color Color = color(0.0, 0.0, 0.0), output point Point = point(0.0, 0.0, 0.0)) { - Val = (Normal[0] + Normal[1] + Normal[2])*(1.0/3.0); + Val = (Normal[0] + Normal[1] + Normal[2]) * (1.0 / 3.0); Vector = vector(Normal[0], Normal[1], Normal[2]); Color = color(Normal[0], Normal[1], Normal[2]); Point = point(Normal[0], Normal[1], Normal[2]); diff --git a/intern/cycles/kernel/osl/nodes/node_convert_from_point.osl b/intern/cycles/kernel/osl/nodes/node_convert_from_point.osl index e66d6a864d6..ae9a17dbc80 100644 --- a/intern/cycles/kernel/osl/nodes/node_convert_from_point.osl +++ b/intern/cycles/kernel/osl/nodes/node_convert_from_point.osl @@ -25,7 +25,7 @@ shader node_convert_from_point( output color Color = color(0.0, 0.0, 0.0), output normal Normal = normal(0.0, 0.0, 0.0)) { - Val = (Point[0] + Point[1] + Point[2])*(1.0/3.0); + Val = (Point[0] + Point[1] + Point[2]) * (1.0 / 3.0); Vector = vector(Point[0], Point[1], Point[2]); Color = color(Point[0], Point[1], Point[2]); Normal = normal(Point[0], Point[1], Point[2]); diff --git a/intern/cycles/kernel/osl/nodes/node_convert_from_vector.osl b/intern/cycles/kernel/osl/nodes/node_convert_from_vector.osl index 37ba9582cad..19ef9331c0c 100644 --- a/intern/cycles/kernel/osl/nodes/node_convert_from_vector.osl +++ b/intern/cycles/kernel/osl/nodes/node_convert_from_vector.osl @@ -25,7 +25,7 @@ shader node_convert_from_vector( output point Point = point(0.0, 0.0, 0.0), output normal Normal = normal(0.0, 0.0, 0.0)) { - Val = (Vector[0] + Vector[1] + Vector[2])*(1.0/3.0); + Val = (Vector[0] + Vector[1] + Vector[2]) * (1.0 / 3.0); Color = color(Vector[0], Vector[1], Vector[2]); Point = point(Vector[0], Vector[1], Vector[2]); Normal = normal(Vector[0], Vector[1], Vector[2]); diff --git a/intern/cycles/kernel/osl/nodes/node_diffuse_bsdf.osl b/intern/cycles/kernel/osl/nodes/node_diffuse_bsdf.osl index 6075b7c93f3..d6dc17316e8 100644 --- a/intern/cycles/kernel/osl/nodes/node_diffuse_bsdf.osl +++ b/intern/cycles/kernel/osl/nodes/node_diffuse_bsdf.osl @@ -24,7 +24,7 @@ shader node_diffuse_bsdf( normal Normal = N, output closure color BSDF = diffuse(Normal)) { - if(Roughness == 0.0) + if (Roughness == 0.0) BSDF = Color * diffuse(Normal); else BSDF = Color * oren_nayar(Normal, Roughness); diff --git a/intern/cycles/kernel/osl/nodes/node_emission.osl b/intern/cycles/kernel/osl/nodes/node_emission.osl index 8bfd1af173a..7ad0f9f7760 100644 --- a/intern/cycles/kernel/osl/nodes/node_emission.osl +++ b/intern/cycles/kernel/osl/nodes/node_emission.osl @@ -24,9 +24,9 @@ shader node_emission( float Strength = 1.0, output closure color Emission = emission()) { - if(TotalPower) - Emission = ((Strength/surfacearea())*Color)*emission(); + if (TotalPower) + Emission = ((Strength / surfacearea()) * Color) * emission(); else - Emission = (Strength*Color)*emission(); + Emission = (Strength * Color) * emission(); } diff --git a/intern/cycles/kernel/osl/nodes/node_environment_texture.osl b/intern/cycles/kernel/osl/nodes/node_environment_texture.osl index 3ad806781eb..bad62e56ab4 100644 --- a/intern/cycles/kernel/osl/nodes/node_environment_texture.osl +++ b/intern/cycles/kernel/osl/nodes/node_environment_texture.osl @@ -28,7 +28,7 @@ shader node_environment_texture( { Color = (color)environment(filename, Vector, "alpha", Alpha); - if(color_space == "sRGB") + if (color_space == "sRGB") Color = color_srgb_to_scene_linear(Color); } diff --git a/intern/cycles/kernel/osl/nodes/node_fresnel.osl b/intern/cycles/kernel/osl/nodes/node_fresnel.osl index 3af4448b43f..172f4dd9843 100644 --- a/intern/cycles/kernel/osl/nodes/node_fresnel.osl +++ b/intern/cycles/kernel/osl/nodes/node_fresnel.osl @@ -25,7 +25,7 @@ shader node_fresnel( output float Fac = 0.0) { float f = max(IOR, 1.0 + 1e-5); - float eta = backfacing()? 1.0/f: f; + float eta = backfacing()? 1.0 / f: f; Fac = fresnel_dielectric(I, Normal, eta); } diff --git a/intern/cycles/kernel/osl/nodes/node_geometry.osl b/intern/cycles/kernel/osl/nodes/node_geometry.osl index 9efc2a75c64..a3831cbec9c 100644 --- a/intern/cycles/kernel/osl/nodes/node_geometry.osl +++ b/intern/cycles/kernel/osl/nodes/node_geometry.osl @@ -38,11 +38,11 @@ shader node_geometry( Parametric = point(u, v, 0.0); Backfacing = backfacing(); - if(bump_offset == "dx") { + if (bump_offset == "dx") { Position += Dx(Position); Parametric += Dx(Parametric); } - else if(bump_offset == "dy") { + else if (bump_offset == "dy") { Position += Dy(Position); Parametric += Dy(Parametric); } diff --git a/intern/cycles/kernel/osl/nodes/node_glass_bsdf.osl b/intern/cycles/kernel/osl/nodes/node_glass_bsdf.osl index 52743669c99..8b069248a35 100644 --- a/intern/cycles/kernel/osl/nodes/node_glass_bsdf.osl +++ b/intern/cycles/kernel/osl/nodes/node_glass_bsdf.osl @@ -28,14 +28,16 @@ shader node_glass_bsdf( output closure color BSDF = diffuse(Normal)) { float f = max(IOR, 1.0 + 1e-5); - float eta = backfacing()? 1.0/f: f; + float eta = backfacing()? 1.0 / f: f; float Fr = fresnel_dielectric(I, Normal, eta); - if(distribution == "Sharp") - BSDF = Color*(Fr*reflection(Normal) + (1.0-Fr)*refraction(Normal, eta)); - else if(distribution == "Beckmann") - BSDF = Color*(Fr*microfacet_beckmann(Normal, Roughness, eta) + (1.0-Fr)*microfacet_beckmann_refraction(Normal, Roughness, eta)); - else if(distribution == "GGX") - BSDF = Color*(Fr*microfacet_ggx(Normal, Roughness, eta) + (1.0-Fr)*microfacet_ggx_refraction(Normal, Roughness, eta)); + if (distribution == "Sharp") + BSDF = Color * (Fr * reflection(Normal) + (1.0 - Fr) * refraction(Normal, eta)); + else if (distribution == "Beckmann") + BSDF = Color * (Fr * microfacet_beckmann(Normal, Roughness, eta) + + (1.0 - Fr) * microfacet_beckmann_refraction(Normal, Roughness, eta)); + else if (distribution == "GGX") + BSDF = Color * (Fr * microfacet_ggx(Normal, Roughness, eta) + + (1.0 - Fr) * microfacet_ggx_refraction(Normal, Roughness, eta)); } diff --git a/intern/cycles/kernel/osl/nodes/node_glossy_bsdf.osl b/intern/cycles/kernel/osl/nodes/node_glossy_bsdf.osl index 3890630e8a2..48d61ea0ab5 100644 --- a/intern/cycles/kernel/osl/nodes/node_glossy_bsdf.osl +++ b/intern/cycles/kernel/osl/nodes/node_glossy_bsdf.osl @@ -26,12 +26,12 @@ shader node_glossy_bsdf( normal Normal = N, output closure color BSDF = diffuse(Normal)) { - if(distribution == "Sharp") - BSDF = Color*reflection(Normal); - else if(distribution == "Beckmann") - BSDF = Color*microfacet_beckmann(Normal, Roughness, 1.0); - else if(distribution == "GGX") - BSDF = Color*microfacet_ggx(Normal, Roughness, 1.0); + if (distribution == "Sharp") + BSDF = Color * reflection(Normal); + else if (distribution == "Beckmann") + BSDF = Color * microfacet_beckmann(Normal, Roughness, 1.0); + else if (distribution == "GGX") + BSDF = Color * microfacet_ggx(Normal, Roughness, 1.0); } diff --git a/intern/cycles/kernel/osl/nodes/node_gradient_texture.osl b/intern/cycles/kernel/osl/nodes/node_gradient_texture.osl index e0cbc2cc569..ae7cfa51f59 100644 --- a/intern/cycles/kernel/osl/nodes/node_gradient_texture.osl +++ b/intern/cycles/kernel/osl/nodes/node_gradient_texture.osl @@ -31,31 +31,31 @@ float gradient(point p, string type) float result = 0.0; - if(type == "Linear") { + if (type == "Linear") { result = x; } - else if(type == "Quadratic") { + else if (type == "Quadratic") { float r = max(x, 0.0); - result = r*r; + result = r * r; } - else if(type == "Easing") { + else if (type == "Easing") { float r = min(max(x, 0.0), 1.0); - float t = r*r; + float t = r * r; - result = (3.0*t - 2.0*t*r); + result = (3.0 * t - 2.0 * t * r); } - else if(type == "Diagonal") { - result = (x + y)/2.0; + else if (type == "Diagonal") { + result = (x + y) / 2.0; } - else if(type == "Radial") { - result = atan2(y, x)/(2.0*M_PI) + 0.5; + else if (type == "Radial") { + result = atan2(y, x) / (2.0 * M_PI) + 0.5; } else { - float r = max(1.0 - sqrt(x*x + y*y + z*z), 0.0); + float r = max(1.0 - sqrt(x * x + y * y + z * z), 0.0); - if(type == "Quadratic Sphere") - result = r*r; - else if(type == "Spherical") + if (type == "Quadratic Sphere") + result = r * r; + else if (type == "Spherical") result = r; } diff --git a/intern/cycles/kernel/osl/nodes/node_image_texture.osl b/intern/cycles/kernel/osl/nodes/node_image_texture.osl index 38126401d76..e005f1f4245 100644 --- a/intern/cycles/kernel/osl/nodes/node_image_texture.osl +++ b/intern/cycles/kernel/osl/nodes/node_image_texture.osl @@ -26,9 +26,9 @@ shader node_image_texture( output color Color = color(0.0, 0.0, 0.0), output float Alpha = 1.0) { - Color = (color)texture(filename, Vector[0], 1.0-Vector[1], "wrap", "periodic", "alpha", Alpha); + Color = (color)texture(filename, Vector[0], 1.0 - Vector[1], "wrap", "periodic", "alpha", Alpha); - if(color_space == "sRGB") + if (color_space == "sRGB") Color = color_srgb_to_scene_linear(Color); } diff --git a/intern/cycles/kernel/osl/nodes/node_magic_texture.osl b/intern/cycles/kernel/osl/nodes/node_magic_texture.osl index c013ebfe658..e464b83bc9e 100644 --- a/intern/cycles/kernel/osl/nodes/node_magic_texture.osl +++ b/intern/cycles/kernel/osl/nodes/node_magic_texture.osl @@ -25,51 +25,51 @@ color magic(point p, int n, float distortion) { float dist = distortion; - float x = sin((p[0] + p[1] + p[2])*5.0); - float y = cos((-p[0] + p[1] - p[2])*5.0); - float z = -cos((-p[0] - p[1] + p[2])*5.0); + float x = sin(( p[0] + p[1] + p[2]) * 5.0); + float y = cos((-p[0] + p[1] - p[2]) * 5.0); + float z = -cos((-p[0] - p[1] + p[2]) * 5.0); - if(n > 0) { + if (n > 0) { x *= dist; y *= dist; z *= dist; - y = -cos(x-y+z); + y = -cos(x - y + z); y *= dist; - if(n > 1) { - x = cos(x-y-z); + if (n > 1) { + x = cos(x - y - z); x *= dist; - if(n > 2) { - z = sin(-x-y-z); + if (n > 2) { + z = sin(-x - y - z); z *= dist; - if(n > 3) { - x = -cos(-x+y-z); + if (n > 3) { + x = -cos(-x + y - z); x *= dist; - if(n > 4) { - y = -sin(-x+y+z); + if (n > 4) { + y = -sin(-x + y + z); y *= dist; - if(n > 5) { - y = -cos(-x+y+z); + if (n > 5) { + y = -cos(-x + y + z); y *= dist; - if(n > 6) { - x = cos(x+y+z); + if (n > 6) { + x = cos(x + y + z); x *= dist; - if(n > 7) { - z = sin(x+y-z); + if (n > 7) { + z = sin(x + y - z); z *= dist; - if(n > 8) { - x = -cos(-x-y+z); + if (n > 8) { + x = -cos(-x - y + z); x *= dist; - if(n > 9) { - y = -sin(x-y+z); + if (n > 9) { + y = -sin(x - y + z); y *= dist; } } @@ -82,7 +82,7 @@ color magic(point p, int n, float distortion) } } - if(dist != 0.0) { + if (dist != 0.0) { dist *= 2.0; x /= dist; y /= dist; @@ -99,6 +99,6 @@ shader node_magic_texture( point Vector = P, output color Color = color(0.0, 0.0, 0.0)) { - Color = magic(Vector*Scale, Depth, Distortion); + Color = magic(Vector * Scale, Depth, Distortion); } diff --git a/intern/cycles/kernel/osl/nodes/node_math.osl b/intern/cycles/kernel/osl/nodes/node_math.osl index 3327795286a..24dce898fd2 100644 --- a/intern/cycles/kernel/osl/nodes/node_math.osl +++ b/intern/cycles/kernel/osl/nodes/node_math.osl @@ -22,20 +22,20 @@ float safe_divide(float a, float b) { float result; - if(b == 0.0) + if (b == 0.0) result = 0.0; else - result = a/b; + result = a / b; return result; } float safe_log(float a, float b) { - if(a < 0.0 || b < 0.0) + if (a < 0.0 || b < 0.0) return 0.0; - return log(a)/log(b); + return log(a) / log(b); } shader node_math( @@ -47,42 +47,42 @@ shader node_math( { /* OSL asin, acos, pow check for values that could give rise to nan */ - if(type == "Add") + if (type == "Add") Value = Value1 + Value2; - if(type == "Subtract") + if (type == "Subtract") Value = Value1 - Value2; - if(type == "Multiply") - Value = Value1*Value2; - if(type == "Divide") + if (type == "Multiply") + Value = Value1 * Value2; + if (type == "Divide") Value = safe_divide(Value1, Value2); - if(type == "Sine") + if (type == "Sine") Value = sin(Value1); - if(type == "Cosine") + if (type == "Cosine") Value = cos(Value1); - if(type == "Tangent") + if (type == "Tangent") Value = tan(Value1); - if(type == "Arcsine") + if (type == "Arcsine") Value = asin(Value1); - if(type == "Arccosine") + if (type == "Arccosine") Value = acos(Value1); - if(type == "Arctangent") + if (type == "Arctangent") Value = atan(Value1); - if(type == "Power") + if (type == "Power") Value = pow(Value1, Value2); - if(type == "Logarithm") + if (type == "Logarithm") Value = safe_log(Value1, Value2); - if(type == "Minimum") + if (type == "Minimum") Value = min(Value1, Value2); - if(type == "Maximum") + if (type == "Maximum") Value = max(Value1, Value2); - if(type == "Round") + if (type == "Round") Value = floor(Value1 + 0.5); - if(type == "Less Than") + if (type == "Less Than") Value = Value1 < Value2; - if(type == "Greater Than") + if (type == "Greater Than") Value = Value1 > Value2; - if(Clamp) + if (Clamp) Value = clamp(Value1, 0.0, 1.0); } diff --git a/intern/cycles/kernel/osl/nodes/node_mix.osl b/intern/cycles/kernel/osl/nodes/node_mix.osl index 2ce342c49cd..69e68e5ed15 100644 --- a/intern/cycles/kernel/osl/nodes/node_mix.osl +++ b/intern/cycles/kernel/osl/nodes/node_mix.osl @@ -38,7 +38,7 @@ color node_mix_screen(float t, color col1, color col2) { float tm = 1.0 - t; - return color(1.0) - (color(tm) + t*(color(1.0) - col2))*(color(1.0) - col1); + return color(1.0) - (color(tm) + t * (color(1.0) - col2)) * (color(1.0) - col1); } color node_mix_overlay(float t, color col1, color col2) @@ -47,20 +47,20 @@ color node_mix_overlay(float t, color col1, color col2) color outcol = col1; - if(outcol[0] < 0.5) - outcol[0] *= tm + 2.0*t*col2[0]; + if (outcol[0] < 0.5) + outcol[0] *= tm + 2.0 * t * col2[0]; else - outcol[0] = 1.0 - (tm + 2.0*t*(1.0 - col2[0]))*(1.0 - outcol[0]); + outcol[0] = 1.0 - (tm + 2.0 * t * (1.0 - col2[0])) * (1.0 - outcol[0]); - if(outcol[1] < 0.5) - outcol[1] *= tm + 2.0*t*col2[1]; + if (outcol[1] < 0.5) + outcol[1] *= tm + 2.0 * t * col2[1]; else - outcol[1] = 1.0 - (tm + 2.0*t*(1.0 - col2[1]))*(1.0 - outcol[1]); + outcol[1] = 1.0 - (tm + 2.0 * t * (1.0 - col2[1])) * (1.0 - outcol[1]); - if(outcol[2] < 0.5) - outcol[2] *= tm + 2.0*t*col2[2]; + if (outcol[2] < 0.5) + outcol[2] *= tm + 2.0 * t * col2[2]; else - outcol[2] = 1.0 - (tm + 2.0*t*(1.0 - col2[2]))*(1.0 - outcol[2]); + outcol[2] = 1.0 - (tm + 2.0 * t * (1.0 - col2[2])) * (1.0 - outcol[2]); return outcol; } @@ -76,9 +76,9 @@ color node_mix_div(float t, color col1, color col2) color outcol = col1; - if(col2[0] != 0.0) outcol[0] = tm*outcol[0] + t*outcol[0]/col2[0]; - if(col2[1] != 0.0) outcol[1] = tm*outcol[1] + t*outcol[1]/col2[1]; - if(col2[2] != 0.0) outcol[2] = tm*outcol[2] + t*outcol[2]/col2[2]; + if (col2[0] != 0.0) outcol[0] = tm * outcol[0] + t * outcol[0] / col2[0]; + if (col2[1] != 0.0) outcol[1] = tm * outcol[1] + t * outcol[1] / col2[1]; + if (col2[2] != 0.0) outcol[2] = tm * outcol[2] + t * outcol[2] / col2[2]; return outcol; } @@ -90,41 +90,41 @@ color node_mix_diff(float t, color col1, color col2) color node_mix_dark(float t, color col1, color col2) { - return min(col1, col2*t); + return min(col1, col2 * t); } color node_mix_light(float t, color col1, color col2) { - return max(col1, col2*t); + return max(col1, col2 * t); } color node_mix_dodge(float t, color col1, color col2) { color outcol = col1; - if(outcol[0] != 0.0) { - float tmp = 1.0 - t*col2[0]; - if(tmp <= 0.0) + if (outcol[0] != 0.0) { + float tmp = 1.0 - t * col2[0]; + if (tmp <= 0.0) outcol[0] = 1.0; - else if((tmp = outcol[0]/tmp) > 1.0) + else if ((tmp = outcol[0] / tmp) > 1.0) outcol[0] = 1.0; else outcol[0] = tmp; } - if(outcol[1] != 0.0) { - float tmp = 1.0 - t*col2[1]; - if(tmp <= 0.0) + if (outcol[1] != 0.0) { + float tmp = 1.0 - t * col2[1]; + if (tmp <= 0.0) outcol[1] = 1.0; - else if((tmp = outcol[1]/tmp) > 1.0) + else if ((tmp = outcol[1] / tmp) > 1.0) outcol[1] = 1.0; else outcol[1] = tmp; } - if(outcol[2] != 0.0) { - float tmp = 1.0 - t*col2[2]; - if(tmp <= 0.0) + if (outcol[2] != 0.0) { + float tmp = 1.0 - t * col2[2]; + if (tmp <= 0.0) outcol[2] = 1.0; - else if((tmp = outcol[2]/tmp) > 1.0) + else if ((tmp = outcol[2] / tmp) > 1.0) outcol[2] = 1.0; else outcol[2] = tmp; @@ -139,32 +139,32 @@ color node_mix_burn(float t, color col1, color col2) color outcol = col1; - tmp = tm + t*col2[0]; - if(tmp <= 0.0) + tmp = tm + t * col2[0]; + if (tmp <= 0.0) outcol[0] = 0.0; - else if((tmp = (1.0 - (1.0 - outcol[0])/tmp)) < 0.0) + else if ((tmp = (1.0 - (1.0 - outcol[0]) / tmp)) < 0.0) outcol[0] = 0.0; - else if(tmp > 1.0) + else if (tmp > 1.0) outcol[0] = 1.0; else outcol[0] = tmp; - tmp = tm + t*col2[1]; - if(tmp <= 0.0) + tmp = tm + t * col2[1]; + if (tmp <= 0.0) outcol[1] = 0.0; - else if((tmp = (1.0 - (1.0 - outcol[1])/tmp)) < 0.0) + else if ((tmp = (1.0 - (1.0 - outcol[1]) / tmp)) < 0.0) outcol[1] = 0.0; - else if(tmp > 1.0) + else if (tmp > 1.0) outcol[1] = 1.0; else outcol[1] = tmp; - tmp = tm + t*col2[2]; - if(tmp <= 0.0) + tmp = tm + t * col2[2]; + if (tmp <= 0.0) outcol[2] = 0.0; - else if((tmp = (1.0 - (1.0 - outcol[2])/tmp)) < 0.0) + else if ((tmp = (1.0 - (1.0 - outcol[2]) / tmp)) < 0.0) outcol[2] = 0.0; - else if(tmp > 1.0) + else if (tmp > 1.0) outcol[2] = 1.0; else outcol[2] = tmp; @@ -177,7 +177,7 @@ color node_mix_hue(float t, color col1, color col2) color outcol = col1; color hsv2 = rgb_to_hsv(col2); - if(hsv2[1] != 0.0) { + if (hsv2[1] != 0.0) { color hsv = rgb_to_hsv(outcol); hsv[0] = hsv2[0]; color tmp = hsv_to_rgb(hsv); @@ -196,10 +196,10 @@ color node_mix_sat(float t, color col1, color col2) color hsv = rgb_to_hsv(outcol); - if(hsv[1] != 0.0) { + if (hsv[1] != 0.0) { color hsv2 = rgb_to_hsv(col2); - hsv[1] = tm*hsv[1] + t*hsv2[1]; + hsv[1] = tm * hsv[1] + t * hsv2[1]; outcol = hsv_to_rgb(hsv); } @@ -213,7 +213,7 @@ color node_mix_val(float t, color col1, color col2) color hsv = rgb_to_hsv(col1); color hsv2 = rgb_to_hsv(col2); - hsv[2] = tm*hsv[2] + t*hsv2[2]; + hsv[2] = tm * hsv[2] + t * hsv2[2]; return hsv_to_rgb(hsv); } @@ -223,7 +223,7 @@ color node_mix_color(float t, color col1, color col2) color outcol = col1; color hsv2 = rgb_to_hsv(col2); - if(hsv2[1] != 0.0) { + if (hsv2[1] != 0.0) { color hsv = rgb_to_hsv(outcol); hsv[0] = hsv2[0]; hsv[1] = hsv2[1]; @@ -240,29 +240,29 @@ color node_mix_soft(float t, color col1, color col2) float tm = 1.0 - t; color one = color(1.0); - color scr = one - (one - col2)*(one - col1); + color scr = one - (one - col2) * (one - col1); - return tm*col1 + t*((one - col1)*col2*col1 + col1*scr); + return tm * col1 + t * ((one - col1) * col2 * col1 + col1 * scr); } color node_mix_linear(float t, color col1, color col2) { color outcol = col1; - if(col2[0] > 0.5) - outcol[0]= col1[0] + t*(2.0*(col2[0] - 0.5)); + if (col2[0] > 0.5) + outcol[0] = col1[0] + t * (2.0 * (col2[0] - 0.5)); else - outcol[0]= col1[0] + t*(2.0*(col2[0]) - 1.0); + outcol[0] = col1[0] + t * (2.0 * (col2[0]) - 1.0); - if(col2[1] > 0.5) - outcol[1]= col1[1] + t*(2.0*(col2[1] - 0.5)); + if (col2[1] > 0.5) + outcol[1] = col1[1] + t * (2.0 * (col2[1] - 0.5)); else - outcol[1]= col1[1] + t*(2.0*(col2[1]) - 1.0); + outcol[1] = col1[1] + t * (2.0 * (col2[1]) - 1.0); - if(col2[2] > 0.5) - outcol[2]= col1[2] + t*(2.0*(col2[2] - 0.5)); + if (col2[2] > 0.5) + outcol[2] = col1[2] + t * (2.0 * (col2[2] - 0.5)); else - outcol[2]= col1[2] + t*(2.0*(col2[2]) - 1.0); + outcol[2] = col1[2] + t * (2.0 * (col2[2]) - 1.0); return outcol; } @@ -288,44 +288,44 @@ shader node_mix( { float t = clamp(Fac, 0.0, 1.0); - if(type == "Mix") + if (type == "Mix") Color = node_mix_blend(t, Color1, Color2); - if(type == "Add") + if (type == "Add") Color = node_mix_add(t, Color1, Color2); - if(type == "Multiply") + if (type == "Multiply") Color = node_mix_mul(t, Color1, Color2); - if(type == "Screen") + if (type == "Screen") Color = node_mix_screen(t, Color1, Color2); - if(type == "Overlay") + if (type == "Overlay") Color = node_mix_overlay(t, Color1, Color2); - if(type == "Subtract") + if (type == "Subtract") Color = node_mix_sub(t, Color1, Color2); - if(type == "Divide") + if (type == "Divide") Color = node_mix_div(t, Color1, Color2); - if(type == "Difference") + if (type == "Difference") Color = node_mix_diff(t, Color1, Color2); - if(type == "Darken") + if (type == "Darken") Color = node_mix_dark(t, Color1, Color2); - if(type == "Lighten") + if (type == "Lighten") Color = node_mix_light(t, Color1, Color2); - if(type == "Dodge") + if (type == "Dodge") Color = node_mix_dodge(t, Color1, Color2); - if(type == "Burn") + if (type == "Burn") Color = node_mix_burn(t, Color1, Color2); - if(type == "Hue") + if (type == "Hue") Color = node_mix_hue(t, Color1, Color2); - if(type == "Saturation") + if (type == "Saturation") Color = node_mix_sat(t, Color1, Color2); - if(type == "Value") + if (type == "Value") Color = node_mix_val (t, Color1, Color2); - if(type == "Color") + if (type == "Color") Color = node_mix_color(t, Color1, Color2); - if(type == "Soft Light") + if (type == "Soft Light") Color = node_mix_soft(t, Color1, Color2); - if(type == "Linear Light") + if (type == "Linear Light") Color = node_mix_linear(t, Color1, Color2); - if(Clamp) + if (Clamp) Color = node_mix_clamp(Color); } diff --git a/intern/cycles/kernel/osl/nodes/node_mix_closure.osl b/intern/cycles/kernel/osl/nodes/node_mix_closure.osl index 1a377abd381..e28dd1fc436 100644 --- a/intern/cycles/kernel/osl/nodes/node_mix_closure.osl +++ b/intern/cycles/kernel/osl/nodes/node_mix_closure.osl @@ -25,6 +25,6 @@ shader node_mix_closure( output closure color Closure = background()) { float t = clamp(Fac, 0.0, 1.0); - Closure = (1.0 - t)*Closure1 + t*Closure2; + Closure = (1.0 - t) * Closure1 + t * Closure2; } diff --git a/intern/cycles/kernel/osl/nodes/node_musgrave_texture.osl b/intern/cycles/kernel/osl/nodes/node_musgrave_texture.osl index 7d125d50fd6..71461b8fd79 100644 --- a/intern/cycles/kernel/osl/nodes/node_musgrave_texture.osl +++ b/intern/cycles/kernel/osl/nodes/node_musgrave_texture.osl @@ -36,14 +36,14 @@ float noise_musgrave_fBm(point p, string basis, float H, float lacunarity, float float pwHL = pow(lacunarity, -H); int i; - for(i = 0; i < (int)octaves; i++) { + for (i = 0; i < (int)octaves; i++) { value += noise("perlin", p) * pwr; pwr *= pwHL; p *= lacunarity; } rmd = octaves - floor(octaves); - if(rmd != 0.0) + if (rmd != 0.0) value += rmd * noise("perlin", p) * pwr; return value; @@ -64,14 +64,14 @@ float noise_musgrave_multi_fractal(point p, string basis, float H, float lacunar float pwHL = pow(lacunarity, -H); int i; - for(i = 0; i < (int)octaves; i++) { + for (i = 0; i < (int)octaves; i++) { value *= (pwr * noise("perlin", p) + 1.0); pwr *= pwHL; p *= lacunarity; } rmd = octaves - floor(octaves); - if(rmd != 0.0) + if (rmd != 0.0) value *= (rmd * pwr * noise("perlin", p) + 1.0); /* correct? */ return value; @@ -96,7 +96,7 @@ float noise_musgrave_hetero_terrain(point p, string basis, float H, float lacuna value = offset + noise("perlin", p); p *= lacunarity; - for(i = 1; i < (int)octaves; i++) { + for (i = 1; i < (int)octaves; i++) { increment = (noise("perlin", p) + offset) * pwr * value; value += increment; pwr *= pwHL; @@ -104,7 +104,7 @@ float noise_musgrave_hetero_terrain(point p, string basis, float H, float lacuna } rmd = octaves - floor(octaves); - if(rmd != 0.0) { + if (rmd != 0.0) { increment = (noise("perlin", p) + offset) * pwr * value; value += rmd * increment; } @@ -120,7 +120,8 @@ float noise_musgrave_hetero_terrain(point p, string basis, float H, float lacuna * offset: raises the terrain from `sea level' */ -float noise_musgrave_hybrid_multi_fractal(point p, string basis, float H, float lacunarity, float octaves, float offset, float gain) +float noise_musgrave_hybrid_multi_fractal(point p, string basis, float H, + float lacunarity, float octaves, float offset, float gain) { float result, signal, weight, rmd; float pwHL = pow(lacunarity, -H); @@ -131,8 +132,8 @@ float noise_musgrave_hybrid_multi_fractal(point p, string basis, float H, float weight = gain * result; p *= lacunarity; - for(i = 1; (weight > 0.001) && (i < (int)octaves); i++) { - if(weight > 1.0) + for (i = 1; (weight > 0.001) && (i < (int)octaves); i++) { + if (weight > 1.0) weight = 1.0; signal = (noise("perlin", p) + offset) * pwr; @@ -143,7 +144,7 @@ float noise_musgrave_hybrid_multi_fractal(point p, string basis, float H, float } rmd = octaves - floor(octaves); - if(rmd != 0.0) + if (rmd != 0.0) result += rmd * ((noise("perlin", p) + offset) * pwr); return result; @@ -157,7 +158,8 @@ float noise_musgrave_hybrid_multi_fractal(point p, string basis, float H, float * offset: raises the terrain from `sea level' */ -float noise_musgrave_ridged_multi_fractal(point p, string basis, float H, float lacunarity, float octaves, float offset, float gain) +float noise_musgrave_ridged_multi_fractal(point p, string basis, float H, + float lacunarity, float octaves, float offset, float gain) { float result, signal, weight; float pwHL = pow(lacunarity, -H); @@ -169,7 +171,7 @@ float noise_musgrave_ridged_multi_fractal(point p, string basis, float H, float result = signal; weight = 1.0; - for(i = 1; i < (int)octaves; i++) { + for (i = 1; i < (int)octaves; i++) { p *= lacunarity; weight = clamp(signal * gain, 0.0, 1.0); signal = offset - fabs(noise("perlin", p)); @@ -202,18 +204,18 @@ shader node_musgrave_texture( string Basis = "Perlin"; float intensity = 1.0; - point p = Vector*Scale; + point p = Vector * Scale; - if(Type == "Multifractal") - Fac = intensity*noise_musgrave_multi_fractal(p, Basis, dimension, lacunarity, octaves); - else if(Type == "fBM") - Fac = intensity*noise_musgrave_fBm(p, Basis, dimension, lacunarity, octaves); - else if(Type == "Hybrid Multifractal") - Fac = intensity*noise_musgrave_hybrid_multi_fractal(p, Basis, dimension, lacunarity, octaves, Offset, Gain); - else if(Type == "Ridged Multifractal") - Fac = intensity*noise_musgrave_ridged_multi_fractal(p, Basis, dimension, lacunarity, octaves, Offset, Gain); - else if(Type == "Hetero Terrain") - Fac = intensity*noise_musgrave_hetero_terrain(p, Basis, dimension, lacunarity, octaves, Offset); + if (Type == "Multifractal") + Fac = intensity * noise_musgrave_multi_fractal(p, Basis, dimension, lacunarity, octaves); + else if (Type == "fBM") + Fac = intensity * noise_musgrave_fBm(p, Basis, dimension, lacunarity, octaves); + else if (Type == "Hybrid Multifractal") + Fac = intensity * noise_musgrave_hybrid_multi_fractal(p, Basis, dimension, lacunarity, octaves, Offset, Gain); + else if (Type == "Ridged Multifractal") + Fac = intensity * noise_musgrave_ridged_multi_fractal(p, Basis, dimension, lacunarity, octaves, Offset, Gain); + else if (Type == "Hetero Terrain") + Fac = intensity * noise_musgrave_hetero_terrain(p, Basis, dimension, lacunarity, octaves, Offset); Color = color(Fac, Fac, Fac); } diff --git a/intern/cycles/kernel/osl/nodes/node_noise_texture.osl b/intern/cycles/kernel/osl/nodes/node_noise_texture.osl index 1ddb4d8a08b..227b2bf8cea 100644 --- a/intern/cycles/kernel/osl/nodes/node_noise_texture.osl +++ b/intern/cycles/kernel/osl/nodes/node_noise_texture.osl @@ -25,8 +25,8 @@ float noise(point p, string basis, float distortion, float detail, float fac, co { point r; int hard = 0; - - if(distortion != 0.0) { + + if (distortion != 0.0) { r[0] = noise_basis(p + point(13.5), basis) * distortion; r[1] = noise_basis(p, basis) * distortion; r[2] = noise_basis(p - point(13.5), basis) * distortion; @@ -51,6 +51,6 @@ shader node_noise_texture( output color Color = color(0.2, 0.2, 0.2)) { string Basis = "Perlin"; - Fac = noise(Vector*Scale, Basis, Distortion, Detail, Fac, Color); + Fac = noise(Vector * Scale, Basis, Distortion, Detail, Fac, Color); } diff --git a/intern/cycles/kernel/osl/nodes/node_output_displacement.osl b/intern/cycles/kernel/osl/nodes/node_output_displacement.osl index a6b452c532a..5649b879c5b 100644 --- a/intern/cycles/kernel/osl/nodes/node_output_displacement.osl +++ b/intern/cycles/kernel/osl/nodes/node_output_displacement.osl @@ -20,6 +20,6 @@ displacement node_output_displacement(float Displacement = 0.0) { - P += N*Displacement*0.1; /* todo: get rid of this factor */ + P += N * Displacement * 0.1; /* todo: get rid of this factor */ } diff --git a/intern/cycles/kernel/osl/nodes/node_rgb_ramp.osl b/intern/cycles/kernel/osl/nodes/node_rgb_ramp.osl index 2bc10f31cb3..afce1127305 100644 --- a/intern/cycles/kernel/osl/nodes/node_rgb_ramp.osl +++ b/intern/cycles/kernel/osl/nodes/node_rgb_ramp.osl @@ -28,7 +28,7 @@ shader node_rgb_ramp( output float Alpha = 1.0 ) { - float f = clamp(Fac, 0.0, 1.0)*(RAMP_TABLE_SIZE-1); + float f = clamp(Fac, 0.0, 1.0) * (RAMP_TABLE_SIZE - 1); int i = (int)f; float t = f - (float)i; @@ -37,8 +37,8 @@ shader node_rgb_ramp( Alpha = ramp_alpha[i]; if (t > 0.0) { - Color = (1.0 - t)*Color + t*ramp_color[i+1]; - Alpha = (1.0 - t)*Alpha + t*ramp_alpha[i+1]; + Color = (1.0 - t) * Color + t * ramp_color[i + 1]; + Alpha = (1.0 - t) * Alpha + t * ramp_alpha[i + 1]; } } diff --git a/intern/cycles/kernel/osl/nodes/node_sky_texture.osl b/intern/cycles/kernel/osl/nodes/node_sky_texture.osl index fdb9b1d9708..932fb1e2f17 100644 --- a/intern/cycles/kernel/osl/nodes/node_sky_texture.osl +++ b/intern/cycles/kernel/osl/nodes/node_sky_texture.osl @@ -32,10 +32,10 @@ color xyY_to_xyz(float x, float y, float Y) { float X, Z; - if(y != 0.0) X = (x / y) * Y; + if (y != 0.0) X = (x / y) * Y; else X = 0.0; - if(y != 0.0 && Y != 0.0) Z = ((1.0 - x - y) / y) * Y; + if (y != 0.0 && Y != 0.0) Z = ((1.0 - x - y) / y) * Y; else Z = 0.0; return color(X, Y, Z); @@ -50,11 +50,11 @@ color xyz_to_rgb(float x, float y, float z) float sky_angle_between(float thetav, float phiv, float theta, float phi) { - float cospsi = sin(thetav)*sin(theta)*cos(phi - phiv) + cos(thetav)*cos(theta); + float cospsi = sin(thetav) * sin(theta) * cos(phi - phiv) + cos(thetav) * cos(theta); - if(cospsi > 1.0) + if (cospsi > 1.0) return 0.0; - if(cospsi < -1.0) + if (cospsi < -1.0) return M_PI; return acos(cospsi); @@ -70,7 +70,7 @@ float sky_perez_function(float lam[5], float theta, float gamma) float ctheta = cos(theta); float cgamma = cos(gamma); - return (1.0 + lam[0]*exp(lam[1] / ctheta)) * (1.0 + lam[2]*exp(lam[3]*gamma) + lam[4]*cgamma*cgamma); + return (1.0 + lam[0] * exp(lam[1] / ctheta)) * (1.0 + lam[2] * exp(lam[3] * gamma) + lam[4] * cgamma * cgamma); } color sky_xyz_radiance(KernelSunSky sunsky, vector dir) @@ -106,42 +106,42 @@ void precompute_sunsky(vector dir, float turbidity, output KernelSunSky sunsky) sunsky.phi = phi; sunsky.dir = dir; - float theta2 = theta*theta; - float theta3 = theta*theta*theta; + float theta2 = theta * theta; + float theta3 = theta * theta * theta; float T = turbidity; - float T2 = T*T; + float T2 = T * T; - float chi = (4.0/ 9.0- T / 120.0) * (M_PI - 2.0* theta); - sunsky.zenith_Y = (4.0453*T - 4.9710) * tan(chi) - 0.2155*T + 2.4192; + float chi = (4.0 / 9.0 - T / 120.0) * (M_PI - 2.0 * theta); + sunsky.zenith_Y = (4.0453 * T - 4.9710) * tan(chi) - 0.2155 * T + 2.4192; sunsky.zenith_Y *= 0.06; sunsky.zenith_x = - (0.00166* theta3 - 0.00375* theta2 + 0.00209* theta)*T2 + - (-0.02903* theta3 + 0.06377* theta2 - 0.03202* theta + 0.00394)*T + - (0.11693* theta3 - 0.21196* theta2 + 0.06052* theta + 0.25886); + ( 0.00166 * theta3 - 0.00375 * theta2 + 0.00209 * theta) * T2 + + (-0.02903 * theta3 + 0.06377 * theta2 - 0.03202 * theta + 0.00394) * T + + ( 0.11693 * theta3 - 0.21196 * theta2 + 0.06052 * theta + 0.25886); sunsky.zenith_y = - (0.00275* theta3 - 0.00610* theta2 + 0.00317* theta)*T2 + - (-0.04214* theta3 + 0.08970* theta2 - 0.04153* theta + 0.00516)*T + - (0.15346* theta3 - 0.26756* theta2 + 0.06670* theta + 0.26688); + ( 0.00275 * theta3 - 0.00610 * theta2 + 0.00317 * theta) * T2 + + (-0.04214 * theta3 + 0.08970 * theta2 - 0.04153 * theta + 0.00516) * T + + ( 0.15346 * theta3 - 0.26756 * theta2 + 0.06670 * theta + 0.26688); - sunsky.perez_Y[0] = (0.1787*T - 1.4630); - sunsky.perez_Y[1] = (-0.3554*T + 0.4275); - sunsky.perez_Y[2] = (-0.0227*T + 5.3251); - sunsky.perez_Y[3] = (0.1206*T - 2.5771); - sunsky.perez_Y[4] = (-0.0670*T + 0.3703); + sunsky.perez_Y[0] = ( 0.1787 * T - 1.4630); + sunsky.perez_Y[1] = (-0.3554 * T + 0.4275); + sunsky.perez_Y[2] = (-0.0227 * T + 5.3251); + sunsky.perez_Y[3] = ( 0.1206 * T - 2.5771); + sunsky.perez_Y[4] = (-0.0670 * T + 0.3703); - sunsky.perez_x[0] = (-0.0193*T - 0.2592); - sunsky.perez_x[1] = (-0.0665*T + 0.0008); - sunsky.perez_x[2] = (-0.0004*T + 0.2125); - sunsky.perez_x[3] = (-0.0641*T - 0.8989); - sunsky.perez_x[4] = (-0.0033*T + 0.0452); + sunsky.perez_x[0] = (-0.0193 * T - 0.2592); + sunsky.perez_x[1] = (-0.0665 * T + 0.0008); + sunsky.perez_x[2] = (-0.0004 * T + 0.2125); + sunsky.perez_x[3] = (-0.0641 * T - 0.8989); + sunsky.perez_x[4] = (-0.0033 * T + 0.0452); - sunsky.perez_y[0] = (-0.0167*T - 0.2608); - sunsky.perez_y[1] = (-0.0950*T + 0.0092); - sunsky.perez_y[2] = (-0.0079*T + 0.2102); - sunsky.perez_y[3] = (-0.0441*T - 1.6537); - sunsky.perez_y[4] = (-0.0109*T + 0.0529); + sunsky.perez_y[0] = (-0.0167 * T - 0.2608); + sunsky.perez_y[1] = (-0.0950 * T + 0.0092); + sunsky.perez_y[2] = (-0.0079 * T + 0.2102); + sunsky.perez_y[3] = (-0.0441 * T - 1.6537); + sunsky.perez_y[4] = (-0.0109 * T + 0.0529); sunsky.zenith_Y /= sky_perez_function(sunsky.perez_Y, 0, theta); sunsky.zenith_x /= sky_perez_function(sunsky.perez_x, 0, theta); diff --git a/intern/cycles/kernel/osl/nodes/node_texture.h b/intern/cycles/kernel/osl/nodes/node_texture.h index 7cd0742ffe8..1b3ba8207ab 100644 --- a/intern/cycles/kernel/osl/nodes/node_texture.h +++ b/intern/cycles/kernel/osl/nodes/node_texture.h @@ -235,21 +235,21 @@ float noise_turbulence(point p, string basis, float details, int hard) float rmd = octaves - floor(octaves); - if(rmd != 0.0) { - float t = noise_basis(fscale*p, basis); + if (rmd != 0.0) { + float t = noise_basis(fscale * p, basis); - if(hard) - t = fabs(2.0*t - 1.0); + if (hard) + t = fabs(2.0 * t - 1.0); float sum2 = sum + t*amp; - sum *= ((float)(1 << n)/(float)((1 << (n+1)) - 1)); - sum2 *= ((float)(1 << (n+1))/(float)((1 << (n+2)) - 1)); + sum *= ((float)(1 << n) / (float)((1 << (n + 1)) - 1)); + sum2 *= ((float)(1 << (n + 1)) / (float)((1 << (n + 2)) - 1)); return (1.0 - rmd)*sum + rmd*sum2; } else { - sum *= ((float)(1 << n)/(float)((1 << (n+1)) - 1)); + sum *= ((float)(1 << n) / (float)((1 << (n + 1)) - 1)); return sum; } } diff --git a/intern/cycles/kernel/osl/nodes/node_texture_coordinate.osl b/intern/cycles/kernel/osl/nodes/node_texture_coordinate.osl index 2acf72aef54..883135d2a43 100644 --- a/intern/cycles/kernel/osl/nodes/node_texture_coordinate.osl +++ b/intern/cycles/kernel/osl/nodes/node_texture_coordinate.osl @@ -30,7 +30,7 @@ shader node_texture_coordinate( output point Window = point(0.0, 0.0, 0.0), output point Reflection = point(0.0, 0.0, 0.0)) { - if(is_background) { + if (is_background) { Generated = P; UV = point(0.0, 0.0, 0.0); Object = P; @@ -48,14 +48,14 @@ shader node_texture_coordinate( Reflection = reflect(I, Normal); } - if(bump_offset == "dx") { + if (bump_offset == "dx") { Generated += Dx(Generated); UV += Dx(UV); Object += Dx(Object); Camera += Dx(Camera); Window += Dx(Window); } - else if(bump_offset == "dy") { + else if (bump_offset == "dy") { Generated += Dy(Generated); UV += Dy(UV); Object += Dy(Object); diff --git a/intern/cycles/kernel/osl/nodes/node_translucent_bsdf.osl b/intern/cycles/kernel/osl/nodes/node_translucent_bsdf.osl index 9acd46756d2..e7efe73700c 100644 --- a/intern/cycles/kernel/osl/nodes/node_translucent_bsdf.osl +++ b/intern/cycles/kernel/osl/nodes/node_translucent_bsdf.osl @@ -23,6 +23,6 @@ shader node_translucent_bsdf( normal Normal = N, output closure color BSDF = diffuse(Normal)) { - BSDF = Color*translucent(Normal); + BSDF = Color * translucent(Normal); } diff --git a/intern/cycles/kernel/osl/nodes/node_transparent_bsdf.osl b/intern/cycles/kernel/osl/nodes/node_transparent_bsdf.osl index b347bfb116b..875bce3f16c 100644 --- a/intern/cycles/kernel/osl/nodes/node_transparent_bsdf.osl +++ b/intern/cycles/kernel/osl/nodes/node_transparent_bsdf.osl @@ -23,6 +23,6 @@ shader node_transparent_bsdf( normal Normal = N, output closure color BSDF = diffuse(Normal)) { - BSDF = Color*transparent(); + BSDF = Color * transparent(); } diff --git a/intern/cycles/kernel/osl/nodes/node_vector_math.osl b/intern/cycles/kernel/osl/nodes/node_vector_math.osl index 9e0f0b60522..f22a6e8441a 100644 --- a/intern/cycles/kernel/osl/nodes/node_vector_math.osl +++ b/intern/cycles/kernel/osl/nodes/node_vector_math.osl @@ -25,27 +25,27 @@ shader node_vector_math( output float Value = 0.0, output vector Vector = vector(0.0, 0.0, 0.0)) { - if(type == "Add") { + if (type == "Add") { Vector = Vector1 + Vector2; - Value = (abs(Vector[0]) + abs(Vector[1]) + abs(Vector[2]))/3.0; + Value = (abs(Vector[0]) + abs(Vector[1]) + abs(Vector[2])) / 3.0; } - if(type == "Subtract") { + if (type == "Subtract") { Vector = Vector1 - Vector2; - Value = (abs(Vector[0]) + abs(Vector[1]) + abs(Vector[2]))/3.0; + Value = (abs(Vector[0]) + abs(Vector[1]) + abs(Vector[2])) / 3.0; } - if(type == "Average") { + if (type == "Average") { Value = length(Vector1 + Vector2); Vector = normalize(Vector1 + Vector2); } - if(type == "Dot Product") { + if (type == "Dot Product") { Value = dot(Vector1, Vector2); } - if(type == "Cross Product") { + if (type == "Cross Product") { vector c = cross(Vector1, Vector2); Value = length(c); Vector = normalize(c); } - if(type == "Normalize") { + if (type == "Normalize") { Value = length(Vector1); Vector = normalize(Vector1); } diff --git a/intern/cycles/kernel/osl/nodes/node_velvet_bsdf.osl b/intern/cycles/kernel/osl/nodes/node_velvet_bsdf.osl index 5e0cae8cbd1..4bb4e39a1ba 100644 --- a/intern/cycles/kernel/osl/nodes/node_velvet_bsdf.osl +++ b/intern/cycles/kernel/osl/nodes/node_velvet_bsdf.osl @@ -27,6 +27,6 @@ shader node_velvet_bsdf( { float sigma = clamp(Sigma, 0.0, 1.0); - BSDF = Color*ashikhmin_velvet(Normal, sigma, 1.0); + BSDF = Color * ashikhmin_velvet(Normal, sigma, 1.0); } diff --git a/intern/cycles/kernel/osl/nodes/node_voronoi_texture.osl b/intern/cycles/kernel/osl/nodes/node_voronoi_texture.osl index db08b64de1c..a44df00a267 100644 --- a/intern/cycles/kernel/osl/nodes/node_voronoi_texture.osl +++ b/intern/cycles/kernel/osl/nodes/node_voronoi_texture.osl @@ -32,16 +32,16 @@ shader node_voronoi_texture( float da[4]; point pa[4]; - voronoi(Vector*Scale, "Distance Squared", 1.0, da, pa); + voronoi(Vector * Scale, "Distance Squared", 1.0, da, pa); /* Colored output */ - if(Coloring == "Intensity") { + if (Coloring == "Intensity") { Fac = fabs(da[0]); Color = color(Fac); } else { Color = cellnoise_color(pa[0]); - Fac = (Color[0]+Color[1]+Color[2])*(1.0/3.0); + Fac = (Color[0] + Color[1] + Color[2]) * (1.0 / 3.0); } } diff --git a/intern/cycles/kernel/osl/nodes/node_ward_bsdf.osl b/intern/cycles/kernel/osl/nodes/node_ward_bsdf.osl index 68db07109ed..e204be123b8 100644 --- a/intern/cycles/kernel/osl/nodes/node_ward_bsdf.osl +++ b/intern/cycles/kernel/osl/nodes/node_ward_bsdf.osl @@ -25,6 +25,6 @@ shader node_ward_bsdf( normal Normal = N, output closure color BSDF = diffuse(Normal)) { - BSDF = Color*ward(Normal, normalize(dPdu), RoughnessU, RoughnessV); + BSDF = Color * ward(Normal, normalize(dPdu), RoughnessU, RoughnessV); } diff --git a/intern/cycles/kernel/osl/nodes/node_wave_texture.osl b/intern/cycles/kernel/osl/nodes/node_wave_texture.osl index db53faaf94b..79b8a8885d1 100644 --- a/intern/cycles/kernel/osl/nodes/node_wave_texture.osl +++ b/intern/cycles/kernel/osl/nodes/node_wave_texture.osl @@ -30,15 +30,15 @@ float wave(point p, float scale, string type, float detail, float distortion, fl float result = 0.0; float n = 0.0; - if(type == "Bands") { - n = (x + y + z)*10.0; + if (type == "Bands") { + n = (x + y + z) * 10.0; } - else if(type == "Rings") { - n = (sqrt(x*x + y*y + z*z)*20.0); + else if (type == "Rings") { + n = (sqrt(x * x + y * y + z * z) * 20.0); } - - if(distortion != 0.0) { - n = n +(distortion * noise_turbulence(p*dscale, "Perlin", detail, 0)); + + if (distortion != 0.0) { + n = n + (distortion * noise_turbulence(p * dscale, "Perlin", detail, 0)); } result = noise_wave("Sine", n); From fa06aab433d61949506b2291f69d05caf7cf5d6a Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 17 Oct 2012 01:53:29 +0000 Subject: [PATCH 279/347] code cleanup: add check spelling osl --- GNUmakefile | 17 ++++++++++------- .../cycles/kernel/osl/nodes/node_brightness.osl | 8 ++++---- intern/cycles/kernel/osl/nodes/node_bump.osl | 2 +- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/GNUmakefile b/GNUmakefile index f40f7490c62..f8207787cbe 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -173,13 +173,14 @@ help: @echo " * test_style_osl_qtc - checks OpenShadingLanguage conforms with blenders style guide: http://wiki.blender.org/index.php/Dev:Doc/CodeStyle" @echo "" @echo "Static Source Code Checking (not associated with building blender)" - @echo " * check_cppcheck - run blender source through cppcheck (C & C++)" - @echo " * check_clang_array - run blender source through clang array checking script (C & C++)" - @echo " * check_splint - run blenders source through splint (C only)" - @echo " * check_sparse - run blenders source through sparse (C only)" - @echo " * check_smatch - run blenders source through smatch (C only)" - @echo " * check_spelling_c - check for spelling errors (C/C++ only)" - @echo " * check_spelling_py - check for spelling errors (Python only)" + @echo " * check_cppcheck - run blender source through cppcheck (C & C++)" + @echo " * check_clang_array - run blender source through clang array checking script (C & C++)" + @echo " * check_splint - run blenders source through splint (C only)" + @echo " * check_sparse - run blenders source through sparse (C only)" + @echo " * check_smatch - run blenders source through smatch (C only)" + @echo " * check_spelling_c - check for spelling errors (OSL only)" + @echo " * check_spelling_osl - check for spelling errors (C/C++ only)" + @echo " * check_spelling_py - check for spelling errors (Python only)" @echo "" @echo "Utilities (not associated with building blender)" @echo " * tbz - create a compressed svn export 'blender_archive.tar.bz2'" @@ -293,6 +294,8 @@ check_spelling_py: check_spelling_c: cd $(BUILD_DIR) ; PYTHONIOENCODING=utf_8 python3 $(BLENDER_DIR)/source/tools/spell_check_source.py $(BLENDER_DIR)/source +check_spelling_osl: + cd $(BUILD_DIR) ; PYTHONIOENCODING=utf_8 python3 $(BLENDER_DIR)/source/tools/spell_check_source.py $(BLENDER_DIR)/intern/cycles/kernel/osl # ----------------------------------------------------------------------------- # Utilities diff --git a/intern/cycles/kernel/osl/nodes/node_brightness.osl b/intern/cycles/kernel/osl/nodes/node_brightness.osl index 2074623e3ff..8e9f5c9c796 100644 --- a/intern/cycles/kernel/osl/nodes/node_brightness.osl +++ b/intern/cycles/kernel/osl/nodes/node_brightness.osl @@ -32,10 +32,10 @@ shader node_brightness( float bright_factor = Brightness / 100.0; /* - * The algorithm is by Werner D. Streidt - * (http://visca.com/ffactory/archives/5-99/msg00021.html) - * Extracted of OpenCV demhist.c - */ + * The algorithm is by Werner D. Streidt + * (http://visca.com/ffactory/archives/5-99/msg00021.html) + * Extracted of OpenCV demhist.c + */ if (Contrast > 0.0) { a = (a < 0.0 ? 1.0 / a : 0.0); diff --git a/intern/cycles/kernel/osl/nodes/node_bump.osl b/intern/cycles/kernel/osl/nodes/node_bump.osl index 2fda73dabd5..dbc554e0a72 100644 --- a/intern/cycles/kernel/osl/nodes/node_bump.osl +++ b/intern/cycles/kernel/osl/nodes/node_bump.osl @@ -18,7 +18,7 @@ #include "stdosl.h" -/* "Bump Mapping Unparametrized Surfaces on the GPU" +/* "Bump Mapping Unparameterized Surfaces on the GPU" * Morten S. Mikkelsen, 2010 */ surface node_bump( From 536d9fec80dad342ef28f2fc8a0c5b4e5de98d31 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 17 Oct 2012 04:13:03 +0000 Subject: [PATCH 280/347] code cleanup: - move object_iterators.c --> view3d_iterators. (ED_object.h had to include ED_view3d.h which isn't so nice) - move projection functions from view3d_view.c --> view3d_project.c (view3d_view was becoming a mishmash of utility functions and operators). - some some cmake includes as system-includes. --- extern/libmv/CMakeLists.txt | 6 +- extern/libmv/bundle.sh | 6 +- extern/libmv/third_party/ceres/bundle.sh | 2 +- intern/bsp/CMakeLists.txt | 3 +- intern/cycles/bvh/CMakeLists.txt | 1 + intern/cycles/device/CMakeLists.txt | 1 + intern/cycles/kernel/CMakeLists.txt | 2 + intern/cycles/kernel/osl/CMakeLists.txt | 2 + intern/cycles/render/CMakeLists.txt | 1 + intern/cycles/subd/CMakeLists.txt | 2 + intern/cycles/util/CMakeLists.txt | 1 + intern/opencolorio/CMakeLists.txt | 1 + intern/opennl/CMakeLists.txt | 3 +- source/blender/editors/include/ED_object.h | 44 -- source/blender/editors/include/ED_view3d.h | 81 ++- source/blender/editors/object/CMakeLists.txt | 1 - .../editors/space_view3d/CMakeLists.txt | 2 + .../editors/space_view3d/view3d_intern.h | 2 - .../view3d_iterators.c} | 4 +- .../editors/space_view3d/view3d_project.c | 493 ++++++++++++++++++ .../editors/space_view3d/view3d_view.c | 485 ++--------------- source/blender/nodes/CMakeLists.txt | 8 +- source/blender/python/intern/CMakeLists.txt | 4 +- source/blender/windowmanager/CMakeLists.txt | 2 +- source/gameengine/Converter/CMakeLists.txt | 2 +- 25 files changed, 619 insertions(+), 540 deletions(-) rename source/blender/editors/{object/object_iterators.c => space_view3d/view3d_iterators.c} (99%) create mode 100644 source/blender/editors/space_view3d/view3d_project.c diff --git a/extern/libmv/CMakeLists.txt b/extern/libmv/CMakeLists.txt index 602372f6ff7..38be34add75 100644 --- a/extern/libmv/CMakeLists.txt +++ b/extern/libmv/CMakeLists.txt @@ -28,14 +28,14 @@ set(INC . - ../Eigen3 - third_party/ssba - third_party/ldl/Include ../colamd/Include third_party/ceres/include ) set(INC_SYS + ../Eigen3 + third_party/ssba + third_party/ldl/Include ${PNG_INCLUDE_DIR} ${ZLIB_INCLUDE_DIRS} ) diff --git a/extern/libmv/bundle.sh b/extern/libmv/bundle.sh index 3f877508c46..1e386ec8096 100755 --- a/extern/libmv/bundle.sh +++ b/extern/libmv/bundle.sh @@ -124,14 +124,14 @@ cat > CMakeLists.txt << EOF set(INC . - ../Eigen3 - third_party/ssba - third_party/ldl/Include ../colamd/Include third_party/ceres/include ) set(INC_SYS + ../Eigen3 + third_party/ssba + third_party/ldl/Include \${PNG_INCLUDE_DIR} \${ZLIB_INCLUDE_DIRS} ) diff --git a/extern/libmv/third_party/ceres/bundle.sh b/extern/libmv/third_party/ceres/bundle.sh index 902fce5f398..ccf6d0aca16 100755 --- a/extern/libmv/third_party/ceres/bundle.sh +++ b/extern/libmv/third_party/ceres/bundle.sh @@ -117,13 +117,13 @@ cat > CMakeLists.txt << EOF set(INC . - ../../../Eigen3 include internal ../gflags ) set(INC_SYS + ../../../Eigen3 ) set(SRC diff --git a/intern/bsp/CMakeLists.txt b/intern/bsp/CMakeLists.txt index 136c168bdb8..e3907c5273d 100644 --- a/intern/bsp/CMakeLists.txt +++ b/intern/bsp/CMakeLists.txt @@ -29,11 +29,10 @@ set(INC ../guardedalloc ../memutil ../moto/include - ../../extern/carve/include ) set(INC_SYS - + ../../extern/carve/include ) set(SRC diff --git a/intern/cycles/bvh/CMakeLists.txt b/intern/cycles/bvh/CMakeLists.txt index ba5c3785eac..cbbd23fcff8 100644 --- a/intern/cycles/bvh/CMakeLists.txt +++ b/intern/cycles/bvh/CMakeLists.txt @@ -7,6 +7,7 @@ set(INC ../util ../device ) + set(INC_SYS ) diff --git a/intern/cycles/device/CMakeLists.txt b/intern/cycles/device/CMakeLists.txt index 1d7c6ef4be3..0071bbe5cdc 100644 --- a/intern/cycles/device/CMakeLists.txt +++ b/intern/cycles/device/CMakeLists.txt @@ -7,6 +7,7 @@ set(INC ../util ../render ) + set(INC_SYS ${OPENGL_INCLUDE_DIR} ${GLEW_INCLUDE_PATH} diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt index ad1ce1df295..92d10f31af5 100644 --- a/intern/cycles/kernel/CMakeLists.txt +++ b/intern/cycles/kernel/CMakeLists.txt @@ -5,7 +5,9 @@ set(INC osl svm ) + set(INC_SYS + ) set(SRC diff --git a/intern/cycles/kernel/osl/CMakeLists.txt b/intern/cycles/kernel/osl/CMakeLists.txt index 65d7a7ad53b..f57dc1b666b 100644 --- a/intern/cycles/kernel/osl/CMakeLists.txt +++ b/intern/cycles/kernel/osl/CMakeLists.txt @@ -7,7 +7,9 @@ set(INC ../../util ../../device ) + set(INC_SYS + ) set(SRC diff --git a/intern/cycles/render/CMakeLists.txt b/intern/cycles/render/CMakeLists.txt index e75a3b37f3b..7907061c19c 100644 --- a/intern/cycles/render/CMakeLists.txt +++ b/intern/cycles/render/CMakeLists.txt @@ -8,6 +8,7 @@ set(INC ../bvh ../util ) + set(INC_SYS ${GLEW_INCLUDE_PATH} ) diff --git a/intern/cycles/subd/CMakeLists.txt b/intern/cycles/subd/CMakeLists.txt index c0986e9c173..838776d60bf 100644 --- a/intern/cycles/subd/CMakeLists.txt +++ b/intern/cycles/subd/CMakeLists.txt @@ -6,7 +6,9 @@ set(INC ../kernel/svm ../render ) + set(INC_SYS + ) set(SRC diff --git a/intern/cycles/util/CMakeLists.txt b/intern/cycles/util/CMakeLists.txt index c677f2b13f4..bf5f791a245 100644 --- a/intern/cycles/util/CMakeLists.txt +++ b/intern/cycles/util/CMakeLists.txt @@ -2,6 +2,7 @@ set(INC . ) + set(INC_SYS ${GLEW_INCLUDE_PATH} ${OPENGL_INCLUDE_DIR} diff --git a/intern/opencolorio/CMakeLists.txt b/intern/opencolorio/CMakeLists.txt index d46b09cf76a..c281a6e7bbb 100644 --- a/intern/opencolorio/CMakeLists.txt +++ b/intern/opencolorio/CMakeLists.txt @@ -30,6 +30,7 @@ set(INC ) set(INC_SYS + ) set(SRC diff --git a/intern/opennl/CMakeLists.txt b/intern/opennl/CMakeLists.txt index 322428386b1..b7a24839e38 100644 --- a/intern/opennl/CMakeLists.txt +++ b/intern/opennl/CMakeLists.txt @@ -40,11 +40,10 @@ add_definitions( set(INC extern superlu - ../../extern/colamd/Include ) set(INC_SYS - + ../../extern/colamd/Include ) set(SRC diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h index f792d8b1a87..3f66333f0d5 100644 --- a/source/blender/editors/include/ED_object.h +++ b/source/blender/editors/include/ED_object.h @@ -197,50 +197,6 @@ int ED_object_multires_update_totlevels_cb(struct Object *ob, void *totlevel_v); /* object_select.c */ void ED_object_select_linked_by_id(struct bContext *C, struct ID *id); - -/* object_iterators.c */ - -#include "ED_view3d.h" /* XXX, needed for eV3DProjTest */ - -/* foreach iterators */ -void mesh_foreachScreenVert( - struct ViewContext *vc, - void (*func)(void *userData, struct BMVert *eve, const float screen_co[2], int index), - void *userData, const eV3DProjTest clip_flag); -void mesh_foreachScreenEdge( - struct ViewContext *vc, - void (*func)(void *userData, struct BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], - int index), - void *userData, const eV3DProjTest clip_flag); -void mesh_foreachScreenFace( - struct ViewContext *vc, - void (*func)(void *userData, struct BMFace *efa, const float screen_co[2], int index), - void *userData, const eV3DProjTest clip_flag); -void nurbs_foreachScreenVert( - struct ViewContext *vc, - void (*func)(void *userData, struct Nurb *nu, struct BPoint *bp, struct BezTriple *bezt, - int beztindex, const float screen_co[2]), - void *userData, const eV3DProjTest clip_flag); -void mball_foreachScreenElem( - struct ViewContext *vc, - void (*func)(void *userData, struct MetaElem *ml, const float screen_co[2]), - void *userData, const eV3DProjTest clip_flag); -void lattice_foreachScreenVert( - struct ViewContext *vc, - void (*func)(void *userData, struct BPoint *bp, - const float screen_co[2]), - void *userData, const eV3DProjTest clip_flag); -void armature_foreachScreenBone( - struct ViewContext *vc, - void (*func)(void *userData, struct EditBone *ebone, - const float screen_co_a[2], const float screen_co_b[2]), - void *userData, const eV3DProjTest clip_flag); -void pose_foreachScreenBone( - struct ViewContext *vc, - void (*func)(void *userData, struct bPoseChannel *pchan, - const float screen_co_a[2], const float screen_co_b[2]), - void *userData, const eV3DProjTest clip_flag); - #ifdef __cplusplus } #endif diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index d0243527b83..fc24f68f2d1 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -37,6 +37,7 @@ struct BMEdge; struct BMFace; struct BMVert; struct BPoint; +struct Base; struct BezTriple; struct BezTriple; struct BoundBox; @@ -50,11 +51,12 @@ struct Nurb; struct Object; struct RegionView3D; struct Scene; -struct bScreen; struct ScrArea; struct View3D; struct ViewContext; struct bContext; +struct bPoseChannel; +struct bScreen; struct bglMats; struct rcti; struct wmOperator; @@ -84,15 +86,6 @@ typedef struct ViewDepths { float *give_cursor(struct Scene *scene, struct View3D *v3d); -int initgrabz(struct RegionView3D *rv3d, float x, float y, float z); - -void ED_view3d_win_to_3d(struct ARegion *ar, const float depth_pt[3], const float mval[2], float out[3]); -void ED_view3d_win_to_delta(struct ARegion *ar, const float mval[2], float out[3]); -void ED_view3d_win_to_vector(struct ARegion *ar, const float mval[2], float out[3]); -void ED_view3d_win_to_segment_clip(struct ARegion *ar, struct View3D *v3d, const float mval[2], float ray_start[3], float ray_end[3]); -void ED_view3d_win_to_ray(struct ARegion *ar, struct View3D *v3d, const float mval[2], float ray_start[3], float ray_normal[3]); - -void ED_view3d_global_to_vector(struct RegionView3D *rv3d, const float coord[3], float vec[3]); void ED_view3d_to_m4(float mat[][4], const float ofs[3], const float quat[4], const float dist); void ED_view3d_from_m4(float mat[][4], float ofs[3], float quat[4], float *dist); @@ -132,6 +125,55 @@ typedef enum { #define V3D_PROJ_TEST_ALL (V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) +/* view3d_iterators.c */ + +/* foreach iterators */ +void mesh_foreachScreenVert( + struct ViewContext *vc, + void (*func)(void *userData, struct BMVert *eve, const float screen_co[2], int index), + void *userData, const eV3DProjTest clip_flag); +void mesh_foreachScreenEdge( + struct ViewContext *vc, + void (*func)(void *userData, struct BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], + int index), + void *userData, const eV3DProjTest clip_flag); +void mesh_foreachScreenFace( + struct ViewContext *vc, + void (*func)(void *userData, struct BMFace *efa, const float screen_co[2], int index), + void *userData, const eV3DProjTest clip_flag); +void nurbs_foreachScreenVert( + struct ViewContext *vc, + void (*func)(void *userData, struct Nurb *nu, struct BPoint *bp, struct BezTriple *bezt, + int beztindex, const float screen_co[2]), + void *userData, const eV3DProjTest clip_flag); +void mball_foreachScreenElem( + struct ViewContext *vc, + void (*func)(void *userData, struct MetaElem *ml, const float screen_co[2]), + void *userData, const eV3DProjTest clip_flag); +void lattice_foreachScreenVert( + struct ViewContext *vc, + void (*func)(void *userData, struct BPoint *bp, + const float screen_co[2]), + void *userData, const eV3DProjTest clip_flag); +void armature_foreachScreenBone( + struct ViewContext *vc, + void (*func)(void *userData, struct EditBone *ebone, + const float screen_co_a[2], const float screen_co_b[2]), + void *userData, const eV3DProjTest clip_flag); +void pose_foreachScreenBone( + struct ViewContext *vc, + void (*func)(void *userData, struct bPoseChannel *pchan, + const float screen_co_a[2], const float screen_co_b[2]), + void *userData, const eV3DProjTest clip_flag); +/* *** end iterators *** */ + + +/* view3d_project.c */ +void ED_view3d_project_float_v2_m4(const struct ARegion *a, const float co[3], float r_co[2], float mat[4][4]); +void ED_view3d_project_float_v3_m4(struct ARegion *a, const float co[3], float r_co[3], float mat[4][4]); + +eV3DProjStatus ED_view3d_project_base(struct ARegion *ar, struct Base *base); + /* *** short *** */ eV3DProjStatus ED_view3d_project_short_ex(struct ARegion *ar, float perspmat[4][4], const int is_local, const float co[3], short r_co[2], const eV3DProjTest flag); @@ -150,17 +192,22 @@ eV3DProjStatus ED_view3d_project_float_ex(struct ARegion *ar, float perspmat[4][ eV3DProjStatus ED_view3d_project_float_global(struct ARegion *ar, const float co[3], float r_co[2], const eV3DProjTest flag); eV3DProjStatus ED_view3d_project_float_object(struct ARegion *ar, const float co[3], float r_co[2], const eV3DProjTest flag); -void ED_view3d_project_float_v2_m4(const struct ARegion *a, const float co[3], float r_co[2], float mat[4][4]); -void ED_view3d_project_float_v3_m4(struct ARegion *a, const float co[3], float r_co[3], float mat[4][4]); - -/* Base's get their own function since its a common operation */ -eV3DProjStatus ED_view3d_project_base(struct ARegion *ar, struct Base *base); - +int initgrabz(struct RegionView3D *rv3d, float x, float y, float z); +void ED_view3d_win_to_ray(struct ARegion *ar, struct View3D *v3d, const float mval[2], float ray_start[3], float ray_normal[3]); +void ED_view3d_global_to_vector(struct RegionView3D *rv3d, const float coord[3], float vec[3]); +void ED_view3d_win_to_3d(struct ARegion *ar, const float depth_pt[3], const float mval[2], float out[3]); +void ED_view3d_win_to_delta(struct ARegion *ar, const float mval[2], float out[3]); +void ED_view3d_win_to_vector(struct ARegion *ar, const float mval[2], float out[3]); +void ED_view3d_win_to_segment_clip(struct ARegion *ar, struct View3D *v3d, const float mval[2], float ray_start[3], float ray_end[3]); +void ED_view3d_ob_project_mat_get(struct RegionView3D *v3d, struct Object *ob, float pmat[4][4]); void ED_view3d_unproject(struct bglMats *mats, float out[3], const float x, const float y, const float z); +/* end */ + + + int ED_view3d_clip_range_get(struct View3D *v3d, struct RegionView3D *rv3d, float *clipsta, float *clipend); int ED_view3d_viewplane_get(struct View3D *v3d, struct RegionView3D *rv3d, int winxi, int winyi, struct rctf *viewplane, float *clipsta, float *clipend); -void ED_view3d_ob_project_mat_get(struct RegionView3D *v3d, struct Object *ob, float pmat[4][4]); void ED_view3d_calc_camera_border(struct Scene *scene, struct ARegion *ar, struct View3D *v3d, struct RegionView3D *rv3d, struct rctf *viewborder_r, short no_shift); void ED_view3d_calc_camera_border_size(struct Scene *scene, struct ARegion *ar, struct View3D *v3d, struct RegionView3D *rv3d, float size_r[2]); diff --git a/source/blender/editors/object/CMakeLists.txt b/source/blender/editors/object/CMakeLists.txt index a6745f95ea0..05c042a4182 100644 --- a/source/blender/editors/object/CMakeLists.txt +++ b/source/blender/editors/object/CMakeLists.txt @@ -46,7 +46,6 @@ set(SRC object_edit.c object_group.c object_hook.c - object_iterators.c object_lattice.c object_modifier.c object_ops.c diff --git a/source/blender/editors/space_view3d/CMakeLists.txt b/source/blender/editors/space_view3d/CMakeLists.txt index 1bba237ed5c..35dd88c3209 100644 --- a/source/blender/editors/space_view3d/CMakeLists.txt +++ b/source/blender/editors/space_view3d/CMakeLists.txt @@ -51,7 +51,9 @@ set(SRC view3d_edit.c view3d_fly.c view3d_header.c + view3d_iterators.c view3d_ops.c + view3d_project.c view3d_select.c view3d_snap.c view3d_toolbar.c diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h index 8f7656a1f37..3017891183e 100644 --- a/source/blender/editors/space_view3d/view3d_intern.h +++ b/source/blender/editors/space_view3d/view3d_intern.h @@ -51,8 +51,6 @@ struct wmNDOFMotionData; struct wmOperatorType; struct wmWindowManager; -#define BL_NEAR_CLIP 0.001 - /* drawing flags: */ enum { DRAW_PICKING = (1 << 0), diff --git a/source/blender/editors/object/object_iterators.c b/source/blender/editors/space_view3d/view3d_iterators.c similarity index 99% rename from source/blender/editors/object/object_iterators.c rename to source/blender/editors/space_view3d/view3d_iterators.c index c1841711435..0472f9f2c10 100644 --- a/source/blender/editors/object/object_iterators.c +++ b/source/blender/editors/space_view3d/view3d_iterators.c @@ -20,8 +20,8 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/editors/object/object_iterators.c - * \ingroup edobj +/** \file blender/editors/object/view3d_iterators.c + * \ingroup spview3d */ #include "DNA_curve_types.h" diff --git a/source/blender/editors/space_view3d/view3d_project.c b/source/blender/editors/space_view3d/view3d_project.c new file mode 100644 index 00000000000..5362f0377c3 --- /dev/null +++ b/source/blender/editors/space_view3d/view3d_project.c @@ -0,0 +1,493 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2008 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/space_view3d/view3d_project.c + * \ingroup spview3d + */ + +#include "DNA_object_types.h" +#include "DNA_screen_types.h" +#include "DNA_scene_types.h" +#include "DNA_view3d_types.h" + +#include "BLO_sys_types.h" /* int64_t */ + +#include "BIF_gl.h" /* bglMats */ +#include "BIF_glutil.h" /* bglMats */ + +#include "BLI_math_vector.h" + +#include "ED_view3d.h" /* own include */ + +#define BL_NEAR_CLIP 0.001 + +/* Non Clipping Projection Functions + * ********************************* */ + +/** + * \note use #ED_view3d_ob_project_mat_get to get the projection matrix + */ +void ED_view3d_project_float_v2_m4(const ARegion *ar, const float co[3], float r_co[2], float mat[4][4]) +{ + float vec4[4]; + + copy_v3_v3(vec4, co); + vec4[3] = 1.0; + /* r_co[0] = IS_CLIPPED; */ /* always overwritten */ + + mul_m4_v4(mat, vec4); + + if (vec4[3] > FLT_EPSILON) { + r_co[0] = (float)(ar->winx / 2.0f) + (ar->winx / 2.0f) * vec4[0] / vec4[3]; + r_co[1] = (float)(ar->winy / 2.0f) + (ar->winy / 2.0f) * vec4[1] / vec4[3]; + } + else { + zero_v2(r_co); + } +} + +/** + * \note use #ED_view3d_ob_project_mat_get to get projecting mat + */ +void ED_view3d_project_float_v3_m4(ARegion *ar, const float vec[3], float r_co[3], float mat[4][4]) +{ + float vec4[4]; + + copy_v3_v3(vec4, vec); + vec4[3] = 1.0; + /* r_co[0] = IS_CLIPPED; */ /* always overwritten */ + + mul_m4_v4(mat, vec4); + + if (vec4[3] > FLT_EPSILON) { + r_co[0] = (float)(ar->winx / 2.0f) + (ar->winx / 2.0f) * vec4[0] / vec4[3]; + r_co[1] = (float)(ar->winy / 2.0f) + (ar->winy / 2.0f) * vec4[1] / vec4[3]; + r_co[2] = vec4[2] / vec4[3]; + } + else { + zero_v3(r_co); + } +} + + +/* Clipping Projection Functions + * ***************************** */ + +eV3DProjStatus ED_view3d_project_base(struct ARegion *ar, struct Base *base) +{ + eV3DProjStatus ret = ED_view3d_project_short_global(ar, base->object->obmat[3], &base->sx, V3D_PROJ_TEST_CLIP_DEFAULT); + + if (ret != V3D_PROJ_RET_OK) { + base->sx = IS_CLIPPED; + base->sy = 0; + } + + return ret; +} + +/* perspmat is typically... + * - 'rv3d->perspmat', is_local == FALSE + * - 'rv3d->perspmatob', is_local == TRUE + */ +static eV3DProjStatus ed_view3d_project__internal(ARegion *ar, + float perspmat[4][4], const int is_local, /* normally hidden */ + const float co[3], float r_co[2], const eV3DProjTest flag) +{ + float fx, fy, vec4[4]; + + /* check for bad flags */ + BLI_assert((flag & V3D_PROJ_TEST_ALL) == flag); + + if (flag & V3D_PROJ_TEST_CLIP_BB) { + RegionView3D *rv3d = ar->regiondata; + if (rv3d->rflag & RV3D_CLIPPING) { + if (ED_view3d_clipping_test(rv3d, co, is_local)) { + return V3D_PROJ_RET_CLIP_BB; + } + } + } + + copy_v3_v3(vec4, co); + vec4[3] = 1.0; + mul_m4_v4(perspmat, vec4); + + if (vec4[3] > (float)BL_NEAR_CLIP) { + fx = ((float)ar->winx / 2.0f) * (1.0f + vec4[0] / vec4[3]); + if (((flag & V3D_PROJ_TEST_CLIP_WIN) == 0) || (fx > 0 && fx < ar->winx)) { + fy = ((float)ar->winy / 2.0f) * (1.0f + vec4[1] / vec4[3]); + if (((flag & V3D_PROJ_TEST_CLIP_WIN) == 0) || (fy > 0.0f && fy < (float)ar->winy)) { + r_co[0] = (short)floor(fx); + r_co[1] = (short)floor(fy); + } + else { + return V3D_PROJ_RET_CLIP_WIN; + } + } + else { + return V3D_PROJ_RET_CLIP_WIN; + } + } + else { + return V3D_PROJ_RET_CLIP_NEAR; + } + + return V3D_PROJ_RET_OK; +} + +eV3DProjStatus ED_view3d_project_short_ex(ARegion *ar, float perspmat[4][4], const int is_local, + const float co[3], short r_co[2], const eV3DProjTest flag) +{ + float tvec[2]; + eV3DProjStatus ret = ed_view3d_project__internal(ar, perspmat, is_local, co, tvec, flag); + if (ret == V3D_PROJ_RET_OK) { + if ((tvec[0] > -32700.0 && tvec[0] < 32700.0f) && + (tvec[1] > -32700.0 && tvec[1] < 32700.0f)) + { + r_co[0] = (short)floor(tvec[0]); + r_co[1] = (short)floor(tvec[1]); + } + else { + ret = V3D_PROJ_RET_OVERFLOW; + } + } + return ret; +} + +eV3DProjStatus ED_view3d_project_int_ex(ARegion *ar, float perspmat[4][4], const int is_local, + const float co[3], int r_co[2], const eV3DProjTest flag) +{ + float tvec[2]; + eV3DProjStatus ret = ed_view3d_project__internal(ar, perspmat, is_local, co, tvec, flag); + if (ret == V3D_PROJ_RET_OK) { + if ((tvec[0] > -2140000000.0 && tvec[0] < 2140000000.0f) && + (tvec[1] > -2140000000.0 && tvec[1] < 2140000000.0f)) + { + r_co[0] = (int)floor(tvec[0]); + r_co[1] = (int)floor(tvec[1]); + } + else { + ret = V3D_PROJ_RET_OVERFLOW; + } + } + return ret; +} + +eV3DProjStatus ED_view3d_project_float_ex(ARegion *ar, float perspmat[4][4], const int is_local, + const float co[3], float r_co[2], const eV3DProjTest flag) +{ + float tvec[2]; + eV3DProjStatus ret = ed_view3d_project__internal(ar, perspmat, is_local, co, tvec, flag); + if (ret == V3D_PROJ_RET_OK) { + if (finite(tvec[0]) && + finite(tvec[1])) + { + copy_v2_v2(r_co, tvec); + } + else { + ret = V3D_PROJ_RET_OVERFLOW; + } + } + return ret; +} + +/* --- short --- */ +eV3DProjStatus ED_view3d_project_short_global(ARegion *ar, const float co[3], short r_co[2], const eV3DProjTest flag) +{ + RegionView3D *rv3d = ar->regiondata; + return ED_view3d_project_short_ex(ar, rv3d->persmat, FALSE, co, r_co, flag); +} +/* object space, use ED_view3d_init_mats_rv3d before calling */ +eV3DProjStatus ED_view3d_project_short_object(ARegion *ar, const float co[3], short r_co[2], const eV3DProjTest flag) +{ + RegionView3D *rv3d = ar->regiondata; + return ED_view3d_project_short_ex(ar, rv3d->persmatob, TRUE, co, r_co, flag); +} + +/* --- int --- */ +eV3DProjStatus ED_view3d_project_int_global(ARegion *ar, const float co[3], int r_co[2], const eV3DProjTest flag) +{ + RegionView3D *rv3d = ar->regiondata; + return ED_view3d_project_int_ex(ar, rv3d->persmat, FALSE, co, r_co, flag); +} +/* object space, use ED_view3d_init_mats_rv3d before calling */ +eV3DProjStatus ED_view3d_project_int_object(ARegion *ar, const float co[3], int r_co[2], const eV3DProjTest flag) +{ + RegionView3D *rv3d = ar->regiondata; + return ED_view3d_project_int_ex(ar, rv3d->persmatob, TRUE, co, r_co, flag); +} + +/* --- float --- */ +eV3DProjStatus ED_view3d_project_float_global(ARegion *ar, const float co[3], float r_co[2], const eV3DProjTest flag) +{ + RegionView3D *rv3d = ar->regiondata; + return ED_view3d_project_float_ex(ar, rv3d->persmat, FALSE, co, r_co, flag); +} +/* object space, use ED_view3d_init_mats_rv3d before calling */ +eV3DProjStatus ED_view3d_project_float_object(ARegion *ar, const float co[3], float r_co[2], const eV3DProjTest flag) +{ + RegionView3D *rv3d = ar->regiondata; + return ED_view3d_project_float_ex(ar, rv3d->persmatob, TRUE, co, r_co, flag); +} + + + +/* More Generic Window/Ray/Vector projection functions + * *************************************************** */ + +/* odd function, need to document better */ +int initgrabz(RegionView3D *rv3d, float x, float y, float z) +{ + int flip = FALSE; + if (rv3d == NULL) return flip; + rv3d->zfac = rv3d->persmat[0][3] * x + rv3d->persmat[1][3] * y + rv3d->persmat[2][3] * z + rv3d->persmat[3][3]; + if (rv3d->zfac < 0.0f) + flip = TRUE; + /* if x,y,z is exactly the viewport offset, zfac is 0 and we don't want that + * (accounting for near zero values) + */ + if (rv3d->zfac < 1.e-6f && rv3d->zfac > -1.e-6f) rv3d->zfac = 1.0f; + + /* Negative zfac means x, y, z was behind the camera (in perspective). + * This gives flipped directions, so revert back to ok default case. + */ + /* NOTE: I've changed this to flip zfac to be positive again for now so that GPencil draws ok + * Aligorith, 2009Aug31 */ + //if (rv3d->zfac < 0.0f) rv3d->zfac = 1.0f; + if (rv3d->zfac < 0.0f) rv3d->zfac = -rv3d->zfac; + + return flip; +} + +/** + * Calculate a 3d viewpoint and direction vector from 2d window coordinates. + * This ray_start is located at the viewpoint, ray_normal is the direction towards mval. + * ray_start is clipped by the view near limit so points in front of it are always in view. + * In orthographic view the resulting ray_normal will match the view vector. + * \param ar The region (used for the window width and height). + * \param v3d The 3d viewport (used for near clipping value). + * \param mval The area relative 2d location (such as event->mval, converted into float[2]). + * \param ray_start The world-space starting point of the segment. + * \param ray_normal The normalized world-space direction of towards mval. + */ +void ED_view3d_win_to_ray(ARegion *ar, View3D *v3d, const float mval[2], float ray_start[3], float ray_normal[3]) +{ + float ray_end[3]; + + ED_view3d_win_to_segment_clip(ar, v3d, mval, ray_start, ray_end); + sub_v3_v3v3(ray_normal, ray_end, ray_start); + normalize_v3(ray_normal); +} + +/** + * Calculate a normalized 3d direction vector from the viewpoint towards a global location. + * In orthographic view the resulting vector will match the view vector. + * \param rv3d The region (used for the window width and height). + * \param coord The world-space location. + * \param vec The resulting normalized vector. + */ +void ED_view3d_global_to_vector(RegionView3D *rv3d, const float coord[3], float vec[3]) +{ + if (rv3d->is_persp) { + float p1[4], p2[4]; + + copy_v3_v3(p1, coord); + p1[3] = 1.0f; + copy_v3_v3(p2, p1); + p2[3] = 1.0f; + mul_m4_v4(rv3d->viewmat, p2); + + mul_v3_fl(p2, 2.0f); + + mul_m4_v4(rv3d->viewinv, p2); + + sub_v3_v3v3(vec, p1, p2); + } + else { + copy_v3_v3(vec, rv3d->viewinv[2]); + } + normalize_v3(vec); +} + +/** + * Calculate a 3d location from 2d window coordinates. + * \param ar The region (used for the window width and height). + * \param depth_pt The reference location used to calculate the Z depth. + * \param mval The area relative location (such as event->mval converted to floats). + * \param out The resulting world-space location. + */ +void ED_view3d_win_to_3d(ARegion *ar, const float depth_pt[3], const float mval[2], float out[3]) +{ + RegionView3D *rv3d = ar->regiondata; + + float line_sta[3]; + float line_end[3]; + + if (rv3d->is_persp) { + float mousevec[3]; + copy_v3_v3(line_sta, rv3d->viewinv[3]); + ED_view3d_win_to_vector(ar, mval, mousevec); + add_v3_v3v3(line_end, line_sta, mousevec); + + if (isect_line_plane_v3(out, line_sta, line_end, depth_pt, rv3d->viewinv[2], TRUE) == 0) { + /* highly unlikely to ever happen, mouse vec paralelle with view plane */ + zero_v3(out); + } + } + else { + const float dx = (2.0f * mval[0] / (float)ar->winx) - 1.0f; + const float dy = (2.0f * mval[1] / (float)ar->winy) - 1.0f; + line_sta[0] = (rv3d->persinv[0][0] * dx) + (rv3d->persinv[1][0] * dy) + rv3d->viewinv[3][0]; + line_sta[1] = (rv3d->persinv[0][1] * dx) + (rv3d->persinv[1][1] * dy) + rv3d->viewinv[3][1]; + line_sta[2] = (rv3d->persinv[0][2] * dx) + (rv3d->persinv[1][2] * dy) + rv3d->viewinv[3][2]; + + add_v3_v3v3(line_end, line_sta, rv3d->viewinv[2]); + closest_to_line_v3(out, depth_pt, line_sta, line_end); + } +} + +/** + * Calculate a 3d difference vector from 2d window offset. + * note that initgrabz() must be called first to determine + * the depth used to calculate the delta. + * \param ar The region (used for the window width and height). + * \param mval The area relative 2d difference (such as event->mval[0] - other_x). + * \param out The resulting world-space delta. + */ +void ED_view3d_win_to_delta(ARegion *ar, const float mval[2], float out[3]) +{ + RegionView3D *rv3d = ar->regiondata; + float dx, dy; + + dx = 2.0f * mval[0] * rv3d->zfac / ar->winx; + dy = 2.0f * mval[1] * rv3d->zfac / ar->winy; + + out[0] = (rv3d->persinv[0][0] * dx + rv3d->persinv[1][0] * dy); + out[1] = (rv3d->persinv[0][1] * dx + rv3d->persinv[1][1] * dy); + out[2] = (rv3d->persinv[0][2] * dx + rv3d->persinv[1][2] * dy); +} + +/** + * Calculate a 3d direction vector from 2d window coordinates. + * This direction vector starts and the view in the direction of the 2d window coordinates. + * In orthographic view all window coordinates yield the same vector. + * + * \note doesn't rely on initgrabz + * for perspective view, get the vector direction to + * the mouse cursor as a normalized vector. + * + * \param ar The region (used for the window width and height). + * \param mval The area relative 2d location (such as event->mval converted to floats). + * \param out The resulting normalized world-space direction vector. + */ +void ED_view3d_win_to_vector(ARegion *ar, const float mval[2], float out[3]) +{ + RegionView3D *rv3d = ar->regiondata; + + if (rv3d->is_persp) { + out[0] = 2.0f * (mval[0] / ar->winx) - 1.0f; + out[1] = 2.0f * (mval[1] / ar->winy) - 1.0f; + out[2] = -0.5f; + mul_project_m4_v3(rv3d->persinv, out); + sub_v3_v3(out, rv3d->viewinv[3]); + } + else { + copy_v3_v3(out, rv3d->viewinv[2]); + } + normalize_v3(out); +} + +/** + * Calculate a 3d segment from 2d window coordinates. + * This ray_start is located at the viewpoint, ray_end is a far point. + * ray_start and ray_end are clipped by the view near and far limits + * so points along this line are always in view. + * In orthographic view all resulting segments will be parallel. + * \param ar The region (used for the window width and height). + * \param v3d The 3d viewport (used for near and far clipping range). + * \param mval The area relative 2d location (such as event->mval, converted into float[2]). + * \param ray_start The world-space starting point of the segment. + * \param ray_end The world-space end point of the segment. + */ +void ED_view3d_win_to_segment_clip(ARegion *ar, View3D *v3d, const float mval[2], float ray_start[3], float ray_end[3]) +{ + RegionView3D *rv3d = ar->regiondata; + + if (rv3d->is_persp) { + float vec[3]; + ED_view3d_win_to_vector(ar, mval, vec); + + copy_v3_v3(ray_start, rv3d->viewinv[3]); + madd_v3_v3v3fl(ray_start, rv3d->viewinv[3], vec, v3d->near); + madd_v3_v3v3fl(ray_end, rv3d->viewinv[3], vec, v3d->far); + } + else { + float vec[4]; + vec[0] = 2.0f * mval[0] / ar->winx - 1; + vec[1] = 2.0f * mval[1] / ar->winy - 1; + vec[2] = 0.0f; + vec[3] = 1.0f; + + mul_m4_v4(rv3d->persinv, vec); + + madd_v3_v3v3fl(ray_start, vec, rv3d->viewinv[2], 1000.0f); + madd_v3_v3v3fl(ray_end, vec, rv3d->viewinv[2], -1000.0f); + } + + /* clipping */ + if (rv3d->rflag & RV3D_CLIPPING) { + int a; + for (a = 0; a < 4; a++) { + clip_line_plane(ray_start, ray_end, rv3d->clip[a]); + } + } +} + + +/* Utility functions for projection + * ******************************** */ + +void ED_view3d_ob_project_mat_get(RegionView3D *rv3d, Object *ob, float pmat[4][4]) +{ + float vmat[4][4]; + + mult_m4_m4m4(vmat, rv3d->viewmat, ob->obmat); + mult_m4_m4m4(pmat, rv3d->winmat, vmat); +} + +/** + * Uses window coordinates (x,y) and depth component z to find a point in + * modelspace */ +void ED_view3d_unproject(bglMats *mats, float out[3], const float x, const float y, const float z) +{ + double ux, uy, uz; + + gluUnProject(x, y, z, mats->modelview, mats->projection, + (GLint *)mats->viewport, &ux, &uy, &uz); + + out[0] = ux; + out[1] = uy; + out[2] = uz; +} diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index 6bdb6930fda..de8cbd856e8 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -571,211 +571,40 @@ void ED_view3d_clipping_calc(BoundBox *bb, float planes[4][4], bglMats *mats, co } } -/** - * Calculate a 3d segment from 2d window coordinates. - * This ray_start is located at the viewpoint, ray_end is a far point. - * ray_start and ray_end are clipped by the view near and far limits - * so points along this line are always in view. - * In orthographic view all resulting segments will be parallel. - * \param ar The region (used for the window width and height). - * \param v3d The 3d viewport (used for near and far clipping range). - * \param mval The area relative 2d location (such as event->mval, converted into float[2]). - * \param ray_start The world-space starting point of the segment. - * \param ray_end The world-space end point of the segment. - */ -void ED_view3d_win_to_segment_clip(ARegion *ar, View3D *v3d, const float mval[2], float ray_start[3], float ray_end[3]) + +int ED_view3d_boundbox_clip(RegionView3D *rv3d, float obmat[][4], BoundBox *bb) { - RegionView3D *rv3d = ar->regiondata; - - if (rv3d->is_persp) { - float vec[3]; - ED_view3d_win_to_vector(ar, mval, vec); + /* return 1: draw */ - copy_v3_v3(ray_start, rv3d->viewinv[3]); - madd_v3_v3v3fl(ray_start, rv3d->viewinv[3], vec, v3d->near); - madd_v3_v3v3fl(ray_end, rv3d->viewinv[3], vec, v3d->far); - } - else { - float vec[4]; - vec[0] = 2.0f * mval[0] / ar->winx - 1; - vec[1] = 2.0f * mval[1] / ar->winy - 1; - vec[2] = 0.0f; - vec[3] = 1.0f; - - mul_m4_v4(rv3d->persinv, vec); - - madd_v3_v3v3fl(ray_start, vec, rv3d->viewinv[2], 1000.0f); - madd_v3_v3v3fl(ray_end, vec, rv3d->viewinv[2], -1000.0f); + float mat[4][4]; + float vec[4], min, max; + int a, flag = -1, fl; + + if (bb == NULL) return 1; + if (bb->flag & OB_BB_DISABLED) return 1; + + mult_m4_m4m4(mat, rv3d->persmat, obmat); + + for (a = 0; a < 8; a++) { + copy_v3_v3(vec, bb->vec[a]); + vec[3] = 1.0; + mul_m4_v4(mat, vec); + max = vec[3]; + min = -vec[3]; + + fl = 0; + if (vec[0] < min) fl += 1; + if (vec[0] > max) fl += 2; + if (vec[1] < min) fl += 4; + if (vec[1] > max) fl += 8; + if (vec[2] < min) fl += 16; + if (vec[2] > max) fl += 32; + + flag &= fl; + if (flag == 0) return 1; } - /* clipping */ - if (rv3d->rflag & RV3D_CLIPPING) { - int a; - for (a = 0; a < 4; a++) { - clip_line_plane(ray_start, ray_end, rv3d->clip[a]); - } - } -} - -/** - * Calculate a 3d viewpoint and direction vector from 2d window coordinates. - * This ray_start is located at the viewpoint, ray_normal is the direction towards mval. - * ray_start is clipped by the view near limit so points in front of it are always in view. - * In orthographic view the resulting ray_normal will match the view vector. - * \param ar The region (used for the window width and height). - * \param v3d The 3d viewport (used for near clipping value). - * \param mval The area relative 2d location (such as event->mval, converted into float[2]). - * \param ray_start The world-space starting point of the segment. - * \param ray_normal The normalized world-space direction of towards mval. - */ -void ED_view3d_win_to_ray(ARegion *ar, View3D *v3d, const float mval[2], float ray_start[3], float ray_normal[3]) -{ - float ray_end[3]; - - ED_view3d_win_to_segment_clip(ar, v3d, mval, ray_start, ray_end); - sub_v3_v3v3(ray_normal, ray_end, ray_start); - normalize_v3(ray_normal); -} - -/** - * Calculate a normalized 3d direction vector from the viewpoint towards a global location. - * In orthographic view the resulting vector will match the view vector. - * \param rv3d The region (used for the window width and height). - * \param coord The world-space location. - * \param vec The resulting normalized vector. - */ -void ED_view3d_global_to_vector(RegionView3D *rv3d, const float coord[3], float vec[3]) -{ - if (rv3d->is_persp) { - float p1[4], p2[4]; - - copy_v3_v3(p1, coord); - p1[3] = 1.0f; - copy_v3_v3(p2, p1); - p2[3] = 1.0f; - mul_m4_v4(rv3d->viewmat, p2); - - mul_v3_fl(p2, 2.0f); - - mul_m4_v4(rv3d->viewinv, p2); - - sub_v3_v3v3(vec, p1, p2); - } - else { - copy_v3_v3(vec, rv3d->viewinv[2]); - } - normalize_v3(vec); -} - -int initgrabz(RegionView3D *rv3d, float x, float y, float z) -{ - int flip = FALSE; - if (rv3d == NULL) return flip; - rv3d->zfac = rv3d->persmat[0][3] * x + rv3d->persmat[1][3] * y + rv3d->persmat[2][3] * z + rv3d->persmat[3][3]; - if (rv3d->zfac < 0.0f) - flip = TRUE; - /* if x,y,z is exactly the viewport offset, zfac is 0 and we don't want that - * (accounting for near zero values) - */ - if (rv3d->zfac < 1.e-6f && rv3d->zfac > -1.e-6f) rv3d->zfac = 1.0f; - - /* Negative zfac means x, y, z was behind the camera (in perspective). - * This gives flipped directions, so revert back to ok default case. - */ - /* NOTE: I've changed this to flip zfac to be positive again for now so that GPencil draws ok - * Aligorith, 2009Aug31 */ - //if (rv3d->zfac < 0.0f) rv3d->zfac = 1.0f; - if (rv3d->zfac < 0.0f) rv3d->zfac = -rv3d->zfac; - - return flip; -} - -/** - * Calculate a 3d location from 2d window coordinates. - * \param ar The region (used for the window width and height). - * \param depth_pt The reference location used to calculate the Z depth. - * \param mval The area relative location (such as event->mval converted to floats). - * \param out The resulting world-space location. - */ -void ED_view3d_win_to_3d(ARegion *ar, const float depth_pt[3], const float mval[2], float out[3]) -{ - RegionView3D *rv3d = ar->regiondata; - - float line_sta[3]; - float line_end[3]; - - if (rv3d->is_persp) { - float mousevec[3]; - copy_v3_v3(line_sta, rv3d->viewinv[3]); - ED_view3d_win_to_vector(ar, mval, mousevec); - add_v3_v3v3(line_end, line_sta, mousevec); - - if (isect_line_plane_v3(out, line_sta, line_end, depth_pt, rv3d->viewinv[2], TRUE) == 0) { - /* highly unlikely to ever happen, mouse vec paralelle with view plane */ - zero_v3(out); - } - } - else { - const float dx = (2.0f * mval[0] / (float)ar->winx) - 1.0f; - const float dy = (2.0f * mval[1] / (float)ar->winy) - 1.0f; - line_sta[0] = (rv3d->persinv[0][0] * dx) + (rv3d->persinv[1][0] * dy) + rv3d->viewinv[3][0]; - line_sta[1] = (rv3d->persinv[0][1] * dx) + (rv3d->persinv[1][1] * dy) + rv3d->viewinv[3][1]; - line_sta[2] = (rv3d->persinv[0][2] * dx) + (rv3d->persinv[1][2] * dy) + rv3d->viewinv[3][2]; - - add_v3_v3v3(line_end, line_sta, rv3d->viewinv[2]); - closest_to_line_v3(out, depth_pt, line_sta, line_end); - } -} - -/** - * Calculate a 3d difference vector from 2d window offset. - * note that initgrabz() must be called first to determine - * the depth used to calculate the delta. - * \param ar The region (used for the window width and height). - * \param mval The area relative 2d difference (such as event->mval[0] - other_x). - * \param out The resulting world-space delta. - */ -void ED_view3d_win_to_delta(ARegion *ar, const float mval[2], float out[3]) -{ - RegionView3D *rv3d = ar->regiondata; - float dx, dy; - - dx = 2.0f * mval[0] * rv3d->zfac / ar->winx; - dy = 2.0f * mval[1] * rv3d->zfac / ar->winy; - - out[0] = (rv3d->persinv[0][0] * dx + rv3d->persinv[1][0] * dy); - out[1] = (rv3d->persinv[0][1] * dx + rv3d->persinv[1][1] * dy); - out[2] = (rv3d->persinv[0][2] * dx + rv3d->persinv[1][2] * dy); -} - -/** - * Calculate a 3d direction vector from 2d window coordinates. - * This direction vector starts and the view in the direction of the 2d window coordinates. - * In orthographic view all window coordinates yield the same vector. - * - * \note doesn't rely on initgrabz - * for perspective view, get the vector direction to - * the mouse cursor as a normalized vector. - * - * \param ar The region (used for the window width and height). - * \param mval The area relative 2d location (such as event->mval converted to floats). - * \param out The resulting normalized world-space direction vector. - */ -void ED_view3d_win_to_vector(ARegion *ar, const float mval[2], float out[3]) -{ - RegionView3D *rv3d = ar->regiondata; - - if (rv3d->is_persp) { - out[0] = 2.0f * (mval[0] / ar->winx) - 1.0f; - out[1] = 2.0f * (mval[1] / ar->winy) - 1.0f; - out[2] = -0.5f; - mul_project_m4_v3(rv3d->persinv, out); - sub_v3_v3(out, rv3d->viewinv[3]); - } - else { - copy_v3_v3(out, rv3d->viewinv[2]); - } - normalize_v3(out); + return 0; } float ED_view3d_depth_read_cached(ViewContext *vc, int x, int y) @@ -797,260 +626,6 @@ void ED_view3d_depth_tag_update(RegionView3D *rv3d) rv3d->depths->damaged = 1; } -void ED_view3d_ob_project_mat_get(RegionView3D *rv3d, Object *ob, float pmat[4][4]) -{ - float vmat[4][4]; - - mult_m4_m4m4(vmat, rv3d->viewmat, ob->obmat); - mult_m4_m4m4(pmat, rv3d->winmat, vmat); -} - -/* Uses window coordinates (x,y) and depth component z to find a point in - * modelspace */ -void ED_view3d_unproject(bglMats *mats, float out[3], const float x, const float y, const float z) -{ - double ux, uy, uz; - - gluUnProject(x, y, z, mats->modelview, mats->projection, - (GLint *)mats->viewport, &ux, &uy, &uz); - - out[0] = ux; - out[1] = uy; - out[2] = uz; -} - -/* use #ED_view3d_ob_project_mat_get to get projecting mat */ -void ED_view3d_project_float_v2_m4(const ARegion *ar, const float co[3], float r_co[2], float mat[4][4]) -{ - float vec4[4]; - - copy_v3_v3(vec4, co); - vec4[3] = 1.0; - /* r_co[0] = IS_CLIPPED; */ /* always overwritten */ - - mul_m4_v4(mat, vec4); - - if (vec4[3] > FLT_EPSILON) { - r_co[0] = (float)(ar->winx / 2.0f) + (ar->winx / 2.0f) * vec4[0] / vec4[3]; - r_co[1] = (float)(ar->winy / 2.0f) + (ar->winy / 2.0f) * vec4[1] / vec4[3]; - } - else { - zero_v2(r_co); - } -} - -/* use #ED_view3d_ob_project_mat_get to get projecting mat */ -void ED_view3d_project_float_v3_m4(ARegion *ar, const float vec[3], float r_co[3], float mat[4][4]) -{ - float vec4[4]; - - copy_v3_v3(vec4, vec); - vec4[3] = 1.0; - /* r_co[0] = IS_CLIPPED; */ /* always overwritten */ - - mul_m4_v4(mat, vec4); - - if (vec4[3] > FLT_EPSILON) { - r_co[0] = (float)(ar->winx / 2.0f) + (ar->winx / 2.0f) * vec4[0] / vec4[3]; - r_co[1] = (float)(ar->winy / 2.0f) + (ar->winy / 2.0f) * vec4[1] / vec4[3]; - r_co[2] = vec4[2] / vec4[3]; - } - else { - zero_v3(r_co); - } -} - -eV3DProjStatus ED_view3d_project_base(struct ARegion *ar, struct Base *base) -{ - eV3DProjStatus ret = ED_view3d_project_short_global(ar, base->object->obmat[3], &base->sx, V3D_PROJ_TEST_CLIP_DEFAULT); - - if (ret != V3D_PROJ_RET_OK) { - base->sx = IS_CLIPPED; - base->sy = 0; - } - - return ret; -} - -int ED_view3d_boundbox_clip(RegionView3D *rv3d, float obmat[][4], BoundBox *bb) -{ - /* return 1: draw */ - - float mat[4][4]; - float vec[4], min, max; - int a, flag = -1, fl; - - if (bb == NULL) return 1; - if (bb->flag & OB_BB_DISABLED) return 1; - - mult_m4_m4m4(mat, rv3d->persmat, obmat); - - for (a = 0; a < 8; a++) { - copy_v3_v3(vec, bb->vec[a]); - vec[3] = 1.0; - mul_m4_v4(mat, vec); - max = vec[3]; - min = -vec[3]; - - fl = 0; - if (vec[0] < min) fl += 1; - if (vec[0] > max) fl += 2; - if (vec[1] < min) fl += 4; - if (vec[1] > max) fl += 8; - if (vec[2] < min) fl += 16; - if (vec[2] > max) fl += 32; - - flag &= fl; - if (flag == 0) return 1; - } - - return 0; -} - -/* perspmat is typically... - * - 'rv3d->perspmat', is_local == FALSE - * - 'rv3d->perspmatob', is_local == TRUE - */ -static eV3DProjStatus ed_view3d_project__internal(ARegion *ar, - float perspmat[4][4], const int is_local, /* normally hidden */ - const float co[3], float r_co[2], const eV3DProjTest flag) -{ - float fx, fy, vec4[4]; - - /* check for bad flags */ - BLI_assert((flag & V3D_PROJ_TEST_ALL) == flag); - - if (flag & V3D_PROJ_TEST_CLIP_BB) { - RegionView3D *rv3d = ar->regiondata; - if (rv3d->rflag & RV3D_CLIPPING) { - if (ED_view3d_clipping_test(rv3d, co, is_local)) { - return V3D_PROJ_RET_CLIP_BB; - } - } - } - - copy_v3_v3(vec4, co); - vec4[3] = 1.0; - mul_m4_v4(perspmat, vec4); - - if (vec4[3] > (float)BL_NEAR_CLIP) { - fx = ((float)ar->winx / 2.0f) * (1.0f + vec4[0] / vec4[3]); - if (((flag & V3D_PROJ_TEST_CLIP_WIN) == 0) || (fx > 0 && fx < ar->winx)) { - fy = ((float)ar->winy / 2.0f) * (1.0f + vec4[1] / vec4[3]); - if (((flag & V3D_PROJ_TEST_CLIP_WIN) == 0) || (fy > 0.0f && fy < (float)ar->winy)) { - r_co[0] = (short)floor(fx); - r_co[1] = (short)floor(fy); - } - else { - return V3D_PROJ_RET_CLIP_WIN; - } - } - else { - return V3D_PROJ_RET_CLIP_WIN; - } - } - else { - return V3D_PROJ_RET_CLIP_NEAR; - } - - return V3D_PROJ_RET_OK; -} - -eV3DProjStatus ED_view3d_project_short_ex(ARegion *ar, float perspmat[4][4], const int is_local, - const float co[3], short r_co[2], const eV3DProjTest flag) -{ - float tvec[2]; - eV3DProjStatus ret = ed_view3d_project__internal(ar, perspmat, is_local, co, tvec, flag); - if (ret == V3D_PROJ_RET_OK) { - if ((tvec[0] > -32700.0 && tvec[0] < 32700.0f) && - (tvec[1] > -32700.0 && tvec[1] < 32700.0f)) - { - r_co[0] = (short)floor(tvec[0]); - r_co[1] = (short)floor(tvec[1]); - } - else { - ret = V3D_PROJ_RET_OVERFLOW; - } - } - return ret; -} - -eV3DProjStatus ED_view3d_project_int_ex(ARegion *ar, float perspmat[4][4], const int is_local, - const float co[3], int r_co[2], const eV3DProjTest flag) -{ - float tvec[2]; - eV3DProjStatus ret = ed_view3d_project__internal(ar, perspmat, is_local, co, tvec, flag); - if (ret == V3D_PROJ_RET_OK) { - if ((tvec[0] > -2140000000.0 && tvec[0] < 2140000000.0f) && - (tvec[1] > -2140000000.0 && tvec[1] < 2140000000.0f)) - { - r_co[0] = (int)floor(tvec[0]); - r_co[1] = (int)floor(tvec[1]); - } - else { - ret = V3D_PROJ_RET_OVERFLOW; - } - } - return ret; -} - -eV3DProjStatus ED_view3d_project_float_ex(ARegion *ar, float perspmat[4][4], const int is_local, - const float co[3], float r_co[2], const eV3DProjTest flag) -{ - float tvec[2]; - eV3DProjStatus ret = ed_view3d_project__internal(ar, perspmat, is_local, co, tvec, flag); - if (ret == V3D_PROJ_RET_OK) { - if (finite(tvec[0]) && - finite(tvec[1])) - { - copy_v2_v2(r_co, tvec); - } - else { - ret = V3D_PROJ_RET_OVERFLOW; - } - } - return ret; -} - -/* --- short --- */ -eV3DProjStatus ED_view3d_project_short_global(ARegion *ar, const float co[3], short r_co[2], const eV3DProjTest flag) -{ - RegionView3D *rv3d = ar->regiondata; - return ED_view3d_project_short_ex(ar, rv3d->persmat, FALSE, co, r_co, flag); -} -/* object space, use ED_view3d_init_mats_rv3d before calling */ -eV3DProjStatus ED_view3d_project_short_object(ARegion *ar, const float co[3], short r_co[2], const eV3DProjTest flag) -{ - RegionView3D *rv3d = ar->regiondata; - return ED_view3d_project_short_ex(ar, rv3d->persmatob, TRUE, co, r_co, flag); -} - -/* --- int --- */ -eV3DProjStatus ED_view3d_project_int_global(ARegion *ar, const float co[3], int r_co[2], const eV3DProjTest flag) -{ - RegionView3D *rv3d = ar->regiondata; - return ED_view3d_project_int_ex(ar, rv3d->persmat, FALSE, co, r_co, flag); -} -/* object space, use ED_view3d_init_mats_rv3d before calling */ -eV3DProjStatus ED_view3d_project_int_object(ARegion *ar, const float co[3], int r_co[2], const eV3DProjTest flag) -{ - RegionView3D *rv3d = ar->regiondata; - return ED_view3d_project_int_ex(ar, rv3d->persmatob, TRUE, co, r_co, flag); -} - -/* --- float --- */ -eV3DProjStatus ED_view3d_project_float_global(ARegion *ar, const float co[3], float r_co[2], const eV3DProjTest flag) -{ - RegionView3D *rv3d = ar->regiondata; - return ED_view3d_project_float_ex(ar, rv3d->persmat, FALSE, co, r_co, flag); -} -/* object space, use ED_view3d_init_mats_rv3d before calling */ -eV3DProjStatus ED_view3d_project_float_object(ARegion *ar, const float co[3], float r_co[2], const eV3DProjTest flag) -{ - RegionView3D *rv3d = ar->regiondata; - return ED_view3d_project_float_ex(ar, rv3d->persmatob, TRUE, co, r_co, flag); -} - /* copies logic of get_view3d_viewplane(), keep in sync */ int ED_view3d_clip_range_get(View3D *v3d, RegionView3D *rv3d, float *clipsta, float *clipend) { diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt index a6de5e2fdba..3fd9bfecedf 100644 --- a/source/blender/nodes/CMakeLists.txt +++ b/source/blender/nodes/CMakeLists.txt @@ -25,6 +25,10 @@ set(INC . + composite + intern + shader + texture ../blenfont ../blenkernel ../blenlib @@ -39,10 +43,6 @@ set(INC set(INC_SYS ${GLEW_INCLUDE_PATH} - intern - composite - shader - texture ) set(SRC diff --git a/source/blender/python/intern/CMakeLists.txt b/source/blender/python/intern/CMakeLists.txt index 604166eed3c..61c49027d9a 100644 --- a/source/blender/python/intern/CMakeLists.txt +++ b/source/blender/python/intern/CMakeLists.txt @@ -30,12 +30,12 @@ set(INC ../../blenlib ../../blenloader ../../editors/include + ../../gpu ../../makesdna ../../makesrna ../../windowmanager - ../../gpu - ../../../../intern/guardedalloc ../../../../intern/cycles/blender + ../../../../intern/guardedalloc ) set(INC_SYS diff --git a/source/blender/windowmanager/CMakeLists.txt b/source/blender/windowmanager/CMakeLists.txt index e6782121b69..65a8945f82b 100644 --- a/source/blender/windowmanager/CMakeLists.txt +++ b/source/blender/windowmanager/CMakeLists.txt @@ -29,6 +29,7 @@ set(INC ../blenkernel ../blenlib ../blenloader + ../compositor ../editors/include ../editors/io ../gpu @@ -36,7 +37,6 @@ set(INC ../makesdna ../makesrna ../nodes - ../compositor ../render/extern/include ../../gameengine/BlenderRoutines ../../../intern/elbeem/extern diff --git a/source/gameengine/Converter/CMakeLists.txt b/source/gameengine/Converter/CMakeLists.txt index 309017e84b1..7b801fd4ffb 100644 --- a/source/gameengine/Converter/CMakeLists.txt +++ b/source/gameengine/Converter/CMakeLists.txt @@ -53,10 +53,10 @@ set(INC ../../../intern/guardedalloc ../../../intern/moto/include ../../../intern/string - ../../../extern/recastnavigation/Detour/Include ) set(INC_SYS + ../../../extern/recastnavigation/Detour/Include ../../../extern/Eigen3 ${PTHREADS_INCLUDE_DIRS} From 7061fa7cf1f1aa3f15ce2784c2ec39d561205dad Mon Sep 17 00:00:00 2001 From: Lukas Toenne Date: Wed, 17 Oct 2012 09:49:32 +0000 Subject: [PATCH 281/347] Fix #32887, ParticleInstance: crash with hidden particle system + children. The issue here is that the particle instance modifier (pimd) accesses data from the linked particle system modifier (psmd). This data is only correctly generated when the psmd is enabled; here the design violates the modifier principle of providing valid object data (or rather DM) even when disabled. The solution in this case is to make a custom isDisabled check for the pimd to see if the psmd is enabled. This means the pimd won't work for disabled psmd, but doesn't crash. --- .../modifiers/intern/MOD_particleinstance.c | 40 ++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/source/blender/modifiers/intern/MOD_particleinstance.c b/source/blender/modifiers/intern/MOD_particleinstance.c index e64e80efde3..20b02c63605 100644 --- a/source/blender/modifiers/intern/MOD_particleinstance.c +++ b/source/blender/modifiers/intern/MOD_particleinstance.c @@ -81,6 +81,44 @@ static int dependsOnTime(ModifierData *UNUSED(md)) { return 0; } + +static int isDisabled(ModifierData *md, int useRenderParams) +{ + ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData *)md; + ParticleSystem *psys; + ModifierData *ob_md; + + if (!pimd->ob) + return TRUE; + + psys = BLI_findlink(&pimd->ob->particlesystem, pimd->psys - 1); + if (psys == NULL) + return TRUE; + + /* If the psys modifier is disabled we cannot use its data. + * First look up the psys modifier from the object, then check if it is enabled. + */ + for (ob_md = pimd->ob->modifiers.first; ob_md; ob_md = ob_md->next) { + if (ob_md->type == eModifierType_ParticleSystem) { + ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)ob_md; + if (psmd->psys == psys) { + int required_mode; + + if (useRenderParams) required_mode = eModifierMode_Render; + else required_mode = eModifierMode_Realtime; + + if (!modifier_isEnabled(md->scene, ob_md, required_mode)) + return TRUE; + + break; + } + } + } + + return FALSE; +} + + static void updateDepgraph(ModifierData *md, DagForest *forest, struct Scene *UNUSED(scene), Object *UNUSED(ob), @@ -384,7 +422,7 @@ ModifierTypeInfo modifierType_ParticleInstance = { /* initData */ initData, /* requiredDataMask */ NULL, /* freeData */ NULL, - /* isDisabled */ NULL, + /* isDisabled */ isDisabled, /* updateDepgraph */ updateDepgraph, /* dependsOnTime */ dependsOnTime, /* dependsOnNormals */ NULL, From 45dc9794c1d223b70cdc585f6b31e8f9505d4d3b Mon Sep 17 00:00:00 2001 From: Lukas Toenne Date: Wed, 17 Oct 2012 10:49:42 +0000 Subject: [PATCH 282/347] Fix #32856, Crash in compositor due to deprecated node socket flag in old files. Bit flag 5 has apparently been used for another purpose in old versions, then deprecated and was actually removed from DNA (this should never be done), then later it got reused for SOCK_DYNAMIC. Now a one-time check to clean up these flags is done in do_versions. --- source/blender/blenkernel/BKE_blender.h | 2 +- source/blender/blenloader/intern/readfile.c | 37 +++++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index 95d41a86239..cf67899dfb0 100644 --- a/source/blender/blenkernel/BKE_blender.h +++ b/source/blender/blenkernel/BKE_blender.h @@ -42,7 +42,7 @@ extern "C" { * and keep comment above the defines. * Use STRINGIFY() rather than defining with quotes */ #define BLENDER_VERSION 264 -#define BLENDER_SUBVERSION 3 +#define BLENDER_SUBVERSION 4 /* 262 was the last editmesh release but its has compatibility code for bmesh data, * so set the minversion to 2.61 */ diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 35b6b400559..3d7c9c21eca 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -7058,6 +7058,21 @@ static void do_version_ntree_tex_coord_from_dupli_264(void *UNUSED(data), ID *UN node->flag |= NODE_OPTIONS; } +static void do_version_node_cleanup_dynamic_sockets_264(void *UNUSED(data), ID *UNUSED(id), bNodeTree *ntree) +{ + bNode *node; + bNodeSocket *sock; + + for (node = ntree->nodes.first; node; node = node->next) { + if (!ELEM(node->type, NODE_GROUP, CMP_NODE_IMAGE)) { + for (sock = node->inputs.first; sock; sock = sock->next) + sock->flag &= ~SOCK_DYNAMIC; + for (sock = node->outputs.first; sock; sock = sock->next) + sock->flag &= ~SOCK_DYNAMIC; + } + } +} + static void do_versions(FileData *fd, Library *lib, Main *main) { /* WATCH IT!!!: pointers from libdata have not been converted */ @@ -8110,6 +8125,28 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } } + if (main->versionfile < 264 || (main->versionfile == 264 && main->subversionfile < 4)) { + /* Fix for old node flags: Apparently the SOCK_DYNAMIC flag has been in use for other + * purposes before and then removed and later reused for SOCK_DYNAMIC. This socket should + * only be used by certain node types which don't use template lists, cleaning this up here. + */ + bNodeTreeType *ntreetype; + bNodeTree *ntree; + + ntreetype = ntreeGetType(NTREE_COMPOSIT); + if (ntreetype && ntreetype->foreach_nodetree) + ntreetype->foreach_nodetree(main, NULL, do_version_node_cleanup_dynamic_sockets_264); + ntreetype = ntreeGetType(NTREE_SHADER); + if (ntreetype && ntreetype->foreach_nodetree) + ntreetype->foreach_nodetree(main, NULL, do_version_node_cleanup_dynamic_sockets_264); + ntreetype = ntreeGetType(NTREE_TEXTURE); + if (ntreetype && ntreetype->foreach_nodetree) + ntreetype->foreach_nodetree(main, NULL, do_version_node_cleanup_dynamic_sockets_264); + + for (ntree=main->nodetree.first; ntree; ntree=ntree->id.next) + do_version_node_cleanup_dynamic_sockets_264(NULL, NULL, ntree); + } + /* WATCH IT!!!: pointers from libdata have not been converted yet here! */ /* WATCH IT 2!: Userdef struct init has to be in editors/interface/resources.c! */ From 0551aa14bb2e58e79200823cde6d71c2288ca7fa Mon Sep 17 00:00:00 2001 From: Lukas Toenne Date: Wed, 17 Oct 2012 12:12:26 +0000 Subject: [PATCH 283/347] Fix for OSL 'background' attributes (attributes that are not associated to a particular object). Atm this is only the 'ray_length' attribute. Background attributes are used as fallback in two cases: 1) Non-object light samples (e.g. lamp shaders) 2) Fallback if no implicit object attribute can be found --- intern/cycles/kernel/osl/osl_services.cpp | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/intern/cycles/kernel/osl/osl_services.cpp b/intern/cycles/kernel/osl/osl_services.cpp index be5273b9ad3..103acd61879 100644 --- a/intern/cycles/kernel/osl/osl_services.cpp +++ b/intern/cycles/kernel/osl/osl_services.cpp @@ -459,9 +459,16 @@ static bool get_object_standard_attribute(KernelGlobals *kg, ShaderData *sd, ust set_attribute_float3(fval, type, derivatives, val); return true; } + + else + return false; +} +static bool get_background_attribute(KernelGlobals *kg, ShaderData *sd, ustring name, + TypeDesc type, bool derivatives, void *val) +{ /* Ray Length */ - else if (name == "std::ray_length") { + if (name == "std::ray_length") { float fval[3]; fval[0] = sd->ray_length; fval[1] = fval[2] = 0.0; /* derivates set to 0 */ @@ -492,8 +499,7 @@ bool OSLRenderServices::get_attribute(void *renderstate, bool derivatives, ustri tri = ~0; } else if (object == ~0) { - /* no background attributes supported */ - return false; + return get_background_attribute(kg, sd, name, type, derivatives, val); } /* find attribute on object */ @@ -516,7 +522,12 @@ bool OSLRenderServices::get_attribute(void *renderstate, bool derivatives, ustri } else { /* not found in attribute, check standard object info */ - return get_object_standard_attribute(kg, sd, name, type, derivatives, val); + bool is_std_object_attribute = get_object_standard_attribute(kg, sd, name, type, derivatives, val); + if (is_std_object_attribute) + return true; + else { + return get_background_attribute(kg, sd, name, type, derivatives, val); + } } return false; From afb75ad2af0c30f1bc6fd252ca115a59d04e3b85 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 17 Oct 2012 12:17:17 +0000 Subject: [PATCH 284/347] Cycles: add Tangent input for Anisotropic BSDF. Also refactor SVM BSDF code, preparing it to be shared with OSL. --- intern/cycles/kernel/kernel_attribute.h | 2 +- intern/cycles/kernel/kernel_shader.h | 5 - intern/cycles/kernel/kernel_types.h | 5 +- .../cycles/kernel/svm/bsdf_ashikhmin_velvet.h | 41 +++---- intern/cycles/kernel/svm/bsdf_diffuse.h | 52 ++++---- intern/cycles/kernel/svm/bsdf_microfacet.h | 112 ++++++++---------- intern/cycles/kernel/svm/bsdf_oren_nayar.h | 21 ++-- intern/cycles/kernel/svm/bsdf_reflection.h | 24 ++-- intern/cycles/kernel/svm/bsdf_refraction.h | 18 ++- intern/cycles/kernel/svm/bsdf_transparent.h | 14 +-- intern/cycles/kernel/svm/bsdf_ward.h | 51 ++++---- intern/cycles/kernel/svm/bsdf_westin.h | 66 +++++------ intern/cycles/kernel/svm/svm.h | 8 -- intern/cycles/kernel/svm/svm_bsdf.h | 84 +++++++------ intern/cycles/kernel/svm/svm_closure.h | 24 +--- intern/cycles/kernel/svm/svm_types.h | 2 - intern/cycles/render/nodes.cpp | 21 ++-- .../nodes/node_shader_bsdf_anisotropic.c | 3 +- 18 files changed, 238 insertions(+), 315 deletions(-) diff --git a/intern/cycles/kernel/kernel_attribute.h b/intern/cycles/kernel/kernel_attribute.h index 115de2fdbdb..2774f5e924b 100644 --- a/intern/cycles/kernel/kernel_attribute.h +++ b/intern/cycles/kernel/kernel_attribute.h @@ -59,7 +59,7 @@ __device_inline int find_attribute(KernelGlobals *kg, ShaderData *sd, uint id) attr_map = kernel_tex_fetch(__attributes_map, ++attr_offset); /* return result */ - return (attr_map.y == ATTR_ELEMENT_NONE) ? (int)ATTR_STD_NOT_FOUND : attr_map.z; + return (attr_map.y == ATTR_ELEMENT_NONE) ? (int)ATTR_STD_NOT_FOUND : (int)attr_map.z; } } diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h index 534f0941134..36f7122a380 100644 --- a/intern/cycles/kernel/kernel_shader.h +++ b/intern/cycles/kernel/kernel_shader.h @@ -98,7 +98,6 @@ __device_inline void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd, #ifdef __DPDU__ /* dPdu/dPdv */ triangle_dPdudv(kg, &sd->dPdu, &sd->dPdv, sd->prim); - sd->T = make_float3(0.0f, 0.0f, 0.0f); #endif #ifdef __INSTANCING__ @@ -123,7 +122,6 @@ __device_inline void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd, #ifdef __DPDU__ sd->dPdu = -sd->dPdu; sd->dPdv = -sd->dPdv; - sd->T = make_float3(0.0f, 0.0f, 0.0f); #endif } @@ -223,8 +221,6 @@ __device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd, } #endif } - - sd->T = make_float3(0.0f, 0.0f, 0.0f); #endif /* backfacing test */ @@ -310,7 +306,6 @@ __device_inline void shader_setup_from_background(KernelGlobals *kg, ShaderData /* dPdu/dPdv */ sd->dPdu = make_float3(0.0f, 0.0f, 0.0f); sd->dPdv = make_float3(0.0f, 0.0f, 0.0f); - sd->T = make_float3(0.0f, 0.0f, 0.0f); #endif #ifdef __RAY_DIFFERENTIALS__ diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index b8bbaae5c2b..bcf80cb76fb 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -369,7 +369,9 @@ typedef struct ShaderClosure { #endif float data0; float data1; + float3 N; + float3 T; } ShaderClosure; @@ -440,9 +442,6 @@ typedef struct ShaderData { /* differential of P w.r.t. parametric coordinates. note that dPdu is * not readily suitable as a tangent for shading on triangles. */ float3 dPdu, dPdv; - - /* tangent for shading */ - float3 T; #endif #ifdef __OBJECT_MOTION__ diff --git a/intern/cycles/kernel/svm/bsdf_ashikhmin_velvet.h b/intern/cycles/kernel/svm/bsdf_ashikhmin_velvet.h index 785fc038e9e..5cdfb230fea 100644 --- a/intern/cycles/kernel/svm/bsdf_ashikhmin_velvet.h +++ b/intern/cycles/kernel/svm/bsdf_ashikhmin_velvet.h @@ -35,11 +35,6 @@ CCL_NAMESPACE_BEGIN -typedef struct BsdfAshikhminVelvetClosure { - //float3 m_N; - float m_invsigma2; -} BsdfAshikhminVelvetClosure; - __device void bsdf_ashikhmin_velvet_setup(ShaderData *sd, ShaderClosure *sc, float sigma) { sigma = fmaxf(sigma, 0.01f); @@ -55,17 +50,17 @@ __device void bsdf_ashikhmin_velvet_blur(ShaderClosure *sc, float roughness) { } -__device float3 bsdf_ashikhmin_velvet_eval_reflect(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) +__device float3 bsdf_ashikhmin_velvet_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { float m_invsigma2 = sc->data0; - float3 m_N = sc->N; + float3 N = sc->N; - float cosNO = dot(m_N, I); - float cosNI = dot(m_N, omega_in); + float cosNO = dot(N, I); + float cosNI = dot(N, omega_in); if(cosNO > 0 && cosNI > 0) { float3 H = normalize(omega_in + I); - float cosNH = dot(m_N, H); + float cosNH = dot(N, H); float cosHO = fabsf(dot(I, H)); if(!(fabsf(cosNH) < 1.0f-1e-5f && cosHO > 1e-5f)) @@ -93,32 +88,32 @@ __device float3 bsdf_ashikhmin_velvet_eval_reflect(const ShaderData *sd, const S return make_float3(0, 0, 0); } -__device float3 bsdf_ashikhmin_velvet_eval_transmit(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) +__device float3 bsdf_ashikhmin_velvet_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { return make_float3(0.0f, 0.0f, 0.0f); } -__device float bsdf_ashikhmin_velvet_albedo(const ShaderData *sd, const ShaderClosure *sc, const float3 I) +__device float bsdf_ashikhmin_velvet_albedo(const ShaderClosure *sc, const float3 I) { return 1.0f; } -__device int bsdf_ashikhmin_velvet_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) +__device int bsdf_ashikhmin_velvet_sample(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) { float m_invsigma2 = sc->data0; - float3 m_N = sc->N; + float3 N = sc->N; // we are viewing the surface from above - send a ray out with uniform // distribution over the hemisphere - sample_uniform_hemisphere(m_N, randu, randv, omega_in, pdf); + sample_uniform_hemisphere(N, randu, randv, omega_in, pdf); - if(dot(sd->Ng, *omega_in) > 0) { - float3 H = normalize(*omega_in + sd->I); + if(dot(Ng, *omega_in) > 0) { + float3 H = normalize(*omega_in + I); - float cosNI = dot(m_N, *omega_in); - float cosNO = dot(m_N, sd->I); - float cosNH = dot(m_N, H); - float cosHO = fabsf(dot(sd->I, H)); + float cosNI = dot(N, *omega_in); + float cosNO = dot(N, I); + float cosNH = dot(N, H); + float cosHO = fabsf(dot(I, H)); if(fabsf(cosNO) > 1e-5f && fabsf(cosNH) < 1.0f-1e-5f && cosHO > 1e-5f) { float cosNHdivHO = cosNH / cosHO; @@ -140,8 +135,8 @@ __device int bsdf_ashikhmin_velvet_sample(const ShaderData *sd, const ShaderClos #ifdef __RAY_DIFFERENTIALS__ // TODO: find a better approximation for the retroreflective bounce - *domega_in_dx = (2 * dot(m_N, sd->dI.dx)) * m_N - sd->dI.dx; - *domega_in_dy = (2 * dot(m_N, sd->dI.dy)) * m_N - sd->dI.dy; + *domega_in_dx = (2 * dot(N, dIdx)) * N - dIdx; + *domega_in_dy = (2 * dot(N, dIdy)) * N - dIdy; *domega_in_dx *= 125.0f; *domega_in_dy *= 125.0f; #endif diff --git a/intern/cycles/kernel/svm/bsdf_diffuse.h b/intern/cycles/kernel/svm/bsdf_diffuse.h index 6a67c184854..da3d1ae61ef 100644 --- a/intern/cycles/kernel/svm/bsdf_diffuse.h +++ b/intern/cycles/kernel/svm/bsdf_diffuse.h @@ -37,10 +37,6 @@ CCL_NAMESPACE_BEGIN /* DIFFUSE */ -typedef struct BsdfDiffuseClosure { - //float3 m_N; -} BsdfDiffuseClosure; - __device void bsdf_diffuse_setup(ShaderData *sd, ShaderClosure *sc) { sc->type = CLOSURE_BSDF_DIFFUSE_ID; @@ -51,38 +47,38 @@ __device void bsdf_diffuse_blur(ShaderClosure *sc, float roughness) { } -__device float3 bsdf_diffuse_eval_reflect(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) +__device float3 bsdf_diffuse_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { - float3 m_N = sc->N; + float3 N = sc->N; - float cos_pi = fmaxf(dot(m_N, omega_in), 0.0f) * M_1_PI_F; + float cos_pi = fmaxf(dot(N, omega_in), 0.0f) * M_1_PI_F; *pdf = cos_pi; return make_float3(cos_pi, cos_pi, cos_pi); } -__device float3 bsdf_diffuse_eval_transmit(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) +__device float3 bsdf_diffuse_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { return make_float3(0.0f, 0.0f, 0.0f); } -__device float bsdf_diffuse_albedo(const ShaderData *sd, const ShaderClosure *sc, const float3 I) +__device float bsdf_diffuse_albedo(const ShaderClosure *sc, const float3 I) { return 1.0f; } -__device int bsdf_diffuse_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) +__device int bsdf_diffuse_sample(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) { - float3 m_N = sc->N; + float3 N = sc->N; // distribution over the hemisphere - sample_cos_hemisphere(m_N, randu, randv, omega_in, pdf); + sample_cos_hemisphere(N, randu, randv, omega_in, pdf); - if(dot(sd->Ng, *omega_in) > 0.0f) { + if(dot(Ng, *omega_in) > 0.0f) { *eval = make_float3(*pdf, *pdf, *pdf); #ifdef __RAY_DIFFERENTIALS__ // TODO: find a better approximation for the diffuse bounce - *domega_in_dx = (2 * dot(m_N, sd->dI.dx)) * m_N - sd->dI.dx; - *domega_in_dy = (2 * dot(m_N, sd->dI.dy)) * m_N - sd->dI.dy; + *domega_in_dx = (2 * dot(N, dIdx)) * N - dIdx; + *domega_in_dy = (2 * dot(N, dIdy)) * N - dIdy; *domega_in_dx *= 125.0f; *domega_in_dy *= 125.0f; #endif @@ -95,10 +91,6 @@ __device int bsdf_diffuse_sample(const ShaderData *sd, const ShaderClosure *sc, /* TRANSLUCENT */ -typedef struct BsdfTranslucentClosure { - //float3 m_N; -} BsdfTranslucentClosure; - __device void bsdf_translucent_setup(ShaderData *sd, ShaderClosure *sc) { sc->type = CLOSURE_BSDF_TRANSLUCENT_ID; @@ -109,38 +101,38 @@ __device void bsdf_translucent_blur(ShaderClosure *sc, float roughness) { } -__device float3 bsdf_translucent_eval_reflect(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) +__device float3 bsdf_translucent_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { return make_float3(0.0f, 0.0f, 0.0f); } -__device float3 bsdf_translucent_eval_transmit(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) +__device float3 bsdf_translucent_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { - float3 m_N = sc->N; + float3 N = sc->N; - float cos_pi = fmaxf(-dot(m_N, omega_in), 0.0f) * M_1_PI_F; + float cos_pi = fmaxf(-dot(N, omega_in), 0.0f) * M_1_PI_F; *pdf = cos_pi; return make_float3 (cos_pi, cos_pi, cos_pi); } -__device float bsdf_translucent_albedo(const ShaderData *sd, const ShaderClosure *sc, const float3 I) +__device float bsdf_translucent_albedo(const ShaderClosure *sc, const float3 I) { return 1.0f; } -__device int bsdf_translucent_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) +__device int bsdf_translucent_sample(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) { - float3 m_N = sc->N; + float3 N = sc->N; // we are viewing the surface from the right side - send a ray out with cosine // distribution over the hemisphere - sample_cos_hemisphere (-m_N, randu, randv, omega_in, pdf); - if(dot(sd->Ng, *omega_in) < 0) { + sample_cos_hemisphere (-N, randu, randv, omega_in, pdf); + if(dot(Ng, *omega_in) < 0) { *eval = make_float3(*pdf, *pdf, *pdf); #ifdef __RAY_DIFFERENTIALS__ // TODO: find a better approximation for the diffuse bounce - *domega_in_dx = (2 * dot(m_N, sd->dI.dx)) * m_N - sd->dI.dx; - *domega_in_dy = (2 * dot(m_N, sd->dI.dy)) * m_N - sd->dI.dy; + *domega_in_dx = (2 * dot(N, dIdx)) * N - dIdx; + *domega_in_dy = (2 * dot(N, dIdy)) * N - dIdy; *domega_in_dx *= -125.0f; *domega_in_dy *= -125.0f; #endif diff --git a/intern/cycles/kernel/svm/bsdf_microfacet.h b/intern/cycles/kernel/svm/bsdf_microfacet.h index 60f8e23818c..11a1492cba1 100644 --- a/intern/cycles/kernel/svm/bsdf_microfacet.h +++ b/intern/cycles/kernel/svm/bsdf_microfacet.h @@ -37,12 +37,6 @@ CCL_NAMESPACE_BEGIN /* GGX */ -typedef struct BsdfMicrofacetGGXClosure { - //float3 m_N; - float m_ag; - float m_eta; -} BsdfMicrofacetGGXClosure; - __device_inline float safe_sqrtf(float f) { return sqrtf(max(f, 0.0f)); @@ -71,23 +65,23 @@ __device void bsdf_microfacet_ggx_blur(ShaderClosure *sc, float roughness) sc->data0 = m_ag; } -__device float3 bsdf_microfacet_ggx_eval_reflect(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) +__device float3 bsdf_microfacet_ggx_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { float m_ag = sc->data0; //float m_eta = sc->data1; int m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID; - float3 m_N = sc->N; + float3 N = sc->N; if(m_refractive) return make_float3 (0, 0, 0); - float cosNO = dot(m_N, I); - float cosNI = dot(m_N, omega_in); + float cosNO = dot(N, I); + float cosNI = dot(N, omega_in); if(cosNI > 0 && cosNO > 0) { // get half vector float3 Hr = normalize(omega_in + I); // eq. 20: (F*G*D)/(4*in*on) // eq. 33: first we calculate D(m) with m=Hr: float alpha2 = m_ag * m_ag; - float cosThetaM = dot(m_N, Hr); + float cosThetaM = dot(N, Hr); float cosThetaM2 = cosThetaM * cosThetaM; float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2; float cosThetaM4 = cosThetaM2 * cosThetaM2; @@ -108,16 +102,16 @@ __device float3 bsdf_microfacet_ggx_eval_reflect(const ShaderData *sd, const Sha return make_float3 (0, 0, 0); } -__device float3 bsdf_microfacet_ggx_eval_transmit(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) +__device float3 bsdf_microfacet_ggx_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { float m_ag = sc->data0; float m_eta = sc->data1; int m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID; - float3 m_N = sc->N; + float3 N = sc->N; if(!m_refractive) return make_float3 (0, 0, 0); - float cosNO = dot(m_N, I); - float cosNI = dot(m_N, omega_in); + float cosNO = dot(N, I); + float cosNI = dot(N, omega_in); if(cosNO <= 0 || cosNI >= 0) return make_float3 (0, 0, 0); // vectors on same side -- not possible // compute half-vector of the refraction (eq. 16) @@ -128,7 +122,7 @@ __device float3 bsdf_microfacet_ggx_eval_transmit(const ShaderData *sd, const Sh float cosHI = dot(Ht, omega_in); // eq. 33: first we calculate D(m) with m=Ht: float alpha2 = m_ag * m_ag; - float cosThetaM = dot(m_N, Ht); + float cosThetaM = dot(N, Ht); float cosThetaM2 = cosThetaM * cosThetaM; float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2; float cosThetaM4 = cosThetaM2 * cosThetaM2; @@ -144,21 +138,21 @@ __device float3 bsdf_microfacet_ggx_eval_transmit(const ShaderData *sd, const Sh return make_float3 (out, out, out); } -__device float bsdf_microfacet_ggx_albedo(const ShaderData *sd, const ShaderClosure *sc, const float3 I) +__device float bsdf_microfacet_ggx_albedo(const ShaderClosure *sc, const float3 I) { return 1.0f; } -__device int bsdf_microfacet_ggx_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) +__device int bsdf_microfacet_ggx_sample(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) { float m_ag = sc->data0; float m_eta = sc->data1; int m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID; - float3 m_N = sc->N; + float3 N = sc->N; - float cosNO = dot(m_N, sd->I); + float cosNO = dot(N, I); if(cosNO > 0) { - float3 X, Y, Z = m_N; + float3 X, Y, Z = N; make_orthonormals(Z, &X, &Y); // generate a random microfacet normal m // eq. 35,36: @@ -173,11 +167,11 @@ __device int bsdf_microfacet_ggx_sample(const ShaderData *sd, const ShaderClosur (sinf(phiM) * sinThetaM) * Y + cosThetaM * Z; if(!m_refractive) { - float cosMO = dot(m, sd->I); + float cosMO = dot(m, I); if(cosMO > 0) { // eq. 39 - compute actual reflected direction - *omega_in = 2 * cosMO * m - sd->I; - if(dot(sd->Ng, *omega_in) > 0) { + *omega_in = 2 * cosMO * m - I; + if(dot(Ng, *omega_in) > 0) { // microfacet normal is visible to this ray // eq. 33 float cosThetaM2 = cosThetaM * cosThetaM; @@ -190,7 +184,7 @@ __device int bsdf_microfacet_ggx_sample(const ShaderData *sd, const ShaderClosur // eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf *pdf = pm * 0.25f / cosMO; // eval BRDF*cosNI - float cosNI = dot(m_N, *omega_in); + float cosNI = dot(N, *omega_in); // eq. 34: now calculate G1(i,m) and G1(o,m) float G1o = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO))); float G1i = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI))); @@ -199,8 +193,8 @@ __device int bsdf_microfacet_ggx_sample(const ShaderData *sd, const ShaderClosur float out = (G * D) * 0.25f / cosNO; *eval = make_float3(out, out, out); #ifdef __RAY_DIFFERENTIALS__ - *domega_in_dx = (2 * dot(m, sd->dI.dx)) * m - sd->dI.dx; - *domega_in_dy = (2 * dot(m, sd->dI.dy)) * m - sd->dI.dy; + *domega_in_dx = (2 * dot(m, dIdx)) * m - dIdx; + *domega_in_dy = (2 * dot(m, dIdy)) * m - dIdy; // Since there is some blur to this reflection, make the // derivatives a bit bigger. In theory this varies with the // roughness but the exact relationship is complex and @@ -219,9 +213,9 @@ __device int bsdf_microfacet_ggx_sample(const ShaderData *sd, const ShaderClosur float3 dRdx, dRdy, dTdx, dTdy; #endif bool inside; - fresnel_dielectric(m_eta, m, sd->I, &R, &T, + fresnel_dielectric(m_eta, m, I, &R, &T, #ifdef __RAY_DIFFERENTIALS__ - sd->dI.dx, sd->dI.dy, &dRdx, &dRdy, &dTdx, &dTdy, + dIdx, dIdy, &dRdx, &dRdy, &dTdx, &dTdy, #endif &inside); @@ -238,14 +232,14 @@ __device int bsdf_microfacet_ggx_sample(const ShaderData *sd, const ShaderClosur // eq. 24 float pm = D * cosThetaM; // eval BRDF*cosNI - float cosNI = dot(m_N, *omega_in); + float cosNI = dot(N, *omega_in); // eq. 34: now calculate G1(i,m) and G1(o,m) float G1o = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO))); float G1i = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI))); float G = G1o * G1i; // eq. 21 float cosHI = dot(m, *omega_in); - float cosHO = dot(m, sd->I); + float cosHO = dot(m, I); float Ht2 = m_eta * cosHI + cosHO; Ht2 *= Ht2; float out = (fabsf(cosHI * cosHO) * (m_eta * m_eta) * (G * D)) / (cosNO * Ht2); @@ -268,12 +262,6 @@ __device int bsdf_microfacet_ggx_sample(const ShaderData *sd, const ShaderClosur /* BECKMANN */ -typedef struct BsdfMicrofacetBeckmannClosure { - //float3 m_N; - float m_ab; - float m_eta; -} BsdfMicrofacetBeckmannClosure; - __device void bsdf_microfacet_beckmann_setup(ShaderData *sd, ShaderClosure *sc, float ab, float eta, bool refractive) { float m_ab = clamp(ab, 1e-4f, 1.0f); @@ -297,23 +285,23 @@ __device void bsdf_microfacet_beckmann_blur(ShaderClosure *sc, float roughness) sc->data0 = m_ab; } -__device float3 bsdf_microfacet_beckmann_eval_reflect(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) +__device float3 bsdf_microfacet_beckmann_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { float m_ab = sc->data0; //float m_eta = sc->data1; int m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID; - float3 m_N = sc->N; + float3 N = sc->N; if(m_refractive) return make_float3 (0, 0, 0); - float cosNO = dot(m_N, I); - float cosNI = dot(m_N, omega_in); + float cosNO = dot(N, I); + float cosNI = dot(N, omega_in); if(cosNO > 0 && cosNI > 0) { // get half vector float3 Hr = normalize(omega_in + I); // eq. 20: (F*G*D)/(4*in*on) // eq. 25: first we calculate D(m) with m=Hr: float alpha2 = m_ab * m_ab; - float cosThetaM = dot(m_N, Hr); + float cosThetaM = dot(N, Hr); float cosThetaM2 = cosThetaM * cosThetaM; float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2; float cosThetaM4 = cosThetaM2 * cosThetaM2; @@ -336,16 +324,16 @@ __device float3 bsdf_microfacet_beckmann_eval_reflect(const ShaderData *sd, cons return make_float3 (0, 0, 0); } -__device float3 bsdf_microfacet_beckmann_eval_transmit(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) +__device float3 bsdf_microfacet_beckmann_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { float m_ab = sc->data0; float m_eta = sc->data1; int m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID; - float3 m_N = sc->N; + float3 N = sc->N; if(!m_refractive) return make_float3 (0, 0, 0); - float cosNO = dot(m_N, I); - float cosNI = dot(m_N, omega_in); + float cosNO = dot(N, I); + float cosNI = dot(N, omega_in); if(cosNO <= 0 || cosNI >= 0) return make_float3 (0, 0, 0); // compute half-vector of the refraction (eq. 16) @@ -356,7 +344,7 @@ __device float3 bsdf_microfacet_beckmann_eval_transmit(const ShaderData *sd, con float cosHI = dot(Ht, omega_in); // eq. 33: first we calculate D(m) with m=Ht: float alpha2 = m_ab * m_ab; - float cosThetaM = dot(m_N, Ht); + float cosThetaM = dot(N, Ht); float cosThetaM2 = cosThetaM * cosThetaM; float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2; float cosThetaM4 = cosThetaM2 * cosThetaM2; @@ -374,21 +362,21 @@ __device float3 bsdf_microfacet_beckmann_eval_transmit(const ShaderData *sd, con return make_float3 (out, out, out); } -__device float bsdf_microfacet_beckmann_albedo(const ShaderData *sd, const ShaderClosure *sc, const float3 I) +__device float bsdf_microfacet_beckmann_albedo(const ShaderClosure *sc, const float3 I) { return 1.0f; } -__device int bsdf_microfacet_beckmann_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) +__device int bsdf_microfacet_beckmann_sample(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) { float m_ab = sc->data0; float m_eta = sc->data1; int m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID; - float3 m_N = sc->N; + float3 N = sc->N; - float cosNO = dot(m_N, sd->I); + float cosNO = dot(N, I); if(cosNO > 0) { - float3 X, Y, Z = m_N; + float3 X, Y, Z = N; make_orthonormals(Z, &X, &Y); // generate a random microfacet normal m // eq. 35,36: @@ -404,11 +392,11 @@ __device int bsdf_microfacet_beckmann_sample(const ShaderData *sd, const ShaderC cosThetaM * Z; if(!m_refractive) { - float cosMO = dot(m, sd->I); + float cosMO = dot(m, I); if(cosMO > 0) { // eq. 39 - compute actual reflected direction - *omega_in = 2 * cosMO * m - sd->I; - if(dot(sd->Ng, *omega_in) > 0) { + *omega_in = 2 * cosMO * m - I; + if(dot(Ng, *omega_in) > 0) { // microfacet normal is visible to this ray // eq. 25 float cosThetaM2 = cosThetaM * cosThetaM; @@ -422,7 +410,7 @@ __device int bsdf_microfacet_beckmann_sample(const ShaderData *sd, const ShaderC // eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf *pdf = pm * 0.25f / cosMO; // Eval BRDF*cosNI - float cosNI = dot(m_N, *omega_in); + float cosNI = dot(N, *omega_in); // eq. 26, 27: now calculate G1(i,m) and G1(o,m) float ao = 1 / (m_ab * safe_sqrtf((1 - cosNO * cosNO) / (cosNO * cosNO))); float ai = 1 / (m_ab * safe_sqrtf((1 - cosNI * cosNI) / (cosNI * cosNI))); @@ -433,8 +421,8 @@ __device int bsdf_microfacet_beckmann_sample(const ShaderData *sd, const ShaderC float out = (G * D) * 0.25f / cosNO; *eval = make_float3(out, out, out); #ifdef __RAY_DIFFERENTIALS__ - *domega_in_dx = (2 * dot(m, sd->dI.dx)) * m - sd->dI.dx; - *domega_in_dy = (2 * dot(m, sd->dI.dy)) * m - sd->dI.dy; + *domega_in_dx = (2 * dot(m, dIdx)) * m - dIdx; + *domega_in_dy = (2 * dot(m, dIdy)) * m - dIdy; // Since there is some blur to this reflection, make the // derivatives a bit bigger. In theory this varies with the // roughness but the exact relationship is complex and @@ -453,9 +441,9 @@ __device int bsdf_microfacet_beckmann_sample(const ShaderData *sd, const ShaderC float3 dRdx, dRdy, dTdx, dTdy; #endif bool inside; - fresnel_dielectric(m_eta, m, sd->I, &R, &T, + fresnel_dielectric(m_eta, m, I, &R, &T, #ifdef __RAY_DIFFERENTIALS__ - sd->dI.dx, sd->dI.dy, &dRdx, &dRdy, &dTdx, &dTdy, + dIdx, dIdy, &dRdx, &dRdy, &dTdx, &dTdy, #endif &inside); @@ -474,7 +462,7 @@ __device int bsdf_microfacet_beckmann_sample(const ShaderData *sd, const ShaderC // eq. 24 float pm = D * cosThetaM; // eval BRDF*cosNI - float cosNI = dot(m_N, *omega_in); + float cosNI = dot(N, *omega_in); // eq. 26, 27: now calculate G1(i,m) and G1(o,m) float ao = 1 / (m_ab * safe_sqrtf((1 - cosNO * cosNO) / (cosNO * cosNO))); float ai = 1 / (m_ab * safe_sqrtf((1 - cosNI * cosNI) / (cosNI * cosNI))); @@ -483,7 +471,7 @@ __device int bsdf_microfacet_beckmann_sample(const ShaderData *sd, const ShaderC float G = G1o * G1i; // eq. 21 float cosHI = dot(m, *omega_in); - float cosHO = dot(m, sd->I); + float cosHO = dot(m, I); float Ht2 = m_eta * cosHI + cosHO; Ht2 *= Ht2; float out = (fabsf(cosHI * cosHO) * (m_eta * m_eta) * (G * D)) / (cosNO * Ht2); diff --git a/intern/cycles/kernel/svm/bsdf_oren_nayar.h b/intern/cycles/kernel/svm/bsdf_oren_nayar.h index 04fbb091fb4..8a11e4ec73f 100644 --- a/intern/cycles/kernel/svm/bsdf_oren_nayar.h +++ b/intern/cycles/kernel/svm/bsdf_oren_nayar.h @@ -21,11 +21,6 @@ CCL_NAMESPACE_BEGIN -typedef struct BsdfOrenNayarClosure { - float m_a; - float m_b; -} BsdfOrenNayarClosure; - __device float3 bsdf_oren_nayar_get_intensity(const ShaderClosure *sc, float3 n, float3 v, float3 l) { float nl = max(dot(n, l), 0.0f); @@ -55,7 +50,7 @@ __device void bsdf_oren_nayar_blur(ShaderClosure *sc, float roughness) { } -__device float3 bsdf_oren_nayar_eval_reflect(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) +__device float3 bsdf_oren_nayar_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { if (dot(sc->N, omega_in) > 0.0f) { *pdf = 0.5f * M_1_PI_F; @@ -67,27 +62,27 @@ __device float3 bsdf_oren_nayar_eval_reflect(const ShaderData *sd, const ShaderC } } -__device float3 bsdf_oren_nayar_eval_transmit(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) +__device float3 bsdf_oren_nayar_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { return make_float3(0.0f, 0.0f, 0.0f); } -__device float bsdf_oren_nayar_albedo(const ShaderData *sd, const ShaderClosure *sc, const float3 I) +__device float bsdf_oren_nayar_albedo(const ShaderClosure *sc, const float3 I) { return 1.0f; } -__device int bsdf_oren_nayar_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) +__device int bsdf_oren_nayar_sample(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) { sample_uniform_hemisphere(sc->N, randu, randv, omega_in, pdf); - if (dot(sd->Ng, *omega_in) > 0.0f) { - *eval = bsdf_oren_nayar_get_intensity(sc, sc->N, sd->I, *omega_in); + if (dot(Ng, *omega_in) > 0.0f) { + *eval = bsdf_oren_nayar_get_intensity(sc, sc->N, I, *omega_in); #ifdef __RAY_DIFFERENTIALS__ // TODO: find a better approximation for the bounce - *domega_in_dx = (2.0f * dot(sc->N, sd->dI.dx)) * sc->N - sd->dI.dx; - *domega_in_dy = (2.0f * dot(sc->N, sd->dI.dy)) * sc->N - sd->dI.dy; + *domega_in_dx = (2.0f * dot(sc->N, dIdx)) * sc->N - dIdx; + *domega_in_dy = (2.0f * dot(sc->N, dIdy)) * sc->N - dIdy; *domega_in_dx *= 125.0f; *domega_in_dy *= 125.0f; #endif diff --git a/intern/cycles/kernel/svm/bsdf_reflection.h b/intern/cycles/kernel/svm/bsdf_reflection.h index 7ce38050a9a..0fff1868178 100644 --- a/intern/cycles/kernel/svm/bsdf_reflection.h +++ b/intern/cycles/kernel/svm/bsdf_reflection.h @@ -37,10 +37,6 @@ CCL_NAMESPACE_BEGIN /* REFLECTION */ -typedef struct BsdfReflectionClosure { - //float3 m_N; -} BsdfReflectionClosure; - __device void bsdf_reflection_setup(ShaderData *sd, ShaderClosure *sc) { sc->type = CLOSURE_BSDF_REFLECTION_ID; @@ -51,34 +47,34 @@ __device void bsdf_reflection_blur(ShaderClosure *sc, float roughness) { } -__device float3 bsdf_reflection_eval_reflect(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) +__device float3 bsdf_reflection_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { return make_float3(0.0f, 0.0f, 0.0f); } -__device float3 bsdf_reflection_eval_transmit(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) +__device float3 bsdf_reflection_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { return make_float3(0.0f, 0.0f, 0.0f); } -__device float bsdf_reflection_albedo(const ShaderData *sd, const ShaderClosure *sc, const float3 I) +__device float bsdf_reflection_albedo(const ShaderClosure *sc, const float3 I) { return 1.0f; } -__device int bsdf_reflection_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) +__device int bsdf_reflection_sample(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) { //const BsdfReflectionClosure *self = (const BsdfReflectionClosure*)sc->data; - float3 m_N = sc->N; + float3 N = sc->N; // only one direction is possible - float cosNO = dot(m_N, sd->I); + float cosNO = dot(N, I); if(cosNO > 0) { - *omega_in = (2 * cosNO) * m_N - sd->I; - if(dot(sd->Ng, *omega_in) > 0) { + *omega_in = (2 * cosNO) * N - I; + if(dot(Ng, *omega_in) > 0) { #ifdef __RAY_DIFFERENTIALS__ - *domega_in_dx = 2 * dot(m_N, sd->dI.dx) * m_N - sd->dI.dx; - *domega_in_dy = 2 * dot(m_N, sd->dI.dy) * m_N - sd->dI.dy; + *domega_in_dx = 2 * dot(N, dIdx) * N - dIdx; + *domega_in_dy = 2 * dot(N, dIdy) * N - dIdy; #endif *pdf = 1; *eval = make_float3(1, 1, 1); diff --git a/intern/cycles/kernel/svm/bsdf_refraction.h b/intern/cycles/kernel/svm/bsdf_refraction.h index 7579a4c6276..686f9059857 100644 --- a/intern/cycles/kernel/svm/bsdf_refraction.h +++ b/intern/cycles/kernel/svm/bsdf_refraction.h @@ -37,10 +37,6 @@ CCL_NAMESPACE_BEGIN /* REFRACTION */ -typedef struct BsdfRefractionClosure { - float m_eta; -} BsdfRefractionClosure; - __device void bsdf_refraction_setup(ShaderData *sd, ShaderClosure *sc, float eta) { sc->data0 = eta; @@ -53,34 +49,34 @@ __device void bsdf_refraction_blur(ShaderClosure *sc, float roughness) { } -__device float3 bsdf_refraction_eval_reflect(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) +__device float3 bsdf_refraction_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { return make_float3(0.0f, 0.0f, 0.0f); } -__device float3 bsdf_refraction_eval_transmit(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) +__device float3 bsdf_refraction_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { return make_float3(0.0f, 0.0f, 0.0f); } -__device float bsdf_refraction_albedo(const ShaderData *sd, const ShaderClosure *sc, const float3 I) +__device float bsdf_refraction_albedo(const ShaderClosure *sc, const float3 I) { return 1.0f; } -__device int bsdf_refraction_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) +__device int bsdf_refraction_sample(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) { float m_eta = sc->data0; - float3 m_N = sc->N; + float3 N = sc->N; float3 R, T; #ifdef __RAY_DIFFERENTIALS__ float3 dRdx, dRdy, dTdx, dTdy; #endif bool inside; - fresnel_dielectric(m_eta, m_N, sd->I, &R, &T, + fresnel_dielectric(m_eta, N, I, &R, &T, #ifdef __RAY_DIFFERENTIALS__ - sd->dI.dx, sd->dI.dy, &dRdx, &dRdy, &dTdx, &dTdy, + dIdx, dIdy, &dRdx, &dRdy, &dTdx, &dTdy, #endif &inside); diff --git a/intern/cycles/kernel/svm/bsdf_transparent.h b/intern/cycles/kernel/svm/bsdf_transparent.h index 511836cdfa2..8427862a86b 100644 --- a/intern/cycles/kernel/svm/bsdf_transparent.h +++ b/intern/cycles/kernel/svm/bsdf_transparent.h @@ -45,28 +45,28 @@ __device void bsdf_transparent_blur(ShaderClosure *sc, float roughness) { } -__device float3 bsdf_transparent_eval_reflect(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) +__device float3 bsdf_transparent_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { return make_float3(0.0f, 0.0f, 0.0f); } -__device float3 bsdf_transparent_eval_transmit(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) +__device float3 bsdf_transparent_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { return make_float3(0.0f, 0.0f, 0.0f); } -__device float bsdf_transparent_albedo(const ShaderData *sd, const ShaderClosure *sc, const float3 I) +__device float bsdf_transparent_albedo(const ShaderClosure *sc, const float3 I) { return 1.0f; } -__device int bsdf_transparent_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) +__device int bsdf_transparent_sample(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) { // only one direction is possible - *omega_in = -sd->I; + *omega_in = -I; #ifdef __RAY_DIFFERENTIALS__ - *domega_in_dx = -sd->dI.dx; - *domega_in_dy = -sd->dI.dy; + *domega_in_dx = -dIdx; + *domega_in_dy = -dIdy; #endif *pdf = 1; *eval = make_float3(1, 1, 1); diff --git a/intern/cycles/kernel/svm/bsdf_ward.h b/intern/cycles/kernel/svm/bsdf_ward.h index 3c08a3d54d3..1407078b7bb 100644 --- a/intern/cycles/kernel/svm/bsdf_ward.h +++ b/intern/cycles/kernel/svm/bsdf_ward.h @@ -37,14 +37,7 @@ CCL_NAMESPACE_BEGIN /* WARD */ -typedef struct BsdfWardClosure { - //float3 m_N; - //float3 m_T; - float m_ax; - float m_ay; -} BsdfWardClosure; - -__device void bsdf_ward_setup(ShaderData *sd, ShaderClosure *sc, float3 T, float ax, float ay) +__device void bsdf_ward_setup(ShaderData *sd, ShaderClosure *sc, float ax, float ay) { float m_ax = clamp(ax, 1e-5f, 1.0f); float m_ay = clamp(ay, 1e-5f, 1.0f); @@ -62,25 +55,25 @@ __device void bsdf_ward_blur(ShaderClosure *sc, float roughness) sc->data1 = fmaxf(roughness, sc->data1); } -__device float3 bsdf_ward_eval_reflect(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) +__device float3 bsdf_ward_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { float m_ax = sc->data0; float m_ay = sc->data1; - float3 m_N = sc->N; - float3 m_T = sd->T; + float3 N = sc->N; + float3 T = sc->T; - float cosNO = dot(m_N, I); - float cosNI = dot(m_N, omega_in); + float cosNO = dot(N, I); + float cosNI = dot(N, omega_in); if(cosNI > 0 && cosNO > 0) { // get half vector and get x,y basis on the surface for anisotropy float3 H = normalize(omega_in + I); // normalize needed for pdf float3 X, Y; - make_orthonormals_tangent(m_N, m_T, &X, &Y); + make_orthonormals_tangent(N, T, &X, &Y); // eq. 4 float dotx = dot(H, X) / m_ax; float doty = dot(H, Y) / m_ay; - float dotn = dot(H, m_N); + float dotn = dot(H, N); float exp_arg = (dotx * dotx + doty * doty) / (dotn * dotn); float denom = (4 * M_PI_F * m_ax * m_ay * sqrtf(cosNO * cosNI)); float exp_val = expf(-exp_arg); @@ -94,28 +87,28 @@ __device float3 bsdf_ward_eval_reflect(const ShaderData *sd, const ShaderClosure return make_float3 (0, 0, 0); } -__device float3 bsdf_ward_eval_transmit(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) +__device float3 bsdf_ward_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { return make_float3(0.0f, 0.0f, 0.0f); } -__device float bsdf_ward_albedo(const ShaderData *sd, const ShaderClosure *sc, const float3 I) +__device float bsdf_ward_albedo(const ShaderClosure *sc, const float3 I) { return 1.0f; } -__device int bsdf_ward_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) +__device int bsdf_ward_sample(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) { float m_ax = sc->data0; float m_ay = sc->data1; - float3 m_N = sc->N; - float3 m_T = sd->T; + float3 N = sc->N; + float3 T = sc->T; - float cosNO = dot(m_N, sd->I); + float cosNO = dot(N, I); if(cosNO > 0) { // get x,y basis on the surface for anisotropy float3 X, Y; - make_orthonormals_tangent(m_N, m_T, &X, &Y); + make_orthonormals_tangent(N, T, &X, &Y); // generate random angles for the half vector // eq. 7 (taking care around discontinuities to keep //ttoutput angle in the right quadrant) @@ -167,12 +160,12 @@ __device int bsdf_ward_sample(const ShaderData *sd, const ShaderClosure *sc, flo float doty = h.y / m_ay; float dotn = h.z; // transform to world space - h = h.x * X + h.y * Y + h.z * m_N; + h = h.x * X + h.y * Y + h.z * N; // generate the final sample - float oh = dot(h, sd->I); - *omega_in = 2.0f * oh * h - sd->I; - if(dot(sd->Ng, *omega_in) > 0) { - float cosNI = dot(m_N, *omega_in); + float oh = dot(h, I); + *omega_in = 2.0f * oh * h - I; + if(dot(Ng, *omega_in) > 0) { + float cosNI = dot(N, *omega_in); if(cosNI > 0) { // eq. 9 float exp_arg = (dotx * dotx + doty * doty) / (dotn * dotn); @@ -183,8 +176,8 @@ __device int bsdf_ward_sample(const ShaderData *sd, const ShaderClosure *sc, flo float power = cosNI * expf(-exp_arg) / denom; *eval = make_float3(power, power, power); #ifdef __RAY_DIFFERENTIALS__ - *domega_in_dx = (2 * dot(m_N, sd->dI.dx)) * m_N - sd->dI.dx; - *domega_in_dy = (2 * dot(m_N, sd->dI.dy)) * m_N - sd->dI.dy; + *domega_in_dx = (2 * dot(N, dIdx)) * N - dIdx; + *domega_in_dy = (2 * dot(N, dIdy)) * N - dIdy; // Since there is some blur to this reflection, make the // derivatives a bit bigger. In theory this varies with the // roughness but the exact relationship is complex and diff --git a/intern/cycles/kernel/svm/bsdf_westin.h b/intern/cycles/kernel/svm/bsdf_westin.h index 75f935e3267..44d89cf4866 100644 --- a/intern/cycles/kernel/svm/bsdf_westin.h +++ b/intern/cycles/kernel/svm/bsdf_westin.h @@ -37,11 +37,6 @@ CCL_NAMESPACE_BEGIN /* WESTIN BACKSCATTER */ -typedef struct BsdfWestinBackscatterClosure { - //float3 m_N; - float m_invroughness; -} BsdfWestinBackscatterClosure; - __device void bsdf_westin_backscatter_setup(ShaderData *sd, ShaderClosure *sc, float roughness) { roughness = clamp(roughness, 1e-5f, 1.0f); @@ -59,14 +54,14 @@ __device void bsdf_westin_backscatter_blur(ShaderClosure *sc, float roughness) sc->data0 = m_invroughness; } -__device float3 bsdf_westin_backscatter_eval_reflect(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) +__device float3 bsdf_westin_backscatter_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { float m_invroughness = sc->data0; - float3 m_N = sc->N; + float3 N = sc->N; // pdf is implicitly 0 (no indirect sampling) - float cosNO = dot(m_N, I); - float cosNI = dot(m_N, omega_in); + float cosNO = dot(N, I); + float cosNI = dot(N, omega_in); if(cosNO > 0 && cosNI > 0) { float cosine = dot(I, omega_in); *pdf = cosine > 0 ? (m_invroughness + 1) * powf(cosine, m_invroughness) : 0; @@ -76,40 +71,40 @@ __device float3 bsdf_westin_backscatter_eval_reflect(const ShaderData *sd, const return make_float3 (0, 0, 0); } -__device float3 bsdf_westin_backscatter_eval_transmit(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) +__device float3 bsdf_westin_backscatter_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { return make_float3(0.0f, 0.0f, 0.0f); } -__device float bsdf_westin_backscatter_albedo(const ShaderData *sd, const ShaderClosure *sc, const float3 I) +__device float bsdf_westin_backscatter_albedo(const ShaderClosure *sc, const float3 I) { return 1.0f; } -__device int bsdf_westin_backscatter_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) +__device int bsdf_westin_backscatter_sample(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) { float m_invroughness = sc->data0; - float3 m_N = sc->N; + float3 N = sc->N; - float cosNO = dot(m_N, sd->I); + float cosNO = dot(N, I); if(cosNO > 0) { #ifdef __RAY_DIFFERENTIALS__ - *domega_in_dx = sd->dI.dx; - *domega_in_dy = sd->dI.dy; + *domega_in_dx = dIdx; + *domega_in_dy = dIdy; #endif float3 T, B; - make_orthonormals (sd->I, &T, &B); + make_orthonormals (I, &T, &B); float phi = 2 * M_PI_F * randu; float cosTheta = powf(randv, 1 / (m_invroughness + 1)); float sinTheta2 = 1 - cosTheta * cosTheta; float sinTheta = sinTheta2 > 0 ? sqrtf(sinTheta2) : 0; *omega_in = (cosf(phi) * sinTheta) * T + (sinf(phi) * sinTheta) * B + - (cosTheta) * sd->I; - if(dot(sd->Ng, *omega_in) > 0) + (cosTheta) * I; + if(dot(Ng, *omega_in) > 0) { // common terms for pdf and eval - float cosNI = dot(m_N, *omega_in); + float cosNI = dot(N, *omega_in); // make sure the direction we chose is still in the right hemisphere if(cosNI > 0) { @@ -132,11 +127,6 @@ __device int bsdf_westin_backscatter_sample(const ShaderData *sd, const ShaderCl /* WESTIN SHEEN */ -typedef struct BsdfWestinSheenClosure { - //float3 m_N; - float m_edginess; -} BsdfWestinSheenClosure; - __device void bsdf_westin_sheen_setup(ShaderData *sd, ShaderClosure *sc, float edginess) { sc->type = CLOSURE_BSDF_WESTIN_SHEEN_ID; @@ -148,14 +138,14 @@ __device void bsdf_westin_sheen_blur(ShaderClosure *sc, float roughness) { } -__device float3 bsdf_westin_sheen_eval_reflect(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) +__device float3 bsdf_westin_sheen_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { float m_edginess = sc->data0; - float3 m_N = sc->N; + float3 N = sc->N; // pdf is implicitly 0 (no indirect sampling) - float cosNO = dot(m_N, I); - float cosNI = dot(m_N, omega_in); + float cosNO = dot(N, I); + float cosNI = dot(N, omega_in); if(cosNO > 0 && cosNI > 0) { float sinNO2 = 1 - cosNO * cosNO; *pdf = cosNI * M_1_PI_F; @@ -165,34 +155,34 @@ __device float3 bsdf_westin_sheen_eval_reflect(const ShaderData *sd, const Shade return make_float3 (0, 0, 0); } -__device float3 bsdf_westin_sheen_eval_transmit(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) +__device float3 bsdf_westin_sheen_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { return make_float3(0.0f, 0.0f, 0.0f); } -__device float bsdf_westin_sheen_albedo(const ShaderData *sd, const ShaderClosure *sc, const float3 I) +__device float bsdf_westin_sheen_albedo(const ShaderClosure *sc, const float3 I) { return 1.0f; } -__device int bsdf_westin_sheen_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) +__device int bsdf_westin_sheen_sample(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) { float m_edginess = sc->data0; - float3 m_N = sc->N; + float3 N = sc->N; // we are viewing the surface from the right side - send a ray out with cosine // distribution over the hemisphere - sample_cos_hemisphere(m_N, randu, randv, omega_in, pdf); - if(dot(sd->Ng, *omega_in) > 0) { + sample_cos_hemisphere(N, randu, randv, omega_in, pdf); + if(dot(Ng, *omega_in) > 0) { // TODO: account for sheen when sampling - float cosNO = dot(m_N, sd->I); + float cosNO = dot(N, I); float sinNO2 = 1 - cosNO * cosNO; float westin = sinNO2 > 0 ? powf(sinNO2, 0.5f * m_edginess) * (*pdf) : 0; *eval = make_float3(westin, westin, westin); #ifdef __RAY_DIFFERENTIALS__ // TODO: find a better approximation for the diffuse bounce - *domega_in_dx = (2 * dot(m_N, sd->dI.dx)) * m_N - sd->dI.dx; - *domega_in_dy = (2 * dot(m_N, sd->dI.dy)) * m_N - sd->dI.dy; + *domega_in_dx = (2 * dot(N, dIdx)) * N - dIdx; + *domega_in_dy = (2 * dot(N, dIdy)) * N - dIdy; *domega_in_dx *= 125.0f; *domega_in_dy *= 125.0f; #endif diff --git a/intern/cycles/kernel/svm/svm.h b/intern/cycles/kernel/svm/svm.h index 5e22edc4696..421eb146f88 100644 --- a/intern/cycles/kernel/svm/svm.h +++ b/intern/cycles/kernel/svm/svm.h @@ -205,14 +205,6 @@ __device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ShaderT case NODE_CLOSURE_WEIGHT: svm_node_closure_weight(sd, stack, node.y); break; -#ifdef __DPDU__ - case NODE_CLOSURE_SET_TANGENT: - svm_node_closure_set_tangent(sd, node.y, node.z, node.w); - break; - case NODE_CLOSURE_TANGENT: - svm_node_closure_tangent(sd, stack, node.y); - break; -#endif case NODE_EMISSION_WEIGHT: svm_node_emission_weight(kg, sd, stack, node); break; diff --git a/intern/cycles/kernel/svm/svm_bsdf.h b/intern/cycles/kernel/svm/svm_bsdf.h index 411916f8aa0..043fc727bcb 100644 --- a/intern/cycles/kernel/svm/svm_bsdf.h +++ b/intern/cycles/kernel/svm/svm_bsdf.h @@ -36,45 +36,57 @@ __device int svm_bsdf_sample(const ShaderData *sd, const ShaderClosure *sc, floa switch(sc->type) { case CLOSURE_BSDF_DIFFUSE_ID: - label = bsdf_diffuse_sample(sd, sc, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); + label = bsdf_diffuse_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, + eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); break; #ifdef __SVM__ case CLOSURE_BSDF_OREN_NAYAR_ID: - label = bsdf_oren_nayar_sample(sd, sc, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); + label = bsdf_oren_nayar_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, + eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); break; case CLOSURE_BSDF_TRANSLUCENT_ID: - label = bsdf_translucent_sample(sd, sc, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); + label = bsdf_translucent_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, + eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); break; case CLOSURE_BSDF_REFLECTION_ID: - label = bsdf_reflection_sample(sd, sc, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); + label = bsdf_reflection_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, + eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); break; case CLOSURE_BSDF_REFRACTION_ID: - label = bsdf_refraction_sample(sd, sc, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); + label = bsdf_refraction_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, + eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); break; case CLOSURE_BSDF_TRANSPARENT_ID: - label = bsdf_transparent_sample(sd, sc, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); + label = bsdf_transparent_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, + eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); break; case CLOSURE_BSDF_MICROFACET_GGX_ID: case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID: - label = bsdf_microfacet_ggx_sample(sd, sc, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); + label = bsdf_microfacet_ggx_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, + eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); break; case CLOSURE_BSDF_MICROFACET_BECKMANN_ID: case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID: - label = bsdf_microfacet_beckmann_sample(sd, sc, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); + label = bsdf_microfacet_beckmann_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, + eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); break; #ifdef __DPDU__ case CLOSURE_BSDF_WARD_ID: - label = bsdf_ward_sample(sd, sc, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); + label = bsdf_ward_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, + eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); break; #endif case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID: - label = bsdf_ashikhmin_velvet_sample(sd, sc, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); + label = bsdf_ashikhmin_velvet_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, + eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); break; case CLOSURE_BSDF_WESTIN_BACKSCATTER_ID: - label = bsdf_westin_backscatter_sample(sd, sc, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); + label = bsdf_westin_backscatter_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, + eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); break; case CLOSURE_BSDF_WESTIN_SHEEN_ID: - label = bsdf_westin_sheen_sample(sd, sc, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); + label = bsdf_westin_sheen_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, + eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); break; #endif default: @@ -92,45 +104,45 @@ __device float3 svm_bsdf_eval(const ShaderData *sd, const ShaderClosure *sc, con if(dot(sd->Ng, omega_in) >= 0.0f) { switch(sc->type) { case CLOSURE_BSDF_DIFFUSE_ID: - eval = bsdf_diffuse_eval_reflect(sd, sc, sd->I, omega_in, pdf); + eval = bsdf_diffuse_eval_reflect(sc, sd->I, omega_in, pdf); break; #ifdef __SVM__ case CLOSURE_BSDF_OREN_NAYAR_ID: - eval = bsdf_oren_nayar_eval_reflect(sd, sc, sd->I, omega_in, pdf); + eval = bsdf_oren_nayar_eval_reflect(sc, sd->I, omega_in, pdf); break; case CLOSURE_BSDF_TRANSLUCENT_ID: - eval = bsdf_translucent_eval_reflect(sd, sc, sd->I, omega_in, pdf); + eval = bsdf_translucent_eval_reflect(sc, sd->I, omega_in, pdf); break; case CLOSURE_BSDF_REFLECTION_ID: - eval = bsdf_reflection_eval_reflect(sd, sc, sd->I, omega_in, pdf); + eval = bsdf_reflection_eval_reflect(sc, sd->I, omega_in, pdf); break; case CLOSURE_BSDF_REFRACTION_ID: - eval = bsdf_refraction_eval_reflect(sd, sc, sd->I, omega_in, pdf); + eval = bsdf_refraction_eval_reflect(sc, sd->I, omega_in, pdf); break; case CLOSURE_BSDF_TRANSPARENT_ID: - eval = bsdf_transparent_eval_reflect(sd, sc, sd->I, omega_in, pdf); + eval = bsdf_transparent_eval_reflect(sc, sd->I, omega_in, pdf); break; case CLOSURE_BSDF_MICROFACET_GGX_ID: case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID: - eval = bsdf_microfacet_ggx_eval_reflect(sd, sc, sd->I, omega_in, pdf); + eval = bsdf_microfacet_ggx_eval_reflect(sc, sd->I, omega_in, pdf); break; case CLOSURE_BSDF_MICROFACET_BECKMANN_ID: case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID: - eval = bsdf_microfacet_beckmann_eval_reflect(sd, sc, sd->I, omega_in, pdf); + eval = bsdf_microfacet_beckmann_eval_reflect(sc, sd->I, omega_in, pdf); break; #ifdef __DPDU__ case CLOSURE_BSDF_WARD_ID: - eval = bsdf_ward_eval_reflect(sd, sc, sd->I, omega_in, pdf); + eval = bsdf_ward_eval_reflect(sc, sd->I, omega_in, pdf); break; #endif case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID: - eval = bsdf_ashikhmin_velvet_eval_reflect(sd, sc, sd->I, omega_in, pdf); + eval = bsdf_ashikhmin_velvet_eval_reflect(sc, sd->I, omega_in, pdf); break; case CLOSURE_BSDF_WESTIN_BACKSCATTER_ID: - eval = bsdf_westin_backscatter_eval_reflect(sd, sc, sd->I, omega_in, pdf); + eval = bsdf_westin_backscatter_eval_reflect(sc, sd->I, omega_in, pdf); break; case CLOSURE_BSDF_WESTIN_SHEEN_ID: - eval = bsdf_westin_sheen_eval_reflect(sd, sc, sd->I, omega_in, pdf); + eval = bsdf_westin_sheen_eval_reflect(sc, sd->I, omega_in, pdf); break; #endif default: @@ -141,45 +153,45 @@ __device float3 svm_bsdf_eval(const ShaderData *sd, const ShaderClosure *sc, con else { switch(sc->type) { case CLOSURE_BSDF_DIFFUSE_ID: - eval = bsdf_diffuse_eval_transmit(sd, sc, sd->I, omega_in, pdf); + eval = bsdf_diffuse_eval_transmit(sc, sd->I, omega_in, pdf); break; #ifdef __SVM__ case CLOSURE_BSDF_OREN_NAYAR_ID: - eval = bsdf_oren_nayar_eval_transmit(sd, sc, sd->I, omega_in, pdf); + eval = bsdf_oren_nayar_eval_transmit(sc, sd->I, omega_in, pdf); break; case CLOSURE_BSDF_TRANSLUCENT_ID: - eval = bsdf_translucent_eval_transmit(sd, sc, sd->I, omega_in, pdf); + eval = bsdf_translucent_eval_transmit(sc, sd->I, omega_in, pdf); break; case CLOSURE_BSDF_REFLECTION_ID: - eval = bsdf_reflection_eval_transmit(sd, sc, sd->I, omega_in, pdf); + eval = bsdf_reflection_eval_transmit(sc, sd->I, omega_in, pdf); break; case CLOSURE_BSDF_REFRACTION_ID: - eval = bsdf_refraction_eval_transmit(sd, sc, sd->I, omega_in, pdf); + eval = bsdf_refraction_eval_transmit(sc, sd->I, omega_in, pdf); break; case CLOSURE_BSDF_TRANSPARENT_ID: - eval = bsdf_transparent_eval_transmit(sd, sc, sd->I, omega_in, pdf); + eval = bsdf_transparent_eval_transmit(sc, sd->I, omega_in, pdf); break; case CLOSURE_BSDF_MICROFACET_GGX_ID: case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID: - eval = bsdf_microfacet_ggx_eval_transmit(sd, sc, sd->I, omega_in, pdf); + eval = bsdf_microfacet_ggx_eval_transmit(sc, sd->I, omega_in, pdf); break; case CLOSURE_BSDF_MICROFACET_BECKMANN_ID: case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID: - eval = bsdf_microfacet_beckmann_eval_transmit(sd, sc, sd->I, omega_in, pdf); + eval = bsdf_microfacet_beckmann_eval_transmit(sc, sd->I, omega_in, pdf); break; #ifdef __DPDU__ case CLOSURE_BSDF_WARD_ID: - eval = bsdf_ward_eval_transmit(sd, sc, sd->I, omega_in, pdf); + eval = bsdf_ward_eval_transmit(sc, sd->I, omega_in, pdf); break; #endif case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID: - eval = bsdf_ashikhmin_velvet_eval_transmit(sd, sc, sd->I, omega_in, pdf); + eval = bsdf_ashikhmin_velvet_eval_transmit(sc, sd->I, omega_in, pdf); break; case CLOSURE_BSDF_WESTIN_BACKSCATTER_ID: - eval = bsdf_westin_backscatter_eval_transmit(sd, sc, sd->I, omega_in, pdf); + eval = bsdf_westin_backscatter_eval_transmit(sc, sd->I, omega_in, pdf); break; case CLOSURE_BSDF_WESTIN_SHEEN_ID: - eval = bsdf_westin_sheen_eval_transmit(sd, sc, sd->I, omega_in, pdf); + eval = bsdf_westin_sheen_eval_transmit(sc, sd->I, omega_in, pdf); break; #endif default: diff --git a/intern/cycles/kernel/svm/svm_closure.h b/intern/cycles/kernel/svm/svm_closure.h index 6a0e6915e99..0d30792a594 100644 --- a/intern/cycles/kernel/svm/svm_closure.h +++ b/intern/cycles/kernel/svm/svm_closure.h @@ -190,12 +190,13 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st #endif ShaderClosure *sc = svm_node_closure_get(sd); sc->N = N; + sc->T = stack_load_float3(stack, data_node.z); svm_node_closure_set_mix_weight(sc, mix_weight); float roughness_u = param1; float roughness_v = param2; - bsdf_ward_setup(sd, sc, sd->T, roughness_u, roughness_v); + bsdf_ward_setup(sd, sc, roughness_u, roughness_v); break; } #endif @@ -442,27 +443,6 @@ __device void svm_node_add_closure(ShaderData *sd, float *stack, uint unused, #endif } -/* Tangent */ - -#ifdef __DPDU__ -__device_inline void svm_node_closure_store_tangent(ShaderData *sd, float3 tangent) -{ - sd->T = normalize(tangent); -} - -__device void svm_node_closure_set_tangent(ShaderData *sd, uint x, uint y, uint z) -{ - float3 tangent = make_float3(__int_as_float(x), __int_as_float(y), __int_as_float(z)); - svm_node_closure_store_tangent(sd, tangent); -} - -__device void svm_node_closure_tangent(ShaderData *sd, float *stack, uint tangent_offset) -{ - float3 tangent = stack_load_float3(stack, tangent_offset); - svm_node_closure_store_tangent(sd, tangent); -} -#endif - /* (Bump) normal */ __device void svm_node_set_normal(KernelGlobals *kg, ShaderData *sd, float *stack, uint in_direction, uint out_normal) diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h index 327d9cfa014..487876ed417 100644 --- a/intern/cycles/kernel/svm/svm_types.h +++ b/intern/cycles/kernel/svm/svm_types.h @@ -93,8 +93,6 @@ typedef enum NodeType { NODE_OBJECT_INFO, NODE_PARTICLE_INFO, NODE_TEX_BRICK, - NODE_CLOSURE_SET_TANGENT, - NODE_CLOSURE_TANGENT, NODE_CLOSURE_SET_NORMAL, } NodeType; diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index b4ef93a4ff8..0bd24f71930 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -1184,6 +1184,7 @@ void BsdfNode::compile(SVMCompiler& compiler, ShaderInput *param1, ShaderInput * { ShaderInput *color_in = input("Color"); ShaderInput *normal_in = input("Normal"); + ShaderInput *tangent_in = input("Tangent"); if(color_in->link) { compiler.stack_assign(color_in); @@ -1207,7 +1208,16 @@ void BsdfNode::compile(SVMCompiler& compiler, ShaderInput *param1, ShaderInput * if(normal_in->link) compiler.stack_assign(normal_in); - compiler.add_node(NODE_CLOSURE_BSDF, normal_in->stack_offset); + + if(tangent_in) { + if(tangent_in->link) + compiler.stack_assign(tangent_in); + + compiler.add_node(NODE_CLOSURE_BSDF, normal_in->stack_offset, tangent_in->stack_offset); + } + else { + compiler.add_node(NODE_CLOSURE_BSDF, normal_in->stack_offset); + } } void BsdfNode::compile(SVMCompiler& compiler) @@ -1246,15 +1256,6 @@ void WardBsdfNode::compile(SVMCompiler& compiler) { ShaderInput *tangent_in = input("Tangent"); - if(tangent_in->link) { - int attr = compiler.attribute(ATTR_STD_TANGENT); - compiler.stack_assign(tangent_in); - compiler.add_node(NODE_ATTR, attr, tangent_in->stack_offset, NODE_ATTR_FLOAT3); - compiler.add_node(NODE_CLOSURE_TANGENT, tangent_in->stack_offset); - } - else - compiler.add_node(NODE_CLOSURE_SET_TANGENT, tangent_in->value); - BsdfNode::compile(compiler, input("Roughness U"), input("Roughness V")); } diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.c index ffad6b06eee..82db5553a87 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.c +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.c @@ -33,7 +33,8 @@ static bNodeSocketTemplate sh_node_bsdf_anisotropic_in[]= { { SOCK_RGBA, 1, N_("Color"), 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, { SOCK_FLOAT, 1, N_("Roughness U"), 0.2f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, { SOCK_FLOAT, 1, N_("Roughness V"), 0.2f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, - { SOCK_VECTOR, 1, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE}, + { SOCK_VECTOR, 1, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE}, + { SOCK_VECTOR, 1, N_("Tangent"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE}, { -1, 0, "" } }; From d08b06f773c754c70886901b8964c8093f920a75 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 17 Oct 2012 12:55:23 +0000 Subject: [PATCH 285/347] Cycles: motion blur is now curved and passes exactly through the midpoint. Previously it would only interpolate between the previous and next frame, which meant it might not hit the current frame position. --- intern/cycles/kernel/kernel_object.h | 17 +++++++----- intern/cycles/kernel/kernel_types.h | 2 +- intern/cycles/render/camera.cpp | 3 +-- intern/cycles/render/nodes.cpp | 2 -- intern/cycles/render/object.cpp | 14 +++++----- intern/cycles/util/util_transform.cpp | 3 ++- intern/cycles/util/util_transform.h | 37 +++++++++++++++++++++++---- 7 files changed, 54 insertions(+), 24 deletions(-) diff --git a/intern/cycles/kernel/kernel_object.h b/intern/cycles/kernel/kernel_object.h index 602574cb736..79ff7e2020a 100644 --- a/intern/cycles/kernel/kernel_object.h +++ b/intern/cycles/kernel/kernel_object.h @@ -23,8 +23,9 @@ enum ObjectTransform { OBJECT_INVERSE_TRANSFORM = 3, OBJECT_PROPERTIES = 6, OBJECT_TRANSFORM_MOTION_PRE = 8, - OBJECT_TRANSFORM_MOTION_POST = 12, - OBJECT_DUPLI = 16 + OBJECT_TRANSFORM_MOTION_MID = 12, + OBJECT_TRANSFORM_MOTION_POST = 16, + OBJECT_DUPLI = 18 }; __device_inline Transform object_fetch_transform(KernelGlobals *kg, int object, enum ObjectTransform type) @@ -59,11 +60,15 @@ __device_inline Transform object_fetch_transform_motion(KernelGlobals *kg, int o motion.pre.z = kernel_tex_fetch(__objects, offset + 2); motion.pre.w = kernel_tex_fetch(__objects, offset + 3); + motion.mid.x = kernel_tex_fetch(__objects, offset + 4); + motion.mid.y = kernel_tex_fetch(__objects, offset + 5); + motion.mid.z = kernel_tex_fetch(__objects, offset + 6); + motion.mid.w = kernel_tex_fetch(__objects, offset + 7); - motion.post.x = kernel_tex_fetch(__objects, offset + 4); - motion.post.y = kernel_tex_fetch(__objects, offset + 5); - motion.post.z = kernel_tex_fetch(__objects, offset + 6); - motion.post.w = kernel_tex_fetch(__objects, offset + 7); + motion.post.x = kernel_tex_fetch(__objects, offset + 8); + motion.post.y = kernel_tex_fetch(__objects, offset + 9); + motion.post.z = kernel_tex_fetch(__objects, offset + 10); + motion.post.w = kernel_tex_fetch(__objects, offset + 11); transform_motion_interpolate(&tfm, &motion, time); diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index bcf80cb76fb..4cf414091f5 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -29,7 +29,7 @@ CCL_NAMESPACE_BEGIN /* constants */ -#define OBJECT_SIZE 18 +#define OBJECT_SIZE 22 #define LIGHT_SIZE 4 #define FILTER_TABLE_SIZE 256 #define RAMP_TABLE_SIZE 256 diff --git a/intern/cycles/render/camera.cpp b/intern/cycles/render/camera.cpp index 727b9801d95..7703d0cbc8e 100644 --- a/intern/cycles/render/camera.cpp +++ b/intern/cycles/render/camera.cpp @@ -197,9 +197,8 @@ void Camera::device_update(Device *device, DeviceScene *dscene, Scene *scene) } #ifdef __CAMERA_MOTION__ else if(need_motion == Scene::MOTION_BLUR) { - /* todo: exact camera position will not be hit this way */ if(use_motion) { - transform_motion_decompose(&kcam->motion, &motion); + transform_motion_decompose(&kcam->motion, &motion, &matrix); kcam->have_motion = 1; } } diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index 0bd24f71930..ef139d994da 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -1254,8 +1254,6 @@ void WardBsdfNode::attributes(AttributeRequestSet *attributes) void WardBsdfNode::compile(SVMCompiler& compiler) { - ShaderInput *tangent_in = input("Tangent"); - BsdfNode::compile(compiler, input("Roughness U"), input("Roughness V")); } diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp index f5d78c080c8..63e904511e6 100644 --- a/intern/cycles/render/object.cpp +++ b/intern/cycles/render/object.cpp @@ -57,7 +57,7 @@ void Object::compute_bounds(bool motion_blur) if(motion_blur && use_motion) { MotionTransform decomp; - transform_motion_decompose(&decomp, &motion); + transform_motion_decompose(&decomp, &motion, &tfm); bounds = BoundBox::empty; @@ -219,7 +219,7 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene mtfm_post = mtfm_post * itfm; memcpy(&objects[offset+8], &mtfm_pre, sizeof(float4)*4); - memcpy(&objects[offset+12], &mtfm_post, sizeof(float4)*4); + memcpy(&objects[offset+16], &mtfm_post, sizeof(float4)*4); } #ifdef __OBJECT_MOTION__ else if(need_motion == Scene::MOTION_BLUR) { @@ -227,21 +227,21 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene /* decompose transformations for interpolation */ MotionTransform decomp; - transform_motion_decompose(&decomp, &ob->motion); - memcpy(&objects[offset+8], &decomp, sizeof(float4)*8); + transform_motion_decompose(&decomp, &ob->motion, &ob->tfm); + memcpy(&objects[offset+8], &decomp, sizeof(float4)*12); flag |= SD_OBJECT_MOTION; have_motion = true; } else { float4 no_motion = make_float4(FLT_MAX); - memcpy(&objects[offset+8], &no_motion, sizeof(float4)); + memcpy(&objects[offset+8], &no_motion, sizeof(float4)*12); } } #endif /* dupli object coords */ - objects[offset+16] = make_float4(ob->dupli_generated[0], ob->dupli_generated[1], ob->dupli_generated[2], 0.0f); - objects[offset+17] = make_float4(ob->dupli_uv[0], ob->dupli_uv[1], 0.0f, 0.0f); + objects[offset+20] = make_float4(ob->dupli_generated[0], ob->dupli_generated[1], ob->dupli_generated[2], 0.0f); + objects[offset+21] = make_float4(ob->dupli_uv[0], ob->dupli_uv[1], 0.0f, 0.0f); /* object flag */ if(ob->use_holdout) diff --git a/intern/cycles/util/util_transform.cpp b/intern/cycles/util/util_transform.cpp index b3c6506dfa0..70ee13d96d7 100644 --- a/intern/cycles/util/util_transform.cpp +++ b/intern/cycles/util/util_transform.cpp @@ -246,9 +246,10 @@ static void transform_decompose(Transform *decomp, const Transform *tfm) decomp->w = make_float4(scale.y.z, scale.z.x, scale.z.y, scale.z.z); } -void transform_motion_decompose(MotionTransform *decomp, const MotionTransform *motion) +void transform_motion_decompose(MotionTransform *decomp, const MotionTransform *motion, const Transform *mid) { transform_decompose(&decomp->pre, &motion->pre); + transform_decompose(&decomp->mid, mid); transform_decompose(&decomp->post, &motion->post); } diff --git a/intern/cycles/util/util_transform.h b/intern/cycles/util/util_transform.h index 3d6aefed56d..df525542207 100644 --- a/intern/cycles/util/util_transform.h +++ b/intern/cycles/util/util_transform.h @@ -41,6 +41,7 @@ typedef struct Transform { typedef struct MotionTransform { Transform pre; + Transform mid; Transform post; } MotionTransform; @@ -383,11 +384,37 @@ __device void transform_motion_interpolate(Transform *tfm, const MotionTransform { Transform decomp; - decomp.x = quat_interpolate(motion->pre.x, motion->post.x, t); - decomp.y = (1.0f - t)*motion->pre.y + t*motion->post.y; - decomp.z = (1.0f - t)*motion->pre.z + t*motion->post.z; - decomp.w = (1.0f - t)*motion->pre.w + t*motion->post.w; + /* 3 point bezier curve interpolation for position */ + float3 Ppre = float4_to_float3(motion->pre.y); + float3 Pmid = float4_to_float3(motion->mid.y); + float3 Ppost = float4_to_float3(motion->post.y); + float3 Pcontrol = 2.0f*Pmid - 0.5f*(Ppre + Ppost); + float3 P = Ppre*t*t + Pcontrol*2.0f*t*(1.0f - t) + Ppost*(1.0f - t)*(1.0f - t); + + decomp.y.x = P.x; + decomp.y.y = P.y; + decomp.y.z = P.z; + + /* linear interpolation for rotation and scale */ + if(t < 0.5f) { + t *= 2.0f; + + decomp.x = quat_interpolate(motion->pre.x, motion->mid.x, t); + decomp.y.w = (1.0f - t)*motion->pre.y.w + t*motion->mid.y.w; + decomp.z = (1.0f - t)*motion->pre.z + t*motion->mid.z; + decomp.w = (1.0f - t)*motion->pre.w + t*motion->mid.w; + } + else { + t = (t - 0.5f)*2.0f; + + decomp.x = quat_interpolate(motion->mid.x, motion->post.x, t); + decomp.y.w = (1.0f - t)*motion->mid.y.w + t*motion->post.y.w; + decomp.z = (1.0f - t)*motion->mid.z + t*motion->post.z; + decomp.w = (1.0f - t)*motion->mid.w + t*motion->post.w; + } + + /* compose rotation, translation, scale into matrix */ transform_compose(tfm, &decomp); } @@ -398,7 +425,7 @@ __device_inline bool operator==(const MotionTransform& A, const MotionTransform& return (A.pre == B.pre && A.post == B.post); } -void transform_motion_decompose(MotionTransform *decomp, const MotionTransform *motion); +void transform_motion_decompose(MotionTransform *decomp, const MotionTransform *motion, const Transform *mid); #endif From 20585a8b8dc50bc1a090f2d44066540839ee7303 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 17 Oct 2012 13:32:43 +0000 Subject: [PATCH 286/347] Render: local light group option for materials, blender internal feature from the render branch. When a material is linked in and has a light group override, this can now use a local group in the scene file, by replacing the linked light group with a local group that has the same name. A use case might be controlling the specular highlight on linked character's eyes per scene. Patch from render branch by Pablo Vazquez. --- release/scripts/startup/bl_ui/properties_material.py | 1 + source/blender/blenkernel/intern/material.c | 10 ++++++++++ source/blender/makesdna/DNA_material_types.h | 1 + source/blender/makesrna/intern/rna_material.c | 7 ++++++- 4 files changed, 18 insertions(+), 1 deletion(-) diff --git a/release/scripts/startup/bl_ui/properties_material.py b/release/scripts/startup/bl_ui/properties_material.py index 8eecbf4b604..951644db752 100644 --- a/release/scripts/startup/bl_ui/properties_material.py +++ b/release/scripts/startup/bl_ui/properties_material.py @@ -753,6 +753,7 @@ class MATERIAL_PT_options(MaterialButtonsPanel, Panel): row = sub.row() row.active = bool(mat.light_group) row.prop(mat, "use_light_group_exclusive", text="Exclusive") + row.prop(mat, "use_light_group_local", text="Local") col = split.column() col.prop(mat, "use_face_texture") diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index bea0e33da9a..7d5ed058cca 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -38,6 +38,7 @@ #include "DNA_anim_types.h" #include "DNA_curve_types.h" +#include "DNA_group_types.h" #include "DNA_material_types.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" @@ -980,6 +981,15 @@ static void do_init_render_material(Material *ma, int r_mode, float *amb) /* parses the geom+tex nodes */ if (ma->nodetree && ma->use_nodes) ntreeShaderGetTexcoMode(ma->nodetree, r_mode, &ma->texco, &ma->mode_l); + + /* local group override */ + if((ma->shade_flag & MA_GROUP_LOCAL) && ma->id.lib && ma->group && ma->group->id.lib) { + Group *group; + + for(group= G.main->group.first; group; group= group->id.next) + if(!group->id.lib && strcmp(group->id.name, ma->group->id.name) == 0) + ma->group = group; + } } static void init_render_nodetree(bNodeTree *ntree, Material *basemat, int r_mode, float *amb) diff --git a/source/blender/makesdna/DNA_material_types.h b/source/blender/makesdna/DNA_material_types.h index 374cc8e7379..51f9af278fe 100644 --- a/source/blender/makesdna/DNA_material_types.h +++ b/source/blender/makesdna/DNA_material_types.h @@ -292,6 +292,7 @@ typedef struct Material { #define MA_CUBIC 1 #define MA_OBCOLOR 2 #define MA_APPROX_OCCLUSION 4 +#define MA_GROUP_LOCAL 8 /* diff_shader */ #define MA_DIFF_LAMBERT 0 diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c index ed40f8cffb6..f53adcc6837 100644 --- a/source/blender/makesrna/intern/rna_material.c +++ b/source/blender/makesrna/intern/rna_material.c @@ -1823,7 +1823,12 @@ void RNA_def_material(BlenderRNA *brna) "Material uses the light group exclusively - these lamps are excluded " "from other scene lighting"); RNA_def_property_update(prop, 0, "rna_Material_update"); - + + prop= RNA_def_property(srna, "use_light_group_local", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "shade_flag", MA_GROUP_LOCAL); + RNA_def_property_ui_text(prop, "Light Group Local", "When linked in, Material uses local light group with the same name"); + RNA_def_property_update(prop, 0, "rna_Material_update"); + prop = RNA_def_property(srna, "use_raytrace", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_TRACEBLE); RNA_def_property_ui_text(prop, "Traceable", From f83ae34e037aabef4508b517c49223963ab3c844 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 17 Oct 2012 16:01:57 +0000 Subject: [PATCH 287/347] add a template for a stub script - runs the script relative to the currently open blend file. --- release/scripts/templates/script_stub.py | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 release/scripts/templates/script_stub.py diff --git a/release/scripts/templates/script_stub.py b/release/scripts/templates/script_stub.py new file mode 100644 index 00000000000..69ecbf48d2c --- /dev/null +++ b/release/scripts/templates/script_stub.py @@ -0,0 +1,11 @@ +# This stub runs a python script relative to the currently open +# blend file, useful when editing scripts externally. + +import bpy +import os + +# Use your own script name here: +filename = "my_script.py" + +filepath = os.path.join(os.path.basename(bpy.data.filepath), filename) +exec(compile(open(filepath).read(), filepath, 'exec')) From 0c2a1500f293a1ae103afece42595f97598d8055 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 17 Oct 2012 16:10:04 +0000 Subject: [PATCH 288/347] minor changes - stub from last commit was incorrect (copied old docs) - decimator was making copy of quadric for no reason. - correct typo --- intern/decimation/intern/LOD_Quadric.h | 2 +- intern/decimation/intern/LOD_QuadricEditor.cpp | 2 +- release/scripts/templates/script_stub.py | 2 +- source/blender/bmesh/operators/bmo_unsubdivide.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/intern/decimation/intern/LOD_Quadric.h b/intern/decimation/intern/LOD_Quadric.h index 9dde0502aa3..fc69530ac43 100644 --- a/intern/decimation/intern/LOD_Quadric.h +++ b/intern/decimation/intern/LOD_Quadric.h @@ -45,7 +45,7 @@ private: MT_Scalar c2, cd; MT_Scalar d2; - void init(MT_Scalar a, MT_Scalar b, MT_Scalar c, MT_Scalar d); + //void init(MT_Scalar a, MT_Scalar b, MT_Scalar c, MT_Scalar d); public: diff --git a/intern/decimation/intern/LOD_QuadricEditor.cpp b/intern/decimation/intern/LOD_QuadricEditor.cpp index fbaf0c1180f..9c895ee25f1 100644 --- a/intern/decimation/intern/LOD_QuadricEditor.cpp +++ b/intern/decimation/intern/LOD_QuadricEditor.cpp @@ -179,7 +179,7 @@ BuildQuadrics( MT_Vector3 target = TargetVertex(*edge_it); LOD_Edge &e = *edge_it; - LOD_Quadric q0 = quadrics[e.m_verts[0]]; + const LOD_Quadric &q0 = quadrics[e.m_verts[0]]; const LOD_Quadric &q1 = quadrics[e.m_verts[1]]; e.HeapKey() = -float(q0.Evaluate(target) + q1.Evaluate(target)); diff --git a/release/scripts/templates/script_stub.py b/release/scripts/templates/script_stub.py index 69ecbf48d2c..3b3212892d5 100644 --- a/release/scripts/templates/script_stub.py +++ b/release/scripts/templates/script_stub.py @@ -7,5 +7,5 @@ import os # Use your own script name here: filename = "my_script.py" -filepath = os.path.join(os.path.basename(bpy.data.filepath), filename) +filepath = os.path.join(os.path.dirname(bpy.data.filepath), filename) exec(compile(open(filepath).read(), filepath, 'exec')) diff --git a/source/blender/bmesh/operators/bmo_unsubdivide.c b/source/blender/bmesh/operators/bmo_unsubdivide.c index 01a9b6f8416..64b7151aee5 100644 --- a/source/blender/bmesh/operators/bmo_unsubdivide.c +++ b/source/blender/bmesh/operators/bmo_unsubdivide.c @@ -218,7 +218,7 @@ void bmo_unsubdivide_exec(BMesh *bm, BMOperator *op) BM_elem_index_set(v, VERT_INDEX_IGNORE); /* set_dirty! */ } } - /* dont with selecting tagged verts */ + /* done with selecting tagged verts */ /* main loop, keep tagging until we can't tag any more islands */ From 17c82a7e5709705a96cb4c9d20715a6bc07d688c Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Wed, 17 Oct 2012 16:16:35 +0000 Subject: [PATCH 289/347] Cycles / OSL: * Layer Weight is now available in OSL. --- intern/cycles/kernel/osl/nodes/CMakeLists.txt | 1 + ...blend_weight.osl => node_layer_weight.osl} | 21 ++++++++++++------- intern/cycles/render/nodes.cpp | 2 +- 3 files changed, 15 insertions(+), 9 deletions(-) rename intern/cycles/kernel/osl/nodes/{node_blend_weight.osl => node_layer_weight.osl} (72%) diff --git a/intern/cycles/kernel/osl/nodes/CMakeLists.txt b/intern/cycles/kernel/osl/nodes/CMakeLists.txt index cb965ac1530..65b8504ce43 100644 --- a/intern/cycles/kernel/osl/nodes/CMakeLists.txt +++ b/intern/cycles/kernel/osl/nodes/CMakeLists.txt @@ -29,6 +29,7 @@ set(SRC_OSL node_hsv.osl node_image_texture.osl node_invert.osl + node_layer_weight.osl node_light_path.osl node_light_falloff.osl node_magic_texture.osl diff --git a/intern/cycles/kernel/osl/nodes/node_blend_weight.osl b/intern/cycles/kernel/osl/nodes/node_layer_weight.osl similarity index 72% rename from intern/cycles/kernel/osl/nodes/node_blend_weight.osl rename to intern/cycles/kernel/osl/nodes/node_layer_weight.osl index 836897fc5e3..ea25d0c0e02 100644 --- a/intern/cycles/kernel/osl/nodes/node_blend_weight.osl +++ b/intern/cycles/kernel/osl/nodes/node_layer_weight.osl @@ -19,22 +19,27 @@ #include "stdosl.h" #include "node_fresnel.h" -shader node_blend_weight( - float Blend = 0.3, +shader node_layer_weight( + float Blend = 0.5, normal Normal = N, output float Fresnel = 0.0, output float Facing = 0.0) { - float f = max(1.0 - Blend, 1e-5); - Fresnel = fresnel_dielectric(I, Normal, backfacing()? f: 1.0 / f); + float blend = Blend; + /* Fresnel */ + float eta = max(1.0 - Blend, 1e-5); + eta = backfacing()? eta: 1.0 / eta; + Fresnel = fresnel_dielectric(I, Normal, eta); + + /* Facing */ Facing = abs(dot(I, Normal)); - if (Blend != 0.5) { - Blend = clamp(Blend, 0.0, 1.0); - Blend = (Blend < 0.5)? 2.0 * Blend: 0.5 / (1.0 - Blend); + if (blend != 0.5) { + blend = clamp(blend, 0.0, 1.0); + blend = (blend < 0.5)? 2.0 * blend: 0.5 / (1.0 - blend); - Facing = powf(Facing, Blend); + Facing = pow(Facing, blend); } Facing = 1.0 - Facing; diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index ef139d994da..6030c9f49c1 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -2579,7 +2579,7 @@ void LayerWeightNode::compile(SVMCompiler& compiler) void LayerWeightNode::compile(OSLCompiler& compiler) { - compiler.add(this, "node_blend_weight"); + compiler.add(this, "node_layer_weight"); } /* Output */ From 11908552db8c7ddba63d67577a6010869d72b0c7 Mon Sep 17 00:00:00 2001 From: Jason Wilkins Date: Wed, 17 Oct 2012 17:20:09 +0000 Subject: [PATCH 290/347] Missing semicolons in intern/ghost/intern/GHOST_WindowCocoa.mm --- intern/ghost/intern/GHOST_WindowCocoa.mm | 26 ++++++++++++------------ 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/intern/ghost/intern/GHOST_WindowCocoa.mm b/intern/ghost/intern/GHOST_WindowCocoa.mm index dc05fe42a70..2077afd4086 100644 --- a/intern/ghost/intern/GHOST_WindowCocoa.mm +++ b/intern/ghost/intern/GHOST_WindowCocoa.mm @@ -637,7 +637,7 @@ void* GHOST_WindowCocoa::getOSWindow() const void GHOST_WindowCocoa::setTitle(const STR_String& title) { - GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setTitle(): window invalid") + GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setTitle(): window invalid"); NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSString *windowTitle = [[NSString alloc] initWithCString:title encoding:NSUTF8StringEncoding]; @@ -684,7 +684,7 @@ void GHOST_WindowCocoa::setTitle(const STR_String& title) void GHOST_WindowCocoa::getTitle(STR_String& title) const { - GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getTitle(): window invalid") + GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getTitle(): window invalid"); NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; @@ -701,7 +701,7 @@ void GHOST_WindowCocoa::getTitle(STR_String& title) const void GHOST_WindowCocoa::getWindowBounds(GHOST_Rect& bounds) const { NSRect rect; - GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getWindowBounds(): window invalid") + GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getWindowBounds(): window invalid"); NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; @@ -721,7 +721,7 @@ void GHOST_WindowCocoa::getWindowBounds(GHOST_Rect& bounds) const void GHOST_WindowCocoa::getClientBounds(GHOST_Rect& bounds) const { NSRect rect; - GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getClientBounds(): window invalid") + GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getClientBounds(): window invalid"); NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; @@ -753,7 +753,7 @@ void GHOST_WindowCocoa::getClientBounds(GHOST_Rect& bounds) const GHOST_TSuccess GHOST_WindowCocoa::setClientWidth(GHOST_TUns32 width) { - GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setClientWidth(): window invalid") + GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setClientWidth(): window invalid"); NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; GHOST_Rect cBnds, wBnds; getClientBounds(cBnds); @@ -770,7 +770,7 @@ GHOST_TSuccess GHOST_WindowCocoa::setClientWidth(GHOST_TUns32 width) GHOST_TSuccess GHOST_WindowCocoa::setClientHeight(GHOST_TUns32 height) { - GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setClientHeight(): window invalid") + GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setClientHeight(): window invalid"); NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; GHOST_Rect cBnds, wBnds; getClientBounds(cBnds); @@ -787,7 +787,7 @@ GHOST_TSuccess GHOST_WindowCocoa::setClientHeight(GHOST_TUns32 height) GHOST_TSuccess GHOST_WindowCocoa::setClientSize(GHOST_TUns32 width, GHOST_TUns32 height) { - GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setClientSize(): window invalid") + GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setClientSize(): window invalid"); NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; GHOST_Rect cBnds, wBnds; getClientBounds(cBnds); @@ -806,7 +806,7 @@ GHOST_TSuccess GHOST_WindowCocoa::setClientSize(GHOST_TUns32 width, GHOST_TUns32 GHOST_TWindowState GHOST_WindowCocoa::getState() const { - GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getState(): window invalid") + GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getState(): window invalid"); NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; GHOST_TWindowState state; if (m_fullScreen) { @@ -828,7 +828,7 @@ GHOST_TWindowState GHOST_WindowCocoa::getState() const void GHOST_WindowCocoa::screenToClient(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const { - GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::screenToClient(): window invalid") + GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::screenToClient(): window invalid"); screenToClientIntern(inX, inY, outX, outY); @@ -841,7 +841,7 @@ void GHOST_WindowCocoa::screenToClient(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST void GHOST_WindowCocoa::clientToScreen(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const { - GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::clientToScreen(): window invalid") + GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::clientToScreen(): window invalid"); /* switch y to match ghost convention */ GHOST_Rect cBnds; @@ -895,7 +895,7 @@ NSScreen* GHOST_WindowCocoa::getScreen() */ GHOST_TSuccess GHOST_WindowCocoa::setState(GHOST_TWindowState state) { - GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setState(): window invalid") + GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setState(): window invalid"); switch (state) { case GHOST_kWindowStateMinimized: [m_window miniaturize:nil]; @@ -1049,7 +1049,7 @@ GHOST_TSuccess GHOST_WindowCocoa::setOrder(GHOST_TWindowOrder order) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setOrder(): window invalid") + GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setOrder(): window invalid"); if (order == GHOST_kWindowOrderTop) { [m_window makeKeyAndOrderFront:nil]; } @@ -1199,7 +1199,7 @@ GHOST_TSuccess GHOST_WindowCocoa::removeDrawingContext() GHOST_TSuccess GHOST_WindowCocoa::invalidate() { - GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::invalidate(): window invalid") + GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::invalidate(): window invalid"); NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; [m_openGLView setNeedsDisplay:YES]; [pool drain]; From 4ad103ceddd87ed36dac7f9fed4f1d058c6161b6 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 17 Oct 2012 17:27:30 +0000 Subject: [PATCH 291/347] Fix cycles motion blur not working correct with shutter time > 2.0. The soft limit is 2.0, and anything beyond that is extrapolation which might not work so well but is still allowed. --- intern/cycles/render/mesh.cpp | 4 +++- intern/cycles/render/object.cpp | 9 ++++++--- intern/cycles/render/object.h | 2 +- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp index 3f2fe4ab093..3c41b4f1ad3 100644 --- a/intern/cycles/render/mesh.cpp +++ b/intern/cycles/render/mesh.cpp @@ -19,6 +19,7 @@ #include "bvh.h" #include "bvh_build.h" +#include "camera.h" #include "device.h" #include "shader.h" #include "light.h" @@ -722,6 +723,7 @@ void MeshManager::device_update(Device *device, DeviceScene *dscene, Scene *scen foreach(Shader *shader, scene->shaders) shader->need_update_attributes = false; + float shuttertime = scene->camera->shuttertime; #ifdef __OBJECT_MOTION__ Scene::MotionType need_motion = scene->need_motion(device->info.advanced_shading); bool motion_blur = need_motion == Scene::MOTION_BLUR; @@ -730,7 +732,7 @@ void MeshManager::device_update(Device *device, DeviceScene *dscene, Scene *scen #endif foreach(Object *object, scene->objects) - object->compute_bounds(motion_blur); + object->compute_bounds(motion_blur, shuttertime); if(progress.get_cancel()) return; diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp index 63e904511e6..0b87a530725 100644 --- a/intern/cycles/render/object.cpp +++ b/intern/cycles/render/object.cpp @@ -51,7 +51,7 @@ Object::~Object() { } -void Object::compute_bounds(bool motion_blur) +void Object::compute_bounds(bool motion_blur, float shuttertime) { BoundBox mbounds = mesh->bounds; @@ -64,7 +64,10 @@ void Object::compute_bounds(bool motion_blur) /* todo: this is really terrible. according to pbrt there is a better * way to find this iteratively, but did not find implementation yet * or try to implement myself */ - for(float t = 0.0f; t < 1.0f; t += 1.0f/128.0f) { + float start_t = 0.5f - shuttertime*0.5f; + float end_t = 0.5f - shuttertime*0.5f; + + for(float t = start_t; t < end_t; t += (1.0f/128.0f)*shuttertime) { Transform ttfm; transform_motion_interpolate(&ttfm, &decomp, t); @@ -109,7 +112,7 @@ void Object::apply_transform() if(bounds.valid()) { mesh->compute_bounds(); - compute_bounds(false); + compute_bounds(false, 0.0f); } /* tfm is not reset to identity, all code that uses it needs to check the diff --git a/intern/cycles/render/object.h b/intern/cycles/render/object.h index e2c3ad4e071..922c886d961 100644 --- a/intern/cycles/render/object.h +++ b/intern/cycles/render/object.h @@ -59,7 +59,7 @@ public: void tag_update(Scene *scene); - void compute_bounds(bool motion_blur); + void compute_bounds(bool motion_blur, float shuttertime); void apply_transform(); }; From f732cc53d9a8fee3d0839e5a7922adb866e8c276 Mon Sep 17 00:00:00 2001 From: Daniel Salazar Date: Wed, 17 Oct 2012 19:29:35 +0000 Subject: [PATCH 292/347] Cycles: Sensible limmits for Sky Texture turbidity value --- source/blender/makesrna/intern/rna_nodetree.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index ce0f588a4ba..238cc445ed4 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -1462,7 +1462,9 @@ static void def_sh_tex_sky(StructRNA *srna) RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); prop = RNA_def_property(srna, "turbidity", PROP_FLOAT, PROP_NONE); - RNA_def_property_ui_text(prop, "Turbidity", ""); + RNA_def_property_range(prop, 1.0f, 30.0f); + RNA_def_property_ui_range(prop, 2.0f, 10.0f, 1, 2); + RNA_def_property_ui_text(prop, "Turbidity", "Atmospheric turbidity"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); } From 431caff869e793619aa71c7805624b8e8535978f Mon Sep 17 00:00:00 2001 From: Daniel Salazar Date: Wed, 17 Oct 2012 20:06:58 +0000 Subject: [PATCH 293/347] Maybe hard limmit is good enough. Removing soft limmit for sky turbidity --- source/blender/makesrna/intern/rna_nodetree.c | 1 - 1 file changed, 1 deletion(-) diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 238cc445ed4..0d7d20d04ae 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -1463,7 +1463,6 @@ static void def_sh_tex_sky(StructRNA *srna) prop = RNA_def_property(srna, "turbidity", PROP_FLOAT, PROP_NONE); RNA_def_property_range(prop, 1.0f, 30.0f); - RNA_def_property_ui_range(prop, 2.0f, 10.0f, 1, 2); RNA_def_property_ui_text(prop, "Turbidity", "Atmospheric turbidity"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); } From 6915394a3b91b6ac836537d058d6fb6954d38af1 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 17 Oct 2012 22:48:29 +0000 Subject: [PATCH 294/347] Attempts to fix CUDA issues on sm 2.0 cards, still no luck getting motion blur working, but this should make it not crash. Also fix for wrong shutter time, should have been shorter. --- intern/cycles/kernel/kernel_bvh.h | 14 ++--- intern/cycles/kernel/kernel_camera.h | 2 +- intern/cycles/kernel/kernel_displace.h | 3 + intern/cycles/kernel/kernel_emission.h | 3 + intern/cycles/kernel/kernel_light.h | 2 +- intern/cycles/kernel/kernel_object.h | 83 +++++++++++++------------- intern/cycles/kernel/kernel_shader.h | 33 +++++----- intern/cycles/render/object.cpp | 4 +- 8 files changed, 78 insertions(+), 66 deletions(-) diff --git a/intern/cycles/kernel/kernel_bvh.h b/intern/cycles/kernel/kernel_bvh.h index 9d8ad6f3072..d033fb1d145 100644 --- a/intern/cycles/kernel/kernel_bvh.h +++ b/intern/cycles/kernel/kernel_bvh.h @@ -87,7 +87,7 @@ __device_inline void bvh_instance_pop(KernelGlobals *kg, int object, const Ray * __device_inline void bvh_instance_motion_push(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *idir, float *t, Transform *tfm, const float tmax) { Transform itfm; - *tfm = object_fetch_transform_motion(kg, object, ray->time, &itfm); + *tfm = object_fetch_transform_motion_test(kg, object, ray->time, &itfm); *P = transform_point(&itfm, ray->P); @@ -104,9 +104,8 @@ __device_inline void bvh_instance_motion_push(KernelGlobals *kg, int object, con __device_inline void bvh_instance_motion_pop(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *idir, float *t, Transform *tfm, const float tmax) { - if(*t != FLT_MAX) { + if(*t != FLT_MAX) *t *= len(transform_direction(tfm, 1.0f/(*idir))); - } *P = ray->P; *idir = bvh_inverse_direction(ray->D); @@ -163,7 +162,7 @@ __device_inline void bvh_node_intersect(KernelGlobals *kg, /* Sven Woop's algorithm */ __device_inline void bvh_triangle_intersect(KernelGlobals *kg, Intersection *isect, - float3 P, float3 idir, uint visibility, int object, int triAddr, Transform *tfm) + float3 P, float3 idir, uint visibility, int object, int triAddr) { /* compute and check intersection t-value */ float4 v00 = kernel_tex_fetch(__tri_woop, triAddr*TRI_NODE_SIZE+0); @@ -285,7 +284,7 @@ __device_inline bool bvh_intersect(KernelGlobals *kg, const Ray *ray, const uint /* triangle intersection */ while(primAddr < primAddr2) { /* intersect ray against triangle */ - bvh_triangle_intersect(kg, isect, P, idir, visibility, object, primAddr, NULL); + bvh_triangle_intersect(kg, isect, P, idir, visibility, object, primAddr); /* shadow ray early termination */ if(visibility == PATH_RAY_SHADOW_OPAQUE && isect->prim != ~0) @@ -405,7 +404,7 @@ __device_inline bool bvh_intersect_motion(KernelGlobals *kg, const Ray *ray, con /* triangle intersection */ while(primAddr < primAddr2) { /* intersect ray against triangle */ - bvh_triangle_intersect(kg, isect, P, idir, visibility, object, primAddr, &ob_tfm); + bvh_triangle_intersect(kg, isect, P, idir, visibility, object, primAddr); /* shadow ray early termination */ if(visibility == PATH_RAY_SHADOW_OPAQUE && isect->prim != ~0) @@ -444,7 +443,8 @@ __device_inline bool bvh_intersect_motion(KernelGlobals *kg, const Ray *ray, con __device_inline bool scene_intersect(KernelGlobals *kg, const Ray *ray, const uint visibility, Intersection *isect) { -#ifdef __OBJECT_MOTION__ + /* todo: fix cuda sm 2.0 motion blur */ +#if defined(__OBJECT_MOTION__) && (!defined(__KERNEL_CUDA) || (__CUDA_ARCH__ >= 210)) if(kernel_data.bvh.have_motion) return bvh_intersect_motion(kg, ray, visibility, isect); else diff --git a/intern/cycles/kernel/kernel_camera.h b/intern/cycles/kernel/kernel_camera.h index 08674d0e379..1b2fe8c56ee 100644 --- a/intern/cycles/kernel/kernel_camera.h +++ b/intern/cycles/kernel/kernel_camera.h @@ -217,7 +217,7 @@ __device void camera_sample(KernelGlobals *kg, int x, int y, float filter_u, flo if(kernel_data.cam.shuttertime == 0.0f) ray->time = TIME_INVALID; else - ray->time = 0.5f + (time - 0.5f)*kernel_data.cam.shuttertime; + ray->time = 0.5f + 0.5f*(time - 0.5f)*kernel_data.cam.shuttertime; #endif /* sample */ diff --git a/intern/cycles/kernel/kernel_displace.h b/intern/cycles/kernel/kernel_displace.h index 6461a1eea38..a55f7a7fd75 100644 --- a/intern/cycles/kernel/kernel_displace.h +++ b/intern/cycles/kernel/kernel_displace.h @@ -47,6 +47,9 @@ __device void kernel_shader_evaluate(KernelGlobals *kg, uint4 *input, float4 *ou ray.P = make_float3(0.0f, 0.0f, 0.0f); ray.D = equirectangular_to_direction(u, v); ray.t = 0.0f; +#ifdef __CAMERA_MOTION__ + ray.time = 0.5f; +#endif #ifdef __RAY_DIFFERENTIALS__ ray.dD.dx = make_float3(0.0f, 0.0f, 0.0f); diff --git a/intern/cycles/kernel/kernel_emission.h b/intern/cycles/kernel/kernel_emission.h index 53d53b4bedd..75b6df5f08f 100644 --- a/intern/cycles/kernel/kernel_emission.h +++ b/intern/cycles/kernel/kernel_emission.h @@ -34,6 +34,9 @@ __device float3 direct_emissive_eval(KernelGlobals *kg, float rando, ray.P = ls->P; ray.dP.dx = make_float3(0.0f, 0.0f, 0.0f); ray.dP.dy = make_float3(0.0f, 0.0f, 0.0f); +#ifdef __CAMERA_MOTION__ + ray.time = time; +#endif shader_setup_from_background(kg, &sd, &ray); eval = shader_eval_background(kg, &sd, 0); } diff --git a/intern/cycles/kernel/kernel_light.h b/intern/cycles/kernel/kernel_light.h index 4bb17c0bd5a..2791b3abbb6 100644 --- a/intern/cycles/kernel/kernel_light.h +++ b/intern/cycles/kernel/kernel_light.h @@ -303,7 +303,7 @@ __device void triangle_light_sample(KernelGlobals *kg, int prim, int object, if(ls->object >= 0) { #ifdef __OBJECT_MOTION__ Transform itfm; - Transform tfm = object_fetch_transform_motion(kg, ls->object, time, &itfm); + Transform tfm = object_fetch_transform_motion_test(kg, object, time, &itfm); #else Transform tfm = object_fetch_transform(kg, ls->object, OBJECT_TRANSFORM); Transform itfm = object_fetch_transform(kg, ls->object, OBJECT_INVERSE_TRANSFORM); diff --git a/intern/cycles/kernel/kernel_object.h b/intern/cycles/kernel/kernel_object.h index 79ff7e2020a..2fa9443766e 100644 --- a/intern/cycles/kernel/kernel_object.h +++ b/intern/cycles/kernel/kernel_object.h @@ -25,7 +25,7 @@ enum ObjectTransform { OBJECT_TRANSFORM_MOTION_PRE = 8, OBJECT_TRANSFORM_MOTION_MID = 12, OBJECT_TRANSFORM_MOTION_POST = 16, - OBJECT_DUPLI = 18 + OBJECT_DUPLI = 20 }; __device_inline Transform object_fetch_transform(KernelGlobals *kg, int object, enum ObjectTransform type) @@ -42,49 +42,53 @@ __device_inline Transform object_fetch_transform(KernelGlobals *kg, int object, } #ifdef __OBJECT_MOTION__ -__device_inline Transform object_fetch_transform_motion(KernelGlobals *kg, int object, float time, Transform *itfm) +__device_inline Transform object_fetch_transform_motion(KernelGlobals *kg, int object, float time) { + MotionTransform motion; + + int offset = object*OBJECT_SIZE + (int)OBJECT_TRANSFORM_MOTION_PRE; + + motion.pre.x = kernel_tex_fetch(__objects, offset + 0); + motion.pre.y = kernel_tex_fetch(__objects, offset + 1); + motion.pre.z = kernel_tex_fetch(__objects, offset + 2); + motion.pre.w = kernel_tex_fetch(__objects, offset + 3); + + motion.mid.x = kernel_tex_fetch(__objects, offset + 4); + motion.mid.y = kernel_tex_fetch(__objects, offset + 5); + motion.mid.z = kernel_tex_fetch(__objects, offset + 6); + motion.mid.w = kernel_tex_fetch(__objects, offset + 7); + + motion.post.x = kernel_tex_fetch(__objects, offset + 8); + motion.post.y = kernel_tex_fetch(__objects, offset + 9); + motion.post.z = kernel_tex_fetch(__objects, offset + 10); + motion.post.w = kernel_tex_fetch(__objects, offset + 11); + Transform tfm; - - int object_flag = kernel_tex_fetch(__object_flag, object); - - /* if we do motion blur */ - if(object_flag & SD_OBJECT_MOTION) { - /* fetch motion transforms */ - MotionTransform motion; - - int offset = object*OBJECT_SIZE + (int)OBJECT_TRANSFORM_MOTION_PRE; - - motion.pre.x = kernel_tex_fetch(__objects, offset + 0); - motion.pre.y = kernel_tex_fetch(__objects, offset + 1); - motion.pre.z = kernel_tex_fetch(__objects, offset + 2); - motion.pre.w = kernel_tex_fetch(__objects, offset + 3); - - motion.mid.x = kernel_tex_fetch(__objects, offset + 4); - motion.mid.y = kernel_tex_fetch(__objects, offset + 5); - motion.mid.z = kernel_tex_fetch(__objects, offset + 6); - motion.mid.w = kernel_tex_fetch(__objects, offset + 7); - - motion.post.x = kernel_tex_fetch(__objects, offset + 8); - motion.post.y = kernel_tex_fetch(__objects, offset + 9); - motion.post.z = kernel_tex_fetch(__objects, offset + 10); - motion.post.w = kernel_tex_fetch(__objects, offset + 11); - - transform_motion_interpolate(&tfm, &motion, time); - - /* invert */ - if(itfm) - *itfm = transform_quick_inverse(tfm); - } - else { - tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM); - - if(itfm) - *itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM); - } + transform_motion_interpolate(&tfm, &motion, time); return tfm; } + +__device_inline Transform object_fetch_transform_motion_test(KernelGlobals *kg, int object, float time, Transform *itfm) +{ + int object_flag = kernel_tex_fetch(__object_flag, object); + + if(object_flag & SD_OBJECT_MOTION) { + /* if we do motion blur */ + Transform tfm = object_fetch_transform_motion(kg, object, time); + + if(itfm) + *itfm = transform_quick_inverse(tfm); + + return tfm; + } + else { + Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM); + *itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM); + + return tfm; + } +} #endif __device_inline void object_position_transform(KernelGlobals *kg, ShaderData *sd, float3 *P) @@ -271,6 +275,5 @@ __device float3 particle_angular_velocity(KernelGlobals *kg, int particle) return make_float3(f3.z, f3.w, f4.x); } - CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h index 36f7122a380..814c32dfbd3 100644 --- a/intern/cycles/kernel/kernel_shader.h +++ b/intern/cycles/kernel/kernel_shader.h @@ -43,6 +43,22 @@ CCL_NAMESPACE_BEGIN /* ShaderData setup from incoming ray */ +#ifdef __OBJECT_MOTION__ +__device_noinline void shader_setup_object_transforms(KernelGlobals *kg, ShaderData *sd, float time) +{ + /* note that this is a separate non-inlined function to work around crash + * on CUDA sm 2.0, otherwise kernel execution crashes (compiler bug?) */ + if(sd->flag & SD_OBJECT_MOTION) { + sd->ob_tfm = object_fetch_transform_motion(kg, sd->object, time); + sd->ob_itfm= transform_quick_inverse(sd->ob_tfm); + } + else { + sd->ob_tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM); + sd->ob_itfm = object_fetch_transform(kg, sd->object, OBJECT_INVERSE_TRANSFORM); + } +} +#endif + __device_inline void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd, const Intersection *isect, const Ray *ray) { @@ -72,14 +88,7 @@ __device_inline void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd, /* matrices and time */ #ifdef __OBJECT_MOTION__ - if(sd->flag & SD_OBJECT_MOTION) { - sd->ob_tfm = object_fetch_transform_motion(kg, sd->object, ray->time, &sd->ob_itfm); - } - else { - sd->ob_tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM); - sd->ob_itfm = object_fetch_transform(kg, sd->object, OBJECT_INVERSE_TRANSFORM); - } - + shader_setup_object_transforms(kg, sd, ray->time); sd->time = ray->time; #endif @@ -181,13 +190,7 @@ __device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd, sd->flag |= kernel_tex_fetch(__object_flag, sd->object); #ifdef __OBJECT_MOTION__ - if(sd->flag & SD_OBJECT_MOTION) { - sd->ob_tfm = object_fetch_transform_motion(kg, sd->object, time, &sd->ob_itfm); - } - else { - sd->ob_tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM); - sd->ob_itfm = object_fetch_transform(kg, sd->object, OBJECT_INVERSE_TRANSFORM); - } + shader_setup_object_transforms(kg, sd, time); } sd->time = time; diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp index 0b87a530725..25b4d1f08cc 100644 --- a/intern/cycles/render/object.cpp +++ b/intern/cycles/render/object.cpp @@ -64,8 +64,8 @@ void Object::compute_bounds(bool motion_blur, float shuttertime) /* todo: this is really terrible. according to pbrt there is a better * way to find this iteratively, but did not find implementation yet * or try to implement myself */ - float start_t = 0.5f - shuttertime*0.5f; - float end_t = 0.5f - shuttertime*0.5f; + float start_t = 0.5f - shuttertime*0.25f; + float end_t = 0.5f + shuttertime*0.25f; for(float t = start_t; t < end_t; t += (1.0f/128.0f)*shuttertime) { Transform ttfm; From b2142d6533d740b00ac1578de67f4a8d8dc94121 Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Wed, 17 Oct 2012 22:58:18 +0000 Subject: [PATCH 295/347] Cycles: OSL compile fixes. --- intern/cycles/kernel/osl/osl_services.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/intern/cycles/kernel/osl/osl_services.cpp b/intern/cycles/kernel/osl/osl_services.cpp index 103acd61879..624d20bbd01 100644 --- a/intern/cycles/kernel/osl/osl_services.cpp +++ b/intern/cycles/kernel/osl/osl_services.cpp @@ -73,7 +73,7 @@ bool OSLRenderServices::get_matrix(OSL::Matrix44 &result, OSL::TransformationPtr if (object != ~0) { #ifdef __OBJECT_MOTION__ - Transform tfm = object_fetch_transform_motion(kg, object, time, NULL); + Transform tfm = object_fetch_transform_motion(kg, object, time); #else Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM); #endif @@ -99,7 +99,7 @@ bool OSLRenderServices::get_inverse_matrix(OSL::Matrix44 &result, OSL::Transform if (object != ~0) { #ifdef __OBJECT_MOTION__ Transform itfm; - object_fetch_transform_motion(kg, object, time, &itfm); + object_fetch_transform_motion(kg, object, time); #else Transform itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM); #endif From 9d260eedeb83776416981e2f3a8af9bb5605e1d2 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 17 Oct 2012 23:09:12 +0000 Subject: [PATCH 296/347] Fix #32904: strange pattern on subdivided cube with anistropic shader. Now tangents from generated coordinates are computed per pixel on the fly, avoids bad interpolation of singularities. --- intern/cycles/blender/blender_mesh.cpp | 73 +------------------------ intern/cycles/kernel/svm/bsdf_ward.h | 4 +- intern/cycles/kernel/svm/svm_geometry.h | 29 +++++++++- intern/cycles/render/nodes.cpp | 8 ++- 4 files changed, 37 insertions(+), 77 deletions(-) diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp index bbc9b00b0dc..7055cf981c7 100644 --- a/intern/cycles/blender/blender_mesh.cpp +++ b/intern/cycles/blender/blender_mesh.cpp @@ -33,22 +33,6 @@ CCL_NAMESPACE_BEGIN /* Find/Add */ -static float3 tangent_uv_from_generated(float3 P) -{ - float length = len(P); - - if(length == 0.0f) - return make_float3(0.0f, 0.0f, 0.0f); - - float u = 0.0f; - if(!(P.x == 0.0f && P.y == 0.0f)) - u = (1.0f - atan2f(P.x, P.y))/(2.0f*M_PI_F); - - float v = 1.0f - acosf(clamp(P.z/length, -1.0f, 1.0f))/M_PI_F; - - return make_float3(u, v, 0.0f); -} - static float3 tangent_from_triangle(float3 v0, float3 v1, float3 v2, float3 tx0, float3 tx1, float3 tx2) { float3 duv1 = tx2 - tx0; @@ -176,9 +160,7 @@ static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector< } /* create texcoord-based tangent attributes */ - bool need_tangent = mesh->need_attribute(scene, ATTR_STD_TANGENT); - - if(need_tangent) { + if(mesh->need_attribute(scene, ATTR_STD_TANGENT)) { BL::Mesh::tessface_uv_textures_iterator l; for(b_mesh.tessface_uv_textures.begin(l); l != b_mesh.tessface_uv_textures.end(); ++l) { @@ -233,15 +215,13 @@ static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector< /* normalize tangent vectors */ for(int i = 0; i < mesh->verts.size(); i++) tangents[i] = normalize(tangents[i]); - - need_tangent = false; } } /* create generated coordinates. todo: we should actually get the orco * coordinates from modifiers, for now we use texspace loc/size which * is available in the api. */ - if(mesh->need_attribute(scene, ATTR_STD_GENERATED) || need_tangent) { + if(mesh->need_attribute(scene, ATTR_STD_GENERATED)) { Attribute *attr = mesh->attributes.add(ATTR_STD_GENERATED); float3 loc = get_float3(b_mesh.texspace_location()); float3 size = get_float3(b_mesh.texspace_size()); @@ -257,55 +237,6 @@ static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector< for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v) generated[i++] = get_float3(v->co())*size - loc; - - /* if there is no UV map, we generated tangents from generated coordinates */ - if(need_tangent) { - Attribute *attr = mesh->attributes.add(ATTR_STD_TANGENT, ustring("Tangent")); - - /* compute average tangents per vertex */ - float3 *tangents = attr->data_float3(); - memset(tangents, 0, sizeof(float3)*mesh->verts.size()); - - size_t fi = 0; /* face index */ - for(b_mesh.tessfaces.begin(f); f != b_mesh.tessfaces.end(); ++fi, ++f) { - int4 vi = get_int4(f->vertices_raw()); - - float3 tx0 = tangent_uv_from_generated(generated[vi[0]]); - float3 tx1 = tangent_uv_from_generated(generated[vi[1]]); - float3 tx2 = tangent_uv_from_generated(generated[vi[2]]); - - float3 v0 = mesh->verts[vi[0]]; - float3 v1 = mesh->verts[vi[1]]; - float3 v2 = mesh->verts[vi[2]]; - - /* calculate tangent for the triangle; - * get vertex positions, and find change in position with respect - * to the texture coords in the first texture coord dimension */ - float3 tangent0 = tangent_from_triangle(v0, v1, v2, tx0, tx1, tx2); - - if(nverts[fi] == 4) { - /* quad tangent */ - float3 tx3 = tangent_uv_from_generated(generated[vi[3]]); - float3 v3 = mesh->verts[vi[3]]; - float3 tangent1 = tangent_from_triangle(v0, v2, v3, tx0, tx2, tx3); - - tangents[vi[0]] += 0.5f*(tangent0 + tangent1); - tangents[vi[1]] += tangent0; - tangents[vi[2]] += 0.5f*(tangent0 + tangent1); - tangents[vi[3]] += tangent1; - } - else { - /* triangle tangent */ - tangents[vi[0]] += tangent0; - tangents[vi[1]] += tangent0; - tangents[vi[2]] += tangent0; - } - } - - /* normalize tangent vectors */ - for(int i = 0; i < mesh->verts.size(); i++) - tangents[i] = normalize(tangents[i]); - } } } diff --git a/intern/cycles/kernel/svm/bsdf_ward.h b/intern/cycles/kernel/svm/bsdf_ward.h index 1407078b7bb..d167566bb75 100644 --- a/intern/cycles/kernel/svm/bsdf_ward.h +++ b/intern/cycles/kernel/svm/bsdf_ward.h @@ -39,8 +39,8 @@ CCL_NAMESPACE_BEGIN __device void bsdf_ward_setup(ShaderData *sd, ShaderClosure *sc, float ax, float ay) { - float m_ax = clamp(ax, 1e-5f, 1.0f); - float m_ay = clamp(ay, 1e-5f, 1.0f); + float m_ax = clamp(ax, 1e-4f, 1.0f); + float m_ay = clamp(ay, 1e-4f, 1.0f); sc->data0 = m_ax; sc->data1 = m_ay; diff --git a/intern/cycles/kernel/svm/svm_geometry.h b/intern/cycles/kernel/svm/svm_geometry.h index 30afd6322a7..e0f9e337652 100644 --- a/intern/cycles/kernel/svm/svm_geometry.h +++ b/intern/cycles/kernel/svm/svm_geometry.h @@ -20,6 +20,22 @@ CCL_NAMESPACE_BEGIN /* Geometry Node */ +__device_inline float3 svm_tangent_from_generated(float3 P) +{ + float length = len(P); + + if(length == 0.0f) + return make_float3(0.0f, 0.0f, 0.0f); + + float u = 0.0f; + if(!(P.x == 0.0f && P.y == 0.0f)) + u = (1.0f - atan2f(P.x, P.y))/(2.0f*M_PI_F); + + float v = 1.0f - acosf(clamp(P.z/length, -1.0f, 1.0f))/M_PI_F; + + return make_float3(u, v, 0.0f); +} + __device void svm_node_geometry(KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint out_offset) { float3 data; @@ -36,8 +52,17 @@ __device void svm_node_geometry(KernelGlobals *kg, ShaderData *sd, float *stack, data = triangle_attribute_float3(kg, sd, ATTR_ELEMENT_VERTEX, attr_offset, NULL, NULL); object_normal_transform(kg, sd, &data); } - else - data = normalize(sd->dPdu); + else { + attr_offset = find_attribute(kg, sd, ATTR_STD_GENERATED); + + if(attr_offset != ATTR_STD_NOT_FOUND) { + data = triangle_attribute_float3(kg, sd, ATTR_ELEMENT_VERTEX, attr_offset, NULL, NULL); + svm_tangent_from_generated(data); + object_normal_transform(kg, sd, &data); + } + else + data = normalize(sd->dPdu); + } } else data = normalize(sd->dPdu); diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index 6030c9f49c1..73c45665431 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -1246,8 +1246,10 @@ void WardBsdfNode::attributes(AttributeRequestSet *attributes) { ShaderInput *tangent_in = input("Tangent"); - if(!tangent_in->link) + if(!tangent_in->link) { attributes->add(ATTR_STD_TANGENT); + attributes->add(ATTR_STD_GENERATED); + } ShaderNode::attributes(attributes); } @@ -1595,8 +1597,10 @@ GeometryNode::GeometryNode() void GeometryNode::attributes(AttributeRequestSet *attributes) { - if(!output("Tangent")->links.empty()) + if(!output("Tangent")->links.empty()) { attributes->add(ATTR_STD_TANGENT); + attributes->add(ATTR_STD_GENERATED); + } ShaderNode::attributes(attributes); } From 812b17f306289e657c8df4daf303cc70e978be97 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 18 Oct 2012 04:51:37 +0000 Subject: [PATCH 297/347] style cleanup --- .../kernel/osl/nodes/node_brick_texture.osl | 4 ++-- intern/cycles/kernel/osl/nodes/node_fresnel.osl | 2 +- .../cycles/kernel/osl/nodes/node_glass_bsdf.osl | 2 +- .../kernel/osl/nodes/node_layer_weight.osl | 4 ++-- .../kernel/osl/nodes/node_object_info.osl | 17 ++++++++--------- .../kernel/osl/nodes/node_particle_info.osl | 17 ++++++++--------- 6 files changed, 22 insertions(+), 24 deletions(-) diff --git a/intern/cycles/kernel/osl/nodes/node_brick_texture.osl b/intern/cycles/kernel/osl/nodes/node_brick_texture.osl index d6af5a21ce1..478d9457001 100644 --- a/intern/cycles/kernel/osl/nodes/node_brick_texture.osl +++ b/intern/cycles/kernel/osl/nodes/node_brick_texture.osl @@ -41,8 +41,8 @@ float brick(point p, float mortar_size, float bias, rownum = (int)floor(p[1] / row_height); if (offset_frequency && squash_frequency) { - brick_width *= ((int)(rownum) % squash_frequency ) ? 1.0 : squash_amount; /* squash */ - offset = ((int)(rownum) % offset_frequency ) ? 0 : (brick_width * offset_amount); /* offset */ + brick_width *= ((int)(rownum) % squash_frequency) ? 1.0 : squash_amount; /* squash */ + offset = ((int)(rownum) % offset_frequency) ? 0 : (brick_width * offset_amount); /* offset */ } bricknum = (int)floor((p[0] + offset) / brick_width); diff --git a/intern/cycles/kernel/osl/nodes/node_fresnel.osl b/intern/cycles/kernel/osl/nodes/node_fresnel.osl index 172f4dd9843..e8d8e945f98 100644 --- a/intern/cycles/kernel/osl/nodes/node_fresnel.osl +++ b/intern/cycles/kernel/osl/nodes/node_fresnel.osl @@ -25,7 +25,7 @@ shader node_fresnel( output float Fac = 0.0) { float f = max(IOR, 1.0 + 1e-5); - float eta = backfacing()? 1.0 / f: f; + float eta = backfacing() ? 1.0 / f: f; Fac = fresnel_dielectric(I, Normal, eta); } diff --git a/intern/cycles/kernel/osl/nodes/node_glass_bsdf.osl b/intern/cycles/kernel/osl/nodes/node_glass_bsdf.osl index 8b069248a35..f3fcce572cf 100644 --- a/intern/cycles/kernel/osl/nodes/node_glass_bsdf.osl +++ b/intern/cycles/kernel/osl/nodes/node_glass_bsdf.osl @@ -28,7 +28,7 @@ shader node_glass_bsdf( output closure color BSDF = diffuse(Normal)) { float f = max(IOR, 1.0 + 1e-5); - float eta = backfacing()? 1.0 / f: f; + float eta = backfacing() ? 1.0 / f: f; float Fr = fresnel_dielectric(I, Normal, eta); if (distribution == "Sharp") diff --git a/intern/cycles/kernel/osl/nodes/node_layer_weight.osl b/intern/cycles/kernel/osl/nodes/node_layer_weight.osl index ea25d0c0e02..dc3eb81d712 100644 --- a/intern/cycles/kernel/osl/nodes/node_layer_weight.osl +++ b/intern/cycles/kernel/osl/nodes/node_layer_weight.osl @@ -29,7 +29,7 @@ shader node_layer_weight( /* Fresnel */ float eta = max(1.0 - Blend, 1e-5); - eta = backfacing()? eta: 1.0 / eta; + eta = backfacing() ? eta : 1.0 / eta; Fresnel = fresnel_dielectric(I, Normal, eta); /* Facing */ @@ -37,7 +37,7 @@ shader node_layer_weight( if (blend != 0.5) { blend = clamp(blend, 0.0, 1.0); - blend = (blend < 0.5)? 2.0 * blend: 0.5 / (1.0 - blend); + blend = (blend < 0.5) ? 2.0 * blend : 0.5 / (1.0 - blend); Facing = pow(Facing, blend); } diff --git a/intern/cycles/kernel/osl/nodes/node_object_info.osl b/intern/cycles/kernel/osl/nodes/node_object_info.osl index 21e50d8a43e..0d503258179 100644 --- a/intern/cycles/kernel/osl/nodes/node_object_info.osl +++ b/intern/cycles/kernel/osl/nodes/node_object_info.osl @@ -19,15 +19,14 @@ #include "stdosl.h" shader node_object_info( - output point Location = point(0.0, 0.0, 0.0), - output float ObjectIndex = 0.0, - output float MaterialIndex = 0.0, - output float Random = 0.0 - ) + output point Location = point(0.0, 0.0, 0.0), + output float ObjectIndex = 0.0, + output float MaterialIndex = 0.0, + output float Random = 0.0) { - getattribute("std::object_location", Location); - getattribute("std::object_index", ObjectIndex); - getattribute("std::material_index", MaterialIndex); - getattribute("std::object_random", Random); + getattribute("std::object_location", Location); + getattribute("std::object_index", ObjectIndex); + getattribute("std::material_index", MaterialIndex); + getattribute("std::object_random", Random); } diff --git a/intern/cycles/kernel/osl/nodes/node_particle_info.osl b/intern/cycles/kernel/osl/nodes/node_particle_info.osl index aadc2812865..ba51ccbd953 100644 --- a/intern/cycles/kernel/osl/nodes/node_particle_info.osl +++ b/intern/cycles/kernel/osl/nodes/node_particle_info.osl @@ -25,15 +25,14 @@ shader node_particle_info( output point Location = point(0.0, 0.0, 0.0), output float Size = 0.0, output vector Velocity = point(0.0, 0.0, 0.0), - output vector AngularVelocity = point(0.0, 0.0, 0.0) - ) + output vector AngularVelocity = point(0.0, 0.0, 0.0)) { - getattribute("std::particle_index", Index); - getattribute("std::particle_age", Age); - getattribute("std::particle_lifetime", Lifetime); - getattribute("std::particle_location", Location); - getattribute("std::particle_size", Size); - getattribute("std::particle_velocity", Velocity); - getattribute("std::particle_angular_velocity", AngularVelocity); + getattribute("std::particle_index", Index); + getattribute("std::particle_age", Age); + getattribute("std::particle_lifetime", Lifetime); + getattribute("std::particle_location", Location); + getattribute("std::particle_size", Size); + getattribute("std::particle_velocity", Velocity); + getattribute("std::particle_angular_velocity", AngularVelocity); } From 3086300149464dae8f419cd2066afb5ffd34af56 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 18 Oct 2012 09:48:51 +0000 Subject: [PATCH 298/347] Fix #32896: No compositor tree update with image input color space change --- source/blender/blenkernel/intern/movieclip.c | 12 ++++++++++++ source/blender/editors/space_node/space_node.c | 9 +++++++++ source/blender/makesrna/intern/rna_color.c | 4 ++++ 3 files changed, 25 insertions(+) diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c index 6f1c8d952de..4bd6676608e 100644 --- a/source/blender/blenkernel/intern/movieclip.c +++ b/source/blender/blenkernel/intern/movieclip.c @@ -1091,6 +1091,18 @@ void BKE_movieclip_reload(MovieClip *clip) movieclip_load_get_szie(clip); movieclip_calc_length(clip); + + /* same as for image update -- don't use notifiers because they are not 100% sure to succeeded + * (node trees which are not currently visible wouldn't be refreshed) + */ + { + Scene *scene; + for (scene = G.main->scene.first; scene; scene = scene->id.next) { + if (scene->nodetree) { + nodeUpdateID(scene->nodetree, &clip->id); + } + } + } } void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClipScopes *scopes) diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c index b70d66f60b4..76d1357a83c 100644 --- a/source/blender/editors/space_node/space_node.c +++ b/source/blender/editors/space_node/space_node.c @@ -254,6 +254,15 @@ static void node_area_listener(ScrArea *sa, wmNotifier *wmn) } } break; + + case NC_MOVIECLIP: + if (wmn->action == NA_EDITED) { + if (type == NTREE_COMPOSIT) { + if (nodeUpdateID(snode->nodetree, wmn->reference)) + ED_area_tag_refresh(sa); + } + } + break; } } diff --git a/source/blender/makesrna/intern/rna_color.c b/source/blender/makesrna/intern/rna_color.c index 7fb4a1d3839..1ba2fc1ee7e 100644 --- a/source/blender/makesrna/intern/rna_color.c +++ b/source/blender/makesrna/intern/rna_color.c @@ -475,13 +475,17 @@ static void rna_ColorManagedColorspaceSettings_reload_update(Main *UNUSED(bmain) Image *ima = (Image *) id; BKE_image_signal(ima, NULL, IMA_SIGNAL_RELOAD); + WM_main_add_notifier(NC_IMAGE | ND_DISPLAY, &ima->id); + WM_main_add_notifier(NC_IMAGE | NA_EDITED, &ima->id); } else if (GS(id->name) == ID_MC) { MovieClip *clip = (MovieClip *) id; BKE_movieclip_reload(clip); + WM_main_add_notifier(NC_MOVIECLIP | ND_DISPLAY, &clip->id); + WM_main_add_notifier(NC_MOVIECLIP | NA_EDITED, &clip->id); } } From a4724a2dd8f884fc3beaee4f49e33093069c1a35 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 18 Oct 2012 10:27:09 +0000 Subject: [PATCH 299/347] Fix #32905: Crash with Levels node when no input is connected. --- .../compositor/nodes/COM_ViewLevelsNode.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/source/blender/compositor/nodes/COM_ViewLevelsNode.cpp b/source/blender/compositor/nodes/COM_ViewLevelsNode.cpp index 6bb873e0dec..a515bfc7f47 100644 --- a/source/blender/compositor/nodes/COM_ViewLevelsNode.cpp +++ b/source/blender/compositor/nodes/COM_ViewLevelsNode.cpp @@ -24,6 +24,7 @@ #include "COM_ExecutionSystem.h" #include "COM_CalculateMeanOperation.h" #include "COM_CalculateStandardDeviationOperation.h" +#include "COM_SetValueOperation.h" ViewLevelsNode::ViewLevelsNode(bNode *editorNode) : Node(editorNode) { @@ -64,5 +65,18 @@ void ViewLevelsNode::convertToOperations(ExecutionSystem *graph, CompositorConte graph->addOperation(operation); } } + else { + SetValueOperation *meanOutput = new SetValueOperation(); + SetValueOperation *stdDevOutput = new SetValueOperation(); + + meanOutput->setValue(0.0f); + stdDevOutput->setValue(0.0f); + + this->getOutputSocket(0)->relinkConnections(meanOutput->getOutputSocket()); + this->getOutputSocket(1)->relinkConnections(stdDevOutput->getOutputSocket()); + + graph->addOperation(meanOutput); + graph->addOperation(stdDevOutput); + } } From dd56cc0cddc0372d0db0678c38e56364cd26a54c Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 18 Oct 2012 11:58:54 +0000 Subject: [PATCH 300/347] Fix #32913: missing cycles viewport update when toggling visibility in outliner with V and R shortcut keys. --- source/blender/editors/space_outliner/outliner_edit.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c index 2ec23091019..fbd07c73b12 100644 --- a/source/blender/editors/space_outliner/outliner_edit.c +++ b/source/blender/editors/space_outliner/outliner_edit.c @@ -368,12 +368,14 @@ void group_toggle_visibility_cb(bContext *UNUSED(C), Scene *scene, TreeElement * static int outliner_toggle_visibility_exec(bContext *C, wmOperator *UNUSED(op)) { + Main *bmain = CTX_data_main(C); SpaceOops *soops = CTX_wm_space_outliner(C); Scene *scene = CTX_data_scene(C); ARegion *ar = CTX_wm_region(C); outliner_do_object_operation(C, scene, soops, &soops->tree, object_toggle_visibility_cb); + DAG_id_type_tag(bmain, ID_OB); WM_event_add_notifier(C, NC_SCENE | ND_OB_VISIBLE, scene); ED_region_tag_redraw(ar); @@ -464,11 +466,13 @@ void group_toggle_renderability_cb(bContext *UNUSED(C), Scene *scene, TreeElemen static int outliner_toggle_renderability_exec(bContext *C, wmOperator *UNUSED(op)) { + Main *bmain = CTX_data_main(C); SpaceOops *soops = CTX_wm_space_outliner(C); Scene *scene = CTX_data_scene(C); outliner_do_object_operation(C, scene, soops, &soops->tree, object_toggle_renderability_cb); + DAG_id_type_tag(bmain, ID_OB); WM_event_add_notifier(C, NC_SCENE | ND_OB_RENDER, scene); return OPERATOR_FINISHED; From b3c605e13923b372b2ff18b5970818e2aaae470a Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 18 Oct 2012 12:29:22 +0000 Subject: [PATCH 301/347] Mask editor: create new mask when trying to create new vertex without active mask set --- source/blender/editors/mask/mask_add.c | 8 +++++++- source/blender/editors/mask/mask_intern.h | 3 +++ source/blender/editors/mask/mask_ops.c | 16 ++++++++++++---- 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/source/blender/editors/mask/mask_add.c b/source/blender/editors/mask/mask_add.c index c929436bc82..e43c8a2b53b 100644 --- a/source/blender/editors/mask/mask_add.c +++ b/source/blender/editors/mask/mask_add.c @@ -46,6 +46,7 @@ #include "WM_types.h" #include "ED_mask.h" /* own include */ +#include "ED_screen.h" #include "RNA_access.h" #include "RNA_define.h" @@ -562,6 +563,11 @@ static int add_vertex_exec(bContext *C, wmOperator *op) float co[2]; + if (mask == NULL) { + /* if there's no active mask, create one */ + mask = ED_mask_new(C, NULL); + } + masklay = BKE_mask_layer_active(mask); if (masklay && masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { @@ -647,7 +653,7 @@ void MASK_OT_add_vertex(wmOperatorType *ot) /* api callbacks */ ot->exec = add_vertex_exec; ot->invoke = add_vertex_invoke; - ot->poll = ED_maskedit_mask_poll; + ot->poll = ED_operator_mask; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; diff --git a/source/blender/editors/mask/mask_intern.h b/source/blender/editors/mask/mask_intern.h index ffd4afca182..fcfcfb237e9 100644 --- a/source/blender/editors/mask/mask_intern.h +++ b/source/blender/editors/mask/mask_intern.h @@ -33,6 +33,7 @@ #define __MASK_INTERN_H__ struct bContext; +struct Mask; struct wmEvent; struct wmOperatorType; @@ -43,6 +44,8 @@ void MASK_OT_add_vertex(struct wmOperatorType *ot); void MASK_OT_add_feather_vertex(struct wmOperatorType *ot); /* mask_ops.c */ +struct Mask *ED_mask_new(struct bContext *C, const char *name); + void MASK_OT_new(struct wmOperatorType *ot); void MASK_OT_layer_new(struct wmOperatorType *ot); void MASK_OT_layer_remove(struct wmOperatorType *ot); diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c index bea6b153d20..35f85f3faee 100644 --- a/source/blender/editors/mask/mask_ops.c +++ b/source/blender/editors/mask/mask_ops.c @@ -258,13 +258,10 @@ int ED_mask_feather_find_nearest(const bContext *C, Mask *mask, float normal_co[ /******************** create new mask *********************/ -static int mask_new_exec(bContext *C, wmOperator *op) +Mask *ED_mask_new(bContext *C, const char *name) { ScrArea *sa = CTX_wm_area(C); Mask *mask; - char name[MAX_ID_NAME - 2]; - - RNA_string_get(op->ptr, "name", name); mask = BKE_mask_new(name); @@ -290,6 +287,17 @@ static int mask_new_exec(bContext *C, wmOperator *op) } } + return mask; +} + +static int mask_new_exec(bContext *C, wmOperator *op) +{ + char name[MAX_ID_NAME - 2]; + + RNA_string_get(op->ptr, "name", name); + + ED_mask_new(C, name); + return OPERATOR_FINISHED; } From f7a584b841dc4fe5f15254adaa5d12a7473465ce Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 18 Oct 2012 12:37:51 +0000 Subject: [PATCH 302/347] Fix #32903: bring cycles glsl up to date with latest changes. --- .../blender/gpu/shaders/gpu_shader_material.glsl | 14 ++++++++++---- .../shader/nodes/node_shader_bsdf_anisotropic.c | 5 ++++- .../nodes/shader/nodes/node_shader_bsdf_diffuse.c | 5 ++++- .../nodes/shader/nodes/node_shader_bsdf_glass.c | 5 ++++- .../nodes/shader/nodes/node_shader_bsdf_glossy.c | 6 ++++-- .../shader/nodes/node_shader_bsdf_translucent.c | 5 ++++- .../nodes/shader/nodes/node_shader_bsdf_velvet.c | 5 ++++- .../blender/nodes/shader/nodes/node_shader_bump.c | 5 +++++ 8 files changed, 39 insertions(+), 11 deletions(-) diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl index 81c3cab97d4..716ffc2b254 100644 --- a/source/blender/gpu/shaders/gpu_shader_material.glsl +++ b/source/blender/gpu/shaders/gpu_shader_material.glsl @@ -1992,7 +1992,7 @@ void node_bsdf_diffuse(vec4 color, float roughness, vec3 N, out vec4 result) result = vec4(L*color.rgb, 1.0); } -void node_bsdf_glossy(vec4 color, float roughness, vec3 N, vec3 I, out vec4 result) +void node_bsdf_glossy(vec4 color, float roughness, vec3 N, out vec4 result) { /* ambient light */ vec3 L = vec3(0.2); @@ -2013,12 +2013,12 @@ void node_bsdf_glossy(vec4 color, float roughness, vec3 N, vec3 I, out vec4 resu result = vec4(L*color.rgb, 1.0); } -void node_bsdf_anisotropic(vec4 color, float roughnessU, float roughnessV, vec3 N, vec3 I, out vec4 result) +void node_bsdf_anisotropic(vec4 color, float roughnessU, float roughnessV, vec3 N, vec3 T, out vec4 result) { node_bsdf_diffuse(color, 0.0, N, result); } -void node_bsdf_glass(vec4 color, float roughness, float ior, vec3 N, vec3 I, out vec4 result) +void node_bsdf_glass(vec4 color, float roughness, float ior, vec3 N, out vec4 result) { node_bsdf_diffuse(color, 0.0, N, result); } @@ -2195,7 +2195,8 @@ void node_light_path( out float is_glossy_ray, out float is_singular_ray, out float is_reflection_ray, - out float is_transmission_ray) + out float is_transmission_ray, + out float ray_length) { is_camera_ray = 1.0; is_shadow_ray = 0.0; @@ -2204,6 +2205,7 @@ void node_light_path( is_singular_ray = 0.0; is_reflection_ray = 0.0; is_transmission_ray = 0.0; + ray_length = 1.0; } void node_light_falloff(float strength, float tsmooth, out float quadratic, out float linear, out float constant) @@ -2221,6 +2223,10 @@ void node_object_info(out vec3 location, out float object_index, out float mater random = 0.0; } +void node_bump(float strength, float height, vec3 N, out vec3 result) +{ + result = N; +} /* output */ diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.c index 82db5553a87..4a7643f5771 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.c +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.c @@ -45,7 +45,10 @@ static bNodeSocketTemplate sh_node_bsdf_anisotropic_out[]= { static int node_shader_gpu_bsdf_anisotropic(GPUMaterial *mat, bNode *UNUSED(node), GPUNodeStack *in, GPUNodeStack *out) { - return GPU_stack_link(mat, "node_bsdf_anisotropic", in, out, GPU_builtin(GPU_VIEW_NORMAL), GPU_builtin(GPU_VIEW_POSITION)); + if(!in[3].link) + in[3].link = GPU_builtin(GPU_VIEW_NORMAL); + + return GPU_stack_link(mat, "node_bsdf_anisotropic", in, out); } /* node type definition */ diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_diffuse.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_diffuse.c index f9507d9a755..63ce637fd72 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_diffuse.c +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_diffuse.c @@ -43,7 +43,10 @@ static bNodeSocketTemplate sh_node_bsdf_diffuse_out[]= { static int node_shader_gpu_bsdf_diffuse(GPUMaterial *mat, bNode *UNUSED(node), GPUNodeStack *in, GPUNodeStack *out) { - return GPU_stack_link(mat, "node_bsdf_diffuse", in, out, GPU_builtin(GPU_VIEW_NORMAL)); + if(!in[2].link) + in[2].link = GPU_builtin(GPU_VIEW_NORMAL); + + return GPU_stack_link(mat, "node_bsdf_diffuse", in, out); } /* node type definition */ diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_glass.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_glass.c index 858301a052d..7b8b80ae8e2 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_glass.c +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_glass.c @@ -44,7 +44,10 @@ static bNodeSocketTemplate sh_node_bsdf_glass_out[]= { static int node_shader_gpu_bsdf_glass(GPUMaterial *mat, bNode *UNUSED(node), GPUNodeStack *in, GPUNodeStack *out) { - return GPU_stack_link(mat, "node_bsdf_glass", in, out, GPU_builtin(GPU_VIEW_NORMAL), GPU_builtin(GPU_VIEW_POSITION)); + if(!in[3].link) + in[3].link = GPU_builtin(GPU_VIEW_NORMAL); + + return GPU_stack_link(mat, "node_bsdf_glass", in, out); } /* node type definition */ diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.c index 30697d75eae..9f42e23ebb6 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.c +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.c @@ -43,8 +43,10 @@ static bNodeSocketTemplate sh_node_bsdf_glossy_out[]= { static int node_shader_gpu_bsdf_glossy(GPUMaterial *mat, bNode *UNUSED(node), GPUNodeStack *in, GPUNodeStack *out) { - /* todo: is incoming vector normalized? */ - return GPU_stack_link(mat, "node_bsdf_glossy", in, out, GPU_builtin(GPU_VIEW_NORMAL), GPU_builtin(GPU_VIEW_POSITION)); + if(!in[2].link) + in[2].link = GPU_builtin(GPU_VIEW_NORMAL); + + return GPU_stack_link(mat, "node_bsdf_glossy", in, out); } /* node type definition */ diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_translucent.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_translucent.c index 1023fd2f3fc..b3290411aee 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_translucent.c +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_translucent.c @@ -42,7 +42,10 @@ static bNodeSocketTemplate sh_node_bsdf_translucent_out[]= { static int node_shader_gpu_bsdf_translucent(GPUMaterial *mat, bNode *UNUSED(node), GPUNodeStack *in, GPUNodeStack *out) { - return GPU_stack_link(mat, "node_bsdf_translucent", in, out, GPU_builtin(GPU_VIEW_NORMAL)); + if(!in[1].link) + in[1].link = GPU_builtin(GPU_VIEW_NORMAL); + + return GPU_stack_link(mat, "node_bsdf_translucent", in, out); } /* node type definition */ diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_velvet.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_velvet.c index c1483d41c94..97bc37a84c9 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_velvet.c +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_velvet.c @@ -43,7 +43,10 @@ static bNodeSocketTemplate sh_node_bsdf_velvet_out[]= { static int node_shader_gpu_bsdf_velvet(GPUMaterial *mat, bNode *UNUSED(node), GPUNodeStack *in, GPUNodeStack *out) { - return GPU_stack_link(mat, "node_bsdf_velvet", in, out, GPU_builtin(GPU_VIEW_NORMAL)); + if(!in[2].link) + in[2].link = GPU_builtin(GPU_VIEW_NORMAL); + + return GPU_stack_link(mat, "node_bsdf_velvet", in, out); } /* node type definition */ diff --git a/source/blender/nodes/shader/nodes/node_shader_bump.c b/source/blender/nodes/shader/nodes/node_shader_bump.c index fc612ccc65b..9fd5f495c3b 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bump.c +++ b/source/blender/nodes/shader/nodes/node_shader_bump.c @@ -46,6 +46,10 @@ static bNodeSocketTemplate sh_node_bump_out[]= { { -1, 0, "" } }; +static int gpu_shader_bump(GPUMaterial *mat, bNode *node, GPUNodeStack *in, GPUNodeStack *out) +{ + return GPU_stack_link(mat, "node_bump", in, out, GPU_builtin(GPU_VIEW_NORMAL)); +} /* node type definition */ void register_node_type_sh_bump(bNodeTreeType *ttype) @@ -58,6 +62,7 @@ void register_node_type_sh_bump(bNodeTreeType *ttype) node_type_size(&ntype, 150, 60, 200); node_type_storage(&ntype, "BumpNode", node_free_standard_storage, node_copy_standard_storage); node_type_exec(&ntype, NULL); + node_type_gpu(&ntype, gpu_shader_bump); nodeRegisterType(ttype, &ntype); } From 95963289c81698815d0616850b5f23f6e9f9d852 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 18 Oct 2012 12:45:27 +0000 Subject: [PATCH 303/347] More fixes related to #32900, motion blur with cuda sm 2.0 still disabled. --- intern/cycles/kernel/kernel_bvh.h | 12 +++++++++--- intern/cycles/kernel/kernel_emission.h | 4 ++++ intern/cycles/kernel/kernel_types.h | 4 +++- intern/cycles/kernel/osl/osl_services.cpp | 2 +- intern/cycles/render/camera.cpp | 1 - 5 files changed, 17 insertions(+), 6 deletions(-) diff --git a/intern/cycles/kernel/kernel_bvh.h b/intern/cycles/kernel/kernel_bvh.h index d033fb1d145..e3c8b796e9c 100644 --- a/intern/cycles/kernel/kernel_bvh.h +++ b/intern/cycles/kernel/kernel_bvh.h @@ -443,13 +443,19 @@ __device_inline bool bvh_intersect_motion(KernelGlobals *kg, const Ray *ray, con __device_inline bool scene_intersect(KernelGlobals *kg, const Ray *ray, const uint visibility, Intersection *isect) { - /* todo: fix cuda sm 2.0 motion blur */ -#if defined(__OBJECT_MOTION__) && (!defined(__KERNEL_CUDA) || (__CUDA_ARCH__ >= 210)) +#ifdef __OBJECT_MOTION__ +#if !defined(__KERNEL_CUDA__) || (__CUDA_ARCH__ >= 210) if(kernel_data.bvh.have_motion) return bvh_intersect_motion(kg, ray, visibility, isect); else -#endif return bvh_intersect(kg, ray, visibility, isect); +#else + /* todo: fix cuda sm 2.0 motion blur */ + return bvh_intersect(kg, ray, visibility, isect); +#endif +#else + return bvh_intersect(kg, ray, visibility, isect); +#endif } __device_inline float3 ray_offset(float3 P, float3 Ng) diff --git a/intern/cycles/kernel/kernel_emission.h b/intern/cycles/kernel/kernel_emission.h index 75b6df5f08f..6d650a0158d 100644 --- a/intern/cycles/kernel/kernel_emission.h +++ b/intern/cycles/kernel/kernel_emission.h @@ -32,6 +32,10 @@ __device float3 direct_emissive_eval(KernelGlobals *kg, float rando, Ray ray; ray.D = ls->D; ray.P = ls->P; + ray.t = 1.0f; +#ifdef __OBJECT_MOTION__ + ray.time = time; +#endif ray.dP.dx = make_float3(0.0f, 0.0f, 0.0f); ray.dP.dy = make_float3(0.0f, 0.0f, 0.0f); #ifdef __CAMERA_MOTION__ diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index 4cf414091f5..c341269f4ca 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -514,7 +514,9 @@ typedef struct KernelCamera { /* more matrices */ Transform screentoworld; Transform rastertoworld; - Transform ndctoworld; + /* work around cuda sm 2.0 crash, this seems to + * cross some limit in combination with motion + * Transform ndctoworld; */ Transform worldtoscreen; Transform worldtoraster; Transform worldtondc; diff --git a/intern/cycles/kernel/osl/osl_services.cpp b/intern/cycles/kernel/osl/osl_services.cpp index 624d20bbd01..e8f7e966e92 100644 --- a/intern/cycles/kernel/osl/osl_services.cpp +++ b/intern/cycles/kernel/osl/osl_services.cpp @@ -224,7 +224,7 @@ bool OSLRenderServices::get_matrix(OSL::Matrix44 &result, ustring from) KernelGlobals *kg = kernel_globals; if (from == u_ndc) { - Transform tfm = transform_transpose(kernel_data.cam.ndctoworld); + Transform tfm = transform_transpose(transform_quick_inverse(kernel_data.cam.worldtondc)); result = TO_MATRIX44(tfm); return true; } diff --git a/intern/cycles/render/camera.cpp b/intern/cycles/render/camera.cpp index 7703d0cbc8e..649936bec04 100644 --- a/intern/cycles/render/camera.cpp +++ b/intern/cycles/render/camera.cpp @@ -162,7 +162,6 @@ void Camera::device_update(Device *device, DeviceScene *dscene, Scene *scene) /* store matrices */ kcam->screentoworld = screentoworld; kcam->rastertoworld = rastertoworld; - kcam->ndctoworld = ndctoworld; kcam->rastertocamera = rastertocamera; kcam->cameratoworld = cameratoworld; kcam->worldtoscreen = transform_inverse(screentoworld); From d396bf354607d4150b89f18f9a1560b2fc5a4ca2 Mon Sep 17 00:00:00 2001 From: Lukas Toenne Date: Thu, 18 Oct 2012 13:16:57 +0000 Subject: [PATCH 304/347] Fix for OSL compile errors. 1) object_fetch_transform_motion omits the per-object motion blur test (r51394), must use object_fetch_transform_motion_test. 2) KernelCamera.ndctoworld has been removed (r51402), do transform invert directly. --- intern/cycles/kernel/osl/osl_services.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/intern/cycles/kernel/osl/osl_services.cpp b/intern/cycles/kernel/osl/osl_services.cpp index e8f7e966e92..92dae998a64 100644 --- a/intern/cycles/kernel/osl/osl_services.cpp +++ b/intern/cycles/kernel/osl/osl_services.cpp @@ -73,7 +73,7 @@ bool OSLRenderServices::get_matrix(OSL::Matrix44 &result, OSL::TransformationPtr if (object != ~0) { #ifdef __OBJECT_MOTION__ - Transform tfm = object_fetch_transform_motion(kg, object, time); + Transform tfm = object_fetch_transform_motion_test(kg, object, time, NULL); #else Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM); #endif @@ -99,7 +99,7 @@ bool OSLRenderServices::get_inverse_matrix(OSL::Matrix44 &result, OSL::Transform if (object != ~0) { #ifdef __OBJECT_MOTION__ Transform itfm; - object_fetch_transform_motion(kg, object, time); + object_fetch_transform_motion_test(kg, object, time, &itfm); #else Transform itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM); #endif @@ -118,7 +118,7 @@ bool OSLRenderServices::get_matrix(OSL::Matrix44 &result, ustring from, float ti KernelGlobals *kg = kernel_globals; if (from == u_ndc) { - Transform tfm = transform_transpose(kernel_data.cam.ndctoworld); + Transform tfm = transform_transpose(transform_quick_inverse(kernel_data.cam.worldtondc)); result = TO_MATRIX44(tfm); return true; } From 82329ba1c3437909b18f007345bf00ceec792965 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 18 Oct 2012 13:18:11 +0000 Subject: [PATCH 305/347] Fix #32851: Mouse click coordinates when adding and selecting mask vertices on undistorted footage are off --- source/blender/editors/mask/mask_draw.c | 79 +++++++++++++++++++------ 1 file changed, 61 insertions(+), 18 deletions(-) diff --git a/source/blender/editors/mask/mask_draw.c b/source/blender/editors/mask/mask_draw.c index a60b771d179..490389c6d0c 100644 --- a/source/blender/editors/mask/mask_draw.c +++ b/source/blender/editors/mask/mask_draw.c @@ -20,6 +20,7 @@ * * * Contributor(s): Blender Foundation, + * Campbell Barton, * Sergey Sharybin * * ***** END GPL LICENSE BLOCK ***** @@ -41,7 +42,9 @@ #include "DNA_mask_types.h" #include "DNA_screen_types.h" #include "DNA_object_types.h" /* SELECT */ +#include "DNA_space_types.h" +#include "ED_clip.h" #include "ED_mask.h" /* own include */ #include "ED_space_api.h" #include "BIF_gl.h" @@ -120,13 +123,22 @@ static void draw_spline_parents(MaskLayer *UNUSED(masklay), MaskSpline *spline) } #endif +static void mask_point_undistort_pos(SpaceClip *sc, float r_co[2], float co[2]) +{ + BKE_mask_coord_to_movieclip(sc->clip, &sc->user, r_co, co); + ED_clip_point_undistorted_pos(sc, r_co, r_co); + BKE_mask_coord_from_movieclip(sc->clip, &sc->user, r_co, r_co); +} + /* return non-zero if spline is selected */ -static void draw_spline_points(MaskLayer *masklay, MaskSpline *spline, +static void draw_spline_points(const bContext *C, MaskLayer *masklay, MaskSpline *spline, const char UNUSED(draw_flag), const char draw_type) { const int is_spline_sel = (spline->flag & SELECT) && (masklay->restrictflag & MASK_RESTRICT_SELECT) == 0; unsigned char rgb_spline[4]; MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); + SpaceClip *sc = CTX_wm_space_clip(C); + int undistort = FALSE; int i, hsize, tot_feather_point; float (*feather_points)[2], (*fp)[2]; @@ -134,6 +146,9 @@ static void draw_spline_points(MaskLayer *masklay, MaskSpline *spline, if (!spline->tot_point) return; + if (sc) + undistort = sc->clip && sc->user.render_flag & MCLIP_PROXY_RENDER_UNDISTORT; + /* TODO, add this to sequence editor */ hsize = 4; /* UI_GetThemeValuef(TH_HANDLE_VERTEX_SIZE); */ @@ -151,8 +166,14 @@ static void draw_spline_points(MaskLayer *masklay, MaskSpline *spline, int j; for (j = 0; j < point->tot_uw + 1; j++) { + float feather_point[2]; int sel = FALSE; + copy_v2_v2(feather_point, *fp); + + if (undistort) + mask_point_undistort_pos(sc, feather_point, feather_point); + if (j == 0) { sel = MASKPOINT_ISSEL_ANY(point); } @@ -171,7 +192,7 @@ static void draw_spline_points(MaskLayer *masklay, MaskSpline *spline, } glBegin(GL_POINTS); - glVertex2fv(*fp); + glVertex2fv(feather_point); glEnd(); fp++; @@ -188,11 +209,17 @@ static void draw_spline_points(MaskLayer *masklay, MaskSpline *spline, BezTriple *bezt = &point_deform->bezt; float handle[2]; - float *vert = bezt->vec[1]; + float vert[2]; int has_handle = BKE_mask_point_has_handle(point); + copy_v2_v2(vert, bezt->vec[1]); BKE_mask_point_handle(point_deform, handle); + if (undistort) { + mask_point_undistort_pos(sc, vert, vert); + mask_point_undistort_pos(sc, handle, handle); + } + /* draw handle segment */ if (has_handle) { @@ -265,7 +292,7 @@ static void mask_color_active_tint(unsigned char r_rgb[4], const unsigned char r } } -static void mask_draw_curve_type(MaskSpline *spline, float (*points)[2], int tot_point, +static void mask_draw_curve_type(const bContext *C, MaskSpline *spline, float (*orig_points)[2], int tot_point, const short is_feather, const short is_smooth, const short is_active, const unsigned char rgb_spline[4], const char draw_type) { @@ -273,6 +300,22 @@ static void mask_draw_curve_type(MaskSpline *spline, float (*points)[2], int tot const unsigned char rgb_black[4] = {0x00, 0x00, 0x00, 0xff}; // const unsigned char rgb_white[4] = {0xff, 0xff, 0xff, 0xff}; unsigned char rgb_tmp[4]; + SpaceClip *sc = CTX_wm_space_clip(C); + float (*points)[2] = orig_points; + + if (sc) { + int undistort = sc->clip && sc->user.render_flag & MCLIP_PROXY_RENDER_UNDISTORT; + + if (undistort) { + int i; + + points = MEM_callocN(2 * tot_point * sizeof(float), "undistorthed mask curve"); + + for (i = 0; i < tot_point; i++) { + mask_point_undistort_pos(sc, points[i], orig_points[i]); + } + } + } glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(2, GL_FLOAT, 0, points); @@ -347,8 +390,6 @@ static void mask_draw_curve_type(MaskSpline *spline, float (*points)[2], int tot glVertexPointer(2, GL_FLOAT, 0, points); glDrawArrays(draw_method, 0, tot_point); - glDrawArrays(draw_method, 0, tot_point); - if (is_smooth == FALSE && is_feather) { glDisable(GL_BLEND); } @@ -358,9 +399,11 @@ static void mask_draw_curve_type(MaskSpline *spline, float (*points)[2], int tot glDisableClientState(GL_VERTEX_ARRAY); + if (points != orig_points) + MEM_freeN(points); } -static void draw_spline_curve(MaskLayer *masklay, MaskSpline *spline, +static void draw_spline_curve(const bContext *C, MaskLayer *masklay, MaskSpline *spline, const char draw_flag, const char draw_type, const short is_active, int width, int height) @@ -395,7 +438,7 @@ static void draw_spline_curve(MaskLayer *masklay, MaskSpline *spline, /* draw feather */ mask_spline_feather_color_get(masklay, spline, is_spline_sel, rgb_tmp); - mask_draw_curve_type(spline, feather_points, tot_feather_point, + mask_draw_curve_type(C, spline, feather_points, tot_feather_point, TRUE, is_smooth, is_active, rgb_tmp, draw_type); @@ -414,7 +457,7 @@ static void draw_spline_curve(MaskLayer *masklay, MaskSpline *spline, } /* same as above */ - mask_draw_curve_type(spline, feather_points, tot_feather_point, + mask_draw_curve_type(C, spline, feather_points, tot_feather_point, TRUE, is_smooth, is_active, rgb_tmp, draw_type); } @@ -423,7 +466,7 @@ static void draw_spline_curve(MaskLayer *masklay, MaskSpline *spline, /* draw main curve */ mask_spline_color_get(masklay, spline, is_spline_sel, rgb_tmp); - mask_draw_curve_type(spline, diff_points, tot_diff_point, + mask_draw_curve_type(C, spline, diff_points, tot_diff_point, FALSE, is_smooth, is_active, rgb_tmp, draw_type); MEM_freeN(diff_points); @@ -436,7 +479,7 @@ static void draw_spline_curve(MaskLayer *masklay, MaskSpline *spline, (void)draw_type; } -static void draw_masklays(Mask *mask, const char draw_flag, const char draw_type, +static void draw_masklays(const bContext *C, Mask *mask, const char draw_flag,const char draw_type, int width, int height) { MaskLayer *masklay; @@ -453,13 +496,13 @@ static void draw_masklays(Mask *mask, const char draw_flag, const char draw_type for (spline = masklay->splines.first; spline; spline = spline->next) { /* draw curve itself first... */ - draw_spline_curve(masklay, spline, draw_flag, draw_type, is_active, width, height); + draw_spline_curve(C, masklay, spline, draw_flag, draw_type, is_active, width, height); // draw_spline_parents(masklay, spline); if (!(masklay->restrictflag & MASK_RESTRICT_SELECT)) { /* ...and then handles over the curve so they're nicely visible */ - draw_spline_points(masklay, spline, draw_flag, draw_type); + draw_spline_points(C, masklay, spline, draw_flag, draw_type); } /* show undeform for testing */ @@ -467,9 +510,9 @@ static void draw_masklays(Mask *mask, const char draw_flag, const char draw_type void *back = spline->points_deform; spline->points_deform = NULL; - draw_spline_curve(masklay, spline, draw_flag, draw_type, is_active, width, height); + draw_spline_curve(C, masklay, spline, draw_flag, draw_type, is_active, width, height); // draw_spline_parents(masklay, spline); - draw_spline_points(masklay, spline, draw_flag, draw_type); + draw_spline_points(C, masklay, spline, draw_flag, draw_type); spline->points_deform = back; } } @@ -489,7 +532,7 @@ void ED_mask_draw(const bContext *C, ED_mask_get_size(sa, &width, &height); - draw_masklays(mask, draw_flag, draw_type, width, height); + draw_masklays(C, mask, draw_flag, draw_type, width, height); } /* sets up the opengl context. @@ -500,7 +543,7 @@ void ED_mask_draw_region(Mask *mask, ARegion *ar, const float aspx, const float aspy, const short do_scale_applied, const short do_post_draw, float stabmat[4][4], /* optional - only used by clip */ - const bContext *C /* optional - only used when do_post_draw is set */ + const bContext *C /* optional - only used when do_post_draw is set or called from clip editor */ ) { struct View2D *v2d = &ar->v2d; @@ -559,7 +602,7 @@ void ED_mask_draw_region(Mask *mask, ARegion *ar, } /* draw! */ - draw_masklays(mask, draw_flag, draw_type, width, height); + draw_masklays(C, mask, draw_flag, draw_type, width, height); if (do_post_draw) { ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW); From 92219991789557648bb187efa5823b941bdbfc90 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 18 Oct 2012 13:20:23 +0000 Subject: [PATCH 306/347] Mark unused variables. --- source/blender/nodes/shader/nodes/node_shader_bump.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/nodes/shader/nodes/node_shader_bump.c b/source/blender/nodes/shader/nodes/node_shader_bump.c index 9fd5f495c3b..315565e619b 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bump.c +++ b/source/blender/nodes/shader/nodes/node_shader_bump.c @@ -46,7 +46,7 @@ static bNodeSocketTemplate sh_node_bump_out[]= { { -1, 0, "" } }; -static int gpu_shader_bump(GPUMaterial *mat, bNode *node, GPUNodeStack *in, GPUNodeStack *out) +static int gpu_shader_bump(GPUMaterial *mat, bNode *UNUSED(node), GPUNodeStack *in, GPUNodeStack *out) { return GPU_stack_link(mat, "node_bump", in, out, GPU_builtin(GPU_VIEW_NORMAL)); } From b861f8c3f82110de414f30e401163d23ede738eb Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 18 Oct 2012 13:48:02 +0000 Subject: [PATCH 307/347] Cycles: suppress path to nvcc appearing in the console in cases cuda toolkit is installed to different place than /usr/local/cuda (i.e. happens when using cuda toolkit from repository) --- intern/cycles/util/util_cuda.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/intern/cycles/util/util_cuda.cpp b/intern/cycles/util/util_cuda.cpp index 2960022fd8d..2716f00e173 100644 --- a/intern/cycles/util/util_cuda.cpp +++ b/intern/cycles/util/util_cuda.cpp @@ -17,6 +17,7 @@ */ #include +#include #include "util_cuda.h" #include "util_debug.h" @@ -413,8 +414,18 @@ string cuCompilerPath() return nvcc; #ifndef _WIN32 - if(system("which nvcc") == 0) - return "nvcc"; + { + FILE *handle = popen("which nvcc", "r"); + if(handle) { + char buffer[4096] = {0}; + int len = fread(buffer, 1, sizeof(buffer) - 1, handle); + buffer[len] = '\0'; + pclose(handle); + + if(buffer[0]) + return "nvcc"; + } + } #endif return ""; From c4b46f119c0cf85c25b825e9989dc0d4748cb64d Mon Sep 17 00:00:00 2001 From: Miika Hamalainen Date: Thu, 18 Oct 2012 14:23:04 +0000 Subject: [PATCH 308/347] Fix: Smoke 3d viewport shading was sometimes calculated incorrectly when adaptive domain was enabled. --- source/blender/blenkernel/intern/smoke.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c index 0724ac2711f..c8d6ec73d28 100644 --- a/source/blender/blenkernel/intern/smoke.c +++ b/source/blender/blenkernel/intern/smoke.c @@ -2392,9 +2392,9 @@ static void smoke_calc_transparency(SmokeDomainSettings *sds, Scene *scene) /* convert light pos to sim cell space */ mul_m4_v3(sds->imat, light); - light[0] = (light[0] - sds->p0[0]) / sds->cell_size[0] - 0.5f; - light[1] = (light[1] - sds->p0[1]) / sds->cell_size[1] - 0.5f; - light[2] = (light[2] - sds->p0[2]) / sds->cell_size[2] - 0.5f; + light[0] = (light[0] - sds->p0[0]) / sds->cell_size[0] - 0.5f - (float)sds->res_min[0]; + light[1] = (light[1] - sds->p0[1]) / sds->cell_size[1] - 0.5f - (float)sds->res_min[1]; + light[2] = (light[2] - sds->p0[2]) / sds->cell_size[2] - 0.5f - (float)sds->res_min[2]; for (a = 0; a < size; a++) sds->shadow[a] = -1.0f; From 497ea5f306a802a3f7aaddd1300d29613eba64af Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 18 Oct 2012 15:00:32 +0000 Subject: [PATCH 309/347] Fix #32912: cycles crash with dead particles, actual crash was caused by an inconsistency in the particle system code, using <= and <. Also tightened up checks on cycles side to avoid other potential crashes. --- intern/cycles/blender/blender_object.cpp | 13 ++- intern/cycles/blender/blender_particles.cpp | 93 ++++++++------------- intern/cycles/blender/blender_sync.cpp | 1 - intern/cycles/blender/blender_sync.h | 1 - source/blender/blenkernel/intern/particle.c | 2 +- 5 files changed, 48 insertions(+), 62 deletions(-) diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp index 2c32c8ad83f..6de2b0f08fa 100644 --- a/intern/cycles/blender/blender_object.cpp +++ b/intern/cycles/blender/blender_object.cpp @@ -24,6 +24,7 @@ #include "object.h" #include "scene.h" #include "nodes.h" +#include "particles.h" #include "shader.h" #include "blender_sync.h" @@ -307,6 +308,7 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, int motion) mesh_map.pre_sync(); object_map.pre_sync(); mesh_synced.clear(); + particle_system_map.pre_sync(); } /* object loop */ @@ -362,11 +364,16 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, int motion) object_free_duplilist(*b_ob); } - /* check if we should render or hide particle emitter */ + + /* sync particles and check if we should render or hide particle emitter */ BL::Object::particle_systems_iterator b_psys; - for(b_ob->particle_systems.begin(b_psys); b_psys != b_ob->particle_systems.end(); ++b_psys) + for(b_ob->particle_systems.begin(b_psys); b_psys != b_ob->particle_systems.end(); ++b_psys) { + if(!motion) + sync_particles(*b_ob, *b_psys); + if(b_psys->settings().use_render_emitter()) hide = false; + } if(!hide) { /* object itself */ @@ -393,6 +400,8 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, int motion) scene->mesh_manager->tag_update(scene); if(object_map.post_sync()) scene->object_manager->tag_update(scene); + if(particle_system_map.post_sync()) + scene->particle_system_manager->tag_update(scene); mesh_synced.clear(); } } diff --git a/intern/cycles/blender/blender_particles.cpp b/intern/cycles/blender/blender_particles.cpp index f309960fc55..c4c6d2f79a3 100644 --- a/intern/cycles/blender/blender_particles.cpp +++ b/intern/cycles/blender/blender_particles.cpp @@ -51,7 +51,7 @@ bool BlenderSync::psys_need_update(BL::ParticleSystem b_psys) case BL::ParticleSettings::render_type_PATH: { /* for strand rendering */ BL::ID key = (BKE_object_is_modified(b_ob))? b_ob: b_ob.data(); Mesh *mesh = mesh_map.find(key); - if (mesh) { + if(mesh) { need_update |= mesh->need_attribute(scene, ATTR_STD_PARTICLE) && mesh->need_update; } break; @@ -60,10 +60,10 @@ bool BlenderSync::psys_need_update(BL::ParticleSystem b_psys) case BL::ParticleSettings::render_type_OBJECT: { BL::Object b_dupli_ob = b_psys.settings().dupli_object(); - if (b_dupli_ob) { + if(b_dupli_ob) { BL::ID key = (BKE_object_is_modified(b_dupli_ob))? b_dupli_ob: b_dupli_ob.data(); Mesh *mesh = mesh_map.find(key); - if (mesh) { + if(mesh) { need_update |= mesh->need_attribute(scene, ATTR_STD_PARTICLE) && mesh->need_update; } } @@ -72,12 +72,12 @@ bool BlenderSync::psys_need_update(BL::ParticleSystem b_psys) case BL::ParticleSettings::render_type_GROUP: { BL::Group b_dupli_group = b_psys.settings().dupli_group(); - if (b_dupli_group) { + if(b_dupli_group) { BL::Group::objects_iterator b_gob; for (b_dupli_group.objects.begin(b_gob); b_gob != b_dupli_group.objects.end(); ++b_gob) { BL::ID key = (BKE_object_is_modified(*b_gob))? *b_gob: b_gob->data(); Mesh *mesh = mesh_map.find(key); - if (mesh) { + if(mesh) { need_update |= mesh->need_attribute(scene, ATTR_STD_PARTICLE) && mesh->need_update; } } @@ -109,38 +109,43 @@ static bool use_particle_system(BL::ParticleSystem b_psys) return true; } -static bool use_particle(BL::Particle b_pa) +static bool use_particle(BL::Particle b_pa, bool preview, bool show_unborn, bool use_dead) { - return b_pa.is_exist() && b_pa.is_visible() && - (b_pa.alive_state()==BL::Particle::alive_state_ALIVE || b_pa.alive_state()==BL::Particle::alive_state_DYING); + return b_pa.is_exist() && (!preview || b_pa.is_visible()) && + (b_pa.alive_state() != BL::Particle::alive_state_UNBORN || show_unborn) && + (b_pa.alive_state() != BL::Particle::alive_state_DEAD || use_dead); } -static int psys_count_particles(BL::ParticleSystem b_psys) +static int psys_count_particles(BL::ParticleSystem b_psys, bool preview) { - int tot = 0; BL::ParticleSystem::particles_iterator b_pa; - for(b_psys.particles.begin(b_pa); b_pa != b_psys.particles.end(); ++b_pa) { - if(use_particle(*b_pa)) - ++tot; - } - return tot; + bool show_unborn = b_psys.settings().show_unborn(); + bool use_dead = b_psys.settings().use_dead(); + int num = 0; + + for(b_psys.particles.begin(b_pa); b_pa != b_psys.particles.end(); ++b_pa) + if(use_particle(*b_pa, preview, show_unborn, use_dead)) + ++num; + + return num; } int BlenderSync::object_count_particles(BL::Object b_ob) { - int tot = 0; BL::Object::particle_systems_iterator b_psys; - for(b_ob.particle_systems.begin(b_psys); b_psys != b_ob.particle_systems.end(); ++b_psys) { - if (use_particle_system(*b_psys)) - tot += psys_count_particles(*b_psys); - } - return tot; + int num = 0; + + for(b_ob.particle_systems.begin(b_psys); b_psys != b_ob.particle_systems.end(); ++b_psys) + if(use_particle_system(*b_psys)) + num += psys_count_particles(*b_psys, preview); + + return num; } void BlenderSync::sync_particles(BL::Object b_ob, BL::ParticleSystem b_psys) { /* depending on settings the psys may not even be rendered */ - if (!use_particle_system(b_psys)) + if(!use_particle_system(b_psys)) return; /* key to lookup particle system */ @@ -155,15 +160,19 @@ void BlenderSync::sync_particles(BL::Object b_ob, BL::ParticleSystem b_psys) bool need_update = psys_need_update(b_psys); - if (object_updated || need_update) { - int tot = psys_count_particles(b_psys); + if(object_updated || need_update) { + bool show_unborn = b_psys.settings().show_unborn(); + bool use_dead = b_psys.settings().use_dead(); + + int num = psys_count_particles(b_psys, preview); psys->particles.clear(); - psys->particles.reserve(tot); + psys->particles.reserve(num); - int index = 0; BL::ParticleSystem::particles_iterator b_pa; + int index = 0; + for(b_psys.particles.begin(b_pa); b_pa != b_psys.particles.end(); ++b_pa) { - if(use_particle(*b_pa)) { + if(use_particle(*b_pa, preview, show_unborn, use_dead)) { Particle pa; pa.index = index; @@ -185,34 +194,4 @@ void BlenderSync::sync_particles(BL::Object b_ob, BL::ParticleSystem b_psys) } } -void BlenderSync::sync_particle_systems() -{ - /* layer data */ - uint scene_layer = render_layer.scene_layer; - - particle_system_map.pre_sync(); - - /* object loop */ - BL::Scene::objects_iterator b_ob; - BL::Scene b_sce = b_scene; - - for(; b_sce; b_sce = b_sce.background_set()) { - for(b_sce.objects.begin(b_ob); b_ob != b_sce.objects.end(); ++b_ob) { - bool hide = (render_layer.use_viewport_visibility)? b_ob->hide(): b_ob->hide_render(); - uint ob_layer = get_layer(b_ob->layers(), b_ob->layers_local_view(), render_layer.use_localview, object_is_light(*b_ob)); - hide = hide || !(ob_layer & scene_layer); - - if(!hide) { - BL::Object::particle_systems_iterator b_psys; - for(b_ob->particle_systems.begin(b_psys); b_psys != b_ob->particle_systems.end(); ++b_psys) - sync_particles(*b_ob, *b_psys); - } - } - } - - /* handle removed data and modified pointers */ - if(particle_system_map.post_sync()) - scene->particle_system_manager->tag_update(scene); -} - CCL_NAMESPACE_END diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp index 6c63872333d..24a561116ec 100644 --- a/intern/cycles/blender/blender_sync.cpp +++ b/intern/cycles/blender/blender_sync.cpp @@ -142,7 +142,6 @@ void BlenderSync::sync_data(BL::SpaceView3D b_v3d, BL::Object b_override, const sync_film(); sync_shaders(); sync_objects(b_v3d); - sync_particle_systems(); sync_motion(b_v3d, b_override); } diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h index d7fcb014931..36cd5e684a7 100644 --- a/intern/cycles/blender/blender_sync.h +++ b/intern/cycles/blender/blender_sync.h @@ -77,7 +77,6 @@ private: void sync_world(); void sync_render_layers(BL::SpaceView3D b_v3d, const char *layer); void sync_shaders(); - void sync_particle_systems(); void sync_nodes(Shader *shader, BL::ShaderNodeTree b_ntree); Mesh *sync_mesh(BL::Object b_ob, bool object_updated); diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index cf5ea7e074f..1749ad18c9b 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -4320,7 +4320,7 @@ int psys_get_particle_state(ParticleSimulationData *sim, int p, ParticleKey *sta if (pa) { if (!always) { if ((cfra < pa->time && (part->flag & PART_UNBORN) == 0) || - (cfra > pa->dietime && (part->flag & PART_DIED) == 0)) + (cfra >= pa->dietime && (part->flag & PART_DIED) == 0)) { return 0; } From d3eb9dddd6b49c7977e9fb3cc39f5e621e51fa9f Mon Sep 17 00:00:00 2001 From: Lukas Toenne Date: Thu, 18 Oct 2012 15:54:24 +0000 Subject: [PATCH 310/347] Better fix for #32846. Instead of using time change or object recalc condition, set an explicit object flag to disable particle system modifier update during dupli list creation. This is more transparent and should prevent issues with hair path generation being skipped. --- source/blender/blenkernel/intern/DerivedMesh.c | 8 ++++++++ source/blender/makesdna/DNA_object_types.h | 1 + source/blender/modifiers/intern/MOD_particlesystem.c | 7 +------ 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 9aaeb4c8baf..30804518e1d 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -2249,8 +2249,16 @@ DerivedMesh *mesh_create_derived_view(Scene *scene, Object *ob, CustomDataMask d { DerivedMesh *final; + /* XXX hack + * psys modifier updates particle state when called during dupli-list generation, + * which can lead to wrong transforms. This disables particle system modifier execution. + */ + ob->transflag |= OB_NO_PSYS_UPDATE; + mesh_calc_modifiers(scene, ob, NULL, NULL, &final, 0, 1, 0, dataMask, -1, 0, 0); + ob->transflag &= ~OB_NO_PSYS_UPDATE; + return final; } diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index 3a8620fdaba..2fc04c4a5db 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -378,6 +378,7 @@ typedef struct DupliObject { #define OB_DUPLIPARTS 2048 #define OB_RENDER_DUPLI 4096 #define OB_NO_CONSTRAINTS 8192 /* runtime constraints disable */ +#define OB_NO_PSYS_UPDATE 16384 /* hack to work around particle issue */ /* (short) ipoflag */ /* XXX: many old flags for features removed due to incompatibility diff --git a/source/blender/modifiers/intern/MOD_particlesystem.c b/source/blender/modifiers/intern/MOD_particlesystem.c index c4db9375a4a..6d6c1361566 100644 --- a/source/blender/modifiers/intern/MOD_particlesystem.c +++ b/source/blender/modifiers/intern/MOD_particlesystem.c @@ -190,12 +190,7 @@ static void deformVerts(ModifierData *md, Object *ob, psmd->totdmface = psmd->dm->getNumTessFaces(psmd->dm); } - /* skip the particle update if no timestep is performed or initialization required. - * XXX this is a workaround for bug #32846, which is caused by modifier updates - * during dupli-list generation (in cycles). The dupli-list generation can temporarily change - * the ob->obmat matrix, which in turn leads to wrong particle states if used for reset ... - */ - if (psys->cfra != cfra || psys->recalc) { + if (!(ob->transflag & OB_NO_PSYS_UPDATE)) { psmd->flag &= ~eParticleSystemFlag_psys_updated; particle_system_update(md->scene, ob, psys); psmd->flag |= eParticleSystemFlag_psys_updated; From b8267a0dfba5f85cebc122377bac4d63c7af20b2 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Thu, 18 Oct 2012 16:25:58 +0000 Subject: [PATCH 311/347] More UI messages and BKE_reportf<->BKE_report fixes... --- .../bl_i18n_utils/spell_check_utils.py | 4 +- source/blender/editors/animation/drivers.c | 8 +-- source/blender/editors/animation/keyframing.c | 53 +++++++++++-------- source/blender/editors/animation/keyingsets.c | 18 +++---- source/blender/editors/mesh/mesh_data.c | 30 +++++------ source/blender/editors/mesh/meshtools.c | 6 +-- .../editors/physics/dynamicpaint_ops.c | 6 +-- .../blender/editors/space_node/node_group.c | 16 +++--- .../editors/space_outliner/outliner_edit.c | 2 +- 9 files changed, 76 insertions(+), 67 deletions(-) diff --git a/release/scripts/modules/bl_i18n_utils/spell_check_utils.py b/release/scripts/modules/bl_i18n_utils/spell_check_utils.py index ae463917f88..d8cb77cd364 100644 --- a/release/scripts/modules/bl_i18n_utils/spell_check_utils.py +++ b/release/scripts/modules/bl_i18n_utils/spell_check_utils.py @@ -161,7 +161,7 @@ dict_uimsgs = { "unreacted", "unregister", "unselected", - "unsubdivided", + "unsubdivided", "unsubdivide", "unshadowed", "unspill", "unstitchable", @@ -189,6 +189,7 @@ dict_uimsgs = { "selectability", "slurph", "stitchable", + "symmetrize", "trackability", "transmissivity", "rasterized", "rasterization", @@ -417,6 +418,7 @@ dict_uimsgs = { "dpi", "dvar", "dx", + "eo", "fh", "fov", "fft", diff --git a/source/blender/editors/animation/drivers.c b/source/blender/editors/animation/drivers.c index 672e11ac613..38f9119104b 100644 --- a/source/blender/editors/animation/drivers.c +++ b/source/blender/editors/animation/drivers.c @@ -147,7 +147,7 @@ short ANIM_add_driver(ReportList *reports, ID *id, const char rna_path[], int ar RNA_id_pointer_create(id, &id_ptr); if ((RNA_path_resolve(&id_ptr, rna_path, &ptr, &prop) == 0) || (prop == NULL)) { BKE_reportf(reports, RPT_ERROR, - "Could not add Driver, as RNA Path is invalid for the given ID (ID = %s, Path = %s)", + "Could not add driver, as RNA path is invalid for the given ID (ID = %s, path = %s)", id->name, rna_path); return 0; } @@ -310,7 +310,7 @@ short ANIM_copy_driver(ReportList *reports, ID *id, const char rna_path[], int a RNA_id_pointer_create(id, &id_ptr); if ((RNA_path_resolve(&id_ptr, rna_path, &ptr, &prop) == 0) || (prop == NULL)) { BKE_reportf(reports, RPT_ERROR, - "Could not find Driver to copy, as RNA Path is invalid for the given ID (ID = %s, Path = %s)", + "Could not find driver to copy, as RNA path is invalid for the given ID (ID = %s, path = %s)", id->name, rna_path); return 0; } @@ -357,14 +357,14 @@ short ANIM_paste_driver(ReportList *reports, ID *id, const char rna_path[], int RNA_id_pointer_create(id, &id_ptr); if ((RNA_path_resolve(&id_ptr, rna_path, &ptr, &prop) == 0) || (prop == NULL)) { BKE_reportf(reports, RPT_ERROR, - "Could not paste Driver, as RNA Path is invalid for the given ID (ID = %s, Path = %s)", + "Could not paste driver, as RNA path is invalid for the given ID (ID = %s, path = %s)", id->name, rna_path); return 0; } /* if the buffer is empty, cannot paste... */ if (channeldriver_copypaste_buf == NULL) { - BKE_report(reports, RPT_ERROR, "Paste Driver: No Driver to paste"); + BKE_report(reports, RPT_ERROR, "Paste driver: no driver to paste"); return 0; } diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c index 0454e88e320..f0c5f063e57 100644 --- a/source/blender/editors/animation/keyframing.c +++ b/source/blender/editors/animation/keyframing.c @@ -43,6 +43,8 @@ #include "BLI_dynstr.h" #include "BLI_utildefines.h" +#include "BLF_translation.h" + #include "DNA_anim_types.h" #include "DNA_armature_types.h" #include "DNA_constraint_types.h" @@ -787,14 +789,15 @@ short insert_keyframe_direct(ReportList *reports, PointerRNA ptr, PropertyRNA *p /* F-Curve not editable? */ if (fcurve_is_keyframable(fcu) == 0) { BKE_reportf(reports, RPT_ERROR, - "F-Curve with path = '%s' [%d] cannot be keyframed. Ensure that it is not locked or sampled. Also, try removing F-Modifiers", + "F-Curve with path = '%s' [%d] cannot be keyframed, ensure that it is not locked or sampled, " + "and try removing F-Modifiers", fcu->rna_path, fcu->array_index); return 0; } /* if no property given yet, try to validate from F-Curve info */ if ((ptr.id.data == NULL) && (ptr.data == NULL)) { - BKE_report(reports, RPT_ERROR, "No RNA-pointer available to retrieve values for keyframing from"); + BKE_report(reports, RPT_ERROR, "No RNA pointer available to retrieve values for keyframing from"); return 0; } if (prop == NULL) { @@ -803,10 +806,10 @@ short insert_keyframe_direct(ReportList *reports, PointerRNA ptr, PropertyRNA *p /* try to get property we should be affecting */ if ((RNA_path_resolve(&ptr, fcu->rna_path, &tmp_ptr, &prop) == 0) || (prop == NULL)) { /* property not found... */ - const char *idname = (ptr.id.data) ? ((ID *)ptr.id.data)->name : ""; + const char *idname = (ptr.id.data) ? ((ID *)ptr.id.data)->name : TIP_(""); BKE_reportf(reports, RPT_ERROR, - "Could not insert keyframe, as RNA Path is invalid for the given ID (ID = %s, Path = %s)", + "Could not insert keyframe, as RNA path is invalid for the given ID (ID = %s, path = %s)", idname, fcu->rna_path); return 0; } @@ -906,15 +909,15 @@ short insert_keyframe(ReportList *reports, ID *id, bAction *act, const char grou /* validate pointer first - exit if failure */ if (id == NULL) { - BKE_reportf(reports, RPT_ERROR, "No ID-block to insert keyframe in (Path = %s)", rna_path); + BKE_reportf(reports, RPT_ERROR, "No ID block to insert keyframe in (path = %s)", rna_path); return 0; } RNA_id_pointer_create(id, &id_ptr); if ((RNA_path_resolve(&id_ptr, rna_path, &ptr, &prop) == 0) || (prop == NULL)) { BKE_reportf(reports, RPT_ERROR, - "Could not insert keyframe, as RNA Path is invalid for the given ID (ID = %s, Path = %s)", - (id) ? id->name : "", rna_path); + "Could not insert keyframe, as RNA path is invalid for the given ID (ID = %s, path = %s)", + (id) ? id->name : TIP_(""), rna_path); return 0; } @@ -927,7 +930,7 @@ short insert_keyframe(ReportList *reports, ID *id, bAction *act, const char grou if (act == NULL) { BKE_reportf(reports, RPT_ERROR, - "Could not insert keyframe, as this type does not support animation data (ID = %s, Path = %s)", + "Could not insert keyframe, as this type does not support animation data (ID = %s, path = %s)", id->name, rna_path); return 0; } @@ -997,14 +1000,16 @@ short delete_keyframe(ReportList *reports, ID *id, bAction *act, const char grou /* sanity checks */ if (ELEM(NULL, id, adt)) { - BKE_report(reports, RPT_ERROR, "No ID-Block and/Or AnimData to delete keyframe from"); + BKE_report(reports, RPT_ERROR, "No ID block and/or AnimData to delete keyframe from"); return 0; } /* validate pointer first - exit if failure */ RNA_id_pointer_create(id, &id_ptr); if ((RNA_path_resolve(&id_ptr, rna_path, &ptr, &prop) == 0) || (prop == NULL)) { - BKE_reportf(reports, RPT_ERROR, "Could not delete keyframe, as RNA Path is invalid for the given ID (ID = %s, Path = %s)", id->name, rna_path); + BKE_reportf(reports, RPT_ERROR, + "Could not delete keyframe, as RNA path is invalid for the given ID (ID = %s, path = %s)", + id->name, rna_path); return 0; } @@ -1023,7 +1028,7 @@ short delete_keyframe(ReportList *reports, ID *id, bAction *act, const char grou cfra = BKE_nla_tweakedit_remap(adt, cfra, NLATIME_CONVERT_UNMAP); } else { - BKE_reportf(reports, RPT_ERROR, "No Action to delete keyframes from for ID = %s\n", id->name); + BKE_reportf(reports, RPT_ERROR, "No action to delete keyframes from for ID = %s\n", id->name); return 0; } } @@ -1096,14 +1101,16 @@ static short clear_keyframe(ReportList *reports, ID *id, bAction *act, const cha /* sanity checks */ if (ELEM(NULL, id, adt)) { - BKE_report(reports, RPT_ERROR, "No ID-Block and/Or AnimData to delete keyframe from"); + BKE_report(reports, RPT_ERROR, "No ID block and/or AnimData to delete keyframe from"); return 0; } /* validate pointer first - exit if failure */ RNA_id_pointer_create(id, &id_ptr); if ((RNA_path_resolve(&id_ptr, rna_path, &ptr, &prop) == 0) || (prop == NULL)) { - BKE_reportf(reports, RPT_ERROR, "Could not clear keyframe, as RNA Path is invalid for the given ID (ID = %s, Path = %s)", id->name, rna_path); + BKE_reportf(reports, RPT_ERROR, + "Could not clear keyframe, as RNA path is invalid for the given ID (ID = %s, path = %s)", + id->name, rna_path); return 0; } @@ -1119,7 +1126,7 @@ static short clear_keyframe(ReportList *reports, ID *id, bAction *act, const cha act = adt->action; } else { - BKE_reportf(reports, RPT_ERROR, "No Action to delete keyframes from for ID = %s\n", id->name); + BKE_reportf(reports, RPT_ERROR, "No action to delete keyframes from for ID = %s\n", id->name); return 0; } } @@ -1222,30 +1229,30 @@ static int insert_key_exec(bContext *C, wmOperator *op) /* report failures */ if (ks == NULL) { - BKE_report(op->reports, RPT_ERROR, "No active Keying Set"); + BKE_report(op->reports, RPT_ERROR, "No active keying set"); return OPERATOR_CANCELLED; } /* try to insert keyframes for the channels specified by KeyingSet */ success = ANIM_apply_keyingset(C, NULL, NULL, ks, MODIFYKEY_MODE_INSERT, cfra); if (G.debug & G_DEBUG) - BKE_reportf(op->reports, RPT_INFO, "KeyingSet '%s' - Successfully added %d Keyframes\n", ks->name, success); + BKE_reportf(op->reports, RPT_INFO, "Keying set '%s' - successfully added %d keyframes\n", ks->name, success); /* report failure or do updates? */ if (success == MODIFYKEY_INVALID_CONTEXT) { - BKE_report(op->reports, RPT_ERROR, "No suitable context info for active Keying Set"); + BKE_report(op->reports, RPT_ERROR, "No suitable context info for active keying set"); return OPERATOR_CANCELLED; } else if (success) { /* if the appropriate properties have been set, make a note that we've inserted something */ if (RNA_boolean_get(op->ptr, "confirm_success")) - BKE_reportf(op->reports, RPT_INFO, "Successfully added %d Keyframes for KeyingSet '%s'", success, ks->name); + BKE_reportf(op->reports, RPT_INFO, "Successfully added %d keyframes for keying set '%s'", success, ks->name); /* send notifiers that keyframes have been changed */ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL); } else - BKE_report(op->reports, RPT_WARNING, "Keying Set failed to insert any keyframes"); + BKE_report(op->reports, RPT_WARNING, "Keying set failed to insert any keyframes"); /* send updates */ DAG_ids_flush_update(bmain, 0); @@ -1389,19 +1396,19 @@ static int delete_key_exec(bContext *C, wmOperator *op) /* report failure or do updates? */ if (success == MODIFYKEY_INVALID_CONTEXT) { - BKE_report(op->reports, RPT_ERROR, "No suitable context info for active Keying Set"); + BKE_report(op->reports, RPT_ERROR, "No suitable context info for active keying set"); return OPERATOR_CANCELLED; } else if (success) { /* if the appropriate properties have been set, make a note that we've inserted something */ if (RNA_boolean_get(op->ptr, "confirm_success")) - BKE_reportf(op->reports, RPT_INFO, "Successfully removed %d Keyframes for KeyingSet '%s'", success, ks->name); + BKE_reportf(op->reports, RPT_INFO, "Successfully removed %d keyframes for keying set '%s'", success, ks->name); /* send notifiers that keyframes have been changed */ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL); } else - BKE_report(op->reports, RPT_WARNING, "Keying Set failed to remove any keyframes"); + BKE_report(op->reports, RPT_WARNING, "Keying set failed to remove any keyframes"); /* send updates */ DAG_ids_flush_update(bmain, 0); @@ -1626,7 +1633,7 @@ static int insert_key_button_exec(bContext *C, wmOperator *op) else { if (G.debug & G_DEBUG) printf("Button Insert-Key: no path to property\n"); - BKE_report(op->reports, RPT_WARNING, "Failed to resolve path to property. Try using a Keying Set instead"); + BKE_report(op->reports, RPT_WARNING, "Failed to resolve path to property, try using a keying set instead"); } } else if (G.debug & G_DEBUG) { diff --git a/source/blender/editors/animation/keyingsets.c b/source/blender/editors/animation/keyingsets.c index 04fd7f677b0..5844bd6708f 100644 --- a/source/blender/editors/animation/keyingsets.c +++ b/source/blender/editors/animation/keyingsets.c @@ -161,11 +161,11 @@ static int remove_active_keyingset_exec(bContext *C, wmOperator *op) * - return error if it doesn't exist */ if (scene->active_keyingset == 0) { - BKE_report(op->reports, RPT_ERROR, "No active Keying Set to remove"); + BKE_report(op->reports, RPT_ERROR, "No active keying set to remove"); return OPERATOR_CANCELLED; } else if (scene->active_keyingset < 0) { - BKE_report(op->reports, RPT_ERROR, "Cannot remove built in Keying Set"); + BKE_report(op->reports, RPT_ERROR, "Cannot remove built in keying set"); return OPERATOR_CANCELLED; } else @@ -209,7 +209,7 @@ static int add_empty_ks_path_exec(bContext *C, wmOperator *op) * - return error if it doesn't exist */ if (scene->active_keyingset == 0) { - BKE_report(op->reports, RPT_ERROR, "No active Keying Set to add empty path to"); + BKE_report(op->reports, RPT_ERROR, "No active keying set to add empty path to"); return OPERATOR_CANCELLED; } else @@ -258,12 +258,12 @@ static int remove_active_ks_path_exec(bContext *C, wmOperator *op) ks->active_path--; } else { - BKE_report(op->reports, RPT_ERROR, "No active Keying Set Path to remove"); + BKE_report(op->reports, RPT_ERROR, "No active keying set path to remove"); return OPERATOR_CANCELLED; } } else { - BKE_report(op->reports, RPT_ERROR, "No active Keying Set to remove a path from"); + BKE_report(op->reports, RPT_ERROR, "No active keying set to remove a path from"); return OPERATOR_CANCELLED; } @@ -322,7 +322,7 @@ static int add_keyingset_button_exec(bContext *C, wmOperator *op) scene->active_keyingset = BLI_countlist(&scene->keyingsets); } else if (scene->active_keyingset < 0) { - BKE_report(op->reports, RPT_ERROR, "Cannot add property to built in Keying Set"); + BKE_report(op->reports, RPT_ERROR, "Cannot add property to built in keying set"); return OPERATOR_CANCELLED; } else @@ -404,11 +404,11 @@ static int remove_keyingset_button_exec(bContext *C, wmOperator *op) * - return error if it doesn't exist */ if (scene->active_keyingset == 0) { - BKE_report(op->reports, RPT_ERROR, "No active Keying Set to remove property from"); + BKE_report(op->reports, RPT_ERROR, "No active keying set to remove property from"); return OPERATOR_CANCELLED; } else if (scene->active_keyingset < 0) { - BKE_report(op->reports, RPT_ERROR, "Cannot remove property from built in Keying Set"); + BKE_report(op->reports, RPT_ERROR, "Cannot remove property from built in keying set"); return OPERATOR_CANCELLED; } else @@ -947,7 +947,7 @@ int ANIM_apply_keyingset(bContext *C, ListBase *dsources, bAction *act, KeyingSe /* skip path if no ID pointer is specified */ if (ksp->id == NULL) { BKE_reportf(reports, RPT_WARNING, - "Skipping path in Keying Set, as it has no ID (KS = '%s', Path = '%s'[%d])", + "Skipping path in keying set, as it has no ID (KS = '%s', path = '%s'[%d])", ks->name, ksp->rna_path, ksp->array_index); continue; } diff --git a/source/blender/editors/mesh/mesh_data.c b/source/blender/editors/mesh/mesh_data.c index c0ab7826fcf..4adf37a14c3 100644 --- a/source/blender/editors/mesh/mesh_data.c +++ b/source/blender/editors/mesh/mesh_data.c @@ -593,7 +593,7 @@ static int drop_named_image_invoke(bContext *C, wmOperator *op, wmEvent *event) /* Check context */ if (base == NULL || base->object->type != OB_MESH) { - BKE_report(op->reports, RPT_ERROR, "Not an Object or Mesh"); + BKE_report(op->reports, RPT_ERROR, "Not an object or mesh"); return OPERATOR_CANCELLED; } @@ -610,7 +610,7 @@ static int drop_named_image_invoke(bContext *C, wmOperator *op, wmEvent *event) } if (!ima) { - BKE_report(op->reports, RPT_ERROR, "Not an Image"); + BKE_report(op->reports, RPT_ERROR, "Not an image"); return OPERATOR_CANCELLED; } @@ -1124,7 +1124,7 @@ static void mesh_remove_faces(Mesh *mesh, int len) void ED_mesh_geometry_add(Mesh *mesh, ReportList *reports, int verts, int edges, int faces) { if (mesh->edit_btmesh) { - BKE_report(reports, RPT_ERROR, "Can't add geometry in edit mode"); + BKE_report(reports, RPT_ERROR, "Cannot add geometry in edit mode"); return; } @@ -1140,12 +1140,12 @@ void ED_mesh_geometry_add(Mesh *mesh, ReportList *reports, int verts, int edges, void ED_mesh_tessfaces_add(Mesh *mesh, ReportList *reports, int count) { if (mesh->edit_btmesh) { - BKE_report(reports, RPT_ERROR, "Can't add tessfaces in edit mode"); + BKE_report(reports, RPT_ERROR, "Cannot add tessfaces in edit mode"); return; } if (mesh->mpoly) { - BKE_report(reports, RPT_ERROR, "Can't add tessfaces to a mesh that already has polygons"); + BKE_report(reports, RPT_ERROR, "Cannot add tessfaces to a mesh that already has polygons"); return; } @@ -1155,7 +1155,7 @@ void ED_mesh_tessfaces_add(Mesh *mesh, ReportList *reports, int count) void ED_mesh_edges_add(Mesh *mesh, ReportList *reports, int count) { if (mesh->edit_btmesh) { - BKE_report(reports, RPT_ERROR, "Can't add edges in edit mode"); + BKE_report(reports, RPT_ERROR, "Cannot add edges in edit mode"); return; } @@ -1165,7 +1165,7 @@ void ED_mesh_edges_add(Mesh *mesh, ReportList *reports, int count) void ED_mesh_vertices_add(Mesh *mesh, ReportList *reports, int count) { if (mesh->edit_btmesh) { - BKE_report(reports, RPT_ERROR, "Can't add vertices in edit mode"); + BKE_report(reports, RPT_ERROR, "Cannot add vertices in edit mode"); return; } @@ -1175,11 +1175,11 @@ void ED_mesh_vertices_add(Mesh *mesh, ReportList *reports, int count) void ED_mesh_faces_remove(Mesh *mesh, ReportList *reports, int count) { if (mesh->edit_btmesh) { - BKE_report(reports, RPT_ERROR, "Can't remove faces in edit mode"); + BKE_report(reports, RPT_ERROR, "Cannot remove faces in edit mode"); return; } else if (count > mesh->totface) { - BKE_report(reports, RPT_ERROR, "Can't remove more faces than the mesh contains"); + BKE_report(reports, RPT_ERROR, "Cannot remove more faces than the mesh contains"); return; } @@ -1189,11 +1189,11 @@ void ED_mesh_faces_remove(Mesh *mesh, ReportList *reports, int count) void ED_mesh_edges_remove(Mesh *mesh, ReportList *reports, int count) { if (mesh->edit_btmesh) { - BKE_report(reports, RPT_ERROR, "Can't remove edges in edit mode"); + BKE_report(reports, RPT_ERROR, "Cannot remove edges in edit mode"); return; } else if (count > mesh->totedge) { - BKE_report(reports, RPT_ERROR, "Can't remove more edges than the mesh contains"); + BKE_report(reports, RPT_ERROR, "Cannot remove more edges than the mesh contains"); return; } @@ -1203,11 +1203,11 @@ void ED_mesh_edges_remove(Mesh *mesh, ReportList *reports, int count) void ED_mesh_vertices_remove(Mesh *mesh, ReportList *reports, int count) { if (mesh->edit_btmesh) { - BKE_report(reports, RPT_ERROR, "Can't remove vertices in edit mode"); + BKE_report(reports, RPT_ERROR, "Cannot remove vertices in edit mode"); return; } else if (count > mesh->totvert) { - BKE_report(reports, RPT_ERROR, "Can't remove more vertices than the mesh contains"); + BKE_report(reports, RPT_ERROR, "Cannot remove more vertices than the mesh contains"); return; } @@ -1217,7 +1217,7 @@ void ED_mesh_vertices_remove(Mesh *mesh, ReportList *reports, int count) void ED_mesh_loops_add(Mesh *mesh, ReportList *reports, int count) { if (mesh->edit_btmesh) { - BKE_report(reports, RPT_ERROR, "Can't add loops in edit mode."); + BKE_report(reports, RPT_ERROR, "Cannot add loops in edit mode"); return; } @@ -1227,7 +1227,7 @@ void ED_mesh_loops_add(Mesh *mesh, ReportList *reports, int count) void ED_mesh_polys_add(Mesh *mesh, ReportList *reports, int count) { if (mesh->edit_btmesh) { - BKE_report(reports, RPT_ERROR, "Can't add polygons in edit mode."); + BKE_report(reports, RPT_ERROR, "Cannot add polygons in edit mode"); return; } diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c index b5521a5ecea..d8793505608 100644 --- a/source/blender/editors/mesh/meshtools.c +++ b/source/blender/editors/mesh/meshtools.c @@ -113,7 +113,7 @@ int join_mesh_exec(bContext *C, wmOperator *op) CustomData vdata, edata, fdata, ldata, pdata; if (scene->obedit) { - BKE_report(op->reports, RPT_WARNING, "Cant join while in editmode"); + BKE_report(op->reports, RPT_WARNING, "Cannot join while in editmode"); return OPERATOR_CANCELLED; } @@ -161,8 +161,8 @@ int join_mesh_exec(bContext *C, wmOperator *op) } if (totvert > MESH_MAX_VERTS) { - BKE_reportf(op->reports, RPT_WARNING, "Joining results in %d vertices, limit is " STRINGIFY(MESH_MAX_VERTS), totvert); - return OPERATOR_CANCELLED; + BKE_reportf(op->reports, RPT_WARNING, "Joining results in %d vertices, limit is %ld", totvert, MESH_MAX_VERTS); + return OPERATOR_CANCELLED; } /* new material indices and material array */ diff --git a/source/blender/editors/physics/dynamicpaint_ops.c b/source/blender/editors/physics/dynamicpaint_ops.c index 91f1c0b2730..467ad5c6ff9 100644 --- a/source/blender/editors/physics/dynamicpaint_ops.c +++ b/source/blender/editors/physics/dynamicpaint_ops.c @@ -380,7 +380,7 @@ static int dynamicPaint_initBake(struct bContext *C, struct wmOperator *op) /* Bake was successful: * Report for ended bake and how long it took */ if (status) { - /* Format time string */ + /* Format time string */ char time_str[30]; double time = PIL_check_seconds_timer() - timer; BLI_timestr(time, time_str); @@ -389,11 +389,11 @@ static int dynamicPaint_initBake(struct bContext *C, struct wmOperator *op) BKE_reportf(op->reports, RPT_INFO, "Bake complete! (%s)", time_str); } else { - if (strlen(canvas->error)) { /* If an error occured */ + if (strlen(canvas->error)) { /* If an error occurred */ BKE_reportf(op->reports, RPT_ERROR, "Bake failed: %s", canvas->error); } else { /* User canceled the bake */ - BKE_report(op->reports, RPT_WARNING, "Baking cancelled!"); + BKE_report(op->reports, RPT_WARNING, "Baking canceled!"); } } diff --git a/source/blender/editors/space_node/node_group.c b/source/blender/editors/space_node/node_group.c index b76cc05af5c..19a678a9c6e 100644 --- a/source/blender/editors/space_node/node_group.c +++ b/source/blender/editors/space_node/node_group.c @@ -583,7 +583,7 @@ static int node_group_ungroup_exec(bContext *C, wmOperator *op) ntreeUpdateTree(snode->nodetree); } else { - BKE_report(op->reports, RPT_WARNING, "Can't ungroup"); + BKE_report(op->reports, RPT_WARNING, "Cannot ungroup"); return OPERATOR_CANCELLED; } @@ -755,13 +755,13 @@ static int node_group_separate_exec(bContext *C, wmOperator *op) switch (type) { case NODE_GS_COPY: if (!node_group_separate_selected(snode->nodetree, gnode, 1)) { - BKE_report(op->reports, RPT_WARNING, "Can't separate nodes"); + BKE_report(op->reports, RPT_WARNING, "Cannot separate nodes"); return OPERATOR_CANCELLED; } break; case NODE_GS_MOVE: if (!node_group_separate_selected(snode->nodetree, gnode, 0)) { - BKE_report(op->reports, RPT_WARNING, "Can't separate nodes"); + BKE_report(op->reports, RPT_WARNING, "Cannot separate nodes"); return OPERATOR_CANCELLED; } break; @@ -1036,7 +1036,7 @@ static int node_group_make_exec(bContext *C, wmOperator *op) int type = RNA_enum_get(op->ptr, "type"); if (snode->edittree != snode->nodetree) { - BKE_report(op->reports, RPT_WARNING, "Can not add a new Group in a Group"); + BKE_report(op->reports, RPT_WARNING, "Cannot add a new group in a group"); return OPERATOR_CANCELLED; } @@ -1049,7 +1049,7 @@ static int node_group_make_exec(bContext *C, wmOperator *op) } if (gnode) { - BKE_report(op->reports, RPT_WARNING, "Can not add RenderLayer in a Group"); + BKE_report(op->reports, RPT_WARNING, "Cannot add a Render Layers node in a group"); return OPERATOR_CANCELLED; } } @@ -1062,21 +1062,21 @@ static int node_group_make_exec(bContext *C, wmOperator *op) gnode = node_group_make_from_selected(snode->nodetree); } else { - BKE_report(op->reports, RPT_WARNING, "Can not make Group"); + BKE_report(op->reports, RPT_WARNING, "Cannot make group"); return OPERATOR_CANCELLED; } break; case NODE_GM_INSERT: gnode = nodeGetActive(snode->nodetree); if (!gnode || gnode->type != NODE_GROUP) { - BKE_report(op->reports, RPT_WARNING, "No active Group node"); + BKE_report(op->reports, RPT_WARNING, "No active group node"); return OPERATOR_CANCELLED; } if (node_group_make_test(snode->nodetree, gnode)) { node_group_make_insert_selected(snode->nodetree, gnode); } else { - BKE_report(op->reports, RPT_WARNING, "Can not insert into Group"); + BKE_report(op->reports, RPT_WARNING, "Cannot insert into group"); return OPERATOR_CANCELLED; } break; diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c index fbd07c73b12..8f059b0a735 100644 --- a/source/blender/editors/space_outliner/outliner_edit.c +++ b/source/blender/editors/space_outliner/outliner_edit.c @@ -1344,7 +1344,7 @@ static int outliner_keyingset_additems_exec(bContext *C, wmOperator *op) /* check for invalid states */ if (ks == NULL) { - BKE_report(op->reports, RPT_ERROR, "Operation requires an Active Keying Set"); + BKE_report(op->reports, RPT_ERROR, "Operation requires an active keying set"); return OPERATOR_CANCELLED; } if (soutliner == NULL) From 5ad61e9642a8f0d26c7e5c85477747f4f387bfc3 Mon Sep 17 00:00:00 2001 From: Nicholas Bishop Date: Fri, 19 Oct 2012 02:38:50 +0000 Subject: [PATCH 312/347] Fix for VBO drawing in multires sculpting Was a mistake in a code cleanup commit, r51118. Fixes bug [#32919] Sculting performance regression in svn_51118 projects.blender.org/tracker/?func=detail&aid=32919&group_id=9&atid=498 --- source/blender/gpu/intern/gpu_buffers.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c index 201162262b2..c0b4987c3fc 100644 --- a/source/blender/gpu/intern/gpu_buffers.c +++ b/source/blender/gpu/intern/gpu_buffers.c @@ -1763,7 +1763,7 @@ static GLuint gpu_get_grid_buffer(int gridsize, GLenum *index_type, unsigned *to /* VBO is disabled; delete the previous buffer (if it exists) and * return an invalid handle */ - if (gpu_vbo_enabled()) { + if (!gpu_vbo_enabled()) { if (buffer) glDeleteBuffersARB(1, &buffer); return 0; From 9b07c98bb40ac93774b7cfc9723bd28c95ec409d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 19 Oct 2012 03:07:58 +0000 Subject: [PATCH 313/347] code cleanup: minor style change & quiet warning, also add assert for BM_vert_splice() to check for invalid use. --- .../cycles/kernel/osl/nodes/node_rgb_ramp.osl | 29 +++++++++---------- source/blender/bmesh/intern/bmesh_core.c | 11 +++++-- .../modifiers/intern/MOD_particlesystem.c | 2 +- 3 files changed, 23 insertions(+), 19 deletions(-) diff --git a/intern/cycles/kernel/osl/nodes/node_rgb_ramp.osl b/intern/cycles/kernel/osl/nodes/node_rgb_ramp.osl index afce1127305..a128ebbd1cf 100644 --- a/intern/cycles/kernel/osl/nodes/node_rgb_ramp.osl +++ b/intern/cycles/kernel/osl/nodes/node_rgb_ramp.osl @@ -20,25 +20,24 @@ #include "oslutil.h" shader node_rgb_ramp( - color ramp_color[RAMP_TABLE_SIZE] = {0.0}, - float ramp_alpha[RAMP_TABLE_SIZE] = {0.0}, + color ramp_color[RAMP_TABLE_SIZE] = {0.0}, + float ramp_alpha[RAMP_TABLE_SIZE] = {0.0}, - float Fac = 0.0, - output color Color = color(0.0, 0.0, 0.0), - output float Alpha = 1.0 - ) + float Fac = 0.0, + output color Color = color(0.0, 0.0, 0.0), + output float Alpha = 1.0) { - float f = clamp(Fac, 0.0, 1.0) * (RAMP_TABLE_SIZE - 1); + float f = clamp(Fac, 0.0, 1.0) * (RAMP_TABLE_SIZE - 1); - int i = (int)f; - float t = f - (float)i; + int i = (int)f; + float t = f - (float)i; - Color = ramp_color[i]; - Alpha = ramp_alpha[i]; + Color = ramp_color[i]; + Alpha = ramp_alpha[i]; - if (t > 0.0) { - Color = (1.0 - t) * Color + t * ramp_color[i + 1]; - Alpha = (1.0 - t) * Alpha + t * ramp_alpha[i + 1]; - } + if (t > 0.0) { + Color = (1.0 - t) * Color + t * ramp_color[i + 1]; + Alpha = (1.0 - t) * Alpha + t * ramp_alpha[i + 1]; + } } diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c index 413f480c60d..cef2c1f7573 100644 --- a/source/blender/bmesh/intern/bmesh_core.c +++ b/source/blender/bmesh/intern/bmesh_core.c @@ -1607,10 +1607,10 @@ BMEdge *bmesh_jekv(BMesh *bm, BMEdge *ke, BMVert *kv, const short check_edge_dou BMESH_ASSERT(edok != FALSE); } - /* deallocate edg */ + /* deallocate edge */ bm_kill_only_edge(bm, ke); - /* deallocate verte */ + /* deallocate vertex */ bm_kill_only_vert(bm, kv); /* Validate disk cycle lengths of ov, tv are unchanged */ @@ -1619,7 +1619,7 @@ BMEdge *bmesh_jekv(BMesh *bm, BMEdge *ke, BMVert *kv, const short check_edge_dou edok = bmesh_disk_validate(valence2, tv->e, tv); BMESH_ASSERT(edok != FALSE); - /* Validate loop cycle of all faces attached to oe */ + /* Validate loop cycle of all faces attached to 'oe' */ for (i = 0, l = oe->l; i < radlen; i++, l = l->radial_next) { BMESH_ASSERT(l->e == oe); edok = bmesh_verts_in_edge(l->v, l->next->v, oe); @@ -1800,6 +1800,10 @@ BMFace *bmesh_jfke(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e) * Merges two verts into one (\a v into \a vtarget). * * \return Success + * + * \warning This does't work for collapsing edges, + * where \a v and \a vtarget are connected by an edge + * (assert checks for this case). */ int BM_vert_splice(BMesh *bm, BMVert *v, BMVert *vtarget) { @@ -1827,6 +1831,7 @@ int BM_vert_splice(BMesh *bm, BMVert *v, BMVert *vtarget) bmesh_disk_edge_remove(e, v); bmesh_edge_swapverts(e, v, vtarget); bmesh_disk_edge_append(e, vtarget); + BLI_assert(e->v1 != e->v2); } BM_CHECK_ELEMENT(v); diff --git a/source/blender/modifiers/intern/MOD_particlesystem.c b/source/blender/modifiers/intern/MOD_particlesystem.c index 6d6c1361566..cd2ef5957cd 100644 --- a/source/blender/modifiers/intern/MOD_particlesystem.c +++ b/source/blender/modifiers/intern/MOD_particlesystem.c @@ -131,7 +131,7 @@ static void deformVerts(ModifierData *md, Object *ob, ParticleSystemModifierData *psmd = (ParticleSystemModifierData *) md; ParticleSystem *psys = NULL; int needsFree = 0; - float cfra = BKE_scene_frame_get(md->scene); + /* float cfra = BKE_scene_frame_get(md->scene); */ /* UNUSED */ if (ob->particlesystem.first) psys = psmd->psys; From 03164c315237113236751c834cebcefeed927fc5 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 19 Oct 2012 03:28:41 +0000 Subject: [PATCH 314/347] DM_to_bmesh_ex() now initializes index values when running in empty meshes. saves running extra loop on vert/edge/face data if these values are needed after. --- source/blender/blenkernel/intern/modifiers_bmesh.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/modifiers_bmesh.c b/source/blender/blenkernel/intern/modifiers_bmesh.c index dc3d4a89e62..9ccdddee1ad 100644 --- a/source/blender/blenkernel/intern/modifiers_bmesh.c +++ b/source/blender/blenkernel/intern/modifiers_bmesh.c @@ -55,6 +55,7 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) BLI_array_declare(verts); BLI_array_declare(edges); int i, j, k, totvert, totedge /* , totface */ /* UNUSED */ ; + int is_init = (bm->totvert == 0) && (bm->totedge == 0) && (bm->totface == 0); /*merge custom data layout*/ CustomData_bmesh_merge(&dm->vertData, &bm->vdata, CD_MASK_DERIVEDMESH, CD_CALLOC, bm, BM_VERT); @@ -81,6 +82,7 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) v = BM_vert_create(bm, mv->co, NULL); normal_short_to_float_v3(v->no, mv->no); v->head.hflag = BM_vert_flag_from_mflag(mv->flag); + BM_elem_index_set(v, i); /* set_inline */ CustomData_to_bmesh_block(&dm->vertData, &bm->vdata, i, &v->head.data); @@ -89,6 +91,7 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) vtable[i] = v; } MEM_freeN(mvert); + if (is_init) bm->elem_index_dirty &= ~BM_VERT; /*do edges*/ me = medge = dm->dupEdgeArray(dm); @@ -96,6 +99,7 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) e = BM_edge_create(bm, vtable[me->v1], vtable[me->v2], NULL, FALSE); e->head.hflag = BM_edge_flag_from_mflag(me->flag); + BM_elem_index_set(e, i); /* set_inline */ CustomData_to_bmesh_block(&dm->edgeData, &bm->edata, i, &e->head.data); etable[i] = e; @@ -106,8 +110,10 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) BM_elem_float_data_set(&bm->edata, e, CD_BWEIGHT, (float)me->bweight / 255.0f); } MEM_freeN(medge); + if (is_init) bm->elem_index_dirty &= ~BM_EDGE; - /*do faces*/ + /* do faces */ + /* note: i_alt is aligned with bmesh faces which may not always align with mpolys */ mp = dm->getPolyArray(dm); mloop = dm->getLoopArray(dm); face_normals = CustomData_get_layer(&dm->polyData, CD_NORMAL); /* can be NULL */ @@ -134,6 +140,7 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) } f->head.hflag = BM_face_flag_from_mflag(mp->flag); + BM_elem_index_set(f, bm->totface - 1); /* set_inline */ f->mat_nr = mp->mat_nr; l = BM_iter_new(&liter, bm, BM_LOOPS_OF_FACE, f); @@ -151,6 +158,7 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) BM_face_normal_update(f); } } + if (is_init) bm->elem_index_dirty &= ~BM_FACE; MEM_freeN(vtable); MEM_freeN(etable); From 78f7518bf3c3f00ae0e2c7dd9b3c3ce8023d3083 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 19 Oct 2012 07:20:37 +0000 Subject: [PATCH 315/347] small quadric library ported from Laurence Bourn's LOD_decimator LOD_Quadric class. not used just yet. --- source/blender/blenlib/BLI_quadric.h | 56 ++++++++++ source/blender/blenlib/CMakeLists.txt | 4 +- source/blender/blenlib/intern/quadric.c | 131 ++++++++++++++++++++++++ 3 files changed, 190 insertions(+), 1 deletion(-) create mode 100644 source/blender/blenlib/BLI_quadric.h create mode 100644 source/blender/blenlib/intern/quadric.c diff --git a/source/blender/blenlib/BLI_quadric.h b/source/blender/blenlib/BLI_quadric.h new file mode 100644 index 00000000000..aec11ec2b44 --- /dev/null +++ b/source/blender/blenlib/BLI_quadric.h @@ -0,0 +1,56 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * Contributor(s): Laurence Bourn, Campbell Barton + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef __BLI_QUADRIC_H__ +#define __BLI_QUADRIC_H__ + +/** \file BLI_quadric.h + * \ingroup bli + */ + +typedef struct Quadric { + float a2, ab, ac, ad, + b2, bc, bd, + c2, cd, + d2; +} Quadric; + +/* conversion */ +void BLI_quadric_from_v3_dist(Quadric *q, const float v[3], const float offset); +void BLI_quadric_to_tensor_m3(const Quadric *q, float m[3][3]); +void BLI_quadric_to_vector_v3(const Quadric *q, float v[3]); + +void BLI_quadric_clear(Quadric *q); + +/* math */ +void BLI_quadric_add_qu_qu(Quadric *a, const Quadric *b); +void BLI_quadric_add_qu_ququ(Quadric *r, const Quadric *a, const Quadric *b); +void BLI_quadric_mul(Quadric *a, const float scalar); + +/* solve */ +float BLI_quadric_evaluate(const Quadric *q, const float v[3]); +int BLI_quadric_optimize(const Quadric *q, float v[3]); + +#endif /* __BLI_QUADRIC_H__ */ diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt index 2836174be73..6839f05bfbc 100644 --- a/source/blender/blenlib/CMakeLists.txt +++ b/source/blender/blenlib/CMakeLists.txt @@ -78,6 +78,7 @@ set(SRC intern/noise.c intern/path_util.c intern/pbvh.c + intern/quadric.c intern/rand.c intern/rct.c intern/scanfill.c @@ -90,8 +91,8 @@ set(SRC intern/threads.c intern/time.c intern/uvproject.c - intern/voxel.c intern/voronoi.c + intern/voxel.c intern/winstuff.c BLI_args.h @@ -135,6 +136,7 @@ set(SRC BLI_noise.h BLI_path_util.h BLI_pbvh.h + BLI_quadric.h BLI_rand.h BLI_rect.h BLI_scanfill.h diff --git a/source/blender/blenlib/intern/quadric.c b/source/blender/blenlib/intern/quadric.c new file mode 100644 index 00000000000..1c04beacbfb --- /dev/null +++ b/source/blender/blenlib/intern/quadric.c @@ -0,0 +1,131 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * Contributor(s): Laurence Bourn, Campbell Barton + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/blenlib/intern/quadric.c + * \ingroup bli + * + * \note This isn't fully complete, + * possible there are other useful functions to add here. + * + * \note try to follow BLI_math naming convention here. + */ + +//#include + +#include "BLI_math.h" +#include "BLI_quadric.h" /* own include */ + + +#define QUADRIC_FLT_TOT (sizeof(Quadric) / sizeof(float)) + +void BLI_quadric_from_v3_dist(Quadric *q, const float v[3], const float offset) +{ + q->a2 = v[0] * v[0]; + q->b2 = v[1] * v[1]; + q->c2 = v[2] * v[2]; + + q->ab = v[0] * v[1]; + q->ac = v[0] * v[2]; + q->bc = v[1] * v[2]; + + q->ad = v[0] * offset; + q->bd = v[1] * offset; + q->cd = v[2] * offset; + + q->d2 = offset * offset; +} + +void BLI_quadric_to_tensor_m3(const Quadric *q, float m[3][3]) +{ + m[0][0] = q->a2; + m[0][1] = q->ab; + m[0][2] = q->ac; + + m[1][0] = q->ab; + m[1][1] = q->b2; + m[1][2] = q->bc; + + m[2][0] = q->ac; + m[2][1] = q->bc; + m[2][2] = q->c2; +} + +void BLI_quadric_to_vector_v3(const Quadric *q, float v[3]) +{ + v[0] = q->ad; + v[1] = q->bd; + v[2] = q->cd; +} + +void BLI_quadric_clear(Quadric *q) +{ + memset(q, 0, sizeof(*q)); +} + +void BLI_quadric_add_qu_qu(Quadric *a, const Quadric *b) +{ + add_vn_vn((float *)a, (float *)b, QUADRIC_FLT_TOT); +} + +void BLI_quadric_add_qu_ququ(Quadric *r, const Quadric *a, const Quadric *b) +{ + add_vn_vnvn((float *)r, (const float *)a, (const float *)b, QUADRIC_FLT_TOT); +} + +void BLI_quadric_mul(Quadric *a, const float scalar) +{ + mul_vn_fl((float *)a, QUADRIC_FLT_TOT, scalar); +} + +float BLI_quadric_evaluate(const Quadric *q, const float v[3]) +{ + return (v[0] * v[0] * q->a2 + 2.0f * v[0] * v[1] * q->ab + 2.0f * v[0] * v[2] * q->ac + 2.0f * v[0] * q->ad + + v[1] * v[1] * q->b2 + 2.0f * v[1] * v[2] * q->bc + 2.0f * v[1] * q->bd + + v[2] * v[2] * q->c2 + 2.0f * v[2] * q->cd + + q->d2); +} + +int BLI_quadric_optimize(const Quadric *q, float v[3]) +{ + float m[3][3]; + float det; + + BLI_quadric_to_tensor_m3(q, m); + det = determinant_m3(m[0][0], m[0][1], m[0][2], + m[1][0], m[1][1], m[1][2], + m[2][0], m[2][1], m[2][2]); + + if (det != 0.0f) { + invert_m3(m); + BLI_quadric_to_vector_v3(q, v); + mul_m3_v3(m, v); + negate_v3(v); + + return TRUE; + } + else { + return FALSE; + } +} From e648542872a4887cd9f6c88501403033482df8ee Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 19 Oct 2012 07:31:51 +0000 Subject: [PATCH 316/347] decimate modifier rewrite to use bmesh (#ifdef-disabled by default for now). - maintains quads & ngons - supports some customdata (weight paint for example works fine). TODO - add suppory for loop data (UV's / VCol's). - outputs invalid geometry when heavily reducing some meshes, needs to be made stable in these cases. --- source/blender/bmesh/CMakeLists.txt | 2 + source/blender/bmesh/bmesh.h | 1 + source/blender/bmesh/intern/bmesh_decimate.c | 574 +++++++++++++++++++ source/blender/bmesh/intern/bmesh_decimate.h | 32 ++ 4 files changed, 609 insertions(+) create mode 100644 source/blender/bmesh/intern/bmesh_decimate.c create mode 100644 source/blender/bmesh/intern/bmesh_decimate.h diff --git a/source/blender/bmesh/CMakeLists.txt b/source/blender/bmesh/CMakeLists.txt index 20387684b66..1e56314ab6e 100644 --- a/source/blender/bmesh/CMakeLists.txt +++ b/source/blender/bmesh/CMakeLists.txt @@ -64,6 +64,8 @@ set(SRC intern/bmesh_construct.h intern/bmesh_core.c intern/bmesh_core.h + intern/bmesh_decimate.c + intern/bmesh_decimate.h intern/bmesh_inline.h intern/bmesh_interp.c intern/bmesh_interp.h diff --git a/source/blender/bmesh/bmesh.h b/source/blender/bmesh/bmesh.h index 955b1a729c5..a672ec0b6a7 100644 --- a/source/blender/bmesh/bmesh.h +++ b/source/blender/bmesh/bmesh.h @@ -252,6 +252,7 @@ extern "C" { #include "intern/bmesh_construct.h" #include "intern/bmesh_core.h" +#include "intern/bmesh_decimate.h" #include "intern/bmesh_interp.h" #include "intern/bmesh_iterators.h" #include "intern/bmesh_marking.h" diff --git a/source/blender/bmesh/intern/bmesh_decimate.c b/source/blender/bmesh/intern/bmesh_decimate.c new file mode 100644 index 00000000000..d8aa8adef55 --- /dev/null +++ b/source/blender/bmesh/intern/bmesh_decimate.c @@ -0,0 +1,574 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Campbell Barton + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/bmesh/intern/bmesh_decimate.c + * \ingroup bmesh + * + * BMesh decimator. + */ + +#include + +#include "MEM_guardedalloc.h" + +#include "DNA_scene_types.h" + +#include "BLI_math.h" +#include "BLI_quadric.h" +#include "BLI_heap.h" + +#include "bmesh.h" +#include "bmesh_structure.h" +#include "bmesh_decimate.h" + +/* defines for testing */ +#define USE_CUSTOMDATA +#define USE_TRIANGULATE + +/* these checks are for rare cases that we can't avoid since they are valid meshes still */ +#define USE_SAFETY_CHECKS + +#define BOUNDARY_PRESERVE_WEIGHT 100.0f + + +/* BMesh Helper Functions + * ********************** */ + +/** + * \param vquadrics must be calloc'd + */ +static void bm_decim_build_quadrics(BMesh *bm, Quadric *vquadrics) +{ + BMIter iter; + BMFace *f; + BMEdge *e; + + BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) { + BMLoop *l_first; + BMLoop *l_iter; + + const float *co = BM_FACE_FIRST_LOOP(f)->v->co; + const float *no = f->no; + const float offset = -dot_v3v3(no, co); + Quadric q; + + BLI_quadric_from_v3_dist(&q, no, offset); + + l_iter = l_first = BM_FACE_FIRST_LOOP(f); + do { + BLI_quadric_add_qu_qu(&vquadrics[BM_elem_index_get(l_iter->v)], &q); + } while ((l_iter = l_iter->next) != l_first); + } + + /* boundary edges */ + BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { + if (UNLIKELY(BM_edge_is_boundary(e))) { + float edge_vector[3]; + float edge_cross[3]; + sub_v3_v3v3(edge_vector, e->v2->co, e->v1->co); + f = e->l->f; + cross_v3_v3v3(edge_cross, edge_vector, f->no); + + if (normalize_v3(edge_cross) != 0.0f) { + Quadric q; + BLI_quadric_from_v3_dist(&q, edge_vector, -dot_v3v3(edge_cross, e->v1->co)); + BLI_quadric_mul(&q, BOUNDARY_PRESERVE_WEIGHT); + + BLI_quadric_add_qu_qu(&vquadrics[BM_elem_index_get(e->v1)], &q); + BLI_quadric_add_qu_qu(&vquadrics[BM_elem_index_get(e->v2)], &q); + } + } + } +} + + +static void bm_decim_calc_target_co(BMEdge *e, float optimize_co[3], + const Quadric *vquadrics) +{ + /* compute an edge contration target for edge ei + * this is computed by summing it's vertices quadrics and + * optimizing the result. */ + Quadric q; + + BLI_quadric_add_qu_ququ(&q, + &vquadrics[BM_elem_index_get(e->v1)], + &vquadrics[BM_elem_index_get(e->v2)]); + + + if (BLI_quadric_optimize(&q, optimize_co)) { + return; /* all is good */ + } + else { + mid_v3_v3v3(optimize_co, e->v1->co, e->v2->co); + } +} + +static void bm_decim_build_edge_cost_single(BMEdge *e, + const Quadric *vquadrics, + Heap *eheap, HeapNode **eheap_table) +{ + const Quadric *q1, *q2; + float optimize_co[3]; + float cost; + + if (eheap_table[BM_elem_index_get(e)]) { + BLI_heap_remove(eheap, eheap_table[BM_elem_index_get(e)]); + } + + /* check we can collapse, some edges we better not touch */ + if (BM_edge_is_boundary(e)) { + if (e->l->f->len == 3) { + /* pass */ + } + else { + /* only collapse tri's */ + eheap_table[BM_elem_index_get(e)] = NULL; + return; + } + } + else if (BM_edge_is_manifold(e)) { + if ((e->l->f->len == 3) && (e->l->radial_next->f->len == 3)) { + /* pass */ + } + else { + /* only collapse tri's */ + eheap_table[BM_elem_index_get(e)] = NULL; + return; + } + } + else { + eheap_table[BM_elem_index_get(e)] = NULL; + return; + } + /* end sanity check */ + + + bm_decim_calc_target_co(e, optimize_co, vquadrics); + + q1 = &vquadrics[BM_elem_index_get(e->v1)]; + q2 = &vquadrics[BM_elem_index_get(e->v2)]; + + cost = (BLI_quadric_evaluate(q1, optimize_co) + BLI_quadric_evaluate(q2, optimize_co)); + + eheap_table[BM_elem_index_get(e)] = BLI_heap_insert(eheap, cost, e); +} + +static void bm_decim_build_edge_cost(BMesh *bm, + const Quadric *vquadrics, + Heap *eheap, HeapNode **eheap_table) +{ + BMIter iter; + BMEdge *e; + unsigned int i; + + BM_ITER_MESH_INDEX (e, &iter, bm, BM_EDGES_OF_MESH, i) { + eheap_table[i] = NULL; /* keep sanity check happy */ + bm_decim_build_edge_cost_single(e, vquadrics, eheap, eheap_table); + } +} + +#ifdef USE_TRIANGULATE +/* Temp Triangulation + * ****************** */ + +/** + * To keep things simple we can only collapse edges on triangulated data + * (limitation with edge collapse and error calculation functions). + * + * But to avoid annoying users by only giving triangle results, we can + * triangulate, keeping a reference between the faces, then join after + * if the edges don't collapse, this will also allow more choices when + * collapsing edges so even has some advantage over decimating quads + * directly. + * + * \return TRUE if any faces were triangulated. + */ + +static int bm_decim_triangulate_begin(BMesh *bm) +{ +#ifdef USE_SAFETY_CHECKS + const int check_double_edges = TRUE; +#else + const int check_double_edges = FALSE; +#endif + + BMIter iter; + BMFace *f; + // int has_quad; // could optimize this a little + int has_cut = FALSE; + + BLI_assert((bm->elem_index_dirty & BM_VERT) == 0); + + /* first clear loop index values */ + BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) { + BMLoop *l_iter; + BMLoop *l_first; + + l_iter = l_first = BM_FACE_FIRST_LOOP(f); + do { + BM_elem_index_set(l_iter, -1); + } while ((l_iter = l_iter->next) != l_first); + + // has_quad |= (f->len == 4) + } + + /* adding new faces as we loop over faces + * is normally best avoided, however in this case its not so bad because any face touched twice + * will already be triangulated*/ + BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) { + if (f->len == 4) { + BMLoop *f_l[4]; + BMLoop *l_iter; + BMLoop *l_a, *l_b; + + l_iter = BM_FACE_FIRST_LOOP(f); + + f_l[0] = l_iter; l_iter = l_iter->next; + f_l[1] = l_iter; l_iter = l_iter->next; + f_l[2] = l_iter; l_iter = l_iter->next; + f_l[3] = l_iter; l_iter = l_iter->next; + + if (len_squared_v3v3(f_l[0]->v->co, f_l[2]->v->co) < len_squared_v3v3(f_l[1]->v->co, f_l[3]->v->co)) { + l_a = f_l[0]; + l_b = f_l[2]; + } + else { + l_a = f_l[1]; + l_b = f_l[3]; + } + + { + BMFace *f_new; + BMLoop *l_new; + + /* warning, NO_DOUBLE option here isn't handled as nice as it could be + * - if there is a quad that has a free standing edge joining it along + * where we want to split the face, there isnt a good way we can handle this. + * currently that edge will get removed when joining the tris back into a quad. */ + f_new = BM_face_split(bm, f, l_a->v, l_b->v, &l_new, NULL, check_double_edges); + + if (f_new) { + /* the value of this doesn't matter, only that the 2 loops match and have unique values */ + const int f_index = BM_elem_index_get(f); + + /* since we just split theres only ever 2 loops */ + BLI_assert(BM_edge_is_manifold(l_new->e)); + + BM_elem_index_set(l_new, f_index); + BM_elem_index_set(l_new->radial_next, f_index); + + has_cut = TRUE; + } + } + } + } + + BLI_assert((bm->elem_index_dirty & BM_VERT) == 0); + + if (has_cut) { + /* now triangulation is done we need to correct index values */ + BM_mesh_elem_index_ensure(bm, BM_EDGE | BM_FACE); + } + + return has_cut; +} + +static void bm_decim_triangulate_end(BMesh *bm) +{ + /* decimation finished, now re-join */ + BMIter iter; + BMEdge *e; + + /* boundary edges */ + BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { + BMLoop *l_a, *l_b; + if (BM_edge_loop_pair(e, &l_a, &l_b)) { + const int l_a_index = BM_elem_index_get(l_a); + if (l_a_index != -1) { + const int l_b_index = BM_elem_index_get(l_b); + if (l_a_index == l_b_index) { + /* highly unlikely to fail, but prevents possible double-ups */ + if (l_a->f->len == 3 && l_b->f->len == 3) { + BMFace *f[2] = {l_a->f, l_b->f}; + BM_faces_join(bm, f, 2, TRUE); + } + } + } + } + } +} + +#endif /* USE_TRIANGULATE */ + +/* Edge Collapse Functions + * *********************** */ + +/** + * special, highly limited edge collapse function + * intended for speed over flexibiliy. + * can only collapse edges connected to (1, 2) tris. + * + * Important - dont add vert/edge/face data on collapsing! + * + * \param ke_other let caller know what edges we remove besides \a ke + */ +static int bm_edge_collapse(BMesh *bm, BMEdge *ke, BMVert *kv, int ke_other[2], +#ifdef USE_CUSTOMDATA + const float customdata_fac +#else + const float UNUSED(customdata_fac) +#endif + ) +{ + BMVert *v_other = BM_edge_other_vert(ke, kv); + + BLI_assert(v_other != NULL); + + if (BM_edge_is_manifold(ke)) { + BMLoop *l_a, *l_b; + BMEdge *e_a_other[2], *e_b_other[2]; + int ok; + + ok = BM_edge_loop_pair(ke, &l_a, &l_b); + + BLI_assert(ok == TRUE); + BLI_assert(l_a->f->len == 3); + BLI_assert(l_b->f->len == 3); + + /* keep 'kv' 0th */ + if (BM_vert_in_edge(l_a->prev->e, kv)) { + e_a_other[0] = l_a->prev->e; + e_a_other[1] = l_a->next->e; + } + else { + e_a_other[1] = l_a->prev->e; + e_a_other[0] = l_a->next->e; + } + + if (BM_vert_in_edge(l_b->prev->e, kv)) { + e_b_other[0] = l_b->prev->e; + e_b_other[1] = l_b->next->e; + } + else { + e_b_other[1] = l_b->prev->e; + e_b_other[0] = l_b->next->e; + } + + BLI_assert(BM_edge_share_vert(e_a_other[0], e_b_other[0])); + BLI_assert(BM_edge_share_vert(e_a_other[1], e_b_other[1])); + + /* we could assert this case, but better just bail out */ +#if 0 + BLI_assert(e_a_other[0] != e_b_other[0]); + BLI_assert(e_a_other[0] != e_b_other[1]); + BLI_assert(e_b_other[0] != e_a_other[0]); + BLI_assert(e_b_other[0] != e_a_other[1]); +#endif + /* not totally common but we want to avoid */ + if (ELEM(e_a_other[0], e_b_other[0], e_b_other[1]) || + ELEM(e_a_other[1], e_b_other[0], e_b_other[1])) + { + return FALSE; + } + + ke_other[0] = BM_elem_index_get(e_a_other[0]); + ke_other[1] = BM_elem_index_get(e_b_other[0]); + +#ifdef USE_CUSTOMDATA + /* TODO, loops */ + // const float w[2] = {customdata_fac, 1.0f - customdata_fac}; + + /* before killing, do customdata */ + BM_data_interp_from_verts(bm, v_other, kv, v_other, customdata_fac); +#endif + + BM_edge_kill(bm, ke); + + BM_vert_splice(bm, kv, v_other); + + BM_edge_splice(bm, e_a_other[0], e_a_other[1]); + BM_edge_splice(bm, e_b_other[0], e_b_other[1]); + + // BM_mesh_validate(bm); + + return TRUE; + } + else if (BM_edge_is_boundary(ke)) { + /* same as above but only one triangle */ + BMLoop *l_a; + BMEdge *e_a_other[2]; + + l_a = ke->l; + + BLI_assert(l_a->f->len == 3); + + /* keep 'kv' 0th */ + if (BM_vert_in_edge(l_a->prev->e, kv)) { + e_a_other[0] = l_a->prev->e; + e_a_other[1] = l_a->next->e; + } + else { + e_a_other[1] = l_a->prev->e; + e_a_other[0] = l_a->next->e; + } + + ke_other[0] = BM_elem_index_get(e_a_other[0]); + ke_other[1] = -1; + +#ifdef USE_CUSTOMDATA + /* TODO, loops */ + // const float w[2] = {customdata_fac, 1.0f - customdata_fac}; + + /* before killing, do customdata */ + BM_data_interp_from_verts(bm, v_other, kv, v_other, customdata_fac); +#endif + + BM_edge_kill(bm, ke); + + BM_vert_splice(bm, kv, v_other); + + BM_edge_splice(bm, e_a_other[0], e_a_other[1]); + + // BM_mesh_validate(bm); + + return TRUE; + } + else { + return FALSE; + } +} + + +/* collapse e the edge, removing e->v2 */ +static void bm_decim_edge_collapse(BMesh *bm, BMEdge *e, + Quadric *vquadrics, + Heap *eheap, HeapNode **eheap_table) +{ + int ke_other[2]; + BMVert *v = e->v1; + int kv_index = BM_elem_index_get(e->v2); /* the vert is removed so only store the index */ + float optimize_co[3]; + float customdata_fac; + + bm_decim_calc_target_co(e, optimize_co, vquadrics); + + /* use for customdata merging */ + customdata_fac = line_point_factor_v3(optimize_co, e->v1->co, e->v2->co); + + if (bm_edge_collapse(bm, e, e->v2, ke_other, customdata_fac)) { + /* update collapse info */ + int i; + + e = NULL; /* paranoid safety check */ + + copy_v3_v3(v->co, optimize_co); + + /* remove eheap */ + for (i = 0; i < 2; i++) { + /* highly unlikely 'eheap_table[ke_other[i]]' would be NULL, but do for sanity sake */ + if ((ke_other[i] != -1) && (eheap_table[ke_other[i]] != NULL)) { + BLI_heap_remove(eheap, eheap_table[ke_other[i]]); + eheap_table[ke_other[i]] = NULL; + } + } + + /* update vertex quadric, add kept vertex from killed vertex */ + BLI_quadric_add_qu_qu(&vquadrics[BM_elem_index_get(v)], &vquadrics[kv_index]); + + /* update connected normals */ + BM_vert_normal_update_all(v); + + /* update error costs and the eheap */ + if (LIKELY(v->e)) { + BMEdge *e_iter; + BMEdge *e_first; + e_iter = e_first = v->e; + do { + bm_decim_build_edge_cost_single(e_iter, vquadrics, eheap, eheap_table); + } while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e_first); + } + } +} + + +/* Main Decimate Function + * ********************** */ + +void BM_mesh_decimate(BMesh *bm, const float factor) +{ + Heap *eheap; /* edge heap */ + HeapNode **eheap_table; /* edge index aligned table pointing to the eheap */ + Quadric *vquadrics; /* vert index aligned quadrics */ + int tot_edge_orig; + int face_tot_target; + int use_triangulate; + + +#ifdef USE_TRIANGULATE + /* temp convert quads to triangles */ + use_triangulate = bm_decim_triangulate_begin(bm); +#endif + + + /* alloc vars */ + vquadrics = MEM_callocN(sizeof(Quadric) * bm->totvert, __func__); + eheap = BLI_heap_new(); + eheap_table = MEM_callocN(sizeof(HeapNode *) * bm->totedge, __func__); + tot_edge_orig = bm->totedge; + + + /* build initial edge collapse cost data */ + bm_decim_build_quadrics(bm, vquadrics); + + bm_decim_build_edge_cost(bm, vquadrics, eheap, eheap_table); + + face_tot_target = bm->totface * factor; + bm->elem_index_dirty |= BM_FACE | BM_EDGE | BM_VERT; + + + /* iterative edge collapse and maintain the eheap */ + while ((bm->totface > face_tot_target) && (BLI_heap_empty(eheap) == FALSE)) { + BMEdge *e = BLI_heap_popmin(eheap); + BLI_assert(BM_elem_index_get(e) < tot_edge_orig); /* handy to detect corruptions elsewhere */ + + /* under normal conditions wont be accessed again, + * but NULL just incase so we don't use freed node */ + eheap_table[BM_elem_index_get(e)] = NULL; + + bm_decim_edge_collapse(bm, e, vquadrics, eheap, eheap_table); + } + + +#ifdef USE_TRIANGULATE + /* its possible we only had triangles, skip this step in that case */ + if (LIKELY(use_triangulate)) { + /* temp convert quads to triangles */ + bm_decim_triangulate_end(bm); + } +#endif + + + /* free vars */ + MEM_freeN(vquadrics); + MEM_freeN(eheap_table); + BLI_heap_free(eheap, NULL); +} diff --git a/source/blender/bmesh/intern/bmesh_decimate.h b/source/blender/bmesh/intern/bmesh_decimate.h new file mode 100644 index 00000000000..e44aa576bda --- /dev/null +++ b/source/blender/bmesh/intern/bmesh_decimate.h @@ -0,0 +1,32 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Campbell Barton + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef __BMESH_DECIMATE_H__ +#define __BMESH_DECIMATE_H__ + +/** \file blender/bmesh/intern/bmesh_decimate.h + * \ingroup bmesh + */ + +void BM_mesh_decimate(BMesh *bm, const float factor); + +#endif /* __BMESH_DECIMATE_H__ */ From cf4f4e8a9ba973a22d832b9babb8e7b9d34a6e28 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Fri, 19 Oct 2012 08:49:49 +0000 Subject: [PATCH 317/347] Fix: Text fields for Generator FModifier were too small This was caused by the x^n labels being far too large. Also, replaced old string functions with "safer" versions --- .../blender/editors/animation/fmodifier_ui.c | 43 ++++++++++++------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/source/blender/editors/animation/fmodifier_ui.c b/source/blender/editors/animation/fmodifier_ui.c index 30e4d8570cb..a591b51b0b3 100644 --- a/source/blender/editors/animation/fmodifier_ui.c +++ b/source/blender/editors/animation/fmodifier_ui.c @@ -111,6 +111,7 @@ static void draw_modifier__generator(uiLayout *layout, ID *id, FModifier *fcm, s uiBlock *block; uiBut *but; PointerRNA ptr; + short bwidth = width - 30; /* max button width */ /* init the RNA-pointer */ RNA_pointer_create(id, &RNA_FModifierFunctionGenerator, fcm, &ptr); @@ -119,10 +120,10 @@ static void draw_modifier__generator(uiLayout *layout, ID *id, FModifier *fcm, s /* col = uiLayoutColumn(layout, TRUE); */ /* UNUSED */ block = uiLayoutGetBlock(layout); uiBlockBeginAlign(block); - but = uiDefButR(block, MENU, B_FMODIFIER_REDRAW, NULL, 0, 0, width - 30, UI_UNIT_Y, &ptr, "mode", -1, 0, 0, -1, -1, NULL); + but = uiDefButR(block, MENU, B_FMODIFIER_REDRAW, NULL, 0, 0, bwidth, UI_UNIT_Y, &ptr, "mode", -1, 0, 0, -1, -1, NULL); uiButSetFunc(but, validate_fmodifier_cb, fcm, NULL); - - uiDefButR(block, TOG, B_FMODIFIER_REDRAW, NULL, 0, 0, width - 30, UI_UNIT_Y, &ptr, "use_additive", -1, 0, 0, -1, -1, NULL); + + uiDefButR(block, TOG, B_FMODIFIER_REDRAW, NULL, 0, 0, bwidth, UI_UNIT_Y, &ptr, "use_additive", -1, 0, 0, -1, -1, NULL); uiBlockEndAlign(block); /* now add settings for individual modes */ @@ -132,50 +133,62 @@ static void draw_modifier__generator(uiLayout *layout, ID *id, FModifier *fcm, s float *cp = NULL; char xval[32]; unsigned int i; + int maxXWidth; /* draw polynomial order selector */ row = uiLayoutRow(layout, FALSE); block = uiLayoutGetBlock(row); - but = uiDefButI(block, NUM, B_FMODIFIER_REDRAW, IFACE_("Poly Order:"), 10, 0, width - 30, 19, + but = uiDefButI(block, NUM, B_FMODIFIER_REDRAW, IFACE_("Poly Order:"), 10, 0, bwidth, 20, &data->poly_order, 1, 100, 0, 0, TIP_("'Order' of the Polynomial (for a polynomial with n terms, 'order' is n-1)")); uiButSetFunc(but, validate_fmodifier_cb, fcm, NULL); + /* calculate maximum width of label for "x^n" labels */ + if (data->arraysize > 2) { + BLI_snprintf(xval, sizeof(xval), "x^%u", data->arraysize); + maxXWidth = UI_GetStringWidth(xval) + 10; /* XXX: UI_GetStringWidth is not accurate */ + } + else { + /* basic size (just "x") */ + maxXWidth = 15; + } + /* draw controls for each coefficient and a + sign at end of row */ row = uiLayoutRow(layout, TRUE); block = uiLayoutGetBlock(row); cp = data->coefficients; for (i = 0; (i < data->arraysize) && (cp); i++, cp++) { - /* To align with first line */ + /* To align with first line... */ if (i) - uiDefBut(block, LABEL, 1, " ", 0, 0, 50, 20, NULL, 0.0, 0.0, 0, 0, ""); + uiDefBut(block, LABEL, 1, " ", 0, 0, 40, 20, NULL, 0.0, 0.0, 0, 0, ""); else - uiDefBut(block, LABEL, 1, "y =", 0, 0, 50, 20, NULL, 0.0, 0.0, 0, 0, ""); + uiDefBut(block, LABEL, 1, "y =", 0, 0, 40, 20, NULL, 0.0, 0.0, 0, 0, ""); + /* coefficient */ - uiDefButF(block, NUM, B_FMODIFIER_REDRAW, "", 0, 0, 150, 20, cp, -UI_FLT_MAX, UI_FLT_MAX, + uiDefButF(block, NUM, B_FMODIFIER_REDRAW, "", 0, 0, bwidth/2, 20, cp, -UI_FLT_MAX, UI_FLT_MAX, 10, 3, TIP_("Coefficient for polynomial")); /* 'x' param (and '+' if necessary) */ if (i == 0) - strcpy(xval, ""); + BLI_strncpy(xval, "", sizeof(xval)); else if (i == 1) - strcpy(xval, "x"); + BLI_strncpy(xval, "x", sizeof(xval)); else - sprintf(xval, "x^%u", i); - uiDefBut(block, LABEL, 1, xval, 0, 0, 50, 20, NULL, 0.0, 0.0, 0, 0, TIP_("Power of x")); + BLI_snprintf(xval, sizeof(xval), "x^%u", i); + uiDefBut(block, LABEL, 1, xval, 0, 0, maxXWidth, 20, NULL, 0.0, 0.0, 0, 0, TIP_("Power of x")); if ( (i != (data->arraysize - 1)) || ((i == 0) && data->arraysize == 2) ) { - uiDefBut(block, LABEL, 1, "+", 0, 0, 30, 20, NULL, 0.0, 0.0, 0, 0, ""); + uiDefBut(block, LABEL, 1, "+", 0, 0, 20, 20, NULL, 0.0, 0.0, 0, 0, ""); /* next coefficient on a new row */ row = uiLayoutRow(layout, TRUE); block = uiLayoutGetBlock(row); } else { - /* For alignement in UI! */ - uiDefBut(block, LABEL, 1, " ", 0, 0, 30, 20, NULL, 0.0, 0.0, 0, 0, ""); + /* For alignment in UI! */ + uiDefBut(block, LABEL, 1, " ", 0, 0, 20, 20, NULL, 0.0, 0.0, 0, 0, ""); } } break; From 9d1873154fe0763900a41eb2248f6a89cbdc1a26 Mon Sep 17 00:00:00 2001 From: Gaia Clary Date: Fri, 19 Oct 2012 08:51:31 +0000 Subject: [PATCH 318/347] [#32921] Fix: Python error triggered when installing an addon via 'install addon' button --- release/scripts/startup/bl_operators/wm.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py index 21cd2b47f71..61959c1a789 100644 --- a/release/scripts/startup/bl_operators/wm.py +++ b/release/scripts/startup/bl_operators/wm.py @@ -1755,6 +1755,7 @@ class WM_OT_addon_install(Operator): #check to see if the file is in compressed format (.zip) if zipfile.is_zipfile(pyfile): + is_archive = True try: file_to_extract = zipfile.ZipFile(pyfile, 'r') except: @@ -1784,6 +1785,7 @@ class WM_OT_addon_install(Operator): return {'CANCELLED'} else: + is_archive = False path_dest = os.path.join(path_addons, os.path.basename(pyfile)) if self.overwrite: @@ -1823,9 +1825,19 @@ class WM_OT_addon_install(Operator): bpy.utils.refresh_script_paths() # print message - msg = "File %r installed into %r\n" % (pyfile, path_dest) - self.report({'INFO'}, msg) + msg = "Modules Installed from %r:" % (pyfile) print(msg) + self.report({'INFO'}, msg) + for mod in addon_utils.modules(addon_utils.addons_fake_modules): + if mod.__name__ in addons_new: + info = addon_utils.module_bl_info(mod) + if is_archive: + module_path = os.path.dirname(os.path.abspath(mod.__file__)) + else: + module_path = os.path.abspath(mod.__file__) + msg = "\"%s\" installed in %r" % (info["name"],module_path) + self.report({'INFO'}, msg) + print(msg) return {'FINISHED'} From b7642348e44c10710c0d3f65ccfdafdd964829a2 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 19 Oct 2012 10:37:24 +0000 Subject: [PATCH 319/347] simplify addon install print, Now it only prints the source and destination dirs, with a list of addons added. don't think its needed to print the full path of each addon. also remove the __MACOX check, its harmless and people can make sure there zips dont have cruft in them before distributing them. --- release/scripts/startup/bl_operators/wm.py | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py index 61959c1a789..ac72b39a04d 100644 --- a/release/scripts/startup/bl_operators/wm.py +++ b/release/scripts/startup/bl_operators/wm.py @@ -1755,7 +1755,6 @@ class WM_OT_addon_install(Operator): #check to see if the file is in compressed format (.zip) if zipfile.is_zipfile(pyfile): - is_archive = True try: file_to_extract = zipfile.ZipFile(pyfile, 'r') except: @@ -1774,18 +1773,11 @@ class WM_OT_addon_install(Operator): try: # extract the file to "addons" file_to_extract.extractall(path_addons) - - # zip files can create this dir with metadata, don't need it - macosx_dir = os.path.join(path_addons, '__MACOSX') - if os.path.isdir(macosx_dir): - shutil.rmtree(macosx_dir) - except: traceback.print_exc() return {'CANCELLED'} else: - is_archive = False path_dest = os.path.join(path_addons, os.path.basename(pyfile)) if self.overwrite: @@ -1825,19 +1817,9 @@ class WM_OT_addon_install(Operator): bpy.utils.refresh_script_paths() # print message - msg = "Modules Installed from %r:" % (pyfile) + msg = "Modules Installed from %r into %r (%s)" % (pyfile, path_addons, ", ".join(sorted(addons_new))) print(msg) self.report({'INFO'}, msg) - for mod in addon_utils.modules(addon_utils.addons_fake_modules): - if mod.__name__ in addons_new: - info = addon_utils.module_bl_info(mod) - if is_archive: - module_path = os.path.dirname(os.path.abspath(mod.__file__)) - else: - module_path = os.path.abspath(mod.__file__) - msg = "\"%s\" installed in %r" % (info["name"],module_path) - self.report({'INFO'}, msg) - print(msg) return {'FINISHED'} From e527ce552e9e3864c7a2f5bb688ffa1d4cd0d5f1 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 19 Oct 2012 10:40:32 +0000 Subject: [PATCH 320/347] add option to initialize heap with a known number of elements, since this may be known in advance - it avoids re-allocing too much. --- source/blender/blenlib/BLI_heap.h | 1 + source/blender/blenlib/intern/BLI_heap.c | 12 +++++-- source/blender/bmesh/intern/bmesh_decimate.c | 2 +- .../blender/modifiers/intern/MOD_decimate.c | 32 +++++++++++++++++++ 4 files changed, 43 insertions(+), 4 deletions(-) diff --git a/source/blender/blenlib/BLI_heap.h b/source/blender/blenlib/BLI_heap.h index b378f2bb365..9d7e6107f19 100644 --- a/source/blender/blenlib/BLI_heap.h +++ b/source/blender/blenlib/BLI_heap.h @@ -42,6 +42,7 @@ typedef void (*HeapFreeFP)(void *ptr); /* Creates a new heap. BLI_memarena is used for allocating nodes. Removed nodes * are recycled, so memory usage will not shrink. */ +Heap *BLI_heap_new_ex(unsigned int tot_reserve); Heap *BLI_heap_new(void); void BLI_heap_free(Heap *heap, HeapFreeFP ptrfreefp); diff --git a/source/blender/blenlib/intern/BLI_heap.c b/source/blender/blenlib/intern/BLI_heap.c index ee7d93ea1a9..5e0762a5d68 100644 --- a/source/blender/blenlib/intern/BLI_heap.c +++ b/source/blender/blenlib/intern/BLI_heap.c @@ -67,16 +67,22 @@ struct Heap { /***/ -Heap *BLI_heap_new(void) +/* use when the size of the heap is known in advance */ +Heap *BLI_heap_new_ex(unsigned int tot_reserve) { Heap *heap = (Heap *)MEM_callocN(sizeof(Heap), __func__); - heap->bufsize = 1; - heap->tree = (HeapNode **)MEM_mallocN(sizeof(HeapNode *), "BLIHeapTree"); + heap->bufsize = tot_reserve; + heap->tree = (HeapNode **)MEM_mallocN(tot_reserve * sizeof(HeapNode *), "BLIHeapTree"); heap->arena = BLI_memarena_new(1 << 16, "heap arena"); return heap; } +Heap *BLI_heap_new(void) +{ + return BLI_heap_new_ex(1); +} + void BLI_heap_free(Heap *heap, HeapFreeFP ptrfreefp) { int i; diff --git a/source/blender/bmesh/intern/bmesh_decimate.c b/source/blender/bmesh/intern/bmesh_decimate.c index d8aa8adef55..122f24955c6 100644 --- a/source/blender/bmesh/intern/bmesh_decimate.c +++ b/source/blender/bmesh/intern/bmesh_decimate.c @@ -531,7 +531,7 @@ void BM_mesh_decimate(BMesh *bm, const float factor) /* alloc vars */ vquadrics = MEM_callocN(sizeof(Quadric) * bm->totvert, __func__); - eheap = BLI_heap_new(); + eheap = BLI_heap_new_ex(bm->totedge); eheap_table = MEM_callocN(sizeof(HeapNode *) * bm->totedge, __func__); tot_edge_orig = bm->totedge; diff --git a/source/blender/modifiers/intern/MOD_decimate.c b/source/blender/modifiers/intern/MOD_decimate.c index cb6681bfa68..171d601ea6d 100644 --- a/source/blender/modifiers/intern/MOD_decimate.c +++ b/source/blender/modifiers/intern/MOD_decimate.c @@ -47,6 +47,10 @@ #include "BKE_particle.h" #include "BKE_cdderivedmesh.h" +#include "BKE_tessmesh.h" + +/* testing only! - Campbell */ +// #define USE_DECIMATE_BMESH #ifdef WITH_MOD_DECIMATE #include "LOD_decimation.h" @@ -70,6 +74,33 @@ static void copyData(ModifierData *md, ModifierData *target) } #ifdef WITH_MOD_DECIMATE +#ifdef USE_DECIMATE_BMESH + +#include "bmesh.h" + +static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob), + DerivedMesh *derivedData, + ModifierApplyFlag UNUSED(flag)) +{ + DecimateModifierData *dmd = (DecimateModifierData *) md; + DerivedMesh *dm = derivedData, *result = NULL; + BMEditMesh *em; + BMesh *bm; + + em = DM_to_editbmesh(dm, NULL, FALSE); + bm = em->bm; + + BM_mesh_decimate(bm, dmd->percent); + + BLI_assert(em->looptris == NULL); + result = CDDM_from_BMEditMesh(em, NULL, TRUE, FALSE); + BMEdit_Free(em); + MEM_freeN(em); + + return result; +} + +#else static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob), DerivedMesh *derivedData, ModifierApplyFlag UNUSED(flag)) @@ -192,6 +223,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob), return dm; } } +#endif // USE_DECIMATE_BMESH #else // WITH_MOD_DECIMATE static DerivedMesh *applyModifier(ModifierData *UNUSED(md), Object *UNUSED(ob), DerivedMesh *derivedData, From 4c936221a3ac29d9d356c340a35fa463575d7838 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 19 Oct 2012 11:47:33 +0000 Subject: [PATCH 321/347] Fix #32705: Esc a value change doesn't recalc compositor Seems the issue was caused by G.is_break set to Truth on both escape press and release. This ended up in situation when after press event compositor was tagged to redraw and new job was started. On escape release this compositor job was cancelled. Made it so G.is_break is setting on escape press event only. --- source/blender/windowmanager/intern/wm_event_system.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 8114eb651fb..73950bdfa19 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -2924,7 +2924,7 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U event.keymodifier = 0; /* if test_break set, it catches this. XXX Keep global for now? */ - if (event.type == ESCKEY) + if (event.type == ESCKEY && event.val == KM_PRESS) G.is_break = TRUE; wm_event_add(win, &event); From 3a41ab73ff4e480fe5b86c2845f0fb4f9df113d7 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 19 Oct 2012 12:45:31 +0000 Subject: [PATCH 322/347] fix for some issues with modal mesh tool interaction. When inset and bevel used the mouse input as a distance value, the change could be far too great when zoomed in, or far too small when zoomed out. Now get the pixel-size based on the center point of the selection. --- source/blender/editors/mesh/editmesh_tools.c | 84 ++++++++++++++------ 1 file changed, 60 insertions(+), 24 deletions(-) diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 3255853442a..695afd44408 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -75,6 +75,8 @@ #include "mesh_intern.h" +#define MVAL_PIXEL_MARGIN 5.0f + /* allow accumulated normals to form a new direction but don't * accept direct opposite directions else they will cancel each other out */ static void add_normal_aligned(float nor[3], const float add[3]) @@ -4516,6 +4518,7 @@ typedef struct { int li; int mcenter[2]; float initial_length; + float pixel_size; /* use when mouse input is interpreted as spatial distance */ int is_modal; NumInput num_input; float shift_factor; /* The current factor when shift is pressed. Negative when shift not active. */ @@ -4713,8 +4716,10 @@ static int edbm_bevel_exec(bContext *C, wmOperator *op) static int edbm_bevel_invoke(bContext *C, wmOperator *op, wmEvent *event) { /* TODO make modal keymap (see fly mode) */ + RegionView3D *rv3d = CTX_wm_region_view3d(C); BevelData *opdata; float mlen[2]; + float center_3d[3]; if (!edbm_bevel_init(C, op, TRUE)) { return OPERATOR_CANCELLED; @@ -4723,7 +4728,7 @@ static int edbm_bevel_invoke(bContext *C, wmOperator *op, wmEvent *event) opdata = op->customdata; /* initialize mouse values */ - if (!calculateTransformCenter(C, V3D_CENTROID, NULL, opdata->mcenter)) { + if (!calculateTransformCenter(C, V3D_CENTROID, center_3d, opdata->mcenter)) { /* in this case the tool will likely do nothing, * ideally this will never happen and should be checked for above */ opdata->mcenter[0] = opdata->mcenter[1] = 0; @@ -4731,6 +4736,7 @@ static int edbm_bevel_invoke(bContext *C, wmOperator *op, wmEvent *event) mlen[0] = opdata->mcenter[0] - event->mval[0]; mlen[1] = opdata->mcenter[1] - event->mval[1]; opdata->initial_length = len_v2(mlen); + opdata->pixel_size = rv3d ? ED_view3d_pixel_size(rv3d, center_3d) : 1.0f; edbm_bevel_update_header(op, C); @@ -4744,6 +4750,44 @@ static int edbm_bevel_invoke(bContext *C, wmOperator *op, wmEvent *event) return OPERATOR_RUNNING_MODAL; } +static float edbm_bevel_mval_factor(wmOperator *op, wmEvent *event) +{ + BevelData *opdata = op->customdata; + int use_dist = RNA_boolean_get(op->ptr, "use_dist"); + float mdiff[2]; + float factor; + + mdiff[0] = opdata->mcenter[0] - event->mval[0]; + mdiff[1] = opdata->mcenter[1] - event->mval[1]; + + if (use_dist) { + factor = ((len_v2(mdiff) - MVAL_PIXEL_MARGIN) - opdata->initial_length) * opdata->pixel_size; + } + else { + factor = (len_v2(mdiff) - MVAL_PIXEL_MARGIN) / opdata->initial_length; + factor = factor - 1.0f; /* a different kind of buffer where nothing happens */ + } + + /* Fake shift-transform... */ + if (event->shift) { + if (opdata->shift_factor < 0.0f) + opdata->shift_factor = RNA_float_get(op->ptr, "percent"); + factor = (factor - opdata->shift_factor) * 0.1f + opdata->shift_factor; + } + else if (opdata->shift_factor >= 0.0f) + opdata->shift_factor = -1.0f; + + /* clamp differently based on distance/factor */ + if (use_dist) { + if (factor < 0.0f) factor = 0.0f; + } + else { + CLAMP(factor, 0.0f, 1.0f); + } + + return factor; +} + static int edbm_bevel_modal(bContext *C, wmOperator *op, wmEvent *event) { BevelData *opdata = op->customdata; @@ -4771,25 +4815,7 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, wmEvent *event) case MOUSEMOVE: if (!hasNumInput(&opdata->num_input)) { - float factor; - float mdiff[2]; - - mdiff[0] = opdata->mcenter[0] - event->mval[0]; - mdiff[1] = opdata->mcenter[1] - event->mval[1]; - - factor = opdata->initial_length / -len_v2(mdiff) + 1.0f; - - /* Fake shift-transform... */ - if (event->shift) { - if (opdata->shift_factor < 0.0f) - opdata->shift_factor = RNA_float_get(op->ptr, "percent"); - factor = (factor - opdata->shift_factor) * 0.1f + opdata->shift_factor; - } - else if (opdata->shift_factor >= 0.0f) - opdata->shift_factor = -1.0f; - - CLAMP(factor, 0.0f, 1.0f); - + const float factor = edbm_bevel_mval_factor(op, event); RNA_float_set(op->ptr, "percent", factor); edbm_bevel_calc(C, op); @@ -4819,6 +4845,11 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, wmEvent *event) int use_dist = RNA_boolean_get(op->ptr, "use_dist"); RNA_boolean_set(op->ptr, "use_dist", !use_dist); + { + const float factor = edbm_bevel_mval_factor(op, event); + RNA_float_set(op->ptr, "percent", factor); + } + edbm_bevel_calc(C, op); edbm_bevel_update_header(op, C); } @@ -4845,6 +4876,7 @@ void MESH_OT_bevel(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_GRAB_POINTER | OPTYPE_BLOCKING; + /* take note, used as a factor _and_ a distance depending on 'use_dist' */ RNA_def_float(ot->srna, "percent", 0.0f, -FLT_MAX, FLT_MAX, "Percentage", "", 0.0f, 1.0f); /* XXX, disabled for 2.63 release, needs to work much better without overlap before we can give to users. */ /* RNA_def_int(ot->srna, "recursion", 1, 1, 50, "Recursion Level", "Recursion Level", 1, 8); */ @@ -4909,8 +4941,9 @@ typedef struct { float old_depth; int mcenter[2]; int modify_depth; - int is_modal; float initial_length; + float pixel_size; /* use when mouse input is interpreted as spatial distance */ + int is_modal; int shift; float shift_amount; BMBackup backup; @@ -5076,15 +5109,17 @@ static int edbm_inset_exec(bContext *C, wmOperator *op) static int edbm_inset_invoke(bContext *C, wmOperator *op, wmEvent *event) { + RegionView3D *rv3d = CTX_wm_region_view3d(C); InsetData *opdata; float mlen[2]; + float center_3d[3]; edbm_inset_init(C, op, TRUE); opdata = op->customdata; /* initialize mouse values */ - if (!calculateTransformCenter(C, V3D_CENTROID, NULL, opdata->mcenter)) { + if (!calculateTransformCenter(C, V3D_CENTROID, center_3d, opdata->mcenter)) { /* in this case the tool will likely do nothing, * ideally this will never happen and should be checked for above */ opdata->mcenter[0] = opdata->mcenter[1] = 0; @@ -5092,6 +5127,7 @@ static int edbm_inset_invoke(bContext *C, wmOperator *op, wmEvent *event) mlen[0] = opdata->mcenter[0] - event->mval[0]; mlen[1] = opdata->mcenter[1] - event->mval[1]; opdata->initial_length = len_v2(mlen); + opdata->pixel_size = rv3d ? ED_view3d_pixel_size(rv3d, center_3d) : 1.0f; edbm_inset_calc(C, op); @@ -5141,9 +5177,9 @@ static int edbm_inset_modal(bContext *C, wmOperator *op, wmEvent *event) mdiff[1] = opdata->mcenter[1] - event->mval[1]; if (opdata->modify_depth) - amount = opdata->old_depth + opdata->initial_length / len_v2(mdiff) - 1.0f; + amount = opdata->old_depth + ((len_v2(mdiff) - opdata->initial_length) * opdata->pixel_size); else - amount = opdata->old_thickness - opdata->initial_length / len_v2(mdiff) + 1.0f; + amount = opdata->old_thickness - ((len_v2(mdiff) - opdata->initial_length) * opdata->pixel_size); /* Fake shift-transform... */ if (opdata->shift) From a75f11d03678b094d608382c50d0bb299c53ed1c Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 19 Oct 2012 12:53:03 +0000 Subject: [PATCH 323/347] Fix #32219: Inconsistent influence of Units Scale on new objects Made it so meshes, curves, surfaces and metaballs are scaling to a grid cell size, which makes them behave consistently now. There're still issues to be resolved still: - Lattice is not scaled to grid cell size yet, it uses slightly different add function which makes scaling a bit tricky and hacky. Would prefer to do a bit bigger refactor here, so it's a TODO for now. - Cameras, speakers and other helpers are not scaling. They don't have data on which scale could be applied and perhaps it should be some kind of draw scale. Also would consider it's a TODO for now. --- .../modules/bpy_extras/object_utils.py | 13 +++++++++++ .../startup/bl_operators/add_mesh_torus.py | 6 +++-- source/blender/editors/curve/editcurve.c | 10 +++----- source/blender/editors/include/ED_mball.h | 2 +- source/blender/editors/include/ED_object.h | 3 ++- source/blender/editors/mesh/editmesh_add.c | 22 ++++++++++-------- source/blender/editors/metaball/mball_edit.c | 3 ++- source/blender/editors/object/object_add.c | 23 ++++++++++++++----- source/blender/makesrna/intern/rna_space.c | 16 ++++++++++++- 9 files changed, 70 insertions(+), 28 deletions(-) diff --git a/release/scripts/modules/bpy_extras/object_utils.py b/release/scripts/modules/bpy_extras/object_utils.py index b1de1fd47a4..46731b807f7 100644 --- a/release/scripts/modules/bpy_extras/object_utils.py +++ b/release/scripts/modules/bpy_extras/object_utils.py @@ -187,3 +187,16 @@ class AddObjectHelper: name="Rotation", subtype='EULER', ) + + +def object_add_grid_scale(context): + """ + Return scale which should be applied on object data to align it to grid scale + """ + + space_data = context.space_data + + if space_data and space_data.type == 'VIEW_3D': + return space_data.grid_scale_unit + + return 1.0 diff --git a/release/scripts/startup/bl_operators/add_mesh_torus.py b/release/scripts/startup/bl_operators/add_mesh_torus.py index 7da4d8a480d..552247f0940 100644 --- a/release/scripts/startup/bl_operators/add_mesh_torus.py +++ b/release/scripts/startup/bl_operators/add_mesh_torus.py @@ -133,13 +133,15 @@ class AddTorus(Operator, object_utils.AddObjectHelper): ) def execute(self, context): + grid_scale = object_utils.object_add_grid_scale(context) + if self.use_abso is True: extra_helper = (self.abso_major_rad - self.abso_minor_rad) * 0.5 self.major_radius = self.abso_minor_rad + extra_helper self.minor_radius = extra_helper - verts_loc, faces = add_torus(self.major_radius, - self.minor_radius, + verts_loc, faces = add_torus(self.major_radius * grid_scale, + self.minor_radius * grid_scale, self.major_segments, self.minor_segments) diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index 98dc8aa6eb9..19c7fc39c82 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -6486,12 +6486,7 @@ Nurb *add_nurbs_primitive(bContext *C, Object *obedit, float mat[4][4], int type vec[0] = vec[1] = 0.0; vec[2] = -grid; - if (newob && (U.flag & USER_ADD_VIEWALIGNED) == 0) { - /* pass */ - } - else { - mul_mat3_m4_v3(mat, vec); - } + mul_mat3_m4_v3(mat, vec); translateflagNurb(editnurb, 1, vec); extrudeflagNurb(cu->editnurb, 1); @@ -6609,6 +6604,7 @@ static int curvesurf_prim_add(bContext *C, wmOperator *op, int type, int isSurf) unsigned int layer; float loc[3], rot[3]; float mat[4][4]; + float dia; if (!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, &is_aligned)) return OPERATOR_CANCELLED; @@ -6652,7 +6648,7 @@ static int curvesurf_prim_add(bContext *C, wmOperator *op, int type, int isSurf) if (newob && enter_editmode) ED_undo_push(C, "Enter Editmode"); - ED_object_new_primitive_matrix(C, obedit, loc, rot, mat); + dia = ED_object_new_primitive_matrix(C, obedit, loc, rot, mat, TRUE); nu = add_nurbs_primitive(C, obedit, mat, type, newob); editnurb = object_editcurve_get(obedit); diff --git a/source/blender/editors/include/ED_mball.h b/source/blender/editors/include/ED_mball.h index 5ce6db97305..1321765588d 100644 --- a/source/blender/editors/include/ED_mball.h +++ b/source/blender/editors/include/ED_mball.h @@ -38,7 +38,7 @@ struct wmKeyConfig; void ED_operatortypes_metaball(void); void ED_keymap_metaball(struct wmKeyConfig *keyconf); -struct MetaElem *add_metaball_primitive(struct bContext *C, struct Object *obedit, float mat[4][4], int type, int newname); +struct MetaElem *add_metaball_primitive(struct bContext *C, struct Object *obedit, float mat[4][4], float dia, int type, int newname); int mouse_mball(struct bContext *C, const int mval[2], int extend, int deselect, int toggle); diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h index 3f66333f0d5..d6ac9eb750d 100644 --- a/source/blender/editors/include/ED_object.h +++ b/source/blender/editors/include/ED_object.h @@ -134,7 +134,8 @@ void ED_object_location_from_view(struct bContext *C, float loc[3]); void ED_object_rotation_from_view(struct bContext *C, float rot[3]); void ED_object_base_init_transform(struct bContext *C, struct Base *base, const float loc[3], const float rot[3]); float ED_object_new_primitive_matrix(struct bContext *C, struct Object *editob, - const float loc[3], const float rot[3], float primmat[][4]); + const float loc[3], const float rot[3], float primmat[][4], + int apply_diameter); void ED_object_add_generic_props(struct wmOperatorType *ot, int do_editmode); int ED_object_add_generic_get_opts(struct bContext *C, struct wmOperator *op, float loc[3], float rot[3], diff --git a/source/blender/editors/mesh/editmesh_add.c b/source/blender/editors/mesh/editmesh_add.c index 0cf4ac48bf7..99ed86d7a06 100644 --- a/source/blender/editors/mesh/editmesh_add.c +++ b/source/blender/editors/mesh/editmesh_add.c @@ -73,7 +73,7 @@ static Object *make_prim_init(bContext *C, const char *idname, *state = 1; } - *dia = ED_object_new_primitive_matrix(C, obedit, loc, rot, mat); + *dia = ED_object_new_primitive_matrix(C, obedit, loc, rot, mat, FALSE); return obedit; } @@ -200,7 +200,7 @@ static int add_primitive_circle_exec(bContext *C, wmOperator *op) if (!EDBM_op_call_and_selectf(em, op, "vertout", "create_circle segments=%i diameter=%f cap_ends=%b cap_tris=%b mat=%m4", - RNA_int_get(op->ptr, "vertices"), RNA_float_get(op->ptr, "radius"), + RNA_int_get(op->ptr, "vertices"), RNA_float_get(op->ptr, "radius") * dia, cap_end, cap_tri, mat)) { return OPERATOR_CANCELLED; @@ -256,10 +256,10 @@ static int add_primitive_cylinder_exec(bContext *C, wmOperator *op) em, op, "vertout", "create_cone segments=%i diameter1=%f diameter2=%f cap_ends=%b cap_tris=%b depth=%f mat=%m4", RNA_int_get(op->ptr, "vertices"), - RNA_float_get(op->ptr, "radius"), - RNA_float_get(op->ptr, "radius"), + RNA_float_get(op->ptr, "radius") * dia, + RNA_float_get(op->ptr, "radius") * dia, cap_end, cap_tri, - RNA_float_get(op->ptr, "depth"), mat)) + RNA_float_get(op->ptr, "depth") * dia, mat)) { return OPERATOR_CANCELLED; } @@ -315,8 +315,8 @@ static int add_primitive_cone_exec(bContext *C, wmOperator *op) if (!EDBM_op_call_and_selectf( em, op, "vertout", "create_cone segments=%i diameter1=%f diameter2=%f cap_ends=%b cap_tris=%b depth=%f mat=%m4", - RNA_int_get(op->ptr, "vertices"), RNA_float_get(op->ptr, "radius1"), - RNA_float_get(op->ptr, "radius2"), cap_end, cap_tri, RNA_float_get(op->ptr, "depth"), mat)) + RNA_int_get(op->ptr, "vertices"), RNA_float_get(op->ptr, "radius1") * dia, + RNA_float_get(op->ptr, "radius2") * dia, cap_end, cap_tri, RNA_float_get(op->ptr, "depth") * dia, mat)) { return OPERATOR_CANCELLED; } @@ -421,6 +421,10 @@ static int add_primitive_monkey_exec(bContext *C, wmOperator *op) rot[0] += (float)M_PI / 2.0f; obedit = make_prim_init(C, "Monkey", &dia, mat, &state, loc, rot, layer); + mat[0][0] *= dia; + mat[1][1] *= dia; + mat[2][2] *= dia; + em = BMEdit_FromObject(obedit); if (!EDBM_op_call_and_selectf(em, op, "vertout", "create_monkey mat=%m4", mat)) { @@ -465,7 +469,7 @@ static int add_primitive_uvsphere_exec(bContext *C, wmOperator *op) if (!EDBM_op_call_and_selectf(em, op, "vertout", "create_uvsphere segments=%i revolutions=%i diameter=%f mat=%m4", RNA_int_get(op->ptr, "segments"), RNA_int_get(op->ptr, "ring_count"), - RNA_float_get(op->ptr, "size"), mat)) + RNA_float_get(op->ptr, "size") * dia, mat)) { return OPERATOR_CANCELLED; } @@ -517,7 +521,7 @@ static int add_primitive_icosphere_exec(bContext *C, wmOperator *op) em, op, "vertout", "create_icosphere subdivisions=%i diameter=%f mat=%m4", RNA_int_get(op->ptr, "subdivisions"), - RNA_float_get(op->ptr, "size"), mat)) + RNA_float_get(op->ptr, "size") * dia, mat)) { return OPERATOR_CANCELLED; } diff --git a/source/blender/editors/metaball/mball_edit.c b/source/blender/editors/metaball/mball_edit.c index e9063687506..b9018914633 100644 --- a/source/blender/editors/metaball/mball_edit.c +++ b/source/blender/editors/metaball/mball_edit.c @@ -98,7 +98,7 @@ void load_editMball(Object *UNUSED(obedit)) } /* Add metaelem primitive to metaball object (which is in edit mode) */ -MetaElem *add_metaball_primitive(bContext *UNUSED(C), Object *obedit, float mat[4][4], int type, int UNUSED(newname)) +MetaElem *add_metaball_primitive(bContext *UNUSED(C), Object *obedit, float mat[4][4], float dia, int type, int UNUSED(newname)) { MetaBall *mball = (MetaBall *)obedit->data; MetaElem *ml; @@ -111,6 +111,7 @@ MetaElem *add_metaball_primitive(bContext *UNUSED(C), Object *obedit, float mat[ } ml = BKE_mball_element_add(mball, type); + ml->rad *= dia; copy_v3_v3(&ml->x, mat[3]); ml->flag |= SELECT; diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index dc20e0d69cd..9a2915a5d55 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -186,7 +186,8 @@ void ED_object_base_init_transform(bContext *C, Base *base, const float loc[3], /* Uses context to figure out transform for primitive. * Returns standard diameter. */ float ED_object_new_primitive_matrix(bContext *C, Object *obedit, - const float loc[3], const float rot[3], float primmat[][4]) + const float loc[3], const float rot[3], float primmat[][4], + int apply_diameter) { Scene *scene = CTX_data_scene(C); View3D *v3d = CTX_wm_view3d(C); @@ -209,8 +210,17 @@ float ED_object_new_primitive_matrix(bContext *C, Object *obedit, invert_m3_m3(imat, mat); mul_m3_v3(imat, primmat[3]); - if (v3d) - return ED_view3d_grid_scale(scene, v3d, NULL); + if (v3d) { + float dia = ED_view3d_grid_scale(scene, v3d, NULL); + + if (apply_diameter) { + primmat[0][0] *= dia; + primmat[1][1] *= dia; + primmat[2][2] *= dia; + } + + return dia; + } return 1.0f; } @@ -442,7 +452,7 @@ static int effector_add_exec(bContext *C, wmOperator *op) rename_id(&ob->id, "CurveGuide"); ((Curve *)ob->data)->flag |= CU_PATH | CU_3D; ED_object_enter_editmode(C, 0); - ED_object_new_primitive_matrix(C, ob, loc, rot, mat); + ED_object_new_primitive_matrix(C, ob, loc, rot, mat, FALSE); BLI_addtail(object_editcurve_get(ob), add_nurbs_primitive(C, ob, mat, CU_NURBS | CU_PRIM_PATH, 1)); if (!enter_editmode) ED_object_exit_editmode(C, EM_FREEDATA); @@ -547,6 +557,7 @@ static int object_metaball_add_exec(bContext *C, wmOperator *op) unsigned int layer; float loc[3], rot[3]; float mat[4][4]; + float dia; if (!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL)) return OPERATOR_CANCELLED; @@ -558,9 +569,9 @@ static int object_metaball_add_exec(bContext *C, wmOperator *op) else DAG_id_tag_update(&obedit->id, OB_RECALC_DATA); - ED_object_new_primitive_matrix(C, obedit, loc, rot, mat); + dia = ED_object_new_primitive_matrix(C, obedit, loc, rot, mat, FALSE); - add_metaball_primitive(C, obedit, mat, RNA_enum_get(op->ptr, "type"), newob); + add_metaball_primitive(C, obedit, mat, dia, RNA_enum_get(op->ptr, "type"), newob); /* userdef */ if (newob && !enter_editmode) { diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 13aa5557964..51fb9d413da 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -336,6 +336,15 @@ static void rna_View3D_CursorLocation_set(PointerRNA *ptr, const float *values) copy_v3_v3(cursor, values); } +static float rna_View3D_GridScaleUnit_get(PointerRNA *ptr) +{ + View3D *v3d = (View3D *)(ptr->data); + bScreen *sc = (bScreen *)ptr->id.data; + Scene *scene = (Scene *)sc->scene; + + return ED_view3d_grid_scale(scene, v3d, NULL); +} + static void rna_SpaceView3D_layer_set(PointerRNA *ptr, const int *values) { View3D *v3d = (View3D *)(ptr->data); @@ -1603,7 +1612,12 @@ static void rna_def_space_view3d(BlenderRNA *brna) RNA_def_property_range(prop, 1, 1024); RNA_def_property_int_default(prop, 10); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); - + + prop = RNA_def_property(srna, "grid_scale_unit", PROP_FLOAT, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_float_funcs(prop, "rna_View3D_GridScaleUnit_get", NULL, NULL); + RNA_def_property_ui_text(prop, "Grid Scale Unit", "Grid cell size scaled by scene unit system settings"); + prop = RNA_def_property(srna, "show_floor", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "gridflag", V3D_SHOW_FLOOR); RNA_def_property_ui_text(prop, "Display Grid Floor", "Show the ground plane grid in perspective view"); From ef80ff105fbcdb6af19bd341c1b80b269e63f2be Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Fri, 19 Oct 2012 13:51:37 +0000 Subject: [PATCH 324/347] Cycles/ Layer Weight Node: * Small tweak for the blend value, to avoid division by zero. Thanks to Brecht for pointing out the solution. --- intern/cycles/kernel/osl/nodes/node_layer_weight.osl | 2 +- intern/cycles/kernel/svm/svm_fresnel.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/intern/cycles/kernel/osl/nodes/node_layer_weight.osl b/intern/cycles/kernel/osl/nodes/node_layer_weight.osl index dc3eb81d712..40b60fee7d3 100644 --- a/intern/cycles/kernel/osl/nodes/node_layer_weight.osl +++ b/intern/cycles/kernel/osl/nodes/node_layer_weight.osl @@ -36,7 +36,7 @@ shader node_layer_weight( Facing = abs(dot(I, Normal)); if (blend != 0.5) { - blend = clamp(blend, 0.0, 1.0); + blend = clamp(blend, 0.0, 1.0-1e-5); blend = (blend < 0.5) ? 2.0 * blend : 0.5 / (1.0 - blend); Facing = pow(Facing, blend); diff --git a/intern/cycles/kernel/svm/svm_fresnel.h b/intern/cycles/kernel/svm/svm_fresnel.h index 7684eabeecb..d5b415a87ce 100644 --- a/intern/cycles/kernel/svm/svm_fresnel.h +++ b/intern/cycles/kernel/svm/svm_fresnel.h @@ -54,7 +54,7 @@ __device void svm_node_layer_weight(ShaderData *sd, float *stack, uint4 node) f = fabsf(dot(sd->I, sd->N)); if(blend != 0.5f) { - blend = clamp(blend, 0.0f, 1.0f); + blend = clamp(blend, 0.0f, 1.0f-1e-5f); blend = (blend < 0.5f)? 2.0f*blend: 0.5f/(1.0f - blend); f = powf(f, blend); From 1b2d2da69ab7d68497370c397f39247b3b48378a Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Fri, 19 Oct 2012 14:38:32 +0000 Subject: [PATCH 325/347] Add stub for new ED_view3d_grid_scale(). --- source/blenderplayer/bad_level_call_stubs/stubs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c index c6383b471f7..c410e97252c 100644 --- a/source/blenderplayer/bad_level_call_stubs/stubs.c +++ b/source/blenderplayer/bad_level_call_stubs/stubs.c @@ -297,6 +297,7 @@ struct BGpic *ED_view3D_background_image_new(struct View3D *v3d) {return (struct void ED_view3D_background_image_remove(struct View3D *v3d, struct BGpic *bgpic) {} void ED_view3D_background_image_clear(struct View3D *v3d) {} void ED_view3d_update_viewmat(struct Scene *scene, struct View3D *v3d, struct ARegion *ar, float viewmat[][4], float winmat[][4]) {} +float ED_view3d_grid_scale(struct Scene *scene, struct View3D *v3d, const char **grid_unit) {return 0.0f;} void view3d_apply_mat4(float mat[][4], float *ofs, float *quat, float *dist) {} int text_file_modified(struct Text *text) {return 0;} void ED_node_shader_default(struct Material *ma) {} From 97c68098cca15480f07afb28261021bb3548c89b Mon Sep 17 00:00:00 2001 From: Lukas Toenne Date: Fri, 19 Oct 2012 16:29:17 +0000 Subject: [PATCH 326/347] Additional debug assert in the compositor for checking correct conversion of Nodes to Operations. This will trigger an assert failure whenever a node has remaining socket connections after conversion. This would mean that not all sockets have been properly relinked and helps detect incomplete code. --- .../compositor/intern/COM_ExecutionSystem.cpp | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/source/blender/compositor/intern/COM_ExecutionSystem.cpp b/source/blender/compositor/intern/COM_ExecutionSystem.cpp index 0018cbbae9f..57ff5c5c838 100644 --- a/source/blender/compositor/intern/COM_ExecutionSystem.cpp +++ b/source/blender/compositor/intern/COM_ExecutionSystem.cpp @@ -25,6 +25,7 @@ #include #include "PIL_time.h" +#include "BLI_utildefines.h" #include "BKE_node.h" #include "COM_Converter.h" @@ -240,12 +241,32 @@ void ExecutionSystem::addReadWriteBufferOperations(NodeOperation *operation) } } +#ifndef NDEBUG +/* if this fails, there are still connection to/from this node, + * which have not been properly relinked to operations! + */ +static void debug_check_node_connections(Node *node) +{ + for (int i = 0; i < node->getNumberOfInputSockets(); ++i) { + BLI_assert(!node->getInputSocket(i)->isConnected()); + } + for (int i = 0; i < node->getNumberOfOutputSockets(); ++i) { + BLI_assert(!node->getOutputSocket(i)->isConnected()); + } +} +#else +/* stub */ +#define debug_check_node_connections(node) +#endif + void ExecutionSystem::convertToOperations() { unsigned int index; for (index = 0; index < this->m_nodes.size(); index++) { Node *node = (Node *)this->m_nodes[index]; node->convertToOperations(this, &this->m_context); + + debug_check_node_connections(node); } for (index = 0; index < this->m_connections.size(); index++) { From f72f1dca6c70bd4597f0106adbd50608cdd8c01b Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Fri, 19 Oct 2012 16:43:10 +0000 Subject: [PATCH 327/347] More UI messages fixes and tweaks, BKE_report<->BKE_reportf, and stuff to translate... --- source/blender/blenloader/CMakeLists.txt | 5 ++++ source/blender/blenloader/SConscript | 5 +++- source/blender/blenloader/intern/readfile.c | 28 ++++++++++--------- source/blender/blenloader/intern/runtime.c | 8 +++--- source/blender/blenloader/intern/writefile.c | 6 ++-- .../blender/editors/armature/editarmature.c | 16 +++++------ source/blender/editors/armature/poselib.c | 22 +++++++-------- source/blender/editors/armature/poseobject.c | 4 +-- source/blender/editors/mesh/CMakeLists.txt | 5 ++++ source/blender/editors/mesh/SConscript | 5 +++- source/blender/editors/mesh/editmesh_slide.c | 14 ++++++---- source/blender/editors/mesh/editmesh_tools.c | 6 ++-- source/blender/editors/uvedit/uvedit_ops.c | 6 ++-- .../editors/uvedit/uvedit_unwrap_ops.c | 3 +- .../quicktime/apple/quicktime_export.c | 4 +-- .../blender/windowmanager/intern/wm_files.c | 17 ++++++----- .../windowmanager/intern/wm_operators.c | 13 ++++----- 17 files changed, 92 insertions(+), 75 deletions(-) diff --git a/source/blender/blenloader/CMakeLists.txt b/source/blender/blenloader/CMakeLists.txt index 74df5211dad..3c5812fa513 100644 --- a/source/blender/blenloader/CMakeLists.txt +++ b/source/blender/blenloader/CMakeLists.txt @@ -25,6 +25,7 @@ set(INC . + ../blenfont ../blenkernel ../blenlib ../makesdna @@ -62,4 +63,8 @@ if(WITH_BUILDINFO) add_definitions(-DWITH_BUILDINFO) endif() +if(WITH_INTERNATIONAL) + add_definitions(-DWITH_INTERNATIONAL) +endif() + blender_add_lib(bf_blenloader "${SRC}" "${INC}" "${INC_SYS}") diff --git a/source/blender/blenloader/SConscript b/source/blender/blenloader/SConscript index 20b560744b3..49e8869637e 100644 --- a/source/blender/blenloader/SConscript +++ b/source/blender/blenloader/SConscript @@ -3,7 +3,7 @@ Import ('env') sources = env.Glob('intern/*.c') -incs = '. #/intern/guardedalloc ../blenlib ../blenkernel' +incs = '. #/intern/guardedalloc ../blenfont ../blenlib ../blenkernel' incs += ' ../makesdna ../editors/include' incs += ' ../render/extern/include ../makesrna ../nodes ../bmesh ../imbuf' @@ -11,6 +11,9 @@ incs += ' ' + env['BF_ZLIB_INC'] defs = [] +if env['WITH_BF_INTERNATIONAL']: + defs.append('WITH_INTERNATIONAL') + if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'): env.BlenderLib ( 'bf_blenloader', sources, Split(incs), defs, libtype=['core','player'], priority = [167,30]) #, cc_compileflags=['/WX'] ) else: diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 3d7c9c21eca..41a635a5e01 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -105,6 +105,8 @@ #include "BLI_math.h" #include "BLI_edgehash.h" +#include "BLF_translation.h" + #include "BKE_anim.h" #include "BKE_action.h" #include "BKE_armature.h" @@ -976,13 +978,13 @@ static FileData *blo_decode_and_check(FileData *fd, ReportList *reports) if (fd->flags & FD_FLAGS_FILE_OK) { if (!read_file_dna(fd)) { - BKE_reportf(reports, RPT_ERROR, "Failed to read blend file: \"%s\", incomplete", fd->relabase); + BKE_reportf(reports, RPT_ERROR, "Failed to read blend file '%s', incomplete", fd->relabase); blo_freefiledata(fd); fd = NULL; } } else { - BKE_reportf(reports, RPT_ERROR, "Failed to read blend file: \"%s\", not a blend file", fd->relabase); + BKE_reportf(reports, RPT_ERROR, "Failed to read blend file '%s', not a blend file", fd->relabase); blo_freefiledata(fd); fd = NULL; } @@ -999,7 +1001,8 @@ FileData *blo_openblenderfile(const char *filepath, ReportList *reports) gzfile = BLI_gzopen(filepath, "rb"); if (gzfile == (gzFile)Z_NULL) { - BKE_reportf(reports, RPT_WARNING, "Unable to open \"%s\": %s.", filepath, errno ? strerror(errno) : "Unknown error reading file"); + BKE_reportf(reports, RPT_WARNING, "Unable to open '%s': %s", + filepath, errno ? strerror(errno) : TIP_("Unknown error reading file")); return NULL; } else { @@ -1017,7 +1020,7 @@ FileData *blo_openblenderfile(const char *filepath, ReportList *reports) FileData *blo_openblendermemory(void *mem, int memsize, ReportList *reports) { if (!mem || memsizeobject = newlibadr_us(fd, sce->id.lib, base->object); if (base->object == NULL) { - BKE_reportf_wrap(fd->reports, RPT_WARNING, - "LIB ERROR: Object lost from scene:'%s\'", + BKE_reportf_wrap(fd->reports, RPT_WARNING, "LIB ERROR: object lost from scene: '%s'", sce->id.name + 2); BLI_remlink(&sce->base, base); if (base == sce->basact) sce->basact = NULL; @@ -6613,7 +6615,7 @@ void convert_tface_mt(FileData *fd, Main *main) G.main = main; if (!(do_version_tface(main, 1))) { - BKE_report(fd->reports, RPT_WARNING, "Texface conversion problem (error in console)"); + BKE_report(fd->reports, RPT_WARNING, "Texface conversion problem (see error in console)"); } //XXX hack, material.c uses G.main allover the place, instead of main @@ -7396,8 +7398,8 @@ static void do_versions(FileData *fd, Library *lib, Main *main) prop = BKE_bproperty_object_get(ob, "Text"); if (prop) { BKE_reportf_wrap(fd->reports, RPT_WARNING, - "Game property name conflict in object: \"%s\".\nText objects reserve the " - "[\"Text\"] game property to change their content through Logic Bricks.", + "Game property name conflict in object '%s':\ntext objects reserve the " + "['Text'] game property to change their content through logic bricks", ob->id.name + 2); } } @@ -9681,7 +9683,7 @@ static void read_libraries(FileData *basefd, ListBase *mainlist) if (fd == NULL) { /* printf and reports for now... its important users know this */ BKE_reportf_wrap(basefd->reports, RPT_INFO, - "read library: '%s', '%s'", + "Read library: '%s', '%s'", mainptr->curlib->filepath, mainptr->curlib->name); fd = blo_openblenderfile(mainptr->curlib->filepath, basefd->reports); @@ -9735,7 +9737,7 @@ static void read_libraries(FileData *basefd, ListBase *mainlist) if (fd == NULL) { BKE_reportf_wrap(basefd->reports, RPT_WARNING, - "Can't find lib '%s'", + "Cannot find lib '%s'", mainptr->curlib->filepath); } } @@ -9754,7 +9756,7 @@ static void read_libraries(FileData *basefd, ListBase *mainlist) append_id_part(fd, mainptr, id, &realid); if (!realid) { BKE_reportf_wrap(fd->reports, RPT_WARNING, - "LIB ERROR: %s:'%s' missing from '%s'", + "LIB ERROR: %s: '%s' missing from '%s'", BKE_idcode_to_name(GS(id->name)), id->name+2, mainptr->curlib->filepath); } @@ -9786,7 +9788,7 @@ static void read_libraries(FileData *basefd, ListBase *mainlist) if (id->flag & LIB_READ) { BLI_remlink(lbarray[a], id); BKE_reportf_wrap(basefd->reports, RPT_WARNING, - "LIB ERROR: %s:'%s' unread libblock missing from '%s'", + "LIB ERROR: %s: '%s' unread libblock missing from '%s'", BKE_idcode_to_name(GS(id->name)), id->name + 2, mainptr->curlib->filepath); change_idid_adr(mainlist, basefd, id, NULL); diff --git a/source/blender/blenloader/intern/runtime.c b/source/blender/blenloader/intern/runtime.c index eaf725dda9e..4136f71f050 100644 --- a/source/blender/blenloader/intern/runtime.c +++ b/source/blender/blenloader/intern/runtime.c @@ -104,7 +104,7 @@ BlendFileData *BLO_read_runtime(const char *path, ReportList *reports) fd = BLI_open(path, O_BINARY | O_RDONLY, 0); if (fd == -1) { - BKE_reportf(reports, RPT_ERROR, "Unable to open \"%s\": %s.", path, strerror(errno)); + BKE_reportf(reports, RPT_ERROR, "Unable to open '%s': %s", path, strerror(errno)); goto cleanup; } @@ -115,15 +115,15 @@ BlendFileData *BLO_read_runtime(const char *path, ReportList *reports) datastart = handle_read_msb_int(fd); if (datastart == -1) { - BKE_reportf(reports, RPT_ERROR, "Unable to read \"%s\" (problem seeking)", path); + BKE_reportf(reports, RPT_ERROR, "Unable to read '%s' (problem seeking)", path); goto cleanup; } else if (read(fd, buf, 8) != 8) { - BKE_reportf(reports, RPT_ERROR, "Unable to read \"%s\" (truncated header)", path); + BKE_reportf(reports, RPT_ERROR, "Unable to read '%s' (truncated header)", path); goto cleanup; } else if (memcmp(buf, "BRUNTIME", 8) != 0) { - BKE_reportf(reports, RPT_ERROR, "Unable to read \"%s\" (not a blend file)", path); + BKE_reportf(reports, RPT_ERROR, "Unable to read '%s' (not a blend file)", path); goto cleanup; } else { diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index ab7f5d46f8b..274762679fe 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -3026,7 +3026,7 @@ int BLO_write_file(Main *mainvar, const char *filepath, int write_flags, ReportL file = BLI_open(tempname, O_BINARY+O_WRONLY+O_CREAT+O_TRUNC, 0666); if (file == -1) { - BKE_reportf(reports, RPT_ERROR, "Can't open file %s for writing: %s", tempname, strerror(errno)); + BKE_reportf(reports, RPT_ERROR, "Cannot open file %s for writing: %s", tempname, strerror(errno)); return 0; } @@ -3094,7 +3094,7 @@ int BLO_write_file(Main *mainvar, const char *filepath, int write_flags, ReportL if (0==ret) { /* now rename to real file name, and delete temp @ file too */ if (BLI_rename(gzname, filepath) != 0) { - BKE_report(reports, RPT_ERROR, "Can't change old file (file saved with @)"); + BKE_report(reports, RPT_ERROR, "Cannot change old file (file saved with @)"); return 0; } @@ -3110,7 +3110,7 @@ int BLO_write_file(Main *mainvar, const char *filepath, int write_flags, ReportL } } else if (BLI_rename(tempname, filepath) != 0) { - BKE_report(reports, RPT_ERROR, "Can't change old file (file saved with @)"); + BKE_report(reports, RPT_ERROR, "Cannot change old file (file saved with @)"); return 0; } diff --git a/source/blender/editors/armature/editarmature.c b/source/blender/editors/armature/editarmature.c index 584bbf7a0aa..8a75d07a678 100644 --- a/source/blender/editors/armature/editarmature.c +++ b/source/blender/editors/armature/editarmature.c @@ -654,7 +654,7 @@ static int apply_armature_pose2bones_exec(bContext *C, wmOperator *op) if (ob->type != OB_ARMATURE) return OPERATOR_CANCELLED; if (BKE_object_obdata_is_libdata(ob)) { - BKE_report(op->reports, RPT_ERROR, "Cannot apply pose to lib-linked armature"); //error_libdata(); + BKE_report(op->reports, RPT_ERROR, "Cannot apply pose to lib-linked armature"); /* error_libdata(); */ return OPERATOR_CANCELLED; } @@ -666,7 +666,7 @@ static int apply_armature_pose2bones_exec(bContext *C, wmOperator *op) "transforms stored are relative to the old rest pose"); /* Get editbones of active armature to alter */ - ED_armature_to_edit(ob); + ED_armature_to_edit(ob); /* get pose of active object and move it out of posemode */ pose = ob->pose; @@ -2099,7 +2099,7 @@ static int armature_calc_roll_exec(bContext *C, wmOperator *op) } sub_v3_v3v3(nor, ebone->tail, ebone->head); - vec_roll_to_mat3(nor, ebone->roll, mat); + vec_roll_to_mat3(nor, ebone->roll, mat); copy_v3_v3(vec, mat[2]); } else { /* Axis */ @@ -2969,7 +2969,7 @@ static int armature_fill_bones_exec(bContext *C, wmOperator *op) } } else { - // FIXME.. figure out a method for multiple bones + /* FIXME.. figure out a method for multiple bones */ BKE_reportf(op->reports, RPT_ERROR, "Too many points selected: %d\n", count); BLI_freelistN(&points); return OPERATOR_CANCELLED; @@ -3823,7 +3823,7 @@ static int armature_parent_set_exec(bContext *C, wmOperator *op) /* there must be an active bone */ if (actbone == NULL) { - BKE_report(op->reports, RPT_ERROR, "Operation requires an Active Bone"); + BKE_report(op->reports, RPT_ERROR, "Operation requires an active bone"); return OPERATOR_CANCELLED; } else if (arm->flag & ARM_MIRROR_EDIT) { @@ -4217,7 +4217,7 @@ static int armature_select_similar_exec(bContext *C, wmOperator *op) /* Check for active bone */ if (ebone_act == NULL) { - BKE_report(op->reports, RPT_ERROR, "Operation requires an Active Bone"); + BKE_report(op->reports, RPT_ERROR, "Operation requires an active bone"); return OPERATOR_CANCELLED; } @@ -4409,7 +4409,7 @@ static int armature_align_bones_exec(bContext *C, wmOperator *op) /* there must be an active bone */ if (actbone == NULL) { - BKE_report(op->reports, RPT_ERROR, "Operation requires an Active Bone"); + BKE_report(op->reports, RPT_ERROR, "Operation requires an active bone"); return OPERATOR_CANCELLED; } else if (arm->flag & ARM_MIRROR_EDIT) { @@ -5152,7 +5152,7 @@ static int pose_clear_transform_generic_exec(bContext *C, wmOperator *op, /* sanity checks */ if (ELEM(NULL, clear_func, default_ksName)) { - BKE_report(op->reports, RPT_ERROR, "Programming error: missing clear transform function or Keying Set Name"); + BKE_report(op->reports, RPT_ERROR, "Programming error: missing clear transform function or keying set name"); return OPERATOR_CANCELLED; } diff --git a/source/blender/editors/armature/poselib.c b/source/blender/editors/armature/poselib.c index eea7424c59a..a05a98c58ca 100644 --- a/source/blender/editors/armature/poselib.c +++ b/source/blender/editors/armature/poselib.c @@ -298,7 +298,7 @@ static int poselib_sanitize_exec(bContext *C, wmOperator *op) /* validate action */ if (act == NULL) { - BKE_report(op->reports, RPT_WARNING, "No Action to validate"); + BKE_report(op->reports, RPT_WARNING, "No action to validate"); return OPERATOR_CANCELLED; } @@ -547,7 +547,7 @@ static int poselib_remove_exec(bContext *C, wmOperator *op) /* check if valid poselib */ if (act == NULL) { - BKE_report(op->reports, RPT_ERROR, "Object doesn't have PoseLib data"); + BKE_report(op->reports, RPT_ERROR, "Object does not have pose lib data"); return OPERATOR_CANCELLED; } @@ -562,7 +562,7 @@ static int poselib_remove_exec(bContext *C, wmOperator *op) /* get index (and pointer) of pose to remove */ marker = BLI_findlink(&act->markers, marker_index); if (marker == NULL) { - BKE_reportf(op->reports, RPT_ERROR, "Invalid Pose specified %d", marker_index); + BKE_reportf(op->reports, RPT_ERROR, "Invalid pose specified %d", marker_index); return OPERATOR_CANCELLED; } @@ -628,14 +628,14 @@ static int poselib_rename_invoke(bContext *C, wmOperator *op, wmEvent *evt) /* check if valid poselib */ if (act == NULL) { - BKE_report(op->reports, RPT_ERROR, "Object doesn't have PoseLib data"); + BKE_report(op->reports, RPT_ERROR, "Object does not have pose lib data"); return OPERATOR_CANCELLED; } /* get index (and pointer) of pose to remove */ marker = BLI_findlink(&act->markers, act->active_marker - 1); if (marker == NULL) { - BKE_report(op->reports, RPT_ERROR, "Invalid index for Pose"); + BKE_report(op->reports, RPT_ERROR, "Invalid index for pose"); return OPERATOR_CANCELLED; } else { @@ -657,14 +657,14 @@ static int poselib_rename_exec(bContext *C, wmOperator *op) /* check if valid poselib */ if (act == NULL) { - BKE_report(op->reports, RPT_ERROR, "Object doesn't have PoseLib data"); + BKE_report(op->reports, RPT_ERROR, "Object does not have pose lib data"); return OPERATOR_CANCELLED; } /* get index (and pointer) of pose to remove */ marker = BLI_findlink(&act->markers, RNA_int_get(op->ptr, "pose")); if (marker == NULL) { - BKE_report(op->reports, RPT_ERROR, "Invalid index for Pose"); + BKE_report(op->reports, RPT_ERROR, "Invalid index for pose"); return OPERATOR_CANCELLED; } @@ -1424,12 +1424,12 @@ static void poselib_preview_init_data(bContext *C, wmOperator *op) /* check if valid poselib */ if (ELEM3(NULL, pld->ob, pld->pose, pld->arm)) { - BKE_report(op->reports, RPT_ERROR, "PoseLib is only for Armatures in PoseMode"); + BKE_report(op->reports, RPT_ERROR, "Pose lib is only for armatures in pose mode"); pld->state = PL_PREVIEW_ERROR; return; } if (pld->act == NULL) { - BKE_report(op->reports, RPT_ERROR, "Object doesn't have a valid PoseLib"); + BKE_report(op->reports, RPT_ERROR, "Object does not have a valid pose lib"); pld->state = PL_PREVIEW_ERROR; return; } @@ -1438,10 +1438,10 @@ static void poselib_preview_init_data(bContext *C, wmOperator *op) /* just use first one then... */ pld->marker = pld->act->markers.first; if (pose_index > -2) - BKE_report(op->reports, RPT_WARNING, "PoseLib had no active pose"); + BKE_report(op->reports, RPT_WARNING, "Pose lib had no active pose"); } else { - BKE_report(op->reports, RPT_ERROR, "PoseLib has no poses to preview/apply"); + BKE_report(op->reports, RPT_ERROR, "Pose lib has no poses to preview/apply"); pld->state = PL_PREVIEW_ERROR; return; } diff --git a/source/blender/editors/armature/poseobject.c b/source/blender/editors/armature/poseobject.c index 0e5daea6f16..99de90bc9fa 100644 --- a/source/blender/editors/armature/poseobject.c +++ b/source/blender/editors/armature/poseobject.c @@ -105,7 +105,7 @@ void ED_armature_enter_posemode(bContext *C, Base *base) Object *ob = base->object; if (ob->id.lib) { - BKE_report(reports, RPT_WARNING, "Can't pose libdata"); + BKE_report(reports, RPT_WARNING, "Cannot pose libdata"); return; } @@ -1236,7 +1236,7 @@ static int pose_copy_exec(bContext *C, wmOperator *op) /* sanity checking */ if (ELEM(NULL, ob, ob->pose)) { - BKE_report(op->reports, RPT_ERROR, "No Pose to Copy"); + BKE_report(op->reports, RPT_ERROR, "No pose to copy"); return OPERATOR_CANCELLED; } diff --git a/source/blender/editors/mesh/CMakeLists.txt b/source/blender/editors/mesh/CMakeLists.txt index 246c323213c..9aa3f3633f3 100644 --- a/source/blender/editors/mesh/CMakeLists.txt +++ b/source/blender/editors/mesh/CMakeLists.txt @@ -21,6 +21,7 @@ set(INC ../include ../uvedit + ../../blenfont ../../blenkernel ../../blenlib ../../blenloader @@ -68,4 +69,8 @@ if(WITH_GAMEENGINE) ) endif() +if(WITH_INTERNATIONAL) + add_definitions(-DWITH_INTERNATIONAL) +endif() + blender_add_lib(bf_editor_mesh "${SRC}" "${INC}" "${INC_SYS}") diff --git a/source/blender/editors/mesh/SConscript b/source/blender/editors/mesh/SConscript index b3aba977b21..923bb3f9057 100644 --- a/source/blender/editors/mesh/SConscript +++ b/source/blender/editors/mesh/SConscript @@ -5,7 +5,7 @@ sources = env.Glob('*.c') defs = [] -incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../imbuf' +incs = '../include ../../blenfont ../../blenlib ../../blenkernel ../../makesdna ../../imbuf' incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include' incs += ' ../../gpu ../../blenloader' incs += ' ../../makesrna ../../render/extern/include #/intern/elbeem/extern' @@ -24,4 +24,7 @@ if env['WITH_BF_GAMEENGINE']: else: sources.remove('mesh_navmesh.c') +if env['WITH_BF_INTERNATIONAL']: + defs.append('WITH_INTERNATIONAL') + env.BlenderLib ( 'bf_editors_mesh', sources, Split(incs), defs, libtype=['core'], priority=[45] ) diff --git a/source/blender/editors/mesh/editmesh_slide.c b/source/blender/editors/mesh/editmesh_slide.c index a0cf5efabd9..d370b5a881e 100644 --- a/source/blender/editors/mesh/editmesh_slide.c +++ b/source/blender/editors/mesh/editmesh_slide.c @@ -34,6 +34,8 @@ #include "BLI_array.h" #include "BLI_math.h" +#include "BLF_translation.h" + #include "BKE_context.h" #include "BKE_report.h" #include "BKE_tessmesh.h" @@ -113,11 +115,11 @@ static int vtx_slide_init(bContext *C, wmOperator *op) /* Custom data */ VertexSlideOp *vso; - const char *header_str = "Vertex Slide: Hover over an edge and left-click to select slide edge. " - "Left-Shift: Midpoint Snap, Left-Alt: Snap, Left-Ctrl: Snap&Merge"; + const char *header_str = TIP_("Vertex Slide: Hover over an edge and left-click to select slide edge. " + "Left-Shift: Midpoint Snap, Left-Alt: Snap, Left-Ctrl: Snap & Merge"); if (!obedit) { - BKE_report(op->reports, RPT_ERROR, "Vertex Slide Error: Not object in context"); + BKE_report(op->reports, RPT_ERROR, "Vertex slide error: no object in context"); return FALSE; } @@ -126,7 +128,7 @@ static int vtx_slide_init(bContext *C, wmOperator *op) /* Is there a starting vertex ? */ if (ese == NULL || (ese->htype != BM_VERT && ese->htype != BM_EDGE)) { - BKE_report(op->reports, RPT_ERROR_INVALID_INPUT, "Vertex Slide Error: Select a (single) vertex"); + BKE_report(op->reports, RPT_ERROR_INVALID_INPUT, "Vertex slide error: select a (single) vertex"); return FALSE; } @@ -177,7 +179,7 @@ static int vtx_slide_init(bContext *C, wmOperator *op) /* Init frame */ if (!vtx_slide_set_frame(vso)) { - BKE_report(op->reports, RPT_ERROR_INVALID_INPUT, "Vertex Slide: Can't find starting vertex!"); + BKE_report(op->reports, RPT_ERROR_INVALID_INPUT, "Vertex slide error: cannot find starting vertex!"); vtx_slide_exit(C, op); return FALSE; } @@ -719,7 +721,7 @@ static int edbm_vertex_slide_exec_ex(bContext *C, wmOperator *op, const int do_u /* Is there a starting vertex ? */ if ((ese == NULL) || (ese->htype != BM_VERT && ese->htype != BM_EDGE)) { - BKE_report(op->reports, RPT_ERROR_INVALID_INPUT, "Vertex Slide Error: Select a (single) vertex"); + BKE_report(op->reports, RPT_ERROR_INVALID_INPUT, "Vertex slide error: select a (single) vertex"); return OPERATOR_CANCELLED; } diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 695afd44408..eba71a63e2c 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -2133,7 +2133,7 @@ static int edbm_remove_doubles_exec(bContext *C, wmOperator *op) } count = totvert_orig - em->bm->totvert; - BKE_reportf(op->reports, RPT_INFO, "Removed %d vert%s", count, (count == 1) ? "ex" : "ices"); + BKE_reportf(op->reports, RPT_INFO, "Removed %d vertices", count); EDBM_update_generic(C, em, TRUE); @@ -2218,7 +2218,7 @@ static int edbm_select_vertex_path_exec(bContext *C, wmOperator *op) } if (svert == NULL || evert == NULL) { - BKE_report(op->reports, RPT_WARNING, "Path Selection requires that two vertices be selected"); + BKE_report(op->reports, RPT_WARNING, "Path selection requires two vertices to be selected"); return OPERATOR_CANCELLED; } @@ -4330,7 +4330,7 @@ static int edbm_sort_elements_exec(bContext *C, wmOperator *op) if (ELEM(action, SRT_VIEW_ZAXIS, SRT_VIEW_XAXIS)) { if (rv3d == NULL) { - BKE_report(op->reports, RPT_ERROR, "View not found, can't sort by view axis"); + BKE_report(op->reports, RPT_ERROR, "View not found, cannot sort by view axis"); return OPERATOR_CANCELLED; } } diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c index 59273ee66b3..acc69309a8c 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -2135,7 +2135,7 @@ static int select_linked_internal(bContext *C, wmOperator *op, wmEvent *event, i NearestHit hit, *hit_p = NULL; if (ts->uv_flag & UV_SYNC_SELECTION) { - BKE_report(op->reports, RPT_ERROR, "Can't select linked when sync selection is enabled"); + BKE_report(op->reports, RPT_ERROR, "Cannot select linked when sync selection is enabled"); return OPERATOR_CANCELLED; } @@ -2242,7 +2242,7 @@ static int select_split_exec(bContext *C, wmOperator *op) short change = FALSE; if (ts->uv_flag & UV_SYNC_SELECTION) { - BKE_report(op->reports, RPT_ERROR, "Can't split selection when sync selection is enabled"); + BKE_report(op->reports, RPT_ERROR, "Cannot split selection when sync selection is enabled"); return OPERATOR_CANCELLED; } @@ -2321,7 +2321,7 @@ static int unlink_selection_exec(bContext *C, wmOperator *op) MLoopUV *luv; if (ts->uv_flag & UV_SYNC_SELECTION) { - BKE_report(op->reports, RPT_ERROR, "Can't unlink selection when sync selection is enabled"); + BKE_report(op->reports, RPT_ERROR, "Cannot unlink selection when sync selection is enabled"); return OPERATOR_CANCELLED; } diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c index decd94f77c8..19a1c4339ad 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c @@ -1184,7 +1184,8 @@ static int unwrap_exec(bContext *C, wmOperator *op) mat4_to_size(obsize, obedit->obmat); if (!compare_v3v3(obsize, unitsize, 1e-4f)) - BKE_report(op->reports, RPT_INFO, "Object scale is not 1.0. Unwrap will operate on a non-scaled version of the mesh."); + BKE_report(op->reports, RPT_INFO, + "Object scale is not 1.0, unwrap will operate on a non-scaled version of the mesh"); /* remember last method for live unwrap */ if (RNA_struct_property_is_set(op->ptr, "method")) diff --git a/source/blender/quicktime/apple/quicktime_export.c b/source/blender/quicktime/apple/quicktime_export.c index e376cba9a9f..1d5838e9905 100644 --- a/source/blender/quicktime/apple/quicktime_export.c +++ b/source/blender/quicktime/apple/quicktime_export.c @@ -414,7 +414,7 @@ static void QT_StartAddVideoSamplesToMedia(const Rect *trackFrame, int rectx, in gTemporalSettings = qtdata->gTemporalSettings; if (qtdata->gSpatialSettings.codecType == kH264CodecType) { if (gTemporalSettings.temporalQuality != codecMinQuality) { - BKE_report(reports, RPT_WARNING, "Only minimum quality compression supported for QuickTime H.264"); + BKE_report(reports, RPT_WARNING, "Only minimum quality compression supported for Quicktime H.264"); gTemporalSettings.temporalQuality = codecMinQuality; } } @@ -564,7 +564,7 @@ int start_qt(struct Scene *scene, struct RenderData *rd, int rectx, int recty, R /* hack: create an empty file to make FSPathMakeRef() happy */ myFile = open(theFullPath, O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRUSR | S_IWUSR); if (myFile < 0) { - BKE_report(reports, RPT_ERROR, "error while creating movie file!"); + BKE_report(reports, RPT_ERROR, "Error while creating movie file!"); /* do something? */ } close(myFile); diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index c6bd912e89b..602105fd28c 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -450,9 +450,8 @@ void WM_file_read(bContext *C, const char *filepath, ReportList *reports) if (sce->r.engine[0] && BLI_findstring(&R_engines, sce->r.engine, offsetof(RenderEngineType, idname)) == NULL) { - BKE_reportf(reports, RPT_WARNING, - "Engine not available: '%s' for scene: %s, " - "an addon may need to be installed or enabled", + BKE_reportf(reports, RPT_ERROR, "Engine '%s' not available for scene '%s' " + "(an addon may need to be installed or enabled)", sce->r.engine, sce->id.name + 2); } } @@ -465,17 +464,17 @@ void WM_file_read(bContext *C, const char *filepath, ReportList *reports) else if (retval == BKE_READ_EXOTIC_OK_OTHER) BKE_write_undo(C, "Import file"); else if (retval == BKE_READ_EXOTIC_FAIL_OPEN) { - BKE_reportf(reports, RPT_ERROR, IFACE_("Can't read file: \"%s\", %s."), filepath, - errno ? strerror(errno) : IFACE_("Unable to open the file")); + BKE_reportf(reports, RPT_ERROR, "Cannot read file '%s': %s", filepath, + errno ? strerror(errno) : TIP_("unable to open the file")); } else if (retval == BKE_READ_EXOTIC_FAIL_FORMAT) { - BKE_reportf(reports, RPT_ERROR, IFACE_("File format is not supported in file: \"%s\"."), filepath); + BKE_reportf(reports, RPT_ERROR, "File format is not supported in file '%s'", filepath); } else if (retval == BKE_READ_EXOTIC_FAIL_PATH) { - BKE_reportf(reports, RPT_ERROR, IFACE_("File path invalid: \"%s\"."), filepath); + BKE_reportf(reports, RPT_ERROR, "File path '%s' invalid", filepath); } else { - BKE_reportf(reports, RPT_ERROR, IFACE_("Unknown error loading: \"%s\"."), filepath); + BKE_reportf(reports, RPT_ERROR, "Unknown error loading '%s'", filepath); BLI_assert(!"invalid 'retval'"); } @@ -791,7 +790,7 @@ int WM_file_write(bContext *C, const char *target, int fileflags, ReportList *re /* send the OnSave event */ for (li = G.main->library.first; li; li = li->id.next) { if (BLI_path_cmp(li->filepath, filepath) == 0) { - BKE_reportf(reports, RPT_ERROR, "Can't overwrite used library '%.240s'", filepath); + BKE_reportf(reports, RPT_ERROR, "Cannot overwrite used library '%.240s'", filepath); return -1; } } diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 8496cd8041a..8c9d4861a9e 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -3130,7 +3130,7 @@ static int radial_control_get_path(PointerRNA *ctx_ptr, wmOperator *op, /* check flags */ if ((flags & RC_PROP_REQUIRE_BOOL) && (flags & RC_PROP_REQUIRE_FLOAT)) { - BKE_reportf(op->reports, RPT_ERROR, "Property can't be both boolean and float"); + BKE_report(op->reports, RPT_ERROR, "Property cannot be both boolean and float"); return 0; } @@ -3153,7 +3153,7 @@ static int radial_control_get_path(PointerRNA *ctx_ptr, wmOperator *op, if (flags & RC_PROP_ALLOW_MISSING) return 1; else { - BKE_reportf(op->reports, RPT_ERROR, "Couldn't resolve path %s", name); + BKE_reportf(op->reports, RPT_ERROR, "Could not resolve path '%s'", name); return 0; } } @@ -3166,8 +3166,7 @@ static int radial_control_get_path(PointerRNA *ctx_ptr, wmOperator *op, ((flags & RC_PROP_REQUIRE_FLOAT) && prop_type != PROP_FLOAT)) { MEM_freeN(str); - BKE_reportf(op->reports, RPT_ERROR, - "Property from path %s is not a float", name); + BKE_reportf(op->reports, RPT_ERROR, "Property from path '%s' is not a float", name); return 0; } } @@ -3175,8 +3174,7 @@ static int radial_control_get_path(PointerRNA *ctx_ptr, wmOperator *op, /* check property's array length */ if (*r_prop && (len = RNA_property_array_length(r_ptr, *r_prop)) != req_length) { MEM_freeN(str); - BKE_reportf(op->reports, RPT_ERROR, - "Property from path %s has length %d instead of %d", + BKE_reportf(op->reports, RPT_ERROR, "Property from path '%s' has length %d instead of %d", name, len, req_length); return 0; } @@ -3244,8 +3242,7 @@ static int radial_control_get_properties(bContext *C, wmOperator *op) else if (rc->image_id_ptr.data) { /* extra check, pointer must be to an ID */ if (!RNA_struct_is_ID(rc->image_id_ptr.type)) { - BKE_report(op->reports, RPT_ERROR, - "Pointer from path image_id is not an ID"); + BKE_report(op->reports, RPT_ERROR, "Pointer from path image_id is not an ID"); return 0; } } From 7e620f04a1072e5bcffb92c9db501ebe9a51a25c Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 19 Oct 2012 16:44:08 +0000 Subject: [PATCH 328/347] Fix #32920: cloth physics with collision exploding in some cases, due to uninitialized memory usage. --- source/blender/blenkernel/intern/collision.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index 6631afcddaf..05c916f9362 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -458,7 +458,8 @@ static CollPair* cloth_collision(ModifierData *md1, ModifierData *md2, distance = 2.0 * (double)( epsilon1 + epsilon2 + ALMOST_ZERO ); #endif - if (distance <= (epsilon1 + epsilon2 + ALMOST_ZERO)) { + // distance -1 means no collision result + if (distance != -1.0f && (distance <= (epsilon1 + epsilon2 + ALMOST_ZERO))) { normalize_v3_v3(collpair->normal, collpair->vector); collpair->distance = distance; From 3fec74ec1acbd2d8b3491bc44c87ef60c037a4f8 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Fri, 19 Oct 2012 17:08:46 +0000 Subject: [PATCH 329/347] Minor fix to BKE_reportf(): also output the report's type when printing to console. --- source/blender/blenkernel/intern/report.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source/blender/blenkernel/intern/report.c b/source/blender/blenkernel/intern/report.c index ae6f4f35519..d925d736358 100644 --- a/source/blender/blenkernel/intern/report.c +++ b/source/blender/blenkernel/intern/report.c @@ -134,6 +134,7 @@ void BKE_reportf(ReportList *reports, ReportType type, const char *_format, ...) const char *format = TIP_(_format); if (G.background || !reports || ((reports->flag & RPT_PRINT) && (type >= reports->printlevel))) { + printf("%s: ", report_type_str(type)); va_start(args, _format); vprintf(format, args); va_end(args); From 2256c8e25f597b5499e8bf64dd0fe74c1ea31864 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Fri, 19 Oct 2012 19:16:18 +0000 Subject: [PATCH 330/347] Fix [#32925] Center cursor (shift+C) crashing blender after duplicating bone in armature edit mode. Center Cursor uses BKE_object_minmax(), which uses pchans' bone member to check whether a bone is visible or not. But after a duplication, the duplicated pchan->bone are NULL, skiping in this case (as if they were hidden, not optimal but should do the work for now - anyway, using pchan's values in Edit mode does not really make sense, imho). --- source/blender/blenkernel/intern/object.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index a0d27737705..fd58af34862 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -2300,11 +2300,9 @@ void BKE_object_minmax(Object *ob, float min_r[3], float max_r[3], const short u bPoseChannel *pchan; for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { - - if ((use_hidden == FALSE) && (PBONE_VISIBLE(arm, pchan->bone) == FALSE)) { - /* pass */ - } - else { + /* XXX pchan->bone may be NULL for duplicated bones, see duplicateEditBoneObjects() comment + * (editarmature.c:2592)... Skip in this case too! */ + if (pchan->bone && !((use_hidden == FALSE) && (PBONE_VISIBLE(arm, pchan->bone) == FALSE))) { mul_v3_m4v3(vec, ob->obmat, pchan->pose_head); minmax_v3v3_v3(min_r, max_r, vec); mul_v3_m4v3(vec, ob->obmat, pchan->pose_tail); From 3a52a876b6a8909bca8660f9cde7d65a84c631f5 Mon Sep 17 00:00:00 2001 From: Nicholas Bishop Date: Sat, 20 Oct 2012 00:45:44 +0000 Subject: [PATCH 331/347] Fix for drawing meshes with VBOs disabled in sculpt mode * This is another fix for r51118. Was drawing flat-shaded GPU buffers with VBOs even when VBOs were disabled in the preferences. --- source/blender/gpu/intern/gpu_buffers.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c index c0b4987c3fc..2986ce85c88 100644 --- a/source/blender/gpu/intern/gpu_buffers.c +++ b/source/blender/gpu/intern/gpu_buffers.c @@ -1562,7 +1562,7 @@ GPU_Buffers *GPU_build_mesh_buffers(int (*face_vert_indices)[4], glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); } - if (buffers->index_buf || !buffers->smooth) + if (gpu_vbo_enabled() && (buffers->index_buf || !buffers->smooth)) glGenBuffersARB(1, &buffers->vert_buf); buffers->tot_tri = tottri; From e010c29fa8264f5751805dc9854ac0d5b8c4bf6f Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Sat, 20 Oct 2012 04:56:24 +0000 Subject: [PATCH 332/347] Grease Pencil: Tweaks to make tooltips show up for the different drawing tool types available --- source/blender/editors/gpencil/gpencil_paint.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index d0b48772d85..e5afbdba50b 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -1888,10 +1888,10 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, wmEvent *event) /* ------------------------------- */ static EnumPropertyItem prop_gpencil_drawmodes[] = { - {GP_PAINTMODE_DRAW, "DRAW", 0, "Draw Freehand", ""}, - {GP_PAINTMODE_DRAW_STRAIGHT, "DRAW_STRAIGHT", 0, "Draw Straight Lines", ""}, - {GP_PAINTMODE_DRAW_POLY, "DRAW_POLY", 0, "Draw Poly Line", ""}, - {GP_PAINTMODE_ERASER, "ERASER", 0, "Eraser", ""}, + {GP_PAINTMODE_DRAW, "DRAW", 0, "Draw Freehand", "Draw freehand stroke(s)"}, + {GP_PAINTMODE_DRAW_STRAIGHT, "DRAW_STRAIGHT", 0, "Draw Straight Lines", "Draw straight line segment(s)"}, + {GP_PAINTMODE_DRAW_POLY, "DRAW_POLY", 0, "Draw Poly Line", "Click to place endpoints of straight line segments (connected)"}, + {GP_PAINTMODE_ERASER, "ERASER", 0, "Eraser", "Erase Grease Pencil strokes"}, {0, NULL, 0, NULL, NULL} }; @@ -1913,7 +1913,7 @@ void GPENCIL_OT_draw(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING; /* settings for drawing */ - RNA_def_enum(ot->srna, "mode", prop_gpencil_drawmodes, 0, "Mode", "Way to interpret mouse movements"); + ot->prop = RNA_def_enum(ot->srna, "mode", prop_gpencil_drawmodes, 0, "Mode", "Way to interpret mouse movements"); RNA_def_collection_runtime(ot->srna, "stroke", &RNA_OperatorStrokeElement, "Stroke", ""); } From 0cac50522173c468952dc02544aba2d688b216f8 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Sat, 20 Oct 2012 05:08:26 +0000 Subject: [PATCH 333/347] Code cleanup --- .../editors/space_graph/graph_buttons.c | 39 ++++++++++--------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/source/blender/editors/space_graph/graph_buttons.c b/source/blender/editors/space_graph/graph_buttons.c index 0d56b02e086..3e8f6f1c7fc 100644 --- a/source/blender/editors/space_graph/graph_buttons.c +++ b/source/blender/editors/space_graph/graph_buttons.c @@ -148,6 +148,7 @@ static void graph_panel_view(const bContext *C, Panel *pa) row = uiLayoutSplit(sub, 0.7f, TRUE); uiItemR(row, &sceneptr, "frame_current", 0, IFACE_("Cursor X"), ICON_NONE); uiItemEnumO(row, "GRAPH_OT_snap", IFACE_("To Keys"), 0, "type", GRAPHKEYS_SNAP_CFRA); + row = uiLayoutSplit(sub, 0.7f, TRUE); uiItemR(row, &spaceptr, "cursor_position_y", 0, IFACE_("Cursor Y"), ICON_NONE); uiItemEnumO(row, "GRAPH_OT_snap", IFACE_("To Keys"), 0, "type", GRAPHKEYS_SNAP_VALUE); @@ -308,44 +309,43 @@ static void graph_panel_key_properties(const bContext *C, Panel *pa) * - we use the button-versions of the calls so that we can attach special update handlers * and unit conversion magic that cannot be achieved using a purely RNA-approach */ - // XXX: col = uiLayoutColumn(layout, TRUE); /* keyframe itself */ { uiItemL(col, IFACE_("Key:"), ICON_NONE); - + but = uiDefButR(block, NUM, B_REDR, IFACE_("Frame"), 0, 0, UI_UNIT_X, UI_UNIT_Y, &bezt_ptr, "co", 0, 0, 0, -1, -1, NULL); uiButSetFunc(but, graphedit_activekey_update_cb, fcu, bezt); - + but = uiDefButR(block, NUM, B_REDR, IFACE_("Value"), 0, 0, UI_UNIT_X, UI_UNIT_Y, &bezt_ptr, "co", 1, 0, 0, -1, -1, NULL); uiButSetFunc(but, graphedit_activekey_update_cb, fcu, bezt); uiButSetUnitType(but, unit); } - + /* previous handle - only if previous was Bezier interpolation */ if ((prevbezt) && (prevbezt->ipo == BEZT_IPO_BEZ)) { uiItemL(col, IFACE_("Left Handle:"), ICON_NONE); - + but = uiDefButR(block, NUM, B_REDR, "X", 0, 0, UI_UNIT_X, UI_UNIT_Y, &bezt_ptr, "handle_left", 0, 0, 0, -1, -1, NULL); uiButSetFunc(but, graphedit_activekey_handles_cb, fcu, bezt); - + but = uiDefButR(block, NUM, B_REDR, "Y", 0, 0, UI_UNIT_X, UI_UNIT_Y, &bezt_ptr, "handle_left", 1, 0, 0, -1, -1, NULL); uiButSetFunc(but, graphedit_activekey_handles_cb, fcu, bezt); uiButSetUnitType(but, unit); } - + /* next handle - only if current is Bezier interpolation */ if (bezt->ipo == BEZT_IPO_BEZ) { uiItemL(col, IFACE_("Right Handle:"), ICON_NONE); - + but = uiDefButR(block, NUM, B_REDR, "X", 0, 0, UI_UNIT_X, UI_UNIT_Y, &bezt_ptr, "handle_right", 0, 0, 0, -1, -1, NULL); uiButSetFunc(but, graphedit_activekey_handles_cb, fcu, bezt); - + but = uiDefButR(block, NUM, B_REDR, "Y", 0, 0, UI_UNIT_X, UI_UNIT_Y, &bezt_ptr, "handle_right", 1, 0, 0, -1, -1, NULL); uiButSetFunc(but, graphedit_activekey_handles_cb, fcu, bezt); @@ -437,7 +437,7 @@ static void driver_update_flags_cb(bContext *UNUSED(C), void *fcu_v, void *UNUSE ChannelDriver *driver = fcu->driver; /* clear invalid flags */ - fcu->flag &= ~FCURVE_DISABLED; // XXX? + fcu->flag &= ~FCURVE_DISABLED; driver->flag &= ~DRIVER_FLAG_INVALID; } @@ -467,7 +467,6 @@ static void graph_panel_driverVar__singleProp(uiLayout *layout, ID *id, DriverVa uiTemplateAnyID(row, &dtar_ptr, "id", "id_type", IFACE_("Prop:")); /* Target Property */ - // TODO: make this less technical... if (dtar->id) { PointerRNA root_ptr; @@ -630,12 +629,12 @@ static void graph_panel_drivers(const bContext *C, Panel *pa) /* errors? */ if (driver->flag & DRIVER_FLAG_INVALID) - uiItemL(col, IFACE_("ERROR: invalid Python expression"), ICON_ERROR); + uiItemL(col, IFACE_("ERROR: Invalid Python expression"), ICON_ERROR); } else { /* errors? */ if (driver->flag & DRIVER_FLAG_INVALID) - uiItemL(col, IFACE_("ERROR: invalid target channel(s)"), ICON_ERROR); + uiItemL(col, IFACE_("ERROR: Invalid target channel(s)"), ICON_ERROR); } col = uiLayoutColumn(pa->layout, TRUE); @@ -706,15 +705,15 @@ static void graph_panel_drivers(const bContext *C, Panel *pa) graph_panel_driverVar__transChan(box, ale->id, dvar); break; } - + /* value of variable */ if (driver->flag & DRIVER_FLAG_SHOWDEBUG) { char valBuf[32]; - + box = uiLayoutBox(col); row = uiLayoutRow(box, TRUE); uiItemL(row, IFACE_("Value:"), ICON_NONE); - + BLI_snprintf(valBuf, sizeof(valBuf), "%.3f", dvar->curval); uiItemL(row, valBuf, ICON_NONE); } @@ -724,8 +723,8 @@ static void graph_panel_drivers(const bContext *C, Panel *pa) MEM_freeN(ale); } -/* ******************* f-modifiers ******************************** */ -/* all the drawing code is in editors/animation/fmodifier_ui.c */ +/* ******************* F-Modifiers ******************************** */ +/* All the drawing code is in editors/animation/fmodifier_ui.c */ #define B_FMODIFIER_REDRAW 20 @@ -757,7 +756,9 @@ static void graph_panel_modifiers(const bContext *C, Panel *pa) row = uiLayoutRow(pa->layout, FALSE); block = uiLayoutGetBlock(row); - // XXX for now, this will be a operator button which calls a 'add modifier' operator + /* this is an operator button which calls a 'add modifier' operator... + * a menu might be nicer but would be tricky as we need some custom filtering + */ uiDefButO(block, BUT, "GRAPH_OT_fmodifier_add", WM_OP_INVOKE_REGION_WIN, IFACE_("Add Modifier"), 10, 0, 150, 20, TIP_("Adds a new F-Curve Modifier for the active F-Curve")); From 08dd8a6849c904a0efc390536767e7576d8136e8 Mon Sep 17 00:00:00 2001 From: Dan Eicher Date: Sat, 20 Oct 2012 05:51:45 +0000 Subject: [PATCH 334/347] rna_sequencer_api.c doc string cleanup --- .../makesrna/intern/rna_sequencer_api.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/source/blender/makesrna/intern/rna_sequencer_api.c b/source/blender/makesrna/intern/rna_sequencer_api.c index f63ef6c8d76..734703e6334 100644 --- a/source/blender/makesrna/intern/rna_sequencer_api.c +++ b/source/blender/makesrna/intern/rna_sequencer_api.c @@ -456,7 +456,7 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop) func = RNA_def_function(srna, "new_clip", "rna_Sequences_new_clip"); RNA_def_function_flag(func, FUNC_USE_SELF_ID); RNA_def_function_ui_description(func, "Add a new movie clip sequence"); - parm = RNA_def_string(func, "name", "Name", 0, "", "New name for the sequence"); + parm = RNA_def_string(func, "name", "Name", 0, "", "Name for the new sequence"); RNA_def_property_flag(parm, PROP_REQUIRED); parm = RNA_def_pointer(func, "clip", "MovieClip", "", "Movie clip to add"); RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); @@ -472,8 +472,8 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop) func = RNA_def_function(srna, "new_mask", "rna_Sequences_new_mask"); RNA_def_function_flag(func, FUNC_USE_SELF_ID); - RNA_def_function_ui_description(func, "Add a new movie clip sequence"); - parm = RNA_def_string(func, "name", "Name", 0, "", "New name for the sequence"); + RNA_def_function_ui_description(func, "Add a new mask sequence"); + parm = RNA_def_string(func, "name", "Name", 0, "", "Name for the new sequence"); RNA_def_property_flag(parm, PROP_REQUIRED); parm = RNA_def_pointer(func, "mask", "Mask", "", "Mask to add"); RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); @@ -490,7 +490,7 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop) func = RNA_def_function(srna, "new_scene", "rna_Sequences_new_scene"); RNA_def_function_flag(func, FUNC_USE_SELF_ID); RNA_def_function_ui_description(func, "Add a new scene sequence"); - parm = RNA_def_string(func, "name", "Name", 0, "", "New name for the sequence"); + parm = RNA_def_string(func, "name", "Name", 0, "", "Name for the new sequence"); RNA_def_property_flag(parm, PROP_REQUIRED); parm = RNA_def_pointer(func, "scene", "Scene", "", "Scene to add"); RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); @@ -507,7 +507,7 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop) func = RNA_def_function(srna, "new_image", "rna_Sequences_new_image"); RNA_def_function_flag(func, FUNC_USE_REPORTS | FUNC_USE_SELF_ID); RNA_def_function_ui_description(func, "Add a new image sequence"); - parm = RNA_def_string(func, "name", "Name", 0, "", "New name for the sequence"); + parm = RNA_def_string(func, "name", "Name", 0, "", "Name for the new sequence"); RNA_def_property_flag(parm, PROP_REQUIRED); parm = RNA_def_string(func, "filepath", "File", 0, "", "Filepath to image"); RNA_def_property_flag(parm, PROP_REQUIRED); @@ -524,7 +524,7 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop) func = RNA_def_function(srna, "new_movie", "rna_Sequences_new_movie"); RNA_def_function_flag(func, FUNC_USE_REPORTS | FUNC_USE_SELF_ID); RNA_def_function_ui_description(func, "Add a new movie sequence"); - parm = RNA_def_string(func, "name", "Name", 0, "", "New name for the sequence"); + parm = RNA_def_string(func, "name", "Name", 0, "", "Name for the new sequence"); RNA_def_property_flag(parm, PROP_REQUIRED); parm = RNA_def_string(func, "filepath", "File", 0, "", "Filepath to movie"); RNA_def_property_flag(parm, PROP_REQUIRED); @@ -540,8 +540,8 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop) func = RNA_def_function(srna, "new_sound", "rna_Sequences_new_sound"); RNA_def_function_flag(func, FUNC_USE_REPORTS | FUNC_USE_SELF_ID | FUNC_USE_MAIN); - RNA_def_function_ui_description(func, "Add a new movie clip sequence"); - parm = RNA_def_string(func, "name", "Name", 0, "", "New name for the sequence"); + RNA_def_function_ui_description(func, "Add a new sound sequence"); + parm = RNA_def_string(func, "name", "Name", 0, "", "Name for the new sequence"); RNA_def_property_flag(parm, PROP_REQUIRED); parm = RNA_def_string(func, "filepath", "File", 0, "", "Filepath to movie"); RNA_def_property_flag(parm, PROP_REQUIRED); @@ -558,7 +558,7 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop) func = RNA_def_function(srna, "new_effect", "rna_Sequences_new_effect"); RNA_def_function_flag(func, FUNC_USE_REPORTS | FUNC_USE_SELF_ID); RNA_def_function_ui_description(func, "Add a new effect sequence"); - parm = RNA_def_string(func, "name", "Name", 0, "", "New name for the sequence"); + parm = RNA_def_string(func, "name", "Name", 0, "", "Name for the new sequence"); RNA_def_property_flag(parm, PROP_REQUIRED); parm = RNA_def_enum(func, "type", seq_effect_items, 0, "Type", "type for the new sequence"); From 9f8070d047e1d8458db05fe88aef1a47a2328f14 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 20 Oct 2012 08:02:18 +0000 Subject: [PATCH 335/347] code cleanup: - define array sizes for functions that take vectors. - quiet some -Wshadow warnings. - some copy/paste error in readfile.c made it set the same particle recalc flag twice. --- .../kernel/osl/nodes/node_layer_weight.osl | 3 +- source/blender/blenkernel/BKE_particle.h | 21 +++++++++---- .../blenkernel/intern/modifiers_bmesh.c | 1 + source/blender/blenkernel/intern/particle.c | 21 +++++++++---- source/blender/blenlib/intern/edgehash.c | 2 +- source/blender/blenloader/intern/readfile.c | 22 ++++++-------- .../bmesh/operators/bmo_join_triangles.c | 13 +++++--- source/blender/editors/curve/editcurve.c | 3 +- source/blender/editors/mesh/editmesh_tools.c | 10 +++---- .../blender/render/intern/include/rayobject.h | 2 +- .../render/intern/include/rendercore.h | 5 ++-- .../render/intern/include/renderdatabase.h | 2 +- .../render/intern/raytrace/rayobject.cpp | 2 +- .../intern/raytrace/rayobject_internal.h | 7 ++--- .../intern/raytrace/rayobject_rtbuild.cpp | 14 +++++---- .../intern/raytrace/rayobject_rtbuild.h | 13 ++++---- .../blender/render/intern/source/rayshade.c | 2 +- .../render/intern/source/render_texture.c | 8 +++-- .../blender/render/intern/source/rendercore.c | 2 +- .../render/intern/source/renderdatabase.c | 30 ++++++++++--------- source/blender/render/intern/source/sss.c | 4 +-- 21 files changed, 105 insertions(+), 82 deletions(-) diff --git a/intern/cycles/kernel/osl/nodes/node_layer_weight.osl b/intern/cycles/kernel/osl/nodes/node_layer_weight.osl index 40b60fee7d3..3ea57f71786 100644 --- a/intern/cycles/kernel/osl/nodes/node_layer_weight.osl +++ b/intern/cycles/kernel/osl/nodes/node_layer_weight.osl @@ -36,7 +36,7 @@ shader node_layer_weight( Facing = abs(dot(I, Normal)); if (blend != 0.5) { - blend = clamp(blend, 0.0, 1.0-1e-5); + blend = clamp(blend, 0.0, 1.0 - 1e-5); blend = (blend < 0.5) ? 2.0 * blend : 0.5 / (1.0 - blend); Facing = pow(Facing, blend); @@ -44,4 +44,3 @@ shader node_layer_weight( Facing = 1.0 - Facing; } - diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h index b3e650b2aa5..ec03f53dbdb 100644 --- a/source/blender/blenkernel/BKE_particle.h +++ b/source/blender/blenkernel/BKE_particle.h @@ -257,7 +257,9 @@ void psys_interpolate_mcol(const struct MCol *mcol, int quad, const float w[4], void copy_particle_key(struct ParticleKey *to, struct ParticleKey *from, int time); -void psys_particle_on_emitter(struct ParticleSystemModifierData *psmd, int distr, int index, int index_dmcache, float *fuv, float foffset, float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor); +void psys_particle_on_emitter(struct ParticleSystemModifierData *psmd, int distr, int index, int index_dmcache, + float fuv[4], float foffset, float vec[3], float nor[3], + float utan[3], float vtan[3], float orco[3], float ornor[3]); struct ParticleSystemModifierData *psys_get_modifier(struct Object *ob, struct ParticleSystem *psys); struct ModifierData *object_add_particle_system(struct Scene *scene, struct Object *ob, const char *name); @@ -282,8 +284,11 @@ void psys_get_particle_on_path(struct ParticleSimulationData *sim, int pa_num, s int psys_get_particle_state(struct ParticleSimulationData *sim, int p, struct ParticleKey *state, int always); /* for anim.c */ -void psys_get_dupli_texture(struct ParticleSystem *psys, struct ParticleSettings *part, struct ParticleSystemModifierData *psmd, struct ParticleData *pa, struct ChildParticle *cpa, float *uv, float *orco); -void psys_get_dupli_path_transform(struct ParticleSimulationData *sim, struct ParticleData *pa, struct ChildParticle *cpa, struct ParticleCacheKey *cache, float mat[][4], float *scale); +void psys_get_dupli_texture(struct ParticleSystem *psys, struct ParticleSettings *part, + struct ParticleSystemModifierData *psmd, struct ParticleData *pa, struct ChildParticle *cpa, + float uv[2], float orco[3]); +void psys_get_dupli_path_transform(struct ParticleSimulationData *sim, struct ParticleData *pa, struct ChildParticle *cpa, + struct ParticleCacheKey *cache, float mat[][4], float *scale); ParticleThread *psys_threads_create(struct ParticleSimulationData *sim); void psys_threads_free(ParticleThread *threads); @@ -327,13 +332,17 @@ void psys_free_pdd(struct ParticleSystem *psys); float *psys_cache_vgroup(struct DerivedMesh *dm, struct ParticleSystem *psys, int vgroup); void psys_get_texture(struct ParticleSimulationData *sim, struct ParticleData *pa, struct ParticleTexture *ptex, int event, float cfra); -void psys_interpolate_face(struct MVert *mvert, struct MFace *mface, struct MTFace *tface, float (*orcodata)[3], float *uv, float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor); +void psys_interpolate_face(struct MVert *mvert, struct MFace *mface, struct MTFace *tface, + float (*orcodata)[3], float w[4], float vec[3], float nor[3], float utan[3], float vtan[3], + float orco[3], float ornor[3]); float psys_particle_value_from_verts(struct DerivedMesh *dm, short from, struct ParticleData *pa, float *values); -void psys_get_from_key(struct ParticleKey *key, float *loc, float *vel, float *rot, float *time); +void psys_get_from_key(struct ParticleKey *key, float loc[3], float vel[3], float rot[4], float *time); /* BLI_bvhtree_ray_cast callback */ void BKE_psys_collision_neartest_cb(void *userdata, int index, const struct BVHTreeRay *ray, struct BVHTreeRayHit *hit); -void psys_particle_on_dm(struct DerivedMesh *dm, int from, int index, int index_dmcache, const float fw[4], float foffset, float vec[3], float nor[3], float utan[3], float vtan[3], float orco[3], float ornor[3]); +void psys_particle_on_dm(struct DerivedMesh *dm, int from, int index, int index_dmcache, + const float fw[4], float foffset, float vec[3], float nor[3], float utan[3], float vtan[3], + float orco[3], float ornor[3]); /* particle_system.c */ void initialize_particle(struct ParticleSimulationData *sim, struct ParticleData *pa, int p); diff --git a/source/blender/blenkernel/intern/modifiers_bmesh.c b/source/blender/blenkernel/intern/modifiers_bmesh.c index 9ccdddee1ad..98eac9b95af 100644 --- a/source/blender/blenkernel/intern/modifiers_bmesh.c +++ b/source/blender/blenkernel/intern/modifiers_bmesh.c @@ -96,6 +96,7 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) /*do edges*/ me = medge = dm->dupEdgeArray(dm); for (i = 0; i < totedge; i++, me++) { + //BLI_assert(BM_edge_exists(vtable[me->v1], vtable[me->v2]) == NULL); e = BM_edge_create(bm, vtable[me->v1], vtable[me->v2], NULL, FALSE); e->head.hflag = BM_edge_flag_from_mflag(me->flag); diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 1749ad18c9b..60d3b7a8846 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -1404,7 +1404,8 @@ static void interpolate_pathcache(ParticleCacheKey *first, float t, ParticleCach /************************************************/ /* interpolate a location on a face based on face coordinates */ void psys_interpolate_face(MVert *mvert, MFace *mface, MTFace *tface, float (*orcodata)[3], - float *w, float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor) + float w[4], float vec[3], float nor[3], float utan[3], float vtan[3], + float orco[3], float ornor[3]) { float *v1 = 0, *v2 = 0, *v3 = 0, *v4 = 0; float e1[3], e2[3], s1, s2, t1, t2; @@ -1747,7 +1748,9 @@ static int psys_map_index_on_dm(DerivedMesh *dm, int from, int index, int index_ } /* interprets particle data to get a point on a mesh in object space */ -void psys_particle_on_dm(DerivedMesh *dm, int from, int index, int index_dmcache, const float fw[4], float foffset, float vec[3], float nor[3], float utan[3], float vtan[3], float orco[3], float ornor[3]) +void psys_particle_on_dm(DerivedMesh *dm, int from, int index, int index_dmcache, + const float fw[4], float foffset, float vec[3], float nor[3], float utan[3], float vtan[3], + float orco[3], float ornor[3]) { float tmpnor[3], mapfw[4]; float (*orcodata)[3]; @@ -1843,7 +1846,9 @@ ParticleSystemModifierData *psys_get_modifier(Object *ob, ParticleSystem *psys) /* Particles on a shape */ /************************************************/ /* ready for future use */ -static void psys_particle_on_shape(int UNUSED(distr), int UNUSED(index), float *UNUSED(fuv), float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor) +static void psys_particle_on_shape(int UNUSED(distr), int UNUSED(index), + float *UNUSED(fuv), float vec[3], float nor[3], float utan[3], float vtan[3], + float orco[3], float ornor[3]) { /* TODO */ float zerovec[3] = {0.0f, 0.0f, 0.0f}; @@ -1869,7 +1874,9 @@ static void psys_particle_on_shape(int UNUSED(distr), int UNUSED(index), float * /************************************************/ /* Particles on emitter */ /************************************************/ -void psys_particle_on_emitter(ParticleSystemModifierData *psmd, int from, int index, int index_dmcache, float *fuv, float foffset, float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor) +void psys_particle_on_emitter(ParticleSystemModifierData *psmd, int from, int index, int index_dmcache, + float fuv[4], float foffset, float vec[3], float nor[3], float utan[3], float vtan[3], + float orco[3], float ornor[3]) { if (psmd) { if (psmd->psys->part->distr == PART_DISTR_GRID && psmd->psys->part->from != PART_FROM_VERT) { @@ -3299,7 +3306,7 @@ void copy_particle_key(ParticleKey *to, ParticleKey *from, int time) to->time = to_time; } } -void psys_get_from_key(ParticleKey *key, float *loc, float *vel, float *rot, float *time) +void psys_get_from_key(ParticleKey *key, float loc[3], float vel[3], float rot[4], float *time) { if (loc) copy_v3_v3(loc, key->co); if (vel) copy_v3_v3(vel, key->vel); @@ -4415,7 +4422,9 @@ int psys_get_particle_state(ParticleSimulationData *sim, int p, ParticleKey *sta } } -void psys_get_dupli_texture(ParticleSystem *psys, ParticleSettings *part, ParticleSystemModifierData *psmd, ParticleData *pa, ChildParticle *cpa, float *uv, float *orco) +void psys_get_dupli_texture(ParticleSystem *psys, ParticleSettings *part, + ParticleSystemModifierData *psmd, ParticleData *pa, ChildParticle *cpa, + float uv[2], float orco[3]) { MFace *mface; MTFace *mtface; diff --git a/source/blender/blenlib/intern/edgehash.c b/source/blender/blenlib/intern/edgehash.c index d58ccbbd48e..4fb48d19239 100644 --- a/source/blender/blenlib/intern/edgehash.c +++ b/source/blender/blenlib/intern/edgehash.c @@ -108,7 +108,7 @@ void BLI_edgehash_insert(EdgeHash *eh, unsigned int v0, unsigned int v1, void *v eh->buckets[hash] = e; if (++eh->nentries > eh->nbuckets * 3) { - EdgeEntry *e, **old = eh->buckets; + EdgeEntry **old = eh->buckets; int i, nold = eh->nbuckets; eh->nbuckets = _ehash_hashsizes[++eh->cursize]; diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 41a635a5e01..ea0a711788e 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -3629,12 +3629,13 @@ static void lib_link_customdata_mtpoly(FileData *fd, Mesh *me, CustomData *pdata if (layer->type == CD_MTEXPOLY) { MTexPoly *tf= layer->data; - int i; + int j; - for (i = 0; i < totface; i++, tf++) { + for (j = 0; j < totface; j++, tf++) { tf->tpage = newlibadr(fd, me->id.lib, tf->tpage); - if (tf->tpage && tf->tpage->id.us==0) + if (tf->tpage && tf->tpage->id.us == 0) { tf->tpage->id.us = 1; + } } } } @@ -6788,7 +6789,6 @@ static void do_versions_nodetree_socket_use_flags_2_62(bNodeTree *ntree) static void do_versions_nodetree_multi_file_output_format_2_62_1(Scene *sce, bNodeTree *ntree) { bNode *node; - bNodeSocket *sock; for (node = ntree->nodes.first; node; node = node->next) { if (node->type == CMP_NODE_OUTPUT_FILE) { @@ -6865,6 +6865,7 @@ static void do_versions_nodetree_multi_file_output_format_2_62_1(Scene *sce, bNo } else if (node->type==CMP_NODE_OUTPUT_MULTI_FILE__DEPRECATED) { NodeImageMultiFile *nimf = node->storage; + bNodeSocket *sock; /* CMP_NODE_OUTPUT_MULTI_FILE has been redeclared as CMP_NODE_OUTPUT_FILE */ node->type = CMP_NODE_OUTPUT_FILE; @@ -7188,9 +7189,9 @@ static void do_versions(FileData *fd, Library *lib, Main *main) v3d->bundle_drawtype = OB_PLAINAXES; } else if (sl->spacetype == SPACE_CLIP) { - SpaceClip *sc = (SpaceClip *)sl; - if (sc->scopes.track_preview_height == 0) - sc->scopes.track_preview_height = 120; + SpaceClip *sclip = (SpaceClip *)sl; + if (sclip->scopes.track_preview_height == 0) + sclip->scopes.track_preview_height = 120; } } } @@ -7592,13 +7593,8 @@ static void do_versions(FileData *fd, Library *lib, Main *main) if (main->versionfile < 263) { /* Default for old files is to save particle rotations to pointcache */ ParticleSettings *part; - for (part = main->particle.first; part; part = part->id.next) + for (part = main->particle.first; part; part = part->id.next) { part->flag |= PART_ROTATIONS; - { - /* Default for old files is to save particle rotations to pointcache */ - ParticleSettings *part; - for (part = main->particle.first; part; part = part->id.next) - part->flag |= PART_ROTATIONS; } } diff --git a/source/blender/bmesh/operators/bmo_join_triangles.c b/source/blender/bmesh/operators/bmo_join_triangles.c index 7191aa7a7b6..3dbc0d0a5eb 100644 --- a/source/blender/bmesh/operators/bmo_join_triangles.c +++ b/source/blender/bmesh/operators/bmo_join_triangles.c @@ -199,7 +199,7 @@ void bmo_join_triangles_exec(BMesh *bm, BMOperator *op) { BMIter iter, liter; BMOIter siter; - BMFace *f1, *f2; + BMFace *f; BMLoop *l; BMEdge *e; BLI_array_declare(jedges); @@ -213,15 +213,16 @@ void bmo_join_triangles_exec(BMesh *bm, BMOperator *op) int i, totedge; /* flag all edges of all input face */ - BMO_ITER (f1, &siter, bm, op, "faces", BM_FACE) { - BMO_elem_flag_enable(bm, f1, FACE_INPUT); - BM_ITER_ELEM (l, &liter, f1, BM_LOOPS_OF_FACE) { + BMO_ITER (f, &siter, bm, op, "faces", BM_FACE) { + BMO_elem_flag_enable(bm, f, FACE_INPUT); + BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) { BMO_elem_flag_enable(bm, l->e, EDGE_MARK); } } /* unflag edges that are invalid; e.g. aren't surrounded by triangle */ BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { + BMFace *f1, *f2; if (!BMO_elem_flag_test(bm, e, EDGE_MARK)) continue; @@ -300,6 +301,8 @@ void bmo_join_triangles_exec(BMesh *bm, BMOperator *op) } BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { + BMFace *f1, *f2; + if (!BMO_elem_flag_test(bm, e, EDGE_CHOSEN)) continue; @@ -310,6 +313,8 @@ void bmo_join_triangles_exec(BMesh *bm, BMOperator *op) BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { if (BMO_elem_flag_test(bm, e, EDGE_MARK)) { + BMFace *f1, *f2; + /* ok, this edge wasn't merged, check if it's * in a 2-tri-pair island, and if so merg */ diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index 19c7fc39c82..874b31dd1ca 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -6604,7 +6604,6 @@ static int curvesurf_prim_add(bContext *C, wmOperator *op, int type, int isSurf) unsigned int layer; float loc[3], rot[3]; float mat[4][4]; - float dia; if (!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, &is_aligned)) return OPERATOR_CANCELLED; @@ -6648,7 +6647,7 @@ static int curvesurf_prim_add(bContext *C, wmOperator *op, int type, int isSurf) if (newob && enter_editmode) ED_undo_push(C, "Enter Editmode"); - dia = ED_object_new_primitive_matrix(C, obedit, loc, rot, mat, TRUE); + ED_object_new_primitive_matrix(C, obedit, loc, rot, mat, TRUE); nu = add_nurbs_primitive(C, obedit, mat, type, newob); editnurb = object_editcurve_get(obedit); diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index eba71a63e2c..2dbcd20a276 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -5487,7 +5487,7 @@ static int mesh_symmetrize_exec(bContext *C, wmOperator *op) BMOperator bmop; EDBM_op_init(em, &bmop, op, "symmetrize input=%hvef direction=%i", - BM_ELEM_SELECT, RNA_enum_get(op->ptr, "direction")); + BM_ELEM_SELECT, RNA_enum_get(op->ptr, "direction")); BMO_op_exec(em->bm, &bmop); if (!EDBM_op_finish(em, &bmop, op, TRUE)) { @@ -5502,7 +5502,7 @@ static int mesh_symmetrize_exec(bContext *C, wmOperator *op) void MESH_OT_symmetrize(struct wmOperatorType *ot) { - static EnumPropertyItem direction_items[] = { + static EnumPropertyItem axis_direction_items[] = { {BMO_SYMMETRIZE_NEGATIVE_X, "NEGATIVE_X", 0, "-X to +X", ""}, {BMO_SYMMETRIZE_POSITIVE_X, "POSITIVE_X", 0, "+X to -X", ""}, @@ -5526,7 +5526,7 @@ void MESH_OT_symmetrize(struct wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - ot->prop = RNA_def_enum(ot->srna, "direction", direction_items, - BMO_SYMMETRIZE_NEGATIVE_X, - "Direction", "Which sides to copy from and to"); + ot->prop = RNA_def_enum(ot->srna, "direction", axis_direction_items, + BMO_SYMMETRIZE_NEGATIVE_X, + "Direction", "Which sides to copy from and to"); } diff --git a/source/blender/render/intern/include/rayobject.h b/source/blender/render/intern/include/rayobject.h index 7752baadff4..07fc7d7a6ed 100644 --- a/source/blender/render/intern/include/rayobject.h +++ b/source/blender/render/intern/include/rayobject.h @@ -104,7 +104,7 @@ RayObject *RE_vlakprimitive_from_vlak(VlakPrimitive *face, struct ObjectInstance void RE_rayobject_merge_bb(RayObject *ob, float *min, float *max); /* initializes an hint for optimizing raycast where it is know that a ray will pass by the given BB often the origin point */ -void RE_rayobject_hint_bb(RayObject *r, struct RayHint *hint, float *min, float *max); +void RE_rayobject_hint_bb(RayObject *r, struct RayHint *hint, float min[3], float max[3]); /* initializes an hint for optimizing raycast where it is know that a ray will be contained inside the given cone*/ /* void RE_rayobject_hint_cone(RayObject *r, struct RayHint *hint, float *); */ diff --git a/source/blender/render/intern/include/rendercore.h b/source/blender/render/intern/include/rendercore.h index 0fbbf52e613..30712250440 100644 --- a/source/blender/render/intern/include/rendercore.h +++ b/source/blender/render/intern/include/rendercore.h @@ -62,7 +62,7 @@ typedef struct PixStrMain { /* ------------------------------------------------------------------------- */ -void calc_view_vector(float *view, float x, float y); +void calc_view_vector(float view[3], float x, float y); float mistfactor(float zcor, const float co[3]); /* dist and height, return alpha */ void renderspothalo(struct ShadeInput *shi, float col[4], float alpha); @@ -95,5 +95,4 @@ extern void init_ao_sphere(struct World *wrld); extern void init_render_qmcsampler(Render *re); extern void free_render_qmcsampler(Render *re); -#endif /* RENDER_EXT_H */ - +#endif /* __RENDERCORE_H__ */ diff --git a/source/blender/render/intern/include/renderdatabase.h b/source/blender/render/intern/include/renderdatabase.h index d116dfe7b17..5213f14d773 100644 --- a/source/blender/render/intern/include/renderdatabase.h +++ b/source/blender/render/intern/include/renderdatabase.h @@ -88,7 +88,7 @@ void free_renderdata_vertnodes(struct VertTableNode *vertnodes); void free_renderdata_vlaknodes(struct VlakTableNode *vlaknodes); void project_renderdata(struct Render *re, void (*projectfunc)(const float *, float mat[][4], float *), int do_pano, float xoffs, int do_buckets); -int clip_render_object(float boundbox[][3], float *bounds, float mat[][4]); +int clip_render_object(float boundbox[][3], float bounds[4], float mat[][4]); /* functions are not exported... so wrong names */ diff --git a/source/blender/render/intern/raytrace/rayobject.cpp b/source/blender/render/intern/raytrace/rayobject.cpp index 6f14c6153f9..c3babf99d51 100644 --- a/source/blender/render/intern/raytrace/rayobject.cpp +++ b/source/blender/render/intern/raytrace/rayobject.cpp @@ -467,7 +467,7 @@ float RE_rayobject_cost(RayObject *r) /* Bounding Boxes */ -void RE_rayobject_merge_bb(RayObject *r, float *min, float *max) +void RE_rayobject_merge_bb(RayObject *r, float min[3], float max[3]) { if (RE_rayobject_isRayFace(r)) { RayFace *face = (RayFace *) RE_rayobject_align(r); diff --git a/source/blender/render/intern/raytrace/rayobject_internal.h b/source/blender/render/intern/raytrace/rayobject_internal.h index 3f768e5adcb..07672f7bfb2 100644 --- a/source/blender/render/intern/raytrace/rayobject_internal.h +++ b/source/blender/render/intern/raytrace/rayobject_internal.h @@ -124,9 +124,9 @@ typedef int (*RE_rayobject_raycast_callback)(RayObject *, struct Isect *); typedef void (*RE_rayobject_add_callback)(RayObject *raytree, RayObject *rayobject); typedef void (*RE_rayobject_done_callback)(RayObject *); typedef void (*RE_rayobject_free_callback)(RayObject *); -typedef void (*RE_rayobject_merge_bb_callback)(RayObject *, float *min, float *max); +typedef void (*RE_rayobject_merge_bb_callback)(RayObject *, float min[3], float max[3]); typedef float (*RE_rayobject_cost_callback)(RayObject *); -typedef void (*RE_rayobject_hint_bb_callback)(RayObject *, struct RayHint *, float *, float *); +typedef void (*RE_rayobject_hint_bb_callback)(RayObject *, struct RayHint *, float min[3], float max[3]); typedef struct RayObjectAPI { RE_rayobject_raycast_callback raycast; @@ -154,5 +154,4 @@ int RE_rayobject_intersect(RayObject *r, struct Isect *i); } #endif -#endif - +#endif /* __RAYOBJECT_INTERNAL_H__ */ diff --git a/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp b/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp index 3926e8b8e51..678aa8e5634 100644 --- a/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp +++ b/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp @@ -193,7 +193,7 @@ static void rtbuild_calc_bb(RTBuilder *b) } } -void rtbuild_merge_bb(RTBuilder *b, float *min, float *max) +void rtbuild_merge_bb(RTBuilder *b, float min[3], float max[3]) { rtbuild_calc_bb(b); DO_MIN(b->bb, min); @@ -457,26 +457,26 @@ static void split_leafs(RTBuilder *b, int *nth, int partitions, int split_axis) /* * Bounding Box utils */ -float bb_volume(float *min, float *max) +float bb_volume(const float min[3], const float max[3]) { return (max[0] - min[0]) * (max[1] - min[1]) * (max[2] - min[2]); } -float bb_area(float *min, float *max) +float bb_area(const float min[3], const float max[3]) { float sub[3], a; sub[0] = max[0] - min[0]; sub[1] = max[1] - min[1]; sub[2] = max[2] - min[2]; - a = (sub[0] * sub[1] + sub[0] * sub[2] + sub[1] * sub[2]) * 2; + a = (sub[0] * sub[1] + sub[0] * sub[2] + sub[1] * sub[2]) * 2.0f; /* used to have an assert() here on negative results * however, in this case its likely some overflow or ffast math error. * so just return 0.0f instead. */ return a < 0.0f ? 0.0f : a; } -int bb_largest_axis(float *min, float *max) +int bb_largest_axis(const float min[3], const float max[3]) { float sub[3]; @@ -497,7 +497,9 @@ int bb_largest_axis(float *min, float *max) } } -int bb_fits_inside(float *outer_min, float *outer_max, float *inner_min, float *inner_max) +/* only returns 0 if merging inner and outerbox would create a box larger than outer box */ +int bb_fits_inside(const float outer_min[3], const float outer_max[3], + const float inner_min[3], const float inner_max[3]) { int i; for (i = 0; i < 3; i++) diff --git a/source/blender/render/intern/raytrace/rayobject_rtbuild.h b/source/blender/render/intern/raytrace/rayobject_rtbuild.h index 22e3d009c07..9e296da144b 100644 --- a/source/blender/render/intern/raytrace/rayobject_rtbuild.h +++ b/source/blender/render/intern/raytrace/rayobject_rtbuild.h @@ -86,7 +86,7 @@ RTBuilder *rtbuild_create(int size); void rtbuild_free(RTBuilder *b); void rtbuild_add(RTBuilder *b, RayObject *o); void rtbuild_done(RTBuilder *b, RayObjectControl *c); -void rtbuild_merge_bb(RTBuilder *b, float *min, float *max); +void rtbuild_merge_bb(RTBuilder *b, float min[3], float max[3]); int rtbuild_size(RTBuilder *b); RayObject *rtbuild_get_primitive(RTBuilder *b, int offset); @@ -109,13 +109,14 @@ int rtbuild_median_split_largest_axis(RTBuilder *b, int nchilds); /* bb utils */ -float bb_area(float *min, float *max); -float bb_volume(float *min, float *max); -int bb_largest_axis(float *min, float *max); -int bb_fits_inside(float *outer_min, float *outer_max, float *inner_min, float *inner_max); /* only returns 0 if merging inner and outerbox would create a box larger than outer box */ +float bb_area(const float min[3], const float max[3]); +float bb_volume(const float min[3], const float max[3]); +int bb_largest_axis(const float min[3], const float max[3]); +int bb_fits_inside(const float outer_min[3], const float outer_max[3], + const float inner_min[3], const float inner_max[3]); #ifdef __cplusplus } #endif -#endif +#endif /* __RAYOBJECT_RTBUILD_H__ */ diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index aa35d73f3b5..260a80d70e9 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -2532,7 +2532,7 @@ void ray_shadow(ShadeInput *shi, LampRen *lar, float shadfac[4]) #if 0 /* only when face points away from lamp, in direction of lamp, trace ray and find first exit point */ -static void ray_translucent(ShadeInput *shi, LampRen *lar, float *distfac, float *co) +static void ray_translucent(ShadeInput *shi, LampRen *lar, float *distfac, float co[3]) { Isect isec; float lampco[3]; diff --git a/source/blender/render/intern/source/render_texture.c b/source/blender/render/intern/source/render_texture.c index 91da5c50d01..167e91272e2 100644 --- a/source/blender/render/intern/source/render_texture.c +++ b/source/blender/render/intern/source/render_texture.c @@ -1843,7 +1843,9 @@ static void ntap_bump_init(NTapBump *ntap_bump) memset(ntap_bump, 0, sizeof(*ntap_bump)); } -static int ntap_bump_compute(NTapBump *ntap_bump, ShadeInput *shi, MTex *mtex, Tex *tex, TexResult *texres, float Tnor, float *co, float *dx, float *dy, float texvec[3], float dxt[3], float dyt[3]) +static int ntap_bump_compute(NTapBump *ntap_bump, ShadeInput *shi, MTex *mtex, Tex *tex, TexResult *texres, + float Tnor, const float co[3], const float dx[3], const float dy[3], + float texvec[3], float dxt[3], float dyt[3]) { TexResult ttexr = {0, 0, 0, 0, 0, texres->talpha, NULL}; /* temp TexResult */ @@ -2269,11 +2271,11 @@ void do_material_tex(ShadeInput *shi, Render *re) if (texres.nor && !((tex->type==TEX_IMAGE) && (tex->imaflag & TEX_NORMALMAP))) { if (use_compat_bump) { rgbnor = compatible_bump_compute(&compat_bump, shi, mtex, tex, - &texres, Tnor*stencilTin, co, dx, dy, texvec, dxt, dyt); + &texres, Tnor*stencilTin, co, dx, dy, texvec, dxt, dyt); } else if (use_ntap_bump) { rgbnor = ntap_bump_compute(&ntap_bump, shi, mtex, tex, - &texres, Tnor*stencilTin, co, dx, dy, texvec, dxt, dyt); + &texres, Tnor*stencilTin, co, dx, dy, texvec, dxt, dyt); } else { texco_mapping(shi, tex, mtex, co, dx, dy, texvec, dxt, dyt); diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c index bad3b18919c..0bfbed8e58c 100644 --- a/source/blender/render/intern/source/rendercore.c +++ b/source/blender/render/intern/source/rendercore.c @@ -94,7 +94,7 @@ extern struct Render R; /* x and y are current pixels in rect to be rendered */ /* do not normalize! */ -void calc_view_vector(float *view, float x, float y) +void calc_view_vector(float view[3], float x, float y) { view[2]= -ABS(R.clipsta); diff --git a/source/blender/render/intern/source/renderdatabase.c b/source/blender/render/intern/source/renderdatabase.c index 172af3a6c6f..1721741d64d 100644 --- a/source/blender/render/intern/source/renderdatabase.c +++ b/source/blender/render/intern/source/renderdatabase.c @@ -1356,40 +1356,42 @@ void RE_makeRenderInstances(Render *re) re->instancetable= newlist; } -int clip_render_object(float boundbox[][3], float *bounds, float winmat[][4]) +int clip_render_object(float boundbox[][3], float bounds[4], float winmat[][4]) { float mat[4][4], vec[4]; - int a, fl, flag= -1; + int a, fl, flag = -1; copy_m4_m4(mat, winmat); - for (a=0; a<8; a++) { + for (a=0; a < 8; a++) { vec[0]= (a & 1)? boundbox[0][0]: boundbox[1][0]; vec[1]= (a & 2)? boundbox[0][1]: boundbox[1][1]; vec[2]= (a & 4)? boundbox[0][2]: boundbox[1][2]; vec[3]= 1.0; mul_m4_v4(mat, vec); - fl= 0; + fl = 0; if (bounds) { - if (vec[0] < bounds[0]*vec[3]) fl |= 1; - else if (vec[0] > bounds[1]*vec[3]) fl |= 2; + if (vec[0] < bounds[0] * vec[3]) fl |= 1; + else if (vec[0] > bounds[1] * vec[3]) fl |= 2; - if (vec[1] > bounds[3]*vec[3]) fl |= 4; - else if (vec[1]< bounds[2]*vec[3]) fl |= 8; + if (vec[1] > bounds[3] * vec[3]) fl |= 4; + else if (vec[1] < bounds[2] * vec[3]) fl |= 8; } else { - if (vec[0] < -vec[3]) fl |= 1; - else if (vec[0] > vec[3]) fl |= 2; + if (vec[0] < -vec[3]) fl |= 1; + else if (vec[0] > vec[3]) fl |= 2; - if (vec[1] > vec[3]) fl |= 4; + if (vec[1] > vec[3]) fl |= 4; else if (vec[1] < -vec[3]) fl |= 8; } - if (vec[2] < -vec[3]) fl |= 16; - else if (vec[2] > vec[3]) fl |= 32; + if (vec[2] < -vec[3]) fl |= 16; + else if (vec[2] > vec[3]) fl |= 32; flag &= fl; - if (flag==0) return 0; + if (flag == 0) { + return 0; + } } return flag; diff --git a/source/blender/render/intern/source/sss.c b/source/blender/render/intern/source/sss.c index 9b7a521db41..77d68e6c85a 100644 --- a/source/blender/render/intern/source/sss.c +++ b/source/blender/render/intern/source/sss.c @@ -381,7 +381,7 @@ static void add_radiance(ScatterTree *tree, float *frontrad, float *backrad, flo } } -static void traverse_octree(ScatterTree *tree, ScatterNode *node, float *co, int self, ScatterResult *result) +static void traverse_octree(ScatterTree *tree, ScatterNode *node, const float co[3], int self, ScatterResult *result) { float sub[3], dist; int i, index = 0; @@ -432,7 +432,7 @@ static void traverse_octree(ScatterTree *tree, ScatterNode *node, float *co, int } } -static void compute_radiance(ScatterTree *tree, float *co, float *rad) +static void compute_radiance(ScatterTree *tree, const float co[3], float *rad) { ScatterResult result; float rdsum[3], backrad[3], backrdsum[3]; From 494aa37f94f4b60a32d9eb6ad8fc148d30d73add Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Sat, 20 Oct 2012 08:33:54 +0000 Subject: [PATCH 336/347] Fix unix language setting fallback (long_locale is windows only!). This was preventing setting language when you did not have the relevant locale installed under Linux... --- source/blender/blenfont/intern/blf_lang.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/blenfont/intern/blf_lang.c b/source/blender/blenfont/intern/blf_lang.c index 284983b346a..d251542ead0 100644 --- a/source/blender/blenfont/intern/blf_lang.c +++ b/source/blender/blenfont/intern/blf_lang.c @@ -257,7 +257,7 @@ void BLF_lang_set(const char *str) if (locreturn == NULL) { char language[65]; - get_language(long_locale, default_lang, language, sizeof(language)); + get_language(short_locale, default_lang, language, sizeof(language)); if (G.debug & G_DEBUG) printf("Fallback to LANG=%s and LANGUAGE=%s\n", default_lang, language); From 95a414955ce2d15c62adde665ced18804ca98945 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Sat, 20 Oct 2012 08:52:54 +0000 Subject: [PATCH 337/347] Remove six languages from Blender UI (rational: very low level of translation, 1-2% at most, and no commit done in branch since more than one year): fi (Finnish), ca (Catalan), bg (Bulgarian), el (Greek), ne (Nepali) and pl (Polish). Also fix compile in paranoid warning=errors mode for own last commit. --- .../bl_i18n_utils/import_po_from_branches.py | 4 ++- .../scripts/modules/bl_i18n_utils/settings.py | 3 ++ source/blender/blenfont/intern/blf_lang.c | 33 ++++++++++--------- source/blender/makesrna/intern/rna_userdef.c | 16 ++++----- 4 files changed, 32 insertions(+), 24 deletions(-) diff --git a/release/scripts/modules/bl_i18n_utils/import_po_from_branches.py b/release/scripts/modules/bl_i18n_utils/import_po_from_branches.py index a15bea9ef0d..533dded3c57 100755 --- a/release/scripts/modules/bl_i18n_utils/import_po_from_branches.py +++ b/release/scripts/modules/bl_i18n_utils/import_po_from_branches.py @@ -39,6 +39,8 @@ except: TRUNK_PO_DIR = settings.TRUNK_PO_DIR BRANCHES_DIR = settings.BRANCHES_DIR +IMPORT_LANGUAGES_SKIP = settings.IMPORT_LANGUAGES_SKIP + RTL_PREPROCESS_FILE = settings.RTL_PREPROCESS_FILE PY3 = settings.PYTHON3_EXEC @@ -63,7 +65,7 @@ def main(): threshold = float(args.threshold) / 100.0 for lang in os.listdir(BRANCHES_DIR): - if args.langs and lang not in args.langs: + if (args.langs and lang not in args.langs) or lang in IMPORT_LANGUAGES_SKIP: continue po = os.path.join(BRANCHES_DIR, lang, ".".join((lang, "po"))) if os.path.exists(po): diff --git a/release/scripts/modules/bl_i18n_utils/settings.py b/release/scripts/modules/bl_i18n_utils/settings.py index 5db8f9c7c94..26a4cbaeb01 100644 --- a/release/scripts/modules/bl_i18n_utils/settings.py +++ b/release/scripts/modules/bl_i18n_utils/settings.py @@ -35,6 +35,9 @@ import os.path # into /trunk, as a percentage. -1 means "import everything". IMPORT_MIN_LEVEL = -1 +# Languages in /branches we do not want to import in /trunk currently... +IMPORT_LANGUAGES_SKIP = {'bg', 'ca', 'fi', 'el', 'ko', 'ne', 'pl', 'ro'} + # The comment prefix used in generated messages.txt file. COMMENT_PREFIX = "#~ " diff --git a/source/blender/blenfont/intern/blf_lang.c b/source/blender/blenfont/intern/blf_lang.c index d251542ead0..af2f9df3c00 100644 --- a/source/blender/blenfont/intern/blf_lang.c +++ b/source/blender/blenfont/intern/blf_lang.c @@ -171,7 +171,6 @@ void BLF_lang_set(const char *str) char *locreturn; const char *short_locale; int ok = 1; - const char *long_locale = locales[2 * U.language]; if ((U.transopts & USER_DOTRANSLATE) == 0) return; @@ -182,25 +181,29 @@ void BLF_lang_set(const char *str) short_locale = locales[2 * U.language + 1]; #if defined(_WIN32) && !defined(FREE_WINDOWS) - if (short_locale) { - char *envStr; + { + const char *long_locale = locales[2 * U.language]; - if (U.language == 0) /* Use system setting. */ - envStr = BLI_sprintfN("LANG=%s", getenv("LANG")); - else - envStr = BLI_sprintfN("LANG=%s", short_locale); + if (short_locale) { + char *envStr; - gettext_putenv(envStr); - MEM_freeN(envStr); - } + if (U.language == 0) /* Use system setting. */ + envStr = BLI_sprintfN("LANG=%s", getenv("LANG")); + else + envStr = BLI_sprintfN("LANG=%s", short_locale); - locreturn = setlocale(LC_ALL, long_locale); + gettext_putenv(envStr); + MEM_freeN(envStr); + } - if (locreturn == NULL) { - if (G.debug & G_DEBUG) - printf("Could not change locale to %s\n", long_locale); + locreturn = setlocale(LC_ALL, long_locale); - ok = 0; + if (locreturn == NULL) { + if (G.debug & G_DEBUG) + printf("Could not change locale to %s\n", long_locale); + + ok = 0; + } } #else { diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index e98004db5b7..614029e12ec 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -3005,27 +3005,27 @@ static void rna_def_userdef_system(BlenderRNA *brna) {14, "TRADITIONAL_CHINESE", 0, "Traditional Chinese (繁體中文)", "zh_TW"}, {18, "UKRAINIAN", 0, "Ukrainian (Український)", "uk_UA"}, { 0, "", 0, N_("In Progress"), ""}, - {22, "BULGARIAN", 0, "Bulgarian (Български)", "bg_BG"}, - {10, "CATALAN", 0, "Catalan (Català)", "ca_AD"}, +/* {22, "BULGARIAN", 0, "Bulgarian (Български)", "bg_BG"},*/ /* XXX Not active nor enough translated. */ +/* {10, "CATALAN", 0, "Catalan (Català)", "ca_AD"},*/ /* XXX Not active nor enough translated. */ {16, "CROATIAN", 0, "Croatian (Hrvatski)", "hr_HR"}, {11, "CZECH", 0, "Czech (Český)", "cs_CZ"}, { 3, "DUTCH", 0, "Dutch (Nederlandse taal)", "nl_NL"}, {35, "ESPERANTO", 0, "Esperanto (Esperanto)", "eo"}, {34, "ESTONIAN", 0, "Estonian (Eestlane)", "et_EE"}, - { 6, "FINNISH", 0, "Finnish (Suomi)", "fi_FI"}, +/* { 6, "FINNISH", 0, "Finnish (Suomi)", "fi_FI"},*/ /* XXX Not active nor enough translated. */ { 5, "GERMAN", 0, "German (Deutsch)", "de_DE"}, - {23, "GREEK", 0, "Greek (Ελληνικά)", "el_GR"}, +/* {23, "GREEK", 0, "Greek (Ελληνικά)", "el_GR"},*/ /* XXX Not active nor enough translated. */ /* using the utf8 flipped form of Hebrew (עִבְרִית)) */ {33, "HEBREW", 0, "Hebrew (תירִבְעִ)", "he_IL"}, {31, "HUNGARIAN", 0, "Hungarian (Magyar)", "hu_HU"}, {27, "INDONESIAN", 0, "Indonesian (Bahasa indonesia)", "id_ID"}, {29, "KYRGYZ", 0, "Kyrgyz (Кыргыз тили)", "ky_KG"}, -/* {24, "KOREAN", 0, "Korean (한국 언어)", "ko_KR"}, */ /* XXX No po's yet. */ - {25, "NEPALI", 0, "Nepali (नेपाली)", "ne_NP"}, +/* {24, "KOREAN", 0, "Korean (한국 언어)", "ko_KR"}, */ /* XXX Not active nor enough translated. */ +/* {25, "NEPALI", 0, "Nepali (नेपाली)", "ne_NP"},*/ /* XXX Not active nor enough translated. */ /* using the utf8 flipped form of Persian (فارسی) */ {26, "PERSIAN", 0, "Persian (ﯽﺳﺭﺎﻓ)", "fa_IR"}, - {19, "POLISH", 0, "Polish (Polski)", "pl_PL"}, -/* {20, "ROMANIAN", 0, "Romanian (Român)", "ro_RO"}, */ /* XXX No po's yet. */ +/* {19, "POLISH", 0, "Polish (Polski)", "pl_PL"},*/ /* XXX Not active nor enough translated. */ +/* {20, "ROMANIAN", 0, "Romanian (Român)", "ro_RO"}, */ /* XXX Not active nor enough translated. */ {17, "SERBIAN", 0, "Serbian (Српски)", "sr_RS"}, {28, "SERBIAN_LATIN", 0, "Serbian Latin (Srpski latinica)", "sr_RS@latin"}, { 7, "SWEDISH", 0, "Swedish (Svenska)", "sv_SE"}, From a7a723283b9ec72888850999993287b598ceaecd Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 20 Oct 2012 09:48:41 +0000 Subject: [PATCH 338/347] add BM_edge_find_double() and use in bmesh decimator to fix crash. --- source/blender/bmesh/intern/bmesh_decimate.c | 27 +++++++++++++++++++- source/blender/bmesh/intern/bmesh_queries.c | 22 ++++++++++++++++ source/blender/bmesh/intern/bmesh_queries.h | 1 + 3 files changed, 49 insertions(+), 1 deletion(-) diff --git a/source/blender/bmesh/intern/bmesh_decimate.c b/source/blender/bmesh/intern/bmesh_decimate.c index 122f24955c6..519bdba02a9 100644 --- a/source/blender/bmesh/intern/bmesh_decimate.c +++ b/source/blender/bmesh/intern/bmesh_decimate.c @@ -503,8 +503,31 @@ static void bm_decim_edge_collapse(BMesh *bm, BMEdge *e, BMEdge *e_first; e_iter = e_first = v->e; do { + //BLI_assert(BM_edge_find_double(e_iter) == NULL); +#ifdef USE_SAFETY_CHECKS + /* note! - this check is slow, but we can't avoid it - Campbell */ + BMEdge *e_double; + + e_double = BM_edge_find_double(e_iter); + + if (UNLIKELY(e_double != NULL)) { + int e_index = BM_elem_index_get(e_double); + if (BM_edge_splice(bm, e_double, e_iter)) { + if (eheap_table[e_index]) { + BLI_heap_remove(eheap, eheap_table[e_index]); + eheap_table[e_index] = NULL; + } + } + } + + /* if this happens, the e_double check could be put in a while loop, + * so as to keep removing doubles while they are found. so far this isnt needed */ + BLI_assert(BM_edge_find_double(e_iter) == NULL); +#endif + bm_decim_build_edge_cost_single(e_iter, vquadrics, eheap, eheap_table); } while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e_first); + } } } @@ -566,9 +589,11 @@ void BM_mesh_decimate(BMesh *bm, const float factor) } #endif - /* free vars */ MEM_freeN(vquadrics); MEM_freeN(eheap_table); BLI_heap_free(eheap, NULL); + + /* testing only */ + // BM_mesh_validate(bm); } diff --git a/source/blender/bmesh/intern/bmesh_queries.c b/source/blender/bmesh/intern/bmesh_queries.c index 6bf4e3db1d3..9520b0298d8 100644 --- a/source/blender/bmesh/intern/bmesh_queries.c +++ b/source/blender/bmesh/intern/bmesh_queries.c @@ -1063,6 +1063,28 @@ BMEdge *BM_edge_exists(BMVert *v1, BMVert *v2) return NULL; } +/** + * Returns an edge sharing the same vertices as this one. + * This isn't an invalid state but tools should clean up these cases before + * returning the mesh to the user. + */ +BMEdge *BM_edge_find_double(BMEdge *e) +{ + BMVert *v = e->v1; + BMVert *v_other = e->v2; + + BMEdge *e_iter; + + e_iter = e; + while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e) { + if (UNLIKELY(BM_vert_in_edge(e_iter, v_other))) { + return e_iter; + } + } + + return NULL; +} + /** * Given a set of vertices \a varr, find out if * all those vertices overlap an existing face. diff --git a/source/blender/bmesh/intern/bmesh_queries.h b/source/blender/bmesh/intern/bmesh_queries.h index 84a5ffacec7..166b8a54f8a 100644 --- a/source/blender/bmesh/intern/bmesh_queries.h +++ b/source/blender/bmesh/intern/bmesh_queries.h @@ -74,6 +74,7 @@ BMLoop *BM_face_find_shortest_loop(BMFace *f); BMLoop *BM_face_find_longest_loop(BMFace *f); BMEdge *BM_edge_exists(BMVert *v1, BMVert *v2); +BMEdge *BM_edge_find_double(BMEdge *e); int BM_face_exists_overlap(BMesh *bm, BMVert **varr, int len, BMFace **r_existface); From 23d43396ffd667c6cab5f412bc13fa0b01bee4a3 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 20 Oct 2012 09:56:40 +0000 Subject: [PATCH 339/347] code cleanup: quiet -Wshadow warning, var name changes for splice functions and add assert for BM_edge_splice() when edges don't use the same vertices. --- source/blender/bmesh/intern/bmesh_core.c | 29 +++++++++++-------- .../blender/modifiers/intern/MOD_solidify.c | 13 +++++---- 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c index cef2c1f7573..4e6decfa913 100644 --- a/source/blender/bmesh/intern/bmesh_core.c +++ b/source/blender/bmesh/intern/bmesh_core.c @@ -1805,7 +1805,7 @@ BMFace *bmesh_jfke(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e) * where \a v and \a vtarget are connected by an edge * (assert checks for this case). */ -int BM_vert_splice(BMesh *bm, BMVert *v, BMVert *vtarget) +int BM_vert_splice(BMesh *bm, BMVert *v, BMVert *v_target) { BMEdge *e; @@ -1813,7 +1813,7 @@ int BM_vert_splice(BMesh *bm, BMVert *v, BMVert *vtarget) int i, loops_tot; /* verts already spliced */ - if (v == vtarget) { + if (v == v_target) { return FALSE; } @@ -1821,7 +1821,7 @@ int BM_vert_splice(BMesh *bm, BMVert *v, BMVert *vtarget) loops = BM_iter_as_arrayN(bm, BM_LOOPS_OF_VERT, v, &loops_tot); if (loops) { for (i = 0; i < loops_tot; i++) { - loops[i]->v = vtarget; + loops[i]->v = v_target; } MEM_freeN(loops); } @@ -1829,13 +1829,13 @@ int BM_vert_splice(BMesh *bm, BMVert *v, BMVert *vtarget) /* move all the edges from v's disk to vtarget's disk */ while ((e = v->e)) { bmesh_disk_edge_remove(e, v); - bmesh_edge_swapverts(e, v, vtarget); - bmesh_disk_edge_append(e, vtarget); + bmesh_edge_swapverts(e, v, v_target); + bmesh_disk_edge_append(e, v_target); BLI_assert(e->v1 != e->v2); } BM_CHECK_ELEMENT(v); - BM_CHECK_ELEMENT(vtarget); + BM_CHECK_ELEMENT(v_target); /* v is unused now, and can be killed */ BM_vert_kill(bm, v); @@ -2001,27 +2001,32 @@ int BM_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len, * * \note Edges must already have the same vertices. */ -int BM_edge_splice(BMesh *bm, BMEdge *e, BMEdge *etarget) +int BM_edge_splice(BMesh *bm, BMEdge *e, BMEdge *e_target) { BMLoop *l; - if (!BM_vert_in_edge(e, etarget->v1) || !BM_vert_in_edge(e, etarget->v2)) { + if (!BM_vert_in_edge(e, e_target->v1) || !BM_vert_in_edge(e, e_target->v2)) { /* not the same vertices can't splice */ + + /* the caller should really make sure this doesn't happen ever + * so assert on release builds */ + BLI_assert(0); + return FALSE; } while (e->l) { l = e->l; - BLI_assert(BM_vert_in_edge(etarget, l->v)); - BLI_assert(BM_vert_in_edge(etarget, l->next->v)); + BLI_assert(BM_vert_in_edge(e_target, l->v)); + BLI_assert(BM_vert_in_edge(e_target, l->next->v)); bmesh_radial_loop_remove(l, e); - bmesh_radial_append(etarget, l); + bmesh_radial_append(e_target, l); } BLI_assert(bmesh_radial_length(e->l) == 0); BM_CHECK_ELEMENT(e); - BM_CHECK_ELEMENT(etarget); + BM_CHECK_ELEMENT(e_target); /* removes from disks too */ BM_edge_kill(bm, e); diff --git a/source/blender/modifiers/intern/MOD_solidify.c b/source/blender/modifiers/intern/MOD_solidify.c index 1df7d535c35..cc77d73a736 100644 --- a/source/blender/modifiers/intern/MOD_solidify.c +++ b/source/blender/modifiers/intern/MOD_solidify.c @@ -223,7 +223,6 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, const int numEdges = dm->getNumEdges(dm); const int numFaces = dm->getNumPolys(dm); int numLoops = 0, newLoops = 0, newFaces = 0, newEdges = 0; - int j; /* only use material offsets if we have 2 or more materials */ const short mat_nr_max = ob->totcol > 1 ? ob->totcol - 1 : 0; @@ -292,9 +291,11 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, } for (i = 0, mp = orig_mpoly; i < numFaces; i++, mp++) { - MLoop *ml = orig_mloop + mp->loopstart; unsigned int ml_v1; unsigned int ml_v2; + int j; + + ml = orig_mloop + mp->loopstart; for (j = 0, ml_v1 = ml->v, ml_v2 = ml[mp->totloop - 1].v; j < mp->totloop; @@ -376,6 +377,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, for (i = 0; i < dm->numPolyData; i++, mp++) { MLoop *ml2; int e; + int j; ml2 = mloop + mp->loopstart + dm->numLoopData; for (j = 0; j < mp->totloop; j++) { @@ -591,6 +593,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, int *origindex_edge; int *orig_ed; + int j; /* add faces & edges */ origindex_edge = result->getEdgeDataArray(result, CD_ORIGINDEX); @@ -715,13 +718,13 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, for (i = 0; i < newEdges; i++, ed++) { float nor_cpy[3]; short *nor_short; - int j; + int k; /* note, only the first vertex (lower half of the index) is calculated */ normalize_v3_v3(nor_cpy, edge_vert_nos[ed->v1]); - for (j = 0; j < 2; j++) { /* loop over both verts of the edge */ - nor_short = mvert[*(&ed->v1 + j)].no; + for (k = 0; k < 2; k++) { /* loop over both verts of the edge */ + nor_short = mvert[*(&ed->v1 + k)].no; normal_short_to_float_v3(nor, nor_short); add_v3_v3(nor, nor_cpy); normalize_v3(nor); From deeecc20295e791de6b7e8f734f9d532e99fc075 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 20 Oct 2012 10:11:26 +0000 Subject: [PATCH 340/347] code cleanup: remove unused members of BMIter struct to save some space. (this iterator is used everywhere). also rename vars in the struct. --- source/blender/bmesh/intern/bmesh_core.h | 4 +- source/blender/bmesh/intern/bmesh_iterators.c | 132 +++++++++--------- source/blender/bmesh/intern/bmesh_iterators.h | 12 +- 3 files changed, 76 insertions(+), 72 deletions(-) diff --git a/source/blender/bmesh/intern/bmesh_core.h b/source/blender/bmesh/intern/bmesh_core.h index 491287993df..0667ed9ea1c 100644 --- a/source/blender/bmesh/intern/bmesh_core.h +++ b/source/blender/bmesh/intern/bmesh_core.h @@ -41,8 +41,8 @@ void BM_edge_kill(BMesh *bm, BMEdge *e); void BM_vert_kill(BMesh *bm, BMVert *v); int bmesh_edge_separate(BMesh *bm, BMEdge *e, BMLoop *l_sep); -int BM_edge_splice(BMesh *bm, BMEdge *e, BMEdge *etarget); -int BM_vert_splice(BMesh *bm, BMVert *v, BMVert *vtarget); +int BM_edge_splice(BMesh *bm, BMEdge *e, BMEdge *e_target); +int BM_vert_splice(BMesh *bm, BMVert *v, BMVert *v_target); int bmesh_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len); diff --git a/source/blender/bmesh/intern/bmesh_iterators.c b/source/blender/bmesh/intern/bmesh_iterators.c index 10f0df78fd0..1cb95d94e9b 100644 --- a/source/blender/bmesh/intern/bmesh_iterators.c +++ b/source/blender/bmesh/intern/bmesh_iterators.c @@ -205,10 +205,10 @@ int BM_iter_mesh_count_flag(const char itype, BMesh *bm, const char hflag, const */ static void init_iterator(BMIter *iter) { - iter->firstvert = iter->nextvert = NULL; - iter->firstedge = iter->nextedge = NULL; - iter->firstloop = iter->nextloop = NULL; - iter->firstpoly = iter->nextpoly = NULL; +// iter->v_first = iter->v_next = NULL; // UNUSED + iter->e_first = iter->e_next = NULL; + iter->l_first = iter->l_next = NULL; +// iter->f_first = iter->f_next = NULL; // UNUSED iter->ldata = NULL; } @@ -272,19 +272,19 @@ void bmiter__edge_of_vert_begin(BMIter *iter) { init_iterator(iter); if (iter->vdata->e) { - iter->firstedge = iter->vdata->e; - iter->nextedge = iter->vdata->e; + iter->e_first = iter->vdata->e; + iter->e_next = iter->vdata->e; } } void *bmiter__edge_of_vert_step(BMIter *iter) { - BMEdge *current = iter->nextedge; + BMEdge *current = iter->e_next; - if (iter->nextedge) - iter->nextedge = bmesh_disk_edge_next(iter->nextedge, iter->vdata); + if (iter->e_next) + iter->e_next = bmesh_disk_edge_next(iter->e_next, iter->vdata); - if (iter->nextedge == iter->firstedge) iter->nextedge = NULL; + if (iter->e_next == iter->e_first) iter->e_next = NULL; return current; } @@ -300,27 +300,27 @@ void bmiter__face_of_vert_begin(BMIter *iter) if (iter->vdata->e) iter->count = bmesh_disk_facevert_count(iter->vdata); if (iter->count) { - iter->firstedge = bmesh_disk_faceedge_find_first(iter->vdata->e, iter->vdata); - iter->nextedge = iter->firstedge; - iter->firstloop = bmesh_radial_faceloop_find_first(iter->firstedge->l, iter->vdata); - iter->nextloop = iter->firstloop; + iter->e_first = bmesh_disk_faceedge_find_first(iter->vdata->e, iter->vdata); + iter->e_next = iter->e_first; + iter->l_first = bmesh_radial_faceloop_find_first(iter->e_first->l, iter->vdata); + iter->l_next = iter->l_first; } } void *bmiter__face_of_vert_step(BMIter *iter) { - BMLoop *current = iter->nextloop; + BMLoop *current = iter->l_next; - if (iter->count && iter->nextloop) { + if (iter->count && iter->l_next) { iter->count--; - iter->nextloop = bmesh_radial_faceloop_find_next(iter->nextloop, iter->vdata); - if (iter->nextloop == iter->firstloop) { - iter->nextedge = bmesh_disk_faceedge_find_next(iter->nextedge, iter->vdata); - iter->firstloop = bmesh_radial_faceloop_find_first(iter->nextedge->l, iter->vdata); - iter->nextloop = iter->firstloop; + iter->l_next = bmesh_radial_faceloop_find_next(iter->l_next, iter->vdata); + if (iter->l_next == iter->l_first) { + iter->e_next = bmesh_disk_faceedge_find_next(iter->e_next, iter->vdata); + iter->l_first = bmesh_radial_faceloop_find_first(iter->e_next->l, iter->vdata); + iter->l_next = iter->l_first; } } - if (!iter->count) iter->nextloop = NULL; + if (!iter->count) iter->l_next = NULL; return current ? current->f : NULL; } @@ -338,27 +338,27 @@ void bmiter__loop_of_vert_begin(BMIter *iter) if (iter->vdata->e) iter->count = bmesh_disk_facevert_count(iter->vdata); if (iter->count) { - iter->firstedge = bmesh_disk_faceedge_find_first(iter->vdata->e, iter->vdata); - iter->nextedge = iter->firstedge; - iter->firstloop = bmesh_radial_faceloop_find_first(iter->firstedge->l, iter->vdata); - iter->nextloop = iter->firstloop; + iter->e_first = bmesh_disk_faceedge_find_first(iter->vdata->e, iter->vdata); + iter->e_next = iter->e_first; + iter->l_first = bmesh_radial_faceloop_find_first(iter->e_first->l, iter->vdata); + iter->l_next = iter->l_first; } } void *bmiter__loop_of_vert_step(BMIter *iter) { - BMLoop *current = iter->nextloop; + BMLoop *current = iter->l_next; if (iter->count) { iter->count--; - iter->nextloop = bmesh_radial_faceloop_find_next(iter->nextloop, iter->vdata); - if (iter->nextloop == iter->firstloop) { - iter->nextedge = bmesh_disk_faceedge_find_next(iter->nextedge, iter->vdata); - iter->firstloop = bmesh_radial_faceloop_find_first(iter->nextedge->l, iter->vdata); - iter->nextloop = iter->firstloop; + iter->l_next = bmesh_radial_faceloop_find_next(iter->l_next, iter->vdata); + if (iter->l_next == iter->l_first) { + iter->e_next = bmesh_disk_faceedge_find_next(iter->e_next, iter->vdata); + iter->l_first = bmesh_radial_faceloop_find_first(iter->e_next->l, iter->vdata); + iter->l_next = iter->l_first; } } - if (!iter->count) iter->nextloop = NULL; + if (!iter->count) iter->l_next = NULL; if (current) { @@ -378,19 +378,19 @@ void bmiter__loops_of_edge_begin(BMIter *iter) /* note sure why this sets ldata ... */ init_iterator(iter); - iter->firstloop = iter->nextloop = l; + iter->l_first = iter->l_next = l; } void *bmiter__loops_of_edge_step(BMIter *iter) { - BMLoop *current = iter->nextloop; + BMLoop *current = iter->l_next; - if (iter->nextloop) { - iter->nextloop = iter->nextloop->radial_next; + if (iter->l_next) { + iter->l_next = iter->l_next->radial_next; } - if (iter->nextloop == iter->firstloop) { - iter->nextloop = NULL; + if (iter->l_next == iter->l_first) { + iter->l_next = NULL; } if (current) { @@ -409,23 +409,23 @@ void bmiter__loops_of_loop_begin(BMIter *iter) /* note sure why this sets ldata ... */ init_iterator(iter); - iter->firstloop = l; - iter->nextloop = iter->firstloop->radial_next; + iter->l_first = l; + iter->l_next = iter->l_first->radial_next; - if (iter->nextloop == iter->firstloop) - iter->nextloop = NULL; + if (iter->l_next == iter->l_first) + iter->l_next = NULL; } void *bmiter__loops_of_loop_step(BMIter *iter) { - BMLoop *current = iter->nextloop; + BMLoop *current = iter->l_next; - if (iter->nextloop) { - iter->nextloop = iter->nextloop->radial_next; + if (iter->l_next) { + iter->l_next = iter->l_next->radial_next; } - if (iter->nextloop == iter->firstloop) { - iter->nextloop = NULL; + if (iter->l_next == iter->l_first) { + iter->l_next = NULL; } if (current) { @@ -444,20 +444,20 @@ void bmiter__face_of_edge_begin(BMIter *iter) init_iterator(iter); if (iter->edata->l) { - iter->firstloop = iter->edata->l; - iter->nextloop = iter->edata->l; + iter->l_first = iter->edata->l; + iter->l_next = iter->edata->l; } } void *bmiter__face_of_edge_step(BMIter *iter) { - BMLoop *current = iter->nextloop; + BMLoop *current = iter->l_next; - if (iter->nextloop) { - iter->nextloop = iter->nextloop->radial_next; + if (iter->l_next) { + iter->l_next = iter->l_next->radial_next; } - if (iter->nextloop == iter->firstloop) iter->nextloop = NULL; + if (iter->l_next == iter->l_first) iter->l_next = NULL; return current ? current->f : NULL; } @@ -492,15 +492,15 @@ void *bmiter__vert_of_edge_step(BMIter *iter) void bmiter__vert_of_face_begin(BMIter *iter) { init_iterator(iter); - iter->firstloop = iter->nextloop = BM_FACE_FIRST_LOOP(iter->pdata); + iter->l_first = iter->l_next = BM_FACE_FIRST_LOOP(iter->pdata); } void *bmiter__vert_of_face_step(BMIter *iter) { - BMLoop *current = iter->nextloop; + BMLoop *current = iter->l_next; - if (iter->nextloop) iter->nextloop = iter->nextloop->next; - if (iter->nextloop == iter->firstloop) iter->nextloop = NULL; + if (iter->l_next) iter->l_next = iter->l_next->next; + if (iter->l_next == iter->l_first) iter->l_next = NULL; return current ? current->v : NULL; } @@ -512,15 +512,15 @@ void *bmiter__vert_of_face_step(BMIter *iter) void bmiter__edge_of_face_begin(BMIter *iter) { init_iterator(iter); - iter->firstloop = iter->nextloop = BM_FACE_FIRST_LOOP(iter->pdata); + iter->l_first = iter->l_next = BM_FACE_FIRST_LOOP(iter->pdata); } void *bmiter__edge_of_face_step(BMIter *iter) { - BMLoop *current = iter->nextloop; + BMLoop *current = iter->l_next; - if (iter->nextloop) iter->nextloop = iter->nextloop->next; - if (iter->nextloop == iter->firstloop) iter->nextloop = NULL; + if (iter->l_next) iter->l_next = iter->l_next->next; + if (iter->l_next == iter->l_first) iter->l_next = NULL; return current ? current->e : NULL; } @@ -532,15 +532,15 @@ void *bmiter__edge_of_face_step(BMIter *iter) void bmiter__loop_of_face_begin(BMIter *iter) { init_iterator(iter); - iter->firstloop = iter->nextloop = BM_FACE_FIRST_LOOP(iter->pdata); + iter->l_first = iter->l_next = BM_FACE_FIRST_LOOP(iter->pdata); } void *bmiter__loop_of_face_step(BMIter *iter) { - BMLoop *current = iter->nextloop; + BMLoop *current = iter->l_next; - if (iter->nextloop) iter->nextloop = iter->nextloop->next; - if (iter->nextloop == iter->firstloop) iter->nextloop = NULL; + if (iter->l_next) iter->l_next = iter->l_next->next; + if (iter->l_next == iter->l_first) iter->l_next = NULL; return current; } diff --git a/source/blender/bmesh/intern/bmesh_iterators.h b/source/blender/bmesh/intern/bmesh_iterators.h index 27e01f4eaf5..3c42b3d610c 100644 --- a/source/blender/bmesh/intern/bmesh_iterators.h +++ b/source/blender/bmesh/intern/bmesh_iterators.h @@ -95,22 +95,26 @@ extern const char bm_iter_itype_htype_map[BM_ITYPE_MAX]; for (ele = BM_iter_new(iter, NULL, itype, data), indexvar = 0; ele; ele = BM_iter_step(iter), (indexvar)++) /* Iterator Structure */ +/* note: some of these vars are not used, + * so they have beem commented to save stack space since this struct is used all over */ typedef struct BMIter { BLI_mempool_iter pooliter; - BMVert *firstvert, *nextvert, *vdata; - BMEdge *firstedge, *nextedge, *edata; - BMLoop *firstloop, *nextloop, *ldata, *l; - BMFace *firstpoly, *nextpoly, *pdata; + BMVert /* *v_first, *v_next, */ *vdata; + BMEdge *e_first, *e_next, *edata; + BMLoop *l_first, *l_next, *ldata; + BMFace /* *f_first, *f_next, */ *pdata; BMesh *bm; void (*begin)(struct BMIter *iter); void *(*step)(struct BMIter *iter); + /* union { void *p; int i; long l; float f; } filter; + */ int count; /* note, only some iterators set this, don't rely on it */ char itype; } BMIter; From a99b377167a6c073faa8bfd7398517084c66efa5 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Sat, 20 Oct 2012 10:28:34 +0000 Subject: [PATCH 341/347] More UI messages fixes and tweaks, and BKE_report<->BKE_reportf. --- source/blender/makesrna/intern/rna_access.c | 2 +- source/blender/makesrna/intern/rna_armature.c | 6 +- source/blender/makesrna/intern/rna_curve.c | 4 +- source/blender/makesrna/intern/rna_group.c | 4 +- source/blender/makesrna/intern/rna_main_api.c | 58 +++++++++---------- source/blender/makesrna/intern/rna_material.c | 8 +-- source/blender/makesrna/intern/rna_mesh.c | 8 +-- source/blender/makesrna/intern/rna_meta.c | 2 +- source/blender/makesrna/intern/rna_nla.c | 8 +-- .../blender/makesrna/intern/rna_object_api.c | 18 +++--- source/blender/makesrna/intern/rna_render.c | 2 +- source/blender/makesrna/intern/rna_scene.c | 8 +-- .../makesrna/intern/rna_sequencer_api.c | 25 ++++---- 13 files changed, 76 insertions(+), 77 deletions(-) diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index 7e832455618..610895002aa 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -3169,7 +3169,7 @@ static int rna_raw_access(ReportList *reports, PointerRNA *ptr, PropertyRNA *pro itemtype = RNA_property_type(iprop); } else { - BKE_reportf(reports, RPT_ERROR, "Property named %s not found", propname); + BKE_reportf(reports, RPT_ERROR, "Property named '%s' not found", propname); err = 1; break; } diff --git a/source/blender/makesrna/intern/rna_armature.c b/source/blender/makesrna/intern/rna_armature.c index ceadaa036f1..fa43bf39319 100644 --- a/source/blender/makesrna/intern/rna_armature.c +++ b/source/blender/makesrna/intern/rna_armature.c @@ -103,7 +103,7 @@ static void rna_Armature_act_edit_bone_set(PointerRNA *ptr, PointerRNA value) static EditBone *rna_Armature_edit_bone_new(bArmature *arm, ReportList *reports, const char *name) { if (arm->edbo == NULL) { - BKE_reportf(reports, RPT_ERROR, "Armature '%s' not in editmode, cant add an editbone", arm->id.name + 2); + BKE_reportf(reports, RPT_ERROR, "Armature '%s' not in edit mode, cannot add an editbone", arm->id.name + 2); return NULL; } return ED_armature_edit_bone_add(arm, name); @@ -112,12 +112,12 @@ static EditBone *rna_Armature_edit_bone_new(bArmature *arm, ReportList *reports, static void rna_Armature_edit_bone_remove(bArmature *arm, ReportList *reports, EditBone *ebone) { if (arm->edbo == NULL) { - BKE_reportf(reports, RPT_ERROR, "Armature '%s' not in editmode, cant remove an editbone", arm->id.name + 2); + BKE_reportf(reports, RPT_ERROR, "Armature '%s' not in edit mode, cannot remove an editbone", arm->id.name + 2); return; } if (BLI_findindex(arm->edbo, ebone) == -1) { - BKE_reportf(reports, RPT_ERROR, "Armature '%s' doesn't contain bone '%s'", arm->id.name + 2, ebone->name); + BKE_reportf(reports, RPT_ERROR, "Armature '%s' does not contain bone '%s'", arm->id.name + 2, ebone->name); return; } diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c index fa4c6fcc650..ad05eff9568 100644 --- a/source/blender/makesrna/intern/rna_curve.c +++ b/source/blender/makesrna/intern/rna_curve.c @@ -511,7 +511,7 @@ static void rna_Nurb_update_knot_v(Main *bmain, Scene *scene, PointerRNA *ptr) static void rna_Curve_spline_points_add(ID *id, Nurb *nu, ReportList *reports, int number) { if (nu->type == CU_BEZIER) { - BKE_report(reports, RPT_ERROR, "Bezier spline can't have points added"); + BKE_report(reports, RPT_ERROR, "Bezier spline cannot have points added"); } else if (number == 0) { /* do nothing */ @@ -581,7 +581,7 @@ static void rna_Curve_spline_remove(Curve *cu, ReportList *reports, Nurb *nu) found = BLI_remlink_safe(nurbs, nu); if (!found) { - BKE_reportf(reports, RPT_ERROR, "Curve \"%s\" does not contain spline given", cu->id.name + 2); + BKE_reportf(reports, RPT_ERROR, "Curve '%s' does not contain spline given", cu->id.name + 2); return; } diff --git a/source/blender/makesrna/intern/rna_group.c b/source/blender/makesrna/intern/rna_group.c index 586b71aa2da..4baf46fd0b5 100644 --- a/source/blender/makesrna/intern/rna_group.c +++ b/source/blender/makesrna/intern/rna_group.c @@ -54,7 +54,7 @@ static PointerRNA rna_Group_objects_get(CollectionPropertyIterator *iter) static void rna_Group_objects_link(Group *group, bContext *C, ReportList *reports, Object *object) { if (!add_to_group(group, object, CTX_data_scene(C), NULL)) { - BKE_reportf(reports, RPT_ERROR, "Object \"%s\" already in group \"%s\"", object->id.name + 2, group->id.name + 2); + BKE_reportf(reports, RPT_ERROR, "Object '%s' already in group '%s'", object->id.name + 2, group->id.name + 2); return; } @@ -64,7 +64,7 @@ static void rna_Group_objects_link(Group *group, bContext *C, ReportList *report static void rna_Group_objects_unlink(Group *group, bContext *C, ReportList *reports, Object *object) { if (!rem_from_group(group, object, CTX_data_scene(C), NULL)) { - BKE_reportf(reports, RPT_ERROR, "Object \"%s\" not in group \"%s\"", object->id.name + 2, group->id.name + 2); + BKE_reportf(reports, RPT_ERROR, "Object '%s' not in group '%s'", object->id.name + 2, group->id.name + 2); return; } diff --git a/source/blender/makesrna/intern/rna_main_api.c b/source/blender/makesrna/intern/rna_main_api.c index d8f7d48a74f..329f1273588 100644 --- a/source/blender/makesrna/intern/rna_main_api.c +++ b/source/blender/makesrna/intern/rna_main_api.c @@ -110,7 +110,7 @@ static void rna_Main_cameras_remove(Main *bmain, ReportList *reports, struct Cam if (ID_REAL_USERS(camera) <= 0) BKE_libblock_free(&bmain->camera, camera); else - BKE_reportf(reports, RPT_ERROR, "Camera \"%s\" must have zero users to be removed, found %d", + BKE_reportf(reports, RPT_ERROR, "Camera '%s' must have zero users to be removed, found %d", camera->id.name + 2, ID_REAL_USERS(camera)); /* XXX python now has invalid pointer? */ @@ -130,7 +130,7 @@ static void rna_Main_scenes_remove(Main *bmain, bContext *C, ReportList *reports else if (scene->id.next) newscene = scene->id.next; else { - BKE_reportf(reports, RPT_ERROR, "Scene \"%s\" is the last, can't be removed", scene->id.name + 2); + BKE_reportf(reports, RPT_ERROR, "Scene '%s' is the last, cannot be removed", scene->id.name + 2); return; } @@ -177,7 +177,7 @@ static Object *rna_Main_objects_new(Main *UNUSED(bmain), ReportList *reports, co if (RNA_enum_id_from_value(id_type_items, GS(data->name), &idname) == 0) idname = "UNKNOWN"; - BKE_reportf(reports, RPT_ERROR, "ID type '%s' is not valid for a object", idname); + BKE_reportf(reports, RPT_ERROR, "ID type '%s' is not valid for an object", idname); return NULL; } } @@ -201,7 +201,7 @@ static void rna_Main_objects_remove(Main *bmain, ReportList *reports, struct Obj BKE_libblock_free(&bmain->object, object); } else { - BKE_reportf(reports, RPT_ERROR, "Object \"%s\" must have zero users to be removed, found %d", + BKE_reportf(reports, RPT_ERROR, "Object '%s' must have zero users to be removed, found %d", object->id.name + 2, ID_REAL_USERS(object)); } } @@ -217,7 +217,7 @@ static void rna_Main_materials_remove(Main *bmain, ReportList *reports, struct M if (ID_REAL_USERS(material) <= 0) BKE_libblock_free(&bmain->mat, material); else - BKE_reportf(reports, RPT_ERROR, "Material \"%s\" must have zero users to be removed, found %d", + BKE_reportf(reports, RPT_ERROR, "Material '%s' must have zero users to be removed, found %d", material->id.name + 2, ID_REAL_USERS(material)); /* XXX python now has invalid pointer? */ @@ -235,7 +235,7 @@ static void rna_Main_nodetree_remove(Main *bmain, ReportList *reports, struct bN if (ID_REAL_USERS(tree) <= 0) BKE_libblock_free(&bmain->nodetree, tree); else - BKE_reportf(reports, RPT_ERROR, "Node Tree \"%s\" must have zero users to be removed, found %d", + BKE_reportf(reports, RPT_ERROR, "Node tree '%s' must have zero users to be removed, found %d", tree->id.name + 2, ID_REAL_USERS(tree)); /* XXX python now has invalid pointer? */ @@ -252,7 +252,7 @@ void rna_Main_meshes_remove(Main *bmain, ReportList *reports, Mesh *mesh) if (ID_REAL_USERS(mesh) <= 0) BKE_libblock_free(&bmain->mesh, mesh); else - BKE_reportf(reports, RPT_ERROR, "Mesh \"%s\" must have zero users to be removed, found %d", + BKE_reportf(reports, RPT_ERROR, "Mesh '%s' must have zero users to be removed, found %d", mesh->id.name + 2, ID_REAL_USERS(mesh)); /* XXX python now has invalid pointer? */ @@ -270,7 +270,7 @@ static void rna_Main_lamps_remove(Main *bmain, ReportList *reports, Lamp *lamp) if (ID_REAL_USERS(lamp) <= 0) BKE_libblock_free(&bmain->lamp, lamp); else - BKE_reportf(reports, RPT_ERROR, "Lamp \"%s\" must have zero users to be removed, found %d", + BKE_reportf(reports, RPT_ERROR, "Lamp '%s' must have zero users to be removed, found %d", lamp->id.name + 2, ID_REAL_USERS(lamp)); /* XXX python now has invalid pointer? */ @@ -291,8 +291,8 @@ static Image *rna_Main_images_load(Main *UNUSED(bmain), ReportList *reports, con ima = BKE_image_load(filepath); if (!ima) - BKE_reportf(reports, RPT_ERROR, "Can't read \"%s\": %s", filepath, - errno ? strerror(errno) : TIP_("Unsupported image format")); + BKE_reportf(reports, RPT_ERROR, "Cannot read '%s': %s", filepath, + errno ? strerror(errno) : TIP_("unsupported image format")); return ima; } @@ -301,7 +301,7 @@ static void rna_Main_images_remove(Main *bmain, ReportList *reports, Image *imag if (ID_REAL_USERS(image) <= 0) BKE_libblock_free(&bmain->image, image); else - BKE_reportf(reports, RPT_ERROR, "Image \"%s\" must have zero users to be removed, found %d", + BKE_reportf(reports, RPT_ERROR, "Image '%s' must have zero users to be removed, found %d", image->id.name + 2, ID_REAL_USERS(image)); /* XXX python now has invalid pointer? */ @@ -318,7 +318,7 @@ static void rna_Main_lattices_remove(Main *bmain, ReportList *reports, struct La if (ID_REAL_USERS(lt) <= 0) BKE_libblock_free(&bmain->latt, lt); else - BKE_reportf(reports, RPT_ERROR, "Lattice \"%s\" must have zero users to be removed, found %d", + BKE_reportf(reports, RPT_ERROR, "Lattice '%s' must have zero users to be removed, found %d", lt->id.name + 2, ID_REAL_USERS(lt)); } @@ -333,7 +333,7 @@ static void rna_Main_curves_remove(Main *bmain, ReportList *reports, struct Curv if (ID_REAL_USERS(cu) <= 0) BKE_libblock_free(&bmain->curve, cu); else - BKE_reportf(reports, RPT_ERROR, "Curve \"%s\" must have zero users to be removed, found %d", + BKE_reportf(reports, RPT_ERROR, "Curve '%s' must have zero users to be removed, found %d", cu->id.name + 2, ID_REAL_USERS(cu)); } @@ -348,7 +348,7 @@ static void rna_Main_metaballs_remove(Main *bmain, ReportList *reports, struct M if (ID_REAL_USERS(mb) <= 0) BKE_libblock_free(&bmain->mball, mb); else - BKE_reportf(reports, RPT_ERROR, "Metaball \"%s\" must have zero users to be removed, found %d", + BKE_reportf(reports, RPT_ERROR, "Metaball '%s' must have zero users to be removed, found %d", mb->id.name + 2, ID_REAL_USERS(mb)); } @@ -360,8 +360,8 @@ static VFont *rna_Main_fonts_load(Main *bmain, ReportList *reports, const char * font = BKE_vfont_load(bmain, filepath); if (!font) - BKE_reportf(reports, RPT_ERROR, "Can't read \"%s\": %s", filepath, - errno ? strerror(errno) : TIP_("Unsupported font format")); + BKE_reportf(reports, RPT_ERROR, "Cannot read '%s': %s", filepath, + errno ? strerror(errno) : TIP_("unsupported font format")); return font; @@ -371,7 +371,7 @@ static void rna_Main_fonts_remove(Main *bmain, ReportList *reports, VFont *vfont if (ID_REAL_USERS(vfont) <= 0) BKE_libblock_free(&bmain->vfont, vfont); else - BKE_reportf(reports, RPT_ERROR, "Font \"%s\" must have zero users to be removed, found %d", + BKE_reportf(reports, RPT_ERROR, "Font '%s' must have zero users to be removed, found %d", vfont->id.name + 2, ID_REAL_USERS(vfont)); /* XXX python now has invalid pointer? */ @@ -389,7 +389,7 @@ static void rna_Main_textures_remove(Main *bmain, ReportList *reports, struct Te if (ID_REAL_USERS(tex) <= 0) BKE_libblock_free(&bmain->tex, tex); else - BKE_reportf(reports, RPT_ERROR, "Texture \"%s\" must have zero users to be removed, found %d", + BKE_reportf(reports, RPT_ERROR, "Texture '%s' must have zero users to be removed, found %d", tex->id.name + 2, ID_REAL_USERS(tex)); } @@ -404,7 +404,7 @@ static void rna_Main_brushes_remove(Main *bmain, ReportList *reports, struct Bru if (ID_REAL_USERS(brush) <= 0) BKE_libblock_free(&bmain->brush, brush); else - BKE_reportf(reports, RPT_ERROR, "Brush \"%s\" must have zero users to be removed, found %d", + BKE_reportf(reports, RPT_ERROR, "Brush '%s' must have zero users to be removed, found %d", brush->id.name + 2, ID_REAL_USERS(brush)); } @@ -419,7 +419,7 @@ static void rna_Main_worlds_remove(Main *bmain, ReportList *reports, struct Worl if (ID_REAL_USERS(world) <= 0) BKE_libblock_free(&bmain->world, world); else - BKE_reportf(reports, RPT_ERROR, "World \"%s\" must have zero users to be removed, found %d", + BKE_reportf(reports, RPT_ERROR, "World '%s' must have zero users to be removed, found %d", world->id.name + 2, ID_REAL_USERS(world)); } @@ -445,7 +445,7 @@ static void rna_Main_speakers_remove(Main *bmain, ReportList *reports, Speaker * if (ID_REAL_USERS(speaker) <= 0) BKE_libblock_free(&bmain->speaker, speaker); else - BKE_reportf(reports, RPT_ERROR, "Speaker \"%s\" must have zero users to be removed, found %d", + BKE_reportf(reports, RPT_ERROR, "Speaker '%s' must have zero users to be removed, found %d", speaker->id.name + 2, ID_REAL_USERS(speaker)); /* XXX python now has invalid pointer? */ @@ -470,8 +470,8 @@ static Text *rna_Main_texts_load(Main *bmain, ReportList *reports, const char *f txt = BKE_text_load(filepath, bmain->name); if (!txt) - BKE_reportf(reports, RPT_ERROR, "Can't read \"%s\": %s", filepath, - errno ? strerror(errno) : TIP_("Unable to load text")); + BKE_reportf(reports, RPT_ERROR, "Cannot read '%s': %s", filepath, + errno ? strerror(errno) : TIP_("unable to load text")); return txt; } @@ -487,7 +487,7 @@ static void rna_Main_armatures_remove(Main *bmain, ReportList *reports, bArmatur if (ID_REAL_USERS(arm) <= 0) BKE_libblock_free(&bmain->armature, arm); else - BKE_reportf(reports, RPT_ERROR, "Armature \"%s\" must have zero users to be removed, found %d", + BKE_reportf(reports, RPT_ERROR, "Armature '%s' must have zero users to be removed, found %d", arm->id.name + 2, ID_REAL_USERS(arm)); /* XXX python now has invalid pointer? */ @@ -505,7 +505,7 @@ static void rna_Main_actions_remove(Main *bmain, ReportList *reports, bAction *a if (ID_REAL_USERS(act) <= 0) BKE_libblock_free(&bmain->action, act); else - BKE_reportf(reports, RPT_ERROR, "Action \"%s\" must have zero users to be removed, found %d", + BKE_reportf(reports, RPT_ERROR, "Action '%s' must have zero users to be removed, found %d", act->id.name + 2, ID_REAL_USERS(act)); /* XXX python now has invalid pointer? */ @@ -522,7 +522,7 @@ static void rna_Main_particles_remove(Main *bmain, ReportList *reports, Particle if (ID_REAL_USERS(part) <= 0) BKE_libblock_free(&bmain->particle, part); else - BKE_reportf(reports, RPT_ERROR, "Particle Settings \"%s\" must have zero users to be removed, found %d", + BKE_reportf(reports, RPT_ERROR, "Particle settings '%s' must have zero users to be removed, found %d", part->id.name + 2, ID_REAL_USERS(part)); /* XXX python now has invalid pointer? */ @@ -536,8 +536,8 @@ static MovieClip *rna_Main_movieclip_load(Main *UNUSED(bmain), ReportList *repor clip = BKE_movieclip_file_add(filepath); if (!clip) - BKE_reportf(reports, RPT_ERROR, "Can't read \"%s\": %s", filepath, - errno ? strerror(errno) : TIP_("Unable to load movie clip")); + BKE_reportf(reports, RPT_ERROR, "Cannot read '%s': %s", filepath, + errno ? strerror(errno) : TIP_("unable to load movie clip")); return clip; } @@ -572,7 +572,7 @@ static void rna_Main_grease_pencil_remove(Main *bmain, ReportList *reports, bGPd BKE_libblock_free(&bmain->gpencil, gpd); } else - BKE_reportf(reports, RPT_ERROR, "Grease Pencil \"%s\" must have zero users to be removed, found %d", + BKE_reportf(reports, RPT_ERROR, "Grease Pencil '%s' must have zero users to be removed, found %d", gpd->id.name + 2, ID_REAL_USERS(gpd)); /* XXX python now has invalid pointer? */ diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c index f53adcc6837..a2fbada3cc1 100644 --- a/source/blender/makesrna/intern/rna_material.c +++ b/source/blender/makesrna/intern/rna_material.c @@ -319,7 +319,7 @@ MTex *rna_mtex_texture_slots_add(ID *self_id, struct bContext *C, ReportList *re { MTex *mtex = add_mtex_id(self_id, -1); if (mtex == NULL) { - BKE_reportf(reports, RPT_ERROR, "maximum number of textures added %d", MAX_MTEX); + BKE_reportf(reports, RPT_ERROR, "Maximum number of textures added %d", MAX_MTEX); return NULL; } @@ -334,7 +334,7 @@ MTex *rna_mtex_texture_slots_create(ID *self_id, struct bContext *C, ReportList MTex *mtex; if (index < 0 || index >= MAX_MTEX) { - BKE_reportf(reports, RPT_ERROR, "index %d is invalid", index); + BKE_reportf(reports, RPT_ERROR, "Index %d is invalid", index); return NULL; } @@ -354,12 +354,12 @@ void rna_mtex_texture_slots_clear(ID *self_id, struct bContext *C, ReportList *r give_active_mtex(self_id, &mtex_ar, &act); if (mtex_ar == NULL) { - BKE_report(reports, RPT_ERROR, "mtex not found for this type"); + BKE_report(reports, RPT_ERROR, "Mtex not found for this type"); return; } if (index < 0 || index >= MAX_MTEX) { - BKE_reportf(reports, RPT_ERROR, "index %d is invalid", index); + BKE_reportf(reports, RPT_ERROR, "Index %d is invalid", index); return; } diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index 59cf202a416..048c38d3365 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -1275,12 +1275,12 @@ static PointerRNA rna_Mesh_tessface_vertex_color_new(struct Mesh *me, struct bCo int index; if (me->edit_btmesh) { - BKE_report(reports, RPT_ERROR, "Can't add tessface colors's in editmode"); + BKE_report(reports, RPT_ERROR, "Cannot add tessface colors in edit mode"); return PointerRNA_NULL; } if (me->mpoly) { - BKE_report(reports, RPT_ERROR, "Can't add tessface colors's when MPoly's exist"); + BKE_report(reports, RPT_ERROR, "Cannot add tessface colors when MPoly's exist"); return PointerRNA_NULL; } @@ -1368,12 +1368,12 @@ static PointerRNA rna_Mesh_tessface_uv_texture_new(struct Mesh *me, struct bCont int index; if (me->edit_btmesh) { - BKE_report(reports, RPT_ERROR, "Can't add tessface uv's in editmode"); + BKE_report(reports, RPT_ERROR, "Cannot add tessface uv's in edit mode"); return PointerRNA_NULL; } if (me->mpoly) { - BKE_report(reports, RPT_ERROR, "Can't add tessface uv's when MPoly's exist"); + BKE_report(reports, RPT_ERROR, "Cannot add tessface uv's when MPoly's exist"); return PointerRNA_NULL; } diff --git a/source/blender/makesrna/intern/rna_meta.c b/source/blender/makesrna/intern/rna_meta.c index c8b52b45604..fe2c29632f2 100644 --- a/source/blender/makesrna/intern/rna_meta.c +++ b/source/blender/makesrna/intern/rna_meta.c @@ -133,7 +133,7 @@ static void rna_MetaBall_elements_remove(MetaBall *mb, ReportList *reports, Meta found = BLI_remlink_safe(&mb->elems, ml); if (!found) { - BKE_reportf(reports, RPT_ERROR, "Metaball \"%s\" does not contain spline given", mb->id.name + 2); + BKE_reportf(reports, RPT_ERROR, "Metaball '%s' does not contain spline given", mb->id.name + 2); return; } diff --git a/source/blender/makesrna/intern/rna_nla.c b/source/blender/makesrna/intern/rna_nla.c index 4ff1365427e..8378cb92e20 100644 --- a/source/blender/makesrna/intern/rna_nla.c +++ b/source/blender/makesrna/intern/rna_nla.c @@ -302,7 +302,7 @@ static NlaStrip *rna_NlaStrip_new(NlaTrack *track, bContext *C, ReportList *repo NlaStrip *strip = add_nlastrip(action); if (strip == NULL) { - BKE_reportf(reports, RPT_ERROR, "Unable to create new strip"); + BKE_report(reports, RPT_ERROR, "Unable to create new strip"); return NULL; } @@ -310,8 +310,8 @@ static NlaStrip *rna_NlaStrip_new(NlaTrack *track, bContext *C, ReportList *repo strip->start = start; if (BKE_nlastrips_add_strip(&track->strips, strip) == 0) { - BKE_reportf(reports, RPT_ERROR, - "Unable to add strip. Track doesn't have any space to accommodate this new strip"); + BKE_report(reports, RPT_ERROR, + "Unable to add strip (the track does not have any space to accommodate this new strip)"); free_nlastrip(NULL, strip); return NULL; } @@ -348,7 +348,7 @@ static NlaStrip *rna_NlaStrip_new(NlaTrack *track, bContext *C, ReportList *repo static void rna_NlaStrip_remove(NlaTrack *track, bContext *C, ReportList *reports, NlaStrip *strip) { if (BLI_findindex(&track->strips, strip) == -1) { - BKE_reportf(reports, RPT_ERROR, "NLA's Strip '%s' not found in track '%s'", strip->name, track->name); + BKE_reportf(reports, RPT_ERROR, "NLA strip '%s' not found in track '%s'", strip->name, track->name); return; } else { diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c index 5f5bdb765b1..3204dc8e6bc 100644 --- a/source/blender/makesrna/intern/rna_object_api.c +++ b/source/blender/makesrna/intern/rna_object_api.c @@ -158,7 +158,7 @@ Mesh *rna_Object_to_mesh(Object *ob, ReportList *reports, Scene *sce, int apply_ /* BKE_mesh_from_nurbs changes the type to a mesh, check it worked */ if (tmpobj->type != OB_MESH) { BKE_libblock_free_us(&(G.main->object), tmpobj); - BKE_report(reports, RPT_ERROR, "Can't convert curve to mesh (does the curve have any segments?)"); + BKE_report(reports, RPT_ERROR, "Cannot convert curve to mesh (does the curve have any segments?)"); return NULL; } @@ -351,7 +351,7 @@ void rna_Object_create_duplilist(Object *ob, ReportList *reports, Scene *sce, in /* free duplilist if a user forgets to */ if (ob->duplilist) { - BKE_reportf(reports, RPT_WARNING, "Object.dupli_list has not been freed"); + BKE_report(reports, RPT_WARNING, "Object.dupli_list has not been freed"); free_object_duplilist(ob->duplilist); ob->duplilist = NULL; @@ -387,7 +387,7 @@ static PointerRNA rna_Object_shape_key_add(Object *ob, bContext *C, ReportList * return keyptr; } else { - BKE_reportf(reports, RPT_ERROR, "Object \"%s\"does not support shapes", ob->id.name + 2); + BKE_reportf(reports, RPT_ERROR, "Object '%s' does not support shapes", ob->id.name + 2); return PointerRNA_NULL; } } @@ -402,14 +402,14 @@ static void rna_Mesh_assign_verts_to_group(Object *ob, bDeformGroup *group, int float weight, int assignmode) { if (ob->type != OB_MESH) { - BKE_report(reports, RPT_ERROR, "Object should be of MESH type"); + BKE_report(reports, RPT_ERROR, "Object should be of mesh type"); return; } Mesh *me = (Mesh *)ob->data; int group_index = BLI_findlink(&ob->defbase, group); if (group_index == -1) { - BKE_report(reports, RPT_ERROR, "No deform groups assigned to mesh"); + BKE_report(reports, RPT_ERROR, "No vertex groups assigned to mesh"); return; } @@ -441,7 +441,7 @@ static void rna_Object_ray_cast(Object *ob, ReportList *reports, float ray_start BVHTreeFromMesh treeData = {NULL}; if (ob->derivedFinal == NULL) { - BKE_reportf(reports, RPT_ERROR, "object \"%s\" has no mesh data to be used for ray casting", ob->id.name + 2); + BKE_reportf(reports, RPT_ERROR, "Object '%s' has no mesh data to be used for ray casting", ob->id.name + 2); return; } @@ -449,7 +449,7 @@ static void rna_Object_ray_cast(Object *ob, ReportList *reports, float ray_start bvhtree_from_mesh_faces(&treeData, ob->derivedFinal, 0.0f, 4, 6); if (treeData.tree == NULL) { - BKE_reportf(reports, RPT_ERROR, "object \"%s\" could not create internal data for ray casting", ob->id.name + 2); + BKE_reportf(reports, RPT_ERROR, "Object '%s' could not create internal data for ray casting", ob->id.name + 2); return; } else { @@ -483,7 +483,7 @@ static void rna_Object_closest_point_on_mesh(Object *ob, ReportList *reports, fl BVHTreeFromMesh treeData = {NULL}; if (ob->derivedFinal == NULL) { - BKE_reportf(reports, RPT_ERROR, "object \"%s\" has no mesh data to be used for finding nearest point", + BKE_reportf(reports, RPT_ERROR, "Object '%s' has no mesh data to be used for finding nearest point", ob->id.name + 2); return; } @@ -492,7 +492,7 @@ static void rna_Object_closest_point_on_mesh(Object *ob, ReportList *reports, fl bvhtree_from_mesh_faces(&treeData, ob->derivedFinal, 0.0f, 4, 6); if (treeData.tree == NULL) { - BKE_reportf(reports, RPT_ERROR, "object \"%s\" could not create internal data for finding nearest point", + BKE_reportf(reports, RPT_ERROR, "Object '%s' could not create internal data for finding nearest point", ob->id.name + 2); return; } diff --git a/source/blender/makesrna/intern/rna_render.c b/source/blender/makesrna/intern/rna_render.c index 039d50e4ee8..736753894d1 100644 --- a/source/blender/makesrna/intern/rna_render.c +++ b/source/blender/makesrna/intern/rna_render.c @@ -160,7 +160,7 @@ static StructRNA *rna_RenderEngine_register(Main *bmain, ReportList *reports, vo return NULL; if (strlen(identifier) >= sizeof(dummyet.idname)) { - BKE_reportf(reports, RPT_ERROR, "registering render engine class: '%s' is too long, maximum length is %d", + BKE_reportf(reports, RPT_ERROR, "Registering render engine class: '%s' is too long, maximum length is %d", identifier, (int)sizeof(dummyet.idname)); return NULL; } diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 537dab73340..46a4a630294 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -357,7 +357,7 @@ static Base *rna_Scene_object_link(Scene *scene, bContext *C, ReportList *report Base *base; if (BKE_scene_base_find(scene, ob)) { - BKE_reportf(reports, RPT_ERROR, "Object \"%s\" is already in scene \"%s\"", ob->id.name + 2, scene->id.name + 2); + BKE_reportf(reports, RPT_ERROR, "Object '%s' is already in scene '%s'", ob->id.name + 2, scene->id.name + 2); return NULL; } @@ -389,7 +389,7 @@ static void rna_Scene_object_unlink(Scene *scene, ReportList *reports, Object *o return; } if (base == scene->basact && ob->mode != OB_MODE_OBJECT) { - BKE_reportf(reports, RPT_ERROR, "Object '%s' must be in 'Object Mode' to unlink", ob->id.name + 2); + BKE_reportf(reports, RPT_ERROR, "Object '%s' must be in object mode to unlink", ob->id.name + 2); return; } if (scene->basact == base) { @@ -1326,7 +1326,7 @@ static TimeMarker *rna_TimeLine_add(Scene *scene, const char name[]) static void rna_TimeLine_remove(Scene *scene, ReportList *reports, TimeMarker *marker) { if (!BLI_remlink_safe(&scene->markers, marker)) { - BKE_reportf(reports, RPT_ERROR, "TimelineMarker '%s' not found in scene '%s'", marker->name, scene->id.name + 2); + BKE_reportf(reports, RPT_ERROR, "Timeline marker '%s' not found in scene '%s'", marker->name, scene->id.name + 2); return; } @@ -1357,7 +1357,7 @@ static KeyingSet *rna_Scene_keying_set_new(Scene *sce, ReportList *reports, cons return ks; } else { - BKE_report(reports, RPT_ERROR, "Keying Set could not be added"); + BKE_report(reports, RPT_ERROR, "Keying set could not be added"); return NULL; } } diff --git a/source/blender/makesrna/intern/rna_sequencer_api.c b/source/blender/makesrna/intern/rna_sequencer_api.c index 734703e6334..067589ca543 100644 --- a/source/blender/makesrna/intern/rna_sequencer_api.c +++ b/source/blender/makesrna/intern/rna_sequencer_api.c @@ -234,9 +234,10 @@ static Sequence *rna_Sequences_new_sound(ID *id, Editing *ed, Main *bmain, Repor } #else /* WITH_AUDASPACE */ static Sequence *rna_Sequences_new_sound(ID *UNUSED(id), Editing *UNUSED(ed), Main *UNUSED(bmain), ReportList *reports, - const char *UNUSED(name), const char *UNUSED(file), int UNUSED(channel), int UNUSED(start_frame)) + const char *UNUSED(name), const char *UNUSED(file), int UNUSED(channel), + int UNUSED(start_frame)) { - BKE_report(reports, RPT_ERROR, "Blender compiled without Audaspace support."); + BKE_report(reports, RPT_ERROR, "Blender compiled without Audaspace support"); return NULL; } #endif /* WITH_AUDASPACE */ @@ -249,39 +250,37 @@ static Sequence *rna_Sequences_new_effect(ID *id, Editing *ed, ReportList *repor Scene *scene = (Scene *)id; Sequence *seq; struct SeqEffectHandle sh; + int num_inputs = BKE_sequence_effect_get_num_inputs(type); - switch (BKE_sequence_effect_get_num_inputs(type)) { + switch (num_inputs) { case 0: if (end_frame <= start_frame) { - BKE_report(reports, RPT_ERROR, - "Sequences.new_effect: End frame not set"); + BKE_report(reports, RPT_ERROR, "Sequences.new_effect: end frame not set"); return NULL; } break; case 1: if (seq1 == NULL) { - BKE_report(reports, RPT_ERROR, - "Sequences.new_effect: Effect takes 1 input sequence"); + BKE_report(reports, RPT_ERROR, "Sequences.new_effect: effect takes 1 input sequence"); return NULL; } break; case 2: if (seq1 == NULL || seq2 == NULL) { - BKE_report(reports, RPT_ERROR, - "Sequences.new_effect: Effect takes 2 input sequences"); + BKE_report(reports, RPT_ERROR, "Sequences.new_effect: effect takes 2 input sequences"); return NULL; } break; case 3: if (seq1 == NULL || seq2 == NULL || seq3 == NULL) { - BKE_report(reports, RPT_ERROR, - "Sequences.new_effect: Effect takes 3 input sequences"); + BKE_report(reports, RPT_ERROR, "Sequences.new_effect: effect takes 3 input sequences"); return NULL; } break; default: - BKE_report(reports, RPT_ERROR, - "Sequences.new_effect: BKE_sequence_effect_get_num_inputs() > 3 (should never happen)"); + BKE_reportf(reports, RPT_ERROR, + "Sequences.new_effect: effect expects more than 3 inputs (%d, should never happen!)", + num_inputs); return NULL; } From 1820d3529c7fe37d4a03aca975881c4fc4304f38 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 20 Oct 2012 10:37:15 +0000 Subject: [PATCH 342/347] add TIMEIT_VALUE_PRINT() macro for printing timing between start/end macros. --- source/blender/blenlib/PIL_time.h | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/source/blender/blenlib/PIL_time.h b/source/blender/blenlib/PIL_time.h index 288d2fe78e5..b8f895c5c82 100644 --- a/source/blender/blenlib/PIL_time.h +++ b/source/blender/blenlib/PIL_time.h @@ -30,7 +30,6 @@ * \brief Platform independent time functions. */ - #ifndef __PIL_TIME_H__ #define __PIL_TIME_H__ @@ -61,20 +60,24 @@ void PIL_sleep_ms(int ms); double _timeit_##var = PIL_check_seconds_timer(); \ printf("time start (" #var "): " AT "\n"); \ fflush(stdout); \ - { (void)0 \ - + { (void)0 #define TIMEIT_VALUE(var) (float)(PIL_check_seconds_timer() - _timeit_##var) +#define TIMEIT_VALUE_PRINT(var) \ + { \ + printf("time update(" #var "): %.6f" " " AT "\n", TIMEIT_VALUE(var));\ + fflush(stdout); \ + } (void)0 #define TIMEIT_END(var) \ } \ - printf("time end (" #var "): %.6f" " " AT "\n", TIMEIT_VALUE(var)); \ + printf("time end (" #var "): %.6f" " " AT "\n", TIMEIT_VALUE(var)); \ fflush(stdout); \ -} (void)0 \ +} (void)0 #ifdef __cplusplus } #endif -#endif /* !__PIL_TIME_H__ */ +#endif /* !__PIL_TIME_H__ */ From 3abef3a2e6b77949f2e992baefd660422e3e19fe Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Sat, 20 Oct 2012 12:17:45 +0000 Subject: [PATCH 343/347] Cycles OSL: some build system tweaks to avoid global includes and definitions, which ensures there is no conflict with other libraries, and avoids full rebuild when toggling OSL on/off. --- CMakeLists.txt | 28 ++----------------- intern/cycles/CMakeLists.txt | 1 + intern/cycles/kernel/osl/nodes/CMakeLists.txt | 2 +- 3 files changed, 4 insertions(+), 27 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 38e3c5b2b01..1903a2ad406 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -734,23 +734,14 @@ if(UNIX AND NOT APPLE) execute_process(COMMAND ${LLVM_CONFIG} --libdir OUTPUT_VARIABLE LLVM_LIB_DIR OUTPUT_STRIP_TRAILING_WHITESPACE) - execute_process(COMMAND ${LLVM_CONFIG} --includedir - OUTPUT_VARIABLE LLVM_INCLUDES - OUTPUT_STRIP_TRAILING_WHITESPACE) find_library(LLVM_LIBRARY NAMES libLLVMAnalysis.a # first of a whole bunch of libs to get PATHS ${LLVM_LIB_DIR}) message(STATUS "LLVM version = ${LLVM_VERSION}") message(STATUS "LLVM dir = ${LLVM_DIRECTORY}") - message(STATUS "LLVM includes = ${LLVM_INCLUDES}") message(STATUS "LLVM lib dir = ${LLVM_LIB_DIR}") - if(LLVM_LIBRARY AND LLVM_INCLUDES AND LLVM_DIRECTORY AND LLVM_LIB_DIR) - # ensure include directory is added (in case of non-standard locations - include_directories(BEFORE "${LLVM_INCLUDES}") - string(REGEX REPLACE "\\." "" OSL_LLVM_VERSION ${LLVM_VERSION}) - message(STATUS "LLVM OSL_LLVM_VERSION = ${OSL_LLVM_VERSION}") - add_definitions("-DOSL_LLVM_VERSION=${OSL_LLVM_VERSION}") + if(LLVM_LIBRARY AND LLVM_DIRECTORY AND LLVM_LIB_DIR) if(LLVM_STATIC) # if static LLVM libraries were requested, use llvm-config to generate # the list of what libraries we need, and substitute that in the right @@ -788,8 +779,6 @@ if(UNIX AND NOT APPLE) else() message(STATUS "OSL not found") endif() - - include_directories(${OSL_INCLUDES}) endif() # OpenSuse needs lutil, ArchLinux not, for now keep, can avoid by using --as-needed @@ -957,8 +946,6 @@ elseif(WIN32) else() message(STATUS "OSL not found") endif() - - include_directories(${OSL_INCLUDES}) endif() if(MSVC) @@ -1640,23 +1627,14 @@ elseif(APPLE) execute_process(COMMAND ${LLVM_CONFIG} --libdir OUTPUT_VARIABLE LLVM_LIB_DIR OUTPUT_STRIP_TRAILING_WHITESPACE) - execute_process(COMMAND ${LLVM_CONFIG} --includedir - OUTPUT_VARIABLE LLVM_INCLUDES - OUTPUT_STRIP_TRAILING_WHITESPACE) find_library(LLVM_LIBRARY NAMES libLLVMAnalysis.a # first of a whole bunch of libs to get PATHS ${LLVM_LIB_DIR}) message(STATUS "LLVM version = ${LLVM_VERSION}") message(STATUS "LLVM dir = ${LLVM_DIRECTORY}") - message(STATUS "LLVM includes = ${LLVM_INCLUDES}") message(STATUS "LLVM lib dir = ${LLVM_LIB_DIR}") - if(LLVM_LIBRARY AND LLVM_INCLUDES AND LLVM_DIRECTORY AND LLVM_LIB_DIR) - # ensure include directory is added (in case of non-standard locations - include_directories(BEFORE "${LLVM_INCLUDES}") - string(REGEX REPLACE "\\." "" OSL_LLVM_VERSION ${LLVM_VERSION}) - message(STATUS "LLVM OSL_LLVM_VERSION = ${OSL_LLVM_VERSION}") - add_definitions("-DOSL_LLVM_VERSION=${OSL_LLVM_VERSION}") + if(LLVM_LIBRARY AND LLVM_DIRECTORY AND LLVM_LIB_DIR) if(LLVM_STATIC) # if static LLVM libraries were requested, use llvm-config to generate # the list of what libraries we need, and substitute that in the right @@ -1693,8 +1671,6 @@ elseif(APPLE) else() message(STATUS "OSL not found") endif() - - include_directories(${OSL_INCLUDES}) endif() set(EXETYPE MACOSX_BUNDLE) diff --git a/intern/cycles/CMakeLists.txt b/intern/cycles/CMakeLists.txt index 38daf790955..7562ee0a0a5 100644 --- a/intern/cycles/CMakeLists.txt +++ b/intern/cycles/CMakeLists.txt @@ -41,6 +41,7 @@ endif() if(WITH_CYCLES_OSL) add_definitions(-DWITH_OSL) + include_directories(${OSL_INCLUDES}) endif() if(WITH_CYCLES_PARTIO) diff --git a/intern/cycles/kernel/osl/nodes/CMakeLists.txt b/intern/cycles/kernel/osl/nodes/CMakeLists.txt index 65b8504ce43..faf7941ee5e 100644 --- a/intern/cycles/kernel/osl/nodes/CMakeLists.txt +++ b/intern/cycles/kernel/osl/nodes/CMakeLists.txt @@ -88,7 +88,7 @@ foreach(_file ${SRC_OSL}) unset(_OSO_FILE) endforeach() -add_custom_target(shader ALL DEPENDS ${SRC_OSO} ${SRC_OSL_HEADERS}) +add_custom_target(cycles_osl_shaders ALL DEPENDS ${SRC_OSO} ${SRC_OSL_HEADERS}) # CMAKE_CURRENT_SOURCE_DIR is already included in OSO paths delayed_install("" "${SRC_OSO}" ${CYCLES_INSTALL_PATH}/shader) From 9a1c1f132de971a840816614a0f4657ef1c12c89 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Sat, 20 Oct 2012 12:18:00 +0000 Subject: [PATCH 344/347] Cycles OSL: most closure code is now shared between OSL and SVM. Also fix transmission pass and filter glossy option. The BSDF closure class is now more similar to the SVM closures, and includes some flags and labels that are needed to properly categorize the BSDF's for render passes. Phong closure is gone for the moment, needs to be adapated to the new structure still. --- intern/cycles/kernel/CMakeLists.txt | 23 +- intern/cycles/kernel/{svm => closure}/bsdf.h | 0 .../{svm => closure}/bsdf_ashikhmin_velvet.h | 11 +- .../kernel/{svm => closure}/bsdf_diffuse.h | 13 +- .../kernel/{svm => closure}/bsdf_microfacet.h | 60 +- .../kernel/{svm => closure}/bsdf_oren_nayar.h | 12 +- .../kernel/{svm => closure}/bsdf_reflection.h | 9 +- .../kernel/{svm => closure}/bsdf_refraction.h | 11 +- .../{svm => closure}/bsdf_transparent.h | 9 +- .../kernel/{svm => closure}/bsdf_ward.h | 12 +- .../kernel/{svm => closure}/bsdf_westin.h | 21 +- .../cycles/kernel/{svm => closure}/emissive.h | 12 +- .../cycles/kernel/{svm => closure}/volume.h | 20 +- intern/cycles/kernel/kernel_shader.h | 28 +- intern/cycles/kernel/osl/CMakeLists.txt | 13 - intern/cycles/kernel/osl/background.cpp | 19 +- .../kernel/osl/bsdf_ashikhmin_velvet.cpp | 190 ------ intern/cycles/kernel/osl/bsdf_diffuse.cpp | 195 ------ intern/cycles/kernel/osl/bsdf_microfacet.cpp | 558 ------------------ intern/cycles/kernel/osl/bsdf_oren_nayar.cpp | 142 ----- intern/cycles/kernel/osl/bsdf_phong.cpp | 287 --------- intern/cycles/kernel/osl/bsdf_reflection.cpp | 113 ---- intern/cycles/kernel/osl/bsdf_refraction.cpp | 125 ---- intern/cycles/kernel/osl/bsdf_transparent.cpp | 102 ---- intern/cycles/kernel/osl/bsdf_ward.cpp | 230 -------- intern/cycles/kernel/osl/bsdf_westin.cpp | 251 -------- intern/cycles/kernel/osl/bssrdf.cpp | 110 ---- intern/cycles/kernel/osl/debug.cpp | 85 --- intern/cycles/kernel/osl/emissive.cpp | 38 +- intern/cycles/kernel/osl/osl_closures.cpp | 148 ++++- intern/cycles/kernel/osl/osl_closures.h | 167 ++++-- intern/cycles/kernel/osl/osl_services.cpp | 4 +- intern/cycles/kernel/osl/osl_shader.cpp | 94 +-- intern/cycles/kernel/osl/osl_shader.h | 3 +- intern/cycles/kernel/osl/vol_subsurface.cpp | 141 ----- intern/cycles/kernel/svm/svm_bsdf.h | 18 +- intern/cycles/kernel/svm/svm_closure.h | 66 ++- intern/cycles/render/osl.cpp | 2 + 38 files changed, 443 insertions(+), 2899 deletions(-) rename intern/cycles/kernel/{svm => closure}/bsdf.h (100%) rename intern/cycles/kernel/{svm => closure}/bsdf_ashikhmin_velvet.h (95%) rename intern/cycles/kernel/{svm => closure}/bsdf_diffuse.h (93%) rename intern/cycles/kernel/{svm => closure}/bsdf_microfacet.h (94%) rename intern/cycles/kernel/{svm => closure}/bsdf_oren_nayar.h (92%) rename intern/cycles/kernel/{svm => closure}/bsdf_reflection.h (94%) rename intern/cycles/kernel/{svm => closure}/bsdf_refraction.h (93%) rename intern/cycles/kernel/{svm => closure}/bsdf_transparent.h (93%) rename intern/cycles/kernel/{svm => closure}/bsdf_ward.h (96%) rename intern/cycles/kernel/{svm => closure}/bsdf_westin.h (92%) rename intern/cycles/kernel/{svm => closure}/emissive.h (86%) rename intern/cycles/kernel/{svm => closure}/volume.h (65%) delete mode 100644 intern/cycles/kernel/osl/bsdf_ashikhmin_velvet.cpp delete mode 100644 intern/cycles/kernel/osl/bsdf_diffuse.cpp delete mode 100644 intern/cycles/kernel/osl/bsdf_microfacet.cpp delete mode 100644 intern/cycles/kernel/osl/bsdf_oren_nayar.cpp delete mode 100644 intern/cycles/kernel/osl/bsdf_phong.cpp delete mode 100644 intern/cycles/kernel/osl/bsdf_reflection.cpp delete mode 100644 intern/cycles/kernel/osl/bsdf_refraction.cpp delete mode 100644 intern/cycles/kernel/osl/bsdf_transparent.cpp delete mode 100644 intern/cycles/kernel/osl/bsdf_ward.cpp delete mode 100644 intern/cycles/kernel/osl/bsdf_westin.cpp delete mode 100644 intern/cycles/kernel/osl/bssrdf.cpp delete mode 100644 intern/cycles/kernel/osl/debug.cpp delete mode 100644 intern/cycles/kernel/osl/vol_subsurface.cpp diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt index 92d10f31af5..6ba25881910 100644 --- a/intern/cycles/kernel/CMakeLists.txt +++ b/intern/cycles/kernel/CMakeLists.txt @@ -46,17 +46,17 @@ set(SRC_HEADERS ) set(SRC_SVM_HEADERS - svm/bsdf.h - svm/bsdf_ashikhmin_velvet.h - svm/bsdf_diffuse.h - svm/bsdf_oren_nayar.h - svm/bsdf_microfacet.h - svm/bsdf_reflection.h - svm/bsdf_refraction.h - svm/bsdf_transparent.h - svm/bsdf_ward.h - svm/bsdf_westin.h - svm/emissive.h + closure/bsdf.h + closure/bsdf_ashikhmin_velvet.h + closure/bsdf_microfacet.h + closure/bsdf_reflection.h + closure/bsdf_refraction.h + closure/bsdf_transparent.h + closure/bsdf_ward.h + closure/bsdf_westin.h + closure/emissive.h + closure/volume.h + svm/svm.h svm/svm_attribute.h svm/svm_bsdf.h @@ -92,7 +92,6 @@ set(SRC_SVM_HEADERS svm/svm_value.h svm/svm_voronoi.h svm/svm_wave.h - svm/volume.h ) set(SRC_UTIL_HEADERS diff --git a/intern/cycles/kernel/svm/bsdf.h b/intern/cycles/kernel/closure/bsdf.h similarity index 100% rename from intern/cycles/kernel/svm/bsdf.h rename to intern/cycles/kernel/closure/bsdf.h diff --git a/intern/cycles/kernel/svm/bsdf_ashikhmin_velvet.h b/intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h similarity index 95% rename from intern/cycles/kernel/svm/bsdf_ashikhmin_velvet.h rename to intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h index 5cdfb230fea..016fd73204e 100644 --- a/intern/cycles/kernel/svm/bsdf_ashikhmin_velvet.h +++ b/intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h @@ -35,15 +35,17 @@ CCL_NAMESPACE_BEGIN -__device void bsdf_ashikhmin_velvet_setup(ShaderData *sd, ShaderClosure *sc, float sigma) +__device int bsdf_ashikhmin_velvet_setup(ShaderClosure *sc) { + float sigma = sc->data0; sigma = fmaxf(sigma, 0.01f); float m_invsigma2 = 1.0f/(sigma * sigma); sc->type = CLOSURE_BSDF_ASHIKHMIN_VELVET_ID; - sd->flag |= SD_BSDF|SD_BSDF_HAS_EVAL; sc->data0 = m_invsigma2; + + return SD_BSDF|SD_BSDF_HAS_EVAL; } __device void bsdf_ashikhmin_velvet_blur(ShaderClosure *sc, float roughness) @@ -93,11 +95,6 @@ __device float3 bsdf_ashikhmin_velvet_eval_transmit(const ShaderClosure *sc, con return make_float3(0.0f, 0.0f, 0.0f); } -__device float bsdf_ashikhmin_velvet_albedo(const ShaderClosure *sc, const float3 I) -{ - return 1.0f; -} - __device int bsdf_ashikhmin_velvet_sample(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) { float m_invsigma2 = sc->data0; diff --git a/intern/cycles/kernel/svm/bsdf_diffuse.h b/intern/cycles/kernel/closure/bsdf_diffuse.h similarity index 93% rename from intern/cycles/kernel/svm/bsdf_diffuse.h rename to intern/cycles/kernel/closure/bsdf_diffuse.h index da3d1ae61ef..88b40e3d479 100644 --- a/intern/cycles/kernel/svm/bsdf_diffuse.h +++ b/intern/cycles/kernel/closure/bsdf_diffuse.h @@ -37,10 +37,10 @@ CCL_NAMESPACE_BEGIN /* DIFFUSE */ -__device void bsdf_diffuse_setup(ShaderData *sd, ShaderClosure *sc) +__device int bsdf_diffuse_setup(ShaderClosure *sc) { sc->type = CLOSURE_BSDF_DIFFUSE_ID; - sd->flag |= SD_BSDF|SD_BSDF_HAS_EVAL; + return SD_BSDF|SD_BSDF_HAS_EVAL; } __device void bsdf_diffuse_blur(ShaderClosure *sc, float roughness) @@ -61,11 +61,6 @@ __device float3 bsdf_diffuse_eval_transmit(const ShaderClosure *sc, const float3 return make_float3(0.0f, 0.0f, 0.0f); } -__device float bsdf_diffuse_albedo(const ShaderClosure *sc, const float3 I) -{ - return 1.0f; -} - __device int bsdf_diffuse_sample(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) { float3 N = sc->N; @@ -91,10 +86,10 @@ __device int bsdf_diffuse_sample(const ShaderClosure *sc, float3 Ng, float3 I, f /* TRANSLUCENT */ -__device void bsdf_translucent_setup(ShaderData *sd, ShaderClosure *sc) +__device int bsdf_translucent_setup(ShaderClosure *sc) { sc->type = CLOSURE_BSDF_TRANSLUCENT_ID; - sd->flag |= SD_BSDF|SD_BSDF_HAS_EVAL; + return SD_BSDF|SD_BSDF_HAS_EVAL; } __device void bsdf_translucent_blur(ShaderClosure *sc, float roughness) diff --git a/intern/cycles/kernel/svm/bsdf_microfacet.h b/intern/cycles/kernel/closure/bsdf_microfacet.h similarity index 94% rename from intern/cycles/kernel/svm/bsdf_microfacet.h rename to intern/cycles/kernel/closure/bsdf_microfacet.h index 11a1492cba1..f671e858481 100644 --- a/intern/cycles/kernel/svm/bsdf_microfacet.h +++ b/intern/cycles/kernel/closure/bsdf_microfacet.h @@ -42,20 +42,34 @@ __device_inline float safe_sqrtf(float f) return sqrtf(max(f, 0.0f)); } -__device void bsdf_microfacet_ggx_setup(ShaderData *sd, ShaderClosure *sc, float ag, float eta, bool refractive) +__device int bsdf_microfacet_ggx_setup(ShaderClosure *sc) { + float ag = sc->data0; + float eta = sc->data1; + float m_ag = clamp(ag, 1e-4f, 1.0f); float m_eta = eta; sc->data0 = m_ag; sc->data1 = m_eta; + sc->type = CLOSURE_BSDF_MICROFACET_GGX_ID; - if(refractive) - sc->type = CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID; - else - sc->type = CLOSURE_BSDF_MICROFACET_GGX_ID; + return SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY; +} - sd->flag |= SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY; +__device int bsdf_microfacet_ggx_refraction_setup(ShaderClosure *sc) +{ + float ag = sc->data0; + float eta = sc->data1; + + float m_ag = clamp(ag, 1e-4f, 1.0f); + float m_eta = eta; + + sc->data0 = m_ag; + sc->data1 = m_eta; + sc->type = CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID; + + return SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY; } __device void bsdf_microfacet_ggx_blur(ShaderClosure *sc, float roughness) @@ -138,11 +152,6 @@ __device float3 bsdf_microfacet_ggx_eval_transmit(const ShaderClosure *sc, const return make_float3 (out, out, out); } -__device float bsdf_microfacet_ggx_albedo(const ShaderClosure *sc, const float3 I) -{ - return 1.0f; -} - __device int bsdf_microfacet_ggx_sample(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) { float m_ag = sc->data0; @@ -262,20 +271,32 @@ __device int bsdf_microfacet_ggx_sample(const ShaderClosure *sc, float3 Ng, floa /* BECKMANN */ -__device void bsdf_microfacet_beckmann_setup(ShaderData *sd, ShaderClosure *sc, float ab, float eta, bool refractive) +__device int bsdf_microfacet_beckmann_setup(ShaderClosure *sc) { + float ab = sc->data0; + float eta = sc->data1; float m_ab = clamp(ab, 1e-4f, 1.0f); float m_eta = eta; sc->data0 = m_ab; sc->data1 = m_eta; - if(refractive) - sc->type = CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID; - else - sc->type = CLOSURE_BSDF_MICROFACET_BECKMANN_ID; + sc->type = CLOSURE_BSDF_MICROFACET_BECKMANN_ID; + return SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY; +} - sd->flag |= SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY; +__device int bsdf_microfacet_beckmann_refraction_setup(ShaderClosure *sc) +{ + float ab = sc->data0; + float eta = sc->data1; + float m_ab = clamp(ab, 1e-4f, 1.0f); + float m_eta = eta; + + sc->data0 = m_ab; + sc->data1 = m_eta; + + sc->type = CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID; + return SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY; } __device void bsdf_microfacet_beckmann_blur(ShaderClosure *sc, float roughness) @@ -362,11 +383,6 @@ __device float3 bsdf_microfacet_beckmann_eval_transmit(const ShaderClosure *sc, return make_float3 (out, out, out); } -__device float bsdf_microfacet_beckmann_albedo(const ShaderClosure *sc, const float3 I) -{ - return 1.0f; -} - __device int bsdf_microfacet_beckmann_sample(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) { float m_ab = sc->data0; diff --git a/intern/cycles/kernel/svm/bsdf_oren_nayar.h b/intern/cycles/kernel/closure/bsdf_oren_nayar.h similarity index 92% rename from intern/cycles/kernel/svm/bsdf_oren_nayar.h rename to intern/cycles/kernel/closure/bsdf_oren_nayar.h index 8a11e4ec73f..066937da6eb 100644 --- a/intern/cycles/kernel/svm/bsdf_oren_nayar.h +++ b/intern/cycles/kernel/closure/bsdf_oren_nayar.h @@ -33,10 +33,11 @@ __device float3 bsdf_oren_nayar_get_intensity(const ShaderClosure *sc, float3 n, return make_float3(is, is, is); } -__device void bsdf_oren_nayar_setup(ShaderData *sd, ShaderClosure *sc, float sigma) +__device int bsdf_oren_nayar_setup(ShaderClosure *sc) { + float sigma = sc->data0; + sc->type = CLOSURE_BSDF_OREN_NAYAR_ID; - sd->flag |= SD_BSDF | SD_BSDF_HAS_EVAL; sigma = clamp(sigma, 0.0f, 1.0f); @@ -44,6 +45,8 @@ __device void bsdf_oren_nayar_setup(ShaderData *sd, ShaderClosure *sc, float sig sc->data0 = 1.0f * div; sc->data1 = sigma * div; + + return SD_BSDF | SD_BSDF_HAS_EVAL; } __device void bsdf_oren_nayar_blur(ShaderClosure *sc, float roughness) @@ -67,11 +70,6 @@ __device float3 bsdf_oren_nayar_eval_transmit(const ShaderClosure *sc, const flo return make_float3(0.0f, 0.0f, 0.0f); } -__device float bsdf_oren_nayar_albedo(const ShaderClosure *sc, const float3 I) -{ - return 1.0f; -} - __device int bsdf_oren_nayar_sample(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) { sample_uniform_hemisphere(sc->N, randu, randv, omega_in, pdf); diff --git a/intern/cycles/kernel/svm/bsdf_reflection.h b/intern/cycles/kernel/closure/bsdf_reflection.h similarity index 94% rename from intern/cycles/kernel/svm/bsdf_reflection.h rename to intern/cycles/kernel/closure/bsdf_reflection.h index 0fff1868178..9356f950d98 100644 --- a/intern/cycles/kernel/svm/bsdf_reflection.h +++ b/intern/cycles/kernel/closure/bsdf_reflection.h @@ -37,10 +37,10 @@ CCL_NAMESPACE_BEGIN /* REFLECTION */ -__device void bsdf_reflection_setup(ShaderData *sd, ShaderClosure *sc) +__device int bsdf_reflection_setup(ShaderClosure *sc) { sc->type = CLOSURE_BSDF_REFLECTION_ID; - sd->flag |= SD_BSDF; + return SD_BSDF; } __device void bsdf_reflection_blur(ShaderClosure *sc, float roughness) @@ -57,11 +57,6 @@ __device float3 bsdf_reflection_eval_transmit(const ShaderClosure *sc, const flo return make_float3(0.0f, 0.0f, 0.0f); } -__device float bsdf_reflection_albedo(const ShaderClosure *sc, const float3 I) -{ - return 1.0f; -} - __device int bsdf_reflection_sample(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) { //const BsdfReflectionClosure *self = (const BsdfReflectionClosure*)sc->data; diff --git a/intern/cycles/kernel/svm/bsdf_refraction.h b/intern/cycles/kernel/closure/bsdf_refraction.h similarity index 93% rename from intern/cycles/kernel/svm/bsdf_refraction.h rename to intern/cycles/kernel/closure/bsdf_refraction.h index 686f9059857..ef79d6cc259 100644 --- a/intern/cycles/kernel/svm/bsdf_refraction.h +++ b/intern/cycles/kernel/closure/bsdf_refraction.h @@ -37,12 +37,10 @@ CCL_NAMESPACE_BEGIN /* REFRACTION */ -__device void bsdf_refraction_setup(ShaderData *sd, ShaderClosure *sc, float eta) +__device int bsdf_refraction_setup(ShaderClosure *sc) { - sc->data0 = eta; - sc->type = CLOSURE_BSDF_REFRACTION_ID; - sd->flag |= SD_BSDF; + return SD_BSDF; } __device void bsdf_refraction_blur(ShaderClosure *sc, float roughness) @@ -59,11 +57,6 @@ __device float3 bsdf_refraction_eval_transmit(const ShaderClosure *sc, const flo return make_float3(0.0f, 0.0f, 0.0f); } -__device float bsdf_refraction_albedo(const ShaderClosure *sc, const float3 I) -{ - return 1.0f; -} - __device int bsdf_refraction_sample(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) { float m_eta = sc->data0; diff --git a/intern/cycles/kernel/svm/bsdf_transparent.h b/intern/cycles/kernel/closure/bsdf_transparent.h similarity index 93% rename from intern/cycles/kernel/svm/bsdf_transparent.h rename to intern/cycles/kernel/closure/bsdf_transparent.h index 8427862a86b..81bc7690b50 100644 --- a/intern/cycles/kernel/svm/bsdf_transparent.h +++ b/intern/cycles/kernel/closure/bsdf_transparent.h @@ -35,10 +35,10 @@ CCL_NAMESPACE_BEGIN -__device void bsdf_transparent_setup(ShaderData *sd, ShaderClosure *sc) +__device int bsdf_transparent_setup(ShaderClosure *sc) { sc->type = CLOSURE_BSDF_TRANSPARENT_ID; - sd->flag |= SD_BSDF; + return SD_BSDF; } __device void bsdf_transparent_blur(ShaderClosure *sc, float roughness) @@ -55,11 +55,6 @@ __device float3 bsdf_transparent_eval_transmit(const ShaderClosure *sc, const fl return make_float3(0.0f, 0.0f, 0.0f); } -__device float bsdf_transparent_albedo(const ShaderClosure *sc, const float3 I) -{ - return 1.0f; -} - __device int bsdf_transparent_sample(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) { // only one direction is possible diff --git a/intern/cycles/kernel/svm/bsdf_ward.h b/intern/cycles/kernel/closure/bsdf_ward.h similarity index 96% rename from intern/cycles/kernel/svm/bsdf_ward.h rename to intern/cycles/kernel/closure/bsdf_ward.h index d167566bb75..9c81548a2c3 100644 --- a/intern/cycles/kernel/svm/bsdf_ward.h +++ b/intern/cycles/kernel/closure/bsdf_ward.h @@ -37,8 +37,11 @@ CCL_NAMESPACE_BEGIN /* WARD */ -__device void bsdf_ward_setup(ShaderData *sd, ShaderClosure *sc, float ax, float ay) +__device int bsdf_ward_setup(ShaderClosure *sc) { + float ax = sc->data0; + float ay = sc->data1; + float m_ax = clamp(ax, 1e-4f, 1.0f); float m_ay = clamp(ay, 1e-4f, 1.0f); @@ -46,7 +49,7 @@ __device void bsdf_ward_setup(ShaderData *sd, ShaderClosure *sc, float ax, float sc->data1 = m_ay; sc->type = CLOSURE_BSDF_WARD_ID; - sd->flag |= SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY; + return SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY; } __device void bsdf_ward_blur(ShaderClosure *sc, float roughness) @@ -92,11 +95,6 @@ __device float3 bsdf_ward_eval_transmit(const ShaderClosure *sc, const float3 I, return make_float3(0.0f, 0.0f, 0.0f); } -__device float bsdf_ward_albedo(const ShaderClosure *sc, const float3 I) -{ - return 1.0f; -} - __device int bsdf_ward_sample(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) { float m_ax = sc->data0; diff --git a/intern/cycles/kernel/svm/bsdf_westin.h b/intern/cycles/kernel/closure/bsdf_westin.h similarity index 92% rename from intern/cycles/kernel/svm/bsdf_westin.h rename to intern/cycles/kernel/closure/bsdf_westin.h index 44d89cf4866..968173208b4 100644 --- a/intern/cycles/kernel/svm/bsdf_westin.h +++ b/intern/cycles/kernel/closure/bsdf_westin.h @@ -37,14 +37,16 @@ CCL_NAMESPACE_BEGIN /* WESTIN BACKSCATTER */ -__device void bsdf_westin_backscatter_setup(ShaderData *sd, ShaderClosure *sc, float roughness) +__device int bsdf_westin_backscatter_setup(ShaderClosure *sc) { + float roughness = sc->data0; roughness = clamp(roughness, 1e-5f, 1.0f); float m_invroughness = 1.0f/roughness; sc->type = CLOSURE_BSDF_WESTIN_BACKSCATTER_ID; - sd->flag |= SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY; sc->data0 = m_invroughness; + + return SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY; } __device void bsdf_westin_backscatter_blur(ShaderClosure *sc, float roughness) @@ -76,11 +78,6 @@ __device float3 bsdf_westin_backscatter_eval_transmit(const ShaderClosure *sc, c return make_float3(0.0f, 0.0f, 0.0f); } -__device float bsdf_westin_backscatter_albedo(const ShaderClosure *sc, const float3 I) -{ - return 1.0f; -} - __device int bsdf_westin_backscatter_sample(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) { float m_invroughness = sc->data0; @@ -127,11 +124,12 @@ __device int bsdf_westin_backscatter_sample(const ShaderClosure *sc, float3 Ng, /* WESTIN SHEEN */ -__device void bsdf_westin_sheen_setup(ShaderData *sd, ShaderClosure *sc, float edginess) +__device int bsdf_westin_sheen_setup(ShaderClosure *sc) { + float edginess = sc->data0; sc->type = CLOSURE_BSDF_WESTIN_SHEEN_ID; - sd->flag |= SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY; sc->data0 = edginess; + return SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY; } __device void bsdf_westin_sheen_blur(ShaderClosure *sc, float roughness) @@ -160,11 +158,6 @@ __device float3 bsdf_westin_sheen_eval_transmit(const ShaderClosure *sc, const f return make_float3(0.0f, 0.0f, 0.0f); } -__device float bsdf_westin_sheen_albedo(const ShaderClosure *sc, const float3 I) -{ - return 1.0f; -} - __device int bsdf_westin_sheen_sample(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) { float m_edginess = sc->data0; diff --git a/intern/cycles/kernel/svm/emissive.h b/intern/cycles/kernel/closure/emissive.h similarity index 86% rename from intern/cycles/kernel/svm/emissive.h rename to intern/cycles/kernel/closure/emissive.h index 9a906f82963..cbf9d9a4efb 100644 --- a/intern/cycles/kernel/svm/emissive.h +++ b/intern/cycles/kernel/closure/emissive.h @@ -34,15 +34,21 @@ CCL_NAMESPACE_BEGIN /* EMISSION CLOSURE */ -/// Return the probability distribution function in the direction I, -/// given the parameters and the light's surface normal. This MUST match -/// the PDF computed by sample(). +/* return the probability distribution function in the direction I, + * given the parameters and the light's surface normal. This MUST match + * the PDF computed by sample(). */ __device float emissive_pdf(const float3 Ng, const float3 I) { float cosNO = fabsf(dot(Ng, I)); return (cosNO > 0.0f)? 1.0f: 0.0f; } +__device void emissive_sample(const float3 Ng, float randu, float randv, + float3 *omega_out, float *pdf) +{ + /* todo: not implemented and used yet */ +} + __device float3 emissive_eval(const float3 Ng, const float3 I) { float res = emissive_pdf(Ng, I); diff --git a/intern/cycles/kernel/svm/volume.h b/intern/cycles/kernel/closure/volume.h similarity index 65% rename from intern/cycles/kernel/svm/volume.h rename to intern/cycles/kernel/closure/volume.h index 10e9c5de352..734f9111ab6 100644 --- a/intern/cycles/kernel/svm/volume.h +++ b/intern/cycles/kernel/closure/volume.h @@ -23,44 +23,46 @@ CCL_NAMESPACE_BEGIN /* ISOTROPIC VOLUME CLOSURE */ -__device void volume_isotropic_setup(ShaderData *sd, ShaderClosure *sc, float density) +__device int volume_isotropic_setup(ShaderClosure *sc, float density) { sc->type = CLOSURE_VOLUME_ISOTROPIC_ID; - sd->flag |= SD_VOLUME; sc->data0 = density; + + return SD_VOLUME; } -__device float3 volume_isotropic_eval_phase(const ShaderData *sd, const ShaderClosure *sc, const float3 omega_in, const float3 omega_out) +__device float3 volume_isotropic_eval_phase(const ShaderClosure *sc, const float3 omega_in, const float3 omega_out) { return make_float3(1.0f, 1.0f, 1.0f); } /* TRANSPARENT VOLUME CLOSURE */ -__device void volume_transparent_setup(ShaderData *sd, ShaderClosure *sc, float density) +__device int volume_transparent_setup(ShaderClosure *sc, float density) { sc->type = CLOSURE_VOLUME_TRANSPARENT_ID; - sd->flag |= SD_VOLUME; sc->data0 = density; + + return SD_VOLUME; } -__device float3 volume_transparent_eval_phase(const ShaderData *sd, const ShaderClosure *sc, const float3 omega_in, const float3 omega_out) +__device float3 volume_transparent_eval_phase(const ShaderClosure *sc, const float3 omega_in, const float3 omega_out) { return make_float3(1.0f, 1.0f, 1.0f); } /* VOLUME CLOSURE */ -__device float3 volume_eval_phase(const ShaderData *sd, const ShaderClosure *sc, const float3 omega_in, const float3 omega_out) +__device float3 volume_eval_phase(const ShaderClosure *sc, const float3 omega_in, const float3 omega_out) { float3 eval; switch(sc->type) { case CLOSURE_VOLUME_ISOTROPIC_ID: - eval = volume_isotropic_eval_phase(sd, sc, omega_in, omega_out); + eval = volume_isotropic_eval_phase(sc, omega_in, omega_out); break; case CLOSURE_VOLUME_TRANSPARENT_ID: - eval = volume_transparent_eval_phase(sd, sc, omega_in, omega_out); + eval = volume_transparent_eval_phase(sc, omega_in, omega_out); break; default: eval = make_float3(0.0f, 0.0f, 0.0f); diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h index 814c32dfbd3..86886a6a231 100644 --- a/intern/cycles/kernel/kernel_shader.h +++ b/intern/cycles/kernel/kernel_shader.h @@ -27,18 +27,16 @@ */ #ifdef __OSL__ - #include "osl_shader.h" - #endif -#include "svm/bsdf.h" -#include "svm/emissive.h" -#include "svm/volume.h" +#include "closure/bsdf.h" +#include "closure/emissive.h" +#include "closure/volume.h" + #include "svm/svm_bsdf.h" #include "svm/svm.h" - CCL_NAMESPACE_BEGIN /* ShaderData setup from incoming ray */ @@ -499,18 +497,22 @@ __device int shader_bsdf_sample_closure(KernelGlobals *kg, const ShaderData *sd, __device void shader_bsdf_blur(KernelGlobals *kg, ShaderData *sd, float roughness) { -#ifndef __OSL__ #ifdef __MULTI_CLOSURE__ for(int i = 0; i< sd->num_closure; i++) { ShaderClosure *sc = &sd->closure[i]; - if(CLOSURE_IS_BSDF(sc->type)) - svm_bsdf_blur(sc, roughness); + if(CLOSURE_IS_BSDF(sc->type)) { +#ifdef __OSL__ + if (kernel_osl_use(kg)) + OSLShader::bsdf_blur(sc, roughness); + else +#endif + svm_bsdf_blur(sc, roughness); + } } #else svm_bsdf_blur(&sd->closure, roughness); #endif -#endif } __device float3 shader_bsdf_transparency(KernelGlobals *kg, ShaderData *sd) @@ -720,16 +722,16 @@ __device float3 shader_volume_eval_phase(KernelGlobals *kg, ShaderData *sd, if(CLOSURE_IS_VOLUME(sc->type)) { #ifdef __OSL__ if (kernel_osl_use(kg)) - eval += OSLShader::volume_eval_phase(sd, sc, omega_in, omega_out); + eval += OSLShader::volume_eval_phase(sc, omega_in, omega_out); else #endif - eval += volume_eval_phase(sd, sc, omega_in, omega_out); + eval += volume_eval_phase(sc, omega_in, omega_out); } } return eval; #else - return volume_eval_phase(sd, &sd->closure, omega_in, omega_out); + return volume_eval_phase(&sd->closure, omega_in, omega_out); #endif } diff --git a/intern/cycles/kernel/osl/CMakeLists.txt b/intern/cycles/kernel/osl/CMakeLists.txt index f57dc1b666b..d6449b4349b 100644 --- a/intern/cycles/kernel/osl/CMakeLists.txt +++ b/intern/cycles/kernel/osl/CMakeLists.txt @@ -14,23 +14,10 @@ set(INC_SYS set(SRC background.cpp - bsdf_ashikhmin_velvet.cpp - bsdf_diffuse.cpp - bsdf_oren_nayar.cpp - bsdf_phong.cpp - bsdf_microfacet.cpp - bsdf_reflection.cpp - bsdf_refraction.cpp - bsdf_transparent.cpp - bsdf_ward.cpp - bsdf_westin.cpp - bssrdf.cpp - debug.cpp emissive.cpp osl_closures.cpp osl_services.cpp osl_shader.cpp - vol_subsurface.cpp ) set(HEADER_SRC diff --git a/intern/cycles/kernel/osl/background.cpp b/intern/cycles/kernel/osl/background.cpp index 6290eed0af8..b6e9473b7bf 100644 --- a/intern/cycles/kernel/osl/background.cpp +++ b/intern/cycles/kernel/osl/background.cpp @@ -46,23 +46,16 @@ using namespace OSL; /// to return a color in background shaders. No methods, /// only the weight is taking into account /// -class GenericBackgroundClosure : public BackgroundClosure { +class GenericBackgroundClosure : public OSL::BackgroundClosure { public: GenericBackgroundClosure() {} void setup() {}; - size_t memsize() const { return sizeof(*this); } - const char *name() const { return "background"; } - - void print_on(std::ostream &out) const { - out << name() << " ()"; - } - + void print_on(std::ostream &out) const { out << name() << " ()"; } }; - /// Holdout closure /// /// This will be used by the shader to mark the @@ -75,17 +68,11 @@ public: HoldoutClosure () : ClosurePrimitive(Holdout) {} void setup() {}; - size_t memsize() const { return sizeof(*this); } - const char *name() const { return "holdout"; } - - void print_on(std::ostream &out) const { - out << name() << " ()"; - } + void print_on(std::ostream &out) const { out << name() << " ()"; } }; - ClosureParam *closure_background_params() { static ClosureParam params[] = { diff --git a/intern/cycles/kernel/osl/bsdf_ashikhmin_velvet.cpp b/intern/cycles/kernel/osl/bsdf_ashikhmin_velvet.cpp deleted file mode 100644 index a1904d7f5d7..00000000000 --- a/intern/cycles/kernel/osl/bsdf_ashikhmin_velvet.cpp +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Adapted from Open Shading Language with this license: - * - * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. - * All Rights Reserved. - * - * Modifications Copyright 2011, Blender Foundation. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Sony Pictures Imageworks nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -#include - -#include "osl_closures.h" - -#include "util_math.h" - -CCL_NAMESPACE_BEGIN - -using namespace OSL; - -class AshikhminVelvetClosure : public BSDFClosure { -public: - Vec3 m_N; - float m_sigma; - float m_invsigma2; - - AshikhminVelvetClosure() : BSDFClosure(Labels::DIFFUSE) {} - - void setup() - { - m_sigma = max(m_sigma, 0.01f); - m_invsigma2 = 1.0f / (m_sigma * m_sigma); - } - - bool mergeable(const ClosurePrimitive *other) const { - const AshikhminVelvetClosure *comp = (const AshikhminVelvetClosure *)other; - return m_N == comp->m_N && m_sigma == comp->m_sigma && - BSDFClosure::mergeable(other); - } - - size_t memsize() const { return sizeof(*this); } - - const char *name() const { return "ashikhmin_velvet"; } - - void print_on(std::ostream &out) const - { - out << name() << " ("; - out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), "; - out << m_sigma; - out << ")"; - } - - float albedo(const Vec3 &omega_out) const - { - return 1.0f; - } - - Color3 eval_reflect(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - float cosNO = m_N.dot(omega_out); - float cosNI = m_N.dot(omega_in); - if (cosNO > 0 && cosNI > 0) { - Vec3 H = omega_in + omega_out; - H.normalize(); - - float cosNH = m_N.dot(H); - float cosHO = fabsf(omega_out.dot(H)); - - if(!(fabsf(cosNH) < 1.0f-1e-5f && cosHO > 1e-5f)) - return Color3(0, 0, 0); - - float cosNHdivHO = cosNH / cosHO; - cosNHdivHO = max(cosNHdivHO, 1e-5f); - - float fac1 = 2 * fabsf(cosNHdivHO * cosNO); - float fac2 = 2 * fabsf(cosNHdivHO * cosNI); - - float sinNH2 = 1 - cosNH * cosNH; - float sinNH4 = sinNH2 * sinNH2; - float cotangent2 = (cosNH * cosNH) / sinNH2; - - float D = expf(-cotangent2 * m_invsigma2) * m_invsigma2 * float(M_1_PI) / sinNH4; - float G = min(1.0f, min(fac1, fac2)); // TODO: derive G from D analytically - - float out = 0.25f * (D * G) / cosNO; - - pdf = 0.5f * (float) M_1_PI; - return Color3(out, out, out); - } - return Color3(0, 0, 0); - } - - Color3 eval_transmit(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - return Color3(0, 0, 0); - } - - ustring sample(const Vec3 &Ng, - const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, - float randu, float randv, - Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, - float &pdf, Color3 &eval) const - { - // we are viewing the surface from above - send a ray out with uniform - // distribution over the hemisphere - sample_uniform_hemisphere(m_N, omega_out, randu, randv, omega_in, pdf); - if (Ng.dot(omega_in) > 0) { - Vec3 H = omega_in + omega_out; - H.normalize(); - - float cosNI = m_N.dot(omega_in); - float cosNO = m_N.dot(omega_out); - float cosNH = m_N.dot(H); - float cosHO = fabsf(omega_out.dot(H)); - - if(fabsf(cosNO) > 1e-5f && fabsf(cosNH) < 1.0f-1e-5f && cosHO > 1e-5f) { - float cosNHdivHO = cosNH / cosHO; - cosNHdivHO = max(cosNHdivHO, 1e-5f); - - float fac1 = 2 * fabsf(cosNHdivHO * cosNO); - float fac2 = 2 * fabsf(cosNHdivHO * cosNI); - - float sinNH2 = 1 - cosNH * cosNH; - float sinNH4 = sinNH2 * sinNH2; - float cotangent2 = (cosNH * cosNH) / sinNH2; - - float D = expf(-cotangent2 * m_invsigma2) * m_invsigma2 * float(M_1_PI) / sinNH4; - float G = min(1.0f, min(fac1, fac2)); // TODO: derive G from D analytically - - float power = 0.25f * (D * G) / cosNO; - - eval.setValue(power, power, power); - - // TODO: find a better approximation for the retroreflective bounce - domega_in_dx = (2 * m_N.dot(domega_out_dx)) * m_N - domega_out_dx; - domega_in_dy = (2 * m_N.dot(domega_out_dy)) * m_N - domega_out_dy; - domega_in_dx *= 125; - domega_in_dy *= 125; - } - else - pdf = 0; - } - else - pdf = 0; - return Labels::REFLECT; - } - -}; - - - -ClosureParam *bsdf_ashikhmin_velvet_params() -{ - static ClosureParam params[] = { - CLOSURE_VECTOR_PARAM(AshikhminVelvetClosure, m_N), - CLOSURE_FLOAT_PARAM(AshikhminVelvetClosure, m_sigma), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(AshikhminVelvetClosure) - }; - return params; -} - -CLOSURE_PREPARE(bsdf_ashikhmin_velvet_prepare, AshikhminVelvetClosure) - -CCL_NAMESPACE_END - diff --git a/intern/cycles/kernel/osl/bsdf_diffuse.cpp b/intern/cycles/kernel/osl/bsdf_diffuse.cpp deleted file mode 100644 index 1e06d3b583f..00000000000 --- a/intern/cycles/kernel/osl/bsdf_diffuse.cpp +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Adapted from Open Shading Language with this license: - * - * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. - * All Rights Reserved. - * - * Modifications Copyright 2011, Blender Foundation. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Sony Pictures Imageworks nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -#include - -#include "osl_closures.h" - -#include "util_math.h" - -CCL_NAMESPACE_BEGIN - -using namespace OSL; - -class DiffuseClosure : public BSDFClosure { -public: - Vec3 m_N; - - DiffuseClosure() : BSDFClosure(Labels::DIFFUSE) {} - - void setup() {}; - - bool mergeable(const ClosurePrimitive *other) const { - const DiffuseClosure *comp = (const DiffuseClosure *)other; - return m_N == comp->m_N && BSDFClosure::mergeable(other); - } - - size_t memsize() const { return sizeof(*this); } - - const char *name() const { return "diffuse"; } - - void print_on(std::ostream &out) const - { - out << name() << " ((" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "))"; - } - - float albedo(const Vec3 &omega_out) const - { - return 1.0f; - } - - Color3 eval_reflect(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - float cos_pi = max(m_N.dot(omega_in), 0.0f) * (float) M_1_PI; - pdf = cos_pi; - return Color3(cos_pi, cos_pi, cos_pi); - } - - Color3 eval_transmit(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - return Color3(0, 0, 0); - } - - ustring sample(const Vec3 &Ng, - const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, - float randu, float randv, - Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, - float &pdf, Color3 &eval) const - { - // we are viewing the surface from the right side - send a ray out with cosine - // distribution over the hemisphere - sample_cos_hemisphere(m_N, omega_out, randu, randv, omega_in, pdf); - if (Ng.dot(omega_in) > 0) { - eval.setValue(pdf, pdf, pdf); - // TODO: find a better approximation for the diffuse bounce - domega_in_dx = (2 * m_N.dot(domega_out_dx)) * m_N - domega_out_dx; - domega_in_dy = (2 * m_N.dot(domega_out_dy)) * m_N - domega_out_dy; - domega_in_dx *= 125; - domega_in_dy *= 125; - } - else - pdf = 0; - return Labels::REFLECT; - } -}; - - - -class TranslucentClosure : public BSDFClosure { -public: - Vec3 m_N; - - TranslucentClosure() : BSDFClosure(Labels::DIFFUSE, Back) {} - - void setup() {}; - - bool mergeable(const ClosurePrimitive *other) const { - const TranslucentClosure *comp = (const TranslucentClosure *)other; - return m_N == comp->m_N && BSDFClosure::mergeable(other); - } - - size_t memsize() const { return sizeof(*this); } - - const char *name() const { return "translucent"; } - - void print_on(std::ostream &out) const - { - out << name() << " ((" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "))"; - } - - Color3 eval_reflect(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - return Color3(0, 0, 0); - } - - float albedo(const Vec3 &omega_out) const - { - return 1.0f; - } - - Color3 eval_transmit(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - float cos_pi = max(-m_N.dot(omega_in), 0.0f) * (float) M_1_PI; - pdf = cos_pi; - return Color3(cos_pi, cos_pi, cos_pi); - } - - ustring sample(const Vec3 &Ng, - const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, - float randu, float randv, - Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, - float &pdf, Color3 &eval) const - { - // we are viewing the surface from the right side - send a ray out with cosine - // distribution over the hemisphere - sample_cos_hemisphere(-m_N, omega_out, randu, randv, omega_in, pdf); - if (Ng.dot(omega_in) < 0) { - eval.setValue(pdf, pdf, pdf); - // TODO: find a better approximation for the diffuse bounce - domega_in_dx = (2 * m_N.dot(domega_out_dx)) * m_N - domega_out_dx; - domega_in_dy = (2 * m_N.dot(domega_out_dy)) * m_N - domega_out_dy; - domega_in_dx *= -125; - domega_in_dy *= -125; - } - else - pdf = 0; - return Labels::TRANSMIT; - } -}; - -ClosureParam *bsdf_diffuse_params() -{ - static ClosureParam params[] = { - CLOSURE_VECTOR_PARAM(DiffuseClosure, m_N), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(DiffuseClosure) - }; - return params; -} - -ClosureParam *bsdf_translucent_params() -{ - static ClosureParam params[] = { - CLOSURE_VECTOR_PARAM(TranslucentClosure, m_N), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(TranslucentClosure) - }; - return params; -} - -CLOSURE_PREPARE(bsdf_diffuse_prepare, DiffuseClosure) -CLOSURE_PREPARE(bsdf_translucent_prepare, TranslucentClosure) - -CCL_NAMESPACE_END - diff --git a/intern/cycles/kernel/osl/bsdf_microfacet.cpp b/intern/cycles/kernel/osl/bsdf_microfacet.cpp deleted file mode 100644 index 8446dbbe982..00000000000 --- a/intern/cycles/kernel/osl/bsdf_microfacet.cpp +++ /dev/null @@ -1,558 +0,0 @@ -/* - * Adapted from Open Shading Language with this license: - * - * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. - * All Rights Reserved. - * - * Modifications Copyright 2011, Blender Foundation. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Sony Pictures Imageworks nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -#include - -#include "osl_closures.h" - -#include "util_math.h" - -using namespace OSL; - -CCL_NAMESPACE_BEGIN - -// TODO: fresnel_dielectric is only used for derivatives, could be optimized - -// TODO: refactor these two classes so they share everything by the microfacet -// distribution terms - -// microfacet model with GGX facet distribution -// see http://www.graphics.cornell.edu/~bjw/microfacetbsdf.pdf -template -class MicrofacetGGXClosure : public BSDFClosure { -public: - Vec3 m_N; - float m_ag; // width parameter (roughness) - float m_eta; // index of refraction (for fresnel term) - MicrofacetGGXClosure() : BSDFClosure(Labels::GLOSSY, Refractive ? Back : Front) { m_eta = 1.0f; } - - void setup() - { - m_ag = clamp(m_ag, 1e-5f, 1.0f); - } - - bool mergeable(const ClosurePrimitive *other) const { - const MicrofacetGGXClosure *comp = (const MicrofacetGGXClosure *)other; - return m_N == comp->m_N && m_ag == comp->m_ag && - m_eta == comp->m_eta && BSDFClosure::mergeable(other); - } - - size_t memsize() const { return sizeof(*this); } - - const char *name() const { - return Refractive ? "microfacet_ggx_refraction" : "microfacet_ggx"; - } - - void print_on(std::ostream &out) const { - out << name() << " ("; - out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), "; - out << m_ag << ", "; - out << m_eta; - out << ")"; - } - - float albedo(const Vec3 &omega_out) const - { - return 1.0f; - } - - Color3 eval_reflect(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - if (Refractive == 1) return Color3(0, 0, 0); - float cosNO = m_N.dot(omega_out); - float cosNI = m_N.dot(omega_in); - if (cosNI > 0 && cosNO > 0) { - // get half vector - Vec3 Hr = omega_in + omega_out; - Hr.normalize(); - // eq. 20: (F*G*D)/(4*in*on) - // eq. 33: first we calculate D(m) with m=Hr: - float alpha2 = m_ag * m_ag; - float cosThetaM = m_N.dot(Hr); - float cosThetaM2 = cosThetaM * cosThetaM; - float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2; - float cosThetaM4 = cosThetaM2 * cosThetaM2; - float D = alpha2 / ((float) M_PI * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2)); - // eq. 34: now calculate G1(i,m) and G1(o,m) - float G1o = 2 / (1 + sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO))); - float G1i = 2 / (1 + sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI))); - float G = G1o * G1i; - float out = (G * D) * 0.25f / cosNO; - // eq. 24 - float pm = D * cosThetaM; - // convert into pdf of the sampled direction - // eq. 38 - but see also: - // eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf - pdf = pm * 0.25f / Hr.dot(omega_out); - return Color3(out, out, out); - } - return Color3(0, 0, 0); - } - - Color3 eval_transmit(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - if (Refractive == 0) return Color3(0, 0, 0); - float cosNO = m_N.dot(omega_out); - float cosNI = m_N.dot(omega_in); - if (cosNO <= 0 || cosNI >= 0) - return Color3(0, 0, 0); // vectors on same side -- not possible - // compute half-vector of the refraction (eq. 16) - Vec3 ht = -(m_eta * omega_in + omega_out); - Vec3 Ht = ht; Ht.normalize(); - float cosHO = Ht.dot(omega_out); - - float cosHI = Ht.dot(omega_in); - // eq. 33: first we calculate D(m) with m=Ht: - float alpha2 = m_ag * m_ag; - float cosThetaM = m_N.dot(Ht); - float cosThetaM2 = cosThetaM * cosThetaM; - float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2; - float cosThetaM4 = cosThetaM2 * cosThetaM2; - float D = alpha2 / ((float) M_PI * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2)); - // eq. 34: now calculate G1(i,m) and G1(o,m) - float G1o = 2 / (1 + sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO))); - float G1i = 2 / (1 + sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI))); - float G = G1o * G1i; - // probability - float invHt2 = 1 / ht.dot(ht); - pdf = D * fabsf(cosThetaM) * (fabsf(cosHI) * (m_eta * m_eta)) * invHt2; - float out = (fabsf(cosHI * cosHO) * (m_eta * m_eta) * (G * D) * invHt2) / cosNO; - return Color3(out, out, out); - } - - ustring sample(const Vec3 &Ng, - const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, - float randu, float randv, - Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, - float &pdf, Color3 &eval) const - { - float cosNO = m_N.dot(omega_out); - if (cosNO > 0) { - Vec3 X, Y, Z = m_N; - make_orthonormals(Z, X, Y); - // generate a random microfacet normal m - // eq. 35,36: - // we take advantage of cos(atan(x)) == 1/sqrt(1+x^2) - // and sin(atan(x)) == x/sqrt(1+x^2) - float alpha2 = m_ag * m_ag; - float tanThetaM2 = alpha2 * randu / (1 - randu); - float cosThetaM = 1 / sqrtf(1 + tanThetaM2); - float sinThetaM = cosThetaM * sqrtf(tanThetaM2); - float phiM = 2 * float(M_PI) * randv; - Vec3 m = (cosf(phiM) * sinThetaM) * X + - (sinf(phiM) * sinThetaM) * Y + - cosThetaM * Z; - if (Refractive == 0) { - float cosMO = m.dot(omega_out); - if (cosMO > 0) { - // eq. 39 - compute actual reflected direction - omega_in = 2 * cosMO * m - omega_out; - if (Ng.dot(omega_in) > 0) { - // microfacet normal is visible to this ray - // eq. 33 - float cosThetaM2 = cosThetaM * cosThetaM; - float cosThetaM4 = cosThetaM2 * cosThetaM2; - float D = alpha2 / (float(M_PI) * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2)); - // eq. 24 - float pm = D * cosThetaM; - // convert into pdf of the sampled direction - // eq. 38 - but see also: - // eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf - pdf = pm * 0.25f / cosMO; - // eval BRDF*cosNI - float cosNI = m_N.dot(omega_in); - // eq. 34: now calculate G1(i,m) and G1(o,m) - float G1o = 2 / (1 + sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO))); - float G1i = 2 / (1 + sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI))); - float G = G1o * G1i; - // eq. 20: (F*G*D)/(4*in*on) - float out = (G * D) * 0.25f / cosNO; - eval.setValue(out, out, out); - domega_in_dx = (2 * m.dot(domega_out_dx)) * m - domega_out_dx; - domega_in_dy = (2 * m.dot(domega_out_dy)) * m - domega_out_dy; - - /* disabled for now - gives texture filtering problems */ -#if 0 - // Since there is some blur to this reflection, make the - // derivatives a bit bigger. In theory this varies with the - // roughness but the exact relationship is complex and - // requires more ops than are practical. - domega_in_dx *= 10; - domega_in_dy *= 10; -#endif - } - } - } - else { - // CAUTION: the i and o variables are inverted relative to the paper - // eq. 39 - compute actual refractive direction - Vec3 R, dRdx, dRdy; - Vec3 T, dTdx, dTdy; - bool inside; - fresnel_dielectric(m_eta, m, omega_out, domega_out_dx, domega_out_dy, - R, dRdx, dRdy, - T, dTdx, dTdy, - inside); - - if (!inside) { - omega_in = T; - domega_in_dx = dTdx; - domega_in_dy = dTdy; - // eq. 33 - float cosThetaM2 = cosThetaM * cosThetaM; - float cosThetaM4 = cosThetaM2 * cosThetaM2; - float D = alpha2 / (float(M_PI) * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2)); - // eq. 24 - float pm = D * cosThetaM; - // eval BRDF*cosNI - float cosNI = m_N.dot(omega_in); - // eq. 34: now calculate G1(i,m) and G1(o,m) - float G1o = 2 / (1 + sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO))); - float G1i = 2 / (1 + sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI))); - float G = G1o * G1i; - // eq. 21 - float cosHI = m.dot(omega_in); - float cosHO = m.dot(omega_out); - float Ht2 = m_eta * cosHI + cosHO; - Ht2 *= Ht2; - float out = (fabsf(cosHI * cosHO) * (m_eta * m_eta) * (G * D)) / (cosNO * Ht2); - // eq. 38 and eq. 17 - pdf = pm * (m_eta * m_eta) * fabsf(cosHI) / Ht2; - eval.setValue(out, out, out); - - /* disabled for now - gives texture filtering problems */ -#if 0 - // Since there is some blur to this refraction, make the - // derivatives a bit bigger. In theory this varies with the - // roughness but the exact relationship is complex and - // requires more ops than are practical. - domega_in_dx *= 10; - domega_in_dy *= 10; -#endif - } - } - } - return Refractive ? Labels::TRANSMIT : Labels::REFLECT; - } -}; - -// microfacet model with Beckmann facet distribution -// see http://www.graphics.cornell.edu/~bjw/microfacetbsdf.pdf -template -class MicrofacetBeckmannClosure : public BSDFClosure { -public: - Vec3 m_N; - float m_ab; // width parameter (roughness) - float m_eta; // index of refraction (for fresnel term) - MicrofacetBeckmannClosure() : BSDFClosure(Labels::GLOSSY, Refractive ? Back : Front) { - } - - void setup() - { - m_ab = clamp(m_ab, 1e-5f, 1.0f); - } - - bool mergeable(const ClosurePrimitive *other) const { - const MicrofacetBeckmannClosure *comp = (const MicrofacetBeckmannClosure *)other; - return m_N == comp->m_N && m_ab == comp->m_ab && - m_eta == comp->m_eta && BSDFClosure::mergeable(other); - } - - size_t memsize() const { - return sizeof(*this); - } - - const char *name() const { - return Refractive ? "microfacet_beckmann_refraction" - : "microfacet_beckmann"; - } - - void print_on(std::ostream &out) const - { - out << name() << " ("; - out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), "; - out << m_ab << ", "; - out << m_eta; - out << ")"; - } - - float albedo(const Vec3 &omega_out) const - { - return 1.0f; - } - - Color3 eval_reflect(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - if (Refractive == 1) return Color3(0, 0, 0); - float cosNO = m_N.dot(omega_out); - float cosNI = m_N.dot(omega_in); - if (cosNO > 0 && cosNI > 0) { - // get half vector - Vec3 Hr = omega_in + omega_out; - Hr.normalize(); - // eq. 20: (F*G*D)/(4*in*on) - // eq. 25: first we calculate D(m) with m=Hr: - float alpha2 = m_ab * m_ab; - float cosThetaM = m_N.dot(Hr); - float cosThetaM2 = cosThetaM * cosThetaM; - float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2; - float cosThetaM4 = cosThetaM2 * cosThetaM2; - float D = expf(-tanThetaM2 / alpha2) / (float(M_PI) * alpha2 * cosThetaM4); - // eq. 26, 27: now calculate G1(i,m) and G1(o,m) - float ao = 1 / (m_ab * sqrtf((1 - cosNO * cosNO) / (cosNO * cosNO))); - float ai = 1 / (m_ab * sqrtf((1 - cosNI * cosNI) / (cosNI * cosNI))); - float G1o = ao < 1.6f ? (3.535f * ao + 2.181f * ao * ao) / (1 + 2.276f * ao + 2.577f * ao * ao) : 1.0f; - float G1i = ai < 1.6f ? (3.535f * ai + 2.181f * ai * ai) / (1 + 2.276f * ai + 2.577f * ai * ai) : 1.0f; - float G = G1o * G1i; - float out = (G * D) * 0.25f / cosNO; - // eq. 24 - float pm = D * cosThetaM; - // convert into pdf of the sampled direction - // eq. 38 - but see also: - // eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf - pdf = pm * 0.25f / Hr.dot(omega_out); - return Color3(out, out, out); - } - return Color3(0, 0, 0); - } - - Color3 eval_transmit(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - if (Refractive == 0) return Color3(0, 0, 0); - float cosNO = m_N.dot(omega_out); - float cosNI = m_N.dot(omega_in); - if (cosNO <= 0 || cosNI >= 0) - return Color3(0, 0, 0); - // compute half-vector of the refraction (eq. 16) - Vec3 ht = -(m_eta * omega_in + omega_out); - Vec3 Ht = ht; Ht.normalize(); - float cosHO = Ht.dot(omega_out); - - float cosHI = Ht.dot(omega_in); - // eq. 33: first we calculate D(m) with m=Ht: - float alpha2 = m_ab * m_ab; - float cosThetaM = m_N.dot(Ht); - float cosThetaM2 = cosThetaM * cosThetaM; - float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2; - float cosThetaM4 = cosThetaM2 * cosThetaM2; - float D = expf(-tanThetaM2 / alpha2) / (float(M_PI) * alpha2 * cosThetaM4); - // eq. 26, 27: now calculate G1(i,m) and G1(o,m) - float ao = 1 / (m_ab * sqrtf((1 - cosNO * cosNO) / (cosNO * cosNO))); - float ai = 1 / (m_ab * sqrtf((1 - cosNI * cosNI) / (cosNI * cosNI))); - float G1o = ao < 1.6f ? (3.535f * ao + 2.181f * ao * ao) / (1 + 2.276f * ao + 2.577f * ao * ao) : 1.0f; - float G1i = ai < 1.6f ? (3.535f * ai + 2.181f * ai * ai) / (1 + 2.276f * ai + 2.577f * ai * ai) : 1.0f; - float G = G1o * G1i; - // probability - float invHt2 = 1 / ht.dot(ht); - pdf = D * fabsf(cosThetaM) * (fabsf(cosHI) * (m_eta * m_eta)) * invHt2; - float out = (fabsf(cosHI * cosHO) * (m_eta * m_eta) * (G * D) * invHt2) / cosNO; - return Color3(out, out, out); - } - - ustring sample(const Vec3 &Ng, - const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, - float randu, float randv, - Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, - float &pdf, Color3 &eval) const - { - float cosNO = m_N.dot(omega_out); - if (cosNO > 0) { - Vec3 X, Y, Z = m_N; - make_orthonormals(Z, X, Y); - // generate a random microfacet normal m - // eq. 35,36: - // we take advantage of cos(atan(x)) == 1/sqrt(1+x^2) - // and sin(atan(x)) == x/sqrt(1+x^2) - float alpha2 = m_ab * m_ab; - float tanThetaM = sqrtf(-alpha2 * logf(1 - randu)); - float cosThetaM = 1 / sqrtf(1 + tanThetaM * tanThetaM); - float sinThetaM = cosThetaM * tanThetaM; - float phiM = 2 * float(M_PI) * randv; - Vec3 m = (cosf(phiM) * sinThetaM) * X + - (sinf(phiM) * sinThetaM) * Y + - cosThetaM * Z; - if (Refractive == 0) { - float cosMO = m.dot(omega_out); - if (cosMO > 0) { - // eq. 39 - compute actual reflected direction - omega_in = 2 * cosMO * m - omega_out; - if (Ng.dot(omega_in) > 0) { - // microfacet normal is visible to this ray - // eq. 25 - float cosThetaM2 = cosThetaM * cosThetaM; - float tanThetaM2 = tanThetaM * tanThetaM; - float cosThetaM4 = cosThetaM2 * cosThetaM2; - float D = expf(-tanThetaM2 / alpha2) / (float(M_PI) * alpha2 * cosThetaM4); - // eq. 24 - float pm = D * cosThetaM; - // convert into pdf of the sampled direction - // eq. 38 - but see also: - // eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf - pdf = pm * 0.25f / cosMO; - // Eval BRDF*cosNI - float cosNI = m_N.dot(omega_in); - // eq. 26, 27: now calculate G1(i,m) and G1(o,m) - float ao = 1 / (m_ab * sqrtf((1 - cosNO * cosNO) / (cosNO * cosNO))); - float ai = 1 / (m_ab * sqrtf((1 - cosNI * cosNI) / (cosNI * cosNI))); - float G1o = ao < 1.6f ? (3.535f * ao + 2.181f * ao * ao) / (1 + 2.276f * ao + 2.577f * ao * ao) : 1.0f; - float G1i = ai < 1.6f ? (3.535f * ai + 2.181f * ai * ai) / (1 + 2.276f * ai + 2.577f * ai * ai) : 1.0f; - float G = G1o * G1i; - // eq. 20: (F*G*D)/(4*in*on) - float out = (G * D) * 0.25f / cosNO; - eval.setValue(out, out, out); - domega_in_dx = (2 * m.dot(domega_out_dx)) * m - domega_out_dx; - domega_in_dy = (2 * m.dot(domega_out_dy)) * m - domega_out_dy; - - /* disabled for now - gives texture filtering problems */ -#if 0 - // Since there is some blur to this reflection, make the - // derivatives a bit bigger. In theory this varies with the - // roughness but the exact relationship is complex and - // requires more ops than are practical. - domega_in_dx *= 10; - domega_in_dy *= 10; -#endif - } - } - } - else { - // CAUTION: the i and o variables are inverted relative to the paper - // eq. 39 - compute actual refractive direction - Vec3 R, dRdx, dRdy; - Vec3 T, dTdx, dTdy; - bool inside; - fresnel_dielectric(m_eta, m, omega_out, domega_out_dx, domega_out_dy, - R, dRdx, dRdy, - T, dTdx, dTdy, - inside); - if (!inside) { - omega_in = T; - domega_in_dx = dTdx; - domega_in_dy = dTdy; - // eq. 33 - float cosThetaM2 = cosThetaM * cosThetaM; - float tanThetaM2 = tanThetaM * tanThetaM; - float cosThetaM4 = cosThetaM2 * cosThetaM2; - float D = expf(-tanThetaM2 / alpha2) / (float(M_PI) * alpha2 * cosThetaM4); - // eq. 24 - float pm = D * cosThetaM; - // eval BRDF*cosNI - float cosNI = m_N.dot(omega_in); - // eq. 26, 27: now calculate G1(i,m) and G1(o,m) - float ao = 1 / (m_ab * sqrtf((1 - cosNO * cosNO) / (cosNO * cosNO))); - float ai = 1 / (m_ab * sqrtf((1 - cosNI * cosNI) / (cosNI * cosNI))); - float G1o = ao < 1.6f ? (3.535f * ao + 2.181f * ao * ao) / (1 + 2.276f * ao + 2.577f * ao * ao) : 1.0f; - float G1i = ai < 1.6f ? (3.535f * ai + 2.181f * ai * ai) / (1 + 2.276f * ai + 2.577f * ai * ai) : 1.0f; - float G = G1o * G1i; - // eq. 21 - float cosHI = m.dot(omega_in); - float cosHO = m.dot(omega_out); - float Ht2 = m_eta * cosHI + cosHO; - Ht2 *= Ht2; - float out = (fabsf(cosHI * cosHO) * (m_eta * m_eta) * (G * D)) / (cosNO * Ht2); - // eq. 38 and eq. 17 - pdf = pm * (m_eta * m_eta) * fabsf(cosHI) / Ht2; - eval.setValue(out, out, out); - - /* disabled for now - gives texture filtering problems */ -#if 0 - // Since there is some blur to this refraction, make the - // derivatives a bit bigger. In theory this varies with the - // roughness but the exact relationship is complex and - // requires more ops than are practical. - domega_in_dx *= 10; - domega_in_dy *= 10; -#endif - } - } - } - return Refractive ? Labels::TRANSMIT : Labels::REFLECT; - } -}; - - - -ClosureParam *bsdf_microfacet_ggx_params() -{ - static ClosureParam params[] = { - CLOSURE_VECTOR_PARAM(MicrofacetGGXClosure<0>, m_N), - CLOSURE_FLOAT_PARAM(MicrofacetGGXClosure<0>, m_ag), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(MicrofacetGGXClosure<0>) - }; - return params; -} - -ClosureParam *bsdf_microfacet_ggx_refraction_params() -{ - static ClosureParam params[] = { - CLOSURE_VECTOR_PARAM(MicrofacetGGXClosure<1>, m_N), - CLOSURE_FLOAT_PARAM(MicrofacetGGXClosure<1>, m_ag), - CLOSURE_FLOAT_PARAM(MicrofacetGGXClosure<1>, m_eta), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(MicrofacetGGXClosure<1>) - }; - return params; -} - -ClosureParam *bsdf_microfacet_beckmann_params() -{ - static ClosureParam params[] = { - CLOSURE_VECTOR_PARAM(MicrofacetBeckmannClosure<0>, m_N), - CLOSURE_FLOAT_PARAM(MicrofacetBeckmannClosure<0>, m_ab), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(MicrofacetBeckmannClosure<0>) - }; - return params; -} - -ClosureParam *bsdf_microfacet_beckmann_refraction_params() -{ - static ClosureParam params[] = { - CLOSURE_VECTOR_PARAM(MicrofacetBeckmannClosure<1>, m_N), - CLOSURE_FLOAT_PARAM(MicrofacetBeckmannClosure<1>, m_ab), - CLOSURE_FLOAT_PARAM(MicrofacetBeckmannClosure<1>, m_eta), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(MicrofacetBeckmannClosure<1>) - }; - return params; -} - -CLOSURE_PREPARE(bsdf_microfacet_ggx_prepare, MicrofacetGGXClosure<0>) -CLOSURE_PREPARE(bsdf_microfacet_ggx_refraction_prepare, MicrofacetGGXClosure<1>) -CLOSURE_PREPARE(bsdf_microfacet_beckmann_prepare, MicrofacetBeckmannClosure<0>) -CLOSURE_PREPARE(bsdf_microfacet_beckmann_refraction_prepare, MicrofacetBeckmannClosure<1>) - -CCL_NAMESPACE_END - diff --git a/intern/cycles/kernel/osl/bsdf_oren_nayar.cpp b/intern/cycles/kernel/osl/bsdf_oren_nayar.cpp deleted file mode 100644 index 2a00100c256..00000000000 --- a/intern/cycles/kernel/osl/bsdf_oren_nayar.cpp +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright 2011, Blender Foundation. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include "osl_closures.h" -#include "util_math.h" - -CCL_NAMESPACE_BEGIN - -using namespace OSL; - - -class OrenNayarClosure : public BSDFClosure { -public: - Vec3 m_N; - float m_sigma; - float m_a, m_b; - - OrenNayarClosure() : BSDFClosure(Labels::DIFFUSE) {} - - void setup() { - m_sigma = clamp(m_sigma, 0.0f, 1.0f); - - float div = 1.0f / (M_PI + ((3.0f * M_PI - 4.0f) / 6.0f) * m_sigma); - - m_a = 1.0f * div; - m_b = m_sigma * div; - } - - bool mergeable(const ClosurePrimitive *other) const { - const OrenNayarClosure *comp = static_cast(other); - return - m_N == comp->m_N && - m_sigma == comp->m_sigma && - BSDFClosure::mergeable(other); - } - - size_t memsize() const { - return sizeof(*this); - } - - const char *name() const { - return "oren_nayar"; - } - - void print_on(std::ostream& out) const { - out << name() << " ("; - out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), "; - out << m_sigma; - out << ")"; - } - - float albedo(const Vec3& omega_out) const { - return 1.0f; - } - - Color3 eval_reflect(const Vec3& omega_out, const Vec3& omega_in, float& pdf) const { - if (m_N.dot(omega_in) > 0.0f) { - pdf = float(0.5 * M_1_PI); - float is = get_intensity(m_N, omega_out, omega_in); - return Color3(is, is, is); - } - else { - pdf = 0.0f; - return Color3(0.0f, 0.0f, 0.0f); - } - } - - Color3 eval_transmit(const Vec3& omega_out, const Vec3& omega_in, float& pdf) const { - return Color3(0.0f, 0.0f, 0.0f); - } - - ustring sample( - const Vec3& Ng, - const Vec3& omega_out, const Vec3& domega_out_dx, const Vec3& domega_out_dy, - float randu, float randv, - Vec3& omega_in, Vec3& domega_in_dx, Vec3& domega_in_dy, - float& pdf, Color3& eval - ) const { - sample_uniform_hemisphere(m_N, omega_out, randu, randv, omega_in, pdf); - - if (Ng.dot(omega_in) > 0.0f) { - float is = get_intensity(m_N, omega_out, omega_in); - eval.setValue(is, is, is); - - // TODO: find a better approximation for the bounce - domega_in_dx = (2.0f * m_N.dot(domega_out_dx)) * m_N - domega_out_dx; - domega_in_dy = (2.0f * m_N.dot(domega_out_dy)) * m_N - domega_out_dy; - domega_in_dx *= 125.0f; - domega_in_dy *= 125.0f; - } - else { - pdf = 0.0f; - } - - return Labels::REFLECT; - } - -private: - float get_intensity(Vec3 const& n, Vec3 const& v, Vec3 const& l) const { - float nl = max(n.dot(l), 0.0f); - float nv = max(n.dot(v), 0.0f); - float t = l.dot(v) - nl * nv; - - if (t > 0.0f) { - t /= max(nl, nv) + 1e-8f; - } - return nl * (m_a + m_b * t); - } -}; - -ClosureParam *bsdf_oren_nayar_params() -{ - static ClosureParam params[] = { - CLOSURE_VECTOR_PARAM(OrenNayarClosure, m_N), - CLOSURE_FLOAT_PARAM(OrenNayarClosure, m_sigma), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(OrenNayarClosure) - }; - return params; -} - -CLOSURE_PREPARE(bsdf_oren_nayar_prepare, OrenNayarClosure) - - -CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/osl/bsdf_phong.cpp b/intern/cycles/kernel/osl/bsdf_phong.cpp deleted file mode 100644 index 1f430cc6f5d..00000000000 --- a/intern/cycles/kernel/osl/bsdf_phong.cpp +++ /dev/null @@ -1,287 +0,0 @@ -/* - * Adapted from Open Shading Language with this license: - * - * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. - * All Rights Reserved. - * - * Modifications Copyright 2012, Blender Foundation. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Sony Pictures Imageworks nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -#include -#include "osl_closures.h" -#include "util_math.h" - -CCL_NAMESPACE_BEGIN - -using namespace OSL; - -// vanilla phong - leaks energy at grazing angles -// see Global Illumination Compendium entry (66) -class PhongClosure : public BSDFClosure { -public: - Vec3 m_N; - float m_exponent; - PhongClosure() : BSDFClosure(Labels::GLOSSY) { } - - void setup() {}; - - bool mergeable (const ClosurePrimitive *other) const { - const PhongClosure *comp = (const PhongClosure *)other; - return m_N == comp->m_N && m_exponent == comp->m_exponent && - BSDFClosure::mergeable(other); - } - - size_t memsize () const { return sizeof(*this); } - - const char *name () const { return "phong"; } - - void print_on (std::ostream &out) const { - out << name() << " (("; - out << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), "; - out << m_exponent << ")"; - } - - float albedo (const Vec3 &omega_out) const - { - return 1.0f; - } - - Color3 eval_reflect (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - float cosNI = m_N.dot(omega_in); - float cosNO = m_N.dot(omega_out); - if (cosNI > 0 && cosNO > 0) { - // reflect the view vector - Vec3 R = (2 * cosNO) * m_N - omega_out; - float cosRI = R.dot(omega_in); - if (cosRI > 0) { - float common = 0.5f * (float) M_1_PI * powf(cosRI, m_exponent); - float out = cosNI * (m_exponent + 2) * common; - pdf = (m_exponent + 1) * common; - return Color3 (out, out, out); - } - } - return Color3 (0, 0, 0); - } - - Color3 eval_transmit (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - return Color3 (0, 0, 0); - } - - ustring sample (const Vec3 &Ng, - const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, - float randu, float randv, - Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, - float &pdf, Color3 &eval) const - { - float cosNO = m_N.dot(omega_out); - if (cosNO > 0) { - // reflect the view vector - Vec3 R = (2 * cosNO) * m_N - omega_out; - domega_in_dx = (2 * m_N.dot(domega_out_dx)) * m_N - domega_out_dx; - domega_in_dy = (2 * m_N.dot(domega_out_dy)) * m_N - domega_out_dy; - Vec3 T, B; - make_orthonormals (R, T, B); - float phi = 2 * (float) M_PI * randu; - float cosTheta = powf(randv, 1 / (m_exponent + 1)); - float sinTheta2 = 1 - cosTheta * cosTheta; - float sinTheta = sinTheta2 > 0 ? sqrtf(sinTheta2) : 0; - omega_in = (cosf(phi) * sinTheta) * T + - (sinf(phi) * sinTheta) * B + - ( cosTheta) * R; - if (Ng.dot(omega_in) > 0) - { - // common terms for pdf and eval - float cosNI = m_N.dot(omega_in); - // make sure the direction we chose is still in the right hemisphere - if (cosNI > 0) - { - float common = 0.5f * (float) M_1_PI * powf(cosTheta, m_exponent); - pdf = (m_exponent + 1) * common; - float out = cosNI * (m_exponent + 2) * common; - eval.setValue(out, out, out); - // Since there is some blur to this reflection, make the - // derivatives a bit bigger. In theory this varies with the - // exponent but the exact relationship is complex and - // requires more ops than are practical. - domega_in_dx *= 10; - domega_in_dy *= 10; - } - } - } - return Labels::REFLECT; - } -}; - - -class PhongRampClosure : public BSDFClosure { -public: - static const int MAXCOLORS = 8; - Vec3 m_N; - float m_exponent; - Color3 m_colors[MAXCOLORS]; - PhongRampClosure() : BSDFClosure(Labels::GLOSSY) { } - - void setup() {}; - - bool mergeable (const ClosurePrimitive *other) const { - const PhongRampClosure *comp = (const PhongRampClosure *)other; - if (! (m_N == comp->m_N && m_exponent == comp->m_exponent && - BSDFClosure::mergeable(other))) - return false; - for (int i = 0; i < MAXCOLORS; ++i) - if (m_colors[i] != comp->m_colors[i]) - return false; - return true; - } - - size_t memsize () const { return sizeof(*this); } - - const char *name () const { return "phong_ramp"; } - - void print_on (std::ostream &out) const { - out << name() << " (("; - out << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), "; - out << m_exponent << ")"; - } - - Color3 get_color (float pos) const - { - float npos = pos * (float)(MAXCOLORS - 1); - int ipos = (int)npos; - if (ipos >= (MAXCOLORS - 1)) - return m_colors[MAXCOLORS - 1]; - float offset = npos - (float)ipos; - return m_colors[ipos] * (1.0f - offset) + m_colors[ipos+1] * offset; - } - - float albedo (const Vec3 &omega_out) const - { - return 1.0f; - } - - Color3 eval_reflect (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - float cosNI = m_N.dot(omega_in); - float cosNO = m_N.dot(omega_out); - if (cosNI > 0 && cosNO > 0) { - // reflect the view vector - Vec3 R = (2 * cosNO) * m_N - omega_out; - float cosRI = R.dot(omega_in); - if (cosRI > 0) { - float cosp = powf(cosRI, m_exponent); - float common = 0.5f * (float) M_1_PI * cosp; - float out = cosNI * (m_exponent + 2) * common; - pdf = (m_exponent + 1) * common; - return get_color(cosp) * out; - } - } - return Color3 (0, 0, 0); - } - - Color3 eval_transmit (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - return Color3 (0, 0, 0); - } - - ustring sample (const Vec3 &Ng, - const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, - float randu, float randv, - Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, - float &pdf, Color3 &eval) const - { - float cosNO = m_N.dot(omega_out); - if (cosNO > 0) { - // reflect the view vector - Vec3 R = (2 * cosNO) * m_N - omega_out; - domega_in_dx = (2 * m_N.dot(domega_out_dx)) * m_N - domega_out_dx; - domega_in_dy = (2 * m_N.dot(domega_out_dy)) * m_N - domega_out_dy; - Vec3 T, B; - make_orthonormals (R, T, B); - float phi = 2 * (float) M_PI * randu; - float cosTheta = powf(randv, 1 / (m_exponent + 1)); - float sinTheta2 = 1 - cosTheta * cosTheta; - float sinTheta = sinTheta2 > 0 ? sqrtf(sinTheta2) : 0; - omega_in = (cosf(phi) * sinTheta) * T + - (sinf(phi) * sinTheta) * B + - ( cosTheta) * R; - if (Ng.dot(omega_in) > 0) - { - // common terms for pdf and eval - float cosNI = m_N.dot(omega_in); - // make sure the direction we chose is still in the right hemisphere - if (cosNI > 0) - { - float cosp = powf(cosTheta, m_exponent); - float common = 0.5f * (float) M_1_PI * cosp; - pdf = (m_exponent + 1) * common; - float out = cosNI * (m_exponent + 2) * common; - eval = get_color(cosp) * out; - // Since there is some blur to this reflection, make the - // derivatives a bit bigger. In theory this varies with the - // exponent but the exact relationship is complex and - // requires more ops than are practical. - domega_in_dx *= 10; - domega_in_dy *= 10; - } - } - } - return Labels::REFLECT; - } -}; - - - -ClosureParam *bsdf_phong_params() -{ - static ClosureParam params[] = { - CLOSURE_VECTOR_PARAM(PhongClosure, m_N), - CLOSURE_FLOAT_PARAM (PhongClosure, m_exponent), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(PhongClosure) - }; - return params; -} - -ClosureParam *bsdf_phong_ramp_params() -{ - static ClosureParam params[] = { - CLOSURE_VECTOR_PARAM (PhongRampClosure, m_N), - CLOSURE_FLOAT_PARAM (PhongRampClosure, m_exponent), - CLOSURE_COLOR_ARRAY_PARAM(PhongRampClosure, m_colors, PhongRampClosure::MAXCOLORS), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM (PhongRampClosure) - }; - return params; -} - -CLOSURE_PREPARE(bsdf_phong_prepare, PhongClosure) -CLOSURE_PREPARE(bsdf_phong_ramp_prepare, PhongRampClosure) - -CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/osl/bsdf_reflection.cpp b/intern/cycles/kernel/osl/bsdf_reflection.cpp deleted file mode 100644 index 1b85ec146d3..00000000000 --- a/intern/cycles/kernel/osl/bsdf_reflection.cpp +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Adapted from Open Shading Language with this license: - * - * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. - * All Rights Reserved. - * - * Modifications Copyright 2011, Blender Foundation. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Sony Pictures Imageworks nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -#include - -#include "osl_closures.h" - -CCL_NAMESPACE_BEGIN - -using namespace OSL; - -class ReflectionClosure : public BSDFClosure { -public: - Vec3 m_N; // shading normal - ReflectionClosure() : BSDFClosure(Labels::SINGULAR) {} - - void setup() {}; - - bool mergeable(const ClosurePrimitive *other) const { - const ReflectionClosure *comp = (const ReflectionClosure *)other; - return m_N == comp->m_N && BSDFClosure::mergeable(other); - } - - size_t memsize() const { return sizeof(*this); } - - const char *name() const { return "reflection"; } - - void print_on(std::ostream &out) const { - out << name() << " ("; - out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "))"; - } - - float albedo(const Vec3 &omega_out) const - { - return 1.0f; - } - - Color3 eval_reflect(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - return Color3(0, 0, 0); - } - - Color3 eval_transmit(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - return Color3(0, 0, 0); - } - - ustring sample(const Vec3 &Ng, - const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, - float randu, float randv, - Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, - float &pdf, Color3 &eval) const - { - // only one direction is possible - float cosNO = m_N.dot(omega_out); - if (cosNO > 0) { - omega_in = (2 * cosNO) * m_N - omega_out; - if (Ng.dot(omega_in) > 0) { - domega_in_dx = 2 * m_N.dot(domega_out_dx) * m_N - domega_out_dx; - domega_in_dy = 2 * m_N.dot(domega_out_dy) * m_N - domega_out_dy; - pdf = 1; - eval.setValue(1, 1, 1); - } - } - return Labels::REFLECT; - } -}; - -ClosureParam *bsdf_reflection_params() -{ - static ClosureParam params[] = { - CLOSURE_VECTOR_PARAM(ReflectionClosure, m_N), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(ReflectionClosure) - }; - return params; -} - -CLOSURE_PREPARE(bsdf_reflection_prepare, ReflectionClosure) - -CCL_NAMESPACE_END - diff --git a/intern/cycles/kernel/osl/bsdf_refraction.cpp b/intern/cycles/kernel/osl/bsdf_refraction.cpp deleted file mode 100644 index 76ee53f7929..00000000000 --- a/intern/cycles/kernel/osl/bsdf_refraction.cpp +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Adapted from Open Shading Language with this license: - * - * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. - * All Rights Reserved. - * - * Modifications Copyright 2011, Blender Foundation. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Sony Pictures Imageworks nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -#include - -#include "osl_closures.h" - -CCL_NAMESPACE_BEGIN - -using namespace OSL; - -class RefractionClosure : public BSDFClosure { -public: - Vec3 m_N; // shading normal - float m_eta; // ratio of indices of refraction (inside / outside) - RefractionClosure() : BSDFClosure(Labels::SINGULAR, Back) {} - - void setup() {} - - bool mergeable(const ClosurePrimitive *other) const { - const RefractionClosure *comp = (const RefractionClosure *)other; - return m_N == comp->m_N && m_eta == comp->m_eta && - BSDFClosure::mergeable(other); - } - - size_t memsize() const { return sizeof(*this); } - - const char *name() const { return "refraction"; } - - void print_on(std::ostream &out) const { - out << name() << " ("; - out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), "; - out << m_eta; - out << ")"; - } - - Color3 eval_reflect(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - return Color3(0, 0, 0); - } - - Color3 eval_transmit(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - return Color3(0, 0, 0); - } - - float albedo(const Vec3 &omega_out) const - { - return 1.0f; - } - - ustring sample(const Vec3 &Ng, - const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, - float randu, float randv, - Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, - float &pdf, Color3 &eval) const - { - Vec3 R, dRdx, dRdy; - Vec3 T, dTdx, dTdy; - bool inside; - - fresnel_dielectric(m_eta, m_N, - omega_out, domega_out_dx, domega_out_dy, - R, dRdx, dRdy, - T, dTdx, dTdy, - inside); - - if (!inside) { - pdf = 1; - eval.setValue(1.0f, 1.0f, 1.0f); - omega_in = T; - domega_in_dx = dTdx; - domega_in_dy = dTdy; - } - - return Labels::TRANSMIT; - } -}; - -ClosureParam *bsdf_refraction_params() -{ - static ClosureParam params[] = { - CLOSURE_VECTOR_PARAM(RefractionClosure, m_N), - CLOSURE_FLOAT_PARAM(RefractionClosure, m_eta), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(RefractionClosure) - }; - return params; -} - -CLOSURE_PREPARE(bsdf_refraction_prepare, RefractionClosure) - -CCL_NAMESPACE_END - diff --git a/intern/cycles/kernel/osl/bsdf_transparent.cpp b/intern/cycles/kernel/osl/bsdf_transparent.cpp deleted file mode 100644 index 29cef8e192f..00000000000 --- a/intern/cycles/kernel/osl/bsdf_transparent.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Adapted from Open Shading Language with this license: - * - * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. - * All Rights Reserved. - * - * Modifications Copyright 2011, Blender Foundation. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Sony Pictures Imageworks nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -#include - -#include "osl_closures.h" - -CCL_NAMESPACE_BEGIN - -using namespace OSL; - -class TransparentClosure : public BSDFClosure { -public: - TransparentClosure() : BSDFClosure(Labels::STRAIGHT, Back) {} - - void setup() {} - - size_t memsize() const { return sizeof(*this); } - - const char *name() const { return "transparent"; } - - void print_on(std::ostream &out) const { - out << name() << " ()"; - } - - float albedo(const Vec3 &omega_out) const - { - return 1.0f; - } - - Color3 eval_reflect(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - return Color3(0, 0, 0); - } - - Color3 eval_transmit(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - return Color3(0, 0, 0); - } - - ustring sample(const Vec3 &Ng, - const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, - float randu, float randv, - Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, - float &pdf, Color3 &eval) const - { - // only one direction is possible - omega_in = -omega_out; - domega_in_dx = -domega_out_dx; - domega_in_dy = -domega_out_dy; - pdf = 1; - eval.setValue(1, 1, 1); - return Labels::TRANSMIT; - } -}; - - - -ClosureParam *bsdf_transparent_params() -{ - static ClosureParam params[] = { - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(TransparentClosure) - }; - return params; -} - -CLOSURE_PREPARE(bsdf_transparent_prepare, TransparentClosure) - -CCL_NAMESPACE_END - diff --git a/intern/cycles/kernel/osl/bsdf_ward.cpp b/intern/cycles/kernel/osl/bsdf_ward.cpp deleted file mode 100644 index 9d8d2fc4b76..00000000000 --- a/intern/cycles/kernel/osl/bsdf_ward.cpp +++ /dev/null @@ -1,230 +0,0 @@ -/* - * Adapted from Open Shading Language with this license: - * - * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. - * All Rights Reserved. - * - * Modifications Copyright 2011, Blender Foundation. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Sony Pictures Imageworks nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -#include - -#include "osl_closures.h" - -#include "util_math.h" - -CCL_NAMESPACE_BEGIN - -using namespace OSL; - -// anisotropic ward - leaks energy at grazing angles -// see http://www.graphics.cornell.edu/~bjw/wardnotes.pdf -class WardClosure : public BSDFClosure { -public: - Vec3 m_N; - Vec3 m_T; - float m_ax, m_ay; - WardClosure() : BSDFClosure(Labels::GLOSSY) {} - - void setup() - { - m_ax = clamp(m_ax, 1e-5f, 1.0f); - m_ay = clamp(m_ay, 1e-5f, 1.0f); - } - - bool mergeable(const ClosurePrimitive *other) const { - const WardClosure *comp = (const WardClosure *)other; - return m_N == comp->m_N && m_T == comp->m_T && - m_ax == comp->m_ax && m_ay == comp->m_ay && - BSDFClosure::mergeable(other); - } - - size_t memsize() const { return sizeof(*this); } - - const char *name() const { return "ward"; } - - void print_on(std::ostream &out) const { - out << name() << " (("; - out << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), ("; - out << m_T[0] << ", " << m_T[1] << ", " << m_T[2] << "), "; - out << m_ax << ", " << m_ay << ")"; - } - - float albedo(const Vec3 &omega_out) const - { - return 1.0f; - } - - Color3 eval_reflect(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - float cosNO = m_N.dot(omega_out); - float cosNI = m_N.dot(omega_in); - if (cosNI > 0 && cosNO > 0) { - // get half vector and get x,y basis on the surface for anisotropy - Vec3 H = omega_in + omega_out; - H.normalize(); // normalize needed for pdf - Vec3 X, Y; - make_orthonormals(m_N, m_T, X, Y); - // eq. 4 - float dotx = H.dot(X) / m_ax; - float doty = H.dot(Y) / m_ay; - float dotn = H.dot(m_N); - float exp_arg = (dotx * dotx + doty * doty) / (dotn * dotn); - float denom = (4 * (float) M_PI * m_ax * m_ay * sqrtf(cosNO * cosNI)); - float exp_val = expf(-exp_arg); - float out = cosNI * exp_val / denom; - float oh = H.dot(omega_out); - denom = 4 * (float) M_PI * m_ax * m_ay * oh * dotn * dotn * dotn; - pdf = exp_val / denom; - return Color3(out, out, out); - } - return Color3(0, 0, 0); - } - - Color3 eval_transmit(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const - { - return Color3(0, 0, 0); - } - - ustring sample(const Vec3 &Ng, - const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, - float randu, float randv, - Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, - float &pdf, Color3 &eval) const - { - float cosNO = m_N.dot(omega_out); - if (cosNO > 0) { - // get x,y basis on the surface for anisotropy - Vec3 X, Y; - make_orthonormals(m_N, m_T, X, Y); - // generate random angles for the half vector - // eq. 7 (taking care around discontinuities to keep - // output angle in the right quadrant) - // we take advantage of cos(atan(x)) == 1/sqrt(1+x^2) - // and sin(atan(x)) == x/sqrt(1+x^2) - float alphaRatio = m_ay / m_ax; - float cosPhi, sinPhi; - if (randu < 0.25f) { - float val = 4 * randu; - float tanPhi = alphaRatio * tanf((float) M_PI_2 * val); - cosPhi = 1 / sqrtf(1 + tanPhi * tanPhi); - sinPhi = tanPhi * cosPhi; - } - else if (randu < 0.5) { - float val = 1 - 4 * (0.5f - randu); - float tanPhi = alphaRatio * tanf((float) M_PI_2 * val); - // phi = (float) M_PI - phi; - cosPhi = -1 / sqrtf(1 + tanPhi * tanPhi); - sinPhi = -tanPhi * cosPhi; - } - else if (randu < 0.75f) { - float val = 4 * (randu - 0.5f); - float tanPhi = alphaRatio * tanf((float) M_PI_2 * val); - //phi = (float) M_PI + phi; - cosPhi = -1 / sqrtf(1 + tanPhi * tanPhi); - sinPhi = tanPhi * cosPhi; - } - else { - float val = 1 - 4 * (1 - randu); - float tanPhi = alphaRatio * tanf((float) M_PI_2 * val); - // phi = 2 * (float) M_PI - phi; - cosPhi = 1 / sqrtf(1 + tanPhi * tanPhi); - sinPhi = -tanPhi * cosPhi; - } - // eq. 6 - // we take advantage of cos(atan(x)) == 1/sqrt(1+x^2) - // and sin(atan(x)) == x/sqrt(1+x^2) - float thetaDenom = (cosPhi * cosPhi) / (m_ax * m_ax) + (sinPhi * sinPhi) / (m_ay * m_ay); - float tanTheta2 = -logf(1 - randv) / thetaDenom; - float cosTheta = 1 / sqrtf(1 + tanTheta2); - float sinTheta = cosTheta * sqrtf(tanTheta2); - - Vec3 h; // already normalized becaused expressed from spherical coordinates - h.x = sinTheta * cosPhi; - h.y = sinTheta * sinPhi; - h.z = cosTheta; - // compute terms that are easier in local space - float dotx = h.x / m_ax; - float doty = h.y / m_ay; - float dotn = h.z; - // transform to world space - h = h.x * X + h.y * Y + h.z * m_N; - // generate the final sample - float oh = h.dot(omega_out); - omega_in.x = 2 * oh * h.x - omega_out.x; - omega_in.y = 2 * oh * h.y - omega_out.y; - omega_in.z = 2 * oh * h.z - omega_out.z; - if (Ng.dot(omega_in) > 0) { - float cosNI = m_N.dot(omega_in); - if (cosNI > 0) { - // eq. 9 - float exp_arg = (dotx * dotx + doty * doty) / (dotn * dotn); - float denom = 4 * (float) M_PI * m_ax * m_ay * oh * dotn * dotn * dotn; - pdf = expf(-exp_arg) / denom; - // compiler will reuse expressions already computed - denom = (4 * (float) M_PI * m_ax * m_ay * sqrtf(cosNO * cosNI)); - float power = cosNI * expf(-exp_arg) / denom; - eval.setValue(power, power, power); - domega_in_dx = (2 * m_N.dot(domega_out_dx)) * m_N - domega_out_dx; - domega_in_dy = (2 * m_N.dot(domega_out_dy)) * m_N - domega_out_dy; - - /* disabled for now - gives texture filtering problems */ -#if 0 - // Since there is some blur to this reflection, make the - // derivatives a bit bigger. In theory this varies with the - // roughness but the exact relationship is complex and - // requires more ops than are practical. - domega_in_dx *= 10; - domega_in_dy *= 10; -#endif - } - } - } - return Labels::REFLECT; - } -}; - - - -ClosureParam *bsdf_ward_params() -{ - static ClosureParam params[] = { - CLOSURE_VECTOR_PARAM(WardClosure, m_N), - CLOSURE_VECTOR_PARAM(WardClosure, m_T), - CLOSURE_FLOAT_PARAM(WardClosure, m_ax), - CLOSURE_FLOAT_PARAM(WardClosure, m_ay), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(WardClosure) - }; - return params; -} - -CLOSURE_PREPARE(bsdf_ward_prepare, WardClosure) - -CCL_NAMESPACE_END - diff --git a/intern/cycles/kernel/osl/bsdf_westin.cpp b/intern/cycles/kernel/osl/bsdf_westin.cpp deleted file mode 100644 index 6716376ad3e..00000000000 --- a/intern/cycles/kernel/osl/bsdf_westin.cpp +++ /dev/null @@ -1,251 +0,0 @@ -/* - * Adapted from Open Shading Language with this license: - * - * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. - * All Rights Reserved. - * - * Modifications Copyright 2011, Blender Foundation. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Sony Pictures Imageworks nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -#include - -#include "osl_closures.h" - -#include "util_math.h" - -CCL_NAMESPACE_BEGIN - -using namespace OSL; - -class WestinBackscatterClosure : public BSDFClosure { -public: - Vec3 m_N; - float m_roughness; - float m_invroughness; - WestinBackscatterClosure() : BSDFClosure(Labels::GLOSSY) {} - - void setup() - { - m_roughness = clamp(m_roughness, 1e-5f, 1.0f); - m_invroughness = m_roughness > 0 ? 1 / m_roughness : 0; - } - - bool mergeable(const ClosurePrimitive *other) const { - const WestinBackscatterClosure *comp = (const WestinBackscatterClosure *)other; - return m_N == comp->m_N && m_roughness == comp->m_roughness && - BSDFClosure::mergeable(other); - } - - size_t memsize() const { return sizeof(*this); } - - const char *name() const { return "westin_backscatter"; } - - void print_on(std::ostream &out) const - { - out << name() << " ("; - out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), "; - out << m_roughness; - out << ")"; - } - - float albedo(const Vec3 &omega_out) const - { - return 1.0f; - } - - Color3 eval_reflect(const Vec3 &omega_out, const Vec3 &omega_in, float &pdf) const - { - // pdf is implicitly 0 (no indirect sampling) - float cosNO = m_N.dot(omega_out); - float cosNI = m_N.dot(omega_in); - if (cosNO > 0 && cosNI > 0) { - float cosine = omega_out.dot(omega_in); - pdf = cosine > 0 ? (m_invroughness + 1) * powf(cosine, m_invroughness) : 0; - pdf *= 0.5f * float(M_1_PI); - return Color3(pdf, pdf, pdf); - } - return Color3(0, 0, 0); - } - - Color3 eval_transmit(const Vec3 &omega_out, const Vec3 &omega_in, float &pdf) const - { - return Color3(0, 0, 0); - } - - ustring sample(const Vec3 &Ng, - const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, - float randu, float randv, - Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, - float &pdf, Color3 &eval) const - { - float cosNO = m_N.dot(omega_out); - if (cosNO > 0) { - domega_in_dx = domega_out_dx; - domega_in_dy = domega_out_dy; - Vec3 T, B; - make_orthonormals(omega_out, T, B); - float phi = 2 * (float) M_PI * randu; - float cosTheta = powf(randv, 1 / (m_invroughness + 1)); - float sinTheta2 = 1 - cosTheta * cosTheta; - float sinTheta = sinTheta2 > 0 ? sqrtf(sinTheta2) : 0; - omega_in = (cosf(phi) * sinTheta) * T + - (sinf(phi) * sinTheta) * B + - (cosTheta) * omega_out; - if (Ng.dot(omega_in) > 0) - { - // common terms for pdf and eval - float cosNI = m_N.dot(omega_in); - // make sure the direction we chose is still in the right hemisphere - if (cosNI > 0) - { - pdf = 0.5f * (float) M_1_PI * powf(cosTheta, m_invroughness); - pdf = (m_invroughness + 1) * pdf; - eval.setValue(pdf, pdf, pdf); - // Since there is some blur to this reflection, make the - // derivatives a bit bigger. In theory this varies with the - // exponent but the exact relationship is complex and - // requires more ops than are practical. - domega_in_dx *= 10; - domega_in_dy *= 10; - } - } - } - return Labels::REFLECT; - } - -}; - - -class WestinSheenClosure : public BSDFClosure { -public: - Vec3 m_N; - float m_edginess; -// float m_normalization; - WestinSheenClosure() : BSDFClosure(Labels::DIFFUSE) {} - - void setup() {}; - - bool mergeable(const ClosurePrimitive *other) const { - const WestinSheenClosure *comp = (const WestinSheenClosure *)other; - return m_N == comp->m_N && m_edginess == comp->m_edginess && - BSDFClosure::mergeable(other); - } - - size_t memsize() const { return sizeof(*this); } - - const char *name() const { return "westin_sheen"; } - - void print_on(std::ostream &out) const - { - out << name() << " ("; - out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), "; - out << m_edginess; - out << ")"; - } - - float albedo(const Vec3 &omega_out) const - { - return 1.0f; - } - - Color3 eval_reflect(const Vec3 &omega_out, const Vec3 &omega_in, float &pdf) const - { - // pdf is implicitly 0 (no indirect sampling) - float cosNO = m_N.dot(omega_out); - float cosNI = m_N.dot(omega_in); - if (cosNO > 0 && cosNI > 0) { - float sinNO2 = 1 - cosNO * cosNO; - pdf = cosNI * float(M_1_PI); - float westin = sinNO2 > 0 ? powf(sinNO2, 0.5f * m_edginess) * pdf : 0; - return Color3(westin, westin, westin); - } - return Color3(0, 0, 0); - } - - Color3 eval_transmit(const Vec3 &omega_out, const Vec3 &omega_in, float &pdf) const - { - return Color3(0, 0, 0); - } - - ustring sample(const Vec3 &Ng, - const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy, - float randu, float randv, - Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy, - float &pdf, Color3 &eval) const - { - // we are viewing the surface from the right side - send a ray out with cosine - // distribution over the hemisphere - sample_cos_hemisphere(m_N, omega_out, randu, randv, omega_in, pdf); - if (Ng.dot(omega_in) > 0) { - // TODO: account for sheen when sampling - float cosNO = m_N.dot(omega_out); - float sinNO2 = 1 - cosNO * cosNO; - float westin = sinNO2 > 0 ? powf(sinNO2, 0.5f * m_edginess) * pdf : 0; - eval.setValue(westin, westin, westin); - // TODO: find a better approximation for the diffuse bounce - domega_in_dx = (2 * m_N.dot(domega_out_dx)) * m_N - domega_out_dx; - domega_in_dy = (2 * m_N.dot(domega_out_dy)) * m_N - domega_out_dy; - domega_in_dx *= 125; - domega_in_dy *= 125; - } - else { - pdf = 0; - } - return Labels::REFLECT; - } -}; - - - -ClosureParam *bsdf_westin_backscatter_params() -{ - static ClosureParam params[] = { - CLOSURE_VECTOR_PARAM(WestinBackscatterClosure, m_N), - CLOSURE_FLOAT_PARAM(WestinBackscatterClosure, m_roughness), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(WestinBackscatterClosure) - }; - return params; -} - -ClosureParam *bsdf_westin_sheen_params() -{ - static ClosureParam params[] = { - CLOSURE_VECTOR_PARAM(WestinSheenClosure, m_N), - CLOSURE_FLOAT_PARAM(WestinSheenClosure, m_edginess), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(WestinSheenClosure) - }; - return params; -} - -CLOSURE_PREPARE(bsdf_westin_backscatter_prepare, WestinBackscatterClosure) -CLOSURE_PREPARE(bsdf_westin_sheen_prepare, WestinSheenClosure) - -CCL_NAMESPACE_END - diff --git a/intern/cycles/kernel/osl/bssrdf.cpp b/intern/cycles/kernel/osl/bssrdf.cpp deleted file mode 100644 index 889e8a54796..00000000000 --- a/intern/cycles/kernel/osl/bssrdf.cpp +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Adapted from Open Shading Language with this license: - * - * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. - * All Rights Reserved. - * - * Modifications Copyright 2011, Blender Foundation. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Sony Pictures Imageworks nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -#include - -#include "osl_closures.h" - -CCL_NAMESPACE_BEGIN - -using namespace OSL; - -class BSSRDFCubicClosure : public BSSRDFClosure { -public: - Color3 m_radius; - Color3 m_scale; - float m_max_radius; - - template - static inline T pow3(const T &x) { return x * x * x; } - - template - static inline T pow5(const T &x) { T x2 = x * x; return x2 * x2 * x; } - - BSSRDFCubicClosure() {} - - void setup() - { - // pre-compute some terms - m_max_radius = 0; - for (int i = 0; i < 3; i++) { - m_scale[i] = m_radius[i] > 0 ? 4 / pow5(m_radius[i]) : 0; - m_max_radius = std::max(m_max_radius, m_radius[i]); - } - } - - bool mergeable(const ClosurePrimitive *other) const { - const BSSRDFCubicClosure *comp = (const BSSRDFCubicClosure *)other; - return m_radius == comp->m_radius && BSSRDFClosure::mergeable(other); - } - - size_t memsize() const { return sizeof(*this); } - - const char *name() const { return "bssrdf_cubic"; } - - void print_on(std::ostream &out) const - { - out << name() << " ((" << m_radius[0] << ", " << m_radius[1] << ", " << m_radius[2] << "), (" - << m_scale[0] << ", " << m_scale[1] << ", " << m_scale[2] << "))"; - } - - Color3 eval(float r) const - { - return Color3((r < m_radius.x) ? pow3(m_radius.x - r) * m_scale.x : 0, - (r < m_radius.y) ? pow3(m_radius.y - r) * m_scale.y : 0, - (r < m_radius.z) ? pow3(m_radius.z - r) * m_scale.z : 0); - } - - float max_radius() const - { - return m_max_radius; - } -}; - - - -ClosureParam *closure_bssrdf_cubic_params() -{ - static ClosureParam params[] = { - CLOSURE_COLOR_PARAM(BSSRDFCubicClosure, m_radius), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(BSSRDFCubicClosure) - }; - return params; -} - -CLOSURE_PREPARE(closure_bssrdf_cubic_prepare, BSSRDFCubicClosure) - -CCL_NAMESPACE_END - diff --git a/intern/cycles/kernel/osl/debug.cpp b/intern/cycles/kernel/osl/debug.cpp deleted file mode 100644 index ee5fb30371a..00000000000 --- a/intern/cycles/kernel/osl/debug.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Adapted from Open Shading Language with this license: - * - * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. - * All Rights Reserved. - * - * Modifications Copyright 2011, Blender Foundation. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Sony Pictures Imageworks nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -#include - -#include "osl_closures.h" - -CCL_NAMESPACE_BEGIN - -using namespace OSL; - -/// Debug closure -/// -/// This is going to be used for mask AOV's and similar -/// purposes. A tag (string) is always associated with -/// this closure, that "selects: the channel where the -/// weight should be sent. - -class DebugClosure : public ClosurePrimitive { -public: - ustring m_tag; - - DebugClosure () : ClosurePrimitive(Debug) {} - - bool mergeable(const ClosurePrimitive *other) const { - const DebugClosure *comp = (const DebugClosure *)other; - return m_tag == comp->m_tag && - ClosurePrimitive::mergeable(other); - } - - size_t memsize() const { return sizeof(*this); } - - const char *name() const { return "debug"; } - - void print_on(std::ostream &out) const { - out << name() << " (\"" << m_tag.c_str() << "\")"; - } - -}; - -ClosureParam *closure_debug_params() -{ - static ClosureParam params[] = { - CLOSURE_STRING_PARAM(DebugClosure, m_tag), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(DebugClosure) - }; - return params; -} - -CLOSURE_PREPARE(closure_debug_prepare, DebugClosure) - -CCL_NAMESPACE_END - diff --git a/intern/cycles/kernel/osl/emissive.cpp b/intern/cycles/kernel/osl/emissive.cpp index 3ee57cbe6b6..37e3e37c00a 100644 --- a/intern/cycles/kernel/osl/emissive.cpp +++ b/intern/cycles/kernel/osl/emissive.cpp @@ -36,6 +36,9 @@ #include "osl_closures.h" +#include "kernel_types.h" +#include "closure/emissive.h" + CCL_NAMESPACE_BEGIN using namespace OSL; @@ -52,51 +55,34 @@ public: GenericEmissiveClosure() { } void setup() {} - size_t memsize() const { return sizeof(*this); } - const char *name() const { return "emission"; } - void print_on(std::ostream &out) const { + void print_on(std::ostream &out) const + { out << name() << "()"; } Color3 eval(const Vec3 &Ng, const Vec3 &omega_out) const { - float cosNO = fabsf(Ng.dot(omega_out)); - float res = cosNO > 0 ? 1.0f : 0.0f; - return Color3(res, res, res); + float3 result = emissive_eval(TO_FLOAT3(Ng), TO_FLOAT3(omega_out)); + return TO_COLOR3(result); } void sample(const Vec3 &Ng, float randu, float randv, Vec3 &omega_out, float &pdf) const { - // We don't do anything sophisticated here for the step - // We just sample the whole cone uniformly to the cosine - Vec3 T, B; - make_orthonormals(Ng, T, B); - float phi = 2 * (float) M_PI * randu; - float cosTheta = sqrtf(1.0f - 1.0f * randv); - float sinTheta = sqrtf(1.0f - cosTheta * cosTheta); - omega_out = (cosf(phi) * sinTheta) * T + - (sinf(phi) * sinTheta) * B + - cosTheta * Ng; - pdf = 1.0f / float(M_PI); + float3 omega_out_; + emissive_sample(TO_FLOAT3(Ng), randu, randv, &omega_out_, &pdf); + omega_out = TO_VEC3(omega_out_); } - /// Return the probability distribution function in the direction omega_out, - /// given the parameters and the light's surface normal. This MUST match - /// the PDF computed by sample(). - float pdf(const Vec3 &Ng, - const Vec3 &omega_out) const + float pdf(const Vec3 &Ng, const Vec3 &omega_out) const { - float cosNO = Ng.dot(omega_out); - return cosNO > 0 ? 1.0f : 0.0f; + return emissive_pdf(TO_FLOAT3(Ng), TO_FLOAT3(omega_out)); } }; - - ClosureParam *closure_emission_params() { static ClosureParam params[] = { diff --git a/intern/cycles/kernel/osl/osl_closures.cpp b/intern/cycles/kernel/osl/osl_closures.cpp index 9e99d4d2480..73e96643df7 100644 --- a/intern/cycles/kernel/osl/osl_closures.cpp +++ b/intern/cycles/kernel/osl/osl_closures.cpp @@ -37,10 +37,100 @@ #include "osl_shader.h" #include "util_debug.h" +#include "util_math.h" #include "util_param.h" +#include "kernel_types.h" +#include "kernel_montecarlo.h" + +#include "closure/bsdf.h" +#include "closure/bsdf_ashikhmin_velvet.h" +#include "closure/bsdf_diffuse.h" +#include "closure/bsdf_microfacet.h" +#include "closure/bsdf_oren_nayar.h" +#include "closure/bsdf_reflection.h" +#include "closure/bsdf_refraction.h" +#include "closure/bsdf_transparent.h" +#include "closure/bsdf_ward.h" +#include "closure/bsdf_westin.h" + CCL_NAMESPACE_BEGIN +using namespace OSL; + +/* BSDF class definitions */ + +BSDF_CLOSURE_CLASS_BEGIN(Diffuse, diffuse, diffuse, LABEL_DIFFUSE) + CLOSURE_VECTOR_PARAM(DiffuseClosure, N), +BSDF_CLOSURE_CLASS_END(Diffuse, diffuse) + +BSDF_CLOSURE_CLASS_BEGIN(Translucent, translucent, translucent, LABEL_DIFFUSE) + CLOSURE_VECTOR_PARAM(TranslucentClosure, N), +BSDF_CLOSURE_CLASS_END(Translucent, translucent) + +BSDF_CLOSURE_CLASS_BEGIN(OrenNayar, oren_nayar, oren_nayar, LABEL_DIFFUSE) + CLOSURE_VECTOR_PARAM(OrenNayarClosure, N), + CLOSURE_FLOAT_PARAM(OrenNayarClosure, sc.data0), +BSDF_CLOSURE_CLASS_END(OrenNayar, oren_nayar) + +BSDF_CLOSURE_CLASS_BEGIN(Reflection, reflection, reflection, LABEL_SINGULAR) + CLOSURE_VECTOR_PARAM(ReflectionClosure, N), +BSDF_CLOSURE_CLASS_END(Reflection, reflection) + +BSDF_CLOSURE_CLASS_BEGIN(Refraction, refraction, refraction, LABEL_SINGULAR) + CLOSURE_VECTOR_PARAM(RefractionClosure, N), + CLOSURE_FLOAT_PARAM(RefractionClosure, sc.data0), +BSDF_CLOSURE_CLASS_END(Refraction, refraction) + +BSDF_CLOSURE_CLASS_BEGIN(WestinBackscatter, westin_backscatter, westin_backscatter, LABEL_GLOSSY) + CLOSURE_VECTOR_PARAM(WestinBackscatterClosure, N), + CLOSURE_FLOAT_PARAM(WestinBackscatterClosure, sc.data0), +BSDF_CLOSURE_CLASS_END(WestinBackscatter, westin_backscatter) + +BSDF_CLOSURE_CLASS_BEGIN(WestinSheen, westin_sheen, westin_sheen, LABEL_DIFFUSE) + CLOSURE_VECTOR_PARAM(WestinSheenClosure, N), + CLOSURE_FLOAT_PARAM(WestinSheenClosure, sc.data0), +BSDF_CLOSURE_CLASS_END(WestinSheen, westin_sheen) + +BSDF_CLOSURE_CLASS_BEGIN(Transparent, transparent, transparent, LABEL_SINGULAR) +BSDF_CLOSURE_CLASS_END(Transparent, transparent) + +BSDF_CLOSURE_CLASS_BEGIN(AshikhminVelvet, ashikhmin_velvet, ashikhmin_velvet, LABEL_DIFFUSE) + CLOSURE_VECTOR_PARAM(AshikhminVelvetClosure, N), + CLOSURE_FLOAT_PARAM(AshikhminVelvetClosure, sc.data0), +BSDF_CLOSURE_CLASS_END(AshikhminVelvet, ashikhmin_velvet) + +BSDF_CLOSURE_CLASS_BEGIN(Ward, ward, ward, LABEL_GLOSSY) + CLOSURE_VECTOR_PARAM(WardClosure, N), + CLOSURE_VECTOR_PARAM(WardClosure, T), + CLOSURE_FLOAT_PARAM(WardClosure, sc.data0), + CLOSURE_FLOAT_PARAM(WardClosure, sc.data1), +BSDF_CLOSURE_CLASS_END(Ward, ward) + +BSDF_CLOSURE_CLASS_BEGIN(MicrofacetGGX, microfacet_ggx, microfacet_ggx, LABEL_GLOSSY) + CLOSURE_VECTOR_PARAM(MicrofacetGGXClosure, N), + CLOSURE_FLOAT_PARAM(MicrofacetGGXClosure, sc.data0), +BSDF_CLOSURE_CLASS_END(MicrofacetGGX, microfacet_ggx) + +BSDF_CLOSURE_CLASS_BEGIN(MicrofacetBeckmann, microfacet_beckmann, microfacet_beckmann, LABEL_GLOSSY) + CLOSURE_VECTOR_PARAM(MicrofacetBeckmannClosure, N), + CLOSURE_FLOAT_PARAM(MicrofacetBeckmannClosure, sc.data0), +BSDF_CLOSURE_CLASS_END(MicrofacetBeckmann, microfacet_beckmann) + +BSDF_CLOSURE_CLASS_BEGIN(MicrofacetGGXRefraction, microfacet_ggx_refraction, microfacet_ggx, LABEL_GLOSSY) + CLOSURE_VECTOR_PARAM(MicrofacetGGXRefractionClosure, N), + CLOSURE_FLOAT_PARAM(MicrofacetGGXRefractionClosure, sc.data0), + CLOSURE_FLOAT_PARAM(MicrofacetGGXRefractionClosure, sc.data1), +BSDF_CLOSURE_CLASS_END(MicrofacetGGXRefraction, microfacet_ggx_refraction) + +BSDF_CLOSURE_CLASS_BEGIN(MicrofacetBeckmannRefraction, microfacet_beckmann_refraction, microfacet_beckmann, LABEL_GLOSSY) + CLOSURE_VECTOR_PARAM(MicrofacetBeckmannRefractionClosure, N), + CLOSURE_FLOAT_PARAM(MicrofacetBeckmannRefractionClosure, sc.data0), + CLOSURE_FLOAT_PARAM(MicrofacetBeckmannRefractionClosure, sc.data1), +BSDF_CLOSURE_CLASS_END(MicrofacetBeckmannRefraction, microfacet_beckmann_refraction) + +/* Registration */ + static void generic_closure_setup(OSL::RendererServices *, int id, void *data) { assert(data); @@ -64,28 +154,42 @@ static void register_closure(OSL::ShadingSystem *ss, const char *name, int id, O void OSLShader::register_closures(OSL::ShadingSystem *ss) { - register_closure(ss, "diffuse", OSL_CLOSURE_BSDF_DIFFUSE_ID, bsdf_diffuse_params(), bsdf_diffuse_prepare); - register_closure(ss, "oren_nayar", OSL_CLOSURE_BSDF_OREN_NAYAR_ID, bsdf_oren_nayar_params(), bsdf_oren_nayar_prepare); - register_closure(ss, "translucent", OSL_CLOSURE_BSDF_TRANSLUCENT_ID, bsdf_translucent_params(), bsdf_translucent_prepare); - register_closure(ss, "reflection", OSL_CLOSURE_BSDF_REFLECTION_ID, bsdf_reflection_params(), bsdf_reflection_prepare); - register_closure(ss, "refraction", OSL_CLOSURE_BSDF_REFRACTION_ID, bsdf_refraction_params(), bsdf_refraction_prepare); - register_closure(ss, "transparent", OSL_CLOSURE_BSDF_TRANSPARENT_ID, bsdf_transparent_params(), bsdf_transparent_prepare); - register_closure(ss, "microfacet_ggx", OSL_CLOSURE_BSDF_MICROFACET_GGX_ID, bsdf_microfacet_ggx_params(), bsdf_microfacet_ggx_prepare); - register_closure(ss, "microfacet_ggx_refraction", OSL_CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID, bsdf_microfacet_ggx_refraction_params(), bsdf_microfacet_ggx_refraction_prepare); - register_closure(ss, "microfacet_beckmann", OSL_CLOSURE_BSDF_MICROFACET_BECKMANN_ID, bsdf_microfacet_beckmann_params(), bsdf_microfacet_beckmann_prepare); - register_closure(ss, "microfacet_beckmann_refraction", OSL_CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID, bsdf_microfacet_beckmann_refraction_params(), bsdf_microfacet_beckmann_refraction_prepare); - register_closure(ss, "ward", OSL_CLOSURE_BSDF_WARD_ID, bsdf_ward_params(), bsdf_ward_prepare); - register_closure(ss, "phong", OSL_CLOSURE_BSDF_PHONG_ID, bsdf_phong_params(), bsdf_phong_prepare); - register_closure(ss, "phong_ramp", OSL_CLOSURE_BSDF_PHONG_RAMP_ID, bsdf_phong_ramp_params(), bsdf_phong_ramp_prepare); - register_closure(ss, "ashikhmin_velvet", OSL_CLOSURE_BSDF_ASHIKHMIN_VELVET_ID, bsdf_ashikhmin_velvet_params(), bsdf_ashikhmin_velvet_prepare); - register_closure(ss, "westin_backscatter", OSL_CLOSURE_BSDF_WESTIN_BACKSCATTER_ID, bsdf_westin_backscatter_params(), bsdf_westin_backscatter_prepare); - register_closure(ss, "westin_sheen", OSL_CLOSURE_BSDF_WESTIN_SHEEN_ID, bsdf_westin_sheen_params(), bsdf_westin_sheen_prepare); - register_closure(ss, "bssrdf_cubic", OSL_CLOSURE_BSSRDF_CUBIC_ID, closure_bssrdf_cubic_params(), closure_bssrdf_cubic_prepare); - register_closure(ss, "emission", OSL_CLOSURE_EMISSION_ID, closure_emission_params(), closure_emission_prepare); - register_closure(ss, "debug", OSL_CLOSURE_DEBUG_ID, closure_debug_params(), closure_debug_prepare); - register_closure(ss, "background", OSL_CLOSURE_BACKGROUND_ID, closure_background_params(), closure_background_prepare); - register_closure(ss, "holdout", OSL_CLOSURE_HOLDOUT_ID, closure_holdout_params(), closure_holdout_prepare); - register_closure(ss, "subsurface", OSL_CLOSURE_SUBSURFACE_ID, closure_subsurface_params(), closure_subsurface_prepare); + int id = 0; + + register_closure(ss, "diffuse", id++, + bsdf_diffuse_params(), bsdf_diffuse_prepare); + register_closure(ss, "oren_nayar", id++, + bsdf_oren_nayar_params(), bsdf_oren_nayar_prepare); + register_closure(ss, "translucent", id++, + bsdf_translucent_params(), bsdf_translucent_prepare); + register_closure(ss, "reflection", id++, + bsdf_reflection_params(), bsdf_reflection_prepare); + register_closure(ss, "refraction", id++, + bsdf_refraction_params(), bsdf_refraction_prepare); + register_closure(ss, "transparent", id++, + bsdf_transparent_params(), bsdf_transparent_prepare); + register_closure(ss, "microfacet_ggx", id++, + bsdf_microfacet_ggx_params(), bsdf_microfacet_ggx_prepare); + register_closure(ss, "microfacet_ggx_refraction", id++, + bsdf_microfacet_ggx_refraction_params(), bsdf_microfacet_ggx_refraction_prepare); + register_closure(ss, "microfacet_beckmann", id++, + bsdf_microfacet_beckmann_params(), bsdf_microfacet_beckmann_prepare); + register_closure(ss, "microfacet_beckmann_refraction", id++, + bsdf_microfacet_beckmann_refraction_params(), bsdf_microfacet_beckmann_refraction_prepare); + register_closure(ss, "ward", id++, + bsdf_ward_params(), bsdf_ward_prepare); + register_closure(ss, "ashikhmin_velvet", id++, + bsdf_ashikhmin_velvet_params(), bsdf_ashikhmin_velvet_prepare); + register_closure(ss, "westin_backscatter", id++, + bsdf_westin_backscatter_params(), bsdf_westin_backscatter_prepare); + register_closure(ss, "westin_sheen", id++, + bsdf_westin_sheen_params(), bsdf_westin_sheen_prepare); + register_closure(ss, "emission", id++, + closure_emission_params(), closure_emission_prepare); + register_closure(ss, "background", id++, + closure_background_params(), closure_background_prepare); + register_closure(ss, "holdout", id++, + closure_holdout_params(), closure_holdout_prepare); } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/osl/osl_closures.h b/intern/cycles/kernel/osl/osl_closures.h index a69af45672d..873e03673c3 100644 --- a/intern/cycles/kernel/osl/osl_closures.h +++ b/intern/cycles/kernel/osl/osl_closures.h @@ -37,78 +37,19 @@ #include #include +#include "kernel_types.h" + +#include "util_types.h" + CCL_NAMESPACE_BEGIN -enum { - OSL_CLOSURE_BSDF_DIFFUSE_ID, - OSL_CLOSURE_BSDF_OREN_NAYAR_ID, - OSL_CLOSURE_BSDF_TRANSLUCENT_ID, - OSL_CLOSURE_BSDF_REFLECTION_ID, - OSL_CLOSURE_BSDF_REFRACTION_ID, - OSL_CLOSURE_BSDF_TRANSPARENT_ID, - OSL_CLOSURE_BSDF_MICROFACET_GGX_ID, - OSL_CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID, - OSL_CLOSURE_BSDF_MICROFACET_BECKMANN_ID, - OSL_CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID, - OSL_CLOSURE_BSDF_WARD_ID, - OSL_CLOSURE_BSDF_PHONG_ID, - OSL_CLOSURE_BSDF_PHONG_RAMP_ID, - OSL_CLOSURE_BSDF_ASHIKHMIN_VELVET_ID, - OSL_CLOSURE_BSDF_WESTIN_BACKSCATTER_ID, - OSL_CLOSURE_BSDF_WESTIN_SHEEN_ID, - OSL_CLOSURE_BSSRDF_CUBIC_ID, - OSL_CLOSURE_EMISSION_ID, - OSL_CLOSURE_DEBUG_ID, - OSL_CLOSURE_BACKGROUND_ID, - OSL_CLOSURE_HOLDOUT_ID, - OSL_CLOSURE_SUBSURFACE_ID -}; - -OSL::ClosureParam *bsdf_diffuse_params(); -OSL::ClosureParam *bsdf_oren_nayar_params(); -OSL::ClosureParam *bsdf_translucent_params(); -OSL::ClosureParam *bsdf_reflection_params(); -OSL::ClosureParam *bsdf_refraction_params(); -OSL::ClosureParam *bsdf_transparent_params(); -OSL::ClosureParam *bsdf_microfacet_ggx_params(); -OSL::ClosureParam *bsdf_microfacet_ggx_refraction_params(); -OSL::ClosureParam *bsdf_microfacet_beckmann_params(); -OSL::ClosureParam *bsdf_microfacet_beckmann_refraction_params(); -OSL::ClosureParam *bsdf_ward_params(); -OSL::ClosureParam *bsdf_phong_params(); -OSL::ClosureParam *bsdf_phong_ramp_params(); -OSL::ClosureParam *bsdf_ashikhmin_velvet_params(); -OSL::ClosureParam *bsdf_westin_backscatter_params(); -OSL::ClosureParam *bsdf_westin_sheen_params(); -OSL::ClosureParam *closure_bssrdf_cubic_params(); OSL::ClosureParam *closure_emission_params(); -OSL::ClosureParam *closure_debug_params(); OSL::ClosureParam *closure_background_params(); OSL::ClosureParam *closure_holdout_params(); -OSL::ClosureParam *closure_subsurface_params(); -void bsdf_diffuse_prepare(OSL::RendererServices *, int id, void *data); -void bsdf_oren_nayar_prepare(OSL::RendererServices *, int id, void *data); -void bsdf_translucent_prepare(OSL::RendererServices *, int id, void *data); -void bsdf_reflection_prepare(OSL::RendererServices *, int id, void *data); -void bsdf_refraction_prepare(OSL::RendererServices *, int id, void *data); -void bsdf_transparent_prepare(OSL::RendererServices *, int id, void *data); -void bsdf_microfacet_ggx_prepare(OSL::RendererServices *, int id, void *data); -void bsdf_microfacet_ggx_refraction_prepare(OSL::RendererServices *, int id, void *data); -void bsdf_microfacet_beckmann_prepare(OSL::RendererServices *, int id, void *data); -void bsdf_microfacet_beckmann_refraction_prepare(OSL::RendererServices *, int id, void *data); -void bsdf_ward_prepare(OSL::RendererServices *, int id, void *data); -void bsdf_phong_prepare(OSL::RendererServices *, int id, void *data); -void bsdf_phong_ramp_prepare(OSL::RendererServices *, int id, void *data); -void bsdf_ashikhmin_velvet_prepare(OSL::RendererServices *, int id, void *data); -void bsdf_westin_backscatter_prepare(OSL::RendererServices *, int id, void *data); -void bsdf_westin_sheen_prepare(OSL::RendererServices *, int id, void *data); -void closure_bssrdf_cubic_prepare(OSL::RendererServices *, int id, void *data); void closure_emission_prepare(OSL::RendererServices *, int id, void *data); -void closure_debug_prepare(OSL::RendererServices *, int id, void *data); void closure_background_prepare(OSL::RendererServices *, int id, void *data); void closure_holdout_prepare(OSL::RendererServices *, int id, void *data); -void closure_subsurface_prepare(OSL::RendererServices *, int id, void *data); #define CLOSURE_PREPARE(name, classname) \ void name(RendererServices *, int id, void *data) \ @@ -117,6 +58,106 @@ void name(RendererServices *, int id, void *data) \ new (data) classname(); \ } +#define TO_VEC3(v) (*(OSL::Vec3 *)&(v)) +#define TO_COLOR3(v) (*(OSL::Color3 *)&(v)) +#define TO_FLOAT3(v) make_float3(v[0], v[1], v[2]) + +/* BSDF */ + +class CBSDFClosure : public OSL::ClosurePrimitive { +public: + ShaderClosure sc; + OSL::Vec3 N, T; + + CBSDFClosure(int scattering) : OSL::ClosurePrimitive(BSDF), + m_scattering_label(scattering), m_shaderdata_flag(0) { } + ~CBSDFClosure() { } + + int scattering() const { return m_scattering_label; } + int shaderdata_flag() const { return m_shaderdata_flag; } + ClosureType shaderclosure_type() const { return sc.type; } + + virtual void blur(float roughness); + virtual float3 eval_reflect(const float3 &omega_out, const float3 &omega_in, float &pdf) const = 0; + virtual float3 eval_transmit(const float3 &omega_out, const float3 &omega_in, float &pdf) const = 0; + + virtual int sample(const float3 &Ng, + const float3 &omega_out, const float3 &domega_out_dx, const float3 &domega_out_dy, + float randu, float randv, + float3 &omega_in, float3 &domega_in_dx, float3 &domega_in_dy, + float &pdf, float3 &eval) const = 0; + +protected: + int m_scattering_label; + int m_shaderdata_flag; +}; + +#define BSDF_CLOSURE_CLASS_BEGIN(Upper, lower, svmlower, TYPE) \ +\ +class Upper##Closure : public CBSDFClosure { \ +public: \ + Upper##Closure() : CBSDFClosure(TYPE) {} \ + size_t memsize() const { return sizeof(*this); } \ + const char *name() const { return #lower; } \ +\ + void setup() \ + { \ + sc.N = TO_FLOAT3(N); \ + sc.T = TO_FLOAT3(T); \ + m_shaderdata_flag = bsdf_##lower##_setup(&sc); \ + } \ +\ + bool mergeable(const ClosurePrimitive *other) const \ + { \ + return false; \ + } \ + \ + void blur(float roughness) \ + { \ + bsdf_##svmlower##_blur(&sc, roughness); \ + } \ +\ + void print_on(std::ostream &out) const \ + { \ + out << name() << " ((" << sc.N[0] << ", " << sc.N[1] << ", " << sc.N[2] << "))"; \ + } \ +\ + float3 eval_reflect(const float3 &omega_out, const float3 &omega_in, float& pdf) const \ + { \ + return bsdf_##svmlower##_eval_reflect(&sc, omega_out, omega_in, &pdf); \ + } \ +\ + float3 eval_transmit(const float3 &omega_out, const float3 &omega_in, float& pdf) const \ + { \ + return bsdf_##svmlower##_eval_transmit(&sc, omega_out, omega_in, &pdf); \ + } \ +\ + int sample(const float3 &Ng, \ + const float3 &omega_out, const float3 &domega_out_dx, const float3 &domega_out_dy, \ + float randu, float randv, \ + float3 &omega_in, float3 &domega_in_dx, float3 &domega_in_dy, \ + float &pdf, float3 &eval) const \ + { \ + return bsdf_##svmlower##_sample(&sc, Ng, omega_out, domega_out_dx, domega_out_dy, \ + randu, randv, &eval, &omega_in, &domega_in_dx, &domega_in_dy, &pdf); \ + } \ +}; \ +\ +ClosureParam *bsdf_##lower##_params() \ +{ \ + static ClosureParam params[] = { + +/* parameters */ + +#define BSDF_CLOSURE_CLASS_END(Upper, lower) \ + CLOSURE_STRING_KEYPARAM("label"), \ + CLOSURE_FINISH_PARAM(Upper##Closure) \ + }; \ + return params; \ +} \ +\ +CLOSURE_PREPARE(bsdf_##lower##_prepare, Upper##Closure) + CCL_NAMESPACE_END #endif /* __OSL_CLOSURES_H__ */ diff --git a/intern/cycles/kernel/osl/osl_services.cpp b/intern/cycles/kernel/osl/osl_services.cpp index 92dae998a64..83574c91d31 100644 --- a/intern/cycles/kernel/osl/osl_services.cpp +++ b/intern/cycles/kernel/osl/osl_services.cpp @@ -174,7 +174,6 @@ bool OSLRenderServices::get_matrix(OSL::Matrix44 &result, OSL::TransformationPtr /* this is only used for shader and object space, we don't really have * a concept of shader space, so we just use object space for both. */ if (xform) { - KernelGlobals *kg = kernel_globals; const ShaderData *sd = (const ShaderData *)xform; int object = sd->object; @@ -182,6 +181,7 @@ bool OSLRenderServices::get_matrix(OSL::Matrix44 &result, OSL::TransformationPtr #ifdef __OBJECT_MOTION__ Transform tfm = sd->ob_tfm; #else + KernelGlobals *kg = kernel_globals; Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM); #endif tfm = transform_transpose(tfm); @@ -199,7 +199,6 @@ bool OSLRenderServices::get_inverse_matrix(OSL::Matrix44 &result, OSL::Transform /* this is only used for shader and object space, we don't really have * a concept of shader space, so we just use object space for both. */ if (xform) { - KernelGlobals *kg = kernel_globals; const ShaderData *sd = (const ShaderData *)xform; int object = sd->object; @@ -207,6 +206,7 @@ bool OSLRenderServices::get_inverse_matrix(OSL::Matrix44 &result, OSL::Transform #ifdef __OBJECT_MOTION__ Transform tfm = sd->ob_itfm; #else + KernelGlobals *kg = kernel_globals; Transform tfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM); #endif tfm = transform_transpose(tfm); diff --git a/intern/cycles/kernel/osl/osl_shader.cpp b/intern/cycles/kernel/osl/osl_shader.cpp index ea508dcb660..8b71ac30ab6 100644 --- a/intern/cycles/kernel/osl/osl_shader.cpp +++ b/intern/cycles/kernel/osl/osl_shader.cpp @@ -21,6 +21,7 @@ #include "kernel_globals.h" #include "kernel_object.h" +#include "osl_closures.h" #include "osl_services.h" #include "osl_shader.h" @@ -61,10 +62,6 @@ void OSLShader::thread_free(KernelGlobals *kg) /* Globals */ -#define TO_VEC3(v) (*(OSL::Vec3 *)&(v)) -#define TO_COLOR3(v) (*(OSL::Color3 *)&(v)) -#define TO_FLOAT3(v) make_float3(v[0], v[1], v[2]) - static void shaderdata_to_shaderglobals(KernelGlobals *kg, ShaderData *sd, int path_flag, OSL::ShaderGlobals *globals) { @@ -127,39 +124,20 @@ static void flatten_surface_closure_tree(ShaderData *sd, bool no_glossy, if (sd->num_closure == MAX_CLOSURE) return; - OSL::BSDFClosure *bsdf = (OSL::BSDFClosure *)prim; - ustring scattering = bsdf->scattering(); + CBSDFClosure *bsdf = (CBSDFClosure *)prim; + int scattering = bsdf->scattering(); /* no caustics option */ - if (no_glossy && scattering == OSL::Labels::GLOSSY) + if (no_glossy && scattering == LABEL_GLOSSY) return; /* sample weight */ - float albedo = bsdf->albedo(TO_VEC3(sd->I)); - float sample_weight = fabsf(average(weight)) * albedo; + float sample_weight = fabsf(average(weight)); + + sd->flag |= bsdf->shaderdata_flag(); sc.sample_weight = sample_weight; - - /* scattering flags */ - if (scattering == OSL::Labels::DIFFUSE) { - sd->flag |= SD_BSDF | SD_BSDF_HAS_EVAL; - sc.type = CLOSURE_BSDF_DIFFUSE_ID; - } - else if (scattering == OSL::Labels::GLOSSY) { - sd->flag |= SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_GLOSSY; - sc.type = CLOSURE_BSDF_GLOSSY_ID; - } - else if (scattering == OSL::Labels::STRAIGHT) { - sd->flag |= SD_BSDF; - sc.type = CLOSURE_BSDF_TRANSPARENT_ID; - } - else { - /* todo: we don't actually have a way to determine if - * this closure will reflect/transmit. could add our own - * own scattering flag that do give this info */ - sd->flag |= SD_BSDF; - sc.type = CLOSURE_BSDF_GLOSSY_ID; - } + sc.type = bsdf->shaderclosure_type(); /* add */ sd->closure[sd->num_closure++] = sc; @@ -406,54 +384,34 @@ void OSLShader::release(KernelGlobals *kg, ShaderData *sd) int OSLShader::bsdf_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3& eval, float3& omega_in, differential3& domega_in, float& pdf) { - OSL::BSDFClosure *sample_bsdf = (OSL::BSDFClosure *)sc->prim; - int label = LABEL_NONE; + CBSDFClosure *sample_bsdf = (CBSDFClosure *)sc->prim; pdf = 0.0f; - /* sample BSDF closure */ - ustring ulabel; - - ulabel = sample_bsdf->sample(TO_VEC3(sd->Ng), - TO_VEC3(sd->I), TO_VEC3(sd->dI.dx), TO_VEC3(sd->dI.dy), - randu, randv, - TO_VEC3(omega_in), TO_VEC3(domega_in.dx), TO_VEC3(domega_in.dy), - pdf, TO_COLOR3(eval)); - - /* convert OSL label */ - if (ulabel == OSL::Labels::REFLECT) - label = LABEL_REFLECT; - else if (ulabel == OSL::Labels::TRANSMIT) - label = LABEL_TRANSMIT; - else - return LABEL_NONE; /* sampling failed */ - - /* convert scattering to our bitflag label */ - ustring uscattering = sample_bsdf->scattering(); - - if (uscattering == OSL::Labels::DIFFUSE) - label |= LABEL_DIFFUSE; - else if (uscattering == OSL::Labels::GLOSSY) - label |= LABEL_GLOSSY; - else if (uscattering == OSL::Labels::SINGULAR) - label |= LABEL_SINGULAR; - else - label |= LABEL_TRANSPARENT; - - return label; + return sample_bsdf->sample(sd->Ng, + sd->I, sd->dI.dx, sd->dI.dy, + randu, randv, + omega_in, domega_in.dx, domega_in.dy, + pdf, eval); } float3 OSLShader::bsdf_eval(const ShaderData *sd, const ShaderClosure *sc, const float3& omega_in, float& pdf) { - OSL::BSDFClosure *bsdf = (OSL::BSDFClosure *)sc->prim; - OSL::Color3 bsdf_eval; + CBSDFClosure *bsdf = (CBSDFClosure *)sc->prim; + float3 bsdf_eval; if (dot(sd->Ng, omega_in) >= 0.0f) - bsdf_eval = bsdf->eval_reflect(TO_VEC3(sd->I), TO_VEC3(omega_in), pdf); + bsdf_eval = bsdf->eval_reflect(sd->I, omega_in, pdf); else - bsdf_eval = bsdf->eval_transmit(TO_VEC3(sd->I), TO_VEC3(omega_in), pdf); + bsdf_eval = bsdf->eval_transmit(sd->I, omega_in, pdf); - return TO_FLOAT3(bsdf_eval); + return bsdf_eval; +} + +void OSLShader::bsdf_blur(ShaderClosure *sc, float roughness) +{ + CBSDFClosure *bsdf = (CBSDFClosure *)sc->prim; + bsdf->blur(roughness); } /* Emissive Closure */ @@ -468,7 +426,7 @@ float3 OSLShader::emissive_eval(const ShaderData *sd, const ShaderClosure *sc) /* Volume Closure */ -float3 OSLShader::volume_eval_phase(const ShaderData *sd, const ShaderClosure *sc, const float3 omega_in, const float3 omega_out) +float3 OSLShader::volume_eval_phase(const ShaderClosure *sc, const float3 omega_in, const float3 omega_out) { OSL::VolumeClosure *volume = (OSL::VolumeClosure *)sc->prim; OSL::Color3 volume_eval = volume->eval_phase(TO_VEC3(omega_in), TO_VEC3(omega_out)); diff --git a/intern/cycles/kernel/osl/osl_shader.h b/intern/cycles/kernel/osl/osl_shader.h index e2f4d1e94b8..9ff31e9160b 100644 --- a/intern/cycles/kernel/osl/osl_shader.h +++ b/intern/cycles/kernel/osl/osl_shader.h @@ -72,10 +72,11 @@ public: float3& eval, float3& omega_in, differential3& domega_in, float& pdf); static float3 bsdf_eval(const ShaderData *sd, const ShaderClosure *sc, const float3& omega_in, float& pdf); + static void bsdf_blur(ShaderClosure *sc, float roughness); static float3 emissive_eval(const ShaderData *sd, const ShaderClosure *sc); - static float3 volume_eval_phase(const ShaderData *sd, const ShaderClosure *sc, + static float3 volume_eval_phase(const ShaderClosure *sc, const float3 omega_in, const float3 omega_out); /* release */ diff --git a/intern/cycles/kernel/osl/vol_subsurface.cpp b/intern/cycles/kernel/osl/vol_subsurface.cpp deleted file mode 100644 index 5845428ed43..00000000000 --- a/intern/cycles/kernel/osl/vol_subsurface.cpp +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Adapted from Open Shading Language with this license: - * - * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. - * All Rights Reserved. - * - * Modifications Copyright 2011, Blender Foundation. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Sony Pictures Imageworks nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -#include - -#include "osl_closures.h" - -CCL_NAMESPACE_BEGIN - -using namespace OSL; - -// Computes scattering properties based on Jensen's reparameterization -// described in: -// http://graphics.ucsd.edu/~henrik/papers/fast_bssrdf/ - -class SubsurfaceClosure : public VolumeClosure { -public: - float m_g; - float m_eta; - Color3 m_mfp, m_albedo; - static float root_find_Rd(const float Rd0, const float A) { - // quick exit for trivial cases - if (Rd0 <= 0) return 0; - const float A43 = A * 4.0f / 3.0f; - // Find alpha such that f(alpha) = Rd (see eq.15). A simple bisection - // method can be used because this function is monotonicaly increasing. - float lo = 0, hi = 1; - for (int i = 0; i < 20; i++) { // 2^20 divisions should be sufficient - // eval function at midpoint - float alpha = 0.5f * (lo + hi); - float a1 = sqrtf(3 * (1 - alpha)); - float e1 = expf(-a1); - float e2 = expf(-A43 * a1); - float Rd = 0.5f * alpha * (1 + e2) * e1 - Rd0; - if (fabsf(Rd) < 1e-6f) - return alpha; // close enough - else if (Rd > 0) - hi = alpha; // root is on left side - else - lo = alpha; // root is on right side - } - // didn't quite converge, pick result in the middle of remaining interval - return 0.5f * (lo + hi); - } - SubsurfaceClosure() { - } - - void setup() - { - ior(m_eta); - - if (m_g >= 0.99f) m_g = 0.99f; - if (m_g <= -0.99f) m_g = -0.99f; - - // eq.10 - float inv_eta = 1 / m_eta; - float Fdr = -1.440f * inv_eta * inv_eta + 0.710 * inv_eta + 0.668f + 0.0636 * m_eta; - float A = (1 + Fdr) / (1 - Fdr); - // compute sigma_s, sigma_a (eq.16) - Color3 alpha_prime = Color3(root_find_Rd(m_albedo[0], A), - root_find_Rd(m_albedo[1], A), - root_find_Rd(m_albedo[2], A)); - Color3 sigma_t_prime = Color3(m_mfp.x > 0 ? 1.0f / (m_mfp[0] * sqrtf(3 * (1 - alpha_prime[0]))) : 0.0f, - m_mfp.y > 0 ? 1.0f / (m_mfp[1] * sqrtf(3 * (1 - alpha_prime[1]))) : 0.0f, - m_mfp.z > 0 ? 1.0f / (m_mfp[2] * sqrtf(3 * (1 - alpha_prime[2]))) : 0.0f); - Color3 sigma_s_prime = alpha_prime * sigma_t_prime; - - sigma_s((1.0f / (1 - m_g)) * sigma_s_prime); - sigma_a(sigma_t_prime - sigma_s_prime); - } - - bool mergeable(const ClosurePrimitive *other) const { - const SubsurfaceClosure *comp = (const SubsurfaceClosure *)other; - return m_g == comp->m_g && VolumeClosure::mergeable(other); - } - - size_t memsize() const { return sizeof(*this); } - - const char *name() const { return "subsurface"; } - - void print_on(std::ostream &out) const { - out << name() << " ()"; - } - - virtual Color3 eval_phase(const Vec3 &omega_in, const Vec3 &omega_out) const { - float costheta = omega_in.dot(omega_out); - float ph = 0.25f * float(M_1_PI) * ((1 - m_g * m_g) / powf(1 + m_g * m_g - 2.0f * m_g * costheta, 1.5f)); - return Color3(ph, ph, ph); - } -}; - - - -ClosureParam *closure_subsurface_params() -{ - static ClosureParam params[] = { - CLOSURE_FLOAT_PARAM(SubsurfaceClosure, m_eta), - CLOSURE_FLOAT_PARAM(SubsurfaceClosure, m_g), - CLOSURE_COLOR_PARAM(SubsurfaceClosure, m_mfp), - CLOSURE_COLOR_PARAM(SubsurfaceClosure, m_albedo), - CLOSURE_STRING_KEYPARAM("label"), - CLOSURE_FINISH_PARAM(SubsurfaceClosure) - }; - return params; -} - -CLOSURE_PREPARE(closure_subsurface_prepare, SubsurfaceClosure) - -CCL_NAMESPACE_END - diff --git a/intern/cycles/kernel/svm/svm_bsdf.h b/intern/cycles/kernel/svm/svm_bsdf.h index 043fc727bcb..07c20231d54 100644 --- a/intern/cycles/kernel/svm/svm_bsdf.h +++ b/intern/cycles/kernel/svm/svm_bsdf.h @@ -16,17 +16,17 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#include "bsdf_ashikhmin_velvet.h" -#include "bsdf_diffuse.h" -#include "bsdf_oren_nayar.h" -#include "bsdf_microfacet.h" -#include "bsdf_reflection.h" -#include "bsdf_refraction.h" -#include "bsdf_transparent.h" +#include "../closure/bsdf_ashikhmin_velvet.h" +#include "../closure/bsdf_diffuse.h" +#include "../closure/bsdf_oren_nayar.h" +#include "../closure/bsdf_microfacet.h" +#include "../closure/bsdf_reflection.h" +#include "../closure/bsdf_refraction.h" +#include "../closure/bsdf_transparent.h" #ifdef __DPDU__ -#include "bsdf_ward.h" +#include "../closure/bsdf_ward.h" #endif -#include "bsdf_westin.h" +#include "../closure/bsdf_westin.h" CCL_NAMESPACE_BEGIN diff --git a/intern/cycles/kernel/svm/svm_closure.h b/intern/cycles/kernel/svm/svm_closure.h index 0d30792a594..b72fad26a1f 100644 --- a/intern/cycles/kernel/svm/svm_closure.h +++ b/intern/cycles/kernel/svm/svm_closure.h @@ -23,16 +23,31 @@ CCL_NAMESPACE_BEGIN __device void svm_node_glossy_setup(ShaderData *sd, ShaderClosure *sc, int type, float eta, float roughness, bool refract) { if(type == CLOSURE_BSDF_REFRACTION_ID) { - if(refract) - bsdf_refraction_setup(sd, sc, eta); + if(refract) { + sc->data0 = eta; + sd->flag |= bsdf_refraction_setup(sc); + } else - bsdf_reflection_setup(sd, sc); + sd->flag |= bsdf_reflection_setup(sc); } else if(type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID) { - bsdf_microfacet_beckmann_setup(sd, sc, roughness, eta, refract); + sc->data0 = roughness; + sc->data1 = eta; + + if(refract) + sd->flag |= bsdf_microfacet_beckmann_refraction_setup(sc); + else + sd->flag |= bsdf_microfacet_beckmann_setup(sc); + } + else { + sc->data0 = roughness; + sc->data1 = eta; + + if(refract) + sd->flag |= bsdf_microfacet_ggx_refraction_setup(sc); + else + sd->flag |= bsdf_microfacet_ggx_setup(sc); } - else - bsdf_microfacet_ggx_setup(sd, sc, roughness, eta, refract); } __device_inline ShaderClosure *svm_node_closure_get(ShaderData *sd) @@ -91,24 +106,28 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st svm_node_closure_set_mix_weight(sc, mix_weight); float roughness = param1; - if(roughness == 0.0f) - bsdf_diffuse_setup(sd, sc); - else - bsdf_oren_nayar_setup(sd, sc, roughness); + + if(roughness == 0.0f) { + sd->flag |= bsdf_diffuse_setup(sc); + } + else { + sc->data0 = roughness; + sd->flag |= bsdf_oren_nayar_setup(sc); + } break; } case CLOSURE_BSDF_TRANSLUCENT_ID: { ShaderClosure *sc = svm_node_closure_get(sd); sc->N = N; svm_node_closure_set_mix_weight(sc, mix_weight); - bsdf_translucent_setup(sd, sc); + sd->flag |= bsdf_translucent_setup(sc); break; } case CLOSURE_BSDF_TRANSPARENT_ID: { ShaderClosure *sc = svm_node_closure_get(sd); sc->N = N; svm_node_closure_set_mix_weight(sc, mix_weight); - bsdf_transparent_setup(sd, sc); + sd->flag |= bsdf_transparent_setup(sc); break; } case CLOSURE_BSDF_REFLECTION_ID: @@ -120,17 +139,16 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st #endif ShaderClosure *sc = svm_node_closure_get(sd); sc->N = N; + sc->data0 = param1; svm_node_closure_set_mix_weight(sc, mix_weight); - float roughness = param1; - /* setup bsdf */ if(type == CLOSURE_BSDF_REFLECTION_ID) - bsdf_reflection_setup(sd, sc); + sd->flag |= bsdf_reflection_setup(sc); else if(type == CLOSURE_BSDF_MICROFACET_BECKMANN_ID) - bsdf_microfacet_beckmann_setup(sd, sc, roughness, 1.0f, false); + sd->flag |= bsdf_microfacet_beckmann_setup(sc); else - bsdf_microfacet_ggx_setup(sd, sc, roughness, 1.0f, false); + sd->flag |= bsdf_microfacet_ggx_setup(sc); break; } @@ -193,10 +211,10 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st sc->T = stack_load_float3(stack, data_node.z); svm_node_closure_set_mix_weight(sc, mix_weight); - float roughness_u = param1; - float roughness_v = param2; + sc->data0 = param1; + sc->data1 = param2; - bsdf_ward_setup(sd, sc, roughness_u, roughness_v); + sd->flag |= bsdf_ward_setup(sc); break; } #endif @@ -206,8 +224,8 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st svm_node_closure_set_mix_weight(sc, mix_weight); /* sigma */ - float sigma = clamp(param1, 0.0f, 1.0f); - bsdf_ashikhmin_velvet_setup(sd, sc, sigma); + sc->data0 = clamp(param1, 0.0f, 1.0f); + sd->flag |= bsdf_ashikhmin_velvet_setup(sc); break; } default: @@ -240,7 +258,7 @@ __device void svm_node_closure_volume(KernelGlobals *kg, ShaderData *sd, float * svm_node_closure_set_mix_weight(sc, mix_weight); float density = param1; - volume_transparent_setup(sd, sc, density); + sd->flag |= volume_transparent_setup(sc, density); break; } case CLOSURE_VOLUME_ISOTROPIC_ID: { @@ -248,7 +266,7 @@ __device void svm_node_closure_volume(KernelGlobals *kg, ShaderData *sd, float * svm_node_closure_set_mix_weight(sc, mix_weight); float density = param1; - volume_isotropic_setup(sd, sc, density); + sd->flag |= volume_isotropic_setup(sc, density); break; } default: diff --git a/intern/cycles/render/osl.cpp b/intern/cycles/render/osl.cpp index 6d23097d7a8..7fe7001ab51 100644 --- a/intern/cycles/render/osl.cpp +++ b/intern/cycles/render/osl.cpp @@ -206,6 +206,8 @@ bool OSLCompiler::node_skip_input(ShaderNode *node, ShaderInput *input) return true; if(strcmp(input->name, "Displacement") == 0 && current_type != SHADER_TYPE_DISPLACEMENT) return true; + if(strcmp(input->name, "Normal") == 0) + return true; } else if(current_type == SHADER_TYPE_DISPLACEMENT && input->link && input->link->parent->name == ustring("bump")) return true; From cf7dec94fe96b5905f4c543820c6ad4e27fc7451 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 20 Oct 2012 13:08:51 +0000 Subject: [PATCH 345/347] switch order cmake includes warning flags so its possible to disable them --- CMakeLists.txt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1903a2ad406..90001326997 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1991,9 +1991,10 @@ if(WITH_PYTHON) endif() endif() - -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${PLATFORM_CFLAGS} ${C_WARNINGS}") -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${PLATFORM_CFLAGS} ${CXX_WARNINGS}") +# Include warnings first, so its possible to disable them with user defined flags +# eg: -Wno-uninitialized +set(CMAKE_C_FLAGS "${C_WARNINGS} ${CMAKE_C_FLAGS} ${PLATFORM_CFLAGS}") +set(CMAKE_CXX_FLAGS "${CXX_WARNINGS} ${CMAKE_CXX_FLAGS} ${PLATFORM_CFLAGS}") #------------------------------------------------------------------------------- # Global Defines From d36dc6d8de44194df9053c6c9c3f7842a8394067 Mon Sep 17 00:00:00 2001 From: Lukas Toenne Date: Sat, 20 Oct 2012 13:11:45 +0000 Subject: [PATCH 346/347] Integer socket support in Cycles. Int values are already supported natively in OSL, but were not used as actual ints on the SVM stack. This patch implements all the necessary functionality to support reading input values from RNA properties and convert between SHADER_SOCKET_INT and other types. --- intern/cycles/app/cycles_xml.cpp | 1 + intern/cycles/blender/blender_shader.cpp | 8 +++- intern/cycles/kernel/osl/nodes/CMakeLists.txt | 1 + .../osl/nodes/node_convert_from_color.osl | 2 + .../osl/nodes/node_convert_from_float.osl | 2 + .../osl/nodes/node_convert_from_int.osl | 36 +++++++++++++++++ .../osl/nodes/node_convert_from_normal.osl | 2 + .../osl/nodes/node_convert_from_point.osl | 2 + .../osl/nodes/node_convert_from_vector.osl | 2 + intern/cycles/kernel/svm/svm.h | 19 +++++++++ intern/cycles/kernel/svm/svm_convert.h | 28 ++++++++++++- intern/cycles/kernel/svm/svm_types.h | 7 +++- intern/cycles/render/graph.h | 1 + intern/cycles/render/nodes.cpp | 40 +++++++++++++++---- intern/cycles/render/osl.cpp | 3 ++ intern/cycles/render/svm.cpp | 11 +++-- 16 files changed, 152 insertions(+), 13 deletions(-) create mode 100644 intern/cycles/kernel/osl/nodes/node_convert_from_int.osl diff --git a/intern/cycles/app/cycles_xml.cpp b/intern/cycles/app/cycles_xml.cpp index 87a238e508c..5de9d71b8cc 100644 --- a/intern/cycles/app/cycles_xml.cpp +++ b/intern/cycles/app/cycles_xml.cpp @@ -591,6 +591,7 @@ static void xml_read_shader_graph(const XMLReadState& state, Shader *shader, pug if(string_iequals(in->name, attr.name())) { switch(in->type) { case SHADER_SOCKET_FLOAT: + case SHADER_SOCKET_INT: xml_read_float(&in->value.x, node, attr.name()); break; case SHADER_SOCKET_COLOR: diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp index 98ac8692f36..db34a9fe9aa 100644 --- a/intern/cycles/blender/blender_shader.cpp +++ b/intern/cycles/blender/blender_shader.cpp @@ -80,6 +80,8 @@ static ShaderSocketType convert_socket_type(BL::NodeSocket::type_enum b_type) switch (b_type) { case BL::NodeSocket::type_VALUE: return SHADER_SOCKET_FLOAT; + case BL::NodeSocket::type_INT: + return SHADER_SOCKET_INT; case BL::NodeSocket::type_VECTOR: return SHADER_SOCKET_VECTOR; case BL::NodeSocket::type_RGBA: @@ -89,7 +91,6 @@ static ShaderSocketType convert_socket_type(BL::NodeSocket::type_enum b_type) case BL::NodeSocket::type_BOOLEAN: case BL::NodeSocket::type_MESH: - case BL::NodeSocket::type_INT: default: return SHADER_SOCKET_FLOAT; } @@ -104,6 +105,11 @@ static void set_default_value(ShaderInput *input, BL::NodeSocket sock) input->set(value_sock.default_value()); break; } + case SHADER_SOCKET_INT: { + BL::NodeSocketIntNone value_sock(sock); + input->set((float)value_sock.default_value()); + break; + } case SHADER_SOCKET_COLOR: { BL::NodeSocketRGBA rgba_sock(sock); input->set(get_float3(rgba_sock.default_value())); diff --git a/intern/cycles/kernel/osl/nodes/CMakeLists.txt b/intern/cycles/kernel/osl/nodes/CMakeLists.txt index faf7941ee5e..2c459fd714b 100644 --- a/intern/cycles/kernel/osl/nodes/CMakeLists.txt +++ b/intern/cycles/kernel/osl/nodes/CMakeLists.txt @@ -12,6 +12,7 @@ set(SRC_OSL node_combine_rgb.osl node_convert_from_color.osl node_convert_from_float.osl + node_convert_from_int.osl node_convert_from_normal.osl node_convert_from_point.osl node_convert_from_vector.osl diff --git a/intern/cycles/kernel/osl/nodes/node_convert_from_color.osl b/intern/cycles/kernel/osl/nodes/node_convert_from_color.osl index c55b0f811ff..2884c772414 100644 --- a/intern/cycles/kernel/osl/nodes/node_convert_from_color.osl +++ b/intern/cycles/kernel/osl/nodes/node_convert_from_color.osl @@ -21,11 +21,13 @@ shader node_convert_from_color( color Color = color(0.0, 0.0, 0.0), output float Val = 0.0, + output int ValInt = 0, output vector Vector = vector(0.0, 0.0, 0.0), output point Point = point(0.0, 0.0, 0.0), output normal Normal = normal(0.0, 0.0, 0.0)) { Val = Color[0] * 0.2126 + Color[1] * 0.7152 + Color[2] * 0.0722; + ValInt = (int)(Color[0]*0.2126 + Color[1]*0.7152 + Color[2]*0.0722); Vector = vector(Color[0], Color[1], Color[2]); Point = point(Color[0], Color[1], Color[2]); Normal = normal(Color[0], Color[1], Color[2]); diff --git a/intern/cycles/kernel/osl/nodes/node_convert_from_float.osl b/intern/cycles/kernel/osl/nodes/node_convert_from_float.osl index 00e78f3bab4..4466fbae3a6 100644 --- a/intern/cycles/kernel/osl/nodes/node_convert_from_float.osl +++ b/intern/cycles/kernel/osl/nodes/node_convert_from_float.osl @@ -20,11 +20,13 @@ shader node_convert_from_float( float Val = 0.0, + output int ValInt = 0, output color Color = color(0.0, 0.0, 0.0), output vector Vector = vector(0.0, 0.0, 0.0), output point Point = point(0.0, 0.0, 0.0), output normal Normal = normal(0.0, 0.0, 0.0)) { + ValInt = (int)Val; Color = color(Val, Val, Val); Vector = vector(Val, Val, Val); Point = point(Val, Val, Val); diff --git a/intern/cycles/kernel/osl/nodes/node_convert_from_int.osl b/intern/cycles/kernel/osl/nodes/node_convert_from_int.osl new file mode 100644 index 00000000000..060d4184fa6 --- /dev/null +++ b/intern/cycles/kernel/osl/nodes/node_convert_from_int.osl @@ -0,0 +1,36 @@ +/* + * Copyright 2011, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "stdosl.h" + +shader node_convert_from_int( + int ValInt = 0, + output float Val = 0.0, + output color Color = color(0.0, 0.0, 0.0), + output vector Vector = vector(0.0, 0.0, 0.0), + output point Point = point(0.0, 0.0, 0.0), + output normal Normal = normal(0.0, 0.0, 0.0)) +{ + float f = (float)ValInt; + Val = f; + Color = color(f, f, f); + Vector = vector(f, f, f); + Point = point(f, f, f); + Normal = normal(f, f, f); +} + diff --git a/intern/cycles/kernel/osl/nodes/node_convert_from_normal.osl b/intern/cycles/kernel/osl/nodes/node_convert_from_normal.osl index b2c6c76661c..419e93e1518 100644 --- a/intern/cycles/kernel/osl/nodes/node_convert_from_normal.osl +++ b/intern/cycles/kernel/osl/nodes/node_convert_from_normal.osl @@ -21,11 +21,13 @@ shader node_convert_from_normal( normal Normal = normal(0.0, 0.0, 0.0), output float Val = 0.0, + output int ValInt = 0, output vector Vector = vector(0.0, 0.0, 0.0), output color Color = color(0.0, 0.0, 0.0), output point Point = point(0.0, 0.0, 0.0)) { Val = (Normal[0] + Normal[1] + Normal[2]) * (1.0 / 3.0); + ValInt = (int)((Normal[0] + Normal[1] + Normal[2])*(1.0/3.0)); Vector = vector(Normal[0], Normal[1], Normal[2]); Color = color(Normal[0], Normal[1], Normal[2]); Point = point(Normal[0], Normal[1], Normal[2]); diff --git a/intern/cycles/kernel/osl/nodes/node_convert_from_point.osl b/intern/cycles/kernel/osl/nodes/node_convert_from_point.osl index ae9a17dbc80..cedd200f088 100644 --- a/intern/cycles/kernel/osl/nodes/node_convert_from_point.osl +++ b/intern/cycles/kernel/osl/nodes/node_convert_from_point.osl @@ -21,11 +21,13 @@ shader node_convert_from_point( point Point = point(0.0, 0.0, 0.0), output float Val = 0.0, + output int ValInt = 0, output vector Vector = vector(0.0, 0.0, 0.0), output color Color = color(0.0, 0.0, 0.0), output normal Normal = normal(0.0, 0.0, 0.0)) { Val = (Point[0] + Point[1] + Point[2]) * (1.0 / 3.0); + ValInt = (int)((Normal[0] + Normal[1] + Normal[2])*(1.0/3.0)); Vector = vector(Point[0], Point[1], Point[2]); Color = color(Point[0], Point[1], Point[2]); Normal = normal(Point[0], Point[1], Point[2]); diff --git a/intern/cycles/kernel/osl/nodes/node_convert_from_vector.osl b/intern/cycles/kernel/osl/nodes/node_convert_from_vector.osl index 19ef9331c0c..a9f43a40074 100644 --- a/intern/cycles/kernel/osl/nodes/node_convert_from_vector.osl +++ b/intern/cycles/kernel/osl/nodes/node_convert_from_vector.osl @@ -21,11 +21,13 @@ shader node_convert_from_vector( vector Vector = vector(0.0, 0.0, 0.0), output float Val = 0.0, + output int ValInt = 0, output color Color = color(0.0, 0.0, 0.0), output point Point = point(0.0, 0.0, 0.0), output normal Normal = normal(0.0, 0.0, 0.0)) { Val = (Vector[0] + Vector[1] + Vector[2]) * (1.0 / 3.0); + ValInt = (int)((Normal[0] + Normal[1] + Normal[2])*(1.0/3.0)); Color = color(Vector[0], Vector[1], Vector[2]); Point = point(Vector[0], Vector[1], Vector[2]); Normal = normal(Vector[0], Vector[1], Vector[2]); diff --git a/intern/cycles/kernel/svm/svm.h b/intern/cycles/kernel/svm/svm.h index 421eb146f88..698ef5016f0 100644 --- a/intern/cycles/kernel/svm/svm.h +++ b/intern/cycles/kernel/svm/svm.h @@ -82,6 +82,25 @@ __device_inline void stack_store_float(float *stack, uint a, float f) stack[a] = f; } +__device_inline int stack_load_int(float *stack, uint a) +{ + kernel_assert(a < SVM_STACK_SIZE); + + return __float_as_int(stack[a]); +} + +__device_inline float stack_load_int_default(float *stack, uint a, uint value) +{ + return (a == (uint)SVM_STACK_INVALID)? (int)value: stack_load_int(stack, a); +} + +__device_inline void stack_store_int(float *stack, uint a, int i) +{ + kernel_assert(a < SVM_STACK_SIZE); + + stack[a] = __int_as_float(i); +} + __device_inline bool stack_valid(uint a) { return a != (uint)SVM_STACK_INVALID; diff --git a/intern/cycles/kernel/svm/svm_convert.h b/intern/cycles/kernel/svm/svm_convert.h index 188b0489d9e..f74915a4bc9 100644 --- a/intern/cycles/kernel/svm/svm_convert.h +++ b/intern/cycles/kernel/svm/svm_convert.h @@ -23,6 +23,11 @@ CCL_NAMESPACE_BEGIN __device void svm_node_convert(ShaderData *sd, float *stack, uint type, uint from, uint to) { switch(type) { + case NODE_CONVERT_FI: { + float f = stack_load_float(stack, from); + stack_store_int(stack, to, (int)f); + break; + } case NODE_CONVERT_FV: { float f = stack_load_float(stack, from); stack_store_float3(stack, to, make_float3(f, f, f)); @@ -34,13 +39,34 @@ __device void svm_node_convert(ShaderData *sd, float *stack, uint type, uint fro stack_store_float(stack, to, g); break; } + case NODE_CONVERT_CI: { + float3 f = stack_load_float3(stack, from); + int i = (int)linear_rgb_to_gray(f); + stack_store_int(stack, to, i); + break; + } case NODE_CONVERT_VF: { float3 f = stack_load_float3(stack, from); float g = (f.x + f.y + f.z)*(1.0f/3.0f); stack_store_float(stack, to, g); break; } - + case NODE_CONVERT_VI: { + float3 f = stack_load_float3(stack, from); + int i = (f.x + f.y + f.z)*(1.0f/3.0f); + stack_store_int(stack, to, i); + break; + } + case NODE_CONVERT_IF: { + float f = (float)stack_load_int(stack, from); + stack_store_float(stack, to, f); + break; + } + case NODE_CONVERT_IV: { + float f = (float)stack_load_int(stack, from); + stack_store_float3(stack, to, make_float3(f, f, f)); + break; + } } } diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h index 487876ed417..77df373a159 100644 --- a/intern/cycles/kernel/svm/svm_types.h +++ b/intern/cycles/kernel/svm/svm_types.h @@ -210,8 +210,13 @@ typedef enum NodeVectorMath { typedef enum NodeConvert { NODE_CONVERT_FV, + NODE_CONVERT_FI, NODE_CONVERT_CF, - NODE_CONVERT_VF + NODE_CONVERT_CI, + NODE_CONVERT_VF, + NODE_CONVERT_VI, + NODE_CONVERT_IF, + NODE_CONVERT_IV } NodeConvert; typedef enum NodeDistanceMetric { diff --git a/intern/cycles/render/graph.h b/intern/cycles/render/graph.h index acafe1d5278..b339c3c3847 100644 --- a/intern/cycles/render/graph.h +++ b/intern/cycles/render/graph.h @@ -44,6 +44,7 @@ class OSLCompiler; enum ShaderSocketType { SHADER_SOCKET_FLOAT, + SHADER_SOCKET_INT, SHADER_SOCKET_COLOR, SHADER_SOCKET_VECTOR, SHADER_SOCKET_POINT, diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index 73c45665431..76267e9d014 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -1065,6 +1065,8 @@ ConvertNode::ConvertNode(ShaderSocketType from_, ShaderSocketType to_) if(from == SHADER_SOCKET_FLOAT) add_input("Val", SHADER_SOCKET_FLOAT); + else if(from == SHADER_SOCKET_INT) + add_input("ValInt", SHADER_SOCKET_INT); else if(from == SHADER_SOCKET_COLOR) add_input("Color", SHADER_SOCKET_COLOR); else if(from == SHADER_SOCKET_VECTOR) @@ -1078,6 +1080,8 @@ ConvertNode::ConvertNode(ShaderSocketType from_, ShaderSocketType to_) if(to == SHADER_SOCKET_FLOAT) add_output("Val", SHADER_SOCKET_FLOAT); + else if(to == SHADER_SOCKET_INT) + add_output("ValInt", SHADER_SOCKET_INT); else if(to == SHADER_SOCKET_COLOR) add_output("Color", SHADER_SOCKET_COLOR); else if(to == SHADER_SOCKET_VECTOR) @@ -1095,10 +1099,29 @@ void ConvertNode::compile(SVMCompiler& compiler) ShaderInput *in = inputs[0]; ShaderOutput *out = outputs[0]; - if(to == SHADER_SOCKET_FLOAT) { + if(from == SHADER_SOCKET_FLOAT) { compiler.stack_assign(in); compiler.stack_assign(out); + if(to == SHADER_SOCKET_INT) + /* float to int */ + compiler.add_node(NODE_CONVERT, NODE_CONVERT_FI, in->stack_offset, out->stack_offset); + else + /* float to float3 */ + compiler.add_node(NODE_CONVERT, NODE_CONVERT_FV, in->stack_offset, out->stack_offset); + } + else if(from == SHADER_SOCKET_INT) { + compiler.stack_assign(in); + compiler.stack_assign(out); + + if(to == SHADER_SOCKET_FLOAT) + /* int to float */ + compiler.add_node(NODE_CONVERT, NODE_CONVERT_IF, in->stack_offset, out->stack_offset); + else + /* int to vector/point/normal */ + compiler.add_node(NODE_CONVERT, NODE_CONVERT_IV, in->stack_offset, out->stack_offset); + } + else if(to == SHADER_SOCKET_FLOAT) { if(from == SHADER_SOCKET_COLOR) /* color to float */ compiler.add_node(NODE_CONVERT, NODE_CONVERT_CF, in->stack_offset, out->stack_offset); @@ -1106,12 +1129,13 @@ void ConvertNode::compile(SVMCompiler& compiler) /* vector/point/normal to float */ compiler.add_node(NODE_CONVERT, NODE_CONVERT_VF, in->stack_offset, out->stack_offset); } - else if(from == SHADER_SOCKET_FLOAT) { - compiler.stack_assign(in); - compiler.stack_assign(out); - - /* float to float3 */ - compiler.add_node(NODE_CONVERT, NODE_CONVERT_FV, in->stack_offset, out->stack_offset); + else if(to == SHADER_SOCKET_INT) { + if(from == SHADER_SOCKET_COLOR) + /* color to int */ + compiler.add_node(NODE_CONVERT, NODE_CONVERT_CI, in->stack_offset, out->stack_offset); + else + /* vector/point/normal to int */ + compiler.add_node(NODE_CONVERT, NODE_CONVERT_VI, in->stack_offset, out->stack_offset); } else { /* float3 to float3 */ @@ -1134,6 +1158,8 @@ void ConvertNode::compile(OSLCompiler& compiler) { if(from == SHADER_SOCKET_FLOAT) compiler.add(this, "node_convert_from_float"); + else if(from == SHADER_SOCKET_INT) + compiler.add(this, "node_convert_from_int"); else if(from == SHADER_SOCKET_COLOR) compiler.add(this, "node_convert_from_color"); else if(from == SHADER_SOCKET_VECTOR) diff --git a/intern/cycles/render/osl.cpp b/intern/cycles/render/osl.cpp index 7fe7001ab51..21e6c7749b8 100644 --- a/intern/cycles/render/osl.cpp +++ b/intern/cycles/render/osl.cpp @@ -246,6 +246,9 @@ void OSLCompiler::add(ShaderNode *node, const char *name) case SHADER_SOCKET_FLOAT: parameter(param_name.c_str(), input->value.x); break; + case SHADER_SOCKET_INT: + parameter(param_name.c_str(), (int)input->value.x); + break; case SHADER_SOCKET_CLOSURE: break; } diff --git a/intern/cycles/render/svm.cpp b/intern/cycles/render/svm.cpp index 844ce01569f..c41d503b217 100644 --- a/intern/cycles/render/svm.cpp +++ b/intern/cycles/render/svm.cpp @@ -119,6 +119,8 @@ int SVMCompiler::stack_size(ShaderSocketType type) { if(type == SHADER_SOCKET_FLOAT) return 1; + else if(type == SHADER_SOCKET_INT) + return 1; else if(type == SHADER_SOCKET_COLOR) return 3; else if(type == SHADER_SOCKET_VECTOR) @@ -212,10 +214,13 @@ void SVMCompiler::stack_assign(ShaderInput *input) if(input->type == SHADER_SOCKET_FLOAT) { add_node(NODE_VALUE_F, __float_as_int(input->value.x), input->stack_offset); } + else if(input->type == SHADER_SOCKET_INT) { + add_node(NODE_VALUE_F, (int)input->value.x, input->stack_offset); + } else if(input->type == SHADER_SOCKET_VECTOR || - input->type == SHADER_SOCKET_NORMAL || - input->type == SHADER_SOCKET_POINT || - input->type == SHADER_SOCKET_COLOR) { + input->type == SHADER_SOCKET_NORMAL || + input->type == SHADER_SOCKET_POINT || + input->type == SHADER_SOCKET_COLOR) { add_node(NODE_VALUE_V, input->stack_offset); add_node(NODE_VALUE_V, input->value); From a9e2e2279780ec2fb58e6820b9cad95ba03f4cad Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 20 Oct 2012 13:29:07 +0000 Subject: [PATCH 347/347] dont ise -Wuninitialized on gcc 4.2 and older, it gives annoying warnings. --- CMakeLists.txt | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 90001326997..058da2d40b4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1857,12 +1857,16 @@ if(CMAKE_COMPILER_IS_GNUCC) ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_WRITE_STRINGS -Wwrite-strings) ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_LOGICAL_OP -Wlogical-op) ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_UNDEF -Wundef) - ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_UNINITIALIZED -Wuninitialized) ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_INIT_SELF -Winit-self) # needs -Wuninitialized ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_NO_NULL -Wnonnull) # C only ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_MISSING_INCLUDE_DIRS -Wmissing-include-dirs) ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_NO_DIV_BY_ZERO -Wno-div-by-zero) + # gcc 4.2 gives annoying warnings on every file with this + if (${CMAKE_C_COMPILER_VERSION} VERSION_GREATER "4.2") + ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_UNINITIALIZED -Wuninitialized) + endif() + # disable because it gives warnings for printf() & friends. # ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_DOUBLE_PROMOTION -Wdouble-promotion -Wno-error=double-promotion) @@ -1874,11 +1878,15 @@ if(CMAKE_COMPILER_IS_GNUCC) ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_INVALID_OFFSETOF -Wno-invalid-offsetof) ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_SIGN_COMPARE -Wno-sign-compare) ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_LOGICAL_OP -Wlogical-op) - ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_UNINITIALIZED -Wuninitialized) ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_INIT_SELF -Winit-self) # needs -Wuninitialized ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_MISSING_INCLUDE_DIRS -Wmissing-include-dirs) ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_DIV_BY_ZERO -Wno-div-by-zero) + # gcc 4.2 gives annoying warnings on every file with this + if (${CMAKE_C_COMPILER_VERSION} VERSION_GREATER "4.2") + ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_UNINITIALIZED -Wuninitialized) + endif() + # causes too many warnings if(NOT APPLE) ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_UNDEF -Wundef)