-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Move Application to dedicated source file
- Loading branch information
Showing
4 changed files
with
304 additions
and
282 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,249 @@ | ||
#include "application.h" | ||
|
||
#include "myview.h" | ||
#include "drawingPass.h" | ||
#include "drawingPasses/distanceField.h" | ||
|
||
#include <nanogui/window.h> | ||
#include <nanogui/colorpicker.h> | ||
#include <nanogui/combobox.h> | ||
#include <nanogui/label.h> | ||
#include <nanogui/layout.h> | ||
#include <nanogui/textbox.h> | ||
#include <nanogui/slider.h> | ||
#include <nanogui/textbox.h> | ||
|
||
#include <nanogui/opengl.h> // GLFW_KEY_ESCAPE and others | ||
|
||
using namespace nanogui; | ||
|
||
#define CONFIG_PONCA_FIT_INTERFACE(FitWidget,fit,name) \ | ||
{ \ | ||
FitWidget = new nanogui::Widget(window); \ | ||
FitWidget->set_layout(new GroupLayout()); \ | ||
} | ||
|
||
const int tex_width = 500; | ||
const int tex_height = 500; | ||
|
||
PoncaPlotApplication::PoncaPlotApplication() : Screen(Vector2i(1024, 768), "PoncaPlot"){ | ||
|
||
passDFWithKdTree = new DistanceFieldWithKdTree(); | ||
passPlaneFit = new PlaneFitField(); | ||
passSphereFit = new SphereFitField(); | ||
passOrientedSphereFit = new OrientedSphereFitField(); | ||
passUnorientedSphereFit = new UnorientedSphereFitField(); | ||
|
||
m_passes[0] = new FillPass( {255,255,255,255}); | ||
m_passes[1] = passDFWithKdTree; | ||
m_passes[2] = new DisplayPoint({255,0,0,255}); | ||
|
||
inc_ref(); | ||
auto *window = new Window(this, "Controls"); | ||
window->set_position(Vector2i(0, 0)); | ||
window->set_layout(new GroupLayout()); | ||
|
||
|
||
new nanogui::Label(window, "Select Fit Type", "sans-bold"); | ||
auto combo =new nanogui::ComboBox(window, | ||
{ "Distance Field", | ||
"Plane", | ||
"Sphere", | ||
"Oriented Sphere", | ||
"Unoriented Sphere"}); | ||
combo->set_callback([this](int id){ | ||
switch (id) { | ||
case 0: m_passes[1] = passDFWithKdTree; break; | ||
case 1: m_passes[1] = passPlaneFit; break; | ||
case 2: m_passes[1] = passSphereFit; break; | ||
case 3: m_passes[1] = passOrientedSphereFit; break; | ||
case 4: m_passes[1] = passUnorientedSphereFit; break; | ||
default: throw std::runtime_error("Unknown Field type!"); | ||
} | ||
buildPassInterface(id); | ||
renderPasses(); | ||
}); | ||
|
||
|
||
// create pass 1 interface | ||
{ | ||
pass1Widget = new nanogui::Widget(window); | ||
pass1Widget->set_layout(new GroupLayout()); | ||
new nanogui::Label(pass1Widget, "Background filling", "sans-bold"); | ||
new nanogui::Label(pass1Widget, "Color"); | ||
// dunno why, but sets colorpicker in range [0-255], but reads in [0-1] | ||
auto cp = new ColorPicker(pass1Widget, (dynamic_cast<FillPass *>(m_passes[0]))->m_fillColor); | ||
cp->set_final_callback([this](const Color &c) { | ||
dynamic_cast<FillPass *>(m_passes[0])->m_fillColor = 255.f * c; | ||
renderPasses(); | ||
}); | ||
} | ||
|
||
// create configurable passes interface | ||
{ | ||
distanceFieldWidget = new nanogui::Widget(window); | ||
distanceFieldWidget->set_layout(new GroupLayout()); | ||
new nanogui::Label(distanceFieldWidget, "Distance Field", "sans-bold"); | ||
new nanogui::Label(distanceFieldWidget, "no parameter available"); | ||
} | ||
|
||
{ | ||
genericFitWidget = new nanogui::Widget(window); | ||
genericFitWidget->set_layout(new GroupLayout()); | ||
new nanogui::Label(genericFitWidget, "Local Fitting", "sans-bold"); | ||
new nanogui::Label(genericFitWidget, "Scale"); | ||
auto slider = new Slider(genericFitWidget); | ||
slider->set_value(passPlaneFit->m_scale); // init with plane, but sync with current. | ||
slider->set_range({5,200}); | ||
slider->set_callback([&](float value) { | ||
passPlaneFit->m_scale = value; | ||
passSphereFit->m_scale = value; | ||
passOrientedSphereFit->m_scale = value; | ||
passUnorientedSphereFit->m_scale = value; | ||
renderPasses(); | ||
}); | ||
|
||
new Label(genericFitWidget, "MLS Iterations :", "sans-bold"); | ||
auto int_box = new IntBox<int>(genericFitWidget, passPlaneFit->m_iter); | ||
int_box->set_editable(true); | ||
int_box->set_spinnable(true); | ||
int_box->set_min_value(1); | ||
int_box->set_max_value(10); | ||
int_box->set_value_increment(1); | ||
int_box->set_callback([&](int value) { | ||
passPlaneFit->m_iter = value; | ||
passSphereFit->m_iter = value; | ||
passOrientedSphereFit->m_iter = value; | ||
passUnorientedSphereFit->m_iter = value; | ||
renderPasses(); | ||
}); | ||
} | ||
|
||
CONFIG_PONCA_FIT_INTERFACE(planeFitWidget,passPlaneFit,combo->items()[1]) | ||
CONFIG_PONCA_FIT_INTERFACE(sphereFitWidget,passSphereFit,combo->items()[2]) | ||
CONFIG_PONCA_FIT_INTERFACE(orientedSphereFitWidget,passOrientedSphereFit,combo->items()[3]) | ||
CONFIG_PONCA_FIT_INTERFACE(unorientedSphereFitWidget,passUnorientedSphereFit,combo->items()[4]) | ||
|
||
// create pass 3 interface | ||
{ | ||
pass3Widget = new nanogui::Widget(window); | ||
pass3Widget->set_layout(new GroupLayout()); | ||
new nanogui::Label(pass3Widget, "Points Display", "sans-bold"); | ||
new nanogui::Label(pass3Widget, "Color"); | ||
// dunno why, but sets colorpicker in range [0-255], but reads in [0-1] | ||
auto cp = new ColorPicker(pass3Widget, (dynamic_cast<DisplayPoint *>(m_passes[2]))->m_pointColor); | ||
cp->set_final_callback([this](const Color &c) { | ||
dynamic_cast<DisplayPoint *>(m_passes[2])->m_pointColor = 255.f * c; | ||
renderPasses(); | ||
}); | ||
auto slider = new Slider(pass3Widget); | ||
slider->set_value(dynamic_cast<DisplayPoint *>(m_passes[2])->m_halfSize); | ||
slider->set_range({1,20}); | ||
slider->set_callback([&](float value) { | ||
dynamic_cast<DisplayPoint *>(m_passes[2])->m_halfSize = int(value); | ||
m_image_view->setSelectionThreshold(value); | ||
renderPasses(); | ||
}); | ||
} | ||
|
||
window = new Window(this, "Image"); | ||
window->set_position(Vector2i(200, 0)); | ||
window->set_size(Vector2i(768,768)); | ||
window->set_layout(new GroupLayout(3)); | ||
|
||
m_textureBufferPing = new uint8_t [tex_width * tex_height * 4]; // use UInt8 RGBA textures | ||
m_textureBufferPong = new uint8_t [tex_width * tex_height * 4]; // use UInt8 RGBA textures | ||
m_texture = new Texture( | ||
Texture::PixelFormat::RGBA, | ||
Texture::ComponentFormat::UInt8, | ||
{tex_width,tex_height}, | ||
Texture::InterpolationMode::Trilinear, | ||
Texture::InterpolationMode::Nearest, | ||
Texture::WrapMode::ClampToEdge); | ||
|
||
m_image_view = new MyView(window); | ||
m_image_view->set_size(Vector2i(768, 768)); | ||
m_image_view->set_image(m_texture ); | ||
m_image_view->fitImage(); | ||
m_image_view->center(); | ||
m_image_view->setUpdateFunction([this](){ this->renderPasses();}); | ||
|
||
renderPasses(); // render twice to fill m_textureBufferPing and m_textureBufferPong | ||
renderPasses(); | ||
|
||
// call perform_layout | ||
buildPassInterface(0); | ||
} | ||
|
||
|
||
bool | ||
PoncaPlotApplication::keyboard_event(int key, int scancode, int action, int modifiers) { | ||
if (Screen::keyboard_event(key, scancode, action, modifiers)) | ||
return true; | ||
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) { | ||
set_visible(false); | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
void | ||
PoncaPlotApplication::draw(NVGcontext *ctx) { | ||
// if (m_needUpdate) | ||
Screen::draw(ctx); | ||
} | ||
|
||
void | ||
PoncaPlotApplication::draw_contents() { | ||
if (m_needUpdate){ | ||
m_texture->upload(m_computeInPing ? m_textureBufferPong : m_textureBufferPing); | ||
m_needUpdate = false; | ||
} | ||
Screen::draw_contents(); | ||
} | ||
|
||
void | ||
PoncaPlotApplication::buildPassInterface(int id){ | ||
distanceFieldWidget->set_visible(false); | ||
genericFitWidget->set_visible(false); | ||
planeFitWidget->set_visible(false); | ||
sphereFitWidget->set_visible(false); | ||
orientedSphereFitWidget->set_visible(false); | ||
unorientedSphereFitWidget->set_visible(false); | ||
switch (id) { | ||
case 0: | ||
distanceFieldWidget->set_visible(true); | ||
break; | ||
case 1: | ||
genericFitWidget->set_visible(true); | ||
planeFitWidget->set_visible(true); | ||
break; | ||
case 2: | ||
genericFitWidget->set_visible(true); | ||
sphereFitWidget->set_visible(true); | ||
break; | ||
case 3: | ||
genericFitWidget->set_visible(true); | ||
orientedSphereFitWidget->set_visible(true); | ||
break; | ||
case 4: | ||
genericFitWidget->set_visible(true); | ||
unorientedSphereFitWidget->set_visible(true); | ||
break; | ||
default: throw std::runtime_error("Unknown Field type!"); | ||
} | ||
perform_layout(); | ||
} | ||
|
||
void | ||
PoncaPlotApplication::renderPasses() { | ||
std::cout << "[Main] Update texture" << std::endl; | ||
const auto& points = m_image_view->getPointCollection(); | ||
for (auto* p : m_passes) { | ||
p->render(points, m_computeInPing ? m_textureBufferPing : m_textureBufferPong, tex_width, tex_height); | ||
} | ||
|
||
m_computeInPing = ! m_computeInPing; | ||
m_needUpdate = true; | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
#pragma once | ||
|
||
#include <nanogui/screen.h> | ||
|
||
// cannot forward declare aliases | ||
#include "drawingPasses/poncaFitField.h" | ||
|
||
// forward declarations | ||
class DrawingPass; | ||
class DistanceFieldWithKdTree; | ||
class MyView; | ||
|
||
namespace nanogui{ | ||
class Texture; | ||
} | ||
|
||
|
||
|
||
class PoncaPlotApplication : public nanogui::Screen { | ||
|
||
public: | ||
PoncaPlotApplication(); | ||
|
||
bool keyboard_event(int key, int scancode, int action, int modifiers) override; | ||
|
||
void draw(NVGcontext *ctx) override; | ||
|
||
void draw_contents() override; | ||
|
||
private: | ||
void buildPassInterface(int id); | ||
|
||
void renderPasses(); | ||
private: | ||
uint8_t* m_textureBufferPing {nullptr}, * m_textureBufferPong {nullptr}; | ||
bool m_computeInPing{true}; | ||
nanogui::Texture* m_texture {nullptr}; | ||
std::array<DrawingPass*,3> m_passes{nullptr, nullptr, nullptr}; | ||
bool m_needUpdate{false}; | ||
MyView *m_image_view {nullptr}; | ||
Widget* pass1Widget, *distanceFieldWidget, | ||
*genericFitWidget, //< parameters applicable to all fitting techniques | ||
*planeFitWidget, *sphereFitWidget, *orientedSphereFitWidget, *unorientedSphereFitWidget, | ||
*pass3Widget; | ||
DistanceFieldWithKdTree *passDFWithKdTree; | ||
PlaneFitField *passPlaneFit; | ||
SphereFitField *passSphereFit; | ||
OrientedSphereFitField *passOrientedSphereFit; | ||
UnorientedSphereFitField *passUnorientedSphereFit; | ||
}; |
Oops, something went wrong.