diff options
-rw-r--r-- | source/blender/blenkernel/intern/fcurve.c | 57 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_layout.c | 4 | ||||
-rw-r--r-- | source/blender/editors/space_graph/graph_buttons.c | 35 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_anim_types.h | 11 |
4 files changed, 80 insertions, 27 deletions
diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c index 23f3a3ad3fd..64480980acd 100644 --- a/source/blender/blenkernel/intern/fcurve.c +++ b/source/blender/blenkernel/intern/fcurve.c @@ -1014,7 +1014,7 @@ static float dtar_get_prop_val(ChannelDriver *driver, DriverTarget *dtar) PointerRNA id_ptr, ptr; PropertyRNA *prop; ID *id; - int index; + int index = -1; float value = 0.0f; /* sanity check */ @@ -1029,6 +1029,7 @@ static float dtar_get_prop_val(ChannelDriver *driver, DriverTarget *dtar) printf("Error: driver has an invalid target to use\n"); if (G.debug & G_DEBUG) printf("\tpath = %s\n", dtar->rna_path); driver->flag |= DRIVER_FLAG_INVALID; + dtar->flag |= DTAR_FLAG_INVALID; return 0.0f; } @@ -1039,7 +1040,7 @@ static float dtar_get_prop_val(ChannelDriver *driver, DriverTarget *dtar) if (RNA_path_resolve_full(&id_ptr, dtar->rna_path, &ptr, &prop, &index)) { if (RNA_property_array_check(prop)) { /* array */ - if (index < RNA_property_array_length(&ptr, prop)) { + if ((index >= 0) && (index < RNA_property_array_length(&ptr, prop))) { switch (RNA_property_type(prop)) { case PROP_BOOLEAN: value = (float)RNA_property_boolean_get_index(&ptr, prop, index); @@ -1054,6 +1055,17 @@ static float dtar_get_prop_val(ChannelDriver *driver, DriverTarget *dtar) break; } } + else { + /* out of bounds */ + if (G.debug & G_DEBUG) { + printf("Driver Evaluation Error: array index is out of bounds for %s -> %s (%d)", + id->name, dtar->rna_path, index); + } + + driver->flag |= DRIVER_FLAG_INVALID; + dtar->flag |= DTAR_FLAG_INVALID; + return 0.0f; + } } else { /* not an array */ @@ -1074,16 +1086,19 @@ static float dtar_get_prop_val(ChannelDriver *driver, DriverTarget *dtar) break; } } - } else { + /* path couldn't be resolved */ if (G.debug & G_DEBUG) printf("Driver Evaluation Error: cannot resolve target for %s -> %s\n", id->name, dtar->rna_path); driver->flag |= DRIVER_FLAG_INVALID; + dtar->flag |= DTAR_FLAG_INVALID; return 0.0f; } + /* if we're still here, we should be ok... */ + dtar->flag &= ~DTAR_FLAG_INVALID; return value; } @@ -1122,25 +1137,39 @@ static float dvar_eval_singleProp(ChannelDriver *driver, DriverVar *dvar) /* evaluate 'rotation difference' driver variable */ static float dvar_eval_rotDiff(ChannelDriver *driver, DriverVar *dvar) { + DriverTarget *dtar1 = &dvar->targets[0]; + DriverTarget *dtar2 = &dvar->targets[1]; bPoseChannel *pchan, *pchan2; float q1[4], q2[4], quat[4], angle; /* get pose channels, and check if we've got two */ - pchan = dtar_get_pchan_ptr(driver, &dvar->targets[0]); - pchan2 = dtar_get_pchan_ptr(driver, &dvar->targets[1]); + pchan = dtar_get_pchan_ptr(driver, dtar1); + pchan2 = dtar_get_pchan_ptr(driver, dtar2); if (ELEM(NULL, pchan, pchan2)) { /* disable this driver, since it doesn't work correctly... */ driver->flag |= DRIVER_FLAG_INVALID; /* check what the error was */ - if ((pchan == NULL) && (pchan2 == NULL)) + if ((pchan == NULL) && (pchan2 == NULL)) { printf("Driver Evaluation Error: Rotational difference failed - first 2 targets invalid\n"); - else if (pchan == NULL) + + dtar1->flag |= DTAR_FLAG_INVALID; + dtar2->flag |= DTAR_FLAG_INVALID; + } + else if (pchan == NULL) { printf("Driver Evaluation Error: Rotational difference failed - first target not valid PoseChannel\n"); - else if (pchan2 == NULL) + + dtar1->flag |= DTAR_FLAG_INVALID; + dtar2->flag &= ~DTAR_FLAG_INVALID; + } + else if (pchan2 == NULL) { printf("Driver Evaluation Error: Rotational difference failed - second target not valid PoseChannel\n"); + dtar1->flag &= ~DTAR_FLAG_INVALID; + dtar2->flag |= DTAR_FLAG_INVALID; + } + /* stop here... */ return 0.0f; } @@ -1177,8 +1206,13 @@ static float dvar_eval_locDiff(ChannelDriver *driver, DriverVar *dvar) if ((ob == NULL) || (GS(ob->id.name) != ID_OB)) { /* invalid target, so will not have enough targets */ driver->flag |= DRIVER_FLAG_INVALID; + dtar->flag |= DTAR_FLAG_INVALID; return 0.0f; } + else { + /* target seems to be OK now... */ + dtar->flag &= ~DTAR_FLAG_INVALID; + } /* try to get posechannel */ pchan = BKE_pose_channel_find_name(ob->pose, dtar->pchan_name); @@ -1264,8 +1298,13 @@ static float dvar_eval_transChan(ChannelDriver *driver, DriverVar *dvar) if ((ob == NULL) || (GS(ob->id.name) != ID_OB)) { /* invalid target, so will not have enough targets */ driver->flag |= DRIVER_FLAG_INVALID; + dtar->flag |= DTAR_FLAG_INVALID; return 0.0f; } + else { + /* target should be valid now */ + dtar->flag &= ~DTAR_FLAG_INVALID; + } /* try to get posechannel */ pchan = BKE_pose_channel_find_name(ob->pose, dtar->pchan_name); @@ -1463,7 +1502,7 @@ void driver_change_variable_type(DriverVar *dvar, int type) /* store the flags */ dtar->flag = flags; - /* object ID types only, or idtype not yet initialized*/ + /* object ID types only, or idtype not yet initialized */ if ((flags & DTAR_FLAG_ID_OB_ONLY) || (dtar->idtype == 0)) dtar->idtype = ID_OB; } diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index c69f53a53d2..1e95b4df762 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -2263,6 +2263,7 @@ uiLayout *uiLayoutRow(uiLayout *layout, int align) litem->enabled = 1; litem->context = layout->context; litem->space = (align) ? 0 : layout->root->style->buttonspacex; + litem->redalert = layout->redalert; litem->w = layout->w; BLI_addtail(&layout->items, litem); @@ -2283,6 +2284,7 @@ uiLayout *uiLayoutColumn(uiLayout *layout, int align) litem->enabled = 1; litem->context = layout->context; litem->space = (litem->align) ? 0 : layout->root->style->buttonspacey; + litem->redalert = layout->redalert; litem->w = layout->w; BLI_addtail(&layout->items, litem); @@ -2303,6 +2305,7 @@ uiLayout *uiLayoutColumnFlow(uiLayout *layout, int number, int align) flow->litem.enabled = 1; flow->litem.context = layout->context; flow->litem.space = (flow->litem.align) ? 0 : layout->root->style->columnspace; + flow->litem.redalert = layout->redalert; flow->litem.w = layout->w; flow->number = number; BLI_addtail(&layout->items, flow); @@ -2323,6 +2326,7 @@ static uiLayoutItemBx *ui_layout_box(uiLayout *layout, int type) box->litem.enabled = 1; box->litem.context = layout->context; box->litem.space = layout->root->style->columnspace; + box->litem.redalert = layout->redalert; box->litem.w = layout->w; BLI_addtail(&layout->items, box); diff --git a/source/blender/editors/space_graph/graph_buttons.c b/source/blender/editors/space_graph/graph_buttons.c index ab16a9d55e6..7da147b1575 100644 --- a/source/blender/editors/space_graph/graph_buttons.c +++ b/source/blender/editors/space_graph/graph_buttons.c @@ -461,6 +461,7 @@ static void graph_panel_driverVar__singleProp(uiLayout *layout, ID *id, DriverVa /* Target ID */ row = uiLayoutRow(layout, FALSE); + uiLayoutSetRedAlert(row, ((dtar->flag & DTAR_FLAG_INVALID) && !dtar->id)); uiTemplateAnyID(row, &dtar_ptr, "id", "id_type", IFACE_("Prop:")); /* Target Property */ @@ -470,8 +471,9 @@ static void graph_panel_driverVar__singleProp(uiLayout *layout, ID *id, DriverVa /* get pointer for resolving the property selected */ RNA_id_pointer_create(dtar->id, &root_ptr); - col = uiLayoutColumn(layout, TRUE); /* rna path */ + col = uiLayoutColumn(layout, TRUE); + uiLayoutSetRedAlert(col, (dtar->flag & DTAR_FLAG_INVALID)); uiTemplatePathBuilder(col, &dtar_ptr, "data_path", &root_ptr, IFACE_("Path")); } } @@ -492,21 +494,23 @@ static void graph_panel_driverVar__rotDiff(uiLayout *layout, ID *id, DriverVar * /* Bone 1 */ col = uiLayoutColumn(layout, TRUE); + uiLayoutSetRedAlert(col, (dtar->flag & DTAR_FLAG_INVALID)); /* XXX: per field... */ uiTemplateAnyID(col, &dtar_ptr, "id", "id_type", IFACE_("Bone 1:")); - + if (dtar->id && ob1->pose) { PointerRNA tar_ptr; - + RNA_pointer_create(dtar->id, &RNA_Pose, ob1->pose, &tar_ptr); uiItemPointerR(col, &dtar_ptr, "bone_target", &tar_ptr, "bones", "", ICON_BONE_DATA); } col = uiLayoutColumn(layout, TRUE); + uiLayoutSetRedAlert(col, (dtar2->flag & DTAR_FLAG_INVALID)); /* XXX: per field... */ uiTemplateAnyID(col, &dtar2_ptr, "id", "id_type", IFACE_("Bone 2:")); if (dtar2->id && ob2->pose) { PointerRNA tar_ptr; - + RNA_pointer_create(dtar2->id, &RNA_Pose, ob2->pose, &tar_ptr); uiItemPointerR(col, &dtar2_ptr, "bone_target", &tar_ptr, "bones", "", ICON_BONE_DATA); } @@ -515,7 +519,7 @@ static void graph_panel_driverVar__rotDiff(uiLayout *layout, ID *id, DriverVar * /* settings for 'location difference' driver variable type */ static void graph_panel_driverVar__locDiff(uiLayout *layout, ID *id, DriverVar *dvar) { - DriverTarget *dtar = &dvar->targets[0]; + DriverTarget *dtar = &dvar->targets[0]; DriverTarget *dtar2 = &dvar->targets[1]; Object *ob1 = (Object *)dtar->id; Object *ob2 = (Object *)dtar2->id; @@ -523,16 +527,17 @@ static void graph_panel_driverVar__locDiff(uiLayout *layout, ID *id, DriverVar * uiLayout *col; /* initialize RNA pointer to the target */ - RNA_pointer_create(id, &RNA_DriverTarget, dtar, &dtar_ptr); + RNA_pointer_create(id, &RNA_DriverTarget, dtar, &dtar_ptr); RNA_pointer_create(id, &RNA_DriverTarget, dtar2, &dtar2_ptr); /* Bone 1 */ col = uiLayoutColumn(layout, TRUE); + uiLayoutSetRedAlert(col, (dtar->flag & DTAR_FLAG_INVALID)); /* XXX: per field... */ uiTemplateAnyID(col, &dtar_ptr, "id", "id_type", IFACE_("Ob/Bone 1:")); if (dtar->id && ob1->pose) { PointerRNA tar_ptr; - + RNA_pointer_create(dtar->id, &RNA_Pose, ob1->pose, &tar_ptr); uiItemPointerR(col, &dtar_ptr, "bone_target", &tar_ptr, "bones", "", ICON_BONE_DATA); } @@ -540,11 +545,12 @@ static void graph_panel_driverVar__locDiff(uiLayout *layout, ID *id, DriverVar * uiItemR(col, &dtar_ptr, "transform_space", 0, NULL, ICON_NONE); col = uiLayoutColumn(layout, TRUE); + uiLayoutSetRedAlert(col, (dtar2->flag & DTAR_FLAG_INVALID)); /* XXX: per field... */ uiTemplateAnyID(col, &dtar2_ptr, "id", "id_type", IFACE_("Ob/Bone 2:")); if (dtar2->id && ob2->pose) { PointerRNA tar_ptr; - + RNA_pointer_create(dtar2->id, &RNA_Pose, ob2->pose, &tar_ptr); uiItemPointerR(col, &dtar2_ptr, "bone_target", &tar_ptr, "bones", "", ICON_BONE_DATA); } @@ -565,11 +571,12 @@ static void graph_panel_driverVar__transChan(uiLayout *layout, ID *id, DriverVar /* properties */ col = uiLayoutColumn(layout, TRUE); + uiLayoutSetRedAlert(col, (dtar->flag & DTAR_FLAG_INVALID)); /* XXX: per field... */ uiTemplateAnyID(col, &dtar_ptr, "id", "id_type", IFACE_("Ob/Bone:")); if (dtar->id && ob->pose) { PointerRNA tar_ptr; - + RNA_pointer_create(dtar->id, &RNA_Pose, ob->pose, &tar_ptr); uiItemPointerR(col, &dtar_ptr, "bone_target", &tar_ptr, "bones", "", ICON_BONE_DATA); } @@ -623,7 +630,7 @@ static void graph_panel_drivers(const bContext *C, Panel *pa) if (driver->type == DRIVER_TYPE_PYTHON) { /* expression */ uiItemR(col, &driver_ptr, "expression", 0, IFACE_("Expr"), ICON_NONE); - + /* errors? */ if (driver->flag & DRIVER_FLAG_INVALID) uiItemL(col, IFACE_("ERROR: Invalid Python expression"), ICON_ERROR); @@ -668,19 +675,19 @@ static void graph_panel_drivers(const bContext *C, Panel *pa) box = uiLayoutBox(col); /* first row context info for driver */ RNA_pointer_create(ale->id, &RNA_DriverVariable, dvar, &dvar_ptr); - + row = uiLayoutRow(box, FALSE); block = uiLayoutGetBlock(row); /* variable name */ uiItemR(row, &dvar_ptr, "name", 0, "", ICON_NONE); - + /* remove button */ uiBlockSetEmboss(block, UI_EMBOSSN); but = uiDefIconBut(block, BUT, B_IPO_DEPCHANGE, ICON_X, 290, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0.0, 0.0, IFACE_("Delete target variable")); uiButSetFunc(but, driver_delete_var_cb, driver, dvar); uiBlockSetEmboss(block, UI_EMBOSS); - + /* variable type */ row = uiLayoutRow(box, FALSE); uiItemR(row, &dvar_ptr, "type", 0, "", ICON_NONE); @@ -721,7 +728,7 @@ static void graph_panel_drivers(const bContext *C, Panel *pa) else { BLI_snprintf(valBuf, sizeof(valBuf), "%.3f", dvar->curval); } - + uiItemL(row, valBuf, ICON_NONE); } } diff --git a/source/blender/makesdna/DNA_anim_types.h b/source/blender/makesdna/DNA_anim_types.h index 1ac6e6db94b..73e2a9f433b 100644 --- a/source/blender/makesdna/DNA_anim_types.h +++ b/source/blender/makesdna/DNA_anim_types.h @@ -284,15 +284,18 @@ typedef enum eDriverTarget_Flag { /* used for targets that use the pchan_name instead of RNA path * (i.e. rotation difference) */ - DTAR_FLAG_STRUCT_REF = (1<<0), + DTAR_FLAG_STRUCT_REF = (1 << 0), /* idtype can only be 'Object' */ - DTAR_FLAG_ID_OB_ONLY = (1<<1), + DTAR_FLAG_ID_OB_ONLY = (1 << 1), /* "localspace" flags */ /* base flag - basically "pre parent+constraints" */ - DTAR_FLAG_LOCALSPACE = (1<<2), + DTAR_FLAG_LOCALSPACE = (1 << 2), /* include constraints transformed to space including parents */ - DTAR_FLAG_LOCAL_CONSTS = (1<<3), + DTAR_FLAG_LOCAL_CONSTS = (1 << 3), + + /* error flags */ + DTAR_FLAG_INVALID = (1 << 4), } eDriverTarget_Flag; /* Transform Channels for Driver Targets */ |