mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-08 07:27:41 -06:00
NEW:add paint tool in assembly view
Change-Id: I108e1e24ca9d033d2279c8153585166971a347a6
This commit is contained in:
parent
5236f17792
commit
ab0c6611c8
13 changed files with 265 additions and 108 deletions
|
@ -1288,6 +1288,15 @@ void GLCanvas3D::on_change_color_mode(bool is_dark, bool reinit) {
|
|||
m_gizmos.set_icon_dirty();
|
||||
}
|
||||
}
|
||||
if (m_canvas_type == CanvasAssembleView) {
|
||||
m_gizmos.on_change_color_mode(is_dark);
|
||||
if (reinit) {
|
||||
// reset svg
|
||||
m_gizmos.switch_gizmos_icon_filename();
|
||||
// set dirty to re-generate icon texture
|
||||
m_gizmos.set_icon_dirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GLCanvas3D::set_as_dirty()
|
||||
|
@ -2369,9 +2378,6 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
|
|||
deleted_wipe_towers.emplace_back(volume, volume_id);
|
||||
delete volume;
|
||||
}
|
||||
|
||||
// BBS
|
||||
m_explosion_ratio = 1.0;
|
||||
}
|
||||
else {
|
||||
// This GLVolume will be reused.
|
||||
|
@ -3045,7 +3051,7 @@ void GLCanvas3D::on_char(wxKeyEvent& evt)
|
|||
#else /* __APPLE__ */
|
||||
case WXK_CONTROL_Y:
|
||||
#endif /* __APPLE__ */
|
||||
if (m_canvas_type == CanvasView3D) {
|
||||
if (m_canvas_type == CanvasView3D || m_canvas_type == CanvasAssembleView) {
|
||||
post_event(SimpleEvent(EVT_GLCANVAS_REDO));
|
||||
}
|
||||
break;
|
||||
|
@ -3056,7 +3062,7 @@ void GLCanvas3D::on_char(wxKeyEvent& evt)
|
|||
case WXK_CONTROL_Z:
|
||||
#endif /* __APPLE__ */
|
||||
// only support redu/undo in CanvasView3D
|
||||
if (m_canvas_type == CanvasView3D) {
|
||||
if (m_canvas_type == CanvasView3D || m_canvas_type == CanvasAssembleView) {
|
||||
post_event(SimpleEvent(EVT_GLCANVAS_UNDO));
|
||||
}
|
||||
break;
|
||||
|
@ -6229,7 +6235,7 @@ bool GLCanvas3D::_init_assemble_view_toolbar()
|
|||
item.tooltip = _utf8(L("Assembly View"));
|
||||
item.sprite_id = 1;
|
||||
item.left.toggable = false;
|
||||
item.left.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLVIEWTOOLBAR_ASSEMBLE)); };
|
||||
item.left.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLVIEWTOOLBAR_ASSEMBLE)); m_gizmos.reset_all_states(); wxGetApp().plater()->get_assmeble_canvas3D()->get_gizmos_manager().reset_all_states(); };
|
||||
item.left.render_callback = GLToolbarItem::Default_Render_Callback;
|
||||
item.visible = true;
|
||||
item.visibility_callback = [this]()->bool { return true; };
|
||||
|
@ -6742,7 +6748,10 @@ void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type, bool with
|
|||
else {
|
||||
m_volumes.set_clipping_plane(m_camera_clipping_plane.get_data());
|
||||
}
|
||||
m_volumes.set_show_sinking_contours(! m_gizmos.is_hiding_instances());
|
||||
if (m_canvas_type == CanvasAssembleView)
|
||||
m_volumes.set_show_sinking_contours(false);
|
||||
else
|
||||
m_volumes.set_show_sinking_contours(!m_gizmos.is_hiding_instances());
|
||||
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("gouraud");
|
||||
ECanvasType canvas_type = this->m_canvas_type;
|
||||
|
@ -7233,9 +7242,6 @@ void GLCanvas3D::_render_gizmos_overlay()
|
|||
const float size = int(GLGizmosManager::Default_Icons_Size * wxGetApp().toolbar_icon_scale());
|
||||
m_gizmos.set_overlay_icon_size(size); //! #ys_FIXME_experiment
|
||||
#endif /* __WXMSW__ */
|
||||
if (m_canvas_type == CanvasAssembleView)
|
||||
return;
|
||||
|
||||
m_gizmos.render_overlay();
|
||||
|
||||
if (m_gizmo_highlighter.m_render_arrow)
|
||||
|
@ -7648,6 +7654,8 @@ void GLCanvas3D::_render_return_toolbar() const
|
|||
if (ImGui::ImageTextButton(real_size,_utf8(L("return")).c_str(), m_return_toolbar.get_return_texture_id(), button_icon_size, uv0, uv1, -1, bg_col, tint_col, margin)) {
|
||||
if (m_canvas != nullptr)
|
||||
wxPostEvent(m_canvas, SimpleEvent(EVT_GLVIEWTOOLBAR_3D));
|
||||
const_cast<GLGizmosManager*>(&m_gizmos)->reset_all_states();
|
||||
wxGetApp().plater()->get_view3D_canvas3D()->get_gizmos_manager().reset_all_states();
|
||||
}
|
||||
ImGui::PopStyleColor(5);
|
||||
ImGui::PopStyleVar(1);
|
||||
|
@ -7849,6 +7857,7 @@ void GLCanvas3D::_render_paint_toolbar() const
|
|||
ImGui::BBLRenderArrow(draw_list, right_arrow_button.GetCenter() - ImVec2(draw_list->_Data->FontSize, draw_list->_Data->FontSize) * 0.5f, arrow_color, ImGuiDir_Right, 2.0f);
|
||||
}
|
||||
|
||||
m_paint_toolbar_width = (ImGui::GetWindowWidth() + 50.0f * em_unit * f_scale);
|
||||
imgui.end();
|
||||
ImGui::PopStyleVar(3);
|
||||
ImGui::PopStyleColor();
|
||||
|
@ -7861,6 +7870,10 @@ void GLCanvas3D::_render_assemble_control() const
|
|||
GLVolume::explosion_ratio = m_explosion_ratio = 1.0;
|
||||
return;
|
||||
}
|
||||
if (m_gizmos.get_current_type() == GLGizmosManager::EType::MmuSegmentation) {
|
||||
m_gizmos.m_assemble_view_data->model_objects_clipper()->set_position(0.0, true);
|
||||
return;
|
||||
}
|
||||
|
||||
ImGuiWrapper* imgui = wxGetApp().imgui();
|
||||
|
||||
|
|
|
@ -520,6 +520,7 @@ private:
|
|||
mutable IMToolbar m_sel_plate_toolbar;
|
||||
mutable GLToolbar m_assemble_view_toolbar;
|
||||
mutable IMReturnToolbar m_return_toolbar;
|
||||
mutable float m_paint_toolbar_width;
|
||||
|
||||
//BBS: add canvas type for assemble view usage
|
||||
ECanvasType m_canvas_type;
|
||||
|
@ -713,6 +714,7 @@ public:
|
|||
bool init();
|
||||
void post_event(wxEvent &&event);
|
||||
|
||||
void reset_explosion_ratio() { m_explosion_ratio = 1.0; }
|
||||
void on_change_color_mode(bool is_dark, bool reinit = true);
|
||||
const bool get_dark_mode_status() { return m_is_dark; }
|
||||
void set_as_dirty();
|
||||
|
@ -819,6 +821,7 @@ public:
|
|||
float get_main_toolbar_width() { return m_main_toolbar.get_width();}
|
||||
float get_assemble_view_toolbar_width() { return m_assemble_view_toolbar.get_width(); }
|
||||
float get_assemble_view_toolbar_height() { return m_assemble_view_toolbar.get_height(); }
|
||||
float get_assembly_paint_toolbar_width() { return m_paint_toolbar_width; }
|
||||
float get_separator_toolbar_width() { return m_separator_toolbar.get_width(); }
|
||||
float get_separator_toolbar_height() { return m_separator_toolbar.get_height(); }
|
||||
float get_collapse_toolbar_width();
|
||||
|
|
|
@ -1194,6 +1194,7 @@ void ObjectList::list_manipulation(const wxPoint& mouse_pos, bool evt_context_me
|
|||
}
|
||||
}
|
||||
else if (col_num == colColorPaint) {
|
||||
if (wxGetApp().plater()->get_current_canvas3D()->get_canvas_type() != GLCanvas3D::CanvasAssembleView) {
|
||||
ObjectDataViewModelNode* node = (ObjectDataViewModelNode*)item.GetID();
|
||||
if (node->HasColorPainting()) {
|
||||
GLGizmosManager& gizmos_mgr = wxGetApp().plater()->get_view3D_canvas3D()->get_gizmos_manager();
|
||||
|
@ -1203,6 +1204,7 @@ void ObjectList::list_manipulation(const wxPoint& mouse_pos, bool evt_context_me
|
|||
gizmos_mgr.reset_all_states();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (col_num == colSinking) {
|
||||
Plater * plater = wxGetApp().plater();
|
||||
GLCanvas3D *cnv = plater->canvas3D();
|
||||
|
@ -2775,6 +2777,9 @@ void ObjectList::merge(bool to_multipart_object)
|
|||
new_object->center_around_origin();
|
||||
new_object->translate_instances(-new_object->origin_translation);
|
||||
new_object->origin_translation = Vec3d::Zero();
|
||||
//BBS init asssmble transformation
|
||||
Geometry::Transformation t = new_object->instances[0]->get_transformation();
|
||||
new_object->instances[0]->set_assemble_transformation(t);
|
||||
//BBS: notify it before remove
|
||||
notify_instance_updated(m_objects->size() - 1);
|
||||
|
||||
|
@ -4457,12 +4462,12 @@ void ObjectList::update_selections()
|
|||
|
||||
void ObjectList::update_selections_on_canvas()
|
||||
{
|
||||
Selection& selection = wxGetApp().plater()->get_view3D_canvas3D()->get_selection();
|
||||
Selection& selection = wxGetApp().plater()->get_current_canvas3D()->get_selection();
|
||||
|
||||
const int sel_cnt = GetSelectedItemsCount();
|
||||
if (sel_cnt == 0) {
|
||||
selection.remove_all();
|
||||
wxGetApp().plater()->get_view3D_canvas3D()->update_gizmos_on_off_state();
|
||||
wxGetApp().plater()->get_current_canvas3D()->update_gizmos_on_off_state();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -4566,7 +4571,7 @@ void ObjectList::update_selections_on_canvas()
|
|||
selection.add_volumes(mode, volume_idxs, single_selection);
|
||||
}
|
||||
|
||||
wxGetApp().plater()->get_view3D_canvas3D()->update_gizmos_on_off_state();
|
||||
wxGetApp().plater()->get_current_canvas3D()->update_gizmos_on_off_state();
|
||||
wxGetApp().plater()->canvas3D()->render();
|
||||
}
|
||||
|
||||
|
|
|
@ -212,7 +212,14 @@ void GLGizmoMmuSegmentation::render_triangles(const Selection &selection) const
|
|||
|
||||
++mesh_id;
|
||||
|
||||
const Transform3d trafo_matrix = mo->instances[selection.get_instance_idx()]->get_transformation().get_matrix() * mv->get_matrix();
|
||||
Transform3d trafo_matrix;
|
||||
if (m_parent.get_canvas_type() == GLCanvas3D::CanvasAssembleView) {
|
||||
trafo_matrix = mo->instances[selection.get_instance_idx()]->get_assemble_transformation().get_matrix() * mv->get_matrix();
|
||||
trafo_matrix.translate(mv->get_transformation().get_offset() * (GLVolume::explosion_ratio - 1.0) + mo->instances[selection.get_instance_idx()]->get_offset_to_assembly() * (GLVolume::explosion_ratio - 1.0));
|
||||
}
|
||||
else {
|
||||
trafo_matrix = mo->instances[selection.get_instance_idx()]->get_transformation().get_matrix()* mv->get_matrix();
|
||||
}
|
||||
|
||||
bool is_left_handed = trafo_matrix.matrix().determinant() < 0.;
|
||||
if (is_left_handed)
|
||||
|
|
|
@ -86,9 +86,14 @@ void GLGizmoPainterBase::render_triangles(const Selection& selection) const
|
|||
|
||||
++mesh_id;
|
||||
|
||||
const Transform3d trafo_matrix =
|
||||
mo->instances[selection.get_instance_idx()]->get_transformation().get_matrix() *
|
||||
mv->get_matrix();
|
||||
Transform3d trafo_matrix;
|
||||
if (m_parent.get_canvas_type() == GLCanvas3D::CanvasAssembleView) {
|
||||
trafo_matrix = mo->instances[selection.get_instance_idx()]->get_assemble_transformation().get_matrix() * mv->get_matrix();
|
||||
trafo_matrix.translate(mv->get_transformation().get_offset() * (GLVolume::explosion_ratio - 1.0) + mo->instances[selection.get_instance_idx()]->get_offset_to_assembly() * (GLVolume::explosion_ratio - 1.0));
|
||||
}
|
||||
else {
|
||||
trafo_matrix = mo->instances[selection.get_instance_idx()]->get_transformation().get_matrix()* mv->get_matrix();
|
||||
}
|
||||
|
||||
bool is_left_handed = trafo_matrix.matrix().determinant() < 0.;
|
||||
if (is_left_handed)
|
||||
|
@ -124,8 +129,17 @@ void GLGizmoPainterBase::render_cursor() const
|
|||
std::vector<Transform3d> trafo_matrices;
|
||||
for (const ModelVolume* mv : mo->volumes) {
|
||||
if (mv->is_model_part())
|
||||
{
|
||||
if (m_parent.get_canvas_type() == GLCanvas3D::CanvasAssembleView) {
|
||||
Transform3d temp = mi->get_assemble_transformation().get_matrix() * mv->get_matrix();
|
||||
temp.translate(mv->get_transformation().get_offset() * (GLVolume::explosion_ratio - 1.0) + mi->get_offset_to_assembly() * (GLVolume::explosion_ratio - 1.0));
|
||||
trafo_matrices.emplace_back(temp);
|
||||
}
|
||||
else {
|
||||
trafo_matrices.emplace_back(mi->get_transformation().get_matrix() * mv->get_matrix());
|
||||
}
|
||||
}
|
||||
}
|
||||
// Raycast and return if there's no hit.
|
||||
update_raycast_cache(m_parent.get_local_mouse_position(), camera, trafo_matrices);
|
||||
if (m_rr.mesh_id == -1)
|
||||
|
@ -230,11 +244,27 @@ void GLGizmoPainterBase::render_cursor_height_range(const Transform3d& trafo) co
|
|||
const BoundingBoxf3 box = bounding_box();
|
||||
Vec3d hit_world = trafo * Vec3d(m_rr.hit(0), m_rr.hit(1), m_rr.hit(2));
|
||||
float max_z = (float)box.max.z();
|
||||
float min_z = (float)box.min.z();
|
||||
|
||||
float cursor_z = std::clamp((float)hit_world.z(), min_z, max_z);
|
||||
std::array<float, 2> zs = { cursor_z, std::clamp(cursor_z + m_cursor_height, min_z, max_z) };
|
||||
|
||||
const Selection& selection = m_parent.get_selection();
|
||||
const ModelObject* model_object = wxGetApp().model().objects[selection.get_object_idx()];
|
||||
const ModelInstance* mi = model_object->instances[selection.get_instance_idx()];
|
||||
for (const ModelVolume* mv : model_object->volumes) {
|
||||
TriangleMesh vol_mesh = mv->mesh();
|
||||
if (m_parent.get_canvas_type() == GLCanvas3D::CanvasAssembleView) {
|
||||
Transform3d temp = mi->get_assemble_transformation().get_matrix() * mv->get_matrix();
|
||||
temp.translate(mv->get_transformation().get_offset() * (GLVolume::explosion_ratio - 1.0) + mi->get_offset_to_assembly() * (GLVolume::explosion_ratio - 1.0));
|
||||
vol_mesh.transform(temp);
|
||||
}
|
||||
else {
|
||||
vol_mesh.transform(mi->get_transformation().get_matrix() * mv->get_matrix());
|
||||
}
|
||||
|
||||
float cursor_z = std::clamp((float)hit_world.z(), 0.f, max_z);
|
||||
std::array<float, 2> zs = { cursor_z, std::clamp(cursor_z + m_cursor_height, 0.f, max_z) };
|
||||
for (int i = 0; i < zs.size(); i++) {
|
||||
update_contours(zs[i], max_z);
|
||||
update_contours(vol_mesh, zs[i], max_z, min_z);
|
||||
|
||||
glsafe(::glPushMatrix());
|
||||
glsafe(::glTranslated(m_cut_contours.shift.x(), m_cut_contours.shift.y(), m_cut_contours.shift.z()));
|
||||
|
@ -242,6 +272,8 @@ void GLGizmoPainterBase::render_cursor_height_range(const Transform3d& trafo) co
|
|||
m_cut_contours.contours.render();
|
||||
glsafe(::glPopMatrix());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
BoundingBoxf3 GLGizmoPainterBase::bounding_box() const
|
||||
|
@ -257,7 +289,7 @@ BoundingBoxf3 GLGizmoPainterBase::bounding_box() const
|
|||
return ret;
|
||||
}
|
||||
|
||||
void GLGizmoPainterBase::update_contours(float cursor_z, float max_z) const
|
||||
void GLGizmoPainterBase::update_contours(const TriangleMesh& vol_mesh, float cursor_z, float max_z, float min_z) const
|
||||
{
|
||||
const Selection& selection = m_parent.get_selection();
|
||||
const GLVolume* first_glvolume = selection.get_volume(*selection.get_volume_idxs().begin());
|
||||
|
@ -266,12 +298,11 @@ void GLGizmoPainterBase::update_contours(float cursor_z, float max_z) const
|
|||
const ModelObject* model_object = wxGetApp().model().objects[selection.get_object_idx()];
|
||||
const int instance_idx = selection.get_instance_idx();
|
||||
|
||||
if (0.0 < cursor_z && cursor_z < max_z) {
|
||||
if (min_z < cursor_z && cursor_z < max_z) {
|
||||
if (m_cut_contours.cut_z != cursor_z || m_cut_contours.object_id != model_object->id() || m_cut_contours.instance_idx != instance_idx) {
|
||||
m_cut_contours.cut_z = cursor_z;
|
||||
|
||||
if (m_cut_contours.object_id != model_object->id())
|
||||
m_cut_contours.mesh = model_object->raw_mesh();
|
||||
m_cut_contours.mesh = vol_mesh;
|
||||
|
||||
m_cut_contours.position = box.center();
|
||||
m_cut_contours.shift = Vec3d::Zero();
|
||||
|
@ -280,7 +311,7 @@ void GLGizmoPainterBase::update_contours(float cursor_z, float max_z) const
|
|||
m_cut_contours.contours.reset();
|
||||
|
||||
MeshSlicingParams slicing_params;
|
||||
slicing_params.trafo = first_glvolume->get_instance_transformation().get_matrix();
|
||||
slicing_params.trafo = Transform3d::Identity().matrix();
|
||||
const Polygons polys = slice_mesh(m_cut_contours.mesh.its, cursor_z, slicing_params);
|
||||
if (!polys.empty()) {
|
||||
m_cut_contours.contours.init_from(polys, static_cast<float>(cursor_z));
|
||||
|
@ -451,8 +482,12 @@ std::vector<GLGizmoPainterBase::ProjectedHeightRange> GLGizmoPainterBase::get_pr
|
|||
const Selection& selection = m_parent.get_selection();
|
||||
const ModelObject* mo = m_c->selection_info()->model_object();
|
||||
const ModelInstance* mi = mo->instances[selection.get_instance_idx()];
|
||||
const Transform3d instance_trafo = mi->get_transformation().get_matrix();
|
||||
const Transform3d instance_trafo_not_translate = mi->get_transformation().get_matrix(true);
|
||||
const Transform3d instance_trafo = m_parent.get_canvas_type() == GLCanvas3D::CanvasAssembleView ?
|
||||
mi->get_assemble_transformation().get_matrix() :
|
||||
mi->get_transformation().get_matrix();
|
||||
const Transform3d instance_trafo_not_translate = m_parent.get_canvas_type() == GLCanvas3D::CanvasAssembleView ?
|
||||
mi->get_assemble_transformation().get_matrix(true) :
|
||||
mi->get_transformation().get_matrix(true);
|
||||
|
||||
for (int mesh_idx = 0; mesh_idx < part_volumes.size(); mesh_idx++) {
|
||||
if (mesh_idx == m_rr.mesh_id)
|
||||
|
@ -518,8 +553,12 @@ bool GLGizmoPainterBase::gizmo_event(SLAGizmoEventType action, const Vec2d& mous
|
|||
const Selection &selection = m_parent.get_selection();
|
||||
const ModelObject *mo = m_c->selection_info()->model_object();
|
||||
const ModelInstance *mi = mo->instances[selection.get_instance_idx()];
|
||||
const Transform3d trafo_matrix_not_translate = mi->get_transformation().get_matrix(true) * mo->volumes[m_rr.mesh_id]->get_matrix(true);
|
||||
const Transform3d trafo_matrix = mi->get_transformation().get_matrix() * mo->volumes[m_rr.mesh_id]->get_matrix();
|
||||
const Transform3d trafo_matrix_not_translate = m_parent.get_canvas_type() == GLCanvas3D::CanvasAssembleView ?
|
||||
mi->get_assemble_transformation().get_matrix(true) * mo->volumes[m_rr.mesh_id]->get_matrix(true) :
|
||||
mi->get_transformation().get_matrix(true) * mo->volumes[m_rr.mesh_id]->get_matrix(true);
|
||||
const Transform3d trafo_matrix = m_parent.get_canvas_type() == GLCanvas3D::CanvasAssembleView ?
|
||||
mi->get_assemble_transformation().get_matrix() * mo->volumes[m_rr.mesh_id]->get_matrix() :
|
||||
mi->get_transformation().get_matrix() * mo->volumes[m_rr.mesh_id]->get_matrix();
|
||||
m_triangle_selectors[m_rr.mesh_id]->seed_fill_select_triangles(m_rr.hit, int(m_rr.facet), trafo_matrix_not_translate, this->get_clipping_plane_in_volume_coordinates(trafo_matrix), m_smart_fill_angle,
|
||||
m_paint_on_overhangs_only ? m_highlight_by_angle_threshold_deg : 0.f, true);
|
||||
m_triangle_selectors[m_rr.mesh_id]->request_update_render_data();
|
||||
|
@ -581,8 +620,12 @@ bool GLGizmoPainterBase::gizmo_event(SLAGizmoEventType action, const Vec2d& mous
|
|||
const Selection &selection = m_parent.get_selection();
|
||||
const ModelObject *mo = m_c->selection_info()->model_object();
|
||||
const ModelInstance *mi = mo->instances[selection.get_instance_idx()];
|
||||
const Transform3d instance_trafo = mi->get_transformation().get_matrix();
|
||||
const Transform3d instance_trafo_not_translate = mi->get_transformation().get_matrix(true);
|
||||
Transform3d instance_trafo = m_parent.get_canvas_type() == GLCanvas3D::CanvasAssembleView ?
|
||||
mi->get_assemble_transformation().get_matrix() :
|
||||
mi->get_transformation().get_matrix();
|
||||
Transform3d instance_trafo_not_translate = m_parent.get_canvas_type() == GLCanvas3D::CanvasAssembleView ?
|
||||
mi->get_assemble_transformation().get_matrix(true) :
|
||||
mi->get_transformation().get_matrix(true);
|
||||
std::vector<const ModelVolume*> part_volumes;
|
||||
|
||||
// Precalculate transformations of individual meshes.
|
||||
|
@ -590,7 +633,14 @@ bool GLGizmoPainterBase::gizmo_event(SLAGizmoEventType action, const Vec2d& mous
|
|||
std::vector<Transform3d> trafo_matrices_not_translate;
|
||||
for (const ModelVolume *mv : mo->volumes)
|
||||
if (mv->is_model_part()) {
|
||||
trafo_matrices.emplace_back(instance_trafo * mv->get_matrix());
|
||||
if (m_parent.get_canvas_type() == GLCanvas3D::CanvasAssembleView) {
|
||||
Transform3d temp = instance_trafo * mv->get_matrix();
|
||||
temp.translate(mv->get_transformation().get_offset() * (GLVolume::explosion_ratio - 1.0) + mi->get_offset_to_assembly() * (GLVolume::explosion_ratio - 1.0));
|
||||
trafo_matrices.emplace_back(temp);
|
||||
}
|
||||
else {
|
||||
trafo_matrices.emplace_back(instance_trafo* mv->get_matrix());
|
||||
}
|
||||
trafo_matrices_not_translate.emplace_back(instance_trafo_not_translate * mv->get_matrix(true));
|
||||
part_volumes.push_back(mv);
|
||||
}
|
||||
|
@ -713,15 +763,26 @@ bool GLGizmoPainterBase::gizmo_event(SLAGizmoEventType action, const Vec2d& mous
|
|||
const Selection &selection = m_parent.get_selection();
|
||||
const ModelObject *mo = m_c->selection_info()->model_object();
|
||||
const ModelInstance *mi = mo->instances[selection.get_instance_idx()];
|
||||
const Transform3d instance_trafo = mi->get_transformation().get_matrix();
|
||||
const Transform3d instance_trafo_not_translate = mi->get_transformation().get_matrix(true);
|
||||
const Transform3d instance_trafo = m_parent.get_canvas_type() == GLCanvas3D::CanvasAssembleView ?
|
||||
mi->get_assemble_transformation().get_matrix() :
|
||||
mi->get_transformation().get_matrix();
|
||||
const Transform3d instance_trafo_not_translate = m_parent.get_canvas_type() == GLCanvas3D::CanvasAssembleView ?
|
||||
mi->get_assemble_transformation().get_matrix(true) :
|
||||
mi->get_transformation().get_matrix(true);
|
||||
|
||||
// Precalculate transformations of individual meshes.
|
||||
std::vector<Transform3d> trafo_matrices;
|
||||
std::vector<Transform3d> trafo_matrices_not_translate;
|
||||
for (const ModelVolume *mv : mo->volumes)
|
||||
if (mv->is_model_part()) {
|
||||
if (m_parent.get_canvas_type() == GLCanvas3D::CanvasAssembleView) {
|
||||
Transform3d temp = instance_trafo * mv->get_matrix();
|
||||
temp.translate(mv->get_transformation().get_offset() * (GLVolume::explosion_ratio - 1.0) + mi->get_offset_to_assembly() * (GLVolume::explosion_ratio - 1.0));
|
||||
trafo_matrices.emplace_back(temp);
|
||||
}
|
||||
else {
|
||||
trafo_matrices.emplace_back(instance_trafo * mv->get_matrix());
|
||||
}
|
||||
trafo_matrices_not_translate.emplace_back(instance_trafo_not_translate * mv->get_matrix(true));
|
||||
}
|
||||
|
||||
|
@ -811,7 +872,8 @@ void GLGizmoPainterBase::update_raycast_cache(const Vec2d& mouse_position,
|
|||
hit,
|
||||
normal,
|
||||
m_c->object_clipper()->get_clipping_plane(),
|
||||
&facet))
|
||||
&facet,
|
||||
m_parent.get_canvas_type() != GLCanvas3D::CanvasAssembleView))
|
||||
{
|
||||
// In case this hit is clipped, skip it.
|
||||
if (is_mesh_point_clipped(hit.cast<double>(), trafo_matrices[mesh_id]))
|
||||
|
|
|
@ -368,7 +368,7 @@ private:
|
|||
mutable CutContours m_cut_contours;
|
||||
|
||||
BoundingBoxf3 bounding_box() const;
|
||||
void update_contours(float cursor_z, float max_z) const;
|
||||
void update_contours(const TriangleMesh& vol_mesh, float cursor_z, float max_z, float min_z) const;
|
||||
|
||||
protected:
|
||||
void on_set_state() override;
|
||||
|
|
|
@ -145,6 +145,11 @@ void InstancesHider::on_update()
|
|||
const ModelObject* mo = get_pool()->selection_info()->model_object();
|
||||
int active_inst = get_pool()->selection_info()->get_active_instance();
|
||||
GLCanvas3D* canvas = get_pool()->get_canvas();
|
||||
double z_min;
|
||||
if (canvas->get_canvas_type() == GLCanvas3D::CanvasAssembleView)
|
||||
z_min = std::numeric_limits<double>::max();
|
||||
else
|
||||
z_min = -SINKING_Z_THRESHOLD;
|
||||
|
||||
if (mo && active_inst != -1) {
|
||||
canvas->toggle_model_objects_visibility(false);
|
||||
|
@ -152,7 +157,7 @@ void InstancesHider::on_update()
|
|||
canvas->toggle_sla_auxiliaries_visibility(m_show_supports, mo, active_inst);
|
||||
canvas->set_use_clipping_planes(true);
|
||||
// Some objects may be sinking, do not show whatever is below the bed.
|
||||
canvas->set_clipping_plane(0, ClippingPlane(Vec3d::UnitZ(), -SINKING_Z_THRESHOLD));
|
||||
canvas->set_clipping_plane(0, ClippingPlane(Vec3d::UnitZ(), z_min));
|
||||
canvas->set_clipping_plane(1, ClippingPlane(-Vec3d::UnitZ(), std::numeric_limits<double>::max()));
|
||||
|
||||
|
||||
|
@ -164,7 +169,7 @@ void InstancesHider::on_update()
|
|||
m_clippers.clear();
|
||||
for (const TriangleMesh* mesh : meshes) {
|
||||
m_clippers.emplace_back(new MeshClipper);
|
||||
m_clippers.back()->set_plane(ClippingPlane(-Vec3d::UnitZ(), -SINKING_Z_THRESHOLD));
|
||||
m_clippers.back()->set_plane(ClippingPlane(-Vec3d::UnitZ(), z_min));
|
||||
m_clippers.back()->set_mesh(*mesh);
|
||||
}
|
||||
m_old_meshes = meshes;
|
||||
|
@ -404,17 +409,29 @@ void ObjectClipper::render_cut() const
|
|||
return;
|
||||
const SelectionInfo* sel_info = get_pool()->selection_info();
|
||||
const ModelObject* mo = sel_info->model_object();
|
||||
Geometry::Transformation inst_trafo = mo->instances[sel_info->get_active_instance()]->get_transformation();
|
||||
Geometry::Transformation inst_trafo;
|
||||
bool is_assem_cnv = get_pool()->get_canvas()->get_canvas_type() == GLCanvas3D::CanvasAssembleView;
|
||||
inst_trafo = is_assem_cnv ?
|
||||
mo->instances[sel_info->get_active_instance()]->get_assemble_transformation() :
|
||||
mo->instances[sel_info->get_active_instance()]->get_transformation();
|
||||
auto offset_to_assembly = mo->instances[0]->get_offset_to_assembly();
|
||||
|
||||
size_t clipper_id = 0;
|
||||
for (const ModelVolume* mv : mo->volumes) {
|
||||
Geometry::Transformation vol_trafo = mv->get_transformation();
|
||||
Geometry::Transformation trafo = inst_trafo * vol_trafo;
|
||||
if (is_assem_cnv) {
|
||||
trafo.set_offset(trafo.get_offset() + offset_to_assembly * (GLVolume::explosion_ratio - 1.0) + vol_trafo.get_offset() * (GLVolume::explosion_ratio - 1.0));
|
||||
}
|
||||
else {
|
||||
trafo.set_offset(trafo.get_offset() + Vec3d(0., 0., sel_info->get_sla_shift()));
|
||||
|
||||
}
|
||||
auto& clipper = m_clippers[clipper_id];
|
||||
clipper->set_plane(*m_clp);
|
||||
clipper->set_transformation(trafo);
|
||||
if (is_assem_cnv)
|
||||
clipper->set_limiting_plane(ClippingPlane(Vec3d::UnitZ(), std::numeric_limits<double>::max()));
|
||||
else
|
||||
clipper->set_limiting_plane(ClippingPlane(Vec3d::UnitZ(), -SINKING_Z_THRESHOLD));
|
||||
glsafe(::glPushMatrix());
|
||||
// BBS
|
||||
|
@ -438,14 +455,27 @@ void ObjectClipper::set_position(double pos, bool keep_normal)
|
|||
// camera_dir(2) = 0;
|
||||
|
||||
Vec3d normal = (keep_normal && m_clp) ? m_clp->get_normal() : /*-camera_dir;*/ -wxGetApp().plater()->get_camera().get_dir_forward();
|
||||
const Vec3d& center = mo->instances[active_inst]->get_offset() + Vec3d(0., 0., z_shift);
|
||||
Vec3d center;
|
||||
|
||||
if (get_pool()->get_canvas()->get_canvas_type() == GLCanvas3D::CanvasAssembleView) {
|
||||
const SelectionInfo* sel_info = get_pool()->selection_info();
|
||||
auto trafo = mo->instances[sel_info->get_active_instance()]->get_assemble_transformation();
|
||||
auto offset_to_assembly = mo->instances[0]->get_offset_to_assembly();
|
||||
center = trafo.get_offset() + offset_to_assembly * (GLVolume::explosion_ratio - 1.0);
|
||||
}
|
||||
else {
|
||||
center = mo->instances[active_inst]->get_offset() + Vec3d(0., 0., z_shift);
|
||||
}
|
||||
|
||||
float dist = normal.dot(center);
|
||||
|
||||
if (pos < 0.)
|
||||
pos = m_clp_ratio;
|
||||
|
||||
m_clp_ratio = pos;
|
||||
m_clp.reset(new ClippingPlane(normal, (dist - (-m_active_inst_bb_radius) - m_clp_ratio * 2*m_active_inst_bb_radius)));
|
||||
|
||||
m_clp.reset(new ClippingPlane(normal, (dist - (-m_active_inst_bb_radius) - m_clp_ratio * 2 * m_active_inst_bb_radius)));
|
||||
|
||||
get_pool()->get_canvas()->set_as_dirty();
|
||||
}
|
||||
|
||||
|
|
|
@ -54,9 +54,16 @@ GLGizmosManager::GLGizmosManager(GLCanvas3D& parent)
|
|||
std::vector<size_t> GLGizmosManager::get_selectable_idxs() const
|
||||
{
|
||||
std::vector<size_t> out;
|
||||
for (size_t i=0; i<m_gizmos.size(); ++i)
|
||||
if (m_parent.get_canvas_type() == GLCanvas3D::CanvasAssembleView) {
|
||||
for (size_t i = 0; i < m_gizmos.size(); ++i)
|
||||
if (m_gizmos[i]->get_sprite_id() == (unsigned int)MmuSegmentation)
|
||||
out.push_back(i);
|
||||
}
|
||||
else {
|
||||
for (size_t i = 0; i < m_gizmos.size(); ++i)
|
||||
if (m_gizmos[i]->is_selectable())
|
||||
out.push_back(i);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
|
@ -78,6 +85,8 @@ size_t GLGizmosManager::get_gizmo_idx_from_mouse(const Vec2d& mouse_pos) const
|
|||
#if BBS_TOOLBAR_ON_TOP
|
||||
//float space_width = GLGizmosManager::Default_Icons_Size * wxGetApp().toolbar_icon_scale();;
|
||||
float top_x = std::max(m_parent.get_main_toolbar_width() + border, 0.5f * (cnv_w - width + m_parent.get_main_toolbar_width() + m_parent.get_collapse_toolbar_width() - m_parent.get_assemble_view_toolbar_width()) + border);
|
||||
if (m_parent.get_canvas_type() == GLCanvas3D::CanvasAssembleView)
|
||||
top_x = 0.5f * cnv_w + 0.5f * (m_parent.get_assembly_paint_toolbar_width());
|
||||
float top_y = 0;
|
||||
float stride_x = m_layout.scaled_stride_x();
|
||||
|
||||
|
@ -1372,6 +1381,11 @@ void GLGizmosManager::do_render_overlay() const
|
|||
float width = get_scaled_total_width();
|
||||
float zoomed_border = m_layout.scaled_border() * inv_zoom;
|
||||
|
||||
float zoomed_top_x;
|
||||
if (m_parent.get_canvas_type() == GLCanvas3D::CanvasAssembleView) {
|
||||
zoomed_top_x = 0.5f * m_parent.get_assembly_paint_toolbar_width() * inv_zoom;
|
||||
}
|
||||
else {
|
||||
//BBS: GUI refactor: GLToolbar&&Gizmo adjust
|
||||
#if BBS_TOOLBAR_ON_TOP
|
||||
float main_toolbar_width = (float)m_parent.get_main_toolbar_width();
|
||||
|
@ -1382,7 +1396,8 @@ void GLGizmosManager::do_render_overlay() const
|
|||
|
||||
float main_toolbar_left = std::max(-0.5f * cnv_w, -0.5f * (main_toolbar_width + get_scaled_total_width() + assemble_view_width - collapse_width)) * inv_zoom;
|
||||
//float zoomed_top_x = 0.5f *(main_toolbar_width + collapse_width - width - assemble_view_width) * inv_zoom;
|
||||
float zoomed_top_x = main_toolbar_left + (main_toolbar_width) *inv_zoom;
|
||||
zoomed_top_x = main_toolbar_left + (main_toolbar_width)*inv_zoom;
|
||||
}
|
||||
float zoomed_top_y = 0.5f * cnv_h * inv_zoom;
|
||||
#else
|
||||
//float zoomed_top_x = (-0.5f * cnv_w) * inv_zoom;
|
||||
|
|
|
@ -241,7 +241,7 @@ void MeshRaycaster::line_from_mouse_pos(const Vec2d& mouse_pos, const Transform3
|
|||
|
||||
bool MeshRaycaster::unproject_on_mesh(const Vec2d& mouse_pos, const Transform3d& trafo, const Camera& camera,
|
||||
Vec3f& position, Vec3f& normal, const ClippingPlane* clipping_plane,
|
||||
size_t* facet_idx) const
|
||||
size_t* facet_idx, bool sinking_limit) const
|
||||
{
|
||||
Vec3d point;
|
||||
Vec3d direction;
|
||||
|
@ -258,8 +258,8 @@ bool MeshRaycaster::unproject_on_mesh(const Vec2d& mouse_pos, const Transform3d&
|
|||
// Also, remove anything below the bed (sinking objects).
|
||||
for (i=0; i<hits.size(); ++i) {
|
||||
Vec3d transformed_hit = trafo * hits[i].position();
|
||||
if (transformed_hit.z() >= SINKING_Z_THRESHOLD &&
|
||||
(! clipping_plane || ! clipping_plane->is_point_clipped(transformed_hit)))
|
||||
if (transformed_hit.z() >= sinking_limit ? SINKING_Z_THRESHOLD : -std::numeric_limits<double>::max() &&
|
||||
(!clipping_plane || !clipping_plane->is_point_clipped(transformed_hit)))
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -150,7 +150,8 @@ public:
|
|||
Vec3f& position, // where to save the positibon of the hit (mesh coords)
|
||||
Vec3f& normal, // normal of the triangle that was hit
|
||||
const ClippingPlane* clipping_plane = nullptr, // clipping plane (if active)
|
||||
size_t* facet_idx = nullptr // index of the facet hit
|
||||
size_t* facet_idx = nullptr, // index of the facet hit
|
||||
bool sinking_limit = true
|
||||
) const;
|
||||
|
||||
// Given a vector of points in woorld coordinates, this returns vector
|
||||
|
|
|
@ -2481,6 +2481,8 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
|
|||
assemble_canvas->Bind(EVT_GLCANVAS_OBJECT_SELECT, &priv::on_object_select, this);
|
||||
assemble_canvas->Bind(EVT_GLVIEWTOOLBAR_3D, [q](SimpleEvent&) { q->select_view_3D("3D"); });
|
||||
assemble_canvas->Bind(EVT_GLCANVAS_RIGHT_CLICK, &priv::on_right_click, this);
|
||||
assemble_canvas->Bind(EVT_GLCANVAS_UNDO, [this](SimpleEvent&) { this->undo(); });
|
||||
assemble_canvas->Bind(EVT_GLCANVAS_REDO, [this](SimpleEvent&) { this->redo(); });
|
||||
}
|
||||
|
||||
if (wxGetApp().is_editor()) {
|
||||
|
@ -4158,6 +4160,7 @@ void Plater::priv::reset(bool apply_presets_change)
|
|||
// Stop and reset the Print content.
|
||||
this->background_process.reset();
|
||||
model.clear_objects();
|
||||
assemble_view->get_canvas3d()->reset_explosion_ratio();
|
||||
update();
|
||||
|
||||
//BBS
|
||||
|
@ -7263,18 +7266,19 @@ void Plater::priv::take_snapshot(const std::string& snapshot_name, const UndoRed
|
|||
tower.rotation = proj_cfg.opt_float("wipe_tower_rotation_angle");
|
||||
}
|
||||
}
|
||||
const GLGizmosManager& gizmos = view3D->get_canvas3d()->get_gizmos_manager();
|
||||
const GLGizmosManager& gizmos = get_current_canvas3D()->get_canvas_type() == GLCanvas3D::CanvasAssembleView ? assemble_view->get_canvas3d()->get_gizmos_manager() : view3D->get_canvas3d()->get_gizmos_manager();
|
||||
|
||||
if (snapshot_type == UndoRedo::SnapshotType::ProjectSeparator)
|
||||
this->undo_redo_stack().clear();
|
||||
this->undo_redo_stack().take_snapshot(snapshot_name, model, view3D->get_canvas3d()->get_selection(), view3D->get_canvas3d()->get_gizmos_manager(), partplate_list, snapshot_data);
|
||||
this->undo_redo_stack().take_snapshot(snapshot_name, model, get_current_canvas3D()->get_canvas_type() == GLCanvas3D::CanvasAssembleView ? assemble_view->get_canvas3d()->get_selection() : view3D->get_canvas3d()->get_selection(), gizmos, partplate_list, snapshot_data);
|
||||
if (snapshot_type == UndoRedo::SnapshotType::LeavingGizmoWithAction) {
|
||||
// Filter all but the last UndoRedo::SnapshotType::GizmoAction in a row between the last UndoRedo::SnapshotType::EnteringGizmo and UndoRedo::SnapshotType::LeavingGizmoWithAction.
|
||||
// The remaining snapshot will be renamed to a more generic name,
|
||||
// depending on what gizmo is being left.
|
||||
assert(gizmos.get_current() != nullptr);
|
||||
if (gizmos.get_current() != nullptr) {
|
||||
std::string new_name = gizmos.get_current()->get_action_snapshot_name();
|
||||
this->undo_redo_stack().reduce_noisy_snapshots(new_name);
|
||||
}
|
||||
} else if (snapshot_type == UndoRedo::SnapshotType::ProjectSeparator) {
|
||||
// Reset the "dirty project" flag.
|
||||
m_undo_redo_stack_main.mark_current_as_saved();
|
||||
|
@ -7296,6 +7300,13 @@ void Plater::priv::undo()
|
|||
// BBS: undo-redo until modify record
|
||||
while (--it_current != snapshots.begin() && !snapshot_modifies_project(*it_current));
|
||||
if (it_current == snapshots.begin()) return;
|
||||
if (get_current_canvas3D()->get_canvas_type() == GLCanvas3D::CanvasAssembleView) {
|
||||
if (it_current->snapshot_data.snapshot_type != UndoRedo::SnapshotType::GizmoAction &&
|
||||
it_current->snapshot_data.snapshot_type != UndoRedo::SnapshotType::EnteringGizmo &&
|
||||
it_current->snapshot_data.snapshot_type != UndoRedo::SnapshotType::LeavingGizmoNoAction &&
|
||||
it_current->snapshot_data.snapshot_type != UndoRedo::SnapshotType::LeavingGizmoWithAction)
|
||||
return;
|
||||
}
|
||||
this->undo_redo_to(it_current);
|
||||
}
|
||||
|
||||
|
@ -7398,8 +7409,8 @@ void Plater::priv::undo_redo_to(std::vector<UndoRedo::Snapshot>::const_iterator
|
|||
const UndoRedo::Snapshot snapshot_copy = *it_snapshot;
|
||||
// Do the jump in time.
|
||||
if (it_snapshot->timestamp < this->undo_redo_stack().active_snapshot_time() ?
|
||||
this->undo_redo_stack().undo(model, this->view3D->get_canvas3d()->get_selection(), this->view3D->get_canvas3d()->get_gizmos_manager(), this->partplate_list, top_snapshot_data, it_snapshot->timestamp) :
|
||||
this->undo_redo_stack().redo(model, this->view3D->get_canvas3d()->get_gizmos_manager(), this->partplate_list, it_snapshot->timestamp)) {
|
||||
this->undo_redo_stack().undo(model, get_current_canvas3D()->get_canvas_type() == GLCanvas3D::CanvasAssembleView ? assemble_view->get_canvas3d()->get_selection() : this->view3D->get_canvas3d()->get_selection(), get_current_canvas3D()->get_canvas_type() == GLCanvas3D::CanvasAssembleView ? assemble_view->get_canvas3d()->get_gizmos_manager() : this->view3D->get_canvas3d()->get_gizmos_manager(), this->partplate_list, top_snapshot_data, it_snapshot->timestamp) :
|
||||
this->undo_redo_stack().redo(model, get_current_canvas3D()->get_canvas_type() == GLCanvas3D::CanvasAssembleView ? assemble_view->get_canvas3d()->get_gizmos_manager() : this->view3D->get_canvas3d()->get_gizmos_manager(), this->partplate_list, it_snapshot->timestamp)) {
|
||||
if (printer_technology_changed) {
|
||||
// Switch to the other printer technology. Switch to the last printer active for that particular technology.
|
||||
AppConfig *app_config = wxGetApp().app_config;
|
||||
|
@ -7476,7 +7487,7 @@ void Plater::priv::undo_redo_to(std::vector<UndoRedo::Snapshot>::const_iterator
|
|||
|
||||
void Plater::priv::update_after_undo_redo(const UndoRedo::Snapshot& snapshot, bool /* temp_snapshot_was_taken */)
|
||||
{
|
||||
this->view3D->get_canvas3d()->get_selection().clear();
|
||||
get_current_canvas3D()->get_canvas_type() == GLCanvas3D::CanvasAssembleView ? assemble_view->get_canvas3d()->get_selection().clear() : this->view3D->get_canvas3d()->get_selection().clear();
|
||||
// Update volumes from the deserializd model, always stop / update the background processing (for both the SLA and FFF technologies).
|
||||
this->update((unsigned int)UpdateParams::FORCE_BACKGROUND_PROCESSING_UPDATE | (unsigned int)UpdateParams::POSTPONE_VALIDATION_ERROR_MESSAGE);
|
||||
// Release old snapshots if the memory allocated is excessive. This may remove the top most snapshot if jumping to the very first snapshot.
|
||||
|
@ -7485,7 +7496,11 @@ void Plater::priv::update_after_undo_redo(const UndoRedo::Snapshot& snapshot, bo
|
|||
// triangle meshes may have gotten released from the scene or the background processing, therefore now being calculated into the Undo / Redo stack size.
|
||||
this->undo_redo_stack().release_least_recently_used();
|
||||
//YS_FIXME update obj_list from the deserialized model (maybe store ObjectIDs into the tree?) (no selections at this point of time)
|
||||
get_current_canvas3D()->get_canvas_type() == GLCanvas3D::CanvasAssembleView ?
|
||||
assemble_view->get_canvas3d()->get_selection().set_deserialized(GUI::Selection::EMode(this->undo_redo_stack().selection_deserialized().mode), this->undo_redo_stack().selection_deserialized().volumes_and_instances) :
|
||||
this->view3D->get_canvas3d()->get_selection().set_deserialized(GUI::Selection::EMode(this->undo_redo_stack().selection_deserialized().mode), this->undo_redo_stack().selection_deserialized().volumes_and_instances);
|
||||
get_current_canvas3D()->get_canvas_type() == GLCanvas3D::CanvasAssembleView ?
|
||||
assemble_view->get_canvas3d()->get_gizmos_manager().update_after_undo_redo(snapshot) :
|
||||
this->view3D->get_canvas3d()->get_gizmos_manager().update_after_undo_redo(snapshot);
|
||||
|
||||
wxGetApp().obj_list()->update_after_undo_redo();
|
||||
|
|
|
@ -2712,9 +2712,14 @@ void Selection::paste_objects_from_clipboard()
|
|||
displacement = {empty_cell.x() + point_offset.x(), empty_cell.y() + point_offset.y(), start_offset(2)};
|
||||
}
|
||||
|
||||
for (ModelInstance* inst : dst_object->instances)
|
||||
for (ModelInstance* inst : dst_object->instances) {
|
||||
inst->set_offset(displacement);
|
||||
|
||||
//BBS init asssmble transformation
|
||||
Geometry::Transformation t = inst->get_transformation();
|
||||
inst->set_assemble_transformation(t);
|
||||
}
|
||||
|
||||
object_idxs.push_back(m_model->objects.size() - 1);
|
||||
#ifdef _DEBUG
|
||||
check_model_ids_validity(*m_model);
|
||||
|
|
|
@ -479,10 +479,11 @@ public:
|
|||
assert(! m_history.empty());
|
||||
auto it = std::lower_bound(m_history.begin(), m_history.end(), MutableHistoryInterval(timestamp, timestamp));
|
||||
if (it == m_history.end() || it->begin() > timestamp) {
|
||||
assert(it != m_history.begin());
|
||||
-- it;
|
||||
//assert(it != m_history.begin());
|
||||
if (it != m_history.begin())
|
||||
--it;
|
||||
}
|
||||
assert(timestamp >= it->begin() && timestamp < it->end());
|
||||
//assert(timestamp >= it->begin() && timestamp < it->end());
|
||||
return std::string(it->data(), it->data() + it->size());
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue