diff --git a/Libs/Mesh/Mesh.cpp b/Libs/Mesh/Mesh.cpp index c0cfea9423..d9c439d034 100644 --- a/Libs/Mesh/Mesh.cpp +++ b/Libs/Mesh/Mesh.cpp @@ -680,6 +680,42 @@ std::vector Mesh::distance(const Mesh& target, const DistanceMethod metho } } break; + case SymmetricPointToCell: { + /* + referenceMesh (point) -> targetMesh (cell) (and get closestPoint) + referenceMesh (cell) -> targetMesh (closestPoint) + */ + auto targetCellLocator = vtkSmartPointer::New(); + targetCellLocator->SetDataSet(target.poly_data_); + targetCellLocator->BuildLocator(); + + auto refCellLocator = vtkSmartPointer::New(); + refCellLocator->SetDataSet(poly_data_); + refCellLocator->BuildLocator(); + + double dist2_target, dist2_ref; + auto cell_target = vtkSmartPointer::New(); + auto cell_ref = vtkSmartPointer::New(); + vtkIdType cellId_target, cellId_ref; + int subId_target, subId_ref; + Point3 closestPoint_target, closestPoint_ref; + + + for (int i = 0; i < numPoints(); i++) { + poly_data_->GetPoint(i, currentPoint.GetDataPointer()); // ref point + // ref mesh point -> target mesh cell + targetCellLocator->FindClosestPoint(currentPoint.GetDataPointer(), closestPoint_target.GetDataPointer(), cell_target, cellId_target, + subId_target, dist2_target); + // target mesh closest point -> ref mesh cell + refCellLocator->FindClosestPoint(closestPoint_target.GetDataPointer(), closestPoint_ref.GetDataPointer(), cell_ref, cellId_ref, + subId_ref, dist2_ref); + + ids->SetValue(i, cellId_target); + auto mean_sym_dist = (std::sqrt(dist2_target) + std::sqrt(dist2_ref))/2; + distance->SetValue(i, mean_sym_dist); + } + } break; + default: throw std::invalid_argument("invalid distance method"); } diff --git a/Libs/Mesh/Mesh.h b/Libs/Mesh/Mesh.h index 4ccba5950b..e53b598a27 100644 --- a/Libs/Mesh/Mesh.h +++ b/Libs/Mesh/Mesh.h @@ -20,7 +20,7 @@ class Mesh { public: enum FieldType { Point, Face }; enum AlignmentType { Rigid, Similarity, Affine }; - enum DistanceMethod { PointToPoint, PointToCell }; + enum DistanceMethod { PointToPoint, PointToCell, SymmetricPointToCell }; enum CurvatureType { Principal, Gaussian, Mean }; enum SubdivisionType { Butterfly, Loop }; diff --git a/Libs/Python/ShapeworksPython.cpp b/Libs/Python/ShapeworksPython.cpp index d4e7324e4a..8428460ac3 100644 --- a/Libs/Python/ShapeworksPython.cpp +++ b/Libs/Python/ShapeworksPython.cpp @@ -797,9 +797,10 @@ PYBIND11_MODULE(shapeworks_py, m) { // Mesh::DistanceMethod py::enum_(mesh, "DistanceMethod") - .value("PointToPoint", Mesh::DistanceMethod::PointToPoint) - .value("PointToCell", Mesh::DistanceMethod::PointToCell) - .export_values(); + .value("PointToPoint", Mesh::DistanceMethod::PointToPoint) + .value("PointToCell", Mesh::DistanceMethod::PointToCell) + .value("SymmetricPointToCell", Mesh::DistanceMethod::SymmetricPointToCell) + .export_values(); ; // Mesh::CurvatureType diff --git a/Studio/Visualization/Viewer.cpp b/Studio/Visualization/Viewer.cpp index 10ae0a43cc..7e1efcea0b 100644 --- a/Studio/Visualization/Viewer.cpp +++ b/Studio/Visualization/Viewer.cpp @@ -734,7 +734,9 @@ void Viewer::display_shape(std::shared_ptr shape) { } Mesh m2(compare_poly_data); - auto field = m.distance(m2)[0]; + auto field = m.distance(m2, Mesh::DistanceMethod::SymmetricPointToCell)[0]; + // TODO: disable debug + std::cout << "Debug Mode | Computing distance with SymmetricPointToCell method in Studio Viewer " << std::endl; m.setField("distance", field, Mesh::Point); }