GCC Code Coverage Report


Directory: ./
File: examples/geogram/CSG_builder/main.cpp
Date: 2026-09-07 02:36:43
Exec Total Coverage
Lines: 0 128 0.0%
Functions: 0 7 0.0%
Branches: 0 376 0.0%

Line Branch Exec Source
1 /*
2 * Copyright (c) 2000-2022 Inria
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * * Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * * Neither the name of the ALICE Project-Team nor the names of its
14 * contributors may be used to endorse or promote products derived from this
15 * software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
28 *
29 * Contact: Bruno Levy
30 *
31 * https://www.inria.fr/fr/bruno-levy
32 *
33 * Inria,
34 * Domaine de Voluceau,
35 * 78150 Le Chesnay - Rocquencourt
36 * FRANCE
37 *
38 */
39
40 #include <geogram/basic/common.h>
41 #include <geogram/basic/logger.h>
42 #include <geogram/basic/command_line.h>
43 #include <geogram/basic/command_line_args.h>
44 #include <geogram/basic/stopwatch.h>
45 #include <geogram/mesh/mesh_CSG.h>
46 #include <geogram/mesh/mesh_io.h>
47
48 namespace {
49
50 void configure_builder(GEO::CSGBuilder& builder) {
51 builder.set_simplify_coplanar_facets(
52 GEO::CmdLine::get_arg_bool("simplify_coplanar_facets"),
53 GEO::CmdLine::get_arg_double("coplanar_angle_tolerance")
54 );
55 builder.set_delaunay(GEO::CmdLine::get_arg_bool("delaunay"));
56 builder.set_detect_intersecting_neighbors(
57 GEO::CmdLine::get_arg_bool("detect_intersecting_neighbors")
58 );
59 builder.set_fast_union(GEO::CmdLine::get_arg_bool("fast_union"));
60 builder.set_noop(GEO::CmdLine::get_arg_bool("noop"));
61 if(GEO::CmdLine::get_arg_bool("clear_cache")) {
62 GEOCSG::OpenSCAD_cache_invalidate();
63 }
64 if(GEO::CmdLine::get_arg_bool("ignore_cache_time")) {
65 GEOCSG::OpenSCAD_cache_ignore_time();
66 }
67 }
68
69 std::shared_ptr<GEO::Mesh> example001(GEO::CSGBuilder& B) {
70 return B.difference(
71 B.sphere(25.0),
72 B.rotate(90.0, {0,0,1}, B.cylinder(62.5, 12.5, 12.5, true)),
73 B.rotate(90.0, {1,0,0}, B.cylinder(62.5, 12.5, 12.5, true)),
74 B.rotate(90.0, {0,1,0}, B.cylinder(62.5, 12.5, 12.5, true))
75 );
76 }
77
78 std::shared_ptr<GEO::Mesh> example002(GEO::CSGBuilder& B) {
79 return B.intersection(
80 B.difference(
81 B.union_instr(
82 B.cube({30, 30, 30}, true),
83 B.translate({0, 0, -25}, B.cube({15, 15, 50}, true))
84 ),
85 B.union_instr(
86 B.cube({50, 10, 10}, true),
87 B.cube({10, 50, 10}, true),
88 B.cube({10, 10, 50}, true)
89 )
90 ),
91 B.translate({0, 0, 5}, B.cylinder(50,20,5, true))
92 );
93 }
94
95 std::shared_ptr<GEO::Mesh> example003(GEO::CSGBuilder& B) {
96 return B.difference(
97 B.union_instr(
98 B.cube({30, 30, 30}, true),
99 B.cube({40, 15, 15}, true),
100 B.cube({15, 40, 15}, true),
101 B.cube({15, 15, 40}, true)
102 ),
103 B.union_instr(
104 B.cube({50, 10, 10}, true),
105 B.cube({10, 50, 10}, true),
106 B.cube({10, 10, 50}, true)
107 )
108 );
109 }
110
111 std::shared_ptr<GEO::Mesh> example004(GEO::CSGBuilder& B) {
112 return B.difference(
113 B.cube({30,30,30},true),
114 B.sphere(20)
115 );
116 }
117
118 std::shared_ptr<GEO::Mesh> example005(GEO::CSGBuilder& B) {
119 GEO::CSGScope columns;
120 for(double i=0; i<6.0; ++i) {
121 columns.emplace_back(
122 B.translate(
123 {sin(2.0*M_PI*i/6.0)*80, cos(2.0*M_PI*i/6.0)*80, 0.0},
124 B.cylinder(200,10,10)
125 )
126 );
127 }
128 return B.translate(
129 {0, 0, -120},
130 B.union_instr(
131 B.difference(
132 B.cylinder(50, 100, 100, false),
133 B.translate({0, 0, 10}, B.cylinder(50, 80, 80)),
134 B.translate({100, 0, 35}, B.cube({50,50,50}, true))
135 ),
136 B.union_instr(columns),
137 B.translate({0, 0, 200}, B.cylinder(80, 120, 0))
138 )
139 );
140 }
141 }
142
143 int main(int argc, char** argv) {
144 using namespace GEO;
145 try {
146 GEO::initialize(GEO::GEOGRAM_INSTALL_ALL);
147
148 CmdLine::import_arg_group("standard");
149 CmdLine::import_arg_group("algo");
150
151 std::vector<std::string> filenames;
152
153 CmdLine::declare_arg(
154 "verbose",false,"makes intersection algorithm more chatty"
155 );
156
157 CmdLine::declare_arg(
158 "detailed_verbose", false,
159 "makes intersection algorithm even more chatty"
160 );
161
162 CmdLine::declare_arg(
163 "simplify_coplanar_facets",true,
164 "simplify coplanar facets whenever possible"
165 );
166
167 CmdLine::declare_arg(
168 "coplanar_angle_tolerance",0.0,
169 "maximum angle (in degrees) between coplanar facets"
170 );
171
172 CmdLine::declare_arg(
173 "delaunay",true, "use Delaunay triangulation (nice triangles)"
174 );
175
176 CmdLine::declare_arg(
177 "detect_intersecting_neighbors",true,
178 "detect intersecting neighbors in input and intermediary meshes"
179 );
180
181 CmdLine::declare_arg(
182 "fast_union", true,
183 "fast union mode (there is no cnx component completely inside)"
184 );
185
186 CmdLine::declare_arg(
187 "noop", false, "do not evaluate 3D CSG operations (for testing)"
188 );
189
190 CmdLine::declare_arg(
191 "clear_cache", false,
192 "systematically regenerate files converted with OpenSCAD"
193 );
194
195 GEO::CmdLine::declare_arg(
196 "ignore_cache_time", false,
197 "ignore file modification time for deciding to use cache"
198 );
199
200 if(
201 !CmdLine::parse(
202 argc, argv, filenames, "csgfilename <outputfile|none>"
203 )
204 ) {
205 return 1;
206 }
207
208 Stopwatch Wtot("CSG (total)");
209
210 std::string csg_filename = filenames[0];
211
212 std::string output_filename =
213 filenames.size() >= 2 ? filenames[1] : std::string("out.meshb");
214
215 std::shared_ptr<Mesh> result;
216
217 CSGBuilder B;
218 configure_builder(B);
219
220 if(csg_filename == "example001") {
221 result = example001(B);
222 } else if(csg_filename == "example002") {
223 result = example002(B);
224 } else if(csg_filename == "example003") {
225 result = example003(B);
226 } else if(csg_filename == "example004") {
227 result = example004(B);
228 } else if(csg_filename == "example005") {
229 result = example005(B);
230 } else {
231 Logger::err("CSG") << "input should be example001 ... example005"
232 << std::endl;
233 }
234 if(result == nullptr) {
235 Logger::err("CSG") << "No output (problem occured)" << std::endl;
236 return 2;
237 } else {
238 mesh_save(*result, output_filename);
239 }
240 }
241 catch(const std::exception& e) {
242 std::cerr << "Received an exception: " << e.what() << std::endl;
243 return 1;
244 }
245
246 Logger::out("") << "Everything OK, Returning status 0" << std::endl;
247 return 0;
248 }
249