/*integrate over some volume around particle (ax, ay, az), if there is substrate, add this to potential*/ static gdouble integrate_lj_substrate(GwyDataField *lfield, gdouble ax, gdouble ay, gdouble az, gdouble size) { /*make l-j only from idealistic substrate now*/ gdouble zval, sigma, dist; sigma = 1.2*size; //empiric zval = gwy_data_field_get_val(lfield, CLAMP(gwy_data_field_rtoi(lfield, ax), 0, gwy_data_field_get_xres(lfield)-1), CLAMP(gwy_data_field_rtoi(lfield, ay), 0, gwy_data_field_get_yres(lfield)-1)); dist = sqrt((az-zval)*(az-zval)); //printf("%g %g \n", dist, (pow(sigma, 12)/45.0/pow(dist, 9) - pow(sigma, 6)/6.0/pow(dist, 3))); return 1e18*(pow(sigma, 12)/45.0/pow(dist, 9) - pow(sigma, 6)/6.0/pow(dist, 3)); }
static void preview_selection_updated(GwySelection *selection, G_GNUC_UNUSED gint id, FacetsControls *controls) { GwyDataField *dfield; gdouble theta, phi, xy[2]; gint i, j; if (controls->in_update) return; dfield = GWY_DATA_FIELD(gwy_container_get_object_by_name(controls->mydata, "/0/data")); if (!gwy_selection_get_object(selection, 0, xy)) return; j = gwy_data_field_rtoj(dfield, xy[0]); i = gwy_data_field_rtoi(dfield, xy[1]); dfield = GWY_DATA_FIELD(gwy_container_get_object_by_name(controls->fdata, "/theta")); theta = gwy_data_field_get_val(dfield, j, i); dfield = GWY_DATA_FIELD(gwy_container_get_object_by_name(controls->fdata, "/phi")); phi = gwy_data_field_get_val(dfield, j, i); facet_view_select_angle(controls, theta, phi); }
static void apply(GwyUnitoolState *state) { static const gchar *field_names[] = { "/0/data", "/0/mask", "/0/show" }; GtkWidget *data_window; GwyDataView *data_view; GwyContainer *data; GwyDataField *dfield; gint ximin, yimin, ximax, yimax; gdouble sel[4]; gsize i; if (!gwy_vector_layer_get_selection(state->layer, sel)) return; data_view = GWY_DATA_VIEW(GWY_DATA_VIEW_LAYER(state->layer)->parent); data = gwy_data_view_get_data(data_view); data = GWY_CONTAINER(gwy_serializable_duplicate(G_OBJECT(data))); gwy_app_clean_up_data(data); for (i = 0; i < G_N_ELEMENTS(field_names); i++) { if (!gwy_container_gis_object_by_name(data, field_names[i], (GObject**)&dfield)) continue; ximin = gwy_data_field_rtoj(dfield, sel[0]); yimin = gwy_data_field_rtoi(dfield, sel[1]); ximax = gwy_data_field_rtoj(dfield, sel[2]) + 1; yimax = gwy_data_field_rtoi(dfield, sel[3]) + 1; gwy_data_field_set_xreal(dfield, (ximax - ximin) *gwy_data_field_get_xreal(dfield) /gwy_data_field_get_xres(dfield)); gwy_data_field_set_yreal(dfield, (yimax - yimin) *gwy_data_field_get_yreal(dfield) /gwy_data_field_get_yres(dfield)); gwy_data_field_resize(dfield, ximin, yimin, ximax, yimax); } data_window = gwy_app_data_window_create(data); gwy_app_data_window_set_untitled(GWY_DATA_WINDOW(data_window), NULL); gwy_vector_layer_unselect(state->layer); gwy_data_view_update(data_view); gwy_debug("%d %d", gwy_data_field_get_xres(dfield), gwy_data_field_get_yres(dfield)); }
static void prof_update_curve(ProfControls *controls, gint i) { GwyGraphCurveModel *gcmodel; gdouble xy[4], h; gint xl0, yl0, xl1, yl1; gint n, lineres; gchar *desc; g_return_if_fail(gwy_selection_get_object(controls->selection, i, xy)); /* The ω=0 pixel is always at res/2, for even dimensions it means it is * shifted half-a-pixel to the right from the precise centre. */ xl0 = gwy_data_field_get_xres(controls->psdffield)/2; yl0 = gwy_data_field_get_yres(controls->psdffield)/2; xl1 = floor(gwy_data_field_rtoj(controls->psdffield, xy[0])); yl1 = floor(gwy_data_field_rtoi(controls->psdffield, xy[1])); xy[0] += gwy_data_field_get_xoffset(controls->psdffield); xy[1] += gwy_data_field_get_yoffset(controls->psdffield); h = hypot(controls->hx*xy[0], controls->hy*xy[1])/hypot(xy[0], xy[1]); if (!controls->args->fixres) { lineres = GWY_ROUND(hypot(abs(xl0 - xl1) + 1, abs(yl0 - yl1) + 1)); lineres = MAX(lineres, MIN_RESOLUTION); } else lineres = controls->args->resolution; gwy_data_field_get_profile(controls->psdffield, controls->line, xl0, yl0, xl1, yl1, lineres, 1, controls->args->interpolation); gwy_data_line_multiply(controls->line, h); n = gwy_graph_model_get_n_curves(controls->gmodel); if (i < n) { gcmodel = gwy_graph_model_get_curve(controls->gmodel, i); } else { gcmodel = gwy_graph_curve_model_new(); g_object_set(gcmodel, "mode", GWY_GRAPH_CURVE_LINE, "color", gwy_graph_get_preset_color(i), NULL); gwy_graph_model_add_curve(controls->gmodel, gcmodel); g_object_unref(gcmodel); } gwy_graph_curve_model_set_data_from_dataline(gcmodel, controls->line, 0, 0); desc = g_strdup_printf(_("PSDF %.0f°"), 180.0/G_PI*atan2(-xy[1], xy[0])); g_object_set(gcmodel, "description", desc, NULL); g_free(desc); }
static void noncontact_guess(GwyDataField *data, gdouble height, gdouble radius, G_GNUC_UNUSED gdouble *params, gint *xres, gint *yres) { gdouble angle = 70*G_PI/180; gdouble xreal = 2*(height+radius)/tan(angle); gint xpix = gwy_data_field_rtoi(data, xreal); xpix = CLAMP(xpix, 10, 500); *xres = xpix; *yres = xpix; }
static void pyramide_guess(GwyDataField *data, gdouble height, gdouble radius, gdouble *params, gint *xres, gint *yres) { gdouble angle = params[1]; gdouble xreal = 2*(height+radius)/tan(angle); gint xpix = gwy_data_field_rtoi(data, xreal); xpix = CLAMP(xpix, 10, 500); *xres = xpix; *yres = xpix; }
static void do_level(GwyContainer *data, GwyRunType run, LevelMethod level_type, const gchar *dialog_title) { GwyDataField *dfield; GwyDataField *mfield; LevelArgs args; gdouble c, bx, by; GQuark quark; gint id; g_return_if_fail(run & LEVEL_RUN_MODES); gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD_KEY, &quark, GWY_APP_DATA_FIELD, &dfield, GWY_APP_DATA_FIELD_ID, &id, GWY_APP_MASK_FIELD, &mfield, 0); g_return_if_fail(dfield && quark); load_args(gwy_app_settings_get(), &args); if (run != GWY_RUN_IMMEDIATE && mfield) { gboolean ok = level_dialog(&args, dialog_title); save_args(gwy_app_settings_get(), &args); if (!ok) return; } if (args.masking == GWY_MASK_IGNORE) mfield = NULL; if (mfield) { if (args.masking == GWY_MASK_EXCLUDE) { mfield = gwy_data_field_duplicate(mfield); gwy_data_field_multiply(mfield, -1.0); gwy_data_field_add(mfield, 1.0); } else g_object_ref(mfield); } gwy_app_undo_qcheckpoint(data, quark, NULL); if (mfield) gwy_data_field_area_fit_plane(dfield, mfield, 0, 0, gwy_data_field_get_xres(dfield), gwy_data_field_get_yres(dfield), &c, &bx, &by); else gwy_data_field_fit_plane(dfield, &c, &bx, &by); switch (level_type) { case LEVEL_SUBTRACT: c = -0.5*(bx*gwy_data_field_get_xres(dfield) + by*gwy_data_field_get_yres(dfield)); gwy_data_field_plane_level(dfield, c, bx, by); break; case LEVEL_ROTATE: bx = gwy_data_field_rtoj(dfield, bx); by = gwy_data_field_rtoi(dfield, by); gwy_data_field_plane_rotate(dfield, atan2(bx, 1), atan2(by, 1), GWY_INTERPOLATION_LINEAR); gwy_debug("b = %g, alpha = %g deg, c = %g, beta = %g deg", bx, 180/G_PI*atan2(bx, 1), by, 180/G_PI*atan2(by, 1)); break; default: g_assert_not_reached(); break; } gwy_app_channel_log_add_proc(data, id, id); gwy_data_field_data_changed(dfield); gwy_object_unref(mfield); }
static void preview(DepositControls *controls, DepositArgs *args) { GwyDataField *dfield, *lfield, *zlfield, *zdfield; gint xres, yres, oxres, oyres; gint add, i, ii, m, k; gdouble size, width; gint xdata[10000]; gint ydata[10000]; gdouble disizes[10000]; gdouble rdisizes[10000]; gdouble rx[10000]; gdouble ry[10000]; gdouble rz[10000]; gdouble ax[10000]; gdouble ay[10000]; gdouble az[10000]; gdouble vx[10000]; gdouble vy[10000]; gdouble vz[10000]; gdouble fx[10000]; gdouble fy[10000]; gdouble fz[10000]; gint xpos, ypos, ndata, too_close; gdouble disize, mdisize; gdouble xreal, yreal, oxreal, oyreal; gdouble diff; gdouble mass = 1; gint presetval; gint nloc, maxloc = 1; gint max = 5000000; gdouble rxv, ryv, rzv, timestep = 3e-7; //5e-7 deposit_dialog_update_values(controls, args); dfield = GWY_DATA_FIELD(gwy_container_get_object_by_name(controls->mydata, "/0/data")); gwy_container_set_object_by_name(controls->mydata, "/0/data", gwy_data_field_duplicate(controls->old_dfield)); dfield = GWY_DATA_FIELD(gwy_container_get_object_by_name(controls->mydata, "/0/data")); if (controls->in_init) { gwy_data_field_data_changed(dfield); while (gtk_events_pending()) gtk_main_iteration(); return; } oxres = gwy_data_field_get_xres(dfield); oyres = gwy_data_field_get_yres(dfield); oxreal = gwy_data_field_get_xreal(dfield); oyreal = gwy_data_field_get_yreal(dfield); diff = oxreal/oxres/10; size = args->size*5e-9; // width = args->width*5e-9 + 2*size; //increased manually to fill boundaries width = 2*size; add = gwy_data_field_rtoi(dfield, size + width); mdisize = gwy_data_field_rtoi(dfield, size); xres = oxres + 2*add; yres = oyres + 2*add; xreal = oxreal + 2*(size+width); yreal = oyreal + 2*(size+width); // printf("For field of size %g and particle nominak %g, real %g (%g), the final size will change from %d to %d\n", // gwy_data_field_get_xreal(dfield), args->size, size, disize, oxres, xres); /*make copy of datafield, with mirrored boundaries*/ lfield = gwy_data_field_new(xres, yres, gwy_data_field_itor(dfield, xres), gwy_data_field_jtor(dfield, yres), TRUE); gwy_data_field_area_copy(dfield, lfield, 0, 0, oxres, oyres, add, add); gwy_data_field_invert(dfield, 1, 0, 0); gwy_data_field_area_copy(dfield, lfield, 0, oyres-add-1, oxres, add, add, 0); gwy_data_field_area_copy(dfield, lfield, 0, 0, oxres, add, add, yres-add-1); gwy_data_field_invert(dfield, 1, 0, 0); gwy_data_field_invert(dfield, 0, 1, 0); gwy_data_field_area_copy(dfield, lfield, oxres-add-1, 0, add, oyres, 0, add); gwy_data_field_area_copy(dfield, lfield, 0, 0, add, oyres, xres-add-1, add); gwy_data_field_invert(dfield, 0, 1, 0); gwy_data_field_invert(dfield, 1, 1, 0); gwy_data_field_area_copy(dfield, lfield, oxres-add-1, oyres-add-1, add, add, 0, 0); gwy_data_field_area_copy(dfield, lfield, 0, 0, add, add, xres-add-1, yres-add-1); gwy_data_field_area_copy(dfield, lfield, oxres-add-1, 0, add, add, 0, yres-add-1); gwy_data_field_area_copy(dfield, lfield, 0, oyres-add-1, add, add, xres-add-1, 0); gwy_data_field_invert(dfield, 1, 1, 0); zlfield = gwy_data_field_duplicate(lfield); zdfield = gwy_data_field_duplicate(dfield); /*determine number of spheres necessary for given coverage*/ for (i=0; i<10000; i++) { ax[i] = ay[i] = az[i] = vx[i] = vy[i] = vz[i] = 0; } srand ( time(NULL) ); ndata = 0; /* for test only */ /* disize = mdisize; xpos = oxres/2 - 2*disize; ypos = oyres/2; xdata[ndata] = xpos; ydata[ndata] = ypos; disizes[ndata] = disize; rdisizes[ndata] = size; rx[ndata] = (gdouble)xpos*oxreal/(gdouble)oxres; ry[ndata] = (gdouble)ypos*oyreal/(gdouble)oyres; rz[ndata] = 2.0*gwy_data_field_get_val(lfield, xpos, ypos) + rdisizes[ndata]; ndata++; xpos = oxres/2 + 2*disize; ypos = oyres/2; xdata[ndata] = xpos; ydata[ndata] = ypos; disizes[ndata] = disize; rdisizes[ndata] = size; rx[ndata] = (gdouble)xpos*oxreal/(gdouble)oxres; ry[ndata] = (gdouble)ypos*oyreal/(gdouble)oyres; rz[ndata] = 2.0*gwy_data_field_get_val(lfield, xpos, ypos) + rdisizes[ndata]; ndata++; */ /*end of test*/ i = 0; presetval = args->coverage*10; while (ndata < presetval && i<max) { //disize = mdisize*(0.8+(double)(rand()%20)/40.0); disize = mdisize; xpos = disize+(rand()%(xres-2*(gint)(disize+1))) + 1; ypos = disize+(rand()%(yres-2*(gint)(disize+1))) + 1; i++; { too_close = 0; /*sync real to integer positions*/ for (k=0; k<ndata; k++) { if (((xpos-xdata[k])*(xpos-xdata[k]) + (ypos-ydata[k])*(ypos-ydata[k]))<(4*disize*disize)) { too_close = 1; break; } } if (too_close) continue; if (ndata>=10000) { break; } xdata[ndata] = xpos; ydata[ndata] = ypos; disizes[ndata] = disize; rdisizes[ndata] = size; rx[ndata] = (gdouble)xpos*oxreal/(gdouble)oxres; ry[ndata] = (gdouble)ypos*oyreal/(gdouble)oyres; //printf("surface at %g, particle size %g\n", gwy_data_field_get_val(lfield, xpos, ypos), rdisizes[ndata]); rz[ndata] = 1.0*gwy_data_field_get_val(lfield, xpos, ypos) + rdisizes[ndata]; //2 ndata++; } }; // if (i==max) printf("Maximum reached, only %d particles depositd instead of %d\n", ndata, presetval); // else printf("%d particles depositd\n", ndata); /*refresh shown data and integer positions (necessary in md calculation)*/ gwy_data_field_copy(zlfield, lfield, 0); showit(lfield, zdfield, rdisizes, rx, ry, rz, xdata, ydata, ndata, oxres, oxreal, oyres, oyreal, add, xres, yres); gwy_data_field_area_copy(lfield, dfield, add, add, oxres, oyres, 0, 0); gwy_data_field_data_changed(dfield); for (i=0; i<(20*args->revise); i++) { // printf("###### step %d of %d ##########\n", i, (gint)(20*args->revise)); /*try to add some particles if necessary, do this only for first half of molecular dynamics*/ if (ndata<presetval && i<(10*args->revise)) { ii = 0; nloc = 0; while (ndata < presetval && ii<(max/1000) && nloc<maxloc) { disize = mdisize; xpos = disize+(rand()%(xres-2*(gint)(disize+1))) + 1; ypos = disize+(rand()%(yres-2*(gint)(disize+1))) + 1; ii++; { too_close = 0; rxv = ((gdouble)xpos*oxreal/(gdouble)oxres); ryv = ((gdouble)ypos*oyreal/(gdouble)oyres); rzv = gwy_data_field_get_val(zlfield, xpos, ypos) + 5*size; for (k=0; k<ndata; k++) { if (((rxv-rx[k])*(rxv-rx[k]) + (ryv-ry[k])*(ryv-ry[k]) + (rzv-rz[k])*(rzv-rz[k]))<(4.0*size*size)) { too_close = 1; break; } } if (too_close) continue; if (ndata>=10000) { // printf("Maximum reached!\n"); break; } xdata[ndata] = xpos; ydata[ndata] = ypos; disizes[ndata] = disize; rdisizes[ndata] = size; rx[ndata] = rxv; ry[ndata] = ryv; rz[ndata] = rzv; vz[ndata] = -0.01; ndata++; nloc++; } }; // if (ii==(max/100)) printf("Maximum reached, only %d particles now present instead of %d\n", ndata, presetval); // else printf("%d particles now at surface\n", ndata); } /*test succesive LJ steps on substrate (no relaxation)*/ for (k=0; k<ndata; k++) { fx[k] = fy[k] = fz[k] = 0; /*calculate forces for all particles on substrate*/ if (gwy_data_field_rtoi(lfield, rx[k])<0 || gwy_data_field_rtoj(lfield, ry[k])<0 || gwy_data_field_rtoi(lfield, rx[k])>=xres || gwy_data_field_rtoj(lfield, ry[k])>=yres) continue; for (m=0; m<ndata; m++) { if (m==k) continue; // printf("(%g %g %g) on (%g %g %g)\n", rx[m], ry[m], rz[m], rx[k], ry[k], rz[k]); fx[k] -= (get_lj_potential_spheres(rx[m], ry[m], rz[m], rx[k]+diff, ry[k], rz[k], gwy_data_field_itor(dfield, disizes[k])) -get_lj_potential_spheres(rx[m], ry[m], rz[m], rx[k]-diff, ry[k], rz[k], gwy_data_field_itor(dfield, disizes[k])))/2/diff; fy[k] -= (get_lj_potential_spheres(rx[m], ry[m], rz[m], rx[k], ry[k]+diff, rz[k], gwy_data_field_itor(dfield, disizes[k])) -get_lj_potential_spheres(rx[m], ry[m], rz[m], rx[k], ry[k]-diff, rz[k], gwy_data_field_itor(dfield, disizes[k])))/2/diff; fz[k] -= (get_lj_potential_spheres(rx[m], ry[m], rz[m], rx[k], ry[k], rz[k]+diff, gwy_data_field_itor(dfield, disizes[k])) -get_lj_potential_spheres(rx[m], ry[m], rz[m], rx[k], ry[k], rz[k]-diff, gwy_data_field_itor(dfield, disizes[k])))/2/diff; } fx[k] -= (integrate_lj_substrate(zlfield, rx[k]+diff, ry[k], rz[k], rdisizes[k]) - integrate_lj_substrate(zlfield, rx[k]-diff, ry[k], rz[k], rdisizes[k]))/2/diff; fy[k] -= (integrate_lj_substrate(zlfield, rx[k], ry[k]-diff, rz[k], rdisizes[k]) - integrate_lj_substrate(zlfield, rx[k], ry[k]+diff, rz[k], rdisizes[k]))/2/diff; fz[k] -= (integrate_lj_substrate(zlfield, rx[k], ry[k], rz[k]+diff, rdisizes[k]) - integrate_lj_substrate(zlfield, rx[k], ry[k], rz[k]-diff, rdisizes[k]))/2/diff; } for (k=0; k<ndata; k++) { if (gwy_data_field_rtoi(lfield, rx[k])<0 || gwy_data_field_rtoj(lfield, ry[k])<0 || gwy_data_field_rtoi(lfield, rx[k])>=xres || gwy_data_field_rtoj(lfield, ry[k])>=yres) continue; /*move all particles*/ rx[k] += vx[k]*timestep + 0.5*ax[k]*timestep*timestep; vx[k] += 0.5*ax[k]*timestep; ax[k] = fx[k]/mass; vx[k] += 0.5*ax[k]*timestep; vx[k] *= 0.9; if (fabs(vx[k])>0.01) vx[k] = 0; //0.2 ry[k] += vy[k]*timestep + 0.5*ay[k]*timestep*timestep; vy[k] += 0.5*ay[k]*timestep; ay[k] = fy[k]/mass; vy[k] += 0.5*ay[k]*timestep; vy[k] *= 0.9; if (fabs(vy[k])>0.01) vy[k] = 0; //0.2 rz[k] += vz[k]*timestep + 0.5*az[k]*timestep*timestep; vz[k] += 0.5*az[k]*timestep; az[k] = fz[k]/mass; vz[k] += 0.5*az[k]*timestep; vz[k] *= 0.9; if (fabs(vz[k])>0.01) vz[k] = 0; if (rx[k]<=gwy_data_field_itor(dfield, disizes[k])) rx[k] = gwy_data_field_itor(dfield, disizes[k]); if (ry[k]<=gwy_data_field_itor(dfield, disizes[k])) ry[k] = gwy_data_field_itor(dfield, disizes[k]); if (rx[k]>=(xreal-gwy_data_field_itor(dfield, disizes[k]))) rx[k] = xreal-gwy_data_field_itor(dfield, disizes[k]); if (ry[k]>=(yreal-gwy_data_field_itor(dfield, disizes[k]))) ry[k] = yreal-gwy_data_field_itor(dfield, disizes[k]); } gwy_data_field_copy(zlfield, lfield, 0); showit(lfield, zdfield, rdisizes, rx, ry, rz, xdata, ydata, ndata, oxres, oxreal, oyres, oyreal, add, xres, yres); gwy_data_field_area_copy(lfield, dfield, add, add, oxres, oyres, 0, 0); gwy_data_field_data_changed(dfield); while (gtk_events_pending()) gtk_main_iteration(); } gwy_data_field_area_copy(lfield, dfield, add, add, oxres, oyres, 0, 0); gwy_data_field_data_changed(dfield); args->computed = TRUE; gwy_object_unref(lfield); gwy_object_unref(zlfield); gwy_object_unref(zdfield); }
static void immerse_do(ImmerseArgs *args) { GwyDataField *resampled, *image, *detail, *result; GwyContainer *data; gint newid; gint kxres, kyres; gint x, y, w, h; gdouble iavg, davg; GQuark quark; data = gwy_app_data_browser_get(args->image.datano); quark = gwy_app_get_data_key_for_id(args->image.id); image = GWY_DATA_FIELD(gwy_container_get_object(data, quark)); data = gwy_app_data_browser_get(args->detail.datano); quark = gwy_app_get_data_key_for_id(args->detail.id); detail = GWY_DATA_FIELD(gwy_container_get_object(data, quark)); davg = gwy_data_field_get_avg(detail); kxres = gwy_data_field_get_xres(detail); kyres = gwy_data_field_get_yres(detail); switch (args->sampling) { case GWY_IMMERSE_SAMPLING_DOWN: result = gwy_data_field_duplicate(image); x = gwy_data_field_rtoj(image, args->xpos); y = gwy_data_field_rtoi(image, args->ypos); w = GWY_ROUND(gwy_data_field_get_xreal(detail) /gwy_data_field_get_xmeasure(image)); h = GWY_ROUND(gwy_data_field_get_yreal(detail) /gwy_data_field_get_ymeasure(image)); w = MAX(w, 1); h = MAX(h, 1); gwy_debug("w: %d, h: %d", w, h); resampled = gwy_data_field_new_resampled(detail, w, h, GWY_INTERPOLATION_LINEAR); if (args->leveling == GWY_IMMERSE_LEVEL_MEAN) { iavg = gwy_data_field_area_get_avg(result, NULL, x, y, w, h); gwy_data_field_add(resampled, iavg - davg); } gwy_data_field_area_copy(resampled, result, 0, 0, w, h, x, y); g_object_unref(resampled); break; case GWY_IMMERSE_SAMPLING_UP: w = GWY_ROUND(gwy_data_field_get_xreal(image) /gwy_data_field_get_xmeasure(detail)); h = GWY_ROUND(gwy_data_field_get_yreal(image) /gwy_data_field_get_ymeasure(detail)); gwy_debug("w: %d, h: %d", w, h); result = gwy_data_field_new_resampled(image, w, h, GWY_INTERPOLATION_LINEAR); x = gwy_data_field_rtoj(result, args->xpos); y = gwy_data_field_rtoi(result, args->ypos); if (args->leveling == GWY_IMMERSE_LEVEL_MEAN) { iavg = gwy_data_field_area_get_avg(result, NULL, x, y, kxres, kyres); gwy_data_field_area_copy(detail, result, 0, 0, kxres, kyres, x, y); gwy_data_field_area_add(result, x, y, kxres, kyres, iavg - davg); } else gwy_data_field_area_copy(detail, result, 0, 0, kxres, kyres, x, y); break; default: g_return_if_reached(); break; } gwy_app_data_browser_get_current(GWY_APP_CONTAINER, &data, 0); newid = gwy_app_data_browser_add_data_field(result, data, TRUE); gwy_app_set_data_field_title(data, newid, _("Immersed detail")); g_object_unref(result); gwy_app_channel_log_add_proc(data, args->image.id, newid); }
static void immerse_search(ImmerseControls *controls, gint search_type) { GwyDataField *dfield, *dfieldsub, *ifield, *iarea; gdouble wr, hr, xpos, ypos, deltax, deltay; gint w, h, xfrom, xto, yfrom, yto, ixres, iyres, col, row; GwyContainer *data; GQuark quark; data = gwy_app_data_browser_get(controls->args->detail.datano); quark = gwy_app_get_data_key_for_id(controls->args->detail.id); dfield = gwy_container_get_object(data, quark); data = gwy_app_data_browser_get(controls->args->image.datano); quark = gwy_app_get_data_key_for_id(controls->args->image.id); ifield = gwy_container_get_object(data, quark); ixres = gwy_data_field_get_xres(ifield); iyres = gwy_data_field_get_yres(ifield); wr = gwy_data_field_get_xreal(dfield)/gwy_data_field_get_xmeasure(ifield); hr = gwy_data_field_get_yreal(dfield)/gwy_data_field_get_ymeasure(ifield); if (wr*hr < 6.0) { g_warning("Detail image is too small for correlation"); return; } w = GWY_ROUND(MAX(wr, 1.0)); h = GWY_ROUND(MAX(hr, 1.0)); gwy_debug("w: %d, h: %d", w, h); g_assert(w <= ixres && h <= iyres); if (search_type == RESPONSE_REFINE) { xfrom = gwy_data_field_rtoj(ifield, controls->args->xpos); yfrom = gwy_data_field_rtoi(ifield, controls->args->ypos); /* Calculate the area we will search the detail in */ deltax = improve_search_window(w, ixres); deltay = improve_search_window(h, iyres); gwy_debug("deltax: %g, deltay: %g", deltax, deltay); xto = MIN(xfrom + w + deltax, ixres); yto = MIN(yfrom + h + deltay, iyres); xfrom = MAX(xfrom - deltax, 0); yfrom = MAX(yfrom - deltay, 0); } else { xfrom = yfrom = 0; xto = ixres; yto = iyres; } gwy_debug("x: %d..%d, y: %d..%d", xfrom, xto, yfrom, yto); /* Cut out only the interesting part from the image data field */ if (xfrom == 0 && yfrom == 0 && xto == ixres && yto == iyres) iarea = g_object_ref(ifield); else iarea = gwy_data_field_area_extract(ifield, xfrom, yfrom, xto - xfrom, yto - yfrom); dfieldsub = gwy_data_field_new_resampled(dfield, w, h, GWY_INTERPOLATION_LINEAR); immerse_correlate(iarea, dfieldsub, &col, &row); gwy_debug("[c] col: %d, row: %d", col, row); col += xfrom; row += yfrom; xpos = gwy_data_field_jtor(dfieldsub, col + 0.5); ypos = gwy_data_field_itor(dfieldsub, row + 0.5); g_object_unref(iarea); g_object_unref(dfieldsub); gwy_debug("[C] col: %d, row: %d", col, row); /* Upsample and refine */ xfrom = MAX(col - 1, 0); yfrom = MAX(row - 1, 0); xto = MIN(col + w + 1, ixres); yto = MIN(row + h + 1, iyres); gwy_debug("x: %d..%d, y: %d..%d", xfrom, xto, yfrom, yto); iarea = gwy_data_field_area_extract(ifield, xfrom, yfrom, xto - xfrom, yto - yfrom); wr = gwy_data_field_get_xreal(iarea)/gwy_data_field_get_xmeasure(dfield); hr = gwy_data_field_get_yreal(iarea)/gwy_data_field_get_ymeasure(dfield); gwy_data_field_resample(iarea, GWY_ROUND(wr), GWY_ROUND(hr), GWY_INTERPOLATION_LINEAR); immerse_correlate(iarea, dfield, &col, &row); gwy_debug("[U] col: %d, row: %d", col, row); xpos = gwy_data_field_jtor(dfield, col + 0.5) + gwy_data_field_jtor(ifield, xfrom); ypos = gwy_data_field_itor(dfield, row + 0.5) + gwy_data_field_itor(ifield, yfrom); g_object_unref(iarea); immerse_clamp_detail_offset(controls, xpos, ypos); }
static gboolean curvature_plot_graph(GwyDataField *dfield, const Intersection *i1, const Intersection *i2, GwyGraphModel *gmodel) { GwyGraphCurveModel *gcmodel; GwyDataLine *dline; gint xres, yres; guint i; if (!gwy_graph_model_get_n_curves(gmodel)) { GwySIUnit *siunitxy, *siunitz; gchar *s; siunitxy = gwy_si_unit_duplicate(gwy_data_field_get_si_unit_xy(dfield)); siunitz = gwy_si_unit_duplicate(gwy_data_field_get_si_unit_z(dfield)); g_object_set(gmodel, "title", _("Curvature Sections"), "si-unit-x", siunitxy, "si-unit-y", siunitz, NULL); g_object_unref(siunitxy); g_object_unref(siunitz); for (i = 0; i < 2; i++) { gcmodel = gwy_graph_curve_model_new(); s = g_strdup_printf(_("Profile %d"), (gint)i+1); g_object_set(gcmodel, "description", s, "mode", GWY_GRAPH_CURVE_LINE, "color", gwy_graph_get_preset_color(i), NULL); g_free(s); gwy_graph_model_add_curve(gmodel, gcmodel); g_object_unref(gcmodel); } } else { g_assert(gwy_graph_model_get_n_curves(gmodel) == 2); } dline = gwy_data_line_new(1, 1.0, FALSE); xres = gwy_data_field_get_xres(dfield); yres = gwy_data_field_get_yres(dfield); for (i = 0; i < 2; i++) { gint col1 = gwy_data_field_rtoj(dfield, i1[i].x); gint row1 = gwy_data_field_rtoi(dfield, i1[i].y); gint col2 = gwy_data_field_rtoj(dfield, i2[i].x); gint row2 = gwy_data_field_rtoi(dfield, i2[i].y); gwy_data_field_get_profile(dfield, dline, CLAMP(col1, 0, xres-1), CLAMP(row1, 0, yres-1), CLAMP(col2, 0, xres-1), CLAMP(row2, 0, yres-1), -1, 1, GWY_INTERPOLATION_BILINEAR); gwy_data_line_set_offset(dline, i1[i].t/(i2[i].t - i1[i].t) * gwy_data_line_get_real(dline)); gcmodel = gwy_graph_model_get_curve(gmodel, i); gwy_graph_curve_model_set_data_from_dataline(gcmodel, dline, 0, 0); } g_object_unref(dline); return TRUE; }