mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-11-02 20:51:23 -07: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
				
			
		| 
						 | 
				
			
			@ -50,8 +50,6 @@ varying float world_pos_z;
 | 
			
		|||
varying float world_normal_z;
 | 
			
		||||
varying vec3 eye_normal;
 | 
			
		||||
 | 
			
		||||
uniform bool compute_triangle_normals_in_fs;
 | 
			
		||||
 | 
			
		||||
void main()
 | 
			
		||||
{
 | 
			
		||||
    if (any(lessThan(clipping_planes_dots, ZERO)))
 | 
			
		||||
| 
						 | 
				
			
			@ -59,36 +57,7 @@ void main()
 | 
			
		|||
    vec3  color = uniform_color.rgb;
 | 
			
		||||
    float alpha = uniform_color.a;
 | 
			
		||||
 | 
			
		||||
    vec2  intensity_fs      = intensity;
 | 
			
		||||
    vec3  eye_normal_fs     = eye_normal;
 | 
			
		||||
    float world_normal_z_fs = world_normal_z;
 | 
			
		||||
    if (compute_triangle_normals_in_fs) {
 | 
			
		||||
        vec3 triangle_normal = normalize(cross(dFdx(model_pos.xyz), dFdy(model_pos.xyz)));
 | 
			
		||||
#ifdef FLIP_TRIANGLE_NORMALS
 | 
			
		||||
        triangle_normal = -triangle_normal;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
        // First transform the normal into camera space and normalize the result.
 | 
			
		||||
        eye_normal_fs = normalize(gl_NormalMatrix * triangle_normal);
 | 
			
		||||
 | 
			
		||||
        // Compute the cos of the angle between the normal and lights direction. The light is directional so the direction is constant for every vertex.
 | 
			
		||||
        // Since these two are normalized the cosine is the dot product. We also need to clamp the result to the [0,1] range.
 | 
			
		||||
        float NdotL = max(dot(eye_normal_fs, LIGHT_TOP_DIR), 0.0);
 | 
			
		||||
 | 
			
		||||
        intensity_fs = vec2(0.0, 0.0);
 | 
			
		||||
        intensity_fs.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE;
 | 
			
		||||
        vec3 position = (gl_ModelViewMatrix * model_pos).xyz;
 | 
			
		||||
        intensity_fs.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(position), reflect(-LIGHT_TOP_DIR, eye_normal_fs)), 0.0), LIGHT_TOP_SHININESS);
 | 
			
		||||
 | 
			
		||||
        // Perform the same lighting calculation for the 2nd light source (no specular applied).
 | 
			
		||||
        NdotL = max(dot(eye_normal_fs, LIGHT_FRONT_DIR), 0.0);
 | 
			
		||||
        intensity_fs.x += NdotL * LIGHT_FRONT_DIFFUSE;
 | 
			
		||||
 | 
			
		||||
        // z component of normal vector in world coordinate used for slope shading
 | 
			
		||||
        world_normal_z_fs = slope.actived ? (normalize(slope.volume_world_normal_matrix * triangle_normal)).z : 0.0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (slope.actived && world_normal_z_fs < slope.normal_z - EPSILON) {
 | 
			
		||||
    if (slope.actived && world_normal_z < slope.normal_z - EPSILON) {
 | 
			
		||||
        color = vec3(0.7, 0.7, 1.0);
 | 
			
		||||
        alpha = 1.0;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -96,8 +65,8 @@ void main()
 | 
			
		|||
	color = (any(lessThan(delta_box_min, ZERO)) || any(greaterThan(delta_box_max, ZERO))) ? mix(color, ZERO, 0.3333) : color;
 | 
			
		||||
#ifdef ENABLE_ENVIRONMENT_MAP
 | 
			
		||||
    if (use_environment_tex)
 | 
			
		||||
        gl_FragColor = vec4(0.45 * texture2D(environment_tex, normalize(eye_normal_fs).xy * 0.5 + 0.5).xyz + 0.8 * color * intensity_fs.x, alpha);
 | 
			
		||||
        gl_FragColor = vec4(0.45 * texture2D(environment_tex, normalize(eye_normal).xy * 0.5 + 0.5).xyz + 0.8 * color * intensity.x, alpha);
 | 
			
		||||
    else
 | 
			
		||||
#endif
 | 
			
		||||
        gl_FragColor = vec4(vec3(intensity_fs.y) + color * intensity_fs.x, alpha);
 | 
			
		||||
        gl_FragColor = vec4(vec3(intensity.y) + color * intensity.x, alpha);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -54,26 +54,22 @@ varying float world_pos_z;
 | 
			
		|||
varying float world_normal_z;
 | 
			
		||||
varying vec3 eye_normal;
 | 
			
		||||
 | 
			
		||||
uniform bool compute_triangle_normals_in_fs;
 | 
			
		||||
 | 
			
		||||
void main()
 | 
			
		||||
{
 | 
			
		||||
    if (!compute_triangle_normals_in_fs) {
 | 
			
		||||
        // First transform the normal into camera space and normalize the result.
 | 
			
		||||
        eye_normal = normalize(gl_NormalMatrix * gl_Normal);
 | 
			
		||||
    // First transform the normal into camera space and normalize the result.
 | 
			
		||||
    eye_normal = normalize(gl_NormalMatrix * gl_Normal);
 | 
			
		||||
 | 
			
		||||
        // Compute the cos of the angle between the normal and lights direction. The light is directional so the direction is constant for every vertex.
 | 
			
		||||
        // Since these two are normalized the cosine is the dot product. We also need to clamp the result to the [0,1] range.
 | 
			
		||||
        float NdotL = max(dot(eye_normal, LIGHT_TOP_DIR), 0.0);
 | 
			
		||||
    // Compute the cos of the angle between the normal and lights direction. The light is directional so the direction is constant for every vertex.
 | 
			
		||||
    // Since these two are normalized the cosine is the dot product. We also need to clamp the result to the [0,1] range.
 | 
			
		||||
    float NdotL = max(dot(eye_normal, LIGHT_TOP_DIR), 0.0);
 | 
			
		||||
 | 
			
		||||
        intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE;
 | 
			
		||||
        vec3 position = (gl_ModelViewMatrix * gl_Vertex).xyz;
 | 
			
		||||
        intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(position), reflect(-LIGHT_TOP_DIR, eye_normal)), 0.0), LIGHT_TOP_SHININESS);
 | 
			
		||||
    intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE;
 | 
			
		||||
    vec3 position = (gl_ModelViewMatrix * gl_Vertex).xyz;
 | 
			
		||||
    intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(position), reflect(-LIGHT_TOP_DIR, eye_normal)), 0.0), LIGHT_TOP_SHININESS);
 | 
			
		||||
 | 
			
		||||
        // Perform the same lighting calculation for the 2nd light source (no specular applied).
 | 
			
		||||
        NdotL = max(dot(eye_normal, LIGHT_FRONT_DIR), 0.0);
 | 
			
		||||
        intensity.x += NdotL * LIGHT_FRONT_DIFFUSE;
 | 
			
		||||
    }
 | 
			
		||||
    // Perform the same lighting calculation for the 2nd light source (no specular applied).
 | 
			
		||||
    NdotL = max(dot(eye_normal, LIGHT_FRONT_DIR), 0.0);
 | 
			
		||||
    intensity.x += NdotL * LIGHT_FRONT_DIFFUSE;
 | 
			
		||||
 | 
			
		||||
    model_pos = gl_Vertex;
 | 
			
		||||
    // Point in homogenous coordinates.
 | 
			
		||||
| 
						 | 
				
			
			@ -90,8 +86,7 @@ void main()
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    // z component of normal vector in world coordinate used for slope shading
 | 
			
		||||
    if (!compute_triangle_normals_in_fs)
 | 
			
		||||
        world_normal_z = slope.actived ? (normalize(slope.volume_world_normal_matrix * gl_Normal)).z : 0.0;
 | 
			
		||||
    world_normal_z = slope.actived ? (normalize(slope.volume_world_normal_matrix * gl_Normal)).z : 0.0;
 | 
			
		||||
 | 
			
		||||
    gl_Position = ftransform();
 | 
			
		||||
    // Fill in the scalars for fragment shader clipping. Fragments with any of these components lower than zero are discarded.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										55
									
								
								resources/shaders/mm_gouraud.fs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								resources/shaders/mm_gouraud.fs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,55 @@
 | 
			
		|||
#version 110
 | 
			
		||||
 | 
			
		||||
#define INTENSITY_CORRECTION 0.6
 | 
			
		||||
 | 
			
		||||
// normalized values for (-0.6/1.31, 0.6/1.31, 1./1.31)
 | 
			
		||||
const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929);
 | 
			
		||||
#define LIGHT_TOP_DIFFUSE    (0.8 * INTENSITY_CORRECTION)
 | 
			
		||||
#define LIGHT_TOP_SPECULAR   (0.125 * INTENSITY_CORRECTION)
 | 
			
		||||
#define LIGHT_TOP_SHININESS  20.0
 | 
			
		||||
 | 
			
		||||
// normalized values for (1./1.43, 0.2/1.43, 1./1.43)
 | 
			
		||||
const vec3 LIGHT_FRONT_DIR = vec3(0.6985074, 0.1397015, 0.6985074);
 | 
			
		||||
#define LIGHT_FRONT_DIFFUSE  (0.3 * INTENSITY_CORRECTION)
 | 
			
		||||
 | 
			
		||||
#define INTENSITY_AMBIENT    0.3
 | 
			
		||||
 | 
			
		||||
const vec3  ZERO    = vec3(0.0, 0.0, 0.0);
 | 
			
		||||
const float EPSILON = 0.0001;
 | 
			
		||||
 | 
			
		||||
uniform vec4 uniform_color;
 | 
			
		||||
 | 
			
		||||
varying vec3 clipping_planes_dots;
 | 
			
		||||
varying vec4 model_pos;
 | 
			
		||||
 | 
			
		||||
void main()
 | 
			
		||||
{
 | 
			
		||||
    if (any(lessThan(clipping_planes_dots, ZERO)))
 | 
			
		||||
        discard;
 | 
			
		||||
    vec3  color = uniform_color.rgb;
 | 
			
		||||
    float alpha = uniform_color.a;
 | 
			
		||||
 | 
			
		||||
    vec3 triangle_normal = normalize(cross(dFdx(model_pos.xyz), dFdy(model_pos.xyz)));
 | 
			
		||||
#ifdef FLIP_TRIANGLE_NORMALS
 | 
			
		||||
    triangle_normal = -triangle_normal;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    // First transform the normal into camera space and normalize the result.
 | 
			
		||||
    vec3 eye_normal = normalize(gl_NormalMatrix * triangle_normal);
 | 
			
		||||
 | 
			
		||||
    // Compute the cos of the angle between the normal and lights direction. The light is directional so the direction is constant for every vertex.
 | 
			
		||||
    // Since these two are normalized the cosine is the dot product. We also need to clamp the result to the [0,1] range.
 | 
			
		||||
    float NdotL = max(dot(eye_normal, LIGHT_TOP_DIR), 0.0);
 | 
			
		||||
 | 
			
		||||
    // x = diffuse, y = specular;
 | 
			
		||||
    vec2 intensity = vec2(0.0, 0.0);
 | 
			
		||||
    intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE;
 | 
			
		||||
    vec3 position = (gl_ModelViewMatrix * model_pos).xyz;
 | 
			
		||||
    intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(position), reflect(-LIGHT_TOP_DIR, eye_normal)), 0.0), LIGHT_TOP_SHININESS);
 | 
			
		||||
 | 
			
		||||
    // Perform the same lighting calculation for the 2nd light source (no specular applied).
 | 
			
		||||
    NdotL = max(dot(eye_normal, LIGHT_FRONT_DIR), 0.0);
 | 
			
		||||
    intensity.x += NdotL * LIGHT_FRONT_DIFFUSE;
 | 
			
		||||
 | 
			
		||||
    gl_FragColor = vec4(vec3(intensity.y) + color * intensity.x, alpha);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										23
									
								
								resources/shaders/mm_gouraud.vs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								resources/shaders/mm_gouraud.vs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,23 @@
 | 
			
		|||
#version 110
 | 
			
		||||
 | 
			
		||||
const vec3 ZERO = vec3(0.0, 0.0, 0.0);
 | 
			
		||||
 | 
			
		||||
uniform mat4 volume_world_matrix;
 | 
			
		||||
// Clipping plane, x = min z, y = max z. Used by the FFF and SLA previews to clip with a top / bottom plane.
 | 
			
		||||
uniform vec2 z_range;
 | 
			
		||||
// Clipping plane - general orientation. Used by the SLA gizmo.
 | 
			
		||||
uniform vec4 clipping_plane;
 | 
			
		||||
 | 
			
		||||
varying vec3 clipping_planes_dots;
 | 
			
		||||
varying vec4 model_pos;
 | 
			
		||||
 | 
			
		||||
void main()
 | 
			
		||||
{
 | 
			
		||||
    model_pos = gl_Vertex;
 | 
			
		||||
    // Point in homogenous coordinates.
 | 
			
		||||
    vec4 world_pos = volume_world_matrix * gl_Vertex;
 | 
			
		||||
 | 
			
		||||
    gl_Position = ftransform();
 | 
			
		||||
    // Fill in the scalars for fragment shader clipping. Fragments with any of these components lower than zero are discarded.
 | 
			
		||||
    clipping_planes_dots = vec3(dot(world_pos, clipping_plane), world_pos.z - z_range.x, z_range.y - world_pos.z);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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