diff options
Diffstat (limited to 'source/blender/editors/curve')
-rw-r--r-- | source/blender/editors/curve/editcurve.c | 99 | ||||
-rw-r--r-- | source/blender/editors/curve/editcurve_paint.c | 61 |
2 files changed, 84 insertions, 76 deletions
diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index 6b5a5d81d32..f6528658490 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -92,14 +92,6 @@ typedef struct { int flag; } UndoCurve; -/* Definitions needed for shape keys */ -typedef struct { - void *orig_cv; - int key_index, nu_index, pt_index, vertex_index; - bool switched; - Nurb *orig_nu; -} CVKeyIndex; - void selectend_nurb(Object *obedit, enum eEndPoint_Types selfirst, bool doswap, bool selstatus); static void adduplicateflagNurb(Object *obedit, ListBase *newnurb, const short flag, const bool split); static int curve_delete_segments(Object *obedit, const bool split); @@ -139,9 +131,9 @@ void printknots(Object *obedit) /* ********************* Shape keys *************** */ -static CVKeyIndex *init_cvKeyIndex(void *cv, int key_index, int nu_index, int pt_index, int vertex_index, Nurb *orig_nu) +static CVKeyIndex *init_cvKeyIndex(void *cv, int key_index, int nu_index, int pt_index, int vertex_index) { - CVKeyIndex *cvIndex = MEM_callocN(sizeof(CVKeyIndex), "init_cvKeyIndex"); + CVKeyIndex *cvIndex = MEM_callocN(sizeof(CVKeyIndex), __func__); cvIndex->orig_cv = cv; cvIndex->key_index = key_index; @@ -149,7 +141,6 @@ static CVKeyIndex *init_cvKeyIndex(void *cv, int key_index, int nu_index, int pt cvIndex->pt_index = pt_index; cvIndex->vertex_index = vertex_index; cvIndex->switched = false; - cvIndex->orig_nu = orig_nu; return cvIndex; } @@ -175,7 +166,12 @@ static void init_editNurb_keyIndex(EditNurb *editnurb, ListBase *origBase) origbezt = orignu->bezt; pt_index = 0; while (a--) { - keyIndex = init_cvKeyIndex(origbezt, key_index, nu_index, pt_index, vertex_index, orignu); + /* We cannot keep *any* reference to curve obdata, + * it might be replaced and freed while editcurve remain in use (in viewport render case e.g.). + * Note that we could use a pool to avoid lots of malloc's here, but... not really a problem for now. */ + BezTriple *origbezt_cpy = MEM_mallocN(sizeof(*origbezt), __func__); + *origbezt_cpy = *origbezt; + keyIndex = init_cvKeyIndex(origbezt_cpy, key_index, nu_index, pt_index, vertex_index); BLI_ghash_insert(gh, bezt, keyIndex); key_index += 12; vertex_index += 3; @@ -190,7 +186,12 @@ static void init_editNurb_keyIndex(EditNurb *editnurb, ListBase *origBase) origbp = orignu->bp; pt_index = 0; while (a--) { - keyIndex = init_cvKeyIndex(origbp, key_index, nu_index, pt_index, vertex_index, orignu); + /* We cannot keep *any* reference to curve obdata, + * it might be replaced and freed while editcurve remain in use (in viewport render case e.g.). + * Note that we could use a pool to avoid lots of malloc's here, but... not really a problem for now. */ + BPoint *origbp_cpy = MEM_mallocN(sizeof(*origbp_cpy), __func__); + *origbp_cpy = *origbp; + keyIndex = init_cvKeyIndex(origbp_cpy, key_index, nu_index, pt_index, vertex_index); BLI_ghash_insert(gh, bp, keyIndex); key_index += 4; bp++; @@ -251,23 +252,22 @@ static int getKeyIndexOrig_keyIndex(EditNurb *editnurb, void *cv) return index->key_index; } -static void keyIndex_delCV(EditNurb *editnurb, const void *cv) +static void keyIndex_delBezt(EditNurb *editnurb, BezTriple *bezt) { if (!editnurb->keyindex) { return; } - BLI_ghash_remove(editnurb->keyindex, cv, NULL, MEM_freeN); -} - -static void keyIndex_delBezt(EditNurb *editnurb, BezTriple *bezt) -{ - keyIndex_delCV(editnurb, bezt); + BKE_curve_editNurb_keyIndex_delCV(editnurb->keyindex, bezt); } static void keyIndex_delBP(EditNurb *editnurb, BPoint *bp) { - keyIndex_delCV(editnurb, bp); + if (!editnurb->keyindex) { + return; + } + + BKE_curve_editNurb_keyIndex_delCV(editnurb->keyindex, bp); } static void keyIndex_delNurb(EditNurb *editnurb, Nurb *nu) @@ -283,7 +283,7 @@ static void keyIndex_delNurb(EditNurb *editnurb, Nurb *nu) a = nu->pntsu; while (a--) { - BLI_ghash_remove(editnurb->keyindex, bezt, NULL, MEM_freeN); + BKE_curve_editNurb_keyIndex_delCV(editnurb->keyindex, bezt); bezt++; } } @@ -292,7 +292,7 @@ static void keyIndex_delNurb(EditNurb *editnurb, Nurb *nu) a = nu->pntsu * nu->pntsv; while (a--) { - BLI_ghash_remove(editnurb->keyindex, bp, NULL, MEM_freeN); + BKE_curve_editNurb_keyIndex_delCV(editnurb->keyindex, bp); bp++; } } @@ -536,6 +536,7 @@ static GHash *dupli_keyIndexHash(GHash *keyindex) CVKeyIndex *newIndex = MEM_mallocN(sizeof(CVKeyIndex), "dupli_keyIndexHash index"); memcpy(newIndex, index, sizeof(CVKeyIndex)); + newIndex->orig_cv = MEM_dupallocN(index->orig_cv); BLI_ghash_insert(gh, cv, newIndex); } @@ -625,7 +626,7 @@ static void calc_keyHandles(ListBase *nurb, float *key) } } -static void calc_shapeKeys(Object *obedit) +static void calc_shapeKeys(Object *obedit, ListBase *newnurbs) { Curve *cu = (Curve *)obedit->data; @@ -637,7 +638,7 @@ static void calc_shapeKeys(Object *obedit) KeyBlock *actkey = BLI_findlink(&cu->key->block, editnurb->shapenr - 1); BezTriple *bezt, *oldbezt; BPoint *bp, *oldbp; - Nurb *nu; + Nurb *nu, *newnu; int totvert = BKE_nurbList_verts_count(&editnurb->nurbs); float (*ofs)[3] = NULL; @@ -707,20 +708,25 @@ static void calc_shapeKeys(Object *obedit) currkey = cu->key->block.first; while (currkey) { - int apply_offset = (ofs && (currkey != actkey) && (editnurb->shapenr - 1 == currkey->relative)); + const bool apply_offset = (ofs && (currkey != actkey) && (editnurb->shapenr - 1 == currkey->relative)); float *fp = newkey = MEM_callocN(cu->key->elemsize * totvert, "currkey->data"); ofp = oldkey = currkey->data; nu = editnurb->nurbs.first; + /* We need to restore to original curve into newnurb, *not* editcurve's nurbs. + * Otherwise, in case we update obdata *without* leaving editmode (e.g. viewport render), we would + * invalidate editcurve. */ + newnu = newnurbs->first; i = 0; while (nu) { if (currkey == actkey) { - int restore = actkey != cu->key->refkey; + const bool restore = actkey != cu->key->refkey; if (nu->bezt) { bezt = nu->bezt; a = nu->pntsu; + BezTriple *newbezt = newnu->bezt; while (a--) { int j; oldbezt = getKeyIndexOrig_bezt(editnurb, bezt); @@ -729,7 +735,7 @@ static void calc_shapeKeys(Object *obedit) copy_v3_v3(fp, bezt->vec[j]); if (restore && oldbezt) { - copy_v3_v3(bezt->vec[j], oldbezt->vec[j]); + copy_v3_v3(newbezt->vec[j], oldbezt->vec[j]); } fp += 3; @@ -737,16 +743,18 @@ static void calc_shapeKeys(Object *obedit) fp[0] = bezt->alfa; if (restore && oldbezt) { - bezt->alfa = oldbezt->alfa; + newbezt->alfa = oldbezt->alfa; } fp += 3; ++i; /* alphas */ bezt++; + newbezt++; } } else { bp = nu->bp; a = nu->pntsu * nu->pntsv; + BPoint *newbp = newnu->bp; while (a--) { oldbp = getKeyIndexOrig_bp(editnurb, bp); @@ -755,12 +763,13 @@ static void calc_shapeKeys(Object *obedit) fp[3] = bp->alfa; if (restore && oldbp) { - copy_v3_v3(bp->vec, oldbp->vec); - bp->alfa = oldbp->alfa; + copy_v3_v3(newbp->vec, oldbp->vec); + newbp->alfa = oldbp->alfa; } fp += 4; bp++; + newbp++; i += 2; } } @@ -1205,9 +1214,13 @@ void ED_curve_editnurb_load(Object *obedit) } } + /* We have to pass also new copied nurbs, since we want to restore original curve (without edited shapekey) + * on obdata, but *not* on editcurve itself (ED_curve_editnurb_load call does not always implies freeing + * of editcurve, e.g. when called to generate render data...). */ + calc_shapeKeys(obedit, &newnurb); + cu->nurb = newnurb; - calc_shapeKeys(obedit); ED_curve_updateAnimPaths(obedit->data); BKE_nurbList_free(&oldnurb); @@ -1228,13 +1241,11 @@ void ED_curve_editnurb_make(Object *obedit) if (actkey) { // XXX strcpy(G.editModeTitleExtra, "(Key) "); undo_editmode_clear(); - BKE_keyblock_convert_to_curve(actkey, cu, &cu->nurb); } if (editnurb) { BKE_nurbList_free(&editnurb->nurbs); - BKE_curve_editNurb_keyIndex_free(editnurb); - editnurb->keyindex = NULL; + BKE_curve_editNurb_keyIndex_free(&editnurb->keyindex); } else { editnurb = MEM_callocN(sizeof(EditNurb), "editnurb"); @@ -1249,12 +1260,16 @@ void ED_curve_editnurb_make(Object *obedit) nu = nu->next; } - if (actkey) - editnurb->shapenr = obedit->shapenr; - /* animation could be added in editmode even if there was no animdata in * object mode hence we always need CVs index be created */ init_editNurb_keyIndex(editnurb, &cu->nurb); + + if (actkey) { + editnurb->shapenr = obedit->shapenr; + /* Apply shapekey to new nurbs of editnurb, not those of original curve (and *after* we generated keyIndex), + * else we do not have valid 'original' data to properly restore curve when leaving editmode. */ + BKE_keyblock_convert_to_curve(actkey, cu, &editnurb->nurbs); + } } } @@ -1311,8 +1326,7 @@ static int separate_exec(bContext *C, wmOperator *op) ED_curve_editnurb_make(newob); newedit = newcu->editnurb; BKE_nurbList_free(&newedit->nurbs); - BKE_curve_editNurb_keyIndex_free(newedit); - newedit->keyindex = NULL; + BKE_curve_editNurb_keyIndex_free(&newedit->keyindex); BLI_movelisttolist(&newedit->nurbs, &newnurb); /* 4. put old object out of editmode and delete separated geometry */ @@ -6112,7 +6126,7 @@ static void undoCurve_to_editCurve(void *ucu, void *UNUSED(edata), void *cu_v) BKE_nurbList_free(editbase); if (undoCurve->undoIndex) { - BLI_ghash_free(editnurb->keyindex, NULL, MEM_freeN); + BKE_curve_editNurb_keyIndex_free(&editnurb->keyindex); editnurb->keyindex = dupli_keyIndexHash(undoCurve->undoIndex); } @@ -6190,8 +6204,7 @@ static void free_undoCurve(void *ucv) BKE_nurbList_free(&undoCurve->nubase); - if (undoCurve->undoIndex) - BLI_ghash_free(undoCurve->undoIndex, NULL, MEM_freeN); + BKE_curve_editNurb_keyIndex_free(&undoCurve->undoIndex); free_fcurves(&undoCurve->fcurves); free_fcurves(&undoCurve->drivers); diff --git a/source/blender/editors/curve/editcurve_paint.c b/source/blender/editors/curve/editcurve_paint.c index 4720b76342c..cf7cfec5130 100644 --- a/source/blender/editors/curve/editcurve_paint.c +++ b/source/blender/editors/curve/editcurve_paint.c @@ -48,7 +48,9 @@ #include "BIF_gl.h" #include "BIF_glutil.h" +#include "GPU_batch.h" #include "GPU_immediate.h" +#include "GPU_matrix.h" #include "curve_intern.h" @@ -90,25 +92,17 @@ static float depth_read_zbuf(const ViewContext *vc, int x, int y) } static bool depth_unproject( - const ARegion *ar, const bglMats *mats, + const ARegion *ar, const int mval[2], const double depth, float r_location_world[3]) { - double p[3]; - if (gluUnProject( - (double)ar->winrct.xmin + mval[0] + 0.5, - (double)ar->winrct.ymin + mval[1] + 0.5, - depth, mats->modelview, mats->projection, (const GLint *)mats->viewport, - &p[0], &p[1], &p[2])) - { - copy_v3fl_v3db(r_location_world, p); - return true; - } - return false; + float centx = (float)mval[0] + 0.5f; + float centy = (float)mval[1] + 0.5f; + return ED_view3d_unproject(ar, centx, centy, depth, r_location_world); } static bool depth_read_normal( - const ViewContext *vc, const bglMats *mats, const int mval[2], + const ViewContext *vc, const int mval[2], float r_normal[3]) { /* pixels surrounding */ @@ -124,7 +118,7 @@ static bool depth_read_normal( const double depth = (double)depth_read_zbuf(vc, mval_ofs[0], mval_ofs[1]); if ((depth > depths->depth_range[0]) && (depth < depths->depth_range[1])) { - if (depth_unproject(ar, mats, mval_ofs, depth, coords[i])) { + if (depth_unproject(ar, mval_ofs, depth, coords[i])) { depths_valid[i] = true; } } @@ -226,7 +220,6 @@ struct CurveDrawData { } prev; ViewContext vc; - bglMats mats; enum { CURVE_DRAW_IDLE = 0, CURVE_DRAW_PAINTING = 1, @@ -312,7 +305,7 @@ static bool stroke_elem_project( { const double depth = (double)depth_read_zbuf(&cdd->vc, mval_i[0], mval_i[1]); if ((depth > depths->depth_range[0]) && (depth < depths->depth_range[1])) { - if (depth_unproject(ar, &cdd->mats, mval_i, depth, r_location_world)) { + if (depth_unproject(ar, mval_i, depth, r_location_world)) { is_location_world_set = true; if (r_normal_world) { zero_v3(r_normal_world); @@ -321,7 +314,7 @@ static bool stroke_elem_project( if (surface_offset != 0.0f) { const float offset = cdd->project.use_surface_offset_absolute ? 1.0f : radius; float normal[3]; - if (depth_read_normal(&cdd->vc, &cdd->mats, mval_i, normal)) { + if (depth_read_normal(&cdd->vc, mval_i, normal)) { madd_v3_v3fl(r_location_world, normal, offset * surface_offset); if (r_normal_world) { copy_v3_v3(r_normal_world, normal); @@ -467,39 +460,43 @@ static void curve_draw_stroke_3d(const struct bContext *UNUSED(C), ARegion *UNUS Object *obedit = cdd->vc.obedit; Curve *cu = obedit->data; - UI_ThemeColor(TH_WIRE); - if (cu->ext2 > 0.0f) { - GLUquadricObj *qobj = gluNewQuadric(); - - gluQuadricDrawStyle(qobj, GLU_FILL); - BLI_mempool_iter iter; const struct StrokeElem *selem; const float location_zero[3] = {0}; const float *location_prev = location_zero; + float color[3]; + UI_GetThemeColor3fv(TH_WIRE, color); + + Batch *sphere = Batch_get_sphere(0); + Batch_set_builtin_program(sphere, GPU_SHADER_3D_UNIFORM_COLOR); + Batch_Uniform3fv(sphere, "color", color); + /* scale to edit-mode space */ - glPushMatrix(); - glMultMatrixf(obedit->obmat); + gpuPushMatrix(); + gpuMultMatrix3D(obedit->obmat); BLI_mempool_iternew(cdd->stroke_elem_pool, &iter); for (selem = BLI_mempool_iterstep(&iter); selem; selem = BLI_mempool_iterstep(&iter)) { - glTranslatef( + gpuTranslate3f( selem->location_local[0] - location_prev[0], selem->location_local[1] - location_prev[1], selem->location_local[2] - location_prev[2]); location_prev = selem->location_local; + const float radius = stroke_elem_radius(cdd, selem); - gluSphere(qobj, radius, 12, 8); + + gpuPushMatrix(); + gpuScaleUniform(radius); + Batch_draw(sphere); + gpuPopMatrix(); location_prev = selem->location_local; } - glPopMatrix(); - - gluDeleteQuadric(qobj); + gpuPopMatrix(); } if (stroke_len > 1) { @@ -644,7 +641,7 @@ static void curve_draw_event_add_first(wmOperator *op, const wmEvent *event) CURVE_PAINT_SURFACE_PLANE_NORMAL_VIEW, CURVE_PAINT_SURFACE_PLANE_NORMAL_SURFACE)) { - if (depth_read_normal(&cdd->vc, &cdd->mats, event->mval, normal)) { + if (depth_read_normal(&cdd->vc, event->mval, normal)) { if (cps->surface_plane == CURVE_PAINT_SURFACE_PLANE_NORMAL_VIEW) { float cross_a[3], cross_b[3]; cross_v3_v3v3(cross_a, rv3d->viewinv[2], normal); @@ -1180,8 +1177,6 @@ static int curve_draw_invoke(bContext *C, wmOperator *op, const wmEvent *event) if ((cps->depth_mode == CURVE_PAINT_PROJECT_SURFACE) && (v3d->drawtype > OB_WIRE)) { - view3d_get_transformation(cdd->vc.ar, cdd->vc.rv3d, NULL, &cdd->mats); - /* needed or else the draw matrix can be incorrect */ view3d_operator_needs_opengl(C); |