Skip to content

Commit 0c1a973

Browse files
committed
mechanism to replay latest command, command to compute surface mesh intersection in geobox
1 parent ecdfb93 commit 0c1a973

File tree

6 files changed

+117
-29
lines changed

6 files changed

+117
-29
lines changed

src/bin/geobox/main.cpp

+41-24
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767

6868
#include <geogram/third_party/PoissonRecon/poisson_geogram.h>
6969

70+
#include <geogram/basic/stopwatch.h>
7071
#include <geogram/basic/command_line.h>
7172
#include <geogram/basic/command_line_args.h>
7273
#include <geogram/basic/file_system.h>
@@ -272,8 +273,6 @@ namespace {
272273
texture_ = 0;
273274
checker_texture_ = 0;
274275
texture_mode_ = NO_TEXTURE;
275-
add_key_func("F5", autorepair);
276-
locked_ = false;
277276
}
278277

279278
void geogram_initialize(int argc, char** argv) override {
@@ -474,6 +473,20 @@ namespace {
474473
);
475474
}
476475

476+
if(ImGui::MenuItem("intersect")) {
477+
GEO::Command::set_current(
478+
"void intersect("
479+
"bool neighbors = true"
480+
" [test neighboring triangles for intersections],"
481+
"bool union = true"
482+
" [removes internal shells],"
483+
"bool coplanar = true"
484+
" [re-triangulate sets of coplanar facets]"
485+
") [removes surface mesh intersections]",
486+
this, &GeoBoxApplication::intersect
487+
);
488+
}
489+
477490
if(ImGui::MenuItem("keep largest part")) {
478491
GEO::Command::set_current(
479492
"void keep_largest_component( "
@@ -706,9 +719,11 @@ namespace {
706719
texture_filename_ = "";
707720
bool result = SimpleMeshApplication::load(filename);
708721
if(result && FileSystem::extension(filename) == "stl") {
722+
locked_ = true;
709723
begin();
710724
mesh_repair(mesh_);
711-
end();
725+
end();
726+
locked_ = false;
712727
}
713728

714729
std::string tex_file_name =
@@ -1043,7 +1058,29 @@ namespace {
10431058
end();
10441059
}
10451060

1046-
1061+
void intersect(
1062+
bool detect_intersecting_neighbors = true,
1063+
bool remove_internal_shells = true,
1064+
bool simplify_coplanar_facets = true
1065+
) {
1066+
begin();
1067+
MeshSurfaceIntersection intersection(mesh_);
1068+
intersection.set_delaunay(true);
1069+
intersection.set_detect_intersecting_neighbors(
1070+
detect_intersecting_neighbors
1071+
);
1072+
intersection.set_verbose(false);
1073+
intersection.set_radial_sort(remove_internal_shells);
1074+
intersection.intersect();
1075+
if(remove_internal_shells) {
1076+
intersection.remove_internal_shells();
1077+
}
1078+
if(simplify_coplanar_facets) {
1079+
intersection.simplify_coplanar_facets();
1080+
}
1081+
end();
1082+
}
1083+
10471084
void remesh_smooth(
10481085
index_t nb_points = 30000,
10491086
double tri_shape_adapt = 1.0,
@@ -1644,7 +1681,6 @@ namespace {
16441681
* for all geometry processing functions.
16451682
*/
16461683
void begin() {
1647-
locked_ = true;
16481684
mesh()->vertices.set_double_precision();
16491685
}
16501686

@@ -1671,7 +1707,6 @@ namespace {
16711707
if(mesh()->facets.nb() == 0 && mesh()->cells.nb() == 0) {
16721708
show_vertices();
16731709
}
1674-
locked_ = false;
16751710
}
16761711

16771712
/**
@@ -1852,30 +1887,12 @@ namespace {
18521887
glupDisable(GLUP_NORMAL_MAPPING);
18531888
}
18541889

1855-
protected:
1856-
static void autorepair() {
1857-
GeoBoxApplication* app =
1858-
static_cast<GeoBoxApplication*>(instance());
1859-
app->begin();
1860-
MeshSurfaceIntersection intersection(app->mesh_);
1861-
intersection.set_delaunay(true);
1862-
intersection.set_detect_intersecting_neighbors(true);
1863-
intersection.set_verbose(false);
1864-
intersection.set_radial_sort(true);
1865-
intersection.intersect();
1866-
intersection.remove_internal_shells();
1867-
intersection.simplify_coplanar_facets();
1868-
app->end();
1869-
}
1870-
18711890
protected:
18721891
std::string texture_filename_;
18731892
Image_var texture_image_;
18741893
GLuint texture_;
18751894
GLuint checker_texture_;
18761895
TextureMode texture_mode_;
1877-
bool locked_; // to avoid weird behavior when pressing up/down while
1878-
// command or mesh repair is running.
18791896
};
18801897
}
18811898

src/lib/geogram_gfx/gui/command.cpp

+14
Original file line numberDiff line numberDiff line change
@@ -108,10 +108,23 @@ namespace GEO {
108108
if(queued_ != nullptr) {
109109
// Steal the queued command to avoid
110110
// infinite recursion.
111+
/*
111112
SmartPointer<Command> queued = queued_;
112113
queued_ = nullptr;
113114
queued->apply();
114115
*(queued->is_visible_ptr()) = false;
116+
*/
117+
118+
latest_ = queued_;
119+
queued_ = nullptr;
120+
latest_->apply();
121+
*(latest_->is_visible_ptr()) = false;
122+
}
123+
}
124+
125+
void Command::replay_latest() {
126+
if(!latest_.is_null()) {
127+
latest_->apply();
115128
}
116129
}
117130

@@ -546,5 +559,6 @@ namespace GEO {
546559

547560
SmartPointer<Command> Command::current_;
548561
SmartPointer<Command> Command::queued_;
562+
SmartPointer<Command> Command::latest_;
549563
}
550564

src/lib/geogram_gfx/gui/command.h

+20-4
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,12 @@ namespace GEO {
211211
* it would nest two ImGUI handlers, which is not allowed.
212212
*/
213213
static void flush_queue();
214+
215+
216+
/**
217+
* \brief Replays the latest invoked command
218+
*/
219+
static void replay_latest();
214220

215221
/**
216222
* \brief Command constructor.
@@ -307,6 +313,18 @@ namespace GEO {
307313
return current_;
308314
}
309315

316+
317+
/**
318+
* \brief Gets the latest command.
319+
* \return a pointer to the command that was last executed.
320+
* \details Used by playback mechanism ('F5' in applications).
321+
*/
322+
static Command* latest() {
323+
return latest_;
324+
}
325+
326+
327+
310328
/**
311329
* \brief Resets the current command.
312330
*/
@@ -1023,10 +1041,6 @@ namespace GEO {
10231041
args_[i] = Arg("arg " + String::to_string(i), default_val);
10241042
}
10251043

1026-
static void set_queued(Command* command) {
1027-
queued_ = command;
1028-
}
1029-
10301044
private:
10311045

10321046
/**
@@ -1191,6 +1205,7 @@ namespace GEO {
11911205
geo_assert(i < args_.size());
11921206
return args_[i];
11931207
}
1208+
11941209

11951210
private:
11961211
std::string name_;
@@ -1205,6 +1220,7 @@ namespace GEO {
12051220
bool auto_create_args_;
12061221
static SmartPointer<Command> current_;
12071222
static SmartPointer<Command> queued_;
1223+
static SmartPointer<Command> latest_;
12081224
};
12091225

12101226
/***********************************************************************/

src/lib/geogram_gfx/gui/simple_application.cpp

+23
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
#include <geogram/basic/string.h>
4444
#include <geogram/basic/logger.h>
4545
#include <geogram/basic/command_line.h>
46+
#include <geogram/basic/stopwatch.h>
4647
#include <geogram/bibliography/bibliography.h>
4748

4849
#include <geogram_gfx/full_screen_effects/ambient_occlusion.h>
@@ -164,6 +165,9 @@ namespace GEO {
164165
add_key_toggle("F8", &object_properties_visible_, "object properties");
165166
add_key_toggle("F9", &console_visible_, "console");
166167
add_key_toggle("F12", &menubar_visible_, "menubar");
168+
169+
add_key_func("F5", replay_latest_command, "replay latest command");
170+
167171
set_region_of_interest(0.0, 0.0, 0.0, 1.0, 1.0, 1.0);
168172

169173
object_translation_ = vec3(0.0, 0.0, 0.0);
@@ -194,6 +198,7 @@ namespace GEO {
194198
);
195199

196200
props_pinned_ = false;
201+
locked_ = false;
197202
}
198203

199204
SimpleApplication::~SimpleApplication() {
@@ -1147,7 +1152,12 @@ namespace GEO {
11471152
}
11481153

11491154
void SimpleApplication::post_draw() {
1155+
if(locked_) {
1156+
return;
1157+
}
1158+
locked_ = true;
11501159
Command::flush_queue();
1160+
locked_ = false;
11511161
}
11521162

11531163
void SimpleApplication::mouse_button_callback(
@@ -1511,5 +1521,18 @@ namespace GEO {
15111521
load(f[i]);
15121522
}
15131523
}
1524+
1525+
void SimpleApplication::replay_latest_command() {
1526+
if(instance()->locked_ || Command::latest() == nullptr) {
1527+
return;
1528+
}
1529+
Logger::out("Command") << Command::latest()->name() << " start..."
1530+
<< std::endl;
1531+
instance()->draw(); // so that we can see the logger message
1532+
Stopwatch W("Command");
1533+
instance()->locked_ = true;
1534+
Command::replay_latest();
1535+
instance()->locked_ = false;
1536+
}
15141537
}
15151538

src/lib/geogram_gfx/gui/simple_application.h

+5-1
Original file line numberDiff line numberDiff line change
@@ -486,8 +486,12 @@ namespace GEO {
486486
virtual const char* default_layout() const;
487487
virtual const char* default_layout_android_vertical() const;
488488
virtual const char* default_layout_android_horizontal() const;
489-
489+
490+
protected:
491+
static void replay_latest_command();
492+
490493
protected:
494+
bool locked_; // avoid starting command when command is running
491495
bool lighting_;
492496
bool edit_light_;
493497
bool clipping_;

src/lib/geogram_gfx/gui/simple_mesh_application.cpp

+14
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,13 @@ namespace GEO {
359359
}
360360
} while(MeshIOHandler::get_handler(*it) == nullptr);
361361
instance()->load(*it);
362+
Logger::out("I/O") << "Loaded " << FileSystem::base_name(*it)
363+
<< "."
364+
<< FileSystem::extension(*it)
365+
<< " (" << (it - files.begin() + 1)
366+
<< "/"
367+
<< files.size() << ")"
368+
<< std::endl;
362369
}
363370

364371
void SimpleMeshApplication::next_file() {
@@ -384,6 +391,13 @@ namespace GEO {
384391
}
385392
} while(MeshIOHandler::get_handler(*it) == nullptr);
386393
instance()->load(*it);
394+
Logger::out("I/O") << "Loaded " << FileSystem::base_name(*it)
395+
<< "."
396+
<< FileSystem::extension(*it)
397+
<< " (" << (it - files.begin() + 1)
398+
<< "/"
399+
<< files.size() << ")"
400+
<< std::endl;
387401
}
388402

389403
void SimpleMeshApplication::GL_initialize() {

0 commit comments

Comments
 (0)