Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/prusa3d/PrusaSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortamasmeszaros <meszaros.q@gmail.com>2019-12-19 18:10:34 +0300
committertamasmeszaros <meszaros.q@gmail.com>2019-12-19 18:10:34 +0300
commitd3925abb13aa6e43257eafa0638d94e39b41e3a5 (patch)
tree75fbd94942b21ee94b042e8af2ee9c91ff90ef9e /sandboxes
parent9363344a6fd7df457da0f5a68635f89b5c3d7f2c (diff)
Add some comments.
Diffstat (limited to 'sandboxes')
-rw-r--r--sandboxes/opencsg/Engine.hpp54
-rw-r--r--sandboxes/opencsg/main.cpp60
2 files changed, 87 insertions, 27 deletions
diff --git a/sandboxes/opencsg/Engine.hpp b/sandboxes/opencsg/Engine.hpp
index 5e7030523..2b58e9b75 100644
--- a/sandboxes/opencsg/Engine.hpp
+++ b/sandboxes/opencsg/Engine.hpp
@@ -17,33 +17,36 @@ class SLAPrint;
namespace GL {
+// Simple shorthands for smart pointers
template<class T> using shptr = std::shared_ptr<T>;
template<class T> using uqptr = std::unique_ptr<T>;
template<class T> using wkptr = std::weak_ptr<T>;
-template<class T, class A = std::allocator<T>>
-using vector = std::vector<T, A>;
+template<class T, class A = std::allocator<T>> using vector = std::vector<T, A>;
+// remove empty weak pointers from a vector
template<class L> void cleanup(vector<std::weak_ptr<L>> &listeners) {
auto it = std::remove_if(listeners.begin(), listeners.end(),
[](auto &l) { return !l.lock(); });
listeners.erase(it, listeners.end());
}
+// Call a class method on each element of a vector of objects (weak pointers)
+// of the same type.
template<class F, class L, class...Args>
void call(F &&f, vector<std::weak_ptr<L>> &listeners, Args&&... args) {
for (auto &l : listeners)
if (auto p = l.lock()) ((p.get())->*f)(std::forward<Args>(args)...);
}
+// A representation of a mouse input for the engine.
class MouseInput
{
public:
+ enum WheelAxis { waVertical, waHorizontal };
- enum WheelAxis {
- waVertical, waHorizontal
- };
-
+ // Interface to implement if an object wants to receive notifications
+ // about mouse events.
class Listener {
public:
virtual ~Listener();
@@ -99,6 +102,7 @@ public:
}
};
+// This is a stripped down version of Slic3r::IndexedVertexArray
class IndexedVertexArray {
public:
~IndexedVertexArray() { release_geometry(); }
@@ -164,8 +168,11 @@ public:
void shrink_to_fit();
};
+// Try to enable or disable multisampling.
bool enable_multisampling(bool e = true);
+// A primitive that can be used with OpenCSG rendering algorithms.
+// Does a similar job to GLVolume.
class Primitive : public OpenCSG::Primitive
{
IndexedVertexArray m_geom;
@@ -176,19 +183,21 @@ public:
Primitive() : OpenCSG::Primitive(OpenCSG::Intersection, 1) {}
- void render();
+ void render() override;
void translation(const Vec3d &offset) { m_trafo.set_offset(offset); }
void rotation(const Vec3d &rot) { m_trafo.set_rotation(rot); }
void scale(const Vec3d &scaleing) { m_trafo.set_scaling_factor(scaleing); }
void scale(double s) { scale({s, s, s}); }
- inline void load_mesh(const TriangleMesh &mesh) {
+ inline void load_mesh(const TriangleMesh &mesh)
+ {
m_geom.load_mesh(mesh);
m_geom.finalize_geometry();
}
};
+// A simple representation of a camera in a 3D scene
class Camera {
protected:
Vec2f m_rot = {0., 0.};
@@ -209,6 +218,7 @@ public:
void set_clip_z(double z) { m_clip_z = z; }
};
+// Reset a camera object
inline void reset(Camera &cam)
{
cam.set_rotation({0., 0.});
@@ -217,12 +227,15 @@ inline void reset(Camera &cam)
cam.set_clip_z(0.);
}
+// Specialization of a camera which shows in perspective projection
class PerspectiveCamera: public Camera {
public:
void set_screen(long width, long height) override;
};
+// A simple counter of FPS. Subscribed objects will receive updates of the
+// current fps.
class FpsCounter {
vector<std::function<void(double)>> m_listeners;
@@ -259,6 +272,7 @@ public:
double get_mesure_window_size() const { return m_window_size; }
};
+// Collection of the used OpenCSG library settings.
class CSGSettings {
public:
static const constexpr unsigned DEFAULT_CONVEXITY = 10;
@@ -286,12 +300,19 @@ public:
unsigned get_convexity() const { return m_convexity; }
void set_convexity(unsigned c) { m_convexity = c; }
};
-
+
+// The scene is a wrapper around SLAPrint which holds the data to be visualized.
class Scene
{
uqptr<SLAPrint> m_print;
public:
+ // Subscribers will be notified if the model is changed. This might be a
+ // display which will have to load the meshes and repaint itself when
+ // the scene data changes.
+ // eg. We load a new 3mf through the UI, this will notify the controller
+ // associated with the scene and all the displays that the controller is
+ // connected with.
class Listener {
public:
virtual ~Listener() = default;
@@ -316,6 +337,11 @@ private:
vector<wkptr<Listener>> m_listeners;
};
+// The basic Display. This is almost just an interface but will do all the
+// initialization and show the fps values. Overriding the render_scene is
+// needed to show the scene content. The specific method of displaying the
+// scene is up the the particular implementation (OpenCSG or other screen space
+// boolean algorithms)
class Display : public Scene::Listener
{
protected:
@@ -356,10 +382,13 @@ public:
FpsCounter &get_fps_counter() { return m_fps_counter; }
};
+// Special dispaly using OpenCSG for rendering the scene.
class CSGDisplay : public Display {
protected:
CSGSettings m_csgsettings;
+ // Cache the renderable primitives. These will be fetched when the scene
+ // is modified.
struct SceneCache {
vector<shptr<Primitive>> primitives;
vector<Primitive *> primitives_free;
@@ -375,6 +404,7 @@ protected:
public:
+ // Receive or apply the new settings.
const CSGSettings & get_csgsettings() const { return m_csgsettings; }
void apply_csgsettings(const CSGSettings &settings);
@@ -383,6 +413,11 @@ public:
void on_scene_updated(const Scene &scene) override;
};
+
+// The controller is a hub which dispatches mouse events to the connected
+// displays. It keeps track of the mouse wheel position, the states whether
+// the mouse is being held, dragged, etc... All the connected displays will
+// mirror the camera movement (if there is more than one display).
class Controller : public std::enable_shared_from_this<Controller>,
public MouseInput::Listener,
public Scene::Listener
@@ -404,6 +439,7 @@ class Controller : public std::enable_shared_from_this<Controller>,
public:
+ // Set the scene that will be controlled.
void set_scene(shptr<Scene> scene)
{
m_scene = scene;
diff --git a/sandboxes/opencsg/main.cpp b/sandboxes/opencsg/main.cpp
index 95e00b366..b609657c0 100644
--- a/sandboxes/opencsg/main.cpp
+++ b/sandboxes/opencsg/main.cpp
@@ -30,8 +30,11 @@
using namespace Slic3r::GL;
+// The opengl rendering facility. Here we implement the rendering objects.
class Canvas: public wxGLCanvas
{
+
+ // Tell the CSGDisplay how to swap buffers and set the gl context.
class OCSGRenderer: public Slic3r::GL::CSGDisplay {
Canvas *m_canvas;
shptr<wxGLContext> m_context;
@@ -62,8 +65,10 @@ class Canvas: public wxGLCanvas
~OCSGRenderer() override { m_scene_cache.clear(); }
};
+ // Create the OCSGDisplay for rendering with OpenCSG algorithms
shptr<OCSGRenderer> m_ocsgdisplay = std::make_shared<OCSGRenderer>(this);
+ // One display is active at a time, the OCSGRenderer by default.
shptr<Slic3r::GL::Display> m_display = m_ocsgdisplay;
public:
@@ -94,6 +99,7 @@ public:
shptr<Slic3r::GL::CSGDisplay> get_ocsg_display() const { return m_ocsgdisplay; }
};
+// Enumerate possible mouse events, we will record them.
enum EEvents { LCLK_U, RCLK_U, LCLK_D, RCLK_D, DDCLK, SCRL, MV };
struct Event
{
@@ -102,6 +108,8 @@ struct Event
Event(EEvents t, long x = 0, long y = 0) : type{t}, a{x}, b{y} {}
};
+// Create a special mouse input adapter, which can store (record) the received
+// mouse signals into a file and play back the stored events later.
class RecorderMouseInput: public MouseInput {
std::vector<Event> m_events;
bool m_recording = false, m_playing = false;
@@ -181,16 +189,20 @@ public:
}
};
+// The top level frame of the application.
class MyFrame: public wxFrame
{
+ // Instantiate the 3D engine.
shptr<Scene> m_scene; // Model
shptr<Canvas> m_canvas; // View
shptr<Controller> m_ctl; // Controller
-
+
+ // Add a status bar with progress indication.
shptr<Slic3r::GUI::ProgressStatusBar> m_stbar;
RecorderMouseInput m_mouse;
+ // When loading a Model from 3mf and preparing it, we use a separate thread.
class SLAJob: public Slic3r::GUI::Job {
MyFrame *m_parent;
std::unique_ptr<Slic3r::SLAPrint> m_print;
@@ -202,12 +214,15 @@ class MyFrame: public wxFrame
, m_parent{frame}
, m_fname{fname}
{}
-
+
+ // Runs in separate thread
void process() override;
const std::string & get_project_fname() const { return m_fname; }
protected:
+
+ // Runs in the UI thread.
void finalize() override
{
m_parent->m_scene->set_print(std::move(m_print));
@@ -218,16 +233,22 @@ class MyFrame: public wxFrame
uqptr<SLAJob> m_ui_job;
+ // To keep track of the running average of measured fps values.
double m_fps_avg = 0.;
public:
- MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size, const Slic3r::GL::CSGSettings &settings);
+ MyFrame(const wxString & title,
+ const wxPoint & pos,
+ const wxSize & size,
+ const Slic3r::GL::CSGSettings &settings);
+ // Grab a 3mf and load (hollow it out) within the UI job.
void load_model(const std::string &fname) {
m_ui_job = std::make_unique<SLAJob>(this, fname);
m_ui_job->start();
}
+ // Load a previously stored mouse event log and play it back.
void play_back_mouse(const std::string &events_fname)
{
std::fstream stream(events_fname, std::fstream::in);
@@ -249,11 +270,14 @@ public:
Canvas * canvas() { return m_canvas.get(); }
const Canvas * canvas() const { return m_canvas.get(); }
+ // Bind the canvas mouse events to a class implementing MouseInput interface
void bind_canvas_events(MouseInput &msinput);
double get_fps_average() const { return m_fps_avg; }
};
+// Possible OpenCSG configuration values. Will be used on the command line and
+// on the UI widgets.
static const std::vector<wxString> CSG_ALGS = {"Auto", "Goldfeather", "SCS"};
static const std::vector<wxString> CSG_DEPTH = {"Off", "OcclusionQuery", "On"};
static const std::vector<wxString> CSG_OPT = { "Default", "ForceOn", "On", "Off" };
@@ -482,9 +506,9 @@ MyFrame::MyFrame(const wxString &title, const wxPoint &pos, const wxSize &size,
});
csg_toggle->Bind(wxEVT_TOGGLEBUTTON, [this, csg_toggle](wxCommandEvent &){
- CSGSettings settings = m_canvas->get_ocsg_display()->get_csgsettings();
- settings.enable_csg(csg_toggle->GetValue());
- m_canvas->get_ocsg_display()->apply_csgsettings(settings);
+ CSGSettings stt = m_canvas->get_ocsg_display()->get_csgsettings();
+ stt.enable_csg(csg_toggle->GetValue());
+ m_canvas->get_ocsg_display()->apply_csgsettings(stt);
});
alg_select->Bind(wxEVT_COMBOBOX,
@@ -492,33 +516,33 @@ MyFrame::MyFrame(const wxString &title, const wxPoint &pos, const wxSize &size,
{
int sel = alg_select->GetSelection();
depth_select->Enable(sel > 0);
- CSGSettings settings = m_canvas->get_ocsg_display()->get_csgsettings();
- settings.set_algo(OpenCSG::Algorithm(sel));
- m_canvas->get_ocsg_display()->apply_csgsettings(settings);
+ CSGSettings stt = m_canvas->get_ocsg_display()->get_csgsettings();
+ stt.set_algo(OpenCSG::Algorithm(sel));
+ m_canvas->get_ocsg_display()->apply_csgsettings(stt);
});
depth_select->Bind(wxEVT_COMBOBOX, [this, depth_select](wxCommandEvent &) {
int sel = depth_select->GetSelection();
- CSGSettings settings = m_canvas->get_ocsg_display()->get_csgsettings();
- settings.set_depth_algo(OpenCSG::DepthComplexityAlgorithm(sel));
- m_canvas->get_ocsg_display()->apply_csgsettings(settings);
+ CSGSettings stt = m_canvas->get_ocsg_display()->get_csgsettings();
+ stt.set_depth_algo(OpenCSG::DepthComplexityAlgorithm(sel));
+ m_canvas->get_ocsg_display()->apply_csgsettings(stt);
});
optimization_select->Bind(wxEVT_COMBOBOX,
[this, optimization_select](wxCommandEvent &) {
int sel = optimization_select->GetSelection();
- CSGSettings settings = m_canvas->get_ocsg_display()->get_csgsettings();
- settings.set_optimization(OpenCSG::Optimization(sel));
- m_canvas->get_ocsg_display()->apply_csgsettings(settings);
+ CSGSettings stt = m_canvas->get_ocsg_display()->get_csgsettings();
+ stt.set_optimization(OpenCSG::Optimization(sel));
+ m_canvas->get_ocsg_display()->apply_csgsettings(stt);
});
convexity_spin->Bind(wxEVT_SPINCTRL, [this, convexity_spin](wxSpinEvent &) {
- CSGSettings settings = m_canvas->get_ocsg_display()->get_csgsettings();
+ CSGSettings stt = m_canvas->get_ocsg_display()->get_csgsettings();
int c = convexity_spin->GetValue();
if (c > 0) {
- settings.set_convexity(unsigned(c));
- m_canvas->get_ocsg_display()->apply_csgsettings(settings);
+ stt.set_convexity(unsigned(c));
+ m_canvas->get_ocsg_display()->apply_csgsettings(stt);
}
});