mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-30 12:11:15 -06:00 
			
		
		
		
	Follow-up of 6194e67e68 - Separated the part that computed triangles normals and lighting inside the fragment shader into a separate shader mm_gouraud, which is only used for the multi-material painting gizmo.
				
					
				
			This commit is contained in:
		
							parent
							
								
									912f73d79c
								
							
						
					
					
						commit
						b45675b4e1
					
				
					 10 changed files with 179 additions and 84 deletions
				
			
		|  | @ -456,7 +456,7 @@ private: | |||
|     GLGizmosManager m_gizmos; | ||||
|     GLToolbar m_main_toolbar; | ||||
|     GLToolbar m_undoredo_toolbar; | ||||
|     ClippingPlane m_clipping_planes[2]; | ||||
|     std::array<ClippingPlane, 2> m_clipping_planes; | ||||
|     ClippingPlane m_camera_clipping_plane; | ||||
|     bool m_use_clipping_planes; | ||||
|     SlaCap m_sla_caps[2]; | ||||
|  | @ -651,6 +651,9 @@ public: | |||
|     void reset_clipping_planes_cache() { m_sla_caps[0].triangles.clear(); m_sla_caps[1].triangles.clear(); } | ||||
|     void set_use_clipping_planes(bool use) { m_use_clipping_planes = use; } | ||||
| 
 | ||||
|     bool                                get_use_clipping_planes() const { return m_use_clipping_planes; } | ||||
|     const std::array<ClippingPlane, 2> &get_clipping_planes() const { return m_clipping_planes; }; | ||||
| 
 | ||||
|     void set_color_by(const std::string& value); | ||||
| 
 | ||||
|     void refresh_camera_scene_box(); | ||||
|  |  | |||
|  | @ -61,25 +61,23 @@ std::pair<bool, std::string> GLShadersManager::init() | |||
|     // used to render extrusion and travel paths as lines in gcode preview
 | ||||
|     valid &= append_shader("toolpaths_lines", { "toolpaths_lines.vs", "toolpaths_lines.fs" }); | ||||
|     // used to render objects in 3d editor
 | ||||
|     // For Apple's on Arm CPU computed triangle normals inside fragment shader using dFdx and dFdy has the opposite direction.
 | ||||
|     // Because of this, objects had darker colors inside the multi-material gizmo.
 | ||||
|     // Based on https://stackoverflow.com/a/66206648, the similar behavior was also spotted on some other devices with Arm CPU.
 | ||||
|     if (platform_flavor() == PlatformFlavor::OSXOnArm) | ||||
|         valid &= append_shader("gouraud", { "gouraud.vs", "gouraud.fs" }, { "FLIP_TRIANGLE_NORMALS"sv | ||||
|     valid &= append_shader("gouraud", { "gouraud.vs", "gouraud.fs" } | ||||
| #if ENABLE_ENVIRONMENT_MAP | ||||
|             , "ENABLE_ENVIRONMENT_MAP"sv | ||||
| #endif | ||||
|         }); | ||||
|     else | ||||
|         valid &= append_shader("gouraud", { "gouraud.vs", "gouraud.fs" } | ||||
| #if ENABLE_ENVIRONMENT_MAP | ||||
|             , { "ENABLE_ENVIRONMENT_MAP"sv } | ||||
|         , { "ENABLE_ENVIRONMENT_MAP"sv } | ||||
| #endif | ||||
|         ); | ||||
|     // used to render variable layers heights in 3d editor
 | ||||
|     valid &= append_shader("variable_layer_height", { "variable_layer_height.vs", "variable_layer_height.fs" }); | ||||
|     // used to render highlight contour around selected triangles inside the multi-material gizmo
 | ||||
|     valid &= append_shader("mm_contour", { "mm_contour.vs", "mm_contour.fs" }); | ||||
|     // Used to render painted triangles inside the multi-material gizmo. Triangle normals are computed inside fragment shader.
 | ||||
|     // For Apple's on Arm CPU computed triangle normals inside fragment shader using dFdx and dFdy has the opposite direction.
 | ||||
|     // Because of this, objects had darker colors inside the multi-material gizmo.
 | ||||
|     // Based on https://stackoverflow.com/a/66206648, the similar behavior was also spotted on some other devices with Arm CPU.
 | ||||
|     if (platform_flavor() == PlatformFlavor::OSXOnArm) | ||||
|         valid &= append_shader("mm_gouraud", {"mm_gouraud.vs", "mm_gouraud.fs"}, {"FLIP_TRIANGLE_NORMALS"sv}); | ||||
|     else | ||||
|         valid &= append_shader("mm_gouraud", {"mm_gouraud.vs", "mm_gouraud.fs"}); | ||||
| 
 | ||||
|     return { valid, error }; | ||||
| } | ||||
|  |  | |||
|  | @ -174,6 +174,43 @@ void GLGizmoMmuSegmentation::set_painter_gizmo_data(const Selection &selection) | |||
|     } | ||||
| } | ||||
| 
 | ||||
| void GLGizmoMmuSegmentation::render_triangles(const Selection &selection, const bool use_polygon_offset_fill) const | ||||
| { | ||||
|     ClippingPlaneDataWrapper clp_data = this->get_clipping_plane_data(); | ||||
|     auto                    *shader   = wxGetApp().get_shader("mm_gouraud"); | ||||
|     if (!shader) | ||||
|         return; | ||||
|     shader->start_using(); | ||||
|     shader->set_uniform("clipping_plane", clp_data.clp_dataf); | ||||
|     shader->set_uniform("z_range", clp_data.z_range); | ||||
|     ScopeGuard guard([shader]() { if (shader) shader->stop_using(); }); | ||||
| 
 | ||||
|     const ModelObject *mo      = m_c->selection_info()->model_object(); | ||||
|     int                mesh_id = -1; | ||||
|     for (const ModelVolume *mv : mo->volumes) { | ||||
|         if (!mv->is_model_part()) | ||||
|             continue; | ||||
| 
 | ||||
|         ++mesh_id; | ||||
| 
 | ||||
|         const Transform3d trafo_matrix = mo->instances[selection.get_instance_idx()]->get_transformation().get_matrix() * mv->get_matrix(); | ||||
| 
 | ||||
|         bool is_left_handed = trafo_matrix.matrix().determinant() < 0.; | ||||
|         if (is_left_handed) | ||||
|             glsafe(::glFrontFace(GL_CW)); | ||||
| 
 | ||||
|         glsafe(::glPushMatrix()); | ||||
|         glsafe(::glMultMatrixd(trafo_matrix.data())); | ||||
| 
 | ||||
|         shader->set_uniform("volume_world_matrix", trafo_matrix); | ||||
|         m_triangle_selectors[mesh_id]->render(m_imgui); | ||||
| 
 | ||||
|         glsafe(::glPopMatrix()); | ||||
|         if (is_left_handed) | ||||
|             glsafe(::glFrontFace(GL_CCW)); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| static void render_extruders_combo(const std::string                       &label, | ||||
|                                    const std::vector<std::string>          &extruders, | ||||
|                                    const std::vector<std::array<float, 4>> &extruders_colors, | ||||
|  | @ -554,9 +591,7 @@ void TriangleSelectorMmGui::render(ImGuiWrapper *imgui) | |||
|     auto *shader = wxGetApp().get_current_shader(); | ||||
|     if (!shader) | ||||
|         return; | ||||
|     assert(shader->get_name() == "gouraud"); | ||||
|     ScopeGuard guard([shader]() { if (shader) shader->set_uniform("compute_triangle_normals_in_fs", false);}); | ||||
|     shader->set_uniform("compute_triangle_normals_in_fs", true); | ||||
|     assert(shader->get_name() == "mm_gouraud"); | ||||
| 
 | ||||
|     for (size_t color_idx = 0; color_idx < m_gizmo_scene.triangle_indices.size(); ++color_idx) | ||||
|         if (m_gizmo_scene.has_VBOs(color_idx)) { | ||||
|  | @ -569,7 +604,7 @@ void TriangleSelectorMmGui::render(ImGuiWrapper *imgui) | |||
|         } | ||||
| 
 | ||||
|     if (m_paint_contour.has_VBO()) { | ||||
|         ScopeGuard guard_gouraud([shader]() { shader->start_using(); }); | ||||
|         ScopeGuard guard_mm_gouraud([shader]() { shader->start_using(); }); | ||||
|         shader->stop_using(); | ||||
| 
 | ||||
|         auto *contour_shader = wxGetApp().get_shader("mm_contour"); | ||||
|  |  | |||
|  | @ -89,6 +89,8 @@ public: | |||
| 
 | ||||
|     void set_painter_gizmo_data(const Selection& selection) override; | ||||
| 
 | ||||
|     void render_triangles(const Selection& selection, bool use_polygon_offset_fill) const override; | ||||
| 
 | ||||
|     // TriangleSelector::serialization/deserialization has a limit to store 19 different states.
 | ||||
|     // EXTRUDER_LIMIT + 1 states are used to storing the painting because also uncolored triangles are stored.
 | ||||
|     // When increasing EXTRUDER_LIMIT, it needs to ensure that TriangleSelector::serialization/deserialization
 | ||||
|  |  | |||
|  | @ -43,12 +43,29 @@ void GLGizmoPainterBase::set_painter_gizmo_data(const Selection& selection) | |||
|     } | ||||
| } | ||||
| 
 | ||||
| GLGizmoPainterBase::ClippingPlaneDataWrapper GLGizmoPainterBase::get_clipping_plane_data() const | ||||
| { | ||||
|     ClippingPlaneDataWrapper clp_data_out{{0.f, 0.f, 1.f, FLT_MAX}, {-FLT_MAX, FLT_MAX}}; | ||||
|     // Take care of the clipping plane. The normal of the clipping plane is
 | ||||
|     // saved with opposite sign than we need to pass to OpenGL (FIXME)
 | ||||
|     if (bool clipping_plane_active = m_c->object_clipper()->get_position() != 0.; clipping_plane_active) { | ||||
|         const ClippingPlane *clp = m_c->object_clipper()->get_clipping_plane(); | ||||
|         for (size_t i = 0; i < 3; ++i) | ||||
|             clp_data_out.clp_dataf[i] = -1.f * float(clp->get_data()[i]); | ||||
|         clp_data_out.clp_dataf[3] = float(clp->get_data()[3]); | ||||
|     } | ||||
| 
 | ||||
|     // z_range is calculated in the same way as in GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type)
 | ||||
|     if (m_c->get_canvas()->get_use_clipping_planes()) { | ||||
|         const std::array<ClippingPlane, 2> &clps = m_c->get_canvas()->get_clipping_planes(); | ||||
|         clp_data_out.z_range                     = {float(-clps[0].get_data()[3]), float(clps[1].get_data()[3])}; | ||||
|     } | ||||
| 
 | ||||
|     return clp_data_out; | ||||
| } | ||||
| 
 | ||||
| void GLGizmoPainterBase::render_triangles(const Selection& selection, const bool use_polygon_offset_fill) const | ||||
| { | ||||
|     const ModelObject* mo = m_c->selection_info()->model_object(); | ||||
| 
 | ||||
|     ScopeGuard offset_fill_guard([&use_polygon_offset_fill]() { | ||||
|         if (use_polygon_offset_fill) | ||||
|             glsafe(::glDisable(GL_POLYGON_OFFSET_FILL)); | ||||
|  | @ -58,27 +75,17 @@ void GLGizmoPainterBase::render_triangles(const Selection& selection, const bool | |||
|         glsafe(::glPolygonOffset(-5.0, -5.0)); | ||||
|     } | ||||
| 
 | ||||
|     // Take care of the clipping plane. The normal of the clipping plane is
 | ||||
|     // saved with opposite sign than we need to pass to OpenGL (FIXME)
 | ||||
|     bool clipping_plane_active = m_c->object_clipper()->get_position() != 0.; | ||||
|     float clp_dataf[4] = {0.f, 0.f, 1.f, FLT_MAX}; | ||||
|     if (clipping_plane_active) { | ||||
|         const ClippingPlane* clp = m_c->object_clipper()->get_clipping_plane(); | ||||
|         for (size_t i=0; i<3; ++i) | ||||
|             clp_dataf[i] = -1.f * float(clp->get_data()[i]); | ||||
|         clp_dataf[3] = float(clp->get_data()[3]); | ||||
|     } | ||||
| 
 | ||||
|     auto *shader = wxGetApp().get_shader("gouraud"); | ||||
|     if (! shader) | ||||
|         return; | ||||
|     shader->start_using(); | ||||
|     shader->set_uniform("slope.actived", false); | ||||
|     shader->set_uniform("print_box.actived", false); | ||||
|     shader->set_uniform("clipping_plane", clp_dataf, 4); | ||||
|     shader->set_uniform("clipping_plane", this->get_clipping_plane_data().clp_dataf); | ||||
|     ScopeGuard guard([shader]() { if (shader) shader->stop_using(); }); | ||||
| 
 | ||||
|     int mesh_id = -1; | ||||
|     const ModelObject *mo      = m_c->selection_info()->model_object(); | ||||
|     int                mesh_id = -1; | ||||
|     for (const ModelVolume* mv : mo->volumes) { | ||||
|         if (! mv->is_model_part()) | ||||
|             continue; | ||||
|  |  | |||
|  | @ -126,7 +126,7 @@ public: | |||
|     virtual bool gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position, bool shift_down, bool alt_down, bool control_down); | ||||
| 
 | ||||
| protected: | ||||
|     void render_triangles(const Selection& selection, const bool use_polygon_offset_fill = true) const; | ||||
|     virtual void render_triangles(const Selection& selection, bool use_polygon_offset_fill = true) const; | ||||
|     void render_cursor() const; | ||||
|     void render_cursor_circle() const; | ||||
|     void render_cursor_sphere(const Transform3d& trafo) const; | ||||
|  | @ -176,6 +176,14 @@ protected: | |||
|         Right | ||||
|     }; | ||||
| 
 | ||||
|     struct ClippingPlaneDataWrapper | ||||
|     { | ||||
|         std::array<float, 4> clp_dataf; | ||||
|         std::array<float, 2> z_range; | ||||
|     }; | ||||
| 
 | ||||
|     ClippingPlaneDataWrapper get_clipping_plane_data() const; | ||||
| 
 | ||||
| private: | ||||
|     bool is_mesh_point_clipped(const Vec3d& point, const Transform3d& trafo) const; | ||||
|     void update_raycast_cache(const Vec2d& mouse_position, | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Lukáš Hejl
						Lukáš Hejl