Merge branch 'master' of https://github.com/Prusa-Development/PrusaSlicerPrivate into et_transformations
This commit is contained in:
commit
7b255aa2ab
37 changed files with 30981 additions and 29620 deletions
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -24,6 +24,9 @@ struct SlopeDetection
|
|||
};
|
||||
|
||||
uniform vec4 uniform_color;
|
||||
uniform bool use_color_clip_plane;
|
||||
uniform vec4 uniform_color_clip_plane_1;
|
||||
uniform vec4 uniform_color_clip_plane_2;
|
||||
uniform SlopeDetection slope;
|
||||
|
||||
#ifdef ENABLE_ENVIRONMENT_MAP
|
||||
|
@ -34,6 +37,7 @@ uniform SlopeDetection slope;
|
|||
uniform PrintVolumeDetection print_volume;
|
||||
|
||||
varying vec3 clipping_planes_dots;
|
||||
varying float color_clip_plane_dot;
|
||||
|
||||
// x = diffuse, y = specular;
|
||||
varying vec2 intensity;
|
||||
|
@ -46,12 +50,18 @@ void main()
|
|||
{
|
||||
if (any(lessThan(clipping_planes_dots, ZERO)))
|
||||
discard;
|
||||
vec3 color = uniform_color.rgb;
|
||||
float alpha = uniform_color.a;
|
||||
|
||||
vec4 color;
|
||||
if (use_color_clip_plane) {
|
||||
color.rgb = (color_clip_plane_dot < 0.0) ? uniform_color_clip_plane_1.rgb : uniform_color_clip_plane_2.rgb;
|
||||
color.a = uniform_color.a;
|
||||
}
|
||||
else
|
||||
color = uniform_color;
|
||||
|
||||
if (slope.actived && world_normal_z < slope.normal_z - EPSILON) {
|
||||
color = vec3(0.7, 0.7, 1.0);
|
||||
alpha = 1.0;
|
||||
color.rgb = vec3(0.7, 0.7, 1.0);
|
||||
color.a = 1.0;
|
||||
}
|
||||
|
||||
// if the fragment is outside the print volume -> use darker color
|
||||
|
@ -67,13 +77,13 @@ void main()
|
|||
float delta_radius = print_volume.xy_data.z - distance(world_pos.xy, print_volume.xy_data.xy);
|
||||
pv_check_min = vec3(delta_radius, 0.0, world_pos.z - print_volume.z_data.x);
|
||||
pv_check_max = vec3(0.0, 0.0, world_pos.z - print_volume.z_data.y);
|
||||
}
|
||||
color = (any(lessThan(pv_check_min, ZERO)) || any(greaterThan(pv_check_max, ZERO))) ? mix(color, ZERO, 0.3333) : color;
|
||||
}
|
||||
color.rgb = (any(lessThan(pv_check_min, ZERO)) || any(greaterThan(pv_check_max, ZERO))) ? mix(color.rgb, ZERO, 0.3333) : color.rgb;
|
||||
|
||||
#ifdef ENABLE_ENVIRONMENT_MAP
|
||||
if (use_environment_tex)
|
||||
gl_FragColor = vec4(0.45 * texture2D(environment_tex, normalize(eye_normal).xy * 0.5 + 0.5).xyz + 0.8 * color * intensity.x, alpha);
|
||||
gl_FragColor = vec4(0.45 * texture(environment_tex, normalize(eye_normal).xy * 0.5 + 0.5).xyz + 0.8 * color.rgb * intensity.x, color.a);
|
||||
else
|
||||
#endif
|
||||
gl_FragColor = vec4(vec3(intensity.y) + color * intensity.x, alpha);
|
||||
gl_FragColor = vec4(vec3(intensity.y) + color.rgb * intensity.x, color.a);
|
||||
}
|
||||
|
|
|
@ -35,6 +35,8 @@ uniform SlopeDetection slope;
|
|||
uniform vec2 z_range;
|
||||
// Clipping plane - general orientation. Used by the SLA gizmo.
|
||||
uniform vec4 clipping_plane;
|
||||
// Color clip plane - general orientation. Used by the cut gizmo.
|
||||
uniform vec4 color_clip_plane;
|
||||
|
||||
attribute vec3 v_position;
|
||||
attribute vec3 v_normal;
|
||||
|
@ -43,6 +45,7 @@ attribute vec3 v_normal;
|
|||
varying vec2 intensity;
|
||||
|
||||
varying vec3 clipping_planes_dots;
|
||||
varying float color_clip_plane_dot;
|
||||
|
||||
varying vec4 world_pos;
|
||||
varying float world_normal_z;
|
||||
|
@ -74,4 +77,5 @@ void main()
|
|||
gl_Position = projection_matrix * position;
|
||||
// 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);
|
||||
color_clip_plane_dot = dot(world_pos, color_clip_plane);
|
||||
}
|
||||
|
|
|
@ -24,6 +24,9 @@ struct SlopeDetection
|
|||
};
|
||||
|
||||
uniform vec4 uniform_color;
|
||||
uniform bool use_color_clip_plane;
|
||||
uniform vec4 uniform_color_clip_plane_1;
|
||||
uniform vec4 uniform_color_clip_plane_2;
|
||||
uniform SlopeDetection slope;
|
||||
|
||||
#ifdef ENABLE_ENVIRONMENT_MAP
|
||||
|
@ -34,6 +37,7 @@ uniform SlopeDetection slope;
|
|||
uniform PrintVolumeDetection print_volume;
|
||||
|
||||
in vec3 clipping_planes_dots;
|
||||
in float color_clip_plane_dot;
|
||||
|
||||
// x = diffuse, y = specular;
|
||||
in vec2 intensity;
|
||||
|
@ -48,12 +52,18 @@ void main()
|
|||
{
|
||||
if (any(lessThan(clipping_planes_dots, ZERO)))
|
||||
discard;
|
||||
vec3 color = uniform_color.rgb;
|
||||
float alpha = uniform_color.a;
|
||||
|
||||
vec4 color;
|
||||
if (use_color_clip_plane) {
|
||||
color.rgb = (color_clip_plane_dot < 0.0) ? uniform_color_clip_plane_1.rgb : uniform_color_clip_plane_2.rgb;
|
||||
color.a = uniform_color.a;
|
||||
}
|
||||
else
|
||||
color = uniform_color;
|
||||
|
||||
if (slope.actived && world_normal_z < slope.normal_z - EPSILON) {
|
||||
color = vec3(0.7, 0.7, 1.0);
|
||||
alpha = 1.0;
|
||||
color.rgb = vec3(0.7, 0.7, 1.0);
|
||||
color.a = 1.0;
|
||||
}
|
||||
|
||||
// if the fragment is outside the print volume -> use darker color
|
||||
|
@ -69,13 +79,13 @@ void main()
|
|||
float delta_radius = print_volume.xy_data.z - distance(world_pos.xy, print_volume.xy_data.xy);
|
||||
pv_check_min = vec3(delta_radius, 0.0, world_pos.z - print_volume.z_data.x);
|
||||
pv_check_max = vec3(0.0, 0.0, world_pos.z - print_volume.z_data.y);
|
||||
}
|
||||
color = (any(lessThan(pv_check_min, ZERO)) || any(greaterThan(pv_check_max, ZERO))) ? mix(color, ZERO, 0.3333) : color;
|
||||
}
|
||||
color.rgb = (any(lessThan(pv_check_min, ZERO)) || any(greaterThan(pv_check_max, ZERO))) ? mix(color.rgb, ZERO, 0.3333) : color.rgb;
|
||||
|
||||
#ifdef ENABLE_ENVIRONMENT_MAP
|
||||
if (use_environment_tex)
|
||||
out_color = vec4(0.45 * texture(environment_tex, normalize(eye_normal).xy * 0.5 + 0.5).xyz + 0.8 * color * intensity.x, alpha);
|
||||
out_color = vec4(0.45 * texture(environment_tex, normalize(eye_normal).xy * 0.5 + 0.5).xyz + 0.8 * color.rgb * intensity.x, color.a);
|
||||
else
|
||||
#endif
|
||||
out_color = vec4(vec3(intensity.y) + color * intensity.x, alpha);
|
||||
out_color = vec4(vec3(intensity.y) + color.rgb * intensity.x, color.a);
|
||||
}
|
||||
|
|
|
@ -35,6 +35,8 @@ uniform SlopeDetection slope;
|
|||
uniform vec2 z_range;
|
||||
// Clipping plane - general orientation. Used by the SLA gizmo.
|
||||
uniform vec4 clipping_plane;
|
||||
// Color clip plane - general orientation. Used by the cut gizmo.
|
||||
uniform vec4 color_clip_plane;
|
||||
|
||||
in vec3 v_position;
|
||||
in vec3 v_normal;
|
||||
|
@ -43,6 +45,7 @@ in vec3 v_normal;
|
|||
out vec2 intensity;
|
||||
|
||||
out vec3 clipping_planes_dots;
|
||||
out float color_clip_plane_dot;
|
||||
|
||||
out vec4 world_pos;
|
||||
out float world_normal_z;
|
||||
|
@ -74,4 +77,5 @@ void main()
|
|||
gl_Position = projection_matrix * position;
|
||||
// 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);
|
||||
color_clip_plane_dot = dot(world_pos, color_clip_plane);
|
||||
}
|
||||
|
|
|
@ -26,6 +26,9 @@ struct SlopeDetection
|
|||
};
|
||||
|
||||
uniform vec4 uniform_color;
|
||||
uniform bool use_color_clip_plane;
|
||||
uniform vec4 uniform_color_clip_plane_1;
|
||||
uniform vec4 uniform_color_clip_plane_2;
|
||||
uniform SlopeDetection slope;
|
||||
|
||||
#ifdef ENABLE_ENVIRONMENT_MAP
|
||||
|
@ -36,6 +39,7 @@ uniform SlopeDetection slope;
|
|||
uniform PrintVolumeDetection print_volume;
|
||||
|
||||
varying vec3 clipping_planes_dots;
|
||||
varying float color_clip_plane_dot;
|
||||
|
||||
// x = diffuse, y = specular;
|
||||
varying vec2 intensity;
|
||||
|
@ -48,12 +52,18 @@ void main()
|
|||
{
|
||||
if (any(lessThan(clipping_planes_dots, ZERO)))
|
||||
discard;
|
||||
vec3 color = uniform_color.rgb;
|
||||
float alpha = uniform_color.a;
|
||||
|
||||
vec4 color;
|
||||
if (use_color_clip_plane) {
|
||||
color.rgb = (color_clip_plane_dot < 0.0) ? uniform_color_clip_plane_1.rgb : uniform_color_clip_plane_2.rgb;
|
||||
color.a = uniform_color.a;
|
||||
}
|
||||
else
|
||||
color = uniform_color;
|
||||
|
||||
if (slope.actived && world_normal_z < slope.normal_z - EPSILON) {
|
||||
color = vec3(0.7, 0.7, 1.0);
|
||||
alpha = 1.0;
|
||||
color.rgb = vec3(0.7, 0.7, 1.0);
|
||||
color.a = 1.0;
|
||||
}
|
||||
|
||||
// if the fragment is outside the print volume -> use darker color
|
||||
|
@ -70,12 +80,12 @@ void main()
|
|||
pv_check_min = vec3(delta_radius, 0.0, world_pos.z - print_volume.z_data.x);
|
||||
pv_check_max = vec3(0.0, 0.0, world_pos.z - print_volume.z_data.y);
|
||||
}
|
||||
color = (any(lessThan(pv_check_min, ZERO)) || any(greaterThan(pv_check_max, ZERO))) ? mix(color, ZERO, 0.3333) : color;
|
||||
color.rgb = (any(lessThan(pv_check_min, ZERO)) || any(greaterThan(pv_check_max, ZERO))) ? mix(color.rgb, ZERO, 0.3333) : color.rgb;
|
||||
|
||||
#ifdef ENABLE_ENVIRONMENT_MAP
|
||||
if (use_environment_tex)
|
||||
gl_FragColor = vec4(0.45 * texture2D(environment_tex, normalize(eye_normal).xy * 0.5 + 0.5).xyz + 0.8 * color * intensity.x, alpha);
|
||||
gl_FragColor = vec4(0.45 * texture(environment_tex, normalize(eye_normal).xy * 0.5 + 0.5).xyz + 0.8 * color.rgb * intensity.x, color.a);
|
||||
else
|
||||
#endif
|
||||
gl_FragColor = vec4(vec3(intensity.y) + color * intensity.x, alpha);
|
||||
gl_FragColor = vec4(vec3(intensity.y) + color.rgb * intensity.x, color.a);
|
||||
}
|
||||
|
|
|
@ -35,6 +35,8 @@ uniform SlopeDetection slope;
|
|||
uniform vec2 z_range;
|
||||
// Clipping plane - general orientation. Used by the SLA gizmo.
|
||||
uniform vec4 clipping_plane;
|
||||
// Color clip plane - general orientation. Used by the cut gizmo.
|
||||
uniform vec4 color_clip_plane;
|
||||
|
||||
attribute vec3 v_position;
|
||||
attribute vec3 v_normal;
|
||||
|
@ -43,6 +45,7 @@ attribute vec3 v_normal;
|
|||
varying vec2 intensity;
|
||||
|
||||
varying vec3 clipping_planes_dots;
|
||||
varying float color_clip_plane_dot;
|
||||
|
||||
varying vec4 world_pos;
|
||||
varying float world_normal_z;
|
||||
|
@ -74,4 +77,5 @@ void main()
|
|||
gl_Position = projection_matrix * position;
|
||||
// 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);
|
||||
color_clip_plane_dot = dot(world_pos, color_clip_plane);
|
||||
}
|
||||
|
|
|
@ -1194,7 +1194,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
|
|||
m_placeholder_parser.set("first_layer_print_size", new ConfigOptionFloats({ bbox.size().x(), bbox.size().y() }));
|
||||
|
||||
std::vector<unsigned char> is_extruder_used(print.config().nozzle_diameter.size(), 0);
|
||||
for (unsigned int extruder_id : print.extruders())
|
||||
for (unsigned int extruder_id : tool_ordering.all_extruders())
|
||||
is_extruder_used[extruder_id] = true;
|
||||
m_placeholder_parser.set("is_extruder_used", new ConfigOptionBools(is_extruder_used));
|
||||
}
|
||||
|
@ -2793,8 +2793,14 @@ std::string GCode::_extrude(const ExtrusionPath &path, const std::string_view de
|
|||
acceleration = m_config.first_layer_acceleration_over_raft.value;
|
||||
} else if (m_config.bridge_acceleration.value > 0 && path.role().is_bridge()) {
|
||||
acceleration = m_config.bridge_acceleration.value;
|
||||
} else if (m_config.top_solid_infill_acceleration > 0 && path.role() == ExtrusionRole::TopSolidInfill) {
|
||||
acceleration = m_config.top_solid_infill_acceleration.value;
|
||||
} else if (m_config.solid_infill_acceleration > 0 && path.role().is_solid_infill()) {
|
||||
acceleration = m_config.solid_infill_acceleration.value;
|
||||
} else if (m_config.infill_acceleration.value > 0 && path.role().is_infill()) {
|
||||
acceleration = m_config.infill_acceleration.value;
|
||||
} else if (m_config.external_perimeter_acceleration > 0 && path.role().is_external_perimeter()) {
|
||||
acceleration = m_config.external_perimeter_acceleration.value;
|
||||
} else if (m_config.perimeter_acceleration.value > 0 && path.role().is_perimeter()) {
|
||||
acceleration = m_config.perimeter_acceleration.value;
|
||||
} else {
|
||||
|
|
|
@ -1305,7 +1305,9 @@ void ModelObject::synchronize_model_after_cut()
|
|||
void ModelObject::apply_cut_attributes(ModelObjectCutAttributes attributes)
|
||||
{
|
||||
// we don't save cut information, if result will not contains all parts of initial object
|
||||
if (!attributes.has(ModelObjectCutAttribute::KeepUpper) || !attributes.has(ModelObjectCutAttribute::KeepLower))
|
||||
if (!attributes.has(ModelObjectCutAttribute::KeepUpper) ||
|
||||
!attributes.has(ModelObjectCutAttribute::KeepLower) ||
|
||||
attributes.has(ModelObjectCutAttribute::InvalidateCutInfo))
|
||||
return;
|
||||
|
||||
if (cut_id.id().invalid())
|
||||
|
@ -1425,7 +1427,7 @@ void ModelObject::process_modifier_cut(ModelVolume* volume, const Transform3d& i
|
|||
lower->add_volume(*volume);
|
||||
}
|
||||
|
||||
static void add_cut_volume(TriangleMesh& mesh, ModelObject* object, const ModelVolume* src_volume, const Transform3d& cut_matrix)
|
||||
static void add_cut_volume(TriangleMesh& mesh, ModelObject* object, const ModelVolume* src_volume, const Transform3d& cut_matrix, const std::string& suffix = {})
|
||||
{
|
||||
if (mesh.empty())
|
||||
return;
|
||||
|
@ -1433,7 +1435,7 @@ static void add_cut_volume(TriangleMesh& mesh, ModelObject* object, const ModelV
|
|||
mesh.transform(cut_matrix);
|
||||
ModelVolume* vol = object->add_volume(mesh);
|
||||
|
||||
vol->name = src_volume->name;
|
||||
vol->name = src_volume->name + suffix;
|
||||
// Don't copy the config's ID.
|
||||
vol->config.assign_config(src_volume->config);
|
||||
assert(vol->config.id().valid());
|
||||
|
@ -1477,6 +1479,12 @@ void ModelObject::process_solid_part_cut(ModelVolume* volume, const Transform3d&
|
|||
|
||||
// Add required cut parts to the objects
|
||||
|
||||
if (attributes.has(ModelObjectCutAttribute::KeepAsParts)) {
|
||||
add_cut_volume(upper_mesh, upper, volume, cut_matrix, "_A");
|
||||
add_cut_volume(lower_mesh, upper, volume, cut_matrix, "_B");
|
||||
return;
|
||||
}
|
||||
|
||||
if (attributes.has(ModelObjectCutAttribute::KeepUpper))
|
||||
add_cut_volume(upper_mesh, upper, volume, cut_matrix);
|
||||
|
||||
|
@ -1560,7 +1568,7 @@ ModelObjectPtrs ModelObject::cut(size_t instance, const Transform3d& cut_matrix,
|
|||
clone_for_cut(&upper);
|
||||
|
||||
ModelObject* lower{ nullptr };
|
||||
if (attributes.has(ModelObjectCutAttribute::KeepLower))
|
||||
if (attributes.has(ModelObjectCutAttribute::KeepLower) && !attributes.has(ModelObjectCutAttribute::KeepAsParts))
|
||||
clone_for_cut(&lower);
|
||||
|
||||
std::vector<ModelObject*> dowels;
|
||||
|
@ -1608,34 +1616,40 @@ ModelObjectPtrs ModelObject::cut(size_t instance, const Transform3d& cut_matrix,
|
|||
|
||||
ModelObjectPtrs res;
|
||||
|
||||
if (attributes.has(ModelObjectCutAttribute::KeepUpper) && !upper->volumes.empty()) {
|
||||
invalidate_translations(upper, instances[instance]);
|
||||
|
||||
reset_instance_transformation(upper, instance, cut_matrix,
|
||||
attributes.has(ModelObjectCutAttribute::PlaceOnCutUpper),
|
||||
attributes.has(ModelObjectCutAttribute::FlipUpper),
|
||||
local_displace);
|
||||
if (attributes.has(ModelObjectCutAttribute::KeepAsParts) && !upper->volumes.empty()) {
|
||||
reset_instance_transformation(upper, instance, cut_matrix);
|
||||
res.push_back(upper);
|
||||
}
|
||||
else {
|
||||
if (attributes.has(ModelObjectCutAttribute::KeepUpper) && !upper->volumes.empty()) {
|
||||
invalidate_translations(upper, instances[instance]);
|
||||
|
||||
if (attributes.has(ModelObjectCutAttribute::KeepLower) && !lower->volumes.empty()) {
|
||||
invalidate_translations(lower, instances[instance]);
|
||||
reset_instance_transformation(upper, instance, cut_matrix,
|
||||
attributes.has(ModelObjectCutAttribute::PlaceOnCutUpper),
|
||||
attributes.has(ModelObjectCutAttribute::FlipUpper),
|
||||
local_displace);
|
||||
res.push_back(upper);
|
||||
}
|
||||
|
||||
reset_instance_transformation(lower, instance, cut_matrix,
|
||||
attributes.has(ModelObjectCutAttribute::PlaceOnCutLower),
|
||||
attributes.has(ModelObjectCutAttribute::PlaceOnCutLower) ? true : attributes.has(ModelObjectCutAttribute::FlipLower));
|
||||
res.push_back(lower);
|
||||
}
|
||||
if (attributes.has(ModelObjectCutAttribute::KeepLower) && !lower->volumes.empty()) {
|
||||
invalidate_translations(lower, instances[instance]);
|
||||
|
||||
if (attributes.has(ModelObjectCutAttribute::CreateDowels) && !dowels.empty()) {
|
||||
for (auto dowel : dowels) {
|
||||
invalidate_translations(dowel, instances[instance]);
|
||||
reset_instance_transformation(lower, instance, cut_matrix,
|
||||
attributes.has(ModelObjectCutAttribute::PlaceOnCutLower),
|
||||
attributes.has(ModelObjectCutAttribute::PlaceOnCutLower) ? true : attributes.has(ModelObjectCutAttribute::FlipLower));
|
||||
res.push_back(lower);
|
||||
}
|
||||
|
||||
reset_instance_transformation(dowel, instance, Transform3d::Identity(), false, false, local_dowels_displace);
|
||||
if (attributes.has(ModelObjectCutAttribute::CreateDowels) && !dowels.empty()) {
|
||||
for (auto dowel : dowels) {
|
||||
invalidate_translations(dowel, instances[instance]);
|
||||
|
||||
local_dowels_displace += dowel->full_raw_mesh_bounding_box().size().cwiseProduct(Vec3d(-1.5, -1.5, 0.0));
|
||||
dowel->name += "-Dowel-" + dowel->volumes[0]->name;
|
||||
res.push_back(dowel);
|
||||
reset_instance_transformation(dowel, instance, Transform3d::Identity(), false, false, local_dowels_displace);
|
||||
|
||||
local_dowels_displace += dowel->full_raw_mesh_bounding_box().size().cwiseProduct(Vec3d(-1.5, -1.5, 0.0));
|
||||
dowel->name += "-Dowel-" + dowel->volumes[0]->name;
|
||||
res.push_back(dowel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -316,7 +316,7 @@ enum class ModelVolumeType : int {
|
|||
SUPPORT_ENFORCER,
|
||||
};
|
||||
|
||||
enum class ModelObjectCutAttribute : int { KeepUpper, KeepLower, FlipUpper, FlipLower, PlaceOnCutUpper, PlaceOnCutLower, CreateDowels };
|
||||
enum class ModelObjectCutAttribute : int { KeepUpper, KeepLower, KeepAsParts, FlipUpper, FlipLower, PlaceOnCutUpper, PlaceOnCutLower, CreateDowels, InvalidateCutInfo };
|
||||
using ModelObjectCutAttributes = enum_bitmask<ModelObjectCutAttribute>;
|
||||
ENABLE_ENUM_BITMASK_OPERATORS(ModelObjectCutAttribute);
|
||||
|
||||
|
|
|
@ -443,6 +443,7 @@ static std::vector<std::string> s_Preset_print_options {
|
|||
"enable_dynamic_overhang_speeds", "dynamic_overhang_speeds", "overhang_overlap_levels",
|
||||
"top_solid_infill_speed", "support_material_speed", "support_material_xy_spacing", "support_material_interface_speed",
|
||||
"bridge_speed", "gap_fill_speed", "gap_fill_enabled", "travel_speed", "travel_speed_z", "first_layer_speed", "first_layer_speed_over_raft", "perimeter_acceleration", "infill_acceleration",
|
||||
"external_perimeter_acceleration", "top_solid_infill_acceleration", "solid_infill_acceleration",
|
||||
"bridge_acceleration", "first_layer_acceleration", "first_layer_acceleration_over_raft", "default_acceleration", "skirts", "skirt_distance", "skirt_height", "draft_shield",
|
||||
"min_skirt_length", "brim_width", "brim_separation", "brim_type", "support_material", "support_material_auto", "support_material_threshold", "support_material_enforce_layers",
|
||||
"raft_layers", "raft_first_layer_density", "raft_first_layer_expansion", "raft_contact_distance", "raft_expansion",
|
||||
|
|
|
@ -74,6 +74,7 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n
|
|||
"duplicate_distance",
|
||||
"end_gcode",
|
||||
"end_filament_gcode",
|
||||
"external_perimeter_acceleration",
|
||||
"extrusion_axis",
|
||||
"extruder_clearance_height",
|
||||
"extruder_clearance_radius",
|
||||
|
@ -125,10 +126,12 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n
|
|||
"retract_speed",
|
||||
"single_extruder_multi_material_priming",
|
||||
"slowdown_below_layer_time",
|
||||
"solid_infill_acceleration",
|
||||
"standby_temperature_delta",
|
||||
"start_gcode",
|
||||
"start_filament_gcode",
|
||||
"toolchange_gcode",
|
||||
"top_solid_infill_acceleration",
|
||||
"thumbnails",
|
||||
"thumbnails_format",
|
||||
"use_firmware_retraction",
|
||||
|
|
|
@ -1398,12 +1398,31 @@ void PrintConfigDef::init_fff_params()
|
|||
def = this->add("infill_acceleration", coFloat);
|
||||
def->label = L("Infill");
|
||||
def->tooltip = L("This is the acceleration your printer will use for infill. Set zero to disable "
|
||||
"acceleration control for infill.");
|
||||
"acceleration control for infill.");
|
||||
def->sidetext = L("mm/s²");
|
||||
def->min = 0;
|
||||
def->mode = comExpert;
|
||||
def->set_default_value(new ConfigOptionFloat(0));
|
||||
|
||||
def = this->add("solid_infill_acceleration", coFloat);
|
||||
def->label = L("Solid infill");
|
||||
def->tooltip = L("This is the acceleration your printer will use for solid infill. Set zero to use "
|
||||
"the value for infill.");
|
||||
def->sidetext = L("mm/s²");
|
||||
def->min = 0;
|
||||
def->mode = comExpert;
|
||||
def->set_default_value(new ConfigOptionFloat(0));
|
||||
|
||||
def = this->add("top_solid_infill_acceleration", coFloat);
|
||||
def->label = L("Top solid infill");
|
||||
def->tooltip = L("This is the acceleration your printer will use for top solid infill. Set zero to use "
|
||||
"the value for solid infill.");
|
||||
def->sidetext = L("mm/s²");
|
||||
def->min = 0;
|
||||
def->mode = comExpert;
|
||||
def->set_default_value(new ConfigOptionFloat(0));
|
||||
|
||||
|
||||
def = this->add("infill_every_layers", coInt);
|
||||
def->label = L("Combine infill every");
|
||||
def->category = L("Infill");
|
||||
|
@ -1950,6 +1969,14 @@ void PrintConfigDef::init_fff_params()
|
|||
def->mode = comExpert;
|
||||
def->set_default_value(new ConfigOptionFloat(0));
|
||||
|
||||
def = this->add("external_perimeter_acceleration", coFloat);
|
||||
def->label = L("External perimeters");
|
||||
def->tooltip = L("This is the acceleration your printer will use for external perimeters. "
|
||||
"Set zero to use the value for perimeters.");
|
||||
def->sidetext = L("mm/s²");
|
||||
def->mode = comExpert;
|
||||
def->set_default_value(new ConfigOptionFloat(0));
|
||||
|
||||
def = this->add("perimeter_extruder", coInt);
|
||||
def->label = L("Perimeter extruder");
|
||||
def->category = L("Extruders");
|
||||
|
|
|
@ -755,6 +755,7 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE(
|
|||
((ConfigOptionInts, disable_fan_first_layers))
|
||||
((ConfigOptionEnum<DraftShield>, draft_shield))
|
||||
((ConfigOptionFloat, duplicate_distance))
|
||||
((ConfigOptionFloat, external_perimeter_acceleration))
|
||||
((ConfigOptionFloat, extruder_clearance_height))
|
||||
((ConfigOptionFloat, extruder_clearance_radius))
|
||||
((ConfigOptionStrings, extruder_colour))
|
||||
|
@ -797,12 +798,14 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE(
|
|||
((ConfigOptionInt, skirt_height))
|
||||
((ConfigOptionInt, skirts))
|
||||
((ConfigOptionInts, slowdown_below_layer_time))
|
||||
((ConfigOptionFloat, solid_infill_acceleration))
|
||||
((ConfigOptionBool, spiral_vase))
|
||||
((ConfigOptionInt, standby_temperature_delta))
|
||||
((ConfigOptionInts, temperature))
|
||||
((ConfigOptionInt, threads))
|
||||
((ConfigOptionPoints, thumbnails))
|
||||
((ConfigOptionEnum<GCodeThumbnailsFormat>, thumbnails_format))
|
||||
((ConfigOptionFloat, top_solid_infill_acceleration))
|
||||
((ConfigOptionBools, wipe))
|
||||
((ConfigOptionBool, wipe_tower))
|
||||
((ConfigOptionFloat, wipe_tower_x))
|
||||
|
|
|
@ -814,6 +814,10 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disab
|
|||
|
||||
shader->set_uniform("z_range", m_z_range);
|
||||
shader->set_uniform("clipping_plane", m_clipping_plane);
|
||||
shader->set_uniform("use_color_clip_plane", m_use_color_clip_plane);
|
||||
shader->set_uniform("color_clip_plane", m_color_clip_plane);
|
||||
shader->set_uniform("uniform_color_clip_plane_1", m_color_clip_plane_colors[0]);
|
||||
shader->set_uniform("uniform_color_clip_plane_2", m_color_clip_plane_colors[1]);
|
||||
shader->set_uniform("print_volume.type", static_cast<int>(m_print_volume.type));
|
||||
shader->set_uniform("print_volume.xy_data", m_print_volume.data);
|
||||
shader->set_uniform("print_volume.z_data", m_print_volume.zs);
|
||||
|
|
|
@ -387,6 +387,12 @@ private:
|
|||
// plane coeffs for clipping in shaders
|
||||
std::array<double, 4> m_clipping_plane;
|
||||
|
||||
// plane coeffs for render volumes with different colors in shaders
|
||||
// used by cut gizmo
|
||||
std::array<double, 4> m_color_clip_plane;
|
||||
bool m_use_color_clip_plane{ false };
|
||||
std::array<ColorRGBA, 2> m_color_clip_plane_colors{ ColorRGBA::RED(), ColorRGBA::BLUE() };
|
||||
|
||||
struct Slope
|
||||
{
|
||||
// toggle for slope rendering
|
||||
|
@ -445,6 +451,14 @@ public:
|
|||
const std::array<float, 2>& get_z_range() const { return m_z_range; }
|
||||
const std::array<double, 4>& get_clipping_plane() const { return m_clipping_plane; }
|
||||
|
||||
void set_use_color_clip_plane(bool use) { m_use_color_clip_plane = use; }
|
||||
void set_color_clip_plane(const Vec3d& cp_normal, double offset) {
|
||||
for (int i = 0; i < 3; ++i)
|
||||
m_color_clip_plane[i] = -cp_normal[i];
|
||||
m_color_clip_plane[3] = offset;
|
||||
}
|
||||
void set_color_clip_plane_colors(const std::array<ColorRGBA, 2>& colors) { m_color_clip_plane_colors = colors; }
|
||||
|
||||
bool is_slope_active() const { return m_slope.active; }
|
||||
void set_slope_active(bool active) { m_slope.active = active; }
|
||||
|
||||
|
|
|
@ -261,7 +261,8 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig* config)
|
|||
toggle_field(el, has_top_solid_infill || (has_spiral_vase && has_bottom_solid_infill));
|
||||
|
||||
bool have_default_acceleration = config->opt_float("default_acceleration") > 0;
|
||||
for (auto el : { "perimeter_acceleration", "infill_acceleration",
|
||||
for (auto el : { "perimeter_acceleration", "infill_acceleration", "top_solid_infill_acceleration",
|
||||
"solid_infill_acceleration", "external_perimeter_acceleration"
|
||||
"bridge_acceleration", "first_layer_acceleration" })
|
||||
toggle_field(el, have_default_acceleration);
|
||||
|
||||
|
|
|
@ -712,6 +712,10 @@ public:
|
|||
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_use_color_clip_plane(bool use) { m_volumes.set_use_color_clip_plane(use); }
|
||||
void set_color_clip_plane(const Vec3d& cp_normal, double offset) { m_volumes.set_color_clip_plane(cp_normal, offset); }
|
||||
void set_color_clip_plane_colors(const std::array<ColorRGBA, 2>& colors) { m_volumes.set_color_clip_plane_colors(colors); }
|
||||
|
||||
void refresh_camera_scene_box();
|
||||
|
||||
BoundingBoxf3 volumes_bounding_box() const;
|
||||
|
|
|
@ -21,6 +21,8 @@ namespace Slic3r {
|
|||
namespace GUI {
|
||||
|
||||
static const ColorRGBA GRABBER_COLOR = ColorRGBA::YELLOW();
|
||||
static const ColorRGBA UPPER_PART_COLOR = ColorRGBA::CYAN();
|
||||
static const ColorRGBA LOWER_PART_COLOR = ColorRGBA::MAGENTA();
|
||||
|
||||
// connector colors
|
||||
static const ColorRGBA PLAG_COLOR = ColorRGBA::YELLOW();
|
||||
|
@ -196,7 +198,7 @@ static void init_from_angle_arc(GLModel& model, double angle, double radius)
|
|||
|
||||
GLGizmoCut3D::GLGizmoCut3D(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id)
|
||||
: GLGizmoBase(parent, icon_filename, sprite_id)
|
||||
, m_connectors_group_id (3)
|
||||
, m_connectors_group_id (GrabberID::Count)
|
||||
, m_connector_type (CutConnectorType::Plug)
|
||||
, m_connector_style (size_t(CutConnectorStyle::Prizm))
|
||||
, m_connector_shape_id (size_t(CutConnectorShape::Circle))
|
||||
|
@ -227,13 +229,19 @@ GLGizmoCut3D::GLGizmoCut3D(GLCanvas3D& parent, const std::string& icon_filename,
|
|||
|
||||
m_axis_names = { "X", "Y", "Z" };
|
||||
|
||||
m_part_orientation_names = {
|
||||
{"none", _L("Keep orientation")},
|
||||
{"on_cut", _L("Place on cut")},
|
||||
{"flip", _L("Flip upside down")},
|
||||
};
|
||||
|
||||
update_connector_shape();
|
||||
}
|
||||
|
||||
std::string GLGizmoCut3D::get_tooltip() const
|
||||
{
|
||||
std::string tooltip;
|
||||
if (m_hover_id == Z) {
|
||||
if (m_hover_id == Z || (m_dragging && m_hover_id == CutPlane)) {
|
||||
double koef = m_imperial_units ? ObjectManipulation::mm_to_in : 1.0;
|
||||
std::string unit_str = " " + (m_imperial_units ? _u8L("inch") : _u8L("mm"));
|
||||
const BoundingBoxf3 tbb = transformed_bounding_box(m_plane_center);
|
||||
|
@ -249,6 +257,11 @@ std::string GLGizmoCut3D::get_tooltip() const
|
|||
}
|
||||
return tooltip;
|
||||
}
|
||||
|
||||
if (!m_dragging && m_hover_id == CutPlane)
|
||||
return _u8L("Click to flip the cut plane\n"
|
||||
"Drag to move the cut plane");
|
||||
|
||||
if (tooltip.empty() && (m_hover_id == X || m_hover_id == Y)) {
|
||||
std::string axis = m_hover_id == X ? "X" : "Y";
|
||||
return axis + ": " + format(float(rad2deg(m_angle)), 1) + _u8L("°");
|
||||
|
@ -264,6 +277,8 @@ bool GLGizmoCut3D::on_mouse(const wxMouseEvent &mouse_event)
|
|||
|
||||
if (mouse_event.ShiftDown() && mouse_event.LeftDown())
|
||||
return gizmo_event(SLAGizmoEventType::LeftDown, mouse_pos, mouse_event.ShiftDown(), mouse_event.AltDown(), mouse_event.CmdDown());
|
||||
if (mouse_event.CmdDown() && mouse_event.LeftDown())
|
||||
return false;
|
||||
if (cut_line_processing()) {
|
||||
if (mouse_event.ShiftDown()) {
|
||||
if (mouse_event.Moving()|| mouse_event.Dragging())
|
||||
|
@ -278,11 +293,17 @@ bool GLGizmoCut3D::on_mouse(const wxMouseEvent &mouse_event)
|
|||
|
||||
if (use_grabbers(mouse_event)) {
|
||||
if (m_hover_id >= m_connectors_group_id) {
|
||||
if (mouse_event.LeftDown() && !mouse_event.CmdDown()&& !mouse_event.AltDown())
|
||||
if (mouse_event.LeftDown() && !mouse_event.CmdDown() && !mouse_event.AltDown())
|
||||
unselect_all_connectors();
|
||||
if (mouse_event.LeftUp() && !mouse_event.ShiftDown())
|
||||
gizmo_event(SLAGizmoEventType::LeftUp, mouse_pos, mouse_event.ShiftDown(), mouse_event.AltDown(), mouse_event.CmdDown());
|
||||
}
|
||||
else if (m_hover_id == CutPlane) {
|
||||
if (mouse_event.LeftDown())
|
||||
m_was_cut_plane_dragged = false;
|
||||
else if (mouse_event.LeftUp() && !m_was_cut_plane_dragged)
|
||||
flip_cut_plane();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -392,9 +413,18 @@ void GLGizmoCut3D::update_clipper()
|
|||
|
||||
// calculate normal for cut plane
|
||||
Vec3d normal = m_cut_normal = end - beg;
|
||||
m_cut_normal.normalize();
|
||||
|
||||
// calculate normal and offset for clipping plane
|
||||
double dist = (m_plane_center - beg).norm();
|
||||
dist = std::clamp(dist, 0.0001, normal.norm());
|
||||
normal.normalize();
|
||||
m_clp_normal = normal;
|
||||
double offset = normal.dot(beg) + dist;
|
||||
|
||||
m_parent.set_color_clip_plane(normal, offset);
|
||||
|
||||
if (!is_looking_forward()) {
|
||||
// recalculate normal and offset for clipping plane, if camera is looking downward to cut plane
|
||||
end = beg = m_plane_center;
|
||||
beg[Z] = box.center().z() + m_radius;
|
||||
end[Z] = box.center().z() - m_radius;
|
||||
|
@ -402,18 +432,16 @@ void GLGizmoCut3D::update_clipper()
|
|||
rotate_vec3d_around_plane_center(beg);
|
||||
rotate_vec3d_around_plane_center(end);
|
||||
|
||||
// recalculate normal for clipping plane, if camera is looking downward to cut plane
|
||||
normal = end - beg;
|
||||
if (normal == Vec3d::Zero())
|
||||
return;
|
||||
}
|
||||
|
||||
// calculate normal and offset for clipping plane
|
||||
double dist = (m_plane_center - beg).norm();
|
||||
dist = std::clamp(dist, 0.0001, normal.norm());
|
||||
normal.normalize();
|
||||
m_clp_normal = normal;
|
||||
const double offset = normal.dot(beg) + dist;
|
||||
dist = (m_plane_center - beg).norm();
|
||||
dist = std::clamp(dist, 0.0001, normal.norm());
|
||||
normal.normalize();
|
||||
m_clp_normal = normal;
|
||||
offset = normal.dot(beg) + dist;
|
||||
}
|
||||
|
||||
m_c->object_clipper()->set_range_and_pos(normal, offset, dist);
|
||||
|
||||
|
@ -656,12 +684,15 @@ void GLGizmoCut3D::render_cut_plane()
|
|||
shader->set_uniform("view_model_matrix", view_model_matrix);
|
||||
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
|
||||
|
||||
if (can_perform_cut() && has_valid_contour())
|
||||
// m_plane.set_color({ 0.8f, 0.8f, 0.8f, 0.5f });
|
||||
m_plane.set_color({ 0.9f, 0.9f, 0.9f, 0.5f });
|
||||
if (can_perform_cut() && has_valid_contour()) {
|
||||
if (m_hover_id == CutPlane)
|
||||
m_plane.model.set_color({ 0.9f, 0.9f, 0.9f, 0.5f });
|
||||
else
|
||||
m_plane.model.set_color({ 0.8f, 0.8f, 0.8f, 0.5f });
|
||||
}
|
||||
else
|
||||
m_plane.set_color({ 1.0f, 0.8f, 0.8f, 0.5f });
|
||||
m_plane.render();
|
||||
m_plane.model.set_color({ 1.0f, 0.8f, 0.8f, 0.5f });
|
||||
m_plane.model.render();
|
||||
|
||||
glsafe(::glEnable(GL_CULL_FACE));
|
||||
glsafe(::glDisable(GL_BLEND));
|
||||
|
@ -717,7 +748,7 @@ void GLGizmoCut3D::render_line(GLModel& line_model, const ColorRGBA& color, Tran
|
|||
}
|
||||
}
|
||||
|
||||
void GLGizmoCut3D::render_rotation_snapping(Axis axis, const ColorRGBA& color)
|
||||
void GLGizmoCut3D::render_rotation_snapping(GrabberID axis, const ColorRGBA& color)
|
||||
{
|
||||
GLShaderProgram* line_shader = OpenGLManager::get_gl_info().is_core_profile() ? wxGetApp().get_shader("dashed_thick_lines") : wxGetApp().get_shader("flat");
|
||||
if (!line_shader)
|
||||
|
@ -760,49 +791,34 @@ void GLGizmoCut3D::render_cut_plane_grabbers()
|
|||
{
|
||||
glsafe(::glClear(GL_DEPTH_BUFFER_BIT));
|
||||
|
||||
ColorRGBA color = m_hover_id == Z ? complementary(GRABBER_COLOR) : GRABBER_COLOR;
|
||||
ColorRGBA color = ColorRGBA::GRAY();
|
||||
|
||||
const Transform3d view_matrix = wxGetApp().plater()->get_camera().get_view_matrix() * translation_transform(m_plane_center) * m_rotation_m;
|
||||
|
||||
const double mean_size = get_grabber_mean_size(bounding_box());
|
||||
double size;
|
||||
|
||||
double size = m_dragging && m_hover_id == Z ? get_dragging_half_size(mean_size) : get_half_size(mean_size);
|
||||
const bool dragging_by_cut_plane = m_dragging && m_hover_id == CutPlane;
|
||||
|
||||
Vec3d cone_scale = Vec3d(0.75 * size, 0.75 * size, 1.8 * size);
|
||||
Vec3d offset = 1.25 * size * Vec3d::UnitZ();
|
||||
if (!dragging_by_cut_plane) {
|
||||
render_grabber_connection(GRABBER_COLOR, view_matrix);
|
||||
|
||||
// render Z grabber
|
||||
|
||||
if (!m_dragging && m_hover_id < 0)
|
||||
render_grabber_connection(color, view_matrix);
|
||||
render_model(m_sphere.model, color, view_matrix * scale_transform(size));
|
||||
|
||||
if ((!m_dragging && m_hover_id < 0) || m_hover_id == Z)
|
||||
{
|
||||
const BoundingBoxf3 tbb = transformed_bounding_box(m_plane_center);
|
||||
if (tbb.min.z() <= 0.0)
|
||||
render_model(m_cone.model, color, view_matrix * translation_transform(-offset) * rotation_transform(PI * Vec3d::UnitX()) * scale_transform(cone_scale));
|
||||
|
||||
if (tbb.max.z() >= 0.0)
|
||||
render_model(m_cone.model, color, view_matrix * translation_transform(offset) * scale_transform(cone_scale));
|
||||
}
|
||||
|
||||
// render top sphere for X/Y grabbers
|
||||
|
||||
if ((!m_dragging && m_hover_id < 0) || m_hover_id == X || m_hover_id == Y)
|
||||
{
|
||||
// render sphere grabber
|
||||
size = m_dragging ? get_dragging_half_size(mean_size) : get_half_size(mean_size);
|
||||
color = m_hover_id == Y ? complementary(ColorRGBA::GREEN()) :
|
||||
m_hover_id == X ? complementary(ColorRGBA::RED()) : ColorRGBA::GRAY();
|
||||
color = m_hover_id == Y ? complementary(ColorRGBA::GREEN()) :
|
||||
m_hover_id == X ? complementary(ColorRGBA::RED()) :
|
||||
m_hover_id == Z ? GRABBER_COLOR : ColorRGBA::GRAY();
|
||||
render_model(m_sphere.model, color, view_matrix * translation_transform(m_grabber_connection_len * Vec3d::UnitZ()) * scale_transform(size));
|
||||
}
|
||||
|
||||
const bool no_one_grabber_hovered = !m_dragging && (m_hover_id < 0 || m_hover_id == CutPlane);
|
||||
|
||||
// render X grabber
|
||||
|
||||
if ((!m_dragging && m_hover_id < 0) || m_hover_id == X)
|
||||
if (no_one_grabber_hovered || m_hover_id == X)
|
||||
{
|
||||
size = m_dragging && m_hover_id == X ? get_dragging_half_size(mean_size) : get_half_size(mean_size);
|
||||
cone_scale = Vec3d(0.75 * size, 0.75 * size, 1.8 * size);
|
||||
const Vec3d cone_scale = Vec3d(0.75 * size, 0.75 * size, 1.8 * size);
|
||||
color = m_hover_id == X ? complementary(ColorRGBA::RED()) : ColorRGBA::RED();
|
||||
|
||||
if (m_hover_id == X) {
|
||||
|
@ -810,7 +826,7 @@ void GLGizmoCut3D::render_cut_plane_grabbers()
|
|||
render_rotation_snapping(X, color);
|
||||
}
|
||||
|
||||
offset = Vec3d(0.0, 1.25 * size, m_grabber_connection_len);
|
||||
Vec3d offset = Vec3d(0.0, 1.25 * size, m_grabber_connection_len);
|
||||
render_model(m_cone.model, color, view_matrix * translation_transform(offset) * rotation_transform(-0.5 * PI * Vec3d::UnitX()) * scale_transform(cone_scale));
|
||||
offset = Vec3d(0.0, -1.25 * size, m_grabber_connection_len);
|
||||
render_model(m_cone.model, color, view_matrix * translation_transform(offset) * rotation_transform(0.5 * PI * Vec3d::UnitX()) * scale_transform(cone_scale));
|
||||
|
@ -818,10 +834,10 @@ void GLGizmoCut3D::render_cut_plane_grabbers()
|
|||
|
||||
// render Y grabber
|
||||
|
||||
if ((!m_dragging && m_hover_id < 0) || m_hover_id == Y)
|
||||
if (no_one_grabber_hovered || m_hover_id == Y)
|
||||
{
|
||||
size = m_dragging && m_hover_id == Y ? get_dragging_half_size(mean_size) : get_half_size(mean_size);
|
||||
cone_scale = Vec3d(0.75 * size, 0.75 * size, 1.8 * size);
|
||||
const Vec3d cone_scale = Vec3d(0.75 * size, 0.75 * size, 1.8 * size);
|
||||
color = m_hover_id == Y ? complementary(ColorRGBA::GREEN()) : ColorRGBA::GREEN();
|
||||
|
||||
if (m_hover_id == Y) {
|
||||
|
@ -829,7 +845,7 @@ void GLGizmoCut3D::render_cut_plane_grabbers()
|
|||
render_rotation_snapping(Y, color);
|
||||
}
|
||||
|
||||
offset = Vec3d(1.25 * size, 0.0, m_grabber_connection_len);
|
||||
Vec3d offset = Vec3d(1.25 * size, 0.0, m_grabber_connection_len);
|
||||
render_model(m_cone.model, color, view_matrix * translation_transform(offset) * rotation_transform(0.5 * PI * Vec3d::UnitY()) * scale_transform(cone_scale));
|
||||
offset = Vec3d(-1.25 * size, 0.0, m_grabber_connection_len);
|
||||
render_model(m_cone.model, color, view_matrix * translation_transform(offset)* rotation_transform(-0.5 * PI * Vec3d::UnitY()) * scale_transform(cone_scale));
|
||||
|
@ -898,6 +914,9 @@ std::string GLGizmoCut3D::on_get_name() const
|
|||
void GLGizmoCut3D::on_set_state()
|
||||
{
|
||||
if (m_state == On) {
|
||||
m_parent.set_use_color_clip_plane(true);
|
||||
m_parent.set_color_clip_plane_colors({ UPPER_PART_COLOR , LOWER_PART_COLOR });
|
||||
|
||||
update_bb();
|
||||
m_connectors_editing = !m_selected.empty();
|
||||
|
||||
|
@ -913,6 +932,7 @@ void GLGizmoCut3D::on_set_state()
|
|||
oc->release();
|
||||
}
|
||||
m_selected.clear();
|
||||
m_parent.set_use_color_clip_plane(false);
|
||||
}
|
||||
force_update_clipper_on_render = m_state == On;
|
||||
}
|
||||
|
@ -940,8 +960,8 @@ void GLGizmoCut3D::on_register_raycasters_for_picking()
|
|||
m_raycasters.emplace_back(m_parent.add_raycaster_for_picking(SceneRaycaster::EType::Gizmo, Y, *m_cone.mesh_raycaster, Transform3d::Identity()));
|
||||
|
||||
m_raycasters.emplace_back(m_parent.add_raycaster_for_picking(SceneRaycaster::EType::Gizmo, Z, *m_sphere.mesh_raycaster, Transform3d::Identity()));
|
||||
m_raycasters.emplace_back(m_parent.add_raycaster_for_picking(SceneRaycaster::EType::Gizmo, Z, *m_cone.mesh_raycaster, Transform3d::Identity()));
|
||||
m_raycasters.emplace_back(m_parent.add_raycaster_for_picking(SceneRaycaster::EType::Gizmo, Z, *m_cone.mesh_raycaster, Transform3d::Identity()));
|
||||
|
||||
m_raycasters.emplace_back(m_parent.add_raycaster_for_picking(SceneRaycaster::EType::Gizmo, CutPlane, *m_plane.mesh_raycaster, Transform3d::Identity()));
|
||||
}
|
||||
|
||||
update_raycasters_for_picking_transform();
|
||||
|
@ -1018,20 +1038,22 @@ void GLGizmoCut3D::update_raycasters_for_picking_transform()
|
|||
const double size = get_half_size(get_grabber_mean_size(box));
|
||||
Vec3d scale = Vec3d(0.75 * size, 0.75 * size, 1.8 * size);
|
||||
|
||||
int id = 0;
|
||||
|
||||
Vec3d offset = Vec3d(0.0, 1.25 * size, m_grabber_connection_len);
|
||||
m_raycasters[0]->set_transform(trafo * translation_transform(offset) * rotation_transform(-0.5 * PI * Vec3d::UnitX()) * scale_transform(scale));
|
||||
m_raycasters[id++]->set_transform(trafo * translation_transform(offset) * rotation_transform(-0.5 * PI * Vec3d::UnitX()) * scale_transform(scale));
|
||||
offset = Vec3d(0.0, -1.25 * size, m_grabber_connection_len);
|
||||
m_raycasters[1]->set_transform(trafo * translation_transform(offset) * rotation_transform(0.5 * PI * Vec3d::UnitX()) * scale_transform(scale));
|
||||
m_raycasters[id++]->set_transform(trafo * translation_transform(offset) * rotation_transform(0.5 * PI * Vec3d::UnitX()) * scale_transform(scale));
|
||||
|
||||
offset = Vec3d(1.25 * size, 0.0, m_grabber_connection_len);
|
||||
m_raycasters[2]->set_transform(trafo * translation_transform(offset) * rotation_transform(0.5 * PI * Vec3d::UnitY()) * scale_transform(scale));
|
||||
m_raycasters[id++]->set_transform(trafo * translation_transform(offset) * rotation_transform(0.5 * PI * Vec3d::UnitY()) * scale_transform(scale));
|
||||
offset = Vec3d(-1.25 * size, 0.0, m_grabber_connection_len);
|
||||
m_raycasters[3]->set_transform(trafo * translation_transform(offset) * rotation_transform(-0.5 * PI * Vec3d::UnitY()) * scale_transform(scale));
|
||||
m_raycasters[id++]->set_transform(trafo * translation_transform(offset) * rotation_transform(-0.5 * PI * Vec3d::UnitY()) * scale_transform(scale));
|
||||
|
||||
offset = 1.25 * size * Vec3d::UnitZ();
|
||||
m_raycasters[4]->set_transform(trafo * scale_transform(size));
|
||||
m_raycasters[5]->set_transform(trafo * translation_transform(-offset) * rotation_transform(PI * Vec3d::UnitX()) * scale_transform(scale));
|
||||
m_raycasters[6]->set_transform(trafo * translation_transform(offset) * scale_transform(scale));
|
||||
m_raycasters[id++]->set_transform(trafo * translation_transform(m_grabber_connection_len * Vec3d::UnitZ()) * scale_transform(size));
|
||||
|
||||
m_raycasters[id++]->set_transform(trafo);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1046,25 +1068,16 @@ bool GLGizmoCut3D::on_is_activable() const
|
|||
if (object_idx < 0 || selection.is_wipe_tower())
|
||||
return false;
|
||||
|
||||
bool is_dowel_object = false;
|
||||
if (const ModelObject* mo = wxGetApp().plater()->model().objects[object_idx]; mo->is_cut()) {
|
||||
int solid_connector_cnt = 0;
|
||||
int connectors_cnt = 0;
|
||||
for (const ModelVolume* volume : mo->volumes) {
|
||||
if (volume->is_cut_connector()) {
|
||||
connectors_cnt++;
|
||||
if (volume->is_model_part())
|
||||
solid_connector_cnt++;
|
||||
}
|
||||
if (connectors_cnt > 1)
|
||||
break;
|
||||
}
|
||||
is_dowel_object = connectors_cnt == 1 && solid_connector_cnt == 1;
|
||||
if (const ModelObject* mo = wxGetApp().plater()->model().objects[object_idx];
|
||||
mo->is_cut() && mo->volumes.size() == 1) {
|
||||
const ModelVolume* volume = mo->volumes[0];
|
||||
if (volume->is_cut_connector() && volume->cut_info.connector_type == CutConnectorType::Dowel)
|
||||
return false;
|
||||
}
|
||||
|
||||
// This is assumed in GLCanvas3D::do_rotate, do not change this
|
||||
// without updating that function too.
|
||||
return selection.is_single_full_instance() && !is_dowel_object && !m_parent.is_layers_editing_enabled();
|
||||
return selection.is_single_full_instance() && !m_parent.is_layers_editing_enabled();
|
||||
}
|
||||
|
||||
bool GLGizmoCut3D::on_is_selectable() const
|
||||
|
@ -1072,7 +1085,7 @@ bool GLGizmoCut3D::on_is_selectable() const
|
|||
return wxGetApp().get_mode() != comSimple;
|
||||
}
|
||||
|
||||
Vec3d GLGizmoCut3D::mouse_position_in_local_plane(Axis axis, const Linef3& mouse_ray) const
|
||||
Vec3d GLGizmoCut3D::mouse_position_in_local_plane(GrabberID axis, const Linef3& mouse_ray) const
|
||||
{
|
||||
double half_pi = 0.5 * PI;
|
||||
|
||||
|
@ -1108,13 +1121,11 @@ Vec3d GLGizmoCut3D::mouse_position_in_local_plane(Axis axis, const Linef3& mouse
|
|||
|
||||
void GLGizmoCut3D::dragging_grabber_z(const GLGizmoBase::UpdateData &data)
|
||||
{
|
||||
Vec3d starting_box_center = m_plane_center - Vec3d::UnitZ(); // some Margin
|
||||
rotate_vec3d_around_plane_center(starting_box_center);
|
||||
const Vec3d grabber_init_pos = (m_hover_id == CutPlane ? 0. : m_grabber_connection_len) * Vec3d::UnitZ();
|
||||
const Vec3d starting_drag_position = translation_transform(m_plane_center) * m_rotation_m * grabber_init_pos;
|
||||
double projection = 0.0;
|
||||
|
||||
const Vec3d&starting_drag_position = m_plane_center;
|
||||
double projection = 0.0;
|
||||
|
||||
Vec3d starting_vec = starting_drag_position - starting_box_center;
|
||||
Vec3d starting_vec = m_rotation_m * Vec3d::UnitZ();
|
||||
if (starting_vec.norm() != 0.0) {
|
||||
const Vec3d mouse_dir = data.mouse_ray.unit_vector();
|
||||
// finds the intersection of the mouse ray with the plane parallel to the camera viewport and passing throught the starting position
|
||||
|
@ -1130,17 +1141,19 @@ void GLGizmoCut3D::dragging_grabber_z(const GLGizmoBase::UpdateData &data)
|
|||
projection = inters_vec.dot(starting_vec);
|
||||
}
|
||||
if (wxGetKeyState(WXK_SHIFT))
|
||||
projection = m_snap_step * (double)std::round(projection / m_snap_step);
|
||||
projection = m_snap_step * std::round(projection / m_snap_step);
|
||||
|
||||
const Vec3d shift = starting_vec * projection;
|
||||
|
||||
// move cut plane center
|
||||
set_center(m_plane_center + shift);
|
||||
|
||||
m_was_cut_plane_dragged = true;
|
||||
}
|
||||
|
||||
void GLGizmoCut3D::dragging_grabber_xy(const GLGizmoBase::UpdateData &data)
|
||||
{
|
||||
const Vec2d mouse_pos = to_2d(mouse_position_in_local_plane((Axis)m_hover_id, data.mouse_ray));
|
||||
const Vec2d mouse_pos = to_2d(mouse_position_in_local_plane((GrabberID)m_hover_id, data.mouse_ray));
|
||||
|
||||
const Vec2d orig_dir = Vec2d::UnitX();
|
||||
const Vec2d new_dir = mouse_pos.normalized();
|
||||
|
@ -1197,7 +1210,7 @@ void GLGizmoCut3D::on_dragging(const UpdateData& data)
|
|||
{
|
||||
if (m_hover_id < 0)
|
||||
return;
|
||||
if (m_hover_id == Z)
|
||||
if (m_hover_id == Z || m_hover_id == CutPlane)
|
||||
dragging_grabber_z(data);
|
||||
else if (m_hover_id == X || m_hover_id == Y)
|
||||
dragging_grabber_xy(data);
|
||||
|
@ -1223,8 +1236,9 @@ void GLGizmoCut3D::on_stop_dragging()
|
|||
Plater::TakeSnapshot snapshot(wxGetApp().plater(), _L("Rotate cut plane"), UndoRedo::SnapshotType::GizmoAction);
|
||||
m_start_dragging_m = m_rotation_m;
|
||||
}
|
||||
else if (m_hover_id == Z) {
|
||||
Plater::TakeSnapshot snapshot(wxGetApp().plater(), _L("Move cut plane"), UndoRedo::SnapshotType::GizmoAction);
|
||||
else if (m_hover_id == Z || m_hover_id == CutPlane) {
|
||||
if (m_was_cut_plane_dragged)
|
||||
Plater::TakeSnapshot snapshot(wxGetApp().plater(), _L("Move cut plane"), UndoRedo::SnapshotType::GizmoAction);
|
||||
m_ar_plane_center = m_plane_center;
|
||||
}
|
||||
}
|
||||
|
@ -1332,7 +1346,7 @@ bool GLGizmoCut3D::update_bb()
|
|||
set_center_pos(m_bb_center, true);
|
||||
|
||||
m_radius = box.radius();
|
||||
m_grabber_connection_len = 0.75 * m_radius;// std::min<double>(0.75 * m_radius, 35.0);
|
||||
m_grabber_connection_len = 0.5 * m_radius;// std::min<double>(0.75 * m_radius, 35.0);
|
||||
m_grabber_radius = m_grabber_connection_len * 0.85;
|
||||
|
||||
m_snap_coarse_in_radius = m_grabber_radius / 3.0;
|
||||
|
@ -1372,6 +1386,14 @@ void GLGizmoCut3D::init_picking_models()
|
|||
m_sphere.model.init_from(its);
|
||||
m_sphere.mesh_raycaster = std::make_unique<MeshRaycaster>(std::make_shared<const TriangleMesh>(std::move(its)));
|
||||
}
|
||||
|
||||
if (!m_plane.model.is_initialized() && !m_hide_cut_plane && !m_connectors_editing) {
|
||||
const double cp_width = 0.02 * get_grabber_mean_size(bounding_box());
|
||||
indexed_triangle_set its = its_make_frustum_dowel((double)m_cut_plane_radius_koef * m_radius, cp_width, m_cut_plane_as_circle ? 180 : 4);
|
||||
m_plane.model.init_from(its);
|
||||
m_plane.mesh_raycaster = std::make_unique<MeshRaycaster>(std::make_shared<const TriangleMesh>(std::move(its)));
|
||||
}
|
||||
|
||||
if (m_shapes.empty())
|
||||
init_connector_shapes();
|
||||
}
|
||||
|
@ -1392,18 +1414,6 @@ void GLGizmoCut3D::init_rendering_items()
|
|||
}
|
||||
if (!m_angle_arc.is_initialized() || m_angle != 0.0)
|
||||
init_from_angle_arc(m_angle_arc, m_angle, m_grabber_connection_len);
|
||||
|
||||
if (!m_plane.is_initialized() && !m_hide_cut_plane && !m_connectors_editing) {
|
||||
#if 1
|
||||
const double cp_width = 0.02 * get_grabber_mean_size(bounding_box());
|
||||
m_plane.init_from(its_make_frustum_dowel((double)m_cut_plane_radius_koef * m_radius, cp_width, m_cut_plane_as_circle ? 180 : 4));
|
||||
#else
|
||||
if (m_cut_plane_as_circle)
|
||||
m_plane.init_from(its_make_frustum_dowel(2. * m_radius, 0.3, 180));
|
||||
else
|
||||
m_plane.init_from(its_make_square_plane(float(m_radius)));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void GLGizmoCut3D::render_clipper_cut()
|
||||
|
@ -1566,6 +1576,8 @@ void GLGizmoCut3D::render_connectors_input_window(CutConnectors &connectors)
|
|||
reset_connectors();
|
||||
m_imgui->disabled_end();
|
||||
|
||||
render_flip_plane_button(m_connectors_editing && connectors.empty());
|
||||
|
||||
m_imgui->text(_L("Type"));
|
||||
bool type_changed = render_connect_type_radio_button(CutConnectorType::Plug);
|
||||
type_changed |= render_connect_type_radio_button(CutConnectorType::Dowel);
|
||||
|
@ -1660,6 +1672,57 @@ void GLGizmoCut3D::set_connectors_editing(bool connectors_editing)
|
|||
m_parent.request_extra_frame();
|
||||
}
|
||||
|
||||
void GLGizmoCut3D::flip_cut_plane()
|
||||
{
|
||||
m_rotation_m = m_rotation_m * rotation_transform(PI * Vec3d::UnitX());
|
||||
Plater::TakeSnapshot snapshot(wxGetApp().plater(), _L("Flip cut plane"), UndoRedo::SnapshotType::GizmoAction);
|
||||
m_start_dragging_m = m_rotation_m;
|
||||
|
||||
update_clipper();
|
||||
}
|
||||
|
||||
void GLGizmoCut3D::render_flip_plane_button(bool disable_pred /*=false*/)
|
||||
{
|
||||
ImGui::SameLine(2.5 * m_label_width);
|
||||
|
||||
if (m_hover_id == CutPlane)
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, ImGui::GetColorU32(ImGuiCol_ButtonHovered));
|
||||
|
||||
m_imgui->disabled_begin(disable_pred);
|
||||
if (m_imgui->button(_L("Flip cut plane")))
|
||||
flip_cut_plane();
|
||||
m_imgui->disabled_end();
|
||||
|
||||
if (m_hover_id == CutPlane)
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
|
||||
void GLGizmoCut3D::add_vertical_scaled_interval(float interval)
|
||||
{
|
||||
ImGui::GetCurrentWindow()->DC.CursorPos.y += m_imgui->scaled(interval);
|
||||
}
|
||||
|
||||
void GLGizmoCut3D::add_horizontal_scaled_interval(float interval)
|
||||
{
|
||||
ImGui::GetCurrentWindow()->DC.CursorPos.x += m_imgui->scaled(interval);
|
||||
}
|
||||
|
||||
void GLGizmoCut3D::add_horizontal_shift(float shift)
|
||||
{
|
||||
ImGui::GetCurrentWindow()->DC.CursorPos.x += shift;
|
||||
}
|
||||
|
||||
void GLGizmoCut3D::render_color_marker(float size, const ImU32& color)
|
||||
{
|
||||
ImGui::SameLine();
|
||||
const float radius = 0.5f * size;
|
||||
ImVec2 pos = ImGui::GetCurrentWindow()->DC.CursorPos;
|
||||
pos.x += size;
|
||||
pos.y += 1.25f * radius;
|
||||
ImGui::GetCurrentWindow()->DrawList->AddNgonFilled(pos, radius, color, 6);
|
||||
ImGuiWrapper::text(" ");
|
||||
}
|
||||
|
||||
void GLGizmoCut3D::render_cut_plane_input_window(CutConnectors &connectors)
|
||||
{
|
||||
// WIP : cut plane mode
|
||||
|
@ -1667,65 +1730,130 @@ void GLGizmoCut3D::render_cut_plane_input_window(CutConnectors &connectors)
|
|||
|
||||
if (m_mode == size_t(CutMode::cutPlanar)) {
|
||||
ImGui::AlignTextToFramePadding();
|
||||
m_imgui->text(wxString(ImGui::InfoMarkerSmall));
|
||||
ImGuiWrapper::text(wxString(ImGui::InfoMarkerSmall));
|
||||
ImGui::SameLine();
|
||||
m_imgui->text_colored(ImGuiWrapper::COL_ORANGE_LIGHT,
|
||||
get_wraped_wxString(_L("Hold SHIFT key and connect some two points of an object to cut by line"), 40));
|
||||
ImGuiWrapper::text_colored(ImGuiWrapper::COL_ORANGE_LIGHT,
|
||||
get_wraped_wxString(_L("Hold SHIFT key to draw a cut line"), 40));
|
||||
ImGui::Separator();
|
||||
|
||||
render_build_size();
|
||||
|
||||
ImGui::AlignTextToFramePadding();
|
||||
m_imgui->text(_L("Cut position: "));
|
||||
ImGuiWrapper::text(_L("Cut position: "));
|
||||
ImGui::SameLine(m_label_width);
|
||||
render_move_center_input(Z);
|
||||
ImGui::SameLine();
|
||||
|
||||
const bool has_connectors = !connectors.empty();
|
||||
|
||||
const bool is_cut_plane_init = m_rotation_m.isApprox(Transform3d::Identity()) && bounding_box().center() == m_plane_center;
|
||||
m_imgui->disabled_begin(is_cut_plane_init);
|
||||
if (render_reset_button("cut_plane", _u8L("Reset cutting plane")))
|
||||
reset_cut_plane();
|
||||
if (render_reset_button("cut_plane", _u8L("Reset cutting plane")))
|
||||
reset_cut_plane();
|
||||
m_imgui->disabled_end();
|
||||
|
||||
m_imgui->disabled_begin(!m_keep_upper || !m_keep_lower);
|
||||
if (m_imgui->button(_L("Add/Edit connectors")))
|
||||
// render_flip_plane_button();
|
||||
|
||||
add_vertical_scaled_interval(0.75f);
|
||||
|
||||
m_imgui->disabled_begin(!m_keep_upper || !m_keep_lower || m_keep_as_parts);
|
||||
if (m_imgui->button(has_connectors ? _L("Edit connectors") : _L("Add connectors")))
|
||||
set_connectors_editing(true);
|
||||
m_imgui->disabled_end();
|
||||
|
||||
ImGui::SameLine(2.5f * m_label_width);
|
||||
|
||||
m_imgui->disabled_begin(is_cut_plane_init && !has_connectors);
|
||||
if (m_imgui->button(_L("Reset cut"), _L("Reset cutting plane and remove connectors"))) {
|
||||
reset_cut_plane();
|
||||
reset_connectors();
|
||||
}
|
||||
m_imgui->disabled_end();
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
float label_width = 0;
|
||||
for (const wxString& label : {_L("Upper part"), _L("Lower part")}) {
|
||||
const float width = m_imgui->calc_text_size(label).x + m_imgui->scaled(1.5f);
|
||||
if (label_width < width)
|
||||
label_width = width;
|
||||
// render "After Cut" section
|
||||
|
||||
ImVec2 label_size;
|
||||
for (const auto& item : m_part_orientation_names) {
|
||||
const ImVec2 text_size = ImGuiWrapper::calc_text_size(item.second);
|
||||
if (label_size.x < text_size.x)
|
||||
label_size.x = text_size.x;
|
||||
if (label_size.y < text_size.y)
|
||||
label_size.y = text_size.y;
|
||||
}
|
||||
|
||||
auto render_part_action_line = [this, label_width, connectors](const wxString& label, const wxString& suffix, bool& keep_part, bool& place_on_cut_part, bool& rotate_part) {
|
||||
const float h_shift = label_size.x + m_imgui->scaled(3.f);
|
||||
const float marker_size = label_size.y;
|
||||
|
||||
auto render_part_name = [this, marker_size, has_connectors](const wxString& name, bool& keep_part, const ImU32& color) {
|
||||
bool keep = true;
|
||||
ImGui::AlignTextToFramePadding();
|
||||
m_imgui->text(label);
|
||||
add_horizontal_shift(m_imgui->scaled(1.2f));
|
||||
m_imgui->checkbox((m_keep_as_parts ? _L("Part") : _L("Object")) + " " + name, has_connectors ? keep : keep_part);
|
||||
render_color_marker(marker_size, color);
|
||||
};
|
||||
|
||||
ImGui::SameLine(label_width);
|
||||
|
||||
m_imgui->disabled_begin(!connectors.empty());
|
||||
m_imgui->checkbox(_L("Keep") + suffix, connectors.empty() ? keep_part : keep);
|
||||
m_imgui->disabled_end();
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
m_imgui->disabled_begin(!keep_part);
|
||||
if (m_imgui->checkbox(_L("Place on cut") + suffix, place_on_cut_part))
|
||||
auto render_part_actions = [this, h_shift] (const wxString& suffix, const bool& keep_part, bool& place_on_cut_part, bool& rotate_part)
|
||||
{
|
||||
float shift = m_imgui->scaled(1.2f);
|
||||
if (suffix == "##lower")
|
||||
shift += h_shift;
|
||||
m_imgui->disabled_begin(!keep_part || m_keep_as_parts);
|
||||
add_horizontal_shift(shift);
|
||||
if (m_imgui->radio_button(m_part_orientation_names.at("none") + suffix, !place_on_cut_part && !rotate_part)) {
|
||||
rotate_part = false;
|
||||
ImGui::SameLine();
|
||||
if (m_imgui->checkbox(_L("Flip") + suffix, rotate_part))
|
||||
place_on_cut_part = false;
|
||||
}
|
||||
|
||||
add_horizontal_shift(shift);
|
||||
if (m_imgui->radio_button(m_part_orientation_names.at("on_cut") + suffix, place_on_cut_part)) {
|
||||
place_on_cut_part = !place_on_cut_part;
|
||||
rotate_part = false;
|
||||
}
|
||||
|
||||
add_horizontal_shift(shift);
|
||||
if (m_imgui->radio_button(m_part_orientation_names.at("flip") + suffix, rotate_part)) {
|
||||
rotate_part = !rotate_part;
|
||||
place_on_cut_part = false;
|
||||
}
|
||||
m_imgui->disabled_end();
|
||||
};
|
||||
|
||||
m_imgui->text(_L("After cut") + ": ");
|
||||
render_part_action_line( _L("Upper part"), "##upper", m_keep_upper, m_place_on_cut_upper, m_rotate_upper);
|
||||
render_part_action_line( _L("Lower part"), "##lower", m_keep_lower, m_place_on_cut_lower, m_rotate_lower);
|
||||
ImGuiWrapper::text(_L("After cut") + ": ");
|
||||
add_vertical_scaled_interval(0.5f);
|
||||
|
||||
m_imgui->disabled_begin(has_connectors || m_keep_as_parts);
|
||||
render_part_name("A", m_keep_upper, m_imgui->to_ImU32(UPPER_PART_COLOR));
|
||||
ImGui::SameLine(h_shift + ImGui::GetCurrentWindow()->WindowPadding.x);
|
||||
render_part_name("B", m_keep_lower, m_imgui->to_ImU32(LOWER_PART_COLOR));
|
||||
m_imgui->disabled_end();
|
||||
|
||||
add_vertical_scaled_interval(0.5f);
|
||||
|
||||
const ImVec2 pos = ImGui::GetCurrentWindow()->DC.CursorPos;
|
||||
render_part_actions("##upper", m_keep_upper, m_place_on_cut_upper, m_rotate_upper);
|
||||
|
||||
ImGui::GetCurrentWindow()->DC.CursorPos = pos;
|
||||
render_part_actions("##lower", m_keep_lower, m_place_on_cut_lower, m_rotate_lower);
|
||||
|
||||
add_vertical_scaled_interval(0.75f);
|
||||
|
||||
m_imgui->disabled_begin(has_connectors);
|
||||
add_horizontal_shift(m_imgui->scaled(/*1*/.2f));
|
||||
ImGuiWrapper::text(_L("Cut to") + ":");
|
||||
|
||||
ImGui::SameLine();
|
||||
if (m_imgui->radio_button(_L("Objects"), !m_keep_as_parts))
|
||||
m_keep_as_parts = false;
|
||||
ImGui::SameLine();
|
||||
if (m_imgui->radio_button(_L("Parts"), m_keep_as_parts))
|
||||
m_keep_as_parts = true;
|
||||
|
||||
if (m_keep_as_parts) {
|
||||
m_keep_upper = m_keep_lower = true;
|
||||
m_place_on_cut_upper = m_place_on_cut_lower = false;
|
||||
m_rotate_upper = m_rotate_lower = false;
|
||||
}
|
||||
m_imgui->disabled_end();
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
|
@ -2110,11 +2238,13 @@ void GLGizmoCut3D::perform_cut(const Selection& selection)
|
|||
plater->cut(object_idx, instance_idx, translation_transform(cut_center_offset) * m_rotation_m,
|
||||
only_if(has_connectors ? true : m_keep_upper, ModelObjectCutAttribute::KeepUpper) |
|
||||
only_if(has_connectors ? true : m_keep_lower, ModelObjectCutAttribute::KeepLower) |
|
||||
only_if(has_connectors ? false: m_keep_as_parts, ModelObjectCutAttribute::KeepAsParts) |
|
||||
only_if(m_place_on_cut_upper, ModelObjectCutAttribute::PlaceOnCutUpper) |
|
||||
only_if(m_place_on_cut_lower, ModelObjectCutAttribute::PlaceOnCutLower) |
|
||||
only_if(m_rotate_upper, ModelObjectCutAttribute::FlipUpper) |
|
||||
only_if(m_rotate_lower, ModelObjectCutAttribute::FlipLower) |
|
||||
only_if(create_dowels_as_separate_object, ModelObjectCutAttribute::CreateDowels));
|
||||
only_if(create_dowels_as_separate_object, ModelObjectCutAttribute::CreateDowels) |
|
||||
only_if(!has_connectors, ModelObjectCutAttribute::InvalidateCutInfo));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2349,7 +2479,7 @@ bool GLGizmoCut3D::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_posi
|
|||
if (is_dragging() || m_connector_mode == CutConnectorMode::Auto)
|
||||
return false;
|
||||
|
||||
if ( m_hover_id < 0 && shift_down && ! m_connectors_editing &&
|
||||
if ( (m_hover_id < 0 || m_hover_id == CutPlane) && shift_down && ! m_connectors_editing &&
|
||||
(action == SLAGizmoEventType::LeftDown || action == SLAGizmoEventType::LeftUp || action == SLAGizmoEventType::Moving) )
|
||||
return process_cut_line(action, mouse_position);
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "slic3r/GUI/GLModel.hpp"
|
||||
#include "libslic3r/TriangleMesh.hpp"
|
||||
#include "libslic3r/Model.hpp"
|
||||
#include "imgui/imgui.h"
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
|
@ -20,6 +21,14 @@ enum class SLAGizmoEventType : unsigned char;
|
|||
|
||||
class GLGizmoCut3D : public GLGizmoBase
|
||||
{
|
||||
enum GrabberID {
|
||||
X = 0,
|
||||
Y,
|
||||
Z,
|
||||
CutPlane,
|
||||
Count,
|
||||
};
|
||||
|
||||
Transform3d m_rotation_m{ Transform3d::Identity() };
|
||||
double m_snap_step{ 1.0 };
|
||||
int m_connectors_group_id;
|
||||
|
@ -57,10 +66,10 @@ class GLGizmoCut3D : public GLGizmoBase
|
|||
|
||||
Vec2d m_ldown_mouse_position{ Vec2d::Zero() };
|
||||
|
||||
GLModel m_plane;
|
||||
GLModel m_grabber_connection;
|
||||
GLModel m_cut_line;
|
||||
|
||||
PickingModel m_plane;
|
||||
PickingModel m_sphere;
|
||||
PickingModel m_cone;
|
||||
std::map<CutConnectorAttributes, PickingModel> m_shapes;
|
||||
|
@ -90,6 +99,7 @@ class GLGizmoCut3D : public GLGizmoBase
|
|||
|
||||
bool m_keep_upper{ true };
|
||||
bool m_keep_lower{ true };
|
||||
bool m_keep_as_parts{ false };
|
||||
bool m_place_on_cut_upper{ true };
|
||||
bool m_place_on_cut_lower{ false };
|
||||
bool m_rotate_upper{ false };
|
||||
|
@ -121,6 +131,7 @@ class GLGizmoCut3D : public GLGizmoBase
|
|||
GLSelectionRectangle m_selection_rectangle;
|
||||
|
||||
bool m_has_invalid_connector{ false };
|
||||
bool m_was_cut_plane_dragged { false };
|
||||
|
||||
bool m_show_shortcuts{ false };
|
||||
std::vector<std::pair<wxString, wxString>> m_shortcuts;
|
||||
|
@ -154,6 +165,8 @@ class GLGizmoCut3D : public GLGizmoBase
|
|||
|
||||
std::vector<std::string> m_axis_names;
|
||||
|
||||
std::map<std::string, wxString> m_part_orientation_names;
|
||||
|
||||
public:
|
||||
GLGizmoCut3D(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id);
|
||||
|
||||
|
@ -192,7 +205,7 @@ protected:
|
|||
void on_set_hover_id() override;
|
||||
bool on_is_activable() const override;
|
||||
bool on_is_selectable() const override;
|
||||
Vec3d mouse_position_in_local_plane(Axis axis, const Linef3&mouse_ray) const;
|
||||
Vec3d mouse_position_in_local_plane(GrabberID axis, const Linef3&mouse_ray) const;
|
||||
void dragging_grabber_z(const GLGizmoBase::UpdateData &data);
|
||||
void dragging_grabber_xy(const GLGizmoBase::UpdateData &data);
|
||||
void dragging_connector(const GLGizmoBase::UpdateData &data);
|
||||
|
@ -211,6 +224,12 @@ protected:
|
|||
void render_build_size();
|
||||
void reset_cut_plane();
|
||||
void set_connectors_editing(bool connectors_editing);
|
||||
void flip_cut_plane();
|
||||
void render_flip_plane_button(bool disable_pred = false);
|
||||
void add_vertical_scaled_interval(float interval);
|
||||
void add_horizontal_scaled_interval(float interval);
|
||||
void add_horizontal_shift(float shift);
|
||||
void render_color_marker(float size, const ImU32& color);
|
||||
void render_cut_plane_input_window(CutConnectors &connectors);
|
||||
void init_input_window_data(CutConnectors &connectors);
|
||||
void render_input_window_warning() const;
|
||||
|
@ -258,7 +277,7 @@ private:
|
|||
void render_cut_plane();
|
||||
void render_model(GLModel& model, const ColorRGBA& color, Transform3d view_model_matrix);
|
||||
void render_line(GLModel& line_model, const ColorRGBA& color, Transform3d view_model_matrix, float width);
|
||||
void render_rotation_snapping(Axis axis, const ColorRGBA& color);
|
||||
void render_rotation_snapping(GrabberID axis, const ColorRGBA& color);
|
||||
void render_grabber_connection(const ColorRGBA& color, Transform3d view_matrix);
|
||||
void render_cut_plane_grabbers();
|
||||
void render_cut_line();
|
||||
|
|
|
@ -453,10 +453,17 @@ void ImGuiWrapper::end()
|
|||
ImGui::End();
|
||||
}
|
||||
|
||||
bool ImGuiWrapper::button(const wxString &label)
|
||||
bool ImGuiWrapper::button(const wxString &label, const wxString& tooltip)
|
||||
{
|
||||
auto label_utf8 = into_u8(label);
|
||||
return ImGui::Button(label_utf8.c_str());
|
||||
const bool ret = ImGui::Button(label_utf8.c_str());
|
||||
|
||||
if (!tooltip.IsEmpty() && ImGui::IsItemHovered()) {
|
||||
auto tooltip_utf8 = into_u8(tooltip);
|
||||
ImGui::SetTooltip(tooltip_utf8.c_str());
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool ImGuiWrapper::button(const wxString& label, float width, float height)
|
||||
|
|
|
@ -91,7 +91,7 @@ public:
|
|||
bool begin(const wxString& name, bool* close, int flags = 0);
|
||||
void end();
|
||||
|
||||
bool button(const wxString &label);
|
||||
bool button(const wxString &label, const wxString& tooltip = {});
|
||||
bool button(const wxString& label, float width, float height);
|
||||
bool button(const wxString& label, const ImVec2 &size, bool enable); // default size = ImVec2(0.f, 0.f)
|
||||
bool radio_button(const wxString &label, bool active);
|
||||
|
|
|
@ -462,7 +462,7 @@ void PhysicalPrinterDialog::build_printhost_settings(ConfigOptionsGroup* m_optgr
|
|||
choice->set_selection();
|
||||
}
|
||||
|
||||
update();
|
||||
update(true);
|
||||
}
|
||||
|
||||
void PhysicalPrinterDialog::update_printhost_buttons()
|
||||
|
@ -632,11 +632,12 @@ void PhysicalPrinterDialog::update_host_type(bool printer_change)
|
|||
|
||||
Choice* choice = dynamic_cast<Choice*>(ht);
|
||||
choice->set_values(types);
|
||||
int index_in_choice = (printer_change ? 0 : last_in_conf);
|
||||
int dif = (int)ht->m_opt.enum_def->values().size() - (int)types.size();
|
||||
int index_in_choice = (printer_change ? std::clamp(last_in_conf - ((int)ht->m_opt.enum_def->values().size() - (int)types.size()), 0, (int)ht->m_opt.enum_def->values().size() - 1) : last_in_conf);
|
||||
choice->set_value(index_in_choice);
|
||||
if (link.supported && link.label == _(ht->m_opt.enum_def->label(index_in_choice)))
|
||||
m_config->set_key_value("host_type", new ConfigOptionEnum<PrintHostType>(htPrusaLink));
|
||||
else if (link.supported && link.label == _(ht->m_opt.enum_def->label(index_in_choice)))
|
||||
else if (connect.supported && connect.label == _(ht->m_opt.enum_def->label(index_in_choice)))
|
||||
m_config->set_key_value("host_type", new ConfigOptionEnum<PrintHostType>(htPrusaConnect));
|
||||
else {
|
||||
int host_type = std::clamp(index_in_choice + ((int)ht->m_opt.enum_def->values().size() - (int)types.size()), 0, (int)ht->m_opt.enum_def->values().size() - 1);
|
||||
|
|
|
@ -1571,7 +1571,10 @@ void TabPrint::build()
|
|||
optgroup->append_single_option_line("first_layer_speed_over_raft");
|
||||
|
||||
optgroup = page->new_optgroup(L("Acceleration control (advanced)"));
|
||||
optgroup->append_single_option_line("external_perimeter_acceleration");
|
||||
optgroup->append_single_option_line("perimeter_acceleration");
|
||||
optgroup->append_single_option_line("top_solid_infill_acceleration");
|
||||
optgroup->append_single_option_line("solid_infill_acceleration");
|
||||
optgroup->append_single_option_line("infill_acceleration");
|
||||
optgroup->append_single_option_line("bridge_acceleration");
|
||||
optgroup->append_single_option_line("first_layer_acceleration");
|
||||
|
|
Loading…
Add table
Reference in a new issue