X-Git-Url: https://git.cinelerra-gg.org/git/?a=blobdiff_plain;f=cinelerra-5.1%2Fplugins%2Ftracer%2Ftracer.C;h=822b5d78b99cbf93ca8b3b5d17acf703a8c80343;hb=c9c0e07706fad701a70ee0d1ffb0fcb6304f138c;hp=be58496d7c29d346acf22e79d42e457eb16de706;hpb=f06e8ed85bd5937d704d57b65e0fb26ed288996d;p=goodguy%2Fcinelerra.git diff --git a/cinelerra-5.1/plugins/tracer/tracer.C b/cinelerra-5.1/plugins/tracer/tracer.C index be58496d..822b5d78 100644 --- a/cinelerra-5.1/plugins/tracer/tracer.C +++ b/cinelerra-5.1/plugins/tracer/tracer.C @@ -28,9 +28,13 @@ #include "bccmodels.h" #include "bccolors.h" #include "clip.h" +#include "edl.h" #include "edlsession.h" #include "filexml.h" +#include "keyframe.h" +#include "keyframes.h" #include "tracer.h" +#include "transportque.inc" #include "tracerwindow.h" #include "language.h" #include "vframe.h" @@ -56,9 +60,9 @@ TracerPoint::~TracerPoint() TracerConfig::TracerConfig() { - drag = draw = fill = 0; - radius = 0; scale = 1; - selected = 0; + drag = draw = 1; fill = 0; + feather = 0; radius = 1; + invert = 0; selected = -1; } TracerConfig::~TracerConfig() { @@ -69,8 +73,9 @@ int TracerConfig::equivalent(TracerConfig &that) if( this->drag != that.drag ) return 0; if( this->draw != that.draw ) return 0; if( this->fill != that.fill ) return 0; + if( this->feather != that.feather ) return 0; + if( this->invert != that.invert ) return 0; if( this->radius != that.radius ) return 0; - if( this->scale != that.scale ) return 0; if( this->points.size() != that.points.size() ) return 0; for( int i=0, n=points.size(); ipoints[i], *bp = that.points[i]; @@ -86,8 +91,9 @@ void TracerConfig::copy_from(TracerConfig &that) this->draw = that.draw; this->fill = that.fill; this->selected = that.selected; + this->feather = that.feather; + this->invert = that.invert; this->radius = that.radius; - this->scale = that.scale; points.remove_all_objects(); for( int i=0,n=that.points.size(); isession; float x = !session ? 0.f : session->output_w / 2.f; float y = !session ? 0.f : session->output_h / 2.f; return config.add_point(x, y); } -void Tracer::save_data(KeyFrame *keyframe) +void TracerConfig::save_data(KeyFrame *keyframe) { FileXML output; @@ -172,19 +178,20 @@ void Tracer::save_data(KeyFrame *keyframe) output.set_shared_output(keyframe->xbuf); output.tag.set_title("TRACER"); - output.tag.set_property("DRAG", config.drag); - output.tag.set_property("DRAW", config.draw); - output.tag.set_property("FILL", config.fill); - output.tag.set_property("RADIUS", config.radius); - output.tag.set_property("SCALE", config.scale); - output.tag.set_property("SELECTED", config.selected); + output.tag.set_property("DRAG", drag); + output.tag.set_property("DRAW", draw); + output.tag.set_property("FILL", fill); + output.tag.set_property("FEATHER", feather); + output.tag.set_property("RADIUS", radius); + output.tag.set_property("INVERT", invert); + output.tag.set_property("SELECTED", selected); output.append_tag(); output.append_newline(); output.tag.set_title("/TRACER"); output.append_tag(); output.append_newline(); - for( int i=0, n=config.points.size(); ixbuf); - config.points.remove_all_objects(); + points.remove_all_objects(); int result = 0; while( !(result=input.read_tag()) ) { if( input.tag.title_is("TRACER") ) { - config.drag = input.tag.get_property("DRAG", config.drag); - config.draw = input.tag.get_property("DRAW", config.draw); - config.fill = input.tag.get_property("FILL", config.fill); - config.radius = input.tag.get_property("RADIUS", config.radius); - config.scale = input.tag.get_property("SCALE", config.scale); - config.selected = input.tag.get_property("SELECTED", 0); - config.limits(); + drag = input.tag.get_property("DRAG", drag); + draw = input.tag.get_property("DRAW", draw); + fill = input.tag.get_property("FILL", fill); + feather = input.tag.get_property("FEATHER", feather); + radius = input.tag.get_property("RADIUS", radius); + invert = input.tag.get_property("INVERT", invert); + selected = input.tag.get_property("SELECTED", 0); + limits(); } else if( !strncmp(input.tag.get_title(),"POINT_",6) ) { float x = input.tag.get_property("X", 0.f); float y = input.tag.get_property("Y", 0.f); - config.add_point(x, y); + add_point(x, y); } } +} - if( !config.points.size() ) new_point(); +void Tracer::read_data(KeyFrame *keyframe) +{ + config.read_data(keyframe); +} + +void Tracer::span_keyframes(KeyFrame *src, int64_t start, int64_t end) +{ + TracerConfig src_config; + src_config.read_data(src); + KeyFrames *keyframes = (KeyFrames *)src->autos; + KeyFrame *prev = keyframes->get_prev_keyframe(start, PLAY_FORWARD); + TracerConfig prev_config; + prev_config.read_data(prev); +// Always update the first one + update_parameter(prev_config, src_config, prev); + KeyFrame *curr = (KeyFrame*)prev->next; + while( curr && curr->position < end ) { + update_parameter(prev_config, src_config, curr); + curr = (KeyFrame*)curr->next; + } +} + +void TracerPoint::update_parameter(TracerPoint *prev, TracerPoint *src) +{ + if( prev->x != src->x ) x = src->x; + if( prev->y != src->y ) y = src->y; +} + +void Tracer::update_parameter(TracerConfig &prev_config, TracerConfig &src_config, + KeyFrame *keyframe) +{ + TracerConfig dst_config; + dst_config.read_data(keyframe); + if( prev_config.drag != src_config.drag ) + dst_config.drag = src_config.drag; + if( prev_config.draw != src_config.draw ) + dst_config.draw = src_config.draw; + if( prev_config.fill != src_config.fill ) + dst_config.fill = src_config.fill; + if( prev_config.feather != src_config.feather ) + dst_config.feather = src_config.feather; + if( prev_config.invert != src_config.invert ) + dst_config.invert = src_config.invert; + if( prev_config.radius != src_config.radius ) + dst_config.radius = src_config.radius; + int src_points = src_config.points.size(); + int dst_points = dst_config.points.size(); + int prev_points = prev_config.points.size(); + int npoints = bmin(prev_points, bmin(src_points, dst_points)); + for( int i=0; iupdate_parameter(prev_point, src_point); + } + dst_config.save_data(keyframe); } void Tracer::update_gui() @@ -538,15 +607,18 @@ void FillRegion::run() void Tracer::feather(int r, double s) { - if( !r || !s ) return; - int dir = r<0 ? (r=-r, -1) : 1; - if( dir < 0 ) s = 1./s; + if( !r ) return; + int dir = r < 0 ? (r=-r, -1) : 1; int rr = r * r; int psf[rr]; // pt spot fn - int k = dir>=0 ? 0 : rr-1; - for( int i=0; i 0 ? 0xff : 0; + float p = powf(10.f, s/2); + for( int i=0; i 255 ) vv = 255; + psf[i] = vv; + } for( int i=0,n=points.size(); ix-r, xn=pt->x+r; @@ -557,12 +629,11 @@ void Tracer::feather(int r, double s) bclamp(yn, 0, h); for( int y=ys ; yx, dy = y-pt->y; int dd = dx*dx + dy*dy; if( dd >= rr ) continue; - int pix = msk_rows[y][x], v = psf[dd]; - msk_rows[y][x] = dir >= 0 ? pix+v-(pix*v)/255 : (pix*v)/255; + int v = psf[dd], px = msk_rows[y][x]; + if( dir < 0 ? pxv ) msk_rows[y][x] = v; } } } @@ -576,8 +647,7 @@ void Tracer::draw_mask() uint8_t *mp = msk_rows[y]; uint8_t *rp = frm_rows[y]; for( int x=0; xclear_frame(); + edg->black_frame(); edg_rows = edg->get_rows(); int n = config.points.size()-1; @@ -666,19 +734,19 @@ int Tracer::process_buffer(VFrame *frame, int64_t start_position, double frame_r TracePoint *pt0 = &points[0], *pt1 = &points[l2]; int cx = (pt0->x+pt1->x)/2, cy = (pt0->y+pt1->y)/2; VFrame::get_temp(msk, w, h, BC_GREY8); - msk->clear_frame(); + msk->black_frame(); msk_rows = msk->get_rows(); FillRegion fill_region(edg, msk); fill_region.fill(cx, cy); fill_region.run(); - feather(config.radius, config.scale); + feather(config.feather, config.radius); } } - if( config.fill ) + if( config.fill && msk ) draw_mask(); - if( config.draw ) + if( config.draw && edg ) draw_edge(); if( config.drag ) draw_points();