OrcaSlicer latest
OrcaSlicer
Loading...
Searching...
No Matches
anonymous_namespace{SurfaceDrag.cpp} Namespace Reference

Functions

Vec2d mouse_position (const wxMouseEvent &mouse_event)
 Extract position of mouse from mouse event.
bool start_dragging (const Vec2d &mouse_pos, const Camera &camera, std::optional< SurfaceDrag > &surface_drag, GLCanvas3D &canvas, RaycastManager &raycast_manager, const std::optional< double > &up_limit)
bool dragging (const Vec2d &mouse_pos, const Camera &camera, SurfaceDrag &surface_drag, GLCanvas3D &canvas, const RaycastManager &raycast_manager, const std::optional< double > &up_limit)
Transform3d get_volume_transformation (Transform3d world, const Vec3d &world_dir, const Vec3d &world_position, const std::optional< Transform3d > &fix, const Transform3d &instance_inv, std::optional< float > current_angle={}, const std::optional< double > &up_limit={})
bool is_embossed_object (const Selection &selection)
const Transform3d * get_fix_transformation (const Selection &selection)
 Get fix transformation for selected volume Fix after store to 3mf.

Variables

constexpr Slic3r::MinMax< double > surface_distance_sq {1e-4, 10.}

Function Documentation

◆ dragging()

bool anonymous_namespace{SurfaceDrag.cpp}::dragging ( const Vec2d & mouse_pos,
const Camera & camera,
SurfaceDrag & surface_drag,
GLCanvas3D & canvas,
const RaycastManager & raycast_manager,
const std::optional< double > & up_limit )
673{
674 Vec2d offseted_mouse = mouse_pos + surface_drag.mouse_offset_without_sla_shift;
675 std::optional<RaycastManager::Hit> hit = ray_from_camera(
676 raycast_manager, offseted_mouse, camera, &surface_drag.condition);
677
678 surface_drag.exist_hit = hit.has_value();
679 if (!hit.has_value()) {
680 // cross hair need redraw
681 canvas.set_as_dirty();
682 return true;
683 }
684
685 const ModelVolume *volume = get_model_volume(*surface_drag.gl_volume, canvas.get_model()->objects);
686 std::optional<Transform3d> fix;
687 if (volume !=nullptr &&
688 volume->emboss_shape.has_value() &&
689 volume->emboss_shape->fix_3mf_tr.has_value())
690 fix = volume->emboss_shape->fix_3mf_tr;
691 Transform3d volume_new = get_volume_transformation(surface_drag.world, hit->normal, hit->position,
692 fix, surface_drag.instance_inv, surface_drag.start_angle, up_limit);
693
694 // Update transformation for all instances
695 for (GLVolume *vol : canvas.get_volumes().volumes) {
696 if (vol->object_idx() != surface_drag.gl_volume->object_idx() ||
697 vol->volume_idx() != surface_drag.gl_volume->volume_idx())
698 continue;
699 vol->set_volume_transformation(volume_new);
700 }
701
702 canvas.set_as_dirty();
703 // Show current position in manipulation panel
704 wxGetApp().obj_manipul()->set_dirty();
705 return true;
706}
GLVolumePtrs volumes
Definition 3DScene.hpp:468
Definition 3DScene.hpp:90
int volume_idx() const
Definition 3DScene.hpp:345
int object_idx() const
Definition 3DScene.hpp:344
const GLVolumeCollection & get_volumes() const
Definition GLCanvas3D.hpp:993
void set_as_dirty()
Definition GLCanvas3D.hpp:984
const Model * get_model() const
Definition GLCanvas3D.hpp:1026
Definition Model.hpp:832
std::optional< EmbossShape > emboss_shape
Definition Model.hpp:1019
ModelObjectPtrs objects
Definition Model.hpp:1702
Transform3d world
Definition SurfaceDrag.hpp:29
RaycastManager::AllowVolumes condition
Definition SurfaceDrag.hpp:39
bool exist_hit
Definition SurfaceDrag.hpp:48
Transform3d instance_inv
Definition SurfaceDrag.hpp:33
GLVolume * gl_volume
Definition SurfaceDrag.hpp:36
std::optional< float > start_angle
Definition SurfaceDrag.hpp:42
static ModelVolume * get_model_volume(const Selection &selection, Model &model)
Definition GLGizmoBrimEars.cpp:66
Vec2d mouse_offset_without_sla_shift
Definition SurfaceDrag.hpp:51
std::optional< RaycastManager::Hit > ray_from_camera(const RaycastManager &raycaster, const Vec2d &mouse_pos, const Camera &camera, const RaycastManager::ISkip *skip)
Unproject on mesh by Mesh raycasters.
Definition RaycastManager.cpp:365
Eigen::Transform< double, 3, Eigen::Affine, Eigen::DontAlign > Transform3d
Definition Point.hpp:96
Eigen::Matrix< double, 2, 1, Eigen::DontAlign > Vec2d
Definition Point.hpp:67
Transform3d get_volume_transformation(Transform3d world, const Vec3d &world_dir, const Vec3d &world_position, const std::optional< Transform3d > &fix, const Transform3d &instance_inv, std::optional< float > current_angle={}, const std::optional< double > &up_limit={})
Definition SurfaceDrag.cpp:604

References Slic3r::GUI::SurfaceDrag::condition, Slic3r::ModelVolume::emboss_shape, Slic3r::GUI::SurfaceDrag::exist_hit, Slic3r::GUI::GLCanvas3D::get_model(), Slic3r::GUI::get_model_volume(), get_volume_transformation(), Slic3r::GUI::GLCanvas3D::get_volumes(), Slic3r::GUI::SurfaceDrag::gl_volume, Slic3r::GUI::SurfaceDrag::instance_inv, Slic3r::GUI::SurfaceDrag::mouse_offset_without_sla_shift, Slic3r::GLVolume::object_idx(), Slic3r::Model::objects, Slic3r::GUI::ray_from_camera(), Slic3r::GUI::GLCanvas3D::set_as_dirty(), Slic3r::GUI::SurfaceDrag::start_angle, Slic3r::GLVolume::volume_idx(), Slic3r::GLVolumeCollection::volumes, and Slic3r::GUI::SurfaceDrag::world.

Here is the call graph for this function:

◆ get_fix_transformation()

const Transform3d * anonymous_namespace{SurfaceDrag.cpp}::get_fix_transformation ( const Selection & selection)

Get fix transformation for selected volume Fix after store to 3mf.

Parameters
selectionSelect only wanted volume
Returns
Pointer on fix transformation from ModelVolume when exists otherwise nullptr
714 {
715 const GLVolume *gl_volume = get_selected_gl_volume(selection);
716 assert(gl_volume != nullptr);
717 if (gl_volume == nullptr)
718 return nullptr;
719
720 const ModelVolume *volume = get_model_volume(*gl_volume, selection.get_model()->objects);
721 assert(volume != nullptr);
722 if (volume == nullptr)
723 return nullptr;
724
725 const std::optional<EmbossShape> &es = volume->emboss_shape;
726 if (!volume->emboss_shape.has_value())
727 return nullptr;
728 if (!es->fix_3mf_tr.has_value())
729 return nullptr;
730 return &(*es->fix_3mf_tr);
731}
Model * get_model() const
Definition Selection.hpp:219
GLVolume * get_selected_gl_volume(const GLCanvas3D &canvas)
Definition GLCanvas3D.cpp:13003

References Slic3r::ModelVolume::emboss_shape, Slic3r::GUI::Selection::get_model(), Slic3r::GUI::get_model_volume(), Slic3r::GUI::get_selected_gl_volume(), and Slic3r::Model::objects.

Here is the call graph for this function:

◆ get_volume_transformation()

Transform3d anonymous_namespace{SurfaceDrag.cpp}::get_volume_transformation ( Transform3d world,
const Vec3d & world_dir,
const Vec3d & world_position,
const std::optional< Transform3d > & fix,
const Transform3d & instance_inv,
std::optional< float > current_angle = {},
const std::optional< double > & up_limit = {} )
615{
616 auto world_linear = world.linear().eval();
617 // Calculate offset: transformation to wanted position
618 {
619 // Reset skew of the text Z axis:
620 // Project the old Z axis into a new Z axis, which is perpendicular to the old XY plane.
621 Vec3d old_z = world_linear.col(2);
622 Vec3d new_z = world_linear.col(0).cross(world_linear.col(1));
623 world_linear.col(2) = new_z * (old_z.dot(new_z) / new_z.squaredNorm());
624 }
625
626 Vec3d text_z_world = world_linear.col(2); // world_linear * Vec3d::UnitZ()
627 auto z_rotation = Eigen::Quaternion<double, Eigen::DontAlign>::FromTwoVectors(text_z_world, world_dir);
628 Transform3d world_new = z_rotation * world;
629 auto world_new_linear = world_new.linear().eval();
630
631 // Fix direction of up vector to zero initial rotation
632 if(up_limit.has_value()){
633 Vec3d z_world = world_new_linear.col(2);
634 z_world.normalize();
635 Vec3d wanted_up = Emboss::suggest_up(z_world, *up_limit);
636
637 Vec3d y_world = world_new_linear.col(1);
638 auto y_rotation = Eigen::Quaternion<double, Eigen::DontAlign>::FromTwoVectors(y_world, wanted_up);
639
640 world_new = y_rotation * world_new;
641 world_new_linear = world_new.linear();
642 }
643
644 // Edit position from right
645 Transform3d volume_new{Eigen::Translation<double, 3>(instance_inv * world_position)};
646 volume_new.linear() = instance_inv.linear() * world_new_linear;
647
648 // Check that transformation matrix is valid transformation
649 assert(volume_new.matrix()(0, 0) == volume_new.matrix()(0, 0)); // Check valid transformation not a NAN
650 if (volume_new.matrix()(0, 0) != volume_new.matrix()(0, 0))
651 return Transform3d::Identity();
652
653 // Check that scale in world did not changed
654 assert(!calc_scale(world_linear, world_new_linear, Vec3d::UnitY()).has_value());
655 assert(!calc_scale(world_linear, world_new_linear, Vec3d::UnitZ()).has_value());
656
657 // fix baked transformation from .3mf store process
658 if (fix.has_value())
659 volume_new = volume_new * (*fix);
660
661 // apply move in Z direction and rotation by up vector
662 Emboss::apply_transformation(current_angle, {}, volume_new);
663
664 return volume_new;
665}
void apply_transformation(const std::optional< float > &angle, const std::optional< float > &distance, Transform3d &transformation)
Use data from font property to modify transformation.
Definition Emboss.cpp:1480
Vec3d suggest_up(const Vec3d normal, double up_limit=0.9)
Suggest wanted up vector of embossed text by emboss direction.
Definition Emboss.cpp:1749
static std::optional< double > calc_scale(const Matrix3d &from, const Matrix3d &to, const Vec3d &dir)
Definition SurfaceDrag.cpp:89
Eigen::Matrix< double, 3, 1, Eigen::DontAlign > Vec3d
Definition Point.hpp:68

References Slic3r::Emboss::apply_transformation(), Slic3r::GUI::calc_scale(), and Slic3r::Emboss::suggest_up().

Referenced by dragging().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ is_embossed_object()

bool anonymous_namespace{SurfaceDrag.cpp}::is_embossed_object ( const Selection & selection)
709{
710 assert(selection.volumes_count() == 1);
711 return selection.is_single_full_object() || selection.is_single_full_instance();
712}
unsigned int volumes_count() const
Definition Selection.hpp:322
bool is_single_full_instance() const
Definition Selection.cpp:848
bool is_single_full_object() const
Definition Selection.hpp:279

References Slic3r::GUI::Selection::is_single_full_instance(), Slic3r::GUI::Selection::is_single_full_object(), and Slic3r::GUI::Selection::volumes_count().

Here is the call graph for this function:

◆ mouse_position()

Vec2d anonymous_namespace{SurfaceDrag.cpp}::mouse_position ( const wxMouseEvent & mouse_event)

Extract position of mouse from mouse event.

Parameters
mouse_eventEvent
Returns
Position
502 {
503 // wxCoord == int --> wx/types.h
504 Vec2i32 mouse_coord(mouse_event.GetX(), mouse_event.GetY());
505 return mouse_coord.cast<double>();
506}
Eigen::Matrix< int32_t, 2, 1, Eigen::DontAlign > Vec2i32
Definition Point.hpp:57

References Slic3r::GUI::wxMouseEvent.

◆ start_dragging()

bool anonymous_namespace{SurfaceDrag.cpp}::start_dragging ( const Vec2d & mouse_pos,
const Camera & camera,
std::optional< SurfaceDrag > & surface_drag,
GLCanvas3D & canvas,
RaycastManager & raycast_manager,
const std::optional< double > & up_limit )
514{
515 // selected volume
516 GLVolume *gl_volume_ptr = get_selected_gl_volume(canvas);
517 if (gl_volume_ptr == nullptr)
518 return false;
519 const GLVolume &gl_volume = *gl_volume_ptr;
520
521 // is selected volume closest hovered?
522 const GLVolumePtrs &gl_volumes = canvas.get_volumes().volumes;
523 if (int hovered_idx = canvas.get_first_hover_volume_idx(); hovered_idx < 0)
524 return false;
525 else if (auto hovered_idx_ = static_cast<size_t>(hovered_idx);
526 hovered_idx_ >= gl_volumes.size() || gl_volumes[hovered_idx_] != gl_volume_ptr)
527 return false;
528
529 const ModelObjectPtrs &objects = canvas.get_model()->objects;
530 const ModelObject *object = get_model_object(gl_volume, objects);
531 assert(object != nullptr);
532 if (object == nullptr)
533 return false;
534
535 const ModelInstance *instance = get_model_instance(gl_volume, *object);
536 const ModelVolume *volume = get_model_volume(gl_volume, *object);
537 assert(instance != nullptr && volume != nullptr);
538 if (object == nullptr || instance == nullptr || volume == nullptr)
539 return false;
540
541 // allowed drag&drop by canvas for object
542 if (volume->is_the_only_one_part())
543 return false;
544
545 RaycastManager::AllowVolumes condition = create_condition(object->volumes, volume->id());
546 RaycastManager::Meshes meshes = create_meshes(canvas, condition);
547 // initialize raycasters
548 // INFO: It could slows down for big objects
549 // (may be move to thread and do not show drag until it finish)
550 raycast_manager.actualize(*instance, &condition, &meshes);
551
552 // world_matrix_fixed() without sla shift
553 Transform3d to_world = world_matrix_fixed(gl_volume, objects);
554
555 // zero point of volume in world coordinate system
556 Vec3d volume_center = to_world.translation();
557 // screen coordinate of volume center
558 auto coor = CameraUtils::project(camera, volume_center);
559 Vec2d mouse_offset = coor.cast<double>() - mouse_pos;
560 Vec2d mouse_offset_without_sla_shift = mouse_offset;
561 if (double sla_shift = gl_volume.get_sla_shift_z(); !is_approx(sla_shift, 0.)) {
562 Transform3d to_world_without_sla_move = instance->get_matrix() * volume->get_matrix();
563 if (volume->emboss_shape.has_value() && volume->emboss_shape->fix_3mf_tr.has_value())
564 to_world_without_sla_move = to_world_without_sla_move * (*volume->emboss_shape->fix_3mf_tr);
565 // zero point of volume in world coordinate system
566 volume_center = to_world_without_sla_move.translation();
567 // screen coordinate of volume center
568 coor = CameraUtils::project(camera, volume_center);
569 mouse_offset_without_sla_shift = coor.cast<double>() - mouse_pos;
570 }
571
572 Transform3d volume_tr = gl_volume.get_volume_transformation().get_matrix();
573
574 // fix baked transformation from .3mf store process
575 if (const std::optional<EmbossShape> &es_opt = volume->emboss_shape; es_opt.has_value()) {
576 const std::optional<Slic3r::Transform3d> &fix = es_opt->fix_3mf_tr;
577 if (fix.has_value())
578 volume_tr = volume_tr * fix->inverse();
579 }
580
581 Transform3d instance_tr = instance->get_matrix();
582 Transform3d instance_tr_inv = instance_tr.inverse();
583 Transform3d world_tr = instance_tr * volume_tr;
584 std::optional<float> start_angle;
585 if (up_limit.has_value()) {
586 start_angle = Emboss::calc_up(world_tr, *up_limit);
587 if (start_angle.has_value() && has_reflection(world_tr))
588 start_angle = -(*start_angle);
589 }
590
591 std::optional<float> start_distance;
592 if (!volume->emboss_shape->projection.use_surface)
593 start_distance = calc_distance(gl_volume, raycast_manager, &condition, volume->emboss_shape->fix_3mf_tr);
594 surface_drag = SurfaceDrag{mouse_offset, world_tr, instance_tr_inv,
595 gl_volume_ptr, condition, start_angle,
596 start_distance, true, mouse_offset_without_sla_shift};
597
598 // disable moving with object by mouse
599 canvas.enable_moving(false);
600 canvas.enable_picking(false);
601 return true;
602}
double get_sla_shift_z() const
Definition 3DScene.hpp:334
const Geometry::Transformation & get_volume_transformation() const
Definition 3DScene.hpp:306
static Points project(const Camera &camera, const std::vector< Vec3d > &points)
Project point throw camera to 2d coordinate into imgui window.
Definition CameraUtils.cpp:23
void enable_picking(bool enable)
Definition GLCanvas3D.hpp:1086
int get_first_hover_volume_idx() const
Definition GLCanvas3D.hpp:1333
void enable_moving(bool enable)
Definition GLCanvas3D.hpp:1094
Definition RaycastManager.hpp:106
void actualize(const ModelObject &object, const ISkip *skip=nullptr, Meshes *meshes=nullptr)
Actualize raycasters + transformation Detection of removed object Detection of removed instance Detec...
Definition RaycastManager.cpp:38
std::vector< Mesh > Meshes
Definition RaycastManager.hpp:29
const Transform3d & get_matrix() const
Definition Geometry.hpp:477
Definition Model.hpp:1421
const Transform3d & get_matrix() const
Definition Model.hpp:1511
Definition Model.hpp:382
ModelVolumePtrs volumes
Definition Model.hpp:393
const Transform3d & get_matrix() const
Definition Model.hpp:1139
bool is_the_only_one_part() const
Definition Model.cpp:2128
ObjectID id() const
Definition ObjectID.hpp:69
std::optional< float > calc_up(const Transform3d &tr, double up_limit=0.9)
By transformation calculate angle between suggested and actual up vector.
Definition Emboss.cpp:1768
ModelObject * get_model_object(const GLVolume &gl_volume, const Model &model)
Definition GLCanvas3D.cpp:13015
RaycastManager::Meshes create_meshes(GLCanvas3D &canvas, const RaycastManager::AllowVolumes &condition)
Use scene Raycasters and prepare data for actualize RaycasterManager.
Definition RaycastManager.cpp:330
std::optional< float > calc_distance(const GLVolume &gl_volume, RaycastManager &raycaster, GLCanvas3D &canvas)
Calculate distance by ray to surface of object in emboss direction.
Definition SurfaceDrag.cpp:198
Transform3d world_matrix_fixed(const GLVolume &gl_volume, const ModelObjectPtrs &objects)
Get transformation to world.
Definition SurfaceDrag.cpp:278
RaycastManager::AllowVolumes create_condition(const ModelVolumePtrs &volumes, const ObjectID &disallowed_volume_id)
Create condition to allowe only parts from volumes without one given.
Definition RaycastManager.cpp:376
ModelInstance * get_model_instance(const GLVolume &gl_volume, const Model &model)
Definition GLCanvas3D.cpp:13028
constexpr bool is_approx(Number value, Number test_value, Number precision=EPSILON)
Definition libslic3r.h:320
std::vector< GLVolume * > GLVolumePtrs
Definition 3DScene.hpp:412
bool has_reflection(const Transform3d &transform)
Check whether transformation matrix contains odd number of mirroring. NOTE: In code is sometime funct...
Definition Point.hpp:179
std::vector< ModelObject * > ModelObjectPtrs
Definition CutUtils.hpp:13

References Slic3r::GUI::RaycastManager::actualize(), Slic3r::GUI::calc_distance(), Slic3r::Emboss::calc_up(), Slic3r::GUI::create_condition(), Slic3r::GUI::create_meshes(), Slic3r::ModelVolume::emboss_shape, Slic3r::GUI::GLCanvas3D::enable_moving(), Slic3r::GUI::GLCanvas3D::enable_picking(), Slic3r::GUI::GLCanvas3D::get_first_hover_volume_idx(), Slic3r::Geometry::Transformation::get_matrix(), Slic3r::ModelInstance::get_matrix(), Slic3r::ModelVolume::get_matrix(), Slic3r::GUI::GLCanvas3D::get_model(), Slic3r::GUI::get_model_instance(), Slic3r::GUI::get_model_object(), Slic3r::GUI::get_model_volume(), Slic3r::GUI::get_selected_gl_volume(), Slic3r::GLVolume::get_sla_shift_z(), Slic3r::GLVolume::get_volume_transformation(), Slic3r::GUI::GLCanvas3D::get_volumes(), Slic3r::has_reflection(), Slic3r::ObjectBase::id(), Slic3r::is_approx(), Slic3r::ModelVolume::is_the_only_one_part(), Slic3r::Model::objects, Slic3r::GUI::CameraUtils::project(), Slic3r::GLVolumeCollection::volumes, Slic3r::ModelObject::volumes, and Slic3r::GUI::world_matrix_fixed().

Here is the call graph for this function:

Variable Documentation

◆ surface_distance_sq

Slic3r::MinMax<double> anonymous_namespace{SurfaceDrag.cpp}::surface_distance_sq {1e-4, 10.}
constexpr
39{1e-4, 10.}; // [in mm]