2762 {
2763 std::string output_buffer;
2764 output_buffer += " <";
2766 output_buffer += ">\n <";
2768 output_buffer += ">\n";
2769
2770 auto flush = [this, &output_buffer, &context](bool force = false) {
2771 if ((force && ! output_buffer.empty()) || output_buffer.size() >= 65536 * 16) {
2773 add_error(
"Error during writing or compression");
2774 return false;
2775 }
2776 output_buffer.clear();
2777 }
2778 return true;
2779 };
2780
2781 auto format_coordinate = [](
float f,
char *buf) ->
char* {
2783#if EXPORT_3MF_USE_SPIRIT_KARMA_FP
2784
2785
2786
2787
2788 coordinate_type_fixed const coordinate_fixed = coordinate_type_fixed();
2789 coordinate_type_scientific const coordinate_scientific = coordinate_type_scientific();
2790
2791 char *ptr = buf;
2792 boost::spirit::karma::generate(ptr, coordinate_fixed,
f);
2793
2794 char *ptr2 = ptr;
2795 boost::spirit::karma::generate(ptr2, coordinate_scientific,
f);
2796
2797 auto len2 = ptr2 - ptr;
2798 if (ptr - buf > len2) {
2799
2800 memcpy(buf, ptr, len2);
2801 ptr = buf + len2;
2802 }
2803
2804 return ptr;
2805#else
2806
2807 return buf + sprintf(buf,
"%.9g",
f);
2808#endif
2809 };
2810
2811 char buf[256];
2812 unsigned int vertices_count = 0;
2813 for (ModelVolume* volume : object.volumes) {
2814 if (volume == nullptr)
2815 continue;
2816
2817 volumes_offsets.insert({
volume, Offsets(vertices_count) });
2818
2822 return false;
2823 }
2824
2825 vertices_count += (int)its.
vertices.size();
2826
2828 for (const auto& vertex: its.vertices) {
2829 Vec3f v = (matrix *
vertex.cast<
double>()).cast<
float>();
2830 char *ptr = buf;
2831 boost::spirit::karma::generate(ptr, boost::spirit::lit(
" <") <<
VERTEX_TAG <<
" x=\"");
2832 ptr = format_coordinate(v.x(), ptr);
2833 boost::spirit::karma::generate(ptr, "\" y=\"");
2834 ptr = format_coordinate(v.y(), ptr);
2835 boost::spirit::karma::generate(ptr, "\" z=\"");
2836 ptr = format_coordinate(v.z(), ptr);
2837 boost::spirit::karma::generate(ptr, "\"/>\n");
2838 *ptr = '\0';
2839 output_buffer += buf;
2840 if (! flush())
2841 return false;
2842 }
2843 }
2844
2845 output_buffer += " </";
2847 output_buffer += ">\n <";
2849 output_buffer += ">\n";
2850
2851 unsigned int triangles_count = 0;
2852 for (ModelVolume* volume : object.volumes) {
2853 if (volume == nullptr)
2854 continue;
2855
2856 bool is_left_handed =
volume->is_left_handed();
2857 VolumeToOffsetsMap::iterator volume_it = volumes_offsets.find(volume);
2858 assert(volume_it != volumes_offsets.end());
2859
2861
2862
2863 volume_it->second.first_triangle_id = triangles_count;
2864 triangles_count += (int)its.
indices.size();
2865 volume_it->second.last_triangle_id = triangles_count - 1;
2866
2867 for (
int i = 0; i < int(its.
indices.size()); ++ i) {
2868 {
2870 char *ptr = buf;
2871 boost::spirit::karma::generate(ptr, boost::spirit::lit(
" <") <<
TRIANGLE_TAG <<
2872 " v1=\"" << boost::spirit::int_ <<
2873 "\" v2=\"" << boost::spirit::int_ <<
2874 "\" v3=\"" << boost::spirit::int_ << "\"",
2875 idx[is_left_handed ? 2 : 0] + volume_it->second.first_vertex_id,
2876 idx[1] + volume_it->second.first_vertex_id,
2877 idx[is_left_handed ? 0 : 2] + volume_it->second.first_vertex_id);
2878 *ptr = '\0';
2879 output_buffer += buf;
2880 }
2881
2882 std::string custom_supports_data_string =
volume->supported_facets.get_triangle_as_string(i);
2883 if (! custom_supports_data_string.empty()) {
2884 output_buffer += " ";
2886 output_buffer += "=\"";
2887 output_buffer += custom_supports_data_string;
2888 output_buffer += "\"";
2889 }
2890
2891 std::string custom_seam_data_string =
volume->seam_facets.get_triangle_as_string(i);
2892 if (! custom_seam_data_string.empty()) {
2893 output_buffer += " ";
2895 output_buffer += "=\"";
2896 output_buffer += custom_seam_data_string;
2897 output_buffer += "\"";
2898 }
2899
2900 std::string mmu_painting_data_string =
volume->mmu_segmentation_facets.get_triangle_as_string(i);
2901 if (! mmu_painting_data_string.empty()) {
2902 output_buffer += " ";
2904 output_buffer += "=\"";
2905 output_buffer += mmu_painting_data_string;
2906 output_buffer += "\"";
2907 }
2908
2909 output_buffer += "/>\n";
2910
2911 if (! flush())
2912 return false;
2913 }
2914 }
2915
2916 output_buffer += " </";
2918 output_buffer += ">\n </";
2920 output_buffer += ">\n";
2921
2922
2923 return flush(true);
2924 }
static constexpr const char * MMU_SEGMENTATION_ATTR
Definition 3mf.cpp:118
static constexpr const char * TRIANGLES_TAG
Definition 3mf.cpp:91
static constexpr const char * CUSTOM_SEAM_ATTR
Definition 3mf.cpp:117
static constexpr const char * CUSTOM_SUPPORTS_ATTR
Definition 3mf.cpp:116
static constexpr const char * VERTEX_TAG
Definition 3mf.cpp:90
static constexpr const char * MESH_TAG
Definition 3mf.cpp:88
static constexpr const char * VERTICES_TAG
Definition 3mf.cpp:89
static constexpr const char * TRIANGLE_TAG
Definition 3mf.cpp:92
mz_bool mz_zip_writer_add_staged_data(mz_zip_writer_staged_context *pContext, const char *pRead_buf, size_t n)
Definition miniz.c:6856
Eigen::Transform< double, 3, Eigen::Affine, Eigen::DontAlign > Transform3d
Definition Point.hpp:81
Eigen::Matrix< int, 3, 1, Eigen::DontAlign > Vec3i
Definition Point.hpp:40
Eigen::Matrix< float, 3, 1, Eigen::DontAlign > Vec3f
Definition Point.hpp:49
static double f(double x, double z_sin, double z_cos, bool vertical, bool flip)
Definition FillGyroid.cpp:12
TPoint< S > & vertex(S &sh, unsigned long idx, const PolygonTag &)
Definition geometry_traits.hpp:1180
std::vector< stl_vertex > vertices
Definition stl.h:165
std::vector< stl_triangle_vertex_indices > indices
Definition stl.h:164