commit 03851d9783bae8a8af2bde36cab66ea9863d59be
parent 0088efdaab3a8ded2b626fdabdeccb2cdddf6512
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date: Tue, 9 Apr 2024 15:45:35 +0200
Merge branch 'release_0.6'
Diffstat:
9 files changed, 2466 insertions(+), 255 deletions(-)
diff --git a/README.md b/README.md
@@ -39,6 +39,14 @@ variable the install directories of its dependencies.
Release notes
-------------
+### Version 0.6
+
+- Major rework on the code that groups connex components to create enclosures.
+- Add tests showing bugs at the grouping stage in previous release.
+- Add debug code that allows to dump how connex components are grouped.
+- Fix compilation warnings.
+- Sets the required version of Star-3D to 0.9.
+
### Version 0.5.5
- Fixes a crash linked to numerical accuracy that caused connex components
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -30,7 +30,7 @@ cmake_dependent_option(HUGE_ADDITIONAL_TESTS
# Check dependencies
###############################################################################
find_package(RCMake 0.4 REQUIRED)
-find_package(Star3D 0.8 REQUIRED)
+find_package(Star3D 0.9 REQUIRED)
find_package(RSys 0.8.1 REQUIRED)
find_package(OpenMP 2.0 REQUIRED)
@@ -63,8 +63,8 @@ endif()
# Configure and define targets
###############################################################################
set(VERSION_MAJOR 0)
-set(VERSION_MINOR 5)
-set(VERSION_PATCH 5)
+set(VERSION_MINOR 6)
+set(VERSION_PATCH 0)
set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH})
set(SENC3D_FILES_SRC
@@ -162,6 +162,7 @@ if(NOT NO_TEST)
new_test(test_senc3d_some_triangles)
new_test(test_senc3d_unspecified_medium)
new_test(test_senc3d_zero_distance)
+ new_test(test_senc3d_glazing)
target_link_libraries(test_senc3d_enclosure Star3D)
rcmake_copy_runtime_libraries(test_senc3d_enclosure)
diff --git a/src/senc3d.h b/src/senc3d.h
@@ -141,7 +141,16 @@ enum senc3d_convention {
/* Geometrical normals point toward the enclosure */
SENC3D_CONVENTION_NORMAL_INSIDE = BIT(2),
/* Geometrical normals point to the opposite of the enclosure */
- SENC3D_CONVENTION_NORMAL_OUTSIDE = BIT(3)
+ SENC3D_CONVENTION_NORMAL_OUTSIDE = BIT(3),
+
+ /*
+ * Additional bits used for debugging purposes
+ */
+
+ /* Dump identified connex components before grouping in STL files */
+ SENC3D_DUMP_COMPONENTS_STL = BIT(4),
+ /* Extensive logs on grouping algorithm */
+ SENC3D_LOG_COMPONENTS_INFORMATION = BIT(5)
};
BEGIN_DECLS
diff --git a/src/senc3d_scene_analyze.c b/src/senc3d_scene_analyze.c
@@ -27,8 +27,10 @@
#include <rsys/mem_allocator.h>
#include <rsys/hash_table.h>
#include <rsys/dynamic_array.h>
+#include <rsys/dynamic_array_uint.h>
#include <rsys/dynamic_array_uchar.h>
#include <rsys/clock_time.h>
+#include <rsys/str.h>
#include <star/s3d.h>
@@ -38,7 +40,7 @@
#include <stdlib.h>
#define CC_DESCRIPTOR_NULL__ {\
- 0, 0, NULL,\
+ 0, 0, {{DBL_MAX,-DBL_MAX}, {DBL_MAX,-DBL_MAX}, {DBL_MAX,-DBL_MAX}}, NULL,\
0, INT_MAX, VRTX_NULL__, 0,\
CC_ID_NONE, CC_GROUP_ROOT_NONE, ENCLOSURE_NULL__,\
{ TRG_NULL__, 0}\
@@ -61,15 +63,28 @@ const struct cc_descriptor CC_DESCRIPTOR_NULL = CC_DESCRIPTOR_NULL__;
#define HTABLE_DATA char
#include <rsys/hash_table.h>
+/* A threshold for dot products:
+ * If ray.normal < threshold we suspect accuracy could be a problem */
+#define DOT_THRESHOLD 0.0001f
+
+struct filter_ctx0 {
+ component_id_t origin_component;
+ struct darray_triangle_comp* triangles_comp;
+};
+
struct filter_ctx1 {
struct senc3d_scene* scn;
struct s3d_scene_view* view;
component_id_t origin_component;
struct darray_triangle_comp* triangles_comp;
struct darray_ptr_component_descriptor* components;
- /* Result of hit */
+ /* Tmp data used across filter calls */
double current_6volume;
+ float s;
+ /* Result of hit */
component_id_t hit_component;
+ float hit_dir[3], hit_dist;
+ struct s3d_primitive hit_prim;
};
struct filter_ctx2 {
@@ -79,6 +94,7 @@ struct filter_ctx2 {
};
enum fctx_type {
+ FCTX0,
FCTX1,
FCTX2
};
@@ -86,6 +102,7 @@ enum fctx_type {
struct filter_ctx {
enum fctx_type type;
union {
+ struct filter_ctx0 ctx0;
struct filter_ctx1 ctx1;
struct filter_ctx2 ctx2;
} c;
@@ -107,6 +124,76 @@ neighbour_cmp(const void* w1, const void* w2)
return (a1 > a2) - (a1 < a2);
}
+/* Returns 1 if cc2 is inside cc1, 0 otherwise */
+static FINLINE int
+is_component_inside
+ (struct cc_descriptor* cc1,
+ struct cc_descriptor* cc2,
+ struct filter_ctx1* ctx)
+{
+ int i;
+ side_id_t side;
+ const struct triangle_in* trg = NULL;
+ double pt[3] = { 0, 0, 0 };
+ float org[3], dir[3] = { 0, 0, 1 }, rg[2] = { 0, FLT_MAX };
+ struct filter_ctx ctx2;
+ struct s3d_hit hit = S3D_HIT_NULL;
+ const struct triangle_comp*
+ trg_comp = darray_triangle_comp_cdata_get(ctx->triangles_comp);
+ const struct triangle_in*
+ triangles = darray_triangle_in_cdata_get(&ctx->scn->triangles_in);
+ const union double3* vertices = darray_position_cdata_get(&ctx->scn->vertices);
+ ASSERT(cc1 && cc2 && ctx);
+ /* Volume must be compatible */
+ if(fabs(cc2->_6volume) >= fabs(cc1->_6volume))
+ return 0;
+ /* Bbox must be compatible */
+ for(i = 0; i < 3; i++) {
+ if(cc2->bbox[i][0] < cc1->bbox[i][0] || cc2->bbox[i][1] > cc1->bbox[i][1])
+ return 0;
+ }
+ /* Check if component cc2 is inside component cc1.
+ * We already know that bbox and volume allow cc2 to fit inside component
+ * ccc1, but it is not enough.
+ * The method is to cast a ray from cc2 and count the number of times it
+ * crosses component cc1; as components must not overlap, testing from a
+ * single point is OK, as long as the point is not on cc1 boundary (it is on
+ * cc2 boundary, though). */
+ for(side = cc2->side_range.first; side <= cc2->side_range.last; side++) {
+ /* Find a triangle on cc2 boundary that is not on cc1 boundary (it exists,
+ * as the 2 components cannot share all their triangles) */
+ trg_id_t t = TRGSIDE_2_TRG(side);
+ const component_id_t* candidate_comp = trg_comp[t].component;
+ if(candidate_comp[SENC3D_FRONT] != cc2->cc_id
+ && candidate_comp[SENC3D_BACK] != cc2->cc_id)
+ continue;
+ if(candidate_comp[SENC3D_FRONT] == cc1->cc_id
+ || candidate_comp[SENC3D_BACK] == cc1->cc_id)
+ continue;
+ /* This triangle is OK */
+ trg = triangles + t;
+ break;
+ }
+ ASSERT(trg != NULL);
+ /* Any point on trg can do the trick: use the barycenter */
+ FOR_EACH(i, 0, 3) {
+ vrtx_id_t v = trg->vertice_id[i];
+ ASSERT(v < darray_position_size_get(&ctx->scn->vertices));
+ d3_add(pt, pt, vertices[v].vec);
+ }
+ d3_divd(pt, pt, 3);
+ f3_set_d3(org, pt);
+ /* Trace a ray and count intersections with component c */
+ ctx2.type = FCTX2;
+ ctx2.c.ctx2.triangles_comp = ctx->triangles_comp;
+ ctx2.c.ctx2.cpt = 0;
+ ctx2.c.ctx2.component = cc1->cc_id;
+ S3D(scene_view_trace_ray(ctx->view, org, dir, rg, &ctx2, &hit));
+ /* cc2 is not inside cc1 if cpt is even */
+ if(ctx2.c.ctx2.cpt % 2 == 0) return 0;
+ return 1;
+}
+
static side_id_t
get_side_not_in_connex_component
(const side_id_t last_side,
@@ -131,7 +218,11 @@ get_side_not_in_connex_component
/* Here unsigned are required by s3d API */
static void
-get_scn_indices(const unsigned itri, unsigned ids[3], void* ctx) {
+get_scn_indices
+ (const unsigned itri,
+ unsigned ids[3],
+ void* ctx)
+{
int i;
const struct senc3d_scene* scene = ctx;
const struct triangle_in* trg =
@@ -145,7 +236,11 @@ get_scn_indices(const unsigned itri, unsigned ids[3], void* ctx) {
/* Here unsigned are required by s3d API */
static void
-get_scn_position(const unsigned ivert, float pos[3], void* ctx) {
+get_scn_position
+ (const unsigned ivert,
+ float pos[3],
+ void* ctx)
+{
const struct senc3d_scene* scene = ctx;
const union double3* pt =
darray_position_cdata_get(&scene->vertices) + ivert;
@@ -162,212 +257,330 @@ self_hit_filter
void* filter_data)
{
struct filter_ctx* fctx_ = ray_data;
- struct filter_ctx1* fctx;
- const struct triangle_comp* trg_comp;
- const component_id_t* hit_comp;
- float s = 0;
- enum senc3d_side hit_side;
- int i;
- double org_z, mz = -INF;
- const struct triangle_in* triangles;
- const struct triangle_in* trg = NULL;
- const union double3* vertices;
- struct cc_descriptor* const* comp_descriptors;
-
- (void)ray_dir; (void)ray_range; (void)filter_data;
- ASSERT(hit && fctx_);
-
- if(fctx_->type == FCTX2) {
- /* The filter is used to count the hits on some component along
- * an infinite ray */
- struct filter_ctx2* ctx2 = &fctx_->c.ctx2;
- ASSERT(hit->prim.prim_id
- < darray_triangle_comp_size_get(ctx2->triangles_comp));
- trg_comp = darray_triangle_comp_cdata_get(ctx2->triangles_comp);
- hit_comp = trg_comp[hit->prim.prim_id].component;
- if(hit_comp[SENC3D_FRONT] == ctx2->component
- || hit_comp[SENC3D_BACK] == ctx2->component)
- {
- ctx2->cpt++;
- }
- return 1; /* Reject to continue counting */
- }
- /* The filter is called from a point query on successive hits found from
- * ray_org, that belongs to origin_component. It can keep or reject the hit.
- * Hits are only submitted inside a certain radius from ray_org, that is
- * decreased to the hit distance for every hit that is kept.
- * At the end, the last kept hit (= the closest), determines a component to
- * which origin_component is linked. At a later stage the algorithm process
- * linked components to determine their relative inclusions.
- *
- * For each hit, the filter computes if the hit is on a component above
- * origin_component (that is with >= Z).
- * If the hit is distant (dist>0), we just keep the hit as a valid candidate,
- * but things get more tricky when dist==0 (ray_org is a vertex where some
- * other components are in contact with origin_component).
- * In this case, one of the other components can include the origin_component
- * (greater volume needed), or they can be disjoint, with (at least) ray_org
- * as a common vertex (they can also partially intersect, but this is invalid
- * and remains undetected by star enclosures). */
- ASSERT(fctx_->type == FCTX1);
- fctx = &fctx_->c.ctx1;
- comp_descriptors = darray_ptr_component_descriptor_cdata_get(fctx->components);
- trg_comp = darray_triangle_comp_cdata_get(fctx->triangles_comp);
- hit_comp = trg_comp[hit->prim.prim_id].component;
- triangles = darray_triangle_in_cdata_get(&fctx->scn->triangles_in);
- vertices = darray_position_cdata_get(&fctx->scn->vertices);
- ASSERT(hit->prim.prim_id
- < darray_triangle_comp_size_get(fctx->triangles_comp));
+ (void)ray_org; (void)ray_range; (void)filter_data;
+ ASSERT(fctx_);
ASSERT(hit->uv[0] == CLAMP(hit->uv[0], 0, 1));
ASSERT(hit->uv[1] == CLAMP(hit->uv[1], 0, 1));
- /* No self hit */
- if(hit_comp[SENC3D_FRONT] == fctx->origin_component
- || hit_comp[SENC3D_BACK] == fctx->origin_component)
- return 1; /* Reject */
-
- if(hit->distance == 0) {
- /* origin_component is in contact with some other components
- * We will need further exploration to know if they should be considered */
- int n;
-
- /* If same component, process only once */
- FOR_EACH(n, 0, (hit_comp[SENC3D_FRONT] == hit_comp[SENC3D_BACK] ? 1 : 2)) {
- const enum senc3d_side sides[2] = { SENC3D_FRONT, SENC3D_BACK };
- component_id_t c = hit_comp[sides[n]];
- side_id_t side;
- double pt[3] = { 0, 0, 0 };
- float org[3], dir[3] = { 0, 0, 1 }, rg[2] = { 0, FLT_MAX };
- struct s3d_hit hit2 = S3D_HIT_NULL;
- struct filter_ctx fctx2;
- ASSERT(c < darray_ptr_component_descriptor_size_get(fctx->components));
- if(comp_descriptors[c]->is_outer_border) {
- if(fabs(comp_descriptors[c]->_6volume)
- <= fabs(comp_descriptors[fctx->origin_component]->_6volume))
- /* Component is not large enough to include origin_component */
- continue;
- } else {
- vrtx_id_t c_z_id = comp_descriptors[c]->max_z_vrtx_id;
- vrtx_id_t o_z_id = comp_descriptors[fctx->origin_component]->max_z_vrtx_id;
- ASSERT(c_z_id < darray_position_size_get(&fctx->scn->vertices));
- ASSERT(o_z_id < darray_position_size_get(&fctx->scn->vertices));
- if(vertices[c_z_id].pos.z <= vertices[o_z_id].pos.z)
- /* Component is not above origin_component */
- continue;
- }
- /* Check if component c includes origin_component; as components cannot
- * overlap, testing a single point is OK, as long as the point is not on
- * c boundary (can be on origin_component boundary, though).
- * As this case is supposed to be rare, we go for a basic algorithm */
- for(side = comp_descriptors[fctx->origin_component]->side_range.first;
- side <= comp_descriptors[fctx->origin_component]->side_range.last;
- side++)
+ switch (fctx_->type) {
+ default: FATAL("Invalid");
+
+ case FCTX2: {
+ /* The filter is used to count the hits on some component along an
+ * infinite ray */
+ struct filter_ctx2* ctx2 = &fctx_->c.ctx2;
+ const struct triangle_comp* trg_comp;
+ const component_id_t* hit_comp;
+ ASSERT(hit->prim.prim_id
+ < darray_triangle_comp_size_get(ctx2->triangles_comp));
+ trg_comp = darray_triangle_comp_cdata_get(ctx2->triangles_comp);
+ hit_comp = trg_comp[hit->prim.prim_id].component;
+ if(hit_comp[SENC3D_FRONT] == ctx2->component
+ || hit_comp[SENC3D_BACK] == ctx2->component)
{
- /* Find a triangle on origin_component boundary that is not on c
- * boundary (the 2 components cannot share all their triangles) */
- trg_id_t t = TRGSIDE_2_TRG(side);
- const component_id_t* candidate_comp = trg_comp[t].component;
- if(candidate_comp[SENC3D_FRONT] != fctx->origin_component
- && candidate_comp[SENC3D_BACK] != fctx->origin_component)
- continue;
- if(candidate_comp[SENC3D_FRONT] == c
- || candidate_comp[SENC3D_BACK] == c)
- continue;
- /* This triangle is OK */
- trg = triangles + t;
- break;
+ ctx2->cpt++;
}
- ASSERT(trg != NULL);
- /* Any point on trg not on an edge can do the trick: use the barycenter */
- FOR_EACH(i, 0, 3) {
- vrtx_id_t v = trg->vertice_id[i];
- ASSERT(v < darray_position_size_get(&fctx->scn->vertices));
- d3_add(pt, pt, vertices[v].vec);
+ return 1; /* Reject to continue counting */
+ }
+
+ case FCTX0: {
+ /* This filter is called from a closest point query from a point belonging
+ * to origin_component. The returned hit is used to determine the search
+ * radius for FCTX1 main computation. */
+ struct filter_ctx0* ctx = &fctx_->c.ctx0;
+ const struct triangle_comp*
+ trg_comp = darray_triangle_comp_cdata_get(ctx->triangles_comp);
+ const component_id_t*
+ hit_comp = trg_comp[hit->prim.prim_id].component;
+
+ ASSERT(hit->prim.prim_id
+ < darray_triangle_comp_size_get(ctx->triangles_comp));
+
+ if(hit_comp[SENC3D_FRONT] == ctx->origin_component
+ || hit_comp[SENC3D_BACK] == ctx->origin_component)
+ {
+ /* Self hit */
+ return 1; /* Reject */
}
- d3_divd(pt, pt, 3);
- f3_set_d3(org, pt);
- /* Trace a ray and count intersections with components of trg */
- fctx2.type = FCTX2;
- fctx2.c.ctx2.triangles_comp = fctx->triangles_comp;
- fctx2.c.ctx2.cpt = 0;
- fctx2.c.ctx2.component = c;
- S3D(scene_view_trace_ray(fctx->view, org, dir, rg, &fctx2, &hit2));
- ASSERT(S3D_HIT_NONE(&hit2)); /* The ray is supposed to go to infinity */
- /* origin_component is linked_to an outer component if cpt is odd,
- * linked_to an inner component if cpt is even */
- if(comp_descriptors[c]->is_outer_border == (fctx2.c.ctx2.cpt % 2)) {
- double v = fabs(comp_descriptors[c]->_6volume);
- /* If origin_component is inside several components, the one we are
- * looking for is the smallest one */
- if(v >= fctx->current_6volume) continue;
- fctx->hit_component = fctx2.c.ctx2.component;
- fctx->current_6volume = v;
- /* Continue searching for a smaller component that includes
- * origin_component */
+
+ if(hit->distance > 0 && ray_dir[2] <= 0) {
+ return 1; /* Not upward */
}
+
+ return 0; /* Keep*/
}
- return 1; /* Reject */
- }
- /* Reject hits with < Z */
- ASSERT(hit->prim.prim_id <
- darray_triangle_in_size_get(&fctx->scn->triangles_in));
- trg = triangles + hit->prim.prim_id;
- /* Check if the hit is above ray_org (hit[2] > ray_org[2])
- * As we cannot rely on numerical accuracy when computing hit positions,
- * we use the triangle vertices to check if some part of the hit triangle
- * is above ray_org */
- FOR_EACH(i, 0, 3) {
- vrtx_id_t v = trg->vertice_id[i];
- const union double3* p = vertices + v;
- ASSERT(v < darray_position_size_get(&fctx->scn->vertices));
- if(i == 0 || mz < p->pos.z) mz = p->pos.z;
- }
- /* Don't use org[2] as, being float, it would lead to a float VS double
- * comparison that causes accuracy problems. */
- org_z = vertices[comp_descriptors[fctx->origin_component]->max_z_vrtx_id].pos.z;
- if(mz <= org_z)
- return 1; /* Hit triangle is below ray_org: reject */
-
- if(hit_comp[SENC3D_FRONT] == hit_comp[SENC3D_BACK]) {
- /* Easy case and hit component is known */
- fctx->hit_component = hit_comp[SENC3D_FRONT];
- return 0; /* Keep */
- }
+ case FCTX1: {
+ /* This filter is called from a closest point query from a point belonging
+ * to origin_component. The returned hit is used to determine a component
+ * to which origin_component is linked. At a later stage the algorithm
+ * process linked components to determine their relative inclusions.
+ *
+ * This filter is called with a search distance that has been ajusted in
+ * FCTX0 filter. This distance must be left unchanged to ensure visiting
+ * all the surfaces at the determined distance: allways reject hits to
+ * avoid decreasing search distance.
+ *
+ * For each hit, the filter computes if the hit is on a component above
+ * origin_component (that is with >= Z).
+ * If the hit is distant (dist>0), we just keep the hit as a valid candidate,
+ * but things get more tricky when dist==0 (ray_org is a vertex where some
+ * other components can be in contact with origin_component).
+ * In this case, one of the other components can include the origin_component
+ * (greater volume needed), or they can be disjoint, with (at least) ray_org
+ * as a common vertex (they can also partially intersect, but this is invalid
+ * and remains undetected by star enclosures). */
+ struct filter_ctx1* ctx = &fctx_->c.ctx1;
+ struct cc_descriptor* const*
+ comp_descriptors = darray_ptr_component_descriptor_cdata_get(ctx->components);
+ const struct triangle_comp*
+ trg_comp = darray_triangle_comp_cdata_get(ctx->triangles_comp);
+ const component_id_t*
+ hit_comp = trg_comp[hit->prim.prim_id].component;
+ const union double3* vertices = darray_position_cdata_get(&ctx->scn->vertices);
+ enum senc3d_side hit_side;
+ float s = 0, hit_normal[3], rdir[3];
+ const int log_components =
+ ctx->scn->convention & SENC3D_LOG_COMPONENTS_INFORMATION;
+
+ ASSERT(hit->prim.prim_id
+ < darray_triangle_comp_size_get(ctx->triangles_comp));
+
+ if(log_components) {
+ printf("Component #%u: investigating hit (d=%g, n= %g %g %g).\n",
+ ctx->origin_component, hit->distance, SPLIT3(hit->normal));
+ }
- /* Compute hit side by using the vertex with best accuracy */
- FOR_EACH(i, 0, 3) {
- float tmps, tmp[3], dir[3];
- vrtx_id_t v = trg->vertice_id[i];
- const union double3* p = vertices + v;
- ASSERT(v < darray_position_size_get(&fctx->scn->vertices));
- f3_sub(dir, f3_set_d3(tmp, p->vec), ray_org);
- tmps = f3_dot(dir, hit->normal);
- if(i == 0 || fabsf(s) < fabsf(tmps)) s = tmps;
- }
+ if(hit->distance > ctx->hit_dist) {
+ /* No improvement */
+ if(log_components) {
+ printf("Component #%u: further away => reject.\n", ctx->origin_component);
+ }
+ return 1;
+ }
- /* We cannot know which side to consider if s==0.
- * As hit distance > 0 and the 2 sides belong to 2 different components,
- * another candidate must selected afterwards (can be at greater distance,
- * disallowing to restrict the search distance here) */
- if(s == 0) {
- fctx->hit_component = COMPONENT_NULL__;
- return 1; /* Reject */
- }
+ if(hit_comp[SENC3D_FRONT] == ctx->origin_component
+ || hit_comp[SENC3D_BACK] == ctx->origin_component)
+ {
+ /* Self hit */
+ if(log_components) {
+ printf("Component #%u: self hit => reject.\n", ctx->origin_component);
+ }
+ return 1;
+ }
- /* Determine which side was hit */
- hit_side =
- ((s < 0) /* Facing geometrical normal of hit */
- == ((fctx->scn->convention & SENC3D_CONVENTION_NORMAL_FRONT) != 0))
- /* Warning: following Embree 2 convention for geometrical normals,
- * the Star3D hit normal is left-handed while star-enclosures-3d uses
- * right-handed convention */
- ? SENC3D_BACK : SENC3D_FRONT;
+ if(hit->distance > 0 && ray_dir[2] <= 0) {
+ /* Not upward */
+ if(log_components) {
+ printf("Component #%u: not upward => reject.\n", ctx->origin_component);
+ }
+ return 1;
+ }
- fctx->hit_component = hit_comp[hit_side];
+ if(hit->distance == 0) {
+ /* origin_component is in contact with some other components
+ * We will need further exploration to know if they should be considered */
+ int n;
+
+ /* If same component, process only once */
+ FOR_EACH(n, 0, (hit_comp[SENC3D_FRONT] == hit_comp[SENC3D_BACK] ? 1 : 2)) {
+ const enum senc3d_side sides[2] = { SENC3D_FRONT, SENC3D_BACK };
+ component_id_t c = hit_comp[sides[n]];
+ ASSERT(c < darray_ptr_component_descriptor_size_get(ctx->components));
+ if(c == ctx->hit_component) {
+ /* Cannot change ctx->hit_component */
+ if(log_components) {
+ printf("Component #%u: hit component #%u and already linked to it:"
+ " reject\n", ctx->origin_component, c);
+ }
+ continue;
+ }
+ if(comp_descriptors[c]->is_outer_border) {
+ double v;
+ /* The inner component we are trying to link can only be linked to
+ * an outer component if it is inside */
+ if(log_components) {
+ printf("Component #%u: hit outer component #%u\n",
+ ctx->origin_component, c);
+ }
+ if(!is_component_inside(comp_descriptors[c],
+ comp_descriptors[ctx->origin_component], ctx))
+ {
+ if(log_components) {
+ printf("Component #%u: not inside: reject\n", ctx->origin_component);
+ }
+ continue;
+ }
+ v = fabs(comp_descriptors[c]->_6volume);
+ /* If already linked to an inner component, prefer an outer one
+ * regardless of their respective volumes.
+ * If origin_component is inside several outer components, the one
+ * we are looking for is the smallest one (to manage outer component
+ * inside another outer component). */
+ if((ctx->hit_component != COMPONENT_NULL__
+ && !comp_descriptors[ctx->hit_component]->is_outer_border )
+ || v < ctx->current_6volume) {
+ ctx->hit_component = c;
+ ctx->current_6volume = v;
+ ctx->hit_dist = 0;
+ ctx->hit_prim = hit->prim;
+ if(log_components) {
+ if(v < ctx->current_6volume) {
+ printf("Component #%u: currently the smaller one: keep component"
+ " #%u\n", ctx->origin_component, ctx->hit_component);
+ } else {
+ printf("Component #%u: change from inner to outer: keep component"
+ " #%u\n", ctx->origin_component, ctx->hit_component);
+ }
+ }
+ } else {
+ if(log_components) {
+ printf("Component #%u: not the smaller one: reject\n",
+ ctx->origin_component);
+ }
+ continue;
+ }
+ } else {
+ /* c is an inner component */
+ vrtx_id_t c_z_id;
+ double org_z, v;
+ /* If we've already found a valid outer component, inner components
+ * should not be considered anymore */
+ if(log_components) {
+ printf("Component #%u: hit inner component #%u\n",
+ ctx->origin_component, c);
+ }
+ if(ctx->hit_component != COMPONENT_NULL__
+ && comp_descriptors[ctx->hit_component]->is_outer_border )
+ {
+ if(log_components) {
+ printf("Component #%u: already in an outer component: reject\n",
+ ctx->origin_component);
+ }
+ continue;
+ }
+ /* The inner component we are trying to link can only be linked to
+ * another inner component if (at least partly) above it and not
+ * inside */
+ c_z_id = comp_descriptors[c]->max_z_vrtx_id;
+ org_z =
+ vertices[comp_descriptors[ctx->origin_component]->max_z_vrtx_id].pos.z;
+ ASSERT(c_z_id < darray_position_size_get(&ctx->scn->vertices));
+ ASSERT(vertices[c_z_id].pos.z >= org_z);
+ if(vertices[c_z_id].pos.z == org_z) {
+ if(log_components) {
+ printf("Component #%u: not (even in part) above: reject\n",
+ ctx->origin_component);
+ }
+ continue; /* Not above */
+ }
+ if(is_component_inside(comp_descriptors[c],
+ comp_descriptors[ctx->origin_component], ctx))
+ {
+ if(log_components) {
+ printf("Component #%u: not outside: reject\n", ctx->origin_component);
+ }
+ continue; /* Inside */
+ }
+ v = fabs(comp_descriptors[c]->_6volume);
+ /* If origin_component is facing several inner components, the one
+ * we are looking for is the largest one (to manage inner component
+ * inside another inner component) */
+ if(ctx->current_6volume == DBL_MAX || v > ctx->current_6volume) {
+ ctx->hit_component = c;
+ ctx->current_6volume = v;
+ ctx->hit_dist = 0;
+ ctx->hit_prim = hit->prim;
+ if(log_components) {
+ printf("Component #%u: currently the bigger one: keep component"
+ " #%u\n", ctx->origin_component, ctx->hit_component);
+ }
+ } else {
+ if(log_components) {
+ printf("Component #%u: not the bigger one: reject\n",
+ ctx->origin_component);
+ }
+ continue;
+ }
+ }
+ }
+ return 1;
+ }
+
+ ASSERT(hit->distance > 0);
+ if(hit_comp[SENC3D_FRONT] == hit_comp[SENC3D_BACK]) {
+ /* Easy case and hit component is known */
+ ctx->hit_component = hit_comp[SENC3D_FRONT];
+ ctx->s = 1;
+ f3_set(ctx->hit_dir, ray_dir);
+ ctx->hit_dist = hit->distance;
+ ctx->hit_prim = hit->prim;
+ if(log_components) {
+ printf("Component #%u: 2 sides with same component: keep component"
+ " #%u\n", ctx->origin_component, ctx->hit_component);
+ }
+ return 1;
+ }
+
+ /* Compute hit side */
+ /* For s to be comparable, vectors must be normailzed */
+ f3_normalize(hit_normal, hit->normal);
+ f3_normalize(rdir, ray_dir);
+ s = f3_dot(rdir, hit_normal); /* Can be NaN for tiny distances */
+ if(isnan(s)) {
+ /* Try to fix it */
+ f3_divf(rdir, ray_dir, hit->distance);
+ f3_normalize(rdir, rdir);
+ s = f3_dot(rdir, hit_normal);
+ ASSERT(!isnan(s));
+ if(log_components) {
+ printf("Component #%u: had to fix s (was NaN)\n", ctx->origin_component);
+ }
+ }
- return 0; /* Keep */
+ if(ctx->hit_dist == hit->distance && fabsf(ctx->s) >= fabsf(s)) {
+ /* Same distance with no s improvement: keep the previous hit */
+ if(log_components) {
+ printf("Component #%u: not improving s (%g VS %g): reject\n",
+ ctx->origin_component, s, ctx->s);
+ }
+ return 1;
+ }
+
+ if(fabsf(s) < DOT_THRESHOLD) {
+ /* We cannot know for sure which side to consider */
+ ctx->hit_component = COMPONENT_NULL__;
+ ctx->s = s;
+ f3_set(ctx->hit_dir, ray_dir);
+ ctx->hit_dist = hit->distance;
+ ctx->hit_prim = hit->prim;
+ if(log_components) {
+ printf("Component #%u: tiny s (%g): keep but don't know the component\n",
+ ctx->origin_component, s);
+ }
+ return 1;
+ }
+ /* Determine which side was hit */
+ hit_side =
+ ((s < 0) /* Facing geometrical normal of hit */
+ == ((ctx->scn->convention & SENC3D_CONVENTION_NORMAL_FRONT) != 0))
+ /* Warning: following Embree 2 convention for geometrical normals,
+ * the Star3D hit normal is left-handed while star-enclosures-3d uses
+ * right-handed convention */
+ ? SENC3D_BACK : SENC3D_FRONT;
+ ctx->hit_component = hit_comp[hit_side];
+ ctx->s = s;
+ f3_set(ctx->hit_dir, ray_dir);
+ ctx->hit_dist = hit->distance;
+ ctx->hit_prim = hit->prim;
+ if(log_components) {
+ printf("Component #%u: standard s (%g): keep component #%u\n",
+ ctx->origin_component, s, ctx->hit_component);
+ }
+ return 1;
+ }
+ }
}
static void
@@ -425,7 +638,7 @@ extract_connex_components
const struct side_range* media_use
= darray_side_range_cdata_get(&scn->media_use);
FOR_EACH(s, 0, 2) {
- const side_id_t side = TRGIDxSIDE_2_TRGSIDE(t_, s);
+ const side_id_t side = TRGIDxSIDE_2_TRGSIDE(t_, (enum senc3d_side)s);
medium_id_t medium = trg_in->medium[s];
m_idx = medium_id_2_medium_idx(medium);
ASSERT(media_use[m_idx].first <= side && side
@@ -636,8 +849,8 @@ extract_connex_components
>= medium_id_2_medium_idx(medium));
cmp[side] = cc->cc_id;
}
- /* Compute component area and volume, and record information on the
- * max_z side of the component to help find out if the component is
+ /* Compute component's bbox, area and volume, and record information on
+ * the max_z side of the component to help find out if the component is
* inner or outer */
fst_nz = 1;
max_nz = 0;
@@ -656,10 +869,18 @@ extract_connex_components
const double* v0 = vertices[trg_in->vertice_id[0]].vec;
const double* v1 = vertices[trg_in->vertice_id[1]].vec;
const double* v2 = vertices[trg_in->vertice_id[2]].vec;
- int is_2sided = (trg_comp->component[SENC3D_FRONT]
+ int n, is_2sided = (trg_comp->component[SENC3D_FRONT]
== trg_comp->component[SENC3D_BACK]);
- /* Compute component area and volume */
+ /* Compute component's bbox, area and volume */
+ for(n = 0; n < 3; n++) {
+ cc->bbox[n][0] = MMIN(cc->bbox[n][0], v0[n]);
+ cc->bbox[n][0] = MMIN(cc->bbox[n][0], v1[n]);
+ cc->bbox[n][0] = MMIN(cc->bbox[n][0], v2[n]);
+ cc->bbox[n][1] = MMAX(cc->bbox[n][1], v0[n]);
+ cc->bbox[n][1] = MMAX(cc->bbox[n][1], v1[n]);
+ cc->bbox[n][1] = MMAX(cc->bbox[n][1], v2[n]);
+ }
d3_sub(edge0, v1, v0);
d3_sub(edge1, v2, v0);
d3_cross(normal, edge0, edge1);
@@ -893,8 +1114,10 @@ group_connex_components
size_t tmp;
component_id_t cc_count;
int64_t ccc;
- struct filter_ctx fctx;
+ struct filter_ctx ctx0, ctx1;
float lower[3], upper[3];
+ const int log_components = scn->convention & SENC3D_LOG_COMPONENTS_INFORMATION;
+ const int dump_components = scn->convention & SENC3D_DUMP_COMPONENTS_STL;
ASSERT(scn && triangles_comp && connex_components
&& s3d_view && next_enclosure_id && res);
@@ -908,20 +1131,80 @@ group_connex_components
}
if(*res != RES_OK) return;
#endif
-
descriptors = darray_ptr_component_descriptor_data_get(connex_components);
tmp = darray_ptr_component_descriptor_size_get(connex_components);
ASSERT(tmp <= COMPONENT_MAX__);
cc_count = (component_id_t)tmp;
positions = darray_position_cdata_get(&scn->vertices);
- fctx.type = FCTX1;
- fctx.c.ctx1.scn = scn;
- fctx.c.ctx1.view = s3d_view;
- fctx.c.ctx1.triangles_comp = triangles_comp;
- fctx.c.ctx1.components = connex_components;
+
+ if(dump_components) {
+ /* Do it now before any other problem can occur (fingers crossed).
+ * Do it sequential and not optimized as it is debug code.
+ * Don't throw errors, just skip to the next component. */
+ static unsigned scene_cpt = 0;
+ struct str name;
+ res_T tmp_res;
+ const struct triangle_comp* tc =
+ darray_triangle_comp_cdata_get(triangles_comp);
+ const struct triangle_in* tin = darray_triangle_in_cdata_get(&scn->triangles_in);
+ const int output_normal_in =
+ (scn->convention & SENC3D_CONVENTION_NORMAL_INSIDE) != 0;
+ str_init(scn->dev->allocator, &name);
+ printf("Dumping components for scene #%u.\n", scene_cpt);
+ for(ccc = 0; ccc < (int64_t)cc_count; ccc++) {
+ FILE* f;
+ trg_id_t t;
+ component_id_t c = (component_id_t)ccc;
+ tmp_res = str_printf(&name, "scn_%u_comp_%u.stl", scene_cpt, c);
+ if(tmp_res != RES_OK) continue;
+ f = fopen(str_cget(&name), "w");
+ if(!f) continue;
+ fprintf(f, "solid %s\n", str_cget(&name));
+ for(t = 0; t < scn->ntris; t++) {
+ const component_id_t cf_id = tc[t].component[SENC3D_FRONT];
+ const component_id_t cb_id = tc[t].component[SENC3D_BACK];
+ if(cf_id == c || cb_id == c) {
+ const vrtx_id_t* vertice_id = tin[t].vertice_id;
+ double n[3], e1[3], e2[3];
+ const int input_normal_in = (cf_id == c);
+ const int revert_triangle = (input_normal_in != output_normal_in);
+ const vrtx_id_t i0 = vertice_id[0];
+ const vrtx_id_t i1 = vertice_id[revert_triangle ? 2 : 1];
+ const vrtx_id_t i2 = vertice_id[revert_triangle ? 1 : 2];
+ /* This triangle is in component #c */
+ if(cf_id == cb_id) { /* Both sides in component */
+ /* Could add some log */
+ }
+ d3_sub(e1, positions[i1].vec, positions[i0].vec);
+ d3_sub(e2, positions[i2].vec, positions[i0].vec);
+ d3_normalize(n, d3_cross(n, e1, e2));
+ fprintf(f, " facet normal %16g %16g %16g\n", SPLIT3(n));
+ fprintf(f, " outer loop\n");
+ fprintf(f, " vertex %16g %16g %16g\n", SPLIT3(positions[i0].vec));
+ fprintf(f, " vertex %16g %16g %16g\n", SPLIT3(positions[i1].vec));
+ fprintf(f, " vertex %16g %16g %16g\n", SPLIT3(positions[i2].vec));
+ fprintf(f, " endloop\n");
+ fprintf(f, " endfacet\n");
+ }
+ }
+ printf("Dumped component #%u in file %s.\n", c, str_cget(&name));
+ fprintf(f, "endsolid %s\n", str_cget(&name));
+ fclose(f);
+ }
+ str_release(&name);
+ scene_cpt++;
+ }
+
+
+ ctx0.type = FCTX0;
+ ctx0.c.ctx0.triangles_comp = triangles_comp;
+ ctx1.type = FCTX1;
+ ctx1.c.ctx1.scn = scn;
+ ctx1.c.ctx1.view = s3d_view;
+ ctx1.c.ctx1.triangles_comp = triangles_comp;
+ ctx1.c.ctx1.components = connex_components;
*res = s3d_scene_view_get_aabb(s3d_view, lower, upper);
if(*res != RES_OK) goto end;
- /* Cast rays to find links between connex components */
#pragma omp for schedule(dynamic)
for(ccc = 0; ccc < (int64_t)cc_count; ccc++) {
res_T tmp_res = RES_OK;
@@ -937,44 +1220,91 @@ group_connex_components
ASSERT(cc->cc_group_root == CC_GROUP_ID_NONE);
ASSERT(cc->max_z_vrtx_id < scn->nverts);
- max_vrtx = positions[cc->max_z_vrtx_id].vec;
if(cc->is_outer_border) {
ATOMIC id;
- /* No need to query closest point */
+ /* No need to create a link from this CC: inner CC are doing the job */
cc->cc_group_root = cc->cc_id; /* New group with self as root */
id = ATOMIC_INCR(next_enclosure_id) - 1;
ASSERT(id <= ENCLOSURE_MAX__);
cc->enclosure_id = (enclosure_id_t)id;
+ if(log_components) {
+ printf("Component #%u: is outer, not processed\n", c);
+ }
continue;
}
+ /* First step is to determine the distance of the closest upward geometry */
+ max_vrtx = positions[cc->max_z_vrtx_id].vec;
f3_set_d3(origin, max_vrtx);
- /* Self-hit data: self hit if hit this component "on the other side" */
- fctx.c.ctx1.origin_component = cc->cc_id;
- fctx.c.ctx1.current_6volume = DBL_MAX;
- fctx.c.ctx1.hit_component = COMPONENT_NULL__;
/* Limit search radius. Only upwards moves (+Z) will be considered.
* Use a radius allowing to reach the closest top vertex of scene's AABB */
FOR_EACH(i, 0, 2) {
ASSERT(lower[i] <= origin[i] && origin[i] <= upper[i]);
rrr[i] = MMIN(origin[i] - lower[i], upper[i] - origin[i]);
}
- ASSERT(lower[2] <= origin[2] && origin[2] <= upper[2]);
rrr[2] = upper[2] - origin[2];
r = f3_len(rrr) + FLT_EPSILON; /* Ensure r > 0 */
- tmp_res = s3d_scene_view_closest_point(s3d_view, origin, r, &fctx, &hit);
+ ctx0.c.ctx0.origin_component = cc->cc_id;
+ tmp_res = s3d_scene_view_closest_point(s3d_view, origin, r, &ctx0, &hit);
if(tmp_res != RES_OK) {
*res = tmp_res;
continue;
}
/* If no hit, the component is facing an infinite medium */
- if(fctx.c.ctx1.hit_component == COMPONENT_NULL__) {
+ if(S3D_HIT_NONE(&hit)) {
+ cc->cc_group_root = CC_GROUP_ROOT_INFINITE;
+ cc->enclosure_id = 0;
+ if(log_components) {
+ printf("Component #%u: is part of enclosure #0\n", c);
+ }
+ continue;
+ }
+
+ /* Second step is to determine which component faces component #c */
+ ctx1.c.ctx1.origin_component = cc->cc_id;
+ ctx1.c.ctx1.current_6volume = DBL_MAX;
+ ctx1.c.ctx1.hit_dist = FLT_MAX;
+ ctx1.c.ctx1.hit_component = COMPONENT_NULL__;
+ /* New search radius is hit.distance + some margin to cope with numerical
+ * issues (and r==0 is an error) */
+ r = hit.distance * (1 + FLT_EPSILON) + FLT_EPSILON;
+ if(log_components) {
+ printf("Component #%u: starting search for components (R=%g) from %g %g %g\n",
+ c, r, SPLIT3(origin));
+ }
+ /* Cast a sphere to find links between connex components */
+ tmp_res = s3d_scene_view_closest_point(s3d_view, origin, r, &ctx1, &hit);
+ if(tmp_res != RES_OK) {
+ *res = tmp_res;
+ continue;
+ }
+ /* As FCTX1 filter rejects any hit, do not rely on hit but use result as
+ * stored in ctx1 */
+ /* If no hit is accepted, the component is facing an infinite medium */
+ if(ctx1.c.ctx1.hit_dist == FLT_MAX) {
cc->cc_group_root = CC_GROUP_ROOT_INFINITE;
cc->enclosure_id = 0;
+ if(log_components) {
+ printf("Component #%u: is part of enclosure #0\n", c);
+ }
+ continue;
+ }
+ else if(ctx1.c.ctx1.hit_component == COMPONENT_NULL__) {
+ /* The selected triangle was nearly parallel to the line of sight:
+ * FRONT/BACK discrimination was not reliable enough and should be done
+ * differently. */
+ /* Could try something; now just report a failure */
+ log_err(scn->dev, LIB_NAME": %s: %d: search failed.\n", FUNC_NAME,
+ __LINE__ );
+ *res = RES_BAD_OP;
+ continue;
} else {
/* If hit, group this component */
- cc->cc_group_root = fctx.c.ctx1.hit_component;
+ cc->cc_group_root = ctx1.c.ctx1.hit_component;
ASSERT(cc->cc_group_root < cc_count);
+ if(log_components) {
+ printf("Component #%u: linked to component #%u\n", c, cc->cc_group_root);
+ }
}
}
/* Implicit barrier here */
@@ -1179,7 +1509,7 @@ collect_and_link_neighbours
/* Compute rotation angle around common edge */
d3_sub(edge, vertices[v2].vec, vertices[v0].vec);
d33_muld3(edge, basis, edge);
- ASSERT(d3_len(edge) && (edge[0] || edge[1]));
+ ASSERT(d3_len(edge) != 0 && (edge[0] != 0 || edge[1] != 0));
neighbour_info->angle = atan2(edge[1], edge[0]); /* in ]-pi + pi]*/
if(is_reversed)
d3(n.vec, +edge[1], -edge[0], 0);
@@ -1501,7 +1831,7 @@ build_result
/* Build side and vertex lists. */
OK2(darray_sides_enc_resize(&enc->sides, enc->side_count));
- /* Size is just a int */
+ /* Size is just a hint */
OK2(darray_vrtx_id_reserve(&enc->vertices,
(size_t)(enc->side_count * 0.6)));
/* New vertex numbering scheme local to the enclosure */
diff --git a/src/senc3d_scene_analyze_c.h b/src/senc3d_scene_analyze_c.h
@@ -17,6 +17,8 @@
#define SENC3D_SCNENE_ANALYZE_C_H
#include "senc3d_internal_types.h"
+#include "senc3d_side_range.h"
+#include "senc3d_scene_c.h"
#include "senc3d.h"
#include <rsys/mem_allocator.h>
@@ -47,6 +49,8 @@ struct cc_descriptor {
double _2area;
/* Six times the signed volume of the component */
double _6volume;
+ /* The component's bounding Box */
+ double bbox[3][2];
/* Media used by this component */
uchar* media;
unsigned media_count;
diff --git a/src/test_senc3d_glazing.c b/src/test_senc3d_glazing.c
@@ -0,0 +1,1127 @@
+/* Copyright (C) 2018-2020, 2023 |Méso|Star> (contact@meso-star.com)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* This test has been created using the sg3_geometry_dump_as_C_code feature
+ * of star-geometry. It uses output from test_sg3_cube_on_cube. */
+
+#define _POSIX_C_SOURCE 200112L /* snprintf */
+
+#include "senc3d.h"
+#include "test_senc3d_utils.h"
+
+#include <rsys/double3.h>
+
+#include <stdio.h>
+
+#define glazing_UNSPECIFIED_PROPERTY 4294967295
+
+static const unsigned
+glazing_vertices_count = 223;
+
+static const unsigned
+glazing_triangles_count = 398;
+
+static const double
+glazing_vertices[223*3] = {
+ 82.6042, 60.329, 2.7625,
+ 83.9367, 60.4228, 2.51177,
+ 82.6042, 60.329, 1.24942,
+ 84.3672, 60.4531, 1.24942,
+ 84.3672, 60.4531, 4.27558,
+ 83.4786, 60.3906, 3.4916,
+ 82.6042, 60.329, 4.27558,
+ 86.1302, 60.5772, 4.27558,
+ 85.0127, 60.4986, 3.24271,
+ 85.1251, 60.5065, 2.219,
+ 86.1302, 60.5772, 1.24942,
+ 86.1302, 60.5772, 2.7625,
+ 86.1319, 60.5533, 1.24942,
+ 84.3689, 60.4292, 1.24942,
+ 82.6059, 60.3051, 1.24942,
+ 82.6059, 60.3051, 2.7625,
+ 82.6059, 60.3051, 4.27558,
+ 84.3689, 60.4292, 4.27558,
+ 86.1319, 60.5533, 4.27558,
+ 86.1319, 60.5533, 2.7625,
+ 84.7508, 60.4561, 2.59095,
+ 83.6545, 60.3789, 3.23353,
+ 83.611, 60.3758, 2.219,
+ 89.8033, 59.2472, 2.7625,
+ 89.1016, 59.2344, 1.24942,
+ 88.3998, 59.2215, 2.7625,
+ 89.1016, 59.2344, 4.27558,
+ 89.8033, 59.2472, 1.24942,
+ 88.3998, 59.2215, 1.24942,
+ 88.3998, 59.2215, 4.27558,
+ 89.8033, 59.2472, 4.27558,
+ 89.8038, 59.2232, 1.24942,
+ 89.102, 59.2104, 1.24942,
+ 88.4002, 59.1975, 1.24942,
+ 88.4002, 59.1975, 2.7625,
+ 88.4002, 59.1975, 4.27558,
+ 89.102, 59.2104, 4.27558,
+ 89.8038, 59.2232, 4.27558,
+ 89.8038, 59.2232, 2.7625,
+ 86.1302, 60.5772, 8.4875,
+ 84.7976, 60.4834, 8.73823,
+ 86.1302, 60.5772, 10.0006,
+ 84.3672, 60.4531, 10.0006,
+ 84.3672, 60.4531, 6.97442,
+ 85.2558, 60.5157, 7.7584,
+ 86.1302, 60.5772, 6.97442,
+ 82.6042, 60.329, 6.97442,
+ 83.7217, 60.4077, 8.00729,
+ 83.6093, 60.3998, 9.031,
+ 82.6042, 60.329, 10.0006,
+ 82.6042, 60.329, 8.4875,
+ 82.6059, 60.3051, 6.97442,
+ 84.3689, 60.4292, 6.97442,
+ 86.1319, 60.5533, 6.97442,
+ 82.6059, 60.3051, 8.4875,
+ 82.6059, 60.3051, 10.0006,
+ 84.3689, 60.4292, 10.0006,
+ 86.1319, 60.5533, 10.0006,
+ 86.1319, 60.5533, 8.4875,
+ 84.7993, 60.4595, 8.73823,
+ 85.2575, 60.4917, 7.7584,
+ 83.7234, 60.3837, 8.00729,
+ 83.611, 60.3758, 9.031,
+ 82.2266, 68.3242, 10.0006,
+ 82.2266, 68.3242, 6.97442,
+ 82.8171, 72.7595, 8.4875,
+ 81.636, 63.889, 8.4875,
+ 82.8171, 72.7595, 6.97442,
+ 81.636, 63.889, 6.97442,
+ 82.8171, 72.7595, 10.0006,
+ 81.636, 63.889, 10.0006,
+ 82.7933, 72.7627, 6.97442,
+ 82.2028, 68.3274, 6.97442,
+ 81.6123, 63.8921, 6.97442,
+ 82.7933, 72.7627, 8.4875,
+ 82.7933, 72.7627, 10.0006,
+ 82.2028, 68.3274, 10.0006,
+ 81.6123, 63.8921, 10.0006,
+ 81.6123, 63.8921, 8.4875,
+ 84.5273, 76.4272, 8.4875,
+ 85.6048, 76.4318, 8.93555,
+ 84.5273, 76.4272, 10.0006,
+ 87.4884, 76.44, 6.97442,
+ 86.3533, 76.4351, 8.11727,
+ 86.0078, 76.4336, 6.97442,
+ 87.4884, 76.44, 8.4875,
+ 86.0078, 76.4336, 10.0006,
+ 84.5273, 76.4272, 6.97442,
+ 85.3385, 76.4307, 7.80041,
+ 87.4884, 76.44, 10.0006,
+ 86.6106, 76.4362, 9.11589,
+ 87.4883, 76.464, 6.97442,
+ 86.0077, 76.4576, 6.97442,
+ 84.5271, 76.4512, 6.97442,
+ 87.4883, 76.464, 8.4875,
+ 87.4883, 76.464, 10.0006,
+ 86.0077, 76.4576, 10.0006,
+ 84.5271, 76.4512, 10.0006,
+ 84.5271, 76.4512, 8.4875,
+ 85.6047, 76.4558, 8.93555,
+ 86.3532, 76.4591, 8.11727,
+ 85.3384, 76.4547, 7.80041,
+ 86.6105, 76.4602, 9.11589,
+ 90.2861, 60.7753, 8.4875,
+ 90.3545, 59.7013, 8.4875,
+ 90.3203, 60.2383, 10.0006,
+ 90.3203, 60.2383, 6.97442,
+ 90.3545, 59.7013, 6.97442,
+ 90.2861, 60.7753, 6.97442,
+ 90.3545, 59.7013, 10.0006,
+ 90.2861, 60.7753, 10.0006,
+ 90.3785, 59.7028, 6.97442,
+ 90.3443, 60.2398, 6.97442,
+ 90.31, 60.7768, 6.97442,
+ 90.3785, 59.7028, 8.4875,
+ 90.3785, 59.7028, 10.0006,
+ 90.3443, 60.2398, 10.0006,
+ 90.31, 60.7768, 10.0006,
+ 90.31, 60.7768, 8.4875,
+ 84.5273, 76.4272, 2.7625,
+ 85.6048, 76.4318, 3.21055,
+ 84.5273, 76.4272, 4.27558,
+ 87.4884, 76.44, 1.24942,
+ 86.3533, 76.4351, 2.39227,
+ 86.0078, 76.4336, 1.24942,
+ 87.4884, 76.44, 2.7625,
+ 86.0078, 76.4336, 4.27558,
+ 84.5273, 76.4272, 1.24942,
+ 85.3385, 76.4307, 2.07541,
+ 87.4884, 76.44, 4.27558,
+ 86.6106, 76.4362, 3.39089,
+ 84.5271, 76.4512, 1.24942,
+ 86.0077, 76.4576, 1.24942,
+ 87.4883, 76.464, 1.24942,
+ 87.4883, 76.464, 2.7625,
+ 87.4883, 76.464, 4.27558,
+ 86.0077, 76.4576, 4.27558,
+ 84.5271, 76.4512, 4.27558,
+ 84.5271, 76.4512, 2.7625,
+ 86.4107, 76.4593, 3.21055,
+ 85.6622, 76.4561, 2.39227,
+ 86.677, 76.4605, 2.07541,
+ 85.405, 76.455, 3.39089,
+ 81.636, 63.889, 2.7625,
+ 82.2266, 68.3242, 1.24942,
+ 82.2266, 68.3242, 4.27558,
+ 82.8171, 72.7595, 2.7625,
+ 81.636, 63.889, 1.24942,
+ 82.8171, 72.7595, 1.24942,
+ 82.8171, 72.7595, 4.27558,
+ 81.636, 63.889, 4.27558,
+ 81.6123, 63.8921, 1.24942,
+ 82.2028, 68.3274, 1.24942,
+ 82.7933, 72.7627, 1.24942,
+ 82.7933, 72.7627, 2.7625,
+ 82.7933, 72.7627, 4.27558,
+ 82.2028, 68.3274, 4.27558,
+ 81.6123, 63.8921, 4.27558,
+ 81.6123, 63.8921, 2.7625,
+ 89.8033, 59.2472, 8.4875,
+ 88.3998, 59.2215, 8.4875,
+ 89.1016, 59.2344, 10.0006,
+ 89.1016, 59.2344, 6.97442,
+ 88.3998, 59.2215, 6.97442,
+ 89.8033, 59.2472, 6.97442,
+ 88.3998, 59.2215, 10.0006,
+ 89.8033, 59.2472, 10.0006,
+ 88.4002, 59.1975, 6.97442,
+ 89.102, 59.2104, 6.97442,
+ 89.8038, 59.2232, 6.97442,
+ 88.4002, 59.1975, 8.4875,
+ 88.4002, 59.1975, 10.0006,
+ 89.102, 59.2104, 10.0006,
+ 89.8038, 59.2232, 10.0006,
+ 89.8038, 59.2232, 8.4875,
+ 90.2861, 60.7753, 2.7625,
+ 90.3545, 59.7013, 2.7625,
+ 90.3203, 60.2383, 4.27558,
+ 90.3203, 60.2383, 1.24942,
+ 90.2861, 60.7753, 1.24942,
+ 90.3545, 59.7013, 1.24942,
+ 90.3545, 59.7013, 4.27558,
+ 90.2861, 60.7753, 4.27558,
+ 90.31, 60.7768, 1.24942,
+ 90.3443, 60.2398, 1.24942,
+ 90.3785, 59.7028, 1.24942,
+ 90.3785, 59.7028, 2.7625,
+ 90.3785, 59.7028, 4.27558,
+ 90.3443, 60.2398, 4.27558,
+ 90.31, 60.7768, 4.27558,
+ 90.31, 60.7768, 2.7625,
+ 89.0607, 73.002, 2.7625,
+ 89.4844, 68.832, 1.24942,
+ 89.4844, 68.832, 4.27558,
+ 89.908, 64.6621, 2.7625,
+ 89.0607, 73.002, 1.24942,
+ 89.908, 64.6621, 1.24942,
+ 89.908, 64.6621, 4.27558,
+ 89.0607, 73.002, 4.27558,
+ 89.0846, 73.0044, 1.24942,
+ 89.5083, 68.8345, 1.24942,
+ 89.9319, 64.6645, 1.24942,
+ 89.9319, 64.6645, 2.7625,
+ 89.9319, 64.6645, 4.27558,
+ 89.5083, 68.8345, 4.27558,
+ 89.0846, 73.0044, 4.27558,
+ 89.0846, 73.0044, 2.7625,
+ 89.0607, 73.002, 8.4875,
+ 89.4844, 68.832, 6.97442,
+ 89.4844, 68.832, 10.0006,
+ 89.908, 64.6621, 8.4875,
+ 89.908, 64.6621, 6.97442,
+ 89.0607, 73.002, 6.97442,
+ 89.908, 64.6621, 10.0006,
+ 89.0607, 73.002, 10.0006,
+ 89.9319, 64.6645, 6.97442,
+ 89.5083, 68.8345, 6.97442,
+ 89.0846, 73.0044, 6.97442,
+ 89.9319, 64.6645, 8.4875,
+ 89.9319, 64.6645, 10.0006,
+ 89.5083, 68.8345, 10.0006,
+ 89.0846, 73.0044, 10.0006,
+ 89.0846, 73.0044, 8.4875
+};
+
+static const unsigned
+glazing_triangles[398*3] = {
+ 0, 1, 2,
+ 2, 1, 3,
+ 4, 5, 6,
+ 7, 8, 4,
+ 3, 9, 10,
+ 11, 8, 7,
+ 1, 5, 8,
+ 8, 5, 4,
+ 6, 5, 0,
+ 10, 9, 11,
+ 1, 8, 9,
+ 3, 1, 9,
+ 0, 5, 1,
+ 9, 8, 11,
+ 3, 10, 12,
+ 13, 14, 2,
+ 3, 13, 2,
+ 3, 12, 13,
+ 0, 2, 14,
+ 15, 16, 6,
+ 0, 15, 6,
+ 0, 14, 15,
+ 4, 6, 16,
+ 17, 18, 7,
+ 4, 17, 7,
+ 4, 16, 17,
+ 11, 12, 10,
+ 19, 7, 18,
+ 11, 7, 19,
+ 11, 19, 12,
+ 17, 20, 18,
+ 19, 20, 12,
+ 12, 20, 13,
+ 16, 21, 17,
+ 13, 22, 14,
+ 15, 21, 16,
+ 17, 21, 20,
+ 14, 22, 15,
+ 20, 21, 22,
+ 13, 20, 22,
+ 22, 21, 15,
+ 18, 20, 19,
+ 23, 24, 25,
+ 23, 25, 26,
+ 23, 27, 24,
+ 24, 28, 25,
+ 25, 29, 26,
+ 26, 30, 23,
+ 24, 27, 31,
+ 32, 33, 28,
+ 24, 32, 28,
+ 24, 31, 32,
+ 25, 28, 33,
+ 34, 35, 29,
+ 25, 34, 29,
+ 25, 33, 34,
+ 26, 29, 35,
+ 36, 37, 30,
+ 26, 36, 30,
+ 26, 35, 36,
+ 23, 31, 27,
+ 38, 30, 37,
+ 23, 30, 38,
+ 23, 38, 31,
+ 34, 32, 38,
+ 36, 34, 38,
+ 32, 31, 38,
+ 34, 33, 32,
+ 36, 35, 34,
+ 38, 37, 36,
+ 39, 40, 41,
+ 41, 40, 42,
+ 43, 44, 45,
+ 46, 47, 43,
+ 42, 48, 49,
+ 50, 47, 46,
+ 40, 44, 47,
+ 47, 44, 43,
+ 45, 44, 39,
+ 49, 48, 50,
+ 40, 47, 48,
+ 42, 40, 48,
+ 39, 44, 40,
+ 48, 47, 50,
+ 43, 51, 46,
+ 52, 45, 53,
+ 43, 45, 52,
+ 43, 52, 51,
+ 50, 46, 51,
+ 54, 55, 49,
+ 50, 54, 49,
+ 50, 51, 54,
+ 56, 49, 55,
+ 42, 49, 56,
+ 42, 57, 41,
+ 42, 56, 57,
+ 39, 53, 45,
+ 58, 41, 57,
+ 41, 58, 39,
+ 39, 58, 53,
+ 57, 59, 58,
+ 56, 59, 57,
+ 53, 60, 52,
+ 52, 61, 51,
+ 55, 62, 56,
+ 51, 61, 54,
+ 61, 60, 59,
+ 52, 60, 61,
+ 58, 60, 53,
+ 54, 62, 55,
+ 62, 61, 59,
+ 62, 59, 56,
+ 59, 60, 58,
+ 54, 61, 62,
+ 63, 64, 65,
+ 66, 64, 63,
+ 64, 67, 65,
+ 66, 68, 64,
+ 65, 69, 63,
+ 63, 70, 66,
+ 64, 71, 67,
+ 72, 68, 73,
+ 64, 68, 72,
+ 64, 72, 71,
+ 65, 67, 71,
+ 74, 75, 69,
+ 65, 74, 69,
+ 65, 71, 74,
+ 76, 69, 75,
+ 63, 69, 76,
+ 63, 77, 70,
+ 63, 76, 77,
+ 66, 73, 68,
+ 78, 70, 77,
+ 70, 78, 66,
+ 66, 78, 73,
+ 74, 72, 76,
+ 76, 72, 78,
+ 74, 71, 72,
+ 72, 73, 78,
+ 76, 75, 74,
+ 78, 77, 76,
+ 79, 80, 81,
+ 82, 83, 84,
+ 85, 83, 82,
+ 81, 80, 86,
+ 87, 88, 79,
+ 89, 90, 85,
+ 84, 88, 87,
+ 86, 90, 89,
+ 79, 88, 80,
+ 90, 83, 85,
+ 80, 88, 83,
+ 83, 88, 84,
+ 90, 80, 83,
+ 86, 80, 90,
+ 84, 91, 82,
+ 92, 87, 93,
+ 84, 87, 92,
+ 84, 92, 91,
+ 85, 82, 91,
+ 94, 95, 89,
+ 85, 94, 89,
+ 85, 91, 94,
+ 96, 89, 95,
+ 86, 89, 96,
+ 86, 97, 81,
+ 86, 96, 97,
+ 79, 93, 87,
+ 98, 81, 97,
+ 81, 98, 79,
+ 79, 98, 93,
+ 97, 99, 98,
+ 92, 100, 91,
+ 91, 100, 94,
+ 96, 99, 97,
+ 98, 101, 93,
+ 94, 102, 95,
+ 93, 101, 92,
+ 95, 102, 96,
+ 99, 101, 98,
+ 94, 100, 102,
+ 100, 101, 99,
+ 92, 101, 100,
+ 100, 99, 102,
+ 102, 99, 96,
+ 103, 104, 105,
+ 103, 106, 104,
+ 106, 107, 104,
+ 103, 108, 106,
+ 104, 109, 105,
+ 105, 110, 103,
+ 106, 111, 107,
+ 112, 108, 113,
+ 106, 108, 112,
+ 106, 112, 111,
+ 104, 107, 111,
+ 114, 115, 109,
+ 104, 114, 109,
+ 104, 111, 114,
+ 116, 109, 115,
+ 105, 109, 116,
+ 105, 117, 110,
+ 105, 116, 117,
+ 103, 113, 108,
+ 118, 110, 117,
+ 110, 118, 103,
+ 103, 118, 113,
+ 114, 112, 118,
+ 116, 114, 118,
+ 114, 111, 112,
+ 112, 113, 118,
+ 116, 115, 114,
+ 118, 117, 116,
+ 119, 120, 121,
+ 122, 123, 124,
+ 125, 123, 122,
+ 121, 120, 126,
+ 127, 128, 119,
+ 129, 130, 125,
+ 124, 128, 127,
+ 126, 130, 129,
+ 119, 128, 120,
+ 130, 123, 125,
+ 120, 128, 123,
+ 123, 128, 124,
+ 130, 120, 123,
+ 126, 120, 130,
+ 124, 127, 131,
+ 132, 133, 122,
+ 124, 132, 122,
+ 124, 131, 132,
+ 125, 122, 133,
+ 134, 135, 129,
+ 125, 134, 129,
+ 125, 133, 134,
+ 126, 129, 135,
+ 136, 137, 121,
+ 126, 136, 121,
+ 126, 135, 136,
+ 119, 131, 127,
+ 138, 121, 137,
+ 119, 121, 138,
+ 119, 138, 131,
+ 134, 139, 135,
+ 131, 140, 132,
+ 138, 140, 131,
+ 135, 139, 136,
+ 133, 141, 134,
+ 137, 142, 138,
+ 132, 141, 133,
+ 136, 142, 137,
+ 134, 141, 139,
+ 142, 140, 138,
+ 139, 141, 140,
+ 140, 141, 132,
+ 142, 139, 140,
+ 136, 139, 142,
+ 143, 144, 145,
+ 145, 144, 146,
+ 143, 147, 144,
+ 144, 148, 146,
+ 146, 149, 145,
+ 145, 150, 143,
+ 144, 147, 151,
+ 152, 153, 148,
+ 144, 152, 148,
+ 144, 151, 152,
+ 146, 148, 153,
+ 154, 155, 149,
+ 146, 154, 149,
+ 146, 153, 154,
+ 145, 149, 155,
+ 156, 157, 150,
+ 145, 156, 150,
+ 145, 155, 156,
+ 143, 151, 147,
+ 158, 150, 157,
+ 143, 150, 158,
+ 143, 158, 151,
+ 156, 152, 158,
+ 154, 152, 156,
+ 152, 151, 158,
+ 154, 153, 152,
+ 156, 155, 154,
+ 158, 157, 156,
+ 159, 160, 161,
+ 159, 162, 160,
+ 162, 163, 160,
+ 159, 164, 162,
+ 160, 165, 161,
+ 161, 166, 159,
+ 162, 167, 163,
+ 168, 164, 169,
+ 162, 164, 168,
+ 162, 168, 167,
+ 160, 163, 167,
+ 170, 171, 165,
+ 160, 170, 165,
+ 160, 167, 170,
+ 172, 165, 171,
+ 161, 165, 172,
+ 161, 173, 166,
+ 161, 172, 173,
+ 159, 169, 164,
+ 174, 166, 173,
+ 166, 174, 159,
+ 159, 174, 169,
+ 172, 170, 174,
+ 170, 168, 174,
+ 170, 167, 168,
+ 168, 169, 174,
+ 172, 171, 170,
+ 174, 173, 172,
+ 175, 176, 177,
+ 175, 178, 176,
+ 175, 179, 178,
+ 178, 180, 176,
+ 176, 181, 177,
+ 177, 182, 175,
+ 178, 179, 183,
+ 184, 185, 180,
+ 178, 184, 180,
+ 178, 183, 184,
+ 176, 180, 185,
+ 186, 187, 181,
+ 176, 186, 181,
+ 176, 185, 186,
+ 177, 181, 187,
+ 188, 189, 182,
+ 177, 188, 182,
+ 177, 187, 188,
+ 175, 183, 179,
+ 190, 182, 189,
+ 175, 182, 190,
+ 175, 190, 183,
+ 188, 186, 190,
+ 186, 184, 190,
+ 184, 183, 190,
+ 186, 185, 184,
+ 188, 187, 186,
+ 190, 189, 188,
+ 191, 192, 193,
+ 193, 192, 194,
+ 191, 195, 192,
+ 192, 196, 194,
+ 194, 197, 193,
+ 193, 198, 191,
+ 192, 195, 199,
+ 200, 201, 196,
+ 192, 200, 196,
+ 192, 199, 200,
+ 194, 196, 201,
+ 202, 203, 197,
+ 194, 202, 197,
+ 194, 201, 202,
+ 193, 197, 203,
+ 204, 205, 198,
+ 193, 204, 198,
+ 193, 203, 204,
+ 191, 199, 195,
+ 206, 198, 205,
+ 191, 198, 206,
+ 191, 206, 199,
+ 204, 200, 206,
+ 202, 200, 204,
+ 200, 199, 206,
+ 202, 201, 200,
+ 204, 203, 202,
+ 206, 205, 204,
+ 207, 208, 209,
+ 209, 208, 210,
+ 208, 211, 210,
+ 207, 212, 208,
+ 210, 213, 209,
+ 209, 214, 207,
+ 208, 215, 211,
+ 216, 212, 217,
+ 208, 212, 216,
+ 208, 216, 215,
+ 210, 211, 215,
+ 218, 219, 213,
+ 210, 218, 213,
+ 210, 215, 218,
+ 220, 213, 219,
+ 209, 213, 220,
+ 209, 221, 214,
+ 209, 220, 221,
+ 207, 217, 212,
+ 222, 214, 221,
+ 214, 222, 207,
+ 207, 222, 217,
+ 220, 216, 222,
+ 218, 216, 220,
+ 218, 215, 216,
+ 216, 217, 222,
+ 220, 219, 218,
+ 222, 221, 220
+};
+
+static const unsigned
+glazing_properties[398*3] = {
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY,
+ 0, glazing_UNSPECIFIED_PROPERTY, glazing_UNSPECIFIED_PROPERTY
+};
+
+
+int
+main(int argc, char** argv)
+{
+ struct mem_allocator allocator;
+ struct senc3d_device* dev = NULL;
+ struct senc3d_scene* scn = NULL;
+ struct context ctx = CONTEXT_NULL__;
+ unsigned ecount, tcount, e;
+ /* Triangle counts and their numbers of occurence */
+ const unsigned possible_trg_counts[] = { 28, 44, 398, 42 };
+ int possible_cpt[] = { 8, 3, 1, 1 };
+ const size_t sz = sizeof(possible_trg_counts)/sizeof(*possible_trg_counts);
+ size_t i;
+ (void)argc, (void)argv;
+ ASSERT(sz == sizeof(possible_cpt)/sizeof(*possible_cpt));
+
+ OK(mem_init_proxy_allocator(&allocator, &mem_default_allocator));
+ OK(senc3d_device_create(NULL, &allocator, SENC3D_NTHREADS_DEFAULT, 1, &dev));
+
+ /* Degenerated triangle: duplicated vertex */
+ ctx.positions = glazing_vertices;
+ ctx.indices = glazing_triangles;
+ ctx.properties = glazing_properties;
+ OK(senc3d_scene_create(dev,
+ SENC3D_CONVENTION_NORMAL_FRONT | SENC3D_CONVENTION_NORMAL_INSIDE,
+ glazing_triangles_count, get_indices, get_media_from_properties,
+ glazing_vertices_count, get_position, &ctx, &scn));
+
+ OK(senc3d_scene_get_triangles_count(scn, &tcount));
+ CHK(tcount == glazing_triangles_count);
+ OK(senc3d_scene_get_enclosure_count(scn, &ecount));
+ CHK(ecount == 13);
+ for(e = 0; e < ecount; e++) {
+ struct senc3d_enclosure_header header;
+ struct senc3d_enclosure* enc;
+ int found = 0;
+ OK(senc3d_scene_get_enclosure(scn, e, &enc));
+ OK(senc3d_enclosure_get_header(enc, &header));
+ for(i = 0; i < sz; i++) {
+ if(possible_trg_counts[i] == header.unique_primitives_count) {
+ possible_cpt[i]--;
+ found = 1;
+ break;
+ }
+ }
+ CHK(found);
+ OK(senc3d_enclosure_ref_put(enc));
+ }
+ for(i = 0; i < sz; i++) {
+ CHK(possible_cpt[i] == 0);
+ }
+
+ OK(senc3d_scene_ref_put(scn));
+ OK(senc3d_device_ref_put(dev));
+
+ check_memory_allocator(&allocator);
+ mem_shutdown_proxy_allocator(&allocator);
+ CHK(mem_allocated_size() == 0);
+ return 0;
+}
diff --git a/src/test_senc3d_unspecified_medium.c b/src/test_senc3d_unspecified_medium.c
@@ -19,12 +19,11 @@
* geometry by program. */
#include "senc3d.h"
-#include "senc3d_sXd_helper.h"
#include "test_senc3d_utils.h"
#include <rsys/double3.h>
-#define SG3_UNSPECIFED_PROPERTY UINT_MAX
+#define SG3D_UNSPECIFIED_PROPERTY UINT_MAX
/* Dump of star-geometry 'front_unspecified'. */
static const unsigned front_unspecified_vertices_count = 8;
@@ -57,18 +56,18 @@ static const unsigned front_unspecified_triangles[36] =
};
static const unsigned front_unspecified_properties[36] =
{
- SG3_UNSPECIFED_PROPERTY, 1, SG3_UNSPECIFED_PROPERTY,
- SG3_UNSPECIFED_PROPERTY, 1, SG3_UNSPECIFED_PROPERTY,
- SG3_UNSPECIFED_PROPERTY, 1, SG3_UNSPECIFED_PROPERTY,
- SG3_UNSPECIFED_PROPERTY, 1, SG3_UNSPECIFED_PROPERTY,
- SG3_UNSPECIFED_PROPERTY, 1, SG3_UNSPECIFED_PROPERTY,
- SG3_UNSPECIFED_PROPERTY, 1, SG3_UNSPECIFED_PROPERTY,
- SG3_UNSPECIFED_PROPERTY, 1, SG3_UNSPECIFED_PROPERTY,
- SG3_UNSPECIFED_PROPERTY, 1, SG3_UNSPECIFED_PROPERTY,
- SG3_UNSPECIFED_PROPERTY, 1, SG3_UNSPECIFED_PROPERTY,
- SG3_UNSPECIFED_PROPERTY, 1, SG3_UNSPECIFED_PROPERTY,
- SG3_UNSPECIFED_PROPERTY, 1, SG3_UNSPECIFED_PROPERTY,
- SG3_UNSPECIFED_PROPERTY, 1, SG3_UNSPECIFED_PROPERTY
+ SG3D_UNSPECIFIED_PROPERTY, 1, SG3D_UNSPECIFIED_PROPERTY,
+ SG3D_UNSPECIFIED_PROPERTY, 1, SG3D_UNSPECIFIED_PROPERTY,
+ SG3D_UNSPECIFIED_PROPERTY, 1, SG3D_UNSPECIFIED_PROPERTY,
+ SG3D_UNSPECIFIED_PROPERTY, 1, SG3D_UNSPECIFIED_PROPERTY,
+ SG3D_UNSPECIFIED_PROPERTY, 1, SG3D_UNSPECIFIED_PROPERTY,
+ SG3D_UNSPECIFIED_PROPERTY, 1, SG3D_UNSPECIFIED_PROPERTY,
+ SG3D_UNSPECIFIED_PROPERTY, 1, SG3D_UNSPECIFIED_PROPERTY,
+ SG3D_UNSPECIFIED_PROPERTY, 1, SG3D_UNSPECIFIED_PROPERTY,
+ SG3D_UNSPECIFIED_PROPERTY, 1, SG3D_UNSPECIFIED_PROPERTY,
+ SG3D_UNSPECIFIED_PROPERTY, 1, SG3D_UNSPECIFIED_PROPERTY,
+ SG3D_UNSPECIFIED_PROPERTY, 1, SG3D_UNSPECIFIED_PROPERTY,
+ SG3D_UNSPECIFIED_PROPERTY, 1, SG3D_UNSPECIFIED_PROPERTY
};
/* Dump of star-geometry 'front_half_unspecified'. */
static const unsigned front_half_unspecified_vertices_count = 8;
@@ -101,17 +100,17 @@ static const unsigned front_half_unspecified_triangles[36] =
};
static const unsigned front_half_unspecified_properties[36] =
{
- SG3_UNSPECIFED_PROPERTY, 1, SG3_UNSPECIFED_PROPERTY,
+ SG3D_UNSPECIFIED_PROPERTY, 1, SG3D_UNSPECIFIED_PROPERTY,
0, 1, 0,
- SG3_UNSPECIFED_PROPERTY, 1, SG3_UNSPECIFED_PROPERTY,
+ SG3D_UNSPECIFIED_PROPERTY, 1, SG3D_UNSPECIFIED_PROPERTY,
0, 1, 0,
- SG3_UNSPECIFED_PROPERTY, 1, SG3_UNSPECIFED_PROPERTY,
+ SG3D_UNSPECIFIED_PROPERTY, 1, SG3D_UNSPECIFIED_PROPERTY,
0, 1, 0,
- SG3_UNSPECIFED_PROPERTY, 1, SG3_UNSPECIFED_PROPERTY,
+ SG3D_UNSPECIFIED_PROPERTY, 1, SG3D_UNSPECIFIED_PROPERTY,
0, 1, 0,
- SG3_UNSPECIFED_PROPERTY, 1, SG3_UNSPECIFED_PROPERTY,
+ SG3D_UNSPECIFIED_PROPERTY, 1, SG3D_UNSPECIFIED_PROPERTY,
0, 1, 0,
- SG3_UNSPECIFED_PROPERTY, 1, SG3_UNSPECIFED_PROPERTY,
+ SG3D_UNSPECIFIED_PROPERTY, 1, SG3D_UNSPECIFIED_PROPERTY,
0, 1, 0
};
/* Dump of star-geometry 'all_defined'. */
@@ -159,7 +158,7 @@ static const unsigned all_defined_properties[36] =
0, 1, 0
};
-#undef SG3_UNSPECIFED_PROPERTY
+#undef SG3D_UNSPECIFIED_PROPERTY
static void
test(const int convention)
diff --git a/src/test_senc3d_utils.h b/src/test_senc3d_utils.h
@@ -22,6 +22,8 @@
#include <stdio.h>
+#include <star/senc3d.h>
+
#define OK(Expr) CHK((Expr) == RES_OK)
#define BA(Expr) CHK((Expr) == RES_BAD_ARG)
#define BO(Expr) CHK((Expr) == RES_BAD_OP)
@@ -113,7 +115,7 @@ static INLINE void
get_position(const unsigned ivert, double pos[3], void* context)
{
const struct context* ctx = context;
- ASSERT(pos && ctx && ctx->scale);
+ ASSERT(pos && ctx && ctx->scale != 0);
pos[0] = ctx->positions[ivert * 3 + 0] * ctx->scale + ctx->offset[0];
pos[1] = ctx->positions[ivert * 3 + 1] * ctx->scale + ctx->offset[1];
pos[2] = ctx->positions[ivert * 3 + 2] * ctx->scale + ctx->offset[2];
diff --git a/src/test_senc3d_zero_distance.c b/src/test_senc3d_zero_distance.c
@@ -145,6 +145,270 @@ zero_1_properties[36][3] = {
{ 1, 0, zero_1_UNSPECIFIED_PROPERTY }
};
+/* zero_1d is similar as zero_1, with geometry duplicated in mirror along Z axis */
+static const unsigned
+zero_1d_vertices_count = 44;
+
+static const unsigned
+zero_1d_triangles_count = 72;
+
+static const double
+zero_1d_vertices[44][3] = {
+ { 10, 10, -11 },
+ { 10, 0, -11 },
+ { 0, 10, -11 },
+ { 0, 0, -11 },
+ { 0, 10, -1 },
+ { 0, 0, -1 },
+ { 10, 0, -1 },
+ { 9, 9, 0 },
+ { 8, 9, -10 },
+ { 4, 7, -10 },
+ { 1, 9, -10 },
+ { 1, 2, -10 },
+ { 1, 9, -2 },
+ { 1, 2, -2 },
+ { 4, 7, -2 },
+ { 7, 5, -10 },
+ { 9, 8, -10 },
+ { 9, 1, -10 },
+ { 2, 1, -10 },
+ { 2, 1, -2 },
+ { 9, 1, -2 },
+ { 7, 4, -2 },
+ { 10, 10, 11 },
+ { 10, 0, 11 },
+ { 0, 10, 11 },
+ { 0, 0, 11 },
+ { 0, 10, 1 },
+ { 0, 0, 1 },
+ { 10, 0, 1 },
+ { 9, 9, 0.1 }, /* Vertex #29 == vertex #7 => keep a dummy placeholder here and use #7 instead in triangles */
+ { 8, 9, 10 },
+ { 4, 7, 10 },
+ { 1, 9, 10 },
+ { 1, 2, 10 },
+ { 1, 9, 2 },
+ { 1, 2, 2 },
+ { 4, 7, 2 },
+ { 7, 5, 10 },
+ { 9, 8, 10 },
+ { 9, 1, 10 },
+ { 2, 1, 10 },
+ { 2, 1, 2 },
+ { 9, 1, 2 },
+ { 7, 4, 2 }
+};
+
+static const unsigned
+zero_1d_triangles[72][3] = {
+ { 0, 1, 2 },
+ { 1, 3, 2 },
+ { 4, 5, 6 },
+ { 7, 4, 6 },
+ { 2, 3, 4 },
+ { 3, 5, 4 },
+ { 6, 1, 7 },
+ { 1, 0, 7 },
+ { 0, 2, 4 },
+ { 7, 0, 4 },
+ { 5, 3, 1 },
+ { 6, 5, 1 },
+ { 8, 9, 10 },
+ { 9, 11, 10 },
+ { 12, 13, 14 },
+ { 7, 12, 14 },
+ { 10, 11, 12 },
+ { 11, 13, 12 },
+ { 14, 9, 7 },
+ { 9, 8, 7 },
+ { 8, 10, 12 },
+ { 7, 8, 12 },
+ { 13, 11, 9 },
+ { 14, 13, 9 },
+ { 15, 16, 17 },
+ { 18, 15, 17 },
+ { 19, 20, 21 },
+ { 20, 7, 21 },
+ { 18, 17, 20 },
+ { 19, 18, 20 },
+ { 15, 21, 7 },
+ { 16, 15, 7 },
+ { 17, 16, 20 },
+ { 16, 7, 20 },
+ { 18, 19, 15 },
+ { 19, 21, 15 },
+ { 22, 23, 24 },
+ { 23, 25, 24 },
+ { 26, 27, 28 },
+ { 7, 26, 28 },
+ { 24, 25, 26 },
+ { 25, 27, 26 },
+ { 28, 23, 7 },
+ { 23, 22, 7 },
+ { 22, 24, 26 },
+ { 7, 22, 26 },
+ { 27, 25, 23 },
+ { 28, 27, 23 },
+ { 30, 31, 32 },
+ { 31, 33, 32 },
+ { 34, 35, 36 },
+ { 7, 34, 36 },
+ { 32, 33, 34 },
+ { 33, 35, 34 },
+ { 36, 31, 7 },
+ { 31, 30, 7 },
+ { 30, 32, 34 },
+ { 7, 30, 34 },
+ { 35, 33, 31 },
+ { 36, 35, 31 },
+ { 37, 38, 39 },
+ { 40, 37, 39 },
+ { 41, 42, 43 },
+ { 42, 7, 43 },
+ { 40, 39, 42 },
+ { 41, 40, 42 },
+ { 37, 43, 7 },
+ { 38, 37, 7 },
+ { 39, 38, 42 },
+ { 38, 7, 42 },
+ { 40, 41, 37 },
+ { 41, 43, 37 }
+};
+
+static const unsigned
+zero_1d_properties[72][3] = {
+ { 0, zero_1_UNSPECIFIED_PROPERTY, 2 },
+ { 0, zero_1_UNSPECIFIED_PROPERTY, 2 },
+ { 0, zero_1_UNSPECIFIED_PROPERTY, 2 },
+ { 0, zero_1_UNSPECIFIED_PROPERTY, 2 },
+ { 0, zero_1_UNSPECIFIED_PROPERTY, 2 },
+ { 0, zero_1_UNSPECIFIED_PROPERTY, 2 },
+ { 0, zero_1_UNSPECIFIED_PROPERTY, 2 },
+ { 0, zero_1_UNSPECIFIED_PROPERTY, 2 },
+ { 0, zero_1_UNSPECIFIED_PROPERTY, 2 },
+ { 0, zero_1_UNSPECIFIED_PROPERTY, 2 },
+ { 0, zero_1_UNSPECIFIED_PROPERTY, 2 },
+ { 0, zero_1_UNSPECIFIED_PROPERTY, 2 },
+ { 1, 0, zero_1_UNSPECIFIED_PROPERTY },
+ { 1, 0, zero_1_UNSPECIFIED_PROPERTY },
+ { 1, 0, zero_1_UNSPECIFIED_PROPERTY },
+ { 1, 0, zero_1_UNSPECIFIED_PROPERTY },
+ { 1, 0, zero_1_UNSPECIFIED_PROPERTY },
+ { 1, 0, zero_1_UNSPECIFIED_PROPERTY },
+ { 1, 0, zero_1_UNSPECIFIED_PROPERTY },
+ { 1, 0, zero_1_UNSPECIFIED_PROPERTY },
+ { 1, 0, zero_1_UNSPECIFIED_PROPERTY },
+ { 1, 0, zero_1_UNSPECIFIED_PROPERTY },
+ { 1, 0, zero_1_UNSPECIFIED_PROPERTY },
+ { 1, 0, zero_1_UNSPECIFIED_PROPERTY },
+ { 1, 0, zero_1_UNSPECIFIED_PROPERTY },
+ { 1, 0, zero_1_UNSPECIFIED_PROPERTY },
+ { 1, 0, zero_1_UNSPECIFIED_PROPERTY },
+ { 1, 0, zero_1_UNSPECIFIED_PROPERTY },
+ { 1, 0, zero_1_UNSPECIFIED_PROPERTY },
+ { 1, 0, zero_1_UNSPECIFIED_PROPERTY },
+ { 1, 0, zero_1_UNSPECIFIED_PROPERTY },
+ { 1, 0, zero_1_UNSPECIFIED_PROPERTY },
+ { 1, 0, zero_1_UNSPECIFIED_PROPERTY },
+ { 1, 0, zero_1_UNSPECIFIED_PROPERTY },
+ { 1, 0, zero_1_UNSPECIFIED_PROPERTY },
+ { 1, 0, zero_1_UNSPECIFIED_PROPERTY },
+
+ { zero_1_UNSPECIFIED_PROPERTY, 0, 2 },
+ { zero_1_UNSPECIFIED_PROPERTY, 0, 2 },
+ { zero_1_UNSPECIFIED_PROPERTY, 0, 2 },
+ { zero_1_UNSPECIFIED_PROPERTY, 0, 2 },
+ { zero_1_UNSPECIFIED_PROPERTY, 0, 2 },
+ { zero_1_UNSPECIFIED_PROPERTY, 0, 2 },
+ { zero_1_UNSPECIFIED_PROPERTY, 0, 2 },
+ { zero_1_UNSPECIFIED_PROPERTY, 0, 2 },
+ { zero_1_UNSPECIFIED_PROPERTY, 0, 2 },
+ { zero_1_UNSPECIFIED_PROPERTY, 0, 2 },
+ { zero_1_UNSPECIFIED_PROPERTY, 0, 2 },
+ { zero_1_UNSPECIFIED_PROPERTY, 0, 2 },
+ { 0, 1, zero_1_UNSPECIFIED_PROPERTY },
+ { 0, 1, zero_1_UNSPECIFIED_PROPERTY },
+ { 0, 1, zero_1_UNSPECIFIED_PROPERTY },
+ { 0, 1, zero_1_UNSPECIFIED_PROPERTY },
+ { 0, 1, zero_1_UNSPECIFIED_PROPERTY },
+ { 0, 1, zero_1_UNSPECIFIED_PROPERTY },
+ { 0, 1, zero_1_UNSPECIFIED_PROPERTY },
+ { 0, 1, zero_1_UNSPECIFIED_PROPERTY },
+ { 0, 1, zero_1_UNSPECIFIED_PROPERTY },
+ { 0, 1, zero_1_UNSPECIFIED_PROPERTY },
+ { 0, 1, zero_1_UNSPECIFIED_PROPERTY },
+ { 0, 1, zero_1_UNSPECIFIED_PROPERTY },
+ { 0, 1, zero_1_UNSPECIFIED_PROPERTY },
+ { 0, 1, zero_1_UNSPECIFIED_PROPERTY },
+ { 0, 1, zero_1_UNSPECIFIED_PROPERTY },
+ { 0, 1, zero_1_UNSPECIFIED_PROPERTY },
+ { 0, 1, zero_1_UNSPECIFIED_PROPERTY },
+ { 0, 1, zero_1_UNSPECIFIED_PROPERTY },
+ { 0, 1, zero_1_UNSPECIFIED_PROPERTY },
+ { 0, 1, zero_1_UNSPECIFIED_PROPERTY },
+ { 0, 1, zero_1_UNSPECIFIED_PROPERTY },
+ { 0, 1, zero_1_UNSPECIFIED_PROPERTY },
+ { 0, 1, zero_1_UNSPECIFIED_PROPERTY },
+ { 0, 1, zero_1_UNSPECIFIED_PROPERTY }
+};
+
+/* zero_1D is similar as zero_1d, with a tiny distance between mirrored
+ * geometries */
+static const double
+zero_1D_vertices[44][3] = {
+ { 10, 10, -11 },
+ { 10, 0, -11 },
+ { 0, 10, -11 },
+ { 0, 0, -11 },
+ { 0, 10, -1 },
+ { 0, 0, -1 },
+ { 10, 0, -1 },
+ { 9, 9, 0 },
+ { 8, 9, -10 },
+ { 4, 7, -10 },
+ { 1, 9, -10 },
+ { 1, 2, -10 },
+ { 1, 9, -2 },
+ { 1, 2, -2 },
+ { 4, 7, -2 },
+ { 7, 5, -10 },
+ { 9, 8, -10 },
+ { 9, 1, -10 },
+ { 2, 1, -10 },
+ { 2, 1, -2 },
+ { 9, 1, -2 },
+ { 7, 4, -2 },
+ { 10, 10, 11 },
+ { 10, 0, 11 },
+ { 0, 10, 11 },
+ { 0, 0, 11 },
+ { 0, 10, 1 },
+ { 0, 0, 1 },
+ { 10, 0, 1 },
+ { 9, 9, 1e-30 },
+ { 8, 9, 10 },
+ { 4, 7, 10 },
+ { 1, 9, 10 },
+ { 1, 2, 10 },
+ { 1, 9, 2 },
+ { 1, 2, 2 },
+ { 4, 7, 2 },
+ { 7, 5, 10 },
+ { 9, 8, 10 },
+ { 9, 1, 10 },
+ { 2, 1, 10 },
+ { 2, 1, 2 },
+ { 9, 1, 2 },
+ { 7, 4, 2 }
+};
+
+#define zero_1D_triangles zero_1d_triangles
+
+#define zero_1D_properties zero_1d_properties
+static unsigned zero_1D_triangles_count = zero_1d_triangles_count;
+static unsigned zero_1D_vertices_count = zero_1d_vertices_count;
+
/* zero_2 geometry is made of 5 nested distorded cubes of decreasing sizes, that
* all join at a single vertex V (the highest vertex in the model). Distance between
* the 10 components (inside and outside of each shape) is zero. */
@@ -324,6 +588,422 @@ zero_2_properties[60][3] = {
{ 4, 3, zero_2_UNSPECIFIED_PROPERTY }
};
+/* zero_2d is similar as zero_2, with geometry duplicated in mirror along Z axis */
+static const unsigned
+zero_2d_vertices_count = 72;
+
+static const unsigned
+zero_2d_triangles_count = 120;
+
+static const double
+zero_2d_vertices[72][3] = {
+ { 0, 10, -11 },
+ { 0, 0, -11 },
+ { 0, 10, -1 },
+ { 0, 0, -1 },
+ { 10, 0, -1 },
+ { 10, 0, -11 },
+ { 9, 9, 0 },
+ { 10, 10, -11 },
+ { 1, 9, -10 },
+ { 1, 1, -10 },
+ { 1, 9, -2 },
+ { 1, 1, -2 },
+ { 9, 1, -2 },
+ { 9, 1, -10 },
+ { 9, 9, -10 },
+ { 2, 8, -9 },
+ { 2, 2, -9 },
+ { 2, 8, -3 },
+ { 2, 2, -3 },
+ { 8, 2, -3 },
+ { 8, 2, -9 },
+ { 8, 8, -9 },
+ { 3, 7, -8 },
+ { 3, 3, -8 },
+ { 3, 7, -4 },
+ { 3, 3, -4 },
+ { 7, 3, -4 },
+ { 7, 3, -8 },
+ { 7, 7, -8 },
+ { 4, 6, -7 },
+ { 4, 4, -7 },
+ { 4, 6, -5 },
+ { 4, 4, -5 },
+ { 6, 4, -5 },
+ { 6, 4, -7 },
+ { 6, 6, -7 },
+ { 0, 10, 11 },
+ { 0, 0, 11 },
+ { 0, 10, 1 },
+ { 0, 0, 1 },
+ { 10, 0, 1 },
+ { 10, 0, 11 },
+ { 9, 9, 0.1 }, /* Vertex #42 == vertex #6 => keep a dummy placeholder here and use #6 instead in triangles */
+ { 10, 10, 11 },
+ { 1, 9, 10 },
+ { 1, 1, 10 },
+ { 1, 9, 2 },
+ { 1, 1, 2 },
+ { 9, 1, 2 },
+ { 9, 1, 10 },
+ { 9, 9, 10 },
+ { 2, 8, 9 },
+ { 2, 2, 9 },
+ { 2, 8, 3 },
+ { 2, 2, 3 },
+ { 8, 2, 3 },
+ { 8, 2, 9 },
+ { 8, 8, 9 },
+ { 3, 7, 8 },
+ { 3, 3, 8 },
+ { 3, 7, 4 },
+ { 3, 3, 4 },
+ { 7, 3, 4 },
+ { 7, 3, 8 },
+ { 7, 7, 8 },
+ { 4, 6, 7 },
+ { 4, 4, 7 },
+ { 4, 6, 5 },
+ { 4, 4, 5 },
+ { 6, 4, 5 },
+ { 6, 4, 7 },
+ { 6, 6, 7 }
+};
+
+static const unsigned
+zero_2d_triangles[120][3] = {
+ { 0, 1, 2 },
+ { 1, 3, 2 },
+ { 4, 5, 6 },
+ { 5, 7, 6 },
+ { 2, 3, 4 },
+ { 6, 2, 4 },
+ { 5, 1, 0 },
+ { 7, 5, 0 },
+ { 3, 1, 5 },
+ { 4, 3, 5 },
+ { 7, 0, 2 },
+ { 6, 7, 2 },
+ { 8, 9, 10 },
+ { 9, 11, 10 },
+ { 12, 13, 6 },
+ { 13, 14, 6 },
+ { 10, 11, 12 },
+ { 6, 10, 12 },
+ { 13, 9, 8 },
+ { 14, 13, 8 },
+ { 11, 9, 13 },
+ { 12, 11, 13 },
+ { 14, 8, 10 },
+ { 6, 14, 10 },
+ { 15, 16, 17 },
+ { 16, 18, 17 },
+ { 19, 20, 6 },
+ { 20, 21, 6 },
+ { 17, 18, 19 },
+ { 6, 17, 19 },
+ { 20, 16, 15 },
+ { 21, 20, 15 },
+ { 18, 16, 20 },
+ { 19, 18, 20 },
+ { 21, 15, 17 },
+ { 6, 21, 17 },
+ { 22, 23, 24 },
+ { 23, 25, 24 },
+ { 26, 27, 6 },
+ { 27, 28, 6 },
+ { 24, 25, 26 },
+ { 6, 24, 26 },
+ { 27, 23, 22 },
+ { 28, 27, 22 },
+ { 25, 23, 27 },
+ { 26, 25, 27 },
+ { 28, 22, 24 },
+ { 6, 28, 24 },
+ { 29, 30, 31 },
+ { 30, 32, 31 },
+ { 33, 34, 6 },
+ { 34, 35, 6 },
+ { 31, 32, 33 },
+ { 6, 31, 33 },
+ { 34, 30, 29 },
+ { 35, 34, 29 },
+ { 32, 30, 34 },
+ { 33, 32, 34 },
+ { 35, 29, 31 },
+ { 6, 35, 31 },
+ { 36, 37, 38 },
+ { 37, 39, 38 },
+ { 40, 41, 6 },
+ { 41, 43, 6 },
+ { 38, 39, 40 },
+ { 6, 38, 40 },
+ { 41, 37, 36 },
+ { 43, 41, 36 },
+ { 39, 37, 41 },
+ { 40, 39, 41 },
+ { 43, 36, 38 },
+ { 6, 43, 38 },
+ { 44, 45, 46 },
+ { 45, 47, 46 },
+ { 48, 49, 6 },
+ { 49, 50, 6 },
+ { 46, 47, 48 },
+ { 6, 46, 48 },
+ { 49, 45, 44 },
+ { 50, 49, 44 },
+ { 47, 45, 49 },
+ { 48, 47, 49 },
+ { 50, 44, 46 },
+ { 6, 50, 46 },
+ { 51, 52, 53 },
+ { 52, 54, 53 },
+ { 55, 56, 6 },
+ { 56, 57, 6 },
+ { 53, 54, 55 },
+ { 6, 53, 55 },
+ { 56, 52, 51 },
+ { 57, 56, 51 },
+ { 54, 52, 56 },
+ { 55, 54, 56 },
+ { 57, 51, 53 },
+ { 6, 57, 53 },
+ { 58, 59, 60 },
+ { 59, 61, 60 },
+ { 62, 63, 6 },
+ { 63, 64, 6 },
+ { 60, 61, 62 },
+ { 6, 60, 62 },
+ { 63, 59, 58 },
+ { 64, 63, 58 },
+ { 61, 59, 63 },
+ { 62, 61, 63 },
+ { 64, 58, 60 },
+ { 6, 64, 60 },
+ { 65, 66, 67 },
+ { 66, 68, 67 },
+ { 69, 70, 6 },
+ { 70, 71, 6 },
+ { 67, 68, 69 },
+ { 6, 67, 69 },
+ { 70, 66, 65 },
+ { 71, 70, 65 },
+ { 68, 66, 70 },
+ { 69, 68, 70 },
+ { 71, 65, 67 },
+ { 6, 71, 67 }
+};
+
+static const unsigned
+zero_2d_properties[120][3] = {
+ { 0, zero_2_UNSPECIFIED_PROPERTY, 5 },
+ { 0, zero_2_UNSPECIFIED_PROPERTY, 5 },
+ { 0, zero_2_UNSPECIFIED_PROPERTY, 5 },
+ { 0, zero_2_UNSPECIFIED_PROPERTY, 5 },
+ { 0, zero_2_UNSPECIFIED_PROPERTY, 5 },
+ { 0, zero_2_UNSPECIFIED_PROPERTY, 5 },
+ { 0, zero_2_UNSPECIFIED_PROPERTY, 5 },
+ { 0, zero_2_UNSPECIFIED_PROPERTY, 5 },
+ { 0, zero_2_UNSPECIFIED_PROPERTY, 5 },
+ { 0, zero_2_UNSPECIFIED_PROPERTY, 5 },
+ { 0, zero_2_UNSPECIFIED_PROPERTY, 5 },
+ { 0, zero_2_UNSPECIFIED_PROPERTY, 5 },
+ { 1, 0, zero_2_UNSPECIFIED_PROPERTY },
+ { 1, 0, zero_2_UNSPECIFIED_PROPERTY },
+ { 1, 0, zero_2_UNSPECIFIED_PROPERTY },
+ { 1, 0, zero_2_UNSPECIFIED_PROPERTY },
+ { 1, 0, zero_2_UNSPECIFIED_PROPERTY },
+ { 1, 0, zero_2_UNSPECIFIED_PROPERTY },
+ { 1, 0, zero_2_UNSPECIFIED_PROPERTY },
+ { 1, 0, zero_2_UNSPECIFIED_PROPERTY },
+ { 1, 0, zero_2_UNSPECIFIED_PROPERTY },
+ { 1, 0, zero_2_UNSPECIFIED_PROPERTY },
+ { 1, 0, zero_2_UNSPECIFIED_PROPERTY },
+ { 1, 0, zero_2_UNSPECIFIED_PROPERTY },
+ { 2, 1, zero_2_UNSPECIFIED_PROPERTY },
+ { 2, 1, zero_2_UNSPECIFIED_PROPERTY },
+ { 2, 1, zero_2_UNSPECIFIED_PROPERTY },
+ { 2, 1, zero_2_UNSPECIFIED_PROPERTY },
+ { 2, 1, zero_2_UNSPECIFIED_PROPERTY },
+ { 2, 1, zero_2_UNSPECIFIED_PROPERTY },
+ { 2, 1, zero_2_UNSPECIFIED_PROPERTY },
+ { 2, 1, zero_2_UNSPECIFIED_PROPERTY },
+ { 2, 1, zero_2_UNSPECIFIED_PROPERTY },
+ { 2, 1, zero_2_UNSPECIFIED_PROPERTY },
+ { 2, 1, zero_2_UNSPECIFIED_PROPERTY },
+ { 2, 1, zero_2_UNSPECIFIED_PROPERTY },
+ { 3, 2, zero_2_UNSPECIFIED_PROPERTY },
+ { 3, 2, zero_2_UNSPECIFIED_PROPERTY },
+ { 3, 2, zero_2_UNSPECIFIED_PROPERTY },
+ { 3, 2, zero_2_UNSPECIFIED_PROPERTY },
+ { 3, 2, zero_2_UNSPECIFIED_PROPERTY },
+ { 3, 2, zero_2_UNSPECIFIED_PROPERTY },
+ { 3, 2, zero_2_UNSPECIFIED_PROPERTY },
+ { 3, 2, zero_2_UNSPECIFIED_PROPERTY },
+ { 3, 2, zero_2_UNSPECIFIED_PROPERTY },
+ { 3, 2, zero_2_UNSPECIFIED_PROPERTY },
+ { 3, 2, zero_2_UNSPECIFIED_PROPERTY },
+ { 3, 2, zero_2_UNSPECIFIED_PROPERTY },
+ { 4, 3, zero_2_UNSPECIFIED_PROPERTY },
+ { 4, 3, zero_2_UNSPECIFIED_PROPERTY },
+ { 4, 3, zero_2_UNSPECIFIED_PROPERTY },
+ { 4, 3, zero_2_UNSPECIFIED_PROPERTY },
+ { 4, 3, zero_2_UNSPECIFIED_PROPERTY },
+ { 4, 3, zero_2_UNSPECIFIED_PROPERTY },
+ { 4, 3, zero_2_UNSPECIFIED_PROPERTY },
+ { 4, 3, zero_2_UNSPECIFIED_PROPERTY },
+ { 4, 3, zero_2_UNSPECIFIED_PROPERTY },
+ { 4, 3, zero_2_UNSPECIFIED_PROPERTY },
+ { 4, 3, zero_2_UNSPECIFIED_PROPERTY },
+ { 4, 3, zero_2_UNSPECIFIED_PROPERTY },
+ { zero_2_UNSPECIFIED_PROPERTY, 0, 5 },
+ { zero_2_UNSPECIFIED_PROPERTY, 0, 5 },
+ { zero_2_UNSPECIFIED_PROPERTY, 0, 5 },
+ { zero_2_UNSPECIFIED_PROPERTY, 0, 5 },
+ { zero_2_UNSPECIFIED_PROPERTY, 0, 5 },
+ { zero_2_UNSPECIFIED_PROPERTY, 0, 5 },
+ { zero_2_UNSPECIFIED_PROPERTY, 0, 5 },
+ { zero_2_UNSPECIFIED_PROPERTY, 0, 5 },
+ { zero_2_UNSPECIFIED_PROPERTY, 0, 5 },
+ { zero_2_UNSPECIFIED_PROPERTY, 0, 5 },
+ { zero_2_UNSPECIFIED_PROPERTY, 0, 5 },
+ { zero_2_UNSPECIFIED_PROPERTY, 0, 5 },
+ { 0, 1, zero_2_UNSPECIFIED_PROPERTY },
+ { 0, 1, zero_2_UNSPECIFIED_PROPERTY },
+ { 0, 1, zero_2_UNSPECIFIED_PROPERTY },
+ { 0, 1, zero_2_UNSPECIFIED_PROPERTY },
+ { 0, 1, zero_2_UNSPECIFIED_PROPERTY },
+ { 0, 1, zero_2_UNSPECIFIED_PROPERTY },
+ { 0, 1, zero_2_UNSPECIFIED_PROPERTY },
+ { 0, 1, zero_2_UNSPECIFIED_PROPERTY },
+ { 0, 1, zero_2_UNSPECIFIED_PROPERTY },
+ { 0, 1, zero_2_UNSPECIFIED_PROPERTY },
+ { 0, 1, zero_2_UNSPECIFIED_PROPERTY },
+ { 0, 1, zero_2_UNSPECIFIED_PROPERTY },
+ { 1, 2, zero_2_UNSPECIFIED_PROPERTY },
+ { 1, 2, zero_2_UNSPECIFIED_PROPERTY },
+ { 1, 2, zero_2_UNSPECIFIED_PROPERTY },
+ { 1, 2, zero_2_UNSPECIFIED_PROPERTY },
+ { 1, 2, zero_2_UNSPECIFIED_PROPERTY },
+ { 1, 2, zero_2_UNSPECIFIED_PROPERTY },
+ { 1, 2, zero_2_UNSPECIFIED_PROPERTY },
+ { 1, 2, zero_2_UNSPECIFIED_PROPERTY },
+ { 1, 2, zero_2_UNSPECIFIED_PROPERTY },
+ { 1, 2, zero_2_UNSPECIFIED_PROPERTY },
+ { 1, 2, zero_2_UNSPECIFIED_PROPERTY },
+ { 1, 2, zero_2_UNSPECIFIED_PROPERTY },
+ { 2, 3, zero_2_UNSPECIFIED_PROPERTY },
+ { 2, 3, zero_2_UNSPECIFIED_PROPERTY },
+ { 2, 3, zero_2_UNSPECIFIED_PROPERTY },
+ { 2, 3, zero_2_UNSPECIFIED_PROPERTY },
+ { 2, 3, zero_2_UNSPECIFIED_PROPERTY },
+ { 2, 3, zero_2_UNSPECIFIED_PROPERTY },
+ { 2, 3, zero_2_UNSPECIFIED_PROPERTY },
+ { 2, 3, zero_2_UNSPECIFIED_PROPERTY },
+ { 2, 3, zero_2_UNSPECIFIED_PROPERTY },
+ { 2, 3, zero_2_UNSPECIFIED_PROPERTY },
+ { 2, 3, zero_2_UNSPECIFIED_PROPERTY },
+ { 2, 3, zero_2_UNSPECIFIED_PROPERTY },
+ { 3, 4, zero_2_UNSPECIFIED_PROPERTY },
+ { 3, 4, zero_2_UNSPECIFIED_PROPERTY },
+ { 3, 4, zero_2_UNSPECIFIED_PROPERTY },
+ { 3, 4, zero_2_UNSPECIFIED_PROPERTY },
+ { 3, 4, zero_2_UNSPECIFIED_PROPERTY },
+ { 3, 4, zero_2_UNSPECIFIED_PROPERTY },
+ { 3, 4, zero_2_UNSPECIFIED_PROPERTY },
+ { 3, 4, zero_2_UNSPECIFIED_PROPERTY },
+ { 3, 4, zero_2_UNSPECIFIED_PROPERTY },
+ { 3, 4, zero_2_UNSPECIFIED_PROPERTY },
+ { 3, 4, zero_2_UNSPECIFIED_PROPERTY },
+ { 3, 4, zero_2_UNSPECIFIED_PROPERTY }
+};
+
+/* zero_2D is similar as zero_2d, with a tiny distance between mirrored
+ * geometries */
+static const double
+zero_2D_vertices[72][3] = {
+ { 0, 10, -11 },
+ { 0, 0, -11 },
+ { 0, 10, -1 },
+ { 0, 0, -1 },
+ { 10, 0, -1 },
+ { 10, 0, -11 },
+ { 9, 9, 0 },
+ { 10, 10, -11 },
+ { 1, 9, -10 },
+ { 1, 1, -10 },
+ { 1, 9, -2 },
+ { 1, 1, -2 },
+ { 9, 1, -2 },
+ { 9, 1, -10 },
+ { 9, 9, -10 },
+ { 2, 8, -9 },
+ { 2, 2, -9 },
+ { 2, 8, -3 },
+ { 2, 2, -3 },
+ { 8, 2, -3 },
+ { 8, 2, -9 },
+ { 8, 8, -9 },
+ { 3, 7, -8 },
+ { 3, 3, -8 },
+ { 3, 7, -4 },
+ { 3, 3, -4 },
+ { 7, 3, -4 },
+ { 7, 3, -8 },
+ { 7, 7, -8 },
+ { 4, 6, -7 },
+ { 4, 4, -7 },
+ { 4, 6, -5 },
+ { 4, 4, -5 },
+ { 6, 4, -5 },
+ { 6, 4, -7 },
+ { 6, 6, -7 },
+ { 0, 10, 11 },
+ { 0, 0, 11 },
+ { 0, 10, 1 },
+ { 0, 0, 1 },
+ { 10, 0, 1 },
+ { 10, 0, 11 },
+ { 9, 9, 1e-30 },
+ { 10, 10, 11 },
+ { 1, 9, 10 },
+ { 1, 1, 10 },
+ { 1, 9, 2 },
+ { 1, 1, 2 },
+ { 9, 1, 2 },
+ { 9, 1, 10 },
+ { 9, 9, 10 },
+ { 2, 8, 9 },
+ { 2, 2, 9 },
+ { 2, 8, 3 },
+ { 2, 2, 3 },
+ { 8, 2, 3 },
+ { 8, 2, 9 },
+ { 8, 8, 9 },
+ { 3, 7, 8 },
+ { 3, 3, 8 },
+ { 3, 7, 4 },
+ { 3, 3, 4 },
+ { 7, 3, 4 },
+ { 7, 3, 8 },
+ { 7, 7, 8 },
+ { 4, 6, 7 },
+ { 4, 4, 7 },
+ { 4, 6, 5 },
+ { 4, 4, 5 },
+ { 6, 4, 5 },
+ { 6, 4, 7 },
+ { 6, 6, 7 }
+};
+
+#define zero_2D_triangles zero_2d_triangles
+
+#define zero_2D_properties zero_2d_properties
+static unsigned zero_2D_triangles_count = zero_2d_triangles_count;
+static unsigned zero_2D_vertices_count = zero_2d_vertices_count;
+
+
/* Enclosures' order is consistent accross runs as they are sorted by triangle
* sides, thus allowing to expect a given order */
struct expected {
@@ -356,12 +1036,10 @@ test
ctx.indices = indices;
ctx.properties = properties;
- if(n == 1) {
- /* Same model with symmetry / origin
- * (need to reverse vertices' order to keep same inside/outside) */
- ctx.scale = -1;
- ctx.reverse_vrtx = 1;
- }
+ /* If n==1, same model with symmetry / origin
+ * (need to reverse vertices' order to keep same inside/outside) */
+ ctx.scale = (n == 1) ? -1 : +1;
+ ctx.reverse_vrtx = (n == 1) ? 1 : 0;
OK(senc3d_scene_create(dev,
SENC3D_CONVENTION_NORMAL_BACK | SENC3D_CONVENTION_NORMAL_OUTSIDE,
@@ -390,7 +1068,7 @@ test
CHK(eq_eps(header.volume, expected->volume[e], 0.01));
OK(senc3d_enclosure_ref_put(enclosure));
#ifdef DUMP_ENCLOSURES
- snprintf(name, sizeof(name), "test_cube_on_cube_%u.obj", e);
+ snprintf(name, sizeof(name), "test_zero_distance_%u.obj", e);
dump_enclosure(scn, e, name);
#endif
}
@@ -425,6 +1103,29 @@ main(int argc, char** argv)
(unsigned *)zero_1_properties, zero_1_triangles_count,
zero_1_vertices_count, &expected);
+ expected.enclosure_count = 7;
+ expected.medium[0] = SENC3D_UNSPECIFIED_MEDIUM;
+ expected.volume[0] = -1933.33;
+ expected.medium[1] = 0;
+ expected.volume[1] = 647.33;
+ expected.medium[2] = 1;
+ expected.volume[2] = 150;
+ expected.medium[3] = 1;
+ expected.volume[3] = 169.33;
+ expected.medium[4] = 0;
+ expected.volume[4] = 647.33;
+ expected.medium[5] = 1;
+ expected.volume[5] = 150;
+ expected.medium[6] = 1;
+ expected.volume[6] = 169.33;
+ test((double *)zero_1d_vertices, (unsigned*)zero_1d_triangles,
+ (unsigned *)zero_1d_properties, zero_1d_triangles_count,
+ zero_1d_vertices_count, &expected);
+
+ test((double *)zero_1D_vertices, (unsigned*)zero_1D_triangles,
+ (unsigned *)zero_1D_properties, zero_1D_triangles_count,
+ zero_1D_vertices_count, &expected);
+
expected.enclosure_count = 6;
expected.medium[0] = SENC3D_UNSPECIFIED_MEDIUM;
expected.volume[0] = -966.67;
@@ -442,5 +1143,36 @@ main(int argc, char** argv)
(unsigned*)zero_2_properties, zero_2_triangles_count,
zero_2_vertices_count, &expected);
+ expected.enclosure_count = 11;
+ expected.medium[0] = SENC3D_UNSPECIFIED_MEDIUM;
+ expected.volume[0] = -1933.33;
+ expected.medium[1] = 0;
+ expected.volume[1] = 433.33;
+ expected.medium[2] = 1;
+ expected.volume[2] = 281.33;
+ expected.medium[3] = 2;
+ expected.volume[3] = 161.33;
+ expected.medium[4] = 3;
+ expected.volume[4] = 73.33;
+ expected.medium[5] = 4;
+ expected.volume[5] = 17.33;
+ expected.medium[6] = 0;
+ expected.volume[6] = 433.33;
+ expected.medium[7] = 1;
+ expected.volume[7] = 281.33;
+ expected.medium[8] = 2;
+ expected.volume[8] = 161.33;
+ expected.medium[9] = 3;
+ expected.volume[9] = 73.33;
+ expected.medium[10] = 4;
+ expected.volume[10] = 17.33;
+ test((double*)zero_2d_vertices, (unsigned*)zero_2d_triangles,
+ (unsigned*)zero_2d_properties, zero_2d_triangles_count,
+ zero_2d_vertices_count, &expected);
+
+ test((double*)zero_2D_vertices, (unsigned*)zero_2D_triangles,
+ (unsigned*)zero_2D_properties, zero_2D_triangles_count,
+ zero_2d_vertices_count, &expected);
+
return 0;
-}
-\ No newline at end of file
+}