From 6722ef01e34f75bde72ba29e3279c0d1df030593 Mon Sep 17 00:00:00 2001 From: sanine Date: Sat, 11 Feb 2023 19:46:23 -0600 Subject: add materials and images processing --- src/CMakeLists.txt | 4 +- src/effect/CMakeLists.txt | 3 ++ src/effect/effect.h | 9 +++++ src/image/CMakeLists.txt | 3 ++ src/image/image.c | 99 +++++++++++++++++++++++++++++++++++++++++++++ src/image/image.h | 16 ++++++++ src/kalmia.c | 51 ++++++++++++++++++++--- src/material/CMakeLists.txt | 3 ++ src/material/material.c | 77 +++++++++++++++++++++++++++++++++++ src/material/material.h | 16 ++++++++ src/util/util.h | 7 ++++ 11 files changed, 281 insertions(+), 7 deletions(-) create mode 100644 src/effect/CMakeLists.txt create mode 100644 src/effect/effect.h create mode 100644 src/image/CMakeLists.txt create mode 100644 src/image/image.c create mode 100644 src/image/image.h create mode 100644 src/material/CMakeLists.txt create mode 100644 src/material/material.c create mode 100644 src/material/material.h (limited to 'src') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 746f370..d6141b3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -10,6 +10,8 @@ if (KALMIA_BUILD_TESTS) ) endif() -add_subdirectory(util) add_subdirectory(geometry) +add_subdirectory(image) +add_subdirectory(material) +add_subdirectory(util) add_subdirectory(xml) diff --git a/src/effect/CMakeLists.txt b/src/effect/CMakeLists.txt new file mode 100644 index 0000000..4b737fd --- /dev/null +++ b/src/effect/CMakeLists.txt @@ -0,0 +1,3 @@ +project(kalmia) + +target_sources(kalmia PUBLIC effect.c) diff --git a/src/effect/effect.h b/src/effect/effect.h new file mode 100644 index 0000000..91ed454 --- /dev/null +++ b/src/effect/effect.h @@ -0,0 +1,9 @@ +#ifndef KALMIA_EFFECT_H +#define KALMIA_EFFECT_H + +#include +#include "xml/xml.h" + + + +#endif diff --git a/src/image/CMakeLists.txt b/src/image/CMakeLists.txt new file mode 100644 index 0000000..991b39d --- /dev/null +++ b/src/image/CMakeLists.txt @@ -0,0 +1,3 @@ +project(kalmia) + +target_sources(kalmia PUBLIC image.c) diff --git a/src/image/image.c b/src/image/image.c new file mode 100644 index 0000000..464b86d --- /dev/null +++ b/src/image/image.c @@ -0,0 +1,99 @@ +#include +#include + +#include +#include "image.h" +#include "xml/xml.h" +#include "util/util.h" + + +int kai_read_init_from(struct ka_init_from_t *dest, struct kai_tag_t *src) +{ + KAI_CHECK_TAG_TYPE("init_from"); + + struct kai_tag_t *ref = kai_tag_get_first_child_with_type(src, "ref"); + if (ref != NULL) { + dest->ref = strdup(ref->content); + } + else { + dest->ref = strdup(src->content); + } + return 0; +} + +void kai_release_init_from(struct ka_init_from_t i) +{ + free(i.ref); +} + + +int kai_read_image(struct ka_image_t *dest, struct kai_tag_t *src) +{ + KAI_CHECK_TAG_TYPE("image"); + + dest->id = kai_tag_attr_to_dup(src, "id"); + dest->sid = kai_tag_attr_to_dup(src, "sid"); + dest->name = kai_tag_attr_to_dup(src, "name"); + + struct kai_tag_t *init_from = kai_tag_get_first_child_with_type(src, "init_from"); + if (init_from == NULL) { + free(dest->id); + free(dest->sid); + free(dest->name); + return -1; + } + + int result = kai_read_init_from(&(dest->init_from), init_from); + if (result != 0) { + free(dest->id); + free(dest->sid); + free(dest->name); + return -1; + } + + return 0; +} + +void kai_release_image(struct ka_image_t i) +{ + free(i.id); + free(i.sid); + free(i.name); + kai_release_init_from(i.init_from); +} + + +int kai_read_library_images(struct ka_library_images_t *dest, struct kai_tag_t *src) +{ + KAI_CHECK_TAG_TYPE("library_images"); + + dest->id = kai_tag_attr_to_dup(src, "id"); + dest->name = kai_tag_attr_to_dup(src, "name"); + + int result; + KAI_FILL_ARRAY_FROM_TAGS( + result, + dest->image, dest->image_count, struct ka_image_t, + src, "image", + kai_read_image, kai_release_image + ); + + if (result != 0) { + kai_release_library_images(*dest); + return -1; + } + + return 0; +} + +void kai_release_library_images(struct ka_library_images_t l) +{ + free(l.id); + free(l.name); + + int i; + for (i=0; i +#include "xml/xml.h" + +int kai_read_init_from(struct ka_init_from_t *dest, struct kai_tag_t *src); +void kai_release_init_from(struct ka_init_from_t i); + +int kai_read_image(struct ka_image_t *dest, struct kai_tag_t *src); +void kai_release_image(struct ka_image_t i); + +int kai_read_library_images(struct ka_library_images_t *dest, struct kai_tag_t *src); +void kai_release_library_images(struct ka_library_images_t l); + +#endif diff --git a/src/kalmia.c b/src/kalmia.c index 1ae0588..b789c4d 100644 --- a/src/kalmia.c +++ b/src/kalmia.c @@ -1,8 +1,19 @@ #include #include "geometry/geometry.h" +#include "image/image.h" +#include "material/material.h" #include "util/util.h" #include "xml/xml.h" +#define CHECK_ERROR(condition) \ +do { \ + if (condition) { \ + kai_tag_destroy(document); \ + kalmia_destroy(k); \ + return NULL; \ + } \ +} while (0) + struct kalmia_t * kalmia_parse_file(const char *filename) { @@ -12,6 +23,7 @@ struct kalmia_t * kalmia_parse_file(const char *filename) } struct kai_tag_t *lib; + int result; /* create kalmia_t */ struct kalmia_t *k = kai_alloc(sizeof(struct kalmia_t), "kalmia_t"); @@ -20,6 +32,10 @@ struct kalmia_t * kalmia_parse_file(const char *filename) return NULL; } + k->library_geometries = NULL; + k->library_materials = NULL; + k->library_images = NULL; + /* parse geometry */ lib = kai_tag_get_first_child_with_type(document, "library_geometries"); if (lib == NULL) { @@ -28,12 +44,35 @@ struct kalmia_t * kalmia_parse_file(const char *filename) } else { k->library_geometries = kai_alloc(sizeof(struct ka_library_geometries_t), "library_geometries"); - if (k->library_geometries == NULL) { - kai_tag_destroy(document); - free(k); - return NULL; - } - kai_read_library_geometries(k->library_geometries, lib); + CHECK_ERROR(k->library_geometries == NULL); + result = kai_read_library_geometries(k->library_geometries, lib); + CHECK_ERROR(result != 0); + } + + /* parse materials */ + lib = kai_tag_get_first_child_with_type(document, "library_materials"); + if (lib == NULL) { + /* no materials to read */ + k->library_materials = NULL; + } + else { + k->library_materials = kai_alloc(sizeof(struct ka_library_materials_t), "library_materials"); + CHECK_ERROR(k->library_materials == NULL); + result = kai_read_library_materials(k->library_materials, lib); + CHECK_ERROR(result != 0); + } + + /* parse images */ + lib = kai_tag_get_first_child_with_type(document, "library_images"); + if (lib == NULL) { + /* no images to read */ + k->library_images = NULL; + } + else { + k->library_images = kai_alloc(sizeof(struct ka_library_images_t), "library_images"); + CHECK_ERROR(k->library_images == NULL); + result = kai_read_library_images(k->library_images, lib); + CHECK_ERROR(result != 0); } /* clean up */ diff --git a/src/material/CMakeLists.txt b/src/material/CMakeLists.txt new file mode 100644 index 0000000..b5941da --- /dev/null +++ b/src/material/CMakeLists.txt @@ -0,0 +1,3 @@ +project(kalmia) + +target_sources(kalmia PUBLIC material.c) diff --git a/src/material/material.c b/src/material/material.c new file mode 100644 index 0000000..65e13d2 --- /dev/null +++ b/src/material/material.c @@ -0,0 +1,77 @@ +#include +#include "util/util.h" +#include "xml/xml.h" + + +int kai_read_instance_effect(struct ka_instance_effect_t *dest, struct kai_tag_t *src) +{ + KAI_CHECK_TAG_TYPE("instance_effect"); + + char *url = kai_tag_attr_to_dup(src, "url"); + if (url == NULL) { return -1; } + + dest->sid = kai_tag_attr_to_dup(src, "sid"); + dest->name = kai_tag_attr_to_dup(src, "name"); + dest->url = url; + + return 0; +} + +void kai_release_instance_effect(struct ka_instance_effect_t i) +{ + free(i.sid); + free(i.name); + free(i.url); +} + + +int kai_read_material(struct ka_material_t *dest, struct kai_tag_t *src) +{ + KAI_CHECK_TAG_TYPE("material"); + + struct kai_tag_t *child = kai_tag_get_first_child_with_type(src, "instance_effect"); + if (child == NULL) { return -1; } + int result = kai_read_instance_effect(&(dest->instance_effect), child); + if (result != 0) { return -1; } + + dest->id = kai_tag_attr_to_dup(src, "id"); + dest->name = kai_tag_attr_to_dup(src, "name"); + + return 0; +} + +void kai_release_material(struct ka_material_t m) +{ + free(m.id); + free(m.name); + kai_release_instance_effect(m.instance_effect); +} + + +int kai_read_library_materials(struct ka_library_materials_t *dest, struct kai_tag_t *src) +{ + int result; + KAI_FILL_ARRAY_FROM_TAGS( + result, + dest->material, dest->material_count, struct ka_material_t, + src, "material", + kai_read_material, kai_release_material + ); + if (result != 0) { return -1; } + + dest->id = kai_tag_attr_to_dup(src, "id"); + dest->name = kai_tag_attr_to_dup(src, "name"); + + return 0; +} + +void kai_release_library_materials(struct ka_library_materials_t l) +{ + free(l.id); + free(l.name); + int i; + for (i=0; i +#include "xml/xml.h" + +int kai_read_instance_effect(struct ka_instance_effect_t *dest, struct kai_tag_t *src); +void kai_release_instance_effect(struct ka_instance_effect_t i); + +int kai_read_material(struct ka_material_t *dest, struct kai_tag_t *src); +void kai_release_material(struct ka_material_t m); + +int kai_read_library_materials(struct ka_library_materials_t *dest, struct kai_tag_t *src); +void kai_release_library_materials(struct ka_library_materials_t l); + +#endif diff --git a/src/util/util.h b/src/util/util.h index 71cae4e..db957c6 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -88,4 +88,11 @@ do { \ } \ } while (0) + +/* macro to ensure tag type matches what we expect */ +#define KAI_CHECK_TAG_TYPE(expected) \ +if (strcmp(src->type, expected) != 0) { \ + return -1; \ +} + #endif -- cgit v1.2.1