575{
576 ModelObject* cut_mo =
m_model.objects.front();
577
578
579 ModelObject* upper{ nullptr };
580 cut_mo->clone_for_cut(&upper);
581 ModelObject* lower{ nullptr };
582 cut_mo->clone_for_cut(&lower);
583
584 if (upper && lower) {
585 upper->name = upper->name + "_A";
586 lower->name = lower->name + "_B";
587 }
588
589
590 std::vector<std::optional<TriangleSelector::SavedPainting>> saved_paintings;
592 const auto instance_matrix = cut_mo->instances[
m_instance]->get_transformation().get_matrix_no_offset();
593 for (const auto volume : cut_mo->volumes) {
594 saved_paintings.emplace_back(volume->save_painting());
595 if (saved_paintings.back()) {
596
597 saved_paintings.back()->mesh.transform(instance_matrix * volume->get_matrix(), true);
598 }
599 }
600 }
601
602 const double groove_half_depth = 0.5 * double(groove.depth);
603
604 Model tmp_model_for_cut = Model();
605
606 Model tmp_model = Model();
607 tmp_model.add_object(*cut_mo);
608 ModelObject* tmp_object = tmp_model.objects.front();
609
610 auto add_volumes_from_cut = [](ModelObject* object,
const ModelObjectCutAttribute attribute,
const Model& tmp_model_for_cut) {
611 const auto& volumes = tmp_model_for_cut.objects.front()->volumes;
612 for (const ModelVolume* volume : volumes)
613 if (volume->is_model_part()) {
616 ModelVolume* new_vol = object->add_volume(*volume);
617 new_vol->reset_from_upper();
618 }
619 }
620 };
621
622 auto cut = [this, add_volumes_from_cut]
625
626 tmp_model_for_cut = Model();
627 tmp_model_for_cut.add_object(*cut.perform_with_plane().front());
628 assert(!tmp_model_for_cut.objects.empty());
629
630 object->clear_volumes();
631 add_volumes_from_cut(object, add_volumes_attribute, tmp_model_for_cut);
633 };
634
635
636 {
638
641 }
642
643
644 {
646
649 }
650
651
653
654 ModelObject* groove_object{nullptr};
655
656
657 for (int i = 0; i < groove_count; i++) {
658 bool is_first_groove = i == 0;
659 bool is_last_groove = i == groove_count - 1;
660
661
662 float groove_offset_factor_start = -.5 * ((groove_count - 1));
663 float groove_offset_factor = groove_offset_factor_start + i;
664
665 float offset_x = groove_offset_factor * (groove_gap + groove_width);
666
667
668 tmp_object->clone_for_cut(&groove_object);
669 for (ModelVolume* volume : tmp_object->volumes) {
670 ModelVolume* new_vol = groove_object->add_volume(*volume);
671 new_vol->reset_from_upper();
672 }
673
674
675 if (!is_first_groove) {
676 float left_cut_position = (-groove_gap / 2.f) - (groove_width / 2.f) + offset_x;
677
680
682 }
683 if (!is_last_groove) {
684 float right_cut_position = (groove_gap / 2.f) + (groove_width / 2.f) + offset_x;
685
689 }
690
692
693 const double h_side_shift = 0.5 * double(groove.width + groove.depth / tan(groove.flaps_angle));
694
695
696 {
699
702 }
703
704
705 {
708
711 }
712
713
714 {
715 const double h_groove_shift_tolerance = groove_half_depth - (double)groove.depth_tolerance;
716
720
721 const double h_side_shift_tolerance = h_side_shift - 0.5 * double(groove.width_tolerance);
722
726
730 }
731
733
734 groove_object->clear_volumes();
735 }
736
738
739 if (keep_as_parts) {
740
741 const auto& volumes = lower->volumes;
742 for (const ModelVolume* volume : volumes) {
743 ModelVolume* new_vol = upper->add_volume(*volume);
744 new_vol->cut_info.is_from_upper = false;
745 }
746
747
748 for (const ModelVolume* volume : cut_mo->volumes)
749 if (!volume->is_model_part())
750 upper->add_volume(*volume);
751
752 cut_object_ptrs.push_back(upper);
753
754
755 cut_object_ptrs.push_back(lower);
756 }
757 else {
758
759 for (const ModelVolume* volume : cut_mo->volumes)
760 if (!volume->is_model_part()) {
762 break;
763 }
764
765 assert(!upper->volumes.empty() && !lower->volumes.empty());
766
767
768
770
771
773 }
774
775 finalize(cut_object_ptrs, saved_paintings);
776
778}
#define M_PI
Definition ExtrusionSimulator.cpp:31
static float calculate_groove_width(const Cut::Groove &groove, const float m_radius)
Definition CutUtils.cpp:780
void translation_transform(Transform3d &transform, const Vec3d &translation)
Definition Geometry.cpp:346
void rotation_transform(Transform3d &transform, const Vec3d &rotation)
Definition Geometry.cpp:359
Eigen::Matrix< double, 3, 1, Eigen::DontAlign > Vec3d
Definition Point.hpp:68
Eigen::Transform< double, 3, Eigen::Affine, Eigen::DontAlign > Transform3d
Definition Point.hpp:96
static void reset_instance_transformation(ModelObject *object, size_t src_instance_idx, const Transform3d &cut_matrix=Transform3d::Identity(), bool place_on_cut=false, bool flip=false)
Definition CutUtils.cpp:218
ModelObjectCutAttribute
Definition CutUtils.hpp:15