Optimization
To improve the performance of our program we would like to parallelize it as much as possible. Since the processing of trees (i.e. setting the foliage, computing the cartesian coordinates, scaling, translating…) is independent from one tree to another, we can already parallelize this part of the program.
Do do so, we’ll use the async library from the C++ standard library for asynchronous tasks. We’ll create a task for each tree and run them in parallel.
We’ll to start by putting the logic of the for loop
in a function that we’re going to pass to the std::async
function.
processTree(
Tree<MeshCgal, K> &tree, const MeshCgal &foliage_round,
const MeshCgal &foliage_oval, const MeshCgal &foliage_cone,
const std::array<double, 2> &M_origin,
const std::array<double, 2> &M_height_range, int &M_nNoHeight,
const Config &config, std::shared_ptr<MeshGeom> terrainMesh)
Then we’ll create a vector of std::future
objects that will store the results of the asynchronous tasks and we’ll run the tasks in parallel.
std::vector<std::future<std::shared_ptr<MeshGeom>>> futures;
for (auto &tree : M_treeLibrary) {
futures.push_back(
std::async(std::launch::async, [this, &tree, &foliage_round,
&foliage_oval, &foliage_cone] {
std::shared_ptr<MeshGeom> localTerrainMesh =
std::make_shared<MeshGeom>();
this->processTree(tree, foliage_round, foliage_oval,
foliage_cone, M_origin, M_height_range,
M_nNoHeight, this->config(),
localTerrainMesh);
return localTerrainMesh;
}));
}
Where :
-
std::async
is a function that runs a function asynchronously (potentially in a separate thread) and returns astd::future
object that will store the result of the function. -
std::launch::async
is a policy that tellsstd::async
to run the function asynchronously. -
The lambda function passed to
std::async
is the function that will be run asynchronously. It takes a tree and the foliage meshes as arguments and returns astd::shared_ptr<MeshGeom>
object.
Note that we had to create a localTerrainMesh
object for each task because the processTree
function modifies the terrainMesh
object passed as an argument. If we used the same terrainMesh
object for all the tasks, we would have concurrency issues.
Finally, we will wait for all the tasks to finish, collect the results and merge them into the main terrain mesh.
for (auto &future : futures) {
// Wait for task to complete and get result
auto localTerrainMesh = future.get();
// Merge result into the main terrain mesh
terrainMesh->merge(*localTerrainMesh);
}
The improvement in performance is evaluated in the Complexity section.
To further improve performance, we could try to parallelize the autorefine
function, which is responsible for merging meshes and excluding intersections between them. This function is one of the most time-consuming parts of the program, making it a good candidate for parallelization. However, the autorefine function is not inherently thread-safe.
The lack of thread safety arises because autorefine
modifies shared data structures—like the mesh and its associated geometries—during its execution. When multiple threads attempt to modify the same data simultaneously, it can lead to data corruption, race conditions, or inconsistent results, as the threads may interfere with each other’s operations.
To make autorefine thread-safe, one approach could be to split the mesh into smaller, independent segments, with each segment processed in a separate thread. This way, threads would not interfere with each other, and the function could safely operate in a multi-threaded environment, ensuring both performance gains and data integrity.

References
-
[verdie15] Yannick Verdie, Florent Lafarge, Pierre Alliez, "LOD Generation for Urban Scenes", ACM Transactions on Graphics, 34(3): 15, 2015, DOI: 10.1145/2766946
-
[verdie14] Yannick Verdie, Florent Lafarge, "Detecting parametric objects in large scenes by Monte Carlo sampling", International Journal of Computer Vision, 106(1): 57—75, 2014, DOI: 10.1007/s11263-013-0641-0
-
[stava14] O. Stava, S. Pirk, J. Kratt, B. Chen, R. Mech, O. Deussen, B. Benes, "Inverse Procedural Modeling of Trees", Preprint, 2014, Adobe Systems Inc., USA; University of Konstanz, Germany; Shenzhen Institute of Advanced Technology, China; Purdue University, USA.
-
[adtree] Shenglan Du, Roderik Lindenbergh, Hugo Ledoux, Jantien Stoter, Liangliang Nan, "AdTree: Accurate, Detailed, and Automatic Modelling of Laser-Scanned Trees", MDPI, 2019, MDPI: 2072-4292/11/8/942
-
[benes] Bedrich Benes, "Computational Vegetation", Computational Vegetation
-
[cgal] CGAL Development Team, "CGAL User and Reference Manual", CGAL User and Reference Manual
-
[feelpp] Feel Consortium, "Feel", Feel++ Documentation
-
[curl] "curl", curl Homepage
-
[meshlab] MeshLab Developers, "MeshLab", MeshLab Homepage
-
[overpass] OpenStreetMap Contributors, "Overpass API", Overpass API
-
[openstreetmap] "OpenStreetMap", OpenStreetMap Help
-
[img:TreeShade] Yujin Park, Jean-Michel Guldmann, Desheng Liu, "Impacts of tree and building shades on the urban heat island: Combining remote sensing, 3D digital city and spatial regression approaches", 2021, ScienceDirect: Impacts of tree and building shades on the urban heat island
-
[img:NY] Christophe Prud’homme, "New York City mesh", 2023, GitHub: New York City mesh
-
[img:aerialview] Conseil départemental de la Somme, "Aerial thermal view", 2023, Aerial thermal view
-
[img:street_thermography] P. Verchere, "Thermal image of a street in the city", 2023, The Conversation: Thermal image of a street in the city
-
[img:mercator] Bibm@th, "Mercator projection", 2024, Bibm@th: Mercator projection
-
[stl] Wikipedia, "STL (file format) - Wikipedia", 2023, Wikipedia: STL (file format)
-
[cgal_alpha_wrapper] Pierre Alliez, David Cohen-Steiner, Michael Hemmer, Cédric Portaneri, Mael Rouxel-Labbé, "CGAL 5.6.1 - 3D Alpha Wrapping", 2024, CGAL: 3D Alpha Wrapping
-
[cgal_affine_transformation] CGAL Development Team, "CGAL 5.6.1 - 2D and 3D Linear Geometry Kernel", 2024, CGAL: 2D and 3D Linear Geometry Kernel
-
[wgs84] Wikipedia, "World Geodetic System", 2024, Wikipedia: World Geodetic System
-
[wgs84_to_cartesian] Christian Berger, "WGS84toCartesian", 2021, GitHub: WGS84toCartesian
-
[k-nn] Wikipedia, "K-nearest neighbors algorithm", 2024, Wikipedia: K-nearest neighbors algorithm
-
[mercator-proj] Wikipedia, "Mercator projection", 2024, Wikipedia: Mercator projection
-
[sketchup] Wikipedia, "SketchUp", 2024, Wikipedia: SketchUp
-
[json] Wikipedia, "JSON", 2024, Wikipedia: JSON
-
[corefine-compute] CGAL Development Team, "CGAL 5.6.1 - 3D Alpha Shapes", 2024, CGAL: 3D Alpha Shapes
-
[hidalgo2-ubm] HiDALGO2, "Hidalgo2-UBM", 2024, HiDALGO2: Urban Building Model
-
[hidalgo2] HiDALGO2, "HiDALGO2", 2024, HiDALGO2 Homepage
-
[green-deal] European Commission, "European Green Deal", 2024, European Green Deal
-
[delaunay-wiki] Wikipedia, "Delaunay triangulation", 2024, Wikipedia: Delaunay triangulation
-
[hidalgo2-about] HiDALGO2, "About HiDALGO2", 2024, HiDALGO2: About
-
[cemosis] Cemosis, "Cemosis", 2024, Cemosis Homepage
-
[irma] IRMA, "IRMA", 2024, IRMA Homepage
-
[inria] INRIA, "INRIA", 2024, INRIA Homepage
-
[alliez] Pierre Alliez, "Pierre Alliez", 2024, Pierre Alliez Homepage
-
[chabannes] Vincent Chabannes, "Vincent Chabannes", 2024, ResearchGate: Vincent Chabannes
-
[paraview] Kitware, "ParaView", 2024, ParaView Homepage
-
[cgal-master] CGAL Development Team, "CGAL", 2024, CGAL GitHub
-
[overpass-ql] Roland Olbricht, "Overpass QL", 2024, Overpass QL
-
[overpass-turbo] Roland Olbricht, Martin Raifer, "Overpass turbo", 2024, Overpass turbo
-
[exaMA] ExaMA Consortium, "Exa-MA", 2024, Exa-MA: Methods and Algorithms for Exascale
-
[numpex] Numpex Consortium, "Numpex", 2024, Numpex Homepage
-
[gmsh] Christophe Geuzaine, Jean-François Remacle, "Gmsh", 2024, Gmsh Homepage
-
[img:tree-shape] Noriah Othman, Mashitah Mat Isa, Noralizawati Mohamed, Ramly Hasan, "Street Planting Compositions: The Public and Expert Perspectives", 2019, ResearchGate: Street Planting Compositions
-
[prudhomme] Christophe Prud’homme, "Christophe Prud’homme", 2024, ResearchGate: Christophe Prud’homme
-
[auto-refine-triangle-soup] CGAL Development Team, "CGAL 6.0 - Polygon Mesh Processing", 2024, CGAL: Polygon Mesh Processing
-
[cpr] CPR Developers, "Cpp Requests: Curl for People", 2024, GitHub: Cpp Requests
-
[pouvoir-arbre] Tania Landes , "The Conversation: D’où vient le pouvoir rafraîchissant des arbres en ville ?", 2023, The Conversation: D’où vient le pouvoir rafraîchissant des arbres en ville?
-
[science-direct] Yujin Park, Jean-Michel Guldmann, Desheng Liu, "Impacts of tree and building shades on the urban heat island: Combining remote sensing, 3D digital city and spatial regression approaches", 2021, ScienceDirect: Impacts of tree and building shades on the urban heat island
-
[gmsh-geo] Gmsh Developers, "Gmsh .geo file format", 2024, Gmsh .geo file format
-
[highest-plants] New Scientist - Aisling Irwin, "World’s highest plants discovered growing 6km above sea level", 2016, New Scientist: World’s highest plants discovered growing 6km above sea level
-
[raycasting] Wikipedia, "Ray casting", 2024, Wikipedia: Ray casting
-
[bvh] Wikipedia, "Bounding volume hierarchy", 2024, Wikipedia: Bounding volume hierarchy
-
[kd-tree] Wikipedia, "K-d tree", 2024, Wikipedia: K-d tree
-
[async] cplusplus.com, "std::async", 2024, cplusplus.com: std::async
-
[is_valid] CGAL Development Team, "CGAL 5.6.1 - 3D Mesh Generation", 2024, link:https://doc.cgal.org/latest/Surface_mesh/classCGAL_1_1Surface__mesh.html#a14cb5e4c51a02d652ba33bf906f39fc0[CGAL: is_valid()
-
[auto_refine_triangle_soup]] CGAL Development Team, "CGAL 6.0 - Polygon Mesh Processing", 2024, CGAL: autorefine_triangle_soup()
-
[deep_learning] Wikipedia, "Deep learning", 2024, Wikipedia: Deep learning
-
[numpex_exama] Numpex, "Exa-MA PC1", 2024, Numpex: Exa-MA PC1