diff --git a/resources/data/hints.ini b/resources/data/hints.ini index b0bced57b98..dcfa7fbf34b 100644 --- a/resources/data/hints.ini +++ b/resources/data/hints.ini @@ -21,7 +21,7 @@ # Settings highlight (like search feature) # hypertext_type = settings # hypertext_settings_opt = name_of_settings (hover over settings value and copy last line of hover text) -# hypertext_settings_type = 1 (1 - 5 according to settings tab - to be channged to name of tabs instead of numbers) +# hypertext_settings_type = print ( {print, filament, sla_print, sla_material, printer} according to settings tab) # hypertext_settings_category = Infill (name of panel - written on left in settings) # # Plater top toolbar highlight @@ -67,7 +67,7 @@ text = Fuzzy skin\nDid you know that you can create rough fibre-like texture on the sides of your models using theFuzzy skinfeature? You can also use modifiers to apply fuzzy-skin only to a portion of your model. hypertext_type = settings hypertext_settings_opt = fuzzy_skin -hypertext_settings_type = 1 +hypertext_settings_type = print hypertext_settings_category = Layers and perimeters disabled_tags = SLA @@ -118,7 +118,7 @@ text = Set number of instances\nDid you know that you can right-click a model an text = Combine infill\nDid you know that you can print the infill with a higher layer height compared to perimeters to save print time using the settingCombine infill every. hypertext_type = settings hypertext_settings_opt = infill_every_layers -hypertext_settings_type = 1 +hypertext_settings_type = print hypertext_settings_category = Infill disabled_tags = SLA; simple @@ -142,7 +142,7 @@ disabled_tags = SLA text = Solid infill threshold area\nDid you know that you can make parts of your model with a small cross-section be filled with solid infill automatically? Set theSolid infill threshold area. (Expert mode only.) hypertext_type = settings hypertext_settings_opt = solid_infill_below_area -hypertext_settings_type = 1 +hypertext_settings_type = print hypertext_settings_category = Infill enabled_tags = FFF; expert @@ -207,7 +207,7 @@ hypertext_menubar_item_name = &Configuration Snapshots text = Minimum shell thickness\nDid you know that instead of the number of top and bottom layers, you can define theMinimum shell thicknessin millimeters? This feature is especially useful when using the variable layer height function. hypertext_type = settings hypertext_settings_opt = top_solid_min_thickness -hypertext_settings_type = 1 +hypertext_settings_type = print hypertext_settings_category = Layers and perimeters disabled_tags = SLA diff --git a/resources/ui_layout/default/print.ui b/resources/ui_layout/default/print.ui index 3fb60dcb189..b07794e5d28 100644 --- a/resources/ui_layout/default/print.ui +++ b/resources/ui_layout/default/print.ui @@ -204,7 +204,7 @@ group:sidetext_width$5:Infill angle end_line line:Modifiers setting:label_width$6:width$5:label$increment:fill_angle_increment - setting:label_width$6:width$5:label$increment:fill_angle_cross + setting:width$5:fill_angle_cross vector_line:fill_angle_template # setting:fill_angle_template group:sidetext_width$5:Advanced diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7b2defea726..90a891c70cc 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 3.13) project(Slic3r-native) add_subdirectory(build-utils) +add_subdirectory(test-utils) add_subdirectory(admesh) add_subdirectory(avrdude) # boost/nowide diff --git a/src/libslic3r/Arachne/utils/ExtrusionLine.hpp b/src/libslic3r/Arachne/utils/ExtrusionLine.hpp index 638d7f237f8..0b13859e207 100644 --- a/src/libslic3r/Arachne/utils/ExtrusionLine.hpp +++ b/src/libslic3r/Arachne/utils/ExtrusionLine.hpp @@ -224,6 +224,10 @@ static inline Slic3r::ThickPolyline to_thick_polyline(const ClipperLib_Z::Path & out.points_width.emplace_back(it->z()); } } + assert(out.points.front().x() == path.front().x()); + assert(out.points.front().y() == path.front().y()); + assert(out.points.back().x() == path.back().x()); + assert(out.points.back().y() == path.back().y()); return out; } diff --git a/src/libslic3r/Config.hpp b/src/libslic3r/Config.hpp index e0688b7f850..c9e4e7536d6 100644 --- a/src/libslic3r/Config.hpp +++ b/src/libslic3r/Config.hpp @@ -1326,7 +1326,7 @@ class ConfigOptionFloatsOrPercentsTempl : public ConfigOptionVectorvalues) - if (! std::isnan(v.value) || v != NIL_VALUE()) + if (!(std::isnan(v.value) || v.value == NIL_VALUE().value || v.value > std::numeric_limits::max())) return false; return true; } else { @@ -1344,7 +1344,9 @@ class ConfigOptionFloatsOrPercentsTempl : public ConfigOptionVector(to_check).value) || boost::any_cast(to_check).value == NIL_VALUE().value; + bool ok = std::isnan(boost::any_cast(to_check).value) || boost::any_cast(to_check).value == NIL_VALUE().value + || boost::any_cast(to_check).value > std::numeric_limits::max(); + return ok; } // don't use it to compare, use is_nil() to check. static inline boost::any create_nil() { return boost::any(NIL_VALUE()); } @@ -1411,7 +1413,7 @@ class ConfigOptionFloatsOrPercentsTempl : public ConfigOptionVector std::numeric_limits::max()) { if (NULLABLE) ss << NIL_STR_VALUE; else @@ -1424,8 +1426,8 @@ class ConfigOptionFloatsOrPercentsTempl : public ConfigOptionVectorvalue) || it1->value == NIL_VALUE().value) && - (std::isnan(it2->value) || it2->value == NIL_VALUE().value)) || + if (!(((std::isnan(it1->value) || it1->value == NIL_VALUE().value || it1->value > std::numeric_limits::max()) && + (std::isnan(it2->value) || it2->value == NIL_VALUE().value || it1->value > std::numeric_limits::max())) || *it1 == *it2)) return false; return true; @@ -1436,8 +1438,8 @@ class ConfigOptionFloatsOrPercentsTempl : public ConfigOptionVector &v1, const std::vector &v2) { if (NULLABLE) { for (auto it1 = v1.begin(), it2 = v2.begin(); it1 != v1.end() && it2 != v2.end(); ++ it1, ++ it2) { - auto null1 = int(std::isnan(it1->value) || it1->value == NIL_VALUE().value); - auto null2 = int(std::isnan(it2->value) || it2->value == NIL_VALUE().value); + auto null1 = int(std::isnan(it1->value) || it1->value == NIL_VALUE().value || it1->value > std::numeric_limits::max()); + auto null2 = int(std::isnan(it2->value) || it2->value == NIL_VALUE().value || it1->value > std::numeric_limits::max()); return (null1 < null2) || (null1 == null2 && *it1 < *it2); } return v1.size() < v2.size(); @@ -2321,6 +2323,10 @@ class ConfigBase : public ConfigOptionResolver bool set_deserialize_nothrow(const t_config_option_key &opt_key_src, const std::string &value_src, ConfigSubstitutionContext& substitutions, bool append = false); // May throw BadOptionTypeException() if the operation fails. void set_deserialize(const t_config_option_key &opt_key, const std::string &str, ConfigSubstitutionContext& config_substitutions, bool append = false); + void set_deserialize(const t_config_option_key &opt_key, const std::string &str){ //for tests + ConfigSubstitutionContext no_context(ForwardCompatibilitySubstitutionRule::Disable); + set_deserialize(opt_key, str, no_context); + } void set_deserialize_strict(const t_config_option_key &opt_key, const std::string &str, bool append = false) { ConfigSubstitutionContext ctxt{ ForwardCompatibilitySubstitutionRule::Disable }; this->set_deserialize(opt_key, str, ctxt, append); } struct SetDeserializeItem { diff --git a/src/libslic3r/Extruder.hpp b/src/libslic3r/Extruder.hpp index e4e16d2639e..b3113a04d99 100644 --- a/src/libslic3r/Extruder.hpp +++ b/src/libslic3r/Extruder.hpp @@ -1,6 +1,8 @@ #ifndef slic3r_Extruder_hpp_ #define slic3r_Extruder_hpp_ +#include + #include "libslic3r.h" #include "Point.hpp" diff --git a/src/libslic3r/ExtrusionEntity.cpp b/src/libslic3r/ExtrusionEntity.cpp index 2874cddaa3b..2d610338c42 100644 --- a/src/libslic3r/ExtrusionEntity.cpp +++ b/src/libslic3r/ExtrusionEntity.cpp @@ -378,29 +378,80 @@ ExtrusionRole ExtrusionEntity::string_to_role(const std::string_view role) else return erNone; } + + +std::string role_to_code(ExtrusionRole role) +{ + switch (role) { + case erNone : return L("None"); + case erPerimeter : return L("IPeri"); + case erExternalPerimeter : return L("EPeri"); + case erOverhangPerimeter : return L("OPeri"); + case erInternalInfill : return L("IFill"); + case erSolidInfill : return L("SFill"); + case erTopSolidInfill : return L("TFill"); + case erIroning : return L("Iron"); + case erBridgeInfill : return L("EBridge"); + case erInternalBridgeInfill : return L("IBridge"); + case erThinWall : return L("ThinW"); + case erGapFill : return L("GFill"); + case erSkirt : return L("Skirt"); + case erSupportMaterial : return L("Supp"); + case erSupportMaterialInterface : return L("SuppI"); + case erWipeTower : return L("WTower"); + case erMilling : return L("Mill"); + case erCustom : return L("Custom"); + case erMixed : return L("Mixed"); + case erTravel : return L("Travel"); + default : assert(false); + } + + return ""; +} + + +std::string looprole_to_code(ExtrusionLoopRole looprole) +{ + std::string code; + if(elrDefault == (looprole & elrDefault)) + code += std::string("D"); + if(elrInternal == (looprole & elrInternal)) + code += std::string("Int"); + if(elrSkirt == (looprole & elrSkirt)) + code += std::string("Skirt"); + if(elrHole == (looprole & elrHole)) + code += std::string("Hole"); + if(elrVase == (looprole & elrVase)) + code += std::string("Vase"); + if(elrFirstLoop == (looprole & elrFirstLoop)) + code += std::string("First"); + + return code; +} + void ExtrusionPrinter::use(const ExtrusionPath &path) { - ss << "ExtrusionPath:" << (uint16_t)path.role() << "{"; + ss << (json?"\"":"") << "ExtrusionPath" << (path.can_reverse()?"":"Oriented") << (json?"_":":") << role_to_code(path.role()) << (json?"\":":"") << "["; for (int i = 0; i < path.polyline.size(); i++) { if (i != 0) ss << ","; double x = (mult * (path.polyline.get_points()[i].x())); double y = (mult * (path.polyline.get_points()[i].y())); - ss << std::fixed << "{"<<(trunc?(int)x:x) << "," << (trunc ? (int)y : y) <<"}"; + ss << std::fixed << "["<<(trunc>0?(int(x*trunc))/double(trunc):x) << "," << (trunc>0?(int(y*trunc))/double(trunc):y) <<"]"; } - ss << "}"; + ss << "]"; } void ExtrusionPrinter::use(const ExtrusionPath3D &path3D) { - ss << "ExtrusionPath3D:" << (uint16_t)path3D.role() << "{"; + ss << (json?"\"":"") << "ExtrusionPath3D" << (path3D.can_reverse()?"":"Oriented") << (json?"_":":") << role_to_code(path3D.role()) << (json?"\":":"") << "["; for (int i = 0; i < path3D.polyline.size();i++){ if (i != 0) ss << ","; double x = (mult * (path3D.polyline.get_points()[i].x())); double y = (mult * (path3D.polyline.get_points()[i].y())); double z = (path3D.z_offsets.size() > i ? mult * (path3D.z_offsets[i]) : -1); - ss << std::fixed << "{" << (trunc ? (int)x : x) << "," << (trunc ? (int)y : y) << "," << (trunc ? (int)z : z) << "}"; + ss << std::fixed << "[" << (trunc>0?(int(x*trunc))/double(trunc):x) << "," << (trunc>0?(int(y*trunc))/double(trunc):y) << "," << (trunc>0?(int(z*trunc))/double(trunc):z) << "]"; } - ss << "}"; + ss << "]"; } void ExtrusionPrinter::use(const ExtrusionMultiPath &multipath) { - ss << "ExtrusionMultiPath:" << (uint16_t)multipath.role() << "{"; + ss << (json?"\"":"") << "ExtrusionMultiPath" << (multipath.can_reverse()?"":"Oriented") << (json?"_":":") << role_to_code(multipath.role()) << (json?"\":":"") << "{"; for (int i = 0; i < multipath.paths.size(); i++) { if (i != 0) ss << ","; multipath.paths[i].visit(*this); @@ -408,7 +459,7 @@ void ExtrusionPrinter::use(const ExtrusionMultiPath &multipath) { ss << "}"; } void ExtrusionPrinter::use(const ExtrusionMultiPath3D &multipath3D) { - ss << "multipath3D:" << (uint16_t)multipath3D.role() << "{"; + ss << (json?"\"":"") << "multipath3D" << (multipath3D.can_reverse()?"":"Oriented") << (json?"_":":") << role_to_code(multipath3D.role()) << (json?"\":":"") << "{"; for (int i = 0; i < multipath3D.paths.size(); i++) { if (i != 0) ss << ","; multipath3D.paths[i].visit(*this); @@ -416,7 +467,8 @@ void ExtrusionPrinter::use(const ExtrusionMultiPath3D &multipath3D) { ss << "}"; } void ExtrusionPrinter::use(const ExtrusionLoop &loop) { - ss << "ExtrusionLoop:" << (uint16_t)loop.role()<<":" <<(uint16_t)loop.loop_role()<<"{"; + ss << (json?"\"":"") << "ExtrusionLoop" << (json?"_":":") << role_to_code(loop.role())<<"_" << looprole_to_code(loop.loop_role()) << (json?"\":":"") << "{"; + if(!loop.can_reverse()) ss << (json?"\"":"") << "oriented" << (json?"\":":"=") << "true,"; for (int i = 0; i < loop.paths.size(); i++) { if (i != 0) ss << ","; loop.paths[i].visit(*this); @@ -424,12 +476,13 @@ void ExtrusionPrinter::use(const ExtrusionLoop &loop) { ss << "}"; } void ExtrusionPrinter::use(const ExtrusionEntityCollection &collection) { - ss << "ExtrusionEntityCollection:" << (uint16_t)collection.role() << "{"; + ss << (json?"\"":"") << "ExtrusionEntityCollection" << (json?"_":":") << role_to_code(collection.role()) << (json?"\":":"") << "{"; + if(!collection.can_sort()) ss << (json?"\"":"") << "no_sort" << (json?"\":":"=") << "true,"; + if(!collection.can_reverse()) ss << (json?"\"":"") << "oriented" << (json?"\":":"=") << "true,"; for (int i = 0; i < collection.entities().size(); i++) { if (i != 0) ss << ","; collection.entities()[i]->visit(*this); } - if(!collection.can_sort()) ss<<", no_sort=true"; ss << "}"; } diff --git a/src/libslic3r/ExtrusionEntity.hpp b/src/libslic3r/ExtrusionEntity.hpp index bbc81a65899..6bc37026572 100644 --- a/src/libslic3r/ExtrusionEntity.hpp +++ b/src/libslic3r/ExtrusionEntity.hpp @@ -628,9 +628,10 @@ inline void extrusion_entities_append_loops_and_paths(ExtrusionEntitiesPtr &dst, class ExtrusionPrinter : public ExtrusionVisitorConst { std::stringstream ss; double mult; - bool trunc; + int trunc; + bool json; public: - ExtrusionPrinter(double mult = 0.0001, bool trunc = false) : mult(mult), trunc(trunc) { } + ExtrusionPrinter(double mult = 0.000001, int trunc = 0, bool json = false) : mult(mult), trunc(trunc), json(json) { } virtual void use(const ExtrusionPath& path) override; virtual void use(const ExtrusionPath3D& path3D) override; virtual void use(const ExtrusionMultiPath& multipath) override; diff --git a/src/libslic3r/ExtrusionEntityCollection.hpp b/src/libslic3r/ExtrusionEntityCollection.hpp index 336859cd1cf..3618c0d33de 100644 --- a/src/libslic3r/ExtrusionEntityCollection.hpp +++ b/src/libslic3r/ExtrusionEntityCollection.hpp @@ -52,6 +52,11 @@ class ExtrusionEntityCollection : public ExtrusionEntity return *this; } ~ExtrusionEntityCollection() override { clear(); } + // move all entitites from src into this + void append_move_from(ExtrusionEntityCollection &src) { + m_entities.insert(m_entities.end(), src.m_entities.begin(), src.m_entities.end()); + src.m_entities.clear(); + } /// Operator to convert and flatten this collection to a single vector of ExtrusionPaths. explicit operator ExtrusionPaths() const; diff --git a/src/libslic3r/Fill/Fill.cpp b/src/libslic3r/Fill/Fill.cpp index 63de0d2d51b..fd6774661a5 100644 --- a/src/libslic3r/Fill/Fill.cpp +++ b/src/libslic3r/Fill/Fill.cpp @@ -532,7 +532,14 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive: //give the overlap size to let the infill do his overlap //add overlap if at least one perimeter - const float perimeter_spacing = layerm->flow(frPerimeter).spacing(); + float perimeter_spacing = 0; + if(layerm->region().config().perimeters == 1) + perimeter_spacing = layerm->flow(frExternalPerimeter).spacing(); + else if(layerm->region().config().only_one_perimeter_top) + //note: use the min of the two to avoid overextrusion if only one perimeter top + perimeter_spacing = std::min(layerm->flow(frPerimeter).spacing(), layerm->flow(frExternalPerimeter).spacing()); + else //if(layerm->region().config().perimeters > 1) + perimeter_spacing = layerm->flow(frPerimeter).spacing(); // Used by the concentric infill pattern to clip the loops to create extrusion paths. f->loop_clipping = scale_t(layerm->region().config().get_computed_value("seam_gap", surface_fill.params.extruder - 1) * surface_fill.params.flow.nozzle_diameter()); diff --git a/src/libslic3r/Fill/FillBase.cpp b/src/libslic3r/Fill/FillBase.cpp index 08daf3c2222..5008b80a01d 100644 --- a/src/libslic3r/Fill/FillBase.cpp +++ b/src/libslic3r/Fill/FillBase.cpp @@ -167,17 +167,7 @@ double Fill::compute_unscaled_volume_to_fill(const Surface* surface, const FillP } else { for (const ExPolygon& poly : intersection_ex(ExPolygons{ surface->expolygon }, this->no_overlap_expolygons)) { polyline_volume += params.flow.height() * unscaled(unscaled(poly.area())); - double perimeter_gap_usage = params.config->perimeter_overlap.get_abs_value(1); - // add external "perimeter gap" - //TODO: use filament_max_overlap to reduce it - //double filament_max_overlap = params.config->get_computed_value("filament_max_overlap", params.extruder - 1); - double perimeter_round_gap = unscaled(poly.contour.length()) * params.flow.height() * (1 - 0.25 * PI) * 0.5; - // add holes "perimeter gaps" - double holes_gaps = 0; - for (auto hole = poly.holes.begin(); hole != poly.holes.end(); ++hole) { - holes_gaps += unscaled(hole->length()) * params.flow.height() * (1 - 0.25 * PI) * 0.5; - } - polyline_volume += (perimeter_round_gap + holes_gaps) * perimeter_gap_usage; + //note: the no_overlap_expolygons is already at spacing from the centerline of the perimeter. } } return polyline_volume; diff --git a/src/libslic3r/Fill/FillBase.hpp b/src/libslic3r/Fill/FillBase.hpp index 5dcadea8fc4..83dc11161bf 100644 --- a/src/libslic3r/Fill/FillBase.hpp +++ b/src/libslic3r/Fill/FillBase.hpp @@ -173,6 +173,7 @@ class Fill ExPolygon /* expolygon */, Polylines & /* polylines_out */) const { BOOST_LOG_TRIVIAL(error)<<"Error, the fill isn't implemented"; + assert(false); }; // Used for concentric infill to generate ThickPolylines using Arachne. @@ -182,6 +183,7 @@ class Fill ExPolygon expolygon, ThickPolylines &thick_polylines_out) const { BOOST_LOG_TRIVIAL(error) << "Error, the arachne fill isn't implemented"; + assert(false); }; virtual float _layer_angle(size_t idx) const { return can_angle_cross && (idx & 1) ? float(M_PI/2.) : 0; } diff --git a/src/libslic3r/Flow.cpp b/src/libslic3r/Flow.cpp index 269c1cb3b53..d81be3aeef9 100644 --- a/src/libslic3r/Flow.cpp +++ b/src/libslic3r/Flow.cpp @@ -526,12 +526,12 @@ float Flow::rounded_rectangle_extrusion_spacing(float width, float height, float #endif } -float Flow::rounded_rectangle_extrusion_width_from_spacing(float spacing, float height, float m_spacing_ratio) +float Flow::rounded_rectangle_extrusion_width_from_spacing(float spacing, float height, float spacing_ratio) { #ifdef HAS_PERIMETER_LINE_OVERLAP return (spacing + PERIMETER_LINE_OVERLAP_FACTOR * height * (1. - 0.25 * PI) * spacing_ratio); #else - return float(spacing + height * (1. - 0.25 * PI) * m_spacing_ratio); + return float(spacing + height * (1. - 0.25 * PI) * spacing_ratio); #endif } diff --git a/src/libslic3r/Format/3mf.cpp b/src/libslic3r/Format/3mf.cpp index aa9e27e37ab..d827cdab641 100644 --- a/src/libslic3r/Format/3mf.cpp +++ b/src/libslic3r/Format/3mf.cpp @@ -2934,7 +2934,7 @@ namespace Slic3r { } } else { std::string value = config.opt_serialize(opt_key); - if (!value.empty()) { + if (!value.empty() || opt_key.find("_pattern") == std::string::npos) { pt::ptree& opt_tree = range_tree.add("option", value); opt_tree.put(".opt_key", opt_key); } else { @@ -3160,7 +3160,7 @@ namespace Slic3r { } else { for (const std::string& key : obj->config.keys()) { std::string value = obj->config.opt_serialize(key); - if (!value.empty()) { + if (!value.empty() || key.find("_pattern") == std::string::npos) { stream << " <" << METADATA_TAG << " " << TYPE_ATTR << "=\"" << OBJECT_TYPE << "\" " << KEY_ATTR << "=\"" << key << "\" " << VALUE_ATTR << "=\"" << value << "\"/>\n"; } else { std::ofstream log("ERROR_FILE_TO_SEND_TO_MERILL_PLZZZZ.txt", std::ios_base::app); @@ -3268,7 +3268,7 @@ namespace Slic3r { for (const std::string& key : volume->config.keys()) { //stream << " <" << METADATA_TAG << " " << TYPE_ATTR << "=\"" << VOLUME_TYPE << "\" " << KEY_ATTR << "=\"" << key << "\" " << VALUE_ATTR << "=\"" << volume->config.opt_serialize(key) << "\"/>\n"; std::string value = volume->config.opt_serialize(key); - if (!value.empty() && key.find("pattern") == std::string::npos) { + if (!value.empty() || key.find("_pattern") == std::string::npos) { stream << " <" << METADATA_TAG << " " << TYPE_ATTR << "=\"" << VOLUME_TYPE << "\" " << KEY_ATTR << "=\"" << key << "\" " << VALUE_ATTR << "=\"" << value << "\"/>\n"; } else { std::ofstream log("ERROR_FILE_TO_SEND_TO_MERILL_PLZZZZ.txt", std::ios_base::app); diff --git a/src/libslic3r/Format/STL.hpp b/src/libslic3r/Format/STL.hpp index cff7dc08696..b2c4345129d 100644 --- a/src/libslic3r/Format/STL.hpp +++ b/src/libslic3r/Format/STL.hpp @@ -5,6 +5,7 @@ namespace Slic3r { class TriangleMesh; class ModelObject; +class Model; // Load an STL file into a provided model. extern bool load_stl(const char *path, Model *model, const char *object_name = nullptr); diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 69545332479..ce20991b3a2 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -32,7 +32,6 @@ #include #include #include -#include #include #include @@ -1426,6 +1425,7 @@ void GCode::_do_export(Print& print_mod, GCodeOutputStream &file, ThumbnailsGene } BoundingBoxf3 global_bounding_box; size_t nb_items = 0; + std::wregex pattern(L"[^\\w]+", std::regex_constants::ECMAScript); for (PrintObject *print_object : print.objects()) { this->m_ordered_objects.push_back(print_object); uint32_t copy_id = 0; @@ -1471,9 +1471,14 @@ void GCode::_do_export(Print& print_mod, GCodeOutputStream &file, ThumbnailsGene for (const Point& point : poly.points) s_poly += (boost::format(format_point) % unscaled(point.x()) % unscaled(point.y())).str() + ","; s_poly += (boost::format(format_point) % unscaled(poly.points.front().x()) % unscaled(poly.points.front().y())).str(); - + //std::string good_name_without_space = boost::algorithm::replace_all_regex(print_object->model_object()->name, regex_space, std::string("_")); + //std::locale::global(std::locale("en_US.UTF-8")); + std::wstring wname = boost::nowide::widen(print_object->model_object()->name); + std::wstring wname_without_space = std::regex_replace(wname, pattern, L"_"); + std::string name_without_space = boost::nowide::narrow(wname_without_space); + raw_str_to_objectid_str[print_object->model_object()->name] = name_without_space; file.write_format("EXCLUDE_OBJECT_DEFINE NAME=%s_id_%d_copy_%d CENTER=%f,%f POLYGON=[%s]\n", - boost::algorithm::replace_all_regex_copy(print_object->model_object()->name, boost::regex("[^\\w]+"), std::string("_")).c_str(), + name_without_space.c_str(), this->m_ordered_objects.size() - 1, copy_id, bounding_box.center().x(), bounding_box.center().y(), s_poly.c_str() @@ -2836,7 +2841,7 @@ namespace Skirt { } // namespace Skirt // Matches "G92 E0" with various forms of writing the zero and with an optional comment. -boost::regex regex_g92e0_gcode{ "^[ \\t]*[gG]92[ \\t]*[eE](0(\\.0*)?|\\.0+)[ \\t]*(;.*)?$" }; +std::regex regex_g92e0_gcode{ "^[ \\t]*[gG]92[ \\t]*[eE](0(\\.0*)?|\\.0+)[ \\t]*(;.*)?$" }; // In sequential mode, process_layer is called once per each object and its copy, // therefore layers will contain a single entry and single_object_instance_idx will point to the copy of the object. @@ -2978,8 +2983,8 @@ LayerResult GCode::process_layer( } //put G92 E0 is relative extrusion - bool before_layer_gcode_resets_extruder = boost::regex_search(print.config().before_layer_gcode.value, regex_g92e0_gcode); - bool layer_gcode_resets_extruder = boost::regex_search(print.config().layer_gcode.value, regex_g92e0_gcode); + bool before_layer_gcode_resets_extruder = std::regex_search(print.config().before_layer_gcode.value, regex_g92e0_gcode); + bool layer_gcode_resets_extruder = std::regex_search(print.config().layer_gcode.value, regex_g92e0_gcode); if (m_config.use_relative_e_distances) { // See GH issues prusa#6336 #5073$ if (!before_layer_gcode_resets_extruder && !layer_gcode_resets_extruder) { @@ -3277,7 +3282,7 @@ LayerResult GCode::process_layer( if (this->m_layer != nullptr && this->m_layer->id() == 0) { m_avoid_crossing_perimeters.use_external_mp(true); for (const ExtrusionEntity* ee : print_object->brim().entities()) - gcode += this->extrude_entity(*ee, "brim"); + gcode += this->extrude_entity(*ee, "Brim"); m_avoid_crossing_perimeters.use_external_mp(false); m_avoid_crossing_perimeters.disable_once(); m_last_too_small.polyline.clear(); @@ -3306,20 +3311,12 @@ LayerResult GCode::process_layer( bool object_layer_over_raft = layer_to_print.object_layer && layer_to_print.object_layer->id() > 0 && instance_to_print.print_object.slicing_parameters().raft_layers() == layer_to_print.object_layer->id(); // Get data for gcode_label_objects - std::string instance_clean_name = - boost::algorithm::replace_all_regex_copy( - instance_to_print.print_object.model_object()->name, - boost::regex("[^\\w]+"), std::string("_")); - std::string instance_id = std::to_string( - std::find(this->m_ordered_objects.begin(), - this->m_ordered_objects.end(), - &instance_to_print.print_object) - - this->m_ordered_objects.begin()); - std::string instance_copy = std::to_string( - instance_to_print.instance_id); - std::string instance_full_id = instance_clean_name + "_id_" + - instance_id + "_copy_" + - instance_copy; + std::string instance_id = std::to_string(std::find(this->m_ordered_objects.begin(), + this->m_ordered_objects.end(), + &instance_to_print.print_object) - + this->m_ordered_objects.begin()); + std::string instance_copy = std::to_string(instance_to_print.instance_id); + std::string instance_full_id; // for klipper m_layer = layer_to_print.layer(); m_object_layer_over_raft = object_layer_over_raft; @@ -3344,6 +3341,17 @@ LayerResult GCode::process_layer( instance_plater_id += instance_to_print.instance_id; m_gcode_label_objects_start += std::string("M486 S") + std::to_string(instance_plater_id) + "\n"; } else if (print.config().gcode_flavor.value == gcfKlipper) { + std::string instance_clean_name; + if (auto found = raw_str_to_objectid_str.find( + instance_to_print.print_object.model_object()->name); + found != raw_str_to_objectid_str.end()) { + instance_clean_name = found->second; + } else { + assert(false); // should already been done in EXCLUDE_OBJECT_DEFINE + instance_clean_name = instance_to_print.print_object.model_object()->name; + } + instance_full_id = instance_clean_name + "_id_" + instance_id + "_copy_" + + instance_copy; m_gcode_label_objects_start += std::string("EXCLUDE_OBJECT_START NAME=") + instance_full_id + @@ -3386,7 +3394,7 @@ LayerResult GCode::process_layer( assert(instance_to_print.print_object.brim().entities()[instance_to_print.instance_id]->is_collection()); if (const ExtrusionEntityCollection* coll = dynamic_cast(instance_to_print.print_object.brim().entities()[instance_to_print.instance_id])) { for (const ExtrusionEntity* ee : coll->entities()) - gcode += this->extrude_entity(*ee, "brim"); + gcode += this->extrude_entity(*ee, "Brim"); } m_avoid_crossing_perimeters.use_external_mp(false); m_avoid_crossing_perimeters.disable_once(); @@ -3430,6 +3438,7 @@ LayerResult GCode::process_layer( m_gcode_label_objects_end += std::string("M486 S-1") + "\n"; } else if (print.config().gcode_flavor.value == gcfKlipper) { + assert(!instance_full_id.empty()); m_gcode_label_objects_end += std::string("EXCLUDE_OBJECT_END NAME=") + instance_full_id + diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp index 89653e6363c..5a42e0bfe87 100644 --- a/src/libslic3r/GCode.hpp +++ b/src/libslic3r/GCode.hpp @@ -491,6 +491,7 @@ class GCode : ExtrusionVisitorConst { std::string m_gcode_label_objects_start; std::string m_gcode_label_objects_end; void _add_object_change_labels(std::string &gcode); + std::map raw_str_to_objectid_str; bool m_silent_time_estimator_enabled; diff --git a/src/libslic3r/GCode/SeamPlacer.cpp b/src/libslic3r/GCode/SeamPlacer.cpp index 765b60be632..e050289a083 100644 --- a/src/libslic3r/GCode/SeamPlacer.cpp +++ b/src/libslic3r/GCode/SeamPlacer.cpp @@ -431,6 +431,7 @@ Polygons extract_perimeter_polygons(const Layer *layer, const SeamPosition confi const LayerRegion* current_layer_region; SeamPosition configured_seam_preference; public: + bool also_overhangs = false; PerimeterCopy(std::vector* regions_out, Polygons* polys, SeamPosition configured_seam) : corresponding_regions_out(regions_out), configured_seam_preference(configured_seam), polygons(polys) { } @@ -441,9 +442,13 @@ Polygons extract_perimeter_polygons(const Layer *layer, const SeamPosition confi if (path.role() == ExtrusionRole::erExternalPerimeter) { role = ExtrusionRole::erExternalPerimeter; } + if (path.role() == ExtrusionRole::erOverhangPerimeter && + also_overhangs) { // TODO find a way to search for external overhangs only + role = ExtrusionRole::erOverhangPerimeter; + } } - if (role == ExtrusionRole::erExternalPerimeter + if (role == ExtrusionRole::erExternalPerimeter || (role == ExtrusionRole::erOverhangPerimeter && also_overhangs) || (is_perimeter(role) && configured_seam_preference == spAllRandom)) { //for random seam alignment, extract all perimeters Points p; loop.collect_points(p); @@ -464,12 +469,20 @@ Polygons extract_perimeter_polygons(const Layer *layer, const SeamPosition confi visitor.set_current_layer_region(layer_region); ex_entity->visit(visitor); if (polygons.empty()) { - Points p; - ex_entity->collect_points(p); - polygons.emplace_back(std::move(p)); - corresponding_regions_out.push_back(layer_region); - //shouldn't happen - assert(false); + //can happen if the external is fully an overhang + visitor.also_overhangs = true; + ex_entity->visit(visitor); + visitor.also_overhangs = false; + if (polygons.empty()) { + //shouldn't happen + ex_entity->visit(visitor); + assert(false); + // what to do in this case? + Points p; + ex_entity->collect_points(p); + polygons.emplace_back(std::move(p)); + corresponding_regions_out.push_back(layer_region); + } } } } diff --git a/src/libslic3r/GCodeWriter.cpp b/src/libslic3r/GCodeWriter.cpp index 97eb7ecf31a..ccd8fd25c44 100644 --- a/src/libslic3r/GCodeWriter.cpp +++ b/src/libslic3r/GCodeWriter.cpp @@ -311,23 +311,34 @@ std::string GCodeWriter::write_acceleration(){ //try to set only printing acceleration, travel should be untouched if possible if (FLAVOR_IS(gcfRepetier)) { // M201: Set max printing acceleration - gcode << "M201 X" << m_current_acceleration << " Y" << m_current_acceleration; + if (m_current_acceleration > 0) + gcode << "M201 X" << m_current_acceleration << " Y" << m_current_acceleration; } else if(FLAVOR_IS(gcfLerdge) || FLAVOR_IS(gcfSprinter)){ // M204: Set printing acceleration // This is new MarlinFirmware with separated print/retraction/travel acceleration. // Use M204 P, we don't want to override travel acc by M204 S (which is deprecated anyway). - gcode << "M204 P" << m_current_acceleration; + if (m_current_acceleration > 0) + gcode << "M204 P" << m_current_acceleration; } else if (FLAVOR_IS(gcfMarlinFirmware) || FLAVOR_IS(gcfRepRap)) { // M204: Set printing & travel acceleration - gcode << "M204 P" << m_current_acceleration << " T" << (m_current_travel_acceleration > 0 ? m_current_travel_acceleration : m_current_acceleration); + if (m_current_acceleration > 0) + gcode << "M204 P" << m_current_acceleration << " T" << (m_current_travel_acceleration > 0 ? m_current_travel_acceleration : m_current_acceleration); + else if(m_current_travel_acceleration > 0) + gcode << "M204 T" << m_current_travel_acceleration; } else { // gcfMarlinLegacy // M204: Set default acceleration - gcode << "M204 S" << m_current_acceleration; + if (m_current_acceleration > 0) + gcode << "M204 S" << m_current_acceleration; } - if (this->config.gcode_comments) gcode << " ; adjust acceleration"; - gcode << "\n"; - - return gcode.str(); + //if at least something, add comment and line return + if (gcode.tellp() != std::streampos(0)) { + if (this->config.gcode_comments) + gcode << " ; adjust acceleration"; + gcode << "\n"; + return gcode.str(); + } + assert(gcode.str().empty()); + return ""; } std::string GCodeWriter::reset_e(bool force) @@ -433,7 +444,7 @@ std::string GCodeWriter::set_speed(const double speed, const std::string &commen const double F = speed * 60; m_current_speed = speed; assert(F > 0.); - assert(F < 100000.); + assert(F < 10000000.); // GCodeG1Formatter w; // w.emit_f(F); // w.emit_comment(this->config.gcode_comments, comment); @@ -565,7 +576,7 @@ bool GCodeWriter::will_move_z(double z) const we don't perform an actual Z move. */ if (m_lifted > 0) { double nominal_z = m_pos.z() - m_lifted; - if (z >= nominal_z + EPSILON && z <= m_pos.z() - EPSILON) + if (z >= nominal_z - EPSILON && z <= m_pos.z() + EPSILON) return false; } return true; @@ -637,6 +648,9 @@ std::string GCodeWriter::retract(bool before_wipe) { double factor = before_wipe ? m_tool->retract_before_wipe() : 1.; assert(factor >= 0. && factor <= 1. + EPSILON); + // if before_wipe but no retract_before_wipe, then no retract + if (factor == 0) + return ""; //check for override if (config_region && config_region->print_retract_length >= 0) { return this->_retract( diff --git a/src/libslic3r/GCodeWriter.hpp b/src/libslic3r/GCodeWriter.hpp index 85735706a76..352dbe4fd3c 100644 --- a/src/libslic3r/GCodeWriter.hpp +++ b/src/libslic3r/GCodeWriter.hpp @@ -17,13 +17,7 @@ class GCodeWriter { // override from region const PrintRegionConfig* config_region = nullptr; - GCodeWriter() : - multiple_extruders(false), m_extrusion_axis("E"), m_tool(nullptr), - m_single_extruder_multi_material(false), - m_last_acceleration(0), m_current_acceleration(0), m_current_speed(0), - m_last_bed_temperature(0), m_last_bed_temperature_reached(true), - m_lifted(0) - {} + GCodeWriter() {} Tool* tool() { return m_tool; } const Tool* tool() const { return m_tool; } @@ -96,25 +90,25 @@ class GCodeWriter { // Extruders are sorted by their ID, so that binary search is possible. std::vector m_extruders; std::vector m_millers; - std::string m_extrusion_axis; - bool m_single_extruder_multi_material; - Tool* m_tool; - uint32_t m_last_acceleration; - uint32_t m_last_travel_acceleration; - uint32_t m_current_acceleration; - uint32_t m_current_travel_acceleration; - double m_current_speed; - uint8_t m_last_fan_speed; - int16_t m_last_temperature; - int16_t m_last_temperature_with_offset; - int16_t m_last_bed_temperature; - bool m_last_bed_temperature_reached; + std::string m_extrusion_axis = "E"; + bool m_single_extruder_multi_material = false; + Tool* m_tool = nullptr; + uint32_t m_last_acceleration = 0; + uint32_t m_last_travel_acceleration = 0; + uint32_t m_current_acceleration = 0; + uint32_t m_current_travel_acceleration = 0; + double m_current_speed = 0; + uint8_t m_last_fan_speed = 0; + int16_t m_last_temperature = 0; + int16_t m_last_temperature_with_offset = 0; + int16_t m_last_bed_temperature = 0; + bool m_last_bed_temperature_reached = true; // if positive, it's set, and the next lift wil have this extra lift double m_extra_lift = 0; // current lift, to remove from m_pos to have the current height. - double m_lifted; + double m_lifted = 0; Vec3d m_pos = Vec3d::Zero(); - + std::string _travel_to_z(double z, const std::string &comment); std::string _retract(double length, std::optional restart_extra, std::optional restart_extra_toolchange, const std::string &comment); diff --git a/src/libslic3r/PerimeterGenerator.cpp b/src/libslic3r/PerimeterGenerator.cpp index 9a4a7318e77..d3f01c621f4 100644 --- a/src/libslic3r/PerimeterGenerator.cpp +++ b/src/libslic3r/PerimeterGenerator.cpp @@ -38,6 +38,25 @@ #endif namespace Slic3r { + +//struct CollectionSimplifyVisitor : public ExtrusionVisitor +//{ +// ExtrusionEntityCollection *previous = nullptr; +// virtual void default_use(ExtrusionEntity& entity) override {}; +// virtual void use(ExtrusionEntityCollection &coll) override +// { +// if (previous && coll.entities().size() == 1) { +// previous->append_move_from(coll); +// } else { +// ExtrusionEntityCollection *old_previous = previous; +// previous = &coll; +// for (size_t i = 0; i < coll.entities().size(); ++i) { coll.set_entities()[i]->visit(*this); } +// previous = old_previous; +// } +// } +//}; + + PerimeterGeneratorLoops get_all_Childs(PerimeterGeneratorLoop loop) { PerimeterGeneratorLoops ret; for (PerimeterGeneratorLoop &child : loop.children) { @@ -348,8 +367,12 @@ ProcessSurfaceResult PerimeterGenerator::process_arachne(int& loop_number, const std::unordered_map map_extrusion_to_idx; for (size_t idx = 0; idx < all_extrusions.size(); idx++) map_extrusion_to_idx.emplace(all_extrusions[idx], idx); - - auto extrusions_constrains = Arachne::WallToolPaths::getRegionOrder(all_extrusions, this->config->external_perimeters_first); + + //TODO: order extrusion for contour/hole separatly + bool reverse_order = this->config->external_perimeters_first + || (this->object_config->brim_width.value > 0 && this->layer->id() == 0) + || (this->object_config->brim_width_interior.value > 0 && this->layer->id() == 0); + auto extrusions_constrains = Arachne::WallToolPaths::getRegionOrder(all_extrusions, reverse_order); for (auto [before, after] : extrusions_constrains) { auto after_it = map_extrusion_to_idx.find(after); ++blocked[after_it->second]; @@ -781,7 +804,19 @@ void PerimeterGenerator::process() this->get_ext_perimeter_spacing() / 2 : // two or more loops? this->get_perimeter_spacing() / 2; - infill_peri_overlap = scale_t(this->config->get_abs_value("infill_overlap", unscale(perimeter_spacing + solid_infill_spacing) / 2)); + //infill_peri_overlap = scale_t(this->config->get_abs_value("infill_overlap", unscale(perimeter_spacing + solid_infill_spacing) / 2)); + //give the overlap size to let the infill do his overlap + //add overlap if at least one perimeter + coordf_t perimeter_spacing_for_encroach = 0; + if(this->config->perimeters == 1) + perimeter_spacing_for_encroach = this->ext_perimeter_flow.spacing(); + else if(this->config->only_one_perimeter_top.value) + //note: use the min of the two to avoid overextrusion if only one perimeter top + // TODO: only do that if there is a top & a not-top surface + perimeter_spacing_for_encroach = std::min(this->perimeter_flow.spacing(), this->ext_perimeter_flow.spacing()); + else //if(layerm->region().config().perimeters > 1) + perimeter_spacing_for_encroach = this->perimeter_flow.spacing(); + infill_peri_overlap = scale_t(this->config->get_abs_value("infill_overlap", perimeter_spacing_for_encroach)); } //remove gapfill from last @@ -1598,6 +1633,19 @@ ProcessSurfaceResult PerimeterGenerator::process_classic(int& loop_number, const #if _DEBUG peri_entities.visit(LoopAssertVisitor{}); #endif + // remove the un-needed top collection if only one child. + //peri_entities.visit(CollectionSimplifyVisitor{}); + if (peri_entities.entities().size() == 1) { + if (ExtrusionEntityCollection *coll_child = dynamic_cast( + peri_entities.set_entities().front()); + coll_child != nullptr) { + peri_entities.set_can_sort_reverse(coll_child->can_sort(), coll_child->can_reverse()); + peri_entities.append_move_from(*coll_child); + peri_entities.remove(0); + } + } + + //{ // static int aodfjiaqsdz = 0; // std::stringstream stri; @@ -1613,69 +1661,6 @@ ProcessSurfaceResult PerimeterGenerator::process_classic(int& loop_number, const // svg.Close(); //} - - // if brim will be printed, reverse the order of perimeters so that - // we continue inwards after having finished the brim - // be careful to not print thin walls before perimeters (gapfill will be added after so don't worry for them) - // TODO: add test for perimeter order - const bool brim_first_layer = this->layer->id() == 0 && (this->object_config->brim_width.value > 0 || this->object_config->brim_width_interior.value > 0); - if (this->config->external_perimeters_first || brim_first_layer) { - if (this->config->external_perimeters_nothole.value || brim_first_layer) { - if (this->config->external_perimeters_hole.value || brim_first_layer) { - //reverse only not-thin wall - ExtrusionEntityCollection coll2; - for (const ExtrusionEntity* loop : peri_entities.entities()) { - if ( (loop->is_loop() && loop->role() != erThinWall)) { - coll2.append(*loop); - } - } - coll2.reverse(); - for (const ExtrusionEntity* loop : peri_entities.entities()) { - if (!((loop->is_loop() && loop->role() != erThinWall))) { - coll2.append(*loop); - } - } - //note: this hacky thing is possible because coll2.entities contains in fact peri_entities's entities - //if you does peri_entities = coll2, you'll delete peri_entities's entities() and then you have nothing. - peri_entities = std::move(coll2); - } else { - //reverse only not-hole perimeters - ExtrusionEntityCollection coll2; - for (const ExtrusionEntity* loop : peri_entities.entities()) { - if ((loop->is_loop() && loop->role() != erThinWall) && !(((ExtrusionLoop*)loop)->loop_role() & ExtrusionLoopRole::elrHole) != 0) { - coll2.append(*loop); - } - } - coll2.reverse(); - for (const ExtrusionEntity* loop : peri_entities.entities()) { - if (!((loop->is_loop() && loop->role() != erThinWall) && !(((ExtrusionLoop*)loop)->loop_role() & ExtrusionLoopRole::elrHole) != 0)) { - coll2.append(*loop); - } - } - //note: this hacky thing is possible because coll2.entities contains in fact entities's entities - //if you does peri_entities = coll2, you'll delete peri_entities's entities and then you have nothing. - peri_entities = std::move(coll2); - } - } else if (this->config->external_perimeters_hole.value) { - //reverse the hole, and put them in first place. - ExtrusionEntityCollection coll2; - for (const ExtrusionEntity* loop : peri_entities.entities()) { - if ((loop->is_loop() && loop->role() != erThinWall) && (((ExtrusionLoop*)loop)->loop_role() & ExtrusionLoopRole::elrHole) != 0) { - coll2.append(*loop); - } - } - coll2.reverse(); - for (const ExtrusionEntity* loop : peri_entities.entities()) { - if (!((loop->is_loop() && loop->role() != erThinWall) && (((ExtrusionLoop*)loop)->loop_role() & ExtrusionLoopRole::elrHole) != 0)) { - coll2.append(*loop); - } - } - //note: this hacky thing is possible because coll2.entities contains in fact peri_entities's entities - //if you does peri_entities = coll2, you'll delete peri_entities's entities and then you have nothing. - peri_entities = std::move(coll2); - } - - } // append perimeters for this slice as a collection if (!peri_entities.empty()) { //move it, to avoid to clone evrything and then delete it @@ -2103,6 +2088,60 @@ ExtrusionPaths PerimeterGenerator::create_overhangs(const Polyline& loop_polygon return paths; } +#ifdef _DEBUG +void test_overhangs(const std::vector& path1, const std::vector& path2, Points &outer_points) +{ + for (const ClipperLib_Z::Path &poly : path1) + for (int i = 0; i < poly.size() - 1; i++) + assert(poly[i] != poly[i + 1]); + for (const ClipperLib_Z::Path &poly : path2) + for (int i = 0; i < poly.size() - 1; i++) + assert(poly[i] != poly[i + 1]); + // check if points are equal + //Points path2_points; + //Points path1_points; + //for (auto &line : path2) + // for (auto &pt : line) path2_points.emplace_back(coord_t(pt.x()), coord_t(pt.y())); + //for (auto &line : path1) + // for (auto &pt : line) path1_points.emplace_back(coord_t(pt.x()), coord_t(pt.y())); + //for (Point &pt : path2_points) { + // bool found = false; + // bool in_outer = false; + // Point pt2_almost; + // for (Point &pt2 : path1_points) + // if (pt.coincides_with_epsilon(pt2)) { + // found = true; + // pt2_almost = pt2; + // break; + // } + // for (Point &pt2 : outer_points) + // if (pt.coincides_with_epsilon(pt2)) { + // found = true; + // in_outer = true; + // pt2_almost = pt2; + // break; + // } + // assert(found); + // found = false; + // in_outer = false; + // for (Point &pt2 : path1_points) + // if (pt.coincides_with(pt2)) { + // found = true; + // break; + // } + // for (Point &pt2 : outer_points) + // if (pt.coincides_with(pt2)) { + // found = true; + // in_outer = true; + // break; + // } + // assert(found); + //} + // => points can be different from diff & intersect + // TODO: create a new operation that create the diff & intersect at the same time +} +#endif + //TODO: transform to ExtrusionMultiPath instead of ExtrusionPaths ExtrusionPaths PerimeterGenerator::create_overhangs(const ClipperLib_Z::Path& arachne_path, ExtrusionRole role, bool is_external) const { ExtrusionPaths paths; @@ -2145,6 +2184,10 @@ ExtrusionPaths PerimeterGenerator::create_overhangs(const ClipperLib_Z::Path& ar if (overhangs_width_speed > 0 && (overhangs_width_speed < overhangs_width || overhangs_width == 0)) { if (!this->_lower_slices_bridge_speed_small_clipperpaths.empty()) { //small_speed = diff_pl(*previous, this->_lower_slices_bridge_speed_small); +#ifdef _DEBUG + Points outer_points; + for(auto & line: *previous) for(auto &pt : line) outer_points.emplace_back(coord_t(pt.x()), coord_t(pt.y())); +#endif small_speed = clip_extrusion(*previous, this->_lower_slices_bridge_speed_small_clipperpaths, ClipperLib_Z::ctDifference); #ifdef _DEBUG for (ClipperLib_Z::Path& poly : small_speed) // assert small_speed @@ -2154,14 +2197,17 @@ ExtrusionPaths PerimeterGenerator::create_overhangs(const ClipperLib_Z::Path& ar if (!small_speed.empty()) { *previous = clip_extrusion(*previous, this->_lower_slices_bridge_speed_small_clipperpaths, ClipperLib_Z::ctIntersection); #ifdef _DEBUG - for (ClipperLib_Z::Path& poly : *previous) // assert previous - for (int i = 0; i < poly.size() - 1; i++) // assert previous - assert(poly[i] != poly[i + 1]); // assert previous + test_overhangs(small_speed, *previous, outer_points); + test_overhangs(*previous, small_speed, outer_points); #endif previous = &small_speed; } } if (!this->_lower_slices_bridge_speed_big.empty()) { +#ifdef _DEBUG + Points outer_points; + for(auto & line: *previous) for(auto &pt : line) outer_points.emplace_back(coord_t(pt.x()), coord_t(pt.y())); +#endif big_speed = clip_extrusion(*previous, this->_lower_slices_bridge_speed_big_clipperpaths, ClipperLib_Z::ctDifference); #ifdef _DEBUG for (ClipperLib_Z::Path& poly : big_speed) // assert big_speed @@ -2171,9 +2217,8 @@ ExtrusionPaths PerimeterGenerator::create_overhangs(const ClipperLib_Z::Path& ar if (!big_speed.empty()) { *previous = clip_extrusion(*previous, this->_lower_slices_bridge_speed_big_clipperpaths, ClipperLib_Z::ctIntersection); #ifdef _DEBUG - for (ClipperLib_Z::Path& poly : *previous) // assert previous - for (int i = 0; i < poly.size() - 1; i++) // assert previous - assert(poly[i] != poly[i + 1]); // assert previous + test_overhangs(big_speed, *previous, outer_points); + test_overhangs(*previous, big_speed, outer_points); #endif previous = &big_speed; } @@ -2181,6 +2226,10 @@ ExtrusionPaths PerimeterGenerator::create_overhangs(const ClipperLib_Z::Path& ar } if (overhangs_width > 0) { if (!this->_lower_slices_bridge_flow_small.empty()) { +#ifdef _DEBUG + Points outer_points; + for(auto & line: *previous) for(auto &pt : line) outer_points.emplace_back(coord_t(pt.x()), coord_t(pt.y())); +#endif small_flow = clip_extrusion(*previous, this->_lower_slices_bridge_flow_small_clipperpaths, ClipperLib_Z::ctDifference); #ifdef _DEBUG for (ClipperLib_Z::Path& poly : small_flow) // assert small_flow @@ -2190,14 +2239,17 @@ ExtrusionPaths PerimeterGenerator::create_overhangs(const ClipperLib_Z::Path& ar if (!small_flow.empty()) { *previous = clip_extrusion(*previous, this->_lower_slices_bridge_flow_small_clipperpaths, ClipperLib_Z::ctIntersection); #ifdef _DEBUG - for (ClipperLib_Z::Path& poly : *previous) // assert previous - for (int i = 0; i < poly.size() - 1; i++) // assert previous - assert(poly[i] != poly[i + 1]); // assert previous + test_overhangs(small_flow, *previous, outer_points); + test_overhangs(*previous, small_flow, outer_points); #endif previous = &small_flow; } } if (!this->_lower_slices_bridge_flow_big.empty()) { +#ifdef _DEBUG + Points outer_points; + for(auto & line: *previous) for(auto &pt : line) outer_points.emplace_back(coord_t(pt.x()), coord_t(pt.y())); +#endif big_flow = clip_extrusion(*previous, this->_lower_slices_bridge_flow_big_clipperpaths, ClipperLib_Z::ctDifference); #ifdef _DEBUG for (ClipperLib_Z::Path& poly : big_flow) // assert big_flow @@ -2207,9 +2259,8 @@ ExtrusionPaths PerimeterGenerator::create_overhangs(const ClipperLib_Z::Path& ar if (!big_flow.empty()) { *previous = clip_extrusion(*previous, this->_lower_slices_bridge_flow_big_clipperpaths, ClipperLib_Z::ctIntersection); #ifdef _DEBUG - for (ClipperLib_Z::Path& poly : *previous) // assert previous - for (int i = 0; i < poly.size() - 1; i++) // assert previous - assert(poly[i] != poly[i + 1]); // assert previous + test_overhangs(big_flow, *previous, outer_points); + test_overhangs(*previous, big_flow, outer_points); #endif previous = &big_flow; } @@ -2220,22 +2271,43 @@ ExtrusionPaths PerimeterGenerator::create_overhangs(const ClipperLib_Z::Path& ar if (!ok_polylines.empty()) { //fast track if (small_speed.empty() && big_speed.empty() && small_flow.empty() && big_flow.empty()) { - for (auto&& path : Geometry::unsafe_variable_width(Arachne::to_thick_polyline(arachne_path), + ExtrusionPaths thickpaths = Geometry::unsafe_variable_width(Arachne::to_thick_polyline(arachne_path), role, is_external ? this->ext_perimeter_flow : this->perimeter_flow, std::max(this->ext_perimeter_flow.scaled_width() / 4, scale_t(this->print_config->resolution)), - (is_external ? this->ext_perimeter_flow : this->perimeter_flow).scaled_width() / 10)) { + (is_external ? this->ext_perimeter_flow : this->perimeter_flow).scaled_width() / 10); +#ifdef _DEBUG + for (int i = 1; i < thickpaths.size(); i++) { + assert(thickpaths[i - 1].last_point() == thickpaths[i].first_point()); + } +#endif + assert(thickpaths.front().first_point().x() == arachne_path.front().x()); + assert(thickpaths.front().first_point().y() == arachne_path.front().y()); + assert(thickpaths.back().last_point().x() == arachne_path.back().x()); + assert(thickpaths.back().last_point().y() == arachne_path.back().y()); + for (ExtrusionPath& path : thickpaths) { path.set_can_reverse(!is_loop); paths.push_back(std::move(path)); } return paths; } for (const ClipperLib_Z::Path& extrusion_path : ok_polylines) { - for (auto&& path : Geometry::unsafe_variable_width(Arachne::to_thick_polyline(extrusion_path), + auto thick_poly = Arachne::to_thick_polyline(extrusion_path); + ExtrusionPaths thickpaths = Geometry::unsafe_variable_width(thick_poly, role, is_external ? this->ext_perimeter_flow : this->perimeter_flow, std::max(this->ext_perimeter_flow.scaled_width() / 4, scale_t(this->print_config->resolution)), - (is_external ? this->ext_perimeter_flow : this->perimeter_flow).scaled_width() / 10)) { + (is_external ? this->ext_perimeter_flow : this->perimeter_flow).scaled_width() / 10); +#ifdef _DEBUG + for (int i = 1; i < thickpaths.size(); i++) { + assert(thickpaths[i - 1].last_point() == thickpaths[i].first_point()); + } +#endif + assert(thickpaths.front().first_point().x() == extrusion_path.front().x()); + assert(thickpaths.front().first_point().y() == extrusion_path.front().y()); + assert(thickpaths.back().last_point().x() == extrusion_path.back().x()); + assert(thickpaths.back().last_point().y() == extrusion_path.back().y()); + for (ExtrusionPath& path : thickpaths) { path.set_can_reverse(!is_loop); path.height = 0; paths.push_back(std::move(path)); @@ -2244,11 +2316,21 @@ ExtrusionPaths PerimeterGenerator::create_overhangs(const ClipperLib_Z::Path& ar } if (!small_speed.empty()) { for (const ClipperLib_Z::Path& extrusion_path : small_speed) { - for (auto&& path : Geometry::unsafe_variable_width(Arachne::to_thick_polyline(extrusion_path), + ExtrusionPaths thickpaths = Geometry::unsafe_variable_width(Arachne::to_thick_polyline(extrusion_path), erOverhangPerimeter, is_external ? this->ext_perimeter_flow : this->perimeter_flow, std::max(this->ext_perimeter_flow.scaled_width() / 4, scale_t(this->print_config->resolution)), - (is_external ? this->ext_perimeter_flow : this->perimeter_flow).scaled_width() / 10)) { + (is_external ? this->ext_perimeter_flow : this->perimeter_flow).scaled_width() / 10); +#ifdef _DEBUG + for (int i = 1; i < thickpaths.size(); i++) { + assert(thickpaths[i - 1].last_point() == thickpaths[i].first_point()); + } +#endif + assert(thickpaths.front().first_point().x() == extrusion_path.front().x()); + assert(thickpaths.front().first_point().y() == extrusion_path.front().y()); + assert(thickpaths.back().last_point().x() == extrusion_path.back().x()); + assert(thickpaths.back().last_point().y() == extrusion_path.back().y()); + for (ExtrusionPath& path : thickpaths) { path.set_can_reverse(!is_loop); path.height = no_small_flow ? 2 : 1; paths.push_back(std::move(path)); @@ -2257,11 +2339,21 @@ ExtrusionPaths PerimeterGenerator::create_overhangs(const ClipperLib_Z::Path& ar } if (!big_speed.empty()) { for (const ClipperLib_Z::Path& extrusion_path : big_speed) { - for (auto&& path : Geometry::unsafe_variable_width(Arachne::to_thick_polyline(extrusion_path), + ExtrusionPaths thickpaths = Geometry::unsafe_variable_width(Arachne::to_thick_polyline(extrusion_path), erOverhangPerimeter, is_external ? this->ext_perimeter_flow : this->perimeter_flow, std::max(this->ext_perimeter_flow.scaled_width() / 4, scale_t(this->print_config->resolution)), - (is_external ? this->ext_perimeter_flow : this->perimeter_flow).scaled_width() / 10)) { + (is_external ? this->ext_perimeter_flow : this->perimeter_flow).scaled_width() / 10); +#ifdef _DEBUG + for (int i = 1; i < thickpaths.size(); i++) { + assert(thickpaths[i - 1].last_point() == thickpaths[i].first_point()); + } +#endif + assert(thickpaths.front().first_point().x() == extrusion_path.front().x()); + assert(thickpaths.front().first_point().y() == extrusion_path.front().y()); + assert(thickpaths.back().last_point().x() == extrusion_path.back().x()); + assert(thickpaths.back().last_point().y() == extrusion_path.back().y()); + for (ExtrusionPath& path : thickpaths) { path.set_can_reverse(!is_loop); path.height = no_small_flow ? 3 : 2; paths.push_back(std::move(path)); @@ -2270,11 +2362,21 @@ ExtrusionPaths PerimeterGenerator::create_overhangs(const ClipperLib_Z::Path& ar } if (!small_flow.empty()) { for (const ClipperLib_Z::Path& extrusion_path : small_flow) { - for (auto&& path : Geometry::unsafe_variable_width(Arachne::to_thick_polyline(extrusion_path), + ExtrusionPaths thickpaths = Geometry::unsafe_variable_width(Arachne::to_thick_polyline(extrusion_path), erOverhangPerimeter, is_external ? this->ext_perimeter_flow : this->perimeter_flow, std::max(this->ext_perimeter_flow.scaled_width() / 4, scale_t(this->print_config->resolution)), - (is_external ? this->ext_perimeter_flow : this->perimeter_flow).scaled_width() / 10)) { + (is_external ? this->ext_perimeter_flow : this->perimeter_flow).scaled_width() / 10); +#ifdef _DEBUG + for (int i = 1; i < thickpaths.size(); i++) { + assert(thickpaths[i - 1].last_point() == thickpaths[i].first_point()); + } +#endif + assert(thickpaths.front().first_point().x() == extrusion_path.front().x()); + assert(thickpaths.front().first_point().y() == extrusion_path.front().y()); + assert(thickpaths.back().last_point().x() == extrusion_path.back().x()); + assert(thickpaths.back().last_point().y() == extrusion_path.back().y()); + for (ExtrusionPath& path : thickpaths) { // change flow to overhang one if too much. if (path.mm3_per_mm > this->overhang_flow.mm3_per_mm() ){ path.mm3_per_mm = this->overhang_flow.mm3_per_mm(); @@ -2289,11 +2391,21 @@ ExtrusionPaths PerimeterGenerator::create_overhangs(const ClipperLib_Z::Path& ar } if (!big_flow.empty()) { for (const ClipperLib_Z::Path& extrusion_path : big_flow) { - for (auto&& path : Geometry::unsafe_variable_width(Arachne::to_thick_polyline(extrusion_path), + ExtrusionPaths thickpaths = Geometry::unsafe_variable_width(Arachne::to_thick_polyline(extrusion_path), erOverhangPerimeter, is_external ? this->ext_perimeter_flow : this->perimeter_flow, std::max(this->ext_perimeter_flow.scaled_width() / 4, scale_t(this->print_config->resolution)), - (is_external ? this->ext_perimeter_flow : this->perimeter_flow).scaled_width() / 10)) { + (is_external ? this->ext_perimeter_flow : this->perimeter_flow).scaled_width() / 10); +#ifdef _DEBUG + for (int i = 1; i < thickpaths.size(); i++) { + assert(thickpaths[i - 1].last_point() == thickpaths[i].first_point()); + } +#endif + assert(thickpaths.front().first_point().x() == extrusion_path.front().x()); + assert(thickpaths.front().first_point().y() == extrusion_path.front().y()); + assert(thickpaths.back().last_point().x() == extrusion_path.back().x()); + assert(thickpaths.back().last_point().y() == extrusion_path.back().y()); + for (ExtrusionPath& path : thickpaths) { // change flow to overhang one if too much. if (path.mm3_per_mm > this->overhang_flow.mm3_per_mm()) { path.mm3_per_mm = this->overhang_flow.mm3_per_mm(); @@ -2314,6 +2426,21 @@ ExtrusionPaths PerimeterGenerator::create_overhangs(const ClipperLib_Z::Path& ar if (!paths.empty()) chain_and_reorder_extrusion_paths(paths, &paths.front().first_point()); + for (int i = 1; i < paths.size(); i++) { + // diff/inter can generate points with ~3-5 unit of diff. + if (paths[i - 1].last_point() != paths[i].first_point()) { + assert(paths[i - 1].last_point().coincides_with_epsilon(paths[i].first_point())); + Point middle = (paths[i - 1].last_point() + paths[i].first_point()) / 2; + paths[i - 1].polyline.set_points().back() = middle; + paths[i].polyline.set_points().front() = middle; + } + } +#ifdef _DEBUG + for (int i = 1; i < paths.size(); i++) { + assert(paths[i - 1].last_point() == paths[i].first_point()); + } +#endif + bool has_normal = !ok_polylines.empty(); bool has_speed = !small_speed.empty() || !big_speed.empty(); bool has_flow = !small_flow.empty() || !big_flow.empty(); @@ -2357,11 +2484,6 @@ ExtrusionPaths PerimeterGenerator::create_overhangs(const ClipperLib_Z::Path& ar if (paths.size() > 2) { double min_length = this->perimeter_flow.scaled_width() * 2; double ok_length = this->perimeter_flow.scaled_width() * 20; -#ifdef _DEBUG - for (int i = 1; i < paths.size(); i++) { - assert(paths[i - 1].last_point() == paths[i].first_point()); - } -#endif foreach(paths, [min_length, ok_length](ExtrusionPath& prev, ExtrusionPath& curr, ExtrusionPath& next) { assert(prev.last_point() == curr.first_point()); if (curr.length() < min_length) { @@ -2636,21 +2758,32 @@ ExtrusionEntityCollection PerimeterGenerator::_traverse_loops( //little check: if you have external holes with only one extrusion and internal things, please draw the internal first, just in case it can help print the hole better. std::vector> better_chain; - for (const std::pair& idx : chain) { - if(idx.first < loops.size()) - if (!loops[idx.first].is_external() || (!loops[idx.first].is_contour && !loops[idx.first].children.empty())) - better_chain.push_back(idx); - } - for (const std::pair& idx : chain) { - if (idx.first < loops.size()) - if (idx.first < loops.size() && loops[idx.first].is_external() && !(!loops[idx.first].is_contour && !loops[idx.first].children.empty())) - better_chain.push_back(idx); - } - //thin walls always last! - for (const std::pair& idx : chain) { - if (idx.first >= loops.size()) - better_chain.push_back(idx); + { + std::vector> alone_holes; + std::vector> keep_ordering; + std::vector> thin_walls; + for (const std::pair &idx : chain) { + if (idx.first < loops.size()) + if (!loops[idx.first].is_external() || + (!loops[idx.first].is_contour && !loops[idx.first].children.empty())) + alone_holes.push_back(idx); + else + keep_ordering.push_back(idx); + else + thin_walls.push_back(idx); + } + append(better_chain, std::move(alone_holes)); + append(better_chain, std::move(keep_ordering)); + append(better_chain, std::move(thin_walls)); } + assert(better_chain.size() == chain.size()); + + // if brim will be printed, reverse the order of perimeters so that + // we continue inwards after having finished the brim + const bool reverse_contour = (this->layer->id() == 0 && this->object_config->brim_width.value > 0) || + (this->config->external_perimeters_first.value && this->config->external_perimeters_nothole.value); + const bool reverse_hole = (this->layer->id() == 0 && this->object_config->brim_width_interior.value > 0) || + (this->config->external_perimeters_first.value && this->config->external_perimeters_hole.value); //move from coll to coll_out and getting children of each in the same time. (deep first) for (const std::pair &idx : better_chain) { @@ -2691,9 +2824,10 @@ ExtrusionEntityCollection PerimeterGenerator::_traverse_loops( assert(thin_walls.empty()); ExtrusionEntityCollection children = this->_traverse_loops(loop.children, thin_walls, has_overhang ? 1 : count_since_overhang < 0 ? -1 : (count_since_overhang+1)); coll[idx.first] = nullptr; - if (loop.is_contour) { + if ((loop.is_contour && !reverse_contour) || (!loop.is_contour && reverse_hole)) { //note: this->layer->id() % 2 == 1 already taken into account in the is_steep_overhang compute (to save time). - if (loop.is_steep_overhang && this->layer->id() % 2 == 1) + // if contour: reverse if steep_overhang & odd. if hole: the opposite + if ((loop.is_steep_overhang && this->layer->id() % 2 == 1) == loop.is_contour) eloop->make_clockwise(); else eloop->make_counter_clockwise(); @@ -2701,10 +2835,10 @@ ExtrusionEntityCollection PerimeterGenerator::_traverse_loops( if (!children.empty()) { ExtrusionEntityCollection print_child_beforeplz; print_child_beforeplz.set_can_sort_reverse(false, false); - if (children.entities().size() > 1) { + if (children.entities().size() > 1 && (children.can_reverse() || children.can_sort())) { print_child_beforeplz.append(children); } else { - print_child_beforeplz.append(std::move(children.entities())); + print_child_beforeplz.append_move_from(children); } print_child_beforeplz.append(*eloop); coll_out.append(std::move(print_child_beforeplz)); @@ -2712,7 +2846,8 @@ ExtrusionEntityCollection PerimeterGenerator::_traverse_loops( coll_out.append(*eloop); } } else { - if (loop.is_steep_overhang && this->layer->id() % 2 == 1) + // if hole: reverse if steep_overhang & odd. if contour: the opposite + if ((loop.is_steep_overhang && this->layer->id() % 2 == 1) != loop.is_contour) eloop->make_counter_clockwise(); else eloop->make_clockwise(); @@ -2721,10 +2856,10 @@ ExtrusionEntityCollection PerimeterGenerator::_traverse_loops( ExtrusionEntityCollection print_child_beforeplz; print_child_beforeplz.set_can_sort_reverse(false, false); print_child_beforeplz.append(*eloop); - if (children.entities().size() > 1) { + if (children.entities().size() > 1 && (children.can_reverse() || children.can_sort())) { print_child_beforeplz.append(children); } else { - print_child_beforeplz.append(std::move(children.entities())); + print_child_beforeplz.append_move_from(children); } coll_out.append(std::move(print_child_beforeplz)); } else { @@ -2778,7 +2913,7 @@ ExtrusionEntityCollection PerimeterGenerator::_traverse_extrusions(std::vector

size()); for (const Arachne::ExtrusionJunction& ej : extrusion->junctions) { - //remove duplicate poitns from arachne + //remove duplicate points from arachne if(extrusion_path.empty() || (ej.p.x() != extrusion_path.back().x() || ej.p.y() != extrusion_path.back().y())) extrusion_path.emplace_back(ej.p.x(), ej.p.y(), ej.w); @@ -3016,7 +3151,6 @@ void PerimeterGenerator::_merge_thin_walls(ExtrusionEntityCollection &extrusions current_loop = last_loop; } virtual void use(ExtrusionEntityCollection &collection) override { - collection.set_can_sort_reverse(true, true); //for each loop? (or other collections) for (ExtrusionEntity *entity : collection.entities()) entity->visit(*this); diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index c2a68acdca5..52a0c4e872e 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -1743,6 +1743,20 @@ std::string Preset::type_name(Type t) { } } +Preset::Type Preset::type_from_name(std::string name) { + if ("print" == name) + return Preset::TYPE_FFF_PRINT; + if ("filament" == name) + return Preset::TYPE_FFF_FILAMENT; + if ("sla_print" == name) + return Preset::TYPE_SLA_PRINT; + if ("sla_material" == name) + return Preset::TYPE_SLA_MATERIAL; + if ("printer" == name) + return Preset::TYPE_PRINTER; + return Preset::TYPE_INVALID; +} + std::string PresetCollection::section_name() const { return Preset::type_name(this->type()); diff --git a/src/libslic3r/Preset.hpp b/src/libslic3r/Preset.hpp index d70fa6c3474..f4a07870889 100644 --- a/src/libslic3r/Preset.hpp +++ b/src/libslic3r/Preset.hpp @@ -142,6 +142,7 @@ class Preset return PrinterTechnology::ptUnknown; } static std::string type_name(Type t); + static Type type_from_name(std::string name); Type type = TYPE_INVALID; diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index ebaf8b197b8..19c1e232561 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -52,7 +52,7 @@ void Print::clear() } // Called by Print::apply(). -// This method only accepts PrintConfig option keys. +// This method only accepts PrintConfig option keys. Not PrintObjectConfig or PrintRegionConfig, go to PrintObject for these bool Print::invalidate_state_by_config_options(const ConfigOptionResolver& /* new_config */, const std::vector &opt_keys) { if (opt_keys.empty()) @@ -67,13 +67,14 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver& /* ne "avoid_crossing_top", "bed_shape", "bed_temperature", - "chamber_temperature", "before_layer_gcode", "between_objects_gcode", "bridge_acceleration", "bridge_internal_acceleration", "bridge_fan_speed", "bridge_internal_fan_speed", + "brim_acceleration", + "chamber_temperature", "colorprint_heights", "complete_objects_sort", "cooling", @@ -230,16 +231,7 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver& /* ne } else if (steps_ignore.find(opt_key) != steps_ignore.end()) { // These steps have no influence on the G-code whatsoever. Just ignore them. } else if ( - opt_key == "brim_inside_holes" - || opt_key == "brim_width" - || opt_key == "brim_width_interior" - || opt_key == "brim_ears" - || opt_key == "brim_ears_detection_length" - || opt_key == "brim_ears_max_angle" - || opt_key == "brim_ears_pattern" - || opt_key == "brim_per_object" - || opt_key == "brim_separation" - || opt_key == "complete_objects_one_skirt" + opt_key == "complete_objects_one_skirt" || opt_key == "draft_shield" || opt_key == "min_skirt_length" || opt_key == "ooze_prevention" diff --git a/src/libslic3r/PrintBase.hpp b/src/libslic3r/PrintBase.hpp index 7b9073f7755..03a89ef7a92 100644 --- a/src/libslic3r/PrintBase.hpp +++ b/src/libslic3r/PrintBase.hpp @@ -463,8 +463,16 @@ class PrintBase : public ObjectBase m_status_callback(SlicingStatus(percent, message, flags)); else m_status_callback(SlicingStatus(percent, message, args, flags)); + } else { + printf("%d => ", percent); + if(args.empty()) + printf(message.c_str()); + else if (args.size()==1) + printf(message.c_str(), args.front().c_str()); + else if (args.size()==2) + printf(message.c_str(), args.front().c_str(), args.back().c_str()); + printf("\n"); } - else printf("%d => %s\n", percent, message.c_str()); } typedef std::function cancel_callback_type; diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index b917eb1269d..609366e7c21 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -2293,7 +2293,7 @@ void PrintConfigDef::init_fff_params() def = this->add("fill_angle_cross", coBool); def->label = L("Alternate Fill Angle"); def->category = OptionCategory::infill; - def->tooltip = L("It's better for some infill like rectilinear to rotate 90° each layer. If this settign is deactivated, they won't do that anymore."); + def->tooltip = L("It's better for some infill like rectilinear to rotate 90° each layer. If this setting is deactivated, they won't do that anymore."); def->mode = comAdvancedE | comSuSi; def->set_default_value(new ConfigOptionBool(true)); @@ -4246,7 +4246,7 @@ void PrintConfigDef::init_fff_params() def->category = OptionCategory::customgcode; def->tooltip = L("If you want to process the output G-code through custom scripts, " "just list their absolute paths here." - "\nSeparate multiple scripts with a semicolon or a line return.\n!! please use '\;' here if you want a not-line-separation ';'!!" + "\nSeparate multiple scripts with a semicolon or a line return.\n!! please use '\\;' here if you want a not-line-separation ';'!!" "\nScripts will be passed the absolute path to the G-code file as the first argument, " "and they can access the Slic3r config settings by reading environment variables." "\nThe script, if passed as a relative path, will also be searched from the slic3r directory, " @@ -7989,6 +7989,7 @@ std::unordered_set prusa_export_to_remove_keys = { "solid_infill_acceleration", "solid_infill_extrusion_spacing", "solid_infill_fan_speed", +"solid_infill_overlap", "start_gcode_manual", "support_material_angle_height", "support_material_acceleration", diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index c1f28c9cfe3..abbaa325c4c 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -1086,8 +1086,6 @@ bool PrintObject::invalidate_state_by_config_options( invalidated |= m_print->invalidate_step(psGCodeExport); } else if ( opt_key == "brim_inside_holes" - || opt_key == "brim_width" - || opt_key == "brim_width_interior" || opt_key == "brim_ears" || opt_key == "brim_ears_detection_length" || opt_key == "brim_ears_max_angle" @@ -1097,6 +1095,14 @@ bool PrintObject::invalidate_state_by_config_options( invalidated |= m_print->invalidate_step(psSkirtBrim); // Brim is printed below supports, support invalidates brim and skirt. steps.emplace_back(posSupportMaterial); + } else if ( + opt_key == "brim_width" + || opt_key == "brim_width_interior") { + invalidated |= m_print->invalidate_step(psSkirtBrim); + // these two may change the ordering of first layer perimeters + steps.emplace_back(posPerimeters); + // Brim is printed below supports, support invalidates brim and skirt. + steps.emplace_back(posSupportMaterial); } else { // for legacy, if we can't handle this option let's invalidate all steps this->invalidate_all_steps(); diff --git a/src/libslic3r/ShortestPath.cpp b/src/libslic3r/ShortestPath.cpp index d5a9207598e..84f885bc796 100644 --- a/src/libslic3r/ShortestPath.cpp +++ b/src/libslic3r/ShortestPath.cpp @@ -1021,7 +1021,7 @@ std::vector> chain_segments_greedy2(SegmentEndPointFunc std::vector> chain_extrusion_entities(std::vector &entities, const Point *start_near) { auto segment_end_point = [&entities](size_t idx, bool first_point) -> const Point& { return first_point ? entities[idx]->first_point() : entities[idx]->last_point(); }; - auto could_reverse = [&entities](size_t idx) { const ExtrusionEntity *ee = entities[idx]; return ee->is_loop() || ee->can_reverse(); }; + auto could_reverse = [&entities](size_t idx) { const ExtrusionEntity *ee = entities[idx]; return ee->can_reverse(); }; std::vector> out = chain_segments_greedy_constrained_reversals(segment_end_point, could_reverse, entities.size(), start_near); for (std::pair &segment : out) { ExtrusionEntity *ee = entities[segment.first]; diff --git a/src/libslic3r/TriangleMesh.hpp b/src/libslic3r/TriangleMesh.hpp index 533cc12c6a7..4b8563f7eb0 100644 --- a/src/libslic3r/TriangleMesh.hpp +++ b/src/libslic3r/TriangleMesh.hpp @@ -152,9 +152,6 @@ class TriangleMesh const TriangleMeshStats& stats() const { return m_stats; } indexed_triangle_set its; - -/// --- for tests ----- /// - Pointf3s vertices(); private: TriangleMeshStats m_stats; diff --git a/src/libslic3r/Utils.hpp b/src/libslic3r/Utils.hpp index f525c98378d..283010cce32 100644 --- a/src/libslic3r/Utils.hpp +++ b/src/libslic3r/Utils.hpp @@ -8,6 +8,7 @@ #include #include +#include #include "libslic3r.h" diff --git a/src/slic3r/GUI/ConfigManipulation.cpp b/src/slic3r/GUI/ConfigManipulation.cpp index aba0b1ef753..5f585fe7ece 100644 --- a/src/slic3r/GUI/ConfigManipulation.cpp +++ b/src/slic3r/GUI/ConfigManipulation.cpp @@ -345,13 +345,13 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig* config) bool has_spiral_vase = have_perimeters && config->opt_bool("spiral_vase"); - for (auto el : { "external_perimeters_vase", "external_perimeters_nothole", "external_perimeters_hole", "perimeter_bonding"}) - toggle_field(el, config->opt_bool("external_perimeters_first")); - bool have_arachne = have_perimeters && config->opt_enum("perimeter_generator") == PerimeterGeneratorType::Arachne; for (auto el : { "wall_transition_length", "wall_transition_filter_deviation", "wall_transition_angle", "wall_distribution_count", "min_feature_size", "min_bead_width", "aaa" }) toggle_field(el, have_arachne); + toggle_field("external_perimeters_vase", config->opt_bool("external_perimeters_first")); + for (auto el : { "external_perimeters_nothole", "external_perimeters_hole", "perimeter_bonding"}) + toggle_field(el, config->opt_bool("external_perimeters_first") && !have_arachne); for (auto el : {"perimeter_loop", "extra_perimeters_overhangs", "no_perimeter_unsupported_algo", "thin_perimeters", "overhangs_reverse", "perimeter_round_corners"}) diff --git a/src/slic3r/GUI/DoubleSlider.cpp b/src/slic3r/GUI/DoubleSlider.cpp index 8c9aa40cc18..87d29b3c201 100644 --- a/src/slic3r/GUI/DoubleSlider.cpp +++ b/src/slic3r/GUI/DoubleSlider.cpp @@ -1098,6 +1098,10 @@ void Control::Ruler::update(wxWindow* win, const std::vector& values, do { if (values.empty()) return; + if (values.size() < 2) { + long_step = -1.0; + return; + } int DPI = GUI::get_dpi_for_window(win); int pixels_per_sm = lround((double)(DPI) * 5.0/25.4); diff --git a/src/slic3r/GUI/HintNotification.cpp b/src/slic3r/GUI/HintNotification.cpp index dbedd0ac632..5d5ada87604 100644 --- a/src/slic3r/GUI/HintNotification.cpp +++ b/src/slic3r/GUI/HintNotification.cpp @@ -415,7 +415,8 @@ void HintDatabase::load_hints_from_file(const boost::filesystem::path& path) // highlight settings } else if (dict["hypertext_type"] == "settings") { std::string opt = dict["hypertext_settings_opt"]; - Preset::Type type = static_cast(std::atoi(dict["hypertext_settings_type"].c_str())); + Preset::Type type = static_cast(Preset::type_from_name(dict["hypertext_settings_type"])); + assert(type != Preset::Type::TYPE_INVALID && wxGetApp().get_tab(type) != nullptr); std::wstring category = boost::nowide::widen(dict["hypertext_settings_category"]); HintData hint_data{ id_string, text1, weight, was_displayed, hypertext_text, follow_text, disabled_tags, enabled_tags, true, documentation_link, [opt, type, category]() { GUI::wxGetApp().sidebar().jump_to_option(opt, type, category); } }; m_loaded_hints.emplace_back(hint_data); diff --git a/src/slic3r/GUI/PresetHints.cpp b/src/slic3r/GUI/PresetHints.cpp index cb549477076..4ae6d925924 100644 --- a/src/slic3r/GUI/PresetHints.cpp +++ b/src/slic3r/GUI/PresetHints.cpp @@ -170,9 +170,10 @@ std::string PresetHints::cooling_description(const Preset &preset_fil, const Pre surface_list += ","; surface_list += _L("Perimeter overhangs"); } - - out += format_wxstr(_L("but for %1% where the speed-up phase is skipped."), surface_list.substr(1)); - has_disable = true; + if (surface_list.size() > 2) { + out += format_wxstr(_L("but for %1% where the speed-up phase is skipped."), surface_list.substr(1)); + has_disable = true; + } } if(has_disable) out += "."; diff --git a/src/slic3r/GUI/SavePresetDialog.cpp b/src/slic3r/GUI/SavePresetDialog.cpp index 59418c3f89c..3f30d8e8715 100644 --- a/src/slic3r/GUI/SavePresetDialog.cpp +++ b/src/slic3r/GUI/SavePresetDialog.cpp @@ -124,7 +124,7 @@ void SavePresetDialog::Item::update() } if (m_valid_type == Valid && existing && (existing->is_external)) { - info_line = _L("Cannot overwrite an external profile."); + info_line = _L("Cannot overwrite an external profile. Please choose another name."); m_valid_type = NoValid; } diff --git a/src/test-utils/CMakeLists.txt b/src/test-utils/CMakeLists.txt new file mode 100644 index 00000000000..713593a9a04 --- /dev/null +++ b/src/test-utils/CMakeLists.txt @@ -0,0 +1,10 @@ +project(test-utils) + +# convert stl to c++ code to inclusion in test +add_executable(stl_to_cpp stl_to_cpp.cpp) + +target_link_libraries(stl_to_cpp libslic3r) + +if (WIN32) + prusaslicer_copy_dlls(stl_to_cpp) +endif() diff --git a/src/test-utils/ClipboardXX/include/clipboardxx.hpp b/src/test-utils/ClipboardXX/include/clipboardxx.hpp new file mode 100644 index 00000000000..03687fe37e1 --- /dev/null +++ b/src/test-utils/ClipboardXX/include/clipboardxx.hpp @@ -0,0 +1,41 @@ +#pragma once + +#include "detail/interface.hpp" +#if defined(_WIN32) || defined(WIN32) + #define WINDOWS + #include "detail/windows.hpp" +#elif defined(__linux__) + #define LINUX + #include "detail/linux.hpp" +#else + #error "platform not supported" +#endif + +#include +#include + +namespace clipboardxx { + +#ifdef WINDOWS +using ClipboardType = ClipboardWindows; +#elif defined(LINUX) +using ClipboardType = ClipboardLinux; +#endif + +class clipboard { +public: + clipboard() : m_clipboard(std::make_unique()) {} + + void operator<<(const std::string &text) const { copy(text); } + + void copy(const std::string &text) const { m_clipboard->copy(text); } + + void operator>>(std::string &result) const { result = paste(); } + + std::string paste() const { return m_clipboard->paste(); } + +private: + std::unique_ptr m_clipboard; +}; + +} // namespace clipboardxx diff --git a/src/test-utils/ClipboardXX/include/detail/exception.hpp b/src/test-utils/ClipboardXX/include/detail/exception.hpp new file mode 100644 index 00000000000..442786891f9 --- /dev/null +++ b/src/test-utils/ClipboardXX/include/detail/exception.hpp @@ -0,0 +1,13 @@ +#pragma once + +#include +#include + +namespace clipboardxx { + +class exception : public std::runtime_error { +public: + exception(const std::string &reason) : std::runtime_error(reason){}; +}; + +} // namespace clipboardxx diff --git a/src/test-utils/ClipboardXX/include/detail/interface.hpp b/src/test-utils/ClipboardXX/include/detail/interface.hpp new file mode 100644 index 00000000000..69d5c4fb185 --- /dev/null +++ b/src/test-utils/ClipboardXX/include/detail/interface.hpp @@ -0,0 +1,14 @@ +#pragma once + +#include + +namespace clipboardxx { + +class ClipboardInterface { +public: + virtual ~ClipboardInterface() = default; + virtual void copy(const std::string &text) const = 0; + virtual std::string paste() const = 0; +}; + +} // namespace clipboardxx diff --git a/src/test-utils/ClipboardXX/include/detail/linux.hpp b/src/test-utils/ClipboardXX/include/detail/linux.hpp new file mode 100644 index 00000000000..34abc7c7b59 --- /dev/null +++ b/src/test-utils/ClipboardXX/include/detail/linux.hpp @@ -0,0 +1,30 @@ +#pragma once + +#ifdef LINUX + #include "exception.hpp" + #include "interface.hpp" + #include "linux/x11_provider.hpp" + +namespace clipboardxx { + +class ClipboardLinux : public ClipboardInterface { +public: + ClipboardLinux() : m_provider(std::make_unique()) {} + + void copy(const std::string &text) const override { + try { + m_provider->copy(text); + } catch (const exception &error) { + throw exception("XCB Error: " + std::string(error.what())); + } + } + + std::string paste() const override { return m_provider->paste(); } + +private: + const std::unique_ptr m_provider; +}; + +} // namespace clipboardxx + +#endif diff --git a/src/test-utils/ClipboardXX/include/detail/linux/provider.hpp b/src/test-utils/ClipboardXX/include/detail/linux/provider.hpp new file mode 100644 index 00000000000..465976792e7 --- /dev/null +++ b/src/test-utils/ClipboardXX/include/detail/linux/provider.hpp @@ -0,0 +1,14 @@ +#pragma once + +#include + +namespace clipboardxx { + +class LinuxClipboardProvider { +public: + virtual void copy(const std::string &text) = 0; + virtual std::string paste() = 0; + virtual ~LinuxClipboardProvider() = default; +}; + +} // namespace clipboardxx diff --git a/src/test-utils/ClipboardXX/include/detail/linux/x11_event_handler.hpp b/src/test-utils/ClipboardXX/include/detail/linux/x11_event_handler.hpp new file mode 100644 index 00000000000..b127148bef4 --- /dev/null +++ b/src/test-utils/ClipboardXX/include/detail/linux/x11_event_handler.hpp @@ -0,0 +1,167 @@ +#pragma once + +#include "xcb/xcb.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace clipboardxx { + +constexpr std::chrono::duration kHandleEventsForEverDelay = std::chrono::milliseconds(20); +constexpr std::chrono::duration kWaitForPasteDataTimeout = std::chrono::milliseconds(300); +constexpr std::array kSupportedTextFormats = { + "UTF8_STRING", "text/plain;charset=utf-8", "text/plain;charset=UTF-8", "GTK_TEXT_BUFFER_CONTENTS", "STRING", "TEXT", + "text/plain"}; + +struct EssentialAtoms { + std::vector supported_text_formats; + xcb::Atom clipboard, targets, atom, buffer; +}; + +class X11EventHandler { +public: + X11EventHandler(std::shared_ptr xcb) + : m_xcb(std::move(xcb)), m_atoms(create_essential_atoms()), + m_targets(generate_targets_atom_array(m_atoms.targets, m_atoms.supported_text_formats)), + m_stop_event_thread(false) { + m_event_thread = std::thread(&X11EventHandler::handle_events_for_ever, this); + } + + ~X11EventHandler() { + m_stop_event_thread = true; + m_event_thread.join(); + } + + void set_copy_data(const std::string &data) { + std::lock_guard lock_guard(m_lock); + m_copy_data = std::optional(data); + } + + std::string get_paste_data() { + { + std::lock_guard lock_guard(m_lock); + if (do_we_own_clipoard()) + return m_copy_data.value(); + else + m_xcb->request_selection_data(m_atoms.clipboard, m_atoms.supported_text_formats.at(0), m_atoms.buffer); + } + + wait_for_paste_data_with_timeout(kWaitForPasteDataTimeout); + std::lock_guard lock_guard(m_lock); + std::string result = m_paste_data.value_or(std::string("")); + m_paste_data.reset(); + return result; + } + +private: + EssentialAtoms create_essential_atoms() const { + EssentialAtoms atoms; + atoms.clipboard = m_xcb->create_atom("CLIPBOARD"); + atoms.buffer = m_xcb->create_atom("BUFFER"); + atoms.targets = m_xcb->create_atom("TARGETS"); + atoms.atom = m_xcb->create_atom("ATOM"); + + atoms.supported_text_formats = std::vector(kSupportedTextFormats.size()); + std::transform(kSupportedTextFormats.begin(), kSupportedTextFormats.end(), atoms.supported_text_formats.begin(), + [this](const char* name) { return m_xcb->create_atom(std::string(name)); }); + return atoms; + } + + std::vector generate_targets_atom_array(xcb::Atom target, const std::vector &atoms) { + std::vector targets(atoms.size() + 1); + targets[0] = target; + std::copy(atoms.begin(), atoms.end(), targets.begin() + 1); + return targets; + } + + bool do_we_own_clipoard() const { return m_copy_data.has_value(); } + + void wait_for_paste_data_with_timeout(std::chrono::milliseconds timeout) { + m_paste_data.reset(); + std::chrono::system_clock::time_point start_time = std::chrono::system_clock::now(); + + while (true) { + if (std::chrono::system_clock::now() - start_time > timeout) + break; + + std::this_thread::sleep_for(std::chrono::milliseconds(kHandleEventsForEverDelay)); + std::lock_guard lock_guard(m_lock); + + if (m_paste_data.has_value()) + break; + } + } + + void handle_events_for_ever() noexcept { + while (true) { + if (m_stop_event_thread) + break; + + std::this_thread::sleep_for(kHandleEventsForEverDelay); + std::lock_guard lock_guard(m_lock); + std::optional> event = m_xcb->get_latest_event(); + + if (event.has_value()) + handle_event(std::move(event.value())); + } + } + + void handle_event(std::unique_ptr event) { + switch (event->get_type()) { + case xcb::Event::Type::kRequestSelection: + handle_request_selection_event(reinterpret_cast(event.get())); + break; + case xcb::Event::Type::kSelectionClear: + m_copy_data = std::nullopt; + break; + case xcb::Event::Type::kSelectionNotify: + handle_selection_notify_event(reinterpret_cast(event.get())); + break; + case xcb::Event::Type::kNone: + return; + } + } + + void handle_request_selection_event(const xcb::RequestSelectionEvent* event) { + if (event->m_selection != m_atoms.clipboard || !m_copy_data.has_value()) + return; + + bool found_format = std::find(m_atoms.supported_text_formats.begin(), m_atoms.supported_text_formats.end(), + event->m_target) != m_atoms.supported_text_formats.end(); + if (event->m_target == m_atoms.targets) { + m_xcb->write_on_window_property(event->m_requestor, event->m_property, m_atoms.atom, m_targets); + m_xcb->notify_window_property_change(event->m_requestor, event->m_property, m_atoms.atom, + event->m_selection); + } else if (found_format) { + m_xcb->write_on_window_property(event->m_requestor, event->m_property, event->m_target, + m_copy_data.value()); + m_xcb->notify_window_property_change(event->m_requestor, event->m_property, event->m_target, + event->m_selection); + } else { + m_xcb->notify_window_property_change(event->m_requestor, 0, event->m_target, event->m_selection); + } + } + + void handle_selection_notify_event(const xcb::SelectionNotifyEvent* event) { + if (event->m_selection != m_atoms.clipboard || m_paste_data.has_value()) + return; + m_paste_data = m_xcb->get_our_property_value(m_atoms.buffer); + } + + const std::shared_ptr m_xcb; + const EssentialAtoms m_atoms; + const std::vector m_targets; + std::optional m_copy_data, m_paste_data; + std::mutex m_lock; + std::thread m_event_thread; + std::atomic m_stop_event_thread; +}; + +} // namespace clipboardxx diff --git a/src/test-utils/ClipboardXX/include/detail/linux/x11_provider.hpp b/src/test-utils/ClipboardXX/include/detail/linux/x11_provider.hpp new file mode 100644 index 00000000000..ebc9da4d0c1 --- /dev/null +++ b/src/test-utils/ClipboardXX/include/detail/linux/x11_provider.hpp @@ -0,0 +1,33 @@ +#pragma once + +#include "../exception.hpp" +#include "provider.hpp" +#include "x11_event_handler.hpp" +#include "xcb/xcb.hpp" + +#include + +namespace clipboardxx { + +constexpr const char* kClipboardAtomName = "CLIPBOARD"; + +class X11Provider : public LinuxClipboardProvider { +public: + X11Provider() + : m_xcb(std::make_shared()), m_clipboard_atom(m_xcb->create_atom(kClipboardAtomName)), + m_event_handler(X11EventHandler(m_xcb)) {} + + void copy(const std::string &text) override { + m_xcb->become_selection_owner(m_clipboard_atom); + m_event_handler.set_copy_data(text); + } + + std::string paste() override { return m_event_handler.get_paste_data(); } + +private: + const std::shared_ptr m_xcb; + const xcb::Xcb::Atom m_clipboard_atom; + X11EventHandler m_event_handler; +}; + +} // namespace clipboardxx diff --git a/src/test-utils/ClipboardXX/include/detail/linux/xcb/xcb.hpp b/src/test-utils/ClipboardXX/include/detail/linux/xcb/xcb.hpp new file mode 100644 index 00000000000..a44bfb8a64f --- /dev/null +++ b/src/test-utils/ClipboardXX/include/detail/linux/xcb/xcb.hpp @@ -0,0 +1,177 @@ +#pragma once + +#include "../../exception.hpp" +#include "xcb_event.hpp" + +#include +#include +#include +#include + +namespace clipboardxx { +namespace xcb { + +constexpr uint8_t kBitsPerByte = 8; +constexpr uint8_t kFilterXcbEventType = 0x80; + +class Xcb { +public: + using Atom = xcb_atom_t; + using Window = xcb_window_t; + + class XcbException : public exception { + public: + XcbException(const std::string &reason, int32_t error_code) + : exception(reason + " (" + std::to_string(error_code) + ")"){}; + }; + + Xcb() : m_conn(create_connection()), m_window(create_window(m_conn.get())) {} + + Atom create_atom(const std::string &name) { + xcb_intern_atom_cookie_t cookie = xcb_intern_atom(m_conn.get(), false, name.size(), name.c_str()); + + xcb_generic_error_t* error = nullptr; + std::unique_ptr reply(xcb_intern_atom_reply(m_conn.get(), cookie, &error)); + handle_generic_error(error, "Cannot create atom with name '" + name + "'"); + + return reply->atom; + } + + void become_selection_owner(Atom selection) { + xcb_void_cookie_t cookie = xcb_set_selection_owner_checked(m_conn.get(), m_window, selection, XCB_CURRENT_TIME); + handle_generic_error(xcb_request_check(m_conn.get(), cookie), "Cannot become owner of clipboard selection"); + xcb_flush(m_conn.get()); + } + + std::optional> get_latest_event() { + std::unique_ptr event(xcb_poll_for_event(m_conn.get())); + + // TODO: find a workaround for this + assert(m_conn != nullptr); + + if (!event) + return std::nullopt; + return convert_generic_event_to_event(std::move(event)); + } + + template + void write_on_window_property(Window window, Atom property, Atom target, const Container &data) { + xcb_change_property(m_conn.get(), XCB_PROP_MODE_REPLACE, window, property, target, + sizeof(ValueType) * kBitsPerByte, data.size(), data.data()); + xcb_flush(m_conn.get()); + } + + void notify_window_property_change(Window window, Atom property, Atom target, Atom selection) { + const xcb_selection_notify_event_t event{.response_type = XCB_SELECTION_NOTIFY, + .pad0 = 0, + .sequence = 0, + .time = XCB_CURRENT_TIME, + .requestor = window, + .selection = selection, + .target = target, + .property = property}; + + xcb_send_event(m_conn.get(), false, window, XCB_EVENT_MASK_PROPERTY_CHANGE, + reinterpret_cast(&event)); + xcb_flush(m_conn.get()); + } + + void request_selection_data(Atom selection, Atom target, Atom result) { + xcb_convert_selection_checked(m_conn.get(), m_window, selection, target, result, XCB_CURRENT_TIME); + xcb_flush(m_conn.get()); + } + + std::string get_our_property_value(Atom property) { + xcb_get_property_cookie_t cookie = + xcb_get_property(m_conn.get(), static_cast(true), m_window, property, XCB_ATOM_ANY, 0, -1); + + xcb_generic_error_t* error = nullptr; + std::unique_ptr reply(xcb_get_property_reply(m_conn.get(), cookie, &error)); + std::unique_ptr error_ptr(error); + if (error != nullptr) + return std::string(""); + + const char* data = reinterpret_cast(xcb_get_property_value(reply.get())); + uint32_t length = xcb_get_property_value_length(reply.get()); + return std::string(data, length); + } + +private: + class XcbConnectionDeleter { + public: + void operator()(xcb_connection_t* conn) { xcb_disconnect(conn); } + }; + + using XcbConnectionPtr = std::unique_ptr; + + XcbConnectionPtr create_connection() const { + XcbConnectionPtr connection(xcb_connect(nullptr, nullptr)); + int32_t error = xcb_connection_has_error(connection.get()); + if (error > 0) + throw XcbException("Cannot connect to X server", error); + + return connection; + } + + xcb_window_t create_window(xcb_connection_t* conn) const { + xcb_screen_t* screen = get_root_screen(conn); + xcb_window_t window = xcb_generate_id(conn); + + uint32_t mask_value = XCB_EVENT_MASK_PROPERTY_CHANGE; + xcb_void_cookie_t cookie = xcb_create_window_checked(conn, XCB_COPY_FROM_PARENT, window, screen->root, 0, 0, 1, + 1, 0, XCB_WINDOW_CLASS_COPY_FROM_PARENT, + screen->root_visual, XCB_CW_EVENT_MASK, &mask_value); + handle_generic_error(xcb_request_check(conn, cookie), "Cannot create window"); + + return window; + } + + xcb_screen_t* get_root_screen(xcb_connection_t* conn) const { + const xcb_setup_t* setup_info = xcb_get_setup(conn); + xcb_screen_iterator_t screens = xcb_setup_roots_iterator(setup_info); + return screens.data; + } + + void handle_generic_error(xcb_generic_error_t* error, const std::string &error_msg) const { + std::unique_ptr error_ptr(error); + if (error_ptr) + throw XcbException(error_msg, error_ptr->error_code); + } + + std::unique_ptr convert_generic_event_to_event(std::unique_ptr event) { + uint8_t event_type = event->response_type & ~kFilterXcbEventType; + switch (event_type) { + // someone requested clipboard data + case XCB_SELECTION_REQUEST: { + xcb_selection_request_event_t* sel_request_event = + reinterpret_cast(event.get()); + return std::make_unique(sel_request_event->requestor, sel_request_event->owner, + sel_request_event->selection, sel_request_event->target, + sel_request_event->property); + } + + // we are no longer owner of clipboard + case XCB_SELECTION_CLEAR: { + xcb_selection_clear_event_t* sel_clear_event = reinterpret_cast(event.get()); + return std::make_unique(sel_clear_event->selection); + } + + // our selection has been changed + case XCB_SELECTION_NOTIFY: { + xcb_selection_notify_event_t* sel_notify_event = + reinterpret_cast(event.get()); + return std::make_unique(sel_notify_event->requestor, sel_notify_event->selection, + sel_notify_event->target, sel_notify_event->property); + } + + default: + return std::make_unique(Event::Type::kNone); + } + } + + const XcbConnectionPtr m_conn; + const xcb_window_t m_window; +}; + +} // namespace xcb +} // namespace clipboardxx diff --git a/src/test-utils/ClipboardXX/include/detail/linux/xcb/xcb_event.hpp b/src/test-utils/ClipboardXX/include/detail/linux/xcb/xcb_event.hpp new file mode 100644 index 00000000000..694b234d71b --- /dev/null +++ b/src/test-utils/ClipboardXX/include/detail/linux/xcb/xcb_event.hpp @@ -0,0 +1,51 @@ +#pragma once + +#include + +namespace clipboardxx { +namespace xcb { + +using Atom = xcb_atom_t; +using Window = xcb_window_t; + +class Event { +public: + enum Type { kNone = 0, kRequestSelection, kSelectionClear, kSelectionNotify }; + + Event(Type type) : m_type(type) {} + + Type get_type() const { return m_type; } + +private: + Type m_type; +}; + +class RequestSelectionEvent : public Event { +public: + RequestSelectionEvent(Window requestor, Window owner, Atom selection, Atom target, Atom property) + : Event(Type::kRequestSelection), m_requestor(requestor), m_owner(owner), m_selection(selection), + m_target(target), m_property(property) {} + + const Window m_requestor, m_owner; + const Atom m_selection, m_target, m_property; +}; + +class SelectionNotifyEvent : public Event { +public: + SelectionNotifyEvent(Window requestor, Atom selection, Atom target, Atom property) + : Event(Type::kSelectionNotify), m_requestor(requestor), m_selection(selection), m_target(target), + m_property(property) {} + + const Window m_requestor; + const Atom m_selection, m_target, m_property; +}; + +class SelectionClearEvent : public Event { +public: + SelectionClearEvent(Atom selection) : Event(Type::kSelectionClear), m_selection(selection) {} + + const Atom m_selection; +}; + +} // namespace xcb +} // namespace clipboardxx diff --git a/src/test-utils/ClipboardXX/include/detail/windows.hpp b/src/test-utils/ClipboardXX/include/detail/windows.hpp new file mode 100644 index 00000000000..c2f7e3d18ed --- /dev/null +++ b/src/test-utils/ClipboardXX/include/detail/windows.hpp @@ -0,0 +1,110 @@ +#pragma once + +#include "exception.hpp" +#include "interface.hpp" + +#include +#include + +#ifdef WINDOWS + #include + +namespace clipboardxx { + +class ClipboardWindows : public ClipboardInterface { +public: + void copy(const std::string &text) const override { + OpenCloseClipboardRaii clipboard_raii; + + empty_clipboard(); + std::unique_ptr buffer = allocate_memory_with_size(text.size() + 1); + write_string_to_memory_null_terminated(text, buffer.get()); + set_clipboard_data_from_memory(std::move(buffer)); + } + + std::string paste() const noexcept override { + OpenCloseClipboardRaii clipboard_raii; + return get_clipboard_data(); + } + +private: + class OpenCloseClipboardRaii { + public: + OpenCloseClipboardRaii() { + if (!OpenClipboard(0)) + throw WindowsException("Cannot open clipboard"); + } + + ~OpenCloseClipboardRaii() { CloseClipboard(); } + }; + + class WindowsException : public exception { + public: + WindowsException(const std::string &reason) : exception(reason + " (" + get_last_windows_error() + ")"){}; + + private: + std::string get_last_windows_error() const { + DWORD error = GetLastError(); + if (error) { + LPVOID buffer = nullptr; + DWORD buffer_len = FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + nullptr, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), reinterpret_cast(&buffer), 0, nullptr); + + if (buffer_len) { + LPTSTR buffer_char = reinterpret_cast(buffer); + std::string result(buffer_char, buffer_char + buffer_len); + LocalFree(buffer); + return result; + } + } + + return std::string("unknown windows error"); + } + }; + + class WindowsPtrDeleter { + public: + void operator()(char* ptr) { GlobalFree(ptr); } + }; + + void empty_clipboard() const { + BOOL succeed = EmptyClipboard(); + if (!succeed) + throw WindowsException("Cannot empty clipboard"); + } + + std::unique_ptr allocate_memory_with_size(size_t size) const { + std::unique_ptr global( + reinterpret_cast(GlobalAlloc(GMEM_FIXED, sizeof(char) * size))); + if (!global) + throw WindowsException("Cannot allocate memory for copying text"); + + return global; + } + + void write_string_to_memory_null_terminated(const std::string &text, char* memory) const { + std::copy(text.begin(), text.end(), memory); + memory[text.size()] = '\0'; + } + + void set_clipboard_data_from_memory(std::unique_ptr buffer) const { + if (SetClipboardData(CF_TEXT, buffer.get())) { + // from now on the system owns the buffer + buffer.release(); + } else { + throw WindowsException("Cannot set clipboard data"); + } + } + + std::string get_clipboard_data() const { + char* result = reinterpret_cast(GetClipboardData(CF_TEXT)); + if (!result) + return std::string(""); + return std::string(result); + } +}; + +} // namespace clipboardxx + +#endif diff --git a/src/test-utils/stl_to_cpp.cpp b/src/test-utils/stl_to_cpp.cpp new file mode 100644 index 00000000000..a896d47f4c3 --- /dev/null +++ b/src/test-utils/stl_to_cpp.cpp @@ -0,0 +1,60 @@ +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "ClipboardXX/include/clipboardxx.hpp" + +int main(int argc, char const *argv[]) +{ + if (argc != 2) { + std::cout<<"usage: stl_to_cpp \"path/to/stl.stl\"\n"; + return 0; + } + std::string path_str = argv[1]; + if(path_str.front() == '\"' && path_str.back() == '\"') + path_str = path_str.substr(1,path_str.size()-2); + Slic3r::Model model; + bool result = load_stl(path_str.c_str(), &model, "obj"); + if (!result) { + std::cout << "error, can't read '" << path_str << "'\n"; + return 0; + } + clipboardxx::clipboard clipboard; + //TriangleMesh tm2 = TriangleMesh(std::vector{{-5, -5, -0.1}},std::vector{{1,4,3}}); + std::stringstream out_cpp; + int idx_obj = 0; + for (Slic3r::ModelObject* obj : model.objects) { + int idx_vol = 0; + for(Slic3r::ModelVolume *vol : obj->volumes) { + Slic3r::TriangleMesh mesh = vol->mesh(); + Slic3r::sla::IndexedMesh indexed_mesh(mesh); // more user-friendly + out_cpp << "TriangleMesh vol_"<< idx_obj << "_" << idx_vol <<" = TriangleMesh(std::vector{"; + int ptidx= 0; + for(const Slic3r::Vec3f &pt : indexed_mesh.vertices()) + out_cpp << (0==ptidx++?"{":",{") << Slic3r::to_string_nozero(pt.x(), 7) + << ',' << Slic3r::to_string_nozero(pt.y(), 7) + << ',' << Slic3r::to_string_nozero(pt.z(), 7) << '}'; + out_cpp << "},std::vector{"; + ptidx= 0; + for(const Slic3r::Vec3i32 &tri : indexed_mesh.indices()) + out_cpp << (0==ptidx++?"{":",{") << tri(0) << ',' << tri(1) << ',' << tri(2) << '}'; + out_cpp << "});\n"; + + idx_vol++; + } + out_cpp << "\n"; + idx_obj++; + } + + clipboard << out_cpp.str(); + std::cout << out_cpp.str(); + + return 0; +} diff --git a/tests/superslicerlibslic3r/CMakeLists.txt b/tests/superslicerlibslic3r/CMakeLists.txt index 150400ef9fd..63d0f96d2f1 100644 --- a/tests/superslicerlibslic3r/CMakeLists.txt +++ b/tests/superslicerlibslic3r/CMakeLists.txt @@ -1,31 +1,30 @@ get_filename_component(_TEST_NAME ${CMAKE_CURRENT_LIST_DIR} NAME) -add_executable(${_TEST_NAME}_tests - ${_TEST_NAME}_tests.cpp - test_complete_objects.cpp - # test_fill.cpp - # test_flow.cpp - # test_gcodewriter.cpp - # test_geometry.cpp - # test_model.cpp - test_print.cpp - # test_thin.cpp - # test_denserinfill.cpp - # test_extrusion_entity.cpp - # test_skirt_brim.cpp - test_data.hpp - test_data.cpp - # test_clipper_utils.cpp - test_dense_infill.cpp - ) - -target_link_libraries(${_TEST_NAME}_tests test_common libslic3r) -set_property(TARGET ${_TEST_NAME}_tests PROPERTY FOLDER "tests") +function(create_test test_name) + add_executable(${test_name}_test + ${test_name}.cpp + test_data.hpp + test_data.cpp + ) + target_link_libraries(${test_name}_test test_common libslic3r) + set_property(TARGET ${test_name}_test PROPERTY FOLDER "tests") + if (WIN32) + prusaslicer_copy_dlls(${test_name}_test) + endif() + add_test(${test_name}_test ${test_name}_test ${CATCH_EXTRA_ARGS}) +endfunction() -if (WIN32) - prusaslicer_copy_dlls(${_TEST_NAME}_tests) -endif() - -# catch_discover_tests(${_TEST_NAME}_tests TEST_PREFIX "${_TEST_NAME}: ") -add_test(${_TEST_NAME}_tests ${_TEST_NAME}_tests ${CATCH_EXTRA_ARGS}) +create_test(test_complete_objects) +create_test(test_clipper_utils) +create_test(test_dense_infill) +create_test(test_denserinfill) +create_test(test_extrusion_entity) +create_test(test_fill) +create_test(test_flow) +create_test(test_gcodewriter) +create_test(test_geometry) +create_test(test_model) +create_test(test_print) +create_test(test_skirt_brim) +create_test(test_thin) diff --git a/tests/superslicerlibslic3r/test_clipper_utils.cpp b/tests/superslicerlibslic3r/test_clipper_utils.cpp index e30379e4e4e..0af733e2d3f 100644 --- a/tests/superslicerlibslic3r/test_clipper_utils.cpp +++ b/tests/superslicerlibslic3r/test_clipper_utils.cpp @@ -1,4 +1,5 @@ -#include + +#include #include #include @@ -34,7 +35,7 @@ SCENARIO("Various Clipper operations - xs/t/11_clipper.t", "[ClipperUtils]") { } } WHEN("offset2_ex") { - ExPolygons result = Slic3r::offset2_ex(square_with_hole, 5.f, -2.f); + ExPolygons result = Slic3r::offset2_ex({square_with_hole}, 5.f, -2.f); THEN("offset matches") { REQUIRE(result == ExPolygons { { { { 203, 203 }, { 97, 203 }, { 97, 97 }, { 203, 97 } }, @@ -56,7 +57,7 @@ SCENARIO("Various Clipper operations - xs/t/11_clipper.t", "[ClipperUtils]") { } GIVEN("square and hole") { WHEN("diff_ex") { - ExPolygons result = Slic3r::diff_ex({ square }, { hole_in_square }); + ExPolygons result = Slic3r::diff_ex(Polygons{ square }, Polygons{ hole_in_square }); THEN("hole is created") { REQUIRE(result.size() == 1); REQUIRE(square_with_hole.area() == result.front().area()); @@ -64,7 +65,7 @@ SCENARIO("Various Clipper operations - xs/t/11_clipper.t", "[ClipperUtils]") { } } GIVEN("polyline") { - Polyline polyline { { 50, 150 }, { 300, 150 } }; + Slic3r::Polyline polyline { { 50, 150 }, { 300, 150 } }; WHEN("intersection_pl") { Polylines result = Slic3r::intersection_pl({ polyline }, { square, hole_in_square }); THEN("correct number of result lines") { @@ -77,19 +78,19 @@ SCENARIO("Various Clipper operations - xs/t/11_clipper.t", "[ClipperUtils]") { } } WHEN("diff_pl") { - Polylines result = Slic3r::diff_pl({ polyline }, { square, hole_in_square }); + Polylines result = Slic3r::diff_pl(Polylines{ polyline }, Polygons{ square, hole_in_square }); THEN("correct number of result lines") { REQUIRE(result.size() == 3); } // results are in no particular order THEN("the left result line has correct length") { - REQUIRE(std::count_if(result.begin(), result.end(), [](const Polyline &pl) { return pl.length() == 50; }) == 1); + REQUIRE(std::count_if(result.begin(), result.end(), [](const Slic3r::Polyline &pl) { return pl.length() == 50; }) == 1); } THEN("the right result line has correct length") { - REQUIRE(std::count_if(result.begin(), result.end(), [](const Polyline &pl) { return pl.length() == 100; }) == 1); + REQUIRE(std::count_if(result.begin(), result.end(), [](const Slic3r::Polyline &pl) { return pl.length() == 100; }) == 1); } THEN("the central result line has correct length") { - REQUIRE(std::count_if(result.begin(), result.end(), [](const Polyline &pl) { return pl.length() == 20; }) == 1); + REQUIRE(std::count_if(result.begin(), result.end(), [](const Slic3r::Polyline &pl) { return pl.length() == 20; }) == 1); } } } @@ -99,8 +100,11 @@ SCENARIO("Various Clipper operations - xs/t/11_clipper.t", "[ClipperUtils]") { { 74730000, 74730000 }, { 55270000, 74730000 }, { 55270000, 68063296 }, { 44730000, 68063296 }, { 44730000, 74730000 }, { 25270000, 74730000 }, { 25270000, 55270000 }, { 31936670, 55270000 }, { 31936670, 44730000 }, { 25270000, 44730000 }, { 25270000, 25270000 }, { 44730000, 25270000 }, { 44730000, 31936670 } }; Slic3r::Polygon clip { {75200000, 45200000}, {54800000, 45200000}, {54800000, 24800000}, {75200000, 24800000} }; - Slic3r::Polylines result = Slic3r::intersection_pl({ subject }, { clip }); + Slic3r::Polylines result = Slic3r::intersection_pl(Polylines{ subject }, clip); THEN("intersection_pl - result is not empty") { + REQUIRE(result.size() == 1); } + result = Slic3r::intersection_pl(subject, Polygons{clip}); + THEN("intersection_pl(2) - result is not empty") { REQUIRE(result.size() == 1); } } @@ -108,22 +112,41 @@ SCENARIO("Various Clipper operations - xs/t/11_clipper.t", "[ClipperUtils]") { Slic3r::Polyline subject { { 1975, 1975 }, { 25, 1975 }, { 25, 25 }, { 1975, 25 }, { 1975, 1975 } }; Slic3r::Polygons clip { { { 2025, 2025 }, { -25, 2025 } , { -25, -25 }, { 2025, -25 } }, { { 525, 525 }, { 525, 1475 }, { 1475, 1475 }, { 1475, 525 } } }; - Slic3r::Polylines result = Slic3r::intersection_pl({ subject }, clip); + Slic3r::Polylines result = Slic3r::intersection_pl(Polylines{ subject }, clip); THEN("intersection_pl - result is not empty") { REQUIRE(result.size() == 1); REQUIRE(result.front().points.size() == 5); } + result = Slic3r::intersection_pl(subject, Polygons{clip}); + THEN("intersection_pl(2) - result is not empty") { + REQUIRE(result.size() == 1); + REQUIRE(result.front().points.size() == 5); + } } GIVEN("Clipper bug #126") { Slic3r::Polyline subject { { 200000, 19799999 }, { 200000, 200000 }, { 24304692, 200000 }, { 15102879, 17506106 }, { 13883200, 19799999 }, { 200000, 19799999 } }; Slic3r::Polygon clip { { 15257205, 18493894 }, { 14350057, 20200000 }, { -200000, 20200000 }, { -200000, -200000 }, { 25196917, -200000 } }; - Slic3r::Polylines result = Slic3r::intersection_pl({ subject }, { clip }); + Slic3r::Polylines result = Slic3r::intersection_pl(Polylines{ subject }, clip); THEN("intersection_pl - result is not empty") { REQUIRE(result.size() == 1); } THEN("intersection_pl - result has same length as subject polyline") { REQUIRE(result.front().length() == Approx(subject.length())); } + result = Slic3r::intersection_pl(subject, Polygons{clip}); + THEN("intersection_pl(2) - result is not empty") { + REQUIRE(result.size() == 1); + } + THEN("intersection_pl(2) - result has same length as subject polyline") { + REQUIRE(result.front().length() == Approx(subject.length())); + } + result = Slic3r::intersection_pl(Polylines{subject}, Polygons{clip}); + THEN("intersection_pl(3) - result is not empty") { + REQUIRE(result.size() == 1); + } + THEN("intersection_pl(3) - result has same length as subject polyline") { + REQUIRE(result.front().length() == Approx(subject.length())); + } } #if 0 @@ -180,7 +203,7 @@ SCENARIO("Various Clipper operations - t/clipper.t", "[ClipperUtils]") { // CW oriented contour Slic3r::Polygon hole_in_square { { 14, 14 }, { 14, 16 }, { 16, 16 }, { 16, 14 } }; WHEN("intersection_ex with another square") { - ExPolygons intersection = Slic3r::intersection_ex({ square, hole_in_square }, { square2 }); + ExPolygons intersection = Slic3r::intersection_ex(Polygons{ square, hole_in_square }, Polygons{ square2 }); THEN("intersection area matches (hole is preserved)") { ExPolygon match({ { 20, 18 }, { 10, 18 }, { 10, 12 }, { 20, 12 } }, { { 14, 16 }, { 16, 16 }, { 16, 14 }, { 14, 14 } }); @@ -196,14 +219,14 @@ SCENARIO("Various Clipper operations - t/clipper.t", "[ClipperUtils]") { // CW oriented contour Slic3r::Polygon hole { { 15, 15 }, { 15, 25 }, { 25, 25 }, {25, 15 } }; WHEN("union_ex with another square") { - ExPolygons union_ = Slic3r::union_ex({ square, square2, hole }); + ExPolygons union_ = Slic3r::union_ex(Polygons{ square, square2, hole }); THEN("union of two ccw and one cw is a contour with no holes") { REQUIRE(union_.size() == 1); REQUIRE(union_.front() == ExPolygon { { 40, 40 }, { 0, 40 }, { 0, 0 }, { 40, 0 } } ); } } WHEN("diff_ex with another square") { - ExPolygons diff = Slic3r::diff_ex({ square, square2 }, { hole }); + ExPolygons diff = Slic3r::diff_ex(Polygons{ square, square2 }, Polygons{ hole }); THEN("difference of a cw from two ccw is a contour with one hole") { REQUIRE(diff.size() == 1); REQUIRE(diff.front().area() == Approx(ExPolygon({ {40, 40}, {0, 40}, {0, 0}, {40, 0} }, { {15, 25}, {25, 25}, {25, 15}, {15, 15} }).area())); @@ -244,26 +267,26 @@ size_t count_polys(const ExPolygons& expolys) TEST_CASE("Traversing Clipper PolyTree", "[ClipperUtils]") { // Create a polygon representing unit box - Polygon unitbox; + Slic3r::Polygon unitbox; const int32_t UNIT = int32_t(1. / SCALING_FACTOR); unitbox.points = Points{Point{0, 0}, Point{UNIT, 0}, Point{UNIT, UNIT}, Point{0, UNIT}}; - Polygon box_frame = unitbox; + Slic3r::Polygon box_frame = unitbox; box_frame.scale(20, 10); - Polygon hole_left = unitbox; + Slic3r::Polygon hole_left = unitbox; hole_left.scale(8); hole_left.translate(UNIT, UNIT); hole_left.reverse(); - Polygon hole_right = hole_left; + Slic3r::Polygon hole_right = hole_left; hole_right.translate(UNIT * 10, 0); - Polygon inner_left = unitbox; + Slic3r::Polygon inner_left = unitbox; inner_left.scale(4); inner_left.translate(UNIT * 3, UNIT * 3); - Polygon inner_right = inner_left; + Slic3r::Polygon inner_right = inner_left; inner_right.translate(UNIT * 10, 0); Polygons reference = union_({box_frame, hole_left, hole_right, inner_left, inner_right}); @@ -299,3 +322,90 @@ TEST_CASE("Traversing Clipper PolyTree", "[ClipperUtils]") { REQUIRE(count_polys(output) == reference.size()); } } + +TEST_CASE("Testing ", "[ClipperUtils]") { + Slic3r::Polygon src_polygon( + {{-29766902, -30710288}, {-30290102, -30802646}, {-30799114, -30715083}, {-31876243, -30562718}, + {-33030941, -30449754}, {-33231822, -30436946}, {-34268178, -30384775}, {-34891023, -30367930}, + {-34938429, -30367343}, {-36307009, -30380364}, {-36686920, -30395327}, {-38057500, -30465424}, + {-38066183, -30465841}, {-39121269, -30543247}, {-39144586, -30545052}, {-41393647, -30762768}, + {-41400772, -30763367}, {-42606470, -30898534}, {-43049745, -30951762}, {-43526989, -31152101}, + {-44543970, -31296610}, {-49896253, -32067648}, {-53031149, -32453333}, {-54983432, -32629283}, + {-55876108, -32681239}, {-57207787, -32710144}, {-57287031, -32707371}, {-56999037, -31773098}, + {-57020109, -31574537}, {-57153102, -31460716}, {-59114378, -30732754}, {-59554951, -30452156}, + {-59664101, -30265002}, {-59753496, -29913462}, {-59728476, -29015470}, {-59648533, -27590938}, + {-59696516, -27427759}, {-59871882, -27324947}, {-60861946, -27207800}, {-60553293, -26514064}, + {-60221446, -25827699}, {-59983819, -25377161}, {-59431848, -24334493}, {-58071530, -22002475}, + {-57086298, -20406564}, {-54532068, -16383584}, {-54152045, -16033352}, {-53418323, -14810628}, + {-53037302, -14152026}, {-52585902, -13384179}, {-52093130, -12530959}, {-52089199, -12523696}, + {-51416049, -11301170}, {-51399188, -11269626}, {-50899221, -10293557}, {-50548785, -9599755}, + {-50422361, -9325954}, {-49913114, -8198227}, {-49857361, -8070473}, {-49486084, -7130146}, + {-49262185, -6546354}, {-48814997, -5175926}, {-48666648, -4650820}, {-48416355, -3640670}, + {-48173788, -2389333}, {-48059689, -1542776}, {-47989236, -963142}, {-47988421, -954092}, + {-47908090, 106824}, {-47878053, 573422}, {-47849952, 1687025}, {-47645107, 4755332}, + {-47768143, 5288883}, {-47768047, 5291706}, {-47527604, 7621018}, {-47663943, 7838131}, + {-47525823, 8455742}, {-47689343, 9155509}, {-47795210, 10268834}, {-47978714, 11428999}, + {-48194112, 12344043}, {-48481144, 13309478}, {-48642179, 13794190}, {-48842780, 14334161}, + {-49197836, 15187901}, {-49588991, 16033320}, {-49853153, 16562549}, {-50513053, 17792804}, + {-50882667, 18419696}, {-51438514, 19339116}, {-51718684, 19773192}, {-52179489, 20475205}, + {-52491489, 20942905}, {-52496021, 20949622}, {-53290936, 22086329}, {-53752870, 22724706}, + {-54177967, 23303509}, {-54181286, 23308060}, {-55141698, 24578760}, {-55144467, 24582493}, + {-55936527, 25607586}, {-56390354, 26180675}, {-56401601, 26194795}, {-57375148, 27425084}, + {-57796140, 27725621}, {-58510273, 28592781}, {-65026204, 36326237}, {-66321141, 37899688}, + {-67553055, 39431322}, {-68707652, 40912081}, {-69414421, 41847539}, {-70373648, 43171709}, + {-70802160, 43801970}, {-69626708, 44423826}, {-69500832, 44580612}, {-69517438, 44759180}, + {-70402232, 46571248}, {-70631353, 47139129}, {-70790322, 47645204}, {-70880079, 48170004}, + {-70836022, 48432201}, {-70393757, 48597581}, {-69696951, 48717065}, {-69166672, 48746854}, + {-66168401, 48719007}, {-66004571, 48777066}, {-65913199, 48953792}, {-65819709, 50214929}, + {-64567977, 49966674}, {-63318168, 49705469}, {-60009943, 48909169}, {-56515788, 47981280}, + {-54126539, 47316536}, {-46386391, 45110400}, {-43369296, 44277479}, {-40263700, 43467720}, + {-39395835, 43264181}, {-37625205, 42849082}, {-37483166, 42819432}, {-36253801, 42563516}, + {-35674412, 42454458}, {-35515136, 42424491}, {-35048870, 42199191}, {-34862709, 42168781}, + {-33252621, 41926411}, {-32502942, 41835599}, {-31999592, 41778303}, {-31076021, 41691629}, + {-30193707, 41636746}, {-29260187, 41590640}, {-29176144, 41589180}, {-28142088, 41581326}, + {-27548623, 41596261}, {-26950500, 41621514}, {-26907420, 41624187}, {-27296983, 41112633}, + {-27381326, 40996047}, {-27989012, 40963451}, {-28138692, 40959253}, {-29172601, 40940110}, + {-30216723, 40958086}, {-30968347, 40990968}, {-32059596, 41069576}, {-32574047, 41111839}, + {-33323922, 41188523}, {-33355502, 41192102}, {-34970203, 41401547}, {-35176124, 41432378}, + {-35690171, 41369764}, {-36438808, 41490323}, {-37698617, 41699347}, {-39653744, 42065692}, + {-43800396, 42915182}, {-45342457, 43261526}, {-45348345, 43262775}, {-50568599, 44305692}, + {-50574460, 44306791}, {-53615613, 44840310}, {-53623507, 44841566}, {-55534335, 45114997}, + {-56455716, 45222015}, {-56990415, 45265339}, {-58176151, 45361070}, {-58988986, 45390201}, + {-59754351, 45388396}, {-60364211, 45358767}, {-61360217, 45251837}, {-62159687, 45076387}, + {-62794134, 44850846}, {-63424043, 44497175}, {-63912607, 44054027}, {-64275381, 43487793}, + {-64498459, 42717071}, {-64535148, 42192268}, {-64471205, 41405650}, {-64314543, 40690545}, + {-64120100, 40058090}, {-63874462, 39404122}, {-63581000, 38726318}, {-63242248, 38023061}, + {-63048962, 37665614}, {-62451850, 36563209}, {-61998277, 35793781}, {-61994661, 35787838}, + {-61010738, 34219433}, {-61006329, 34212647}, {-59353428, 31755703}, {-58915997, 31155400}, + {-58904968, 31139811}, {-58173450, 30074020}, {-57605465, 29308774}, {-57267309, 28853350}, + {-56935597, 28379741}, {-56758677, 27893678}, {-55833774, 26626414}, {-55384145, 26031982}, + {-55378724, 26024436}, {-54620031, 24974408}, {-54614601, 24966864}, {-53686336, 23672495}, + {-53263954, 23077836}, {-52819950, 22424397}, {-52812898, 22413958}, {-52039562, 21262463}, + {-51720551, 20779964}, {-51268827, 20062375}, {-51004463, 19621601}, {-50993923, 19603829}, + {-50450501, 18677012}, {-50134549, 18108099}, {-49637035, 17140780}, {-49202252, 16226805}, + {-48915776, 15586329}, {-48502177, 14536860}, {-48293881, 13926867}, {-48131171, 13424218}, + {-47957911, 12802996}, {-47710562, 11741154}, {-47547264, 10744476}, {-47411827, 9350391}, + {-47399989, 9163312}, {-47526019, 8468044}, {-47381692, 7839505}, {-47527604, 7621018}, + {-47487457, 5279674}, {-47644915, 4762661}, {-47645107, 4755332}, {-47560209, 1681367}, + {-47560253, 1679345}, {-47591199, 565817}, {-47610875, 84616}, {-47689099, -976457}, + {-47742308, -1576171}, {-47842045, -2389891}, {-47996471, -3333559}, {-48219314, -4396851}, + {-48438557, -5270192}, {-48712153, -6237043}, {-49060161, -7284025}, {-49063021, -7292452}, + {-49415948, -8239818}, {-49473812, -8389762}, {-49953551, -9530354}, {-50412680, -10529202}, + {-50415227, -10534771}, {-50893546, -11521628}, {-50916067, -11567425}, {-51554754, -12808303}, + {-52019235, -13695926}, {-52446210, -14467999}, {-52801876, -15142704}, {-52808818, -15155800}, + {-53480037, -16413921}, {-53584936, -16919960}, {-53843700, -17435906}, {-53846126, -17440877}, + {-54868733, -19595920}, {-54872166, -19603470}, {-55326937, -20648845}, {-55543581, -21190124}, + {-55680915, -21533885}, {-56036127, -22524045}, {-56325917, -23486648}, {-56536000, -24407114}, + {-56625601, -25224967}, {-56678029, -25738177}, {-56653328, -26373647}, {-56547823, -26988562}, + {-56342934, -27593803}, {-56040970, -28128453}, {-55803719, -28427693}, {-55381973, -28822864}, + {-54839359, -29182948}, {-54386222, -29398844}, {-53567537, -29700868}, {-52853584, -29879786}, + {-52093673, -30015999}, {-51292005, -30115523}, {-50452932, -30183406}, {-49578991, -30224183}, + {-49569346, -30224448}, {-47759328, -30239656}, {-47749986, -30239561}, {-45372177, -30171922}, + {-44666915, -30125409}, {-43916922, -30103842}, {-43639264, -30083267}, {-43130808, -30180062}, + {-42674180, -30139307}, {-41463591, -30058983}, {-41449327, -30058073}, {-39193983, -29919875}, + {-39155994, -29917901}, {-38098825, -29878010}, {-38081454, -29877418}, {-36709714, -29835798}, + {-36306241, -29836742}, {-34937704, -29853628}, {-34254369, -29892783}, {-34238932, -29893784}, + {-33203711, -29965009}, {-32164627, -30082538}, {-31146078, -30236999}, {-30227180, -30411554}, + {-29766902, -30710288}}); + +} diff --git a/tests/superslicerlibslic3r/test_complete_objects.cpp b/tests/superslicerlibslic3r/test_complete_objects.cpp index 5ff5bd7d45c..85d7d364355 100644 --- a/tests/superslicerlibslic3r/test_complete_objects.cpp +++ b/tests/superslicerlibslic3r/test_complete_objects.cpp @@ -1,7 +1,6 @@ -#define CATCH_CONFIG_DISABLE -#include -//#include +//#define CATCH_CONFIG_DISABLE +#include #include #include "test_data.hpp" @@ -38,7 +37,7 @@ std::unique_ptr init_print_with_dist(DynamicPrintConfig &config, float di if (distance <= 0) { print->apply(model, config); - arrange_objects(model, InfiniteBed{}, ArrangeParams{ scaled(/*min_object_distance(config)) });/*/ PrintConfig::min_object_distance(&print->config(), 999999)) }); + arrange_objects(model, InfiniteBed{}, ArrangeParams{ scale_t(10)/*min_object_distance(config)) }); PrintConfig::min_object_distance(&print->config(), 999999))/*/ }); model.center_instances_around_point(Slic3r::Vec2d(100, 100)); } @@ -51,15 +50,16 @@ std::unique_ptr init_print_with_dist(DynamicPrintConfig &config, float di SCENARIO("Complete objects separatly") { GIVEN("20mm cubes and extruder_clearance_radius to 10") { + ConfigSubstitutionContext subst(ForwardCompatibilitySubstitutionRule::Disable); DynamicPrintConfig& config = Slic3r::DynamicPrintConfig::full_print_config(); config.set_key_value("fill_density", new ConfigOptionPercent(0)); - config.set_deserialize("nozzle_diameter", "0.4"); - config.set_deserialize("layer_height", "0.3"); - config.set_deserialize("extruder_clearance_height", "50"); - config.set_deserialize("extruder_clearance_radius", "10"); - config.set_deserialize("skirts", "0"); - config.set_deserialize("skirt_height", "0"); - config.set_deserialize("brim_width", "0"); + config.set_deserialize("nozzle_diameter", "0.4", subst); + config.set_deserialize("layer_height", "0.3", subst); + config.set_deserialize("extruder_clearance_height", "50", subst); + config.set_deserialize("extruder_clearance_radius", "10", subst); + config.set_deserialize("skirts", "0", subst); + config.set_deserialize("skirt_height", "0", subst); + config.set_deserialize("brim_width", "0", subst); std::pair result; @@ -93,7 +93,7 @@ SCENARIO("Complete objects separatly") { } WHEN("with a 10 mm brim, so the dist should be 40mm ") { config.set_key_value("complete_objects", new ConfigOptionBool(true)); - config.set_deserialize("brim_width", "10"); + config.set_deserialize("brim_width", "10", subst); THEN("(too near)") { result = init_print_with_dist(config, 39.9)->validate(); REQUIRE(result.first == PrintBase::PrintValidationError::pveWrongPosition); @@ -106,10 +106,10 @@ SCENARIO("Complete objects separatly") { } WHEN("with a 10 mm dist short skirt, so the dist should be 40mm +extrusionwidth") { config.set_key_value("complete_objects", new ConfigOptionBool(true)); - config.set_deserialize("skirts", "1"); - config.set_deserialize("skirt_height", "1"); - config.set_deserialize("skirt_distance", "10"); - config.set_deserialize("complete_objects_one_skirt", "0"); + config.set_deserialize("skirts", "1", subst); + config.set_deserialize("skirt_height", "1", subst); + config.set_deserialize("skirt_distance", "10", subst); + config.set_deserialize("complete_objects_one_skirt", "0", subst); THEN("(too near)") { result = init_print_with_dist(config, 40)->validate(); @@ -125,15 +125,16 @@ SCENARIO("Complete objects separatly") { } SCENARIO("Arrange is good enough") { GIVEN("20mm cubes and extruder_clearance_radius to 10") { + ConfigSubstitutionContext subst(ForwardCompatibilitySubstitutionRule::Disable); DynamicPrintConfig& config = Slic3r::DynamicPrintConfig::full_print_config(); config.set_key_value("fill_density", new ConfigOptionPercent(0)); - config.set_deserialize("nozzle_diameter", "0.4"); - config.set_deserialize("layer_height", "0.3"); - config.set_deserialize("extruder_clearance_height", "50"); - config.set_deserialize("extruder_clearance_radius", "10"); - config.set_deserialize("skirts", "0"); - config.set_deserialize("skirt_height", "0"); - config.set_deserialize("brim_width", "0"); + config.set_deserialize("nozzle_diameter", "0.4", subst); + config.set_deserialize("layer_height", "0.3", subst); + config.set_deserialize("extruder_clearance_height", "50", subst); + config.set_deserialize("extruder_clearance_radius", "10", subst); + config.set_deserialize("skirts", "0", subst); + config.set_deserialize("skirt_height", "0", subst); + config.set_deserialize("brim_width", "0", subst); std::pair result; @@ -148,16 +149,16 @@ SCENARIO("Arrange is good enough") { } WHEN("complete objects whith brim") { config.set_key_value("complete_objects", new ConfigOptionBool(true)); - config.set_deserialize("brim_width", "10"); + config.set_deserialize("brim_width", "10", subst); result = init_print_with_dist(config, -1)->validate(); REQUIRE(result.second == ""); } WHEN("complete objects whith skirt") { config.set_key_value("complete_objects", new ConfigOptionBool(true)); - config.set_deserialize("skirts", "1"); - config.set_deserialize("skirt_height", "1"); - config.set_deserialize("skirt_distance", "10"); - config.set_deserialize("complete_objects_one_skirt", "0"); + config.set_deserialize("skirts", "1", subst); + config.set_deserialize("skirt_height", "1", subst); + config.set_deserialize("skirt_distance", "10", subst); + config.set_deserialize("complete_objects_one_skirt", "0", subst); result = init_print_with_dist(config, -1)->validate(); REQUIRE(result.second == ""); } diff --git a/tests/superslicerlibslic3r/test_data.cpp b/tests/superslicerlibslic3r/test_data.cpp index 23a19ffce5a..659249b77cc 100644 --- a/tests/superslicerlibslic3r/test_data.cpp +++ b/tests/superslicerlibslic3r/test_data.cpp @@ -48,106 +48,106 @@ const std::unordered_map mesh_names { TriangleMesh mesh(TestMesh m) { std::vector facets; - std::vector vertices; + std::vector vertices; switch(m) { case TestMesh::cube_with_hole: - vertices = { Vec3d(0,0,0), Vec3d(0,0,10), Vec3d(0,20,0), Vec3d(0,20,10), Vec3d(20,0,0), Vec3d(20,0,10), Vec3d(5,5,0), Vec3d(15,5,0), Vec3d(5,15,0), Vec3d(20,20,0), Vec3d(15,15,0), Vec3d(20,20,10), Vec3d(5,5,10), Vec3d(5,15,10), Vec3d(15,5,10), Vec3d(15,15,10) }; + vertices = { Vec3f(0,0,0), Vec3f(0,0,10), Vec3f(0,20,0), Vec3f(0,20,10), Vec3f(20,0,0), Vec3f(20,0,10), Vec3f(5,5,0), Vec3f(15,5,0), Vec3f(5,15,0), Vec3f(20,20,0), Vec3f(15,15,0), Vec3f(20,20,10), Vec3f(5,5,10), Vec3f(5,15,10), Vec3f(15,5,10), Vec3f(15,15,10) }; facets = std::vector{ Vec3i32(0,1,2), Vec3i32(2,1,3), Vec3i32(1,0,4), Vec3i32(5,1,4), Vec3i32(6,7,4), Vec3i32(8,2,9), Vec3i32(0,2,8), Vec3i32(10,8,9), Vec3i32(0,8,6), Vec3i32(0,6,4), Vec3i32(4,7,9), Vec3i32(7,10,9), Vec3i32(2,3,9), Vec3i32(9,3,11), Vec3i32(12,1,5), Vec3i32(13,3,12), Vec3i32(14,12,5), Vec3i32(3,1,12), Vec3i32(11,3,13), Vec3i32(11,15,5), Vec3i32(11,13,15), Vec3i32(15,14,5), Vec3i32(5,4,9), Vec3i32(11,5,9), Vec3i32(8,13,12), Vec3i32(6,8,12), Vec3i32(10,15,13), Vec3i32(8,10,13), Vec3i32(15,10,14), Vec3i32(14,10,7), Vec3i32(14,7,12), Vec3i32(12,7,6) }; break; case TestMesh::cube_with_concave_hole: - vertices = std::vector{ - Vec3d(-10,-10,-5), Vec3d(-10,-10,5), Vec3d(-10,10,-5), Vec3d(-10,10,5), Vec3d(10,-10,-5), Vec3d(10,-10,5), Vec3d(-5,-5,-5), Vec3d(5,-5,-5), Vec3d(5,5,-5), Vec3d(5,10,-5), Vec3d(-5,5,-5), Vec3d(3.06161699911402e-16,5,-5), Vec3d(5,0,-5), Vec3d(0,0,-5), Vec3d(10,5,-5), Vec3d(5,10,5), Vec3d(-5,-5,5), Vec3d(5,0,5), Vec3d(5,-5,5), Vec3d(-5,5,5), Vec3d(10,5,5), Vec3d(5,5,5), Vec3d(3.06161699911402e-16,5,5), Vec3d(0,0,5) + vertices = std::vector{ + Vec3f(-10,-10,-5), Vec3f(-10,-10,5), Vec3f(-10,10,-5), Vec3f(-10,10,5), Vec3f(10,-10,-5), Vec3f(10,-10,5), Vec3f(-5,-5,-5), Vec3f(5,-5,-5), Vec3f(5,5,-5), Vec3f(5,10,-5), Vec3f(-5,5,-5), Vec3f(0,5,-5), Vec3f(5,0,-5), Vec3f(0,0,-5), Vec3f(10,5,-5), Vec3f(5,10,5), Vec3f(-5,-5,5), Vec3f(5,0,5), Vec3f(5,-5,5), Vec3f(-5,5,5), Vec3f(10,5,5), Vec3f(5,5,5), Vec3f(0,5,5), Vec3f(0,0,5) }; facets = std::vector{ Vec3i32(0,1,2), Vec3i32(2,1,3), Vec3i32(1,0,4), Vec3i32(5,1,4), Vec3i32(6,7,4), Vec3i32(8,2,9), Vec3i32(10,2,11), Vec3i32(11,12,13), Vec3i32(0,2,10), Vec3i32(0,10,6), Vec3i32(0,6,4), Vec3i32(11,2,8), Vec3i32(4,7,12), Vec3i32(4,12,8), Vec3i32(12,11,8), Vec3i32(14,4,8), Vec3i32(2,3,9), Vec3i32(9,3,15), Vec3i32(16,1,5), Vec3i32(17,18,5), Vec3i32(19,3,16), Vec3i32(20,21,5), Vec3i32(18,16,5), Vec3i32(3,1,16), Vec3i32(22,3,19), Vec3i32(21,3,22), Vec3i32(21,17,5), Vec3i32(21,22,17), Vec3i32(21,15,3), Vec3i32(23,17,22), Vec3i32(5,4,14), Vec3i32(20,5,14), Vec3i32(20,14,21), Vec3i32(21,14,8), Vec3i32(9,15,21), Vec3i32(8,9,21), Vec3i32(10,19,16), Vec3i32(6,10,16), Vec3i32(11,22,19), Vec3i32(10,11,19), Vec3i32(13,23,11), Vec3i32(11,23,22), Vec3i32(23,13,12), Vec3i32(17,23,12), Vec3i32(17,12,18), Vec3i32(18,12,7), Vec3i32(18,7,16), Vec3i32(16,7,6) }; break; case TestMesh::V: - vertices = std::vector{ - Vec3d(-14,0,20), Vec3d(-14,15,20), Vec3d(0,0,0), Vec3d(0,15,0), Vec3d(-4,0,20), Vec3d(-4,15,20), Vec3d(5,0,7.14286), Vec3d(10,0,0), Vec3d(24,0,20), Vec3d(14,0,20), Vec3d(10,15,0), Vec3d(5,15,7.14286), Vec3d(14,15,20), Vec3d(24,15,20) + vertices = std::vector{ + Vec3f(-14,0,20), Vec3f(-14,15,20), Vec3f(0,0,0), Vec3f(0,15,0), Vec3f(-4,0,20), Vec3f(-4,15,20), Vec3f(5,0,7.14286), Vec3f(10,0,0), Vec3f(24,0,20), Vec3f(14,0,20), Vec3f(10,15,0), Vec3f(5,15,7.14286f), Vec3f(14,15,20), Vec3f(24,15,20) }; facets = std::vector{ Vec3i32(0,1,2), Vec3i32(2,1,3), Vec3i32(1,0,4), Vec3i32(5,1,4), Vec3i32(4,0,2), Vec3i32(6,4,2), Vec3i32(7,6,2), Vec3i32(8,9,7), Vec3i32(9,6,7), Vec3i32(2,3,7), Vec3i32(7,3,10), Vec3i32(1,5,3), Vec3i32(3,5,11), Vec3i32(11,12,13), Vec3i32(11,13,3), Vec3i32(3,13,10), Vec3i32(5,4,6), Vec3i32(11,5,6), Vec3i32(6,9,11), Vec3i32(11,9,12), Vec3i32(12,9,8), Vec3i32(13,12,8), Vec3i32(8,7,10), Vec3i32(13,8,10) }; break; case TestMesh::L: - vertices = std::vector{ - Vec3d(0,10,0), Vec3d(0,10,10), Vec3d(0,20,0), Vec3d(0,20,10), Vec3d(10,10,0), Vec3d(10,10,10), Vec3d(20,20,0), Vec3d(20,0,0), Vec3d(10,0,0), Vec3d(20,20,10), Vec3d(10,0,10), Vec3d(20,0,10) + vertices = std::vector{ + Vec3f(0,10,0), Vec3f(0,10,10), Vec3f(0,20,0), Vec3f(0,20,10), Vec3f(10,10,0), Vec3f(10,10,10), Vec3f(20,20,0), Vec3f(20,0,0), Vec3f(10,0,0), Vec3f(20,20,10), Vec3f(10,0,10), Vec3f(20,0,10) }; facets = std::vector{ Vec3i32(0,1,2), Vec3i32(2,1,3), Vec3i32(4,5,1), Vec3i32(0,4,1), Vec3i32(0,2,4), Vec3i32(4,2,6), Vec3i32(4,6,7), Vec3i32(4,7,8), Vec3i32(2,3,6), Vec3i32(6,3,9), Vec3i32(3,1,5), Vec3i32(9,3,5), Vec3i32(10,11,5), Vec3i32(11,9,5), Vec3i32(5,4,10), Vec3i32(10,4,8), Vec3i32(10,8,7), Vec3i32(11,10,7), Vec3i32(11,7,6), Vec3i32(9,11,6) }; break; case TestMesh::overhang: - vertices = std::vector{ - Vec3d(1364.68505859375,614.398010253906,20.002498626709), Vec3d(1389.68505859375,614.398010253906,20.002498626709), Vec3d(1377.18505859375,589.398986816406,20.002498626709), Vec3d(1389.68505859375,589.398986816406,20.002498626709), Vec3d(1389.68505859375,564.398986816406,20.0014991760254), Vec3d(1364.68505859375,589.398986816406,20.002498626709), Vec3d(1364.68505859375,564.398986816406,20.0014991760254), Vec3d(1360.93505859375,589.398986816406,17.0014991760254), Vec3d(1360.93505859375,585.64697265625,17.0014991760254), Vec3d(1357.18505859375,564.398986816406,17.0014991760254), Vec3d(1364.68505859375,589.398986816406,17.0014991760254), Vec3d(1364.68505859375,571.899963378906,17.0014991760254), Vec3d(1364.68505859375,564.398986816406,17.0014991760254), Vec3d(1348.43603515625,564.398986816406,17.0014991760254), Vec3d(1352.80908203125,589.398986816406,17.0014991760254), Vec3d(1357.18408203125,589.398986816406,17.0014991760254), Vec3d(1357.18310546875,614.398010253906,17.0014991760254), Vec3d(1364.68505859375,606.89599609375,17.0014991760254), Vec3d(1364.68505859375,614.398010253906,17.0014991760254), Vec3d(1352.18603515625,564.398986816406,20.0014991760254), Vec3d(1363.65405273438,589.398986816406,23.3004989624023), Vec3d(1359.46704101562,589.398986816406,23.3004989624023), Vec3d(1358.37109375,564.398986816406,23.3004989624023), Vec3d(1385.56103515625,564.398986816406,23.3004989624023), Vec3d(1373.06311035156,589.398986816406,23.3004989624023), Vec3d(1368.80810546875,564.398986816406,23.3004989624023), Vec3d(1387.623046875,589.398986816406,23.3004989624023), Vec3d(1387.623046875,585.276000976562,23.3004989624023), Vec3d(1389.68505859375,589.398986816406,23.3004989624023), Vec3d(1389.68505859375,572.64599609375,23.3004989624023), Vec3d(1389.68505859375,564.398986816406,23.3004989624023), Vec3d(1367.77709960938,589.398986816406,23.3004989624023), Vec3d(1366.7470703125,564.398986816406,23.3004989624023), Vec3d(1354.31201171875,589.398986816406,23.3004989624023), Vec3d(1352.18603515625,564.398986816406,23.3004989624023), Vec3d(1389.68505859375,614.398010253906,23.3004989624023), Vec3d(1377.31701660156,614.398010253906,23.3004989624023), Vec3d(1381.43908691406,589.398986816406,23.3004989624023), Vec3d(1368.80700683594,614.398010253906,23.3004989624023), Vec3d(1368.80810546875,589.398986816406,23.3004989624023), Vec3d(1356.43908691406,614.398010253906,23.3004989624023), Vec3d(1357.40502929688,589.398986816406,23.3004989624023), Vec3d(1360.56201171875,614.398010253906,23.3004989624023), Vec3d(1348.705078125,614.398010253906,23.3004989624023), Vec3d(1350.44506835938,589.398986816406,23.3004989624023), Vec3d(1389.68505859375,606.153015136719,23.3004989624023), Vec3d(1347.35205078125,589.398986816406,23.3004989624023), Vec3d(1346.56005859375,589.398986816406,23.3004989624023), Vec3d(1346.56005859375,594.159912109375,17.0014991760254), Vec3d(1346.56005859375,589.398986816406,17.0014991760254), Vec3d(1346.56005859375,605.250427246094,23.3004989624023), Vec3d(1346.56005859375,614.398010253906,23.3004989624023), Vec3d(1346.56005859375,614.398010253906,20.8258285522461), Vec3d(1346.56005859375,614.398010253906,17.0014991760254), Vec3d(1346.56005859375,564.398986816406,19.10133934021), Vec3d(1346.56005859375,567.548583984375,23.3004989624023), Vec3d(1346.56005859375,564.398986816406,17.0020332336426), Vec3d(1346.56005859375,564.398986816406,23.0018501281738), Vec3d(1346.56005859375,564.398986816406,23.3004989624023), Vec3d(1346.56005859375,575.118957519531,17.0014991760254), Vec3d(1346.56005859375,574.754028320312,23.3004989624023) + vertices = std::vector{ + Vec3f(1364.68505859375,614.398010253906,20.002498626709), Vec3f(1389.68505859375,614.398010253906,20.002498626709), Vec3f(1377.18505859375,589.398986816406,20.002498626709), Vec3f(1389.68505859375,589.398986816406,20.002498626709), Vec3f(1389.68505859375,564.398986816406,20.0014991760254), Vec3f(1364.68505859375,589.398986816406,20.002498626709), Vec3f(1364.68505859375,564.398986816406,20.0014991760254), Vec3f(1360.93505859375,589.398986816406,17.0014991760254), Vec3f(1360.93505859375,585.64697265625,17.0014991760254), Vec3f(1357.18505859375,564.398986816406,17.0014991760254), Vec3f(1364.68505859375,589.398986816406,17.0014991760254), Vec3f(1364.68505859375,571.899963378906,17.0014991760254), Vec3f(1364.68505859375,564.398986816406,17.0014991760254), Vec3f(1348.43603515625,564.398986816406,17.0014991760254), Vec3f(1352.80908203125,589.398986816406,17.0014991760254), Vec3f(1357.18408203125,589.398986816406,17.0014991760254), Vec3f(1357.18310546875,614.398010253906,17.0014991760254), Vec3f(1364.68505859375,606.89599609375,17.0014991760254), Vec3f(1364.68505859375,614.398010253906,17.0014991760254), Vec3f(1352.18603515625,564.398986816406,20.0014991760254), Vec3f(1363.65405273438,589.398986816406,23.3004989624023), Vec3f(1359.46704101562,589.398986816406,23.3004989624023), Vec3f(1358.37109375,564.398986816406,23.3004989624023), Vec3f(1385.56103515625,564.398986816406,23.3004989624023), Vec3f(1373.06311035156,589.398986816406,23.3004989624023), Vec3f(1368.80810546875,564.398986816406,23.3004989624023), Vec3f(1387.623046875,589.398986816406,23.3004989624023), Vec3f(1387.623046875,585.276000976562,23.3004989624023), Vec3f(1389.68505859375,589.398986816406,23.3004989624023), Vec3f(1389.68505859375,572.64599609375,23.3004989624023), Vec3f(1389.68505859375,564.398986816406,23.3004989624023), Vec3f(1367.77709960938,589.398986816406,23.3004989624023), Vec3f(1366.7470703125,564.398986816406,23.3004989624023), Vec3f(1354.31201171875,589.398986816406,23.3004989624023), Vec3f(1352.18603515625,564.398986816406,23.3004989624023), Vec3f(1389.68505859375,614.398010253906,23.3004989624023), Vec3f(1377.31701660156,614.398010253906,23.3004989624023), Vec3f(1381.43908691406,589.398986816406,23.3004989624023), Vec3f(1368.80700683594,614.398010253906,23.3004989624023), Vec3f(1368.80810546875,589.398986816406,23.3004989624023), Vec3f(1356.43908691406,614.398010253906,23.3004989624023), Vec3f(1357.40502929688,589.398986816406,23.3004989624023), Vec3f(1360.56201171875,614.398010253906,23.3004989624023), Vec3f(1348.705078125,614.398010253906,23.3004989624023), Vec3f(1350.44506835938,589.398986816406,23.3004989624023), Vec3f(1389.68505859375,606.153015136719,23.3004989624023), Vec3f(1347.35205078125,589.398986816406,23.3004989624023), Vec3f(1346.56005859375,589.398986816406,23.3004989624023), Vec3f(1346.56005859375,594.159912109375,17.0014991760254), Vec3f(1346.56005859375,589.398986816406,17.0014991760254), Vec3f(1346.56005859375,605.250427246094,23.3004989624023), Vec3f(1346.56005859375,614.398010253906,23.3004989624023), Vec3f(1346.56005859375,614.398010253906,20.8258285522461), Vec3f(1346.56005859375,614.398010253906,17.0014991760254), Vec3f(1346.56005859375,564.398986816406,19.10133934021), Vec3f(1346.56005859375,567.548583984375,23.3004989624023), Vec3f(1346.56005859375,564.398986816406,17.0020332336426), Vec3f(1346.56005859375,564.398986816406,23.0018501281738), Vec3f(1346.56005859375,564.398986816406,23.3004989624023), Vec3f(1346.56005859375,575.118957519531,17.0014991760254), Vec3f(1346.56005859375,574.754028320312,23.3004989624023) }; facets = std::vector{ Vec3i32(0,1,2), Vec3i32(2,3,4), Vec3i32(2,5,0), Vec3i32(4,6,2), Vec3i32(2,6,5), Vec3i32(2,1,3), Vec3i32(7,8,9), Vec3i32(10,9,8), Vec3i32(11,9,10), Vec3i32(12,9,11), Vec3i32(9,13,14), Vec3i32(7,15,16), Vec3i32(10,17,0), Vec3i32(10,0,5), Vec3i32(12,11,6), Vec3i32(18,16,0), Vec3i32(6,19,13), Vec3i32(6,13,9), Vec3i32(9,12,6), Vec3i32(17,18,0), Vec3i32(11,10,5), Vec3i32(11,5,6), Vec3i32(14,16,15), Vec3i32(17,7,18), Vec3i32(16,18,7), Vec3i32(14,15,9), Vec3i32(7,9,15), Vec3i32(7,17,8), Vec3i32(10,8,17), Vec3i32(20,21,22), Vec3i32(23,24,25), Vec3i32(26,23,27), Vec3i32(28,27,23), Vec3i32(29,28,23), Vec3i32(30,29,23), Vec3i32(25,31,32), Vec3i32(22,33,34), Vec3i32(35,36,37), Vec3i32(24,38,39), Vec3i32(21,40,41), Vec3i32(38,42,20), Vec3i32(33,43,44), Vec3i32(6,4,23), Vec3i32(6,23,25), Vec3i32(36,35,1), Vec3i32(1,0,38), Vec3i32(1,38,36), Vec3i32(29,30,4), Vec3i32(25,32,6), Vec3i32(40,42,0), Vec3i32(35,45,1), Vec3i32(4,3,28), Vec3i32(4,28,29), Vec3i32(3,1,45), Vec3i32(3,45,28), Vec3i32(22,34,19), Vec3i32(19,6,32), Vec3i32(19,32,22), Vec3i32(42,38,0), Vec3i32(30,23,4), Vec3i32(0,16,43), Vec3i32(0,43,40), Vec3i32(24,37,36), Vec3i32(38,24,36), Vec3i32(24,23,37), Vec3i32(37,23,26), Vec3i32(22,32,20), Vec3i32(20,32,31), Vec3i32(33,41,40), Vec3i32(43,33,40), Vec3i32(45,35,26), Vec3i32(37,26,35), Vec3i32(33,44,34), Vec3i32(44,43,46), Vec3i32(20,42,21), Vec3i32(40,21,42), Vec3i32(31,39,38), Vec3i32(20,31,38), Vec3i32(33,22,41), Vec3i32(21,41,22), Vec3i32(31,25,39), Vec3i32(24,39,25), Vec3i32(26,27,45), Vec3i32(28,45,27), Vec3i32(47,48,49), Vec3i32(47,50,48), Vec3i32(51,48,50), Vec3i32(52,48,51), Vec3i32(53,48,52), Vec3i32(54,55,56), Vec3i32(57,55,54), Vec3i32(58,55,57), Vec3i32(49,59,47), Vec3i32(60,56,55), Vec3i32(59,56,60), Vec3i32(60,47,59), Vec3i32(48,53,16), Vec3i32(56,13,19), Vec3i32(54,56,19), Vec3i32(56,59,13), Vec3i32(59,49,14), Vec3i32(59,14,13), Vec3i32(49,48,16), Vec3i32(49,16,14), Vec3i32(44,46,60), Vec3i32(44,60,55), Vec3i32(51,50,43), Vec3i32(19,34,58), Vec3i32(19,58,57), Vec3i32(53,52,16), Vec3i32(43,16,52), Vec3i32(43,52,51), Vec3i32(57,54,19), Vec3i32(47,60,46), Vec3i32(55,58,34), Vec3i32(55,34,44), Vec3i32(50,47,46), Vec3i32(50,46,43) }; break; case TestMesh::_40x10: - vertices = std::vector{ - Vec3d(12.8680295944214,29.5799007415771,12), Vec3d(11.7364797592163,29.8480796813965,12), Vec3d(11.1571502685547,29.5300102233887,12), Vec3d(10.5814504623413,29.9830799102783,12), Vec3d(10,29.6000003814697,12), Vec3d(9.41855144500732,29.9830799102783,12), Vec3d(8.84284687042236,29.5300102233887,12), Vec3d(8.26351833343506,29.8480796813965,12), Vec3d(7.70256900787354,29.3210391998291,12), Vec3d(7.13196802139282,29.5799007415771,12), Vec3d(6.59579277038574,28.9761600494385,12), Vec3d(6.03920221328735,29.1821594238281,12), Vec3d(5.53865718841553,28.5003795623779,12), Vec3d(5,28.6602592468262,12), Vec3d(4.54657793045044,27.9006500244141,12), Vec3d(4.02841377258301,28.0212306976318,12), Vec3d(3.63402199745178,27.1856994628906,12), Vec3d(3.13758301734924,27.2737407684326,12), Vec3d(2.81429696083069,26.3659801483154,12), Vec3d(2.33955597877502,26.4278793334961,12), Vec3d(2.0993549823761,25.4534206390381,12), Vec3d(1.64512205123901,25.4950904846191,12), Vec3d(1.49962198734283,24.4613399505615,12), Vec3d(1.0636739730835,24.4879894256592,12), Vec3d(1.02384400367737,23.4042091369629,12), Vec3d(0.603073298931122,23.4202003479004,12), Vec3d(0.678958415985107,22.2974300384521,12), Vec3d(0.269550800323486,22.3061599731445,12), Vec3d(0.469994693994522,21.1571502685547,12), Vec3d(0.067615881562233,21.1609306335449,12), Vec3d(0.399999290704727,20,12), Vec3d(0,20,12), Vec3d(0.399999290704727,5,12), Vec3d(0,5,12), Vec3d(0.456633001565933,4.2804012298584,12), Vec3d(0.0615576282143593,4.21782684326172,12), Vec3d(0.625140011310577,3.5785219669342,12), Vec3d(0.244717106223106,3.45491504669189,12), Vec3d(0.901369392871857,2.91164398193359,12), Vec3d(0.544967114925385,2.73004698753357,12), Vec3d(1.27852201461792,2.29618692398071,12), Vec3d(0.954914808273315,2.06107401847839,12), Vec3d(1.74730801582336,1.74730801582336,12), Vec3d(1.46446597576141,1.46446597576141,12), Vec3d(2.29618692398071,1.27852201461792,12), Vec3d(2.06107401847839,0.954914808273315,12), Vec3d(2.91164398193359,0.901369392871857,12), Vec3d(2.73004698753357,0.544967114925385,12), Vec3d(3.5785219669342,0.625140011310577,12), Vec3d(3.45491504669189,0.244717106223106,12), Vec3d(4.2804012298584,0.456633001565933,12), Vec3d(4.21782684326172,0.0615576282143593,12), Vec3d(5,0.399999290704727,12), Vec3d(5,0,12), Vec3d(19.6000003814697,0.399999290704727,12), Vec3d(20,0,12), Vec3d(19.6000003814697,20,12), Vec3d(20,20,12), Vec3d(19.5300102233887,21.1571502685547,12), Vec3d(19.9323806762695,21.1609306335449,12), Vec3d(19.3210391998291,22.2974300384521,12), Vec3d(19.7304496765137,22.3061599731445,12), Vec3d(18.9761600494385,23.4042091369629,12), Vec3d(19.3969306945801,23.4202003479004,12), Vec3d(18.5003795623779,24.4613399505615,12), Vec3d(18.9363307952881,24.4879894256592,12), Vec3d(17.9006500244141,25.4534206390381,12), Vec3d(18.3548793792725,25.4950904846191,12), Vec3d(17.1856994628906,26.3659801483154,12), Vec3d(17.6604404449463,26.4278793334961,12), Vec3d(16.3659801483154,27.1856994628906,12), Vec3d(16.862419128418,27.2737407684326,12), Vec3d(15.4534196853638,27.9006500244141,12), Vec3d(15.9715900421143,28.0212306976318,12), Vec3d(14.4613399505615,28.5003795623779,12), Vec3d(15,28.6602592468262,12), Vec3d(13.4042100906372,28.9761600494385,12), Vec3d(13.9608001708984,29.1821594238281,12), Vec3d(12.2974300384521,29.3210391998291,12), Vec3d(7.13196802139282,29.5799007415771,0), Vec3d(8.26351833343506,29.8480796813965,0), Vec3d(8.84284687042236,29.5300102233887,0), Vec3d(9.41855144500732,29.9830799102783,0), Vec3d(10,29.6000003814697,0), Vec3d(10.5814504623413,29.9830799102783,0), Vec3d(11.1571502685547,29.5300102233887,0), Vec3d(11.7364797592163,29.8480796813965,0), Vec3d(12.2974300384521,29.3210391998291,0), Vec3d(12.8680295944214,29.5799007415771,0), Vec3d(13.4042100906372,28.9761600494385,0), Vec3d(13.9608001708984,29.1821594238281,0), Vec3d(14.4613399505615,28.5003795623779,0), Vec3d(15,28.6602592468262,0), Vec3d(15.4534196853638,27.9006500244141,0), Vec3d(15.9715900421143,28.0212306976318,0), Vec3d(16.3659801483154,27.1856994628906,0), Vec3d(16.862419128418,27.2737407684326,0), Vec3d(17.1856994628906,26.3659801483154,0), Vec3d(17.6604404449463,26.4278793334961,0), Vec3d(17.9006500244141,25.4534206390381,0), Vec3d(18.3548793792725,25.4950904846191,0), Vec3d(18.5003795623779,24.4613399505615,0), Vec3d(18.9363307952881,24.4879894256592,0), Vec3d(18.9761600494385,23.4042091369629,0), Vec3d(19.3969306945801,23.4202003479004,0), Vec3d(19.3210391998291,22.2974300384521,0), Vec3d(19.7304496765137,22.3061599731445,0), Vec3d(19.5300102233887,21.1571502685547,0), Vec3d(19.9323806762695,21.1609306335449,0), Vec3d(19.6000003814697,20,0), Vec3d(20,20,0), Vec3d(19.6000003814697,0.399999290704727,0), Vec3d(20,0,0), Vec3d(5,0.399999290704727,0), Vec3d(5,0,0), Vec3d(4.2804012298584,0.456633001565933,0), Vec3d(4.21782684326172,0.0615576282143593,0), Vec3d(3.5785219669342,0.625140011310577,0), Vec3d(3.45491504669189,0.244717106223106,0), Vec3d(2.91164398193359,0.901369392871857,0), Vec3d(2.73004698753357,0.544967114925385,0), Vec3d(2.29618692398071,1.27852201461792,0), Vec3d(2.06107401847839,0.954914808273315,0), Vec3d(1.74730801582336,1.74730801582336,0), Vec3d(1.46446597576141,1.46446597576141,0), Vec3d(1.27852201461792,2.29618692398071,0), Vec3d(0.954914808273315,2.06107401847839,0), Vec3d(0.901369392871857,2.91164398193359,0), Vec3d(0.544967114925385,2.73004698753357,0), Vec3d(0.625140011310577,3.5785219669342,0), Vec3d(0.244717106223106,3.45491504669189,0), Vec3d(0.456633001565933,4.2804012298584,0), Vec3d(0.0615576282143593,4.21782684326172,0), Vec3d(0.399999290704727,5,0), Vec3d(0,5,0), Vec3d(0.399999290704727,20,0), Vec3d(0,20,0), Vec3d(0.469994693994522,21.1571502685547,0), Vec3d(0.067615881562233,21.1609306335449,0), Vec3d(0.678958415985107,22.2974300384521,0), Vec3d(0.269550800323486,22.3061599731445,0), Vec3d(1.02384400367737,23.4042091369629,0), Vec3d(0.603073298931122,23.4202003479004,0), Vec3d(1.49962198734283,24.4613399505615,0), Vec3d(1.0636739730835,24.4879894256592,0), Vec3d(2.0993549823761,25.4534206390381,0), Vec3d(1.64512205123901,25.4950904846191,0), Vec3d(2.81429696083069,26.3659801483154,0), Vec3d(2.33955597877502,26.4278793334961,0), Vec3d(3.63402199745178,27.1856994628906,0), Vec3d(3.13758301734924,27.2737407684326,0), Vec3d(4.54657793045044,27.9006500244141,0), Vec3d(4.02841377258301,28.0212306976318,0), Vec3d(5.53865718841553,28.5003795623779,0), Vec3d(5,28.6602592468262,0), Vec3d(6.59579277038574,28.9761600494385,0), Vec3d(6.03920221328735,29.1821594238281,0), Vec3d(7.70256900787354,29.3210391998291,0) + vertices = std::vector{ + Vec3f(12.8680295944214,29.5799007415771,12), Vec3f(11.7364797592163,29.8480796813965,12), Vec3f(11.1571502685547,29.5300102233887,12), Vec3f(10.5814504623413,29.9830799102783,12), Vec3f(10,29.6000003814697,12), Vec3f(9.41855144500732,29.9830799102783,12), Vec3f(8.84284687042236,29.5300102233887,12), Vec3f(8.26351833343506,29.8480796813965,12), Vec3f(7.70256900787354,29.3210391998291,12), Vec3f(7.13196802139282,29.5799007415771,12), Vec3f(6.59579277038574,28.9761600494385,12), Vec3f(6.03920221328735,29.1821594238281,12), Vec3f(5.53865718841553,28.5003795623779,12), Vec3f(5,28.6602592468262,12), Vec3f(4.54657793045044,27.9006500244141,12), Vec3f(4.02841377258301,28.0212306976318,12), Vec3f(3.63402199745178,27.1856994628906,12), Vec3f(3.13758301734924,27.2737407684326,12), Vec3f(2.81429696083069,26.3659801483154,12), Vec3f(2.33955597877502,26.4278793334961,12), Vec3f(2.0993549823761,25.4534206390381,12), Vec3f(1.64512205123901,25.4950904846191,12), Vec3f(1.49962198734283,24.4613399505615,12), Vec3f(1.0636739730835,24.4879894256592,12), Vec3f(1.02384400367737,23.4042091369629,12), Vec3f(0.603073298931122,23.4202003479004,12), Vec3f(0.678958415985107,22.2974300384521,12), Vec3f(0.269550800323486,22.3061599731445,12), Vec3f(0.469994693994522,21.1571502685547,12), Vec3f(0.067615881562233,21.1609306335449,12), Vec3f(0.399999290704727,20,12), Vec3f(0,20,12), Vec3f(0.399999290704727,5,12), Vec3f(0,5,12), Vec3f(0.456633001565933,4.2804012298584,12), Vec3f(0.0615576282143593,4.21782684326172,12), Vec3f(0.625140011310577,3.5785219669342,12), Vec3f(0.244717106223106,3.45491504669189,12), Vec3f(0.901369392871857,2.91164398193359,12), Vec3f(0.544967114925385,2.73004698753357,12), Vec3f(1.27852201461792,2.29618692398071,12), Vec3f(0.954914808273315,2.06107401847839,12), Vec3f(1.74730801582336,1.74730801582336,12), Vec3f(1.46446597576141,1.46446597576141,12), Vec3f(2.29618692398071,1.27852201461792,12), Vec3f(2.06107401847839,0.954914808273315,12), Vec3f(2.91164398193359,0.901369392871857,12), Vec3f(2.73004698753357,0.544967114925385,12), Vec3f(3.5785219669342,0.625140011310577,12), Vec3f(3.45491504669189,0.244717106223106,12), Vec3f(4.2804012298584,0.456633001565933,12), Vec3f(4.21782684326172,0.0615576282143593,12), Vec3f(5,0.399999290704727,12), Vec3f(5,0,12), Vec3f(19.6000003814697,0.399999290704727,12), Vec3f(20,0,12), Vec3f(19.6000003814697,20,12), Vec3f(20,20,12), Vec3f(19.5300102233887,21.1571502685547,12), Vec3f(19.9323806762695,21.1609306335449,12), Vec3f(19.3210391998291,22.2974300384521,12), Vec3f(19.7304496765137,22.3061599731445,12), Vec3f(18.9761600494385,23.4042091369629,12), Vec3f(19.3969306945801,23.4202003479004,12), Vec3f(18.5003795623779,24.4613399505615,12), Vec3f(18.9363307952881,24.4879894256592,12), Vec3f(17.9006500244141,25.4534206390381,12), Vec3f(18.3548793792725,25.4950904846191,12), Vec3f(17.1856994628906,26.3659801483154,12), Vec3f(17.6604404449463,26.4278793334961,12), Vec3f(16.3659801483154,27.1856994628906,12), Vec3f(16.862419128418,27.2737407684326,12), Vec3f(15.4534196853638,27.9006500244141,12), Vec3f(15.9715900421143,28.0212306976318,12), Vec3f(14.4613399505615,28.5003795623779,12), Vec3f(15,28.6602592468262,12), Vec3f(13.4042100906372,28.9761600494385,12), Vec3f(13.9608001708984,29.1821594238281,12), Vec3f(12.2974300384521,29.3210391998291,12), Vec3f(7.13196802139282,29.5799007415771,0), Vec3f(8.26351833343506,29.8480796813965,0), Vec3f(8.84284687042236,29.5300102233887,0), Vec3f(9.41855144500732,29.9830799102783,0), Vec3f(10,29.6000003814697,0), Vec3f(10.5814504623413,29.9830799102783,0), Vec3f(11.1571502685547,29.5300102233887,0), Vec3f(11.7364797592163,29.8480796813965,0), Vec3f(12.2974300384521,29.3210391998291,0), Vec3f(12.8680295944214,29.5799007415771,0), Vec3f(13.4042100906372,28.9761600494385,0), Vec3f(13.9608001708984,29.1821594238281,0), Vec3f(14.4613399505615,28.5003795623779,0), Vec3f(15,28.6602592468262,0), Vec3f(15.4534196853638,27.9006500244141,0), Vec3f(15.9715900421143,28.0212306976318,0), Vec3f(16.3659801483154,27.1856994628906,0), Vec3f(16.862419128418,27.2737407684326,0), Vec3f(17.1856994628906,26.3659801483154,0), Vec3f(17.6604404449463,26.4278793334961,0), Vec3f(17.9006500244141,25.4534206390381,0), Vec3f(18.3548793792725,25.4950904846191,0), Vec3f(18.5003795623779,24.4613399505615,0), Vec3f(18.9363307952881,24.4879894256592,0), Vec3f(18.9761600494385,23.4042091369629,0), Vec3f(19.3969306945801,23.4202003479004,0), Vec3f(19.3210391998291,22.2974300384521,0), Vec3f(19.7304496765137,22.3061599731445,0), Vec3f(19.5300102233887,21.1571502685547,0), Vec3f(19.9323806762695,21.1609306335449,0), Vec3f(19.6000003814697,20,0), Vec3f(20,20,0), Vec3f(19.6000003814697,0.399999290704727,0), Vec3f(20,0,0), Vec3f(5,0.399999290704727,0), Vec3f(5,0,0), Vec3f(4.2804012298584,0.456633001565933,0), Vec3f(4.21782684326172,0.0615576282143593,0), Vec3f(3.5785219669342,0.625140011310577,0), Vec3f(3.45491504669189,0.244717106223106,0), Vec3f(2.91164398193359,0.901369392871857,0), Vec3f(2.73004698753357,0.544967114925385,0), Vec3f(2.29618692398071,1.27852201461792,0), Vec3f(2.06107401847839,0.954914808273315,0), Vec3f(1.74730801582336,1.74730801582336,0), Vec3f(1.46446597576141,1.46446597576141,0), Vec3f(1.27852201461792,2.29618692398071,0), Vec3f(0.954914808273315,2.06107401847839,0), Vec3f(0.901369392871857,2.91164398193359,0), Vec3f(0.544967114925385,2.73004698753357,0), Vec3f(0.625140011310577,3.5785219669342,0), Vec3f(0.244717106223106,3.45491504669189,0), Vec3f(0.456633001565933,4.2804012298584,0), Vec3f(0.0615576282143593,4.21782684326172,0), Vec3f(0.399999290704727,5,0), Vec3f(0,5,0), Vec3f(0.399999290704727,20,0), Vec3f(0,20,0), Vec3f(0.469994693994522,21.1571502685547,0), Vec3f(0.067615881562233,21.1609306335449,0), Vec3f(0.678958415985107,22.2974300384521,0), Vec3f(0.269550800323486,22.3061599731445,0), Vec3f(1.02384400367737,23.4042091369629,0), Vec3f(0.603073298931122,23.4202003479004,0), Vec3f(1.49962198734283,24.4613399505615,0), Vec3f(1.0636739730835,24.4879894256592,0), Vec3f(2.0993549823761,25.4534206390381,0), Vec3f(1.64512205123901,25.4950904846191,0), Vec3f(2.81429696083069,26.3659801483154,0), Vec3f(2.33955597877502,26.4278793334961,0), Vec3f(3.63402199745178,27.1856994628906,0), Vec3f(3.13758301734924,27.2737407684326,0), Vec3f(4.54657793045044,27.9006500244141,0), Vec3f(4.02841377258301,28.0212306976318,0), Vec3f(5.53865718841553,28.5003795623779,0), Vec3f(5,28.6602592468262,0), Vec3f(6.59579277038574,28.9761600494385,0), Vec3f(6.03920221328735,29.1821594238281,0), Vec3f(7.70256900787354,29.3210391998291,0) }; facets = std::vector{ Vec3i32(0,1,2), Vec3i32(2,1,3), Vec3i32(2,3,4), Vec3i32(4,3,5), Vec3i32(4,5,6), Vec3i32(6,5,7), Vec3i32(6,7,8), Vec3i32(8,7,9), Vec3i32(8,9,10), Vec3i32(10,9,11), Vec3i32(10,11,12), Vec3i32(12,11,13), Vec3i32(12,13,14), Vec3i32(14,13,15), Vec3i32(14,15,16), Vec3i32(16,15,17), Vec3i32(16,17,18), Vec3i32(18,17,19), Vec3i32(18,19,20), Vec3i32(20,19,21), Vec3i32(20,21,22), Vec3i32(22,21,23), Vec3i32(22,23,24), Vec3i32(24,23,25), Vec3i32(24,25,26), Vec3i32(26,25,27), Vec3i32(26,27,28), Vec3i32(28,27,29), Vec3i32(28,29,30), Vec3i32(30,29,31), Vec3i32(30,31,32), Vec3i32(32,31,33), Vec3i32(32,33,34), Vec3i32(34,33,35), Vec3i32(34,35,36), Vec3i32(36,35,37), Vec3i32(36,37,38), Vec3i32(38,37,39), Vec3i32(38,39,40), Vec3i32(40,39,41), Vec3i32(40,41,42), Vec3i32(42,41,43), Vec3i32(42,43,44), Vec3i32(44,43,45), Vec3i32(44,45,46), Vec3i32(46,45,47), Vec3i32(46,47,48), Vec3i32(48,47,49), Vec3i32(48,49,50), Vec3i32(50,49,51), Vec3i32(50,51,52), Vec3i32(52,51,53), Vec3i32(52,53,54), Vec3i32(54,53,55), Vec3i32(54,55,56), Vec3i32(56,55,57), Vec3i32(56,57,58), Vec3i32(58,57,59), Vec3i32(58,59,60), Vec3i32(60,59,61), Vec3i32(60,61,62), Vec3i32(62,61,63), Vec3i32(62,63,64), Vec3i32(64,63,65), Vec3i32(64,65,66), Vec3i32(66,65,67), Vec3i32(66,67,68), Vec3i32(68,67,69), Vec3i32(68,69,70), Vec3i32(70,69,71), Vec3i32(70,71,72), Vec3i32(72,71,73), Vec3i32(72,73,74), Vec3i32(74,73,75), Vec3i32(74,75,76), Vec3i32(76,75,77), Vec3i32(76,77,78), Vec3i32(78,77,0), Vec3i32(78,0,2), Vec3i32(79,80,81), Vec3i32(81,80,82), Vec3i32(81,82,83), Vec3i32(83,82,84), Vec3i32(83,84,85), Vec3i32(85,84,86), Vec3i32(85,86,87), Vec3i32(87,86,88), Vec3i32(87,88,89), Vec3i32(89,88,90), Vec3i32(89,90,91), Vec3i32(91,90,92), Vec3i32(91,92,93), Vec3i32(93,92,94), Vec3i32(93,94,95), Vec3i32(95,94,96), Vec3i32(95,96,97), Vec3i32(97,96,98), Vec3i32(97,98,99), Vec3i32(99,98,100), Vec3i32(99,100,101), Vec3i32(101,100,102), Vec3i32(101,102,103), Vec3i32(103,102,104), Vec3i32(103,104,105), Vec3i32(105,104,106), Vec3i32(105,106,107), Vec3i32(107,106,108), Vec3i32(107,108,109), Vec3i32(109,108,110), Vec3i32(109,110,111), Vec3i32(111,110,112), Vec3i32(111,112,113), Vec3i32(113,112,114), Vec3i32(113,114,115), Vec3i32(115,114,116), Vec3i32(115,116,117), Vec3i32(117,116,118), Vec3i32(117,118,119), Vec3i32(119,118,120), Vec3i32(119,120,121), Vec3i32(121,120,122), Vec3i32(121,122,123), Vec3i32(123,122,124), Vec3i32(123,124,125), Vec3i32(125,124,126), Vec3i32(125,126,127), Vec3i32(127,126,128), Vec3i32(127,128,129), Vec3i32(129,128,130), Vec3i32(129,130,131), Vec3i32(131,130,132), Vec3i32(131,132,133), Vec3i32(133,132,134), Vec3i32(133,134,135), Vec3i32(135,134,136), Vec3i32(135,136,137), Vec3i32(137,136,138), Vec3i32(137,138,139), Vec3i32(139,138,140), Vec3i32(139,140,141), Vec3i32(141,140,142), Vec3i32(141,142,143), Vec3i32(143,142,144), Vec3i32(143,144,145), Vec3i32(145,144,146), Vec3i32(145,146,147), Vec3i32(147,146,148), Vec3i32(147,148,149), Vec3i32(149,148,150), Vec3i32(149,150,151), Vec3i32(151,150,152), Vec3i32(151,152,153), Vec3i32(153,152,154), Vec3i32(153,154,155), Vec3i32(155,154,156), Vec3i32(155,156,157), Vec3i32(157,156,79), Vec3i32(157,79,81), Vec3i32(57,110,108), Vec3i32(57,108,59), Vec3i32(59,108,106), Vec3i32(59,106,61), Vec3i32(61,106,104), Vec3i32(61,104,63), Vec3i32(63,104,102), Vec3i32(63,102,65), Vec3i32(65,102,100), Vec3i32(65,100,67), Vec3i32(67,100,98), Vec3i32(67,98,69), Vec3i32(69,98,96), Vec3i32(69,96,71), Vec3i32(71,96,94), Vec3i32(71,94,73), Vec3i32(73,94,92), Vec3i32(73,92,75), Vec3i32(75,92,90), Vec3i32(75,90,77), Vec3i32(77,90,88), Vec3i32(77,88,0), Vec3i32(0,88,86), Vec3i32(0,86,1), Vec3i32(1,86,84), Vec3i32(1,84,3), Vec3i32(3,84,82), Vec3i32(3,82,5), Vec3i32(5,82,80), Vec3i32(5,80,7), Vec3i32(7,80,79), Vec3i32(7,79,9), Vec3i32(9,79,156), Vec3i32(9,156,11), Vec3i32(11,156,154), Vec3i32(11,154,13), Vec3i32(13,154,152), Vec3i32(13,152,15), Vec3i32(15,152,150), Vec3i32(15,150,17), Vec3i32(17,150,148), Vec3i32(17,148,19), Vec3i32(19,148,146), Vec3i32(19,146,21), Vec3i32(21,146,144), Vec3i32(21,144,23), Vec3i32(23,144,142), Vec3i32(23,142,25), Vec3i32(25,142,140), Vec3i32(25,140,27), Vec3i32(27,140,138), Vec3i32(27,138,29), Vec3i32(29,138,136), Vec3i32(29,136,31), Vec3i32(33,31,134), Vec3i32(134,31,136), Vec3i32(33,134,132), Vec3i32(33,132,35), Vec3i32(35,132,130), Vec3i32(35,130,37), Vec3i32(37,130,128), Vec3i32(37,128,39), Vec3i32(39,128,126), Vec3i32(39,126,41), Vec3i32(41,126,124), Vec3i32(41,124,43), Vec3i32(43,124,122), Vec3i32(43,122,45), Vec3i32(45,122,120), Vec3i32(45,120,47), Vec3i32(47,120,118), Vec3i32(47,118,49), Vec3i32(49,118,116), Vec3i32(49,116,51), Vec3i32(51,116,114), Vec3i32(51,114,53), Vec3i32(55,53,112), Vec3i32(112,53,114), Vec3i32(57,55,110), Vec3i32(110,55,112), Vec3i32(30,135,137), Vec3i32(30,137,28), Vec3i32(28,137,139), Vec3i32(28,139,26), Vec3i32(26,139,141), Vec3i32(26,141,24), Vec3i32(24,141,143), Vec3i32(24,143,22), Vec3i32(22,143,145), Vec3i32(22,145,20), Vec3i32(20,145,147), Vec3i32(20,147,18), Vec3i32(18,147,149), Vec3i32(18,149,16), Vec3i32(16,149,151), Vec3i32(16,151,14), Vec3i32(14,151,153), Vec3i32(14,153,12), Vec3i32(12,153,155), Vec3i32(12,155,10), Vec3i32(10,155,157), Vec3i32(10,157,8), Vec3i32(8,157,81), Vec3i32(8,81,6), Vec3i32(6,81,83), Vec3i32(6,83,4), Vec3i32(4,83,85), Vec3i32(4,85,2), Vec3i32(2,85,87), Vec3i32(2,87,78), Vec3i32(78,87,89), Vec3i32(78,89,76), Vec3i32(76,89,91), Vec3i32(76,91,74), Vec3i32(74,91,93), Vec3i32(74,93,72), Vec3i32(72,93,95), Vec3i32(72,95,70), Vec3i32(70,95,97), Vec3i32(70,97,68), Vec3i32(68,97,99), Vec3i32(68,99,66), Vec3i32(66,99,101), Vec3i32(66,101,64), Vec3i32(64,101,103), Vec3i32(64,103,62), Vec3i32(62,103,105), Vec3i32(62,105,60), Vec3i32(60,105,107), Vec3i32(60,107,58), Vec3i32(58,107,109), Vec3i32(58,109,56), Vec3i32(30,32,135), Vec3i32(135,32,133), Vec3i32(52,113,115), Vec3i32(52,115,50), Vec3i32(50,115,117), Vec3i32(50,117,48), Vec3i32(48,117,119), Vec3i32(48,119,46), Vec3i32(46,119,121), Vec3i32(46,121,44), Vec3i32(44,121,123), Vec3i32(44,123,42), Vec3i32(42,123,125), Vec3i32(42,125,40), Vec3i32(40,125,127), Vec3i32(40,127,38), Vec3i32(38,127,129), Vec3i32(38,129,36), Vec3i32(36,129,131), Vec3i32(36,131,34), Vec3i32(34,131,133), Vec3i32(34,133,32), Vec3i32(52,54,113), Vec3i32(113,54,111), Vec3i32(54,56,111), Vec3i32(111,56,109) }; break; case TestMesh::sloping_hole: - vertices = std::vector{ - Vec3d(-20,-20,-5), Vec3d(-20,-20,5), Vec3d(-20,20,-5), Vec3d(-20,20,5), Vec3d(20,-20,-5), Vec3d(20,-20,5), Vec3d(4.46294021606445,7.43144989013672,-5), Vec3d(20,20,-5), Vec3d(-19.1420993804932,0,-5), Vec3d(-18.8330993652344,-2.07911992073059,-5), Vec3d(-17.9195003509521,-4.06736993789673,-5), Vec3d(-16.4412002563477,-5.87785005569458,-5), Vec3d(-14.4629001617432,-7.43144989013672,-5), Vec3d(-12.0711002349854,-8.66024971008301,-5), Vec3d(-9.37016010284424,-9.51056003570557,-5), Vec3d(-3.5217399597168,-9.94521999359131,-5), Vec3d(-6.4782600402832,-9.94521999359131,-5), Vec3d(-0.629840016365051,-9.51056003570557,-5), Vec3d(2.07106995582581,-8.66024971008301,-5), Vec3d(6.44122982025146,-5.87785005569458,-5), Vec3d(4.46294021606445,-7.43144989013672,-5), Vec3d(-12.0711002349854,8.66024971008301,-5), Vec3d(-9.37016010284424,9.51056003570557,-5), Vec3d(7.91947984695435,-4.06736993789673,-5), Vec3d(8.83310031890869,-2.07911992073059,-5), Vec3d(-6.4782600402832,9.94521999359131,-5), Vec3d(-0.629840016365051,9.51056003570557,-5), Vec3d(2.07106995582581,8.66024971008301,-5), Vec3d(9.14214038848877,0,-5), Vec3d(8.83310031890869,2.07911992073059,-5), Vec3d(-3.5217399597168,9.94521999359131,-5), Vec3d(7.91947984695435,4.06736993789673,-5), Vec3d(6.44122982025146,5.87785005569458,-5), Vec3d(-14.4629001617432,7.43144989013672,-5), Vec3d(-16.4412002563477,5.87785005569458,-5), Vec3d(-17.9195003509521,4.06736993789673,-5), Vec3d(-18.8330993652344,2.07911992073059,-5), Vec3d(20,20,5), Vec3d(3.5217399597168,-9.94521999359131,5), Vec3d(-8.83310031890869,-2.07911992073059,5), Vec3d(-9.14214038848877,0,5), Vec3d(-8.83310031890869,2.07911992073059,5), Vec3d(6.4782600402832,-9.94521999359131,5), Vec3d(-7.91947984695435,4.06736993789673,5), Vec3d(-6.44122982025146,5.87785005569458,5), Vec3d(-4.46294021606445,7.43144989013672,5), Vec3d(-2.07106995582581,8.66024971008301,5), Vec3d(0.629840016365051,9.51056003570557,5), Vec3d(12.0711002349854,-8.66024971008301,5), Vec3d(9.37016010284424,-9.51056003570557,5), Vec3d(3.5217399597168,9.94521999359131,5), Vec3d(6.4782600402832,9.94521999359131,5), Vec3d(9.37016010284424,9.51056003570557,5), Vec3d(12.0711002349854,8.66024971008301,5), Vec3d(14.4629001617432,7.43144989013672,5), Vec3d(16.4412002563477,-5.87785005569458,5), Vec3d(14.4629001617432,-7.43144989013672,5), Vec3d(16.4412002563477,5.87785005569458,5), Vec3d(17.9195003509521,4.06736993789673,5), Vec3d(18.8330993652344,-2.07911992073059,5), Vec3d(17.9195003509521,-4.06736993789673,5), Vec3d(18.8330993652344,2.07911992073059,5), Vec3d(19.1420993804932,0,5), Vec3d(0.629840016365051,-9.51056003570557,5), Vec3d(-2.07106995582581,-8.66024971008301,5), Vec3d(-4.46294021606445,-7.43144989013672,5), Vec3d(-6.44122982025146,-5.87785005569458,5), Vec3d(-7.91947984695435,-4.06736993789673,5) + vertices = std::vector{ + Vec3f(-20,-20,-5), Vec3f(-20,-20,5), Vec3f(-20,20,-5), Vec3f(-20,20,5), Vec3f(20,-20,-5), Vec3f(20,-20,5), Vec3f(4.46294021606445,7.43144989013672,-5), Vec3f(20,20,-5), Vec3f(-19.1420993804932,0,-5), Vec3f(-18.8330993652344,-2.07911992073059,-5), Vec3f(-17.9195003509521,-4.06736993789673,-5), Vec3f(-16.4412002563477,-5.87785005569458,-5), Vec3f(-14.4629001617432,-7.43144989013672,-5), Vec3f(-12.0711002349854,-8.66024971008301,-5), Vec3f(-9.37016010284424,-9.51056003570557,-5), Vec3f(-3.5217399597168,-9.94521999359131,-5), Vec3f(-6.4782600402832,-9.94521999359131,-5), Vec3f(-0.629840016365051,-9.51056003570557,-5), Vec3f(2.07106995582581,-8.66024971008301,-5), Vec3f(6.44122982025146,-5.87785005569458,-5), Vec3f(4.46294021606445,-7.43144989013672,-5), Vec3f(-12.0711002349854,8.66024971008301,-5), Vec3f(-9.37016010284424,9.51056003570557,-5), Vec3f(7.91947984695435,-4.06736993789673,-5), Vec3f(8.83310031890869,-2.07911992073059,-5), Vec3f(-6.4782600402832,9.94521999359131,-5), Vec3f(-0.629840016365051,9.51056003570557,-5), Vec3f(2.07106995582581,8.66024971008301,-5), Vec3f(9.14214038848877,0,-5), Vec3f(8.83310031890869,2.07911992073059,-5), Vec3f(-3.5217399597168,9.94521999359131,-5), Vec3f(7.91947984695435,4.06736993789673,-5), Vec3f(6.44122982025146,5.87785005569458,-5), Vec3f(-14.4629001617432,7.43144989013672,-5), Vec3f(-16.4412002563477,5.87785005569458,-5), Vec3f(-17.9195003509521,4.06736993789673,-5), Vec3f(-18.8330993652344,2.07911992073059,-5), Vec3f(20,20,5), Vec3f(3.5217399597168,-9.94521999359131,5), Vec3f(-8.83310031890869,-2.07911992073059,5), Vec3f(-9.14214038848877,0,5), Vec3f(-8.83310031890869,2.07911992073059,5), Vec3f(6.4782600402832,-9.94521999359131,5), Vec3f(-7.91947984695435,4.06736993789673,5), Vec3f(-6.44122982025146,5.87785005569458,5), Vec3f(-4.46294021606445,7.43144989013672,5), Vec3f(-2.07106995582581,8.66024971008301,5), Vec3f(0.629840016365051,9.51056003570557,5), Vec3f(12.0711002349854,-8.66024971008301,5), Vec3f(9.37016010284424,-9.51056003570557,5), Vec3f(3.5217399597168,9.94521999359131,5), Vec3f(6.4782600402832,9.94521999359131,5), Vec3f(9.37016010284424,9.51056003570557,5), Vec3f(12.0711002349854,8.66024971008301,5), Vec3f(14.4629001617432,7.43144989013672,5), Vec3f(16.4412002563477,-5.87785005569458,5), Vec3f(14.4629001617432,-7.43144989013672,5), Vec3f(16.4412002563477,5.87785005569458,5), Vec3f(17.9195003509521,4.06736993789673,5), Vec3f(18.8330993652344,-2.07911992073059,5), Vec3f(17.9195003509521,-4.06736993789673,5), Vec3f(18.8330993652344,2.07911992073059,5), Vec3f(19.1420993804932,0,5), Vec3f(0.629840016365051,-9.51056003570557,5), Vec3f(-2.07106995582581,-8.66024971008301,5), Vec3f(-4.46294021606445,-7.43144989013672,5), Vec3f(-6.44122982025146,-5.87785005569458,5), Vec3f(-7.91947984695435,-4.06736993789673,5) }; facets = std::vector{ Vec3i32(0,1,2), Vec3i32(2,1,3), Vec3i32(1,0,4), Vec3i32(5,1,4), Vec3i32(6,2,7), Vec3i32(0,2,8), Vec3i32(0,8,9), Vec3i32(0,9,10), Vec3i32(0,10,11), Vec3i32(0,11,12), Vec3i32(0,12,13), Vec3i32(0,13,4), Vec3i32(13,14,4), Vec3i32(15,4,16), Vec3i32(17,4,15), Vec3i32(18,4,17), Vec3i32(19,4,20), Vec3i32(18,20,4), Vec3i32(21,2,22), Vec3i32(4,19,23), Vec3i32(4,23,7), Vec3i32(23,24,7), Vec3i32(22,2,25), Vec3i32(26,2,27), Vec3i32(28,29,7), Vec3i32(25,2,30), Vec3i32(29,31,7), Vec3i32(30,2,26), Vec3i32(31,32,7), Vec3i32(27,2,6), Vec3i32(32,6,7), Vec3i32(28,7,24), Vec3i32(33,2,21), Vec3i32(34,2,33), Vec3i32(35,2,34), Vec3i32(36,2,35), Vec3i32(8,2,36), Vec3i32(16,4,14), Vec3i32(2,3,7), Vec3i32(7,3,37), Vec3i32(38,1,5), Vec3i32(3,1,39), Vec3i32(3,39,40), Vec3i32(3,40,41), Vec3i32(42,38,5), Vec3i32(3,41,43), Vec3i32(3,43,44), Vec3i32(37,3,45), Vec3i32(37,45,46), Vec3i32(37,46,47), Vec3i32(48,49,5), Vec3i32(37,47,50), Vec3i32(49,42,5), Vec3i32(37,50,51), Vec3i32(37,51,52), Vec3i32(37,52,53), Vec3i32(37,53,54), Vec3i32(55,56,5), Vec3i32(37,54,57), Vec3i32(37,57,58), Vec3i32(59,60,5), Vec3i32(37,58,61), Vec3i32(37,62,5), Vec3i32(37,61,62), Vec3i32(62,59,5), Vec3i32(60,55,5), Vec3i32(63,1,38), Vec3i32(64,1,63), Vec3i32(65,1,64), Vec3i32(66,1,65), Vec3i32(67,1,66), Vec3i32(39,1,67), Vec3i32(44,45,3), Vec3i32(56,48,5), Vec3i32(5,4,7), Vec3i32(37,5,7), Vec3i32(41,40,36), Vec3i32(36,40,8), Vec3i32(39,9,40), Vec3i32(40,9,8), Vec3i32(43,41,35), Vec3i32(35,41,36), Vec3i32(44,43,34), Vec3i32(34,43,35), Vec3i32(33,45,44), Vec3i32(34,33,44), Vec3i32(21,46,45), Vec3i32(33,21,45), Vec3i32(22,47,46), Vec3i32(21,22,46), Vec3i32(25,50,47), Vec3i32(22,25,47), Vec3i32(30,51,50), Vec3i32(25,30,50), Vec3i32(26,52,51), Vec3i32(30,26,51), Vec3i32(27,53,52), Vec3i32(26,27,52), Vec3i32(6,54,53), Vec3i32(27,6,53), Vec3i32(32,57,54), Vec3i32(6,32,54), Vec3i32(31,58,57), Vec3i32(32,31,57), Vec3i32(29,61,58), Vec3i32(31,29,58), Vec3i32(28,62,61), Vec3i32(29,28,61), Vec3i32(59,62,28), Vec3i32(24,59,28), Vec3i32(60,59,24), Vec3i32(23,60,24), Vec3i32(55,60,23), Vec3i32(19,55,23), Vec3i32(55,19,56), Vec3i32(56,19,20), Vec3i32(56,20,48), Vec3i32(48,20,18), Vec3i32(48,18,49), Vec3i32(49,18,17), Vec3i32(49,17,42), Vec3i32(42,17,15), Vec3i32(42,15,38), Vec3i32(38,15,16), Vec3i32(38,16,63), Vec3i32(63,16,14), Vec3i32(63,14,64), Vec3i32(64,14,13), Vec3i32(64,13,65), Vec3i32(65,13,12), Vec3i32(65,12,66), Vec3i32(66,12,11), Vec3i32(66,11,67), Vec3i32(67,11,10), Vec3i32(67,10,39), Vec3i32(39,10,9) }; break; case TestMesh::ipadstand: - vertices = std::vector{ - Vec3d(17.4344673156738,-2.69879599481136e-16,9.5), Vec3d(14.2814798355103,10,9.5), Vec3d(0,0,9.5), Vec3d(31.7159481048584,10,9.5), Vec3d(62.2344741821289,2.06667568800577e-16,20), Vec3d(31.7159481048584,10,20), Vec3d(17.4344673156738,-2.69879599481136e-16,20), Vec3d(62.2344741821289,10,20), Vec3d(98.2079696655273,10,0), Vec3d(98.2079696655273,8.56525380796383e-16,10), Vec3d(98.2079696655273,0,0), Vec3d(98.2079696655273,10,20), Vec3d(98.2079696655273,0,20), Vec3d(81.6609649658203,-4.39753856997999e-16,10), Vec3d(90.0549850463867,10,10), Vec3d(78.5079803466797,10,10), Vec3d(93.2079696655273,8.56525380796383e-16,10), Vec3d(14.2814798355103,10,20), Vec3d(0,0,20), Vec3d(87.4344711303711,2.81343962782118e-15,20), Vec3d(84.2814788818359,10,20), Vec3d(0,10,20), Vec3d(0,0,0), Vec3d(0,10,0), Vec3d(62.2344741821289,2.06667568800577e-16,30), Vec3d(66.9609756469727,10,30), Vec3d(62.2344741821289,10,30), Vec3d(70.1139602661133,8.5525763717214e-16,30), Vec3d(67.7053375244141,10,28.7107200622559), Vec3d(71.6787109375,1.24046736339707e-15,27.2897701263428) + vertices = std::vector{ + Vec3f(17.4344673156738,-2.69879599481136e-16,9.5), Vec3f(14.2814798355103,10,9.5), Vec3f(0,0,9.5), Vec3f(31.7159481048584,10,9.5), Vec3f(62.2344741821289,2.06667568800577e-16,20), Vec3f(31.7159481048584,10,20), Vec3f(17.4344673156738,-2.69879599481136e-16,20), Vec3f(62.2344741821289,10,20), Vec3f(98.2079696655273,10,0), Vec3f(98.2079696655273,8.56525380796383e-16,10), Vec3f(98.2079696655273,0,0), Vec3f(98.2079696655273,10,20), Vec3f(98.2079696655273,0,20), Vec3f(81.6609649658203,-4.39753856997999e-16,10), Vec3f(90.0549850463867,10,10), Vec3f(78.5079803466797,10,10), Vec3f(93.2079696655273,8.56525380796383e-16,10), Vec3f(14.2814798355103,10,20), Vec3f(0,0,20), Vec3f(87.4344711303711,2.81343962782118e-15,20), Vec3f(84.2814788818359,10,20), Vec3f(0,10,20), Vec3f(0,0,0), Vec3f(0,10,0), Vec3f(62.2344741821289,2.06667568800577e-16,30), Vec3f(66.9609756469727,10,30), Vec3f(62.2344741821289,10,30), Vec3f(70.1139602661133,8.5525763717214e-16,30), Vec3f(67.7053375244141,10,28.7107200622559), Vec3f(71.6787109375,1.24046736339707e-15,27.2897701263428) }; facets = std::vector{ Vec3i32(0,1,2), Vec3i32(1,0,3), Vec3i32(4,5,6), Vec3i32(5,4,7), Vec3i32(8,9,10), Vec3i32(9,11,12), Vec3i32(11,9,8), Vec3i32(13,14,15), Vec3i32(14,13,16), Vec3i32(17,2,1), Vec3i32(2,17,18), Vec3i32(19,11,20), Vec3i32(11,19,12), Vec3i32(17,21,18), Vec3i32(21,2,18), Vec3i32(2,21,22), Vec3i32(22,21,23), Vec3i32(8,22,23), Vec3i32(22,8,10), Vec3i32(24,25,26), Vec3i32(25,24,27), Vec3i32(23,1,8), Vec3i32(1,23,21), Vec3i32(1,21,17), Vec3i32(5,15,3), Vec3i32(15,5,7), Vec3i32(15,7,28), Vec3i32(28,7,26), Vec3i32(28,26,25), Vec3i32(8,14,11), Vec3i32(14,8,3), Vec3i32(3,8,1), Vec3i32(14,3,15), Vec3i32(11,14,20), Vec3i32(26,4,24), Vec3i32(4,26,7), Vec3i32(12,16,9), Vec3i32(16,12,19), Vec3i32(29,4,13), Vec3i32(4,29,24), Vec3i32(24,29,27), Vec3i32(9,22,10), Vec3i32(22,9,0), Vec3i32(0,9,16), Vec3i32(0,16,13), Vec3i32(0,13,6), Vec3i32(6,13,4), Vec3i32(2,22,0), Vec3i32(19,14,16), Vec3i32(14,19,20), Vec3i32(15,29,13), Vec3i32(29,25,27), Vec3i32(25,29,15), Vec3i32(25,15,28), Vec3i32(6,3,0), Vec3i32(3,6,5) }; break; case TestMesh::A: - vertices = std::vector{ - Vec3d(513.075988769531,51.6074333190918,36.0009002685547), Vec3d(516.648803710938,51.7324333190918,36.0009002685547), Vec3d(513.495178222656,51.7324333190918,36.0009002685547), Vec3d(489.391204833984,51.4824333190918,24.0011005401611), Vec3d(488.928588867188,51.7324333190918,24.0011005401611), Vec3d(492.06201171875,51.7324333190918,24.0011005401611), Vec3d(496.840393066406,51.2324333190918,24.0011005401611), Vec3d(495.195404052734,51.7324333190918,24.0011005401611), Vec3d(498.981994628906,51.7324333190918,24.0011005401611), Vec3d(506.966613769531,51.6074333190918,24.0011005401611), Vec3d(510.342010498047,51.7324333190918,24.0011005401611), Vec3d(507.163818359375,51.6074333190918,24.0011005401611), Vec3d(512.515380859375,54.7190322875977,36.0009002685547), Vec3d(514.161987304688,54.5058326721191,36.0009002685547), Vec3d(493.06201171875,54.7190322875977,36.0009002685547), Vec3d(495.195404052734,51.7324333190918,36.0009002685547), Vec3d(496.195404052734,54.7190322875977,36.0009002685547), Vec3d(497.195404052734,57.7058334350586,36.0009002685547), Vec3d(500.851989746094,60.2658309936523,36.0009002685547), Vec3d(498.915405273438,62.8258323669434,36.0009002685547), Vec3d(506.701995849609,62.8258323669434,36.0009002685547), Vec3d(503.648590087891,60.2658309936523,36.0009002685547), Vec3d(508.381805419922,57.7058334350586,36.0009002685547), Vec3d(496.418792724609,60.052433013916,36.0009002685547), Vec3d(506.515197753906,72.2124328613281,36.0009002685547), Vec3d(502.808807373047,74.5324325561523,36.0009002685547), Vec3d(503.781982421875,71.6058349609375,36.0009002685547), Vec3d(515.358764648438,55.4658317565918,36.0009002685547), Vec3d(499.375183105469,76.9058380126953,36.0009002685547), Vec3d(501.168792724609,78.0658340454102,36.0009002685547), Vec3d(504.568786621094,78.0658340454102,36.0009002685547), Vec3d(506.32861328125,81.599235534668,36.0009002685547), Vec3d(502.928588867188,81.599235534668,36.0009002685547), Vec3d(499.528594970703,81.599235534668,36.0009002685547), Vec3d(498.20361328125,77.8658294677734,36.0009002685547), Vec3d(495.195404052734,51.7324333190918,30.0011005401611), Vec3d(498.981994628906,51.7324333190918,27.0011005401611), Vec3d(506.555206298828,51.7324333190918,33.0009002685547), Vec3d(506.555206298828,51.7324333190918,36.0009002685547), Vec3d(510.342010498047,51.7324333190918,36.0009002685547), Vec3d(512.515380859375,54.7190322875977,24.0011005401611), Vec3d(509.361999511719,54.7190322875977,24.0011005401611), Vec3d(508.381805419922,57.7058334350586,24.0011005401611), Vec3d(506.701995849609,62.8258323669434,24.0011005401611), Vec3d(509.188812255859,60.052433013916,24.0011005401611), Vec3d(493.06201171875,54.7190322875977,24.0011005401611), Vec3d(503.648590087891,60.2658309936523,24.0011005401611), Vec3d(500.851989746094,60.2658309936523,24.0011005401611), Vec3d(498.915405273438,62.8258323669434,24.0011005401611), Vec3d(502.808807373047,62.8258323669434,24.0011005401611), Vec3d(491.425201416016,54.5058326721191,24.0011005401611), Vec3d(506.421813964844,76.9058380126953,24.0011005401611), Vec3d(502.808807373047,74.5324325561523,24.0011005401611), Vec3d(504.568786621094,78.0658340454102,24.0011005401611), Vec3d(506.32861328125,81.599235534668,24.0011005401611), Vec3d(507.618804931641,77.8658294677734,24.0011005401611), Vec3d(499.221801757812,72.2124328613281,24.0011005401611), Vec3d(501.835388183594,71.6058349609375,24.0011005401611), Vec3d(501.168792724609,78.0658340454102,24.0011005401611), Vec3d(499.528594970703,81.599235534668,24.0011005401611), Vec3d(502.048583984375,79.8324356079102,24.0011005401611), Vec3d(490.253601074219,55.4658317565918,24.0011005401611), Vec3d(488.928588867188,51.7324333190918,30.0011005401611), Vec3d(488.928588867188,51.7324333190918,36.0009002685547), Vec3d(490.253601074219,55.4658317565918,31.5009002685547), Vec3d(498.20361328125,77.8658294677734,34.5009002685547), Vec3d(508.381805419922,57.7058334350586,30.0011005401611), Vec3d(505.585388183594,57.7058334350586,27.0011005401611), Vec3d(502.788818359375,57.7058334350586,36.0009002685547), Vec3d(499.992004394531,57.7058334350586,33.0009002685547), Vec3d(509.851989746094,53.2258338928223,33.0009002685547), Vec3d(509.361999511719,54.7190322875977,36.0009002685547), Vec3d(508.871795654297,56.2124328613281,27.0011005401611), Vec3d(496.695404052734,56.2124328613281,33.0009002685547), Vec3d(495.695404052734,53.2258338928223,27.0011005401611), Vec3d(506.32861328125,81.599235534668,30.0011005401611), Vec3d(507.618804931641,77.8658294677734,25.5011005401611), Vec3d(515.358764648438,55.4658317565918,34.5009002685547), Vec3d(501.228607177734,81.599235534668,33.0009002685547), Vec3d(504.628601074219,81.599235534668,27.0011005401611), Vec3d(503.781982421875,71.6058349609375,33.0009002685547), Vec3d(502.808807373047,74.5324325561523,30.0011005401611), Vec3d(498.915405273438,62.8258323669434,30.0011005401611), Vec3d(500.861999511719,62.8258323669434,27.0011005401611), Vec3d(502.808807373047,62.8258323669434,36.0009002685547), Vec3d(504.755187988281,62.8258323669434,33.0009002685547), Vec3d(501.835388183594,71.6058349609375,33.0009002685547), Vec3d(499.888793945312,65.7524337768555,33.0009002685547), Vec3d(499.888793945312,65.7524337768555,36.0009002685547), Vec3d(513.128601074219,51.4824333190918,36.0009002685547), Vec3d(513.075988769531,51.6074333190918,24.0011005401611), Vec3d(516.648803710938,51.7324333190918,24.0011005401611), Vec3d(513.128601074219,51.4824333190918,24.0011005401611), Vec3d(513.495178222656,51.7324333190918,24.0011005401611), Vec3d(506.966613769531,51.6074333190918,36.0009002685547), Vec3d(507.163818359375,51.6074333190918,36.0009002685547), Vec3d(490.337799072266,51.4824333190918,24.0011005401611), Vec3d(489.391204833984,51.4824333190918,36.0009002685547), Vec3d(492.06201171875,51.7324333190918,36.0009002685547), Vec3d(490.337799072266,51.4824333190918,36.0009002685547), Vec3d(513.233764648438,51.2324333190918,24.0011005401611), Vec3d(513.233764648438,51.2324333190918,36.0009002685547), Vec3d(504.773803710938,51.4824333190918,36.0009002685547), Vec3d(504.773803710938,51.4824333190918,24.0011005401611), Vec3d(489.266998291016,51.2324333190918,24.0011005401611), Vec3d(489.266998291016,51.2324333190918,36.0009002685547), Vec3d(490.253601074219,55.4658317565918,25.5011005401611), Vec3d(499.528594970703,81.599235534668,30.0011005401611), Vec3d(498.20361328125,77.8658294677734,31.5009002685547), Vec3d(515.358764648438,55.4658317565918,28.5011005401611), Vec3d(515.358764648438,55.4658317565918,25.5011005401611), Vec3d(495.246795654297,61.0124320983887,36.0009002685547), Vec3d(490.253601074219,55.4658317565918,34.5009002685547), Vec3d(490.253601074219,55.4658317565918,36.0009002685547), Vec3d(494.228607177734,66.6658325195312,24.0011005401611), Vec3d(499.068786621094,67.5192337036133,24.0011005401611), Vec3d(498.20361328125,77.8658294677734,25.5011005401611), Vec3d(498.20361328125,77.8658294677734,24.0011005401611), Vec3d(506.608795166016,67.5192337036133,36.0009002685547), Vec3d(509.09521484375,64.7458343505859,36.0009002685547), Vec3d(507.618804931641,77.8658294677734,34.5009002685547), Vec3d(507.618804931641,77.8658294677734,36.0009002685547), Vec3d(510.385406494141,61.0124320983887,24.0011005401611), Vec3d(515.358764648438,55.4658317565918,24.0011005401611), Vec3d(489.32861328125,47.7324333190918,31.5009002685547), Vec3d(492.95361328125,47.7324333190918,33.5634994506836), Vec3d(489.32861328125,47.7324333190918,34.5009002685547), Vec3d(489.32861328125,47.7324333190918,28.5011005401611), Vec3d(489.32861328125,47.7324333190918,25.5011005401611), Vec3d(492.95361328125,47.7324333190918,26.4385013580322), Vec3d(492.95361328125,47.7324333190918,30.5635013580322), Vec3d(492.95361328125,47.7324333190918,32.0634994506836), Vec3d(492.95361328125,47.7324333190918,31.3135013580322), Vec3d(492.95361328125,47.7324333190918,35.4384994506836), Vec3d(489.32861328125,47.7324333190918,36.0009002685547), Vec3d(492.95361328125,47.7324333190918,34.3134994506836), Vec3d(492.95361328125,47.7324333190918,34.6884994506836), Vec3d(492.95361328125,47.7324333190918,27.9385013580322), Vec3d(492.95361328125,47.7324333190918,28.6885013580322), Vec3d(492.95361328125,47.7324333190918,29.0635013580322), Vec3d(489.32861328125,47.7324333190918,24.0011005401611), Vec3d(492.95361328125,47.7324333190918,24.5635013580322), Vec3d(492.95361328125,47.7324333190918,25.6885013580322), Vec3d(492.95361328125,47.7324333190918,25.3135013580322), Vec3d(492.95361328125,47.7324333190918,24.1885013580322), Vec3d(492.95361328125,47.7324333190918,24.0011005401611), Vec3d(513.443786621094,50.7324333190918,24.0011005401611), Vec3d(492.95361328125,47.7324333190918,35.8134994506836), Vec3d(492.95361328125,47.7324333190918,36.0009002685547), Vec3d(513.443786621094,50.7324333190918,36.0009002685547), Vec3d(506.350402832031,51.4824333190918,36.0009002685547), Vec3d(506.350402832031,51.4824333190918,24.0011005401611), Vec3d(492.743804931641,48.2324333190918,24.0011005401611), Vec3d(492.638793945312,48.4824333190918,24.0011005401611), Vec3d(492.743804931641,48.2324333190918,36.0009002685547), Vec3d(492.638793945312,48.4824333190918,36.0009002685547), Vec3d(490.089599609375,50.9824333190918,36.0009002685547), Vec3d(490.089599609375,50.9824333190918,24.0011005401611), Vec3d(510.342010498047,51.7324333190918,30.0011005401611), Vec3d(499.068786621094,67.5192337036133,36.0009002685547), Vec3d(494.228607177734,66.6658325195312,36.0009002685547), Vec3d(499.375183105469,76.9058380126953,24.0011005401611), Vec3d(506.421813964844,76.9058380126953,36.0009002685547), Vec3d(506.608795166016,67.5192337036133,24.0011005401611), Vec3d(505.728607177734,65.7524337768555,24.0011005401611), Vec3d(509.09521484375,64.7458343505859,24.0011005401611), Vec3d(506.701995849609,62.8258323669434,30.0011005401611), Vec3d(505.728607177734,65.7524337768555,27.0011005401611), Vec3d(501.835388183594,71.6058349609375,27.0011005401611), Vec3d(499.888793945312,65.7524337768555,27.0011005401611), Vec3d(494.228607177734,66.6658325195312,30.0011005401611), Vec3d(495.553588867188,70.3992309570312,28.5011005401611), Vec3d(492.903594970703,62.9324340820312,28.5011005401611), Vec3d(495.553588867188,70.3992309570312,31.5009002685547), Vec3d(492.903594970703,62.9324340820312,31.5009002685547), Vec3d(511.488800048828,66.6658325195312,24.0011005401611), Vec3d(511.488800048828,66.6658325195312,30.0011005401611), Vec3d(512.778564453125,62.9324340820312,28.5011005401611), Vec3d(515.358764648438,55.4658317565918,31.5009002685547), Vec3d(507.618804931641,77.8658294677734,31.5009002685547), Vec3d(510.198791503906,70.3992309570312,28.5011005401611), Vec3d(511.488800048828,66.6658325195312,36.0009002685547), Vec3d(512.778564453125,62.9324340820312,31.5009002685547), Vec3d(510.198791503906,70.3992309570312,31.5009002685547), Vec3d(502.788818359375,57.7058334350586,24.0011005401611), Vec3d(497.195404052734,57.7058334350586,30.0011005401611), Vec3d(492.903594970703,62.9324340820312,34.5009002685547), Vec3d(492.903594970703,62.9324340820312,36.0009002685547), Vec3d(495.553588867188,70.3992309570312,24.0011005401611), Vec3d(496.725189208984,69.4392318725586,24.0011005401611), Vec3d(495.553588867188,70.3992309570312,25.5011005401611), Vec3d(495.246795654297,61.0124320983887,24.0011005401611), Vec3d(492.903594970703,62.9324340820312,25.5011005401611), Vec3d(492.903594970703,62.9324340820312,24.0011005401611), Vec3d(495.553588867188,70.3992309570312,36.0009002685547), Vec3d(496.725189208984,69.4392318725586,36.0009002685547), Vec3d(495.553588867188,70.3992309570312,34.5009002685547), Vec3d(510.198791503906,70.3992309570312,36.0009002685547), Vec3d(509.002014160156,69.4392318725586,36.0009002685547), Vec3d(510.198791503906,70.3992309570312,34.5009002685547), Vec3d(512.778564453125,62.9324340820312,25.5011005401611), Vec3d(512.778564453125,62.9324340820312,24.0011005401611), Vec3d(510.198791503906,70.3992309570312,24.0011005401611), Vec3d(509.002014160156,69.4392318725586,24.0011005401611), Vec3d(510.198791503906,70.3992309570312,25.5011005401611), Vec3d(510.385406494141,61.0124320983887,36.0009002685547), Vec3d(512.778564453125,62.9324340820312,34.5009002685547), Vec3d(512.778564453125,62.9324340820312,36.0009002685547), Vec3d(496.840393066406,51.2324333190918,36.0009002685547), Vec3d(498.981994628906,51.7324333190918,36.0009002685547), Vec3d(498.981994628906,51.7324333190918,33.0009002685547), Vec3d(506.555206298828,51.7324333190918,24.0011005401611), Vec3d(506.555206298828,51.7324333190918,27.0011005401611), Vec3d(503.82861328125,47.7324333190918,30.7509002685547), Vec3d(507.45361328125,47.7324333190918,32.8134994506836), Vec3d(503.82861328125,47.7324333190918,33.7509002685547), Vec3d(503.82861328125,47.7324333190918,29.2511005401611), Vec3d(503.82861328125,47.7324333190918,26.2511005401611), Vec3d(507.45361328125,47.7324333190918,27.1885013580322), Vec3d(493.921813964844,57.2792320251465,36.0009002685547), Vec3d(491.425201416016,54.5058326721191,36.0009002685547), Vec3d(497.195404052734,57.7058334350586,24.0011005401611), Vec3d(496.418792724609,60.052433013916,24.0011005401611), Vec3d(509.188812255859,60.052433013916,36.0009002685547), Vec3d(511.675415039062,57.2792320251465,24.0011005401611), Vec3d(514.161987304688,54.5058326721191,24.0011005401611), Vec3d(507.45361328125,47.7324333190918,34.3134994506836), Vec3d(503.82861328125,47.7324333190918,35.2509002685547), Vec3d(507.45361328125,47.7324333190918,25.6885013580322), Vec3d(503.82861328125,47.7324333190918,24.7511005401611), Vec3d(500.20361328125,47.7324333190918,31.6885013580322), Vec3d(500.20361328125,47.7324333190918,28.3135013580322), Vec3d(500.20361328125,47.7324333190918,30.1885013580322), Vec3d(507.45361328125,47.7324333190918,29.8135013580322), Vec3d(507.45361328125,47.7324333190918,31.3135013580322), Vec3d(507.45361328125,47.7324333190918,30.5635013580322), Vec3d(503.82861328125,47.7324333190918,36.0009002685547), Vec3d(507.45361328125,47.7324333190918,35.4384994506836), Vec3d(507.45361328125,47.7324333190918,35.0634994506836), Vec3d(507.45361328125,47.7324333190918,28.6885013580322), Vec3d(507.45361328125,47.7324333190918,29.4385013580322), Vec3d(503.82861328125,47.7324333190918,24.0011005401611), Vec3d(507.45361328125,47.7324333190918,24.5635013580322), Vec3d(507.45361328125,47.7324333190918,24.9385013580322), Vec3d(500.20361328125,47.7324333190918,34.6884994506836), Vec3d(500.20361328125,47.7324333190918,33.1884994506836), Vec3d(500.20361328125,47.7324333190918,33.9384994506836), Vec3d(500.20361328125,47.7324333190918,25.3135013580322), Vec3d(500.20361328125,47.7324333190918,26.8135013580322), Vec3d(500.20361328125,47.7324333190918,26.0635013580322), Vec3d(500.20361328125,47.7324333190918,30.9385013580322), Vec3d(500.20361328125,47.7324333190918,35.0634994506836), Vec3d(500.20361328125,47.7324333190918,35.4384994506836), Vec3d(500.20361328125,47.7324333190918,29.0635013580322), Vec3d(500.20361328125,47.7324333190918,29.4385013580322), Vec3d(500.20361328125,47.7324333190918,24.9385013580322), Vec3d(500.20361328125,47.7324333190918,24.5635013580322), Vec3d(507.45361328125,47.7324333190918,24.1885013580322), Vec3d(507.45361328125,47.7324333190918,24.0011005401611), Vec3d(513.86376953125,49.7324333190918,24.0011005401611), Vec3d(507.45361328125,47.7324333190918,35.8134994506836), Vec3d(507.45361328125,47.7324333190918,36.0009002685547), Vec3d(513.86376953125,49.7324333190918,36.0009002685547), Vec3d(500.20361328125,47.7324333190918,24.1885013580322), Vec3d(500.20361328125,47.7324333190918,24.0011005401611), Vec3d(502.988800048828,49.7324333190918,24.0011005401611), Vec3d(500.20361328125,47.7324333190918,35.8134994506836), Vec3d(500.20361328125,47.7324333190918,36.0009002685547), Vec3d(502.988800048828,49.7324333190918,36.0009002685547), Vec3d(504.755187988281,62.8258323669434,27.0011005401611), Vec3d(499.205383300781,51.2324333190918,36.0009002685547), Vec3d(498.786193847656,51.1074333190918,36.0009002685547), Vec3d(502.358795166016,51.2324333190918,36.0009002685547), Vec3d(499.205383300781,51.2324333190918,24.0011005401611), Vec3d(502.358795166016,51.2324333190918,24.0011005401611), Vec3d(498.786193847656,51.1074333190918,24.0011005401611), Vec3d(502.568786621094,50.7324333190918,24.0011005401611), Vec3d(505.931213378906,51.3574333190918,24.0011005401611), Vec3d(509.503601074219,51.4824333190918,24.0011005401611), Vec3d(502.568786621094,50.7324333190918,36.0009002685547), Vec3d(505.931213378906,51.3574333190918,36.0009002685547), Vec3d(509.503601074219,51.4824333190918,36.0009002685547), Vec3d(499.048583984375,50.4824333190918,36.0009002685547), Vec3d(492.428588867188,48.9824333190918,36.0009002685547), Vec3d(499.048583984375,50.4824333190918,24.0011005401611), Vec3d(492.428588867188,48.9824333190918,24.0011005401611), Vec3d(506.088806152344,50.9824333190918,24.0011005401611), Vec3d(506.036010742188,51.1074333190918,24.0011005401611), Vec3d(506.088806152344,50.9824333190918,36.0009002685547), Vec3d(506.036010742188,51.1074333190918,36.0009002685547), Vec3d(498.891204833984,50.8574333190918,36.0009002685547), Vec3d(498.943786621094,50.7324333190918,36.0009002685547), Vec3d(498.891204833984,50.8574333190918,24.0011005401611), Vec3d(498.943786621094,50.7324333190918,24.0011005401611), Vec3d(499.573608398438,49.2324333190918,24.0011005401611), Vec3d(499.783813476562,48.7324333190918,24.0011005401611), Vec3d(499.573608398438,49.2324333190918,36.0009002685547), Vec3d(499.783813476562,48.7324333190918,36.0009002685547), Vec3d(506.403594970703,50.2324333190918,24.0011005401611), Vec3d(506.298797607422,50.4824333190918,24.0011005401611), Vec3d(506.403594970703,50.2324333190918,36.0009002685547), Vec3d(506.298797607422,50.4824333190918,36.0009002685547), Vec3d(501.228607177734,81.599235534668,27.0011005401611), Vec3d(502.928588867188,81.599235534668,24.0011005401611), Vec3d(499.2587890625,49.9824333190918,36.0009002685547), Vec3d(499.363800048828,49.7324333190918,36.0009002685547), Vec3d(499.2587890625,49.9824333190918,24.0011005401611), Vec3d(499.363800048828,49.7324333190918,24.0011005401611), Vec3d(496.695404052734,56.2124328613281,27.0011005401611), Vec3d(496.195404052734,54.7190322875977,24.0011005401611), Vec3d(509.851989746094,53.2258338928223,27.0011005401611), Vec3d(493.464782714844,51.1074333190918,36.0009002685547), Vec3d(493.464782714844,51.1074333190918,24.0011005401611), Vec3d(502.768798828125,51.7324333190918,24.0011005401611), Vec3d(500.215789794922,51.3574333190918,24.0011005401611), Vec3d(497.628601074219,51.2324333190918,24.0011005401611), Vec3d(502.768798828125,51.7324333190918,36.0009002685547), Vec3d(500.215789794922,51.3574333190918,36.0009002685547), Vec3d(497.628601074219,51.2324333190918,36.0009002685547), Vec3d(507.033813476562,48.7324333190918,24.0011005401611), Vec3d(506.823791503906,49.2324333190918,24.0011005401611), Vec3d(507.033813476562,48.7324333190918,36.0009002685547), Vec3d(506.823791503906,49.2324333190918,36.0009002685547), Vec3d(494.4501953125,51.1074333190918,24.0011005401611), Vec3d(494.4501953125,51.1074333190918,36.0009002685547), Vec3d(500.807006835938,51.3574333190918,36.0009002685547), Vec3d(503.591186523438,51.4824333190918,36.0009002685547), Vec3d(503.591186523438,51.4824333190918,24.0011005401611), Vec3d(500.807006835938,51.3574333190918,24.0011005401611), Vec3d(505.728607177734,65.7524337768555,36.0009002685547), Vec3d(505.728607177734,65.7524337768555,33.0009002685547), Vec3d(499.221801757812,72.2124328613281,36.0009002685547), Vec3d(501.835388183594,71.6058349609375,36.0009002685547), Vec3d(506.515197753906,72.2124328613281,24.0011005401611), Vec3d(503.781982421875,71.6058349609375,24.0011005401611), Vec3d(503.781982421875,71.6058349609375,27.0011005401611), Vec3d(499.888793945312,65.7524337768555,24.0011005401611), Vec3d(495.695404052734,53.2258338928223,33.0009002685547), Vec3d(516.648803710938,51.7324333190918,30.0011005401611), Vec3d(498.20361328125,77.8658294677734,28.5011005401611), Vec3d(505.585388183594,57.7058334350586,33.0009002685547), Vec3d(508.871795654297,56.2124328613281,33.0009002685547), Vec3d(499.992004394531,57.7058334350586,27.0011005401611), Vec3d(504.628601074219,81.599235534668,33.0009002685547), Vec3d(500.861999511719,62.8258323669434,33.0009002685547), Vec3d(496.878601074219,74.1324310302734,27.0011005401611), Vec3d(496.878601074219,74.1324310302734,33.0009002685547), Vec3d(491.57861328125,59.199031829834,27.0011005401611), Vec3d(490.253601074219,55.4658317565918,28.5011005401611), Vec3d(491.57861328125,59.199031829834,33.0009002685547), Vec3d(514.068786621094,59.199031829834,27.0011005401611), Vec3d(514.068786621094,59.199031829834,33.0009002685547), Vec3d(508.908813476562,74.1324310302734,27.0011005401611), Vec3d(507.618804931641,77.8658294677734,28.5011005401611), Vec3d(508.908813476562,74.1324310302734,33.0009002685547), Vec3d(491.271789550781,50.9824333190918,36.0009002685547), Vec3d(490.877807617188,50.9824333190918,36.0009002685547), Vec3d(491.271789550781,50.9824333190918,24.0011005401611), Vec3d(490.877807617188,50.9824333190918,24.0011005401611), Vec3d(495.213806152344,50.9824333190918,36.0009002685547), Vec3d(493.636993408203,50.9824333190918,36.0009002685547), Vec3d(495.213806152344,50.9824333190918,24.0011005401611), Vec3d(493.636993408203,50.9824333190918,24.0011005401611), Vec3d(503.985412597656,51.4824333190918,36.0009002685547), Vec3d(503.985412597656,51.4824333190918,24.0011005401611), Vec3d(511.675415039062,57.2792320251465,36.0009002685547), Vec3d(493.921813964844,57.2792320251465,24.0011005401611), Vec3d(502.768798828125,51.7324333190918,30.0011005401611), Vec3d(506.555206298828,51.7324333190918,30.0011005401611), Vec3d(498.981994628906,51.7324333190918,30.0011005401611), Vec3d(492.848815917969,50.9824333190918,24.0011005401611), Vec3d(492.848815917969,50.9824333190918,36.0009002685547), Vec3d(500.861999511719,68.6792297363281,36.0009002685547), Vec3d(500.861999511719,68.6792297363281,24.0011005401611), Vec3d(496.878601074219,74.1324310302734,24.0011005401611), Vec3d(496.878601074219,74.1324310302734,36.0009002685547), Vec3d(504.755187988281,68.6792297363281,24.0011005401611), Vec3d(504.755187988281,68.6792297363281,36.0009002685547), Vec3d(508.908813476562,74.1324310302734,36.0009002685547), Vec3d(508.908813476562,74.1324310302734,24.0011005401611), Vec3d(505.728607177734,65.7524337768555,30.0011005401611), Vec3d(504.755187988281,68.6792297363281,30.0011005401611), Vec3d(503.781982421875,71.6058349609375,30.0011005401611), Vec3d(500.861999511719,68.6792297363281,30.0011005401611), Vec3d(499.888793945312,65.7524337768555,30.0011005401611), Vec3d(501.835388183594,71.6058349609375,30.0011005401611), Vec3d(491.57861328125,59.199031829834,24.0011005401611), Vec3d(491.57861328125,59.199031829834,36.0009002685547), Vec3d(514.068786621094,59.199031829834,36.0009002685547), Vec3d(514.068786621094,59.199031829834,24.0011005401611), Vec3d(511.07861328125,47.7324333190918,34.8759002685547), Vec3d(511.07861328125,47.7324333190918,31.8759002685547), Vec3d(514.70361328125,47.7324333190918,33.9384994506836), Vec3d(511.07861328125,47.7324333190918,25.1261005401611), Vec3d(514.70361328125,47.7324333190918,26.0635013580322), Vec3d(511.07861328125,47.7324333190918,28.1261005401611), Vec3d(502.788818359375,57.7058334350586,30.0011005401611), Vec3d(502.048583984375,79.8324356079102,36.0009002685547), Vec3d(514.70361328125,47.7324333190918,30.9385013580322), Vec3d(511.07861328125,47.7324333190918,30.3759002685547), Vec3d(514.70361328125,47.7324333190918,29.0635013580322), Vec3d(511.07861328125,47.7324333190918,29.6261005401611), Vec3d(496.57861328125,47.7324333190918,31.1259002685547), Vec3d(496.57861328125,47.7324333190918,32.6259002685547), Vec3d(496.57861328125,47.7324333190918,34.1259002685547), Vec3d(496.57861328125,47.7324333190918,28.8761005401611), Vec3d(496.57861328125,47.7324333190918,27.3761005401611), Vec3d(496.57861328125,47.7324333190918,25.8761005401611), Vec3d(496.57861328125,47.7324333190918,29.6261005401611), Vec3d(514.70361328125,47.7324333190918,35.4384994506836), Vec3d(511.07861328125,47.7324333190918,35.6259002685547), Vec3d(514.70361328125,47.7324333190918,24.5635013580322), Vec3d(511.07861328125,47.7324333190918,24.3761005401611), Vec3d(496.57861328125,47.7324333190918,34.8759002685547), Vec3d(496.57861328125,47.7324333190918,25.1261005401611), Vec3d(496.57861328125,47.7324333190918,35.6259002685547), Vec3d(496.57861328125,47.7324333190918,24.3761005401611), Vec3d(511.07861328125,47.7324333190918,36.0009002685547), Vec3d(511.07861328125,47.7324333190918,24.0011005401611), Vec3d(514.70361328125,47.7324333190918,30.1885013580322), Vec3d(514.70361328125,47.7324333190918,35.8134994506836), Vec3d(514.70361328125,47.7324333190918,29.8135013580322), Vec3d(514.70361328125,47.7324333190918,24.1885013580322), Vec3d(496.57861328125,47.7324333190918,36.0009002685547), Vec3d(496.57861328125,47.7324333190918,24.0011005401611), Vec3d(510.238800048828,49.7324333190918,24.0011005401611), Vec3d(510.238800048828,49.7324333190918,36.0009002685547), Vec3d(514.70361328125,47.7324333190918,24.0011005401611), Vec3d(514.70361328125,47.7324333190918,36.0009002685547), Vec3d(496.158813476562,48.7324333190918,36.0009002685547), Vec3d(496.158813476562,48.7324333190918,24.0011005401611), Vec3d(502.808807373047,62.8258323669434,30.0011005401611), Vec3d(509.608795166016,51.2324333190918,24.0011005401611), Vec3d(509.608795166016,51.2324333190918,36.0009002685547), Vec3d(491.641204833984,50.8574333190918,24.0011005401611), Vec3d(495.423797607422,50.4824333190918,36.0009002685547), Vec3d(495.423797607422,50.4824333190918,24.0011005401611), Vec3d(491.641204833984,50.8574333190918,36.0009002685547), Vec3d(495.528594970703,50.2324333190918,24.0011005401611), Vec3d(492.0087890625,49.9824333190918,24.0011005401611), Vec3d(509.818786621094,50.7324333190918,24.0011005401611), Vec3d(495.948608398438,49.2324333190918,36.0009002685547), Vec3d(495.528594970703,50.2324333190918,36.0009002685547), Vec3d(495.948608398438,49.2324333190918,24.0011005401611), Vec3d(509.818786621094,50.7324333190918,36.0009002685547), Vec3d(492.0087890625,49.9824333190918,36.0009002685547), Vec3d(491.956207275391,50.1074333190918,24.0011005401611), Vec3d(491.956207275391,50.1074333190918,36.0009002685547), Vec3d(502.928588867188,81.599235534668,30.0011005401611), Vec3d(491.851013183594,50.3574333190918,36.0009002685547), Vec3d(491.851013183594,50.3574333190918,24.0011005401611), Vec3d(496.195404052734,54.7190322875977,30.0011005401611), Vec3d(509.361999511719,54.7190322875977,30.0011005401611), Vec3d(488.632598876953,51.7256317138672,30.0011005401611), Vec3d(488.632598876953,51.7256317138672,29.5091018676758), Vec3d(488.632598876953,51.7188339233398,24.0011005401611), Vec3d(488.632598876953,51.7256317138672,27.4929008483887), Vec3d(488.632598876953,51.7324333190918,30.0011005401611), Vec3d(488.632598876953,51.7324333190918,29.0175018310547), Vec3d(488.632598876953,51.7324333190918,24.9847011566162), Vec3d(488.632598876953,51.7324333190918,24.0011005401611), Vec3d(488.632598876953,51.7188339233398,30.0011005401611), Vec3d(488.632598876953,51.7176322937012,24.0011005401611), Vec3d(488.632598876953,51.7182312011719,30.0011005401611), Vec3d(488.632598876953,51.7176322937012,30.0011005401611), Vec3d(488.632598876953,51.715030670166,24.0011005401611), Vec3d(488.632598876953,51.7162322998047,30.0011005401611), Vec3d(488.632598876953,50.761833190918,24.0011005401611), Vec3d(488.632598876953,50.7578315734863,24.0011005401611), Vec3d(488.632598876953,50.7598342895508,30.0011005401611), Vec3d(488.632598876953,50.7522315979004,24.0011005401611), Vec3d(488.632598876953,49.7838325500488,24.0011005401611), Vec3d(488.632598876953,50.2680320739746,30.0011005401611), Vec3d(488.632598876953,51.7046318054199,24.0011005401611), Vec3d(488.632598876953,51.709831237793,30.0011005401611), Vec3d(488.632598876953,50.9120330810547,24.0011005401611), Vec3d(488.632598876953,50.8882331848145,24.0011005401611), Vec3d(488.632598876953,50.9002304077148,30.0011005401611), Vec3d(488.632598876953,47.7324333190918,24.0370998382568), Vec3d(488.632598876953,48.5612335205078,30.0011005401611), Vec3d(488.632598876953,47.7324333190918,24.0011005401611), Vec3d(488.632598876953,47.7324333190918,24.1091003417969), Vec3d(488.632598876953,48.5612335205078,30.0189018249512), Vec3d(488.632598876953,47.7324333190918,25.3211002349854), Vec3d(488.632598876953,48.5612335205078,30.0551013946533), Vec3d(488.632598876953,47.7324333190918,25.4651012420654), Vec3d(488.632598876953,48.5612335205078,30.6609001159668), Vec3d(488.632598876953,47.7324333190918,25.5371017456055), Vec3d(488.632598876953,48.5612335205078,30.7329006195068), Vec3d(488.632598876953,47.7324333190918,25.6091003417969), Vec3d(488.632598876953,48.5612335205078,30.7689018249512), Vec3d(488.632598876953,47.7324333190918,25.8971004486084), Vec3d(488.632598876953,48.5612335205078,30.8051013946533), Vec3d(488.632598876953,47.7324333190918,28.321102142334), Vec3d(488.632598876953,48.5612335205078,30.9491004943848), Vec3d(488.632598876953,47.7324333190918,28.4651012420654), Vec3d(488.632598876953,48.5612335205078,32.1609001159668), Vec3d(488.632598876953,47.7324333190918,28.5371017456055), Vec3d(488.632598876953,48.5612335205078,32.2329025268555), Vec3d(488.632598876953,47.7324333190918,28.6811008453369), Vec3d(488.632598876953,48.5612335205078,32.2689018249512), Vec3d(488.632598876953,47.7324333190918,31.1049003601074), Vec3d(488.632598876953,48.5612335205078,32.3411026000977), Vec3d(488.632598876953,47.7324333190918,31.3929004669189), Vec3d(488.632598876953,49.3900299072266,36.0009002685547), Vec3d(488.632598876953,47.7324333190918,31.536901473999), Vec3d(488.632598876953,47.7324333190918,31.6809005737305), Vec3d(488.632598876953,47.7324333190918,34.1049003601074), Vec3d(488.632598876953,47.7324333190918,34.3929023742676), Vec3d(488.632598876953,47.7324333190918,34.464900970459), Vec3d(488.632598876953,47.7324333190918,34.5369033813477), Vec3d(488.632598876953,47.7324333190918,34.6809005737305), Vec3d(488.632598876953,47.7324333190918,35.8929023742676), Vec3d(488.632598876953,47.7324333190918,35.964900970459), Vec3d(488.632598876953,47.7324333190918,36.0009002685547), Vec3d(488.632598876953,50.8816299438477,24.0011005401611), Vec3d(488.632598876953,50.8850326538086,30.0011005401611), Vec3d(488.632598876953,49.7480316162109,24.0011005401611), Vec3d(488.632598876953,49.7426300048828,24.0011005401611), Vec3d(488.632598876953,49.745231628418,30.0011005401611), Vec3d(488.632598876953,49.7592315673828,24.0011005401611), Vec3d(488.632598876953,49.7536315917969,30.0011005401611), Vec3d(488.632598876953,49.3900299072266,24.0011005401611), Vec3d(488.632598876953,49.5664329528809,30.0011005401611), Vec3d(488.632598876953,50.8786315917969,24.0011005401611), Vec3d(488.632598876953,50.7764320373535,24.0011005401611), Vec3d(488.632598876953,50.8274307250977,30.0011005401611), Vec3d(488.632598876953,50.7550315856934,30.0011005401611), Vec3d(488.632598876953,50.7692337036133,30.0011005401611), Vec3d(488.632598876953,50.9284324645996,24.0011005401611), Vec3d(488.632598876953,50.9202308654785,30.0011005401611), Vec3d(488.632598876953,51.1788330078125,24.0011005401611), Vec3d(488.632598876953,51.139232635498,24.0011005401611), Vec3d(488.632598876953,51.1590309143066,30.0011005401611), Vec3d(488.632598876953,51.2324333190918,24.0011005401611), Vec3d(488.632598876953,51.2056312561035,30.0011005401611), Vec3d(488.632598876953,51.4340324401855,24.0011005401611), Vec3d(488.632598876953,51.3946304321289,24.0011005401611), Vec3d(488.632598876953,51.4142303466797,30.0011005401611), Vec3d(488.632598876953,51.4498329162598,24.0011005401611), Vec3d(488.632598876953,51.5772323608398,30.0011005401611), Vec3d(488.632598876953,51.4418334960938,30.0011005401611), Vec3d(488.632598876953,51.3136329650879,30.0011005401611), Vec3d(488.632598876953,49.7714309692383,30.0011005401611), Vec3d(488.632598876953,51.0338325500488,30.0011005401611), Vec3d(488.632598876953,50.8816299438477,30.0011005401611), Vec3d(488.632598876953,50.8800315856934,30.0011005401611), Vec3d(488.632598876953,51.7188339233398,36.0009002685547), Vec3d(488.632598876953,51.7176322937012,36.0009002685547), Vec3d(488.632598876953,49.3900299072266,30.0011005401611), Vec3d(488.632598876953,50.7522315979004,30.0011005401611), Vec3d(488.632598876953,50.7522315979004,36.0009002685547), Vec3d(488.632598876953,49.7426300048828,30.0011005401611), Vec3d(488.632598876953,49.7426300048828,36.0009002685547), Vec3d(488.632598876953,49.7480316162109,30.0011005401611), Vec3d(488.632598876953,49.7480316162109,36.0009002685547), Vec3d(488.632598876953,51.715030670166,30.0011005401611), Vec3d(488.632598876953,51.715030670166,36.0009002685547), Vec3d(488.632598876953,50.7578315734863,30.0011005401611), Vec3d(488.632598876953,50.7578315734863,36.0009002685547), Vec3d(488.632598876953,50.761833190918,30.0011005401611), Vec3d(488.632598876953,50.761833190918,36.0009002685547), Vec3d(488.632598876953,50.8882331848145,30.0011005401611), Vec3d(488.632598876953,50.8882331848145,36.0009002685547), Vec3d(488.632598876953,49.7592315673828,30.0011005401611), Vec3d(488.632598876953,49.7592315673828,36.0009002685547), Vec3d(488.632598876953,51.1788330078125,30.0011005401611), Vec3d(488.632598876953,51.1788330078125,36.0009002685547), Vec3d(488.632598876953,50.9120330810547,30.0011005401611), Vec3d(488.632598876953,50.9120330810547,36.0009002685547), Vec3d(488.632598876953,51.4498329162598,30.0011005401611), Vec3d(488.632598876953,51.4498329162598,36.0009002685547), Vec3d(488.632598876953,51.7046318054199,30.0011005401611), Vec3d(488.632598876953,51.7046318054199,36.0009002685547), Vec3d(488.632598876953,51.2324333190918,30.0011005401611), Vec3d(488.632598876953,51.2324333190918,36.0009002685547), Vec3d(488.632598876953,51.3946304321289,30.0011005401611), Vec3d(488.632598876953,51.3946304321289,36.0009002685547), Vec3d(488.632598876953,51.4340324401855,30.0011005401611), Vec3d(488.632598876953,51.4340324401855,36.0009002685547), Vec3d(488.632598876953,49.7838325500488,30.0011005401611), Vec3d(488.632598876953,49.7838325500488,36.0009002685547), Vec3d(488.632598876953,50.7764320373535,30.0011005401611), Vec3d(488.632598876953,50.7764320373535,36.0009002685547), Vec3d(488.632598876953,51.139232635498,30.0011005401611), Vec3d(488.632598876953,51.139232635498,36.0009002685547), Vec3d(488.632598876953,50.9284324645996,30.0011005401611), Vec3d(488.632598876953,50.9284324645996,36.0009002685547), Vec3d(488.632598876953,50.8816299438477,36.0009002685547), Vec3d(488.632598876953,50.8786315917969,30.0011005401611), Vec3d(488.632598876953,50.8786315917969,36.0009002685547), Vec3d(488.632598876953,51.7324333190918,35.0173034667969), Vec3d(488.632598876953,51.7324333190918,36.0009002685547), Vec3d(488.632598876953,51.7324333190918,30.9847011566162), Vec3d(517.188415527344,51.7140884399414,24.0011005401611), Vec3d(517.188415527344,51.7140884399414,36.0009002685547), Vec3d(517.188415527344,50.4475173950195,24.0011005401611), Vec3d(517.188415527344,51.7324333190918,35.3734130859375), Vec3d(517.188415527344,51.7324333190918,36.0009002685547), Vec3d(517.188415527344,51.7324333190918,34.1185760498047), Vec3d(517.188415527344,51.7324333190918,31.88330078125), Vec3d(517.188415527344,51.7324333190918,30.0011005401611), Vec3d(517.188415527344,51.7324333190918,28.1187744140625), Vec3d(517.188415527344,51.7324333190918,25.8834266662598), Vec3d(517.188415527344,51.7324333190918,24.6285915374756), Vec3d(517.188415527344,51.7324333190918,24.0011005401611), Vec3d(517.188415527344,47.7324333190918,24.0600452423096), Vec3d(517.188415527344,47.7324333190918,24.0011005401611), Vec3d(517.188415527344,50.4475173950195,36.0009002685547), Vec3d(517.188415527344,47.7324333190918,24.1779975891113), Vec3d(517.188415527344,47.7324333190918,24.6498031616211), Vec3d(517.188415527344,47.7324333190918,28.7625770568848), Vec3d(517.188415527344,47.7324333190918,29.7061901092529), Vec3d(517.188415527344,47.7324333190918,29.9420928955078), Vec3d(517.188415527344,47.7324333190918,30.0600452423096), Vec3d(517.188415527344,47.7324333190918,30.2959480285645), Vec3d(517.188415527344,47.7324333190918,31.2395629882812), Vec3d(517.188415527344,47.7324333190918,35.3521995544434), Vec3d(517.188415527344,47.7324333190918,35.8240051269531), Vec3d(517.188415527344,47.7324333190918,35.9419555664062), Vec3d(517.188415527344,47.7324333190918,36.0009002685547) + vertices = std::vector{ + Vec3f(513.075988769531,51.6074333190918,36.0009002685547), Vec3f(516.648803710938,51.7324333190918,36.0009002685547), Vec3f(513.495178222656,51.7324333190918,36.0009002685547), Vec3f(489.391204833984,51.4824333190918,24.0011005401611), Vec3f(488.928588867188,51.7324333190918,24.0011005401611), Vec3f(492.06201171875,51.7324333190918,24.0011005401611), Vec3f(496.840393066406,51.2324333190918,24.0011005401611), Vec3f(495.195404052734,51.7324333190918,24.0011005401611), Vec3f(498.981994628906,51.7324333190918,24.0011005401611), Vec3f(506.966613769531,51.6074333190918,24.0011005401611), Vec3f(510.342010498047,51.7324333190918,24.0011005401611), Vec3f(507.163818359375,51.6074333190918,24.0011005401611), Vec3f(512.515380859375,54.7190322875977,36.0009002685547), Vec3f(514.161987304688,54.5058326721191,36.0009002685547), Vec3f(493.06201171875,54.7190322875977,36.0009002685547), Vec3f(495.195404052734,51.7324333190918,36.0009002685547), Vec3f(496.195404052734,54.7190322875977,36.0009002685547), Vec3f(497.195404052734,57.7058334350586,36.0009002685547), Vec3f(500.851989746094,60.2658309936523,36.0009002685547), Vec3f(498.915405273438,62.8258323669434,36.0009002685547), Vec3f(506.701995849609,62.8258323669434,36.0009002685547), Vec3f(503.648590087891,60.2658309936523,36.0009002685547), Vec3f(508.381805419922,57.7058334350586,36.0009002685547), Vec3f(496.418792724609,60.052433013916,36.0009002685547), Vec3f(506.515197753906,72.2124328613281,36.0009002685547), Vec3f(502.808807373047,74.5324325561523,36.0009002685547), Vec3f(503.781982421875,71.6058349609375,36.0009002685547), Vec3f(515.358764648438,55.4658317565918,36.0009002685547), Vec3f(499.375183105469,76.9058380126953,36.0009002685547), Vec3f(501.168792724609,78.0658340454102,36.0009002685547), Vec3f(504.568786621094,78.0658340454102,36.0009002685547), Vec3f(506.32861328125,81.599235534668,36.0009002685547), Vec3f(502.928588867188,81.599235534668,36.0009002685547), Vec3f(499.528594970703,81.599235534668,36.0009002685547), Vec3f(498.20361328125,77.8658294677734,36.0009002685547), Vec3f(495.195404052734,51.7324333190918,30.0011005401611), Vec3f(498.981994628906,51.7324333190918,27.0011005401611), Vec3f(506.555206298828,51.7324333190918,33.0009002685547), Vec3f(506.555206298828,51.7324333190918,36.0009002685547), Vec3f(510.342010498047,51.7324333190918,36.0009002685547), Vec3f(512.515380859375,54.7190322875977,24.0011005401611), Vec3f(509.361999511719,54.7190322875977,24.0011005401611), Vec3f(508.381805419922,57.7058334350586,24.0011005401611), Vec3f(506.701995849609,62.8258323669434,24.0011005401611), Vec3f(509.188812255859,60.052433013916,24.0011005401611), Vec3f(493.06201171875,54.7190322875977,24.0011005401611), Vec3f(503.648590087891,60.2658309936523,24.0011005401611), Vec3f(500.851989746094,60.2658309936523,24.0011005401611), Vec3f(498.915405273438,62.8258323669434,24.0011005401611), Vec3f(502.808807373047,62.8258323669434,24.0011005401611), Vec3f(491.425201416016,54.5058326721191,24.0011005401611), Vec3f(506.421813964844,76.9058380126953,24.0011005401611), Vec3f(502.808807373047,74.5324325561523,24.0011005401611), Vec3f(504.568786621094,78.0658340454102,24.0011005401611), Vec3f(506.32861328125,81.599235534668,24.0011005401611), Vec3f(507.618804931641,77.8658294677734,24.0011005401611), Vec3f(499.221801757812,72.2124328613281,24.0011005401611), Vec3f(501.835388183594,71.6058349609375,24.0011005401611), Vec3f(501.168792724609,78.0658340454102,24.0011005401611), Vec3f(499.528594970703,81.599235534668,24.0011005401611), Vec3f(502.048583984375,79.8324356079102,24.0011005401611), Vec3f(490.253601074219,55.4658317565918,24.0011005401611), Vec3f(488.928588867188,51.7324333190918,30.0011005401611), Vec3f(488.928588867188,51.7324333190918,36.0009002685547), Vec3f(490.253601074219,55.4658317565918,31.5009002685547), Vec3f(498.20361328125,77.8658294677734,34.5009002685547), Vec3f(508.381805419922,57.7058334350586,30.0011005401611), Vec3f(505.585388183594,57.7058334350586,27.0011005401611), Vec3f(502.788818359375,57.7058334350586,36.0009002685547), Vec3f(499.992004394531,57.7058334350586,33.0009002685547), Vec3f(509.851989746094,53.2258338928223,33.0009002685547), Vec3f(509.361999511719,54.7190322875977,36.0009002685547), Vec3f(508.871795654297,56.2124328613281,27.0011005401611), Vec3f(496.695404052734,56.2124328613281,33.0009002685547), Vec3f(495.695404052734,53.2258338928223,27.0011005401611), Vec3f(506.32861328125,81.599235534668,30.0011005401611), Vec3f(507.618804931641,77.8658294677734,25.5011005401611), Vec3f(515.358764648438,55.4658317565918,34.5009002685547), Vec3f(501.228607177734,81.599235534668,33.0009002685547), Vec3f(504.628601074219,81.599235534668,27.0011005401611), Vec3f(503.781982421875,71.6058349609375,33.0009002685547), Vec3f(502.808807373047,74.5324325561523,30.0011005401611), Vec3f(498.915405273438,62.8258323669434,30.0011005401611), Vec3f(500.861999511719,62.8258323669434,27.0011005401611), Vec3f(502.808807373047,62.8258323669434,36.0009002685547), Vec3f(504.755187988281,62.8258323669434,33.0009002685547), Vec3f(501.835388183594,71.6058349609375,33.0009002685547), Vec3f(499.888793945312,65.7524337768555,33.0009002685547), Vec3f(499.888793945312,65.7524337768555,36.0009002685547), Vec3f(513.128601074219,51.4824333190918,36.0009002685547), Vec3f(513.075988769531,51.6074333190918,24.0011005401611), Vec3f(516.648803710938,51.7324333190918,24.0011005401611), Vec3f(513.128601074219,51.4824333190918,24.0011005401611), Vec3f(513.495178222656,51.7324333190918,24.0011005401611), Vec3f(506.966613769531,51.6074333190918,36.0009002685547), Vec3f(507.163818359375,51.6074333190918,36.0009002685547), Vec3f(490.337799072266,51.4824333190918,24.0011005401611), Vec3f(489.391204833984,51.4824333190918,36.0009002685547), Vec3f(492.06201171875,51.7324333190918,36.0009002685547), Vec3f(490.337799072266,51.4824333190918,36.0009002685547), Vec3f(513.233764648438,51.2324333190918,24.0011005401611), Vec3f(513.233764648438,51.2324333190918,36.0009002685547), Vec3f(504.773803710938,51.4824333190918,36.0009002685547), Vec3f(504.773803710938,51.4824333190918,24.0011005401611), Vec3f(489.266998291016,51.2324333190918,24.0011005401611), Vec3f(489.266998291016,51.2324333190918,36.0009002685547), Vec3f(490.253601074219,55.4658317565918,25.5011005401611), Vec3f(499.528594970703,81.599235534668,30.0011005401611), Vec3f(498.20361328125,77.8658294677734,31.5009002685547), Vec3f(515.358764648438,55.4658317565918,28.5011005401611), Vec3f(515.358764648438,55.4658317565918,25.5011005401611), Vec3f(495.246795654297,61.0124320983887,36.0009002685547), Vec3f(490.253601074219,55.4658317565918,34.5009002685547), Vec3f(490.253601074219,55.4658317565918,36.0009002685547), Vec3f(494.228607177734,66.6658325195312,24.0011005401611), Vec3f(499.068786621094,67.5192337036133,24.0011005401611), Vec3f(498.20361328125,77.8658294677734,25.5011005401611), Vec3f(498.20361328125,77.8658294677734,24.0011005401611), Vec3f(506.608795166016,67.5192337036133,36.0009002685547), Vec3f(509.09521484375,64.7458343505859,36.0009002685547), Vec3f(507.618804931641,77.8658294677734,34.5009002685547), Vec3f(507.618804931641,77.8658294677734,36.0009002685547), Vec3f(510.385406494141,61.0124320983887,24.0011005401611), Vec3f(515.358764648438,55.4658317565918,24.0011005401611), Vec3f(489.32861328125,47.7324333190918,31.5009002685547), Vec3f(492.95361328125,47.7324333190918,33.5634994506836), Vec3f(489.32861328125,47.7324333190918,34.5009002685547), Vec3f(489.32861328125,47.7324333190918,28.5011005401611), Vec3f(489.32861328125,47.7324333190918,25.5011005401611), Vec3f(492.95361328125,47.7324333190918,26.4385013580322), Vec3f(492.95361328125,47.7324333190918,30.5635013580322), Vec3f(492.95361328125,47.7324333190918,32.0634994506836), Vec3f(492.95361328125,47.7324333190918,31.3135013580322), Vec3f(492.95361328125,47.7324333190918,35.4384994506836), Vec3f(489.32861328125,47.7324333190918,36.0009002685547), Vec3f(492.95361328125,47.7324333190918,34.3134994506836), Vec3f(492.95361328125,47.7324333190918,34.6884994506836), Vec3f(492.95361328125,47.7324333190918,27.9385013580322), Vec3f(492.95361328125,47.7324333190918,28.6885013580322), Vec3f(492.95361328125,47.7324333190918,29.0635013580322), Vec3f(489.32861328125,47.7324333190918,24.0011005401611), Vec3f(492.95361328125,47.7324333190918,24.5635013580322), Vec3f(492.95361328125,47.7324333190918,25.6885013580322), Vec3f(492.95361328125,47.7324333190918,25.3135013580322), Vec3f(492.95361328125,47.7324333190918,24.1885013580322), Vec3f(492.95361328125,47.7324333190918,24.0011005401611), Vec3f(513.443786621094,50.7324333190918,24.0011005401611), Vec3f(492.95361328125,47.7324333190918,35.8134994506836), Vec3f(492.95361328125,47.7324333190918,36.0009002685547), Vec3f(513.443786621094,50.7324333190918,36.0009002685547), Vec3f(506.350402832031,51.4824333190918,36.0009002685547), Vec3f(506.350402832031,51.4824333190918,24.0011005401611), Vec3f(492.743804931641,48.2324333190918,24.0011005401611), Vec3f(492.638793945312,48.4824333190918,24.0011005401611), Vec3f(492.743804931641,48.2324333190918,36.0009002685547), Vec3f(492.638793945312,48.4824333190918,36.0009002685547), Vec3f(490.089599609375,50.9824333190918,36.0009002685547), Vec3f(490.089599609375,50.9824333190918,24.0011005401611), Vec3f(510.342010498047,51.7324333190918,30.0011005401611), Vec3f(499.068786621094,67.5192337036133,36.0009002685547), Vec3f(494.228607177734,66.6658325195312,36.0009002685547), Vec3f(499.375183105469,76.9058380126953,24.0011005401611), Vec3f(506.421813964844,76.9058380126953,36.0009002685547), Vec3f(506.608795166016,67.5192337036133,24.0011005401611), Vec3f(505.728607177734,65.7524337768555,24.0011005401611), Vec3f(509.09521484375,64.7458343505859,24.0011005401611), Vec3f(506.701995849609,62.8258323669434,30.0011005401611), Vec3f(505.728607177734,65.7524337768555,27.0011005401611), Vec3f(501.835388183594,71.6058349609375,27.0011005401611), Vec3f(499.888793945312,65.7524337768555,27.0011005401611), Vec3f(494.228607177734,66.6658325195312,30.0011005401611), Vec3f(495.553588867188,70.3992309570312,28.5011005401611), Vec3f(492.903594970703,62.9324340820312,28.5011005401611), Vec3f(495.553588867188,70.3992309570312,31.5009002685547), Vec3f(492.903594970703,62.9324340820312,31.5009002685547), Vec3f(511.488800048828,66.6658325195312,24.0011005401611), Vec3f(511.488800048828,66.6658325195312,30.0011005401611), Vec3f(512.778564453125,62.9324340820312,28.5011005401611), Vec3f(515.358764648438,55.4658317565918,31.5009002685547), Vec3f(507.618804931641,77.8658294677734,31.5009002685547), Vec3f(510.198791503906,70.3992309570312,28.5011005401611), Vec3f(511.488800048828,66.6658325195312,36.0009002685547), Vec3f(512.778564453125,62.9324340820312,31.5009002685547), Vec3f(510.198791503906,70.3992309570312,31.5009002685547), Vec3f(502.788818359375,57.7058334350586,24.0011005401611), Vec3f(497.195404052734,57.7058334350586,30.0011005401611), Vec3f(492.903594970703,62.9324340820312,34.5009002685547), Vec3f(492.903594970703,62.9324340820312,36.0009002685547), Vec3f(495.553588867188,70.3992309570312,24.0011005401611), Vec3f(496.725189208984,69.4392318725586,24.0011005401611), Vec3f(495.553588867188,70.3992309570312,25.5011005401611), Vec3f(495.246795654297,61.0124320983887,24.0011005401611), Vec3f(492.903594970703,62.9324340820312,25.5011005401611), Vec3f(492.903594970703,62.9324340820312,24.0011005401611), Vec3f(495.553588867188,70.3992309570312,36.0009002685547), Vec3f(496.725189208984,69.4392318725586,36.0009002685547), Vec3f(495.553588867188,70.3992309570312,34.5009002685547), Vec3f(510.198791503906,70.3992309570312,36.0009002685547), Vec3f(509.002014160156,69.4392318725586,36.0009002685547), Vec3f(510.198791503906,70.3992309570312,34.5009002685547), Vec3f(512.778564453125,62.9324340820312,25.5011005401611), Vec3f(512.778564453125,62.9324340820312,24.0011005401611), Vec3f(510.198791503906,70.3992309570312,24.0011005401611), Vec3f(509.002014160156,69.4392318725586,24.0011005401611), Vec3f(510.198791503906,70.3992309570312,25.5011005401611), Vec3f(510.385406494141,61.0124320983887,36.0009002685547), Vec3f(512.778564453125,62.9324340820312,34.5009002685547), Vec3f(512.778564453125,62.9324340820312,36.0009002685547), Vec3f(496.840393066406,51.2324333190918,36.0009002685547), Vec3f(498.981994628906,51.7324333190918,36.0009002685547), Vec3f(498.981994628906,51.7324333190918,33.0009002685547), Vec3f(506.555206298828,51.7324333190918,24.0011005401611), Vec3f(506.555206298828,51.7324333190918,27.0011005401611), Vec3f(503.82861328125,47.7324333190918,30.7509002685547), Vec3f(507.45361328125,47.7324333190918,32.8134994506836), Vec3f(503.82861328125,47.7324333190918,33.7509002685547), Vec3f(503.82861328125,47.7324333190918,29.2511005401611), Vec3f(503.82861328125,47.7324333190918,26.2511005401611), Vec3f(507.45361328125,47.7324333190918,27.1885013580322), Vec3f(493.921813964844,57.2792320251465,36.0009002685547), Vec3f(491.425201416016,54.5058326721191,36.0009002685547), Vec3f(497.195404052734,57.7058334350586,24.0011005401611), Vec3f(496.418792724609,60.052433013916,24.0011005401611), Vec3f(509.188812255859,60.052433013916,36.0009002685547), Vec3f(511.675415039062,57.2792320251465,24.0011005401611), Vec3f(514.161987304688,54.5058326721191,24.0011005401611), Vec3f(507.45361328125,47.7324333190918,34.3134994506836), Vec3f(503.82861328125,47.7324333190918,35.2509002685547), Vec3f(507.45361328125,47.7324333190918,25.6885013580322), Vec3f(503.82861328125,47.7324333190918,24.7511005401611), Vec3f(500.20361328125,47.7324333190918,31.6885013580322), Vec3f(500.20361328125,47.7324333190918,28.3135013580322), Vec3f(500.20361328125,47.7324333190918,30.1885013580322), Vec3f(507.45361328125,47.7324333190918,29.8135013580322), Vec3f(507.45361328125,47.7324333190918,31.3135013580322), Vec3f(507.45361328125,47.7324333190918,30.5635013580322), Vec3f(503.82861328125,47.7324333190918,36.0009002685547), Vec3f(507.45361328125,47.7324333190918,35.4384994506836), Vec3f(507.45361328125,47.7324333190918,35.0634994506836), Vec3f(507.45361328125,47.7324333190918,28.6885013580322), Vec3f(507.45361328125,47.7324333190918,29.4385013580322), Vec3f(503.82861328125,47.7324333190918,24.0011005401611), Vec3f(507.45361328125,47.7324333190918,24.5635013580322), Vec3f(507.45361328125,47.7324333190918,24.9385013580322), Vec3f(500.20361328125,47.7324333190918,34.6884994506836), Vec3f(500.20361328125,47.7324333190918,33.1884994506836), Vec3f(500.20361328125,47.7324333190918,33.9384994506836), Vec3f(500.20361328125,47.7324333190918,25.3135013580322), Vec3f(500.20361328125,47.7324333190918,26.8135013580322), Vec3f(500.20361328125,47.7324333190918,26.0635013580322), Vec3f(500.20361328125,47.7324333190918,30.9385013580322), Vec3f(500.20361328125,47.7324333190918,35.0634994506836), Vec3f(500.20361328125,47.7324333190918,35.4384994506836), Vec3f(500.20361328125,47.7324333190918,29.0635013580322), Vec3f(500.20361328125,47.7324333190918,29.4385013580322), Vec3f(500.20361328125,47.7324333190918,24.9385013580322), Vec3f(500.20361328125,47.7324333190918,24.5635013580322), Vec3f(507.45361328125,47.7324333190918,24.1885013580322), Vec3f(507.45361328125,47.7324333190918,24.0011005401611), Vec3f(513.86376953125,49.7324333190918,24.0011005401611), Vec3f(507.45361328125,47.7324333190918,35.8134994506836), Vec3f(507.45361328125,47.7324333190918,36.0009002685547), Vec3f(513.86376953125,49.7324333190918,36.0009002685547), Vec3f(500.20361328125,47.7324333190918,24.1885013580322), Vec3f(500.20361328125,47.7324333190918,24.0011005401611), Vec3f(502.988800048828,49.7324333190918,24.0011005401611), Vec3f(500.20361328125,47.7324333190918,35.8134994506836), Vec3f(500.20361328125,47.7324333190918,36.0009002685547), Vec3f(502.988800048828,49.7324333190918,36.0009002685547), Vec3f(504.755187988281,62.8258323669434,27.0011005401611), Vec3f(499.205383300781,51.2324333190918,36.0009002685547), Vec3f(498.786193847656,51.1074333190918,36.0009002685547), Vec3f(502.358795166016,51.2324333190918,36.0009002685547), Vec3f(499.205383300781,51.2324333190918,24.0011005401611), Vec3f(502.358795166016,51.2324333190918,24.0011005401611), Vec3f(498.786193847656,51.1074333190918,24.0011005401611), Vec3f(502.568786621094,50.7324333190918,24.0011005401611), Vec3f(505.931213378906,51.3574333190918,24.0011005401611), Vec3f(509.503601074219,51.4824333190918,24.0011005401611), Vec3f(502.568786621094,50.7324333190918,36.0009002685547), Vec3f(505.931213378906,51.3574333190918,36.0009002685547), Vec3f(509.503601074219,51.4824333190918,36.0009002685547), Vec3f(499.048583984375,50.4824333190918,36.0009002685547), Vec3f(492.428588867188,48.9824333190918,36.0009002685547), Vec3f(499.048583984375,50.4824333190918,24.0011005401611), Vec3f(492.428588867188,48.9824333190918,24.0011005401611), Vec3f(506.088806152344,50.9824333190918,24.0011005401611), Vec3f(506.036010742188,51.1074333190918,24.0011005401611), Vec3f(506.088806152344,50.9824333190918,36.0009002685547), Vec3f(506.036010742188,51.1074333190918,36.0009002685547), Vec3f(498.891204833984,50.8574333190918,36.0009002685547), Vec3f(498.943786621094,50.7324333190918,36.0009002685547), Vec3f(498.891204833984,50.8574333190918,24.0011005401611), Vec3f(498.943786621094,50.7324333190918,24.0011005401611), Vec3f(499.573608398438,49.2324333190918,24.0011005401611), Vec3f(499.783813476562,48.7324333190918,24.0011005401611), Vec3f(499.573608398438,49.2324333190918,36.0009002685547), Vec3f(499.783813476562,48.7324333190918,36.0009002685547), Vec3f(506.403594970703,50.2324333190918,24.0011005401611), Vec3f(506.298797607422,50.4824333190918,24.0011005401611), Vec3f(506.403594970703,50.2324333190918,36.0009002685547), Vec3f(506.298797607422,50.4824333190918,36.0009002685547), Vec3f(501.228607177734,81.599235534668,27.0011005401611), Vec3f(502.928588867188,81.599235534668,24.0011005401611), Vec3f(499.2587890625,49.9824333190918,36.0009002685547), Vec3f(499.363800048828,49.7324333190918,36.0009002685547), Vec3f(499.2587890625,49.9824333190918,24.0011005401611), Vec3f(499.363800048828,49.7324333190918,24.0011005401611), Vec3f(496.695404052734,56.2124328613281,27.0011005401611), Vec3f(496.195404052734,54.7190322875977,24.0011005401611), Vec3f(509.851989746094,53.2258338928223,27.0011005401611), Vec3f(493.464782714844,51.1074333190918,36.0009002685547), Vec3f(493.464782714844,51.1074333190918,24.0011005401611), Vec3f(502.768798828125,51.7324333190918,24.0011005401611), Vec3f(500.215789794922,51.3574333190918,24.0011005401611), Vec3f(497.628601074219,51.2324333190918,24.0011005401611), Vec3f(502.768798828125,51.7324333190918,36.0009002685547), Vec3f(500.215789794922,51.3574333190918,36.0009002685547), Vec3f(497.628601074219,51.2324333190918,36.0009002685547), Vec3f(507.033813476562,48.7324333190918,24.0011005401611), Vec3f(506.823791503906,49.2324333190918,24.0011005401611), Vec3f(507.033813476562,48.7324333190918,36.0009002685547), Vec3f(506.823791503906,49.2324333190918,36.0009002685547), Vec3f(494.4501953125,51.1074333190918,24.0011005401611), Vec3f(494.4501953125,51.1074333190918,36.0009002685547), Vec3f(500.807006835938,51.3574333190918,36.0009002685547), Vec3f(503.591186523438,51.4824333190918,36.0009002685547), Vec3f(503.591186523438,51.4824333190918,24.0011005401611), Vec3f(500.807006835938,51.3574333190918,24.0011005401611), Vec3f(505.728607177734,65.7524337768555,36.0009002685547), Vec3f(505.728607177734,65.7524337768555,33.0009002685547), Vec3f(499.221801757812,72.2124328613281,36.0009002685547), Vec3f(501.835388183594,71.6058349609375,36.0009002685547), Vec3f(506.515197753906,72.2124328613281,24.0011005401611), Vec3f(503.781982421875,71.6058349609375,24.0011005401611), Vec3f(503.781982421875,71.6058349609375,27.0011005401611), Vec3f(499.888793945312,65.7524337768555,24.0011005401611), Vec3f(495.695404052734,53.2258338928223,33.0009002685547), Vec3f(516.648803710938,51.7324333190918,30.0011005401611), Vec3f(498.20361328125,77.8658294677734,28.5011005401611), Vec3f(505.585388183594,57.7058334350586,33.0009002685547), Vec3f(508.871795654297,56.2124328613281,33.0009002685547), Vec3f(499.992004394531,57.7058334350586,27.0011005401611), Vec3f(504.628601074219,81.599235534668,33.0009002685547), Vec3f(500.861999511719,62.8258323669434,33.0009002685547), Vec3f(496.878601074219,74.1324310302734,27.0011005401611), Vec3f(496.878601074219,74.1324310302734,33.0009002685547), Vec3f(491.57861328125,59.199031829834,27.0011005401611), Vec3f(490.253601074219,55.4658317565918,28.5011005401611), Vec3f(491.57861328125,59.199031829834,33.0009002685547), Vec3f(514.068786621094,59.199031829834,27.0011005401611), Vec3f(514.068786621094,59.199031829834,33.0009002685547), Vec3f(508.908813476562,74.1324310302734,27.0011005401611), Vec3f(507.618804931641,77.8658294677734,28.5011005401611), Vec3f(508.908813476562,74.1324310302734,33.0009002685547), Vec3f(491.271789550781,50.9824333190918,36.0009002685547), Vec3f(490.877807617188,50.9824333190918,36.0009002685547), Vec3f(491.271789550781,50.9824333190918,24.0011005401611), Vec3f(490.877807617188,50.9824333190918,24.0011005401611), Vec3f(495.213806152344,50.9824333190918,36.0009002685547), Vec3f(493.636993408203,50.9824333190918,36.0009002685547), Vec3f(495.213806152344,50.9824333190918,24.0011005401611), Vec3f(493.636993408203,50.9824333190918,24.0011005401611), Vec3f(503.985412597656,51.4824333190918,36.0009002685547), Vec3f(503.985412597656,51.4824333190918,24.0011005401611), Vec3f(511.675415039062,57.2792320251465,36.0009002685547), Vec3f(493.921813964844,57.2792320251465,24.0011005401611), Vec3f(502.768798828125,51.7324333190918,30.0011005401611), Vec3f(506.555206298828,51.7324333190918,30.0011005401611), Vec3f(498.981994628906,51.7324333190918,30.0011005401611), Vec3f(492.848815917969,50.9824333190918,24.0011005401611), Vec3f(492.848815917969,50.9824333190918,36.0009002685547), Vec3f(500.861999511719,68.6792297363281,36.0009002685547), Vec3f(500.861999511719,68.6792297363281,24.0011005401611), Vec3f(496.878601074219,74.1324310302734,24.0011005401611), Vec3f(496.878601074219,74.1324310302734,36.0009002685547), Vec3f(504.755187988281,68.6792297363281,24.0011005401611), Vec3f(504.755187988281,68.6792297363281,36.0009002685547), Vec3f(508.908813476562,74.1324310302734,36.0009002685547), Vec3f(508.908813476562,74.1324310302734,24.0011005401611), Vec3f(505.728607177734,65.7524337768555,30.0011005401611), Vec3f(504.755187988281,68.6792297363281,30.0011005401611), Vec3f(503.781982421875,71.6058349609375,30.0011005401611), Vec3f(500.861999511719,68.6792297363281,30.0011005401611), Vec3f(499.888793945312,65.7524337768555,30.0011005401611), Vec3f(501.835388183594,71.6058349609375,30.0011005401611), Vec3f(491.57861328125,59.199031829834,24.0011005401611), Vec3f(491.57861328125,59.199031829834,36.0009002685547), Vec3f(514.068786621094,59.199031829834,36.0009002685547), Vec3f(514.068786621094,59.199031829834,24.0011005401611), Vec3f(511.07861328125,47.7324333190918,34.8759002685547), Vec3f(511.07861328125,47.7324333190918,31.8759002685547), Vec3f(514.70361328125,47.7324333190918,33.9384994506836), Vec3f(511.07861328125,47.7324333190918,25.1261005401611), Vec3f(514.70361328125,47.7324333190918,26.0635013580322), Vec3f(511.07861328125,47.7324333190918,28.1261005401611), Vec3f(502.788818359375,57.7058334350586,30.0011005401611), Vec3f(502.048583984375,79.8324356079102,36.0009002685547), Vec3f(514.70361328125,47.7324333190918,30.9385013580322), Vec3f(511.07861328125,47.7324333190918,30.3759002685547), Vec3f(514.70361328125,47.7324333190918,29.0635013580322), Vec3f(511.07861328125,47.7324333190918,29.6261005401611), Vec3f(496.57861328125,47.7324333190918,31.1259002685547), Vec3f(496.57861328125,47.7324333190918,32.6259002685547), Vec3f(496.57861328125,47.7324333190918,34.1259002685547), Vec3f(496.57861328125,47.7324333190918,28.8761005401611), Vec3f(496.57861328125,47.7324333190918,27.3761005401611), Vec3f(496.57861328125,47.7324333190918,25.8761005401611), Vec3f(496.57861328125,47.7324333190918,29.6261005401611), Vec3f(514.70361328125,47.7324333190918,35.4384994506836), Vec3f(511.07861328125,47.7324333190918,35.6259002685547), Vec3f(514.70361328125,47.7324333190918,24.5635013580322), Vec3f(511.07861328125,47.7324333190918,24.3761005401611), Vec3f(496.57861328125,47.7324333190918,34.8759002685547), Vec3f(496.57861328125,47.7324333190918,25.1261005401611), Vec3f(496.57861328125,47.7324333190918,35.6259002685547), Vec3f(496.57861328125,47.7324333190918,24.3761005401611), Vec3f(511.07861328125,47.7324333190918,36.0009002685547), Vec3f(511.07861328125,47.7324333190918,24.0011005401611), Vec3f(514.70361328125,47.7324333190918,30.1885013580322), Vec3f(514.70361328125,47.7324333190918,35.8134994506836), Vec3f(514.70361328125,47.7324333190918,29.8135013580322), Vec3f(514.70361328125,47.7324333190918,24.1885013580322), Vec3f(496.57861328125,47.7324333190918,36.0009002685547), Vec3f(496.57861328125,47.7324333190918,24.0011005401611), Vec3f(510.238800048828,49.7324333190918,24.0011005401611), Vec3f(510.238800048828,49.7324333190918,36.0009002685547), Vec3f(514.70361328125,47.7324333190918,24.0011005401611), Vec3f(514.70361328125,47.7324333190918,36.0009002685547), Vec3f(496.158813476562,48.7324333190918,36.0009002685547), Vec3f(496.158813476562,48.7324333190918,24.0011005401611), Vec3f(502.808807373047,62.8258323669434,30.0011005401611), Vec3f(509.608795166016,51.2324333190918,24.0011005401611), Vec3f(509.608795166016,51.2324333190918,36.0009002685547), Vec3f(491.641204833984,50.8574333190918,24.0011005401611), Vec3f(495.423797607422,50.4824333190918,36.0009002685547), Vec3f(495.423797607422,50.4824333190918,24.0011005401611), Vec3f(491.641204833984,50.8574333190918,36.0009002685547), Vec3f(495.528594970703,50.2324333190918,24.0011005401611), Vec3f(492.0087890625,49.9824333190918,24.0011005401611), Vec3f(509.818786621094,50.7324333190918,24.0011005401611), Vec3f(495.948608398438,49.2324333190918,36.0009002685547), Vec3f(495.528594970703,50.2324333190918,36.0009002685547), Vec3f(495.948608398438,49.2324333190918,24.0011005401611), Vec3f(509.818786621094,50.7324333190918,36.0009002685547), Vec3f(492.0087890625,49.9824333190918,36.0009002685547), Vec3f(491.956207275391,50.1074333190918,24.0011005401611), Vec3f(491.956207275391,50.1074333190918,36.0009002685547), Vec3f(502.928588867188,81.599235534668,30.0011005401611), Vec3f(491.851013183594,50.3574333190918,36.0009002685547), Vec3f(491.851013183594,50.3574333190918,24.0011005401611), Vec3f(496.195404052734,54.7190322875977,30.0011005401611), Vec3f(509.361999511719,54.7190322875977,30.0011005401611), Vec3f(488.632598876953,51.7256317138672,30.0011005401611), Vec3f(488.632598876953,51.7256317138672,29.5091018676758), Vec3f(488.632598876953,51.7188339233398,24.0011005401611), Vec3f(488.632598876953,51.7256317138672,27.4929008483887), Vec3f(488.632598876953,51.7324333190918,30.0011005401611), Vec3f(488.632598876953,51.7324333190918,29.0175018310547), Vec3f(488.632598876953,51.7324333190918,24.9847011566162), Vec3f(488.632598876953,51.7324333190918,24.0011005401611), Vec3f(488.632598876953,51.7188339233398,30.0011005401611), Vec3f(488.632598876953,51.7176322937012,24.0011005401611), Vec3f(488.632598876953,51.7182312011719,30.0011005401611), Vec3f(488.632598876953,51.7176322937012,30.0011005401611), Vec3f(488.632598876953,51.715030670166,24.0011005401611), Vec3f(488.632598876953,51.7162322998047,30.0011005401611), Vec3f(488.632598876953,50.761833190918,24.0011005401611), Vec3f(488.632598876953,50.7578315734863,24.0011005401611), Vec3f(488.632598876953,50.7598342895508,30.0011005401611), Vec3f(488.632598876953,50.7522315979004,24.0011005401611), Vec3f(488.632598876953,49.7838325500488,24.0011005401611), Vec3f(488.632598876953,50.2680320739746,30.0011005401611), Vec3f(488.632598876953,51.7046318054199,24.0011005401611), Vec3f(488.632598876953,51.709831237793,30.0011005401611), Vec3f(488.632598876953,50.9120330810547,24.0011005401611), Vec3f(488.632598876953,50.8882331848145,24.0011005401611), Vec3f(488.632598876953,50.9002304077148,30.0011005401611), Vec3f(488.632598876953,47.7324333190918,24.0370998382568), Vec3f(488.632598876953,48.5612335205078,30.0011005401611), Vec3f(488.632598876953,47.7324333190918,24.0011005401611), Vec3f(488.632598876953,47.7324333190918,24.1091003417969), Vec3f(488.632598876953,48.5612335205078,30.0189018249512), Vec3f(488.632598876953,47.7324333190918,25.3211002349854), Vec3f(488.632598876953,48.5612335205078,30.0551013946533), Vec3f(488.632598876953,47.7324333190918,25.4651012420654), Vec3f(488.632598876953,48.5612335205078,30.6609001159668), Vec3f(488.632598876953,47.7324333190918,25.5371017456055), Vec3f(488.632598876953,48.5612335205078,30.7329006195068), Vec3f(488.632598876953,47.7324333190918,25.6091003417969), Vec3f(488.632598876953,48.5612335205078,30.7689018249512), Vec3f(488.632598876953,47.7324333190918,25.8971004486084), Vec3f(488.632598876953,48.5612335205078,30.8051013946533), Vec3f(488.632598876953,47.7324333190918,28.321102142334), Vec3f(488.632598876953,48.5612335205078,30.9491004943848), Vec3f(488.632598876953,47.7324333190918,28.4651012420654), Vec3f(488.632598876953,48.5612335205078,32.1609001159668), Vec3f(488.632598876953,47.7324333190918,28.5371017456055), Vec3f(488.632598876953,48.5612335205078,32.2329025268555), Vec3f(488.632598876953,47.7324333190918,28.6811008453369), Vec3f(488.632598876953,48.5612335205078,32.2689018249512), Vec3f(488.632598876953,47.7324333190918,31.1049003601074), Vec3f(488.632598876953,48.5612335205078,32.3411026000977), Vec3f(488.632598876953,47.7324333190918,31.3929004669189), Vec3f(488.632598876953,49.3900299072266,36.0009002685547), Vec3f(488.632598876953,47.7324333190918,31.536901473999), Vec3f(488.632598876953,47.7324333190918,31.6809005737305), Vec3f(488.632598876953,47.7324333190918,34.1049003601074), Vec3f(488.632598876953,47.7324333190918,34.3929023742676), Vec3f(488.632598876953,47.7324333190918,34.464900970459), Vec3f(488.632598876953,47.7324333190918,34.5369033813477), Vec3f(488.632598876953,47.7324333190918,34.6809005737305), Vec3f(488.632598876953,47.7324333190918,35.8929023742676), Vec3f(488.632598876953,47.7324333190918,35.964900970459), Vec3f(488.632598876953,47.7324333190918,36.0009002685547), Vec3f(488.632598876953,50.8816299438477,24.0011005401611), Vec3f(488.632598876953,50.8850326538086,30.0011005401611), Vec3f(488.632598876953,49.7480316162109,24.0011005401611), Vec3f(488.632598876953,49.7426300048828,24.0011005401611), Vec3f(488.632598876953,49.745231628418,30.0011005401611), Vec3f(488.632598876953,49.7592315673828,24.0011005401611), Vec3f(488.632598876953,49.7536315917969,30.0011005401611), Vec3f(488.632598876953,49.3900299072266,24.0011005401611), Vec3f(488.632598876953,49.5664329528809,30.0011005401611), Vec3f(488.632598876953,50.8786315917969,24.0011005401611), Vec3f(488.632598876953,50.7764320373535,24.0011005401611), Vec3f(488.632598876953,50.8274307250977,30.0011005401611), Vec3f(488.632598876953,50.7550315856934,30.0011005401611), Vec3f(488.632598876953,50.7692337036133,30.0011005401611), Vec3f(488.632598876953,50.9284324645996,24.0011005401611), Vec3f(488.632598876953,50.9202308654785,30.0011005401611), Vec3f(488.632598876953,51.1788330078125,24.0011005401611), Vec3f(488.632598876953,51.139232635498,24.0011005401611), Vec3f(488.632598876953,51.1590309143066,30.0011005401611), Vec3f(488.632598876953,51.2324333190918,24.0011005401611), Vec3f(488.632598876953,51.2056312561035,30.0011005401611), Vec3f(488.632598876953,51.4340324401855,24.0011005401611), Vec3f(488.632598876953,51.3946304321289,24.0011005401611), Vec3f(488.632598876953,51.4142303466797,30.0011005401611), Vec3f(488.632598876953,51.4498329162598,24.0011005401611), Vec3f(488.632598876953,51.5772323608398,30.0011005401611), Vec3f(488.632598876953,51.4418334960938,30.0011005401611), Vec3f(488.632598876953,51.3136329650879,30.0011005401611), Vec3f(488.632598876953,49.7714309692383,30.0011005401611), Vec3f(488.632598876953,51.0338325500488,30.0011005401611), Vec3f(488.632598876953,50.8816299438477,30.0011005401611), Vec3f(488.632598876953,50.8800315856934,30.0011005401611), Vec3f(488.632598876953,51.7188339233398,36.0009002685547), Vec3f(488.632598876953,51.7176322937012,36.0009002685547), Vec3f(488.632598876953,49.3900299072266,30.0011005401611), Vec3f(488.632598876953,50.7522315979004,30.0011005401611), Vec3f(488.632598876953,50.7522315979004,36.0009002685547), Vec3f(488.632598876953,49.7426300048828,30.0011005401611), Vec3f(488.632598876953,49.7426300048828,36.0009002685547), Vec3f(488.632598876953,49.7480316162109,30.0011005401611), Vec3f(488.632598876953,49.7480316162109,36.0009002685547), Vec3f(488.632598876953,51.715030670166,30.0011005401611), Vec3f(488.632598876953,51.715030670166,36.0009002685547), Vec3f(488.632598876953,50.7578315734863,30.0011005401611), Vec3f(488.632598876953,50.7578315734863,36.0009002685547), Vec3f(488.632598876953,50.761833190918,30.0011005401611), Vec3f(488.632598876953,50.761833190918,36.0009002685547), Vec3f(488.632598876953,50.8882331848145,30.0011005401611), Vec3f(488.632598876953,50.8882331848145,36.0009002685547), Vec3f(488.632598876953,49.7592315673828,30.0011005401611), Vec3f(488.632598876953,49.7592315673828,36.0009002685547), Vec3f(488.632598876953,51.1788330078125,30.0011005401611), Vec3f(488.632598876953,51.1788330078125,36.0009002685547), Vec3f(488.632598876953,50.9120330810547,30.0011005401611), Vec3f(488.632598876953,50.9120330810547,36.0009002685547), Vec3f(488.632598876953,51.4498329162598,30.0011005401611), Vec3f(488.632598876953,51.4498329162598,36.0009002685547), Vec3f(488.632598876953,51.7046318054199,30.0011005401611), Vec3f(488.632598876953,51.7046318054199,36.0009002685547), Vec3f(488.632598876953,51.2324333190918,30.0011005401611), Vec3f(488.632598876953,51.2324333190918,36.0009002685547), Vec3f(488.632598876953,51.3946304321289,30.0011005401611), Vec3f(488.632598876953,51.3946304321289,36.0009002685547), Vec3f(488.632598876953,51.4340324401855,30.0011005401611), Vec3f(488.632598876953,51.4340324401855,36.0009002685547), Vec3f(488.632598876953,49.7838325500488,30.0011005401611), Vec3f(488.632598876953,49.7838325500488,36.0009002685547), Vec3f(488.632598876953,50.7764320373535,30.0011005401611), Vec3f(488.632598876953,50.7764320373535,36.0009002685547), Vec3f(488.632598876953,51.139232635498,30.0011005401611), Vec3f(488.632598876953,51.139232635498,36.0009002685547), Vec3f(488.632598876953,50.9284324645996,30.0011005401611), Vec3f(488.632598876953,50.9284324645996,36.0009002685547), Vec3f(488.632598876953,50.8816299438477,36.0009002685547), Vec3f(488.632598876953,50.8786315917969,30.0011005401611), Vec3f(488.632598876953,50.8786315917969,36.0009002685547), Vec3f(488.632598876953,51.7324333190918,35.0173034667969), Vec3f(488.632598876953,51.7324333190918,36.0009002685547), Vec3f(488.632598876953,51.7324333190918,30.9847011566162), Vec3f(517.188415527344,51.7140884399414,24.0011005401611), Vec3f(517.188415527344,51.7140884399414,36.0009002685547), Vec3f(517.188415527344,50.4475173950195,24.0011005401611), Vec3f(517.188415527344,51.7324333190918,35.3734130859375), Vec3f(517.188415527344,51.7324333190918,36.0009002685547), Vec3f(517.188415527344,51.7324333190918,34.1185760498047), Vec3f(517.188415527344,51.7324333190918,31.88330078125), Vec3f(517.188415527344,51.7324333190918,30.0011005401611), Vec3f(517.188415527344,51.7324333190918,28.1187744140625), Vec3f(517.188415527344,51.7324333190918,25.8834266662598), Vec3f(517.188415527344,51.7324333190918,24.6285915374756), Vec3f(517.188415527344,51.7324333190918,24.0011005401611), Vec3f(517.188415527344,47.7324333190918,24.0600452423096), Vec3f(517.188415527344,47.7324333190918,24.0011005401611), Vec3f(517.188415527344,50.4475173950195,36.0009002685547), Vec3f(517.188415527344,47.7324333190918,24.1779975891113), Vec3f(517.188415527344,47.7324333190918,24.6498031616211), Vec3f(517.188415527344,47.7324333190918,28.7625770568848), Vec3f(517.188415527344,47.7324333190918,29.7061901092529), Vec3f(517.188415527344,47.7324333190918,29.9420928955078), Vec3f(517.188415527344,47.7324333190918,30.0600452423096), Vec3f(517.188415527344,47.7324333190918,30.2959480285645), Vec3f(517.188415527344,47.7324333190918,31.2395629882812), Vec3f(517.188415527344,47.7324333190918,35.3521995544434), Vec3f(517.188415527344,47.7324333190918,35.8240051269531), Vec3f(517.188415527344,47.7324333190918,35.9419555664062), Vec3f(517.188415527344,47.7324333190918,36.0009002685547) }; facets = std::vector{ Vec3i32(0,1,2), Vec3i32(3,4,5), Vec3i32(6,7,8), Vec3i32(9,10,11), Vec3i32(12,2,1), Vec3i32(12,1,13), Vec3i32(14,15,16), Vec3i32(17,18,19), Vec3i32(20,21,22), Vec3i32(17,19,23), Vec3i32(24,25,26), Vec3i32(27,13,1), Vec3i32(28,25,29), Vec3i32(30,31,32), Vec3i32(28,33,34), Vec3i32(35,36,7), Vec3i32(37,38,39), Vec3i32(40,10,41), Vec3i32(42,43,44), Vec3i32(45,5,4), Vec3i32(46,47,48), Vec3i32(46,48,49), Vec3i32(45,4,50), Vec3i32(51,52,53), Vec3i32(51,54,55), Vec3i32(56,52,57), Vec3i32(58,59,60), Vec3i32(61,50,4), Vec3i32(62,63,64), Vec3i32(65,34,33), Vec3i32(66,67,42), Vec3i32(68,17,69), Vec3i32(70,71,22), Vec3i32(66,42,72), Vec3i32(73,16,15), Vec3i32(35,7,74), Vec3i32(75,76,54), Vec3i32(77,27,1), Vec3i32(78,32,31), Vec3i32(75,54,79), Vec3i32(80,26,25), Vec3i32(81,80,25), Vec3i32(82,83,48), Vec3i32(84,20,85), Vec3i32(81,25,86), Vec3i32(87,88,19), Vec3i32(0,89,1), Vec3i32(90,91,92), Vec3i32(90,10,93), Vec3i32(38,94,39), Vec3i32(94,95,39), Vec3i32(3,7,96), Vec3i32(97,15,98), Vec3i32(97,99,15), Vec3i32(92,91,100), Vec3i32(89,101,1), Vec3i32(102,39,95), Vec3i32(103,11,10), Vec3i32(104,96,7), Vec3i32(105,15,99), Vec3i32(106,61,4), Vec3i32(107,108,33), Vec3i32(76,55,54), Vec3i32(109,91,110), Vec3i32(111,23,19), Vec3i32(112,63,113), Vec3i32(114,115,48), Vec3i32(116,59,117), Vec3i32(118,20,119), Vec3i32(120,31,121), Vec3i32(122,44,43), Vec3i32(110,91,123), Vec3i32(124,125,126), Vec3i32(127,128,129), Vec3i32(127,130,124), Vec3i32(131,124,132), Vec3i32(126,133,134), Vec3i32(135,136,126), Vec3i32(137,138,127), Vec3i32(139,127,138), Vec3i32(128,140,141), Vec3i32(142,128,143), Vec3i32(144,140,145), Vec3i32(100,91,146), Vec3i32(147,148,134), Vec3i32(101,149,1), Vec3i32(102,150,39), Vec3i32(103,10,151), Vec3i32(145,140,152), Vec3i32(152,140,153), Vec3i32(148,154,134), Vec3i32(154,155,134), Vec3i32(156,15,105), Vec3i32(157,104,7), Vec3i32(36,8,7), Vec3i32(158,37,39), Vec3i32(159,19,88), Vec3i32(160,19,159), Vec3i32(161,59,58), Vec3i32(161,117,59), Vec3i32(162,31,30), Vec3i32(162,121,31), Vec3i32(163,43,164), Vec3i32(163,165,43), Vec3i32(166,167,43), Vec3i32(167,164,43), Vec3i32(168,57,52), Vec3i32(82,48,169), Vec3i32(114,170,171), Vec3i32(108,65,33), Vec3i32(64,63,112), Vec3i32(114,172,170), Vec3i32(160,173,170), Vec3i32(171,170,173), Vec3i32(172,174,170), Vec3i32(160,170,174), Vec3i32(175,176,177), Vec3i32(178,77,1), Vec3i32(179,31,120), Vec3i32(175,180,176), Vec3i32(181,182,176), Vec3i32(177,176,182), Vec3i32(180,183,176), Vec3i32(181,176,183), Vec3i32(184,42,67), Vec3i32(185,69,17), Vec3i32(160,111,19), Vec3i32(186,187,160), Vec3i32(188,189,114), Vec3i32(190,188,114), Vec3i32(114,48,191), Vec3i32(192,114,193), Vec3i32(194,160,195), Vec3i32(196,160,194), Vec3i32(197,198,181), Vec3i32(199,197,181), Vec3i32(122,43,165), Vec3i32(200,201,175), Vec3i32(202,175,203), Vec3i32(204,175,202), Vec3i32(205,119,20), Vec3i32(206,181,207), Vec3i32(208,209,15), Vec3i32(210,15,209), Vec3i32(211,10,9), Vec3i32(212,10,211), Vec3i32(213,214,215), Vec3i32(216,217,218), Vec3i32(219,14,17), Vec3i32(113,63,220), Vec3i32(221,222,48), Vec3i32(191,48,222), Vec3i32(22,223,20), Vec3i32(205,20,223), Vec3i32(224,40,42), Vec3i32(123,91,225), Vec3i32(214,226,215), Vec3i32(227,215,226), Vec3i32(218,217,228), Vec3i32(229,228,217), Vec3i32(215,230,213), Vec3i32(125,135,126), Vec3i32(217,216,231), Vec3i32(129,128,142), Vec3i32(216,213,232), Vec3i32(130,132,124), Vec3i32(213,216,233), Vec3i32(234,213,235), Vec3i32(236,227,237), Vec3i32(238,237,227), Vec3i32(239,240,216), Vec3i32(233,216,240), Vec3i32(241,242,229), Vec3i32(243,229,242), Vec3i32(215,227,244), Vec3i32(245,215,246), Vec3i32(217,247,229), Vec3i32(248,249,217), Vec3i32(232,213,250), Vec3i32(230,250,213), Vec3i32(133,147,134), Vec3i32(244,227,251), Vec3i32(236,252,227), Vec3i32(251,227,252), Vec3i32(231,216,253), Vec3i32(254,253,216), Vec3i32(141,140,144), Vec3i32(247,255,229), Vec3i32(241,229,256), Vec3i32(255,256,229), Vec3i32(257,241,258), Vec3i32(259,146,91), Vec3i32(260,261,236), Vec3i32(262,1,149), Vec3i32(263,264,241), Vec3i32(265,241,264), Vec3i32(266,236,267), Vec3i32(268,267,236), Vec3i32(49,48,83), Vec3i32(166,43,269), Vec3i32(270,271,272), Vec3i32(273,274,275), Vec3i32(276,274,277), Vec3i32(278,151,10), Vec3i32(279,280,272), Vec3i32(281,39,150), Vec3i32(272,282,279), Vec3i32(155,283,134), Vec3i32(274,276,284), Vec3i32(153,140,285), Vec3i32(286,276,287), Vec3i32(265,276,286), Vec3i32(288,289,279), Vec3i32(268,288,279), Vec3i32(290,291,272), Vec3i32(271,290,272), Vec3i32(292,274,293), Vec3i32(275,274,292), Vec3i32(294,265,295), Vec3i32(276,265,294), Vec3i32(296,297,268), Vec3i32(279,296,268), Vec3i32(241,265,298), Vec3i32(298,265,299), Vec3i32(236,300,268), Vec3i32(300,301,268), Vec3i32(107,33,78), Vec3i32(302,303,59), Vec3i32(304,305,279), Vec3i32(282,304,279), Vec3i32(306,276,307), Vec3i32(284,276,306), Vec3i32(185,17,73), Vec3i32(308,309,221), Vec3i32(158,39,70), Vec3i32(310,41,10), Vec3i32(15,311,208), Vec3i32(7,6,312), Vec3i32(313,314,6), Vec3i32(315,6,314), Vec3i32(316,208,317), Vec3i32(318,317,208), Vec3i32(258,241,319), Vec3i32(319,241,320), Vec3i32(261,321,236), Vec3i32(321,322,236), Vec3i32(6,315,323), Vec3i32(208,324,318), Vec3i32(270,325,318), Vec3i32(326,318,325), Vec3i32(327,328,315), Vec3i32(273,315,328), Vec3i32(118,329,20), Vec3i32(330,20,329), Vec3i32(331,332,25), Vec3i32(86,25,332), Vec3i32(333,334,52), Vec3i32(335,52,334), Vec3i32(115,336,48), Vec3i32(169,48,336), Vec3i32(62,106,4), Vec3i32(35,15,210), Vec3i32(35,337,15), Vec3i32(158,10,212), Vec3i32(158,310,10), Vec3i32(338,178,1), Vec3i32(339,59,116), Vec3i32(107,302,59), Vec3i32(66,22,340), Vec3i32(66,341,22), Vec3i32(185,221,342), Vec3i32(185,308,221), Vec3i32(75,31,179), Vec3i32(75,343,31), Vec3i32(166,20,330), Vec3i32(166,85,20), Vec3i32(81,52,335), Vec3i32(81,168,52), Vec3i32(82,19,344), Vec3i32(82,87,19), Vec3i32(108,339,345), Vec3i32(346,108,345), Vec3i32(64,347,348), Vec3i32(349,347,64), Vec3i32(178,109,350), Vec3i32(351,178,350), Vec3i32(179,352,353), Vec3i32(354,352,179), Vec3i32(355,208,356), Vec3i32(356,208,311), Vec3i32(357,358,6), Vec3i32(358,312,6), Vec3i32(68,22,21), Vec3i32(68,340,22), Vec3i32(221,48,47), Vec3i32(184,342,221), Vec3i32(359,270,360), Vec3i32(318,360,270), Vec3i32(361,362,273), Vec3i32(315,273,362), Vec3i32(272,102,270), Vec3i32(363,270,102), Vec3i32(274,273,103), Vec3i32(364,103,273), Vec3i32(21,19,18), Vec3i32(21,20,84), Vec3i32(184,46,42), Vec3i32(43,42,46), Vec3i32(12,22,71), Vec3i32(365,22,12), Vec3i32(14,98,15), Vec3i32(14,220,63), Vec3i32(40,93,10), Vec3i32(40,225,91), Vec3i32(45,221,309), Vec3i32(366,221,45), Vec3i32(313,367,212), Vec3i32(212,367,368), Vec3i32(36,369,367), Vec3i32(313,36,367), Vec3i32(316,37,367), Vec3i32(37,368,367), Vec3i32(210,367,369), Vec3i32(316,367,210), Vec3i32(362,370,315), Vec3i32(370,323,315), Vec3i32(360,318,371), Vec3i32(371,318,324), Vec3i32(372,331,159), Vec3i32(159,195,160), Vec3i32(373,115,56), Vec3i32(115,114,189), Vec3i32(52,56,161), Vec3i32(374,161,56), Vec3i32(25,28,331), Vec3i32(375,331,28), Vec3i32(376,333,163), Vec3i32(163,203,175), Vec3i32(377,118,24), Vec3i32(118,181,198), Vec3i32(25,24,162), Vec3i32(378,162,24), Vec3i32(52,51,333), Vec3i32(379,333,51), Vec3i32(167,380,381), Vec3i32(376,167,381), Vec3i32(377,381,330), Vec3i32(330,381,380), Vec3i32(335,381,382), Vec3i32(376,381,335), Vec3i32(373,383,169), Vec3i32(169,383,384), Vec3i32(168,385,383), Vec3i32(373,168,383), Vec3i32(372,87,383), Vec3i32(87,384,383), Vec3i32(377,80,381), Vec3i32(80,382,381), Vec3i32(86,383,385), Vec3i32(372,383,86), Vec3i32(106,348,347), Vec3i32(386,106,347), Vec3i32(375,65,346), Vec3i32(108,346,65), Vec3i32(64,112,349), Vec3i32(387,349,112), Vec3i32(171,190,114), Vec3i32(346,345,171), Vec3i32(374,190,345), Vec3i32(171,345,190), Vec3i32(349,172,347), Vec3i32(172,114,192), Vec3i32(386,347,192), Vec3i32(172,192,347), Vec3i32(173,160,196), Vec3i32(171,173,346), Vec3i32(375,346,196), Vec3i32(173,196,346), Vec3i32(172,349,174), Vec3i32(174,186,160), Vec3i32(387,186,349), Vec3i32(174,349,186), Vec3i32(64,348,62), Vec3i32(106,62,348), Vec3i32(108,107,339), Vec3i32(59,339,107), Vec3i32(374,345,116), Vec3i32(339,116,345), Vec3i32(76,353,352), Vec3i32(379,76,352), Vec3i32(388,77,351), Vec3i32(178,351,77), Vec3i32(179,120,354), Vec3i32(378,354,120), Vec3i32(177,200,175), Vec3i32(351,350,177), Vec3i32(389,200,350), Vec3i32(177,350,200), Vec3i32(354,180,352), Vec3i32(180,175,204), Vec3i32(379,352,204), Vec3i32(180,204,352), Vec3i32(182,181,206), Vec3i32(177,182,351), Vec3i32(388,351,206), Vec3i32(182,206,351), Vec3i32(180,354,183), Vec3i32(183,199,181), Vec3i32(378,199,354), Vec3i32(183,354,199), Vec3i32(91,109,338), Vec3i32(178,338,109), Vec3i32(76,75,353), Vec3i32(179,353,75), Vec3i32(389,350,110), Vec3i32(109,110,350), Vec3i32(390,391,392), Vec3i32(393,394,395), Vec3i32(224,122,389), Vec3i32(122,175,201), Vec3i32(365,388,205), Vec3i32(205,207,181), Vec3i32(66,340,396), Vec3i32(68,396,340), Vec3i32(184,396,342), Vec3i32(185,342,396), Vec3i32(66,396,67), Vec3i32(184,67,396), Vec3i32(68,69,396), Vec3i32(185,396,69), Vec3i32(219,111,387), Vec3i32(111,160,187), Vec3i32(366,386,191), Vec3i32(191,193,114), Vec3i32(150,272,280), Vec3i32(102,272,150), Vec3i32(151,277,274), Vec3i32(103,151,274), Vec3i32(161,374,117), Vec3i32(116,117,374), Vec3i32(366,61,386), Vec3i32(106,386,61), Vec3i32(111,187,387), Vec3i32(186,387,187), Vec3i32(56,188,374), Vec3i32(190,374,188), Vec3i32(191,386,193), Vec3i32(192,193,386), Vec3i32(331,375,194), Vec3i32(196,194,375), Vec3i32(28,34,375), Vec3i32(65,375,34), Vec3i32(219,387,113), Vec3i32(112,113,387), Vec3i32(224,389,123), Vec3i32(110,123,389), Vec3i32(51,55,379), Vec3i32(76,379,55), Vec3i32(24,197,378), Vec3i32(199,378,197), Vec3i32(122,201,389), Vec3i32(200,389,201), Vec3i32(333,379,202), Vec3i32(204,202,379), Vec3i32(205,388,207), Vec3i32(206,207,388), Vec3i32(365,27,388), Vec3i32(77,388,27), Vec3i32(162,378,121), Vec3i32(120,121,378), Vec3i32(162,30,25), Vec3i32(30,29,25), Vec3i32(51,53,54), Vec3i32(303,60,59), Vec3i32(28,29,33), Vec3i32(29,397,33), Vec3i32(161,58,52), Vec3i32(53,52,58), Vec3i32(21,84,19), Vec3i32(84,344,19), Vec3i32(46,49,43), Vec3i32(49,269,43), Vec3i32(208,316,209), Vec3i32(210,209,316), Vec3i32(327,313,211), Vec3i32(212,211,313), Vec3i32(36,35,369), Vec3i32(210,369,35), Vec3i32(37,158,368), Vec3i32(212,368,158), Vec3i32(6,8,313), Vec3i32(36,313,8), Vec3i32(326,38,316), Vec3i32(37,316,38), Vec3i32(392,391,398), Vec3i32(399,398,391), Vec3i32(394,400,395), Vec3i32(401,395,400), Vec3i32(390,214,391), Vec3i32(214,213,234), Vec3i32(393,395,218), Vec3i32(218,239,216), Vec3i32(402,230,403), Vec3i32(230,215,245), Vec3i32(125,124,131), Vec3i32(404,125,403), Vec3i32(405,406,231), Vec3i32(231,248,217), Vec3i32(129,137,127), Vec3i32(407,406,129), Vec3i32(130,127,139), Vec3i32(402,130,408), Vec3i32(194,195,331), Vec3i32(159,331,195), Vec3i32(115,189,56), Vec3i32(188,56,189), Vec3i32(14,219,220), Vec3i32(113,220,219), Vec3i32(45,50,366), Vec3i32(61,366,50), Vec3i32(221,366,222), Vec3i32(191,222,366), Vec3i32(17,23,219), Vec3i32(111,219,23), Vec3i32(118,198,24), Vec3i32(197,24,198), Vec3i32(202,203,333), Vec3i32(163,333,203), Vec3i32(40,224,225), Vec3i32(123,225,224), Vec3i32(12,13,365), Vec3i32(27,365,13), Vec3i32(22,365,223), Vec3i32(205,223,365), Vec3i32(42,44,224), Vec3i32(122,224,44), Vec3i32(399,391,234), Vec3i32(214,234,391), Vec3i32(401,239,395), Vec3i32(218,395,239), Vec3i32(214,390,226), Vec3i32(226,238,227), Vec3i32(218,228,393), Vec3i32(228,229,243), Vec3i32(401,399,233), Vec3i32(233,235,213), Vec3i32(392,409,390), Vec3i32(410,390,409), Vec3i32(394,393,411), Vec3i32(412,411,393), Vec3i32(402,403,131), Vec3i32(125,131,403), Vec3i32(405,137,406), Vec3i32(129,406,137), Vec3i32(405,408,139), Vec3i32(130,139,408), Vec3i32(230,245,403), Vec3i32(404,403,245), Vec3i32(231,406,248), Vec3i32(407,248,406), Vec3i32(232,254,216), Vec3i32(402,408,232), Vec3i32(413,404,244), Vec3i32(244,246,215), Vec3i32(414,247,407), Vec3i32(247,217,249), Vec3i32(133,126,136), Vec3i32(415,133,413), Vec3i32(141,143,128), Vec3i32(416,414,141), Vec3i32(410,238,390), Vec3i32(226,390,238), Vec3i32(412,393,243), Vec3i32(228,243,393), Vec3i32(233,399,235), Vec3i32(234,235,399), Vec3i32(237,260,236), Vec3i32(238,410,237), Vec3i32(417,260,410), Vec3i32(237,410,260), Vec3i32(239,401,240), Vec3i32(233,240,401), Vec3i32(242,241,257), Vec3i32(243,242,412), Vec3i32(418,412,257), Vec3i32(242,257,412), Vec3i32(401,419,399), Vec3i32(398,399,419), Vec3i32(417,410,420), Vec3i32(409,420,410), Vec3i32(400,421,401), Vec3i32(419,401,421), Vec3i32(418,422,412), Vec3i32(411,412,422), Vec3i32(413,135,404), Vec3i32(125,404,135), Vec3i32(414,407,142), Vec3i32(129,142,407), Vec3i32(130,402,132), Vec3i32(131,132,402), Vec3i32(133,136,413), Vec3i32(135,413,136), Vec3i32(423,147,415), Vec3i32(133,415,147), Vec3i32(137,405,138), Vec3i32(139,138,405), Vec3i32(141,414,143), Vec3i32(142,143,414), Vec3i32(424,416,144), Vec3i32(141,144,416), Vec3i32(405,254,408), Vec3i32(232,408,254), Vec3i32(244,404,246), Vec3i32(245,246,404), Vec3i32(247,249,407), Vec3i32(248,407,249), Vec3i32(232,250,402), Vec3i32(230,402,250), Vec3i32(415,413,251), Vec3i32(244,251,413), Vec3i32(252,236,266), Vec3i32(251,252,415), Vec3i32(423,415,266), Vec3i32(252,266,415), Vec3i32(231,253,405), Vec3i32(254,405,253), Vec3i32(416,255,414), Vec3i32(247,414,255), Vec3i32(256,263,241), Vec3i32(255,416,256), Vec3i32(424,263,416), Vec3i32(256,416,263), Vec3i32(257,258,418), Vec3i32(425,418,258), Vec3i32(260,417,261), Vec3i32(426,261,417), Vec3i32(422,418,427), Vec3i32(427,259,91), Vec3i32(420,428,417), Vec3i32(428,1,262), Vec3i32(147,423,148), Vec3i32(429,148,423), Vec3i32(263,424,264), Vec3i32(264,295,265), Vec3i32(266,267,423), Vec3i32(267,268,297), Vec3i32(144,145,424), Vec3i32(430,424,145), Vec3i32(49,431,269), Vec3i32(166,269,431), Vec3i32(82,431,83), Vec3i32(49,83,431), Vec3i32(84,85,431), Vec3i32(166,431,85), Vec3i32(82,344,431), Vec3i32(84,431,344), Vec3i32(432,278,90), Vec3i32(10,90,278), Vec3i32(433,0,281), Vec3i32(39,281,0), Vec3i32(362,361,434), Vec3i32(435,271,359), Vec3i32(270,359,271), Vec3i32(436,361,275), Vec3i32(273,275,361), Vec3i32(360,437,359), Vec3i32(277,287,276), Vec3i32(151,278,277), Vec3i32(280,279,289), Vec3i32(150,280,281), Vec3i32(436,438,439), Vec3i32(439,285,140), Vec3i32(90,92,432), Vec3i32(440,432,92), Vec3i32(282,272,291), Vec3i32(441,282,442), Vec3i32(284,293,274), Vec3i32(443,438,284), Vec3i32(278,432,286), Vec3i32(286,299,265), Vec3i32(281,288,433), Vec3i32(288,268,301), Vec3i32(0,433,89), Vec3i32(444,89,433), Vec3i32(435,445,442), Vec3i32(445,134,283), Vec3i32(439,446,436), Vec3i32(361,436,446), Vec3i32(442,290,435), Vec3i32(271,435,290), Vec3i32(438,436,292), Vec3i32(275,292,436), Vec3i32(445,435,447), Vec3i32(359,447,435), Vec3i32(286,287,278), Vec3i32(277,278,287), Vec3i32(288,281,289), Vec3i32(280,289,281), Vec3i32(145,152,430), Vec3i32(443,430,152), Vec3i32(148,429,154), Vec3i32(441,154,429), Vec3i32(424,430,294), Vec3i32(294,307,276), Vec3i32(423,296,429), Vec3i32(296,279,305), Vec3i32(425,440,100), Vec3i32(92,100,440), Vec3i32(290,442,291), Vec3i32(282,291,442), Vec3i32(292,293,438), Vec3i32(284,438,293), Vec3i32(298,320,241), Vec3i32(432,440,298), Vec3i32(300,236,322), Vec3i32(433,300,444), Vec3i32(426,101,444), Vec3i32(89,444,101), Vec3i32(107,448,302), Vec3i32(302,79,54), Vec3i32(78,31,343), Vec3i32(107,78,448), Vec3i32(75,79,448), Vec3i32(302,448,79), Vec3i32(78,343,448), Vec3i32(75,448,343), Vec3i32(427,418,259), Vec3i32(425,259,418), Vec3i32(428,262,417), Vec3i32(426,417,262), Vec3i32(437,449,359), Vec3i32(447,359,449), Vec3i32(434,361,450), Vec3i32(446,450,361), Vec3i32(32,33,397), Vec3i32(78,33,32), Vec3i32(53,303,54), Vec3i32(302,54,303), Vec3i32(152,153,443), Vec3i32(438,443,153), Vec3i32(429,304,441), Vec3i32(282,441,304), Vec3i32(430,443,306), Vec3i32(284,306,443), Vec3i32(154,441,155), Vec3i32(442,155,441), Vec3i32(298,299,432), Vec3i32(286,432,299), Vec3i32(300,433,301), Vec3i32(288,301,433), Vec3i32(185,451,308), Vec3i32(308,74,7), Vec3i32(73,15,337), Vec3i32(185,73,451), Vec3i32(35,74,451), Vec3i32(308,451,74), Vec3i32(73,337,451), Vec3i32(35,451,337), Vec3i32(158,452,310), Vec3i32(310,72,42), Vec3i32(70,22,341), Vec3i32(158,70,452), Vec3i32(66,72,452), Vec3i32(310,452,72), Vec3i32(70,341,452), Vec3i32(66,452,341), Vec3i32(313,327,314), Vec3i32(315,314,327), Vec3i32(316,317,326), Vec3i32(318,326,317), Vec3i32(15,156,311), Vec3i32(356,311,156), Vec3i32(7,312,157), Vec3i32(358,157,312), Vec3i32(211,9,327), Vec3i32(364,327,9), Vec3i32(38,326,94), Vec3i32(363,94,326), Vec3i32(294,295,424), Vec3i32(264,424,295), Vec3i32(296,423,297), Vec3i32(267,297,423), Vec3i32(262,149,426), Vec3i32(101,426,149), Vec3i32(258,319,425), Vec3i32(440,425,319), Vec3i32(261,426,321), Vec3i32(444,321,426), Vec3i32(259,425,146), Vec3i32(100,146,425), Vec3i32(306,307,430), Vec3i32(294,430,307), Vec3i32(304,429,305), Vec3i32(296,305,429), Vec3i32(319,320,440), Vec3i32(298,440,320), Vec3i32(321,444,322), Vec3i32(300,322,444), Vec3i32(445,283,442), Vec3i32(155,442,283), Vec3i32(439,438,285), Vec3i32(153,285,438), Vec3i32(17,68,18), Vec3i32(21,18,68), Vec3i32(46,184,47), Vec3i32(221,47,184), Vec3i32(102,95,363), Vec3i32(94,363,95), Vec3i32(9,11,364), Vec3i32(103,364,11), Vec3i32(6,323,357), Vec3i32(370,357,323), Vec3i32(371,324,355), Vec3i32(208,355,324), Vec3i32(270,363,325), Vec3i32(326,325,363), Vec3i32(327,364,328), Vec3i32(273,328,364), Vec3i32(0,2,39), Vec3i32(12,39,2), Vec3i32(90,93,91), Vec3i32(40,91,93), Vec3i32(14,16,17), Vec3i32(73,17,16), Vec3i32(45,309,7), Vec3i32(308,7,309), Vec3i32(12,71,39), Vec3i32(70,39,71), Vec3i32(40,41,42), Vec3i32(310,42,41), Vec3i32(97,98,63), Vec3i32(14,63,98), Vec3i32(3,5,7), Vec3i32(45,7,5), Vec3i32(118,377,329), Vec3i32(330,329,377), Vec3i32(331,372,332), Vec3i32(86,332,372), Vec3i32(333,376,334), Vec3i32(335,334,376), Vec3i32(115,373,336), Vec3i32(169,336,373), Vec3i32(167,166,380), Vec3i32(330,380,166), Vec3i32(80,81,382), Vec3i32(335,382,81), Vec3i32(86,385,81), Vec3i32(168,81,385), Vec3i32(169,384,82), Vec3i32(87,82,384), Vec3i32(159,88,372), Vec3i32(87,372,88), Vec3i32(163,164,376), Vec3i32(167,376,164), Vec3i32(24,26,377), Vec3i32(80,377,26), Vec3i32(56,57,373), Vec3i32(168,373,57), Vec3i32(32,397,30), Vec3i32(29,30,397), Vec3i32(58,60,53), Vec3i32(303,53,60), Vec3i32(205,181,119), Vec3i32(118,119,181), Vec3i32(163,175,165), Vec3i32(122,165,175), Vec3i32(453,454,455), Vec3i32(454,456,455), Vec3i32(457,455,456), Vec3i32(458,455,457), Vec3i32(459,455,458), Vec3i32(460,455,459), Vec3i32(461,462,463), Vec3i32(464,465,466), Vec3i32(467,468,469), Vec3i32(470,471,472), Vec3i32(465,473,474), Vec3i32(475,476,477), Vec3i32(478,479,480), Vec3i32(481,482,478), Vec3i32(483,484,481), Vec3i32(485,486,483), Vec3i32(487,488,485), Vec3i32(489,490,487), Vec3i32(491,492,489), Vec3i32(493,494,491), Vec3i32(495,496,493), Vec3i32(497,498,495), Vec3i32(499,500,497), Vec3i32(501,502,499), Vec3i32(503,504,501), Vec3i32(505,504,503), Vec3i32(506,504,505), Vec3i32(507,504,506), Vec3i32(508,504,507), Vec3i32(509,504,508), Vec3i32(510,504,509), Vec3i32(511,504,510), Vec3i32(512,504,511), Vec3i32(513,504,512), Vec3i32(514,504,513), Vec3i32(476,515,516), Vec3i32(517,518,519), Vec3i32(520,517,521), Vec3i32(518,522,523), Vec3i32(522,480,479), Vec3i32(524,525,526), Vec3i32(468,470,527), Vec3i32(525,467,528), Vec3i32(529,475,530), Vec3i32(531,532,533), Vec3i32(534,531,535), Vec3i32(536,537,538), Vec3i32(473,539,540), Vec3i32(539,536,541), Vec3i32(537,534,542), Vec3i32(471,520,543), Vec3i32(532,529,544), Vec3i32(545,524,546), Vec3i32(453,461,547), Vec3i32(463,464,548), Vec3i32(523,549,504), Vec3i32(527,550,551), Vec3i32(519,552,553), Vec3i32(521,554,555), Vec3i32(466,556,557), Vec3i32(469,558,559), Vec3i32(528,560,561), Vec3i32(477,562,563), Vec3i32(543,564,565), Vec3i32(535,566,567), Vec3i32(530,568,569), Vec3i32(540,570,571), Vec3i32(474,572,573), Vec3i32(542,574,575), Vec3i32(538,576,577), Vec3i32(541,578,579), Vec3i32(472,580,581), Vec3i32(526,582,583), Vec3i32(533,584,585), Vec3i32(544,586,587), Vec3i32(516,545,588), Vec3i32(588,589,590), Vec3i32(455,460,4), Vec3i32(591,592,63), Vec3i32(462,455,4), Vec3i32(592,547,63), Vec3i32(547,548,63), Vec3i32(465,462,4), Vec3i32(548,557,63), Vec3i32(127,124,501), Vec3i32(127,501,499), Vec3i32(505,503,124), Vec3i32(124,126,507), Vec3i32(124,507,506), Vec3i32(509,508,126), Vec3i32(126,134,512), Vec3i32(126,512,511), Vec3i32(510,509,126), Vec3i32(128,127,493), Vec3i32(128,493,491), Vec3i32(497,495,127), Vec3i32(489,487,128), Vec3i32(140,128,483), Vec3i32(140,483,481), Vec3i32(487,485,128), Vec3i32(478,480,140), Vec3i32(480,522,140), Vec3i32(514,513,134), Vec3i32(504,514,134), Vec3i32(551,581,437), Vec3i32(471,470,434), Vec3i32(445,447,555), Vec3i32(445,555,553), Vec3i32(134,445,553), Vec3i32(134,553,504), Vec3i32(446,439,518), Vec3i32(446,518,517), Vec3i32(439,140,522), Vec3i32(439,522,518), Vec3i32(515,476,358), Vec3i32(563,588,356), Vec3i32(557,573,63), Vec3i32(473,465,4), Vec3i32(437,360,559), Vec3i32(437,559,551), Vec3i32(360,371,561), Vec3i32(360,561,559), Vec3i32(362,434,470), Vec3i32(362,470,468), Vec3i32(370,362,468), Vec3i32(370,468,467), Vec3i32(499,497,127), Vec3i32(506,505,124), Vec3i32(495,493,127), Vec3i32(513,512,134), Vec3i32(481,478,140), Vec3i32(447,449,565), Vec3i32(447,565,555), Vec3i32(450,446,517), Vec3i32(450,517,520), Vec3i32(356,156,569), Vec3i32(356,569,563), Vec3i32(157,358,476), Vec3i32(157,476,475), Vec3i32(357,370,467), Vec3i32(357,467,525), Vec3i32(371,355,583), Vec3i32(371,583,561), Vec3i32(460,459,4), Vec3i32(63,62,593), Vec3i32(63,593,591), Vec3i32(62,4,459), Vec3i32(62,459,458), Vec3i32(532,531,104), Vec3i32(531,534,104), Vec3i32(567,585,105), Vec3i32(575,567,105), Vec3i32(4,3,539), Vec3i32(4,539,473), Vec3i32(536,539,3), Vec3i32(97,63,573), Vec3i32(97,573,571), Vec3i32(571,579,97), Vec3i32(99,97,579), Vec3i32(99,579,577), Vec3i32(105,99,577), Vec3i32(105,577,575), Vec3i32(96,104,534), Vec3i32(96,534,537), Vec3i32(3,96,537), Vec3i32(3,537,536), Vec3i32(503,501,124), Vec3i32(508,507,126), Vec3i32(491,489,128), Vec3i32(511,510,126), Vec3i32(485,483,128), Vec3i32(434,450,520), Vec3i32(434,520,471), Vec3i32(449,437,581), Vec3i32(449,581,565), Vec3i32(156,105,585), Vec3i32(156,585,587), Vec3i32(587,569,156), Vec3i32(104,157,529), Vec3i32(104,529,532), Vec3i32(475,529,157), Vec3i32(590,583,355), Vec3i32(355,356,588), Vec3i32(355,588,590), Vec3i32(358,357,524), Vec3i32(358,524,515), Vec3i32(525,524,357), Vec3i32(458,457,62), Vec3i32(457,593,62), Vec3i32(479,478,482), Vec3i32(479,504,549), Vec3i32(479,482,504), Vec3i32(482,481,484), Vec3i32(472,551,550), Vec3i32(581,551,472), Vec3i32(482,484,504), Vec3i32(484,483,486), Vec3i32(523,553,552), Vec3i32(504,553,523), Vec3i32(540,573,572), Vec3i32(571,573,540), Vec3i32(544,585,584), Vec3i32(587,585,544), Vec3i32(542,577,576), Vec3i32(575,577,542), Vec3i32(526,590,589), Vec3i32(583,590,526), Vec3i32(535,575,574), Vec3i32(567,575,535), Vec3i32(533,567,566), Vec3i32(585,567,533), Vec3i32(538,579,578), Vec3i32(577,579,538), Vec3i32(543,581,580), Vec3i32(565,581,543), Vec3i32(477,569,568), Vec3i32(563,569,477), Vec3i32(530,587,586), Vec3i32(569,587,530), Vec3i32(541,571,570), Vec3i32(579,571,541), Vec3i32(528,583,582), Vec3i32(561,583,528), Vec3i32(591,453,592), Vec3i32(547,592,453), Vec3i32(521,565,564), Vec3i32(555,565,521), Vec3i32(474,557,556), Vec3i32(573,557,474), Vec3i32(516,563,562), Vec3i32(588,563,516), Vec3i32(519,555,554), Vec3i32(553,555,519), Vec3i32(527,559,558), Vec3i32(551,559,527), Vec3i32(469,561,560), Vec3i32(559,561,469), Vec3i32(462,461,455), Vec3i32(453,455,461), Vec3i32(461,463,547), Vec3i32(548,547,463), Vec3i32(465,464,462), Vec3i32(463,462,464), Vec3i32(464,466,548), Vec3i32(557,548,466), Vec3i32(469,560,467), Vec3i32(528,467,560), Vec3i32(472,550,470), Vec3i32(527,470,550), Vec3i32(474,556,465), Vec3i32(466,465,556), Vec3i32(477,568,475), Vec3i32(530,475,568), Vec3i32(516,562,476), Vec3i32(477,476,562), Vec3i32(519,554,517), Vec3i32(521,517,554), Vec3i32(521,564,520), Vec3i32(543,520,564), Vec3i32(523,552,518), Vec3i32(519,518,552), Vec3i32(479,549,522), Vec3i32(523,522,549), Vec3i32(526,589,524), Vec3i32(589,546,524), Vec3i32(527,558,468), Vec3i32(469,468,558), Vec3i32(528,582,525), Vec3i32(526,525,582), Vec3i32(530,586,529), Vec3i32(544,529,586), Vec3i32(533,566,531), Vec3i32(535,531,566), Vec3i32(535,574,534), Vec3i32(542,534,574), Vec3i32(538,578,536), Vec3i32(541,536,578), Vec3i32(540,572,473), Vec3i32(474,473,572), Vec3i32(541,570,539), Vec3i32(540,539,570), Vec3i32(542,576,537), Vec3i32(538,537,576), Vec3i32(543,580,471), Vec3i32(472,471,580), Vec3i32(544,584,532), Vec3i32(533,532,584), Vec3i32(524,545,515), Vec3i32(516,515,545), Vec3i32(545,546,588), Vec3i32(589,588,546), Vec3i32(453,591,454), Vec3i32(593,454,591), Vec3i32(484,486,504), Vec3i32(486,485,488), Vec3i32(486,488,504), Vec3i32(488,487,490), Vec3i32(488,490,504), Vec3i32(490,489,492), Vec3i32(490,492,504), Vec3i32(492,491,494), Vec3i32(492,494,504), Vec3i32(494,493,496), Vec3i32(494,496,504), Vec3i32(496,495,498), Vec3i32(496,498,504), Vec3i32(498,497,500), Vec3i32(498,500,504), Vec3i32(500,499,502), Vec3i32(500,502,504), Vec3i32(501,504,502), Vec3i32(454,593,456), Vec3i32(457,456,593), Vec3i32(594,595,596), Vec3i32(597,598,594), Vec3i32(599,597,594), Vec3i32(600,599,594), Vec3i32(601,600,594), Vec3i32(602,601,594), Vec3i32(603,602,594), Vec3i32(604,603,594), Vec3i32(605,604,594), Vec3i32(606,607,608), Vec3i32(609,606,608), Vec3i32(610,609,608), Vec3i32(611,610,608), Vec3i32(612,611,608), Vec3i32(613,612,608), Vec3i32(614,613,608), Vec3i32(615,614,608), Vec3i32(616,615,608), Vec3i32(617,616,608), Vec3i32(618,617,608), Vec3i32(619,618,608), Vec3i32(620,619,608), Vec3i32(596,608,607), Vec3i32(595,594,598), Vec3i32(608,596,595), Vec3i32(605,594,91), Vec3i32(91,338,602), Vec3i32(91,602,603), Vec3i32(598,597,1), Vec3i32(594,596,91), Vec3i32(608,595,1), Vec3i32(595,598,1), Vec3i32(616,617,392), Vec3i32(610,611,394), Vec3i32(419,421,613), Vec3i32(419,613,614), Vec3i32(422,427,607), Vec3i32(422,607,606), Vec3i32(427,91,596), Vec3i32(427,596,607), Vec3i32(428,420,619), Vec3i32(428,619,620), Vec3i32(1,428,620), Vec3i32(1,620,608), Vec3i32(420,409,618), Vec3i32(420,618,619), Vec3i32(411,422,606), Vec3i32(411,606,609), Vec3i32(398,419,614), Vec3i32(398,614,615), Vec3i32(421,400,612), Vec3i32(421,612,613), Vec3i32(409,392,617), Vec3i32(409,617,618), Vec3i32(394,411,609), Vec3i32(394,609,610), Vec3i32(604,605,91), Vec3i32(338,1,599), Vec3i32(338,599,600), Vec3i32(392,398,615), Vec3i32(392,615,616), Vec3i32(400,394,611), Vec3i32(400,611,612), Vec3i32(603,604,91), Vec3i32(601,602,338), Vec3i32(597,599,1), Vec3i32(600,601,338) }; break; case TestMesh::gt2_teeth: - vertices = std::vector{ - Vec3d(15.8899993896484,19.444055557251,2.67489433288574), Vec3d(15.9129991531372,19.1590557098389,2.67489433288574), Vec3d(15.9039993286133,19.1500549316406,2.67489433288574), Vec3d(15.9489994049072,19.2490558624268,2.67489433288574), Vec3d(15.9579992294312,19.3570556640625,2.67489433288574), Vec3d(15.8819999694824,18.690055847168,2.67489433288574), Vec3d(15.8319997787476,17.7460556030273,2.67489433288574), Vec3d(15.8489999771118,18.819055557251,2.67489433288574), Vec3d(15.8589992523193,17.7190551757812,2.67489433288574), Vec3d(15.8769998550415,19.0490550994873,2.67489433288574), Vec3d(15.7529993057251,17.8080558776855,2.67489433288574), Vec3d(15.7869997024536,19.5010547637939,2.67489433288574), Vec3d(14.0329990386963,18.7170543670654,2.67489433288574), Vec3d(13.9599990844727,18.7460556030273,2.67489433288574), Vec3d(13.9869995117188,20.2840557098389,2.67489433288574), Vec3d(14.2029991149902,20.149055480957,2.67489433288574), Vec3d(14.1939992904663,19.9560546875,2.67489433288574), Vec3d(14.1939992904663,20.1670551300049,2.67489433288574), Vec3d(14.2119998931885,20.0590553283691,2.67489433288574), Vec3d(12.1899995803833,19.1840553283691,2.67489433288574), Vec3d(12.096999168396,19.1950550079346,2.67489433288574), Vec3d(12.1099996566772,20.6690559387207,2.67489433288574), Vec3d(11.382999420166,19.9750556945801,2.67489433288574), Vec3d(11.2599992752075,19.2490558624268,2.67489433288574), Vec3d(11.2369995117188,19.9320545196533,2.67489433288574), Vec3d(11.5349998474121,20.0640544891357,2.67489433288574), Vec3d(11.6259994506836,20.1550559997559,2.67489433288574), Vec3d(11.6829986572266,20.2390556335449,2.67489433288574), Vec3d(11.7369995117188,20.3570556640625,2.67489433288574), Vec3d(11.8449993133545,20.645055770874,2.67489433288574), Vec3d(11.7729988098145,20.4640560150146,2.67489433288574), Vec3d(11.7799987792969,20.5370559692383,9.41389465332031), Vec3d(11.7639999389648,20.4470558166504,2.67489433288574), Vec3d(11.9559993743896,20.6810550689697,2.67489433288574), Vec3d(12.3079996109009,20.6020545959473,2.67489433288574), Vec3d(12.1959991455078,19.1860542297363,2.67489433288574), Vec3d(12.2059993743896,20.6540546417236,2.67489433288574), Vec3d(12.3489990234375,20.3740558624268,2.67489433288574), Vec3d(12.3579998016357,20.2750549316406,2.67489433288574), Vec3d(12.3669996261597,20.266056060791,2.67489433288574), Vec3d(12.3849992752075,20.1670551300049,2.67489433288574), Vec3d(12.4269990921021,20.0680541992188,2.67489433288574), Vec3d(12.5029993057251,19.9540557861328,2.67489433288574), Vec3d(12.6169996261597,19.8550548553467,2.67489433288574), Vec3d(12.7449989318848,19.7800559997559,2.67489433288574), Vec3d(12.7629995346069,19.7800559997559,2.67489433288574), Vec3d(12.8799991607666,19.7350559234619,2.67489433288574), Vec3d(13.0369997024536,19.7250556945801,2.67489433288574), Vec3d(13.0149993896484,19.0340557098389,2.67489433288574), Vec3d(11.1699991226196,19.2580547332764,2.67489433288574), Vec3d(11.0959987640381,19.2580547332764,2.67489433288574), Vec3d(11.1209993362427,19.9230556488037,2.67489433288574), Vec3d(13.0599994659424,19.024055480957,2.67489433288574), Vec3d(14.9049997329712,18.3170547485352,2.67489433288574), Vec3d(14.8779993057251,18.3400554656982,2.67489433288574), Vec3d(14.8779993057251,19.149055480957,2.67489433288574), Vec3d(13.3039989471436,19.77805519104,2.67489433288574), Vec3d(13.1589994430542,18.9890556335449,2.67489433288574), Vec3d(13.1559991836548,19.7350559234619,2.67489433288574), Vec3d(13.4269990921021,19.8600559234619,2.67489433288574), Vec3d(13.5339994430542,19.9700546264648,2.67389440536499), Vec3d(13.6359996795654,20.1220550537109,2.67489433288574), Vec3d(13.6359996795654,20.1400547027588,2.67489433288574), Vec3d(13.6719989776611,20.2210559844971,2.67489433288574), Vec3d(13.6899995803833,20.2300548553467,2.67489433288574), Vec3d(13.7509994506836,20.3010559082031,2.67489433288574), Vec3d(13.8539991378784,20.3180541992188,2.67489433288574), Vec3d(14.8329992294312,18.3580551147461,2.67489433288574), Vec3d(14.1849994659424,19.8530559539795,2.67489433288574), Vec3d(14.0769996643066,18.7000541687012,2.67489433288574), Vec3d(14.1099996566772,20.2400550842285,2.67489433288574), Vec3d(14.2009992599487,19.6230545043945,2.67489433288574), Vec3d(14.2729997634888,19.4670543670654,2.67489433288574), Vec3d(14.3379993438721,19.3790550231934,2.67489433288574), Vec3d(14.4549999237061,19.2770557403564,2.67489433288574), Vec3d(14.5899991989136,19.2040557861328,2.67489433288574), Vec3d(14.6079998016357,19.2040557861328,2.67489433288574), Vec3d(14.7209997177124,19.1600551605225,2.67489433288574), Vec3d(15.1379995346069,19.210054397583,2.67489433288574), Vec3d(14.9949998855591,18.2680549621582,2.67489433288574), Vec3d(15.0029993057251,19.1580543518066,2.67489433288574), Vec3d(15.2369995117188,19.2760543823242,2.67489433288574), Vec3d(15.3779993057251,19.4060554504395,2.67489433288574), Vec3d(15.4539995193481,19.520055770874,2.67489433288574), Vec3d(15.471999168396,19.52805519104,2.67489433288574), Vec3d(15.5449991226196,19.5830554962158,2.67489433288574), Vec3d(15.6529998779297,19.573055267334,2.67489433288574), Vec3d(15.7059993743896,17.8360557556152,2.67489433288574), Vec3d(15.9449996948242,18.5560550689697,2.67489433288574), Vec3d(15.8589992523193,18.9380550384521,2.67489433288574), Vec3d(14.9589996337891,18.2950553894043,2.67489433288574), Vec3d(15.7779998779297,19.5100555419922,2.67489433288574), Vec3d(14.0049991607666,20.2750549316406,2.67489433288574), Vec3d(12.3489990234375,20.5000553131104,2.67489433288574), Vec3d(13.0689992904663,19.0150547027588,2.67489433288574), Vec3d(13.0999994277954,19.0100555419922,2.67489433288574), Vec3d(15.9489994049072,19.3670558929443,9.41489505767822), Vec3d(15.9489994049072,19.2490558624268,9.41489505767822), Vec3d(15.75,17.8080558776855,9.41489505767822), Vec3d(15.6639995574951,19.5710544586182,9.41489505767822), Vec3d(15.5709991455078,17.9260559082031,9.41489505767822), Vec3d(15.8769998550415,18.690055847168,9.41489505767822), Vec3d(15.8499994277954,18.8170547485352,9.41489505767822), Vec3d(15.9459991455078,18.5520553588867,9.41489505767822), Vec3d(15.914999961853,17.6890544891357,9.41489505767822), Vec3d(15.3999996185303,19.4290542602539,9.41489505767822), Vec3d(15.3099994659424,19.339054107666,9.41489505767822), Vec3d(15.3729991912842,18.0440559387207,9.41489505767822), Vec3d(15.4579992294312,19.5170555114746,9.41489505767822), Vec3d(15.5469999313354,19.5820541381836,9.41489505767822), Vec3d(13.2309989929199,19.7610549926758,9.41489505767822), Vec3d(13.168999671936,19.7360553741455,9.41489505767822), Vec3d(13.096999168396,19.0140552520752,9.41489505767822), Vec3d(13.1999988555908,18.9870548248291,9.41489505767822), Vec3d(15.1399993896484,19.2080554962158,9.41489505767822), Vec3d(15.0159997940063,19.1600551605225,9.41489505767822), Vec3d(14.9859991073608,18.2770557403564,9.41489505767822), Vec3d(15.1749992370605,18.1690559387207,9.41489505767822), Vec3d(15.9039993286133,19.1320552825928,9.41489505767822), Vec3d(15.8949995040894,19.4460544586182,9.41489505767822), Vec3d(15.8769998550415,19.0420551300049,9.41489505767822), Vec3d(12.2169990539551,20.6500549316406,9.41489505767822), Vec3d(11.9379997253418,20.6810550689697,9.41489505767822), Vec3d(11.8629989624023,19.2130546569824,9.41489505767822), Vec3d(12.096999168396,19.1950550079346,9.41489505767822), Vec3d(14.1669998168945,18.6640548706055,9.41489505767822), Vec3d(14.1039991378784,20.2460556030273,9.41489505767822), Vec3d(13.9849996566772,18.7360553741455,9.41489505767822), Vec3d(14.7349996566772,19.1590557098389,9.41489505767822), Vec3d(14.5849990844727,19.2050552368164,9.41489505767822), Vec3d(14.5719995498657,18.4850559234619,9.41489505767822), Vec3d(14.1939992904663,19.6760559082031,9.41489505767822), Vec3d(14.1849994659424,19.9330558776855,9.41489505767822), Vec3d(14.1759996414185,18.6640548706055,9.41489505767822), Vec3d(14.261999130249,19.4890556335449,9.41489505767822), Vec3d(14.3539991378784,19.3610553741455,9.41489505767822), Vec3d(14.3559989929199,18.5830554962158,9.41489505767822), Vec3d(11.6039991378784,20.1250553131104,9.41489505767822), Vec3d(11.5209999084473,20.0520553588867,9.41489505767822), Vec3d(11.4209995269775,19.2480545043945,9.41489505767822), Vec3d(11.6989994049072,20.2690544128418,9.41389465332031), Vec3d(11.7609996795654,20.4310550689697,9.41489505767822), Vec3d(11.8359994888306,19.2130546569824,9.41489505767822), Vec3d(14.1889991760254,20.1710548400879,9.41489505767822), Vec3d(13.9689998626709,20.2840557098389,9.41489505767822), Vec3d(13.8739995956421,20.315055847168,9.41489505767822), Vec3d(13.7799997329712,18.8080558776855,9.41489505767822), Vec3d(13.9869995117188,20.2750549316406,9.41489505767822), Vec3d(12.3129997253418,20.5980548858643,9.41489505767822), Vec3d(12.3399991989136,20.5090560913086,9.41489505767822), Vec3d(12.3489990234375,20.3830547332764,9.41489505767822), Vec3d(12.3599996566772,20.2680549621582,9.41489505767822), Vec3d(12.3849992752075,20.1850547790527,9.41489505767822), Vec3d(12.3849992752075,20.1670551300049,9.41489505767822), Vec3d(12.4249992370605,20.065055847168,9.41489505767822), Vec3d(12.4729995727539,19.1350555419922,9.41489505767822), Vec3d(14.4399995803833,19.2900543212891,9.41489505767822), Vec3d(14.3649997711182,18.5740547180176,9.41489505767822), Vec3d(13.5729999542236,20.0310554504395,9.41489505767822), Vec3d(13.4889993667603,19.9140548706055,9.41489505767822), Vec3d(13.5639991760254,18.8710556030273,9.41489505767822), Vec3d(13.6389999389648,20.1310558319092,9.41489505767822), Vec3d(13.6719989776611,20.2130546569824,9.41489505767822), Vec3d(13.75,20.3020553588867,9.41489505767822), Vec3d(12.7399997711182,19.7810554504395,9.41489505767822), Vec3d(12.6189994812012,19.8520545959473,9.41489505767822), Vec3d(12.5799999237061,19.1200542449951,9.41489505767822), Vec3d(12.8349990844727,19.069055557251,9.41489505767822), Vec3d(11.2669992446899,19.9350547790527,9.41489505767822), Vec3d(11.1029987335205,19.9230556488037,9.41489505767822), Vec3d(11.0209999084473,19.2600555419922,9.41489505767822), Vec3d(11.3819999694824,19.9710559844971,9.41489505767822), Vec3d(13.418999671936,19.8530559539795,9.41489505767822), Vec3d(13.4329996109009,18.9160556793213,9.41489505767822), Vec3d(11.8399991989136,20.6430549621582,9.41489505767822), Vec3d(13.3119993209839,19.7800559997559,9.41489505767822), Vec3d(15.2189998626709,19.2600555419922,9.41489505767822), Vec3d(15.1839990615845,18.1600551605225,9.41489505767822), Vec3d(15.3639993667603,18.0520553588867,9.41489505767822), Vec3d(13.0189990997314,19.7250556945801,9.41489505767822), Vec3d(12.8949995040894,19.7350559234619,9.41489505767822), Vec3d(15.9039993286133,19.1500549316406,9.41489505767822), Vec3d(15.7699995040894,19.5140552520752,9.41489505767822), Vec3d(15.8589992523193,18.9340553283691,9.41489505767822), Vec3d(14.1939992904663,19.9510555267334,9.41489505767822), Vec3d(14.2119998931885,20.0630550384521,9.41489505767822), Vec3d(14.8589992523193,19.149055480957,9.41489505767822), Vec3d(14.8159999847412,18.3670558929443,9.41489505767822), Vec3d(14.8959999084473,18.3220558166504,9.41489505767822), Vec3d(12.5189990997314,19.9360542297363,9.41489505767822), Vec3d(11.0209999084473,19.9290542602539,9.41489505767822), Vec3d(11.0209999084473,19.2530555725098,2.67489433288574), Vec3d(11.0209999084473,19.9300556182861,2.67489433288574), Vec3d(15.9799995422363,18.505931854248,5.58724021911621), Vec3d(15.9799995422363,18.5044555664062,9.41489505767822), Vec3d(15.9799995422363,18.5041732788086,2.67489433288574), Vec3d(15.9799995422363,18.1684837341309,2.67489433288574), Vec3d(15.9799995422363,18.1288299560547,9.41489505767822), Vec3d(15.9799995422363,17.9876575469971,2.67489433288574), Vec3d(15.9799995422363,17.6247596740723,3.91620373725891), Vec3d(15.9799995422363,17.6247596740723,2.67489433288574), Vec3d(15.9799995422363,17.6254329681396,4.32245063781738), Vec3d(15.9799995422363,17.8920269012451,9.41489505767822), Vec3d(15.9799995422363,17.8795108795166,2.67489433288574), Vec3d(15.9799995422363,17.629810333252,4.58585262298584), Vec3d(15.9799995422363,17.6336059570312,5.27938556671143), Vec3d(15.9799995422363,17.8311748504639,2.67489433288574), Vec3d(15.9799995422363,17.638355255127,9.41489505767822), Vec3d(15.9799995422363,17.6346111297607,5.98653984069824), Vec3d(15.9799995422363,17.8728256225586,2.67489433288574), Vec3d(15.9799995422363,18.2221603393555,2.67489433288574) + vertices = std::vector{ + Vec3f(15.8899993896484,19.444055557251,2.67489433288574), Vec3f(15.9129991531372,19.1590557098389,2.67489433288574), Vec3f(15.9039993286133,19.1500549316406,2.67489433288574), Vec3f(15.9489994049072,19.2490558624268,2.67489433288574), Vec3f(15.9579992294312,19.3570556640625,2.67489433288574), Vec3f(15.8819999694824,18.690055847168,2.67489433288574), Vec3f(15.8319997787476,17.7460556030273,2.67489433288574), Vec3f(15.8489999771118,18.819055557251,2.67489433288574), Vec3f(15.8589992523193,17.7190551757812,2.67489433288574), Vec3f(15.8769998550415,19.0490550994873,2.67489433288574), Vec3f(15.7529993057251,17.8080558776855,2.67489433288574), Vec3f(15.7869997024536,19.5010547637939,2.67489433288574), Vec3f(14.0329990386963,18.7170543670654,2.67489433288574), Vec3f(13.9599990844727,18.7460556030273,2.67489433288574), Vec3f(13.9869995117188,20.2840557098389,2.67489433288574), Vec3f(14.2029991149902,20.149055480957,2.67489433288574), Vec3f(14.1939992904663,19.9560546875,2.67489433288574), Vec3f(14.1939992904663,20.1670551300049,2.67489433288574), Vec3f(14.2119998931885,20.0590553283691,2.67489433288574), Vec3f(12.1899995803833,19.1840553283691,2.67489433288574), Vec3f(12.096999168396,19.1950550079346,2.67489433288574), Vec3f(12.1099996566772,20.6690559387207,2.67489433288574), Vec3f(11.382999420166,19.9750556945801,2.67489433288574), Vec3f(11.2599992752075,19.2490558624268,2.67489433288574), Vec3f(11.2369995117188,19.9320545196533,2.67489433288574), Vec3f(11.5349998474121,20.0640544891357,2.67489433288574), Vec3f(11.6259994506836,20.1550559997559,2.67489433288574), Vec3f(11.6829986572266,20.2390556335449,2.67489433288574), Vec3f(11.7369995117188,20.3570556640625,2.67489433288574), Vec3f(11.8449993133545,20.645055770874,2.67489433288574), Vec3f(11.7729988098145,20.4640560150146,2.67489433288574), Vec3f(11.7799987792969,20.5370559692383,9.41389465332031), Vec3f(11.7639999389648,20.4470558166504,2.67489433288574), Vec3f(11.9559993743896,20.6810550689697,2.67489433288574), Vec3f(12.3079996109009,20.6020545959473,2.67489433288574), Vec3f(12.1959991455078,19.1860542297363,2.67489433288574), Vec3f(12.2059993743896,20.6540546417236,2.67489433288574), Vec3f(12.3489990234375,20.3740558624268,2.67489433288574), Vec3f(12.3579998016357,20.2750549316406,2.67489433288574), Vec3f(12.3669996261597,20.266056060791,2.67489433288574), Vec3f(12.3849992752075,20.1670551300049,2.67489433288574), Vec3f(12.4269990921021,20.0680541992188,2.67489433288574), Vec3f(12.5029993057251,19.9540557861328,2.67489433288574), Vec3f(12.6169996261597,19.8550548553467,2.67489433288574), Vec3f(12.7449989318848,19.7800559997559,2.67489433288574), Vec3f(12.7629995346069,19.7800559997559,2.67489433288574), Vec3f(12.8799991607666,19.7350559234619,2.67489433288574), Vec3f(13.0369997024536,19.7250556945801,2.67489433288574), Vec3f(13.0149993896484,19.0340557098389,2.67489433288574), Vec3f(11.1699991226196,19.2580547332764,2.67489433288574), Vec3f(11.0959987640381,19.2580547332764,2.67489433288574), Vec3f(11.1209993362427,19.9230556488037,2.67489433288574), Vec3f(13.0599994659424,19.024055480957,2.67489433288574), Vec3f(14.9049997329712,18.3170547485352,2.67489433288574), Vec3f(14.8779993057251,18.3400554656982,2.67489433288574), Vec3f(14.8779993057251,19.149055480957,2.67489433288574), Vec3f(13.3039989471436,19.77805519104,2.67489433288574), Vec3f(13.1589994430542,18.9890556335449,2.67489433288574), Vec3f(13.1559991836548,19.7350559234619,2.67489433288574), Vec3f(13.4269990921021,19.8600559234619,2.67489433288574), Vec3f(13.5339994430542,19.9700546264648,2.67389440536499), Vec3f(13.6359996795654,20.1220550537109,2.67489433288574), Vec3f(13.6359996795654,20.1400547027588,2.67489433288574), Vec3f(13.6719989776611,20.2210559844971,2.67489433288574), Vec3f(13.6899995803833,20.2300548553467,2.67489433288574), Vec3f(13.7509994506836,20.3010559082031,2.67489433288574), Vec3f(13.8539991378784,20.3180541992188,2.67489433288574), Vec3f(14.8329992294312,18.3580551147461,2.67489433288574), Vec3f(14.1849994659424,19.8530559539795,2.67489433288574), Vec3f(14.0769996643066,18.7000541687012,2.67489433288574), Vec3f(14.1099996566772,20.2400550842285,2.67489433288574), Vec3f(14.2009992599487,19.6230545043945,2.67489433288574), Vec3f(14.2729997634888,19.4670543670654,2.67489433288574), Vec3f(14.3379993438721,19.3790550231934,2.67489433288574), Vec3f(14.4549999237061,19.2770557403564,2.67489433288574), Vec3f(14.5899991989136,19.2040557861328,2.67489433288574), Vec3f(14.6079998016357,19.2040557861328,2.67489433288574), Vec3f(14.7209997177124,19.1600551605225,2.67489433288574), Vec3f(15.1379995346069,19.210054397583,2.67489433288574), Vec3f(14.9949998855591,18.2680549621582,2.67489433288574), Vec3f(15.0029993057251,19.1580543518066,2.67489433288574), Vec3f(15.2369995117188,19.2760543823242,2.67489433288574), Vec3f(15.3779993057251,19.4060554504395,2.67489433288574), Vec3f(15.4539995193481,19.520055770874,2.67489433288574), Vec3f(15.471999168396,19.52805519104,2.67489433288574), Vec3f(15.5449991226196,19.5830554962158,2.67489433288574), Vec3f(15.6529998779297,19.573055267334,2.67489433288574), Vec3f(15.7059993743896,17.8360557556152,2.67489433288574), Vec3f(15.9449996948242,18.5560550689697,2.67489433288574), Vec3f(15.8589992523193,18.9380550384521,2.67489433288574), Vec3f(14.9589996337891,18.2950553894043,2.67489433288574), Vec3f(15.7779998779297,19.5100555419922,2.67489433288574), Vec3f(14.0049991607666,20.2750549316406,2.67489433288574), Vec3f(12.3489990234375,20.5000553131104,2.67489433288574), Vec3f(13.0689992904663,19.0150547027588,2.67489433288574), Vec3f(13.0999994277954,19.0100555419922,2.67489433288574), Vec3f(15.9489994049072,19.3670558929443,9.41489505767822), Vec3f(15.9489994049072,19.2490558624268,9.41489505767822), Vec3f(15.75,17.8080558776855,9.41489505767822), Vec3f(15.6639995574951,19.5710544586182,9.41489505767822), Vec3f(15.5709991455078,17.9260559082031,9.41489505767822), Vec3f(15.8769998550415,18.690055847168,9.41489505767822), Vec3f(15.8499994277954,18.8170547485352,9.41489505767822), Vec3f(15.9459991455078,18.5520553588867,9.41489505767822), Vec3f(15.914999961853,17.6890544891357,9.41489505767822), Vec3f(15.3999996185303,19.4290542602539,9.41489505767822), Vec3f(15.3099994659424,19.339054107666,9.41489505767822), Vec3f(15.3729991912842,18.0440559387207,9.41489505767822), Vec3f(15.4579992294312,19.5170555114746,9.41489505767822), Vec3f(15.5469999313354,19.5820541381836,9.41489505767822), Vec3f(13.2309989929199,19.7610549926758,9.41489505767822), Vec3f(13.168999671936,19.7360553741455,9.41489505767822), Vec3f(13.096999168396,19.0140552520752,9.41489505767822), Vec3f(13.1999988555908,18.9870548248291,9.41489505767822), Vec3f(15.1399993896484,19.2080554962158,9.41489505767822), Vec3f(15.0159997940063,19.1600551605225,9.41489505767822), Vec3f(14.9859991073608,18.2770557403564,9.41489505767822), Vec3f(15.1749992370605,18.1690559387207,9.41489505767822), Vec3f(15.9039993286133,19.1320552825928,9.41489505767822), Vec3f(15.8949995040894,19.4460544586182,9.41489505767822), Vec3f(15.8769998550415,19.0420551300049,9.41489505767822), Vec3f(12.2169990539551,20.6500549316406,9.41489505767822), Vec3f(11.9379997253418,20.6810550689697,9.41489505767822), Vec3f(11.8629989624023,19.2130546569824,9.41489505767822), Vec3f(12.096999168396,19.1950550079346,9.41489505767822), Vec3f(14.1669998168945,18.6640548706055,9.41489505767822), Vec3f(14.1039991378784,20.2460556030273,9.41489505767822), Vec3f(13.9849996566772,18.7360553741455,9.41489505767822), Vec3f(14.7349996566772,19.1590557098389,9.41489505767822), Vec3f(14.5849990844727,19.2050552368164,9.41489505767822), Vec3f(14.5719995498657,18.4850559234619,9.41489505767822), Vec3f(14.1939992904663,19.6760559082031,9.41489505767822), Vec3f(14.1849994659424,19.9330558776855,9.41489505767822), Vec3f(14.1759996414185,18.6640548706055,9.41489505767822), Vec3f(14.261999130249,19.4890556335449,9.41489505767822), Vec3f(14.3539991378784,19.3610553741455,9.41489505767822), Vec3f(14.3559989929199,18.5830554962158,9.41489505767822), Vec3f(11.6039991378784,20.1250553131104,9.41489505767822), Vec3f(11.5209999084473,20.0520553588867,9.41489505767822), Vec3f(11.4209995269775,19.2480545043945,9.41489505767822), Vec3f(11.6989994049072,20.2690544128418,9.41389465332031), Vec3f(11.7609996795654,20.4310550689697,9.41489505767822), Vec3f(11.8359994888306,19.2130546569824,9.41489505767822), Vec3f(14.1889991760254,20.1710548400879,9.41489505767822), Vec3f(13.9689998626709,20.2840557098389,9.41489505767822), Vec3f(13.8739995956421,20.315055847168,9.41489505767822), Vec3f(13.7799997329712,18.8080558776855,9.41489505767822), Vec3f(13.9869995117188,20.2750549316406,9.41489505767822), Vec3f(12.3129997253418,20.5980548858643,9.41489505767822), Vec3f(12.3399991989136,20.5090560913086,9.41489505767822), Vec3f(12.3489990234375,20.3830547332764,9.41489505767822), Vec3f(12.3599996566772,20.2680549621582,9.41489505767822), Vec3f(12.3849992752075,20.1850547790527,9.41489505767822), Vec3f(12.3849992752075,20.1670551300049,9.41489505767822), Vec3f(12.4249992370605,20.065055847168,9.41489505767822), Vec3f(12.4729995727539,19.1350555419922,9.41489505767822), Vec3f(14.4399995803833,19.2900543212891,9.41489505767822), Vec3f(14.3649997711182,18.5740547180176,9.41489505767822), Vec3f(13.5729999542236,20.0310554504395,9.41489505767822), Vec3f(13.4889993667603,19.9140548706055,9.41489505767822), Vec3f(13.5639991760254,18.8710556030273,9.41489505767822), Vec3f(13.6389999389648,20.1310558319092,9.41489505767822), Vec3f(13.6719989776611,20.2130546569824,9.41489505767822), Vec3f(13.75,20.3020553588867,9.41489505767822), Vec3f(12.7399997711182,19.7810554504395,9.41489505767822), Vec3f(12.6189994812012,19.8520545959473,9.41489505767822), Vec3f(12.5799999237061,19.1200542449951,9.41489505767822), Vec3f(12.8349990844727,19.069055557251,9.41489505767822), Vec3f(11.2669992446899,19.9350547790527,9.41489505767822), Vec3f(11.1029987335205,19.9230556488037,9.41489505767822), Vec3f(11.0209999084473,19.2600555419922,9.41489505767822), Vec3f(11.3819999694824,19.9710559844971,9.41489505767822), Vec3f(13.418999671936,19.8530559539795,9.41489505767822), Vec3f(13.4329996109009,18.9160556793213,9.41489505767822), Vec3f(11.8399991989136,20.6430549621582,9.41489505767822), Vec3f(13.3119993209839,19.7800559997559,9.41489505767822), Vec3f(15.2189998626709,19.2600555419922,9.41489505767822), Vec3f(15.1839990615845,18.1600551605225,9.41489505767822), Vec3f(15.3639993667603,18.0520553588867,9.41489505767822), Vec3f(13.0189990997314,19.7250556945801,9.41489505767822), Vec3f(12.8949995040894,19.7350559234619,9.41489505767822), Vec3f(15.9039993286133,19.1500549316406,9.41489505767822), Vec3f(15.7699995040894,19.5140552520752,9.41489505767822), Vec3f(15.8589992523193,18.9340553283691,9.41489505767822), Vec3f(14.1939992904663,19.9510555267334,9.41489505767822), Vec3f(14.2119998931885,20.0630550384521,9.41489505767822), Vec3f(14.8589992523193,19.149055480957,9.41489505767822), Vec3f(14.8159999847412,18.3670558929443,9.41489505767822), Vec3f(14.8959999084473,18.3220558166504,9.41489505767822), Vec3f(12.5189990997314,19.9360542297363,9.41489505767822), Vec3f(11.0209999084473,19.9290542602539,9.41489505767822), Vec3f(11.0209999084473,19.2530555725098,2.67489433288574), Vec3f(11.0209999084473,19.9300556182861,2.67489433288574), Vec3f(15.9799995422363,18.505931854248,5.58724021911621), Vec3f(15.9799995422363,18.5044555664062,9.41489505767822), Vec3f(15.9799995422363,18.5041732788086,2.67489433288574), Vec3f(15.9799995422363,18.1684837341309,2.67489433288574), Vec3f(15.9799995422363,18.1288299560547,9.41489505767822), Vec3f(15.9799995422363,17.9876575469971,2.67489433288574), Vec3f(15.9799995422363,17.6247596740723,3.91620373725891), Vec3f(15.9799995422363,17.6247596740723,2.67489433288574), Vec3f(15.9799995422363,17.6254329681396,4.32245063781738), Vec3f(15.9799995422363,17.8920269012451,9.41489505767822), Vec3f(15.9799995422363,17.8795108795166,2.67489433288574), Vec3f(15.9799995422363,17.629810333252,4.58585262298584), Vec3f(15.9799995422363,17.6336059570312,5.27938556671143), Vec3f(15.9799995422363,17.8311748504639,2.67489433288574), Vec3f(15.9799995422363,17.638355255127,9.41489505767822), Vec3f(15.9799995422363,17.6346111297607,5.98653984069824), Vec3f(15.9799995422363,17.8728256225586,2.67489433288574), Vec3f(15.9799995422363,18.2221603393555,2.67489433288574) }; facets = std::vector{ Vec3i32(0,1,2), Vec3i32(0,3,1), Vec3i32(0,4,3), Vec3i32(5,6,7), Vec3i32(8,6,5), Vec3i32(2,9,0), Vec3i32(6,10,11), Vec3i32(12,13,14), Vec3i32(15,16,17), Vec3i32(18,16,15), Vec3i32(19,20,21), Vec3i32(22,23,24), Vec3i32(25,23,22), Vec3i32(26,23,25), Vec3i32(27,23,26), Vec3i32(28,23,27), Vec3i32(29,30,31), Vec3i32(29,32,30), Vec3i32(29,28,32), Vec3i32(33,28,29), Vec3i32(33,23,28), Vec3i32(21,23,33), Vec3i32(20,23,21), Vec3i32(34,35,36), Vec3i32(37,35,34), Vec3i32(38,35,37), Vec3i32(39,35,38), Vec3i32(40,35,39), Vec3i32(41,35,40), Vec3i32(42,35,41), Vec3i32(43,35,42), Vec3i32(44,35,43), Vec3i32(45,35,44), Vec3i32(46,35,45), Vec3i32(47,35,46), Vec3i32(48,35,47), Vec3i32(49,50,51), Vec3i32(52,48,47), Vec3i32(23,49,24), Vec3i32(53,54,55), Vec3i32(56,57,58), Vec3i32(59,57,56), Vec3i32(60,57,59), Vec3i32(61,57,60), Vec3i32(62,57,61), Vec3i32(63,57,62), Vec3i32(64,57,63), Vec3i32(65,57,64), Vec3i32(66,57,65), Vec3i32(13,57,66), Vec3i32(54,67,55), Vec3i32(68,69,70), Vec3i32(71,69,68), Vec3i32(72,69,71), Vec3i32(73,69,72), Vec3i32(74,69,73), Vec3i32(75,69,74), Vec3i32(76,69,75), Vec3i32(77,69,76), Vec3i32(67,69,77), Vec3i32(70,16,68), Vec3i32(70,17,16), Vec3i32(78,79,80), Vec3i32(81,79,78), Vec3i32(82,79,81), Vec3i32(83,79,82), Vec3i32(84,79,83), Vec3i32(85,79,84), Vec3i32(86,79,85), Vec3i32(87,79,86), Vec3i32(88,8,5), Vec3i32(11,7,6), Vec3i32(11,89,7), Vec3i32(11,9,89), Vec3i32(11,0,9), Vec3i32(55,90,53), Vec3i32(55,79,90), Vec3i32(55,80,79), Vec3i32(91,11,10), Vec3i32(92,69,12), Vec3i32(92,70,69), Vec3i32(34,93,37), Vec3i32(47,94,52), Vec3i32(47,95,94), Vec3i32(47,57,95), Vec3i32(47,58,57), Vec3i32(51,24,49), Vec3i32(21,35,19), Vec3i32(21,36,35), Vec3i32(14,92,12), Vec3i32(86,10,87), Vec3i32(86,91,10), Vec3i32(77,55,67), Vec3i32(66,14,13), Vec3i32(96,97,4), Vec3i32(98,99,100), Vec3i32(101,102,98), Vec3i32(103,101,98), Vec3i32(104,103,98), Vec3i32(105,106,107), Vec3i32(108,105,107), Vec3i32(109,108,107), Vec3i32(100,109,107), Vec3i32(110,111,112), Vec3i32(113,110,112), Vec3i32(114,115,116), Vec3i32(117,114,116), Vec3i32(118,119,120), Vec3i32(121,122,123), Vec3i32(124,121,123), Vec3i32(125,126,127), Vec3i32(128,129,130), Vec3i32(131,132,133), Vec3i32(71,131,133), Vec3i32(134,71,133), Vec3i32(135,134,133), Vec3i32(136,135,133), Vec3i32(137,138,139), Vec3i32(140,137,139), Vec3i32(141,140,139), Vec3i32(142,31,141), Vec3i32(142,141,139), Vec3i32(143,126,132), Vec3i32(144,145,146), Vec3i32(147,144,146), Vec3i32(127,147,146), Vec3i32(148,121,124), Vec3i32(149,148,124), Vec3i32(150,149,124), Vec3i32(151,150,124), Vec3i32(152,151,124), Vec3i32(153,152,124), Vec3i32(154,153,124), Vec3i32(155,154,124), Vec3i32(129,156,157), Vec3i32(130,129,157), Vec3i32(158,159,160), Vec3i32(161,158,160), Vec3i32(162,161,160), Vec3i32(163,162,160), Vec3i32(146,163,160), Vec3i32(164,165,166), Vec3i32(167,164,166), Vec3i32(168,169,170), Vec3i32(171,168,170), Vec3i32(139,171,170), Vec3i32(159,172,173), Vec3i32(123,174,142), Vec3i32(175,110,113), Vec3i32(173,175,113), Vec3i32(106,176,177), Vec3i32(178,106,177), Vec3i32(179,180,167), Vec3i32(112,179,167), Vec3i32(175,173,172), Vec3i32(119,118,181), Vec3i32(119,181,97), Vec3i32(119,97,96), Vec3i32(182,98,102), Vec3i32(182,102,183), Vec3i32(182,183,120), Vec3i32(182,120,119), Vec3i32(143,132,184), Vec3i32(184,185,143), Vec3i32(147,127,126), Vec3i32(174,123,122), Vec3i32(159,173,160), Vec3i32(126,125,133), Vec3i32(126,133,132), Vec3i32(186,187,188), Vec3i32(186,188,116), Vec3i32(186,116,115), Vec3i32(99,98,182), Vec3i32(109,100,99), Vec3i32(106,178,107), Vec3i32(114,117,177), Vec3i32(114,177,176), Vec3i32(128,130,187), Vec3i32(128,187,186), Vec3i32(135,136,157), Vec3i32(135,157,156), Vec3i32(163,146,145), Vec3i32(164,167,180), Vec3i32(179,112,111), Vec3i32(171,139,138), Vec3i32(189,155,166), Vec3i32(189,166,165), Vec3i32(149,150,93), Vec3i32(154,155,189), Vec3i32(31,142,174), Vec3i32(114,176,78), Vec3i32(81,78,176), Vec3i32(7,89,183), Vec3i32(89,9,120), Vec3i32(89,120,183), Vec3i32(78,80,114), Vec3i32(176,106,81), Vec3i32(88,5,103), Vec3i32(183,102,7), Vec3i32(118,120,9), Vec3i32(9,2,181), Vec3i32(9,181,118), Vec3i32(115,114,80), Vec3i32(82,81,106), Vec3i32(101,103,5), Vec3i32(102,101,5), Vec3i32(5,7,102), Vec3i32(97,181,2), Vec3i32(2,1,97), Vec3i32(1,3,97), Vec3i32(80,55,115), Vec3i32(172,159,59), Vec3i32(59,56,172), Vec3i32(3,4,97), Vec3i32(4,0,96), Vec3i32(105,108,82), Vec3i32(186,115,55), Vec3i32(82,106,105), Vec3i32(83,82,108), Vec3i32(60,59,159), Vec3i32(175,172,56), Vec3i32(119,96,0), Vec3i32(0,11,119), Vec3i32(108,109,84), Vec3i32(84,83,108), Vec3i32(55,77,186), Vec3i32(56,58,110), Vec3i32(56,110,175), Vec3i32(60,159,158), Vec3i32(11,91,182), Vec3i32(182,119,11), Vec3i32(91,86,182), Vec3i32(85,84,109), Vec3i32(86,85,99), Vec3i32(128,186,77), Vec3i32(58,111,110), Vec3i32(158,161,60), Vec3i32(26,25,137), Vec3i32(138,137,25), Vec3i32(99,182,86), Vec3i32(109,99,85), Vec3i32(77,76,128), Vec3i32(58,47,111), Vec3i32(61,60,161), Vec3i32(137,140,26), Vec3i32(27,26,140), Vec3i32(25,22,138), Vec3i32(129,128,76), Vec3i32(76,75,129), Vec3i32(75,74,129), Vec3i32(74,73,156), Vec3i32(73,72,135), Vec3i32(68,16,184), Vec3i32(68,184,132), Vec3i32(16,18,185), Vec3i32(161,162,62), Vec3i32(62,61,161), Vec3i32(179,111,47), Vec3i32(171,138,22), Vec3i32(156,129,74), Vec3i32(135,156,73), Vec3i32(134,135,72), Vec3i32(72,71,134), Vec3i32(68,132,131), Vec3i32(185,184,16), Vec3i32(18,15,185), Vec3i32(63,62,162), Vec3i32(28,27,140), Vec3i32(22,24,171), Vec3i32(71,68,131), Vec3i32(15,17,143), Vec3i32(15,143,185), Vec3i32(17,70,143), Vec3i32(70,92,126), Vec3i32(162,163,64), Vec3i32(64,63,162), Vec3i32(180,179,47), Vec3i32(47,46,180), Vec3i32(140,141,28), Vec3i32(168,171,24), Vec3i32(126,143,70), Vec3i32(92,14,147), Vec3i32(147,126,92), Vec3i32(14,66,144), Vec3i32(14,144,147), Vec3i32(65,64,163), Vec3i32(66,65,145), Vec3i32(46,45,180), Vec3i32(32,28,141), Vec3i32(24,51,168), Vec3i32(145,144,66), Vec3i32(163,145,65), Vec3i32(164,180,45), Vec3i32(45,44,164), Vec3i32(44,43,164), Vec3i32(43,42,165), Vec3i32(38,37,151), Vec3i32(150,151,37), Vec3i32(37,93,150), Vec3i32(141,31,30), Vec3i32(30,32,141), Vec3i32(169,168,51), Vec3i32(165,164,43), Vec3i32(189,165,42), Vec3i32(42,41,189), Vec3i32(40,39,152), Vec3i32(40,152,153), Vec3i32(151,152,39), Vec3i32(39,38,151), Vec3i32(93,34,149), Vec3i32(154,189,41), Vec3i32(153,154,41), Vec3i32(41,40,153), Vec3i32(148,149,34), Vec3i32(34,36,148), Vec3i32(36,21,121), Vec3i32(31,174,29), Vec3i32(121,148,36), Vec3i32(21,33,122), Vec3i32(21,122,121), Vec3i32(33,29,122), Vec3i32(174,122,29), Vec3i32(116,188,53), Vec3i32(104,98,10), Vec3i32(87,10,98), Vec3i32(98,100,87), Vec3i32(79,87,100), Vec3i32(79,100,107), Vec3i32(90,79,107), Vec3i32(90,107,178), Vec3i32(178,177,90), Vec3i32(53,90,177), Vec3i32(53,177,117), Vec3i32(117,116,53), Vec3i32(54,53,188), Vec3i32(54,188,187), Vec3i32(67,54,187), Vec3i32(67,187,130), Vec3i32(69,67,130), Vec3i32(69,130,157), Vec3i32(12,69,157), Vec3i32(12,157,136), Vec3i32(136,133,12), Vec3i32(12,133,125), Vec3i32(125,127,12), Vec3i32(13,12,127), Vec3i32(127,146,13), Vec3i32(57,13,146), Vec3i32(57,146,160), Vec3i32(95,57,160), Vec3i32(95,160,173), Vec3i32(173,113,95), Vec3i32(94,95,113), Vec3i32(113,112,94), Vec3i32(52,94,112), Vec3i32(48,52,112), Vec3i32(112,167,48), Vec3i32(35,48,167), Vec3i32(35,167,166), Vec3i32(19,35,166), Vec3i32(139,170,50), Vec3i32(50,49,139), Vec3i32(166,155,19), Vec3i32(20,19,155), Vec3i32(155,124,20), Vec3i32(23,20,124), Vec3i32(23,124,123), Vec3i32(49,23,123), Vec3i32(49,123,142), Vec3i32(142,139,49), Vec3i32(190,191,170), Vec3i32(192,191,190), Vec3i32(191,192,51), Vec3i32(191,51,50), Vec3i32(170,169,190), Vec3i32(169,51,192), Vec3i32(169,192,190), Vec3i32(170,191,50), Vec3i32(193,194,195), Vec3i32(196,197,198), Vec3i32(199,200,201), Vec3i32(198,202,203), Vec3i32(204,201,200), Vec3i32(205,204,200), Vec3i32(206,207,208), Vec3i32(206,208,205), Vec3i32(206,205,200), Vec3i32(207,206,209), Vec3i32(207,209,203), Vec3i32(207,203,202), Vec3i32(202,198,197), Vec3i32(197,196,210), Vec3i32(197,210,195), Vec3i32(197,195,194), Vec3i32(8,88,195), Vec3i32(8,195,210), Vec3i32(210,196,8), Vec3i32(196,198,8), Vec3i32(198,203,8), Vec3i32(203,209,8), Vec3i32(209,206,8), Vec3i32(206,200,8), Vec3i32(202,197,104), Vec3i32(207,202,104), Vec3i32(103,104,197), Vec3i32(103,197,194), Vec3i32(193,195,88), Vec3i32(88,103,194), Vec3i32(88,194,193), Vec3i32(200,199,8), Vec3i32(199,201,8), Vec3i32(204,205,6), Vec3i32(6,8,201), Vec3i32(6,201,204), Vec3i32(10,6,205), Vec3i32(10,205,208), Vec3i32(104,10,208), Vec3i32(104,208,207) }; break; case TestMesh::pyramid: - vertices = std::vector{ - Vec3d(10,10,40), Vec3d(0,0,0), Vec3d(20,0,0), Vec3d(20,20,0), Vec3d(0,20,0) + vertices = std::vector{ + Vec3f(10,10,40), Vec3f(0,0,0), Vec3f(20,0,0), Vec3f(20,20,0), Vec3f(0,20,0) }; facets = std::vector{ Vec3i32(0,1,2), Vec3i32(0,3,4), Vec3i32(3,1,4), Vec3i32(1,3,2), Vec3i32(3,0,2), Vec3i32(4,1,0) }; break; case TestMesh::two_hollow_squares: - vertices = std::vector{ - Vec3d(66.7133483886719,104.286666870117,0), Vec3d(66.7133483886719,95.7133331298828,0), Vec3d(65.6666870117188,94.6666717529297,0), Vec3d(75.2866821289062,95.7133331298828,0), Vec3d(76.3333435058594,105.333335876465,0), Vec3d(76.3333435058594,94.6666717529297,0), - Vec3d(65.6666870117188,105.33332824707,0), Vec3d(75.2866821289062,104.286666870117,0), Vec3d(71.1066818237305,104.58666229248,2.79999995231628), Vec3d(66.4133529663086,104.58666229248,2.79999995231628), Vec3d(75.5866851806641,104.58666229248,2.79999995231628), - Vec3d(66.4133529663086,99.8933334350586,2.79999995231628), Vec3d(66.4133529663086,95.4133377075195,2.79999995231628), Vec3d(71.1066818237305,95.4133377075195,2.79999995231628), Vec3d(75.5866851806641,95.4133377075195,2.79999995231628), Vec3d(75.5866851806641,100.106666564941,2.79999995231628), - Vec3d(74.5400161743164,103.540000915527,2.79999995231628), Vec3d(70.0320129394531,103.540000915527,2.79999995231628), Vec3d(67.4600067138672,103.540000915527,2.79999995231628), Vec3d(67.4600067138672,100.968002319336,2.79999995231628), Vec3d(67.4600067138672,96.4599990844727,2.79999995231628), - Vec3d(74.5400161743164,99.0319976806641,2.79999995231628), Vec3d(74.5400161743164,96.4599990844727,2.79999995231628), Vec3d(70.0320129394531,96.4599990844727,2.79999995231628), Vec3d(123.666717529297,94.6666717529297,0), Vec3d(134.333312988281,94.6666717529297,0), - Vec3d(124.413360595703,95.4133377075195,2.79999995231628), Vec3d(129.106674194336,95.4133377075195,2.79999995231628), Vec3d(133.586669921875,95.4133377075195,2.79999995231628), Vec3d(123.666717529297,105.33332824707,0), Vec3d(124.413360595703,104.58666229248,2.79999995231628), - Vec3d(124.413360595703,99.8933334350586,2.79999995231628), Vec3d(134.333312988281,105.33332824707,0), Vec3d(129.106674194336,104.58666229248,2.79999995231628), Vec3d(133.586669921875,104.58666229248,2.79999995231628), Vec3d(133.586669921875,100.106666564941,2.79999995231628), - Vec3d(124.713317871094,104.286666870117,0), Vec3d(124.713317871094,95.7133331298828,0), Vec3d(133.286712646484,95.7133331298828,0), Vec3d(133.286712646484,104.286666870117,0), Vec3d(132.540023803711,103.540000915527,2.79999995231628), Vec3d(128.032028198242,103.540008544922,2.79999995231628), - Vec3d(125.460006713867,103.540000915527,2.79999995231628), Vec3d(125.460006713867,100.968002319336,2.79999995231628), Vec3d(125.460006713867,96.4599990844727,2.79999995231628), Vec3d(132.540023803711,99.0319976806641,2.79999995231628), Vec3d(132.540023803711,96.4599990844727,2.79999995231628), - Vec3d(128.032028198242,96.4599990844727,2.79999995231628) + vertices = std::vector{ + Vec3f(66.7133483886719,104.286666870117,0), Vec3f(66.7133483886719,95.7133331298828,0), Vec3f(65.6666870117188,94.6666717529297,0), Vec3f(75.2866821289062,95.7133331298828,0), Vec3f(76.3333435058594,105.333335876465,0), Vec3f(76.3333435058594,94.6666717529297,0), + Vec3f(65.6666870117188,105.33332824707,0), Vec3f(75.2866821289062,104.286666870117,0), Vec3f(71.1066818237305,104.58666229248,2.79999995231628), Vec3f(66.4133529663086,104.58666229248,2.79999995231628), Vec3f(75.5866851806641,104.58666229248,2.79999995231628), + Vec3f(66.4133529663086,99.8933334350586,2.79999995231628), Vec3f(66.4133529663086,95.4133377075195,2.79999995231628), Vec3f(71.1066818237305,95.4133377075195,2.79999995231628), Vec3f(75.5866851806641,95.4133377075195,2.79999995231628), Vec3f(75.5866851806641,100.106666564941,2.79999995231628), + Vec3f(74.5400161743164,103.540000915527,2.79999995231628), Vec3f(70.0320129394531,103.540000915527,2.79999995231628), Vec3f(67.4600067138672,103.540000915527,2.79999995231628), Vec3f(67.4600067138672,100.968002319336,2.79999995231628), Vec3f(67.4600067138672,96.4599990844727,2.79999995231628), + Vec3f(74.5400161743164,99.0319976806641,2.79999995231628), Vec3f(74.5400161743164,96.4599990844727,2.79999995231628), Vec3f(70.0320129394531,96.4599990844727,2.79999995231628), Vec3f(123.666717529297,94.6666717529297,0), Vec3f(134.333312988281,94.6666717529297,0), + Vec3f(124.413360595703,95.4133377075195,2.79999995231628), Vec3f(129.106674194336,95.4133377075195,2.79999995231628), Vec3f(133.586669921875,95.4133377075195,2.79999995231628), Vec3f(123.666717529297,105.33332824707,0), Vec3f(124.413360595703,104.58666229248,2.79999995231628), + Vec3f(124.413360595703,99.8933334350586,2.79999995231628), Vec3f(134.333312988281,105.33332824707,0), Vec3f(129.106674194336,104.58666229248,2.79999995231628), Vec3f(133.586669921875,104.58666229248,2.79999995231628), Vec3f(133.586669921875,100.106666564941,2.79999995231628), + Vec3f(124.713317871094,104.286666870117,0), Vec3f(124.713317871094,95.7133331298828,0), Vec3f(133.286712646484,95.7133331298828,0), Vec3f(133.286712646484,104.286666870117,0), Vec3f(132.540023803711,103.540000915527,2.79999995231628), Vec3f(128.032028198242,103.540008544922,2.79999995231628), + Vec3f(125.460006713867,103.540000915527,2.79999995231628), Vec3f(125.460006713867,100.968002319336,2.79999995231628), Vec3f(125.460006713867,96.4599990844727,2.79999995231628), Vec3f(132.540023803711,99.0319976806641,2.79999995231628), Vec3f(132.540023803711,96.4599990844727,2.79999995231628), + Vec3f(128.032028198242,96.4599990844727,2.79999995231628) }; facets = std::vector{ Vec3i32(0,1,2), Vec3i32(3,4,5), Vec3i32(6,4,0), Vec3i32(6,0,2), Vec3i32(2,1,5), Vec3i32(7,4,3), Vec3i32(1,3,5), Vec3i32(0,4,7), Vec3i32(4,6,8), Vec3i32(6,9,8), Vec3i32(4,8,10), Vec3i32(6,2,9), Vec3i32(2,11,9), Vec3i32(2,12,11), Vec3i32(2,5,12), Vec3i32(5,13,12), Vec3i32(5,14,13), @@ -160,17 +160,17 @@ TriangleMesh mesh(TestMesh m) { }; break; case TestMesh::small_dorito: - vertices = std::vector{ - Vec3d(6.00058937072754,-22.9982089996338,0), Vec3d(22.0010242462158,-49.9998741149902,0), Vec3d(-9.99957847595215,-49.999870300293,0), Vec3d(6.00071382522583,-32.2371635437012,28.0019245147705), Vec3d(11.1670551300049,-37.9727020263672,18.9601669311523), - Vec3d(6.00060224533081,-26.5392456054688,10.7321853637695) + vertices = std::vector{ + Vec3f(6.00058937072754,-22.9982089996338,0), Vec3f(22.0010242462158,-49.9998741149902,0), Vec3f(-9.99957847595215,-49.999870300293,0), Vec3f(6.00071382522583,-32.2371635437012,28.0019245147705), Vec3f(11.1670551300049,-37.9727020263672,18.9601669311523), + Vec3f(6.00060224533081,-26.5392456054688,10.7321853637695) }; facets = std::vector{ Vec3i32(0,1,2), Vec3i32(3,4,5), Vec3i32(2,1,4), Vec3i32(2,4,3), Vec3i32(2,3,5), Vec3i32(2,5,0), Vec3i32(5,4,1), Vec3i32(5,1,0) }; break; case TestMesh::bridge: - vertices = std::vector{ - Vec3d(75,84.5,8), Vec3d(125,84.5,8), Vec3d(75,94.5,8), Vec3d(120,84.5,5), Vec3d(125,94.5,8), Vec3d(75,84.5,0), Vec3d(80,84.5,5), Vec3d(125,84.5,0), Vec3d(125,94.5,0), Vec3d(80,94.5,5), Vec3d(75,94.5,0), Vec3d(120,94.5,5), Vec3d(120,84.5,0), Vec3d(80,94.5,0), Vec3d(80,84.5,0), Vec3d(120,94.5,0) + vertices = std::vector{ + Vec3f(75,84.5,8), Vec3f(125,84.5,8), Vec3f(75,94.5,8), Vec3f(120,84.5,5), Vec3f(125,94.5,8), Vec3f(75,84.5,0), Vec3f(80,84.5,5), Vec3f(125,84.5,0), Vec3f(125,94.5,0), Vec3f(80,94.5,5), Vec3f(75,94.5,0), Vec3f(120,94.5,5), Vec3f(120,84.5,0), Vec3f(80,94.5,0), Vec3f(80,84.5,0), Vec3f(120,94.5,0) }; facets = std::vector{ Vec3i32(0,1,2), Vec3i32(1,0,3), Vec3i32(2,1,4), Vec3i32(2,5,0), Vec3i32(0,6,3), Vec3i32(1,3,7), Vec3i32(1,8,4), Vec3i32(4,9,2), Vec3i32(10,5,2), Vec3i32(5,6,0), Vec3i32(6,11,3), Vec3i32(3,12,7), Vec3i32(7,8,1), Vec3i32(4,8,11), Vec3i32(4,11,9), Vec3i32(9,10,2), Vec3i32(10,13,5), @@ -178,8 +178,8 @@ TriangleMesh mesh(TestMesh m) { }; break; case TestMesh::bridge_with_hole: - vertices = std::vector{ - Vec3d(75,69.5,8), Vec3d(80,76.9091644287109,8), Vec3d(75,94.5,8), Vec3d(125,69.5,8), Vec3d(120,76.9091644287109,8), Vec3d(120,87.0908355712891,8), Vec3d(80,87.0908355712891,8), Vec3d(125,94.5,8), Vec3d(80,87.0908355712891,5), Vec3d(120,87.0908355712891,5), Vec3d(125,94.5,0), Vec3d(120,69.5,0), Vec3d(120,94.5,0), Vec3d(125,69.5,0), Vec3d(120,94.5,5), Vec3d(80,94.5,5), Vec3d(80,94.5,0), Vec3d(75,94.5,0), Vec3d(80,69.5,5), Vec3d(80,69.5,0), Vec3d(80,76.9091644287109,5), Vec3d(120,69.5,5), Vec3d(75,69.5,0), Vec3d(120,76.9091644287109,5) + vertices = std::vector{ + Vec3f(75,69.5,8), Vec3f(80,76.9091644287109,8), Vec3f(75,94.5,8), Vec3f(125,69.5,8), Vec3f(120,76.9091644287109,8), Vec3f(120,87.0908355712891,8), Vec3f(80,87.0908355712891,8), Vec3f(125,94.5,8), Vec3f(80,87.0908355712891,5), Vec3f(120,87.0908355712891,5), Vec3f(125,94.5,0), Vec3f(120,69.5,0), Vec3f(120,94.5,0), Vec3f(125,69.5,0), Vec3f(120,94.5,5), Vec3f(80,94.5,5), Vec3f(80,94.5,0), Vec3f(75,94.5,0), Vec3f(80,69.5,5), Vec3f(80,69.5,0), Vec3f(80,76.9091644287109,5), Vec3f(120,69.5,5), Vec3f(75,69.5,0), Vec3f(120,76.9091644287109,5) }; facets = std::vector{ Vec3i32(0,1,2), Vec3i32(1,0,3), Vec3i32(1,3,4), Vec3i32(4,3,5), Vec3i32(2,6,7), Vec3i32(6,2,1), Vec3i32(7,6,5), Vec3i32(7,5,3), Vec3i32(5,8,9), Vec3i32(8,5,6), Vec3i32(10,11,12), Vec3i32(11,10,13), Vec3i32(14,8,15), Vec3i32(8,14,9), Vec3i32(2,16,17), Vec3i32(16,2,15), Vec3i32(15,2,14), @@ -187,8 +187,8 @@ TriangleMesh mesh(TestMesh m) { }; break; case TestMesh::step: - vertices = std::vector{ - Vec3d(0,20,5), Vec3d(0,20,0), Vec3d(0,0,5), Vec3d(0,0,0), Vec3d(20,0,0), Vec3d(20,0,5), Vec3d(1,19,5), Vec3d(1,1,5), Vec3d(19,1,5), Vec3d(20,20,5), Vec3d(19,19,5), Vec3d(20,20,0), Vec3d(19,19,10), Vec3d(1,19,10), Vec3d(1,1,10), Vec3d(19,1,10) + vertices = std::vector{ + Vec3f(0,20,5), Vec3f(0,20,0), Vec3f(0,0,5), Vec3f(0,0,0), Vec3f(20,0,0), Vec3f(20,0,5), Vec3f(1,19,5), Vec3f(1,1,5), Vec3f(19,1,5), Vec3f(20,20,5), Vec3f(19,19,5), Vec3f(20,20,0), Vec3f(19,19,10), Vec3f(1,19,10), Vec3f(1,1,10), Vec3f(19,1,10) }; facets = std::vector{ Vec3i32(0,1,2), Vec3i32(1,3,2), Vec3i32(3,4,5), Vec3i32(2,3,5), Vec3i32(6,0,2), Vec3i32(6,2,7), Vec3i32(5,8,7), Vec3i32(5,7,2), Vec3i32(9,10,8), Vec3i32(9,8,5), Vec3i32(9,0,6), Vec3i32(9,6,10), Vec3i32(9,11,1), Vec3i32(9,1,0), Vec3i32(3,1,11), Vec3i32(4,3,11), Vec3i32(5,11,9), @@ -196,9 +196,9 @@ TriangleMesh mesh(TestMesh m) { }; break; case TestMesh::slopy_cube: - vertices = std::vector{ - Vec3d(-10,-10,0) , Vec3d(-10,-10,20) , Vec3d(-10,10,0) , Vec3d(-10,10,20) , Vec3d(0,-10,10) , Vec3d(10,-10,0) , Vec3d(2.92893,-10,10) , Vec3d(10,-10,2.92893) , - Vec3d(0,-10,20) , Vec3d(10,10,0) , Vec3d(0,10,10) , Vec3d(0,10,20) , Vec3d(2.92893,10,10) , Vec3d(10,10,2.92893) + vertices = std::vector{ + Vec3f(-10,-10,0) , Vec3f(-10,-10,20) , Vec3f(-10,10,0) , Vec3f(-10,10,20) , Vec3f(0,-10,10) , Vec3f(10,-10,0) , Vec3f(2.92893,-10,10) , Vec3f(10,-10,2.92893) , + Vec3f(0,-10,20) , Vec3f(10,10,0) , Vec3f(0,10,10) , Vec3f(0,10,20) , Vec3f(2.92893,10,10) , Vec3f(10,10,2.92893) }; facets = std::vector{ Vec3i32(0,1,2) , Vec3i32(2,1,3) , Vec3i32(4,0,5) , Vec3i32(4,1,0) , Vec3i32(6,4,7) , Vec3i32(7,4,5) , Vec3i32(4,8,1) , Vec3i32(0,2,5) , Vec3i32(5,2,9) , Vec3i32(2,10,9) , Vec3i32(10,3,11) , @@ -207,8 +207,8 @@ TriangleMesh mesh(TestMesh m) { }; break; case TestMesh::di_5mm_center_notch: - vertices = std::vector{ - Vec3d(-15,-15,0),Vec3d(-15,15,10),Vec3d(-15,15,0),Vec3d(-15,-15,10),Vec3d(3,-2,10),Vec3d(15,15,10),Vec3d(3,3,10),Vec3d(-2,3,10),Vec3d(-2,-2,10),Vec3d(15,-15,10),Vec3d(15,15,0),Vec3d(15,-15,0),Vec3d(-2,3,5),Vec3d(-2,-2,5),Vec3d(3,-2,5),Vec3d(3,3,5) + vertices = std::vector{ + Vec3f(-15,-15,0),Vec3f(-15,15,10),Vec3f(-15,15,0),Vec3f(-15,-15,10),Vec3f(3,-2,10),Vec3f(15,15,10),Vec3f(3,3,10),Vec3f(-2,3,10),Vec3f(-2,-2,10),Vec3f(15,-15,10),Vec3f(15,15,0),Vec3f(15,-15,0),Vec3f(-2,3,5),Vec3f(-2,-2,5),Vec3f(3,-2,5),Vec3f(3,3,5) }; facets = std::vector{ Vec3i32(0,1,2),Vec3i32(1,0,3),Vec3i32(4,5,6),Vec3i32(5,7,6),Vec3i32(7,1,8),Vec3i32(1,7,5),Vec3i32(5,4,9),Vec3i32(8,9,4),Vec3i32(8,3,9),Vec3i32(3,8,1),Vec3i32(9,10,5),Vec3i32(10,9,11),Vec3i32(10,1,5),Vec3i32(1,10,2),Vec3i32(0,10,11),Vec3i32(10,0,2),Vec3i32(0,9,3),Vec3i32(9,0,11), @@ -216,8 +216,8 @@ TriangleMesh mesh(TestMesh m) { }; break; case TestMesh::di_10mm_notch: - vertices = std::vector{ - Vec3d(-15,15,0),Vec3d(-15,-5,5),Vec3d(-15,15,10),Vec3d(-15,-15,0),Vec3d(-15,-15,5),Vec3d(-15,-5,10),Vec3d(15,15,10),Vec3d(-5,-5,10),Vec3d(15,-15,10),Vec3d(-5,-15,10),Vec3d(15,15,0),Vec3d(15,-15,0),Vec3d(-5,-15,5),Vec3d(-5,-5,5) + vertices = std::vector{ + Vec3f(-15,15,0),Vec3f(-15,-5,5),Vec3f(-15,15,10),Vec3f(-15,-15,0),Vec3f(-15,-15,5),Vec3f(-15,-5,10),Vec3f(15,15,10),Vec3f(-5,-5,10),Vec3f(15,-15,10),Vec3f(-5,-15,10),Vec3f(15,15,0),Vec3f(15,-15,0),Vec3f(-5,-15,5),Vec3f(-5,-5,5) }; facets = std::vector{ Vec3i32(0,1,2),Vec3i32(3,1,0),Vec3i32(1,3,4),Vec3i32(2,1,5),Vec3i32(6,7,8),Vec3i32(2,7,6),Vec3i32(7,2,5),Vec3i32(8,7,9),Vec3i32(8,10,6),Vec3i32(10,8,11),Vec3i32(10,2,6),Vec3i32(2,10,0),Vec3i32(3,10,11),Vec3i32(10,3,0),Vec3i32(4,3,12),Vec3i32(12,8,9),Vec3i32(11,12,3),Vec3i32(12,11,8), @@ -225,8 +225,8 @@ TriangleMesh mesh(TestMesh m) { }; break; case TestMesh::di_20mm_notch: - vertices = std::vector{ - Vec3d(-15,15,0),Vec3d(-15,5,5),Vec3d(-15,15,10),Vec3d(-15,-15,0),Vec3d(-15,-15,5),Vec3d(-15,5,10),Vec3d(15,15,10),Vec3d(5,5,10),Vec3d(15,-15,10),Vec3d(5,-15,10),Vec3d(15,15,0),Vec3d(15,-15,0),Vec3d(5,-15,5),Vec3d(5,5,5) + vertices = std::vector{ + Vec3f(-15,15,0),Vec3f(-15,5,5),Vec3f(-15,15,10),Vec3f(-15,-15,0),Vec3f(-15,-15,5),Vec3f(-15,5,10),Vec3f(15,15,10),Vec3f(5,5,10),Vec3f(15,-15,10),Vec3f(5,-15,10),Vec3f(15,15,0),Vec3f(15,-15,0),Vec3f(5,-15,5),Vec3f(5,5,5) }; facets = std::vector{ Vec3i32(0,1,2),Vec3i32(3,1,0),Vec3i32(1,3,4),Vec3i32(2,1,5),Vec3i32(6,7,8),Vec3i32(2,7,6),Vec3i32(7,2,5),Vec3i32(8,7,9),Vec3i32(8,10,6),Vec3i32(10,8,11),Vec3i32(3,10,11),Vec3i32(10,3,0),Vec3i32(4,3,12),Vec3i32(12,8,9),Vec3i32(12,11,8),Vec3i32(11,12,3),Vec3i32(10,2,6),Vec3i32(2,10,0), @@ -234,8 +234,8 @@ TriangleMesh mesh(TestMesh m) { }; break; case TestMesh::di_25mm_notch: - vertices = std::vector{ - Vec3d(-15,15,0),Vec3d(-15,10,5),Vec3d(-15,15,10),Vec3d(-15,-15,0),Vec3d(-15,-15,5),Vec3d(-15,10,10),Vec3d(15,15,10),Vec3d(10,10,10),Vec3d(15,-15,10),Vec3d(10,-15,10),Vec3d(15,15,0),Vec3d(15,-15,0),Vec3d(10,-15,5),Vec3d(10,10,5) + vertices = std::vector{ + Vec3f(-15,15,0),Vec3f(-15,10,5),Vec3f(-15,15,10),Vec3f(-15,-15,0),Vec3f(-15,-15,5),Vec3f(-15,10,10),Vec3f(15,15,10),Vec3f(10,10,10),Vec3f(15,-15,10),Vec3f(10,-15,10),Vec3f(15,15,0),Vec3f(15,-15,0),Vec3f(10,-15,5),Vec3f(10,10,5) }; facets = std::vector{ Vec3i32(0,1,2),Vec3i32(3,1,0),Vec3i32(1,3,4),Vec3i32(2,1,5),Vec3i32(6,7,8),Vec3i32(2,7,6),Vec3i32(7,2,5),Vec3i32(8,7,9),Vec3i32(8,10,6),Vec3i32(10,8,11),Vec3i32(3,10,11),Vec3i32(10,3,0),Vec3i32(4,3,12),Vec3i32(12,8,9),Vec3i32(12,11,8),Vec3i32(11,12,3),Vec3i32(10,2,6),Vec3i32(2,10,0), @@ -261,7 +261,7 @@ TriangleMesh mesh(TestMesh m) { _mesh = TriangleMesh(vertices, facets); } - _mesh.repair(); + //_mesh.repair(); return _mesh; } @@ -269,7 +269,9 @@ TriangleMesh mesh(TestMesh m) { void init_print(Print& print, std::initializer_list meshes, Slic3r::Model& model, DynamicPrintConfig* _config, bool comments) { DynamicPrintConfig &config = Slic3r::DynamicPrintConfig::full_print_config(); config.apply(*_config); - + + //remove print of status + print.set_status_callback([](const PrintBase::SlicingStatus &) {}); //const std::string v {std::getenv("SLIC3R_TESTS_GCODE")}; //auto tests_gcode {(v == "" ? ""s : std::string(v))}; @@ -288,7 +290,7 @@ void init_print(Print& print, std::initializer_list meshes, Slic3r::Mo } print.apply(model, config); // apply config for the arrange_objects - arrange_objects(model, InfiniteBed{}, ArrangeParams{ scaled(print.config().min_object_distance()) }); + arrange_objects(model, InfiniteBed{}, ArrangeParams{ scale_t(10)});//print.config().min_object_distance()) }); model.center_instances_around_point(Slic3r::Vec2d(100,100)); for (auto* mo : model.objects) { print.auto_assign_extruders(mo); @@ -304,7 +306,9 @@ void init_print(Print& print, std::initializer_list meshes, Slic3r::Mo void init_print(Print& print, std::vector meshes, Slic3r::Model& model, DynamicPrintConfig* _config, bool comments) { DynamicPrintConfig &config = Slic3r::DynamicPrintConfig::full_print_config(); config.apply(*_config); - + + //remove print of status + print.set_status_callback([](const PrintBase::SlicingStatus &) {}); //const std::string v {std::getenv("SLIC3R_TESTS_GCODE")}; //std::string tests_gcode {(v == "" ? "" : v)}; @@ -312,8 +316,8 @@ void init_print(Print& print, std::vector meshes, Slic3r::Model& m //config->set_key_value("gcode_comments", new ConfigOptionBool(true)); for (TriangleMesh& t : meshes) { - if(!t.repaired) - t.repair(); + //if(!t.repaired()) + //t.repair(); ModelObject* object {model.add_object()}; object->name += "object.stl"s; object->add_volume(t); @@ -324,7 +328,7 @@ void init_print(Print& print, std::vector meshes, Slic3r::Model& m } print.apply(model, config); // apply config for the arrange_objects - arrange_objects(model, InfiniteBed{}, ArrangeParams{ scaled(print.config().min_object_distance()) }); + arrange_objects(model, InfiniteBed{}, ArrangeParams{scale_t(10)} );//print.config().min_object_distance())}); model.center_instances_around_point(Slic3r::Vec2d(100,100)); print.apply(model, config); for (ModelObject* mo : model.objects) { diff --git a/tests/superslicerlibslic3r/test_dense_infill.cpp b/tests/superslicerlibslic3r/test_dense_infill.cpp index 060483cecb1..a57f77b3fca 100644 --- a/tests/superslicerlibslic3r/test_dense_infill.cpp +++ b/tests/superslicerlibslic3r/test_dense_infill.cpp @@ -2,7 +2,6 @@ //#define CATCH_CONFIG_DISABLE //#include #include -//#include #include #include "test_data.hpp" @@ -33,18 +32,17 @@ SCENARIO("test auto generation") { //config.set_deserialize("infill_dense_algo", "50"); //config.set_deserialize("extruder_clearance_radius", "10"); WHEN("little surface") { - ExPolygon polygon_to_cover; - polygon_to_cover.contour = get_polygon_scale({ {0,0}, {10,0}, {10,10}, {0,10} }); + ExPolygon expolygon_to_cover; + expolygon_to_cover.contour = get_polygon_scale({ {0,0}, {10,0}, {10,10}, {0,10} }); ExPolygon growing_area; growing_area.contour = get_polygon_scale({ {0,0}, {40,0}, {0,40} }); - ExPolygons allowedPoints; - allowedPoints.emplace_back(); - //diff_ex(offset_ex(growing_area, scale_(1)), offset_ex(layerm->fill_no_overlap_expolygons, double(-layerm->flow(frInfill).scaled_width()))); - allowedPoints.back().contour = get_polygon_scale({ {0,0}, {40,0}, {0,40} }); + //ExPolygons allowedPoints; + //allowedPoints.emplace_back(); + //allowedPoints.back().contour = get_polygon_scale({ {0,0}, {40,0}, {0,40} }); coord_t offset = scale_(2); float coverage = 1.f; - ExPolygons solution = dense_fill_fit_to_size(polygon_to_cover, allowedPoints, growing_area, offset, coverage); + ExPolygons solution = dense_fill_fit_to_size(expolygon_to_cover, growing_area, offset, coverage); THEN("little support") { double area_result = 0; for (ExPolygon& p : solution) diff --git a/tests/superslicerlibslic3r/test_denserinfill.cpp b/tests/superslicerlibslic3r/test_denserinfill.cpp index 2b09c8df727..961c5feb4ab 100644 --- a/tests/superslicerlibslic3r/test_denserinfill.cpp +++ b/tests/superslicerlibslic3r/test_denserinfill.cpp @@ -1,9 +1,10 @@ //#define CATCH_CONFIG_DISABLE - -#include +#include #include "test_data.hpp" #include +#include +#include using namespace Slic3r; using namespace Slic3r::Geometry; @@ -26,14 +27,14 @@ SCENARIO("denser infills: ") config.save("C:\\Users\\Admin\\Desktop\\config_def.ini"); Slic3r::Test::init_print(print, { Slic3r::Test::TestMesh::di_5mm_center_notch }, model, &config, false); print.process(); - PrintObject& object = *(print.objects().at(0)); + const PrintObject& object = *(print.objects().at(0)); //for (int lidx = 0; lidx < object.layers().size(); lidx++) { // std::cout << "layer " << lidx << " : \n"; // std::cout << " - region_count= " << object.layers()[lidx]->region_count() << "\n"; // for (int ridx = 0; ridx < object.layers()[lidx]->regions().size(); ridx++) { // std::cout << " region " << ridx << " : \n"; - // std::cout << " - fills= " << object.layers()[lidx]->regions()[ridx]->fills.entities.size() << "\n"; + // std::cout << " - fills= " << object.layers()[lidx]->regions()[ridx]->fills.entities().size() << "\n"; // std::cout << " - surfaces= " << object.layers()[lidx]->regions()[ridx]->fill_surfaces.surfaces.size() << "\n"; // for (int sidx = 0; sidx < object.layers()[lidx]->regions()[ridx]->fill_surfaces.surfaces.size(); sidx++) { // std::cout << " - type= " << object.layers()[lidx]->regions()[ridx]->fill_surfaces.surfaces[sidx].surface_type << "\n"; @@ -53,8 +54,8 @@ SCENARIO("denser infills: ") REQUIRE(object.layers()[18]->region_count() == 2); }*/ THEN("correct number of fills") { - REQUIRE(object.layers()[20]->regions()[0]->fills.entities.size() == 1); //sparse - REQUIRE(object.layers()[21]->regions()[0]->fills.entities.size() == 2); //sparse + dense + REQUIRE(object.layers()[20]->regions()[0]->fills.entities().size() == 1); //sparse + REQUIRE(object.layers()[21]->regions()[0]->fills.entities().size() == 2); //sparse + dense REQUIRE(object.layers()[21]->regions()[0]->fill_surfaces.surfaces.size() == 2); REQUIRE(object.layers()[21]->regions()[0]->fill_surfaces.surfaces[0].surface_type == (SurfaceType::stDensSparse | SurfaceType::stPosInternal)); REQUIRE(object.layers()[21]->regions()[0]->fill_surfaces.surfaces[1].surface_type == (SurfaceType::stDensSparse | SurfaceType::stPosInternal)); @@ -67,7 +68,7 @@ SCENARIO("denser infills: ") } //std::cout << "sparse area = " << unscaled(unscaled(srfSparse->area())) << " , dense area = " << unscaled(unscaled(srfDense->area())) << "\n"; REQUIRE(unscaled(unscaled(srfSparse->area())) > unscaled(unscaled(srfDense->area()))); - REQUIRE(object.layers()[22]->regions()[0]->fills.entities.size() == 2); //sparse + solid-bridge + REQUIRE(object.layers()[22]->regions()[0]->fills.entities().size() == 2); //sparse + solid-bridge REQUIRE(object.layers()[22]->regions()[0]->fill_surfaces.surfaces.size() == 2); if (object.layers()[22]->regions()[0]->fill_surfaces.surfaces[0].surface_type == (SurfaceType::stDensSparse | SurfaceType::stPosInternal)) { REQUIRE(object.layers()[22]->regions()[0]->fill_surfaces.surfaces[1].surface_type == (SurfaceType::stDensSolid | SurfaceType::stPosInternal | SurfaceType::stModBridge)); @@ -75,9 +76,9 @@ SCENARIO("denser infills: ") REQUIRE(object.layers()[22]->regions()[0]->fill_surfaces.surfaces[0].surface_type == (SurfaceType::stDensSolid | SurfaceType::stPosInternal | SurfaceType::stModBridge)); REQUIRE(object.layers()[22]->regions()[0]->fill_surfaces.surfaces[1].surface_type == (SurfaceType::stDensSparse | SurfaceType::stPosInternal)); } - REQUIRE(object.layers()[23]->regions()[0]->fills.entities.size() == 2); //sparse + solid - REQUIRE(object.layers()[24]->regions()[0]->fills.entities.size() == 3); //sparse + solid-top + solid-top (over perimeters) - REQUIRE(object.layers()[25]->regions()[0]->fills.entities.size() == 1); //sparse + REQUIRE(object.layers()[23]->regions()[0]->fills.entities().size() == 2); //sparse + solid + REQUIRE(object.layers()[24]->regions()[0]->fills.entities().size() == 3); //sparse + solid-top + solid-top (over perimeters) + REQUIRE(object.layers()[25]->regions()[0]->fills.entities().size() == 1); //sparse } } } @@ -95,11 +96,11 @@ SCENARIO("denser infills: ") config.save("C:\\Users\\Admin\\Desktop\\config_def.ini"); Slic3r::Test::init_print(print, { Slic3r::Test::TestMesh::di_10mm_notch }, model, &config, false); print.process(); - PrintObject& object = *(print.objects().at(0)); + const PrintObject& object = *(print.objects().at(0)); THEN("correct number of fills") { REQUIRE(object.layers().size() == 50); - REQUIRE(object.layers()[20]->regions()[0]->fills.entities.size() == 1); //sparse - REQUIRE(object.layers()[21]->regions()[0]->fills.entities.size() == 2); //sparse + dense + REQUIRE(object.layers()[20]->regions()[0]->fills.entities().size() == 1); //sparse + REQUIRE(object.layers()[21]->regions()[0]->fills.entities().size() == 2); //sparse + dense REQUIRE(object.layers()[21]->regions()[0]->fill_surfaces.surfaces.size() == 2); REQUIRE(object.layers()[21]->regions()[0]->fill_surfaces.surfaces[0].surface_type == (SurfaceType::stDensSparse | SurfaceType::stPosInternal)); REQUIRE(object.layers()[21]->regions()[0]->fill_surfaces.surfaces[1].surface_type == (SurfaceType::stDensSparse | SurfaceType::stPosInternal)); @@ -111,7 +112,7 @@ SCENARIO("denser infills: ") srfDense = &object.layers()[21]->regions()[0]->fill_surfaces.surfaces[0]; } REQUIRE(unscaled(unscaled(srfSparse->area())) > unscaled(unscaled(srfDense->area()))); - REQUIRE(object.layers()[22]->regions()[0]->fills.entities.size() == 2); //sparse + solid-bridge + REQUIRE(object.layers()[22]->regions()[0]->fills.entities().size() == 2); //sparse + solid-bridge REQUIRE(object.layers()[22]->regions()[0]->fill_surfaces.surfaces.size() == 2); if (object.layers()[22]->regions()[0]->fill_surfaces.surfaces[0].surface_type == (SurfaceType::stDensSparse | SurfaceType::stPosInternal)) { REQUIRE(object.layers()[22]->regions()[0]->fill_surfaces.surfaces[1].surface_type == (SurfaceType::stDensSolid | SurfaceType::stPosInternal | SurfaceType::stModBridge)); @@ -119,27 +120,27 @@ SCENARIO("denser infills: ") REQUIRE(object.layers()[22]->regions()[0]->fill_surfaces.surfaces[0].surface_type == (SurfaceType::stDensSolid | SurfaceType::stPosInternal | SurfaceType::stModBridge)); REQUIRE(object.layers()[22]->regions()[0]->fill_surfaces.surfaces[1].surface_type == (SurfaceType::stDensSparse | SurfaceType::stPosInternal)); } - REQUIRE(object.layers()[23]->regions()[0]->fills.entities.size() == 2); //sparse + solid - REQUIRE(object.layers()[24]->regions()[0]->fills.entities.size() == 3); //sparse + solid-top + solid-top (over perimeters) - REQUIRE(object.layers()[25]->regions()[0]->fills.entities.size() == 1); //sparse - REQUIRE(object.layers()[45]->regions()[0]->fills.entities.size() == 1); //sparse + REQUIRE(object.layers()[23]->regions()[0]->fills.entities().size() == 2); //sparse + solid + REQUIRE(object.layers()[24]->regions()[0]->fills.entities().size() == 3); //sparse + solid-top + solid-top (over perimeters) + REQUIRE(object.layers()[25]->regions()[0]->fills.entities().size() == 1); //sparse + REQUIRE(object.layers()[45]->regions()[0]->fills.entities().size() == 1); //sparse REQUIRE(object.layers()[45]->regions()[0]->fill_surfaces.surfaces.size() == 1); REQUIRE(object.layers()[45]->regions()[0]->fill_surfaces.surfaces[0].surface_type == (SurfaceType::stDensSparse | SurfaceType::stPosInternal)); REQUIRE(object.layers()[45]->regions()[0]->fill_surfaces.surfaces[0].maxNbSolidLayersOnTop > 1); - REQUIRE(object.layers()[46]->regions()[0]->fills.entities.size() == 1); //dense - REQUIRE(object.layers()[46]->regions()[0]->fills.entities.size() == 1); + REQUIRE(object.layers()[46]->regions()[0]->fills.entities().size() == 1); //dense + REQUIRE(object.layers()[46]->regions()[0]->fills.entities().size() == 1); REQUIRE(object.layers()[46]->regions()[0]->fill_surfaces.surfaces.size() == 1); REQUIRE(object.layers()[46]->regions()[0]->fill_surfaces.surfaces[0].surface_type == (SurfaceType::stDensSparse | SurfaceType::stPosInternal)); REQUIRE(object.layers()[46]->regions()[0]->fill_surfaces.surfaces[0].maxNbSolidLayersOnTop == 1); - REQUIRE(object.layers()[47]->regions()[0]->fills.entities.size() == 1); //solid-bridge + REQUIRE(object.layers()[47]->regions()[0]->fills.entities().size() == 1); //solid-bridge REQUIRE(object.layers()[47]->regions()[0]->fill_surfaces.surfaces.size() == 1); REQUIRE(object.layers()[47]->regions()[0]->fill_surfaces.surfaces[0].surface_type == (SurfaceType::stDensSolid | SurfaceType::stPosInternal | SurfaceType::stModBridge)); REQUIRE(object.layers()[47]->regions()[0]->fill_surfaces.surfaces[0].maxNbSolidLayersOnTop > 1); - REQUIRE(object.layers()[48]->regions()[0]->fills.entities.size() == 1); //solid + REQUIRE(object.layers()[48]->regions()[0]->fills.entities().size() == 1); //solid REQUIRE(object.layers()[48]->regions()[0]->fill_surfaces.surfaces.size() == 1); REQUIRE(object.layers()[48]->regions()[0]->fill_surfaces.surfaces[0].surface_type == (SurfaceType::stDensSolid | SurfaceType::stPosInternal)); REQUIRE(object.layers()[48]->regions()[0]->fill_surfaces.surfaces[0].maxNbSolidLayersOnTop > 1); - REQUIRE(object.layers()[49]->regions()[0]->fills.entities.size() == 1); //top + REQUIRE(object.layers()[49]->regions()[0]->fills.entities().size() == 1); //top REQUIRE(object.layers()[49]->regions()[0]->fill_surfaces.surfaces.size() == 1); REQUIRE(object.layers()[49]->regions()[0]->fill_surfaces.surfaces[0].surface_type == (SurfaceType::stDensSolid | SurfaceType::stPosTop)); REQUIRE(object.layers()[49]->regions()[0]->fill_surfaces.surfaces[0].maxNbSolidLayersOnTop > 1); @@ -157,11 +158,11 @@ SCENARIO("denser infills: ") config.save("C:\\Users\\Admin\\Desktop\\config_def.ini"); Slic3r::Test::init_print(print, { Slic3r::Test::TestMesh::di_10mm_notch }, model, &config, false); print.process(); - PrintObject& object = *(print.objects().at(0)); + const PrintObject& object = *(print.objects().at(0)); THEN("correct number of fills") { REQUIRE(object.layers().size() == 50); - REQUIRE(object.layers()[20]->regions()[0]->fills.entities.size() == 1); //sparse - REQUIRE(object.layers()[21]->regions()[0]->fills.entities.size() == 2); //sparse + dense + REQUIRE(object.layers()[20]->regions()[0]->fills.entities().size() == 1); //sparse + REQUIRE(object.layers()[21]->regions()[0]->fills.entities().size() == 2); //sparse + dense REQUIRE(object.layers()[21]->regions()[0]->fill_surfaces.surfaces.size() == 2); REQUIRE(object.layers()[21]->regions()[0]->fill_surfaces.surfaces[0].surface_type == (SurfaceType::stDensSparse | SurfaceType::stPosInternal)); REQUIRE(object.layers()[21]->regions()[0]->fill_surfaces.surfaces[1].surface_type == (SurfaceType::stDensSparse | SurfaceType::stPosInternal)); @@ -173,7 +174,7 @@ SCENARIO("denser infills: ") srfDense = &object.layers()[21]->regions()[0]->fill_surfaces.surfaces[0]; } REQUIRE(unscaled(unscaled(srfSparse->area())) > unscaled(unscaled(srfDense->area()))); - REQUIRE(object.layers()[22]->regions()[0]->fills.entities.size() == 2); //sparse + solid-bridge + REQUIRE(object.layers()[22]->regions()[0]->fills.entities().size() == 2); //sparse + solid-bridge REQUIRE(object.layers()[22]->regions()[0]->fill_surfaces.surfaces.size() == 2); if (object.layers()[22]->regions()[0]->fill_surfaces.surfaces[0].surface_type == (SurfaceType::stDensSparse | SurfaceType::stPosInternal)) { REQUIRE(object.layers()[22]->regions()[0]->fill_surfaces.surfaces[1].surface_type == (SurfaceType::stDensSolid | SurfaceType::stPosInternal | SurfaceType::stModBridge)); @@ -181,26 +182,26 @@ SCENARIO("denser infills: ") REQUIRE(object.layers()[22]->regions()[0]->fill_surfaces.surfaces[0].surface_type == (SurfaceType::stDensSolid | SurfaceType::stPosInternal | SurfaceType::stModBridge)); REQUIRE(object.layers()[22]->regions()[0]->fill_surfaces.surfaces[1].surface_type == (SurfaceType::stDensSparse | SurfaceType::stPosInternal)); } - REQUIRE(object.layers()[23]->regions()[0]->fills.entities.size() == 2); //sparse + solid - REQUIRE(object.layers()[24]->regions()[0]->fills.entities.size() == 3); //sparse + solid-top + solid-top (over perimeters) - REQUIRE(object.layers()[25]->regions()[0]->fills.entities.size() == 1); //sparse - REQUIRE(object.layers()[45]->regions()[0]->fills.entities.size() == 1); //sparse + REQUIRE(object.layers()[23]->regions()[0]->fills.entities().size() == 2); //sparse + solid + REQUIRE(object.layers()[24]->regions()[0]->fills.entities().size() == 3); //sparse + solid-top + solid-top (over perimeters) + REQUIRE(object.layers()[25]->regions()[0]->fills.entities().size() == 1); //sparse + REQUIRE(object.layers()[45]->regions()[0]->fills.entities().size() == 1); //sparse REQUIRE(object.layers()[45]->regions()[0]->fill_surfaces.surfaces.size() == 1); REQUIRE(object.layers()[45]->regions()[0]->fill_surfaces.surfaces[0].surface_type == (SurfaceType::stDensSparse | SurfaceType::stPosInternal)); REQUIRE(object.layers()[45]->regions()[0]->fill_surfaces.surfaces[0].maxNbSolidLayersOnTop > 1); - REQUIRE(object.layers()[46]->regions()[0]->fills.entities.size() == 1); //dense + REQUIRE(object.layers()[46]->regions()[0]->fills.entities().size() == 1); //dense REQUIRE(object.layers()[46]->regions()[0]->fill_surfaces.surfaces.size() == 1); REQUIRE(object.layers()[46]->regions()[0]->fill_surfaces.surfaces[0].surface_type == (SurfaceType::stDensSparse | SurfaceType::stPosInternal)); REQUIRE(object.layers()[46]->regions()[0]->fill_surfaces.surfaces[0].maxNbSolidLayersOnTop > 1); - REQUIRE(object.layers()[47]->regions()[0]->fills.entities.size() == 1); //solid-bridge + REQUIRE(object.layers()[47]->regions()[0]->fills.entities().size() == 1); //solid-bridge REQUIRE(object.layers()[47]->regions()[0]->fill_surfaces.surfaces.size() == 1); REQUIRE(object.layers()[47]->regions()[0]->fill_surfaces.surfaces[0].surface_type == (SurfaceType::stDensSolid | SurfaceType::stPosInternal | SurfaceType::stModBridge)); REQUIRE(object.layers()[47]->regions()[0]->fill_surfaces.surfaces[0].maxNbSolidLayersOnTop > 1); - REQUIRE(object.layers()[48]->regions()[0]->fills.entities.size() == 1); //solid + REQUIRE(object.layers()[48]->regions()[0]->fills.entities().size() == 1); //solid REQUIRE(object.layers()[48]->regions()[0]->fill_surfaces.surfaces.size() == 1); REQUIRE(object.layers()[48]->regions()[0]->fill_surfaces.surfaces[0].surface_type == (SurfaceType::stDensSolid | SurfaceType::stPosInternal)); REQUIRE(object.layers()[48]->regions()[0]->fill_surfaces.surfaces[0].maxNbSolidLayersOnTop > 1); - REQUIRE(object.layers()[49]->regions()[0]->fills.entities.size() == 1); //top + REQUIRE(object.layers()[49]->regions()[0]->fills.entities().size() == 1); //top REQUIRE(object.layers()[49]->regions()[0]->fill_surfaces.surfaces.size() == 1); REQUIRE(object.layers()[49]->regions()[0]->fill_surfaces.surfaces[0].surface_type == (SurfaceType::stDensSolid | SurfaceType::stPosTop)); REQUIRE(object.layers()[49]->regions()[0]->fill_surfaces.surfaces[0].maxNbSolidLayersOnTop > 1); diff --git a/tests/superslicerlibslic3r/test_extrusion_entity.cpp b/tests/superslicerlibslic3r/test_extrusion_entity.cpp index a4d308a99a5..88a1fc01c5e 100644 --- a/tests/superslicerlibslic3r/test_extrusion_entity.cpp +++ b/tests/superslicerlibslic3r/test_extrusion_entity.cpp @@ -1,13 +1,15 @@ //#define CATCH_CONFIG_DISABLE -#include +#include #include #include "test_data.hpp" #include #include #include #include +#include +#include #include #include @@ -21,7 +23,7 @@ Slic3r::Point random_point(float LO=-50, float HI=50) { // build a sample extrusion entity collection with random start and end points. Slic3r::ExtrusionPath random_path(size_t length = 20, float LO=-50, float HI=50) { - Slic3r::ExtrusionPath t { Slic3r::ExtrusionRole::erPerimeter, 1.0, 1.0, 1.0}; + Slic3r::ExtrusionPath t(Slic3r::ExtrusionRole::erPerimeter, 1.0, 1.0f, 1.0f, true); for (size_t j = 0; j < length; j++) { t.polyline.append(random_point(LO, HI)); } @@ -45,10 +47,10 @@ SCENARIO("ExtrusionEntityCollection: Polygon flattening") { Slic3r::ExtrusionEntityCollection sub_nosort; sub_nosort.append(nosort_path_set); - sub_nosort.no_sort = true; + sub_nosort.set_can_sort_reverse(true, true); Slic3r::ExtrusionEntityCollection sub_sort; - sub_sort.no_sort = false; + sub_nosort.set_can_sort_reverse(false, false); sub_sort.append(random_paths()); @@ -61,24 +63,24 @@ SCENARIO("ExtrusionEntityCollection: Polygon flattening") { WHEN("The EEC is flattened with default options (preserve_order=false)") { Slic3r::ExtrusionEntityCollection output = Slic3r::FlatenEntities(false).flatten(sample); THEN("The output EEC contains no Extrusion Entity Collections") { - CHECK(std::count_if(output.entities.cbegin(), output.entities.cend(), [=](const ExtrusionEntity* e) {return e->is_collection();}) == 0); + CHECK(std::count_if(output.entities().cbegin(), output.entities().cend(), [=](const ExtrusionEntity* e) {return e->is_collection();}) == 0); } } WHEN("The EEC is flattened with preservation (preserve_order=true)") { Slic3r::ExtrusionEntityCollection output = Slic3r::FlatenEntities(true).flatten(sample); THEN("The output EECs contains one EEC.") { - CHECK(std::count_if(output.entities.cbegin(), output.entities.cend(), [=](const ExtrusionEntity* e) {return e->is_collection();}) == 1); + CHECK(std::count_if(output.entities().cbegin(), output.entities().cend(), [=](const ExtrusionEntity* e) {return e->is_collection();}) == 1); } AND_THEN("The ordered EEC contains the same order of elements than the original") { // find the entity in the collection - for (auto e : output.entities) { + for (auto e : output.entities()) { if (!e->is_collection()) continue; Slic3r::ExtrusionEntityCollection* temp = dynamic_cast(e); // check each Extrusion path against nosort_path_set to see if the first and last match the same - CHECK(nosort_path_set.size() == temp->entities.size()); + CHECK(nosort_path_set.size() == temp->entities().size()); for (size_t i = 0; i < nosort_path_set.size(); i++) { - CHECK(temp->entities[i]->first_point() == nosort_path_set[i].first_point()); - CHECK(temp->entities[i]->last_point() == nosort_path_set[i].last_point()); + CHECK(temp->entities()[i]->first_point() == nosort_path_set[i].first_point()); + CHECK(temp->entities()[i]->last_point() == nosort_path_set[i].last_point()); } } } @@ -100,9 +102,9 @@ SCENARIO("ExtrusionEntityCollection: no sort") { print.process(); //replace extrusion from sliceing by manual ones - print.objects()[0]->clear_layers(); - Layer* customL_layer = print.objects()[0]->add_layer(0, 0.2, 0.2, 0.1); - LayerRegion* custom_region = customL_layer->add_region(print.regions()[0]); + print.objects_mutable()[0]->clear_layers(); + Layer* customL_layer = print.objects_mutable()[0]->add_layer(0, 0.2, 0.2, 0.1); + LayerRegion* custom_region = customL_layer->add_region(&print.get_print_region(0)); ExtrusionPath path_peri(ExtrusionRole::erPerimeter); path_peri.polyline.append(Point{ 0,0 }); @@ -123,7 +125,7 @@ SCENARIO("ExtrusionEntityCollection: no sort") { WHEN("sort") { custom_region->fills.append(coll_fill); custom_region->perimeters.append(coll_peri); - coll_fill.no_sort = false; + coll_fill.set_can_sort_reverse(false, false); Slic3r::Test::gcode(gcode_filepath, print); auto parser{ Slic3r::GCodeReader() }; std::vector extrude_x; @@ -142,7 +144,7 @@ SCENARIO("ExtrusionEntityCollection: no sort") { WHEN("no sort") { - coll_fill.no_sort = true; + coll_fill.set_can_sort_reverse(true, true); custom_region->fills.append(coll_fill); custom_region->perimeters.append(coll_peri); Slic3r::Test::gcode(gcode_filepath, print); diff --git a/tests/superslicerlibslic3r/test_fill.cpp b/tests/superslicerlibslic3r/test_fill.cpp index 17165e94c9a..ce8a70f85e2 100644 --- a/tests/superslicerlibslic3r/test_fill.cpp +++ b/tests/superslicerlibslic3r/test_fill.cpp @@ -1,14 +1,16 @@ //#define CATCH_CONFIG_DISABLE -#include +#include #include "test_data.hpp" #include #include +#include #include #include #include #include +#include using namespace Slic3r; using namespace Slic3r::Geometry; @@ -91,7 +93,7 @@ TEST_CASE("Fill: Pattern Path Length") { filler->angle = angle; Slic3r::ExPolygon e{}; e.contour = Slic3r::Polygon(test_square); - e.holes = Slic3r::Polygons(Slic3r::Polygon(test_hole)); + e.holes = Slic3r::Polygons{Slic3r::Polygon(test_hole)}; Polylines paths {test(e, *filler, params_local)}; //std::cout << "paths.size="<angle = 0.F; Surface surface {(stPosTop|stDensSolid), expolygon}; - Flow flow {0.69f, 0.4f, 0.50f}; + Flow flow = Flow::new_from_width(0.69f, 0.4f, 0.50f, 1.f, false); //width, height, nozzle_diameter, spacing_ratio, is_bridge params.density = 1.0; filler->init_spacing(flow.spacing(), params); @@ -156,10 +158,10 @@ TEST_CASE("Fill: Pattern Path Length") { } SECTION("Solid surface fill") { Points points { - Point::new_scale(6883102, 9598327.01296997), - Point::new_scale(6883102, 20327272.01297), - Point::new_scale(3116896, 20327272.01297), - Point::new_scale(3116896, 9598327.01296997) + Point(6883102, 9598327), + Point(6883102, 20327272), + Point(3116896, 20327272), + Point(3116896, 9598327) }; Slic3r::ExPolygon expolygon{}; expolygon.contour = Slic3r::Polygon{ points }; @@ -169,7 +171,7 @@ TEST_CASE("Fill: Pattern Path Length") { { expolygon.scale(1.05); //FIXME number overflow. - //REQUIRE(test_if_solid_surface_filled(expolygon, 0.55) == true); + REQUIRE(test_if_solid_surface_filled(expolygon, 0.55) == true); } } SECTION("Solid surface fill") { @@ -217,22 +219,144 @@ class ExtrusionGetVolume : public ExtrusionVisitor { void use(ExtrusionMultiPath &multipath) override { for (ExtrusionPath path : multipath.paths) path.visit(*this); } void use(ExtrusionMultiPath3D &multipath) override { for (ExtrusionPath path : multipath.paths) path.visit(*this); } void use(ExtrusionLoop &loop) override { for (ExtrusionPath path : loop.paths) path.visit(*this); } - void use(ExtrusionEntityCollection &collection) override { for (ExtrusionEntity *entity : collection.entities) entity->visit(*this); } + void use(ExtrusionEntityCollection &collection) override { for (ExtrusionEntity *entity : collection.entities()) entity->visit(*this); } double get(ExtrusionEntityCollection &coll) { - for (ExtrusionEntity *entity : coll.entities) entity->visit(*this); + for (ExtrusionEntity *entity : coll.entities()) entity->visit(*this); return volume; } }; +TEST_CASE("Fill area: check if periemter give the good values") +{ + Model model{}; + TriangleMesh sample_mesh = make_cube(5, 5, 0.2); + double volume = (5 * 5 * 0.2); + DynamicPrintConfig &config = Slic3r::DynamicPrintConfig::full_print_config(); + config.set_key_value("perimeters", new ConfigOptionInt(1)); + config.set_key_value("top_solid_layers", new ConfigOptionInt(1)); + config.set_key_value("bottom_solid_layers", new ConfigOptionInt(1)); + + config.set_key_value("enforce_full_fill_volume", new ConfigOptionBool(false)); + config.set_key_value("infill_overlap", new ConfigOptionFloatOrPercent(0.1, false)); + + config.set_key_value("skirts", new ConfigOptionInt(0)); + + config.set_key_value("layer_height", new ConfigOptionFloat(0.2)); // get a known number of layers + config.set_key_value("first_layer_height", new ConfigOptionFloatOrPercent(0.2, false)); + + config.set_key_value("extrusion_width", new ConfigOptionFloatOrPercent(0.5, false)); + config.set_key_value("infill_extrusion_width", new ConfigOptionFloatOrPercent(0.5, false)); + config.set_key_value("perimeter_extrusion_width", new ConfigOptionFloatOrPercent(0.5, false)); + config.set_key_value("first_layer_extrusion_width", new ConfigOptionFloatOrPercent(0.5, false)); + config.set_key_value("external_perimeter_extrusion_width", new ConfigOptionFloatOrPercent(0.5, false)); + config.set_key_value("solid_infill_extrusion_width", new ConfigOptionFloatOrPercent(0.5, false)); + config.set_key_value("top_infill_extrusion_width", new ConfigOptionFloatOrPercent(0.5, false)); + SECTION("no overlap") + { + config.set_key_value("infill_overlap", new ConfigOptionFloatOrPercent(0, false)); + config.set_key_value("external_perimeter_overlap", new ConfigOptionPercent(0)); + config.set_key_value("solid_infill_overlap", new ConfigOptionPercent(0)); + Print print{}; + Slic3r::Test::init_print(print, { sample_mesh }, model, &config); + print.process(); + const LayerRegion *lr = print.get_object(0)->get_layer(0)->regions()[0]; + double area_infill = unscaled(unscaled(lr->fill_surfaces.surfaces.front().area())); + REQUIRE(lr->fill_no_overlap_expolygons.empty()); + double area_computed = (5-0.5*2) * (5-0.5*2); + REQUIRE(std::abs(area_computed - area_infill) < 0.001); + } + SECTION("only encroachment (0.2mm)") + { + config.set_key_value("infill_overlap", new ConfigOptionFloatOrPercent(0.2, false)); + config.set_key_value("external_perimeter_overlap", new ConfigOptionPercent(0)); + config.set_key_value("perimeter_overlap", new ConfigOptionPercent(100)); + config.set_key_value("solid_infill_overlap", new ConfigOptionPercent(0)); + Print print{}; + Slic3r::Test::init_print(print, { sample_mesh }, model, &config); + print.process(); + const LayerRegion *lr = print.get_object(0)->get_layer(0)->regions()[0]; + REQUIRE(1 == lr->fill_surfaces.surfaces.size()); + REQUIRE(1 == lr->fill_no_overlap_expolygons.size()); + double area_infill = unscaled(unscaled(lr->fill_surfaces.surfaces[0].area())); + double area_infill_no_overlap = unscaled(unscaled(lr->fill_no_overlap_expolygons[0].area())); // note: don't need to intersect as there is only one fill_surfaces + double area_no_encroach_computed = (5-0.5*2) * (5-0.5*2); + double area_computed = (5-0.3*2) * (5-0.3*2); + REQUIRE(area_infill_no_overlap < area_infill); + REQUIRE(std::abs(area_computed - area_infill) < 0.001); + REQUIRE(std::abs(area_no_encroach_computed - area_infill_no_overlap) < 0.001); + } + SECTION("only encroachment (40%)") + { + // % over (perimeter_spacing + solid_fill_spacing)/2, but no periemter overlap + // (note: here it's the external perimeter, as we have only one perimeter) + config.set_key_value("infill_overlap", new ConfigOptionFloatOrPercent(40, true)); // 40% -> 0.2 value + config.set_key_value("external_perimeter_overlap", new ConfigOptionPercent(0)); + config.set_key_value("perimeter_overlap", new ConfigOptionPercent(100)); + config.set_key_value("solid_infill_overlap", new ConfigOptionPercent(0)); + Print print{}; + Slic3r::Test::init_print(print, { sample_mesh }, model, &config); + print.process(); + const LayerRegion *lr = print.get_object(0)->get_layer(0)->regions()[0]; + REQUIRE(1 == lr->fill_surfaces.surfaces.size()); + REQUIRE(1 == lr->fill_no_overlap_expolygons.size()); + double area_infill = unscaled(unscaled(lr->fill_surfaces.surfaces[0].area())); + double area_infill_no_overlap = unscaled(unscaled(lr->fill_no_overlap_expolygons[0].area())); // note: don't need to intersect as there is only one fill_surfaces + double area_no_encroach_computed = (5-0.5*2) * (5-0.5*2); + double area_computed = (5-0.3*2) * (5-0.3*2); + REQUIRE(area_infill_no_overlap < area_infill); + REQUIRE(std::abs(area_computed - area_infill) < 0.001); + REQUIRE(std::abs(area_no_encroach_computed - area_infill_no_overlap) < 0.001); + } + SECTION("only overlap") + { + config.set_key_value("infill_overlap", new ConfigOptionFloatOrPercent(0, false)); + config.set_key_value("external_perimeter_overlap", new ConfigOptionPercent(100)); + config.set_key_value("perimeter_overlap", new ConfigOptionPercent(100)); + config.set_key_value("solid_infill_overlap", new ConfigOptionPercent(100)); + Print print{}; + Slic3r::Test::init_print(print, { sample_mesh }, model, &config); + print.process(); + const LayerRegion *lr = print.get_object(0)->get_layer(0)->regions()[0]; + REQUIRE(1 == lr->fill_surfaces.surfaces.size()); + REQUIRE(lr->fill_no_overlap_expolygons.empty()); + double area_infill = unscaled(unscaled(lr->fill_surfaces.surfaces[0].area())); + double spacing_diff = (0.5f - Flow::rounded_rectangle_extrusion_spacing(0.5f, 0.2f, 1.f))/2; + double area_computed = (5-(0.5-spacing_diff)*2) * (5-(0.5-spacing_diff)*2); + REQUIRE(std::abs(area_computed - area_infill) < 0.001); + } + SECTION("both") + { + config.set_key_value("infill_overlap", new ConfigOptionFloatOrPercent(0.1, false)); + config.set_key_value("external_perimeter_overlap", new ConfigOptionPercent(100)); + config.set_key_value("perimeter_overlap", new ConfigOptionPercent(100)); + config.set_key_value("solid_infill_overlap", new ConfigOptionPercent(100)); + Print print{}; + Slic3r::Test::init_print(print, { sample_mesh }, model, &config); + print.process(); + const LayerRegion *lr = print.get_object(0)->get_layer(0)->regions()[0]; + REQUIRE(1 == lr->fill_surfaces.surfaces.size()); + REQUIRE(1 == lr->fill_no_overlap_expolygons.size()); + double area_infill = unscaled(unscaled(lr->fill_surfaces.surfaces[0].area())); + double area_infill_no_overlap = unscaled(unscaled(lr->fill_no_overlap_expolygons[0].area())); // note: don't need to intersect as there is only one fill_surfaces + double spacing_diff = (0.5f - Flow::rounded_rectangle_extrusion_spacing(0.5f, 0.2f, 1.f))/2; + double area_no_encroach_computed = (5-(0.5-spacing_diff)*2) * (5-(0.5-spacing_diff)*2); + double area_computed = (5-(0.4-spacing_diff)*2) * (5-(0.4-spacing_diff)*2); + REQUIRE(area_infill_no_overlap < area_infill); + REQUIRE(std::abs(area_computed - area_infill) < 0.001); + REQUIRE(std::abs(area_no_encroach_computed - area_infill_no_overlap) < 0.001); + } +} + #include "libslic3r/GCodeReader.hpp" TEST_CASE("Fill: extrude gcode and check it") { - SECTION("simple square") { + SECTION("simple square") + { Model model{}; TriangleMesh sample_mesh = make_cube(5, 5, 0.2); double volume = (5 * 5 * 0.2); - sample_mesh.repair(); + //sample_mesh.repair(); DynamicPrintConfig &config = Slic3r::DynamicPrintConfig::full_print_config(); config.set_key_value("perimeters", new ConfigOptionInt(1)); @@ -240,7 +364,10 @@ TEST_CASE("Fill: extrude gcode and check it") config.set_key_value("bottom_solid_layers", new ConfigOptionInt(1)); config.set_key_value("enforce_full_fill_volume", new ConfigOptionBool(true)); - config.set_key_value("infill_overlap", new ConfigOptionFloatOrPercent(0.1, true)); + config.set_key_value("infill_overlap", new ConfigOptionFloatOrPercent(0.1, false)); + config.set_key_value("external_perimeter_overlap", new ConfigOptionPercent(100)); + config.set_key_value("perimeter_overlap", new ConfigOptionPercent(100)); + config.set_key_value("solid_infill_overlap", new ConfigOptionPercent(100)); config.set_key_value("skirts", new ConfigOptionInt(0)); @@ -264,6 +391,8 @@ TEST_CASE("Fill: extrude gcode and check it") Slic3r::Test::gcode(gcode_filepath, print); //std::cout << "gcode generation done\n"; std::string gcode_from_file = read_to_string(gcode_filepath); + model = print.model(); + Slic3r::store_3mf("test.3mf", &model, &print.full_print_config(), OptionStore3mf{}); //string[] lineArray = gcode_from_file GCodeReader parser; @@ -288,29 +417,42 @@ TEST_CASE("Fill: extrude gcode and check it") } }); - double perimeterRoundGapRemove = unscaled(print.objects()[0]->layers()[0]->lslices[0].contour.length()) * 0.1*0.1 * (2 - (PI / 2)); - double perimeterRoundGapAdd = unscaled(print.objects()[0]->layers()[0]->lslices[0].contour.length()) * 0.1*0.1 * ((PI / 2)); - //for (Line &l : print.objects()[0]->layers()[0]->slices.expolygons[0].contour.lines()) { + ExPolygons perimeter_center_line = offset_ex(print.get_object(0)->get_layer(0)->lslices[0], -scale_t(0.25f)); + + //double perimeterRoundGapRemove = unscaled(print.get_object(0)->get_layer(0)->lslices[0].contour.length()) * 0.1*0.1 * (2 - (PI / 2)); + double perimeterRoundGapRemove = unscaled(perimeter_center_line[0].contour.length()) * 0.1*0.1 * (2 - (PI / 2)); + //double perimeterRoundGapAdd = unscaled(print.get_object(0)->get_layer(0)->lslices[0].contour.length()) * 0.1*0.1 * ((PI / 2)); + //for (Line &l : print.get_object(0)->get_layer(0)->slices.expolygons[0].contour.lines()) { //} //std::cout << "flow mm3permm: " << Flow{ 0.5f,0.2f,0.4f,false }.mm3_per_mm() << "\n"; - //std::cout << "perimeter : " << unscaled(print.objects()[0]->layers()[0]->slices.expolygons[0].contour.length()) << " != " << (PI * 10) << "\n"; + //std::cout << "perimeter : " << unscaled(print.get_object(0)->get_layer(0)->slices.expolygons[0].contour.length()) << " != " << (PI * 10) << "\n"; //std::cout << "created a mesh of volume " << volume << " and i have extruded " << volume_extruded << " mm3.\n"; //std::cout << "Note that if we remove the bits of the external extrusion, it's only a volume of " << (volume - perimeterRoundGapRemove) << " that needs to be filled\n"; //std::cout << "Note that if we add the bits of the external extrusion, it's a volume of " << (volume + perimeterRoundGapAdd) << " that needs to be filled\n"; - double volumeExtrPerimeter = ExtrusionGetVolume{}.get(print.objects()[0]->layers()[0]->regions()[0]->perimeters); - double volumeExtrInfill = ExtrusionGetVolume{}.get(print.objects()[0]->layers()[0]->regions()[0]->fills); + double volumeExtrPerimeter = ExtrusionGetVolume{}.get(print.get_object(0)->get_layer(0)->regions()[0]->perimeters); + double volumeExtrInfill = ExtrusionGetVolume{}.get(print.get_object(0)->get_layer(0)->regions()[0]->fills); double volumeInfill = 0; - for (const ExPolygon & p : print.objects()[0]->layers()[0]->regions()[0]->fill_no_overlap_expolygons) { + for (const ExPolygon & p : print.get_object(0)->get_layer(0)->regions()[0]->fill_no_overlap_expolygons) { volumeInfill += unscaled(unscaled(p.area())); } - volumeInfill *= 0.2;/* - std::cout << "volumeRealr=" << (volume_perimeter_extruded + volume_infill_extruded) << " volumeRealPerimeter= " << volume_perimeter_extruded << " and volumeRealInfill=" << volume_infill_extruded << " mm3." << "\n"; + double spacing_diff = (0.5f - Flow::rounded_rectangle_extrusion_spacing(0.5f, 0.2f, 1.f))/2; + double raw_area_no_encroach = (5-(0.5-spacing_diff)*2) * (5-(0.5-spacing_diff)*2); + double raw_area = (5-(0.4-spacing_diff)*2) * (5-(0.4-spacing_diff)*2); + + double compute_perimeter_area = 4.5*4*Flow::rounded_rectangle_extrusion_spacing(0.5f, 0.2f, 1.f); + + std::cout << "area fill_no_overlap_expolygons= " << (unscaled(unscaled(print.get_object(0)->get_layer(0)->regions()[0]->fill_no_overlap_expolygons.front().contour.area()))) << "\n"; + volumeInfill *= 0.2; + std::cout << "\nvolumeRealr=" << (volume_perimeter_extruded + volume_infill_extruded) << " volumeRealPerimeter= " << volume_perimeter_extruded << " and volumeRealInfill=" << volume_infill_extruded << " mm3." << "\n"; std::cout << "volumeExtr=" << (volumeExtrPerimeter + volumeExtrInfill) << " volumeExtrPerimeter= " << volumeExtrPerimeter << " and volumeExtrInfill=" << volumeExtrInfill << " mm3." << "\n"; - std::cout << "volumePerimeter= " << (volume - volumeInfill) << " volumePerimeter(wo/bits)= " << (volume - volumeInfill- perimeterRoundGapRemove) << " and volumeInfill=" << volumeInfill << " mm3." << "\n";*/ + std::cout << "volumePerimeter= " << (volume - volumeInfill) << " volumePerimeter(wo/bits)= " << (volume - volumeInfill- perimeterRoundGapRemove) << " and volumeInfill=" << volumeInfill << " mm3." << "\n"; + std::cout << "volume= " << (volume) << " raw_fill_volume="<layers()[0]->slices.expolygons[0].contour, "green"); - // svg.draw(print.objects()[0]->layers()[0]->regions()[0]->fill_no_overlap_expolygons, "black", scale_(0.01)); - // svg.draw(print.objects()[0]->layers()[0]->regions()[0]->perimeters.as_polylines(), "orange", fl.scaled_width()); - // svg.draw(print.objects()[0]->layers()[0]->regions()[0]->perimeters.as_polylines(), "red", fl.scaled_spacing()); - // svg.draw(print.objects()[0]->layers()[0]->regions()[0]->fills.as_polylines(), "cyan", fl.scaled_width()); - // svg.draw(print.objects()[0]->layers()[0]->regions()[0]->fills.as_polylines(), "blue", fl.scaled_spacing()); + // svg.draw(print.get_object(0)->get_layer(0)->slices.expolygons[0].contour, "green"); + // svg.draw(print.get_object(0)->get_layer(0)->regions()[0]->fill_no_overlap_expolygons, "black", scale_(0.01)); + // svg.draw(print.get_object(0)->get_layer(0)->regions()[0]->perimeters.as_polylines(), "orange", fl.scaled_width()); + // svg.draw(print.get_object(0)->get_layer(0)->regions()[0]->perimeters.as_polylines(), "red", fl.scaled_spacing()); + // svg.draw(print.get_object(0)->get_layer(0)->regions()[0]->fills.as_polylines(), "cyan", fl.scaled_width()); + // svg.draw(print.get_object(0)->get_layer(0)->regions()[0]->fills.as_polylines(), "blue", fl.scaled_spacing()); // svg.Close(); //} + REQUIRE(abs(raw_area_no_encroach*0.2 - volumeInfill) < 0.01); + REQUIRE(abs(compute_perimeter_area * 0.2 - volumeExtrPerimeter) < 0.01); //std::cout << gcode_from_file; REQUIRE(abs(volumeInfill - volumeExtrInfill) < EPSILON); @@ -339,8 +483,7 @@ TEST_CASE("Fill: extrude gcode and check it") SECTION("simple disk") { Model model{}; TriangleMesh sample_mesh = make_cylinder(5, 0.2); - double volume = (PI * 25 * 0.2); - sample_mesh.repair(); + const double volume = (PI * 25 * 0.2); DynamicPrintConfig &config = Slic3r::DynamicPrintConfig::full_print_config(); config.set_key_value("perimeters", new ConfigOptionInt(1)); @@ -349,6 +492,9 @@ TEST_CASE("Fill: extrude gcode and check it") config.set_key_value("enforce_full_fill_volume", new ConfigOptionBool(true)); config.set_key_value("infill_overlap", new ConfigOptionFloatOrPercent(0.1, true)); + config.set_key_value("perimeter_overlap", new ConfigOptionPercent(100)); + config.set_key_value("external_perimeter_overlap", new ConfigOptionPercent(100)); + config.set_deserialize("external_perimeter_cut_corners", "0"); config.set_key_value("skirts", new ConfigOptionInt(0)); @@ -376,45 +522,54 @@ TEST_CASE("Fill: extrude gcode and check it") //string[] lineArray = gcode_from_file GCodeReader parser; double volume_extruded = 0; - int idx = 0; + //int idx = 0; + int step = 0; double volume_perimeter_extruded = 0; double volume_infill_extruded = 0; // add remaining time lines where needed parser.parse_buffer(gcode_from_file, [&](GCodeReader& reader, const GCodeReader::GCodeLine& line) { - if (line.cmd_is("G1")) + if(line.comment() == "TYPE:External perimeter") + step = 1; + if(line.comment() == "TYPE:Solid infill") + step = 2; + if (line.cmd_is("G1") && step > 0) { if (line.dist_E(reader) > 0 && line.dist_XY(reader) > 0) { //std::cout << "add " << line.dist_E(reader)<<" now "<< volume_extruded<<"=>"; volume_extruded += line.dist_E(reader)*(PI*1.75*1.75 / 4.); //std::cout << volume_extruded << "\n"; - if (idx<36)volume_perimeter_extruded += line.dist_E(reader)*(PI*1.75*1.75 / 4.); - else volume_infill_extruded += line.dist_E(reader)*(PI*1.75*1.75 / 4.); - idx++; + if (step == 1) volume_perimeter_extruded += line.dist_E(reader)*(PI*1.75*1.75 / 4.); + else if (step == 2) volume_infill_extruded += line.dist_E(reader)*(PI*1.75*1.75 / 4.); } } }); - double perimeterRoundGapRemove = unscaled(print.objects()[0]->layers()[0]->lslices[0].contour.length()) * 0.1*0.1 * (2 - (PI / 2)); - double perimeterRoundGapAdd = unscaled(print.objects()[0]->layers()[0]->lslices[0].contour.length()) * 0.1*0.1 * ((PI / 2)); + ExPolygons perimeter_center_line = offset_ex(print.get_object(0)->get_layer(0)->lslices[0], -scale_t(0.25f)); - double volumeExtrPerimeter = ExtrusionGetVolume{}.get(print.objects()[0]->layers()[0]->regions()[0]->perimeters); - double volumeExtrInfill = ExtrusionGetVolume{}.get(print.objects()[0]->layers()[0]->regions()[0]->fills); + //double perimeterRoundGapRemove = unscaled(print.get_object(0)->get_layer(0)->lslices[0].contour.length()) * 0.1*0.1 * (2 - (PI / 2)); + double perimeterRoundGapRemove = unscaled(perimeter_center_line[0].contour.length()) * 0.1*0.1 * (2 - (PI / 2)); + //double perimeterRoundGapAdd = unscaled(print.get_object(0)->get_layer(0)->lslices[0].contour.length()) * 0.1*0.1 * ((PI / 2)); + + double volumeExtrPerimeter = ExtrusionGetVolume{}.get(print.get_object(0)->get_layer(0)->regions()[0]->perimeters); + double volumeExtrInfill = ExtrusionGetVolume{}.get(print.get_object(0)->get_layer(0)->regions()[0]->fills); double volumeInfill = 0; - for (const ExPolygon & p : print.objects()[0]->layers()[0]->regions()[0]->fill_no_overlap_expolygons) { + ExPolygons infill_area = intersection_ex(print.get_object(0)->get_layer(0)->regions()[0]->fill_no_overlap_expolygons, print.get_object(0)->get_layer(0)->regions()[0]->fill_expolygons); + for (const ExPolygon & p : infill_area) { volumeInfill += unscaled(unscaled(p.area())); } volumeInfill *= 0.2; std::cout << "volumeRealr=" << (volume_perimeter_extruded + volume_infill_extruded) << " volumeRealPerimeter= " << volume_perimeter_extruded << " and volumeRealInfill=" << volume_infill_extruded << " mm3." << "\n"; std::cout << "volumeExtr=" << (volumeExtrPerimeter + volumeExtrInfill) << " volumeExtrPerimeter= " << volumeExtrPerimeter << " and volumeExtrInfill=" << volumeExtrInfill << " mm3." << "\n"; std::cout << "volumePerimeter= " << (volume - volumeInfill) << " volumePerimeter(wo/bits)= " << (volume - volumeInfill - perimeterRoundGapRemove) << " and volumeInfill=" << volumeInfill << " mm3." << "\n"; + std::cout << "volume= " << (volume) << "\n"; - REQUIRE(abs(volumeInfill - volumeExtrInfill) < EPSILON); - REQUIRE(abs(volumeInfill - volume_infill_extruded) < 0.01); - REQUIRE(abs((volume - volumeInfill - perimeterRoundGapRemove) - volumeExtrPerimeter) < EPSILON); - REQUIRE(abs((volume - volumeInfill - perimeterRoundGapRemove) - volume_perimeter_extruded) < 0.1); //there are a bit less for seam mitigation + REQUIRE(abs(volumeInfill - volumeExtrInfill) < 0.001); + REQUIRE(abs(volumeInfill - volume_infill_extruded) < 0.001); + REQUIRE(abs((volume - volumeInfill - perimeterRoundGapRemove) - volumeExtrPerimeter) < 0.1); //there are a bit less for seam mitigation + REQUIRE(abs(volumeExtrPerimeter - volume_perimeter_extruded) < 0.01); clean_file(gcode_filepath, "gcode"); } @@ -660,6 +815,23 @@ for my $pattern (qw(rectilinear honeycomb hilbertcurve concentric)) { } */ +class ExtrusionGetExtrusionArea : public ExtrusionVisitor { + Polygons grown_paths; +public: + ExtrusionGetExtrusionArea() {} + void use(ExtrusionPath &path) override { + polygons_append(grown_paths, offset(path.as_polyline().as_polyline(), scale_t(path.width))); + } + void use(ExtrusionPath3D &path3D) override { assert(false); } + void use(ExtrusionMultiPath &multipath) override { for (ExtrusionPath path : multipath.paths) path.visit(*this); } + void use(ExtrusionMultiPath3D &multipath) override { for (ExtrusionPath path : multipath.paths) path.visit(*this); } + void use(ExtrusionLoop &loop) override { for (ExtrusionPath path : loop.paths) path.visit(*this); } + void use(ExtrusionEntityCollection &collection) override { for (ExtrusionEntity *entity : collection.entities()) entity->visit(*this); } + Polygons get(ExtrusionEntityCollection &coll) { + for (ExtrusionEntity *entity : coll.entities()) entity->visit(*this); + return grown_paths; + } +}; //TODO: also check by volume extruded //TODO: replace the simple area coverage check by one that takes into account the width of the path, not only the default flow spacing //TODO: test more fills @@ -669,26 +841,31 @@ bool test_if_solid_surface_filled(const ExPolygon& expolygon, double flow_width, filler->angle = angle; FillParams params; params.dont_adjust = false; + FullPrintConfig config= FullPrintConfig::defaults(); + params.config = &config; Surface surface((stPosBottom | stDensSolid), expolygon); //note: here we do flow.width = flow_width , flow.gheight = 0.4, flow.nozzle_size = flow_width; - Flow flow(flow_width, 0.4, flow_width); + params.flow = Flow::new_from_width( float(flow_width), 0.4, float(flow_width), 1.f, false); params.density = density; - filler->init_spacing(flow.spacing(), params); + filler->init_spacing(params.flow.spacing(), params); - Polylines paths {filler->fill_surface(&surface, params)}; + // concentricgapfill can't output only Polylines, as it's a composed thing with gapfill + //Polylines paths {filler->fill_surface(&surface, params)}; + ExtrusionEntityCollection coll; + filler->fill_surface_extrusion(&surface, params, coll.set_entities()); // check whether any part was left uncovered - Polygons grown_paths; - grown_paths.reserve(paths.size()); // figure out what is actually going on here re: data types - std::for_each(paths.begin(), paths.end(), [filler, &grown_paths] (const Slic3r::Polyline& p) { - polygons_append(grown_paths, offset(p, scale_(filler->get_spacing() / 2.0))); - }); + Polygons grown_paths = ExtrusionGetExtrusionArea{}.get(coll); + //grown_paths.reserve(paths.size()); + //std::for_each(paths.begin(), paths.end(), [filler, &grown_paths] (const Slic3r::Polyline& p) { + // polygons_append(grown_paths, offset(p, scale_(filler->get_spacing() / 2.0))); + //}); - ExPolygons uncovered = diff_ex(expolygon, grown_paths, true); + ExPolygons uncovered = diff_ex(expolygon, grown_paths, Slic3r::ApplySafetyOffset::Yes); // ignore very small dots const auto scaled_flow_width { std::pow(scale_(flow_width), 2) }; @@ -700,6 +877,6 @@ bool test_if_solid_surface_filled(const ExPolygon& expolygon, double flow_width, double uncovered_area = 0; for (ExPolygon &p : uncovered) uncovered_area += unscaled(unscaled(p.area())); std::cout << "uncovered size =" << uncovered_area << " / "<< unscaled(unscaled(expolygon.area()))<<"\n"; - return uncovered.size() == 0; // solid surface is fully filled + return uncovered_area < 0.05; // solid surface is (almost) fully filled } diff --git a/tests/superslicerlibslic3r/test_flow.cpp b/tests/superslicerlibslic3r/test_flow.cpp index e3e5f97ab66..7d4c7db16e9 100644 --- a/tests/superslicerlibslic3r/test_flow.cpp +++ b/tests/superslicerlibslic3r/test_flow.cpp @@ -1,7 +1,7 @@ //#define CATCH_CONFIG_DISABLE -#include +#include #include #include @@ -104,8 +104,11 @@ SCENARIO(" Bridge flow specifics.", "[!mayfail]") { /// Test the expected behavior for auto-width, /// spacing, etc SCENARIO("Flow: Flow math for non-bridges", "[!mayfail]") { + auto width_0 = ConfigOptionFloatOrPercent(1.0, false); + auto spacing_0 = ConfigOptionFloatOrPercent(1.0, false,true); GIVEN("Nozzle Diameter of 0.4, a desired width of 1mm and layer height of 0.5") { - auto width {ConfigOptionFloatOrPercent{1.0, false}}; + auto width_1 = ConfigOptionFloatOrPercent(1.0, false); + auto spacing_1 = ConfigOptionFloatOrPercent(1.0, false,true); float spacing {0.4f}; float nozzle_diameter {0.4f}; float bridge_flow {1.0f}; @@ -113,19 +116,19 @@ SCENARIO("Flow: Flow math for non-bridges", "[!mayfail]") { // Spacing for non-bridges is has some overlap THEN("External perimeter flow has a default spacing fixed to 1.05*nozzle_diameter") { - Flow flow {Flow::new_from_config_width(frExternalPerimeter, ConfigOptionFloatOrPercent{0, false}, nozzle_diameter, layer_height, 0.0f)}; + Flow flow = Flow::new_from_config_width(frExternalPerimeter, width_0, spacing_0, nozzle_diameter, layer_height, 0.0f); REQUIRE(flow.spacing() == Approx((1.05f*nozzle_diameter) - layer_height * (1.0 - PI / 4.0))); } THEN("Internal perimeter flow has a default spacing fixed to 1.125*nozzle_diameter") { - Flow flow {Flow::new_from_config_width(frPerimeter, ConfigOptionFloatOrPercent{0, false}, nozzle_diameter, layer_height, 0.0f)}; + Flow flow {Flow::new_from_config_width(frPerimeter, width_0, spacing_0, nozzle_diameter, layer_height, 0.0f)}; REQUIRE(flow.spacing() == Approx((1.125*nozzle_diameter) - layer_height * (1.0 - PI / 4.0))); } THEN("Spacing for supplied width is 0.8927f") { - Flow flow {Flow::new_from_config_width(frExternalPerimeter, width, nozzle_diameter, layer_height, 0.0f)}; - REQUIRE(flow.spacing() == Approx(width - layer_height * (1.0 - PI / 4.0))); - flow = Flow::new_from_config_width(frPerimeter, width, nozzle_diameter, layer_height, 0.0f); - REQUIRE(flow.spacing() == Approx(width - layer_height * (1.0 - PI / 4.0))); + Flow flow {Flow::new_from_config_width(frExternalPerimeter, width_1, spacing_1, nozzle_diameter, layer_height, 0.0f)}; + REQUIRE(flow.spacing() == Approx(width_1.get_abs_value(1.f) - layer_height * (1.0 - PI / 4.0))); + flow = Flow::new_from_config_width(frPerimeter, width_1, spacing_1, nozzle_diameter, layer_height, 0.0f); + REQUIRE(flow.spacing() == Approx(width_1.get_abs_value(1.f) - layer_height * (1.0 - PI / 4.0))); } } /// Check the min/max @@ -135,23 +138,23 @@ SCENARIO("Flow: Flow math for non-bridges", "[!mayfail]") { WHEN("layer height is set to 0.15") { layer_height = 5.f; THEN("Max width is respected.") { - auto flow {Flow::new_from_config_width(frPerimeter, ConfigOptionFloatOrPercent{0, false}, nozzle_diameter, layer_height, 0.0f)}; - REQUIRE(flow.width <= Approx(1.4*nozzle_diameter)); + auto flow {Flow::new_from_config_width(frPerimeter, width_0, spacing_0, nozzle_diameter, layer_height, 0.0f)}; + REQUIRE(flow.width() <= Approx(1.4*nozzle_diameter)); } THEN("Min width is respected") { - auto flow{ Flow::new_from_config_width(frPerimeter, ConfigOptionFloatOrPercent{0, false}, nozzle_diameter, layer_height, 0.0f) }; - REQUIRE(flow.width >= Approx(1.05*nozzle_diameter)); + auto flow{ Flow::new_from_config_width(frPerimeter, width_0, spacing_0, nozzle_diameter, layer_height, 0.0f) }; + REQUIRE(flow.width() >= Approx(1.05*nozzle_diameter)); } } WHEN("Layer height is set to 0.3") { layer_height = 0.01f; THEN("Max width is respected.") { - auto flow{ Flow::new_from_config_width(frPerimeter, ConfigOptionFloatOrPercent{0, false}, nozzle_diameter, layer_height, 0.0f) }; - REQUIRE(flow.width <= Approx(1.4*nozzle_diameter)); + auto flow{ Flow::new_from_config_width(frPerimeter, width_0, spacing_0, nozzle_diameter, layer_height, 0.0f) }; + REQUIRE(flow.width() <= Approx(1.4*nozzle_diameter)); } THEN("Min width is respected.") { - auto flow{ Flow::new_from_config_width(frPerimeter, ConfigOptionFloatOrPercent{0, false}, nozzle_diameter, layer_height, 0.0f) }; - REQUIRE(flow.width >= Approx(1.05*nozzle_diameter)); + auto flow{ Flow::new_from_config_width(frPerimeter, width_0, spacing_0, nozzle_diameter, layer_height, 0.0f) }; + REQUIRE(flow.width() >= Approx(1.05*nozzle_diameter)); } } } @@ -176,42 +179,43 @@ SCENARIO("Flow: Flow math for non-bridges", "[!mayfail]") { /// Spacing, width calculation for bridge extrusions SCENARIO("Flow: Flow math for bridges", "[!mayfail]") { GIVEN("Nozzle Diameter of 0.4, a desired width of 1mm and layer height of 0.5") { + float BRIDGE_EXTRA_SPACING_MULT = 0.f; // not used anymore auto width {ConfigOptionFloatOrPercent{1.0, false}}; - auto spacing {0.4}; - auto nozzle_diameter {0.4}; - auto bridge_flow {1.0}; - auto layer_height {0.5}; + auto spacing = ConfigOptionFloatOrPercent(1.0, false, false); + float nozzle_diameter {0.4f}; + float spacing_ratio {1.0f}; + float layer_height {0.5f}; WHEN("Flow role is frExternalPerimeter") { - auto flow {Flow::new_from_config_width(frExternalPerimeter, width, nozzle_diameter, layer_height, bridge_flow)}; + auto flow {Flow::new_from_config_width(frExternalPerimeter, width, spacing, nozzle_diameter, layer_height, spacing_ratio)}; THEN("Bridge width is same as nozzle diameter") { - REQUIRE(flow.width == Approx(nozzle_diameter)); + REQUIRE(flow.width() == Approx(nozzle_diameter)); } THEN("Bridge spacing is same as nozzle diameter + BRIDGE_EXTRA_SPACING_MULT * nozzle_diameter") { REQUIRE(flow.spacing() == Approx(nozzle_diameter + BRIDGE_EXTRA_SPACING_MULT * nozzle_diameter)); } } WHEN("Flow role is frInfill") { - auto flow {Flow::new_from_config_width(frInfill, width, nozzle_diameter, layer_height, bridge_flow)}; + auto flow {Flow::new_from_config_width(frInfill, width, spacing, nozzle_diameter, layer_height, spacing_ratio)}; THEN("Bridge width is same as nozzle diameter") { - REQUIRE(flow.width == Approx(nozzle_diameter)); + REQUIRE(flow.width() == Approx(nozzle_diameter)); } THEN("Bridge spacing is same as nozzle diameter + BRIDGE_EXTRA_SPACING_MULT * nozzle_diameter") { REQUIRE(flow.spacing() == Approx(nozzle_diameter + BRIDGE_EXTRA_SPACING_MULT * nozzle_diameter)); } } WHEN("Flow role is frPerimeter") { - auto flow {Flow::new_from_config_width(frPerimeter, width, nozzle_diameter, layer_height, bridge_flow)}; + auto flow {Flow::new_from_config_width(frPerimeter, width, spacing, nozzle_diameter, layer_height, spacing_ratio)}; THEN("Bridge width is same as nozzle diameter") { - REQUIRE(flow.width == Approx(nozzle_diameter)); + REQUIRE(flow.width() == Approx(nozzle_diameter)); } THEN("Bridge spacing is same as nozzle diameter + BRIDGE_EXTRA_SPACING_MULT * nozzle_diameter") { REQUIRE(flow.spacing() == Approx(nozzle_diameter + BRIDGE_EXTRA_SPACING_MULT * nozzle_diameter)); } } WHEN("Flow role is frSupportMaterial") { - auto flow {Flow::new_from_config_width(frSupportMaterial, width, nozzle_diameter, layer_height, bridge_flow)}; + auto flow {Flow::new_from_config_width(frSupportMaterial, width, spacing, nozzle_diameter, layer_height, spacing_ratio)}; THEN("Bridge width is same as nozzle diameter") { - REQUIRE(flow.width == Approx(nozzle_diameter)); + REQUIRE(flow.width() == Approx(nozzle_diameter)); } THEN("Bridge spacing is same as nozzle diameter + BRIDGE_EXTRA_SPACING_MULT * nozzle_diameter") { REQUIRE(flow.spacing() == Approx(nozzle_diameter + BRIDGE_EXTRA_SPACING_MULT * nozzle_diameter)); diff --git a/tests/superslicerlibslic3r/test_gcodewriter.cpp b/tests/superslicerlibslic3r/test_gcodewriter.cpp index 58e4225af02..3a93d85768d 100644 --- a/tests/superslicerlibslic3r/test_gcodewriter.cpp +++ b/tests/superslicerlibslic3r/test_gcodewriter.cpp @@ -1,7 +1,7 @@ //#define CATCH_CONFIG_DISABLE -#include +#include #include #include "libslic3r/GCodeWriter.hpp" @@ -9,8 +9,6 @@ #include #include //#include "test_data.hpp" // get access to init_print, etc -#define PRECISION(val, precision) std::fixed << std::setprecision(precision) << val -#define XYZF_NUM(val) PRECISION(val, 3) using namespace Slic3r; using namespace std::literals::string_literals; @@ -22,17 +20,20 @@ SCENARIO("lift() and unlift() behavior with large values of Z", "[!shouldfail]") GCodeWriter writer{}; GCodeConfig& config {writer.config}; config.set_defaults(); - config.load(std::string{ TEST_DATA_DIR PATH_SEPARATOR } +"test_gcodewriter/config_lift_unlift.ini"s); + config.load(std::string{ TEST_DATA_DIR PATH_SEPARATOR } +"fff_print_tests/test_gcodewriter/config_lift_unlift.ini"s, Slic3r::ForwardCompatibilitySubstitutionRule::Disable); + assert(!config.retract_lift.values.empty() && config.retract_lift.values.front() > 0); std::vector extruder_ids {0}; writer.set_extruders(extruder_ids); writer.set_tool(0); + int lift_layer_id = 1; // not first layer, as lift is deactivated on it by default WHEN("Z is set to 9007199254740992") { double trouble_Z{ 9007199254740992 }; - writer.travel_to_z(trouble_Z); + const std::string travel_str = writer.travel_to_z(trouble_Z); + REQUIRE(travel_str.size() > 0); AND_WHEN("GcodeWriter::Lift() is called") { - const std::string lift = writer.lift(); + const std::string lift = writer.lift(lift_layer_id); REQUIRE(lift.size() > 0); AND_WHEN("Z is moved post-lift to the same delta as the config Z lift") { REQUIRE(writer.travel_to_z(trouble_Z + config.retract_lift.values[0]).size() == 0); @@ -40,7 +41,7 @@ SCENARIO("lift() and unlift() behavior with large values of Z", "[!shouldfail]") const std::string unlift = writer.unlift(); REQUIRE(unlift.size() == 0); // we're the same height so no additional move happens. THEN("GCodeWriter::Lift() emits gcode.") { - const std::string lift_again = writer.lift(); + const std::string lift_again = writer.lift(lift_layer_id); REQUIRE(lift_again.size() > 0); } } @@ -55,23 +56,24 @@ SCENARIO("lift() is not ignored after unlift() at normal values of Z") { GCodeWriter writer{}; GCodeConfig& config {writer.config}; config.set_defaults(); - config.load(std::string{ TEST_DATA_DIR PATH_SEPARATOR } +"test_gcodewriter/config_lift_unlift.ini"s); + config.load(std::string{ TEST_DATA_DIR PATH_SEPARATOR } +"fff_print_tests/test_gcodewriter/config_lift_unlift.ini"s, Slic3r::ForwardCompatibilitySubstitutionRule::Disable); std::vector extruder_ids {0}; writer.set_extruders(extruder_ids); writer.set_tool(0); + int lift_layer_id = 1; WHEN("Z is set to 203") { double trouble_Z{ 203 }; writer.travel_to_z(trouble_Z); AND_WHEN("GcodeWriter::Lift() is called") { - REQUIRE(writer.lift().size() > 0); + REQUIRE(writer.lift(lift_layer_id).size() > 0); AND_WHEN("Z is moved post-lift to the same delta as the config Z lift") { REQUIRE(writer.travel_to_z(trouble_Z + config.retract_lift.values[0]).size() == 0); AND_WHEN("GCodeWriter::Unlift() is called") { REQUIRE(writer.unlift().size() == 0); // we're the same height so no additional move happens. THEN("GCodeWriter::Lift() emits gcode.") { - REQUIRE(writer.lift().size() > 0); + REQUIRE(writer.lift(lift_layer_id).size() > 0); } } } @@ -81,13 +83,13 @@ SCENARIO("lift() is not ignored after unlift() at normal values of Z") { double trouble_Z{ 500003 }; writer.travel_to_z(trouble_Z); AND_WHEN("GcodeWriter::Lift() is called") { - REQUIRE(writer.lift().size() > 0); + REQUIRE(writer.lift(lift_layer_id).size() > 0); AND_WHEN("Z is moved post-lift to the same delta as the config Z lift") { REQUIRE(writer.travel_to_z(trouble_Z + config.retract_lift.values[0]).size() == 0); AND_WHEN("GCodeWriter::Unlift() is called") { REQUIRE(writer.unlift().size() == 0); // we're the same height so no additional move happens. THEN("GCodeWriter::Lift() emits gcode.") { - REQUIRE(writer.lift().size() > 0); + REQUIRE(writer.lift(lift_layer_id).size() > 0); } } } @@ -97,13 +99,13 @@ SCENARIO("lift() is not ignored after unlift() at normal values of Z") { double trouble_Z{ 10.3 }; writer.travel_to_z(trouble_Z); AND_WHEN("GcodeWriter::Lift() is called") { - REQUIRE(writer.lift().size() > 0); + REQUIRE(writer.lift(lift_layer_id).size() > 0); AND_WHEN("Z is moved post-lift to the same delta as the config Z lift") { REQUIRE(writer.travel_to_z(trouble_Z + config.retract_lift.values[0]).size() == 0); AND_WHEN("GCodeWriter::Unlift() is called") { REQUIRE(writer.unlift().size() == 0); // we're the same height so no additional move happens. THEN("GCodeWriter::Lift() emits gcode.") { - REQUIRE(writer.lift().size() > 0); + REQUIRE(writer.lift(lift_layer_id).size() > 0); } } } @@ -123,23 +125,23 @@ SCENARIO("set_speed emits values with fixed-point output.") { // } //} WHEN("set_speed is called to set speed to 9.99321e+04") { - THEN("Output string is G1 F99932.100") { - REQUIRE_THAT(writer.set_speed(9.99321e+04), Catch::Equals("G1 F10932.100\n")); + THEN("Output string is G1 F5995926") { + REQUIRE_THAT(writer.set_speed(9.99321e+04), Catch::Equals("G1 F5995926\n")); } } WHEN("set_speed is called to set speed to 1") { - THEN("Output string is G1 F1.000") { - REQUIRE_THAT(writer.set_speed(1.0), Catch::Equals("G1 F1.000\n")); + THEN("Output string is G1 F60") { + REQUIRE_THAT(writer.set_speed(1.0), Catch::Equals("G1 F60\n")); } } - WHEN("set_speed is called to set speed to 203.200022") { - THEN("Output string is G1 F203.200") { - REQUIRE_THAT(writer.set_speed(203.200022), Catch::Equals("G1 F203.200\n")); + WHEN("set_speed is called to set speed to 203.2000022") { + THEN("Output string is G1 F12192") { + REQUIRE_THAT(writer.set_speed(203.2000022), Catch::Equals("G1 F12192\n")); } } - WHEN("set_speed is called to set speed to 203.200522") { - THEN("Output string is G1 F203.200") { - REQUIRE_THAT(writer.set_speed(203.200522), Catch::Equals("G1 F203.201\n")); + WHEN("set_speed is called to set speed to 203.2000522") { + THEN("Output string is G1 F12192.003") { + REQUIRE_THAT(writer.set_speed(203.2000522), Catch::Equals("G1 F12192.003\n")); } } } diff --git a/tests/superslicerlibslic3r/test_geometry.cpp b/tests/superslicerlibslic3r/test_geometry.cpp index 0b19912ae31..5f02c918b84 100644 --- a/tests/superslicerlibslic3r/test_geometry.cpp +++ b/tests/superslicerlibslic3r/test_geometry.cpp @@ -1,7 +1,5 @@ -#define CATCH_CONFIG_DISABLE - -#include +#include #include #include @@ -15,7 +13,7 @@ using namespace Slic3r; TEST_CASE("Polygon::contains works properly", ""){ // this test was failing on Windows (GH #1950) - Polygon polygon{ Points{ + Slic3r::Polygon polygon( Points{ Point{207802834,-57084522}, Point{196528149,-37556190}, Point{173626821,-25420928}, @@ -26,7 +24,7 @@ TEST_CASE("Polygon::contains works properly", ""){ Point{82156517,-57084523}, Point{129714478,-84542120}, Point{160244873,-84542120} - } }; + } ); Point point{ 95706562, -57294774 }; REQUIRE(polygon.contains(point)); } @@ -43,8 +41,8 @@ SCENARIO("Intersections of line segments"){ } GIVEN("Scaled coordinates"){ - Line line1{ Point{73.6310778185108 / 0.0000001, 371.74239268924 / 0.0000001}, Point{73.6310778185108 / 0.0000001, 501.74239268924 / 0.0000001} }; - Line line2{ Point{75 / 0.0000001, 437.9853 / 0.0000001}, Point{62.7484 / 0.0000001, 440.4223 / 0.0000001} }; + Line line1{ Point::new_scale(73.6310778185108, 371.74239268924), Point::new_scale(73.6310778185108, 501.74239268924) }; + Line line2{ Point::new_scale(75, 437.9853), Point::new_scale(62.7484, 440.4223) }; THEN("There is still an intersection"){ Point point; REQUIRE(line1.intersection(line2,&point)); @@ -130,7 +128,7 @@ SCENARIO("polygon_is_convex works"){ TEST_CASE("Creating a polyline generates the obvious lines"){ - auto polyline = Polyline(); + auto polyline = Slic3r::Polyline(); polyline.points = std::vector({Point{0, 0}, Point{10, 0}, Point{20, 0}}); REQUIRE(polyline.lines().at(0).a == Point{0,0}); REQUIRE(polyline.lines().at(0).b == Point{10,0}); @@ -139,7 +137,7 @@ TEST_CASE("Creating a polyline generates the obvious lines"){ } TEST_CASE("Splitting a Polygon generates a polyline correctly"){ - auto polygon = Polygon(std::vector({Point{0, 0}, Point{10, 0}, Point{5, 5}})); + auto polygon = Slic3r::Polygon(std::vector({Point{0, 0}, Point{10, 0}, Point{5, 5}})); auto split = polygon.split_at_index(1); REQUIRE(split.points[0]==Point{10,0}); REQUIRE(split.points[1]==Point{5,5}); @@ -157,9 +155,9 @@ TEST_CASE("Bounding boxes are scaled appropriately"){ TEST_CASE("Offseting a line generates a polygon correctly"){ - Polyline tmp({ Point{10,10}, Point{20,10} }); - Polygon area = offset(tmp,5).at(0); - REQUIRE(area.area() == Polygon(std::vector({Point{10,5},Point{20,5},Point{20,15},Point{10,15}})).area()); + Slic3r::Polyline tmp(Points{{10,10},{20,10} }); + Slic3r::Polygon area = offset(tmp,5).at(0); + REQUIRE(area.area() == Slic3r::Polygon(std::vector({Point{10,5},Point{20,5},Point{20,15},Point{10,15}})).area()); } SCENARIO("Circle Fit, TaubinFit with Newton's method") { @@ -170,29 +168,29 @@ SCENARIO("Circle Fit, TaubinFit with Newton's method") { WHEN("Circle fit is called on the entire array") { Vec2d result_center(0,0); - result_center = Geometry::circle_taubin_newton(sample); + result_center = Geometry::circle_center_taubin_newton(sample); THEN("A center point of -6,0 is returned.") { - REQUIRE(result_center == expected_center); + REQUIRE((result_center - expected_center).norm() < EPSILON); } } WHEN("Circle fit is called on the first four points") { Vec2d result_center(0,0); - result_center = Geometry::circle_taubin_newton(sample.cbegin(), sample.cbegin()+4); + result_center = Geometry::circle_center_taubin_newton(sample.cbegin(), sample.cbegin()+4); THEN("A center point of -6,0 is returned.") { - REQUIRE(result_center == expected_center); + REQUIRE((result_center - expected_center).norm() < EPSILON); } } WHEN("Circle fit is called on the middle four points") { Vec2d result_center(0,0); - result_center = Geometry::circle_taubin_newton(sample.cbegin()+2, sample.cbegin()+6); + result_center = Geometry::circle_center_taubin_newton(sample.cbegin()+2, sample.cbegin()+6); THEN("A center point of -6,0 is returned.") { - REQUIRE(result_center == expected_center); + REQUIRE((result_center - expected_center).norm() < EPSILON); } } } GIVEN("A vector of Pointfs arranged in a half-circle with approximately the same distance R from some point") { Vec2d expected_center(-3, 9); - Pointfs sample {Vec2d{6.0, 0}, Vec2d{5.1961524, 3}, Vec2d{3 ,5.1961524}, + Vec2ds sample {Vec2d{6.0, 0}, Vec2d{5.1961524, 3}, Vec2d{3 ,5.1961524}, Vec2d{0, 6.0}, Vec2d{3, 5.1961524}, Vec2d{-5.1961524, 3}, Vec2d{-6.0, 0}}; @@ -201,23 +199,23 @@ SCENARIO("Circle Fit, TaubinFit with Newton's method") { WHEN("Circle fit is called on the entire array") { Vec2d result_center(0,0); - result_center = Geometry::circle_taubin_newton(sample); + result_center = Geometry::circle_center_taubin_newton(sample); THEN("A center point of 3,9 is returned.") { - REQUIRE(result_center == expected_center); + REQUIRE((result_center - expected_center).norm() < EPSILON); } } WHEN("Circle fit is called on the first four points") { Vec2d result_center(0,0); - result_center = Geometry::circle_taubin_newton(sample.cbegin(), sample.cbegin()+4); + result_center = Geometry::circle_center_taubin_newton(sample.cbegin(), sample.cbegin()+4); THEN("A center point of 3,9 is returned.") { - REQUIRE(result_center == expected_center); + REQUIRE((result_center - expected_center).norm() < EPSILON); } } WHEN("Circle fit is called on the middle four points") { Vec2d result_center(0,0); - result_center = Geometry::circle_taubin_newton(sample.cbegin()+2, sample.cbegin()+6); + result_center = Geometry::circle_center_taubin_newton(sample.cbegin()+2, sample.cbegin()+6); THEN("A center point of 3,9 is returned.") { - REQUIRE(result_center == expected_center); + REQUIRE((result_center - expected_center).norm() < EPSILON); } } } @@ -232,21 +230,21 @@ SCENARIO("Circle Fit, TaubinFit with Newton's method") { WHEN("Circle fit is called on the entire array") { Point result_center(0,0); - result_center = Geometry::circle_taubin_newton(sample); + result_center = Geometry::circle_center_taubin_newton(sample); THEN("A center point of scaled 3,9 is returned.") { REQUIRE(result_center.coincides_with_epsilon(expected_center)); } } WHEN("Circle fit is called on the first four points") { Point result_center(0,0); - result_center = Geometry::circle_taubin_newton(sample.cbegin(), sample.cbegin()+4); + result_center = Geometry::circle_center_taubin_newton(sample.cbegin(), sample.cbegin()+4); THEN("A center point of scaled 3,9 is returned.") { REQUIRE(result_center.coincides_with_epsilon(expected_center)); } } WHEN("Circle fit is called on the middle four points") { Point result_center(0,0); - result_center = Geometry::circle_taubin_newton(sample.cbegin()+2, sample.cbegin()+6); + result_center = Geometry::circle_center_taubin_newton(sample.cbegin()+2, sample.cbegin()+6); THEN("A center point of scaled 3,9 is returned.") { REQUIRE(result_center.coincides_with_epsilon(expected_center)); } @@ -285,7 +283,7 @@ SCENARIO("Line distances"){ SCENARIO("Polygon convex/concave detection"){ GIVEN(("A Square with dimension 100")){ - Polygon square/*new_scale*/{ std::vector{ + Slic3r::Polygon square/*new_scale*/{ std::vector{ Point{100,100}, Point{200,100}, Point{200,200}, @@ -301,7 +299,7 @@ SCENARIO("Polygon convex/concave detection"){ } } GIVEN("A Square with an extra colinearvertex"){ - Polygon square /*new_scale*/{ std::vector{ + Slic3r::Polygon square /*new_scale*/{ std::vector{ Point{150,100}, Point{200,100}, Point{200,200}, @@ -313,7 +311,7 @@ SCENARIO("Polygon convex/concave detection"){ } } GIVEN("A Square with an extra collinear vertex in different order"){ - Polygon square = Polygon /*new_scale*/{ std::vector{ + Slic3r::Polygon square /*new_scale*/{ std::vector{ Point{200,200}, Point{100,200}, Point{100,100}, @@ -326,7 +324,7 @@ SCENARIO("Polygon convex/concave detection"){ } GIVEN("A triangle"){ - Polygon triangle{ std::vector{ + Slic3r::Polygon triangle{ std::vector{ Point{16000170,26257364}, Point{714223,461012}, Point{31286371,461008} @@ -338,7 +336,7 @@ SCENARIO("Polygon convex/concave detection"){ } GIVEN("A triangle with an extra collinear point"){ - Polygon triangle{ std::vector{ + Slic3r::Polygon triangle{ std::vector{ Point{16000170,26257364}, Point{714223,461012}, Point{20000000,461012}, @@ -352,7 +350,7 @@ SCENARIO("Polygon convex/concave detection"){ GIVEN("A polygon with concave vertices with angles of specifically 4/3pi"){ // Two concave vertices of this polygon have angle = PI*4/3, so this test fails // if epsilon is not used. - Polygon polygon{ std::vector{ + Slic3r::Polygon polygon{ std::vector{ Point{60246458,14802768},Point{64477191,12360001}, Point{63727343,11060995},Point{64086449,10853608}, Point{66393722,14850069},Point{66034704,15057334}, @@ -370,7 +368,7 @@ SCENARIO("Polygon convex/concave detection"){ } TEST_CASE("Triangle Simplification does not result in less than 3 points"){ - Polygon triangle{ std::vector{ + Slic3r::Polygon triangle{ std::vector{ Point{16000170,26257364}, Point{714223,461012}, Point{31286371,461008} } }; REQUIRE(triangle.simplify(250000).at(0).points.size() == 3); diff --git a/tests/superslicerlibslic3r/test_model.cpp b/tests/superslicerlibslic3r/test_model.cpp index 98166fbf005..c6410b524ba 100644 --- a/tests/superslicerlibslic3r/test_model.cpp +++ b/tests/superslicerlibslic3r/test_model.cpp @@ -1,9 +1,12 @@ //#define CATCH_CONFIG_DISABLE - -#include +#include #include +#include #include +#include +#include +#include #include "test_data.hpp" // get access to init_print, etc using namespace Slic3r; @@ -13,12 +16,14 @@ SCENARIO("Model construction") { GIVEN("A Slic3r Model") { Model model{}; TriangleMesh sample_mesh = make_cube(20,20,20); - sample_mesh.repair(); + Slic3r::sla::IndexedMesh indexed_mesh(sample_mesh); // for ease of use + //sample_mesh.repair(); DynamicPrintConfig &config = Slic3r::DynamicPrintConfig::full_print_config(); Slic3r::Print print{}; print.apply(model, config); //Slic3r::Test::init_print(print, { sample_mesh }, model, config); + print.set_status_callback([](const PrintBase::SlicingStatus &) {}); WHEN("Model object is added") { ModelObject* mo = model.add_object(); @@ -35,13 +40,15 @@ SCENARIO("Model construction") { REQUIRE(mo->volumes.front()->is_modifier() == false); } THEN("Mesh is equivalent to input mesh.") { - TriangleMesh trimesh = mo->volumes.front()->mesh(); - REQUIRE(sample_mesh.vertices() == trimesh.vertices()); + Slic3r::sla::IndexedMesh trimesh(mo->volumes.front()->mesh()); + REQUIRE(indexed_mesh.vertices() == trimesh.vertices()); } ModelInstance* inst = mo->add_instance(); inst->set_rotation(Vec3d(0,0,0)); inst->set_scaling_factor(Vec3d(1, 1, 1)); - model.arrange_objects(print.config().min_object_distance()); + ArrangeParams params; + params.min_obj_distance = Slic3r::min_object_distance(print.config()); + Slic3r::arrange_objects(model, InfiniteBed{Point(scale_t(100),scale_t(100))}, params); model.center_instances_around_point(Slic3r::Vec2d(100,100)); print.auto_assign_extruders(mo); //print.add_model_object(mo); diff --git a/tests/superslicerlibslic3r/test_print.cpp b/tests/superslicerlibslic3r/test_print.cpp index 8528fb5d742..a0cef053e7c 100644 --- a/tests/superslicerlibslic3r/test_print.cpp +++ b/tests/superslicerlibslic3r/test_print.cpp @@ -1,13 +1,12 @@ //#define CATCH_CONFIG_DISABLE - -//#include -#include +#include #include "test_data.hpp" #include #include #include +#include //#include #include @@ -27,7 +26,7 @@ SCENARIO("PrintObject: Perimeter generation") { WHEN("make_perimeters() is called") { Print print{}; Slic3r::Test::init_print(print, { m }, model, &config); - PrintObject& object = *(print.objects().at(0)); + PrintObject& object = *print.objects_mutable().at(0); print.process(); // there are 66.66666.... layers for 0.3mm in 20mm //slic3r is rounded (slice at half-layer), slic3rPE is less? @@ -37,7 +36,7 @@ SCENARIO("PrintObject: Perimeter generation") { } THEN("Every layer in region 0 has 1 island of perimeters") { for(Layer* layer : object.layers()) { - REQUIRE(layer->regions()[0]->perimeters.entities.size() == 1); + REQUIRE(layer->regions()[0]->perimeters.entities().size() == 1); } } THEN("Every layer (but top) in region 0 has 3 paths in its perimeters list.") { @@ -67,13 +66,13 @@ SCENARIO("Print: Skirt generation") { print.process(); THEN("Skirt Extrusion collection has 2 loops in it") { REQUIRE(print.skirt().items_count() == 2); - REQUIRE(print.skirt().flatten().entities.size() == 2); + REQUIRE(print.skirt().flatten().entities().size() == 2); } } } } -void test_is_solid_infill(Print &p, size_t obj_id, size_t layer_id ) { +void test_is_solid_infill(Print &p, size_t obj_id, size_t layer_id, bool check = true ) { const PrintObject& obj { *(p.objects().at(obj_id)) }; const Layer& layer { *(obj.get_layer((int)layer_id)) }; @@ -81,7 +80,7 @@ void test_is_solid_infill(Print &p, size_t obj_id, size_t layer_id ) { for (const LayerRegion* reg : layer.regions()) { // for each region, iterate over the fill surfaces for (const Surface& su : reg->fill_surfaces.surfaces) { - CHECK(su.has_fill_solid()); + CHECK(su.has_fill_solid() == check); } } } @@ -94,6 +93,7 @@ SCENARIO("Print: Changing number of solid surfaces does not cause all surfaces t config.set_key_value("bottom_solid_layers", new ConfigOptionInt(1)); config.set_key_value("layer_height", new ConfigOptionFloat(0.5)); // get a known number of layers config.set_key_value("first_layer_height", new ConfigOptionFloatOrPercent(0.5, false)); + config.set_key_value("nozzle_diameter", new ConfigOptionFloats({1})); // has to be large enough for 0.5 layer height, the min/max lh depends on it config.set_key_value("enforce_full_fill_volume", new ConfigOptionBool(true)); Slic3r::Model model; auto event_counter {0U}; @@ -103,12 +103,26 @@ SCENARIO("Print: Changing number of solid surfaces does not cause all surfaces t print.process(); // Precondition: Ensure that the model has 2 solid top layers (39, 38) // and one solid bottom layer (0). - test_is_solid_infill(print, 0, 0); // should be solid - test_is_solid_infill(print, 0, 39); // should be solid - test_is_solid_infill(print, 0, 38); // should be solid + THEN("20 mm with 0.5 layer height means 40 layers.") + { + REQUIRE(print.objects().front()->layer_count() == 40); + } + THEN("First layer is solid bottom layer.") + { + test_is_solid_infill(print, 0, 0); // should be solid + test_is_solid_infill(print, 0, 1, false); // should not be solid + } + THEN("Two last layers are solid bottom layer.") + { + test_is_solid_infill(print, 0, 39); // should be solid + test_is_solid_infill(print, 0, 38); // should be solid + test_is_solid_infill(print, 0, 37, false); // should not be solid + } WHEN("Model is re-sliced with top_solid_layers == 3") { - ((ConfigOptionInt&)(print.regions()[0]->config().top_solid_layers)).value = 3; - print.invalidate_state_by_config_options(std::vector{ "posPrepareInfill" }); + ((ConfigOptionInt&)(print.get_print_region(0).config().top_solid_layers)).value = 3; + REQUIRE(print.get_print_region(0).config().top_solid_layers.value == 3); + DynamicPrintConfig useless; + print.invalidate_state_by_config_options(useless, std::vector{ "posPrepareInfill" }); print.process(); THEN("Print object does not have 0 solid bottom layers.") { test_is_solid_infill(print, 0, 0); @@ -160,8 +174,8 @@ SCENARIO("Print: Brim generation") { Print print{}; Slic3r::Test::init_print(print, { m }, model, &config); print.process(); - THEN("Brim Extrusion collection has 5 loops in it") { - REQUIRE(print.brim().items_count() == 5); + THEN("Brim Extrusion collection has 6 loops in it, even with offset") { + REQUIRE(print.brim().items_count() == 6); } } WHEN("Brim without first layer compensation") { @@ -170,25 +184,27 @@ SCENARIO("Print: Brim generation") { Print print{}; Slic3r::Test::init_print(print, { m }, model, &config); print.process(); - THEN("First Brim Extrusion has a length of ~88") { - REQUIRE(print.brim().entities.size() > 0); - double dist = unscaled(ExtrusionLength{}.length(*print.brim().entities.front())); - REQUIRE(dist > 22*4); - REQUIRE(dist < 22*4+1); + Flow brim_flow = print.brim_flow(0, print.default_object_config()); + THEN("First Brim Extrusion has a length of ~84") { + REQUIRE(print.brim().entities().size() > 0); + double dist = unscaled(ExtrusionLength{}.length(*print.brim().entities().front())); + REQUIRE(dist < (20 + brim_flow.spacing()) * 4 ); // little lower because of the round edge at the corners + REQUIRE(dist > (20 + brim_flow.spacing()) * 4 - 1); } } WHEN("Brim with 1mm first layer compensation") { config.set_key_value("brim_width", new ConfigOptionFloat(1)); config.set_key_value("brim_offset", new ConfigOptionFloat(0)); - config.set_key_value("first_layer_size_compensation", new ConfigOptionFloat(-1)); + config.set_key_value("first_layer_size_compensation", new ConfigOptionFloat(-0.5)); Print print{}; Slic3r::Test::init_print(print, { m }, model, &config); print.process(); + Flow brim_flow = print.brim_flow(0, print.objects().at(0)->config()); THEN("First Brim Extrusion has a length of ~80") { - REQUIRE(print.brim().entities.size() > 0); - double dist = unscaled(ExtrusionLength{}.length(*print.brim().entities.front())); - REQUIRE(dist > 20 * 4); - REQUIRE(dist < 20 * 4 + 1); + REQUIRE(print.brim().entities().size() > 0); + double dist = unscaled(ExtrusionLength{}.length(*print.brim().entities().front())); + REQUIRE(dist < (20 + brim_flow.spacing() - 1) * 4 );// little lower because of the round edge at the corners + REQUIRE(dist > (20 + brim_flow.spacing() - 1) * 4 - 1); } } WHEN("Brim is set to 6mm, extrusion width 0.5mm") { @@ -197,8 +213,10 @@ SCENARIO("Print: Brim generation") { Print print{}; Slic3r::Test::init_print(print, { m }, model, &config); print.process(); - double nbLoops = 6.0 / print.brim_flow(print.extruders().front()).spacing(); - THEN("Brim Extrusion collection has " + std::to_string(nbLoops) + " loops in it (flow="+ std::to_string(print.brim_flow(print.extruders().front()).spacing())+")") { + double nbLoops = 6.0 / print.brim_flow(*print.extruders().begin(), print.objects().at(0)->config()).spacing(); + THEN("Brim Extrusion collection has " + std::to_string(nbLoops) + " loops in it (flow=" + + std::to_string(print.brim_flow(*print.extruders().begin(), print.objects().at(0)->config()).spacing()) + ")") + { REQUIRE(print.brim().items_count() == floor(nbLoops)); } } @@ -215,40 +233,246 @@ SCENARIO("Print: Brim generation") { } } -SCENARIO("Print: perimeter generation") { - GIVEN("cube with hole, just enough space for two loops at a point") { - DynamicPrintConfig& config = Slic3r::DynamicPrintConfig::full_print_config(); - Slic3r::Model model{}; - config.set_key_value("first_layer_extrusion_width", new ConfigOptionFloatOrPercent(0.42, false)); - config.set_deserialize("nozzle_diameter", "0.4"); - config.set_deserialize("layer_height", "0.2"); - config.set_deserialize("first_layer_height", "0.2"); - config.set_key_value("only_one_perimeter_top", new ConfigOptionBool(false)); +struct GetFirst : ExtrusionVisitorRecursive +{ + ExtrusionLoop* first = nullptr; + ExtrusionLoop* previous_last = nullptr; + ExtrusionLoop* last = nullptr; + void default_use(ExtrusionEntity &entity) override { assert(false); }; + void use(ExtrusionLoop& loop) override { if(!first) first = &loop; previous_last = last; last = &loop; } +}; + +SCENARIO("Print: perimeter generation : cube with hole, just enough space for two loops at a point") +{ + DynamicPrintConfig &config = Slic3r::DynamicPrintConfig::full_print_config(); + Slic3r::Model model{}; + config.set_key_value("first_layer_extrusion_width", new ConfigOptionFloatOrPercent(0.42, false)); + config.set_deserialize("nozzle_diameter", "0.4"); + config.set_deserialize("layer_height", "0.2"); + config.set_deserialize("first_layer_height", "0.2"); + config.set_key_value("only_one_perimeter_top", new ConfigOptionBool(false)); + + auto facets = std::vector{Vec3i32(1, 4, 3), Vec3i32(4, 1, 2), Vec3i32(16, 12, 14), + Vec3i32(16, 10, 12), Vec3i32(10, 4, 6), Vec3i32(4, 10, 16), + Vec3i32(8, 14, 12), Vec3i32(8, 2, 14), Vec3i32(6, 2, 8), + Vec3i32(2, 6, 4), Vec3i32(14, 15, 16), Vec3i32(15, 14, 13), + Vec3i32(15, 4, 16), Vec3i32(4, 15, 3), Vec3i32(13, 11, 15), + Vec3i32(13, 7, 11), Vec3i32(7, 1, 5), Vec3i32(1, 7, 13), + Vec3i32(9, 15, 11), Vec3i32(9, 3, 15), Vec3i32(5, 3, 9), + Vec3i32(3, 5, 1), Vec3i32(1, 14, 2), Vec3i32(14, 1, 13), + Vec3i32(9, 12, 10), Vec3i32(12, 9, 11), Vec3i32(6, 9, 10), + Vec3i32(9, 6, 5), Vec3i32(8, 5, 6), Vec3i32(5, 8, 7), + Vec3i32(7, 12, 11), Vec3i32(12, 7, 8)}; + for (Vec3i32 &vec : facets) vec -= Vec3i32(1, 1, 1); + TriangleMesh tm = TriangleMesh{std::vector{Vec3f(-5, -5, -0.1), Vec3f(-5, -5, 0.1), Vec3f(-5, 5, -0.1), + Vec3f(-5, 5, 0.1), Vec3f(-1.328430, 0, -0.1), + Vec3f(-1.328430, 0, 0.1), Vec3f(1.5, -2.828430, -0.1), + Vec3f(1.5, -2.828430, 0.1), Vec3f(1.5, 2.828430, -0.1), + Vec3f(1.5, 2.828430, 0.1), Vec3f(4.328430, 0, -0.1), + Vec3f(4.328430, 0, 0.1), Vec3f(5, -5, -0.1), Vec3f(5, -5, 0.1), + Vec3f(5, 5, -0.1), Vec3f(5, 5, 0.1)}, + facets}; + + GIVEN("no brim") + { Print print{}; - auto facets = std::vector{ - Vec3i32(1,4,3),Vec3i32(4,1,2),Vec3i32(16,12,14),Vec3i32(16,10,12),Vec3i32(10,4,6),Vec3i32(4,10,16),Vec3i32(8,14,12),Vec3i32(8,2,14), - Vec3i32(6,2,8),Vec3i32(2,6,4),Vec3i32(14,15,16),Vec3i32(15,14,13),Vec3i32(15,4,16),Vec3i32(4,15,3),Vec3i32(13,11,15),Vec3i32(13,7,11), - Vec3i32(7,1,5),Vec3i32(1,7,13),Vec3i32(9,15,11),Vec3i32(9,3,15),Vec3i32(5,3,9),Vec3i32(3,5,1),Vec3i32(1,14,2),Vec3i32(14,1,13), - Vec3i32(9,12,10),Vec3i32(12,9,11),Vec3i32(6,9,10),Vec3i32(9,6,5),Vec3i32(8,5,6),Vec3i32(5,8,7),Vec3i32(7,12,11),Vec3i32(12,7,8) - }; - for (Vec3i32& vec : facets) - vec -= Vec3i32(1, 1, 1); - TriangleMesh tm = TriangleMesh{ std::vector{Vec3d(-5,-5,-0.1),Vec3d(-5,-5,0.1),Vec3d(-5,5,-0.1),Vec3d(-5,5,0.1), - Vec3d(-1.328430,0,-0.1),Vec3d(-1.328430,0,0.1),Vec3d(1.5,-2.828430,-0.1),Vec3d(1.5,-2.828430,0.1), - Vec3d(1.5,2.828430,-0.1),Vec3d(1.5,2.828430,0.1),Vec3d(4.328430,0,-0.1),Vec3d(4.328430,0,0.1), - Vec3d(5,-5,-0.1),Vec3d(5,-5,0.1),Vec3d(5,5,-0.1),Vec3d(5,5,0.1)}, - facets }; Slic3r::Test::init_print(print, {tm}, model, &config); print.process(); - THEN("hole perimeter should not be printed first") { - ExtrusionEntity* loop = print.objects()[0]->layers()[0]->regions()[0]->perimeters.entities[0]; - REQUIRE(loop->is_collection()); - loop = ((ExtrusionEntityCollection*)loop)->entities.front(); - REQUIRE(loop->is_loop()); - // what we don't want in first is something that is (((ExtrusionLoop*)loop)->loop_role() & ExtrusionLoopRole::elrHole) != 0 && loop->role() == elrExternalPerimeter - REQUIRE( (((ExtrusionLoop*)loop)->loop_role() & ExtrusionLoopRole::elrHole) == 0); + ExtrusionPrinter printer(/*mult=*/0.000001, /*trunc=*/100, /*json=*/true); + //std::cout << "\n\n\nNO BRIM EXTUSIONS:\n"; + //print.objects()[0]->layers()[0]->regions()[0]->perimeters.visit(printer); + //std::cout << "{" << printer.str() << "}"; + //Model model = print.model(); + //Slic3r::store_3mf("test_without_brim.3mf", &model, &print.full_print_config(), OptionStore3mf{}); + // see https://github.com/supermerill/SuperSlicer/issues/242, why the hole is after the contour inner + THEN("hole perimeter should not be printed first, but still before external one") + { + GetFirst get_first_visitor; + print.objects()[0]->layers()[0]->regions()[0]->perimeters.visit(get_first_visitor); + REQUIRE(get_first_visitor.first != nullptr); + REQUIRE(get_first_visitor.first->is_loop()); + // first inner contour peri + REQUIRE((get_first_visitor.first->loop_role() & ExtrusionLoopRole::elrHole) == 0); + REQUIRE(get_first_visitor.first->role() == ExtrusionRole::erPerimeter); + // the external hole perimeter (because it's alone without inner ones, we don't want it to be used as a skirt) + // note: here we may want to have the seam of this one near the next one instead of near our current pos, + // if it's an external one, to avoid oozing before external. + REQUIRE((get_first_visitor.previous_last->loop_role() & ExtrusionLoopRole::elrHole) != 0); + REQUIRE(get_first_visitor.previous_last->role() == ExtrusionRole::erExternalPerimeter); + // the external contour perimeter + REQUIRE((get_first_visitor.last->loop_role() & ExtrusionLoopRole::elrHole) == 0); + REQUIRE(get_first_visitor.last->role() == ExtrusionRole::erExternalPerimeter); + } + } + GIVEN("brim") + { + config.set_deserialize("brim_width", "0.2"); + Print print{}; + Slic3r::Test::init_print(print, {tm}, model, &config); + print.process(); + THEN("hole perimeter should not be printed first") + { + GetFirst get_first_visitor; + print.objects()[0]->layers()[0]->regions()[0]->perimeters.visit(get_first_visitor); + // the external contour perimeter + REQUIRE((get_first_visitor.first->loop_role() & ExtrusionLoopRole::elrHole) == 0); + REQUIRE(get_first_visitor.first->role() == ExtrusionRole::erExternalPerimeter); + // first inner contour peri + REQUIRE((get_first_visitor.previous_last->loop_role() & ExtrusionLoopRole::elrHole) == 0); + REQUIRE(get_first_visitor.previous_last->role() == ExtrusionRole::erPerimeter); + // the external hole perimeter + REQUIRE((get_first_visitor.last->loop_role() & ExtrusionLoopRole::elrHole) == ExtrusionLoopRole::elrHole); + REQUIRE(get_first_visitor.last->role() == ExtrusionRole::erExternalPerimeter); + } + } +} + +struct GetAll : ExtrusionVisitorRecursive +{ + std::vector loops; + void default_use(ExtrusionEntity &entity) override { assert(false); }; + void use(ExtrusionLoop& loop) override { loops.push_back(&loop); } +}; +SCENARIO("Print: perimeter generation : cube with hole in center") { + DynamicPrintConfig& config = Slic3r::DynamicPrintConfig::full_print_config(); + Slic3r::Model model{}; + config.set_key_value("first_layer_extrusion_width", new ConfigOptionFloatOrPercent(0.42, false)); + config.set_deserialize("nozzle_diameter", "0.4"); + config.set_deserialize("layer_height", "0.2"); + config.set_deserialize("first_layer_height", "0.2"); + config.set_key_value("only_one_perimeter_top", new ConfigOptionBool(false)); + + std::vector v{{-10, 10, -0.1}, {-10, -10, -0.1}, {-10, 10, 0.1}, {-10, -10, 0.1}, + {10, -10, -0.1}, {10, -10, 0.1}, {-2.5, 2.5, 0.1}, {-2.5, -2.5, 0.1}, + {2.5, -2.5, 0.1}, {10, 10, 0.1}, {2.5, 2.5, 0.1}, {10, 10, -0.1}, + {-2.5, 2.5, -0.1}, {-2.5, -2.5, -0.1}, {2.5, -2.5, -0.1}, {2.5, 2.5, -0.1}}; + std::vector i{{0, 1, 2}, {1, 3, 2}, {1, 4, 3}, {4, 5, 3}, {6, 2, 3}, {6, 3, 7}, + {5, 8, 7}, {5, 7, 3}, {9, 6, 10}, {9, 10, 8}, {9, 8, 5}, {9, 2, 6}, + {11, 0, 2}, {9, 11, 2}, {0, 12, 1}, {1, 12, 13}, {14, 4, 13}, {13, 4, 1}, + {12, 11, 15}, {15, 11, 14}, {14, 11, 4}, {0, 11, 12}, {4, 11, 9}, {5, 4, 9}, + {7, 13, 12}, {7, 12, 6}, {8, 14, 13}, {8, 13, 7}, {14, 8, 15}, {15, 8, 10}, + {15, 10, 12}, {12, 10, 6}}; + TriangleMesh tm = TriangleMesh(v, i); + + GIVEN("no brim") + { + config.set_deserialize("brim_width", "0"); + config.set_deserialize("brim_width_interior", "0"); + Print print{}; + Slic3r::Test::init_print(print, {tm}, model, &config); + print.process(); + // see https://github.com/supermerill/SuperSlicer/issues/242, why the hole is after the contour inner + GetAll get_all_visitor; + print.objects()[0]->layers()[0]->regions()[0]->perimeters.visit(get_all_visitor); + auto &loops = get_all_visitor.loops; + THEN("hole printed first, external last") + { + REQUIRE(loops.size() == 6); + // first holes + REQUIRE((loops[0]->loop_role() & ExtrusionLoopRole::elrHole) == ExtrusionLoopRole::elrHole); + REQUIRE(loops[0]->role() == ExtrusionRole::erPerimeter); + REQUIRE((loops[2]->loop_role() & ExtrusionLoopRole::elrHole) == ExtrusionLoopRole::elrHole); + REQUIRE(loops[2]->role() == ExtrusionRole::erExternalPerimeter); + } + THEN("contour printed last, external last") + { + //then contour + REQUIRE( (loops[3]->loop_role() & ExtrusionLoopRole::elrHole) == 0); + REQUIRE( loops[3]->role() == ExtrusionRole::erPerimeter); + REQUIRE( (loops[5]->loop_role() & ExtrusionLoopRole::elrHole) == 0); + REQUIRE( loops[5]->role() == ExtrusionRole::erExternalPerimeter); + } + } + GIVEN("contour brim") + { + config.set_deserialize("brim_width", "1"); + config.set_deserialize("brim_width_interior", "0"); + Print print{}; + Slic3r::Test::init_print(print, {tm}, model, &config); + print.process(); + ExtrusionPrinter printer(/*mult=*/0.000001, /*trunc=*/100, /*json=*/true); + GetAll get_all_visitor; + print.objects()[0]->layers()[0]->regions()[0]->perimeters.visit(get_all_visitor); + auto &loops = get_all_visitor.loops; + REQUIRE(loops.size() == 6); + THEN("contour printed first, external first") + { + //then contour + REQUIRE( (loops[0]->loop_role() & ExtrusionLoopRole::elrHole) == 0); + REQUIRE( loops[0]->role() == ExtrusionRole::erExternalPerimeter); + REQUIRE( (loops[2]->loop_role() & ExtrusionLoopRole::elrHole) == 0); + REQUIRE( loops[2]->role() == ExtrusionRole::erPerimeter); + } + THEN("hole printed last, external last as there is no hole brim") + { + // first holes + REQUIRE((loops[3]->loop_role() & ExtrusionLoopRole::elrHole) == ExtrusionLoopRole::elrHole); + REQUIRE(loops[3]->role() == ExtrusionRole::erPerimeter); + REQUIRE((loops[5]->loop_role() & ExtrusionLoopRole::elrHole) == ExtrusionLoopRole::elrHole); + REQUIRE(loops[5]->role() == ExtrusionRole::erExternalPerimeter); + } + //TODO: thinwall after evrything + } + GIVEN("hole brim") + { + config.set_deserialize("brim_width", "0"); + config.set_deserialize("brim_width_interior", "1"); + Print print{}; + Slic3r::Test::init_print(print, {tm}, model, &config); + print.process(); + ExtrusionPrinter printer(/*mult=*/0.000001, /*trunc=*/100, /*json=*/true); + GetAll get_all_visitor; + print.objects()[0]->layers()[0]->regions()[0]->perimeters.visit(get_all_visitor); + auto &loops = get_all_visitor.loops; + REQUIRE(loops.size() == 6); + THEN("hole printed first, external first") + { + // first holes + REQUIRE((loops[0]->loop_role() & ExtrusionLoopRole::elrHole) == ExtrusionLoopRole::elrHole); + REQUIRE(loops[0]->role() == ExtrusionRole::erExternalPerimeter); + REQUIRE((loops[2]->loop_role() & ExtrusionLoopRole::elrHole) == ExtrusionLoopRole::elrHole); + REQUIRE(loops[2]->role() == ExtrusionRole::erPerimeter); + } + THEN("contour printed last, external last") + { + //then contour + REQUIRE( (loops[3]->loop_role() & ExtrusionLoopRole::elrHole) == 0); + REQUIRE( loops[3]->role() == ExtrusionRole::erPerimeter); + REQUIRE( (loops[5]->loop_role() & ExtrusionLoopRole::elrHole) == 0); + REQUIRE( loops[5]->role() == ExtrusionRole::erExternalPerimeter); + } + //TODO: thinwall after evrything + } + GIVEN("both brim") + { + config.set_deserialize("brim_width", "1"); + config.set_deserialize("brim_width_interior", "1"); + Print print{}; + Slic3r::Test::init_print(print, {tm}, model, &config); + print.process(); + ExtrusionPrinter printer(/*mult=*/0.000001, /*trunc=*/100, /*json=*/true); + GetAll get_all_visitor; + print.objects()[0]->layers()[0]->regions()[0]->perimeters.visit(get_all_visitor); + auto &loops = get_all_visitor.loops; + REQUIRE(loops.size() == 6); + THEN("contour printed first, external first") + { + //then contour + REQUIRE( (loops[0]->loop_role() & ExtrusionLoopRole::elrHole) == 0); + REQUIRE( loops[0]->role() == ExtrusionRole::erExternalPerimeter); + REQUIRE( (loops[2]->loop_role() & ExtrusionLoopRole::elrHole) == 0); + REQUIRE( loops[2]->role() == ExtrusionRole::erPerimeter); + } + THEN("hole printed last, external first") + { + // first holes + REQUIRE((loops[3]->loop_role() & ExtrusionLoopRole::elrHole) == ExtrusionLoopRole::elrHole); + REQUIRE(loops[3]->role() == ExtrusionRole::erExternalPerimeter); + REQUIRE((loops[5]->loop_role() & ExtrusionLoopRole::elrHole) == ExtrusionLoopRole::elrHole); + REQUIRE(loops[5]->role() == ExtrusionRole::erPerimeter); } + //TODO: thinwall after evrything } } diff --git a/tests/superslicerlibslic3r/test_skirt_brim.cpp b/tests/superslicerlibslic3r/test_skirt_brim.cpp index aac1cf8b577..34f47adad53 100644 --- a/tests/superslicerlibslic3r/test_skirt_brim.cpp +++ b/tests/superslicerlibslic3r/test_skirt_brim.cpp @@ -1,13 +1,15 @@ //#define CATCH_CONFIG_DISABLE - -#include +#include #include "test_data.hpp" #include using namespace Slic3r::Test; using namespace Slic3r; +constexpr char* SKIRT_TAG = "Skirt"; +constexpr char* BRIM_TAG = "Brim"; + SCENARIO("skirt test by merill", "") { GIVEN("2 objects, don't complete individual object") { @@ -36,25 +38,25 @@ SCENARIO("skirt test by merill", "") { auto parser{ Slic3r::GCodeReader() }; parser.parse_file(gcode_filepath, [&layers_with_skirt, &layers_with_brim, &config](Slic3r::GCodeReader& self, const Slic3r::GCodeReader::GCodeLine& line) { - if (line.extruding(self) && line.comment().find("skirt") != std::string::npos) { + if (line.extruding(self) && line.comment().find(SKIRT_TAG) != std::string::npos) { layers_with_skirt[self.z()] = 1; } - if (line.extruding(self) && line.comment().find("brim") != std::string::npos) { + if (line.extruding(self) && line.comment().find(BRIM_TAG) != std::string::npos) { layers_with_brim[self.z()] = 1; } }); clean_file(gcode_filepath, "gcode"); THEN("one skrit generated") { - REQUIRE(print.skirt().entities.size() == 1); + REQUIRE(print.skirt().entities().size() == 1); for (auto obj : print.objects()) { - REQUIRE(obj->skirt().entities.size() == 0); + REQUIRE(obj->skirt().entities().size() == 0); } } THEN("brim is not generated") { - REQUIRE(print.brim().entities.size() == 0); + REQUIRE(print.brim().entities().size() == 0); for (auto obj : print.objects()) { - REQUIRE(obj->brim().entities.size() == 0); + REQUIRE(obj->brim().entities().size() == 0); } REQUIRE(layers_with_brim.size() == 0); } @@ -79,25 +81,25 @@ SCENARIO("skirt test by merill", "") { auto parser{ Slic3r::GCodeReader() }; parser.parse_file(gcode_filepath, [&layers_with_skirt, &layers_with_brim, &config](Slic3r::GCodeReader& self, const Slic3r::GCodeReader::GCodeLine& line) { - if (line.extruding(self) && line.comment().find("skirt") != std::string::npos) { + if (line.extruding(self) && line.comment().find(SKIRT_TAG) != std::string::npos) { layers_with_skirt[self.z()] = 1; } - if (line.extruding(self) && line.comment().find("brim") != std::string::npos) { + if (line.extruding(self) && line.comment().find(BRIM_TAG) != std::string::npos) { layers_with_brim[self.z()] = 1; } }); clean_file(gcode_filepath, "gcode"); THEN("one skirt generated") { - REQUIRE(print.skirt().entities.size() == 1); + REQUIRE(print.skirt().entities().size() == 1); for (auto obj : print.objects()) { - REQUIRE(obj->skirt().entities.size() == 0); + REQUIRE(obj->skirt().entities().size() == 0); } } THEN("brim generated") { - REQUIRE(print.brim().entities.size() > 0); + REQUIRE(print.brim().entities().size() > 0); for (auto obj : print.objects()) { - REQUIRE(obj->brim().entities.size() == 0); + REQUIRE(obj->brim().entities().size() == 0); } REQUIRE(layers_with_brim.size() == 1); } @@ -122,25 +124,25 @@ SCENARIO("skirt test by merill", "") { auto parser{ Slic3r::GCodeReader() }; parser.parse_file(gcode_filepath, [&layers_with_skirt, &layers_with_brim, &config](Slic3r::GCodeReader& self, const Slic3r::GCodeReader::GCodeLine& line) { - if (line.extruding(self) && line.comment().find("skirt") != std::string::npos) { + if (line.extruding(self) && line.comment().find(SKIRT_TAG) != std::string::npos) { layers_with_skirt[self.z()] = 1; } - if (line.extruding(self) && line.comment().find("brim") != std::string::npos) { + if (line.extruding(self) && line.comment().find(BRIM_TAG) != std::string::npos) { layers_with_brim[self.z()] = 1; } }); clean_file(gcode_filepath, "gcode"); THEN("no skirt generated") { - REQUIRE(print.skirt().entities.size() == 0); + REQUIRE(print.skirt().entities().size() == 0); for (auto obj : print.objects()) { - REQUIRE(obj->skirt().entities.size() == 0); + REQUIRE(obj->skirt().entities().size() == 0); } } THEN("brim generated") { - REQUIRE(print.brim().entities.size() > 0); + REQUIRE(print.brim().entities().size() > 0); for (auto obj : print.objects()) { - REQUIRE(obj->brim().entities.size() == 0); + REQUIRE(obj->brim().entities().size() == 0); } REQUIRE(layers_with_brim.size() == 1); } @@ -158,7 +160,8 @@ SCENARIO("skirt test by merill", "") { config.set_deserialize("fill_density", "0"); config.set_deserialize("perimeters", "1"); config.set_deserialize("complete_objects", "1"); - config.set_key_value("gcode_comments", new ConfigOptionBool(true)); + config.set_deserialize("brim_per_object", "1"); + config.set_deserialize("gcode_comments", "1"); WHEN("skirt with 3 layers is requested") { config.set_deserialize("skirts", "1"); @@ -176,23 +179,23 @@ SCENARIO("skirt test by merill", "") { auto parser{ Slic3r::GCodeReader() }; parser.parse_file(gcode_filepath, [&layers_with_skirt, &layers_with_brim, &config](Slic3r::GCodeReader& self, const Slic3r::GCodeReader::GCodeLine& line) { - if (line.extruding(self) && line.comment().find("skirt") != std::string::npos) { + if (line.extruding(self) && line.comment().find(SKIRT_TAG) != std::string::npos) { layers_with_skirt[self.z()] = 1; } - if (line.extruding(self) && line.comment().find("brim") != std::string::npos) { + if (line.extruding(self) && line.comment().find(BRIM_TAG) != std::string::npos) { layers_with_brim[self.z()] = 1; } }); THEN("one skirt per object") { - REQUIRE(print.skirt().entities.size() == 0); + REQUIRE(print.skirt().entities().size() == 0); for (auto obj : print.objects()) { - REQUIRE(obj->skirt().entities.size() == 1); + REQUIRE(obj->skirt().entities().size() == 1); } } THEN("brim is not generated") { - REQUIRE(print.brim().entities.size() == 0); + REQUIRE(print.brim().entities().size() == 0); for (auto obj : print.objects()) { - REQUIRE(obj->brim().entities.size() == 0); + REQUIRE(obj->brim().entities().size() == 0); } REQUIRE(layers_with_brim.size() == 0); } @@ -217,25 +220,25 @@ SCENARIO("skirt test by merill", "") { auto parser{ Slic3r::GCodeReader() }; parser.parse_file(gcode_filepath, [&layers_with_skirt, &layers_with_brim, &config](Slic3r::GCodeReader& self, const Slic3r::GCodeReader::GCodeLine& line) { - if (line.extruding(self) && line.comment().find("skirt") != std::string::npos) { + if (line.extruding(self) && line.comment().find(SKIRT_TAG) != std::string::npos) { layers_with_skirt[self.z()] = 1; } - if (line.extruding(self) && line.comment().find("brim") != std::string::npos) { + if (line.extruding(self) && line.comment().find(BRIM_TAG) != std::string::npos) { layers_with_brim[self.z()] = 1; } }); clean_file(gcode_filepath, "gcode"); THEN("one skirt per object") { - REQUIRE(print.skirt().entities.size() == 0); + REQUIRE(print.skirt().entities().size() == 0); for (auto obj : print.objects()) { - REQUIRE(obj->skirt().entities.size() == 1); + REQUIRE(obj->skirt().entities().size() == 1); } } THEN("brim generated") { - REQUIRE(print.brim().entities.size() == 0); + REQUIRE(print.brim().entities().size() == 0); for (auto obj : print.objects()) { - REQUIRE(obj->brim().entities.size() > 0); + REQUIRE(obj->brim().entities().size() > 0); } REQUIRE(layers_with_brim.size() == 1); } @@ -260,25 +263,25 @@ SCENARIO("skirt test by merill", "") { auto parser{ Slic3r::GCodeReader() }; parser.parse_file(gcode_filepath, [&layers_with_skirt, &layers_with_brim, &config](Slic3r::GCodeReader& self, const Slic3r::GCodeReader::GCodeLine& line) { - if (line.extruding(self) && line.comment().find("skirt") != std::string::npos) { + if (line.extruding(self) && line.comment().find(SKIRT_TAG) != std::string::npos) { layers_with_skirt[self.z()] = 1; } - if (line.extruding(self) && line.comment().find("brim") != std::string::npos) { + if (line.extruding(self) && line.comment().find(BRIM_TAG) != std::string::npos) { layers_with_brim[self.z()] = 1; } }); clean_file(gcode_filepath, "gcode"); THEN("no skrit") { - REQUIRE(print.skirt().entities.size() == 0); + REQUIRE(print.skirt().entities().size() == 0); for (auto obj : print.objects()) { - REQUIRE(obj->skirt().entities.size() == 0); + REQUIRE(obj->skirt().entities().size() == 0); } } THEN("brim generated") { - REQUIRE(print.brim().entities.size() == 0); + REQUIRE(print.brim().entities().size() == 0); for (auto obj : print.objects()) { - REQUIRE(obj->brim().entities.size() > 0); + REQUIRE(obj->brim().entities().size() > 0); } REQUIRE(layers_with_brim.size() == 1); } @@ -295,7 +298,7 @@ SCENARIO("Original Slic3r Skirt/Brim tests", "[!mayfail]") { config.set_deserialize("skirt_height", "2"); config.set_deserialize("perimeters", "1"); config.set_deserialize("support_material_speed", "99"); - config.set_key_value("gcode_comments", new ConfigOptionBool(true)); + config.set_deserialize("gcode_comments", "1"); // avoid altering speeds unexpectedly config.set_deserialize("cooling", "0"); @@ -312,7 +315,7 @@ SCENARIO("Original Slic3r Skirt/Brim tests", "[!mayfail]") { auto parser {Slic3r::GCodeReader()}; parser.parse_file(gcode_filepath, [&layers_with_skirt, &config] (Slic3r::GCodeReader& self, const Slic3r::GCodeReader::GCodeLine& line) { - if (line.extruding(self) && line.comment().find("skirt") != std::string::npos) { + if (line.extruding(self) && line.comment().find(SKIRT_TAG) != std::string::npos) { layers_with_skirt[self.z()] = 1; } //if (self.z() > 0) { @@ -350,7 +353,7 @@ SCENARIO("Original Slic3r Skirt/Brim tests", "[!mayfail]") { Print print{}; Slic3r::Test::init_print(print, { TestMesh::cube_20x20x20 }, model, &config, false); print.process(); - REQUIRE(print.brim().entities.size()>0); + REQUIRE(print.brim().entities().size()>0); } } diff --git a/tests/superslicerlibslic3r/test_thin.cpp b/tests/superslicerlibslic3r/test_thin.cpp index 53c26e59ab5..5e18d5c28ec 100644 --- a/tests/superslicerlibslic3r/test_thin.cpp +++ b/tests/superslicerlibslic3r/test_thin.cpp @@ -1,12 +1,12 @@ //#define CATCH_CONFIG_DISABLE - -#include +#include #include "test_data.hpp" #include -#include +#include #include #include +#include using namespace Slic3r; using namespace Slic3r::Geometry; @@ -16,7 +16,7 @@ class ExtrusionVolumeVisitor : public ExtrusionVisitorConst { double volume = 0; public: virtual void use(const ExtrusionPath &path) override { - for (int i = 0; i < path.polyline.size() - 1; i++) volume += path.polyline.points[i].distance_to(path.polyline.points[i + 1]) * path.mm3_per_mm; + for (int i = 0; i < path.polyline.size() - 1; i++) volume += unscaled(path.polyline.get_points()[i].distance_to(path.polyline.get_points()[i + 1])) * path.mm3_per_mm; }; virtual void use(const ExtrusionPath3D &path3D) override { std::cout << "error, not supported"; }; virtual void use(const ExtrusionMultiPath &multipath) override { @@ -27,7 +27,7 @@ class ExtrusionVolumeVisitor : public ExtrusionVisitorConst { for (const ExtrusionEntity &path : loop.paths) path.visit(*this); } virtual void use(const ExtrusionEntityCollection &collection) override { - for (const ExtrusionEntity *path : collection.entities) path->visit(*this); + for (const ExtrusionEntity *path : collection.entities()) path->visit(*this); } double compute(const ExtrusionEntity &entity) && { entity.visit(*this); @@ -46,10 +46,12 @@ SCENARIO("extrude_thinwalls") { Point::new_scale(-0.3, 10) } }; ThickPolylines res; - MedialAxis{ expolygon, scale_(1.1), scale_(0.5), scale_(0.2) }.build(res); - Flow periflow{ 1.1, 0.2, 0.4 }; - ExtrusionEntityCollection gap_fill = thin_variable_width(res, erGapFill, periflow); - + MedialAxis{ expolygon, scale_t(1.1), scale_t(0.5), scale_t(0.2) }.build(res); + Flow periflow = Flow::new_from_width(1.1f, 0.4f, 0.2f, 1.f, false); + ExtrusionEntityCollection gap_fill; + gap_fill.append(thin_variable_width(res, erGapFill, periflow, SCALED_EPSILON*2, true)); + + //Flow gapfill_max_flow = Flow::new_from_spacing(1.f, 0.4f, 0.2f, 1.f, false); //std::string gcode = gcodegen.get_visitor_gcode(); THEN("analyse extrusion.") { @@ -63,8 +65,6 @@ SCENARIO("extrude_thinwalls") { SCENARIO("thin walls: ") { - - GIVEN("Square") { Points test_set; @@ -160,13 +160,14 @@ SCENARIO("thin walls: ") } THEN("all medial axis segments of a semicircumference have the same orientation (but the 2 end points)") { Lines lines = res[0].lines(); - double min_angle = 1, max_angle = -1; + double min_angle = PI*4, max_angle = -PI*4; //std::cout << "first angle=" << lines[0].ccw(lines[1].b) << "\n"; for (int idx = 1; idx < lines.size() - 1; idx++) { - double angle = lines[idx - 1].ccw(lines[idx].b); + assert(lines[idx].a== lines[idx - 1].b); + double angle = lines[idx].a.ccw_angle(lines[idx - 1].a, lines[idx].b); if (std::abs(angle) - EPSILON < 0) angle = 0; //if (angle < 0) std::cout << unscale_(lines[idx - 1].a.x()) << ":" << unscale_(lines[idx - 1].a.y()) << " -> " << unscale_(lines[idx - 1].b.x()) << ":" << unscale_(lines[idx - 1].b.y()) << " -> " << unscale_(lines[idx].b.x()) << ":" << unscale_(lines[idx].b.y()) << "\n"; - std::cout << "angle=" << 180 * lines[idx].a.ccw_angle(lines[idx - 1].a, lines[idx].b) / PI << "\n"; + std::cout << "angle=" << 180*angle/PI << "\n"; min_angle = std::min(min_angle, angle); max_angle = std::max(max_angle, angle); } @@ -303,10 +304,10 @@ SCENARIO("thin walls: ") //} }; WHEN("1 nozzle, 0.2 layer height") { const coord_t nozzle_diam = scale_(1); - ExPolygon anchor = union_ex(ExPolygons{ tooth }, intersection_ex(ExPolygons{ base_part }, offset_ex(tooth, nozzle_diam / 2)), true)[0]; + ExPolygon anchor = union_ex(ExPolygons{ tooth }, intersection_ex(ExPolygons{ base_part }, offset_ex(tooth, nozzle_diam / 2)), ApplySafetyOffset::Yes)[0]; ThickPolylines res; //expolygon.medial_axis(scale_(1), scale_(0.5), &res); - Slic3r::MedialAxis ma(tooth, nozzle_diam * 2, nozzle_diam/3, scale_(0.2)); + Slic3r::Geometry::MedialAxis ma(tooth, /*min_width*/nozzle_diam * 2, /*max_width*/nozzle_diam/3, /*height*/scale_(0.2)); ma.use_bounds(anchor) .use_min_real_width(nozzle_diam) .use_tapers(0.25*nozzle_diam); @@ -319,16 +320,16 @@ SCENARIO("thin walls: ") } THEN("medial axis has the line width as max width") { double max_width = 0; - for (coordf_t width : res[0].width) max_width = std::max(max_width, width); + for (coordf_t width : res[0].points_width) max_width = std::max(max_width, width); REQUIRE(std::abs(max_width - scale_(1.2)) < SCALED_EPSILON); } //compute the length of the tapers THEN("medial axis has good tapers length") { int l1 = 0; - for (size_t idx = 0; idx < res[0].width.size() - 1 && res[0].width[idx] - nozzle_diam < SCALED_EPSILON; ++idx) + for (size_t idx = 0; idx < res[0].points_width.size() - 1 && res[0].points_width[idx] - nozzle_diam < SCALED_EPSILON; ++idx) l1 += res[0].lines()[idx].length(); int l2 = 0; - for (size_t idx = res[0].width.size() - 1; idx > 0 && res[0].width[idx] - nozzle_diam < SCALED_EPSILON; --idx) + for (size_t idx = res[0].points_width.size() - 1; idx > 0 && res[0].points_width[idx] - nozzle_diam < SCALED_EPSILON; --idx) l2 += res[0].lines()[idx - 1].length(); REQUIRE(std::abs(l1 - l2) < SCALED_EPSILON); REQUIRE(std::abs(l1 - scale_(0.25 - 0.1)) < SCALED_EPSILON); @@ -338,10 +339,10 @@ SCENARIO("thin walls: ") WHEN("1.2 nozzle, 0.6 layer height") { const coord_t nozzle_diam = scale_(1.2); - ExPolygon anchor = union_ex(ExPolygons{ tooth }, intersection_ex(ExPolygons{ base_part }, offset_ex(tooth, nozzle_diam / 4)), true)[0]; + ExPolygon anchor = union_ex(ExPolygons{ tooth }, intersection_ex(ExPolygons{ base_part }, offset_ex(tooth, nozzle_diam / 4)), ApplySafetyOffset::Yes)[0]; ThickPolylines res; //expolygon.medial_axis(scale_(1), scale_(0.5), &res); - Slic3r::MedialAxis ma(tooth, nozzle_diam * 2, nozzle_diam/3, scale_(0.6)); + Slic3r::Geometry::MedialAxis ma(tooth, /*min_width*/nozzle_diam * 2, /*max_width*/nozzle_diam/3, /*height*/scale_(0.6)); ma.use_bounds(anchor) .use_min_real_width(nozzle_diam) .use_tapers(1.0*nozzle_diam); @@ -354,24 +355,24 @@ SCENARIO("thin walls: ") } THEN("medial axis can'ty have a line width below Flow::new_from_spacing(nozzle_diam).width") { double max_width = 0; - for (coordf_t width : res[0].width) max_width = std::max(max_width, width); - double min_width = Flow::new_from_spacing(float(unscale_(nozzle_diam)), float(unscale_(nozzle_diam)), 0.6f, false).scaled_width(); + for (coordf_t width : res[0].points_width) max_width = std::max(max_width, width); + double min_width = Flow::new_from_spacing(float(unscaled(nozzle_diam)), float(unscaled(nozzle_diam)), 0.6f, 1.f, false).scaled_width(); REQUIRE(std::abs(max_width - min_width) < SCALED_EPSILON); REQUIRE(std::abs(max_width - nozzle_diam) > SCALED_EPSILON); } //compute the length of the tapers THEN("medial axis has a 45� taper and a shorter one") { - int l1 = 0; - for (size_t idx = 0; idx < res[0].width.size() - 1 && res[0].width[idx] - scale_(1.2) < SCALED_EPSILON; ++idx) - l1 += res[0].lines()[idx].length(); - int l2 = 0; - for (size_t idx = res[0].width.size() - 1; idx > 0 && res[0].width[idx] - scale_(1.2) < SCALED_EPSILON; --idx) - l2 += res[0].lines()[idx - 1].length(); + coord_t l1 = 0; + for (size_t idx = 0; idx < res[0].points_width.size() - 1 && res[0].points_width[idx] - scale_(1.2) < SCALED_EPSILON; ++idx) + l1 += coord_t(res[0].lines()[idx].length()); + coord_t l2 = 0; + for (size_t idx = res[0].points_width.size() - 1; idx > 0 && res[0].points_width[idx] - scale_(1.2) < SCALED_EPSILON; --idx) + l2 += coord_t(res[0].lines()[idx - 1].length()); //here the taper is limited by the 0-width spacing - double min_width = Flow::new_from_spacing(float(unscale_(nozzle_diam)), float(unscale_(nozzle_diam)), 0.6f, false).scaled_width(); + double min_width = Flow::new_from_spacing(float(unscaled(nozzle_diam)), float(unscaled(nozzle_diam)), 0.6f, 1.f, false).scaled_width(); REQUIRE(std::abs(l1 - l2) < SCALED_EPSILON); - REQUIRE(l1 < scale_(0.6)); - REQUIRE(l1 > scale_(0.4)); + REQUIRE(l1 < scale_t(0.6)); + REQUIRE(l1 > scale_t(0.4)); } } }