Skip to content

Commit

Permalink
Output normals with a consistent orientation for convex meshes (#48)
Browse files Browse the repository at this point in the history
Co-authored-by: Seth Parker <csparker247@gmail.com>
  • Loading branch information
spelufo and csparker247 committed Nov 3, 2023
1 parent 61861a0 commit 65390bd
Show file tree
Hide file tree
Showing 39 changed files with 1,126 additions and 1,101 deletions.
20 changes: 16 additions & 4 deletions apps/src/GeneratePPM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,17 @@
#include "vc/core/io/MeshIO.hpp"
#include "vc/core/types/PerPixelMap.hpp"
#include "vc/core/util/Logging.hpp"
#include "vc/meshing/OrientNormals.hpp"
#include "vc/texturing/AngleBasedFlattening.hpp"
#include "vc/texturing/PPMGenerator.hpp"

namespace vc = volcart;
namespace vcm = volcart::meshing;
namespace vct = volcart::texturing;
namespace fs = volcart::filesystem;
namespace po = boost::program_options;

int main(int argc, char* argv[])
auto main(int argc, char* argv[]) -> int
{
// clang-format off
po::options_description all("Usage");
Expand All @@ -23,7 +26,8 @@ int main(int argc, char* argv[])
("output-ppm,o", po::value<std::string>()->required(),
"Path for the output ppm")
("uv-reuse", "If input-mesh is specified, attempt to use its existing "
"UV map instead of generating a new one.");
"UV map instead of generating a new one.")
("orient-normals", "Auto-orient surface normals towards the mesh centroid");
// clang-format on

// parsed will hold the values of all parsed options as a Map
Expand Down Expand Up @@ -54,11 +58,19 @@ int main(int argc, char* argv[])
auto mesh = meshFile.mesh;
auto uvMap = meshFile.uv;

// Reorient the surface normals
if (parsed.count("orient-normals") > 0) {
vcm::OrientNormals orient;
orient.setReferenceMode(vcm::OrientNormals::ReferenceMode::Centroid);
orient.setMesh(mesh);
mesh = orient.compute();
}

// Generate UV map
auto genUV = parsed.count("uv-reuse") == 0;
if (genUV or not uvMap) {
// ABF
vc::texturing::AngleBasedFlattening abf;
vct::AngleBasedFlattening abf;
abf.setMesh(mesh);
abf.compute();

Expand All @@ -71,7 +83,7 @@ int main(int argc, char* argv[])

// PPM
vc::Logger()->info("Generating per-pixel map");
vc::texturing::PPMGenerator p;
vct::PPMGenerator p;
p.setDimensions(height, width);
p.setMesh(mesh);
p.setUVMap(uvMap);
Expand Down
19 changes: 15 additions & 4 deletions apps/src/Mesher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,21 @@
#include "vc/core/filesystem.hpp"
#include "vc/core/io/MeshIO.hpp"
#include "vc/core/io/PointSetIO.hpp"
#include "vc/core/types/OrderedPointSet.hpp"
#include "vc/core/util/Logging.hpp"
#include "vc/meshing/OrderedPointSetMesher.hpp"
#include "vc/meshing/OrientNormals.hpp"

namespace fs = volcart::filesystem;
namespace po = boost::program_options;
namespace vc = volcart;
namespace vcm = volcart::meshing;

using psio = vc::PointSetIO<cv::Vec3d>;

auto main(int argc, char* argv[]) -> int
{
///// Parse the command line options /////
// All command line options
// clang-format off
po::options_description all("Usage");
all.add_options()
("help,h", "Show this message")
Expand All @@ -29,7 +30,9 @@ auto main(int argc, char* argv[]) -> int
"Path for the output mesh")
("mode,m", po::value<int>()->default_value(1),
"Reading mode: 0 = ASCII, 1 = Binary")
("disable-triangulation", "Disable vertex triangulation");
("disable-triangulation", "Disable vertex triangulation")
("orient-normals", "Auto-orient surface normals towards the mesh centroid");
// clang-format on

// parsed will hold the values of all parsed options as a Map
po::variables_map parsed;
Expand Down Expand Up @@ -59,10 +62,18 @@ auto main(int argc, char* argv[]) -> int

// Convert to a mesh
vc::Logger()->info("Generating mesh...");
vc::meshing::OrderedPointSetMesher mesher(inputCloud);
vcm::OrderedPointSetMesher mesher(inputCloud);
mesher.setComputeTriangulation(parsed.count("disable-triangulation") == 0);
auto output = mesher.compute();

// Reorient the surface normals
if (parsed.count("orient-normals") > 0) {
vcm::OrientNormals orient;
orient.setReferenceMode(vcm::OrientNormals::ReferenceMode::Centroid);
orient.setMesh(output);
output = orient.compute();
}

// Write the mesh
vc::Logger()->info("Writing mesh...");
vc::WriteMesh(outputPath, output);
Expand Down
27 changes: 18 additions & 9 deletions apps/src/Render.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,8 @@ static auto GetMeshingOpts() -> po::options_description
" 3 = Both before and after mesh resampling")
("intermediate-mesh", po::value<std::string>(),"Output file path for the "
"intermediate (i.e. scale + resampled) mesh. File is saved prior "
"to flattening. Useful for testing meshing parameters.");
"to flattening. Useful for testing meshing parameters.")
("orient-normals", "Auto-orient surface normals towards the mesh centroid");
// clang-format on

return opts;
Expand Down Expand Up @@ -331,7 +332,7 @@ auto main(int argc, char* argv[]) -> int
};
// clang-format on
graph->setProjectMetadata(projectInfo);
// Setup a map to keep a reference to important output ports
// Set up a map to keep a reference to important output ports
std::unordered_map<std::string, smgl::Output*> results;

//// Load the segmentation/mesh ////
Expand Down Expand Up @@ -479,14 +480,22 @@ auto main(int argc, char* argv[]) -> int
smooth->input = *results["mesh"];
results["mesh"] = &smooth->output;
}
}

// Save the intermediate mesh
if (parsed.count("intermediate-mesh") > 0) {
fs::path meshPath = parsed["intermediate-mesh"].as<std::string>();
auto writer = graph->insertNode<WriteMeshNode>();
writer->path = meshPath;
writer->mesh = *results["mesh"];
}
///// Reorient the mesh normals /////
if (parsed.count("orient-normals") > 0) {
auto orient = graph->insertNode<OrientNormalsNode>();
orient->input = *results["mesh"];
orient->referenceMode = OrientNormalsNode::ReferenceMode::Centroid;
results["mesh"] = &orient->output;
}

///// Save the intermediate mesh /////
if (parsed.count("intermediate-mesh") > 0) {
fs::path meshPath = parsed["intermediate-mesh"].as<std::string>();
auto writer = graph->insertNode<WriteMeshNode>();
writer->path = meshPath;
writer->mesh = *results["mesh"];
}

///// Flattening /////
Expand Down
171 changes: 0 additions & 171 deletions apps/src/RenderMeshing.cpp

This file was deleted.

21 changes: 10 additions & 11 deletions core/include/vc/core/shapes/Cube.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,18 +41,17 @@ class Cube : public ShapePrimitive

// generate the 12 cells for faces
addCell_(0, 1, 2);
addCell_(0, 1, 5);
addCell_(0, 2, 3);
addCell_(0, 3, 4);
addCell_(0, 4, 5);
addCell_(1, 2, 6);
addCell_(1, 5, 6);
addCell_(2, 3, 7);
addCell_(2, 6, 7);
addCell_(3, 4, 7);
addCell_(4, 5, 7);
addCell_(5, 6, 7);

addCell_(3, 2, 6);
addCell_(3, 6, 7);
addCell_(7, 6, 5);
addCell_(7, 5, 4);
addCell_(4, 5, 1);
addCell_(4, 1, 0);
addCell_(0, 3, 7);
addCell_(0, 7, 4);
addCell_(5, 6, 2);
addCell_(5, 2, 1);
} // Constructor

}; // Cube
Expand Down
24 changes: 1 addition & 23 deletions core/include/vc/core/types/Metadata.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <opencv2/core.hpp>

#include "vc/core/filesystem.hpp"
#include "vc/core/util/Json.hpp"

namespace volcart
{
Expand Down Expand Up @@ -104,26 +105,3 @@ class Metadata
volcart::filesystem::path path_;
};
} // namespace volcart

/** JSON Serializer for cv::Vec */
namespace nlohmann
{
template <typename T, int Cn>
struct adl_serializer<cv::Vec<T, Cn>> {
// NOLINTNEXTLINE(readability-identifier-naming): Must be exact signature
static void to_json(nlohmann::json& j, const cv::Vec<T, Cn>& v)
{
for (int i = 0; i < Cn; i++) {
j.push_back(v[i]);
}
}

// NOLINTNEXTLINE(readability-identifier-naming): Must be exact signature
static void from_json(const nlohmann::json& j, cv::Vec<T, Cn>& v)
{
for (int i = 0; i < Cn; i++) {
v[i] = j.at(i).get<T>();
}
}
};
} // namespace nlohmann

0 comments on commit 65390bd

Please sign in to comment.