/* note; only does current curvemap! */ void curvemapping_changed(CurveMapping *cumap, int rem_doubles) { CurveMap *cuma= cumap->cm+cumap->cur; CurveMapPoint *cmp= cuma->curve; rctf *clipr= &cumap->clipr; float thresh= 0.01f*(clipr->xmax - clipr->xmin); float dx= 0.0f, dy= 0.0f; int a; cumap->changed_timestamp++; /* clamp with clip */ if(cumap->flag & CUMA_DO_CLIP) { for(a=0; a<cuma->totpoint; a++) { if(cmp[a].flag & CUMA_SELECT) { if(cmp[a].x < clipr->xmin) dx= MIN2(dx, cmp[a].x - clipr->xmin); else if(cmp[a].x > clipr->xmax) dx= MAX2(dx, cmp[a].x - clipr->xmax); if(cmp[a].y < clipr->ymin) dy= MIN2(dy, cmp[a].y - clipr->ymin); else if(cmp[a].y > clipr->ymax) dy= MAX2(dy, cmp[a].y - clipr->ymax); } } for(a=0; a<cuma->totpoint; a++) { if(cmp[a].flag & CUMA_SELECT) { cmp[a].x -= dx; cmp[a].y -= dy; } } } qsort(cmp, cuma->totpoint, sizeof(CurveMapPoint), sort_curvepoints); /* remove doubles, threshold set on 1% of default range */ if(rem_doubles && cuma->totpoint>2) { for(a=0; a<cuma->totpoint-1; a++) { dx= cmp[a].x - cmp[a+1].x; dy= cmp[a].y - cmp[a+1].y; if( sqrtf(dx*dx + dy*dy) < thresh ) { if(a==0) { cmp[a+1].flag|= 2; if(cmp[a+1].flag & CUMA_SELECT) cmp[a].flag |= CUMA_SELECT; } else { cmp[a].flag|= 2; if(cmp[a].flag & CUMA_SELECT) cmp[a+1].flag |= CUMA_SELECT; } break; /* we assume 1 deletion per edit is ok */ } } if(a != cuma->totpoint-1) curvemap_remove(cuma, 2); } curvemap_make_table(cuma, clipr); }
void curvemapping_initialize(CurveMapping *cumap) { int a; if (cumap == NULL) return; for (a = 0; a < CM_TOT; a++) { if (cumap->cm[a].table == NULL) curvemap_make_table(cumap->cm + a, &cumap->clipr); } }
/* it uses a flag to prevent premul or free to happen twice */ void curvemapping_premultiply(CurveMapping *cumap, int restore) { int a; if (restore) { if (cumap->flag & CUMA_PREMULLED) { for (a = 0; a < 3; a++) { MEM_freeN(cumap->cm[a].table); cumap->cm[a].table = cumap->cm[a].premultable; cumap->cm[a].premultable = NULL; } cumap->flag &= ~CUMA_PREMULLED; } } else { if ((cumap->flag & CUMA_PREMULLED) == 0) { /* verify and copy */ for (a = 0; a < 3; a++) { if (cumap->cm[a].table == NULL) curvemap_make_table(cumap->cm + a, &cumap->clipr); cumap->cm[a].premultable = cumap->cm[a].table; cumap->cm[a].table = MEM_mallocN((CM_TABLE + 1) * sizeof(CurveMapPoint), "premul table"); memcpy(cumap->cm[a].table, cumap->cm[a].premultable, (CM_TABLE + 1) * sizeof(CurveMapPoint)); } if (cumap->cm[3].table == NULL) curvemap_make_table(cumap->cm + 3, &cumap->clipr); /* premul */ for (a = 0; a < 3; a++) { int b; for (b = 0; b <= CM_TABLE; b++) { cumap->cm[a].table[b].y = curvemap_evaluateF(cumap->cm + 3, cumap->cm[a].table[b].y); } } cumap->flag |= CUMA_PREMULLED; } } }
/* works with curve 'cur' */ float curvemapping_evaluateF(CurveMapping *cumap, int cur, float value) { CurveMap *cuma = cumap->cm + cur; /* allocate or bail out */ if (cuma->table == NULL) { curvemap_make_table(cuma, &cumap->clipr); if (cuma->table == NULL) return 1.0f - value; } return curvemap_evaluateF(cuma, value); }
/* note; only does current curvemap! */ void curvemapping_changed(CurveMapping *cumap, const bool rem_doubles) { CurveMap *cuma = cumap->cm + cumap->cur; CurveMapPoint *cmp = cuma->curve; rctf *clipr = &cumap->clipr; float thresh = 0.01f * BLI_rctf_size_x(clipr); float dx = 0.0f, dy = 0.0f; int a; cumap->changed_timestamp++; /* clamp with clip */ if (cumap->flag & CUMA_DO_CLIP) { for (a = 0; a < cuma->totpoint; a++) { if (cmp[a].flag & CUMA_SELECT) { if (cmp[a].x < clipr->xmin) dx = min_ff(dx, cmp[a].x - clipr->xmin); else if (cmp[a].x > clipr->xmax) dx = max_ff(dx, cmp[a].x - clipr->xmax); if (cmp[a].y < clipr->ymin) dy = min_ff(dy, cmp[a].y - clipr->ymin); else if (cmp[a].y > clipr->ymax) dy = max_ff(dy, cmp[a].y - clipr->ymax); } } for (a = 0; a < cuma->totpoint; a++) { if (cmp[a].flag & CUMA_SELECT) { cmp[a].x -= dx; cmp[a].y -= dy; } } /* ensure zoom-level respects clipping */ if (BLI_rctf_size_x(&cumap->curr) > BLI_rctf_size_x(&cumap->clipr)) { cumap->curr.xmin = cumap->clipr.xmin; cumap->curr.xmax = cumap->clipr.xmax; } if (BLI_rctf_size_y(&cumap->curr) > BLI_rctf_size_y(&cumap->clipr)) { cumap->curr.ymin = cumap->clipr.ymin; cumap->curr.ymax = cumap->clipr.ymax; } } qsort(cmp, cuma->totpoint, sizeof(CurveMapPoint), sort_curvepoints); /* remove doubles, threshold set on 1% of default range */ if (rem_doubles && cuma->totpoint > 2) { for (a = 0; a < cuma->totpoint - 1; a++) { dx = cmp[a].x - cmp[a + 1].x; dy = cmp[a].y - cmp[a + 1].y; if (sqrtf(dx * dx + dy * dy) < thresh) { if (a == 0) { cmp[a + 1].flag |= CUMA_HANDLE_VECTOR; if (cmp[a + 1].flag & CUMA_SELECT) cmp[a].flag |= CUMA_SELECT; } else { cmp[a].flag |= CUMA_HANDLE_VECTOR; if (cmp[a].flag & CUMA_SELECT) cmp[a + 1].flag |= CUMA_SELECT; } break; /* we assume 1 deletion per edit is ok */ } } if (a != cuma->totpoint - 1) curvemap_remove(cuma, 2); } curvemap_make_table(cuma, clipr); }