Skip to content

Commit

Permalink
optimize() now requires the weights
Browse files Browse the repository at this point in the history
  • Loading branch information
LiangliangNan committed Jan 11, 2025
1 parent 9e4468a commit 10b2008
Show file tree
Hide file tree
Showing 13 changed files with 88 additions and 103 deletions.
3 changes: 3 additions & 0 deletions code/Examples/Example_1_reconstruction_oneshot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,13 @@ int main(int argc, char **argv)
std::cerr << "Reconstruction failed" << std::endl;
return EXIT_FAILURE;
}
// now we don't need the point cloud anymore, and it can be deleted
delete point_cloud;

std::cout << "Reconstructed mesh has " << mesh->size_of_facets() << " faces" << std::endl;
if (MapIO::save(output_file, mesh)) {
std::cout << "Reconstructed model saved to file: " << output_file << std::endl;
delete mesh;
return EXIT_SUCCESS;
}
else {
Expand Down
28 changes: 12 additions & 16 deletions code/Examples/Example_2_reconstruction_with_intermediate_steps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,26 +35,21 @@ int main(int argc, char **argv)
// output mesh file name
const std::string output_file = (argc > 2) ? argv[2] : std::string(POLYFIT_CODE_DIR) + "/../data/toy_data-result.obj";

// below are the default parameters (change these when necessary)
Method::lambda_data_fitting = 0.43;
Method::lambda_model_coverage = 0.27;
Method::lambda_model_complexity = 0.3;

// load point cloud from file
PointSet* pset = PointSetIO::read(input_file);
if (!pset) {
PointSet* point_cloud = PointSetIO::read(input_file);
if (!point_cloud) {
std::cerr << "failed loading point cloud from file: " << input_file << std::endl;
return EXIT_FAILURE;
}

// step 1: refine planes
std::cout << "refining planes..." << std::endl;
const std::vector<VertexGroup::Ptr>& groups = pset->groups();
const std::vector<VertexGroup::Ptr>& groups = point_cloud->groups();
if (groups.empty()) {
std::cerr << "planar segments do not exist" << std::endl;
return EXIT_FAILURE;
}
HypothesisGenerator hypothesis(pset);
HypothesisGenerator hypothesis(point_cloud);
hypothesis.refine_planes();

// step 2: generate face hypothesis
Expand All @@ -68,30 +63,31 @@ int main(int argc, char **argv)

// step 3: face selection
std::cout << "optimization..." << std::endl;
FaceSelection selector(pset, mesh);
FaceSelection selector(point_cloud, mesh);

#ifdef HAS_GUROBI
selector.optimize(&hypothesis, LinearProgramSolver::GUROBI);
selector.optimize(&hypothesis, LinearProgramSolver::GUROBI, 0.43, 0.27, 0.3); // <--- tune if necessary
#else
selector.optimize(&hypothesis, LinearProgramSolver::SCIP);
selector.optimize(&hypothesis, LinearProgramSolver::SCIP, 0.43, 0.27, 0.3); // <--- tune if necessary
#endif

if (mesh->size_of_facets() == 0) {
std::cerr << "optimization failed: model has no face" << std::endl;
return EXIT_FAILURE;
}
// now we don't need the point cloud anymore, and it can be deleted
delete pset;
delete point_cloud;

// step 4: save result to file
if (MapIO::save(output_file, mesh))
if (MapIO::save(output_file, mesh)) {
std::cout << "reconstructed model saved to file: " << output_file << std::endl;
delete mesh;
return EXIT_SUCCESS;
}
else {
std::cerr << "failed saving reconstructed model to file: " << output_file << std::endl;
return EXIT_FAILURE;
}

return EXIT_SUCCESS;
}


30 changes: 15 additions & 15 deletions code/PolyFit/dlg/weight_panel_click.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,11 @@ WeightPanelClick::WeightPanelClick(QWidget *parent)
triangle_[1] = pos_coverage_;
triangle_[2] = pos_complexity_;

pos_ = pointFromWeights(pos_fitting_, pos_coverage_, pos_complexity_, Method::lambda_data_fitting, Method::lambda_model_coverage, Method::lambda_model_complexity);
pos_ = pointFromWeights(pos_fitting_, pos_coverage_, pos_complexity_, Method::weight_data_fitting, Method::weight_model_coverage, Method::weight_model_complexity);

fitting_ = truncate_digits(Method::lambda_data_fitting, 3);
coverage_ = truncate_digits(Method::lambda_model_coverage, 3);
complexity_ = truncate_digits(Method::lambda_model_complexity, 3);
fitting_ = truncate_digits(Method::weight_data_fitting, 3);
coverage_ = truncate_digits(Method::weight_model_coverage, 3);
complexity_ = truncate_digits(Method::weight_model_complexity, 3);

setMouseTracking(true);
}
Expand Down Expand Up @@ -160,13 +160,13 @@ void WeightPanelClick::computeWeight() {
float area_model_coverage = area_of_triangle(pos_complexity_, pos_fitting_, pos_);
float area_model_complexity = area_of_triangle(pos_fitting_, pos_coverage_, pos_);

Method::lambda_data_fitting = area_data_fitting / area_sum;
Method::lambda_model_coverage = area_model_coverage / area_sum;
Method::lambda_model_complexity = area_model_complexity / area_sum;
Method::weight_data_fitting = area_data_fitting / area_sum;
Method::weight_model_coverage = area_model_coverage / area_sum;
Method::weight_model_complexity = area_model_complexity / area_sum;

fitting_ = truncate_digits(Method::lambda_data_fitting, 3);
coverage_ = truncate_digits(Method::lambda_model_coverage, 3);
complexity_ = truncate_digits(Method::lambda_model_complexity, 3);
fitting_ = truncate_digits(Method::weight_data_fitting, 3);
coverage_ = truncate_digits(Method::weight_model_coverage, 3);
complexity_ = truncate_digits(Method::weight_model_complexity, 3);

emit weights_changed();

Expand All @@ -175,11 +175,11 @@ void WeightPanelClick::computeWeight() {


void WeightPanelClick::updateUI() {
float sum = Method::lambda_data_fitting + Method::lambda_model_coverage + Method::lambda_model_complexity;
fitting_ = truncate_digits(Method::lambda_data_fitting / sum, 3);
coverage_ = truncate_digits(Method::lambda_model_coverage / sum, 3);
complexity_ = truncate_digits(Method::lambda_model_complexity / sum, 3);
float sum = Method::weight_data_fitting + Method::weight_model_coverage + Method::weight_model_complexity;
fitting_ = truncate_digits(Method::weight_data_fitting / sum, 3);
coverage_ = truncate_digits(Method::weight_model_coverage / sum, 3);
complexity_ = truncate_digits(Method::weight_model_complexity / sum, 3);

pos_ = pointFromWeights(pos_fitting_, pos_coverage_, pos_complexity_, Method::lambda_data_fitting, Method::lambda_model_coverage, Method::lambda_model_complexity);
pos_ = pointFromWeights(pos_fitting_, pos_coverage_, pos_complexity_, Method::weight_data_fitting, Method::weight_model_coverage, Method::weight_model_complexity);
update();
}
12 changes: 6 additions & 6 deletions code/PolyFit/dlg/weight_panel_manual.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ WeightPanelManual::WeightPanelManual(QWidget *parent)


void WeightPanelManual::updateUI() {
float fitting = truncate_digits(Method::lambda_data_fitting, 3);
float coverage = truncate_digits(Method::lambda_model_coverage, 3);
float complexity = truncate_digits(Method::lambda_model_complexity, 3);
float fitting = truncate_digits(Method::weight_data_fitting, 3);
float coverage = truncate_digits(Method::weight_model_coverage, 3);
float complexity = truncate_digits(Method::weight_model_complexity, 3);

QString text_fitting = QString("%1").arg(fitting);
QString text_coverage = QString("%1").arg(coverage);
Expand All @@ -50,7 +50,7 @@ void WeightPanelManual::updateUI() {


void WeightPanelManual::updateWeights() {
Method::lambda_data_fitting = lineEditFitting->text().toFloat();
Method::lambda_model_coverage = lineEditCoverage->text().toFloat();
Method::lambda_model_complexity = lineEditComplexity->text().toFloat();
Method::weight_data_fitting = lineEditFitting->text().toFloat();
Method::weight_model_coverage = lineEditCoverage->text().toFloat();
Method::weight_model_complexity = lineEditComplexity->text().toFloat();
}
12 changes: 6 additions & 6 deletions code/PolyFit/main_window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -214,9 +214,9 @@ void MainWindow::createActions() {


void MainWindow::createRenderingPanel() {
default_fitting_ = truncate_digits(Method::lambda_data_fitting, 3);
default_coverage_ = truncate_digits(Method::lambda_model_coverage, 3);
default_complexity_ = truncate_digits(Method::lambda_model_complexity, 3);
default_fitting_ = truncate_digits(Method::weight_data_fitting, 3);
default_coverage_ = truncate_digits(Method::weight_model_coverage, 3);
default_complexity_ = truncate_digits(Method::weight_model_complexity, 3);

panelClick_ = new WeightPanelClick(this);
verticalLayoutWeights->addWidget(panelClick_);
Expand Down Expand Up @@ -253,9 +253,9 @@ void MainWindow::defaultRenderingForResult() {


void MainWindow::resetWeights() {
Method::lambda_data_fitting = default_fitting_;
Method::lambda_model_coverage = default_coverage_;
Method::lambda_model_complexity = default_complexity_;
Method::weight_data_fitting = default_fitting_;
Method::weight_model_coverage = default_coverage_;
Method::weight_model_complexity = default_complexity_;

panelClick_->updateUI();
panelManual_->updateUI();
Expand Down
7 changes: 6 additions & 1 deletion code/PolyFit/paint_canvas.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include "../renderer/point_set_render.h"
#include "../method/hypothesis_generator.h"
#include "../method/face_selection.h"
#include "../method/method_global.h"

#include "main_window.h"

Expand Down Expand Up @@ -604,7 +605,11 @@ void PaintCanvas::optimization() {
Map* mesh = Geom::duplicate(hypothesis_mesh_);

FaceSelection selector(point_set_, mesh);
selector.optimize(hypothesis_, main_window_->active_solver());
selector.optimize(hypothesis_,
main_window_->active_solver(),
Method::weight_data_fitting,
Method::weight_model_coverage,
Method::weight_model_complexity);

#if 0 // not stable!!!
{ // to stitch the coincident edges and related vertices
Expand Down
19 changes: 12 additions & 7 deletions code/method/face_selection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,12 @@ FaceSelection::FaceSelection(PointSet* pset, Map* model)
}


void FaceSelection::optimize(HypothesisGenerator* generator, LinearProgramSolver::SolverName solver_name) {
void FaceSelection::optimize(HypothesisGenerator* generator,
LinearProgramSolver::SolverName solver_name,
double data_fitting,
double model_coverage,
double model_complexity)
{
if (pset_ == nullptr || model_ == nullptr)
return;

Expand Down Expand Up @@ -105,13 +110,13 @@ void FaceSelection::optimize(HypothesisGenerator* generator, LinearProgramSolver
}
}

//double coeff_data_fitting = Method::lambda_data_fitting / total_points;
//double coeff_coverage = Method::lambda_model_coverage / model_->bbox().area();
//double coeff_complexity = Method::lambda_model_complexity / double(fans.size());
//double coeff_data_fitting = data_fitting / total_points;
//double coeff_coverage = model_coverage / model_->bbox().area();
//double coeff_complexity = model_complexity / double(fans.size());
// choose a better scale
double coeff_data_fitting = Method::lambda_data_fitting;
double coeff_coverage = total_points * Method::lambda_model_coverage / model_->bbox().area();
double coeff_complexity = total_points * Method::lambda_model_complexity / double(adjacency.size());
double coeff_data_fitting = data_fitting;
double coeff_coverage = total_points * model_coverage / model_->bbox().area();
double coeff_complexity = total_points * model_complexity / double(adjacency.size());

program_.clear();
LinearObjective* objective = program_.create_objective(LinearObjective::MINIMIZE);
Expand Down
7 changes: 6 additions & 1 deletion code/method/face_selection.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,12 @@ class METHOD_API FaceSelection
FaceSelection(PointSet* pset, Map* model);
~FaceSelection() {}

void optimize(HypothesisGenerator* generator, LinearProgramSolver::SolverName solver_name);
void optimize(HypothesisGenerator *generator,
LinearProgramSolver::SolverName solver_name, // solver name
double data_fitting, // weight for data fitting term
double model_coverage, // weight for model coverage term
double model_complexity // weight for model complexity term)
);

protected:
// NOTE: the adjacency is the one extracted after the face optimization step
Expand Down
6 changes: 3 additions & 3 deletions code/method/method_global.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@

namespace Method {

double lambda_data_fitting = 0.43;
double lambda_model_coverage = 0.27;
double lambda_model_complexity = 0.30;
double weight_data_fitting = 0.43;
double weight_model_coverage = 0.27;
double weight_model_complexity = 0.30;

double snap_sqr_distance_threshold = 1e-14;

Expand Down
6 changes: 3 additions & 3 deletions code/method/method_global.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@

namespace Method {

extern METHOD_API double lambda_data_fitting;
extern METHOD_API double lambda_model_coverage;
extern METHOD_API double lambda_model_complexity;
extern METHOD_API double weight_data_fitting;
extern METHOD_API double weight_model_coverage;
extern METHOD_API double weight_model_complexity;

extern METHOD_API double snap_sqr_distance_threshold;

Expand Down
10 changes: 1 addition & 9 deletions code/method/reconstruction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,6 @@ Map* reconstruct(
float model_complexity // weight for model complexity term
)
{
// initialize the logger (this is not optional)
Logger::initialize();

// set the parameters
Method::lambda_data_fitting = data_fitting;
Method::lambda_model_coverage = model_coverage;
Method::lambda_model_complexity = model_complexity;

// step 1: refine planes
const std::vector<VertexGroup::Ptr>& groups = point_cloud->groups();
if (groups.empty()) {
Expand All @@ -59,7 +51,7 @@ Map* reconstruct(

// step 3: face selection
FaceSelection selector(point_cloud, mesh);
selector.optimize(&hypothesis, solver);
selector.optimize(&hypothesis, solver, data_fitting, model_coverage, model_complexity);

if (mesh->size_of_facets() == 0) {
std::cerr << "optimization failed: result has no face" << std::endl;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,6 @@ def main():
# Initialize PolyFit
polyfit.initialize()

# Default parameters
polyfit.lambda_data_fitting = 0.43 # <--- tune this parameter if needed
polyfit.lambda_model_coverage = 0.27 # <--- tune this parameter if needed
polyfit.lambda_model_complexity = 0.3 # <--- tune this parameter if needed

input_file = "../../../data/toy_data.bvg" # <--- Update this path to your point cloud
output_file = "../../../data/toy_data-result.obj" # <--- Update this path to where your want to save the result

Expand Down Expand Up @@ -66,7 +61,11 @@ def main():
print("Optimization...")
# Create an instance of FaceSelection
selector = polyfit.FaceSelection(point_cloud, mesh)
selector.optimize(hypothesis) # optimization (face selection)
selector.optimize(hypothesis,
polyfit.SCIP, # solver name (GUROBI requires a license, free for research and eduction)
0.43, # Weight of data_fitting <--- tune if needed.
0.27, # Weight of model_coverage <--- tune if needed.
0.3) # Weight of model_complexity <--- tune if needed.

if mesh.size_of_facets() == 0:
print("Optimization failed: model has no face", file=sys.stderr)
Expand All @@ -83,4 +82,4 @@ def main():
sys.exit(0)

if __name__ == "__main__":
main()
main()
Loading

0 comments on commit 10b2008

Please sign in to comment.