/* calculate a curve-deform path for a curve * - only called from displist.c -> do_makeDispListCurveTypes */ void calc_curvepath(Object *ob) { BevList *bl; BevPoint *bevp, *bevpn, *bevpfirst, *bevplast; PathPoint *pp; Curve *cu; Nurb *nu; Path *path; float *fp, *dist, *maxdist, xyz[3]; float fac, d = 0, fac1, fac2; int a, tot, cycl = 0; ListBase *nurbs; /* in a path vertices are with equal differences: path->len = number of verts */ /* NOW WITH BEVELCURVE!!! */ if (ob == NULL || ob->type != OB_CURVE) return; cu = ob->data; nurbs = BKE_curve_nurbs_get(cu); nu = nurbs->first; if (cu->path) free_path(cu->path); cu->path = NULL; bl = cu->bev.first; if (bl == NULL || !bl->nr) return; cu->path = path = MEM_callocN(sizeof(Path), "calc_curvepath"); /* if POLY: last vertice != first vertice */ cycl = (bl->poly != -1); if (cycl) tot = bl->nr; else tot = bl->nr - 1; path->len = tot + 1; /* exception: vector handle paths and polygon paths should be subdivided at least a factor resolu */ if (path->len < nu->resolu * SEGMENTSU(nu)) path->len = nu->resolu * SEGMENTSU(nu); dist = (float *)MEM_mallocN((tot + 1) * 4, "calcpathdist"); /* all lengths in *dist */ bevp = bevpfirst = (BevPoint *)(bl + 1); fp = dist; *fp = 0; for (a = 0; a < tot; a++) { fp++; if (cycl && a == tot - 1) sub_v3_v3v3(xyz, bevpfirst->vec, bevp->vec); else sub_v3_v3v3(xyz, (bevp + 1)->vec, bevp->vec); *fp = *(fp - 1) + len_v3(xyz); bevp++; } path->totdist = *fp; /* the path verts in path->data */ /* now also with TILT value */ pp = path->data = (PathPoint *)MEM_callocN(sizeof(PathPoint) * path->len, "pathdata"); bevp = bevpfirst; bevpn = bevp + 1; bevplast = bevpfirst + (bl->nr - 1); fp = dist + 1; maxdist = dist + tot; fac = 1.0f / ((float)path->len - 1.0f); fac = fac * path->totdist; for (a = 0; a < path->len; a++) { d = ((float)a) * fac; /* we're looking for location (distance) 'd' in the array */ while ((d >= *fp) && fp < maxdist) { fp++; if (bevp < bevplast) bevp++; bevpn = bevp + 1; if (bevpn > bevplast) { if (cycl) bevpn = bevpfirst; else bevpn = bevplast; } } fac1 = *(fp) - *(fp - 1); fac2 = *(fp) - d; fac1 = fac2 / fac1; fac2 = 1.0f - fac1; interp_v3_v3v3(pp->vec, bevp->vec, bevpn->vec, fac2); pp->vec[3] = fac1 * bevp->alfa + fac2 * bevpn->alfa; pp->radius = fac1 * bevp->radius + fac2 * bevpn->radius; pp->weight = fac1 * bevp->weight + fac2 * bevpn->weight; interp_qt_qtqt(pp->quat, bevp->quat, bevpn->quat, fac2); normalize_qt(pp->quat); pp++; } MEM_freeN(dist); }
static bool ED_object_shape_key_remove(Main *bmain, Object *ob) { KeyBlock *kb, *rkb; Key *key; key = BKE_key_from_object(ob); if (key == NULL) return false; kb = BLI_findlink(&key->block, ob->shapenr - 1); if (kb) { for (rkb = key->block.first; rkb; rkb = rkb->next) if (rkb->relative == ob->shapenr - 1) rkb->relative = 0; BLI_remlink(&key->block, kb); key->totkey--; if (key->refkey == kb) { key->refkey = key->block.first; if (key->refkey) { /* apply new basis key on original data */ switch (ob->type) { case OB_MESH: BKE_key_convert_to_mesh(key->refkey, ob->data); break; case OB_CURVE: case OB_SURF: BKE_key_convert_to_curve(key->refkey, ob->data, BKE_curve_nurbs_get(ob->data)); break; case OB_LATTICE: BKE_key_convert_to_lattice(key->refkey, ob->data); break; } } } if (kb->data) MEM_freeN(kb->data); MEM_freeN(kb); if (ob->shapenr > 1) { ob->shapenr--; } } if (key->totkey == 0) { switch (GS(key->from->name)) { case ID_ME: ((Mesh *)key->from)->key = NULL; break; case ID_CU: ((Curve *)key->from)->key = NULL; break; case ID_LT: ((Lattice *)key->from)->key = NULL; break; } BKE_libblock_free_us(bmain, key); } return true; }