Skip to content

Commit 9721a15

Browse files
authored
Merge pull request #2169 from SCIInstitute/coarse_geodesics
Coarse geodesics
2 parents c817dbb + ba3981a commit 9721a15

26 files changed

+814
-861
lines changed

Libs/Analyze/Analyze.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ static void write_good_bad_angles(json& json_object, ProjectHandle project, Anal
6969
std::vector<json> good_bad_angles;
7070

7171
for (int d = 0; d < project->get_number_of_domains_per_subject(); d++) {
72-
std::vector<std::shared_ptr<VtkMeshWrapper>> meshes;
72+
std::vector<std::shared_ptr<MeshWrapper>> meshes;
7373
for (auto& shape : analyze.get_shapes()) {
7474
meshes.push_back(shape->get_groomed_mesh_wrappers()[d]);
7575
}

Libs/Analyze/Shape.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
#include <vtkKdTreePointLocator.h>
1717
#include <vtkPointData.h>
1818

19-
#include "Libs/Optimize/Domain/VtkMeshWrapper.h"
19+
#include "Libs/Optimize/Domain/MeshWrapper.h"
2020

2121
using ReaderType = itk::ImageFileReader<ImageType>;
2222

@@ -819,14 +819,14 @@ bool Shape::has_planes() {
819819
}
820820

821821
//---------------------------------------------------------------------------
822-
std::vector<std::shared_ptr<VtkMeshWrapper>> Shape::get_groomed_mesh_wrappers() {
822+
std::vector<std::shared_ptr<MeshWrapper>> Shape::get_groomed_mesh_wrappers() {
823823
if (!groomed_mesh_wrappers_.empty()) {
824824
return groomed_mesh_wrappers_;
825825
}
826826

827827
auto group = get_groomed_meshes(true /* wait */);
828828
for (auto& mesh : group.meshes()) {
829-
auto wrapper = std::make_shared<VtkMeshWrapper>(mesh->get_poly_data());
829+
auto wrapper = std::make_shared<MeshWrapper>(mesh->get_poly_data());
830830
groomed_mesh_wrappers_.push_back(wrapper);
831831
}
832832
return groomed_mesh_wrappers_;

Libs/Analyze/Shape.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ namespace shapeworks {
2222
class Shape;
2323
using ShapeHandle = std::shared_ptr<Shape>;
2424
using ShapeList = std::vector<ShapeHandle>;
25-
class VtkMeshWrapper;
25+
class MeshWrapper;
2626

2727
//! Representation of a single shape/patient/subject.
2828
class Shape {
@@ -175,7 +175,7 @@ class Shape {
175175

176176
bool has_planes();
177177

178-
std::vector<std::shared_ptr<VtkMeshWrapper>> get_groomed_mesh_wrappers();
178+
std::vector<std::shared_ptr<MeshWrapper>> get_groomed_mesh_wrappers();
179179

180180
private:
181181
void generate_meshes(std::vector<std::string> filenames, MeshGroup& mesh_list, bool save_transform,
@@ -191,7 +191,7 @@ class Shape {
191191
MeshGroup original_meshes_;
192192
MeshGroup groomed_meshes_;
193193
MeshGroup reconstructed_meshes_;
194-
std::vector<std::shared_ptr<VtkMeshWrapper>> groomed_mesh_wrappers_;
194+
std::vector<std::shared_ptr<MeshWrapper>> groomed_mesh_wrappers_;
195195

196196
std::string override_feature_;
197197

Libs/Groom/GroomParameters.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,12 +141,18 @@ GroomParameters::GroomParameters(ProjectHandle project, std::string domain_name)
141141
Keys::CENTER,
142142
Keys::ICP};
143143

144+
std::vector<std::string> to_remove;
145+
144146
// check if params_ has any unknown keys
145147
for (auto& param : params_.get_map()) {
146148
if (std::find(all_params.begin(), all_params.end(), param.first) == all_params.end()) {
147149
SW_WARN("Unknown Grooming parameter: " + param.first);
150+
to_remove.push_back(param.first);
148151
}
149152
}
153+
for (auto& param : to_remove) {
154+
params_.remove_entry(param);
155+
}
150156
}
151157

152158
//---------------------------------------------------------------------------

Libs/Mesh/Mesh.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@
6060

6161
#include "FEFixMesh.h"
6262
#include "Image.h"
63-
#include "Libs/Optimize/Domain/VtkMeshWrapper.h"
63+
#include "Libs/Optimize/Domain/MeshWrapper.h"
6464
#include "Logging.h"
6565
#include "MeshComputeThickness.h"
6666
#include "MeshUtils.h"
@@ -768,7 +768,7 @@ double Mesh::geodesicDistance(int source, int target) const {
768768
throw std::invalid_argument("requested point ids outside range of points available in mesh");
769769
}
770770

771-
VtkMeshWrapper wrap(this->poly_data_, true);
771+
MeshWrapper wrap(this->poly_data_, true);
772772
return wrap.ComputeDistance(getPoint(source), -1, getPoint(target), -1);
773773
}
774774

@@ -778,7 +778,7 @@ Field Mesh::geodesicDistance(const Point3 landmark) const {
778778
distance->SetNumberOfTuples(numPoints());
779779
distance->SetName("GeodesicDistanceToLandmark");
780780

781-
VtkMeshWrapper wrap(this->poly_data_, true);
781+
MeshWrapper wrap(this->poly_data_, true);
782782

783783
for (int i = 0; i < numPoints(); i++) {
784784
distance->SetValue(i, wrap.ComputeDistance(landmark, -1, getPoint(i), -1));

Libs/Mesh/Mesh.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ class Mesh {
270270

271271
//! Formats mesh into an IGL format
272272
MeshPoints getIGLMesh(Eigen::MatrixXd& V, Eigen::MatrixXi& F)
273-
const; // Copied directly from VtkMeshWrapper. this->poly_data_ becomes this->mesh. // WARNING: Copied directly
273+
const; // Copied directly from MeshWrapper. this->poly_data_ becomes this->mesh. // WARNING: Copied directly
274274
// from Meshwrapper. TODO: When refactoring, take this into account.
275275

276276
//! Clips the mesh according to a field value
Lines changed: 78 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,8 @@
1-
/*=========================================================================
2-
Copyright (c) 2009 Scientific Computing and Imaging Institute.
3-
See ShapeWorksLicense.txt for details.
4-
5-
This software is distributed WITHOUT ANY WARRANTY; without even
6-
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
7-
PURPOSE. See the above copyright notices for more information.
8-
=========================================================================*/
9-
101
#include "MeshDomain.h"
112

123
namespace shapeworks {
134

5+
//-------------------------------------------------------------------
146
bool MeshDomain::ApplyConstraints(PointType &p, int idx, bool dbg) const {
157
if (!mesh_wrapper_) {
168
return true;
@@ -19,17 +11,20 @@ bool MeshDomain::ApplyConstraints(PointType &p, int idx, bool dbg) const {
1911
return true;
2012
}
2113

14+
//-------------------------------------------------------------------
2215
bool MeshDomain::ApplyVectorConstraints(vnl_vector_fixed<double, DIMENSION> &gradE, const PointType &pos) const {
2316
// TODO need to refactor into update particle method
2417
// TODO reduce magnitude of vector so it doesn't violate constraints
2518
return true;
2619
}
2720

21+
//-------------------------------------------------------------------
2822
vnl_vector_fixed<double, DIMENSION> MeshDomain::ProjectVectorToSurfaceTangent(
2923
vnl_vector_fixed<double, DIMENSION> &gradE, const PointType &pos, int idx) const {
3024
return mesh_wrapper_->ProjectVectorToSurfaceTangent(pos, idx, gradE);
3125
}
3226

27+
//-------------------------------------------------------------------
3328
MeshDomain::PointType MeshDomain::UpdateParticlePosition(const PointType &point, int idx,
3429
vnl_vector_fixed<double, DIMENSION> &update) const {
3530
vnl_vector_fixed<double, DIMENSION> negativeUpdate;
@@ -40,6 +35,7 @@ MeshDomain::PointType MeshDomain::UpdateParticlePosition(const PointType &point,
4035
return newPoint;
4136
}
4237

38+
//-------------------------------------------------------------------
4339
double MeshDomain::GetMaxDiameter() const {
4440
// todo should this not be the length of the bounding box diagonal?
4541
PointType boundingBoxSize = mesh_wrapper_->GetMeshUpperBound() - mesh_wrapper_->GetMeshLowerBound();
@@ -50,6 +46,79 @@ double MeshDomain::GetMaxDiameter() const {
5046
return max;
5147
}
5248

49+
//-------------------------------------------------------------------
50+
vnl_vector_fixed<float, 3> MeshDomain::SampleGradientAtPoint(const PointType &point, int idx) const {
51+
return mesh_wrapper_->SampleNormalAtPoint(point, idx);
52+
}
53+
54+
//-------------------------------------------------------------------
55+
vnl_vector_fixed<float, 3> MeshDomain::SampleNormalAtPoint(const PointType &point, int idx) const {
56+
return mesh_wrapper_->SampleNormalAtPoint(point, idx);
57+
}
58+
59+
//-------------------------------------------------------------------
60+
ParticleDomain::GradNType MeshDomain::SampleGradNAtPoint(const PointType &p, int idx) const {
61+
return mesh_wrapper_->SampleGradNAtPoint(p, idx);
62+
}
63+
64+
//-------------------------------------------------------------------
65+
double MeshDomain::Distance(const PointType &a, int idx_a, const PointType &b, int idx_b,
66+
vnl_vector_fixed<double, 3> *out_grad) const {
67+
return geodesics_mesh_->ComputeDistance(a, idx_a, b, idx_b, out_grad);
68+
}
69+
70+
//-------------------------------------------------------------------
71+
double MeshDomain::SquaredDistance(const PointType &a, int idx_a, const PointType &b, int idx_b) const {
72+
double dist = geodesics_mesh_->ComputeDistance(a, idx_a, b, idx_b);
73+
return dist * dist;
74+
}
75+
76+
//-------------------------------------------------------------------
77+
bool MeshDomain::IsWithinDistance(const PointType &a, int idx_a, const PointType &b, int idx_b, double test_dist,
78+
double &dist) const {
79+
return geodesics_mesh_->IsWithinDistance(a, idx_a, b, idx_b, test_dist, dist);
80+
}
81+
82+
//-------------------------------------------------------------------
83+
void MeshDomain::SetMesh(std::shared_ptr<MeshWrapper> mesh, double geodesic_remesh_percent) {
84+
m_FixedDomain = false;
85+
mesh_wrapper_ = mesh;
86+
sw_mesh_ = std::make_shared<Mesh>(mesh_wrapper_->GetPolydata());
87+
88+
if (geodesic_remesh_percent >= 100.0) { // no remeshing
89+
geodesics_mesh_ = mesh_wrapper_;
90+
} else {
91+
auto poly_data = mesh_wrapper_->GetPolydata();
92+
Mesh mesh_copy(poly_data);
93+
mesh_copy.remeshPercent(geodesic_remesh_percent, 1.0);
94+
geodesics_mesh_ = std::make_shared<MeshWrapper>(mesh_copy.getVTKMesh());
95+
}
96+
}
97+
98+
//-------------------------------------------------------------------
5399
void MeshDomain::InvalidateParticlePosition(int idx) const { this->mesh_wrapper_->InvalidateParticle(idx); }
54100

101+
//-------------------------------------------------------------------
102+
ParticleDomain::PointType MeshDomain::GetZeroCrossingPoint() const {
103+
// TODO Hong
104+
// Apply constraints somehow
105+
if (mesh_wrapper_ == nullptr) {
106+
// Fixed domain. Unsure if this is the correct thing to do, but it preserves existing behaviour.
107+
PointType p;
108+
p[0] = p[1] = p[2] = 0;
109+
return p;
110+
}
111+
return mesh_wrapper_->GetPointOnMesh();
112+
}
113+
114+
//-------------------------------------------------------------------
115+
ParticleDomain::PointType MeshDomain::GetValidLocationNear(PointType p) const {
116+
PointType valid;
117+
valid[0] = p[0];
118+
valid[1] = p[1];
119+
valid[2] = p[2];
120+
ApplyConstraints(valid, -1);
121+
return valid;
122+
}
123+
55124
} // namespace shapeworks

Libs/Optimize/Domain/MeshDomain.h

Lines changed: 12 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -40,26 +40,9 @@ class MeshDomain : public ParticleDomain {
4040
const PointType &GetLowerBound() const override { return mesh_wrapper_->GetMeshLowerBound(); }
4141
const PointType &GetUpperBound() const override { return mesh_wrapper_->GetMeshUpperBound(); }
4242

43-
PointType GetZeroCrossingPoint() const override {
44-
// TODO Hong
45-
// Apply constraints somehow
46-
if (mesh_wrapper_ == nullptr) {
47-
// Fixed domain. Unsure if this is the correct thing to do, but it preserves existing behaviour.
48-
PointType p;
49-
p[0] = p[1] = p[2] = 0;
50-
return p;
51-
}
52-
return mesh_wrapper_->GetPointOnMesh();
53-
}
43+
PointType GetZeroCrossingPoint() const override;
5444

55-
PointType GetValidLocationNear(PointType p) const override {
56-
PointType valid;
57-
valid[0] = p[0];
58-
valid[1] = p[1];
59-
valid[2] = p[2];
60-
ApplyConstraints(valid, -1);
61-
return valid;
62-
}
45+
PointType GetValidLocationNear(PointType p) const override;
6346

6447
double GetSurfaceArea() const override {
6548
// TODO return actual surface area
@@ -68,32 +51,19 @@ class MeshDomain : public ParticleDomain {
6851

6952
double GetMaxDiameter() const override;
7053

71-
inline vnl_vector_fixed<float, DIMENSION> SampleGradientAtPoint(const PointType &point, int idx) const override {
72-
return mesh_wrapper_->SampleNormalAtPoint(point, idx);
73-
}
54+
vnl_vector_fixed<float, DIMENSION> SampleGradientAtPoint(const PointType &point, int idx) const override;
7455

75-
inline vnl_vector_fixed<float, DIMENSION> SampleNormalAtPoint(const PointType &point, int idx) const override {
76-
return mesh_wrapper_->SampleNormalAtPoint(point, idx);
77-
}
56+
vnl_vector_fixed<float, DIMENSION> SampleNormalAtPoint(const PointType &point, int idx) const override;
7857

79-
inline GradNType SampleGradNAtPoint(const PointType &p, int idx) const override {
80-
return mesh_wrapper_->SampleGradNAtPoint(p, idx);
81-
}
58+
GradNType SampleGradNAtPoint(const PointType &p, int idx) const override;
8259

83-
inline double Distance(const PointType &a, int idx_a, const PointType &b, int idx_b,
84-
vnl_vector_fixed<double, DIMENSION> *out_grad = nullptr) const override {
85-
return mesh_wrapper_->ComputeDistance(a, idx_a, b, idx_b, out_grad);
86-
}
60+
double Distance(const PointType &a, int idx_a, const PointType &b, int idx_b,
61+
vnl_vector_fixed<double, DIMENSION> *out_grad = nullptr) const override;
8762

88-
inline double SquaredDistance(const PointType &a, int idx_a, const PointType &b, int idx_b) const override {
89-
double dist = mesh_wrapper_->ComputeDistance(a, idx_a, b, idx_b);
90-
return dist * dist;
91-
}
63+
double SquaredDistance(const PointType &a, int idx_a, const PointType &b, int idx_b) const override;
9264

93-
inline bool IsWithinDistance(const PointType &a, int idx_a, const PointType &b, int idx_b, double test_dist,
94-
double &dist) const override {
95-
return mesh_wrapper_->IsWithinDistance(a, idx_a, b, idx_b, test_dist, dist);
96-
}
65+
bool IsWithinDistance(const PointType &a, int idx_a, const PointType &b, int idx_b, double test_dist,
66+
double &dist) const override;
9767

9868
void DeleteImages() override {
9969
// TODO Change this to a generic delete function
@@ -103,18 +73,15 @@ class MeshDomain : public ParticleDomain {
10373
// TODO Change this to a generic delete function
10474
}
10575

106-
void SetMesh(std::shared_ptr<shapeworks::MeshWrapper> mesh_) {
107-
m_FixedDomain = false;
108-
mesh_wrapper_ = mesh_;
109-
sw_mesh_ = std::make_shared<Mesh>(mesh_wrapper_->GetPolydata());
110-
}
76+
void SetMesh(std::shared_ptr<MeshWrapper> mesh_, double geodesic_remesh_percent);
11177

11278
std::shared_ptr<Mesh> GetSWMesh() const { return sw_mesh_; }
11379

11480
void UpdateZeroCrossingPoint() override {}
11581

11682
private:
11783
std::shared_ptr<MeshWrapper> mesh_wrapper_;
84+
std::shared_ptr<MeshWrapper> geodesics_mesh_;
11885
std::shared_ptr<Mesh> sw_mesh_;
11986
PointType zero_crossing_point_;
12087
};

0 commit comments

Comments
 (0)