Skip to content

Commit 4f9d63a

Browse files
authored
Merge pull request #2178 from SCIInstitute/2177-display-thickness
Resolve #2177 by adding the new feature to display the thickness as an inner surface on slices
2 parents 99c62e8 + fad0ee7 commit 4f9d63a

File tree

9 files changed

+259
-152
lines changed

9 files changed

+259
-152
lines changed

Libs/Mesh/MeshComputeThickness.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ static double get_distance_to_opposite_side(Mesh& mesh, int point_id) {
174174
return distance;
175175
}
176176

177+
//---------------------------------------------------------------------------
177178
double compute_thickness_from_signal(const std::vector<double>& intensities_input, double step_size) {
178179
auto smoothed = median_smooth_signal_intensities(intensities_input);
179180
for (int k = 0; k < 10; k++) {
@@ -518,4 +519,49 @@ void compute_thickness(Mesh& mesh, Image& image, Image* dt, double max_dist, dou
518519
d_mesh.write(distance_mesh);
519520
}
520521
}
522+
523+
//---------------------------------------------------------------------------
524+
Mesh compute_inner_mesh(const Mesh& mesh, std::string array_name) {
525+
// create a copy
526+
Mesh new_mesh = mesh;
527+
528+
auto poly_data = new_mesh.getVTKMesh();
529+
530+
// check if it has this array
531+
if (!poly_data->GetPointData()->HasArray(array_name.c_str())) {
532+
SW_ERROR("Mesh does not have array {}", array_name);
533+
}
534+
535+
// check if it has normals, if not, compute them
536+
if (!poly_data->GetPointData()->GetNormals()) {
537+
new_mesh.computeNormals();
538+
}
539+
540+
auto values = vtkDoubleArray::SafeDownCast(poly_data->GetPointData()->GetArray(array_name.c_str()));
541+
if (!values) {
542+
return new_mesh;
543+
}
544+
545+
// for each vertex, move the particle the distance scalar
546+
for (int i = 0; i < mesh.numPoints(); i++) {
547+
Point3 point;
548+
poly_data->GetPoint(i, point.GetDataPointer());
549+
550+
double value = values->GetValue(i);
551+
552+
// get the normal
553+
double normal[3];
554+
poly_data->GetPointData()->GetNormals()->GetTuple(i, normal);
555+
556+
// move the point in the opposite direction of the normal by the value
557+
for (int j = 0; j < 3; j++) {
558+
point[j] -= normal[j] * value;
559+
}
560+
561+
// modify the point position in the poly_data
562+
poly_data->GetPoints()->SetPoint(i, point.GetDataPointer());
563+
}
564+
return new_mesh;
565+
}
566+
521567
} // namespace shapeworks::mesh

Libs/Mesh/MeshComputeThickness.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,6 @@ namespace shapeworks::mesh {
99
void compute_thickness(Mesh &mesh, Image &image, Image *dt, double max_dist, double median_radius,
1010
std::string distance_mesh);
1111

12+
Mesh compute_inner_mesh(const Mesh &mesh, std::string array_name);
13+
1214
} // namespace shapeworks::mesh

Studio/Data/Session.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1102,6 +1102,28 @@ void Session::set_image_sync_slice(bool enabled) {
11021102
//---------------------------------------------------------------------------
11031103
bool Session::get_image_sync_slice() { return params_.get("image_sync_slice", true); }
11041104

1105+
//---------------------------------------------------------------------------
1106+
void Session::set_image_thickness_feature(bool enabled) {
1107+
if (enabled == get_image_thickness_feature() || is_loading()) {
1108+
return;
1109+
}
1110+
params_.set("image_thickness_feature", enabled);
1111+
Q_EMIT image_slice_settings_changed();
1112+
}
1113+
1114+
//---------------------------------------------------------------------------
1115+
bool Session::get_image_thickness_feature() { return params_.get("image_thickness_feature", false); }
1116+
1117+
//---------------------------------------------------------------------------
1118+
void Session::set_feature_map(std::string feature_map) {
1119+
if (feature_map != get_feature_map() || is_loading()) {
1120+
params_.set("feature_map", feature_map);
1121+
}
1122+
}
1123+
1124+
//---------------------------------------------------------------------------
1125+
std::string Session::get_feature_map() { return params_.get("feature_map", ""); }
1126+
11051127
//---------------------------------------------------------------------------
11061128
bool Session::has_constraints() {
11071129
for (auto& shape : shapes_) {

Studio/Data/Session.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,13 @@ class Session : public QObject, public QEnableSharedFromThis<Session> {
202202
void set_image_sync_slice(bool enabled);
203203
bool get_image_sync_slice();
204204

205+
// 3D image, thickness feature
206+
void set_image_thickness_feature(bool enabled);
207+
bool get_image_thickness_feature();
208+
209+
void set_feature_map(std::string feature_map);
210+
std::string get_feature_map();
211+
205212
bool has_constraints();
206213

207214
void set_loading(bool loading);

Studio/Interface/ShapeWorksStudioApp.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -978,6 +978,7 @@ void ShapeWorksStudioApp::new_session() {
978978
connect(ui_->image_share_window_and_level_, &QCheckBox::clicked, session_.data(),
979979
&Session::set_image_share_window_and_level);
980980
connect(ui_->image_sync_slices, &QCheckBox::clicked, session_.data(), &Session::set_image_sync_slice);
981+
connect(ui_->image_thickness_feature, &QCheckBox::clicked, session_.data(), &Session::set_image_thickness_feature);
981982

982983
connect(ui_->planes_visible_button_, &QToolButton::toggled, session_.data(), &Session::set_show_planes);
983984
connect(ui_->landmarks_visible_button, &QToolButton::clicked, session_.data(), &Session::set_show_landmarks);
@@ -2050,9 +2051,7 @@ void ShapeWorksStudioApp::image_combo_changed(int index) {
20502051
//---------------------------------------------------------------------------
20512052
bool ShapeWorksStudioApp::set_feature_map(std::string feature_map) {
20522053
if (feature_map != get_feature_map()) {
2053-
if (!session_->is_loading()) {
2054-
session_->parameters().set("feature_map", feature_map);
2055-
}
2054+
session_->set_feature_map(feature_map);
20562055
update_view_mode();
20572056
return true;
20582057
}
@@ -2061,7 +2060,7 @@ bool ShapeWorksStudioApp::set_feature_map(std::string feature_map) {
20612060

20622061
//---------------------------------------------------------------------------
20632062
std::string ShapeWorksStudioApp::get_feature_map() {
2064-
std::string feature_map = session_->parameters().get("feature_map", "");
2063+
std::string feature_map = session_->get_feature_map();
20652064

20662065
// confirm that this is a valid feature map
20672066
auto feature_maps = session_->get_project()->get_feature_names();

0 commit comments

Comments
 (0)