commit ce8998df9170829b4dad02be6c9f032647e97ddc
parent 4c3c364acb9c7e686efc371097645af27d2778c5
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date: Fri, 22 Feb 2019 14:31:23 +0100
Output possible holes as OBJ segment files
Diffstat:
2 files changed, 144 insertions(+), 3 deletions(-)
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -23,6 +23,7 @@ set(SDIS_SOURCE_DIR ${PROJECT_SOURCE_DIR}/../src)
################################################################################
find_package(RCMake 0.4 REQUIRED)
find_package(RSys 0.6.1 REQUIRED)
+find_package(StarEnc 0.2.2 REQUIRED)
find_package(Stardis 0.6.1 REQUIRED)
find_package(StarSTL 0.3 REQUIRED)
@@ -30,6 +31,7 @@ set(TINYEXPR_SOURCE_DIR "${PROJECT_SOURCE_DIR}/../tinyexpr" CACHE PATH "Directo
include_directories(
${RSys_INCLUDE_DIR}
+ ${StarEnc_INCLUDE_DIR}
${Stardis_INCLUDE_DIR}
${StarSTL_INCLUDE_DIR}
${TINYEXPR_SOURCE_DIR})
@@ -42,7 +44,7 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${RCMAKE_SOURCE_DIR})
include(rcmake)
include(rcmake_runtime)
-rcmake_append_runtime_dirs(_runtime_dirs RSys Stardis StarSTL)
+rcmake_append_runtime_dirs(_runtime_dirs RSys Stardis StarEnc StarSTL)
################################################################################
# Configure and define targets
@@ -93,12 +95,12 @@ if(CMAKE_COMPILER_IS_GNUCC)
set_target_properties(sdis-app PROPERTIES
COMPILE_FLAGS "-std=c99 ${TE_DEFAULTS}"
VERSION ${VERSION})
- target_link_libraries(sdis-app Stardis StarSTL RSys tinyexpr m)
+ target_link_libraries(sdis-app Stardis StarEnc StarSTL RSys tinyexpr m)
elseif(MSVC)
set_target_properties(sdis-app PROPERTIES
COMPILE_FLAGS "${TE_DEFAULTS}"
VERSION ${VERSION})
- target_link_libraries(sdis-app Stardis StarSTL RSys tinyexpr MuslGetopt)
+ target_link_libraries(sdis-app Stardis StarEnc StarSTL RSys tinyexpr MuslGetopt)
endif()
rcmake_copy_runtime_libraries(sdis-app)
diff --git a/src/stardis-compute.c b/src/stardis-compute.c
@@ -4,8 +4,16 @@
#include <sdis.h>
#include <sdis_version.h>
#include <rsys/double3.h>
+#include <rsys/dynamic_array_uint.h>
#include <rsys/image.h>
+#include<star/senc.h>
+
+#include <rsys/hash_table.h>
+#define HTABLE_NAME vrtx_rank
+#define HTABLE_DATA unsigned
+#define HTABLE_KEY unsigned
+#include <rsys/hash_table.h>
static void
geometry_get_position
@@ -534,6 +542,134 @@ end:
error:
goto end;
}
+res_T
+create_edge_file_if
+ (struct sdis_scene* scn,
+ struct mem_allocator* allocator)
+{
+ res_T res = RES_OK;
+ unsigned i, comp, scount, vcount;
+ char name[64];
+ FILE* obj = NULL;
+ struct htable_vrtx_rank ranks;
+ char structs_initialized = 0;
+ struct senc_descriptor* analyze = NULL;
+ struct darray_uint comps;
+ struct darray_uint edges;
+ unsigned cc_count = 0;
+ unsigned *cc, *ee, uimax = UINT_MAX;
+
+ res = sdis_get_scene_analyze(scn, &analyze);
+ if (res != RES_OK) goto error;
+ res = sdis_release_scene_analyze(scn);
+ if (res != RES_OK) goto error;
+
+ ASSERT(scn && allocator);
+
+ res = senc_descriptor_get_frontier_segments_count(analyze, &scount);
+ if (res != RES_OK) goto error;
+
+ if(scount == 0)
+ /* No edge to exit */
+ return RES_OK;
+
+ fprintf(stderr, "Some frontier edges found: create OBJ files\n");
+
+ htable_vrtx_rank_init(allocator, &ranks);
+ darray_uint_init(allocator, &comps);
+ darray_uint_init(allocator, &edges);
+ structs_initialized = 1;
+
+ /* Exit vertices, with a new numbering scheme */
+ vcount = 0;
+ FOR_EACH(i, 0, scount) {
+ unsigned v, edge[2], rk[2];
+ res = senc_descriptor_get_frontier_segment(analyze, i, edge);
+ if(res != RES_OK) goto error;
+ FOR_EACH(v, 0, 2) {
+ unsigned* p_rank;
+ p_rank = htable_vrtx_rank_find(&ranks, edge + v);
+ if(p_rank) {
+ rk[v] = *p_rank;
+ } else {
+ /* First appearance: allocate a rank and exit it */
+ unsigned rank;
+ size_t tmp = htable_vrtx_rank_size_get(&ranks);
+ ASSERT(tmp < UINT_MAX);
+ rank = (unsigned) tmp;
+ res = htable_vrtx_rank_set(&ranks, edge + v, &rank);
+ if (res != RES_OK) goto error;
+ rk[v] = rank;
+ darray_uint_push_back(&comps, &uimax);
+ darray_uint_push_back(&edges, edge + v);
+ vcount++;
+ }
+ /* Manage components */
+ cc = darray_uint_data_get(&comps);
+ if(cc[rk[0]] != UINT_MAX || cc[rk[1]] != UINT_MAX) {
+ /* If both components known, they must be the same */
+ ASSERT(cc[rk[0]] == UINT_MAX || cc[rk[1]] == UINT_MAX
+ || cc[rk[0]] == cc[rk[1]]);
+ FOR_EACH(v, 0, 2) {
+ unsigned w = 1 - v; /* The other vertex */
+ if (cc[rk[v]] == UINT_MAX) cc[rk[v]] = cc[rk[w]];
+ }
+ } else {
+ /* None are in a know component: create a new one */
+ cc[rk[0]] = cc[rk[1]] = cc_count++;
+ }
+ }
+ }
+
+ /* Exit segments by component using the new numbering scheme */
+ cc = darray_uint_data_get(&comps);
+ ee = darray_uint_data_get(&edges);
+ FOR_EACH(comp, 0, cc_count) {
+ unsigned v;
+ snprintf(name, sizeof(name), "frontier_component_%u.obj", comp);
+ obj = fopen(name, "w");
+ if(!obj) goto error;
+ /* Exit all vertices even unused
+ * (same numbering scheme for all components) */
+ FOR_EACH(v, 0, vcount) {
+ double coord[3];
+ res = senc_descriptor_get_global_vertex(analyze, ee[v], coord);
+ if(res != RES_OK) goto error;
+ fprintf(obj, "v %f %f %f\n", SPLIT3(coord));
+ }
+ FOR_EACH(i, 0, scount) {
+ unsigned edge[2], new_ranks[2];
+ res = senc_descriptor_get_frontier_segment(analyze, i, edge);
+ if(res != RES_OK) goto error;
+ ASSERT(cc[edge[0]] == cc[edge[1]]);
+ if(cc[edge[0]] != comp)
+ /* Segment not in this component */
+ continue;
+ FOR_EACH(v, 0, 2) {
+ unsigned* p_rank;
+ p_rank = htable_vrtx_rank_find(&ranks, edge + v);
+ ASSERT(p_rank && *p_rank < vcount);
+ new_ranks[v] = *p_rank;
+ }
+#define OBJ_IDX(Rank) ((Rank)+1)
+ fprintf(obj, "l %u %u\n", OBJ_IDX(new_ranks[0]), OBJ_IDX(new_ranks[1]));
+#undef OBJ_IDX
+ }
+ fclose(obj); obj = NULL;
+ }
+
+end:
+ if(obj) fclose(obj);
+ if(analyze) senc_descriptor_ref_put(analyze);
+ if(structs_initialized) {
+ htable_vrtx_rank_release(&ranks);
+ darray_uint_release(&comps);
+ darray_uint_release(&edges);
+ }
+ return res;
+error:
+ goto end;
+}
res_T
stardis_compute(struct stardis* stardis, enum stardis_mode mode)
@@ -903,6 +1039,9 @@ stardis_compute(struct stardis* stardis, enum stardis_mode mode)
geometry_get_position, &stardis->geometry, &scn);
if (res != RES_OK) goto error;
+ res = create_edge_file_if(scn, &stardis->allocator);
+ if (res != RES_OK) goto error;
+
if (mode == IR_COMPUTE){
size_t width = (size_t)stardis->camera.img[0];
size_t height = (size_t)stardis->camera.img[1];