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/Config.hpp b/src/libslic3r/Config.hpp index e0688b7f850..7b2708abef0 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(); @@ -2320,7 +2322,7 @@ class ConfigBase : public ConfigOptionResolver // to resolve renamed and removed configuration keys. 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, ConfigSubstitutionContext& config_substitutions = ConfigSubstitutionContext(ForwardCompatibilitySubstitutionRule::Disable), bool append = false); 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/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/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/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 074d966043a..e75bc812028 100644 --- a/src/libslic3r/PerimeterGenerator.cpp +++ b/src/libslic3r/PerimeterGenerator.cpp @@ -802,7 +802,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 @@ -2607,21 +2619,25 @@ 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 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 03f7c2cc152..609366e7c21 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -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/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/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..be33988f63d 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(3.06161699911402e-16,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(3.06161699911402e-16,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.14286), 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)); } } }