city_generator2

Generated conformal 3D meshes representing a city
git clone git://git.meso-star.fr/city_generator2.git
Log | Files | Refs | README | LICENSE

commit c5616fca8c2d661d9a9a89f1e26b0bb435b0fe0d
parent 938659482e1e884e7a4fe1eda9c6ad70834ca9c1
Author: Benjamin Piaud <benjamin.piaud@meso-star.com>
Date:   Thu,  3 Nov 2022 17:19:54 +0100

First version of model1 building. Footprint missing and ground not
functional

Diffstat:
Msrc/cg_building_model1.c | 868+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------
Msrc/cg_building_model1.h | 19++++++++++++++++++-
Msrc/cg_city.c | 5++++-
Msrc/cg_parsing.c | 35+++++++++++++++++++++++------------
4 files changed, 699 insertions(+), 228 deletions(-)

diff --git a/src/cg_building_model1.c b/src/cg_building_model1.c @@ -21,6 +21,7 @@ #include "cg_building.h" #include <rsys/str.h> +#include <rsys/stretchy_array.h> #include <star/scad.h> #include <star/scpr.h> @@ -51,322 +52,692 @@ error: static res_T build_floor (const char* prefix, - struct scpr_polygon* pg, - struct building* b, + const struct scpr_polygon* pg, + const struct data_model1* data, struct scad_geometry** floor) { res_T res = RES_OK; - double e; - struct data_model1* data; + double e_wall = data->wall; + double e_insulation = data->ext_insulation; + double e_floor = data->floor; + double offset = 0; + struct scpr_polygon* pg_int; + size_t nverts = 0; struct scad_geometry* footprint = NULL; double d[3] = {0, 0, 0}; char* floorname = NULL; struct str name; int is_init = 0; - data = (struct data_model1*)b->data; - e = data->floor; + if (!prefix || !pg || !data || !floor) { + res = RES_BAD_ARG; + goto error; + } str_init(NULL, &name); is_init = 1; - if (prefix) { - ERR(str_set(&name, prefix)); - ERR(str_append(&name, "_floor")); - floorname = str_get(&name); - } + ERR(str_set(&name, prefix)); + ERR(str_append(&name, "_floor")); + floorname = str_get(&name); - ERR(build_floor_footprint(pg, &footprint)); + offset = e_wall + e_insulation; + ERR(scpr_polygon_create_copy(NULL, pg, &pg_int)); + ERR(scpr_offset_polygon(pg_int, -offset, SCPR_JOIN_MITER)); - d[2] = e; + /*footprint*/ + ERR(scpr_polygon_get_vertices_count(pg_int, 0, &nverts)); + ERR(scad_add_polygon(NULL, get_position_pg, pg_int, 0, nverts, &footprint)); + + d[2] = -e_floor; ERR(scad_geometry_extrude(footprint, floorname, d, floor)); exit: scad_geometry_delete(footprint); if (is_init) str_release(&name); + if (pg_int) scpr_polygon_ref_put(pg_int); + return res; +error: + goto exit; +} + +static res_T +build_wall + (const char* prefix, + const struct scpr_polygon* pg, + const double height, + const struct data_model1* data, + struct scad_geometry** wall) +{ + res_T res = RES_OK; + double e_wall = data->wall; + double e_insulation = data->ext_insulation; + double depth = data->foundation; + double offset = 0; + struct scpr_polygon* pg_int; + struct scpr_polygon* pg_ext; + size_t nverts = 0; + struct scad_geometry* footprint = NULL; + struct scad_geometry* footprint_int = NULL; + struct scad_geometry* footprint_ext = NULL; + double d[3] = {0, 0, 0}; + char* wallname = NULL; + struct str name; + int is_init = 0; + + if (!prefix || !pg || !data || !wall) { + res = RES_BAD_ARG; + goto error; + } + + str_init(NULL, &name); + is_init = 1; + ERR(str_set(&name, prefix)); + ERR(str_append(&name, "_wall")); + wallname = str_get(&name); + + offset = e_insulation; + ERR(scpr_polygon_create_copy(NULL, pg, &pg_ext)); + ERR(scpr_offset_polygon(pg_ext, -offset, SCPR_JOIN_MITER)); + + offset = e_wall + e_insulation; + ERR(scpr_polygon_create_copy(NULL, pg, &pg_int)); + ERR(scpr_offset_polygon(pg_int, -offset, SCPR_JOIN_MITER)); + + /*wall footprint*/ + ERR(scpr_polygon_get_vertices_count(pg_ext, 0, &nverts)); + ERR(scad_add_polygon( + NULL, get_position_pg, pg_ext, -depth, nverts, &footprint_ext)); + + ERR(scpr_polygon_get_vertices_count(pg_int, 0, &nverts)); + ERR(scad_add_polygon( + NULL, get_position_pg, pg_int, -depth, nverts, &footprint_int)); + + ERR(scad_cut_geometries( + NULL, &footprint_ext, 1, &footprint_int, 1, &footprint)); + + d[2] = depth + height; + ERR(scad_geometry_extrude(footprint, wallname, d, wall)); + +exit: + scad_geometry_delete(footprint); + scad_geometry_delete(footprint_int); + scad_geometry_delete(footprint_ext); + if (is_init) str_release(&name); + if (pg_int) scpr_polygon_ref_put(pg_int); + if (pg_ext) scpr_polygon_ref_put(pg_ext); return res; error: goto exit; } static res_T +build_int_insulation + (const char* prefix, + const struct scpr_polygon* pg, + const double height, + const struct data_model1* data, + struct scad_geometry* inter_floor, + struct scad_geometry** insulation) +{ + res_T res = RES_OK; + double e_wall = data->wall; + double e_roof = data->roof; + double e_roof_insulation = data->roof_insulation; + double attic = data->attic; + double e_ext_insulation = data->ext_insulation; + double e_int_insulation = data->int_insulation; + double offset = 0; + struct scpr_polygon* pg_int; + struct scpr_polygon* pg_ext; + size_t nverts = 0; + struct scad_geometry* footprint = NULL; + struct scad_geometry* footprint_int = NULL; + struct scad_geometry* footprint_ext = NULL; + struct scad_geometry* geom = NULL; + double d[3] = {0, 0, 0}; + char* insulationname = NULL; + struct str name; + int is_init = 0; + + if (!prefix || !pg || !data || !insulation) { + res = RES_BAD_ARG; + goto error; + } + + str_init(NULL, &name); + is_init = 1; + ERR(str_set(&name, prefix)); + ERR(str_append(&name, "_int_insulation")); + insulationname = str_get(&name); + + offset = e_ext_insulation + e_wall; + ERR(scpr_polygon_create_copy(NULL, pg, &pg_ext)); + ERR(scpr_offset_polygon(pg_ext, -offset, SCPR_JOIN_MITER)); + + offset = e_ext_insulation + e_wall + e_int_insulation; + ERR(scpr_polygon_create_copy(NULL, pg, &pg_int)); + ERR(scpr_offset_polygon(pg_int, -offset, SCPR_JOIN_MITER)); + + /* insulation footprint */ + ERR(scpr_polygon_get_vertices_count(pg_ext, 0, &nverts)); + ERR(scad_add_polygon( + NULL, get_position_pg, pg_ext, 0, nverts, &footprint_ext)); + + ERR(scpr_polygon_get_vertices_count(pg_int, 0, &nverts)); + ERR(scad_add_polygon( + NULL, get_position_pg, pg_int, 0, nverts, &footprint_int)); + + ERR(scad_cut_geometries( + NULL, &footprint_ext, 1, &footprint_int, 1, &footprint)); + + d[2] = height - e_roof - attic - e_roof_insulation; + ERR(scad_geometry_extrude(footprint, NULL, d, &geom)); + + if (inter_floor) { + ERR(scad_cut_geometries( + insulationname, &geom, 1, &inter_floor, 1, insulation)); + } else { + ERR(scad_geometry_copy(geom, insulationname, insulation)); + } + + +exit: + scad_geometry_delete(footprint); + scad_geometry_delete(footprint_int); + scad_geometry_delete(footprint_ext); + scad_geometry_delete(geom); + if (is_init) str_release(&name); + if (pg_int) scpr_polygon_ref_put(pg_int); + if (pg_ext) scpr_polygon_ref_put(pg_ext); + return res; +error: + goto exit; +} + +static res_T build_roof (const char* prefix, - const struct building* b, - const struct scad_geometry* floor, + const struct scpr_polygon* pg, + const double height, + const struct data_model1* data, struct scad_geometry** roof) { res_T res = RES_OK; - double height; - double e; + double e_wall = data->wall; + double e_insulation = data->ext_insulation; + double e_roof = data->roof; + double offset = 0; + double z_roof = 0; + struct scpr_polygon* pg_int; + size_t nverts = 0; + struct scad_geometry* footprint = NULL; double d[3] = {0, 0, 0}; - struct data_model1* data; - /*struct data_cad_model1* data_cad;*/ char* roofname = NULL; struct str name; int is_init = 0; + if (!prefix || !pg || !data || !roof) { + res = RES_BAD_ARG; + goto error; + } + str_init(NULL, &name); is_init = 1; - if (prefix) { - ERR(str_set(&name, prefix)); - ERR(str_append(&name, "_roof")); - roofname = str_get(&name); - } + ERR(str_set(&name, prefix)); + ERR(str_append(&name, "_roof")); + roofname = str_get(&name); - height = b->height; - data = (struct data_model1*)b->data; - /*data_cad = (struct data_cad_model1*)b->data_cad;*/ - e = data->floor; + offset = e_wall + e_insulation; + ERR(scpr_polygon_create_copy(NULL, pg, &pg_int)); + ERR(scpr_offset_polygon(pg_int, -offset, SCPR_JOIN_MITER)); - ERR(scad_geometry_copy(floor, roofname, roof)); - d[2] = height - e ; - ERR(scad_geometry_translate(*roof, d)); + /*footprint*/ + ERR(scpr_polygon_get_vertices_count(pg_int, 0, &nverts)); + z_roof = height - e_roof; + ERR(scad_add_polygon(NULL, get_position_pg, pg_int, z_roof, nverts, &footprint)); + + d[2] = e_roof; + ERR(scad_geometry_extrude(footprint, roofname, d, roof)); exit: + scad_geometry_delete(footprint); if (is_init) str_release(&name); + if (pg_int) scpr_polygon_ref_put(pg_int); return res; error: goto exit; } static res_T -build_wall_footprint - (struct scpr_polygon* pg, - struct scpr_polygon* pg_int, - struct scad_geometry** footprint) +build_roof_insulation + (const char* prefix, + const struct scpr_polygon* pg, + const double height, + const struct data_model1* data, + struct scad_geometry** insulation) { res_T res = RES_OK; - /*struct data_cad_model1* data_cad;*/ - struct scad_geometry* polygon = NULL; - struct scad_geometry* polygon_int = NULL; - size_t nverts, nverts_int; + double e_wall = data->wall; + double e_insulation = data->ext_insulation; + double e_roof = data->roof; + double attic = data->attic; + double e_roof_insulation = data->roof_insulation; + double offset = 0; + double z_insulation = 0; + struct scpr_polygon* pg_int; + size_t nverts = 0; + struct scad_geometry* footprint = NULL; + double d[3] = {0, 0, 0}; + char* insulationname = NULL; + struct str name; + int is_init = 0; - ERR(scpr_polygon_get_vertices_count(pg, 0, &nverts)); - ERR(scad_add_polygon(NULL, get_position_pg, pg, 0, nverts, &polygon)); + if (!prefix || !pg || !data || !insulation) { + res = RES_BAD_ARG; + goto error; + } - ERR(scpr_polygon_get_vertices_count(pg_int, 0, &nverts_int)); - ERR(scad_add_polygon(NULL, get_position_pg, pg_int, 0, nverts_int, &polygon_int)); + str_init(NULL, &name); + is_init = 1; + ERR(str_set(&name, prefix)); + ERR(str_append(&name, "_roof_insulation")); + insulationname = str_get(&name); - ERR(scad_cut_geometries(NULL, &polygon, 1, &polygon_int, 1, footprint)); + offset = e_wall + e_insulation; + ERR(scpr_polygon_create_copy(NULL, pg, &pg_int)); + ERR(scpr_offset_polygon(pg_int, -offset, SCPR_JOIN_MITER)); + + /*footprint*/ + ERR(scpr_polygon_get_vertices_count(pg_int, 0, &nverts)); + z_insulation = height - e_roof - attic - e_roof_insulation; + ERR(scad_add_polygon( + NULL, get_position_pg, pg_int, z_insulation, nverts, &footprint)); + + d[2] = e_roof_insulation; + ERR(scad_geometry_extrude(footprint, insulationname, d, insulation)); exit: - if(polygon) scad_geometry_delete(polygon); - if(polygon_int) scad_geometry_delete(polygon_int); + scad_geometry_delete(footprint); + if (is_init) str_release(&name); + if (pg_int) scpr_polygon_ref_put(pg_int); return res; error: goto exit; } static res_T -build_wall - (const char* prefix, - struct scpr_polygon* pg, - struct scpr_polygon* pg_int, - struct building* b, - struct scad_geometry** wall) +build_floor_insulation + (const char* prefix, + const struct scpr_polygon* pg, + const struct data_model1* data, + struct scad_geometry** insulation) { res_T res = RES_OK; - double height; + double e_wall = data->wall; + double e_insulation = data->ext_insulation; + double e_floor = data->floor; + double e_floor_insulation = data->floor_insulation; + double offset = 0; + double z_insulation = 0; + struct scpr_polygon* pg_int; + size_t nverts = 0; struct scad_geometry* footprint = NULL; double d[3] = {0, 0, 0}; - char* wallname = NULL; + char* insulationname = NULL; struct str name; int is_init = 0; - height = b->height; + if (!prefix || !pg || !data || !insulation) { + res = RES_BAD_ARG; + goto error; + } str_init(NULL, &name); is_init = 1; - if (prefix) { - ERR(str_set(&name, prefix)); - ERR(str_append(&name, "_wall")); - wallname = str_get(&name); - } + ERR(str_set(&name, prefix)); + ERR(str_append(&name, "_floor_insulation")); + insulationname = str_get(&name); + + offset = e_wall + e_insulation; + ERR(scpr_polygon_create_copy(NULL, pg, &pg_int)); + ERR(scpr_offset_polygon(pg_int, -offset, SCPR_JOIN_MITER)); - ERR(build_wall_footprint(pg, pg_int, &footprint)); + /*footprint*/ + ERR(scpr_polygon_get_vertices_count(pg_int, 0, &nverts)); + z_insulation = - e_floor - e_floor_insulation; + ERR(scad_add_polygon( + NULL, get_position_pg, pg_int, z_insulation, nverts, &footprint)); - d[2] = height; - ERR(scad_geometry_extrude(footprint, wallname, d, wall)); + d[2] = e_floor_insulation; + ERR(scad_geometry_extrude(footprint, insulationname, d, insulation)); exit: - if(footprint) scad_geometry_delete(footprint); + scad_geometry_delete(footprint); if (is_init) str_release(&name); + if (pg_int) scpr_polygon_ref_put(pg_int); return res; error: goto exit; } - static res_T -build_cavity +build_inter_floor (const char* prefix, - struct scpr_polygon* pg, - const struct building* b, - struct scad_geometry** cavity) + const struct scpr_polygon* pg, + const double height, + const struct data_model1* data, + struct scad_geometry** inter_floor) { res_T res = RES_OK; - double e, height; - struct data_model1* data; + size_t i = 0; + size_t floor_n = data->inter_floor_n; + double e_roof = data->roof; + double e_roof_ins = data->roof_insulation; + double attic = data->attic; + double e_floor = data->inter_floor; + double e_wall = data->wall; + double e_insulation = data->ext_insulation; + double offset = 0; + double z_floor = 0; + double h_cavity = 0; + struct scpr_polygon* pg_int; + size_t nverts = 0; + struct scad_geometry** floor_list = NULL; double d[3] = {0, 0, 0}; - struct scad_geometry* polygon = NULL; - char* cavityname = NULL; + char* floorname = NULL; struct str name; int is_init = 0; - size_t nverts; - height = b->height; - data = (struct data_model1*)b->data; - e = data->floor; + if (!prefix || !pg || !data || !inter_floor) { + res = RES_BAD_ARG; + goto error; + } str_init(NULL, &name); is_init = 1; - if (prefix) { - ERR(str_set(&name, prefix)); - ERR(str_append(&name, "_cavity")); - cavityname = str_get(&name); + ERR(str_set(&name, prefix)); + ERR(str_append(&name, "_inter_floor")); + floorname = str_get(&name); + + offset = e_wall + e_insulation; + ERR(scpr_polygon_create_copy(NULL, pg, &pg_int)); + ERR(scpr_offset_polygon(pg_int, -offset, SCPR_JOIN_MITER)); + ERR(scpr_polygon_get_vertices_count(pg_int, 0, &nverts)); + + h_cavity = height - e_roof - attic - e_roof_ins - (double)floor_n*e_floor; + z_floor = h_cavity/(double)(1 + floor_n); + d[2] = e_floor; + for (i=0; i< floor_n; ++i) { + struct scad_geometry* floor = NULL; + struct scad_geometry* footprint = NULL; + + ERR(scad_add_polygon( + NULL, get_position_pg, pg_int, z_floor, nverts, &footprint)); + ERR(scad_geometry_extrude(footprint, NULL, d, &floor)); + sa_push(floor_list, floor); + ERR(scad_geometry_delete(footprint)); + z_floor += h_cavity/(double)(1 + floor_n) + e_floor; } - ERR(scpr_polygon_get_vertices_count(pg, 0, &nverts)); - ERR(scad_add_polygon(NULL, get_position_pg, pg, e, nverts, &polygon)); + ERR(scad_fuse_geometries( + floorname, + floor_list, sa_size(floor_list), + floor_list, sa_size(floor_list), + inter_floor)); + +exit: + if (is_init) str_release(&name); + if (pg_int) scpr_polygon_ref_put(pg_int); + if (floor_list) { + for (i=0; i< floor_n; ++i) { + scad_geometry_delete(floor_list[i]); + } + sa_release(floor_list); + } + return res; +error: + goto exit; +} +static res_T +build_ext_insulation + (const char* prefix, + const struct scpr_polygon* pg, + const double height, + const struct data_model1* data, + struct scad_geometry** insulation) +{ + res_T res = RES_OK; + double e_insulation = data->ext_insulation; + double offset = 0; + struct scpr_polygon* pg_int; + struct scpr_polygon* pg_ext; + size_t nverts = 0; + struct scad_geometry* footprint = NULL; + struct scad_geometry* footprint_int = NULL; + struct scad_geometry* footprint_ext = NULL; + double d[3] = {0, 0, 0}; + char* insulationname = NULL; + struct str name; + int is_init = 0; + + if (!prefix || !pg || !data || !insulation) { + res = RES_BAD_ARG; + goto error; + } + + str_init(NULL, &name); + is_init = 1; + ERR(str_set(&name, prefix)); + ERR(str_append(&name, "_ext_insulation")); + insulationname = str_get(&name); + + offset = e_insulation; + ERR(scpr_polygon_create_copy(NULL, pg, &pg_int)); + ERR(scpr_polygon_create_copy(NULL, pg, &pg_ext)); + ERR(scpr_offset_polygon(pg_int, -offset, SCPR_JOIN_MITER)); - d[2] = height - e; - ERR(scad_geometry_extrude(polygon, cavityname, d, cavity)); + /*insulation footprint*/ + ERR(scpr_polygon_get_vertices_count(pg_ext, 0, &nverts)); + ERR(scad_add_polygon( + NULL, get_position_pg, pg_ext, 0, nverts, &footprint_ext)); + + ERR(scpr_polygon_get_vertices_count(pg_int, 0, &nverts)); + ERR(scad_add_polygon( + NULL, get_position_pg, pg_int, 0, nverts, &footprint_int)); + + ERR(scad_cut_geometries( + NULL, &footprint_ext, 1, &footprint_int, 1, &footprint)); + + d[2] = height; + ERR(scad_geometry_extrude(footprint, insulationname, d, insulation)); exit: - if(polygon) scad_geometry_delete(polygon); + scad_geometry_delete(footprint); + scad_geometry_delete(footprint_int); + scad_geometry_delete(footprint_ext); if (is_init) str_release(&name); + if (pg_int) scpr_polygon_ref_put(pg_int); + if (pg_ext) scpr_polygon_ref_put(pg_ext); return res; error: goto exit; } static res_T -build_connection +build_crawlspace (const char* prefix, - struct data_cad_model1* cad) + const struct scpr_polygon* pg, + const struct data_model1* data, + struct scad_geometry** crawlspace) { res_T res = RES_OK; - char* cname = NULL; + double e_wall = data->wall; + double e_insulation = data->ext_insulation; + double e_crawl = data->crawl; + double e_floor = data->floor; + double e_floor_insulation = data->floor_insulation; + double offset = 0; + double z_crawl= 0; + struct scpr_polygon* pg_int; + size_t nverts = 0; + struct scad_geometry* footprint = NULL; + double d[3] = {0, 0, 0}; + char* crawlname = NULL; struct str name; int is_init = 0; - cad->connection = malloc(3 * sizeof(struct scad_geometry*)); - cad->n_connection = 3; + if (!prefix || !pg || !data || !crawlspace) { + res = RES_BAD_ARG; + goto error; + } - /* cavity/floor connection */ str_init(NULL, &name); is_init = 1; - if (prefix) { - ERR(str_set(&name, prefix)); - ERR(str_append(&name, "_C_cavity_floor")); - cname = str_get(&name); - } + ERR(str_set(&name, prefix)); + ERR(str_append(&name, "_crawlspace")); + crawlname = str_get(&name); - ERR(scad_geometries_common_boundaries - (cname, - &cad->cavity, 1, - &cad->floor, 1, - &cad->connection[0])); - - /* cavity/wall connection */ - if (prefix) { - ERR(str_set(&name, prefix)); - ERR(str_append(&name, "_C_cavity_wall")); - cname = str_get(&name); - } + offset = e_wall + e_insulation; + ERR(scpr_polygon_create_copy(NULL, pg, &pg_int)); + ERR(scpr_offset_polygon(pg_int, -offset, SCPR_JOIN_MITER)); - ERR(scad_geometries_common_boundaries - (cname, - &cad->cavity, 1, - &cad->wall, 1, - &cad->connection[1])); - - /* cavity/roof connection */ - if (prefix) { - ERR(str_set(&name, prefix)); - ERR(str_append(&name, "_C_cavity_roof")); - cname = str_get(&name); - } + /*footprint*/ + ERR(scpr_polygon_get_vertices_count(pg_int, 0, &nverts)); + z_crawl = - e_floor - e_floor_insulation - e_crawl; + ERR(scad_add_polygon( + NULL, get_position_pg, pg_int, z_crawl, nverts, &footprint)); - ERR(scad_geometries_common_boundaries - (cname, - &cad->cavity, 1, - &cad->roof, 1, - &cad->connection[2])); + d[2] = e_crawl; + ERR(scad_geometry_extrude(footprint, crawlname, d, crawlspace)); exit: + scad_geometry_delete(footprint); if (is_init) str_release(&name); + if (pg_int) scpr_polygon_ref_put(pg_int); return res; error: goto exit; } static res_T -build_ground -(struct scpr_polygon* pg, - struct scad_geometry** ground) +build_habitable + (const char* prefix, + const struct scpr_polygon* pg, + const double height, + const struct data_model1* data, + const struct scad_geometry* floor, + struct scad_geometry** cavity) { res_T res = RES_OK; + double e_wall = data->wall; + double e_ext_insulation = data->ext_insulation; + double e_int_insulation = data->int_insulation; + double e_roof = data->roof; + double e_roof_insulation = data->roof_insulation; + double e_attic = data->attic; + double offset = 0; + struct scpr_polygon* pg_int; + size_t nverts = 0; struct scad_geometry* footprint = NULL; - double dir[3] = {0, 0, -1}; - size_t nverts; + struct scad_geometry* geom = NULL; + double d[3] = {0, 0, 0}; + char* cavityname = NULL; + struct str name; + int is_init = 0; + if (!prefix || !pg || !data || !cavity) { + res = RES_BAD_ARG; + goto error; + } - ERR(scpr_polygon_get_vertices_count(pg, 0, &nverts)); - ERR(scad_add_polygon(NULL, get_position_pg, pg, 0, nverts, &footprint)); + str_init(NULL, &name); + is_init = 1; + ERR(str_set(&name, prefix)); + ERR(str_append(&name, "_cavity")); + cavityname = str_get(&name); - ERR(scad_geometry_extrude(footprint, NULL, dir, ground)); + offset = e_wall + e_ext_insulation + e_int_insulation; + ERR(scpr_polygon_create_copy(NULL, pg, &pg_int)); + ERR(scpr_offset_polygon(pg_int, -offset, SCPR_JOIN_MITER)); + + /*footprint*/ + ERR(scpr_polygon_get_vertices_count(pg_int, 0, &nverts)); + ERR(scad_add_polygon( + NULL, get_position_pg, pg_int, 0, nverts, &footprint)); + + d[2] = height - e_roof - e_attic - e_roof_insulation; + ERR(scad_geometry_extrude(footprint, NULL, d, &geom)); + if (floor) { + ERR(scad_cut_geometries( + cavityname, &geom, 1, &floor, 1, cavity)); + } else { + ERR(scad_geometry_copy(geom, cavityname, cavity)); + } exit: - if(footprint) scad_geometry_delete(footprint); + scad_geometry_delete(footprint); + scad_geometry_delete(geom); + if (is_init) str_release(&name); + if (pg_int) scpr_polygon_ref_put(pg_int); return res; error: goto exit; } static res_T -build_boundary +build_attic (const char* prefix, - struct data_cad_model1* cad) + const struct scpr_polygon* pg, + const double height, + const struct data_model1* data, + struct scad_geometry** attic) { res_T res = RES_OK; - struct scad_geometry** list = NULL; - struct scad_geometry* boundary = NULL; + double e_wall = data->wall; + double e_insulation = data->ext_insulation; + double e_roof = data->roof; + double e_attic = data->attic; + double offset = 0; + double z_attic = 0; + struct scpr_polygon* pg_int; + size_t nverts = 0; struct scad_geometry* footprint = NULL; - char* cname = NULL; + double d[3] = {0, 0, 0}; + char* atticname = NULL; struct str name; int is_init = 0; - list = malloc(4 * sizeof(struct scad_geometry*)); - list[0] = cad->floor; - list[1] = cad->wall; - list[2] = cad->roof; - list[3] = cad->cavity; + if (!prefix || !pg || !data || !attic) { + res = RES_BAD_ARG; + goto error; + } str_init(NULL, &name); is_init = 1; - if (prefix) { - ERR(str_set(&name, prefix)); - ERR(str_append(&name, "_boundary")); - cname = str_get(&name); - } + ERR(str_set(&name, prefix)); + ERR(str_append(&name, "_attic")); + atticname = str_get(&name); - ERR(scad_geometry_boundary(NULL, list, 4, &boundary)); + offset = e_wall + e_insulation; + ERR(scpr_polygon_create_copy(NULL, pg, &pg_int)); + ERR(scpr_offset_polygon(pg_int, -offset, SCPR_JOIN_MITER)); - ERR(scad_geometries_common_boundaries(NULL, list, 4, &cad->ground, 1, - &footprint)); + /*footprint*/ + ERR(scpr_polygon_get_vertices_count(pg_int, 0, &nverts)); + z_attic = height - e_roof - e_attic; + ERR(scad_add_polygon( + NULL, get_position_pg, pg_int, z_attic, nverts, &footprint)); - ERR(scad_cut_geometries(cname, &boundary, 1, &footprint, 1, &cad->boundary)); + d[2] = e_attic; + ERR(scad_geometry_extrude(footprint, atticname, d, attic)); exit: - if(boundary) scad_geometry_delete(boundary); - if(footprint) scad_geometry_delete(footprint); - if (list) free(list); + scad_geometry_delete(footprint); if (is_init) str_release(&name); + if (pg_int) scpr_polygon_ref_put(pg_int); return res; error: goto exit; } - /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ @@ -416,10 +787,8 @@ build_cad_model1(struct building* building) enum model_type model = building->model; double height = building->height; struct scpr_polygon* pg = building->pg; - struct scpr_polygon* pg_int = NULL; struct data_model1* data = (struct data_model1 *)building->data; struct data_cad_model1* data_cad; - double e_wall; struct str prefix; int is_init = 0; @@ -428,11 +797,6 @@ build_cad_model1(struct building* building) goto error; } - if (height <= 0 || data->wall <= 0 || data->floor <= 0) { - res = RES_BAD_ARG; - goto error; - } - str_init(NULL, &prefix); is_init = 1; ERR(str_set(&prefix, "building_")); @@ -442,39 +806,96 @@ build_cad_model1(struct building* building) data_cad = malloc(sizeof(struct data_cad_model1)); building->data_cad = (struct data_cad_model1*)data_cad; - e_wall = data->wall; - ERR(scpr_polygon_create_copy(NULL, pg, &pg_int)); - ERR(scpr_offset_polygon(pg_int, -e_wall, SCPR_JOIN_MITER)); + /* build mandatories elements : + - floor + - wall + - roff + */ - /* build floor with pg_int */ - ERR(build_floor(str_cget(&prefix), pg_int, building, &data_cad->floor)); + ERR(build_floor(str_cget(&prefix), pg, data, &data_cad->floor)); - /* roof is a translated copy of floor */ - ERR(build_roof(str_cget(&prefix), building, data_cad->floor, &data_cad->roof)); + ERR(build_wall(str_cget(&prefix), pg, height, data, &data_cad->wall)); - /* build wall with pg and pg_int */ - ERR(build_wall(str_cget(&prefix), pg, pg_int, building, &data_cad->wall)); + ERR(build_roof(str_cget(&prefix), pg, height, data, &data_cad->roof)); + + + if (data->inter_floor_n > 0) { + ERR(build_inter_floor( + str_cget(&prefix), pg, height, data, &data_cad->intermediate_floor)); + } else { + data_cad->intermediate_floor = NULL; + } - /* build ground */ - /*This is a 'local' ground. It is required to build boundary condition. */ - /*It is not exported.*/ - ERR(build_ground(pg, &data_cad->ground)); + /* build optionnal elements : + - external insulation + - internal insulation + - roof insulation + - floor insulation + */ + + if (data->ext_insulation > 0) { + ERR(build_ext_insulation( + str_cget(&prefix), pg, height, data, &data_cad->external_insulation)); + } else { + data_cad->external_insulation = NULL; + } + + if (data->int_insulation > 0) { + ERR(build_int_insulation( + str_cget(&prefix), pg, height, data, data_cad->intermediate_floor, + &data_cad->internal_insulation)); + } else { + data_cad->internal_insulation = NULL; + } + + if (data->roof_insulation > 0) { + ERR(build_roof_insulation( + str_cget(&prefix), pg, height, data, &data_cad->roof_insulation)); + } else { + data_cad->roof_insulation = NULL; + } + + if (data->floor_insulation > 0) { + ERR(build_floor_insulation( + str_cget(&prefix), pg, data, &data_cad->floor_insulation)); + } else { + data_cad->floor_insulation = NULL; + } + + /* build cavities : + - attic + - habitable + - crawlspace + */ + + if (data->attic > 0) { + ERR(build_attic( + str_cget(&prefix), pg, height, data, &data_cad->attic_cavity)); + } else { + data_cad->attic_cavity = NULL; + } + + ERR(build_habitable( + str_cget(&prefix), pg, height, data, data_cad->intermediate_floor, + &data_cad->habitable_cavity)); + + if (data->crawl > 0) { + ERR(build_crawlspace( + str_cget(&prefix), pg, data, &data_cad->crawlspace_cavity)); + } else { + data_cad->crawlspace_cavity = NULL; + } - /* build cavity */ - ERR(build_cavity(str_cget(&prefix), pg_int, building, &data_cad->cavity)); ERR(scad_scene_partition()); - /* build boundary */ - ERR(build_boundary(str_cget(&prefix), building->data_cad)); + /*scad_synchronize();*/ + /*scad_run_ui();*/ - /* build connection cavity/floor */ - ERR(build_connection(str_cget(&prefix), building->data_cad)); exit: if (is_init) str_release(&prefix); - if(pg_int) scpr_polygon_ref_put(pg_int); return res; error: goto exit; @@ -486,28 +907,20 @@ build_footprint_model1 struct scad_geometry** footprint) { res_T res = RES_OK; - struct scpr_polygon* pg = building->pg; - struct scpr_polygon* pg_int = NULL; - struct data_model1* data = (struct data_model1 *)building->data; - double e_wall; - struct scad_geometry* geom[2]; - - e_wall = data->wall; - ERR(scpr_polygon_create_copy(NULL, pg, &pg_int)); - ERR(scpr_offset_polygon(pg_int, -e_wall, SCPR_JOIN_MITER)); +/* struct scpr_polygon* pg = building->pg;*/ + /*struct scpr_polygon* pg_int = NULL;*/ + /*struct data_model1* data = (struct data_model1 *)building->data;*/ + /*double e_wall;*/ + /*struct scad_geometry* geom[2];*/ - ERR(build_wall_footprint(pg, pg_int, &geom[0])); - ERR(build_floor_footprint(pg, &geom[1])); - ERR(scad_fragment_geometries(NULL, &geom[0], 1, &geom[1], 1, footprint)); - -exit: - scad_geometry_delete(geom[0]); - scad_geometry_delete(geom[1]); - if(pg_int) scpr_polygon_ref_put(pg_int); +/*exit:*/ + /*scad_geometry_delete(geom[0]);*/ + /*scad_geometry_delete(geom[1]);*/ +/* if(pg_int) scpr_polygon_ref_put(pg_int);*/ return res; -error: - goto exit; +/*error:*/ + /*goto exit;*/ } res_T @@ -516,27 +929,54 @@ export_stl_model1 { res_T res = RES_OK; struct data_cad_model1* data_cad = (struct data_cad_model1 *)building->data_cad; - size_t i; + /*size_t i;*/ /* floor export */ ERR(scad_stl_export(data_cad->floor, NULL, binary)); + /* wall export */ + ERR(scad_stl_export(data_cad->wall, NULL, binary)); + /* roof export */ ERR(scad_stl_export(data_cad->roof, NULL, binary)); + + /* intermediate floor export*/ + if (data_cad->intermediate_floor) { + ERR(scad_stl_export(data_cad->intermediate_floor, NULL, binary)); + } - /* wall export */ - ERR(scad_stl_export(data_cad->wall, NULL, binary)); + /* internal insulation export*/ + if (data_cad->internal_insulation) { + ERR(scad_stl_export(data_cad->internal_insulation, NULL, binary)); + } + + /* external insulation export*/ + if (data_cad->external_insulation) { + ERR(scad_stl_export(data_cad->external_insulation, NULL, binary)); + } + + /* roof insulation export*/ + if (data_cad->roof_insulation) { + ERR(scad_stl_export(data_cad->roof_insulation, NULL, binary)); + } - /* cavity export */ - ERR(scad_stl_export(data_cad->cavity, NULL, binary)); + /* floor insulation export*/ + if (data_cad->floor_insulation) { + ERR(scad_stl_export(data_cad->floor_insulation, NULL, binary)); + } - /* connection export */ - for (i=0; i<data_cad->n_connection; ++i) { - ERR(scad_stl_export(data_cad->connection[i], NULL, binary)); + /* attic cavity export*/ + if (data_cad->attic_cavity) { + ERR(scad_stl_export(data_cad->attic_cavity, NULL, binary)); } - /* boundary export */ - ERR(scad_stl_export(data_cad->boundary, NULL, binary)); + /* habitable cavity export*/ + ERR(scad_stl_export(data_cad->habitable_cavity, NULL, binary)); + + /* crawlspace cavity export*/ + if (data_cad->crawlspace_cavity) { + ERR(scad_stl_export(data_cad->crawlspace_cavity, NULL, binary)); + } exit: return res; diff --git a/src/cg_building_model1.h b/src/cg_building_model1.h @@ -30,15 +30,32 @@ struct building_params; /* specific data for model 0 */ struct data_model1 { + size_t inter_floor_n; /* number of intermediate floors */ double wall; /* wall thickness */ double floor; /* floor thickness */ + double inter_floor; /* intermediate floor thickness */ + double roof; /* roof thickness */ + double int_insulation; /* internal insulation thickness */ + double ext_insulation; /* external insulation thickness */ + double floor_insulation; /* floor insulation thickness */ + double roof_insulation; /* roof insulation thickness */ + double foundation; /* foundation depth */ + double crawl; /* crawl space height */ + double attic; /* attic height */ }; struct data_cad_model1 { struct scad_geometry* wall; struct scad_geometry* roof; struct scad_geometry* floor; - struct scad_geometry* cavity; + struct scad_geometry* intermediate_floor; + struct scad_geometry* habitable_cavity; + struct scad_geometry* crawlspace_cavity; + struct scad_geometry* attic_cavity; + struct scad_geometry* internal_insulation; + struct scad_geometry* external_insulation; + struct scad_geometry* floor_insulation; + struct scad_geometry* roof_insulation; struct scad_geometry* ground; struct scad_geometry* boundary; struct scad_geometry** connection; diff --git a/src/cg_city.c b/src/cg_city.c @@ -45,6 +45,7 @@ city_init(struct logger* logger, struct city* city, struct args* args) ERR(parse_building_params(logger, &ht_params)); for (i=0; i<city->n ; ++i) { + city->building[i].release = NULL; switch(city->building[i].model) { case model0: city->building[i].init = &init_model0; @@ -76,7 +77,9 @@ city_release(struct city* city) /* iterate on building */ n = city->n; for (i=0; i<n; ++i) { - ERR(city->building[i].release(&city->building[i])); + if (city->building[i].release) { + ERR(city->building[i].release(&city->building[i])); + } } ERR(ground_release(&city->ground)); diff --git a/src/cg_parsing.c b/src/cg_parsing.c @@ -352,7 +352,8 @@ parse_building_params struct htable_building_params* ht_params) { res_T res = RES_OK; - struct data_model0* data; + struct data_model0* data0; + struct data_model1* data1; struct building_params* params0; (void)logger; @@ -364,32 +365,42 @@ parse_building_params goto error; } - data = malloc(sizeof(struct data_model0)); - if (!data) { + data0 = malloc(sizeof(struct data_model0)); + if (!data0) { res = RES_MEM_ERR; goto error; } params0[0].model = model0; str_init(NULL, &params0[0].name); str_set(&params0[0].name, "b0"); - data->wall = 0.2; - data->floor = 0.3; + data0->wall = 0.2; + data0->floor = 0.3; params0[0].data = malloc(sizeof(struct data_model0)); - params0[0].data = (void*)data; + params0[0].data = (void*)data0; ERR(htable_building_params_set(ht_params, &params0[0].name, &params0[0])); - data = malloc(sizeof(struct data_model0)); - if (!data) { + data1 = malloc(sizeof(struct data_model1)); + if (!data1) { res = RES_MEM_ERR; goto error; } params0[1].model = model1; str_init(NULL, &params0[1].name); str_set(&params0[1].name, "b1"); - data->wall = 0.25; - data->floor = 0.35; - params0[1].data = malloc(sizeof(struct data_model0)); - params0[1].data = (void*)data; + data1->wall = 0.25; + data1->floor = 0.35; + data1->inter_floor = 0.2; + data1->inter_floor_n = 1; + data1->roof = 0.3; + data1->int_insulation = 0.1; + data1->ext_insulation = 0.12; + data1->floor_insulation = 0.15; + data1->roof_insulation = 0.3; + data1->foundation = 1.2; + data1->crawl = 0.5; + data1->attic = 0.3; + params0[1].data = malloc(sizeof(struct data_model1)); + params0[1].data = (void*)data1; ERR(htable_building_params_set(ht_params, &params0[1].name, &params0[1])); exit: