Пример #1
0
void *action_exec(const action_t *action, const arg_t *args)
{
    void *ret = NULL;
    int i, nb_args;
    long vals[4];
    // So that we do not add undo snapshot when an action calls an other one.
    static int reentry = 0;
    // XXX: not sure this is actually legal in C.  func will be called with
    // a variable number or arguments, that might be of any registered types!
    void *(*func)() = action->func;
    bool is_void;

    assert(action);
    nb_args = action->sig.nb_args;
    assert(nb_args <= ARRAY_SIZE(vals));
    is_void = action->sig.ret == TYPE_VOID;

    // For the moment all action cancel the current tool, for simplicity.
    tool_cancel(goxel(), goxel()->tool, goxel()->tool_state);

    if (reentry == 0 && !(action->flags & ACTION_NO_CHANGE)) {
        image_history_push(goxel()->image);
    }

    reentry++;

    for (i = 0; i < nb_args; i++)
        vals[i] = get_arg_value(action->sig.args[i], args);

    if (is_void && nb_args == 0)
        func();
    else if (is_void && nb_args == 1)
        func(vals[0]);
    else if (is_void && nb_args == 2)
        func(vals[0], vals[1]);
    else if (is_void && nb_args == 3)
        func(vals[0], vals[1], vals[2]);
    else if (is_void && nb_args == 4)
        func(vals[0], vals[1], vals[2], vals[3]);
    else if (!is_void && nb_args == 0)
        ret = func();
    else if (!is_void && nb_args == 1)
        ret = func(vals[0]);
    else if (!is_void && nb_args == 2)
        ret = func(vals[0], vals[1]);
    else if (!is_void && nb_args == 3)
        ret = func(vals[0], vals[1], vals[2]);
    else if (!is_void && nb_args == 4)
        ret = func(vals[0], vals[1], vals[2], vals[3]);
    else
        LOG_E("Cannot handle signature for action %s", action->id);

    reentry--;
    if (reentry == 0 && !(action->flags & ACTION_NO_CHANGE)) {
        goxel_update_meshes(goxel(), -1);
    }
    return ret;
}
Пример #2
0
void block_delete(block_t *block)
{
    block->data->ref--;
    if (block->data->ref == 0) {
        free(block->data);
        goxel()->block_count--;
    }
    free(block);
}
Пример #3
0
void block_set_data(block_t *block, block_data_t *data)
{
    block->data->ref--;
    if (block->data->ref == 0) {
        free(block->data);
        goxel()->block_count--;
    }
    block->data = data;
    data->ref++;
}
Пример #4
0
void dicom_import(const char *dirpath)
{
    DIR *dir;
    struct dirent *dirent;
    dicom_t dicom, *dptr;
    static UT_icd dicom_icd = {sizeof(dicom_t), NULL, NULL, NULL};
    UT_array *all_files;
    int w, h, d;    // Dimensions of the full data cube.
    int i;
    uint16_t *data;
    uvec4b_t *cube;

    // First we parse all the dicom images into a sorted array.
    // XXX: how to propery iter a directory?
    utarray_new(all_files, &dicom_icd);
    dir = opendir(dirpath);
    while ((dirent = readdir(dir))) {
        if (dirent->d_name[0] == '.') continue;
        asprintf(&dicom.path, "%s/%s", dirpath, dirent->d_name);
        dicom_load(dicom.path, &dicom, NULL, 0);
        CHECK(dicom.rows && dicom.columns);
        utarray_push_back(all_files, &dicom);
    }
    closedir(dir);
    utarray_sort(all_files, dicom_sort);

    // Read all the file data one by one into the data cube.
    w = dicom.columns;
    h = dicom.rows;
    d = utarray_len(all_files);
    data = calloc(w * h * d, 2);

    dptr = NULL;
    while( (dptr = (dicom_t*)utarray_next(all_files, dptr))) {
        i = utarray_eltidx(all_files, dptr);
        dicom_load(dptr->path, &dicom,
                   (char*)&data[w * h * i], w * h * 2);
        free(dptr->path);
    }
    utarray_free(all_files);

    // Generate 4 * 8bit RGBA values.
    // XXX: we should maybe support voxel data in 2 bytes monochrome.
    cube = malloc(w * h * d * sizeof(*cube));
    for (i = 0; i < w * h * d; i++) {
        cube[i] = uvec4b(255, 255, 255, clamp(data[i], 0, 255));
    }
    free(data);

    // This could belong to the caller function.
    mesh_blit(goxel()->image->active_layer->mesh, cube,
              -w / 2, -h / 2, -d / 2, w, h, d);

    free(cube);
}
Пример #5
0
static long get_arg_value(arg_t arg, const arg_t *args)
{
    const arg_t *argp;
    if (args) {
        for (argp = args; argp->name; argp++) {
            if (strcmp(argp->name, arg.name) == 0)
                return argp->value;
        }
    }
    // Default values for some types.
    if (arg.type == TYPE_GOXEL)
        return (long)goxel();
    if (arg.type == TYPE_IMAGE)
        return (long)goxel()->image;
    if (arg.type == TYPE_LAYER)
        return (long)goxel()->image->active_layer;
    if (arg.type == TYPE_BOX)
        return (long)&goxel()->selection;
    return 0;
}
Пример #6
0
static block_data_t *get_empty_data(void)
{
    static block_data_t *data = NULL;
    if (!data) {
        data = calloc(1, sizeof(*data));
        data->ref = 1;
        data->id = 0;
        goxel()->block_count++;
    }
    return data;
}
Пример #7
0
static long get_arg_value(arg_t arg, const arg_t *args)
{
    const arg_t *argp;
    if (args) {
        for (argp = args; argp->name; argp++) {
            if (strcmp(argp->name, arg.name) == 0)
                return argp->value;
        }
    }
    // Default values for some types.
    if (arg.type == TYPE_GOXEL)
        return (intptr_t)goxel();
    if (arg.type == TYPE_IMAGE)
        return (intptr_t)goxel()->image;
    if (arg.type == TYPE_LAYER)
        return (intptr_t)goxel()->image->active_layer;
    if (arg.type == TYPE_BOX)
        return (intptr_t)&goxel()->selection;
    if (str_equ(arg.name, "width"))
        return (int)goxel()->image->export_width;
    if (str_equ(arg.name, "height"))
        return (int)goxel()->image->export_height;
    return 0;
}
Пример #8
0
static int make_id(void)
{
    return ++goxel()->block_next_id;
}
Пример #9
0
void qubicle_import(const char *path)
{
    FILE *file;
    int version, color_format, orientation, compression, vmask, mat_count;
    int i, j, r, index, len, w, h, d, pos[3], x, y, z;
    char buff[256];
    uint32_t v;
    uvec4b_t *cube;
    const uint32_t CODEFLAG = 2;
    const uint32_t NEXTSLICEFLAG = 6;

    file = fopen(path, "r");
    version = READ(uint32_t, file);
    (void)version;
    color_format = READ(uint32_t, file);
    (void)color_format;
    orientation = READ(uint32_t, file);
    (void)orientation;
    compression = READ(uint32_t, file);
    (void)compression;
    vmask = READ(uint32_t, file);
    (void)vmask;
    mat_count = READ(uint32_t, file);

    for (i = 0; i < mat_count; i++) {
        len = READ(uint8_t, file);
        r = fread(buff, len, 1, file);
        (void)r;
        w = READ(uint32_t, file);
        h = READ(uint32_t, file);
        d = READ(uint32_t, file);
        pos[0] = READ(int32_t, file);
        pos[1] = READ(int32_t, file);
        pos[2] = READ(int32_t, file);
        (void)pos;
        cube = calloc(w * h * d, sizeof(*cube));
        if (compression == 0) {
            for (index = 0; index < w * h * d; index++) {
                v = READ(uint32_t, file);
                cube[index].uint32 = v;
                cube[index].a = cube[index].a ? 255 : 0;
            }
        } else {
            for (z = 0; z < d; z++) {
                index = 0;
                while (true) {
                    v = READ(uint32_t, file);
                    if (v == NEXTSLICEFLAG) {
                        break; // Next z.
                    }
                    len = 1;
                    if (v == CODEFLAG) {
                        len = READ(uint32_t, file);
                        v = READ(uint32_t, file);
                    }
                    for (j = 0; j < len; j++) {
                        x = index % w;
                        y = index / w;
                        cube[x + y * w + z * w * h].uint32 = v;
                        index++;
                    }
                }
            }
        }
        mesh_blit(goxel()->image->active_layer->mesh, cube,
                  pos[0], pos[1], pos[2], w, h, d);
        free(cube);
    }
}