diff --git a/intern/cycles/device/opencl/opencl_base.cpp b/intern/cycles/device/opencl/opencl_base.cpp index 486ef89d22e..6747a8a83ac 100644 --- a/intern/cycles/device/opencl/opencl_base.cpp +++ b/intern/cycles/device/opencl/opencl_base.cpp @@ -1107,7 +1107,7 @@ void OpenCLDeviceBase::shader(DeviceTask& task) if(task.shader_eval_type >= SHADER_EVAL_BAKE) { kernel = base_program(ustring("bake")); } - else if(task.shader_eval_type >= SHADER_EVAL_DISPLACE) { + else if(task.shader_eval_type == SHADER_EVAL_DISPLACE) { kernel = base_program(ustring("displace")); } else { diff --git a/source/blender/blenkernel/BKE_fcurve.h b/source/blender/blenkernel/BKE_fcurve.h index b38f1299763..09f5ecce050 100644 --- a/source/blender/blenkernel/BKE_fcurve.h +++ b/source/blender/blenkernel/BKE_fcurve.h @@ -188,7 +188,7 @@ const FModifierTypeInfo *get_fmodifier_typeinfo(const int type); /* ---------------------- */ -struct FModifier *add_fmodifier(ListBase *modifiers, int type); +struct FModifier *add_fmodifier(ListBase *modifiers, int type, struct FCurve *owner_fcu); struct FModifier *copy_fmodifier(const struct FModifier *src); void copy_fmodifiers(ListBase *dst, const ListBase *src); bool remove_fmodifier(ListBase *modifiers, struct FModifier *fcm); @@ -266,6 +266,9 @@ bool fcurve_are_keyframes_usable(struct FCurve *fcu); bool fcurve_is_keyframable(struct FCurve *fcu); bool BKE_fcurve_is_protected(struct FCurve *fcu); +/* The curve is an infinite cycle via Cycles modifier */ +bool BKE_fcurve_is_cyclic(struct FCurve *fcu); + /* -------- Curve Sanity -------- */ void calchandles_fcurve(struct FCurve *fcu); diff --git a/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv.c b/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv.c index 9c86a22a1f8..c26112d3724 100644 --- a/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv.c +++ b/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv.c @@ -282,6 +282,7 @@ bool ccgSubSurf_prepareGLMesh(CCGSubSurf *ss, sizeof(GLfloat) * 6, (float *)12); glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindVertexArray(0); } else if (ss->osd_coarse_coords_invalid) { ccgSubSurf__updateGLMeshCoords(ss); @@ -299,6 +300,7 @@ void ccgSubSurf_drawGLMesh(CCGSubSurf *ss, bool fill_quads, int start_partition, int num_partitions) { if (LIKELY(ss->osd_mesh != NULL)) { + glBindVertexArray(ss->osd_vao); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, openSubdiv_getOsdGLMeshPatchIndexBuffer(ss->osd_mesh)); diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c index aee465ad0a0..103f23a2c18 100644 --- a/source/blender/blenkernel/intern/fcurve.c +++ b/source/blender/blenkernel/intern/fcurve.c @@ -881,6 +881,46 @@ void fcurve_store_samples(FCurve *fcu, void *data, int start, int end, FcuSample * that the handles are correctly */ +/* Checks if the F-Curve has a Cycles modifier with simple settings that warrant transition smoothing */ +bool BKE_fcurve_is_cyclic(FCurve *fcu) +{ + FModifier *fcm = fcu->modifiers.first; + + if (!fcm || fcm->type != FMODIFIER_TYPE_CYCLES) + return false; + + if (fcm->flag & (FMODIFIER_FLAG_DISABLED | FMODIFIER_FLAG_MUTED)) + return false; + + if (fcm->flag & (FMODIFIER_FLAG_RANGERESTRICT | FMODIFIER_FLAG_USEINFLUENCE)) + return false; + + FMod_Cycles *data = (FMod_Cycles*)fcm->data; + + return data && data->after_cycles == 0 && data->before_cycles == 0 && + ELEM(data->before_mode, FCM_EXTRAPOLATE_CYCLIC, FCM_EXTRAPOLATE_CYCLIC_OFFSET) && + ELEM(data->after_mode, FCM_EXTRAPOLATE_CYCLIC, FCM_EXTRAPOLATE_CYCLIC_OFFSET); +} + +/* Shifts 'in' by the difference in coordinates between 'to' and 'from', using 'out' as the output buffer. + * When 'to' and 'from' are end points of the loop, this moves the 'in' point one loop cycle. + */ +static BezTriple *cycle_offset_triple(bool cycle, BezTriple *out, const BezTriple *in, const BezTriple *from, const BezTriple *to) +{ + if (!cycle) + return NULL; + + memcpy(out, in, sizeof(BezTriple)); + + float delta[3]; + sub_v3_v3v3(delta, to->vec[1], from->vec[1]); + + for (int i = 0; i < 3; i++) + add_v3_v3(out->vec[i], delta); + + return out; +} + /* This function recalculates the handles of an F-Curve * If the BezTriples have been rearranged, sort them first before using this. */ @@ -896,10 +936,16 @@ void calchandles_fcurve(FCurve *fcu) */ if (ELEM(NULL, fcu, fcu->bezt) || (a < 2) /*|| ELEM(fcu->ipo, BEZT_IPO_CONST, BEZT_IPO_LIN)*/) return; - + + /* if the first modifier is Cycles, smooth the curve through the cycle */ + BezTriple *first = &fcu->bezt[0], *last = &fcu->bezt[fcu->totvert-1]; + BezTriple tmp; + + bool cycle = BKE_fcurve_is_cyclic(fcu) && BEZT_IS_AUTOH(first) && BEZT_IS_AUTOH(last); + /* get initial pointers */ bezt = fcu->bezt; - prev = NULL; + prev = cycle_offset_triple(cycle, &tmp, &fcu->bezt[fcu->totvert-2], last, first); next = (bezt + 1); /* loop over all beztriples, adjusting handles */ @@ -912,7 +958,7 @@ void calchandles_fcurve(FCurve *fcu) BKE_nurb_handle_calc(bezt, prev, next, true); /* for automatic ease in and out */ - if (ELEM(bezt->h1, HD_AUTO, HD_AUTO_ANIM) && ELEM(bezt->h2, HD_AUTO, HD_AUTO_ANIM)) { + if (BEZT_IS_AUTOH(bezt) && !cycle) { /* only do this on first or last beztriple */ if ((a == 0) || (a == fcu->totvert - 1)) { /* set both handles to have same horizontal value as keyframe */ @@ -924,8 +970,14 @@ void calchandles_fcurve(FCurve *fcu) /* advance pointers for next iteration */ prev = bezt; - if (a == 1) next = NULL; - else next++; + + if (a == 1) { + next = cycle_offset_triple(cycle, &tmp, &fcu->bezt[1], first, last); + } + else { + next++; + } + bezt++; } } diff --git a/source/blender/blenkernel/intern/fmodifier.c b/source/blender/blenkernel/intern/fmodifier.c index f1732ee7a9a..f1834bdf8a6 100644 --- a/source/blender/blenkernel/intern/fmodifier.c +++ b/source/blender/blenkernel/intern/fmodifier.c @@ -1077,7 +1077,7 @@ const FModifierTypeInfo *fmodifier_get_typeinfo(const FModifier *fcm) /* API --------------------------- */ /* Add a new F-Curve Modifier to the given F-Curve of a certain type */ -FModifier *add_fmodifier(ListBase *modifiers, int type) +FModifier *add_fmodifier(ListBase *modifiers, int type, FCurve *owner_fcu) { const FModifierTypeInfo *fmi = get_fmodifier_typeinfo(type); FModifier *fcm; @@ -1098,6 +1098,7 @@ FModifier *add_fmodifier(ListBase *modifiers, int type) fcm = MEM_callocN(sizeof(FModifier), "F-Curve Modifier"); fcm->type = type; fcm->flag = FMODIFIER_FLAG_EXPANDED; + fcm->curve = owner_fcu; fcm->influence = 1.0f; BLI_addtail(modifiers, fcm); @@ -1111,6 +1112,10 @@ FModifier *add_fmodifier(ListBase *modifiers, int type) /* init custom settings if necessary */ if (fmi->new_data) fmi->new_data(fcm->data); + + /* update the fcurve if the Cycles modifier is added */ + if ((owner_fcu) && (type == FMODIFIER_TYPE_CYCLES)) + calchandles_fcurve(owner_fcu); /* return modifier for further editing */ return fcm; @@ -1129,6 +1134,7 @@ FModifier *copy_fmodifier(const FModifier *src) /* copy the base data, clearing the links */ dst = MEM_dupallocN(src); dst->next = dst->prev = NULL; + dst->curve = NULL; /* make a new copy of the F-Modifier's data */ dst->data = MEM_dupallocN(src->data); @@ -1157,6 +1163,7 @@ void copy_fmodifiers(ListBase *dst, const ListBase *src) /* make a new copy of the F-Modifier's data */ fcm->data = MEM_dupallocN(fcm->data); + fcm->curve = NULL; /* only do specific constraints if required */ if (fmi && fmi->copy_data) @@ -1173,6 +1180,9 @@ bool remove_fmodifier(ListBase *modifiers, FModifier *fcm) if (fcm == NULL) return false; + /* removing the cycles modifier requires a handle update */ + FCurve *update_fcu = (fcm->type == FMODIFIER_TYPE_CYCLES) ? fcm->curve : NULL; + /* free modifier's special data (stored inside fcm->data) */ if (fcm->data) { if (fmi && fmi->free_data) @@ -1185,6 +1195,11 @@ bool remove_fmodifier(ListBase *modifiers, FModifier *fcm) /* remove modifier from stack */ if (modifiers) { BLI_freelinkN(modifiers, fcm); + + /* update the fcurve if the Cycles modifier is removed */ + if (update_fcu) + calchandles_fcurve(update_fcu); + return true; } else { diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c index f3a85dcee2b..90247441631 100644 --- a/source/blender/blenkernel/intern/ipo.c +++ b/source/blender/blenkernel/intern/ipo.c @@ -1192,7 +1192,7 @@ static void icu_to_fcurves(ID *id, ListBase *groups, ListBase *list, IpoCurve *i /* Add a new FModifier (Cyclic) instead of setting extend value * as that's the new equivalent of that option. */ - FModifier *fcm = add_fmodifier(&fcu->modifiers, FMODIFIER_TYPE_CYCLES); + FModifier *fcm = add_fmodifier(&fcu->modifiers, FMODIFIER_TYPE_CYCLES, fcu); FMod_Cycles *data = (FMod_Cycles *)fcm->data; /* if 'offset' one is in use, set appropriate settings */ diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index a421abd852d..e6d534d18c0 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -2453,13 +2453,14 @@ static void lib_link_fcurves(FileData *fd, ID *id, ListBase *list) /* NOTE: this assumes that link_list has already been called on the list */ -static void direct_link_fmodifiers(FileData *fd, ListBase *list) +static void direct_link_fmodifiers(FileData *fd, ListBase *list, FCurve *curve) { FModifier *fcm; for (fcm = list->first; fcm; fcm = fcm->next) { /* relink general data */ fcm->data = newdataadr(fd, fcm->data); + fcm->curve = curve; /* do relinking of data for specific types */ switch (fcm->type) { @@ -2549,7 +2550,7 @@ static void direct_link_fcurves(FileData *fd, ListBase *list) /* modifiers */ link_list(fd, &fcu->modifiers); - direct_link_fmodifiers(fd, &fcu->modifiers); + direct_link_fmodifiers(fd, &fcu->modifiers, fcu); } } @@ -2654,7 +2655,7 @@ static void direct_link_nladata_strips(FileData *fd, ListBase *list) /* strip's F-Modifiers */ link_list(fd, &strip->modifiers); - direct_link_fmodifiers(fd, &strip->modifiers); + direct_link_fmodifiers(fd, &strip->modifiers, NULL); } } diff --git a/source/blender/editors/animation/drivers.c b/source/blender/editors/animation/drivers.c index 1a3d82e5002..e686e278740 100644 --- a/source/blender/editors/animation/drivers.c +++ b/source/blender/editors/animation/drivers.c @@ -125,7 +125,7 @@ FCurve *verify_driver_fcurve(ID *id, const char rna_path[], const int array_inde * Create FModifier so that old scripts won't break * for now before 2.7 series -- (September 4, 2013) */ - add_fmodifier(&fcu->modifiers, FMODIFIER_TYPE_GENERATOR); + add_fmodifier(&fcu->modifiers, FMODIFIER_TYPE_GENERATOR, fcu); } else { /* add 2 keyframes so that user has something to work with diff --git a/source/blender/editors/animation/fmodifier_ui.c b/source/blender/editors/animation/fmodifier_ui.c index 6bb73416fec..8d77460e197 100644 --- a/source/blender/editors/animation/fmodifier_ui.c +++ b/source/blender/editors/animation/fmodifier_ui.c @@ -736,7 +736,7 @@ bool ANIM_fmodifiers_copy_to_buf(ListBase *modifiers, bool active) /* 'Paste' the F-Modifier(s) from the buffer to the specified list * - replace: free all the existing modifiers to leave only the pasted ones */ -bool ANIM_fmodifiers_paste_from_buf(ListBase *modifiers, bool replace) +bool ANIM_fmodifiers_paste_from_buf(ListBase *modifiers, bool replace, FCurve *curve) { FModifier *fcm; bool ok = false; @@ -745,6 +745,8 @@ bool ANIM_fmodifiers_paste_from_buf(ListBase *modifiers, bool replace) if (modifiers == NULL) return 0; + bool was_cyclic = curve && BKE_fcurve_is_cyclic(curve); + /* if replacing the list, free the existing modifiers */ if (replace) free_fmodifiers(modifiers); @@ -753,6 +755,8 @@ bool ANIM_fmodifiers_paste_from_buf(ListBase *modifiers, bool replace) for (fcm = fmodifier_copypaste_buf.first; fcm; fcm = fcm->next) { /* make a copy of it */ FModifier *fcmN = copy_fmodifier(fcm); + + fcmN->curve = curve; /* make sure the new one isn't active, otherwise the list may get several actives */ fcmN->flag &= ~FMODIFIER_FLAG_ACTIVE; @@ -762,6 +766,10 @@ bool ANIM_fmodifiers_paste_from_buf(ListBase *modifiers, bool replace) ok = 1; } + /* adding or removing the Cycles modifier requires an update to handles */ + if (curve && BKE_fcurve_is_cyclic(curve) != was_cyclic) + calchandles_fcurve(curve); + /* did we succeed? */ return ok; } diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h index 797262c685b..77b2ce435c2 100644 --- a/source/blender/editors/include/ED_anim_api.h +++ b/source/blender/editors/include/ED_anim_api.h @@ -573,7 +573,7 @@ bool ANIM_fmodifiers_copy_to_buf(ListBase *modifiers, bool active); /* 'Paste' the F-Modifier(s) from the buffer to the specified list * - replace: free all the existing modifiers to leave only the pasted ones */ -bool ANIM_fmodifiers_paste_from_buf(ListBase *modifiers, bool replace); +bool ANIM_fmodifiers_paste_from_buf(ListBase *modifiers, bool replace, struct FCurve *curve); /* ************************************************* */ /* ASSORTED TOOLS */ diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c index 4e578906e07..f9401433362 100644 --- a/source/blender/editors/object/object_constraint.c +++ b/source/blender/editors/object/object_constraint.c @@ -1031,7 +1031,7 @@ static int followpath_path_animate_exec(bContext *C, wmOperator *op) * and define basic slope of this curve based on the properties */ if (!fcu->bezt && !fcu->fpt && !fcu->modifiers.first) { - FModifier *fcm = add_fmodifier(&fcu->modifiers, FMODIFIER_TYPE_GENERATOR); + FModifier *fcm = add_fmodifier(&fcu->modifiers, FMODIFIER_TYPE_GENERATOR, fcu); FMod_Generator *gen = fcm->data; /* Assume that we have the following equation: diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index c255ce4a45a..34cef2aa588 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -650,7 +650,7 @@ bool ED_object_parent_set(ReportList *reports, const bContext *C, Scene *scene, /* setup dummy 'generator' modifier here to get 1-1 correspondence still working */ if (!fcu->bezt && !fcu->fpt && !fcu->modifiers.first) - add_fmodifier(&fcu->modifiers, FMODIFIER_TYPE_GENERATOR); + add_fmodifier(&fcu->modifiers, FMODIFIER_TYPE_GENERATOR, fcu); } /* fall back on regular parenting now (for follow only) */ diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c index a9920389980..2df5aa29e9a 100644 --- a/source/blender/editors/space_action/action_edit.c +++ b/source/blender/editors/space_action/action_edit.c @@ -1146,7 +1146,7 @@ static void setexpo_action_keys(bAnimContext *ac, short mode) /* only add if one doesn't exist */ if (list_has_suitable_fmodifier(&fcu->modifiers, FMODIFIER_TYPE_CYCLES, -1) == 0) { /* TODO: add some more preset versions which set different extrapolation options? */ - add_fmodifier(&fcu->modifiers, FMODIFIER_TYPE_CYCLES); + add_fmodifier(&fcu->modifiers, FMODIFIER_TYPE_CYCLES, fcu); } } else if (mode == CLEAR_CYCLIC_EXPO) { diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c index 12d872a3c8a..d0ab12b16a3 100644 --- a/source/blender/editors/space_graph/graph_edit.c +++ b/source/blender/editors/space_graph/graph_edit.c @@ -1505,7 +1505,7 @@ static void setexpo_graph_keys(bAnimContext *ac, short mode) /* only add if one doesn't exist */ if (list_has_suitable_fmodifier(&fcu->modifiers, FMODIFIER_TYPE_CYCLES, -1) == 0) { // TODO: add some more preset versions which set different extrapolation options? - add_fmodifier(&fcu->modifiers, FMODIFIER_TYPE_CYCLES); + add_fmodifier(&fcu->modifiers, FMODIFIER_TYPE_CYCLES, fcu); } } else if (mode == CLEAR_CYCLIC_EXPO) { @@ -2447,7 +2447,7 @@ static int graph_fmodifier_add_exec(bContext *C, wmOperator *op) FModifier *fcm; /* add F-Modifier of specified type to active F-Curve, and make it the active one */ - fcm = add_fmodifier(&fcu->modifiers, type); + fcm = add_fmodifier(&fcu->modifiers, type, fcu); if (fcm) { set_active_fmodifier(&fcu->modifiers, fcm); } @@ -2583,7 +2583,7 @@ static int graph_fmodifier_paste_exec(bContext *C, wmOperator *op) FCurve *fcu = (FCurve *)ale->data; int tot; - tot = ANIM_fmodifiers_paste_from_buf(&fcu->modifiers, replace); + tot = ANIM_fmodifiers_paste_from_buf(&fcu->modifiers, replace, fcu); if (tot) { ale->update |= ANIM_UPDATE_DEPS; diff --git a/source/blender/editors/space_nla/nla_edit.c b/source/blender/editors/space_nla/nla_edit.c index f7f7c82171d..a6f76e1d556 100644 --- a/source/blender/editors/space_nla/nla_edit.c +++ b/source/blender/editors/space_nla/nla_edit.c @@ -2316,7 +2316,7 @@ static int nla_fmodifier_add_exec(bContext *C, wmOperator *op) continue; /* add F-Modifier of specified type to selected, and make it the active one */ - fcm = add_fmodifier(&strip->modifiers, type); + fcm = add_fmodifier(&strip->modifiers, type, NULL); if (fcm) { set_active_fmodifier(&strip->modifiers, fcm); @@ -2470,7 +2470,7 @@ static int nla_fmodifier_paste_exec(bContext *C, wmOperator *op) } /* paste FModifiers from buffer */ - ok += ANIM_fmodifiers_paste_from_buf(&strip->modifiers, replace); + ok += ANIM_fmodifiers_paste_from_buf(&strip->modifiers, replace, NULL); ale->update |= ANIM_UPDATE_DEPS; } } diff --git a/source/blender/makesdna/DNA_anim_types.h b/source/blender/makesdna/DNA_anim_types.h index 935a893f689..977cd2347ad 100644 --- a/source/blender/makesdna/DNA_anim_types.h +++ b/source/blender/makesdna/DNA_anim_types.h @@ -52,6 +52,7 @@ extern "C" { typedef struct FModifier { struct FModifier *next, *prev; + struct FCurve *curve; /* containing curve, only used for updates to CYCLES */ void *data; /* pointer to modifier data */ char name[64]; /* user-defined description for the modifier - MAX_ID_NAME-2 */ diff --git a/source/blender/makesdna/DNA_curve_types.h b/source/blender/makesdna/DNA_curve_types.h index e598c32173c..ea446552874 100644 --- a/source/blender/makesdna/DNA_curve_types.h +++ b/source/blender/makesdna/DNA_curve_types.h @@ -437,6 +437,8 @@ typedef enum eBezTriple_KeyframeType { #define BEZT_SEL_ALL(bezt) { (bezt)->f1 |= SELECT; (bezt)->f2 |= SELECT; (bezt)->f3 |= SELECT; } ((void)0) #define BEZT_DESEL_ALL(bezt) { (bezt)->f1 &= ~SELECT; (bezt)->f2 &= ~SELECT; (bezt)->f3 &= ~SELECT; } ((void)0) +#define BEZT_IS_AUTOH(bezt) (ELEM((bezt)->h1, HD_AUTO, HD_AUTO_ANIM) && ELEM((bezt)->h2, HD_AUTO, HD_AUTO_ANIM)) + /* *************** CHARINFO **************** */ /* CharInfo.flag */ diff --git a/source/blender/makesrna/intern/rna_fcurve.c b/source/blender/makesrna/intern/rna_fcurve.c index e951e15ca8c..90c4ec53b45 100644 --- a/source/blender/makesrna/intern/rna_fcurve.c +++ b/source/blender/makesrna/intern/rna_fcurve.c @@ -497,7 +497,7 @@ static void rna_FCurve_active_modifier_set(PointerRNA *ptr, PointerRNA value) static FModifier *rna_FCurve_modifiers_new(FCurve *fcu, int type) { - return add_fmodifier(&fcu->modifiers, type); + return add_fmodifier(&fcu->modifiers, type, fcu); } static void rna_FCurve_modifiers_remove(FCurve *fcu, ReportList *reports, PointerRNA *fcm_ptr) @@ -588,11 +588,15 @@ static void rna_FModifier_blending_range(PointerRNA *ptr, float *min, float *max static void rna_FModifier_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) { ID *id = ptr->id.data; + FModifier *fcm = (FModifier *)ptr->data; AnimData *adt = BKE_animdata_from_id(id); DEG_id_tag_update(id, (GS(id->name) == ID_OB) ? OB_RECALC_OB : OB_RECALC_DATA); if (adt != NULL) { adt->recalc |= ADT_RECALC_ANIM; } + if (fcm->curve && fcm->type == FMODIFIER_TYPE_CYCLES) { + calchandles_fcurve(fcm->curve); + } } static void rna_FModifier_verify_data_update(Main *bmain, Scene *scene, PointerRNA *ptr) diff --git a/source/blender/python/generic/bgl.c b/source/blender/python/generic/bgl.c index 5c938ef2ee3..9672b824843 100644 --- a/source/blender/python/generic/bgl.c +++ b/source/blender/python/generic/bgl.c @@ -476,34 +476,29 @@ int BGL_typeSize(int type) return -1; } -static int gl_buffer_type_from_py_format_char(char *typestr) +static int gl_buffer_type_from_py_buffer(Py_buffer *pybuffer) { + char *typestr = pybuffer->format; + Py_ssize_t itemsize = pybuffer->itemsize; + if (ELEM(typestr[0], '<', '>', '|')) { typestr += 1; } - char format = typestr[0]; - char byte_num = typestr[1]; - switch (format) { + switch (typestr[0]) { case 't': case 'b': case 'h': - if (!byte_num) return GL_BYTE; - ATTR_FALLTHROUGH; case 'i': - if (!byte_num) return GL_SHORT; - ATTR_FALLTHROUGH; case 'l': - if (!byte_num || byte_num == '4') return GL_INT; - if (byte_num == '1') return GL_BYTE; - if (byte_num == '2') return GL_SHORT; + if (itemsize == 1) return GL_BYTE; + if (itemsize == 2) return GL_SHORT; + if (itemsize == 4) return GL_INT; break; case 'f': - if (!byte_num) return GL_FLOAT; - ATTR_FALLTHROUGH; case 'd': - if (!byte_num || byte_num == '8') return GL_DOUBLE; - if (byte_num == '4') return GL_FLOAT; + if (itemsize == 4) return GL_FLOAT; + if (itemsize == 8) return GL_DOUBLE; break; } return -1; /* UNKNOWN */ @@ -801,7 +796,7 @@ static PyObject *Buffer_new(PyTypeObject *UNUSED(type), PyObject *args, PyObject return NULL; } - if (type != gl_buffer_type_from_py_format_char(pybuffer.format)) { + if (type != gl_buffer_type_from_py_buffer(&pybuffer)) { PyErr_Format(PyExc_TypeError, "`GL_TYPE` and `typestr` of object with buffer interface do not match. '%s'", pybuffer.format); } diff --git a/tests/python/bl_alembic_import_test.py b/tests/python/bl_alembic_import_test.py index e64da2fe540..5062e8ff073 100644 --- a/tests/python/bl_alembic_import_test.py +++ b/tests/python/bl_alembic_import_test.py @@ -222,9 +222,9 @@ class VertexColourImportTest(AbstractAlembicTest): layer = ob.data.vertex_colors['Cf'] # MeshLoopColorLayer # Test some known-good values. - self.assertAlmostEqualFloatArray(layer.data[0].color, (0, 0, 0)) - self.assertAlmostEqualFloatArray(layer.data[98].color, (0.9019607, 0.4745098, 0.2666666)) - self.assertAlmostEqualFloatArray(layer.data[99].color, (0.8941176, 0.4705882, 0.2627451)) + self.assertAlmostEqualFloatArray(layer.data[0].color, (0, 0, 0, 1.0)) + self.assertAlmostEqualFloatArray(layer.data[98].color, (0.9019607, 0.4745098, 0.2666666, 1.0)) + self.assertAlmostEqualFloatArray(layer.data[99].color, (0.8941176, 0.4705882, 0.2627451, 1.0)) def test_import_from_blender(self): # Blender saved per-vertex, and as RGBA. @@ -237,9 +237,9 @@ class VertexColourImportTest(AbstractAlembicTest): layer = ob.data.vertex_colors['Cf'] # MeshLoopColorLayer # Test some known-good values. - self.assertAlmostEqualFloatArray(layer.data[0].color, (1.0, 0.0156862, 0.3607843)) - self.assertAlmostEqualFloatArray(layer.data[98].color, (0.0941176, 0.1215686, 0.9137254)) - self.assertAlmostEqualFloatArray(layer.data[99].color, (0.1294117, 0.3529411, 0.7529411)) + self.assertAlmostEqualFloatArray(layer.data[0].color, (1.0, 0.0156862, 0.3607843, 1.0)) + self.assertAlmostEqualFloatArray(layer.data[98].color, (0.0941176, 0.1215686, 0.9137254, 1.0)) + self.assertAlmostEqualFloatArray(layer.data[99].color, (0.1294117, 0.3529411, 0.7529411, 1.0)) def main():