684{
685#ifdef EDGE_GRID_DEBUG_OUTPUT
686 static int iRun = 0;
687 ++ iRun;
688#endif
689
690
691 size_t nrows =
m_rows + 1;
692 size_t ncols =
m_cols + 1;
693
694 std::vector<float>
L(nrows * ncols * 2, FLT_MAX);
695
696
697
698 std::vector<unsigned char> signs(nrows * ncols, 4);
699
700
703
704 for (
int r = 0; r < (int)
m_rows; ++ r) {
705 for (
int c = 0; c < (int)
m_cols; ++ c) {
707
708 for (size_t i = cell.begin; i != cell.end; ++ i) {
712
713 const Slic3r::Point &p1 =
contour.segment_start(ipt);
714 const Slic3r::Point &p2 =
contour.segment_end(ipt);
715
716 const Slic3r::Point v_seg = p2 - p1;
717
718 const int64_t l2_seg = int64_t(v_seg(0)) * int64_t(v_seg(0)) + int64_t(v_seg(1)) * int64_t(v_seg(1));
719
720 for (int corner_y = -1; corner_y < 3; ++ corner_y) {
721 coord_t corner_r = r + corner_y;
722 if (corner_r < 0 || (size_t)corner_r >= nrows)
723 continue;
724 for (int corner_x = -1; corner_x < 3; ++ corner_x) {
725 coord_t corner_c = c + corner_x;
726 if (corner_c < 0 || (size_t)corner_c >= ncols)
727 continue;
730 Slic3r::Point v_pt = pt - p1;
731
732 int64_t t_pt = int64_t(v_seg(0)) * int64_t(v_pt(0)) + int64_t(v_seg(1)) * int64_t(v_pt(1));
733 if (t_pt < 0) {
734
735 double dabs = sqrt(int64_t(v_pt(0)) * int64_t(v_pt(0)) + int64_t(v_pt(1)) * int64_t(v_pt(1)));
736 if (dabs < d_min) {
737
738 const Slic3r::Point &p0 =
contour.segment_prev(ipt);
739 Slic3r::Point v_seg_prev = p1 - p0;
740 int64_t t2_pt = int64_t(v_seg_prev(0)) * int64_t(v_pt(0)) + int64_t(v_seg_prev(1)) * int64_t(v_pt(1));
741 if (t2_pt > 0) {
742
743
744 int64_t det = int64_t(v_seg_prev(0)) * int64_t(v_seg(1)) - int64_t(v_seg_prev(1)) * int64_t(v_seg(0));
745 assert(det != 0);
746 d_min = dabs;
747
748 float *l = &
L[(corner_r * ncols + corner_c) << 1];
749 l[0] = std::abs(v_pt(0));
750 l[1] = std::abs(v_pt(1));
751 #ifdef _DEBUG
752 double dabs2 = sqrt(l[0]*l[0]+l[1]*l[1]);
753 assert(std::abs(dabs-dabs2) < 1e-4 * std::max(dabs, dabs2));
754 #endif
755 signs[corner_r * ncols + corner_c] = ((det < 0) ? 1 : 0) | 2;
756 }
757 }
758 }
759 else if (t_pt > l2_seg) {
760
761 continue;
762 } else {
763
764 assert(t_pt >= 0 && t_pt <= l2_seg);
765 int64_t d_seg = int64_t(v_seg(1)) * int64_t(v_pt(0)) - int64_t(v_seg(0)) * int64_t(v_pt(1));
766 double d = double(d_seg) / sqrt(double(l2_seg));
767 double dabs = std::abs(d);
768 if (dabs < d_min) {
769 d_min = dabs;
770
771 float *l = &
L[(corner_r * ncols + corner_c) << 1];
772 float linv = float(d_seg) / float(l2_seg);
773 l[0] = std::abs(float(v_seg(1)) * linv);
774 l[1] = std::abs(float(v_seg(0)) * linv);
775 #ifdef _DEBUG
776 double dabs2 = sqrt(l[0]*l[0]+l[1]*l[1]);
777 assert(std::abs(dabs-dabs2) <= 1e-4 * std::max(dabs, dabs2));
778 #endif
779 signs[corner_r * ncols + corner_c] = ((d_seg < 0) ? 1 : 0) | 2;
780 }
781 }
782 }
783 }
784 }
785 }
786 }
787
788#ifdef EDGE_GRID_DEBUG_OUTPUT
789 {
790 std::vector<uint8_t> pixels(ncols * nrows * 3, 0);
791 for (
coord_t r = 0; r < nrows; ++ r) {
792 for (
coord_t c = 0; c < ncols; ++ c) {
793 uint8_t *pxl = pixels.data() + (((nrows - r - 1) * ncols) + c) * 3;
795 if (d != search_radius) {
796 float s = 255 * d / search_radius;
797 int is = std::max(0, std::min(255, int(floor(s + 0.5f))));
798 pxl[0] = 255;
799 pxl[1] = 255 - is;
800 pxl[2] = 255 - is;
801 }
802 else {
803 pxl[0] = 0;
804 pxl[1] = 255;
805 pxl[2] = 0;
806 }
807 }
808 }
810 }
811 {
812 std::vector<uint8_t> pixels(ncols * nrows * 3, 0);
813 for (
coord_t r = 0; r < nrows; ++ r) {
814 for (
coord_t c = 0; c < ncols; ++ c) {
815 unsigned char *pxl = pixels.data() + (((nrows - r - 1) * ncols) + c) * 3;
817 if (d != search_radius) {
818 float s = 255 * d / search_radius;
819 int is = std::max(0, std::min(255, int(floor(s + 0.5f))));
820 if ((signs[r * ncols + c] & 1) == 0) {
821
822 pxl[0] = 255;
823 pxl[1] = 255 - is;
824 pxl[2] = 255 - is;
825 }
826 else {
827
828 pxl[0] = 255 - is;
829 pxl[1] = 255 - is;
830 pxl[2] = 255;
831 }
832 }
833 else {
834 pxl[0] = 0;
835 pxl[1] = 255;
836 pxl[2] = 0;
837 }
838 }
839 }
841 }
842#endif
843
844
845 #define PROPAGATE_SIGNUM_SINGLE_STEP(DELTA) do { \
846 size_t addr = r * ncols + c; \
847 unsigned char &cur_val = signs[addr]; \
848 if (cur_val & 4) { \
849 unsigned char old_val = signs[addr + (DELTA)]; \
850 if ((old_val & 4) == 0) \
851 cur_val = old_val & 1; \
852 } \
853 } while (0);
854
855 for (size_t r = 0; r < nrows; ++ r) {
856 if (r > 0)
857 for (size_t c = 0; c < ncols; ++ c)
859 for (size_t c = 1; c < ncols; ++ c)
861 for (int c = int(ncols) - 2; c >= 0; -- c)
863 }
864
865 for (int r = int(nrows) - 2; r >= 0; -- r) {
866 for (size_t c = 0; c < ncols; ++ c)
868 for (size_t c = 1; c < ncols; ++ c)
870 for (int c = int(ncols) - 2; c >= 0; -- c)
872 }
873 #undef PROPAGATE_SIGNUM_SINGLE_STEP
874
875
876
877 PropagateDanielssonSingleStep<1, 0> danielsson_hstep(
L.data(), signs.data(), ncols,
m_resolution);
878 PropagateDanielssonSingleStep<0, 1> danielsson_vstep(
L.data(), signs.data(), ncols,
m_resolution);
879 PropagateDanielssonSingleVStep3 danielsson_vstep3(
L.data(), signs.data(), ncols,
m_resolution);
880
881 for (size_t r = 0; r < nrows; ++ r) {
882 if (r > 0)
883 for (size_t c = 0; c < ncols; ++ c)
884 danielsson_vstep(r, c, -int(ncols));
885
886 for (size_t c = 1; c < ncols; ++ c)
887 danielsson_hstep(r, c, -1);
888 for (int c = int(ncols) - 2; c >= 0; -- c)
889 danielsson_hstep(r, c, +1);
890 }
891
892 for (int r = int(nrows) - 2; r >= 0; -- r) {
893 for (size_t c = 0; c < ncols; ++ c)
894 danielsson_vstep(r, c, +ncols);
895
896 for (size_t c = 1; c < ncols; ++ c)
897 danielsson_hstep(r, c, -1);
898 for (int c = int(ncols) - 2; c >= 0; -- c)
899 danielsson_hstep(r, c, +1);
900 }
901
902
903 for (size_t r = 0; r < nrows; ++ r) {
904 for (size_t c = 0; c < ncols; ++ c) {
905 size_t addr = r * ncols + c;
906 float *v = &
L[addr<<1];
907 float d = sqrt(v[0]*v[0]+v[1]*v[1]);
908 if (signs[addr] & 1)
909 d = -d;
911 }
912 }
913
914#ifdef EDGE_GRID_DEBUG_OUTPUT
915 {
916 std::vector<uint8_t> pixels(ncols * nrows * 3, 0);
918 for (
coord_t r = 0; r < nrows; ++r) {
919 for (
coord_t c = 0; c < ncols; ++c) {
920 uint8_t *pxl = pixels.data() + (((nrows - r - 1) * ncols) + c) * 3;
921 uint8_t sign = signs[r * ncols + c];
922 switch (sign) {
923 case 0:
924
925 pxl[0] = 0;
926 pxl[1] = 0;
927 pxl[2] = 255;
928 break;
929 case 1:
930
931 pxl[0] = 255;
932 pxl[1] = 0;
933 pxl[2] = 0;
934 break;
935 case 2:
936
937 pxl[0] = 100;
938 pxl[1] = 100;
939 pxl[2] = 255;
940 break;
941 case 3:
942
943 pxl[0] = 255;
944 pxl[1] = 100;
945 pxl[2] = 100;
946 break;
947 case 4:
948
949 pxl[0] = 0;
950 pxl[1] = 255;
951 pxl[2] = 0;
952 break;
953 default:
954
955 pxl[0] = 255;
956 pxl[1] = 255;
957 pxl[2] = 255;
958 break;
959 }
960 }
961 }
963 }
964#endif
965
966#ifdef EDGE_GRID_DEBUG_OUTPUT
967 {
968 std::vector<uint8_t> pixels(ncols * nrows * 3, 0);
970 for (
coord_t r = 0; r < nrows; ++r) {
971 for (
coord_t c = 0; c < ncols; ++c) {
972 uint8_t *pxl = pixels.data() + (((nrows - r - 1) * ncols) + c) * 3;
974 float s = 255.f * fabs(d) / search_radius;
975 int is = std::max(0, std::min(255, int(floor(s + 0.5f))));
976 if (d < 0.f) {
977 pxl[0] = 255;
978 pxl[1] = 255 - is;
979 pxl[2] = 255 - is;
980 }
981 else {
982 pxl[0] = 255 - is;
983 pxl[1] = 255 - is;
984 pxl[2] = 255;
985 }
986 }
987 }
989 }
990#endif
991}
#define PROPAGATE_SIGNUM_SINGLE_STEP(DELTA)
#define L(s)
Definition ExtrusionEntity.cpp:25
std::vector< std::pair< size_t, size_t > > m_cell_data
Definition EdgeGrid.hpp:415
std::vector< Cell > m_cells
Definition EdgeGrid.hpp:418
coord_t m_resolution
Definition EdgeGrid.hpp:405
std::vector< Contour > m_contours
Definition EdgeGrid.hpp:412
size_t m_rows
Definition EdgeGrid.hpp:406
std::vector< float > m_signed_distance_field
Definition EdgeGrid.hpp:422
size_t m_cols
Definition EdgeGrid.hpp:407
int64_t coord_t
Definition libslic3r.h:48
bool write_rgb_to_file_scaled(const char *file_name_utf8, size_t width, size_t height, const uint8_t *data_rgb, size_t scale)
Definition PNGReadWrite.cpp:384
std::string debug_out_path(const char *name,...)
Definition utils.cpp:382
const Polygon & contour(const ExPolygon &p)
Definition AGGRaster.hpp:30
Definition EdgeGrid.hpp:379