[xiph-commits] r12766 - trunk/sushivision

xiphmont at svn.xiph.org xiphmont at svn.xiph.org
Thu Mar 15 20:18:34 PDT 2007


Author: xiphmont
Date: 2007-03-15 20:18:33 -0700 (Thu, 15 Mar 2007)
New Revision: 12766

Modified:
   trunk/sushivision/panel-xy.c
   trunk/sushivision/panel-xy.h
Log:
Incremental to move from work->home.  More XY implementation.



Modified: trunk/sushivision/panel-xy.c
===================================================================
--- trunk/sushivision/panel-xy.c	2007-03-15 23:32:36 UTC (rev 12765)
+++ trunk/sushivision/panel-xy.c	2007-03-16 03:18:33 UTC (rev 12766)
@@ -130,9 +130,9 @@
     
     /* by objective */
     for(j=0;j<p->objectives;j++){
-      if(xy->data_head[j] && xy->data_length[j] && !mapping_inactive_p(xy->mappings+j)){
+      if(xy->x_vec[j] && xy->y_vec[j] && !mapping_inactive_p(xy->mappings+j)){
 	
-	int dw = xy->data_length[j];
+	int dw = xy->data_v.pixels;
 	double alpha = slider_get_value(xy->alpha_scale[j],0);
 	int linetype = xy->linetype[j];
 	int pointtype = xy->pointtype[j];
@@ -142,13 +142,8 @@
 	double yv[dw];
 	
 	// copy the list data over
-	xy_data_t *d = xy->data_head[j];
-	i=0;
-	while(d){
-	  xv[i] = d->xval;
-	  yv[i] = d->yval;
-	  d=d->next;
-	}
+	memcpy(xv,xy->x_vec[j],sizeof(xv));
+	memcpy(yv,xy->y_vec[j],sizeof(yv));
 	gdk_threads_leave();
 
 	/* by x */
@@ -181,7 +176,13 @@
 	  
 	  for(i=1;i<dw;i++){
 	    
-	    if(!isnan(yv[i-1]) && !isnan(yv[i])){	
+	    if(!isnan(yv[i-1]) && !isnan(yv[i]) &&
+	       !isnan(xv[i-1]) && !isnan(xv[i]) &&
+	       !(xv[i-1] < 0 && xv[i] < 0) &&
+	       !(yv[i-1] < 0 && yv[i] < 0) &&
+	       !(xv[i-1] > pw && xv[i] > pw) &&
+	       !(yv[i-1] > ph && yv[i] > ph)){
+	      
 	      cairo_move_to(c,xv[i-1],yv[i-1]);
 	      cairo_line_to(c,xv[i],yv[i]);
 	      cairo_stroke(c);
@@ -194,7 +195,13 @@
 	  cairo_set_line_width(c,1.);
 
 	  for(i=0;i<dw;i++){
-	    if(!isnan(yv[i])){
+	    if(!isnan(yv[i]) && 
+	       !isnan(xv[i]) && 
+	       !xv[i]<-10 &&
+	       !yv[i]<-10 &&
+	       !xv[i]-10>pw &&
+	       !yv[i]-10>ph){
+
 	      double xx,yy;
 	      xx = xv[i];
 	      yy = yv[i];
@@ -333,6 +340,96 @@
   }
 }
 
+// call with lock
+static double _determine_rerender_metric(sushiv_panel_t *p, int half){
+  sushiv_panelxy_t *xy = p->subtype->xy;
+  int on = p->objectives;
+  double pw = p->private->graph->allocation.width;
+  double ph = p->private->graph->allocation.height;
+  int dw = xy->data_v.pixels;
+  int off = (half?2;1);
+
+  // if this is a discrete data set, size/view changes cannot affect
+  // the data spacing; that's set by the discrete scale
+  if(p->x_d->type != SUSHIV_DIM_CONTINUOUS) return -1;
+
+  double xscale = scalespace_pixel(&xy->x,1.) - scalespace_pixel(&xy->x,0.);
+  double yscale = scalespace_pixel(&xy->y,1.) - scalespace_pixel(&xy->y,0.);
+
+  // by plane, look at the spacing between visible x/y points
+  double max = -1;
+  for(i=0;i<on;i++){
+
+    if(xy->x_vec[j] && xy->y_vec[j] && !mapping_inactive_p(xy->mappings+i)){
+      double xacc = 0;
+      double yacc = 0;
+      double count = 0;
+      double *x = p->x_vec[i];
+      double *y = p->y_vec[i];
+      
+      for(j = off; j+off<=dw, j+=off){
+	if(!isnan(x[i-off]) &&
+	   !isnan(y[i-off]) &&
+	   !isnan(x[i]) &&
+	   !isnan(y[i]) &&
+	   !(x[i-off] < 0 && x[i] < 0) &&
+	   !(y[i-off] < 0 && y[i] < 0) &&
+	   !(x[i-off] > pw && x[i] > pw) &&
+	   !(y[i-off] > ph && y[i] > ph)){
+	  
+	  xacc += (x[i-off]-x[i]) * (x[i-off]-x[i]);
+	  yacc += (y[i-off]-y[i]) * (y[i-off]-y[i]);
+	  count++;
+	}
+      }
+
+      acc = sqrt(xacc*xscale*xscale + yacc*yscale*yscale);
+
+      if(count>0)
+	if(acc/count > max) max = acc/count;
+    }
+  }
+
+  return max;
+
+}
+
+// call while locked
+static int _mark_recompute_by_metric_change(sushiv_panel_t *p, int recursing){
+  // discrete val dimensions are immune to rerender by metric changes
+  if(p->x_d->type != SUSHIV_DIM_CONTINUOUS) return 0; 
+
+  sushiv_panelxy_t *xy = p->subtype->xy;
+  double target = (double) p->private->oversample_n / p->private->oversample_d;
+  double full =  _determine_rerender_metric(p, 0);
+  
+  if(!recursing) xy->request_scaling = 0;
+
+  if(full > target){
+    // we want to halve the sample spacing.  But first make sure we're
+    // not looping due to uncertainties in the metric.
+    if(xy->request_scaling != -1){
+      xy->request_scaling = 1; // double pixels, halve spacing
+      _sushiv_panel_dirty_plot(p); // trigger recompute
+      return 1;
+    }
+  } else {
+    double half =  _determine_rerender_metric(p, 1);
+    if(half < target){
+      // we want to double the sample spacing.  But first make sure we're
+      // not looping due to uncertainties in the metric.
+      if(xy->request_scaling != 1){
+	xy->request_scaling = -1; // halve pixels, double spacing
+	_sushiv_panel_dirty_plot(p); // trigger recompute
+	return 1;
+      }
+    }
+  }
+
+  xy->request_scaling = 0;
+  return 0;
+}
+
 static void mapchange_callback_xy(GtkWidget *w,gpointer in){
   sushiv_objective_list_t *optr = (sushiv_objective_list_t *)in;
   sushiv_panel_t *p = optr->p;
@@ -348,11 +445,14 @@
   solid_set_func(&xy->mappings[onum],pos);
   slider_set_gradient(xy->alpha_scale[onum], &xy->mappings[onum]);
   
-  _sushiv_panel_dirty_map(p);
+  // a map view size change may trigger a progressive up/down render,
+  // but will at least cause a remap
+  if(!_mark_recompute_by_metric_change(p,0))
+    _sushiv_panel_dirty_map(p);
   _sushiv_panel_dirty_legend(p);
   _sushiv_undo_resume(p->sushi);
 }
-
+XXX
 static void alpha_callback_xy(void * in, int buttonstate){
   sushiv_objective_list_t *optr = (sushiv_objective_list_t *)in;
   sushiv_panel_t *p = optr->p;
@@ -439,9 +539,14 @@
 			      xy->y_scale->legend);
 
   }
+XXX
+  // a map view size change may trigger a progressive up/down render,
+  // but will at least cause a remap
+  if(_determine_rerender_by_metric(p))
+    _mark_recompute_xy(p);
+  else
+    _sushiv_panel_dirty_map(p);
 
-  //redraw the plot
-  _sushiv_panel_dirty_map(p);
   if(buttonstate == 2)
     _sushiv_undo_resume(p->sushi);
 }
@@ -474,159 +579,59 @@
   } 
 }
 
-static void compute_xy_one(sushiv_panel_t *p, 
-			   double *dim_vals,
-			   xy_data_t **out,
-			   _sushiv_bythread_cache_xy *c){
-  sushiv_panelxy_t *xy = p->subtype->xy;
-  double work[w];
-  int i,j,fn=p->sushi->functions;
-
-  /* by function */
-  for(i=0;i<fn;i++){
-    if(c->call[i]){
-      sushiv_function_t *f = p->sushi->function_list[i];
-      int step = f->outputs;
-      double *fout = c->fout[i];
-      
-      c->call[i](dim_vals,fout);
-    }
-  }
-
-  /* process function output by objective */
-  /* XY panels currently only care about the X and Y output value; in the
-     future, Z, etc may also be relevant */
-  for(i=0;i<p->objectives;i++){
-    sushiv_objective_t *o = p->objective_list[i].o;
-    int xoff = o->private->x_fout;
-    int yoff = o->private->y_fout;
-    sushiv_function_t *xf = o->private->x_func;
-    sushiv_function_t *yf = o->private->y_func;
-XXXX
-    if(xf && yf){
-      int step = f->outputs;
-      double *fout = c->fout[f->number]+offset;
-      
-      /* map result from function output to objective output */
-      for(j=0;j<w;j++){
-	work[j] = *fout;
-	fout+=step;
-      }
-      
-      gdk_threads_enter (); // misuse me as a global mutex
-      if(p->private->plot_serialno == serialno){
-	/* store result in panel */
-	memcpy(p1->data_vec[i],work,w*sizeof(*work));
-	gdk_threads_leave (); // misuse me as a global mutex 
-      }else{
-	gdk_threads_leave (); // misuse me as a global mutex 
-	break;
-      }
-    }
-  }
-}
-
 static void compute_xy(sushiv_panel_t *p, 
-		       int serialno,
 		       int x_d, 
 		       scalespace sxi,
-		       int w, 
 		       double *dim_vals,
+		       double **x_vec,
+		       double **y_vec,
 		       _sushiv_bythread_cache_1d *c){
-  sushiv_panel1d_t *p1 = p->subtype->p1;
-  double work[w];
+  sushiv_panelxy_t *xy = p->subtype->xy;
   int i,j,fn=p->sushi->functions;
+  int w = sxi.pixels;
 
-  /* by function */
-  for(i=0;i<fn;i++){
-    if(c->call[i]){
-      sushiv_function_t *f = p->sushi->function_list[i];
-      int step = f->outputs;
-      double *fout = c->fout[i];
-      
-      /* by x */
-      for(j=0;j<w;j++){
-	dim_vals[x_d] = scalespace_value(&sxi,j);
-	c->call[i](dim_vals,fout);
-	fout+=step;
+  /* by x */
+  for(j=0;j<w;j++){
+    dim_vals[x_d] = scalespace_value(&sxi,j);
+
+    /* by function */
+    for(i=0;i<fn;i++){
+      if(c->call[i]){
+	sushiv_function_t *f = p->sushi->function_list[i];
+	double *fout = c->fout[i];
+      	c->call[i](dim_vals,fout);
       }
     }
-  }
 
-  /* process function output by objective */
-  /* 1d panels currently only care about the Y output value; in the
-     future, Z may also be relevant */
-  for(i=0;i<p->objectives;i++){
-    sushiv_objective_t *o = p->objective_list[i].o;
-    int offset = o->private->y_fout;
-    sushiv_function_t *f = o->private->y_func;
-    if(f){
-      int step = f->outputs;
-      double *fout = c->fout[f->number]+offset;
-      
-      /* map result from function output to objective output */
-      for(j=0;j<w;j++){
-	work[j] = *fout;
-	fout+=step;
-      }
-      
-      gdk_threads_enter (); // misuse me as a global mutex
-      if(p->private->plot_serialno == serialno){
-	/* store result in panel */
-	memcpy(p1->data_vec[i],work,w*sizeof(*work));
-	gdk_threads_leave (); // misuse me as a global mutex 
-      }else{
-	gdk_threads_leave (); // misuse me as a global mutex 
-	break;
-      }
+    /* process function output by objective */
+    /* xy panels currently only care about the XY output values; in the
+       future, Z may also be relevant */
+    for(i=0;i<p->objectives;i++){
+      sushiv_objective_t *o = p->objective_list[i].o;
+      int xoff = o->private->x_fout;
+      int yoff = o->private->y_fout;
+      sushiv_function_t *xf = o->private->x_func;
+      sushiv_function_t *yf = o->private->y_func;
+      x_vec[j] = c->fout[xf->number][xoff];
+      y_vec[j] = c->fout[yf->number][yoff];
     }
   }
 }
 
 // call only from main gtk thread
-void _mark_recompute_1d(sushiv_panel_t *p){
+void _mark_recompute_xy(sushiv_panel_t *p){
   if(!p->private->realized) return;
-  sushiv_panel1d_t *p1 = p->subtype->p1;
+  sushiv_panelxy_t *xy = p->subtype->xy;
   Plot *plot = PLOT(p->private->graph);
   int w = plot->w.allocation.width;
   int h = plot->w.allocation.height;
   int dw = w;
-  sushiv_panel_t *link = (p1->link_x ? p1->link_x : p1->link_y);
-  sushiv_panel2d_t *p2 = (link?link->subtype->p2:NULL);
   int i,j;
 
-  if(p1->link_x){
-    dw = p2->x_v.pixels;
-    p1->x_d = p2->x_d;
-    p1->x_scale = p2->x_scale;
-  }
-  if(p1->link_y){
-    dw = p2->y_v.pixels;
-    p1->x_d = p2->y_d;
-    p1->x_scale = p2->y_scale;
-  }
-
+XXXX
   if(plot && GTK_WIDGET_REALIZED(GTK_WIDGET(plot))){
-    if(p1->flip){
       dw = _sushiv_dimension_scales(p1->x_d, 
-				    p1->x_d->bracket[1],
 				    p1->x_d->bracket[0],
-				    h,dw * p->private->oversample_n / p->private->oversample_d,
-				    plot->scalespacing,
-				    p1->x_d->name,
-				    &p1->x,
-				    &p1->x_v,
-				    &p1->x_i);
-      
-      p1->y = scalespace_linear(p1->range_bracket[0],
-				p1->range_bracket[1],
-				w,
-				plot->scalespacing,
-				p1->range_scale->legend);
-      
-    }else{
-      dw = _sushiv_dimension_scales(p1->x_d, 
-				    p1->x_d->bracket[0],
 				    p1->x_d->bracket[1],
 				    w,dw * p->private->oversample_n / p->private->oversample_d,
 				    plot->scalespacing,

Modified: trunk/sushivision/panel-xy.h
===================================================================
--- trunk/sushivision/panel-xy.h	2007-03-15 23:32:36 UTC (rev 12765)
+++ trunk/sushivision/panel-xy.h	2007-03-16 03:18:33 UTC (rev 12766)
@@ -18,17 +18,7 @@
  *
  * 
  */
-tyedef xy_data_t struct xy_data;
 
-struct xy_data{
-  xy_data_t *p;
-  xy_data_t *n;
-
-  double dimx;
-  double xval;
-  double yval;
-};
-
 typedef struct sushiv_panelxy {
   GtkWidget *graph_table;
   GtkWidget *obj_table;
@@ -37,9 +27,6 @@
   int panel_w;
   int panel_h;
 
-  xy_data_t **data_head;
-  int *data_length;
-
   // panel x/y don't correspond to dimensions like on other panels
   scalespace x;
   scalespace y;
@@ -53,9 +40,11 @@
   double x_val;
   double y_val;
   
-
   scalespace data_v; // the x scale aligned to data vector's bins
   scalespace data_i; // the 'counting' scale used to iterate for compute
+  double **x_vec;
+  double **y_vec;
+  double scale_metric;
 
   mapping *mappings;
   int *linetype;



More information about the commits mailing list