FIX:Brim ears support following the movement of the volume

jira: STUDIO-11415
Change-Id: I5c7913e86a8dba597bd721f9f2ceae596a7b328b
This commit is contained in:
Mack 2025-04-30 18:19:16 +08:00 committed by lane.wei
parent d84a3dadbd
commit 36810134cb
5 changed files with 43 additions and 15 deletions

View File

@ -817,7 +817,10 @@ static ExPolygons make_brim_ears(const PrintObject* object, const double& flowWi
const Point &center_offset = object->center_offset();
model_trsf = model_trsf.pretranslate(Vec3d(- unscale<double>(center_offset.x()), - unscale<double>(center_offset.y()), 0));
for (auto &pt : brim_ear_points) {
Vec3f world_pos = pt.transform(trsf.get_matrix());
Transform3d v_trsf = Transform3d::Identity();
if (pt.volume_idx > -1)
v_trsf = object->model_object()->volumes[pt.volume_idx]->get_matrix();
Vec3f world_pos = pt.transform(trsf.get_matrix() * v_trsf);
if ( world_pos.z() > 0) continue;
Polygon point_round;
float brim_width = floor(scale_(pt.head_front_radius) / flowWidth / 2) * flowWidth * 2;
@ -832,7 +835,7 @@ static ExPolygons make_brim_ears(const PrintObject* object, const double& flowWi
}
mouse_ears_ex.emplace_back();
mouse_ears_ex.back().contour = point_round;
Vec3f pos = pt.transform(model_trsf);
Vec3f pos = pt.transform(model_trsf * v_trsf);
int32_t pt_x = scale_(pos.x());
int32_t pt_y = scale_(pos.y());
mouse_ears_ex.back().contour.translate(Point(pt_x, pt_y));

View File

@ -18,6 +18,7 @@ struct BrimPoint
{
Vec3f pos;
float head_front_radius;
int volume_idx;
BrimPoint()
: pos(Vec3f::Zero()), head_front_radius(0.f)
@ -26,14 +27,17 @@ struct BrimPoint
BrimPoint(float pos_x,
float pos_y,
float pos_z,
float head_radius)
float head_radius,
int volume_idx = -1)
: pos(pos_x, pos_y, pos_z)
, head_front_radius(head_radius)
, volume_idx(volume_idx)
{}
BrimPoint(Vec3f position, float head_radius)
BrimPoint(Vec3f position, float head_radius, int volume_idx = -1)
: pos(position)
, head_front_radius(head_radius)
, volume_idx(volume_idx)
{}
Vec3f transform(const Transform3d &trsf)

View File

@ -3124,7 +3124,10 @@ void ObjectList::merge(bool to_multipart_object)
// merge brim ears
BrimPoints temp_brim_points = object->brim_points;
for(auto& p : temp_brim_points) {
p.set_transform(transformation_matrix);
Transform3d v_matrix = Transform3d::Identity();
if (p.volume_idx >= 0)
v_matrix = object->volumes[p.volume_idx]->get_matrix();
p.set_transform(transformation_matrix * v_matrix);
new_object->brim_points.push_back(p);
}
}
@ -3137,10 +3140,13 @@ void ObjectList::merge(bool to_multipart_object)
//BBS init asssmble transformation
Geometry::Transformation new_object_trsf = new_object->instances[0]->get_transformation();
new_object->instances[0]->set_assemble_transformation(new_object_trsf);
// merge brim ears
const Transform3d& new_object_inverse_matrix = new_object_trsf.get_matrix().inverse();
for (auto& p : new_object->brim_points) {
p.set_transform(new_object_inverse_matrix);
Transform3d v_matrix_inverse = Transform3d::Identity();
if (p.volume_idx >= 0)
v_matrix_inverse = new_object->volumes[p.volume_idx]->get_matrix().inverse();
p.set_transform(new_object_inverse_matrix * v_matrix_inverse);
}
//BBS: notify it before remove
notify_instance_updated(m_objects->size() - 1);

View File

@ -122,6 +122,7 @@ void GLGizmoBrimEars::render_points(const Selection &selection, bool picking) co
const Camera& camera = picking ? wxGetApp().plater()->get_picking_camera() : wxGetApp().plater()->get_camera();
const Transform3d& view_matrix = camera.get_view_matrix();
const Transform3d& projection_matrix = camera.get_projection_matrix();
Transform3d volume_matrix = Transform3d::Identity();
shader->set_uniform("projection_matrix", projection_matrix);
@ -133,6 +134,9 @@ void GLGizmoBrimEars::render_points(const Selection &selection, bool picking) co
const bool &error = editing_cache[i].is_error;
if (!is_use_point(brim_point) && !hover)
continue;
if (brim_point.volume_idx >= 0)
volume_matrix = selection.get_volume(brim_point.volume_idx)->get_volume_transformation().get_matrix();
// keep show brim ear
// if (is_mesh_point_clipped(brim_point.pos.cast<double>()))
// continue;
@ -163,7 +167,7 @@ void GLGizmoBrimEars::render_points(const Selection &selection, bool picking) co
if (shader && !picking) shader->set_uniform("emission_factor", 0.5f);
// Inverse matrix of the instance scaling is applied so that the mark does not scale with the object.
const Transform3d brim_matrix = Geometry::assemble_transform(brim_point.pos.cast<double>()) * instance_scaling_matrix_inverse;
const Transform3d brim_matrix = Geometry::assemble_transform(brim_point.pos.cast<double>()) * instance_scaling_matrix_inverse * volume_matrix;
if (vol->is_left_handed())
glFrontFace(GL_CW);
@ -309,7 +313,10 @@ bool GLGizmoBrimEars::gizmo_event(SLAGizmoEventType action, const Vec2d &mouse_p
Transform3d inverse_trsf = volume->get_instance_transformation().get_matrix(true).inverse();
std::pair<Vec3f, Vec3f> pos_and_normal;
if (unproject_on_mesh2(mouse_position, pos_and_normal)) {
render_hover_point = CacheEntry(BrimPoint(pos_and_normal.first, m_new_point_head_diameter / 2.f), false, (inverse_trsf * m_world_normal).cast<float>(), true);
int volume_idx = m_last_hit_volume->volume_idx();
Transform3d v_trsf = selection.get_volume(volume_idx)->get_volume_transformation().get_matrix();
Vec3d set_volume_trsf_pos = v_trsf.inverse() * pos_and_normal.first.cast<double>();
render_hover_point = CacheEntry(BrimPoint(set_volume_trsf_pos.cast<float>(), m_new_point_head_diameter / 2.f, volume_idx), false, (inverse_trsf * m_world_normal).cast<float>(), true);
} else {
render_hover_point.reset();
}
@ -338,17 +345,19 @@ bool GLGizmoBrimEars::gizmo_event(SLAGizmoEventType action, const Vec2d &mouse_p
std::pair<Vec3f, Vec3f> pos_and_normal;
if (unproject_on_mesh2(mouse_position, pos_and_normal)) {
// we got an intersection
int volume_idx = m_last_hit_volume->volume_idx();
const Selection &selection = m_parent.get_selection();
const GLVolume *volume = selection.get_volume(*selection.get_volume_idxs().begin());
Transform3d trsf = volume->get_instance_transformation().get_matrix();
Transform3d inverse_trsf = volume->get_instance_transformation().get_matrix(true).inverse();
Transform3d v_trsf = selection.get_volume(volume_idx)->get_volume_transformation().get_matrix();
// BBS brim ear postion is placed on the bottom side
Vec3d world_pos = trsf * pos_and_normal.first.cast<double>();
world_pos[2] = -0.0001;
Vec3d object_pos = trsf.inverse() * world_pos;
Vec3d object_pos = trsf.inverse() * v_trsf.inverse() * world_pos;
// brim ear always face up
Plater::TakeSnapshot snapshot(wxGetApp().plater(), "Add brim ear");
add_point_to_cache(object_pos.cast<float>(), m_new_point_head_diameter / 2.f, false, (inverse_trsf * m_world_normal).cast<float>());
add_point_to_cache(object_pos.cast<float>(), m_new_point_head_diameter / 2.f, false, (inverse_trsf * m_world_normal).cast<float>(), volume_idx);
m_parent.set_as_dirty();
m_wait_for_up_event = true;
find_single();
@ -982,9 +991,9 @@ void GLGizmoBrimEars::get_detection_radius_max()
}
}
bool GLGizmoBrimEars::add_point_to_cache(Vec3f pos, float head_radius, bool selected, Vec3f normal)
bool GLGizmoBrimEars::add_point_to_cache(Vec3f pos, float head_radius, bool selected, Vec3f normal, int volume_idx)
{
BrimPoint point(pos, head_radius);
BrimPoint point(pos, head_radius, volume_idx);
for (int i = 0; i < m_editing_cache.size(); i++) {
if (m_editing_cache[i].brim_point == point) { return false; }
}
@ -1055,7 +1064,6 @@ void GLGizmoBrimEars::find_single()
}
const Selection &selection = m_parent.get_selection();
const GLVolume *volume = selection.get_volume(*selection.get_volume_idxs().begin());
Geometry::Transformation trsf = volume->get_instance_transformation();
ExPolygons model_pl = m_first_layer;
m_single_brim.clear();
@ -1071,6 +1079,13 @@ void GLGizmoBrimEars::find_single()
}
auto end = --m_single_brim.end();
for (auto it = m_single_brim.begin(); it != m_single_brim.end(); ++it) {
int volume_idx = it->second.brim_point.volume_idx;
Geometry::Transformation trsf = volume->get_instance_transformation();
if (volume_idx >= 0){
const Geometry::Transformation v_trsf = selection.get_volume(volume_idx)->get_volume_transformation();
trsf = trsf * v_trsf;
}
ExPolygon point_pl = make_polygon(it->second.brim_point, trsf);
if (overlaps(model_pl, point_pl)) {
model_pl.emplace_back(point_pl);

View File

@ -164,7 +164,7 @@ protected:
void register_single_mesh_pick();
void update_single_mesh_pick(GLVolume* v);
void reset_all_pick();
bool add_point_to_cache(Vec3f pos, float head_radius, bool selected, Vec3f normal);
bool add_point_to_cache(Vec3f pos, float head_radius, bool selected, Vec3f normal, int volume_idx=-1);
float get_brim_default_radius() const;
ExPolygon make_polygon(BrimPoint point, const Geometry::Transformation &trsf);
void find_single();