示例#1
0
/**
 * gwy_surface_copy:
 * @src: Source surface.
 * @dest: Destination surface.
 *
 * Copies the data of a surface to another surface of the same dimensions.
 *
 * Only the data points are copied.  To make a surface completely identical to
 * another, including units and change of dimensions, you can use
 * gwy_surface_clone().
 *
 * Since: 2.45
 **/
void
gwy_surface_copy(GwySurface *src,
                 GwySurface *dest)
{
    g_return_if_fail(GWY_IS_SURFACE(src));
    g_return_if_fail(GWY_IS_SURFACE(dest));
    g_return_if_fail(dest->n == src->n);
    gwy_assign(dest->data, src->data, src->n);
    gwy_surface_invalidate(dest);
}
示例#2
0
/**
 * gwy_surface_new_part:
 * @surface: A surface.
 * @xfrom: Minimum x-coordinate value.
 * @xto: Maximum x-coordinate value.
 * @yfrom: Minimum y-coordinate value.
 * @yto: Maximum y-coordinate value.
 *
 * Creates a new surface as a part of another surface.
 *
 * The new surface consits of data with lateral coordinates within the
 * specified ranges (inclusively).  It may be empty.
 *
 * Data are physically copied, i.e. changing the new surface data does not
 * change @surface's data and vice versa.
 *
 * Returns: A new surface.
 *
 * Since: 2.45
 **/
GwySurface*
gwy_surface_new_part(GwySurface *surface,
                     gdouble xfrom,
                     gdouble xto,
                     gdouble yfrom,
                     gdouble yto)
{
    GwySurface *part;
    guint n, i;

    g_return_val_if_fail(GWY_IS_SURFACE(surface), NULL);

    part = gwy_surface_new_alike(surface);
    if (!surface->n || xfrom > xto || yfrom > yto)
        return part;

    n = 0;
    for (i = 0; i < surface->n; i++) {
        gdouble x = surface->data[i].x, y = surface->data[i].y;
        if (x >= xfrom && x <= xto && y >= yfrom && y <= yto)
            n++;
    }
    part->n = n;
    alloc_data(part);

    n = 0;
    for (i = 0; i < surface->n; i++) {
        gdouble x = surface->data[i].x, y = surface->data[i].y;
        if (x >= xfrom && x <= xto && y >= yfrom && y <= yto)
            part->data[n++] = surface->data[i];
    }

    return part;
}
示例#3
0
/**
 * gwy_surface_invalidate:
 * @surface: A surface.
 *
 * Invalidates cached surface statistics.
 *
 * Cached statistics include ranges returned by gwy_surface_get_xrange(),
 * gwy_surface_get_yrange() and gwy_surface_get_min_max(), the fingerprint
 * for gwy_surface_xy_is_compatible() and and possibly other characteristics
 * in the future.
 *
 * See gwy_data_field_invalidate() for discussion of invalidation and examples.
 *
 * Since: 2.45
 **/
void
gwy_surface_invalidate(GwySurface *surface)
{
    g_return_if_fail(GWY_IS_SURFACE(surface));
    surface->priv->cached_ranges = FALSE;
    surface->priv->cached_checksum = FALSE;
}
示例#4
0
/**
 * gwy_surface_copy_units_to_data_field:
 * @surface: A surface.
 * @data_field: A two-dimensional data field.
 *
 * Sets lateral and value units of a data field to match a surface.
 *
 * Since: 2.46
 **/
void
gwy_surface_copy_units_to_data_field(GwySurface *surface,
                                     GwyDataField *data_field)
{
    Surface *priv;

    g_return_if_fail(GWY_IS_SURFACE(surface));
    g_return_if_fail(GWY_IS_DATA_FIELD(data_field));

    priv = surface->priv;
    if (priv->si_unit_xy && data_field->si_unit_xy)
        gwy_serializable_clone(G_OBJECT(priv->si_unit_xy),
                               G_OBJECT(data_field->si_unit_xy));
    else if (priv->si_unit_xy && !data_field->si_unit_xy)
        data_field->si_unit_xy = gwy_si_unit_duplicate(priv->si_unit_xy);
    else if (!priv->si_unit_xy && data_field->si_unit_xy)
        GWY_OBJECT_UNREF(data_field->si_unit_xy);

    if (priv->si_unit_z && data_field->si_unit_z)
        gwy_serializable_clone(G_OBJECT(priv->si_unit_z),
                               G_OBJECT(data_field->si_unit_z));
    else if (priv->si_unit_z && !data_field->si_unit_z)
        data_field->si_unit_z = gwy_si_unit_duplicate(priv->si_unit_z);
    else if (!priv->si_unit_z && data_field->si_unit_z)
        GWY_OBJECT_UNREF(data_field->si_unit_z);
}
示例#5
0
/**
 * gwy_surface_get_data:
 * @surface: A surface.
 *
 * Gets the raw XYZ data array of a surface.
 *
 * The returned buffer is not guaranteed to be valid through whole data
 * surface life time.
 *
 * This function invalidates any cached information, use
 * gwy_surface_get_data_const() if you are not going to change the data.
 *
 * See gwy_surface_invalidate() for some discussion.
 *
 * Returns: The surface XYZ data as a pointer to an array of
 *          gwy_surface_get_npoints() items.
 *
 * Since: 2.45
 **/
GwyXYZ*
gwy_surface_get_data(GwySurface *surface)
{
    g_return_val_if_fail(GWY_IS_SURFACE(surface), NULL);
    gwy_surface_invalidate(surface);
    return surface->data;
}
示例#6
0
/**
 * gwy_surface_get_data_full:
 * @surface: A surface.
 * @n: Location to store the count of extracted data points.
 *
 * Provides the values of an entire surface as a flat array.
 *
 * This function, paired with gwy_surface_set_data_full() can be namely useful
 * in language bindings.
 *
 * Note that this function returns a pointer directly to @surface's data.
 *
 * Returns: The array containing the surface points.
 *
 * Since: 2.45
 **/
const GwyXYZ*
gwy_surface_get_data_full(GwySurface *surface,
                          guint *n)
{
    g_return_val_if_fail(GWY_IS_SURFACE(surface), NULL);
    *n = surface->n;
    return surface->data;
}
示例#7
0
/**
 * gwy_surface_set_from_data_field:
 * @surface: A surface.
 * @data_field: A two-dimensional data field.
 *
 * Fills the data of a surface from a data field.
 *
 * The number of points in the new surface will be equal to the number of
 * points in the field.  Lateral coordinates will be equal to the corresponding
 * @data_field coordinates; values will be created in regular grid according to
 * @data_field's physical size and offset.
 *
 * Lateral and value units will correspond to @data_field's units.  This means
 * the field needs to have identical @x and @y units.
 *
 * Since: 2.45
 **/
void
gwy_surface_set_from_data_field(GwySurface *surface,
                                GwyDataField *dfield)
{
    g_return_if_fail(GWY_IS_SURFACE(surface));
    g_return_if_fail(GWY_IS_DATA_FIELD(dfield));
    copy_field_to_surface(dfield, surface, NULL, GWY_MASK_IGNORE);
}
示例#8
0
static void
surface_assert_equal(const GwySurface *result,
                     const GwySurface *reference)
{
    g_assert(GWY_IS_SURFACE(result));
    g_assert(GWY_IS_SURFACE(reference));
    g_assert_cmpuint(result->n, ==, reference->n);
    compare_properties(G_OBJECT(result), G_OBJECT(reference));

    for (guint i = 0; i < result->n; i++) {
        GwyXYZ resxy = result->data[i];
        GwyXYZ refxy = reference->data[i];
        g_assert_cmpfloat(resxy.x, ==, refxy.x);
        g_assert_cmpfloat(resxy.y, ==, refxy.y);
        g_assert_cmpfloat(resxy.z, ==, refxy.z);
    }
}
示例#9
0
static void
gwy_surface_clone_real(GObject *source, GObject *copy)
{
    GwySurface *surface, *clone;

    g_return_if_fail(GWY_IS_SURFACE(source));
    g_return_if_fail(GWY_IS_SURFACE(copy));

    surface = GWY_SURFACE(source);
    clone = GWY_SURFACE(copy);

    if (clone->n != surface->n) {
        clone->n = surface->n;
        alloc_data(clone);
    }
    gwy_assign(clone->data, surface->data, surface->n);
    copy_info(clone, surface);
}
示例#10
0
/**
 * gwy_surface_xy_is_compatible:
 * @surface: A surface.
 * @othersurface: Another surface.
 *
 * Checks whether the XY positions of two surfaces are compatible.
 *
 * Compatible XY positions mean the XY units are the same and the points are
 * the same.  Two surfaces that have the same set of XY points but in different
 * orders are <emphasis>not</emphasis> considered compatible.  This is because
 * the points at the same index in @data are different and thus calculations
 * involving data from the two surfaces are impossible.  It is necessary to
 * match the points order in the two surfaces to make this possible.
 *
 * This information is cached.
 *
 * Returns: %TRUE if the surfaces are XY-position compatible, %FALSE if they
 *          are not.
 *
 * Since: 2.45
 **/
gboolean
gwy_surface_xy_is_compatible(GwySurface *surface,
                             GwySurface *othersurface)
{
    g_return_val_if_fail(GWY_IS_SURFACE(surface), FALSE);
    g_return_val_if_fail(GWY_IS_SURFACE(othersurface), FALSE);

    ensure_units(surface);
    ensure_units(othersurface);
    if (!gwy_si_unit_equal(surface->priv->si_unit_xy,
                           othersurface->priv->si_unit_xy))
        return FALSE;

    ensure_checksum(surface);
    ensure_checksum(othersurface);
    return !memcmp(surface->priv->checksum, othersurface->priv->checksum,
                   sizeof(surface->priv->checksum));
}
示例#11
0
/**
 * gwy_surface_set:
 * @surface: A surface.
 * @pos: Position in @surface.
 * @point: Point to store at given position.
 *
 * Sets a single surface value.
 *
 * This function exists <emphasis>only for language bindings</emphasis> as it
 * is very slow compared to simply accessing @data in #GwySurface directly in
 * C.
 *
 * Since: 2.45
 **/
void
gwy_surface_set(GwySurface *surface,
                guint pos,
                GwyXYZ point)
{
    g_return_if_fail(GWY_IS_SURFACE(surface));
    g_return_if_fail(pos < surface->n);
    surface->data[pos] = point;
}
示例#12
0
/**
 * gwy_surface_get_si_unit_z:
 * @surface: A surface.
 *
 * Returns value SI unit of a surface.
 *
 * Returns: SI unit corresponding to the "height" (Z) dimension of the surface.
 *          Its reference count is not incremented.
 *
 * Since: 2.45
 **/
GwySIUnit*
gwy_surface_get_si_unit_z(GwySurface *surface)
{
    g_return_val_if_fail(GWY_IS_SURFACE(surface), NULL);

    if (!surface->priv->si_unit_z)
        surface->priv->si_unit_z = gwy_si_unit_new(NULL);

    return surface->priv->si_unit_z;
}
示例#13
0
/**
 * gwy_surface_get:
 * @surface: A surface.
 * @pos: Position in @surface.
 *
 * Obtains a single surface point.
 *
 * This function exists <emphasis>only for language bindings</emphasis> as it
 * is very slow compared to simply accessing @data in #GwySurface directly in
 * C.
 *
 * Returns: The point at @pos.
 *
 * Since: 2.45
 **/
GwyXYZ
gwy_surface_get(GwySurface *surface,
                guint pos)
{
    GwyXYZ nullpoint = { 0.0, 0.0, 0.0 };

    g_return_val_if_fail(GWY_IS_SURFACE(surface), nullpoint);
    g_return_val_if_fail(pos < surface->n, nullpoint);
    return surface->data[pos];
}
示例#14
0
/**
 * gwy_surface_set_from_data_field_mask:
 * @surface: A surface.
 * @data_field: A two-dimensional data field.
 * @mask: Mask of pixels to include from/exclude, or %NULL
 * @masking: Masking mode to use.
 *
 * Fills the data of a surface from a data field, possibly using masking.
 *
 * Since: 2.46
 **/
void
gwy_surface_set_from_data_field_mask(GwySurface *surface,
                                     GwyDataField *dfield,
                                     GwyDataField *mask,
                                     GwyMaskingType masking)
{
    g_return_if_fail(GWY_IS_SURFACE(surface));
    g_return_if_fail(GWY_IS_DATA_FIELD(dfield));
    g_return_if_fail(!mask || GWY_IS_DATA_FIELD(mask));
    copy_field_to_surface(dfield, surface, mask, masking);
}
示例#15
0
/**
 * gwy_surface_get_min_max:
 * @surface: A surface.
 * @min: Location where to store the minimum value.
 * @max: Location where to store the maximum value.
 *
 * Gets the range of Z values of a surface.
 *
 * This information is cached.
 *
 * Since: 2.45
 **/
void
gwy_surface_get_min_max(GwySurface *surface,
                        gdouble *min,
                        gdouble *max)
{
    g_return_if_fail(GWY_IS_SURFACE(surface));
    ensure_ranges(surface);
    if (min)
        *min = surface->priv->min.z;
    if (max)
        *max = surface->priv->max.z;
}
示例#16
0
static GObject*
gwy_surface_duplicate_real(GObject *object)
{
    GwySurface *surface, *duplicate;

    g_return_val_if_fail(GWY_IS_SURFACE(object), NULL);
    surface = GWY_SURFACE(object);
    duplicate = gwy_surface_new_from_data(surface->data, surface->n);
    copy_info(duplicate, surface);

    return (GObject*)duplicate;
}
示例#17
0
/**
 * gwy_surface_new_alike:
 * @model: A surface to use as the template.
 *
 * Creates a new empty surface similar to another surface.
 *
 * The units of the new surface will be identical to those of @model but the
 * new surface will not contain any points.  Use gwy_surface_duplicate() to
 * completely duplicate a surface including data.
 *
 * Returns: A new empty surface.
 *
 * Since: 2.45
 **/
GwySurface*
gwy_surface_new_alike(GwySurface *model)
{
    GwySurface *surface;

    g_return_val_if_fail(GWY_IS_SURFACE(model), NULL);

    surface = g_object_newv(GWY_TYPE_SURFACE, 0, NULL);
    copy_info(surface, model);
    gwy_surface_invalidate(surface);
    return surface;
}
示例#18
0
/**
 * gwy_surface_set_si_unit_z:
 * @surface: A surface.
 * @si_unit: SI unit to be set.
 *
 * Sets the SI unit corresponding to the "height" (Z) dimension of a surface.
 *
 * It does not assume a reference on @si_unit, instead it adds its own
 * reference.
 *
 * Since: 2.45
 **/
void
gwy_surface_set_si_unit_z(GwySurface *surface,
                          GwySIUnit *si_unit)
{
    g_return_if_fail(GWY_IS_SURFACE(surface));
    g_return_if_fail(GWY_IS_SI_UNIT(si_unit));
    if (surface->priv->si_unit_z == si_unit)
        return;

    GWY_OBJECT_UNREF(surface->priv->si_unit_z);
    g_object_ref(si_unit);
    surface->priv->si_unit_z = si_unit;
}
示例#19
0
/**
 * gwy_surface_set_data_full:
 * @surface: A surface.
 * @points: Data points to copy to the surface.  They replace whatever points
 *          are in @surface now.
 * @n: The number of points in @data.
 *
 * Puts back values from a flat array to an entire data surface.
 *
 * See gwy_surface_get_data_full() for a discussion.
 *
 * Since: 2.45
 **/
void
gwy_surface_set_data_full(GwySurface *surface,
                          const GwyXYZ *points,
                          guint n)
{
    g_return_if_fail(GWY_IS_SURFACE(surface));
    g_return_if_fail(points || !n);
    if (surface->n != n) {
        surface->n = n;
        alloc_data(surface);
    }
    if (n)
        gwy_assign(surface->data, points, n);
}
示例#20
0
/**
 * gwy_surface_get_value_format_z:
 * @surface: A surface.
 * @style: Unit format style.
 * @format: A SI value format to modify, or %NULL to allocate a new one.
 *
 * Finds value format good for displaying values of a surface.
 *
 * Returns: The value format.  If @format is %NULL, a newly allocated format
 *          is returned, otherwise (modified) @format itself is returned.
 *
 * Since: 2.45
 **/
GwySIValueFormat*
gwy_surface_get_value_format_z(GwySurface *surface,
                               GwySIUnitFormatStyle style,
                               GwySIValueFormat *format)
{
    GwySIUnit *siunit;
    gdouble max, min;

    g_return_val_if_fail(GWY_IS_SURFACE(surface), NULL);

    siunit = gwy_surface_get_si_unit_z(surface);
    gwy_surface_get_min_max(surface, &min, &max);
    if (max == min) {
        max = ABS(max);
        min = 0.0;
    }

    return gwy_si_unit_get_format_with_digits(siunit, style, max - min, 3,
                                              format);
}
示例#21
0
static gsize
gwy_surface_get_size(GObject *obj)
{
    GwySurface *surface;
    guint32 datasize;

    g_return_val_if_fail(GWY_IS_SURFACE(obj), 0);

    surface = GWY_SURFACE(obj);
    ensure_units(surface);
    datasize = 3*surface->n;
    {
        GwySerializeSpec spec[] = {
            { 'o', "si_unit_xy", &surface->priv->si_unit_xy, NULL, },
            { 'o', "si_unit_z", &surface->priv->si_unit_z, NULL, },
            { 'D', "data", &surface->data, &datasize, },
        };
        return gwy_serialize_get_struct_size(GWY_SURFACE_TYPE_NAME,
                                             G_N_ELEMENTS(spec), spec);
    }
}
示例#22
0
/**
 * gwy_surface_get_value_format_xy:
 * @surface: A surface.
 * @style: Unit format style.
 * @format: A SI value format to modify, or %NULL to allocate a new one.
 *
 * Finds value format good for displaying coordinates of a surface.
 *
 * Returns: The value format.  If @format is %NULL, a newly allocated format
 *          is returned, otherwise (modified) @format itself is returned.
 *
 * Since: 2.45
 **/
GwySIValueFormat*
gwy_surface_get_value_format_xy(GwySurface *surface,
                                GwySIUnitFormatStyle style,
                                GwySIValueFormat *format)
{
    gdouble xmin, xmax, ymin, ymax;
    gdouble max, unit;
    GwySIUnit *siunit;

    g_return_val_if_fail(GWY_IS_SURFACE(surface), NULL);

    siunit = gwy_surface_get_si_unit_xy(surface);
    if (!surface->n) {
        return gwy_si_unit_get_format_with_resolution(siunit, style, 1.0, 0.1,
                                                      format);
    }

    if (surface->n == 1) {
        max = MAX(fabs(surface->data[0].x), fabs(surface->data[0].y));
        if (!max)
            max = 1.0;
        return gwy_si_unit_get_format_with_resolution(siunit,
                                                      style, max, max/10.0,
                                                      format);
    }

    gwy_surface_get_xrange(surface, &xmin, &xmax);
    gwy_surface_get_yrange(surface, &ymin, &ymax);
    max = MAX(MAX(fabs(xmax), fabs(xmin)), MAX(fabs(ymax), fabs(ymin)));
    if (!max)
        max = 1.0;
    unit = hypot(ymax - ymin, xmax - xmin)/sqrt(surface->n);
    if (!unit)
        unit = max/10.0;

    return gwy_si_unit_get_format_with_resolution(siunit, style, max, 0.2*unit,
                                                  format);
}
示例#23
0
/**
 * gwy_surface_get_npoints:
 * @surface: A surface.
 *
 * Gets the number of points in an XYZ surface.
 *
 * Returns: The number of points.
 *
 * Since: 2.45
 **/
guint
gwy_surface_get_npoints(GwySurface *surface)
{
    g_return_val_if_fail(GWY_IS_SURFACE(surface), 0);
    return surface->n;
}
示例#24
0
/**
 * gwy_surface_data_changed:
 * @surface: A surface.
 *
 * Emits signal GwySurface::data-changed on a surface.
 *
 * Since: 2.45
 **/
void
gwy_surface_data_changed(GwySurface *surface)
{
    g_return_if_fail(GWY_IS_SURFACE(surface));
    g_signal_emit(surface, signals[DATA_CHANGED], 0);
}
示例#25
0
/**
 * gwy_surface_get_data_const:
 * @surface: A surface.
 *
 * Gets the raw XYZ data array of a surface, read-only.
 *
 * The returned buffer is not guaranteed to be valid through whole data
 * field life time.
 *
 * Use gwy_surface_get_data() if you want to change the data.
 *
 * See gwy_surface_invalidate() for some discussion.
 *
 * Returns: The surface XYZ data as a pointer to an array of
 *          gwy_surface_get_npoints() items.
 *
 * Since: 2.45
 **/
const GwyXYZ*
gwy_surface_get_data_const(GwySurface *surface)
{
    g_return_val_if_fail(GWY_IS_SURFACE(surface), NULL);
    return surface->data;
}