Skip to content

Commit

Permalink
Merge branch 'hotfix-0.1.1'
Browse files Browse the repository at this point in the history
  • Loading branch information
ipadjen committed Sep 7, 2022
2 parents 2414f09 + 1d4b3a0 commit 11ed80f
Show file tree
Hide file tree
Showing 9 changed files with 51 additions and 40 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
# Changelog


## [0.1.1] - 2022-09-02
### Fixed
- Bad triangles at surface edges
- Polygons close to the boundary are defined as 'out of bounds'


## [0.1.0] - 2022-08-14
First release
2 changes: 1 addition & 1 deletion CITATION.bib
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
@article{Paden2022,
author={Paden, Ivan, Garc{\'i}a-S{\'a}nchez Clara and Ledoux, Hugo},
author={Paden, Ivan and Garc{\'i}a-S{\'a}nchez, Clara and Ledoux, Hugo},
title={Towards Automatic Reconstruction of 3D City Models Tailored for Urban Flow Simulations},
journal={Frontiers in Built Environment},
volume={8},
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[![docs](https://img.shields.io/badge/docs-Wiki-brightgreen)](https://github.com/tudelft3d/City4CFD/wiki)
[![GitHub license](https://img.shields.io/github/license/tudelft3d/City4CFD)](https://github.com/tudelft3d/City4CFD/blob/master/LICENSE)
[![DOI:10.3389/fbuil.2022.899332](http://img.shields.io/badge/DOI-10.3389/fbuil.2022.899332-B62030.svg)](https://www.frontiersin.org/articles/10.3389/fbuil.2022.899332)
[![docs](https://img.shields.io/badge/docs-Wiki-brightgreen?style=flat-square)](https://github.com/tudelft3d/City4CFD/wiki)
[![GitHub license](https://img.shields.io/github/license/tudelft3d/City4CFD?style=flat-square)](https://github.com/tudelft3d/City4CFD/blob/master/LICENSE)
[![DOI:10.3389/fbuil.2022.899332](http://img.shields.io/badge/DOI-10.3389/fbuil.2022.899332-B62030.svg?style=flat-square)](https://www.frontiersin.org/articles/10.3389/fbuil.2022.899332)


# City4CFD
Expand Down
10 changes: 5 additions & 5 deletions src/Boundary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,15 @@ void Boundary::set_bnd_poly(Polygon_2& bndPoly, Polygon_2& pcBndPoly, Polygon_2&
}

for (auto& pt : startBufferPoly)
pcBndPoly.push_back(pt - (pt - center) * 0.05 * std::abs(bufferLen));
pcBndPoly.push_back(pt - (pt - center) * 0.001 * std::abs(bufferLen));
} else {
startBufferPoly = bndPoly;
pcBndPoly = startBufferPoly;
}
}

//-- Deactivate point cloud points that are out of bounds
void Boundary::set_bounds_to_pc(Point_set_3& pointCloud, const Polygon_2& pcBndPoly) {
void Boundary::set_bounds_to_buildings_pc(Point_set_3& pointCloud, const Polygon_2& pcBndPoly) {
//-- Remove points out of the boundary region
auto it = pointCloud.points().begin();
int count = 0;
Expand All @@ -82,10 +82,10 @@ void Boundary::set_bounds_to_pc(Point_set_3& pointCloud, const Polygon_2& pcBndP
pointCloud.collect_garbage(); // Free removed points from the memory
}

void Boundary::set_bounds_to_terrain(Point_set_3& pointCloud, const Polygon_2& bndPoly,
const Polygon_2& pcBndPoly, const Polygon_2& startBufferPoly) {
void Boundary::set_bounds_to_terrain_pc(Point_set_3& pointCloud, const Polygon_2& bndPoly,
const Polygon_2& pcBndPoly, const Polygon_2& startBufferPoly) {
//-- Remove points out of the boundary region
Boundary::set_bounds_to_pc(pointCloud, pcBndPoly);
Boundary::set_bounds_to_buildings_pc(pointCloud, pcBndPoly);

//-- Add outer points to match the domain size to prescribed one
SearchTree searchTree(pointCloud.points().begin(),pointCloud.points().end());
Expand Down
6 changes: 3 additions & 3 deletions src/Boundary.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ class Boundary : public TopoFeature {
virtual ~Boundary();

static void set_bnd_poly(Polygon_2& bndPoly, Polygon_2& pcBndPoly, Polygon_2& startBufferPoly);
static void set_bounds_to_pc(Point_set_3& pointCloud, const Polygon_2& pcBndPoly);
static void set_bounds_to_terrain(Point_set_3& pointCloud, const Polygon_2& bndPoly,
const Polygon_2& pcBndPoly, const Polygon_2& startBufferPoly);
static void set_bounds_to_buildings_pc(Point_set_3& pointCloud, const Polygon_2& pcBndPoly);
static void set_bounds_to_terrain_pc(Point_set_3& pointCloud, const Polygon_2& bndPoly,
const Polygon_2& pcBndPoly, const Polygon_2& startBufferPoly);
static std::vector<double> get_domain_bbox();

virtual void reconstruct() = 0;
Expand Down
8 changes: 4 additions & 4 deletions src/Map3d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -248,13 +248,13 @@ void Map3d::set_bnd() {
Boundary::set_bnd_poly(bndPoly, pcBndPoly, startBufferPoly);

//-- Deactivate point cloud points that are out of bounds
Boundary::set_bounds_to_terrain(_pointCloud.get_terrain(),
bndPoly, pcBndPoly, startBufferPoly);
Boundary::set_bounds_to_pc(_pointCloud.get_buildings(), startBufferPoly);
Boundary::set_bounds_to_terrain_pc(_pointCloud.get_terrain(),
bndPoly, pcBndPoly, startBufferPoly);
Boundary::set_bounds_to_buildings_pc(_pointCloud.get_buildings(), startBufferPoly);

//-- Check feature scope for surface layers now that the full domain is known
for (auto& f: _surfaceLayers) {
f->check_feature_scope(pcBndPoly);
f->check_feature_scope(bndPoly);
}
this->clear_inactives();
}
Expand Down
47 changes: 25 additions & 22 deletions src/io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,7 @@ void IO::get_obj_pts(const Mesh& mesh,
std::unordered_map<std::string, int>& dPts)
{
for (auto& face : mesh.faces()) {
if (IO::is_degen(mesh, face)) continue;
std::vector<int> faceIdx; faceIdx.reserve(3);
std::string fsTemp;
std::string bsTemp;
Expand All @@ -309,13 +310,7 @@ void IO::get_obj_pts(const Mesh& mesh,
faceIdx.push_back(it->second);
}
}

if (IO::not_small(faceIdx)) {
bs += "\nf";
bs += bsTemp;
// } else {
// std::cerr << "Found duplicates!" << std::endl;
}
bs += "\nf" + bsTemp;
}
}

Expand All @@ -324,15 +319,11 @@ void IO::get_stl_pts(Mesh& mesh, std::string& fs) {
auto fnormals = mesh.add_property_map<face_descriptor, Vector_3>("f:normals", CGAL::NULL_VECTOR).first;
PMP::compute_normals(mesh, vnormals, fnormals);
for (auto& face : mesh.faces()) {
if (IO::is_degen(mesh, face)) continue;
std::vector<std::string> outputPts;
for (auto index: CGAL::vertices_around_face(mesh.halfedge(face), mesh)) {
outputPts.push_back(gen_key_bucket(mesh.point(index)));
}
//-- Check for round off of small triangles
if (outputPts[0] == outputPts[1]
|| outputPts[0] == outputPts[2]
|| outputPts[1] == outputPts[2]) continue;

fs += "\nfacet normal " + gen_key_bucket(fnormals[face]);
fs += "\n outer loop";
for (auto pt: outputPts) {
Expand All @@ -349,6 +340,7 @@ void IO::get_cityjson_geom(const Mesh& mesh, nlohmann::json& g, std::unordered_m
g["lod"] = Config::get().lod;
g["boundaries"];
for (auto& face: mesh.faces()) {
if (IO::is_degen(mesh, face)) continue;
std::vector<int> faceIdx;
faceIdx.reserve(3);
std::vector<int> tempPoly;
Expand All @@ -367,23 +359,34 @@ void IO::get_cityjson_geom(const Mesh& mesh, nlohmann::json& g, std::unordered_m
tempPoly.push_back(it->second);
}
}

if (IO::not_small(faceIdx)) {
g["boundaries"].push_back({tempPoly});
// } else {
// std::cerr << "Found duplicates!" << std::endl;
}
g["boundaries"].push_back({tempPoly});
}
}

//-- Check for round off of small triangles
bool IO::not_small(std::vector<int> idxLst) {
bool IO::not_same(std::vector<int> idxLst) {
std::sort(idxLst.begin(), idxLst.end());
auto it = std::unique(idxLst.begin(), idxLst.end());

return (it == idxLst.end());
}

bool IO::is_degen(const Mesh& mesh, Mesh::Face_index face) {
std::vector<Point_3> pts; pts.reserve(3);
for (auto index: CGAL::vertices_around_face(mesh.halfedge(face), mesh)) {
pts.push_back(mesh.point(index));
}
//-- Precondition - check that the points are not the same
if (CGAL::squared_distance(pts[0], pts[1]) < 1e-3 ||
CGAL::squared_distance(pts[0], pts[2]) < 1e-3 ||
CGAL::squared_distance(pts[1], pts[2]) < 1e-3) {
return true;
}
if (sin(CGAL::approximate_angle(pts[0], pts[1], pts[2]) * M_PI / 180) < 0.00174) {
return true;
}
return false;
}

void IO::output_log() {
if (!Config::get().outputLog) return;
fs::current_path(Config::get().outputDir);
Expand Down Expand Up @@ -429,15 +432,15 @@ bool IO::has_substr(const std::string& strMain, const std::string& subStr) {

std::string IO::gen_key_bucket(const Point_2 p) {
std::stringstream ss;
ss << std::fixed << std::setprecision(3) << p.x() << " " << p.y();
ss << std::fixed << std::setprecision(6) << p.x() << " " << p.y();
return ss.str();
}

//-- Templated functions
template<typename T>
std::string IO::gen_key_bucket(const T& p) {
std::stringstream ss;
ss << std::fixed << std::setprecision(3) << p.x() << " " << p.y() << " " << p.z();
ss << std::fixed << std::setprecision(6) << p.x() << " " << p.y() << " " << p.z();
return ss.str();
}
//- Explicit template instantiation
Expand Down
3 changes: 2 additions & 1 deletion src/io.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ namespace IO {
void get_stl_pts(Mesh& mesh, std::string& fs);
void get_cityjson_geom(const Mesh& mesh, nlohmann::json& g, std::unordered_map<std::string, int>& dPts, std::string primitive);

bool not_small(std::vector<int> idxLst);
bool not_same(std::vector<int> idxLst);
bool is_degen(const Mesh& mesh, Mesh::Face_index face);

void output_log();
bool has_substr(const std::string& strMain, const std::string& subStr);
Expand Down
2 changes: 1 addition & 1 deletion src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
#include "io.h"
#include "Map3d.h"

std::string CITY4CFD_VERSION = "0.1.0";
std::string CITY4CFD_VERSION = "0.1.1";

void printWelcome() {
auto logo{
Expand Down

0 comments on commit 11ed80f

Please sign in to comment.