mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-05-19 05:47:37 +08:00
Optimization in GLCanvas3D::reload_scene():
Use sorting and binary search instead of linear search. O(n log n) versus O(n^2)
This commit is contained in:
parent
24bbad634a
commit
b12bc5c4d5
@ -303,6 +303,8 @@ public:
|
||||
int instance_id;
|
||||
bool operator==(const CompositeID &rhs) const { return object_id == rhs.object_id && volume_id == rhs.volume_id && instance_id == rhs.instance_id; }
|
||||
bool operator!=(const CompositeID &rhs) const { return ! (*this == rhs); }
|
||||
bool operator< (const CompositeID &rhs) const
|
||||
{ return object_id < rhs.object_id || (object_id == rhs.object_id && (volume_id < rhs.volume_id || (volume_id == rhs.volume_id && instance_id < rhs.instance_id))); }
|
||||
};
|
||||
CompositeID composite_id;
|
||||
// Fingerprint of the source geometry. For ModelVolumes, it is the ModelVolume::ID and ModelInstanceID,
|
||||
|
@ -2063,9 +2063,11 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
|
||||
|
||||
struct GLVolumeState {
|
||||
GLVolumeState() :
|
||||
volume_idx(-1) {}
|
||||
volume_idx(size_t(-1)) {}
|
||||
GLVolumeState(const GLVolume* volume, unsigned int volume_idx) :
|
||||
composite_id(volume->composite_id), volume_idx(volume_idx) {}
|
||||
GLVolumeState(const GLVolume::CompositeID &composite_id) :
|
||||
composite_id(composite_id), volume_idx(size_t(-1)) {}
|
||||
|
||||
GLVolume::CompositeID composite_id;
|
||||
// Volume index in the old GLVolume vector.
|
||||
@ -2191,22 +2193,13 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
|
||||
}
|
||||
}
|
||||
sort_remove_duplicates(instance_ids_selected);
|
||||
auto deleted_volumes_lower = [](const GLVolumeState &v1, const GLVolumeState &v2) { return v1.composite_id < v2.composite_id; };
|
||||
std::sort(deleted_volumes.begin(), deleted_volumes.end(), deleted_volumes_lower);
|
||||
|
||||
if (m_reload_delayed)
|
||||
return;
|
||||
|
||||
bool update_object_list = false;
|
||||
|
||||
auto find_old_volume_id = [&deleted_volumes](const GLVolume::CompositeID& id) -> unsigned int {
|
||||
for (unsigned int i = 0; i < (unsigned int)deleted_volumes.size(); ++i)
|
||||
{
|
||||
const GLVolumeState& v = deleted_volumes[i];
|
||||
if (v.composite_id == id)
|
||||
return v.volume_idx;
|
||||
}
|
||||
return (unsigned int)-1;
|
||||
};
|
||||
|
||||
if (m_volumes.volumes != glvolumes_new)
|
||||
update_object_list = true;
|
||||
m_volumes.volumes = std::move(glvolumes_new);
|
||||
@ -2221,9 +2214,10 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
|
||||
assert(it != model_volume_state.end() && it->geometry_id == key.geometry_id);
|
||||
if (it->new_geometry()) {
|
||||
// New volume.
|
||||
unsigned int old_id = find_old_volume_id(it->composite_id);
|
||||
if (old_id != (unsigned int)-1)
|
||||
map_glvolume_old_to_new[old_id] = m_volumes.volumes.size();
|
||||
auto it_old_volume = std::lower_bound(deleted_volumes.begin(), deleted_volumes.end(), GLVolumeState(it->composite_id), deleted_volumes_lower);
|
||||
if (it_old_volume != deleted_volumes.end() && it_old_volume->composite_id == it->composite_id)
|
||||
// If a volume changed its ObjectID, but it reuses a GLVolume's CompositeID, maintain its selection.
|
||||
map_glvolume_old_to_new[it_old_volume->volume_idx] = m_volumes.volumes.size();
|
||||
m_volumes.load_object_volume(&model_object, obj_idx, volume_idx, instance_idx, m_color_by, m_initialized);
|
||||
m_volumes.volumes.back()->geometry_id = key.geometry_id;
|
||||
update_object_list = true;
|
||||
|
Loading…
x
Reference in New Issue
Block a user