From 4904359399e8aa69e4a3b975c9a335da6d69b3d4 Mon Sep 17 00:00:00 2001
From: bubnikv <bubnikv@gmail.com>
Date: Mon, 8 Apr 2019 18:09:31 +0200
Subject: [PATCH] Finished SLA print / material correction visualization.

---
 src/libslic3r/SLAPrint.cpp    |  17 +----
 src/libslic3r/SLAPrint.hpp    |   4 +-
 src/slic3r/GUI/3DScene.cpp    |  18 +++---
 src/slic3r/GUI/3DScene.hpp    |   2 +
 src/slic3r/GUI/GLCanvas3D.cpp | 116 ++++++++++------------------------
 5 files changed, 46 insertions(+), 111 deletions(-)

diff --git a/src/libslic3r/SLAPrint.cpp b/src/libslic3r/SLAPrint.cpp
index 24b571544..1cbb91fa7 100644
--- a/src/libslic3r/SLAPrint.cpp
+++ b/src/libslic3r/SLAPrint.cpp
@@ -342,7 +342,7 @@ SLAPrint::ApplyStatus SLAPrint::apply(const Model &model, const DynamicPrintConf
             bool sla_trafo_differs  =
                 model_object.instances.empty() != model_object_new.instances.empty() ||
                 (! model_object.instances.empty() &&
-                  (! sla_trafo(*this, model_object_new).isApprox(sla_trafo(*this, model_object_new)) ||
+                  (! sla_trafo(*this, model_object).isApprox(sla_trafo(*this, model_object_new)) ||
                     model_object.instances.front()->is_left_handed() != model_object_new.instances.front()->is_left_handed()));
             if (model_parts_differ || sla_trafo_differs) {
                 // The very first step (the slicing step) is invalidated. One may freely remove all associated PrintObjects.
@@ -368,21 +368,6 @@ SLAPrint::ApplyStatus SLAPrint::apply(const Model &model, const DynamicPrintConf
                         }
                     }
                 }
-                /*if (model_object.sla_support_points != model_object_new.sla_support_points) {
-                    model_object.sla_support_points = model_object_new.sla_support_points;
-                    if (it_print_object_status != print_object_status.end())
-                        update_apply_status(it_print_object_status->print_object->invalidate_step(slaposSupportPoints));
-                }
-                if (model_object.sla_points_status != model_object_new.sla_points_status) {
-                    // Change of this status should invalidate support points. The points themselves are not enough, there are none
-                    // in case that nothing was generated OR that points were autogenerated already and not copied to the front-end.
-                    // These cases can only be differentiated by checking the status change. However, changing from 'Generating' should NOT
-                    // invalidate - that would keep stopping the background processing without a reason.
-                    if (model_object.sla_points_status != sla::PointsStatus::Generating)
-                        if (it_print_object_status != print_object_status.end())
-                            update_apply_status(it_print_object_status->print_object->invalidate_step(slaposSupportPoints));
-                    model_object.sla_points_status = model_object_new.sla_points_status;
-                }*/
 
                 bool old_user_modified = model_object.sla_points_status == sla::PointsStatus::UserModified;
                 bool new_user_modified = model_object_new.sla_points_status == sla::PointsStatus::UserModified;
diff --git a/src/libslic3r/SLAPrint.hpp b/src/libslic3r/SLAPrint.hpp
index 69e7e23dc..f43c3bf7a 100644
--- a/src/libslic3r/SLAPrint.hpp
+++ b/src/libslic3r/SLAPrint.hpp
@@ -398,9 +398,9 @@ public:
     const SLAPrintObjectConfig& default_object_config() const { return m_default_object_config; }
 
     // Extracted value from the configuration objects
-    Vec3d relative_correction() const;
+    Vec3d                       relative_correction() const;
 
-	std::string         output_filename() const override;
+	std::string                 output_filename() const override;
 
     const SLAPrintStatistics&      print_statistics() const { return m_print_statistics; }
 
diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp
index 66d173fc5..6d23d1aa4 100644
--- a/src/slic3r/GUI/3DScene.cpp
+++ b/src/slic3r/GUI/3DScene.cpp
@@ -227,6 +227,12 @@ const float GLVolume::HOVER_COLOR[4] = { 0.4f, 0.9f, 0.1f, 1.0f };
 const float GLVolume::OUTSIDE_COLOR[4] = { 0.0f, 0.38f, 0.8f, 1.0f };
 const float GLVolume::SELECTED_OUTSIDE_COLOR[4] = { 0.19f, 0.58f, 1.0f, 1.0f };
 const float GLVolume::DISABLED_COLOR[4] = { 0.25f, 0.25f, 0.25f, 1.0f };
+const float GLVolume::MODEL_COLOR[4][4] = {
+    { 1.0f, 1.0f, 0.0f, 1.f },
+    { 1.0f, 0.5f, 0.5f, 1.f },
+    { 0.5f, 1.0f, 0.5f, 1.f },
+    { 0.5f, 0.5f, 1.0f, 1.f }
+};
 const float GLVolume::SLA_SUPPORT_COLOR[4] = { 0.75f, 0.75f, 0.75f, 1.0f };
 const float GLVolume::SLA_PAD_COLOR[4] = { 0.0f, 0.2f, 0.0f, 1.0f };
 
@@ -568,19 +574,12 @@ int GLVolumeCollection::load_object_volume(
     const std::string              &color_by,
     bool                            use_VBOs)
 {
-    static float colors[4][4] = {
-        { 1.0f, 1.0f, 0.0f, 1.f }, 
-        { 1.0f, 0.5f, 0.5f, 1.f },
-        { 0.5f, 1.0f, 0.5f, 1.f }, 
-        { 0.5f, 0.5f, 1.0f, 1.f }
-    };
-
     const ModelVolume   *model_volume = model_object->volumes[volume_idx];
     const int            extruder_id  = model_volume->extruder_id();
     const ModelInstance *instance     = model_object->instances[instance_idx];
     const TriangleMesh& mesh = model_volume->mesh;
     float color[4];
-    memcpy(color, colors[((color_by == "volume") ? volume_idx : obj_idx) % 4], sizeof(float) * 3);
+    memcpy(color, GLVolume::MODEL_COLOR[((color_by == "volume") ? volume_idx : obj_idx) % 4], sizeof(float) * 3);
 /*    if (model_volume->is_support_blocker()) {
         color[0] = 1.0f;
         color[1] = 0.2f;
@@ -640,8 +639,7 @@ void GLVolumeCollection::load_object_auxiliary(
 	// Convex hull is required for out of print bed detection.
 	TriangleMesh convex_hull = mesh.convex_hull_3d();
     for (const std::pair<size_t, size_t> &instance_idx : instances) {
-        const ModelInstance            &model_instance = *print_object->model_object()->instances[instance_idx.first];
-        const SLAPrintObject::Instance &print_instance = print_object->instances()[instance_idx.second];
+        const ModelInstance &model_instance = *print_object->model_object()->instances[instance_idx.first];
         this->volumes.emplace_back(new GLVolume((milestone == slaposBasePool) ? GLVolume::SLA_PAD_COLOR : GLVolume::SLA_SUPPORT_COLOR));
         GLVolume &v = *this->volumes.back();
         if (use_VBOs)
diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp
index 0b32707c9..ce7bf8e97 100644
--- a/src/slic3r/GUI/3DScene.hpp
+++ b/src/slic3r/GUI/3DScene.hpp
@@ -116,6 +116,7 @@ public:
 
     void load_mesh_flat_shading(const TriangleMesh &mesh);
     void load_mesh_full_shading(const TriangleMesh &mesh);
+	void load_mesh(const TriangleMesh &mesh, bool use_VBOs) { use_VBOs ? this->load_mesh_full_shading(mesh) : this->load_mesh_flat_shading(mesh); }
 
     inline bool has_VBOs() const { return vertices_and_normals_interleaved_VBO_id != 0; }
 
@@ -228,6 +229,7 @@ public:
     static const float OUTSIDE_COLOR[4];
     static const float SELECTED_OUTSIDE_COLOR[4];
     static const float DISABLED_COLOR[4];
+    static const float MODEL_COLOR[4][4];
     static const float SLA_SUPPORT_COLOR[4];
     static const float SLA_PAD_COLOR[4];
 
diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp
index 3f52a0b9f..b8f724320 100644
--- a/src/slic3r/GUI/GLCanvas3D.cpp
+++ b/src/slic3r/GUI/GLCanvas3D.cpp
@@ -1893,6 +1893,9 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
             size_t idx = 0;
             const SLAPrint *sla_print = this->sla_print();
 			std::vector<double> shift_zs(m_model->objects.size(), 0);
+            double relative_correction_z = sla_print->relative_correction().z();
+            if (relative_correction_z <= EPSILON)
+                relative_correction_z = 1.;
 			for (const SLAPrintObject *print_object : sla_print->objects()) {
                 SLASupportState   &state        = sla_support_state[idx ++];
                 const ModelObject *model_object = print_object->model_object();
@@ -1906,7 +1909,7 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
                 assert(it != sla_print->model().objects.end());
 				object_idx = it - sla_print->model().objects.begin();
 				// Cache the Z offset to be applied to all volumes with this object_idx.
-				shift_zs[object_idx] = print_object->get_current_elevation();
+				shift_zs[object_idx] = print_object->get_current_elevation() / relative_correction_z;
                 // Collect indices of this print_object's instances, for which the SLA support meshes are to be added to the scene.
                 // pairs of <instance_idx, print_instance_idx>
 				std::vector<std::pair<size_t, size_t>> instances[std::tuple_size<SLASteps>::value];
@@ -5038,97 +5041,44 @@ void GLCanvas3D::_load_shells_sla()
         // nothing to render, return
         return;
 
+    auto add_volume = [this](const SLAPrintObject &object, const SLAPrintObject::Instance& instance, 
+                             const TriangleMesh &mesh, const float color[4], bool outside_printer_detection_enabled) {
+        m_volumes.volumes.emplace_back(new GLVolume(color));
+        GLVolume& v = *m_volumes.volumes.back();
+        v.indexed_vertex_array.load_mesh(mesh, m_use_VBOs);
+		v.shader_outside_printer_detection_enabled = outside_printer_detection_enabled;
+        v.composite_id.volume_id = -1;
+        v.set_instance_offset(unscale(instance.shift(0), instance.shift(1), 0));
+        v.set_instance_rotation(Vec3d(0.0, 0.0, (double)instance.rotation));
+        v.set_instance_mirror(X, object.is_left_handed() ? -1. : 1.);
+    };
+
     // adds objects' volumes 
-    int obj_idx = 0;
     for (const SLAPrintObject* obj : print->objects())
-    {
-        if (!obj->is_step_done(slaposSliceSupports))
-            continue;
-
-        unsigned int initial_volumes_count = (unsigned int)m_volumes.volumes.size();
-
-        // selects only instances which were sliced
-        const ModelObject* model_obj = obj->model_object();
-        const std::vector<SLAPrintObject::Instance>& sla_instances = obj->instances();
-        std::vector<int> instances_model_idxs(sla_instances.size());
-        for (int i = 0; i < (int)sla_instances.size(); ++i)
-        {
-            instances_model_idxs[i] = (int)sla_instances[i].instance_id.id;
-        }
-
-        std::vector<int> sliced_instance_idxs;
-        for (int i = 0; i < (int)model_obj->instances.size(); ++i)
-        {
-            if (std::find(instances_model_idxs.begin(), instances_model_idxs.end(), (int)model_obj->instances[i]->id().id) != instances_model_idxs.end())
-                sliced_instance_idxs.push_back(i);
-        }
-
-        m_volumes.load_object(model_obj, obj_idx, sliced_instance_idxs, "object", m_use_VBOs && m_initialized);
-
-        for (const SLAPrintObject::Instance& instance : sla_instances)
-        {
-            Vec3d offset = unscale(instance.shift(0), instance.shift(1), 0);
-            Vec3d rotation(0.0, 0.0, (double)instance.rotation);
-
-            unsigned int partial_volumes_count = (unsigned int)m_volumes.volumes.size();
-
-            // add supports
-            if (obj->is_step_done(slaposSupportTree) && obj->has_mesh(slaposSupportTree))
-            {
-                const TriangleMesh& mesh = obj->support_mesh();
-                m_volumes.volumes.emplace_back(new GLVolume(GLVolume::SLA_SUPPORT_COLOR));
-                GLVolume& v = *m_volumes.volumes.back();
-
-                if (m_use_VBOs)
-                    v.indexed_vertex_array.load_mesh_full_shading(mesh);
-                else
-                    v.indexed_vertex_array.load_mesh_flat_shading(mesh);
-
-                v.shader_outside_printer_detection_enabled = true;
-                v.composite_id.volume_id = -1;
-                v.set_instance_offset(offset);
-                v.set_instance_rotation(rotation);
-                v.set_instance_mirror(X, obj->is_left_handed() ? -1. : 1.);
+        if (obj->is_step_done(slaposSliceSupports)) {
+            unsigned int initial_volumes_count = (unsigned int)m_volumes.volumes.size();
+            for (const SLAPrintObject::Instance& instance : obj->instances()) {
+                add_volume(*obj, instance, obj->transformed_mesh(), GLVolume::MODEL_COLOR[0], true);
+                // Set the extruder_id and volume_id to achieve the same color as in the 3D scene when
+                // through the update_volumes_colors_by_extruder() call.
+                m_volumes.volumes.back()->extruder_id = obj->model_object()->volumes.front()->extruder_id();
+                m_volumes.volumes.back()->composite_id.volume_id = 0;
+                if (obj->is_step_done(slaposSupportTree) && obj->has_mesh(slaposSupportTree))
+                    add_volume(*obj, instance, obj->support_mesh(), GLVolume::SLA_SUPPORT_COLOR, true);
+                if (obj->is_step_done(slaposBasePool) && obj->has_mesh(slaposBasePool))
+                    add_volume(*obj, instance, obj->pad_mesh(), GLVolume::SLA_PAD_COLOR, true);
             }
-
-            // add pad
-            if (obj->is_step_done(slaposBasePool) && obj->has_mesh(slaposBasePool))
-            {
-                const TriangleMesh& mesh = obj->pad_mesh();
-                m_volumes.volumes.emplace_back(new GLVolume(GLVolume::SLA_PAD_COLOR));
-                GLVolume& v = *m_volumes.volumes.back();
-
-                if (m_use_VBOs)
-                    v.indexed_vertex_array.load_mesh_full_shading(mesh);
-                else
-                    v.indexed_vertex_array.load_mesh_flat_shading(mesh);
-
-                v.shader_outside_printer_detection_enabled = false;
-                v.composite_id.volume_id = -1;
-                v.set_instance_offset(offset);
-                v.set_instance_rotation(rotation);
-                v.set_instance_mirror(X, obj->is_left_handed() ? -1. : 1.);
-            }
-
-            // finalize volumes and sends geometry to gpu
-            for (unsigned int i = partial_volumes_count; i < m_volumes.volumes.size(); ++i)
-            {
+            double shift_z = obj->get_current_elevation();
+            for (unsigned int i = initial_volumes_count; i < m_volumes.volumes.size(); ++ i) {
                 GLVolume& v = *m_volumes.volumes[i];
+                // finalize volumes and sends geometry to gpu
                 v.bounding_box = v.indexed_vertex_array.bounding_box();
                 v.indexed_vertex_array.finalize_geometry(m_use_VBOs);
+                // apply shift z
+                v.set_sla_shift_z(shift_z);
             }
-
-            ++obj_idx;
         }
 
-        // apply shift z
-        double shift_z = obj->get_current_elevation();
-        for (unsigned int i = initial_volumes_count; i < m_volumes.volumes.size(); ++i)
-        {
-            m_volumes.volumes[i]->set_sla_shift_z(shift_z);
-        }
-    }
-
     update_volumes_colors_by_extruder();
 #else
     this->reload_scene(true, true);