Optimize RGB color painting. Avoid unnecessary scene reloads
This commit is contained in:
@@ -4952,7 +4952,7 @@ bool model_mmu_segmentation_data_changed(const ModelObject& mo, const ModelObjec
|
||||
template<class T>
|
||||
static bool model_volume_imported_vector_matches(const ModelVolumeImportedVector<T> &lhs, const ModelVolumeImportedVector<T> &rhs)
|
||||
{
|
||||
return lhs.size() == rhs.size() && std::equal(lhs.begin(), lhs.end(), rhs.begin());
|
||||
return lhs.id() == rhs.id() && lhs.size() == rhs.size();
|
||||
}
|
||||
|
||||
static std::string model_volume_texture_mapping_background_config_value(const ModelVolume &volume)
|
||||
|
||||
@@ -675,9 +675,12 @@ void GLVolume::simple_render(GLShaderProgram* shader,
|
||||
texture_preview_used_states_have_surface_gradient(model_volume->mmu_segmentation_facets.get_data().used_states,
|
||||
num_physical,
|
||||
texture_mgr));
|
||||
const bool has_texture_mapping_color_data =
|
||||
model_volume_has_texture_mapping_color_preview_data(*model_volume);
|
||||
const bool has_texture_mapping_color_preview_data =
|
||||
base_uses_texture_preview && model_volume_has_texture_mapping_color_preview_data(*model_volume);
|
||||
base_uses_texture_preview && has_texture_mapping_color_data;
|
||||
const bool has_texture_preview_data = model_volume_has_texture_preview_data(*model_volume);
|
||||
const bool has_vertex_color_preview_data = model_volume_has_vertex_color_preview_data(*model_volume);
|
||||
const Transform3d preview_world_matrix = this->world_matrix();
|
||||
use_original_mesh_texture_preview =
|
||||
!has_mmu_segmentation &&
|
||||
@@ -703,13 +706,23 @@ void GLVolume::simple_render(GLShaderProgram* shader,
|
||||
}
|
||||
|
||||
color_volume = has_mmu_segmentation;
|
||||
size_t preview_visual_signature = texture_preview_settings_signature(num_physical, texture_mgr);
|
||||
const std::vector<bool> *texture_preview_used_states = has_mmu_segmentation ?
|
||||
&model_volume->mmu_segmentation_facets.get_data().used_states : nullptr;
|
||||
size_t preview_visual_signature = texture_preview_model_settings_signature(num_physical,
|
||||
texture_mgr,
|
||||
base_filament_id,
|
||||
texture_preview_used_states,
|
||||
has_texture_preview_data,
|
||||
has_vertex_color_preview_data,
|
||||
has_texture_mapping_color_data);
|
||||
preview_visual_signature ^= size_t(base_filament_id) + 0x9e3779b97f4a7c15ull +
|
||||
(preview_visual_signature << 6) + (preview_visual_signature >> 2);
|
||||
preview_visual_signature ^= texture_preview_simulation_generation_signature() + 0x9e3779b97f4a7c15ull +
|
||||
(preview_visual_signature << 6) + (preview_visual_signature >> 2);
|
||||
preview_visual_signature ^= model_volume_texture_preview_signature(*model_volume) + 0x9e3779b97f4a7c15ull +
|
||||
(preview_visual_signature << 6) + (preview_visual_signature >> 2);
|
||||
preview_visual_signature ^= model_volume->imported_vertex_colors_rgba.id().id + 0x9e3779b97f4a7c15ull +
|
||||
(preview_visual_signature << 6) + (preview_visual_signature >> 2);
|
||||
preview_visual_signature ^= model_volume->imported_vertex_colors_rgba.size() + 0x9e3779b97f4a7c15ull +
|
||||
(preview_visual_signature << 6) + (preview_visual_signature >> 2);
|
||||
preview_visual_signature ^= reinterpret_cast<size_t>(model_volume->imported_vertex_colors_rgba.data()) + 0x9e3779b97f4a7c15ull +
|
||||
@@ -923,9 +936,13 @@ void GLVolume::render_mmu_texture_preview(const Transform3d &view_matrix,
|
||||
|
||||
const Transform3d model_matrix = this->world_matrix();
|
||||
const std::vector<ColorRGBA> extruder_colors = GUI::wxGetApp().plater()->get_extruders_colors();
|
||||
auto adjusted_preview_colors = [this](const std::vector<ColorRGBA> &colors) {
|
||||
auto adjusted_preview_colors = [this, &extruder_colors](const std::vector<unsigned int> &filament_ids, const std::vector<ColorRGBA> &colors) {
|
||||
std::vector<ColorRGBA> preview_colors = colors;
|
||||
for (ColorRGBA &preview_color : preview_colors) {
|
||||
for (size_t idx = 0; idx < preview_colors.size(); ++idx) {
|
||||
ColorRGBA &preview_color = preview_colors[idx];
|
||||
const unsigned int filament_id = idx < filament_ids.size() ? filament_ids[idx] : 0u;
|
||||
if (filament_id > 0 && size_t(filament_id - 1) < extruder_colors.size())
|
||||
preview_color = extruder_colors[size_t(filament_id - 1)];
|
||||
preview_color = adjust_color_for_rendering(preview_color);
|
||||
if (force_native_color && render_color.is_transparent())
|
||||
preview_color.a(render_color.a());
|
||||
@@ -963,7 +980,7 @@ void GLVolume::render_mmu_texture_preview(const Transform3d &view_matrix,
|
||||
opaque);
|
||||
} else {
|
||||
render_model_texture_preview_models(mmuseg_texture_preview_models,
|
||||
adjusted_preview_colors(mmuseg_texture_preview_colors),
|
||||
adjusted_preview_colors(mmuseg_texture_preview_filament_ids, mmuseg_texture_preview_colors),
|
||||
mmuseg_texture_preview_filament_ids,
|
||||
num_physical,
|
||||
texture_mgr,
|
||||
@@ -983,7 +1000,7 @@ void GLVolume::render_mmu_texture_preview(const Transform3d &view_matrix,
|
||||
|
||||
if (!mmuseg_vertex_color_preview_models.empty()) {
|
||||
render_model_vertex_color_preview_models(mmuseg_vertex_color_preview_models,
|
||||
adjusted_preview_colors(mmuseg_vertex_color_preview_colors),
|
||||
adjusted_preview_colors(mmuseg_vertex_color_preview_filament_ids, mmuseg_vertex_color_preview_colors),
|
||||
mmuseg_vertex_color_preview_filament_ids,
|
||||
num_physical,
|
||||
texture_mgr,
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
#include "slic3r/GUI/ObjColorDialog.hpp"
|
||||
#include "slic3r/GUI/MainFrame.hpp"
|
||||
#include "slic3r/GUI/Tab.hpp"
|
||||
#include "slic3r/GUI/3DScene.hpp"
|
||||
#include "slic3r/GUI/MMUPaintedTexturePreview.hpp"
|
||||
#include "libslic3r/PresetBundle.hpp"
|
||||
#include "libslic3r/Format/bbs_3mf.hpp"
|
||||
#include "libslic3r/Model.hpp"
|
||||
@@ -1433,6 +1435,7 @@ static void refresh_imported_texture_storage(ModelVolume &volume)
|
||||
{
|
||||
std::vector<uint8_t> refreshed(volume.imported_texture_rgba.begin(), volume.imported_texture_rgba.end());
|
||||
volume.imported_texture_rgba.swap(refreshed);
|
||||
volume.imported_texture_rgba.set_new_unique_id();
|
||||
}
|
||||
|
||||
static void refresh_imported_texture_raw_storage(ModelVolume &volume)
|
||||
@@ -1440,13 +1443,28 @@ static void refresh_imported_texture_raw_storage(ModelVolume &volume)
|
||||
std::vector<uint8_t> refreshed(volume.imported_texture_raw_filament_offsets.begin(),
|
||||
volume.imported_texture_raw_filament_offsets.end());
|
||||
volume.imported_texture_raw_filament_offsets.swap(refreshed);
|
||||
volume.imported_texture_raw_filament_offsets.set_new_unique_id();
|
||||
}
|
||||
|
||||
static void touch_imported_texture_data(ModelVolume &volume)
|
||||
{
|
||||
volume.imported_texture_uvs_per_face.set_new_unique_id();
|
||||
volume.imported_texture_uv_valid.set_new_unique_id();
|
||||
volume.imported_texture_rgba.set_new_unique_id();
|
||||
volume.imported_texture_raw_filament_offsets.set_new_unique_id();
|
||||
}
|
||||
|
||||
static void clear_imported_texture_raw_atlas(ModelVolume &volume)
|
||||
{
|
||||
const bool changed =
|
||||
!volume.imported_texture_raw_filament_offsets.empty() ||
|
||||
volume.imported_texture_raw_channels != 0 ||
|
||||
!volume.imported_texture_raw_metadata_json.empty();
|
||||
volume.imported_texture_raw_filament_offsets.clear();
|
||||
volume.imported_texture_raw_channels = 0;
|
||||
volume.imported_texture_raw_metadata_json.clear();
|
||||
if (changed)
|
||||
volume.imported_texture_raw_filament_offsets.set_new_unique_id();
|
||||
}
|
||||
|
||||
static ColorRGBA raw_filament_color_for_projection_preview(const ImageMapRawFilament &filament)
|
||||
@@ -1874,6 +1892,8 @@ static bool merge_imported_texture_raw_atlas(ModelVolume &volume, const RawAtlas
|
||||
volume.imported_texture_raw_channels = merged_channels;
|
||||
volume.imported_texture_raw_metadata_json = metadata;
|
||||
volume.imported_texture_raw_filament_offsets = std::move(merged);
|
||||
if (changed)
|
||||
volume.imported_texture_raw_filament_offsets.set_new_unique_id();
|
||||
return changed;
|
||||
}
|
||||
|
||||
@@ -2391,6 +2411,70 @@ static std::vector<int> rgb_existing_source_triangle_depths(const TriangleColorS
|
||||
return depths;
|
||||
}
|
||||
|
||||
static void true_color_rgb_preview_signature_mix(size_t &signature, size_t value)
|
||||
{
|
||||
signature ^= value + 0x9e3779b97f4a7c15ull + (signature << 6) + (signature >> 2);
|
||||
}
|
||||
|
||||
static size_t true_color_rgb_preview_color_facets_signature(const ColorFacetsAnnotation &annotation)
|
||||
{
|
||||
size_t signature = 1469598103934665603ull;
|
||||
const TriangleColorSplittingData &data = annotation.get_data();
|
||||
true_color_rgb_preview_signature_mix(signature, annotation.id().id);
|
||||
true_color_rgb_preview_signature_mix(signature, static_cast<size_t>(annotation.timestamp()));
|
||||
true_color_rgb_preview_signature_mix(signature, data.triangles_to_split.size());
|
||||
true_color_rgb_preview_signature_mix(signature, data.bitstream.size());
|
||||
true_color_rgb_preview_signature_mix(signature, data.colors_rgba.size());
|
||||
true_color_rgb_preview_signature_mix(signature, std::hash<std::string>{}(data.metadata_json));
|
||||
return signature;
|
||||
}
|
||||
|
||||
static size_t true_color_rgb_preview_cache_signature(const ModelVolume &volume,
|
||||
const ColorFacetsAnnotation &annotation,
|
||||
size_t num_physical,
|
||||
const TextureMappingManager *texture_mgr)
|
||||
{
|
||||
size_t signature = model_volume_texture_mapping_color_preview_signature(volume);
|
||||
true_color_rgb_preview_signature_mix(signature, size_t(volume.extruder_id()));
|
||||
true_color_rgb_preview_signature_mix(signature, true_color_rgb_preview_color_facets_signature(annotation));
|
||||
true_color_rgb_preview_signature_mix(signature,
|
||||
texture_preview_model_settings_signature(num_physical,
|
||||
texture_mgr,
|
||||
volume.extruder_id() > 0 ? unsigned(volume.extruder_id()) : 0u,
|
||||
nullptr,
|
||||
model_volume_has_texture_preview_data(volume),
|
||||
model_volume_has_vertex_color_preview_data(volume),
|
||||
!annotation.empty()));
|
||||
true_color_rgb_preview_signature_mix(signature, texture_preview_simulation_generation_signature());
|
||||
return signature;
|
||||
}
|
||||
|
||||
static std::vector<std::vector<TriangleSelector::FacetStateTriangle>> true_color_rgb_preview_triangles(const ModelVolume &volume)
|
||||
{
|
||||
std::vector<std::vector<TriangleSelector::FacetStateTriangle>> triangles_per_type(1);
|
||||
const indexed_triangle_set &its = volume.mesh().its;
|
||||
triangles_per_type.front().reserve(its.indices.size());
|
||||
for (size_t tri_idx = 0; tri_idx < its.indices.size(); ++tri_idx) {
|
||||
const stl_triangle_vertex_indices &tri = its.indices[tri_idx];
|
||||
if (tri[0] < 0 || tri[1] < 0 || tri[2] < 0)
|
||||
continue;
|
||||
if (size_t(tri[0]) >= its.vertices.size() ||
|
||||
size_t(tri[1]) >= its.vertices.size() ||
|
||||
size_t(tri[2]) >= its.vertices.size())
|
||||
continue;
|
||||
|
||||
TriangleSelector::FacetStateTriangle facet;
|
||||
facet.source_triangle = int(tri_idx);
|
||||
facet.vertices = {
|
||||
its.vertices[size_t(tri[0])].cast<float>(),
|
||||
its.vertices[size_t(tri[1])].cast<float>(),
|
||||
its.vertices[size_t(tri[2])].cast<float>()
|
||||
};
|
||||
triangles_per_type.front().emplace_back(std::move(facet));
|
||||
}
|
||||
return triangles_per_type;
|
||||
}
|
||||
|
||||
static bool apply_rgb_stroke_to_volume(ModelVolume &volume,
|
||||
const std::vector<TriangleSelector::FacetStateTriangle> &stroke_facets,
|
||||
const ColorRGBA &brush_color,
|
||||
@@ -2451,20 +2535,32 @@ static bool apply_rgb_stroke_to_volume(ModelVolume
|
||||
if (use_brush_path && (tri_idx >= brush_candidate_triangles.size() || !brush_candidate_triangles[tri_idx]))
|
||||
return pack_vertex_color_rgba(source_color);
|
||||
|
||||
const float alpha = use_brush_path ?
|
||||
sample_rgb_brush_path_alpha(brush_stroke_points_world,
|
||||
transform_point(world_matrix, point),
|
||||
hardness,
|
||||
opacity,
|
||||
brush_radius) :
|
||||
sample_rgb_stroke_alpha(stroke_facets,
|
||||
stroke_by_source_triangle,
|
||||
stroke_boundary_edges,
|
||||
int(tri_idx),
|
||||
point,
|
||||
hardness,
|
||||
opacity,
|
||||
brush_radius);
|
||||
float alpha = 0.f;
|
||||
if (use_brush_path) {
|
||||
alpha = sample_rgb_brush_path_alpha(brush_stroke_points_world,
|
||||
transform_point(world_matrix, point),
|
||||
hardness,
|
||||
opacity,
|
||||
brush_radius);
|
||||
alpha = std::max(alpha,
|
||||
sample_rgb_stroke_alpha(stroke_facets,
|
||||
stroke_by_source_triangle,
|
||||
stroke_boundary_edges,
|
||||
int(tri_idx),
|
||||
point,
|
||||
hardness,
|
||||
opacity,
|
||||
brush_radius));
|
||||
} else {
|
||||
alpha = sample_rgb_stroke_alpha(stroke_facets,
|
||||
stroke_by_source_triangle,
|
||||
stroke_boundary_edges,
|
||||
int(tri_idx),
|
||||
point,
|
||||
hardness,
|
||||
opacity,
|
||||
brush_radius);
|
||||
}
|
||||
if (alpha <= 0.f)
|
||||
return pack_vertex_color_rgba(source_color);
|
||||
if (alpha >= 1.f)
|
||||
@@ -4398,6 +4494,8 @@ static bool initialize_generated_image_texture(ModelVolume &volum
|
||||
}
|
||||
}
|
||||
|
||||
touch_imported_texture_data(volume);
|
||||
|
||||
if (atlas_out != nullptr)
|
||||
*atlas_out = std::move(atlas);
|
||||
return true;
|
||||
@@ -5867,6 +5965,7 @@ static bool clear_object_managed_color_data(ModelObject &object, ManagedColorDat
|
||||
case ManagedColorDataType::VertexColors:
|
||||
if (!volume->imported_vertex_colors_rgba.empty()) {
|
||||
volume->imported_vertex_colors_rgba.clear();
|
||||
volume->imported_vertex_colors_rgba.set_new_unique_id();
|
||||
changed = true;
|
||||
}
|
||||
break;
|
||||
@@ -5883,6 +5982,7 @@ static bool clear_object_managed_color_data(ModelObject &object, ManagedColorDat
|
||||
volume->imported_texture_width = 0;
|
||||
volume->imported_texture_height = 0;
|
||||
volume->uv_map_generator_version = 0;
|
||||
touch_imported_texture_data(*volume);
|
||||
changed = true;
|
||||
}
|
||||
break;
|
||||
@@ -6590,6 +6690,7 @@ static bool managed_color_data_replace_rgba(ColorFacetsAnnotation &annotation, u
|
||||
return false;
|
||||
|
||||
rewritten->set_metadata_json(annotation.metadata_json());
|
||||
rewritten->touch();
|
||||
annotation.assign(*rewritten);
|
||||
return true;
|
||||
}
|
||||
@@ -6878,6 +6979,7 @@ static bool unsplit_volume_rgba_data_once(ModelVolume &volume)
|
||||
if (volume.texture_mapping_color_facets.equals(*unsplit))
|
||||
return false;
|
||||
|
||||
unsplit->touch();
|
||||
volume.texture_mapping_color_facets.assign(*unsplit);
|
||||
return true;
|
||||
}
|
||||
@@ -6937,6 +7039,7 @@ static bool simplify_volume_rgba_data_to_one_color_per_triangle(ModelVolume &vol
|
||||
if (volume.texture_mapping_color_facets.equals(*simplified))
|
||||
return false;
|
||||
|
||||
simplified->touch();
|
||||
volume.texture_mapping_color_facets.assign(*simplified);
|
||||
return true;
|
||||
}
|
||||
@@ -7274,6 +7377,7 @@ static bool convert_object_to_vertex_colors(ModelObject &object, const ManagedCo
|
||||
}
|
||||
|
||||
volume->imported_vertex_colors_rgba = std::move(vertex_colors);
|
||||
volume->imported_vertex_colors_rgba.set_new_unique_id();
|
||||
changed = true;
|
||||
}
|
||||
return changed;
|
||||
@@ -10753,6 +10857,7 @@ void GLGizmoMmuSegmentation::bake_selected_object_image_texture_to_vertex_colors
|
||||
continue;
|
||||
|
||||
volume->imported_vertex_colors_rgba = std::move(vertex_colors);
|
||||
volume->imported_vertex_colors_rgba.set_new_unique_id();
|
||||
volume->imported_texture_uvs_per_face.clear();
|
||||
volume->imported_texture_uv_valid.clear();
|
||||
volume->imported_texture_rgba.clear();
|
||||
@@ -10760,6 +10865,7 @@ void GLGizmoMmuSegmentation::bake_selected_object_image_texture_to_vertex_colors
|
||||
volume->imported_texture_width = 0;
|
||||
volume->imported_texture_height = 0;
|
||||
volume->uv_map_generator_version = 0;
|
||||
touch_imported_texture_data(*volume);
|
||||
baked = true;
|
||||
}
|
||||
|
||||
@@ -11034,6 +11140,7 @@ void GLGizmoMmuSegmentation::clear_selected_object_image_texture_data()
|
||||
volume->imported_texture_width = 0;
|
||||
volume->imported_texture_height = 0;
|
||||
volume->uv_map_generator_version = 0;
|
||||
touch_imported_texture_data(*volume);
|
||||
cleared = true;
|
||||
}
|
||||
|
||||
@@ -11165,6 +11272,8 @@ void GLGizmoTrueColorPainting::on_shutdown()
|
||||
cancel_rgb_data_preview_conversion();
|
||||
m_color_picker_active = false;
|
||||
clear_brush_stroke_points();
|
||||
m_live_selector_preview_active = false;
|
||||
clear_rgb_preview_cache();
|
||||
m_preview_rgb_data_volume_ids.clear();
|
||||
m_preview_rgb_data_by_volume.clear();
|
||||
m_color_picker_source_cache.clear();
|
||||
@@ -11238,7 +11347,20 @@ void GLGizmoTrueColorPainting::render_painter_gizmo()
|
||||
glsafe(::glEnable(GL_BLEND));
|
||||
glsafe(::glEnable(GL_DEPTH_TEST));
|
||||
|
||||
render_triangles(selection);
|
||||
render_cached_rgb_data_preview(*object, selection);
|
||||
if (m_brush_stroke_active || m_live_selector_preview_active) {
|
||||
GLboolean depth_mask = GL_TRUE;
|
||||
GLint depth_func = GL_LESS;
|
||||
glsafe(::glGetBooleanv(GL_DEPTH_WRITEMASK, &depth_mask));
|
||||
glsafe(::glGetIntegerv(GL_DEPTH_FUNC, &depth_func));
|
||||
glsafe(::glDepthMask(GL_FALSE));
|
||||
glsafe(::glDepthFunc(GL_ALWAYS));
|
||||
render_triangles(selection);
|
||||
glsafe(::glDepthFunc(depth_func));
|
||||
glsafe(::glDepthMask(depth_mask));
|
||||
} else {
|
||||
render_triangles(selection);
|
||||
}
|
||||
m_c->object_clipper()->render_cut();
|
||||
m_c->instances_hider()->render_cut();
|
||||
render_cursor();
|
||||
@@ -11297,17 +11419,29 @@ bool GLGizmoTrueColorPainting::gizmo_event(SLAGizmoEventType action,
|
||||
|
||||
if (action == SLAGizmoEventType::LeftDown) {
|
||||
clear_brush_stroke_points();
|
||||
m_brush_stroke_active = !shift_down && !control_down && record_brush_stroke_point(mouse_position);
|
||||
} else if (action == SLAGizmoEventType::Dragging && m_brush_stroke_active && !shift_down && !control_down) {
|
||||
record_brush_stroke_point(mouse_position);
|
||||
int mesh_id = -1;
|
||||
Vec3f hit = Vec3f::Zero();
|
||||
size_t facet = 0;
|
||||
m_live_selector_preview_active = !shift_down && !control_down && !alt_down;
|
||||
m_brush_stroke_active = !shift_down &&
|
||||
!control_down &&
|
||||
raycast_to_selected_mesh(mouse_position, mesh_id, hit, facet) &&
|
||||
mesh_id >= 0;
|
||||
} else if (action == SLAGizmoEventType::Dragging &&
|
||||
(m_brush_stroke_active || m_live_selector_preview_active) &&
|
||||
!shift_down &&
|
||||
!control_down) {
|
||||
m_parent.set_as_dirty();
|
||||
} else if (action == SLAGizmoEventType::RightDown || (action == SLAGizmoEventType::Dragging && shift_down)) {
|
||||
clear_brush_stroke_points();
|
||||
m_live_selector_preview_active = false;
|
||||
}
|
||||
|
||||
const bool handled = GLGizmoPainterBase::gizmo_event(action, mouse_position, shift_down, alt_down, control_down);
|
||||
if (action == SLAGizmoEventType::LeftUp || action == SLAGizmoEventType::RightUp) {
|
||||
clear_brush_stroke_points();
|
||||
m_brush_stroke_active = false;
|
||||
m_live_selector_preview_active = false;
|
||||
}
|
||||
return handled;
|
||||
}
|
||||
@@ -11342,8 +11476,9 @@ void GLGizmoTrueColorPainting::init_model_triangle_selectors()
|
||||
if (TriangleSelectorPatch *patch = dynamic_cast<TriangleSelectorPatch *>(m_triangle_selectors.back().get())) {
|
||||
patch->set_none_state_rendered(render_normal_surface);
|
||||
patch->set_texture_mapping_color_preview(preview_rgb_data);
|
||||
patch->set_texture_preview_needed(preview_rgb_data != nullptr);
|
||||
patch->set_texture_preview_needed(false);
|
||||
patch->set_texture_preview_opaque(true);
|
||||
patch->set_surface_offset(preview_rgb_data != nullptr ? 0.002f : 0.f);
|
||||
}
|
||||
m_triangle_selectors.back()->set_wireframe_needed(true);
|
||||
m_triangle_selectors.back()->request_update_render_data(true);
|
||||
@@ -11441,6 +11576,7 @@ void GLGizmoTrueColorPainting::update_rgb_data_preview_conversion()
|
||||
}
|
||||
|
||||
if (applied) {
|
||||
clear_rgb_preview_cache();
|
||||
init_model_triangle_selectors();
|
||||
m_parent.set_as_dirty();
|
||||
m_parent.request_extra_frame();
|
||||
@@ -11544,16 +11680,16 @@ void GLGizmoTrueColorPainting::start_rgb_data_preview_conversion(ModelObject &ob
|
||||
m_parent.request_extra_frame();
|
||||
}
|
||||
|
||||
bool GLGizmoTrueColorPainting::record_brush_stroke_point(const Vec2d &mouse_position)
|
||||
void GLGizmoTrueColorPainting::on_brush_projected_mouse_positions(
|
||||
SLAGizmoEventType action,
|
||||
int mesh_idx,
|
||||
const std::vector<ProjectedMousePosition> &projected_mouse_positions)
|
||||
{
|
||||
int mesh_id = -1;
|
||||
Vec3f hit = Vec3f::Zero();
|
||||
size_t facet = 0;
|
||||
if (!raycast_to_selected_mesh(mouse_position, mesh_id, hit, facet) || mesh_id < 0)
|
||||
return false;
|
||||
|
||||
if (m_brush_stroke_points_by_volume.size() <= size_t(mesh_id))
|
||||
m_brush_stroke_points_by_volume.resize(size_t(mesh_id) + 1);
|
||||
if (!m_brush_stroke_active ||
|
||||
mesh_idx < 0 ||
|
||||
projected_mouse_positions.empty() ||
|
||||
(action != SLAGizmoEventType::LeftDown && action != SLAGizmoEventType::Dragging))
|
||||
return;
|
||||
|
||||
const ModelObject *object = selected_model_object();
|
||||
const ModelVolume *hit_volume = nullptr;
|
||||
@@ -11563,7 +11699,7 @@ bool GLGizmoTrueColorPainting::record_brush_stroke_point(const Vec2d &mouse_posi
|
||||
if (volume == nullptr || !volume->is_model_part())
|
||||
continue;
|
||||
++model_part_idx;
|
||||
if (model_part_idx == mesh_id) {
|
||||
if (model_part_idx == mesh_idx) {
|
||||
hit_volume = volume;
|
||||
break;
|
||||
}
|
||||
@@ -11576,7 +11712,22 @@ bool GLGizmoTrueColorPainting::record_brush_stroke_point(const Vec2d &mouse_posi
|
||||
world_matrix = projection_world_matrix_for_volume(m_parent, object, hit_volume, selection.get_instance_idx());
|
||||
}
|
||||
|
||||
std::vector<Vec3f> &points = m_brush_stroke_points_by_volume[size_t(mesh_id)];
|
||||
for (auto point_it = projected_mouse_positions.rbegin(); point_it != projected_mouse_positions.rend(); ++point_it) {
|
||||
if (point_it->mesh_idx != mesh_idx)
|
||||
continue;
|
||||
append_brush_stroke_point(mesh_idx, point_it->mesh_hit, world_matrix);
|
||||
}
|
||||
}
|
||||
|
||||
bool GLGizmoTrueColorPainting::append_brush_stroke_point(int mesh_idx, const Vec3f &hit, const Transform3d &world_matrix)
|
||||
{
|
||||
if (mesh_idx < 0)
|
||||
return false;
|
||||
|
||||
if (m_brush_stroke_points_by_volume.size() <= size_t(mesh_idx))
|
||||
m_brush_stroke_points_by_volume.resize(size_t(mesh_idx) + 1);
|
||||
|
||||
std::vector<Vec3f> &points = m_brush_stroke_points_by_volume[size_t(mesh_idx)];
|
||||
const float min_spacing = true_color_brush_subdivision_target(m_cursor_radius);
|
||||
if (points.empty() ||
|
||||
(transform_point(world_matrix, points.back()) - transform_point(world_matrix, hit)).norm() >= min_spacing)
|
||||
@@ -11590,6 +11741,107 @@ void GLGizmoTrueColorPainting::clear_brush_stroke_points()
|
||||
m_brush_stroke_active = false;
|
||||
}
|
||||
|
||||
void GLGizmoTrueColorPainting::clear_rgb_preview_cache()
|
||||
{
|
||||
m_rgb_preview_cache.clear();
|
||||
}
|
||||
|
||||
void GLGizmoTrueColorPainting::render_cached_rgb_data_preview(const ModelObject &object, const Selection &selection)
|
||||
{
|
||||
const size_t num_physical = std::max(0, wxGetApp().filaments_cnt());
|
||||
const TextureMappingManager *texture_mgr = wxGetApp().preset_bundle != nullptr ?
|
||||
&wxGetApp().preset_bundle->texture_mapping_zones : nullptr;
|
||||
|
||||
const Camera &camera = wxGetApp().plater()->get_camera();
|
||||
const Transform3d &view_matrix = camera.get_view_matrix();
|
||||
const Transform3d &projection_matrix = camera.get_projection_matrix();
|
||||
const ClippingPlaneDataWrapper clp_data = get_clipping_plane_data();
|
||||
const ModelInstance *instance = selection.get_instance_idx() >= 0 &&
|
||||
size_t(selection.get_instance_idx()) < object.instances.size() ?
|
||||
object.instances[size_t(selection.get_instance_idx())] :
|
||||
nullptr;
|
||||
if (instance == nullptr)
|
||||
return;
|
||||
|
||||
for (const ModelVolume *volume : object.volumes) {
|
||||
if (volume == nullptr || !volume->is_model_part())
|
||||
continue;
|
||||
|
||||
const ColorFacetsAnnotation *preview_rgb_data = !volume->texture_mapping_color_facets.empty() ?
|
||||
&volume->texture_mapping_color_facets :
|
||||
preview_rgb_data_for_volume(*volume);
|
||||
if (preview_rgb_data == nullptr || preview_rgb_data->empty())
|
||||
continue;
|
||||
|
||||
const size_t signature = true_color_rgb_preview_cache_signature(*volume, *preview_rgb_data, num_physical, texture_mgr);
|
||||
auto cache_it = std::find_if(m_rgb_preview_cache.begin(),
|
||||
m_rgb_preview_cache.end(),
|
||||
[volume_id = volume->id()](const RgbPreviewVolumeCache &cache) {
|
||||
return cache.volume_id == volume_id;
|
||||
});
|
||||
if (cache_it == m_rgb_preview_cache.end()) {
|
||||
m_rgb_preview_cache.emplace_back();
|
||||
cache_it = m_rgb_preview_cache.end() - 1;
|
||||
cache_it->volume_id = volume->id();
|
||||
}
|
||||
|
||||
if (!cache_it->valid || cache_it->signature != signature) {
|
||||
cache_it->models.clear();
|
||||
cache_it->colors.clear();
|
||||
cache_it->filament_ids.clear();
|
||||
const std::vector<ColorRGBA> colors = { ColorRGBA(1.f, 1.f, 1.f, 0.f) };
|
||||
std::vector<std::vector<TriangleSelector::FacetStateTriangle>> triangles_per_type =
|
||||
true_color_rgb_preview_triangles(*volume);
|
||||
build_mmu_vertex_color_preview_models(*volume,
|
||||
triangles_per_type,
|
||||
colors,
|
||||
volume->extruder_id() > 0 ? unsigned(volume->extruder_id()) : 0u,
|
||||
num_physical,
|
||||
texture_mgr,
|
||||
cache_it->models,
|
||||
cache_it->colors,
|
||||
cache_it->filament_ids,
|
||||
preview_rgb_data,
|
||||
reinterpret_cast<size_t>(this));
|
||||
cache_it->signature = signature;
|
||||
cache_it->valid = true;
|
||||
}
|
||||
|
||||
if (cache_it->models.empty())
|
||||
continue;
|
||||
|
||||
Transform3d matrix;
|
||||
if (m_parent.get_canvas_type() == GLCanvas3D::CanvasAssembleView) {
|
||||
matrix = instance->get_assemble_transformation().get_matrix() * volume->get_matrix();
|
||||
matrix.translate(volume->get_transformation().get_offset() * (GLVolume::explosion_ratio - 1.0) +
|
||||
instance->get_offset_to_assembly() * (GLVolume::explosion_ratio - 1.0));
|
||||
} else {
|
||||
matrix = instance->get_transformation().get_matrix() * volume->get_matrix();
|
||||
}
|
||||
|
||||
std::vector<ColorRGBA> preview_colors = cache_it->colors;
|
||||
for (ColorRGBA &preview_color : preview_colors) {
|
||||
preview_color = adjust_color_for_rendering(preview_color);
|
||||
preview_color.a(1.f);
|
||||
}
|
||||
|
||||
render_model_vertex_color_preview_models(cache_it->models,
|
||||
preview_colors,
|
||||
cache_it->filament_ids,
|
||||
num_physical,
|
||||
texture_mgr,
|
||||
matrix,
|
||||
view_matrix,
|
||||
projection_matrix,
|
||||
clp_data.z_range,
|
||||
clp_data.clp_dataf,
|
||||
-1,
|
||||
std::array<float, 4>{ 0.f, 0.f, 0.f, 0.f },
|
||||
std::array<float, 2>{ 0.f, 0.f },
|
||||
true);
|
||||
}
|
||||
}
|
||||
|
||||
void GLGizmoTrueColorPainting::update_triangle_selectors_color()
|
||||
{
|
||||
const std::vector<ColorRGBA> colors = {
|
||||
@@ -11707,6 +11959,7 @@ void GLGizmoTrueColorPainting::open_color_data_management_dialog()
|
||||
cancel_rgb_data_preview_conversion();
|
||||
m_preview_rgb_data_volume_ids.clear();
|
||||
m_preview_rgb_data_by_volume.clear();
|
||||
clear_rgb_preview_cache();
|
||||
Slic3r::GUI::open_color_data_management_dialog(wxGetApp().mainframe, m_parent, object, [this]() {
|
||||
update_selected_object_color_state();
|
||||
init_model_triangle_selectors();
|
||||
@@ -11734,6 +11987,7 @@ void GLGizmoTrueColorPainting::update_selected_object_color_state()
|
||||
cancel_rgb_data_preview_conversion();
|
||||
m_preview_rgb_data_volume_ids.clear();
|
||||
m_preview_rgb_data_by_volume.clear();
|
||||
clear_rgb_preview_cache();
|
||||
m_color_picker_source_cache.clear();
|
||||
m_background_color_edit_config_snapshot.reset();
|
||||
}
|
||||
@@ -11909,6 +12163,7 @@ void GLGizmoTrueColorPainting::refresh_selected_object_after_rgb_change(ModelObj
|
||||
{
|
||||
remember_changed_rgb_data_object(object);
|
||||
update_selected_object_color_state();
|
||||
clear_rgb_preview_cache();
|
||||
init_model_triangle_selectors();
|
||||
m_parent.update_volumes_colors_by_extruder();
|
||||
m_parent.set_as_dirty();
|
||||
@@ -12716,6 +12971,7 @@ void GLGizmoTrueColorPainting::refresh_selected_object_after_background_color_ch
|
||||
cancel_rgb_data_preview_conversion();
|
||||
m_preview_rgb_data_volume_ids.clear();
|
||||
m_preview_rgb_data_by_volume.clear();
|
||||
clear_rgb_preview_cache();
|
||||
m_color_picker_source_cache.clear();
|
||||
update_selected_object_color_state();
|
||||
init_model_triangle_selectors();
|
||||
@@ -13992,6 +14248,7 @@ bool GLGizmoImageProjection::project_to_vertex_colors(ModelObject *object)
|
||||
}
|
||||
volume->imported_vertex_colors_rgba[idx] = pack_vertex_color_rgba(color);
|
||||
}
|
||||
volume->imported_vertex_colors_rgba.set_new_unique_id();
|
||||
changed = true;
|
||||
}
|
||||
return changed;
|
||||
|
||||
@@ -311,6 +311,9 @@ private:
|
||||
void on_shutdown() override;
|
||||
void on_set_state() override;
|
||||
PainterGizmoType get_painter_type() const override;
|
||||
void on_brush_projected_mouse_positions(SLAGizmoEventType action,
|
||||
int mesh_idx,
|
||||
const std::vector<ProjectedMousePosition> &projected_mouse_positions) override;
|
||||
|
||||
void init_model_triangle_selectors();
|
||||
ModelObject *selected_model_object() const;
|
||||
@@ -331,8 +334,10 @@ private:
|
||||
void cancel_rgb_data_preview_conversion();
|
||||
bool rgb_data_preview_conversion_pending_for_selected_object() const;
|
||||
ColorFacetsAnnotation *preview_rgb_data_for_volume(const ModelVolume &volume) const;
|
||||
bool record_brush_stroke_point(const Vec2d &mouse_position);
|
||||
bool append_brush_stroke_point(int mesh_idx, const Vec3f &hit, const Transform3d &world_matrix);
|
||||
void clear_brush_stroke_points();
|
||||
void clear_rgb_preview_cache();
|
||||
void render_cached_rgb_data_preview(const ModelObject &object, const Selection &selection);
|
||||
bool pick_color_from_model(const Vec2d &mouse_position);
|
||||
bool sample_color_from_model(const Vec2d &mouse_position, ColorRGBA &color) const;
|
||||
void set_active_color_from_sample(const ColorRGBA &color);
|
||||
@@ -393,9 +398,20 @@ private:
|
||||
bool m_selected_has_raw_atlas_texture_data = false;
|
||||
bool m_color_picker_active = false;
|
||||
bool m_brush_stroke_active = false;
|
||||
bool m_live_selector_preview_active = false;
|
||||
ObjectID m_selected_color_state_object_id;
|
||||
std::vector<ObjectID> m_changed_rgb_data_object_ids;
|
||||
std::vector<std::vector<Vec3f>> m_brush_stroke_points_by_volume;
|
||||
struct RgbPreviewVolumeCache
|
||||
{
|
||||
ObjectID volume_id;
|
||||
bool valid = false;
|
||||
size_t signature = 0;
|
||||
std::vector<GLModel> models;
|
||||
std::vector<ColorRGBA> colors;
|
||||
std::vector<unsigned int> filament_ids;
|
||||
};
|
||||
std::vector<RgbPreviewVolumeCache> m_rgb_preview_cache;
|
||||
std::vector<ObjectID> m_preview_rgb_data_volume_ids;
|
||||
std::vector<std::unique_ptr<ColorFacetsAnnotation>> m_preview_rgb_data_by_volume;
|
||||
std::unique_ptr<TextureMappingBackgroundConfigSnapshot> m_background_color_edit_config_snapshot;
|
||||
|
||||
@@ -36,6 +36,47 @@ bool model_volume_has_texture_preview_data_for_painting(const ModelVolume &model
|
||||
size_t(model_volume.imported_texture_width) * size_t(model_volume.imported_texture_height) * 4;
|
||||
}
|
||||
|
||||
std::vector<bool> texture_preview_used_states_for_painting(
|
||||
const std::vector<std::vector<TriangleSelector::FacetStateTriangle>> &triangles_per_type)
|
||||
{
|
||||
std::vector<bool> used_states(triangles_per_type.size(), false);
|
||||
for (size_t state_id = 1; state_id < triangles_per_type.size(); ++state_id)
|
||||
used_states[state_id] = !triangles_per_type[state_id].empty();
|
||||
return used_states;
|
||||
}
|
||||
|
||||
size_t texture_preview_visual_signature_for_painting(const ModelVolume &model_volume,
|
||||
const std::vector<bool> *used_states,
|
||||
size_t num_physical,
|
||||
const TextureMappingManager *texture_mgr,
|
||||
const ColorFacetsAnnotation *texture_mapping_color_preview)
|
||||
{
|
||||
const unsigned int base_filament_id = model_volume.extruder_id() > 0 ? unsigned(model_volume.extruder_id()) : 0u;
|
||||
const bool has_texture_mapping_color_preview_data =
|
||||
(texture_mapping_color_preview != nullptr && !texture_mapping_color_preview->empty()) ||
|
||||
model_volume_has_texture_mapping_color_preview_data(model_volume);
|
||||
size_t signature = texture_preview_model_settings_signature(num_physical,
|
||||
texture_mgr,
|
||||
base_filament_id,
|
||||
used_states,
|
||||
model_volume_has_texture_preview_data(model_volume),
|
||||
model_volume_has_vertex_color_preview_data(model_volume),
|
||||
has_texture_mapping_color_preview_data);
|
||||
signature ^= texture_preview_simulation_generation_signature() + 0x9e3779b97f4a7c15ull +
|
||||
(signature << 6) + (signature >> 2);
|
||||
signature ^= model_volume_texture_preview_signature(model_volume) + 0x9e3779b97f4a7c15ull +
|
||||
(signature << 6) + (signature >> 2);
|
||||
signature ^= model_volume.imported_vertex_colors_rgba.id().id + 0x9e3779b97f4a7c15ull +
|
||||
(signature << 6) + (signature >> 2);
|
||||
signature ^= model_volume.imported_vertex_colors_rgba.size() + 0x9e3779b97f4a7c15ull +
|
||||
(signature << 6) + (signature >> 2);
|
||||
signature ^= reinterpret_cast<size_t>(model_volume.imported_vertex_colors_rgba.data()) + 0x9e3779b97f4a7c15ull +
|
||||
(signature << 6) + (signature >> 2);
|
||||
signature ^= model_volume_texture_mapping_color_preview_signature(model_volume) + 0x9e3779b97f4a7c15ull +
|
||||
(signature << 6) + (signature >> 2);
|
||||
return signature;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
std::shared_ptr<GLModel> GLGizmoPainterBase::s_sphere = nullptr;
|
||||
@@ -932,6 +973,8 @@ bool GLGizmoPainterBase::gizmo_event(SLAGizmoEventType action, const Vec2d& mous
|
||||
} else if (m_tool_type == ToolType::BRUSH) {
|
||||
assert(m_cursor_type == TriangleSelector::CursorType::CIRCLE || m_cursor_type == TriangleSelector::CursorType::SPHERE);
|
||||
|
||||
on_brush_projected_mouse_positions(action, mesh_idx, projected_mouse_positions);
|
||||
|
||||
if (projected_mouse_positions.size() == 1) {
|
||||
const ProjectedMousePosition &first_position = projected_mouse_positions.front();
|
||||
std::unique_ptr<TriangleSelector::Cursor> cursor = TriangleSelector::SinglePointCursor::cursor_factory(first_position.mesh_hit,
|
||||
@@ -1509,10 +1552,11 @@ void TriangleSelectorPatch::update_triangles_per_type()
|
||||
int j = triangle.verts_idxs[i];
|
||||
int index = int(patch.patch_vertices.size() / 9);
|
||||
//BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", Line %1%: i=%2%, j=%3%, index=%4%, v[%5%,%6%,%7%]")%__LINE__%i%j%index%m_vertices[j].v(0)%m_vertices[j].v(1)%m_vertices[j].v(2);
|
||||
patch.patch_vertices.emplace_back(m_vertices[j].v(0));
|
||||
patch.patch_vertices.emplace_back(m_vertices[j].v(1));
|
||||
patch.patch_vertices.emplace_back(m_vertices[j].v(2));
|
||||
const Vec3f normal = smooth_normal(triangle, i);
|
||||
const Vec3f position = m_vertices[j].v + normal * m_surface_offset;
|
||||
patch.patch_vertices.emplace_back(position(0));
|
||||
patch.patch_vertices.emplace_back(position(1));
|
||||
patch.patch_vertices.emplace_back(position(2));
|
||||
patch.patch_vertices.emplace_back(normal(0));
|
||||
patch.patch_vertices.emplace_back(normal(1));
|
||||
patch.patch_vertices.emplace_back(normal(2));
|
||||
@@ -1707,18 +1751,23 @@ void TriangleSelectorPatch::update_render_data()
|
||||
m_texture_preview_models.clear();
|
||||
m_texture_preview_colors.clear();
|
||||
m_texture_preview_filament_ids.clear();
|
||||
m_texture_preview_used_states.clear();
|
||||
m_vertex_color_preview_models.clear();
|
||||
m_vertex_color_preview_colors.clear();
|
||||
m_vertex_color_preview_filament_ids.clear();
|
||||
if (m_texture_preview_needed && m_model_volume != nullptr) {
|
||||
std::vector<std::vector<TriangleSelector::FacetStateTriangle>> triangles_per_type;
|
||||
get_facet_triangles(triangles_per_type);
|
||||
m_texture_preview_used_states = texture_preview_used_states_for_painting(triangles_per_type);
|
||||
const size_t num_physical = std::max(0, wxGetApp().filaments_cnt());
|
||||
const TextureMappingManager *texture_mgr = wxGetApp().preset_bundle != nullptr ?
|
||||
&wxGetApp().preset_bundle->texture_mapping_zones : nullptr;
|
||||
m_texture_preview_visual_signature = texture_preview_settings_signature(num_physical, texture_mgr);
|
||||
m_texture_preview_visual_signature ^= texture_preview_simulation_generation_signature() + 0x9e3779b97f4a7c15ull +
|
||||
(m_texture_preview_visual_signature << 6) + (m_texture_preview_visual_signature >> 2);
|
||||
m_texture_preview_visual_signature =
|
||||
texture_preview_visual_signature_for_painting(*m_model_volume,
|
||||
&m_texture_preview_used_states,
|
||||
num_physical,
|
||||
texture_mgr,
|
||||
m_texture_mapping_color_preview);
|
||||
if (m_texture_mapping_color_preview != nullptr && !m_texture_mapping_color_preview->empty()) {
|
||||
build_mmu_vertex_color_preview_models(*m_model_volume,
|
||||
triangles_per_type,
|
||||
@@ -1869,6 +1918,7 @@ void TriangleSelectorPatch::release_geometry()
|
||||
m_texture_preview_models.clear();
|
||||
m_texture_preview_colors.clear();
|
||||
m_texture_preview_filament_ids.clear();
|
||||
m_texture_preview_used_states.clear();
|
||||
m_texture_preview.reset();
|
||||
m_texture_preview_signature = 0;
|
||||
m_texture_preview_visual_signature = 0;
|
||||
@@ -1891,9 +1941,12 @@ void TriangleSelectorPatch::render_texture_preview(const Transform3d& m
|
||||
const size_t num_physical = std::max(0, wxGetApp().filaments_cnt());
|
||||
const TextureMappingManager *texture_mgr = wxGetApp().preset_bundle != nullptr ?
|
||||
&wxGetApp().preset_bundle->texture_mapping_zones : nullptr;
|
||||
size_t current_visual_signature = texture_preview_settings_signature(num_physical, texture_mgr);
|
||||
current_visual_signature ^= texture_preview_simulation_generation_signature() + 0x9e3779b97f4a7c15ull +
|
||||
(current_visual_signature << 6) + (current_visual_signature >> 2);
|
||||
size_t current_visual_signature =
|
||||
texture_preview_visual_signature_for_painting(*m_model_volume,
|
||||
&m_texture_preview_used_states,
|
||||
num_physical,
|
||||
texture_mgr,
|
||||
m_texture_mapping_color_preview);
|
||||
if (current_visual_signature != m_texture_preview_visual_signature) {
|
||||
TriangleSelectorPatch *self = const_cast<TriangleSelectorPatch *>(this);
|
||||
self->request_update_render_data(true);
|
||||
@@ -1903,9 +1956,16 @@ void TriangleSelectorPatch::render_texture_preview(const Transform3d& m
|
||||
if (m_texture_preview_models.empty() && m_vertex_color_preview_models.empty())
|
||||
return;
|
||||
|
||||
auto adjusted_preview_colors = [this](const std::vector<ColorRGBA> &colors) {
|
||||
const std::vector<ColorRGBA> extruder_colors = wxGetApp().plater() != nullptr ?
|
||||
wxGetApp().plater()->get_extruders_colors() : std::vector<ColorRGBA>();
|
||||
auto adjusted_preview_colors = [this, &extruder_colors](const std::vector<unsigned int> &filament_ids,
|
||||
const std::vector<ColorRGBA> &colors) {
|
||||
std::vector<ColorRGBA> preview_colors = colors;
|
||||
for (ColorRGBA &preview_color : preview_colors) {
|
||||
for (size_t idx = 0; idx < preview_colors.size(); ++idx) {
|
||||
ColorRGBA &preview_color = preview_colors[idx];
|
||||
const unsigned int filament_id = idx < filament_ids.size() ? filament_ids[idx] : 0u;
|
||||
if (filament_id > 0 && size_t(filament_id - 1) < extruder_colors.size())
|
||||
preview_color = extruder_colors[size_t(filament_id - 1)];
|
||||
preview_color = adjust_color_for_rendering(preview_color);
|
||||
if (m_texture_preview_opaque)
|
||||
preview_color.a(1.f);
|
||||
@@ -1916,7 +1976,7 @@ void TriangleSelectorPatch::render_texture_preview(const Transform3d& m
|
||||
if (!m_texture_preview_models.empty() &&
|
||||
ensure_model_volume_texture_preview(*m_model_volume, m_texture_preview, m_texture_preview_signature)) {
|
||||
render_model_texture_preview_models(m_texture_preview_models,
|
||||
adjusted_preview_colors(m_texture_preview_colors),
|
||||
adjusted_preview_colors(m_texture_preview_filament_ids, m_texture_preview_colors),
|
||||
m_texture_preview_filament_ids,
|
||||
num_physical,
|
||||
texture_mgr,
|
||||
@@ -1935,7 +1995,7 @@ void TriangleSelectorPatch::render_texture_preview(const Transform3d& m
|
||||
|
||||
if (!m_vertex_color_preview_models.empty()) {
|
||||
render_model_vertex_color_preview_models(m_vertex_color_preview_models,
|
||||
adjusted_preview_colors(m_vertex_color_preview_colors),
|
||||
adjusted_preview_colors(m_vertex_color_preview_filament_ids, m_vertex_color_preview_colors),
|
||||
m_vertex_color_preview_filament_ids,
|
||||
num_physical,
|
||||
texture_mgr,
|
||||
|
||||
@@ -133,6 +133,13 @@ public:
|
||||
void set_texture_preview_needed(bool needed) { m_texture_preview_needed = needed; }
|
||||
void set_texture_preview_opaque(bool opaque) { m_texture_preview_opaque = opaque; }
|
||||
void set_texture_mapping_color_preview(const ColorFacetsAnnotation *preview) { m_texture_mapping_color_preview = preview; }
|
||||
void set_surface_offset(float surface_offset)
|
||||
{
|
||||
if (m_surface_offset != surface_offset) {
|
||||
m_surface_offset = surface_offset;
|
||||
request_update_render_data(true);
|
||||
}
|
||||
}
|
||||
|
||||
constexpr static float GapAreaMin = 0.f;
|
||||
constexpr static float GapAreaMax = 5.f;
|
||||
@@ -191,6 +198,7 @@ protected:
|
||||
mutable std::vector<GLModel> m_texture_preview_models;
|
||||
std::vector<ColorRGBA> m_texture_preview_colors;
|
||||
std::vector<unsigned int> m_texture_preview_filament_ids;
|
||||
std::vector<bool> m_texture_preview_used_states;
|
||||
mutable GLTexture m_texture_preview;
|
||||
mutable size_t m_texture_preview_signature { 0 };
|
||||
size_t m_texture_preview_visual_signature { 0 };
|
||||
@@ -203,6 +211,7 @@ protected:
|
||||
bool m_render_none_state = true;
|
||||
bool m_texture_preview_needed = true;
|
||||
bool m_texture_preview_opaque = false;
|
||||
float m_surface_offset = 0.f;
|
||||
|
||||
private:
|
||||
void update_render_data();
|
||||
@@ -307,6 +316,10 @@ protected:
|
||||
size_t facet_idx;
|
||||
};
|
||||
|
||||
virtual void on_brush_projected_mouse_positions(SLAGizmoEventType,
|
||||
int,
|
||||
const std::vector<ProjectedMousePosition> &) {}
|
||||
|
||||
// BBS: projected result of mouse height range for a mesh
|
||||
struct ProjectedHeightRange
|
||||
{
|
||||
|
||||
@@ -3783,6 +3783,21 @@ size_t texture_preview_state_triangles_signature(const std::vector<TriangleSelec
|
||||
return signature;
|
||||
}
|
||||
|
||||
void mix_color_facets_signature(size_t &signature, const ColorFacetsAnnotation &color_source)
|
||||
{
|
||||
auto mix = [&signature](size_t value) {
|
||||
signature ^= value + 0x9e3779b97f4a7c15ull + (signature << 6) + (signature >> 2);
|
||||
};
|
||||
|
||||
const TriangleColorSplittingData &data = color_source.get_data();
|
||||
mix(color_source.id().id);
|
||||
mix(static_cast<size_t>(color_source.timestamp()));
|
||||
mix(data.triangles_to_split.size());
|
||||
mix(data.bitstream.size());
|
||||
mix(data.colors_rgba.size());
|
||||
mix(std::hash<std::string>{}(data.metadata_json));
|
||||
}
|
||||
|
||||
size_t texture_preview_vertex_color_source_signature(const ModelVolume &model_volume,
|
||||
const std::vector<TriangleSelector::FacetStateTriangle> &state_triangles)
|
||||
{
|
||||
@@ -3792,11 +3807,15 @@ size_t texture_preview_vertex_color_source_signature(const ModelVolume
|
||||
};
|
||||
|
||||
mix(reinterpret_cast<size_t>(model_volume.mesh_ptr().get()));
|
||||
mix(model_volume.id().id);
|
||||
mix(model_volume.mesh().its.vertices.size());
|
||||
mix(model_volume.mesh().its.indices.size());
|
||||
mix(model_volume.mmu_segmentation_facets.id().id);
|
||||
mix(static_cast<size_t>(model_volume.mmu_segmentation_facets.timestamp()));
|
||||
mix(model_volume.imported_vertex_colors_rgba.id().id);
|
||||
mix(model_volume.imported_vertex_colors_rgba.size());
|
||||
mix(reinterpret_cast<size_t>(model_volume.imported_vertex_colors_rgba.data()));
|
||||
mix(texture_preview_state_triangles_signature(state_triangles));
|
||||
mix(state_triangles.size());
|
||||
const ColorRGBA background = texture_mapping_background_color_for_preview(model_volume);
|
||||
auto background_signature_component = [](float value) {
|
||||
return size_t(std::clamp(value, 0.f, 1.f) * 255.f + 0.5f);
|
||||
@@ -3817,24 +3836,13 @@ size_t texture_preview_color_facets_source_signature(const ModelVolume
|
||||
};
|
||||
|
||||
mix(reinterpret_cast<size_t>(model_volume.mesh_ptr().get()));
|
||||
mix(model_volume.id().id);
|
||||
mix(model_volume.mesh().its.vertices.size());
|
||||
mix(model_volume.mesh().its.indices.size());
|
||||
const TriangleColorSplittingData &data = color_source.get_data();
|
||||
mix(data.triangles_to_split.size());
|
||||
mix(data.bitstream.size());
|
||||
mix(data.colors_rgba.size());
|
||||
for (const ColorTriangleBitStreamMapping &mapping : data.triangles_to_split) {
|
||||
mix(size_t(mapping.triangle_idx));
|
||||
mix(size_t(mapping.bitstream_start_idx));
|
||||
mix(size_t(mapping.color_start_idx));
|
||||
}
|
||||
for (const bool bit : data.bitstream)
|
||||
mix(bit ? 1u : 0u);
|
||||
for (const uint32_t color : data.colors_rgba)
|
||||
mix(size_t(color));
|
||||
for (const char ch : data.metadata_json)
|
||||
mix(size_t(static_cast<unsigned char>(ch)));
|
||||
mix(texture_preview_state_triangles_signature(state_triangles));
|
||||
mix(model_volume.mmu_segmentation_facets.id().id);
|
||||
mix(static_cast<size_t>(model_volume.mmu_segmentation_facets.timestamp()));
|
||||
mix_color_facets_signature(signature, color_source);
|
||||
mix(state_triangles.size());
|
||||
const ColorRGBA background = texture_mapping_background_color_for_preview(model_volume, &color_source);
|
||||
auto background_signature_component = [](float value) {
|
||||
return size_t(std::clamp(value, 0.f, 1.f) * 255.f + 0.5f);
|
||||
@@ -3853,10 +3861,13 @@ size_t texture_preview_image_halftone_source_signature(const ModelVolume
|
||||
auto mix = [&signature](size_t value) {
|
||||
signature ^= value + 0x9e3779b97f4a7c15ull + (signature << 6) + (signature >> 2);
|
||||
};
|
||||
mix(model_volume.id().id);
|
||||
mix(reinterpret_cast<size_t>(model_volume.mesh_ptr().get()));
|
||||
mix(model_volume.mesh().its.vertices.size());
|
||||
mix(model_volume.mesh().its.indices.size());
|
||||
mix(texture_preview_state_triangles_signature(state_triangles));
|
||||
mix(model_volume.mmu_segmentation_facets.id().id);
|
||||
mix(static_cast<size_t>(model_volume.mmu_segmentation_facets.timestamp()));
|
||||
mix(state_triangles.size());
|
||||
for (int row = 0; row < 4; ++row)
|
||||
for (int col = 0; col < 4; ++col)
|
||||
mix(std::hash<int>{}(int(std::lround(world_matrix(row, col) * 1000000.0))));
|
||||
@@ -4826,16 +4837,24 @@ size_t model_volume_texture_preview_signature(const ModelVolume &model_volume)
|
||||
auto mix = [&signature](size_t value) {
|
||||
signature ^= value + 0x9e3779b97f4a7c15ull + (signature << 6) + (signature >> 2);
|
||||
};
|
||||
mix(model_volume.id().id);
|
||||
mix(reinterpret_cast<size_t>(model_volume.mesh_ptr().get()));
|
||||
mix(model_volume.mesh().its.vertices.size());
|
||||
mix(model_volume.mesh().its.indices.size());
|
||||
mix(size_t(model_volume.imported_texture_width));
|
||||
mix(size_t(model_volume.imported_texture_height));
|
||||
mix(model_volume.imported_texture_rgba.id().id);
|
||||
mix(model_volume.imported_texture_rgba.size());
|
||||
mix(reinterpret_cast<size_t>(model_volume.imported_texture_rgba.data()));
|
||||
mix(size_t(model_volume.imported_texture_raw_channels));
|
||||
mix(std::hash<std::string>{}(model_volume.imported_texture_raw_metadata_json));
|
||||
mix(model_volume.imported_texture_raw_filament_offsets.id().id);
|
||||
mix(model_volume.imported_texture_raw_filament_offsets.size());
|
||||
mix(reinterpret_cast<size_t>(model_volume.imported_texture_raw_filament_offsets.data()));
|
||||
mix(model_volume.imported_texture_uvs_per_face.id().id);
|
||||
mix(model_volume.imported_texture_uvs_per_face.size());
|
||||
mix(reinterpret_cast<size_t>(model_volume.imported_texture_uvs_per_face.data()));
|
||||
mix(model_volume.imported_texture_uv_valid.id().id);
|
||||
mix(model_volume.imported_texture_uv_valid.size());
|
||||
mix(reinterpret_cast<size_t>(model_volume.imported_texture_uv_valid.data()));
|
||||
const ColorRGBA background = texture_mapping_background_color_for_preview(model_volume);
|
||||
@@ -4855,21 +4874,9 @@ size_t model_volume_texture_mapping_color_preview_signature(const ModelVolume &m
|
||||
signature ^= value + 0x9e3779b97f4a7c15ull + (signature << 6) + (signature >> 2);
|
||||
};
|
||||
|
||||
const TriangleColorSplittingData &data = model_volume.texture_mapping_color_facets.get_data();
|
||||
mix(data.triangles_to_split.size());
|
||||
mix(data.bitstream.size());
|
||||
mix(data.colors_rgba.size());
|
||||
for (const ColorTriangleBitStreamMapping &mapping : data.triangles_to_split) {
|
||||
mix(size_t(mapping.triangle_idx));
|
||||
mix(size_t(mapping.bitstream_start_idx));
|
||||
mix(size_t(mapping.color_start_idx));
|
||||
}
|
||||
for (const bool bit : data.bitstream)
|
||||
mix(bit ? 1u : 0u);
|
||||
for (const uint32_t color : data.colors_rgba)
|
||||
mix(size_t(color));
|
||||
for (const char ch : data.metadata_json)
|
||||
mix(size_t(static_cast<unsigned char>(ch)));
|
||||
mix(model_volume.id().id);
|
||||
mix(reinterpret_cast<size_t>(model_volume.mesh_ptr().get()));
|
||||
mix_color_facets_signature(signature, model_volume.texture_mapping_color_facets);
|
||||
const ColorRGBA background = texture_mapping_background_color_for_preview(model_volume);
|
||||
auto background_signature_component = [](float value) {
|
||||
return size_t(std::clamp(value, 0.f, 1.f) * 255.f + 0.5f);
|
||||
@@ -4904,7 +4911,9 @@ bool ensure_model_volume_texture_preview(const ModelVolume &model_volume,
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t texture_preview_settings_signature(size_t num_physical, const TextureMappingManager *texture_mgr)
|
||||
static size_t texture_preview_settings_signature_impl(size_t num_physical,
|
||||
const TextureMappingManager *texture_mgr,
|
||||
const std::vector<unsigned int> *active_zone_ids)
|
||||
{
|
||||
size_t signature = 1469598103934665603ull;
|
||||
auto signature_mix = [&signature](size_t value) {
|
||||
@@ -4927,7 +4936,14 @@ size_t texture_preview_settings_signature(size_t num_physical, const TextureMapp
|
||||
if (texture_mgr == nullptr)
|
||||
return signature;
|
||||
|
||||
auto zone_is_active = [active_zone_ids](unsigned int zone_id) {
|
||||
return active_zone_ids == nullptr ||
|
||||
std::find(active_zone_ids->begin(), active_zone_ids->end(), zone_id) != active_zone_ids->end();
|
||||
};
|
||||
|
||||
for (const TextureMappingZone &zone : texture_mgr->zones()) {
|
||||
if (!zone_is_active(zone.zone_id))
|
||||
continue;
|
||||
signature_mix(std::hash<uint64_t>{}(zone.stable_id));
|
||||
signature_mix(std::hash<unsigned int>{}(zone.zone_id));
|
||||
signature_mix(std::hash<int>{}(zone.enabled ? 1 : 0));
|
||||
@@ -4978,6 +4994,174 @@ size_t texture_preview_settings_signature(size_t num_physical, const TextureMapp
|
||||
return signature;
|
||||
}
|
||||
|
||||
static std::vector<unsigned int> active_texture_preview_zone_ids(const TextureMappingManager *texture_mgr,
|
||||
unsigned int base_filament_id,
|
||||
const std::vector<bool> *used_states)
|
||||
{
|
||||
std::vector<unsigned int> active_zone_ids;
|
||||
if (texture_mgr == nullptr)
|
||||
return active_zone_ids;
|
||||
|
||||
auto append_active_zone_id = [texture_mgr, &active_zone_ids](unsigned int zone_id) {
|
||||
if (zone_id != 0 && texture_mgr->zone_from_id(zone_id) != nullptr)
|
||||
active_zone_ids.emplace_back(zone_id);
|
||||
};
|
||||
append_active_zone_id(base_filament_id);
|
||||
if (used_states != nullptr) {
|
||||
for (size_t idx = 1; idx < used_states->size(); ++idx)
|
||||
if ((*used_states)[idx])
|
||||
append_active_zone_id(unsigned(idx));
|
||||
}
|
||||
std::sort(active_zone_ids.begin(), active_zone_ids.end());
|
||||
active_zone_ids.erase(std::unique(active_zone_ids.begin(), active_zone_ids.end()), active_zone_ids.end());
|
||||
return active_zone_ids;
|
||||
}
|
||||
|
||||
static bool active_texture_preview_zone_ids_contains(const std::vector<unsigned int> &active_zone_ids, unsigned int zone_id)
|
||||
{
|
||||
return std::binary_search(active_zone_ids.begin(), active_zone_ids.end(), zone_id);
|
||||
}
|
||||
|
||||
static bool texture_preview_zone_uses_halftone_model(const TextureMappingZone &zone)
|
||||
{
|
||||
if (!zone.enabled || zone.deleted || !zone.is_image_texture() || !zone.preview_simulate_colors)
|
||||
return false;
|
||||
const int mapping_mode = std::clamp(zone.texture_mapping_mode,
|
||||
int(TextureMappingZone::TextureMappingFilamentBlending),
|
||||
int(TextureMappingZone::TextureMappingRawValues));
|
||||
const int method = std::clamp(zone.dithering_method,
|
||||
int(TextureMappingZone::DitheringClosest),
|
||||
int(TextureMappingZone::DitheringHalftoneIncreasedDetail));
|
||||
return mapping_mode != int(TextureMappingZone::TextureMappingRawValues) &&
|
||||
zone.dithering_enabled &&
|
||||
(method == int(TextureMappingZone::DitheringHalftone) ||
|
||||
method == int(TextureMappingZone::DitheringHalftoneIncreasedDetail));
|
||||
}
|
||||
|
||||
static void texture_preview_mix_zone_baked_model_settings(size_t &signature,
|
||||
const TextureMappingZone &zone,
|
||||
size_t num_physical)
|
||||
{
|
||||
auto signature_mix = [&signature](size_t value) {
|
||||
signature ^= value + 0x9e3779b97f4a7c15ull + (signature << 6) + (signature >> 2);
|
||||
};
|
||||
auto signature_mix_float = [&signature_mix](float value, float scale = 1000.f) {
|
||||
const float safe_value = std::isfinite(value) ? value : 0.f;
|
||||
signature_mix(std::hash<int>{}(int(std::lround(safe_value * scale))));
|
||||
};
|
||||
|
||||
signature_mix(std::hash<unsigned int>{}(zone.component_a));
|
||||
signature_mix(std::hash<unsigned int>{}(zone.component_b));
|
||||
signature_mix(std::hash<std::string>{}(zone.component_ids));
|
||||
signature_mix(std::hash<std::string>{}(zone.component_weights));
|
||||
signature_mix(std::hash<std::string>{}(zone.offset_distances));
|
||||
signature_mix(std::hash<std::string>{}(zone.offset_angles));
|
||||
signature_mix(std::hash<int>{}(zone.offset_mode));
|
||||
signature_mix(std::hash<int>{}(zone.offset_rotation_enabled ? 1 : 0));
|
||||
signature_mix_float(zone.offset_rotations);
|
||||
signature_mix_float(zone.offset_repeats);
|
||||
signature_mix(std::hash<int>{}(zone.offset_reverse_repeats ? 1 : 0));
|
||||
signature_mix(std::hash<int>{}(zone.offset_clockwise ? 1 : 0));
|
||||
signature_mix(std::hash<int>{}(zone.offset_fade_mode));
|
||||
signature_mix(std::hash<int>{}(zone.offset_angle_mode));
|
||||
signature_mix(std::hash<int>{}(zone.texture_mapping_mode));
|
||||
signature_mix(std::hash<int>{}(zone.filament_color_mode));
|
||||
signature_mix(std::hash<int>{}(zone.force_sequential_filaments ? 1 : 0));
|
||||
signature_mix(std::hash<int>{}(zone.nonlinear_offset_adjustment ? 1 : 0));
|
||||
signature_mix(std::hash<int>{}(zone.compact_offset_mode ? 1 : 0));
|
||||
signature_mix(std::hash<int>{}(zone.use_legacy_fixed_color_mode ? 1 : 0));
|
||||
signature_mix(std::hash<int>{}(zone.dithering_enabled ? 1 : 0));
|
||||
signature_mix(std::hash<int>{}(zone.dithering_method));
|
||||
if (zone.dithering_method == int(TextureMappingZone::DitheringHalftone) ||
|
||||
zone.dithering_method == int(TextureMappingZone::DitheringHalftoneIncreasedDetail))
|
||||
signature_mix_float(zone.halftone_dot_size_mm, 1000.f);
|
||||
else
|
||||
signature_mix_float(zone.dithering_resolution_mm, 1000.f);
|
||||
signature_mix(std::hash<int>{}(zone.minimum_visibility_offset_enabled ? 1 : 0));
|
||||
signature_mix_float(zone.minimum_visibility_offset_pct, 100.f);
|
||||
signature_mix(std::hash<int>{}(zone.generic_solver_lookup_mode));
|
||||
signature_mix(std::hash<int>{}(zone.generic_solver_mode));
|
||||
signature_mix(std::hash<int>{}(TextureMappingZone::DefaultGenericSolverMixModel));
|
||||
signature_mix(std::hash<int>{}(zone.preview_simulate_colors ? 1 : 0));
|
||||
signature_mix(std::hash<int>{}(zone.preview_limit_resolution ? 1 : 0));
|
||||
signature_mix_float(zone.contrast_pct, 100.f);
|
||||
signature_mix_float(zone.tone_gamma);
|
||||
for (const float strength_pct : zone.filament_strengths_pct)
|
||||
signature_mix_float(strength_pct, 100.f);
|
||||
for (const float minimum_offset_pct : zone.filament_minimum_offsets_pct)
|
||||
signature_mix_float(minimum_offset_pct, 100.f);
|
||||
|
||||
if (zone.is_2d_gradient()) {
|
||||
signature_mix_float(texture_preview_config_float("texture_mapping_outer_wall_gradient_global_strength", 100.f), 100.f);
|
||||
signature_mix_float(texture_preview_config_float("texture_mapping_outer_wall_gradient_max_line_width", 0.95f), 1000.f);
|
||||
signature_mix_float(texture_preview_config_float("texture_mapping_outer_wall_gradient_min_line_width", 0.32f), 1000.f);
|
||||
}
|
||||
|
||||
const std::vector<std::string> physical_colors = physical_filament_colors_for_texture_preview(num_physical);
|
||||
for (const std::string &color : physical_colors)
|
||||
signature_mix(std::hash<std::string>{}(color));
|
||||
}
|
||||
|
||||
size_t texture_preview_settings_signature(size_t num_physical, const TextureMappingManager *texture_mgr)
|
||||
{
|
||||
return texture_preview_settings_signature_impl(num_physical, texture_mgr, nullptr);
|
||||
}
|
||||
|
||||
size_t texture_preview_settings_signature(size_t num_physical,
|
||||
const TextureMappingManager *texture_mgr,
|
||||
unsigned int base_filament_id,
|
||||
const std::vector<bool> *used_states)
|
||||
{
|
||||
if (texture_mgr == nullptr)
|
||||
return texture_preview_settings_signature_impl(num_physical, texture_mgr, nullptr);
|
||||
|
||||
std::vector<unsigned int> active_zone_ids = active_texture_preview_zone_ids(texture_mgr, base_filament_id, used_states);
|
||||
return texture_preview_settings_signature_impl(num_physical, texture_mgr, &active_zone_ids);
|
||||
}
|
||||
|
||||
size_t texture_preview_model_settings_signature(size_t num_physical,
|
||||
const TextureMappingManager *texture_mgr,
|
||||
unsigned int base_filament_id,
|
||||
const std::vector<bool> *used_states,
|
||||
bool has_texture_preview_data,
|
||||
bool has_vertex_color_preview_data,
|
||||
bool has_texture_mapping_color_preview_data)
|
||||
{
|
||||
size_t signature = 1469598103934665603ull;
|
||||
auto signature_mix = [&signature](size_t value) {
|
||||
signature ^= value + 0x9e3779b97f4a7c15ull + (signature << 6) + (signature >> 2);
|
||||
};
|
||||
|
||||
signature_mix(std::hash<size_t>{}(num_physical));
|
||||
if (texture_mgr == nullptr)
|
||||
return signature;
|
||||
|
||||
const std::vector<unsigned int> active_zone_ids = active_texture_preview_zone_ids(texture_mgr, base_filament_id, used_states);
|
||||
for (const TextureMappingZone &zone : texture_mgr->zones()) {
|
||||
if (!active_texture_preview_zone_ids_contains(active_zone_ids, zone.zone_id))
|
||||
continue;
|
||||
|
||||
signature_mix(std::hash<unsigned int>{}(zone.zone_id));
|
||||
signature_mix(std::hash<int>{}(zone.enabled ? 1 : 0));
|
||||
signature_mix(std::hash<int>{}(zone.deleted ? 1 : 0));
|
||||
signature_mix(std::hash<int>{}(zone.surface_pattern));
|
||||
|
||||
const bool image_zone = zone.enabled && !zone.deleted && zone.is_image_texture();
|
||||
const bool gradient_zone = zone.enabled && !zone.deleted && zone.is_2d_gradient();
|
||||
const bool halftone_model = texture_preview_zone_uses_halftone_model(zone);
|
||||
const bool simulated_vertex_color_model =
|
||||
image_zone &&
|
||||
zone.preview_simulate_colors &&
|
||||
(has_texture_mapping_color_preview_data || (!has_texture_preview_data && has_vertex_color_preview_data));
|
||||
signature_mix(std::hash<int>{}(halftone_model ? 1 : 0));
|
||||
signature_mix(std::hash<int>{}(simulated_vertex_color_model ? 1 : 0));
|
||||
|
||||
if (gradient_zone || halftone_model || simulated_vertex_color_model)
|
||||
texture_preview_mix_zone_baked_model_settings(signature, zone, num_physical);
|
||||
}
|
||||
return signature;
|
||||
}
|
||||
|
||||
void render_model_texture_preview_models(
|
||||
std::vector<GUI::GLModel> &models,
|
||||
const std::vector<ColorRGBA> &colors,
|
||||
|
||||
@@ -80,6 +80,17 @@ bool texture_preview_simulation_enabled_for_all_filaments(const std::vector<unsi
|
||||
size_t texture_preview_simulation_generation_signature();
|
||||
|
||||
size_t texture_preview_settings_signature(size_t num_physical, const TextureMappingManager *texture_mgr);
|
||||
size_t texture_preview_settings_signature(size_t num_physical,
|
||||
const TextureMappingManager *texture_mgr,
|
||||
unsigned int base_filament_id,
|
||||
const std::vector<bool> *used_states);
|
||||
size_t texture_preview_model_settings_signature(size_t num_physical,
|
||||
const TextureMappingManager *texture_mgr,
|
||||
unsigned int base_filament_id,
|
||||
const std::vector<bool> *used_states,
|
||||
bool has_texture_preview_data,
|
||||
bool has_vertex_color_preview_data,
|
||||
bool has_texture_mapping_color_preview_data);
|
||||
|
||||
void render_model_texture_preview_models(
|
||||
std::vector<GUI::GLModel> &models,
|
||||
|
||||
@@ -555,6 +555,52 @@ static bool assign_imported_texture_mapping_zone(Model &model)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool texture_mapping_config_uses_zone_id(const ConfigOptionResolver &config, unsigned int zone_id)
|
||||
{
|
||||
static constexpr std::array<const char *, 6> filament_keys = {
|
||||
"extruder",
|
||||
"wall_filament",
|
||||
"sparse_infill_filament",
|
||||
"solid_infill_filament",
|
||||
"support_filament",
|
||||
"support_interface_filament"
|
||||
};
|
||||
const int target = int(zone_id);
|
||||
for (const char *key : filament_keys) {
|
||||
const ConfigOptionInt *opt = dynamic_cast<const ConfigOptionInt *>(config.option(key));
|
||||
if (opt != nullptr && opt->getInt() == target)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool model_uses_texture_mapping_zone_id(const Model &model, const ConfigOptionResolver *print_config, unsigned int zone_id)
|
||||
{
|
||||
if (zone_id == 0)
|
||||
return false;
|
||||
if (print_config != nullptr && texture_mapping_config_uses_zone_id(*print_config, zone_id))
|
||||
return true;
|
||||
for (const ModelObject *object : model.objects) {
|
||||
if (object == nullptr)
|
||||
continue;
|
||||
if (texture_mapping_config_uses_zone_id(object->config.get(), zone_id))
|
||||
return true;
|
||||
for (const auto &layer_range : object->layer_config_ranges)
|
||||
if (texture_mapping_config_uses_zone_id(layer_range.second.get(), zone_id))
|
||||
return true;
|
||||
for (const ModelVolume *volume : object->volumes) {
|
||||
if (volume == nullptr)
|
||||
continue;
|
||||
if (texture_mapping_config_uses_zone_id(volume->config.get(), zone_id))
|
||||
return true;
|
||||
const std::vector<bool> &used_states = volume->mmu_segmentation_facets.get_data().used_states;
|
||||
if (size_t(zone_id) < used_states.size() && used_states[zone_id])
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static wxColour parse_texture_mapping_color(const std::string &hex)
|
||||
{
|
||||
unsigned char rgba[4] = {38, 166, 154, 255};
|
||||
@@ -4052,12 +4098,12 @@ Sidebar::Sidebar(Plater *parent)
|
||||
bundle->project_config.set_key_value("texture_mapping_definitions", new ConfigOptionString(serialized));
|
||||
if (auto *print_tab = wxGetApp().get_tab(Preset::TYPE_PRINT))
|
||||
print_tab->update_dirty();
|
||||
if (wxGetApp().mainframe != nullptr)
|
||||
wxGetApp().mainframe->on_config_changed(print_cfg);
|
||||
if (wxGetApp().plater() != nullptr)
|
||||
wxGetApp().plater()->update_project_dirty_from_presets();
|
||||
update_texture_mapping_panel(false);
|
||||
CallAfter([this]() { update_texture_mapping_panel(false); });
|
||||
update_dynamic_filament_list();
|
||||
if (obj_list() != nullptr)
|
||||
obj_list()->update_filament_colors();
|
||||
};
|
||||
auto add_texture_map_action = [this, persist_texture_mapping]() {
|
||||
PresetBundle *bundle = wxGetApp().preset_bundle;
|
||||
@@ -5730,14 +5776,14 @@ void Sidebar::update_texture_mapping_panel(bool sync_manager)
|
||||
bundle->project_config.set_key_value(key, new ConfigOptionString(value));
|
||||
};
|
||||
|
||||
auto notify_change = [this, print_cfg]() {
|
||||
auto notify_change = [this, print_cfg](bool affects_scene) {
|
||||
if (auto *print_tab = wxGetApp().get_tab(Preset::TYPE_PRINT))
|
||||
print_tab->update_dirty();
|
||||
if (wxGetApp().mainframe != nullptr && print_cfg != nullptr)
|
||||
if (affects_scene && wxGetApp().mainframe != nullptr && print_cfg != nullptr)
|
||||
wxGetApp().mainframe->on_config_changed(print_cfg);
|
||||
if (wxGetApp().plater() != nullptr) {
|
||||
wxGetApp().plater()->update_project_dirty_from_presets();
|
||||
if (wxGetApp().plater()->get_view3D_canvas3D() != nullptr)
|
||||
if (affects_scene && wxGetApp().plater()->get_view3D_canvas3D() != nullptr)
|
||||
wxGetApp().plater()->get_view3D_canvas3D()->reload_scene(false);
|
||||
}
|
||||
update_dynamic_filament_list();
|
||||
@@ -5763,12 +5809,9 @@ void Sidebar::update_texture_mapping_panel(bool sync_manager)
|
||||
return;
|
||||
content_sizer->Clear(true);
|
||||
content_sizer->AddSpacer(FromDIP(SidebarProps::ContentMargin()));
|
||||
auto update_texture_mapping_area_height = [this, scroll_texture_mapping_content_to]() {
|
||||
auto update_texture_mapping_area_height = [this]() {
|
||||
if (p->m_panel_texture_mapping_content == nullptr || p->m_panel_texture_mapping_content->GetSizer() == nullptr)
|
||||
return;
|
||||
int scroll_x = 0;
|
||||
int scroll_y = 0;
|
||||
p->m_panel_texture_mapping_content->GetViewStart(&scroll_x, &scroll_y);
|
||||
const int max_height = FromDIP(260);
|
||||
p->m_panel_texture_mapping_content->SetMaxSize(wxSize(-1, max_height));
|
||||
p->m_panel_texture_mapping_content->Layout();
|
||||
@@ -5777,7 +5820,6 @@ void Sidebar::update_texture_mapping_panel(bool sync_manager)
|
||||
if (min_size.y > max_height)
|
||||
min_size.y = max_height;
|
||||
p->m_panel_texture_mapping_content->SetMinSize(wxSize(-1, std::max(FromDIP(1), min_size.y)));
|
||||
scroll_texture_mapping_content_to(scroll_x, scroll_y);
|
||||
};
|
||||
|
||||
if (p->m_btn_add_texture_map != nullptr)
|
||||
@@ -5896,9 +5938,13 @@ void Sidebar::update_texture_mapping_panel(bool sync_manager)
|
||||
canvas->reload_scene(true, true);
|
||||
};
|
||||
|
||||
auto persist_rows = [mgr_ptr, set_config_string, notify_change]() {
|
||||
auto texture_mapping_zone_affects_scene = [print_cfg](unsigned int zone_id) {
|
||||
return model_uses_texture_mapping_zone_id(wxGetApp().model(), print_cfg, zone_id);
|
||||
};
|
||||
|
||||
auto persist_rows = [mgr_ptr, set_config_string, notify_change](bool affects_scene) {
|
||||
set_config_string("texture_mapping_definitions", mgr_ptr->serialize_entries());
|
||||
notify_change();
|
||||
notify_change(affects_scene);
|
||||
};
|
||||
|
||||
for (const size_t zone_index : visible_zone_indices) {
|
||||
@@ -5972,19 +6018,30 @@ void Sidebar::update_texture_mapping_panel(bool sync_manager)
|
||||
};
|
||||
|
||||
auto apply_zone = [zone_index, mgr_ptr, num_physical, set_config_string, notify_change, refresh_texture_mapping_preview,
|
||||
is_preview_only_texture_row_change, refresh_summary_preview](TextureMappingZone updated) {
|
||||
is_preview_only_texture_row_change, refresh_summary_preview, texture_mapping_zone_affects_scene](TextureMappingZone updated) {
|
||||
auto &rows = mgr_ptr->zones();
|
||||
if (zone_index >= rows.size())
|
||||
return;
|
||||
const bool preview_only_change = is_preview_only_texture_row_change(rows[zone_index], updated);
|
||||
return false;
|
||||
const TextureMappingZone before = rows[zone_index];
|
||||
if (before == updated)
|
||||
return false;
|
||||
const unsigned int before_zone_id = before.zone_id;
|
||||
const bool preview_only_change = is_preview_only_texture_row_change(before, updated);
|
||||
rows[zone_index] = std::move(updated);
|
||||
mgr_ptr->normalize_zone_ids(num_physical);
|
||||
const unsigned int after_zone_id = rows[zone_index].zone_id;
|
||||
const bool affects_scene = texture_mapping_zone_affects_scene(before_zone_id) ||
|
||||
texture_mapping_zone_affects_scene(after_zone_id);
|
||||
refresh_summary_preview(rows[zone_index]);
|
||||
set_config_string("texture_mapping_definitions", mgr_ptr->serialize_entries());
|
||||
if (preview_only_change)
|
||||
refresh_texture_mapping_preview();
|
||||
if (preview_only_change) {
|
||||
notify_change(false);
|
||||
if (affects_scene)
|
||||
refresh_texture_mapping_preview();
|
||||
}
|
||||
else
|
||||
notify_change();
|
||||
notify_change(affects_scene);
|
||||
return affects_scene;
|
||||
};
|
||||
|
||||
auto *surface_row = new wxBoxSizer(wxHORIZONTAL);
|
||||
@@ -6202,7 +6259,7 @@ void Sidebar::update_texture_mapping_panel(bool sync_manager)
|
||||
return;
|
||||
updated.surface_pattern = int(TextureMappingZone::Gradient2D);
|
||||
apply_zone(std::move(updated));
|
||||
update_texture_mapping_panel(false);
|
||||
CallAfter([this]() { update_texture_mapping_panel(false); });
|
||||
});
|
||||
advanced_btn->Bind(wxEVT_BUTTON, [this,
|
||||
zone_index,
|
||||
@@ -6344,14 +6401,14 @@ void Sidebar::update_texture_mapping_panel(bool sync_manager)
|
||||
while (!updated.filament_transmission_distances_mm.empty() &&
|
||||
std::abs(updated.filament_transmission_distances_mm.back()) <= 1e-6f)
|
||||
updated.filament_transmission_distances_mm.pop_back();
|
||||
apply_zone(std::move(updated));
|
||||
if (p->plater != nullptr && !p->plater->is_preview_shown()) {
|
||||
const bool affects_scene = apply_zone(std::move(updated));
|
||||
if (affects_scene && p->plater != nullptr && !p->plater->is_preview_shown()) {
|
||||
if (GLCanvas3D *canvas = p->plater->get_view3D_canvas3D())
|
||||
canvas->reload_scene(true, true);
|
||||
if (GLCanvas3D *canvas = p->plater->get_assmeble_canvas3D())
|
||||
canvas->reload_scene(true, true);
|
||||
}
|
||||
update_texture_mapping_panel(false);
|
||||
CallAfter([this]() { update_texture_mapping_panel(false); });
|
||||
});
|
||||
|
||||
auto toggle_editor = [this, zone_index, editor, row, update_texture_mapping_area_height]() {
|
||||
@@ -6385,7 +6442,7 @@ void Sidebar::update_texture_mapping_panel(bool sync_manager)
|
||||
evt.StopPropagation();
|
||||
evt.Skip();
|
||||
});
|
||||
menu_btn->Bind(wxEVT_BUTTON, [this, zone_index, num_physical, physical_colors, mgr_ptr, persist_rows, menu_btn, bundle, set_config_string](wxCommandEvent &) {
|
||||
menu_btn->Bind(wxEVT_BUTTON, [this, zone_index, num_physical, physical_colors, mgr_ptr, persist_rows, menu_btn, bundle, set_config_string, texture_mapping_zone_affects_scene](wxCommandEvent &) {
|
||||
if (menu_btn == nullptr)
|
||||
return;
|
||||
wxMenu menu;
|
||||
@@ -6393,18 +6450,19 @@ void Sidebar::update_texture_mapping_panel(bool sync_manager)
|
||||
const int delete_id = wxWindow::NewControlId();
|
||||
menu.Append(duplicate_id, _L("Duplicate"));
|
||||
menu.Append(delete_id, _L("Delete"));
|
||||
menu.Bind(wxEVT_COMMAND_MENU_SELECTED, [this, zone_index, num_physical, physical_colors, mgr_ptr, persist_rows, duplicate_id, delete_id, bundle, set_config_string](wxCommandEvent &evt) {
|
||||
menu.Bind(wxEVT_COMMAND_MENU_SELECTED, [this, zone_index, num_physical, physical_colors, mgr_ptr, persist_rows, duplicate_id, delete_id, bundle, set_config_string, texture_mapping_zone_affects_scene](wxCommandEvent &evt) {
|
||||
auto &rows = mgr_ptr->zones();
|
||||
if (zone_index >= rows.size())
|
||||
return;
|
||||
if (evt.GetId() == duplicate_id) {
|
||||
mgr_ptr->duplicate_zone(zone_index, num_physical, physical_colors);
|
||||
persist_rows();
|
||||
update_texture_mapping_panel(false);
|
||||
persist_rows(false);
|
||||
CallAfter([this]() { update_texture_mapping_panel(false); });
|
||||
return;
|
||||
}
|
||||
if (evt.GetId() == delete_id) {
|
||||
const uint64_t deleted_stable_id = rows[zone_index].stable_id;
|
||||
const bool affects_scene = texture_mapping_zone_affects_scene(rows[zone_index].zone_id);
|
||||
rows.erase(rows.begin() + ptrdiff_t(zone_index));
|
||||
if (deleted_stable_id != 0 &&
|
||||
bundle->texture_mapping_global_settings.prime_tower_settings_zone_uid == deleted_stable_id) {
|
||||
@@ -6414,8 +6472,8 @@ void Sidebar::update_texture_mapping_panel(bool sync_manager)
|
||||
set_config_string("texture_mapping_global_settings", bundle->texture_mapping_global_settings.serialize());
|
||||
}
|
||||
p->m_expanded_texture_mapping_rows.clear();
|
||||
persist_rows();
|
||||
update_texture_mapping_panel(false);
|
||||
persist_rows(affects_scene);
|
||||
CallAfter([this]() { update_texture_mapping_panel(false); });
|
||||
}
|
||||
});
|
||||
menu_btn->PopupMenu(&menu, wxPoint(0, menu_btn->GetSize().GetHeight()));
|
||||
|
||||
Reference in New Issue
Block a user