mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-11-02 20:51:23 -07:00 
			
		
		
		
	Add boilerplate for shader based csg
This commit is contained in:
		
							parent
							
								
									4f97a7122f
								
							
						
					
					
						commit
						93d0bbd7ef
					
				
					 7 changed files with 282 additions and 122 deletions
				
			
		| 
						 | 
				
			
			@ -2,7 +2,10 @@ cmake_minimum_required(VERSION 3.0)
 | 
			
		|||
 | 
			
		||||
project(OpenCSG-example)
 | 
			
		||||
 | 
			
		||||
add_executable(opencsg_example WIN32 main.cpp  Engine.hpp Engine.cpp 
 | 
			
		||||
add_executable(opencsg_example WIN32 
 | 
			
		||||
    main.cpp 
 | 
			
		||||
    Engine.hpp Engine.cpp 
 | 
			
		||||
    ShaderCSGDisplay.hpp ShaderCSGDisplay.cpp
 | 
			
		||||
    ${CMAKE_CURRENT_SOURCE_DIR}/../../src/slic3r/GUI/ProgressStatusBar.cpp
 | 
			
		||||
    ${CMAKE_CURRENT_SOURCE_DIR}/../../src/slic3r/GUI/I18N.hpp
 | 
			
		||||
    ${CMAKE_CURRENT_SOURCE_DIR}/../../src/slic3r/GUI/I18N.cpp)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,6 @@
 | 
			
		|||
#include "Engine.hpp"
 | 
			
		||||
#include <libslic3r/Utils.hpp>
 | 
			
		||||
#include <libslic3r/SLAPrint.hpp>
 | 
			
		||||
#include <libslic3r/MTUtils.hpp>
 | 
			
		||||
 | 
			
		||||
#include <GL/glew.h>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -66,22 +65,6 @@ void CSGDisplay::render_scene()
 | 
			
		|||
    glFlush();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class It,
 | 
			
		||||
         class Trafo,
 | 
			
		||||
         class GetPt,
 | 
			
		||||
         class V = typename std::iterator_traits<It>::value_type>
 | 
			
		||||
std::vector<V> transform_pts(
 | 
			
		||||
    It from, It to, Trafo &&tr, GetPt &&point)
 | 
			
		||||
{
 | 
			
		||||
    auto ret = reserve_vector<V>(to - from);
 | 
			
		||||
    for(auto it = from; it != to; ++it) {
 | 
			
		||||
        V v = *it;
 | 
			
		||||
        v.pos = tr * point(*it);
 | 
			
		||||
        ret.emplace_back(std::move(v));
 | 
			
		||||
    }
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Scene::set_print(uqptr<SLAPrint> &&print)
 | 
			
		||||
{   
 | 
			
		||||
    m_print = std::move(print);
 | 
			
		||||
| 
						 | 
				
			
			@ -287,7 +270,7 @@ void IndexedVertexArray::shrink_to_fit() {
 | 
			
		|||
    this->quad_indices.shrink_to_fit();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Primitive::render()
 | 
			
		||||
void Volume::render()
 | 
			
		||||
{
 | 
			
		||||
    glsafe(::glPushMatrix());
 | 
			
		||||
    glsafe(::glMultMatrixd(m_trafo.get_matrix().data()));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
#ifndef SLIC3R_OCSG_EXMP_ENGINE_HPP
 | 
			
		||||
#define SLIC3R_OCSG_EXMP_ENGINE_HPP_HPP
 | 
			
		||||
#define SLIC3R_OCSG_EXMP_ENGINE_HPP
 | 
			
		||||
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <memory>
 | 
			
		||||
| 
						 | 
				
			
			@ -25,7 +25,7 @@ template<class T> using wkptr = std::weak_ptr<T>;
 | 
			
		|||
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) {
 | 
			
		||||
template<class L> inline 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());
 | 
			
		||||
| 
						 | 
				
			
			@ -34,7 +34,7 @@ template<class L> void cleanup(vector<std::weak_ptr<L>> &listeners) {
 | 
			
		|||
// 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) {
 | 
			
		||||
inline 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)...);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -171,19 +171,30 @@ public:
 | 
			
		|||
// 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
 | 
			
		||||
template<class It,
 | 
			
		||||
         class Trafo,
 | 
			
		||||
         class GetPt,
 | 
			
		||||
         class V = typename std::iterator_traits<It>::value_type>
 | 
			
		||||
inline std::vector<V> transform_pts(
 | 
			
		||||
    It from, It to, Trafo &&tr, GetPt &&point)
 | 
			
		||||
{
 | 
			
		||||
    vector<V> ret;
 | 
			
		||||
    ret.reserve(to - from);
 | 
			
		||||
    for(auto it = from; it != to; ++it) {
 | 
			
		||||
        V v = *it;
 | 
			
		||||
        v.pos = tr * point(*it);
 | 
			
		||||
        ret.emplace_back(std::move(v));
 | 
			
		||||
    }
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class Volume {
 | 
			
		||||
    IndexedVertexArray m_geom;
 | 
			
		||||
    Geometry::Transformation m_trafo;
 | 
			
		||||
    
 | 
			
		||||
public:
 | 
			
		||||
    
 | 
			
		||||
    using OpenCSG::Primitive::Primitive;
 | 
			
		||||
    
 | 
			
		||||
    Primitive() : OpenCSG::Primitive(OpenCSG::Intersection, 1) {}
 | 
			
		||||
    
 | 
			
		||||
    void render() override;
 | 
			
		||||
    void render();
 | 
			
		||||
    
 | 
			
		||||
    void translation(const Vec3d &offset) { m_trafo.set_offset(offset); }
 | 
			
		||||
    void rotation(const Vec3d &rot) { m_trafo.set_rotation(rot); }
 | 
			
		||||
| 
						 | 
				
			
			@ -197,6 +208,18 @@ public:
 | 
			
		|||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// A primitive that can be used with OpenCSG rendering algorithms.
 | 
			
		||||
// Does a similar job to GLVolume.
 | 
			
		||||
class Primitive : public Volume, public OpenCSG::Primitive
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    using OpenCSG::Primitive::Primitive;
 | 
			
		||||
    
 | 
			
		||||
    Primitive() : OpenCSG::Primitive(OpenCSG::Intersection, 1) {}
 | 
			
		||||
    
 | 
			
		||||
    void render() override { Volume::render(); }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// A simple representation of a camera in a 3D scene
 | 
			
		||||
class Camera {
 | 
			
		||||
protected:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										81
									
								
								sandboxes/opencsg/ShaderCSGDisplay.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								sandboxes/opencsg/ShaderCSGDisplay.cpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,81 @@
 | 
			
		|||
#include "ShaderCSGDisplay.hpp"
 | 
			
		||||
#include "libslic3r/SLAPrint.hpp"
 | 
			
		||||
#include <GL/glew.h>
 | 
			
		||||
 | 
			
		||||
namespace Slic3r { namespace GL {
 | 
			
		||||
 | 
			
		||||
void ShaderCSGDisplay::add_mesh(const TriangleMesh &mesh)
 | 
			
		||||
{
 | 
			
		||||
    auto v = std::make_shared<CSGVolume>();
 | 
			
		||||
    v->load_mesh(mesh);
 | 
			
		||||
    m_volumes.emplace_back(v);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ShaderCSGDisplay::render_scene()
 | 
			
		||||
{
 | 
			
		||||
    GLfloat color[] = {1.f, 1.f, 0.f, 0.f};
 | 
			
		||||
    glColor4fv(color);
 | 
			
		||||
    glDepthFunc(GL_LESS);
 | 
			
		||||
    for (auto &v : m_volumes) v->render();
 | 
			
		||||
    glFlush();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ShaderCSGDisplay::on_scene_updated(const Scene &scene)
 | 
			
		||||
{
 | 
			
		||||
    // TriangleMesh mesh = print->objects().front()->hollowed_interior_mesh();
 | 
			
		||||
    // Look at CSGDisplay::on_scene_updated to see how its done there.
 | 
			
		||||
    
 | 
			
		||||
    const SLAPrint *print = scene.get_print();
 | 
			
		||||
    if (!print) return;
 | 
			
		||||
    
 | 
			
		||||
    m_volumes.clear();
 | 
			
		||||
    
 | 
			
		||||
    for (const SLAPrintObject *po : print->objects()) {
 | 
			
		||||
        const ModelObject *mo = po->model_object();
 | 
			
		||||
        TriangleMesh msh = mo->raw_mesh();
 | 
			
		||||
        
 | 
			
		||||
        sla::DrainHoles holedata = mo->sla_drain_holes;
 | 
			
		||||
        
 | 
			
		||||
        for (const ModelInstance *mi : mo->instances) {
 | 
			
		||||
            
 | 
			
		||||
            TriangleMesh mshinst = msh;
 | 
			
		||||
            auto interior = po->hollowed_interior_mesh();
 | 
			
		||||
            interior.transform(po->trafo().inverse());
 | 
			
		||||
            
 | 
			
		||||
            mshinst.merge(interior);
 | 
			
		||||
            mshinst.require_shared_vertices();
 | 
			
		||||
            
 | 
			
		||||
            mi->transform_mesh(&mshinst);
 | 
			
		||||
            
 | 
			
		||||
            auto bb = mshinst.bounding_box();
 | 
			
		||||
            auto center = bb.center().cast<float>();
 | 
			
		||||
            mshinst.translate(-center);
 | 
			
		||||
            
 | 
			
		||||
            mshinst.require_shared_vertices();
 | 
			
		||||
            add_mesh(mshinst);
 | 
			
		||||
            
 | 
			
		||||
            auto tr = Transform3f::Identity();
 | 
			
		||||
            tr.translate(-center);
 | 
			
		||||
            
 | 
			
		||||
            transform_pts(holedata.begin(), holedata.end(), tr,
 | 
			
		||||
                          [](const sla::DrainHole &dh) {
 | 
			
		||||
                              return dh.pos;
 | 
			
		||||
                          });
 | 
			
		||||
            
 | 
			
		||||
            transform_pts(holedata.begin(), holedata.end(), tr,
 | 
			
		||||
                          [](const sla::DrainHole &dh) {
 | 
			
		||||
                              return dh.normal;
 | 
			
		||||
                          });
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        for (const sla::DrainHole &holept : holedata) {
 | 
			
		||||
            TriangleMesh holemesh = sla::to_triangle_mesh(holept.to_mesh());
 | 
			
		||||
            holemesh.require_shared_vertices();
 | 
			
		||||
            add_mesh(holemesh);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    repaint();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}} // namespace Slic3r::GL
 | 
			
		||||
							
								
								
									
										26
									
								
								sandboxes/opencsg/ShaderCSGDisplay.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								sandboxes/opencsg/ShaderCSGDisplay.hpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,26 @@
 | 
			
		|||
#ifndef SHADERCSGDISPLAY_HPP
 | 
			
		||||
#define SHADERCSGDISPLAY_HPP
 | 
			
		||||
 | 
			
		||||
#include "Engine.hpp"
 | 
			
		||||
 | 
			
		||||
namespace Slic3r { namespace GL {
 | 
			
		||||
 | 
			
		||||
class CSGVolume: public Volume
 | 
			
		||||
{
 | 
			
		||||
    // Extend...    
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class ShaderCSGDisplay: public Display {
 | 
			
		||||
    vector<shptr<CSGVolume>> m_volumes;
 | 
			
		||||
    
 | 
			
		||||
    void add_mesh(const TriangleMesh &mesh);
 | 
			
		||||
public:
 | 
			
		||||
    
 | 
			
		||||
    void render_scene() override;
 | 
			
		||||
    
 | 
			
		||||
    void on_scene_updated(const Scene &scene) override;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
}}
 | 
			
		||||
 | 
			
		||||
#endif // SHADERCSGDISPLAY_HPP
 | 
			
		||||
| 
						 | 
				
			
			@ -3,6 +3,7 @@
 | 
			
		|||
#include <memory>
 | 
			
		||||
 | 
			
		||||
#include "Engine.hpp"
 | 
			
		||||
#include "ShaderCSGDisplay.hpp"
 | 
			
		||||
 | 
			
		||||
#include <GL/glew.h>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -30,41 +31,64 @@
 | 
			
		|||
 | 
			
		||||
using namespace Slic3r::GL;
 | 
			
		||||
 | 
			
		||||
class Renderer {
 | 
			
		||||
protected:
 | 
			
		||||
    wxGLCanvas *m_canvas;
 | 
			
		||||
    shptr<wxGLContext> m_context;
 | 
			
		||||
public:
 | 
			
		||||
    
 | 
			
		||||
    Renderer(wxGLCanvas *c): m_canvas{c} {
 | 
			
		||||
        auto ctx = new wxGLContext(m_canvas);
 | 
			
		||||
        if (!ctx || !ctx->IsOK()) {
 | 
			
		||||
            wxMessageBox("Could not create OpenGL context.", "Error",
 | 
			
		||||
                         wxOK | wxICON_ERROR);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        m_context.reset(ctx);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    wxGLContext * context() { return m_context.get(); }
 | 
			
		||||
    const wxGLContext * context() const { return m_context.get(); }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Tell the CSGDisplay how to swap buffers and set the gl context.
 | 
			
		||||
class OCSGRenderer: public Renderer, public Slic3r::GL::CSGDisplay {
 | 
			
		||||
public:
 | 
			
		||||
    
 | 
			
		||||
    OCSGRenderer(wxGLCanvas *c): Renderer{c} {}
 | 
			
		||||
    
 | 
			
		||||
    void set_active(long w, long h) override
 | 
			
		||||
    {
 | 
			
		||||
        m_canvas->SetCurrent(*m_context);
 | 
			
		||||
        Slic3r::GL::Display::set_active(w, h);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    void swap_buffers() override { m_canvas->SwapBuffers(); }
 | 
			
		||||
    
 | 
			
		||||
    ~OCSGRenderer() override { m_scene_cache.clear(); }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Tell the CSGDisplay how to swap buffers and set the gl context.
 | 
			
		||||
class ShaderCSGRenderer : public Renderer,
 | 
			
		||||
                          public Slic3r::GL::ShaderCSGDisplay
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    
 | 
			
		||||
    ShaderCSGRenderer(wxGLCanvas *c): Renderer{c} {}
 | 
			
		||||
    
 | 
			
		||||
    void set_active(long w, long h) override
 | 
			
		||||
    {
 | 
			
		||||
        m_canvas->SetCurrent(*m_context);
 | 
			
		||||
        Slic3r::GL::Display::set_active(w, h);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    void swap_buffers() override { m_canvas->SwapBuffers(); }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// 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;
 | 
			
		||||
    public:
 | 
			
		||||
        
 | 
			
		||||
        OCSGRenderer(Canvas *c): m_canvas{c} {
 | 
			
		||||
            auto ctx = new wxGLContext(m_canvas);
 | 
			
		||||
            if (!ctx || !ctx->IsOK()) {
 | 
			
		||||
                wxMessageBox("Could not create OpenGL context.", "Error",
 | 
			
		||||
                             wxOK | wxICON_ERROR);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            m_context.reset(ctx);
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        void set_active(long w, long h) override
 | 
			
		||||
        {
 | 
			
		||||
            m_canvas->SetCurrent(*m_context);
 | 
			
		||||
            Slic3r::GL::Display::set_active(w, h);
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        wxGLContext * context() { return m_context.get(); }
 | 
			
		||||
        const wxGLContext * context() const { return m_context.get(); }
 | 
			
		||||
        
 | 
			
		||||
        void swap_buffers() override { m_canvas->SwapBuffers(); }
 | 
			
		||||
        
 | 
			
		||||
        ~OCSGRenderer() override { m_scene_cache.clear(); }
 | 
			
		||||
    };
 | 
			
		||||
    
 | 
			
		||||
    // Create the OCSGDisplay for rendering with OpenCSG algorithms
 | 
			
		||||
    shptr<OCSGRenderer> m_ocsgdisplay = std::make_shared<OCSGRenderer>(this);
 | 
			
		||||
    
 | 
			
		||||
| 
						 | 
				
			
			@ -90,12 +114,14 @@ public:
 | 
			
		|||
            const wxSize ClientSize = GetClientSize();
 | 
			
		||||
            
 | 
			
		||||
            m_display->set_screen_size(ClientSize.x, ClientSize.y);
 | 
			
		||||
            m_display->repaint();
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    shptr<Slic3r::GL::Display> get_display() const { return m_display; }
 | 
			
		||||
 | 
			
		||||
    void set_display(shptr<Slic3r::GL::Display> d) { m_display = d; }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    shptr<Slic3r::GL::CSGDisplay> get_ocsg_display() const { return m_ocsgdisplay; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -172,6 +198,7 @@ public:
 | 
			
		|||
    void play()
 | 
			
		||||
    {
 | 
			
		||||
        m_playing = true;
 | 
			
		||||
        std::cout << "Mouse is playing back" << std::endl;
 | 
			
		||||
        for (const Event &evt : m_events) {
 | 
			
		||||
            switch (evt.type) {
 | 
			
		||||
            case LCLK_U: MouseInput::left_click_up(); break;
 | 
			
		||||
| 
						 | 
				
			
			@ -233,6 +260,7 @@ class MyFrame: public wxFrame
 | 
			
		|||
            m_parent->m_scene->set_print(std::move(m_print));
 | 
			
		||||
            m_parent->m_stbar->set_status_text(
 | 
			
		||||
                        wxString::Format("Model %s loaded.", m_fname));
 | 
			
		||||
            std::cout << "Model loaded" << std::endl;
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
    
 | 
			
		||||
| 
						 | 
				
			
			@ -247,7 +275,7 @@ public:
 | 
			
		|||
    MyFrame(const wxString &               title,
 | 
			
		||||
            const wxPoint &                pos,
 | 
			
		||||
            const wxSize &                 size,
 | 
			
		||||
            const Slic3r::GL::CSGSettings &settings);
 | 
			
		||||
            const wxCmdLineParser &settings);
 | 
			
		||||
    
 | 
			
		||||
    // Grab a 3mf and load (hollow it out) within the UI job.
 | 
			
		||||
    void load_model(const std::string &fname) {
 | 
			
		||||
| 
						 | 
				
			
			@ -264,6 +292,9 @@ public:
 | 
			
		|||
            std::string model_name;
 | 
			
		||||
            std::getline(stream, model_name);
 | 
			
		||||
            load_model(model_name);
 | 
			
		||||
            while (!m_ui_job->is_finalized()) {
 | 
			
		||||
                wxYield();
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            int w, h;
 | 
			
		||||
            stream >> w >> h;
 | 
			
		||||
| 
						 | 
				
			
			@ -286,7 +317,7 @@ public:
 | 
			
		|||
 | 
			
		||||
// 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_ALGS  = {"Auto", "Goldfeather", "SCS", "EnricoShader"};
 | 
			
		||||
static const std::vector<wxString> CSG_DEPTH = {"Off", "OcclusionQuery", "On"};
 | 
			
		||||
static const std::vector<wxString> CSG_OPT   = { "Default", "ForceOn", "On", "Off" };
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -309,41 +340,8 @@ public:
 | 
			
		|||
        wxString fname;
 | 
			
		||||
        bool is_play = parser.Found("play", &fname);
 | 
			
		||||
        
 | 
			
		||||
        wxString alg;
 | 
			
		||||
        parser.Found("algorithm", &alg);
 | 
			
		||||
        
 | 
			
		||||
        wxString depth;
 | 
			
		||||
        parser.Found("depth", &depth);
 | 
			
		||||
        
 | 
			
		||||
        wxString opt;
 | 
			
		||||
        parser.Found("optimization", &opt);
 | 
			
		||||
        
 | 
			
		||||
        long convexity = 1;
 | 
			
		||||
        parser.Found("convexity", &convexity);
 | 
			
		||||
        
 | 
			
		||||
        bool csg_off = parser.Found("disable-csg");
 | 
			
		||||
        
 | 
			
		||||
        auto get_idx = [](const wxString &a, const std::vector<wxString> &v) {
 | 
			
		||||
            auto it = std::find(v.begin(), v.end(), a.ToStdString());
 | 
			
		||||
            return it - v.begin();
 | 
			
		||||
        };
 | 
			
		||||
        
 | 
			
		||||
        Slic3r::GL::CSGSettings settings;
 | 
			
		||||
        
 | 
			
		||||
        if (auto a = get_idx(alg, CSG_ALGS) < OpenCSG::AlgorithmUnused) 
 | 
			
		||||
            settings.set_algo(OpenCSG::Algorithm(a));
 | 
			
		||||
        
 | 
			
		||||
        if (auto a = get_idx(depth, CSG_DEPTH) < OpenCSG::DepthComplexityAlgorithmUnused) 
 | 
			
		||||
            settings.set_depth_algo(OpenCSG::DepthComplexityAlgorithm(a));
 | 
			
		||||
        
 | 
			
		||||
        if (auto a = get_idx(opt, CSG_OPT) < OpenCSG::OptimizationUnused) 
 | 
			
		||||
            settings.set_optimization(OpenCSG::Optimization(a));
 | 
			
		||||
        
 | 
			
		||||
        settings.set_convexity(unsigned(convexity));
 | 
			
		||||
        settings.enable_csg(!csg_off);
 | 
			
		||||
        
 | 
			
		||||
        m_frame = new MyFrame("PrusaSlicer OpenCSG Demo", wxDefaultPosition, wxSize(1024, 768), settings);
 | 
			
		||||
        
 | 
			
		||||
        m_frame = new MyFrame("PrusaSlicer OpenCSG Demo", wxDefaultPosition, wxSize(1024, 768), parser);
 | 
			
		||||
 | 
			
		||||
        if (is_play) {
 | 
			
		||||
            m_frame->Show( true );
 | 
			
		||||
            m_frame->play_back_mouse(fname.ToStdString());
 | 
			
		||||
| 
						 | 
				
			
			@ -361,7 +359,7 @@ public:
 | 
			
		|||
wxIMPLEMENT_APP(App);
 | 
			
		||||
 | 
			
		||||
MyFrame::MyFrame(const wxString &title, const wxPoint &pos, const wxSize &size, 
 | 
			
		||||
                 const Slic3r::GL::CSGSettings &settings):
 | 
			
		||||
                 const wxCmdLineParser &parser):
 | 
			
		||||
    wxFrame(nullptr, wxID_ANY, title, pos, size)
 | 
			
		||||
{
 | 
			
		||||
    wxMenu *menuFile = new wxMenu;
 | 
			
		||||
| 
						 | 
				
			
			@ -396,9 +394,40 @@ MyFrame::MyFrame(const wxString &title, const wxPoint &pos, const wxSize &size,
 | 
			
		|||
                                        wxDefaultPosition, wxDefaultSize,
 | 
			
		||||
                                        wxWANTS_CHARS | wxFULL_REPAINT_ON_RESIZE);
 | 
			
		||||
    
 | 
			
		||||
    m_canvas->get_ocsg_display()->apply_csgsettings(settings);
 | 
			
		||||
    wxString alg;
 | 
			
		||||
    parser.Found("algorithm", &alg);
 | 
			
		||||
    
 | 
			
		||||
    m_ctl->add_display(m_canvas->get_display());
 | 
			
		||||
    wxString depth;
 | 
			
		||||
    parser.Found("depth", &depth);
 | 
			
		||||
    
 | 
			
		||||
    wxString opt;
 | 
			
		||||
    parser.Found("optimization", &opt);
 | 
			
		||||
    
 | 
			
		||||
    long convexity = 1;
 | 
			
		||||
    parser.Found("convexity", &convexity);
 | 
			
		||||
    
 | 
			
		||||
    bool csg_off = parser.Found("disable-csg");
 | 
			
		||||
    
 | 
			
		||||
    auto get_idx = [](const wxString &a, const std::vector<wxString> &v) {
 | 
			
		||||
        auto it = std::find(v.begin(), v.end(), a.ToStdString());
 | 
			
		||||
        return it - v.begin();
 | 
			
		||||
    };
 | 
			
		||||
    
 | 
			
		||||
    Slic3r::GL::CSGSettings settings;
 | 
			
		||||
    
 | 
			
		||||
    if (auto a = get_idx(alg, CSG_ALGS) < OpenCSG::AlgorithmUnused) 
 | 
			
		||||
            settings.set_algo(OpenCSG::Algorithm(a));
 | 
			
		||||
    
 | 
			
		||||
    if (auto a = get_idx(depth, CSG_DEPTH) < OpenCSG::DepthComplexityAlgorithmUnused) 
 | 
			
		||||
            settings.set_depth_algo(OpenCSG::DepthComplexityAlgorithm(a));
 | 
			
		||||
    
 | 
			
		||||
    if (auto a = get_idx(opt, CSG_OPT) < OpenCSG::OptimizationUnused) 
 | 
			
		||||
            settings.set_optimization(OpenCSG::Optimization(a));
 | 
			
		||||
    
 | 
			
		||||
    settings.set_convexity(unsigned(convexity));
 | 
			
		||||
    settings.enable_csg(!csg_off);
 | 
			
		||||
    
 | 
			
		||||
    m_canvas->get_ocsg_display()->apply_csgsettings(settings);
 | 
			
		||||
 | 
			
		||||
    wxPanel *control_panel = new wxPanel(this);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -459,10 +488,6 @@ MyFrame::MyFrame(const wxString &title, const wxPoint &pos, const wxSize &size,
 | 
			
		|||
    
 | 
			
		||||
    auto fpstext = new wxStaticText(control_panel, wxID_ANY, "");
 | 
			
		||||
    console_sizer->Add(fpstext, 0, wxALL, 5);
 | 
			
		||||
    m_canvas->get_ocsg_display()->get_fps_counter().add_listener([this, fpstext](double fps) {
 | 
			
		||||
        fpstext->SetLabel(wxString::Format("fps: %.2f", fps) );
 | 
			
		||||
        m_fps_avg = 0.9 * m_fps_avg + 0.1 * fps;
 | 
			
		||||
    });
 | 
			
		||||
    
 | 
			
		||||
    m_record_btn = new wxToggleButton(control_panel, wxID_ANY, "Record");
 | 
			
		||||
    console_sizer->Add(m_record_btn, 0, wxALL | wxEXPAND, 5);
 | 
			
		||||
| 
						 | 
				
			
			@ -477,12 +502,28 @@ MyFrame::MyFrame(const wxString &title, const wxPoint &pos, const wxSize &size,
 | 
			
		|||
    sizer->Add(control_panel, 0, wxEXPAND);
 | 
			
		||||
    SetSizer(sizer);
 | 
			
		||||
    
 | 
			
		||||
    if (settings.get_algo() > 0) depth_select->Enable(true);
 | 
			
		||||
    alg_select->SetSelection(settings.get_algo());
 | 
			
		||||
    depth_select->SetSelection(settings.get_depth_algo());
 | 
			
		||||
    optimization_select->SetSelection(settings.get_optimization());
 | 
			
		||||
    convexity_spin->SetValue(int(settings.get_convexity()));
 | 
			
		||||
    csg_toggle->SetValue(settings.is_enabled());
 | 
			
		||||
    if (alg != "EnricoShader") {
 | 
			
		||||
        if (settings.get_algo() > 0) depth_select->Enable(true);
 | 
			
		||||
        alg_select->SetSelection(settings.get_algo());
 | 
			
		||||
        depth_select->SetSelection(settings.get_depth_algo());
 | 
			
		||||
        optimization_select->SetSelection(settings.get_optimization());
 | 
			
		||||
        convexity_spin->SetValue(int(settings.get_convexity()));
 | 
			
		||||
        csg_toggle->SetValue(settings.is_enabled());
 | 
			
		||||
    } else {
 | 
			
		||||
        alg_select->SetSelection(int(get_idx("EnricoShader", CSG_ALGS)));
 | 
			
		||||
        depth_select->Disable();
 | 
			
		||||
        optimization_select->Disable();
 | 
			
		||||
        convexity_spin->Disable();
 | 
			
		||||
        csg_toggle->Disable();
 | 
			
		||||
        auto renderer = std::make_shared<ShaderCSGRenderer>(canvas());
 | 
			
		||||
        canvas()->set_display(renderer);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    m_ctl->add_display(m_canvas->get_display());
 | 
			
		||||
    m_canvas->get_display()->get_fps_counter().add_listener([this, fpstext](double fps) {
 | 
			
		||||
        fpstext->SetLabel(wxString::Format("fps: %.2f", fps) );
 | 
			
		||||
        m_fps_avg = 0.9 * m_fps_avg + 0.1 * fps;
 | 
			
		||||
    });
 | 
			
		||||
    
 | 
			
		||||
    Bind(wxEVT_CLOSE_WINDOW, [this](wxCloseEvent &evt){
 | 
			
		||||
        if (m_canvas) RemoveChild(m_canvas.get());
 | 
			
		||||
| 
						 | 
				
			
			@ -504,6 +545,16 @@ MyFrame::MyFrame(const wxString &title, const wxPoint &pos, const wxSize &size,
 | 
			
		|||
        const wxSize ClientSize = GetClientSize();
 | 
			
		||||
        m_canvas->get_display()->set_active(ClientSize.x, ClientSize.y);
 | 
			
		||||
        enable_multisampling(ms_toggle->GetValue());
 | 
			
		||||
        
 | 
			
		||||
        // Do the repaint continuously
 | 
			
		||||
        m_canvas->Bind(wxEVT_IDLE, [this](wxIdleEvent &evt) {
 | 
			
		||||
            if (IsShown() && m_canvas->IsShown())
 | 
			
		||||
                m_canvas->get_display()->repaint();
 | 
			
		||||
            
 | 
			
		||||
            evt.RequestMore();
 | 
			
		||||
        });
 | 
			
		||||
        
 | 
			
		||||
        bind_canvas_events(m_mouse);
 | 
			
		||||
    });
 | 
			
		||||
    
 | 
			
		||||
    Bind(wxEVT_SLIDER, [this, slider](wxCommandEvent &) {
 | 
			
		||||
| 
						 | 
				
			
			@ -585,14 +636,6 @@ MyFrame::MyFrame(const wxString &title, const wxPoint &pos, const wxSize &size,
 | 
			
		|||
            }
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
    
 | 
			
		||||
    // Do the repaint continuously
 | 
			
		||||
    m_canvas->Bind(wxEVT_IDLE, [this](wxIdleEvent &evt) {
 | 
			
		||||
        if (m_canvas->IsShown()) m_canvas->get_display()->repaint();
 | 
			
		||||
        evt.RequestMore();
 | 
			
		||||
    });
 | 
			
		||||
    
 | 
			
		||||
    bind_canvas_events(m_mouse);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MyFrame::bind_canvas_events(MouseInput &ms)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue