diff --git a/CMakeLists.txt b/CMakeLists.txt index 3efc18b8e0..96752abb87 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -173,10 +173,10 @@ if (NOT MSVC AND ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMP # On GCC and Clang, no return from a non-void function is a warning only. Here, we make it an error. add_compile_options(-Werror=return-type) - #removes LOTS of extraneous Eigen warnings (GCC only supports it since 6.1) - #https://eigen.tuxfamily.org/bz/show_bug.cgi?id=1221 - if("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" OR CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 6.1) - add_compile_options(-Wno-ignored-attributes) + # removes LOTS of extraneous Eigen warnings (GCC only supports it since 6.1) + # https://eigen.tuxfamily.org/bz/show_bug.cgi?id=1221 + if("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" OR CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 6.0) + add_compile_options(-Wno-ignored-attributes) # Tamas: Eigen include dirs are marked as SYSTEM endif() #GCC generates loads of -Wunknown-pragmas when compiling igl. The fix is not easy due to a bug in gcc, see diff --git a/cmake/modules/FindTBB.cmake b/cmake/modules/FindTBB.cmake index b09bafda3a..ffdee03ac8 100644 --- a/cmake/modules/FindTBB.cmake +++ b/cmake/modules/FindTBB.cmake @@ -260,6 +260,10 @@ if(NOT TBB_FOUND) if(TBB_LIBRARIES_${TBB_BUILD_TYPE}) set(TBB_LIBRARIES "${TBB_LIBRARIES_${TBB_BUILD_TYPE}}") endif() + + if(NOT MSVC AND NOT TBB_LIBRARIES) + set(TBB_LIBRARIES ${TBB_LIBRARIES_RELEASE}) + endif() if (MSVC AND TBB_STATIC) set(TBB_DEFINITIONS __TBB_NO_IMPLICIT_LINKAGE) diff --git a/src/libslic3r/Config.cpp b/src/libslic3r/Config.cpp index 63bd0c801e..9d24d8cb79 100644 --- a/src/libslic3r/Config.cpp +++ b/src/libslic3r/Config.cpp @@ -425,7 +425,30 @@ std::string ConfigBase::opt_serialize(const t_config_option_key &opt_key) const return opt->serialize(); } -bool ConfigBase::set_deserialize(const t_config_option_key &opt_key_src, const std::string &value_src, bool append) +void ConfigBase::set(const std::string &opt_key, int value, bool create) +{ + ConfigOption *opt = this->option_throw(opt_key, create); + switch (opt->type()) { + case coInt: static_cast(opt)->value = value; break; + case coFloat: static_cast(opt)->value = value; break; + case coFloatOrPercent: static_cast(opt)->value = value; static_cast(opt)->percent = false; break; + case coString: static_cast(opt)->value = std::to_string(value); break; + default: throw BadOptionTypeException("Configbase::set() - conversion from int not possible"); + } +} + +void ConfigBase::set(const std::string &opt_key, double value, bool create) +{ + ConfigOption *opt = this->option_throw(opt_key, create); + switch (opt->type()) { + case coFloat: static_cast(opt)->value = value; break; + case coFloatOrPercent: static_cast(opt)->value = value; static_cast(opt)->percent = false; break; + case coString: static_cast(opt)->value = std::to_string(value); break; + default: throw BadOptionTypeException("Configbase::set() - conversion from float not possible"); + } +} + +bool ConfigBase::set_deserialize_nothrow(const t_config_option_key &opt_key_src, const std::string &value_src, bool append) { t_config_option_key opt_key = opt_key_src; std::string value = value_src; @@ -438,6 +461,18 @@ bool ConfigBase::set_deserialize(const t_config_option_key &opt_key_src, const s return this->set_deserialize_raw(opt_key, value, append); } +void ConfigBase::set_deserialize(const t_config_option_key &opt_key_src, const std::string &value_src, bool append) +{ + if (! this->set_deserialize_nothrow(opt_key_src, value_src, append)) + throw BadOptionTypeException("ConfigBase::set_deserialize() failed"); +} + +void ConfigBase::set_deserialize(std::initializer_list items) +{ + for (const SetDeserializeItem &item : items) + this->set_deserialize(item.opt_key, item.opt_value, item.append); +} + bool ConfigBase::set_deserialize_raw(const t_config_option_key &opt_key_src, const std::string &value, bool append) { t_config_option_key opt_key = opt_key_src; @@ -668,6 +703,12 @@ void ConfigBase::null_nullables() } } +DynamicConfig::DynamicConfig(const ConfigBase& rhs, const t_config_option_keys& keys) +{ + for (const t_config_option_key& opt_key : keys) + this->options[opt_key] = std::unique_ptr(rhs.option(opt_key)->clone()); +} + bool DynamicConfig::operator==(const DynamicConfig &rhs) const { auto it1 = this->options.begin(); @@ -817,7 +858,7 @@ bool DynamicConfig::read_cli(int argc, char** argv, t_config_option_keys* extra, static_cast(opt_base)->value = value; } else { // Any scalar value of a type different from Bool and String. - if (! this->set_deserialize(opt_key, value, false)) { + if (! this->set_deserialize_nothrow(opt_key, value, false)) { boost::nowide::cerr << "Invalid value supplied for --" << token.c_str() << std::endl; return false; } diff --git a/src/libslic3r/Config.hpp b/src/libslic3r/Config.hpp index 463f6ef2d5..c49dd134ed 100644 --- a/src/libslic3r/Config.hpp +++ b/src/libslic3r/Config.hpp @@ -52,6 +52,16 @@ public: std::runtime_error(std::string("No definition exception: ") + opt_key) {} }; +/// Indicate that an unsupported accessor was called on a config option. +class BadOptionTypeException : public std::runtime_error +{ +public: + BadOptionTypeException() : + std::runtime_error("Bad option type exception") {} + BadOptionTypeException(const char* message) : + std::runtime_error(message) {} +}; + // Type of a configuration value. enum ConfigOptionType { coVectorType = 0x4000, @@ -117,10 +127,10 @@ public: virtual ConfigOption* clone() const = 0; // Set a value from a ConfigOption. The two options should be compatible. virtual void set(const ConfigOption *option) = 0; - virtual int getInt() const { throw std::runtime_error("Calling ConfigOption::getInt on a non-int ConfigOption"); } - virtual double getFloat() const { throw std::runtime_error("Calling ConfigOption::getFloat on a non-float ConfigOption"); } - virtual bool getBool() const { throw std::runtime_error("Calling ConfigOption::getBool on a non-boolean ConfigOption"); } - virtual void setInt(int /* val */) { throw std::runtime_error("Calling ConfigOption::setInt on a non-int ConfigOption"); } + virtual int getInt() const { throw BadOptionTypeException("Calling ConfigOption::getInt on a non-int ConfigOption"); } + virtual double getFloat() const { throw BadOptionTypeException("Calling ConfigOption::getFloat on a non-float ConfigOption"); } + virtual bool getBool() const { throw BadOptionTypeException("Calling ConfigOption::getBool on a non-boolean ConfigOption"); } + virtual void setInt(int /* val */) { throw BadOptionTypeException("Calling ConfigOption::setInt on a non-int ConfigOption"); } virtual bool operator==(const ConfigOption &rhs) const = 0; bool operator!=(const ConfigOption &rhs) const { return ! (*this == rhs); } bool is_scalar() const { return (int(this->type()) & int(coVectorType)) == 0; } @@ -1513,32 +1523,48 @@ protected: public: // Non-virtual methods: bool has(const t_config_option_key &opt_key) const { return this->option(opt_key) != nullptr; } + const ConfigOption* option(const t_config_option_key &opt_key) const { return const_cast(this)->option(opt_key, false); } + ConfigOption* option(const t_config_option_key &opt_key, bool create = false) { return this->optptr(opt_key, create); } + template TYPE* option(const t_config_option_key &opt_key, bool create = false) { ConfigOption *opt = this->optptr(opt_key, create); return (opt == nullptr || opt->type() != TYPE::static_type()) ? nullptr : static_cast(opt); } + template const TYPE* option(const t_config_option_key &opt_key) const { return const_cast(this)->option(opt_key, false); } - template - TYPE* option_throw(const t_config_option_key &opt_key, bool create = false) + + ConfigOption* option_throw(const t_config_option_key &opt_key, bool create = false) { ConfigOption *opt = this->optptr(opt_key, create); if (opt == nullptr) throw UnknownOptionException(opt_key); + return opt; + } + + const ConfigOption* option_throw(const t_config_option_key &opt_key) const + { return const_cast(this)->option_throw(opt_key, false); } + + template + TYPE* option_throw(const t_config_option_key &opt_key, bool create = false) + { + ConfigOption *opt = this->option_throw(opt_key, create); if (opt->type() != TYPE::static_type()) - throw std::runtime_error("Conversion to a wrong type"); + throw BadOptionTypeException("Conversion to a wrong type"); return static_cast(opt); } + template const TYPE* option_throw(const t_config_option_key &opt_key) const { return const_cast(this)->option_throw(opt_key, false); } + // Apply all keys of other ConfigBase defined by this->def() to this ConfigBase. // An UnknownOptionException is thrown in case some option keys of other are not defined by this->def(), // or this ConfigBase is of a StaticConfig type and it does not support some of the keys, and ignore_nonexistent is not set. @@ -1551,9 +1577,40 @@ public: t_config_option_keys diff(const ConfigBase &other) const; t_config_option_keys equal(const ConfigBase &other) const; std::string opt_serialize(const t_config_option_key &opt_key) const; + + // Set a value. Convert numeric types using a C style implicit conversion / promotion model. + // Throw if option is not avaiable and create is not enabled, + // or if the conversion is not possible. + // Conversion to string is always possible. + void set(const std::string &opt_key, bool value, bool create = false) + { this->option_throw(opt_key, create)->value = value; } + void set(const std::string &opt_key, int value, bool create = false); + void set(const std::string &opt_key, double value, bool create = false); + void set(const std::string &opt_key, const char *value, bool create = false) + { this->option_throw(opt_key, create)->value = value; } + void set(const std::string &opt_key, const std::string &value, bool create = false) + { this->option_throw(opt_key, create)->value = value; } + // Set a configuration value from a string, it will call an overridable handle_legacy() // to resolve renamed and removed configuration keys. - bool set_deserialize(const t_config_option_key &opt_key, const std::string &str, bool append = false); + bool set_deserialize_nothrow(const t_config_option_key &opt_key_src, const std::string &value_src, bool append = false); + // May throw BadOptionTypeException() if the operation fails. + void set_deserialize(const t_config_option_key &opt_key, const std::string &str, bool append = false); + struct SetDeserializeItem { + SetDeserializeItem(const char *opt_key, const char *opt_value, bool append = false) : opt_key(opt_key), opt_value(opt_value), append(append) {} + SetDeserializeItem(const std::string &opt_key, const std::string &opt_value, bool append = false) : opt_key(opt_key), opt_value(opt_value), append(append) {} + SetDeserializeItem(const char *opt_key, const bool value, bool append = false) : opt_key(opt_key), opt_value(value ? "1" : "0"), append(append) {} + SetDeserializeItem(const std::string &opt_key, const bool value, bool append = false) : opt_key(opt_key), opt_value(value ? "1" : "0"), append(append) {} + SetDeserializeItem(const char *opt_key, const int value, bool append = false) : opt_key(opt_key), opt_value(std::to_string(value)), append(append) {} + SetDeserializeItem(const std::string &opt_key, const int value, bool append = false) : opt_key(opt_key), opt_value(std::to_string(value)), append(append) {} + SetDeserializeItem(const char *opt_key, const float value, bool append = false) : opt_key(opt_key), opt_value(std::to_string(value)), append(append) {} + SetDeserializeItem(const std::string &opt_key, const float value, bool append = false) : opt_key(opt_key), opt_value(std::to_string(value)), append(append) {} + SetDeserializeItem(const char *opt_key, const double value, bool append = false) : opt_key(opt_key), opt_value(std::to_string(value)), append(append) {} + SetDeserializeItem(const std::string &opt_key, const double value, bool append = false) : opt_key(opt_key), opt_value(std::to_string(value)), append(append) {} + std::string opt_key; std::string opt_value; bool append = false; + }; + // May throw BadOptionTypeException() if the operation fails. + void set_deserialize(std::initializer_list items); double get_abs_value(const t_config_option_key &opt_key) const; double get_abs_value(const t_config_option_key &opt_key, double ratio_over) const; @@ -1580,9 +1637,11 @@ class DynamicConfig : public virtual ConfigBase { public: DynamicConfig() {} - DynamicConfig(const DynamicConfig& other) { *this = other; } - DynamicConfig(DynamicConfig&& other) : options(std::move(other.options)) { other.options.clear(); } - virtual ~DynamicConfig() override { clear(); } + DynamicConfig(const DynamicConfig &rhs) { *this = rhs; } + DynamicConfig(DynamicConfig &&rhs) : options(std::move(rhs.options)) { rhs.options.clear(); } + explicit DynamicConfig(const ConfigBase &rhs, const t_config_option_keys &keys); + explicit DynamicConfig(const ConfigBase& rhs) : DynamicConfig(rhs, rhs.keys()) {} + virtual ~DynamicConfig() override { clear(); } // Copy a content of one DynamicConfig to another DynamicConfig. // If rhs.def() is not null, then it has to be equal to this->def(). diff --git a/src/libslic3r/ExPolygon.hpp b/src/libslic3r/ExPolygon.hpp index a7ef2784c6..c510b848ff 100644 --- a/src/libslic3r/ExPolygon.hpp +++ b/src/libslic3r/ExPolygon.hpp @@ -18,15 +18,20 @@ class ExPolygon { public: ExPolygon() {} - ExPolygon(const ExPolygon &other) : contour(other.contour), holes(other.holes) {} + ExPolygon(const ExPolygon &other) : contour(other.contour), holes(other.holes) {} ExPolygon(ExPolygon &&other) : contour(std::move(other.contour)), holes(std::move(other.holes)) {} + explicit ExPolygon(const Polygon &contour) : contour(contour) {} + explicit ExPolygon(Polygon &&contour) : contour(std::move(contour)) {} + explicit ExPolygon(const Points &contour) : contour(contour) {} + explicit ExPolygon(Points &&contour) : contour(std::move(contour)) {} + explicit ExPolygon(const Polygon &contour, const Polygon &hole) : contour(contour) { holes.emplace_back(hole); } + explicit ExPolygon(Polygon &&contour, Polygon &&hole) : contour(std::move(contour)) { holes.emplace_back(std::move(hole)); } + explicit ExPolygon(const Points &contour, const Points &hole) : contour(contour) { holes.emplace_back(hole); } + explicit ExPolygon(Points &&contour, Polygon &&hole) : contour(std::move(contour)) { holes.emplace_back(std::move(hole)); } ExPolygon& operator=(const ExPolygon &other) { contour = other.contour; holes = other.holes; return *this; } ExPolygon& operator=(ExPolygon &&other) { contour = std::move(other.contour); holes = std::move(other.holes); return *this; } - inline explicit ExPolygon(const Polygon &p): contour(p) {} - inline explicit ExPolygon(Polygon &&p): contour(std::move(p)) {} - Polygon contour; Polygons holes; diff --git a/src/libslic3r/ExtrusionEntityCollection.cpp b/src/libslic3r/ExtrusionEntityCollection.cpp index 8c7e00e60b..e1a9709d1a 100644 --- a/src/libslic3r/ExtrusionEntityCollection.cpp +++ b/src/libslic3r/ExtrusionEntityCollection.cpp @@ -126,18 +126,26 @@ size_t ExtrusionEntityCollection::items_count() const } // Returns a single vector of pointers to all non-collection items contained in this one. -ExtrusionEntityCollection ExtrusionEntityCollection::flatten() const +ExtrusionEntityCollection ExtrusionEntityCollection::flatten(bool preserve_ordering) const { struct Flatten { + Flatten(bool preserve_ordering) : preserve_ordering(preserve_ordering) {} ExtrusionEntityCollection out; + bool preserve_ordering; void recursive_do(const ExtrusionEntityCollection &collection) { - for (const ExtrusionEntity* entity : collection.entities) - if (entity->is_collection()) - this->recursive_do(*static_cast(entity)); - else - out.append(*entity); + if (collection.no_sort && preserve_ordering) { + // Don't flatten whatever happens below this level. + out.append(collection); + } else { + for (const ExtrusionEntity *entity : collection.entities) + if (entity->is_collection()) + this->recursive_do(*static_cast(entity)); + else + out.append(*entity); + } } - } flatten; + } flatten(preserve_ordering); + flatten.recursive_do(*this); return flatten.out; } diff --git a/src/libslic3r/ExtrusionEntityCollection.hpp b/src/libslic3r/ExtrusionEntityCollection.hpp index 4e14917240..3084e5741a 100644 --- a/src/libslic3r/ExtrusionEntityCollection.hpp +++ b/src/libslic3r/ExtrusionEntityCollection.hpp @@ -15,17 +15,17 @@ public: ExtrusionEntitiesPtr entities; // we own these entities bool no_sort; - ExtrusionEntityCollection(): no_sort(false) {}; + ExtrusionEntityCollection(): no_sort(false) {} ExtrusionEntityCollection(const ExtrusionEntityCollection &other) : no_sort(other.no_sort) { this->append(other.entities); } ExtrusionEntityCollection(ExtrusionEntityCollection &&other) : entities(std::move(other.entities)), no_sort(other.no_sort) {} explicit ExtrusionEntityCollection(const ExtrusionPaths &paths); ExtrusionEntityCollection& operator=(const ExtrusionEntityCollection &other); - ExtrusionEntityCollection& operator=(ExtrusionEntityCollection &&other) + ExtrusionEntityCollection& operator=(ExtrusionEntityCollection &&other) { this->entities = std::move(other.entities); this->no_sort = other.no_sort; return *this; } ~ExtrusionEntityCollection() { clear(); } explicit operator ExtrusionPaths() const; - bool is_collection() const { return true; }; + bool is_collection() const { return true; } ExtrusionRole role() const override { ExtrusionRole out = erNone; for (const ExtrusionEntity *ee : entities) { @@ -34,8 +34,8 @@ public: } return out; } - bool can_reverse() const { return !this->no_sort; }; - bool empty() const { return this->entities.empty(); }; + bool can_reverse() const { return !this->no_sort; } + bool empty() const { return this->entities.empty(); } void clear(); void swap (ExtrusionEntityCollection &c); void append(const ExtrusionEntity &entity) { this->entities.emplace_back(entity.clone()); } @@ -81,7 +81,10 @@ public: Polygons polygons_covered_by_spacing(const float scaled_epsilon = 0.f) const { Polygons out; this->polygons_covered_by_spacing(out, scaled_epsilon); return out; } size_t items_count() const; - ExtrusionEntityCollection flatten() const; + /// Returns a flattened copy of this ExtrusionEntityCollection. That is, all of the items in its entities vector are not collections. + /// You should be iterating over flatten().entities if you are interested in the underlying ExtrusionEntities (and don't care about hierarchy). + /// \param preserve_ordering Flag to method that will flatten if and only if the underlying collection is sortable when True (default: False). + ExtrusionEntityCollection flatten(bool preserve_ordering = false) const; double min_mm3_per_mm() const; double total_volume() const override { double volume=0.; for (const auto& ent : entities) volume+=ent->total_volume(); return volume; } diff --git a/src/libslic3r/Fill/Fill.hpp b/src/libslic3r/Fill/Fill.hpp index c04305c042..9e35450849 100644 --- a/src/libslic3r/Fill/Fill.hpp +++ b/src/libslic3r/Fill/Fill.hpp @@ -29,8 +29,6 @@ public: FillParams params; }; -void make_fill(LayerRegion &layerm, ExtrusionEntityCollection &out); - } // namespace Slic3r #endif // slic3r_Fill_hpp_ diff --git a/src/libslic3r/Fill/FillBase.hpp b/src/libslic3r/Fill/FillBase.hpp index fb79478930..3b834dede3 100644 --- a/src/libslic3r/Fill/FillBase.hpp +++ b/src/libslic3r/Fill/FillBase.hpp @@ -15,6 +15,7 @@ namespace Slic3r { +class ExPolygon; class Surface; struct FillParams diff --git a/src/libslic3r/GCode/Analyzer.cpp b/src/libslic3r/GCode/Analyzer.cpp index 136959d712..78f6c68068 100644 --- a/src/libslic3r/GCode/Analyzer.cpp +++ b/src/libslic3r/GCode/Analyzer.cpp @@ -141,6 +141,7 @@ void GCodeAnalyzer::reset() _set_start_extrusion(DEFAULT_START_EXTRUSION); _set_fan_speed(DEFAULT_FAN_SPEED); _reset_axes_position(); + _reset_axes_origin(); _reset_cached_position(); m_moves_map.clear(); @@ -310,31 +311,32 @@ void GCodeAnalyzer::_process_gcode_line(GCodeReader&, const GCodeReader::GCodeLi m_process_output += line.raw() + "\n"; } -// Returns the new absolute position on the given axis in dependence of the given parameters -float axis_absolute_position_from_G1_line(GCodeAnalyzer::EAxis axis, const GCodeReader::GCodeLine& lineG1, GCodeAnalyzer::EUnits units, bool is_relative, float current_absolute_position) -{ - float lengthsScaleFactor = (units == GCodeAnalyzer::Inches) ? INCHES_TO_MM : 1.0f; - if (lineG1.has(Slic3r::Axis(axis))) - { - float ret = lineG1.value(Slic3r::Axis(axis)) * lengthsScaleFactor; - return is_relative ? current_absolute_position + ret : ret; - } - else - return current_absolute_position; -} - void GCodeAnalyzer::_processG1(const GCodeReader::GCodeLine& line) { + auto axis_absolute_position = [this](GCodeAnalyzer::EAxis axis, const GCodeReader::GCodeLine& lineG1) -> float + { + float current_absolute_position = _get_axis_position(axis); + float current_origin = _get_axis_origin(axis); + float lengthsScaleFactor = (_get_units() == GCodeAnalyzer::Inches) ? INCHES_TO_MM : 1.0f; + + bool is_relative = (_get_global_positioning_type() == Relative); + if (axis == E) + is_relative |= (_get_e_local_positioning_type() == Relative); + + if (lineG1.has(Slic3r::Axis(axis))) + { + float ret = lineG1.value(Slic3r::Axis(axis)) * lengthsScaleFactor; + return is_relative ? current_absolute_position + ret : ret + current_origin; + } + else + return current_absolute_position; + }; + // updates axes positions from line - EUnits units = _get_units(); float new_pos[Num_Axis]; for (unsigned char a = X; a < Num_Axis; ++a) { - bool is_relative = (_get_global_positioning_type() == Relative); - if (a == E) - is_relative |= (_get_e_local_positioning_type() == Relative); - - new_pos[a] = axis_absolute_position_from_G1_line((EAxis)a, line, units, is_relative, _get_axis_position((EAxis)a)); + new_pos[a] = axis_absolute_position((EAxis)a, line); } // updates feedrate from line, if present @@ -424,25 +426,25 @@ void GCodeAnalyzer::_processG92(const GCodeReader::GCodeLine& line) if (line.has_x()) { - _set_axis_position(X, line.x() * lengthsScaleFactor); + _set_axis_origin(X, _get_axis_position(X) - line.x() * lengthsScaleFactor); anyFound = true; } if (line.has_y()) { - _set_axis_position(Y, line.y() * lengthsScaleFactor); + _set_axis_origin(Y, _get_axis_position(Y) - line.y() * lengthsScaleFactor); anyFound = true; } if (line.has_z()) { - _set_axis_position(Z, line.z() * lengthsScaleFactor); + _set_axis_origin(Z, _get_axis_position(Z) - line.z() * lengthsScaleFactor); anyFound = true; } if (line.has_e()) { - _set_axis_position(E, line.e() * lengthsScaleFactor); + _set_axis_origin(E, _get_axis_position(E) - line.e() * lengthsScaleFactor); anyFound = true; } @@ -450,7 +452,7 @@ void GCodeAnalyzer::_processG92(const GCodeReader::GCodeLine& line) { for (unsigned char a = X; a < Num_Axis; ++a) { - _set_axis_position((EAxis)a, 0.0f); + _set_axis_origin((EAxis)a, _get_axis_position((EAxis)a)); } } } @@ -781,11 +783,26 @@ float GCodeAnalyzer::_get_axis_position(EAxis axis) const return m_state.position[axis]; } +void GCodeAnalyzer::_set_axis_origin(EAxis axis, float position) +{ + m_state.origin[axis] = position; +} + +float GCodeAnalyzer::_get_axis_origin(EAxis axis) const +{ + return m_state.origin[axis]; +} + void GCodeAnalyzer::_reset_axes_position() { ::memset((void*)m_state.position, 0, Num_Axis * sizeof(float)); } +void GCodeAnalyzer::_reset_axes_origin() +{ + ::memset((void*)m_state.origin, 0, Num_Axis * sizeof(float)); +} + void GCodeAnalyzer::_set_start_position(const Vec3d& position) { m_state.start_position = position; diff --git a/src/libslic3r/GCode/Analyzer.hpp b/src/libslic3r/GCode/Analyzer.hpp index 529610b0b2..e90175c49f 100644 --- a/src/libslic3r/GCode/Analyzer.hpp +++ b/src/libslic3r/GCode/Analyzer.hpp @@ -101,6 +101,7 @@ private: float cached_position[5]; float start_extrusion; float position[Num_Axis]; + float origin[Num_Axis]; unsigned int cur_cp_color_id = 0; }; @@ -246,8 +247,13 @@ private: void _set_axis_position(EAxis axis, float position); float _get_axis_position(EAxis axis) const; + void _set_axis_origin(EAxis axis, float position); + float _get_axis_origin(EAxis axis) const; + // Sets axes position to zero void _reset_axes_position(); + // Sets origin position to zero + void _reset_axes_origin(); void _set_start_position(const Vec3d& position); const Vec3d& _get_start_position() const; diff --git a/src/libslic3r/GCodeTimeEstimator.cpp b/src/libslic3r/GCodeTimeEstimator.cpp index 4693ba9e62..c624c0fce8 100644 --- a/src/libslic3r/GCodeTimeEstimator.cpp +++ b/src/libslic3r/GCodeTimeEstimator.cpp @@ -318,12 +318,15 @@ namespace Slic3r { assert((g1_line_id >= (int)data->g1_line_ids.size()) || (data->g1_line_ids[g1_line_id].first >= g1_lines_count)); const Block* block = nullptr; - const G1LineIdToBlockId& map_item = data->g1_line_ids[g1_line_id]; - if ((g1_line_id < (int)data->g1_line_ids.size()) && (map_item.first == g1_lines_count)) + if (g1_line_id < (int)data->g1_line_ids.size()) { - if (line.has_e() && (map_item.second < (unsigned int)data->blocks.size())) - block = &data->blocks[map_item.second]; - ++g1_line_id; + const G1LineIdToBlockId& map_item = data->g1_line_ids[g1_line_id]; + if (map_item.first == g1_lines_count) + { + if (line.has_e() && (map_item.second < (unsigned int)data->blocks.size())) + block = &data->blocks[map_item.second]; + ++g1_line_id; + } } if ((block != nullptr) && (block->elapsed_time != -1.0f)) @@ -412,6 +415,11 @@ namespace Slic3r { m_state.axis[axis].position = position; } + void GCodeTimeEstimator::set_axis_origin(EAxis axis, float position) + { + m_state.axis[axis].origin = position; + } + void GCodeTimeEstimator::set_axis_max_feedrate(EAxis axis, float feedrate_mm_sec) { m_state.axis[axis].max_feedrate = feedrate_mm_sec; @@ -432,6 +440,11 @@ namespace Slic3r { return m_state.axis[axis].position; } + float GCodeTimeEstimator::get_axis_origin(EAxis axis) const + { + return m_state.axis[axis].origin; + } + float GCodeTimeEstimator::get_axis_max_feedrate(EAxis axis) const { return m_state.axis[axis].max_feedrate; @@ -758,6 +771,10 @@ namespace Slic3r { set_axis_position(X, 0.0f); set_axis_position(Y, 0.0f); set_axis_position(Z, 0.0f); + set_axis_origin(X, 0.0f); + set_axis_origin(Y, 0.0f); + set_axis_origin(Z, 0.0f); + if (get_e_local_positioning_type() == Absolute) set_axis_position(E, 0.0f); @@ -954,34 +971,35 @@ namespace Slic3r { } } - // Returns the new absolute position on the given axis in dependence of the given parameters - float axis_absolute_position_from_G1_line(GCodeTimeEstimator::EAxis axis, const GCodeReader::GCodeLine& lineG1, GCodeTimeEstimator::EUnits units, bool is_relative, float current_absolute_position) - { - float lengthsScaleFactor = (units == GCodeTimeEstimator::Inches) ? INCHES_TO_MM : 1.0f; - if (lineG1.has(Slic3r::Axis(axis))) - { - float ret = lineG1.value(Slic3r::Axis(axis)) * lengthsScaleFactor; - return is_relative ? current_absolute_position + ret : ret; - } - else - return current_absolute_position; - } - void GCodeTimeEstimator::_processG1(const GCodeReader::GCodeLine& line) { + auto axis_absolute_position = [this](GCodeTimeEstimator::EAxis axis, const GCodeReader::GCodeLine& lineG1) -> float + { + float current_absolute_position = get_axis_position(axis); + float current_origin = get_axis_origin(axis); + float lengthsScaleFactor = (get_units() == GCodeTimeEstimator::Inches) ? INCHES_TO_MM : 1.0f; + + bool is_relative = (get_global_positioning_type() == Relative); + if (axis == E) + is_relative |= (get_e_local_positioning_type() == Relative); + + if (lineG1.has(Slic3r::Axis(axis))) + { + float ret = lineG1.value(Slic3r::Axis(axis)) * lengthsScaleFactor; + return is_relative ? current_absolute_position + ret : ret + current_origin; + } + else + return current_absolute_position; + }; + PROFILE_FUNC(); increment_g1_line_id(); // updates axes positions from line - EUnits units = get_units(); float new_pos[Num_Axis]; for (unsigned char a = X; a < Num_Axis; ++a) { - bool is_relative = (get_global_positioning_type() == Relative); - if (a == E) - is_relative |= (get_e_local_positioning_type() == Relative); - - new_pos[a] = axis_absolute_position_from_G1_line((EAxis)a, line, units, is_relative, get_axis_position((EAxis)a)); + new_pos[a] = axis_absolute_position((EAxis)a, line); } // updates feedrate from line, if present @@ -1225,25 +1243,25 @@ namespace Slic3r { if (line.has_x()) { - set_axis_position(X, line.x() * lengthsScaleFactor); + set_axis_origin(X, get_axis_position(X) - line.x() * lengthsScaleFactor); anyFound = true; } if (line.has_y()) { - set_axis_position(Y, line.y() * lengthsScaleFactor); + set_axis_origin(Y, get_axis_position(Y) - line.y() * lengthsScaleFactor); anyFound = true; } if (line.has_z()) { - set_axis_position(Z, line.z() * lengthsScaleFactor); + set_axis_origin(Z, get_axis_position(Z) - line.z() * lengthsScaleFactor); anyFound = true; } if (line.has_e()) { - set_axis_position(E, line.e() * lengthsScaleFactor); + set_axis_origin(E, get_axis_position(E) - line.e() * lengthsScaleFactor); anyFound = true; } else @@ -1253,7 +1271,7 @@ namespace Slic3r { { for (unsigned char a = X; a < Num_Axis; ++a) { - set_axis_position((EAxis)a, 0.0f); + set_axis_origin((EAxis)a, get_axis_position((EAxis)a)); } } } diff --git a/src/libslic3r/GCodeTimeEstimator.hpp b/src/libslic3r/GCodeTimeEstimator.hpp index d9f3bc2113..0219c87d1e 100644 --- a/src/libslic3r/GCodeTimeEstimator.hpp +++ b/src/libslic3r/GCodeTimeEstimator.hpp @@ -55,6 +55,7 @@ namespace Slic3r { struct Axis { float position; // mm + float origin; // mm float max_feedrate; // mm/s float max_acceleration; // mm/s^2 float max_jerk; // mm/s @@ -282,6 +283,8 @@ namespace Slic3r { // Set current position on the given axis with the given value void set_axis_position(EAxis axis, float position); + // Set current origin on the given axis with the given value + void set_axis_origin(EAxis axis, float position); void set_axis_max_feedrate(EAxis axis, float feedrate_mm_sec); void set_axis_max_acceleration(EAxis axis, float acceleration); @@ -289,6 +292,8 @@ namespace Slic3r { // Returns current position on the given axis float get_axis_position(EAxis axis) const; + // Returns current origin on the given axis + float get_axis_origin(EAxis axis) const; float get_axis_max_feedrate(EAxis axis) const; float get_axis_max_acceleration(EAxis axis) const; diff --git a/src/libslic3r/LayerRegion.cpp b/src/libslic3r/LayerRegion.cpp index 0ff59d35fc..658bcf7094 100644 --- a/src/libslic3r/LayerRegion.cpp +++ b/src/libslic3r/LayerRegion.cpp @@ -70,7 +70,7 @@ void LayerRegion::make_perimeters(const SurfaceCollection &slices, SurfaceCollec fill_surfaces ); - if (this->layer()->lower_layer != NULL) + if (this->layer()->lower_layer != nullptr) // Cummulative sum of polygons over all the regions. g.lower_slices = &this->layer()->lower_layer->slices; @@ -130,7 +130,7 @@ void LayerRegion::process_external_surfaces(const Layer *lower_layer, const Poly bridges.emplace_back(surface); } if (surface.is_internal()) { - assert(surface.surface_type == stInternal); + assert(surface.surface_type == stInternal || surface.surface_type == stInternalSolid); if (! has_infill && lower_layer != nullptr) polygons_append(voids, surface.expolygon); internal.emplace_back(std::move(surface)); diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index c5fd80b55c..33105bff30 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -433,6 +433,7 @@ void PrintConfigDef::init_fff_params() "If left zero, default extrusion width will be used if set, otherwise 1.125 x nozzle diameter will be used. " "If expressed as percentage (for example 200%), it will be computed over layer height."); def->sidetext = L("mm or %"); + def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloatOrPercent(0, false)); @@ -541,6 +542,7 @@ void PrintConfigDef::init_fff_params() "(see the tooltips for perimeter extrusion width, infill extrusion width etc). " "If expressed as percentage (for example: 230%), it will be computed over layer height."); def->sidetext = L("mm or %"); + def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloatOrPercent(0, false)); @@ -863,6 +865,7 @@ void PrintConfigDef::init_fff_params() "If set to zero, it will use the default extrusion width."); def->sidetext = L("mm or %"); def->ratio_over = "first_layer_height"; + def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloatOrPercent(200, true)); @@ -994,6 +997,7 @@ void PrintConfigDef::init_fff_params() "You may want to use fatter extrudates to speed up the infill and make your parts stronger. " "If expressed as percentage (for example 90%) it will be computed over layer height."); def->sidetext = L("mm or %"); + def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloatOrPercent(0, false)); @@ -1406,6 +1410,7 @@ void PrintConfigDef::init_fff_params() "If expressed as percentage (for example 200%) it will be computed over layer height."); def->sidetext = L("mm or %"); def->aliases = { "perimeters_extrusion_width" }; + def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloatOrPercent(0, false)); @@ -1743,6 +1748,7 @@ void PrintConfigDef::init_fff_params() "If left zero, default extrusion width will be used if set, otherwise 1.125 x nozzle diameter will be used. " "If expressed as percentage (for example 90%) it will be computed over layer height."); def->sidetext = L("mm or %"); + def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloatOrPercent(0, false)); @@ -1917,6 +1923,7 @@ void PrintConfigDef::init_fff_params() "If left zero, default extrusion width will be used if set, otherwise nozzle diameter will be used. " "If expressed as percentage (for example 90%) it will be computed over layer height."); def->sidetext = L("mm or %"); + def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloatOrPercent(0, false)); @@ -2076,6 +2083,7 @@ void PrintConfigDef::init_fff_params() "If left zero, default extrusion width will be used if set, otherwise nozzle diameter will be used. " "If expressed as percentage (for example 90%) it will be computed over layer height."); def->sidetext = L("mm or %"); + def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloatOrPercent(0, false)); @@ -2898,9 +2906,13 @@ void PrintConfigDef::handle_legacy(t_config_option_key &opt_key, std::string &va const PrintConfigDef print_config_def; -DynamicPrintConfig* DynamicPrintConfig::new_from_defaults() +DynamicPrintConfig DynamicPrintConfig::full_print_config() +{ + return DynamicPrintConfig((const PrintRegionConfig&)FullPrintConfig::defaults()); +} + +DynamicPrintConfig::DynamicPrintConfig(const StaticPrintConfig& rhs) : DynamicConfig(rhs, rhs.keys_ref()) { - return new_from_defaults_keys(FullPrintConfig::defaults().keys()); } DynamicPrintConfig* DynamicPrintConfig::new_from_defaults_keys(const std::vector &keys) diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index ce051b05be..5c287ba93e 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -214,6 +214,8 @@ private: // This definition is constant. extern const PrintConfigDef print_config_def; +class StaticPrintConfig; + // Slic3r dynamic configuration, used to override the configuration // per object, per modification volume or per printing material. // The dynamic configuration is also used to store user modifications of the print global parameters, @@ -224,9 +226,11 @@ class DynamicPrintConfig : public DynamicConfig { public: DynamicPrintConfig() {} - DynamicPrintConfig(const DynamicPrintConfig &other) : DynamicConfig(other) {} + DynamicPrintConfig(const DynamicPrintConfig &rhs) : DynamicConfig(rhs) {} + explicit DynamicPrintConfig(const StaticPrintConfig &rhs); + explicit DynamicPrintConfig(const ConfigBase &rhs) : DynamicConfig(rhs) {} - static DynamicPrintConfig* new_from_defaults(); + static DynamicPrintConfig full_print_config(); static DynamicPrintConfig* new_from_defaults_keys(const std::vector &keys); // Overrides ConfigBase::def(). Static configuration definition. Any value stored into this ConfigBase shall have its definition here. @@ -262,6 +266,8 @@ public: // Overrides ConfigBase::def(). Static configuration definition. Any value stored into this ConfigBase shall have its definition here. const ConfigDef* def() const override { return &print_config_def; } + // Reference to the cached list of keys. + virtual const t_config_option_keys& keys_ref() const = 0; protected: // Verify whether the opt_key has not been obsoleted or renamed. @@ -350,6 +356,7 @@ public: \ { return s_cache_##CLASS_NAME.optptr(opt_key, this); } \ /* Overrides ConfigBase::keys(). Collect names of all configuration values maintained by this configuration store. */ \ t_config_option_keys keys() const override { return s_cache_##CLASS_NAME.keys(); } \ + const t_config_option_keys& keys_ref() const override { return s_cache_##CLASS_NAME.keys(); } \ static const CLASS_NAME& defaults() { initialize_cache(); return s_cache_##CLASS_NAME.defaults(); } \ private: \ static void initialize_cache() \ diff --git a/tests/data/test_3mf/Geräte/Büchse.3mf b/tests/data/test_3mf/Geräte/Büchse.3mf new file mode 100644 index 0000000000..3b5a8350d4 Binary files /dev/null and b/tests/data/test_3mf/Geräte/Büchse.3mf differ diff --git a/tests/data/test_config/new_from_ini.ini b/tests/data/test_config/new_from_ini.ini new file mode 100644 index 0000000000..33d65f5902 --- /dev/null +++ b/tests/data/test_config/new_from_ini.ini @@ -0,0 +1 @@ +filament_colour = #ABCD diff --git a/tests/fff_print/CMakeLists.txt b/tests/fff_print/CMakeLists.txt index 1ba953b8bb..703d5b3cf4 100644 --- a/tests/fff_print/CMakeLists.txt +++ b/tests/fff_print/CMakeLists.txt @@ -3,9 +3,16 @@ add_executable(${_TEST_NAME}_tests ${_TEST_NAME}_tests.cpp test_data.cpp test_data.hpp + test_extrusion_entity.cpp + test_fill.cpp test_flow.cpp test_gcodewriter.cpp + test_model.cpp + test_print.cpp + test_printgcode.cpp + test_printobject.cpp test_skirt_brim.cpp + test_support_material.cpp test_trianglemesh.cpp ) target_link_libraries(${_TEST_NAME}_tests test_common libslic3r) diff --git a/tests/fff_print/test_data.cpp b/tests/fff_print/test_data.cpp index a02b7d1bb3..b3c16f4b01 100644 --- a/tests/fff_print/test_data.cpp +++ b/tests/fff_print/test_data.cpp @@ -4,6 +4,8 @@ #include "libslic3r/GCodeReader.hpp" #include "libslic3r/Config.hpp" #include "libslic3r/Print.hpp" +#include "libslic3r/Format/OBJ.hpp" +#include "libslic3r/Format/STL.hpp" #include #include @@ -17,190 +19,129 @@ namespace Slic3r { namespace Test { // Mesh enumeration to name mapping const std::unordered_map mesh_names { - std::pair(TestMesh::A,"A"), - std::pair(TestMesh::L,"L"), - std::pair(TestMesh::V,"V"), - std::pair(TestMesh::_40x10,"40x10"), - std::pair(TestMesh::cube_20x20x20,"cube_20x20x20"), - std::pair(TestMesh::sphere_50mm,"sphere_50mm"), - std::pair(TestMesh::bridge,"bridge"), - std::pair(TestMesh::bridge_with_hole,"bridge_with_hole"), - std::pair(TestMesh::cube_with_concave_hole,"cube_with_concave_hole"), - std::pair(TestMesh::cube_with_hole,"cube_with_hole"), - std::pair(TestMesh::gt2_teeth,"gt2_teeth"), - std::pair(TestMesh::ipadstand,"ipadstand"), - std::pair(TestMesh::overhang,"overhang"), - std::pair(TestMesh::pyramid,"pyramid"), - std::pair(TestMesh::sloping_hole,"sloping_hole"), - std::pair(TestMesh::slopy_cube,"slopy_cube"), - std::pair(TestMesh::small_dorito,"small_dorito"), - std::pair(TestMesh::step,"step"), - std::pair(TestMesh::two_hollow_squares,"two_hollow_squares") + std::pair(TestMesh::A, "A"), + std::pair(TestMesh::L, "L"), + std::pair(TestMesh::V, "V"), + std::pair(TestMesh::_40x10, "40x10"), + std::pair(TestMesh::cube_20x20x20, "cube_20x20x20"), + std::pair(TestMesh::sphere_50mm, "sphere_50mm"), + std::pair(TestMesh::bridge, "bridge"), + std::pair(TestMesh::bridge_with_hole, "bridge_with_hole"), + std::pair(TestMesh::cube_with_concave_hole, "cube_with_concave_hole"), + std::pair(TestMesh::cube_with_hole, "cube_with_hole"), + std::pair(TestMesh::gt2_teeth, "gt2_teeth"), + std::pair(TestMesh::ipadstand, "ipadstand"), + std::pair(TestMesh::overhang, "overhang"), + std::pair(TestMesh::pyramid, "pyramid"), + std::pair(TestMesh::sloping_hole, "sloping_hole"), + std::pair(TestMesh::slopy_cube, "slopy_cube"), + std::pair(TestMesh::small_dorito, "small_dorito"), + std::pair(TestMesh::step, "step"), + std::pair(TestMesh::two_hollow_squares, "two_hollow_squares") }; TriangleMesh mesh(TestMesh m) { - std::vector facets; - std::vector vertices; + TriangleMesh mesh; switch(m) { + case TestMesh::cube_20x20x20: + mesh = Slic3r::make_cube(20, 20, 20); + break; + case TestMesh::sphere_50mm: + mesh = Slic3r::make_sphere(50, PI / 243.0); + break; 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) }; - facets = std::vector({ - Vec3crd(0,1,2), Vec3crd(2,1,3), Vec3crd(1,0,4), Vec3crd(5,1,4), Vec3crd(6,7,4), Vec3crd(8,2,9), Vec3crd(0,2,8), Vec3crd(10,8,9), Vec3crd(0,8,6), Vec3crd(0,6,4), Vec3crd(4,7,9), Vec3crd(7,10,9), Vec3crd(2,3,9), Vec3crd(9,3,11), Vec3crd(12,1,5), Vec3crd(13,3,12), Vec3crd(14,12,5), Vec3crd(3,1,12), Vec3crd(11,3,13), Vec3crd(11,15,5), Vec3crd(11,13,15), Vec3crd(15,14,5), Vec3crd(5,4,9), Vec3crd(11,5,9), Vec3crd(8,13,12), Vec3crd(6,8,12), Vec3crd(10,15,13), Vec3crd(8,10,13), Vec3crd(15,10,14), Vec3crd(14,10,7), Vec3crd(14,7,12), Vec3crd(12,7,6) - }); + mesh = TriangleMesh( + { 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) }, + { Vec3crd(0,1,2), Vec3crd(2,1,3), Vec3crd(1,0,4), Vec3crd(5,1,4), Vec3crd(6,7,4), Vec3crd(8,2,9), Vec3crd(0,2,8), Vec3crd(10,8,9), Vec3crd(0,8,6), Vec3crd(0,6,4), Vec3crd(4,7,9), Vec3crd(7,10,9), Vec3crd(2,3,9), Vec3crd(9,3,11), Vec3crd(12,1,5), Vec3crd(13,3,12), Vec3crd(14,12,5), Vec3crd(3,1,12), Vec3crd(11,3,13), Vec3crd(11,15,5), Vec3crd(11,13,15), Vec3crd(15,14,5), Vec3crd(5,4,9), Vec3crd(11,5,9), Vec3crd(8,13,12), Vec3crd(6,8,12), Vec3crd(10,15,13), Vec3crd(8,10,13), Vec3crd(15,10,14), Vec3crd(14,10,7), Vec3crd(14,7,12), Vec3crd(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) - }); - facets = std::vector({ - Vec3crd(0,1,2), Vec3crd(2,1,3), Vec3crd(1,0,4), Vec3crd(5,1,4), Vec3crd(6,7,4), Vec3crd(8,2,9), Vec3crd(10,2,11), Vec3crd(11,12,13), Vec3crd(0,2,10), Vec3crd(0,10,6), Vec3crd(0,6,4), Vec3crd(11,2,8), Vec3crd(4,7,12), Vec3crd(4,12,8), Vec3crd(12,11,8), Vec3crd(14,4,8), Vec3crd(2,3,9), Vec3crd(9,3,15), Vec3crd(16,1,5), Vec3crd(17,18,5), Vec3crd(19,3,16), Vec3crd(20,21,5), Vec3crd(18,16,5), Vec3crd(3,1,16), Vec3crd(22,3,19), Vec3crd(21,3,22), Vec3crd(21,17,5), Vec3crd(21,22,17), Vec3crd(21,15,3), Vec3crd(23,17,22), Vec3crd(5,4,14), Vec3crd(20,5,14), Vec3crd(20,14,21), Vec3crd(21,14,8), Vec3crd(9,15,21), Vec3crd(8,9,21), Vec3crd(10,19,16), Vec3crd(6,10,16), Vec3crd(11,22,19), Vec3crd(10,11,19), Vec3crd(13,23,11), Vec3crd(11,23,22), Vec3crd(23,13,12), Vec3crd(17,23,12), Vec3crd(17,12,18), Vec3crd(18,12,7), Vec3crd(18,7,16), Vec3crd(16,7,6) - }); + mesh = TriangleMesh( + { 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) }, + { Vec3crd(0,1,2), Vec3crd(2,1,3), Vec3crd(1,0,4), Vec3crd(5,1,4), Vec3crd(6,7,4), Vec3crd(8,2,9), Vec3crd(10,2,11), Vec3crd(11,12,13), Vec3crd(0,2,10), Vec3crd(0,10,6), Vec3crd(0,6,4), Vec3crd(11,2,8), Vec3crd(4,7,12), Vec3crd(4,12,8), Vec3crd(12,11,8), Vec3crd(14,4,8), Vec3crd(2,3,9), Vec3crd(9,3,15), Vec3crd(16,1,5), Vec3crd(17,18,5), Vec3crd(19,3,16), Vec3crd(20,21,5), Vec3crd(18,16,5), Vec3crd(3,1,16), Vec3crd(22,3,19), Vec3crd(21,3,22), Vec3crd(21,17,5), Vec3crd(21,22,17), Vec3crd(21,15,3), Vec3crd(23,17,22), Vec3crd(5,4,14), Vec3crd(20,5,14), Vec3crd(20,14,21), Vec3crd(21,14,8), Vec3crd(9,15,21), Vec3crd(8,9,21), Vec3crd(10,19,16), Vec3crd(6,10,16), Vec3crd(11,22,19), Vec3crd(10,11,19), Vec3crd(13,23,11), Vec3crd(11,23,22), Vec3crd(23,13,12), Vec3crd(17,23,12), Vec3crd(17,12,18), Vec3crd(18,12,7), Vec3crd(18,7,16), Vec3crd(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) - }); - facets = std::vector({ - Vec3crd(0,1,2), Vec3crd(2,1,3), Vec3crd(1,0,4), Vec3crd(5,1,4), Vec3crd(4,0,2), Vec3crd(6,4,2), Vec3crd(7,6,2), Vec3crd(8,9,7), Vec3crd(9,6,7), Vec3crd(2,3,7), Vec3crd(7,3,10), Vec3crd(1,5,3), Vec3crd(3,5,11), Vec3crd(11,12,13), Vec3crd(11,13,3), Vec3crd(3,13,10), Vec3crd(5,4,6), Vec3crd(11,5,6), Vec3crd(6,9,11), Vec3crd(11,9,12), Vec3crd(12,9,8), Vec3crd(13,12,8), Vec3crd(8,7,10), Vec3crd(13,8,10) - }); + mesh = TriangleMesh( + { 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) }, + { Vec3crd(0,1,2), Vec3crd(2,1,3), Vec3crd(1,0,4), Vec3crd(5,1,4), Vec3crd(4,0,2), Vec3crd(6,4,2), Vec3crd(7,6,2), Vec3crd(8,9,7), Vec3crd(9,6,7), Vec3crd(2,3,7), Vec3crd(7,3,10), Vec3crd(1,5,3), Vec3crd(3,5,11), Vec3crd(11,12,13), Vec3crd(11,13,3), Vec3crd(3,13,10), Vec3crd(5,4,6), Vec3crd(11,5,6), Vec3crd(6,9,11), Vec3crd(11,9,12), Vec3crd(12,9,8), Vec3crd(13,12,8), Vec3crd(8,7,10), Vec3crd(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) - }); - facets = std::vector({ - Vec3crd(0,1,2), Vec3crd(2,1,3), Vec3crd(4,5,1), Vec3crd(0,4,1), Vec3crd(0,2,4), Vec3crd(4,2,6), Vec3crd(4,6,7), Vec3crd(4,7,8), Vec3crd(2,3,6), Vec3crd(6,3,9), Vec3crd(3,1,5), Vec3crd(9,3,5), Vec3crd(10,11,5), Vec3crd(11,9,5), Vec3crd(5,4,10), Vec3crd(10,4,8), Vec3crd(10,8,7), Vec3crd(11,10,7), Vec3crd(11,7,6), Vec3crd(9,11,6) - }); + mesh = TriangleMesh( + { 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) }, + { Vec3crd(0,1,2), Vec3crd(2,1,3), Vec3crd(4,5,1), Vec3crd(0,4,1), Vec3crd(0,2,4), Vec3crd(4,2,6), Vec3crd(4,6,7), Vec3crd(4,7,8), Vec3crd(2,3,6), Vec3crd(6,3,9), Vec3crd(3,1,5), Vec3crd(9,3,5), Vec3crd(10,11,5), Vec3crd(11,9,5), Vec3crd(5,4,10), Vec3crd(10,4,8), Vec3crd(10,8,7), Vec3crd(11,10,7), Vec3crd(11,7,6), Vec3crd(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) - }); - facets = std::vector({ - Vec3crd(0,1,2), Vec3crd(2,3,4), Vec3crd(2,5,0), Vec3crd(4,6,2), Vec3crd(2,6,5), Vec3crd(2,1,3), Vec3crd(7,8,9), Vec3crd(10,9,8), Vec3crd(11,9,10), Vec3crd(12,9,11), Vec3crd(9,13,14), Vec3crd(7,15,16), Vec3crd(10,17,0), Vec3crd(10,0,5), Vec3crd(12,11,6), Vec3crd(18,16,0), Vec3crd(6,19,13), Vec3crd(6,13,9), Vec3crd(9,12,6), Vec3crd(17,18,0), Vec3crd(11,10,5), Vec3crd(11,5,6), Vec3crd(14,16,15), Vec3crd(17,7,18), Vec3crd(16,18,7), Vec3crd(14,15,9), Vec3crd(7,9,15), Vec3crd(7,17,8), Vec3crd(10,8,17), Vec3crd(20,21,22), Vec3crd(23,24,25), Vec3crd(26,23,27), Vec3crd(28,27,23), Vec3crd(29,28,23), Vec3crd(30,29,23), Vec3crd(25,31,32), Vec3crd(22,33,34), Vec3crd(35,36,37), Vec3crd(24,38,39), Vec3crd(21,40,41), Vec3crd(38,42,20), Vec3crd(33,43,44), Vec3crd(6,4,23), Vec3crd(6,23,25), Vec3crd(36,35,1), Vec3crd(1,0,38), Vec3crd(1,38,36), Vec3crd(29,30,4), Vec3crd(25,32,6), Vec3crd(40,42,0), Vec3crd(35,45,1), Vec3crd(4,3,28), Vec3crd(4,28,29), Vec3crd(3,1,45), Vec3crd(3,45,28), Vec3crd(22,34,19), Vec3crd(19,6,32), Vec3crd(19,32,22), Vec3crd(42,38,0), Vec3crd(30,23,4), Vec3crd(0,16,43), Vec3crd(0,43,40), Vec3crd(24,37,36), Vec3crd(38,24,36), Vec3crd(24,23,37), Vec3crd(37,23,26), Vec3crd(22,32,20), Vec3crd(20,32,31), Vec3crd(33,41,40), Vec3crd(43,33,40), Vec3crd(45,35,26), Vec3crd(37,26,35), Vec3crd(33,44,34), Vec3crd(44,43,46), Vec3crd(20,42,21), Vec3crd(40,21,42), Vec3crd(31,39,38), Vec3crd(20,31,38), Vec3crd(33,22,41), Vec3crd(21,41,22), Vec3crd(31,25,39), Vec3crd(24,39,25), Vec3crd(26,27,45), Vec3crd(28,45,27), Vec3crd(47,48,49), Vec3crd(47,50,48), Vec3crd(51,48,50), Vec3crd(52,48,51), Vec3crd(53,48,52), Vec3crd(54,55,56), Vec3crd(57,55,54), Vec3crd(58,55,57), Vec3crd(49,59,47), Vec3crd(60,56,55), Vec3crd(59,56,60), Vec3crd(60,47,59), Vec3crd(48,53,16), Vec3crd(56,13,19), Vec3crd(54,56,19), Vec3crd(56,59,13), Vec3crd(59,49,14), Vec3crd(59,14,13), Vec3crd(49,48,16), Vec3crd(49,16,14), Vec3crd(44,46,60), Vec3crd(44,60,55), Vec3crd(51,50,43), Vec3crd(19,34,58), Vec3crd(19,58,57), Vec3crd(53,52,16), Vec3crd(43,16,52), Vec3crd(43,52,51), Vec3crd(57,54,19), Vec3crd(47,60,46), Vec3crd(55,58,34), Vec3crd(55,34,44), Vec3crd(50,47,46), Vec3crd(50,46,43) - }); + mesh = TriangleMesh( + { 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) }, + { Vec3crd(0,1,2), Vec3crd(2,3,4), Vec3crd(2,5,0), Vec3crd(4,6,2), Vec3crd(2,6,5), Vec3crd(2,1,3), Vec3crd(7,8,9), Vec3crd(10,9,8), Vec3crd(11,9,10), Vec3crd(12,9,11), Vec3crd(9,13,14), Vec3crd(7,15,16), Vec3crd(10,17,0), Vec3crd(10,0,5), Vec3crd(12,11,6), Vec3crd(18,16,0), Vec3crd(6,19,13), Vec3crd(6,13,9), Vec3crd(9,12,6), Vec3crd(17,18,0), Vec3crd(11,10,5), Vec3crd(11,5,6), Vec3crd(14,16,15), Vec3crd(17,7,18), Vec3crd(16,18,7), Vec3crd(14,15,9), Vec3crd(7,9,15), Vec3crd(7,17,8), Vec3crd(10,8,17), Vec3crd(20,21,22), Vec3crd(23,24,25), Vec3crd(26,23,27), Vec3crd(28,27,23), Vec3crd(29,28,23), Vec3crd(30,29,23), Vec3crd(25,31,32), Vec3crd(22,33,34), Vec3crd(35,36,37), Vec3crd(24,38,39), Vec3crd(21,40,41), Vec3crd(38,42,20), Vec3crd(33,43,44), Vec3crd(6,4,23), Vec3crd(6,23,25), Vec3crd(36,35,1), Vec3crd(1,0,38), Vec3crd(1,38,36), Vec3crd(29,30,4), Vec3crd(25,32,6), Vec3crd(40,42,0), Vec3crd(35,45,1), Vec3crd(4,3,28), Vec3crd(4,28,29), Vec3crd(3,1,45), Vec3crd(3,45,28), Vec3crd(22,34,19), Vec3crd(19,6,32), Vec3crd(19,32,22), Vec3crd(42,38,0), Vec3crd(30,23,4), Vec3crd(0,16,43), Vec3crd(0,43,40), Vec3crd(24,37,36), Vec3crd(38,24,36), Vec3crd(24,23,37), Vec3crd(37,23,26), Vec3crd(22,32,20), Vec3crd(20,32,31), Vec3crd(33,41,40), Vec3crd(43,33,40), Vec3crd(45,35,26), Vec3crd(37,26,35), Vec3crd(33,44,34), Vec3crd(44,43,46), Vec3crd(20,42,21), Vec3crd(40,21,42), Vec3crd(31,39,38), Vec3crd(20,31,38), Vec3crd(33,22,41), Vec3crd(21,41,22), Vec3crd(31,25,39), Vec3crd(24,39,25), Vec3crd(26,27,45), Vec3crd(28,45,27), Vec3crd(47,48,49), Vec3crd(47,50,48), Vec3crd(51,48,50), Vec3crd(52,48,51), Vec3crd(53,48,52), Vec3crd(54,55,56), Vec3crd(57,55,54), Vec3crd(58,55,57), Vec3crd(49,59,47), Vec3crd(60,56,55), Vec3crd(59,56,60), Vec3crd(60,47,59), Vec3crd(48,53,16), Vec3crd(56,13,19), Vec3crd(54,56,19), Vec3crd(56,59,13), Vec3crd(59,49,14), Vec3crd(59,14,13), Vec3crd(49,48,16), Vec3crd(49,16,14), Vec3crd(44,46,60), Vec3crd(44,60,55), Vec3crd(51,50,43), Vec3crd(19,34,58), Vec3crd(19,58,57), Vec3crd(53,52,16), Vec3crd(43,16,52), Vec3crd(43,52,51), Vec3crd(57,54,19), Vec3crd(47,60,46), Vec3crd(55,58,34), Vec3crd(55,34,44), Vec3crd(50,47,46), Vec3crd(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) - }); - facets = std::vector({ - Vec3crd(0,1,2), Vec3crd(2,1,3), Vec3crd(2,3,4), Vec3crd(4,3,5), Vec3crd(4,5,6), Vec3crd(6,5,7), Vec3crd(6,7,8), Vec3crd(8,7,9), Vec3crd(8,9,10), Vec3crd(10,9,11), Vec3crd(10,11,12), Vec3crd(12,11,13), Vec3crd(12,13,14), Vec3crd(14,13,15), Vec3crd(14,15,16), Vec3crd(16,15,17), Vec3crd(16,17,18), Vec3crd(18,17,19), Vec3crd(18,19,20), Vec3crd(20,19,21), Vec3crd(20,21,22), Vec3crd(22,21,23), Vec3crd(22,23,24), Vec3crd(24,23,25), Vec3crd(24,25,26), Vec3crd(26,25,27), Vec3crd(26,27,28), Vec3crd(28,27,29), Vec3crd(28,29,30), Vec3crd(30,29,31), Vec3crd(30,31,32), Vec3crd(32,31,33), Vec3crd(32,33,34), Vec3crd(34,33,35), Vec3crd(34,35,36), Vec3crd(36,35,37), Vec3crd(36,37,38), Vec3crd(38,37,39), Vec3crd(38,39,40), Vec3crd(40,39,41), Vec3crd(40,41,42), Vec3crd(42,41,43), Vec3crd(42,43,44), Vec3crd(44,43,45), Vec3crd(44,45,46), Vec3crd(46,45,47), Vec3crd(46,47,48), Vec3crd(48,47,49), Vec3crd(48,49,50), Vec3crd(50,49,51), Vec3crd(50,51,52), Vec3crd(52,51,53), Vec3crd(52,53,54), Vec3crd(54,53,55), Vec3crd(54,55,56), Vec3crd(56,55,57), Vec3crd(56,57,58), Vec3crd(58,57,59), Vec3crd(58,59,60), Vec3crd(60,59,61), Vec3crd(60,61,62), Vec3crd(62,61,63), Vec3crd(62,63,64), Vec3crd(64,63,65), Vec3crd(64,65,66), Vec3crd(66,65,67), Vec3crd(66,67,68), Vec3crd(68,67,69), Vec3crd(68,69,70), Vec3crd(70,69,71), Vec3crd(70,71,72), Vec3crd(72,71,73), Vec3crd(72,73,74), Vec3crd(74,73,75), Vec3crd(74,75,76), Vec3crd(76,75,77), Vec3crd(76,77,78), Vec3crd(78,77,0), Vec3crd(78,0,2), Vec3crd(79,80,81), Vec3crd(81,80,82), Vec3crd(81,82,83), Vec3crd(83,82,84), Vec3crd(83,84,85), Vec3crd(85,84,86), Vec3crd(85,86,87), Vec3crd(87,86,88), Vec3crd(87,88,89), Vec3crd(89,88,90), Vec3crd(89,90,91), Vec3crd(91,90,92), Vec3crd(91,92,93), Vec3crd(93,92,94), Vec3crd(93,94,95), Vec3crd(95,94,96), Vec3crd(95,96,97), Vec3crd(97,96,98), Vec3crd(97,98,99), Vec3crd(99,98,100), Vec3crd(99,100,101), Vec3crd(101,100,102), Vec3crd(101,102,103), Vec3crd(103,102,104), Vec3crd(103,104,105), Vec3crd(105,104,106), Vec3crd(105,106,107), Vec3crd(107,106,108), Vec3crd(107,108,109), Vec3crd(109,108,110), Vec3crd(109,110,111), Vec3crd(111,110,112), Vec3crd(111,112,113), Vec3crd(113,112,114), Vec3crd(113,114,115), Vec3crd(115,114,116), Vec3crd(115,116,117), Vec3crd(117,116,118), Vec3crd(117,118,119), Vec3crd(119,118,120), Vec3crd(119,120,121), Vec3crd(121,120,122), Vec3crd(121,122,123), Vec3crd(123,122,124), Vec3crd(123,124,125), Vec3crd(125,124,126), Vec3crd(125,126,127), Vec3crd(127,126,128), Vec3crd(127,128,129), Vec3crd(129,128,130), Vec3crd(129,130,131), Vec3crd(131,130,132), Vec3crd(131,132,133), Vec3crd(133,132,134), Vec3crd(133,134,135), Vec3crd(135,134,136), Vec3crd(135,136,137), Vec3crd(137,136,138), Vec3crd(137,138,139), Vec3crd(139,138,140), Vec3crd(139,140,141), Vec3crd(141,140,142), Vec3crd(141,142,143), Vec3crd(143,142,144), Vec3crd(143,144,145), Vec3crd(145,144,146), Vec3crd(145,146,147), Vec3crd(147,146,148), Vec3crd(147,148,149), Vec3crd(149,148,150), Vec3crd(149,150,151), Vec3crd(151,150,152), Vec3crd(151,152,153), Vec3crd(153,152,154), Vec3crd(153,154,155), Vec3crd(155,154,156), Vec3crd(155,156,157), Vec3crd(157,156,79), Vec3crd(157,79,81), Vec3crd(57,110,108), Vec3crd(57,108,59), Vec3crd(59,108,106), Vec3crd(59,106,61), Vec3crd(61,106,104), Vec3crd(61,104,63), Vec3crd(63,104,102), Vec3crd(63,102,65), Vec3crd(65,102,100), Vec3crd(65,100,67), Vec3crd(67,100,98), Vec3crd(67,98,69), Vec3crd(69,98,96), Vec3crd(69,96,71), Vec3crd(71,96,94), Vec3crd(71,94,73), Vec3crd(73,94,92), Vec3crd(73,92,75), Vec3crd(75,92,90), Vec3crd(75,90,77), Vec3crd(77,90,88), Vec3crd(77,88,0), Vec3crd(0,88,86), Vec3crd(0,86,1), Vec3crd(1,86,84), Vec3crd(1,84,3), Vec3crd(3,84,82), Vec3crd(3,82,5), Vec3crd(5,82,80), Vec3crd(5,80,7), Vec3crd(7,80,79), Vec3crd(7,79,9), Vec3crd(9,79,156), Vec3crd(9,156,11), Vec3crd(11,156,154), Vec3crd(11,154,13), Vec3crd(13,154,152), Vec3crd(13,152,15), Vec3crd(15,152,150), Vec3crd(15,150,17), Vec3crd(17,150,148), Vec3crd(17,148,19), Vec3crd(19,148,146), Vec3crd(19,146,21), Vec3crd(21,146,144), Vec3crd(21,144,23), Vec3crd(23,144,142), Vec3crd(23,142,25), Vec3crd(25,142,140), Vec3crd(25,140,27), Vec3crd(27,140,138), Vec3crd(27,138,29), Vec3crd(29,138,136), Vec3crd(29,136,31), Vec3crd(33,31,134), Vec3crd(134,31,136), Vec3crd(33,134,132), Vec3crd(33,132,35), Vec3crd(35,132,130), Vec3crd(35,130,37), Vec3crd(37,130,128), Vec3crd(37,128,39), Vec3crd(39,128,126), Vec3crd(39,126,41), Vec3crd(41,126,124), Vec3crd(41,124,43), Vec3crd(43,124,122), Vec3crd(43,122,45), Vec3crd(45,122,120), Vec3crd(45,120,47), Vec3crd(47,120,118), Vec3crd(47,118,49), Vec3crd(49,118,116), Vec3crd(49,116,51), Vec3crd(51,116,114), Vec3crd(51,114,53), Vec3crd(55,53,112), Vec3crd(112,53,114), Vec3crd(57,55,110), Vec3crd(110,55,112), Vec3crd(30,135,137), Vec3crd(30,137,28), Vec3crd(28,137,139), Vec3crd(28,139,26), Vec3crd(26,139,141), Vec3crd(26,141,24), Vec3crd(24,141,143), Vec3crd(24,143,22), Vec3crd(22,143,145), Vec3crd(22,145,20), Vec3crd(20,145,147), Vec3crd(20,147,18), Vec3crd(18,147,149), Vec3crd(18,149,16), Vec3crd(16,149,151), Vec3crd(16,151,14), Vec3crd(14,151,153), Vec3crd(14,153,12), Vec3crd(12,153,155), Vec3crd(12,155,10), Vec3crd(10,155,157), Vec3crd(10,157,8), Vec3crd(8,157,81), Vec3crd(8,81,6), Vec3crd(6,81,83), Vec3crd(6,83,4), Vec3crd(4,83,85), Vec3crd(4,85,2), Vec3crd(2,85,87), Vec3crd(2,87,78), Vec3crd(78,87,89), Vec3crd(78,89,76), Vec3crd(76,89,91), Vec3crd(76,91,74), Vec3crd(74,91,93), Vec3crd(74,93,72), Vec3crd(72,93,95), Vec3crd(72,95,70), Vec3crd(70,95,97), Vec3crd(70,97,68), Vec3crd(68,97,99), Vec3crd(68,99,66), Vec3crd(66,99,101), Vec3crd(66,101,64), Vec3crd(64,101,103), Vec3crd(64,103,62), Vec3crd(62,103,105), Vec3crd(62,105,60), Vec3crd(60,105,107), Vec3crd(60,107,58), Vec3crd(58,107,109), Vec3crd(58,109,56), Vec3crd(30,32,135), Vec3crd(135,32,133), Vec3crd(52,113,115), Vec3crd(52,115,50), Vec3crd(50,115,117), Vec3crd(50,117,48), Vec3crd(48,117,119), Vec3crd(48,119,46), Vec3crd(46,119,121), Vec3crd(46,121,44), Vec3crd(44,121,123), Vec3crd(44,123,42), Vec3crd(42,123,125), Vec3crd(42,125,40), Vec3crd(40,125,127), Vec3crd(40,127,38), Vec3crd(38,127,129), Vec3crd(38,129,36), Vec3crd(36,129,131), Vec3crd(36,131,34), Vec3crd(34,131,133), Vec3crd(34,133,32), Vec3crd(52,54,113), Vec3crd(113,54,111), Vec3crd(54,56,111), Vec3crd(111,56,109) - }); + mesh = TriangleMesh( + { 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) }, + { Vec3crd(0,1,2), Vec3crd(2,1,3), Vec3crd(2,3,4), Vec3crd(4,3,5), Vec3crd(4,5,6), Vec3crd(6,5,7), Vec3crd(6,7,8), Vec3crd(8,7,9), Vec3crd(8,9,10), Vec3crd(10,9,11), Vec3crd(10,11,12), Vec3crd(12,11,13), Vec3crd(12,13,14), Vec3crd(14,13,15), Vec3crd(14,15,16), Vec3crd(16,15,17), Vec3crd(16,17,18), Vec3crd(18,17,19), Vec3crd(18,19,20), Vec3crd(20,19,21), Vec3crd(20,21,22), Vec3crd(22,21,23), Vec3crd(22,23,24), Vec3crd(24,23,25), Vec3crd(24,25,26), Vec3crd(26,25,27), Vec3crd(26,27,28), Vec3crd(28,27,29), Vec3crd(28,29,30), Vec3crd(30,29,31), Vec3crd(30,31,32), Vec3crd(32,31,33), Vec3crd(32,33,34), Vec3crd(34,33,35), Vec3crd(34,35,36), Vec3crd(36,35,37), Vec3crd(36,37,38), Vec3crd(38,37,39), Vec3crd(38,39,40), Vec3crd(40,39,41), Vec3crd(40,41,42), Vec3crd(42,41,43), Vec3crd(42,43,44), Vec3crd(44,43,45), Vec3crd(44,45,46), Vec3crd(46,45,47), Vec3crd(46,47,48), Vec3crd(48,47,49), Vec3crd(48,49,50), Vec3crd(50,49,51), Vec3crd(50,51,52), Vec3crd(52,51,53), Vec3crd(52,53,54), Vec3crd(54,53,55), Vec3crd(54,55,56), Vec3crd(56,55,57), Vec3crd(56,57,58), Vec3crd(58,57,59), Vec3crd(58,59,60), Vec3crd(60,59,61), Vec3crd(60,61,62), Vec3crd(62,61,63), Vec3crd(62,63,64), Vec3crd(64,63,65), Vec3crd(64,65,66), Vec3crd(66,65,67), Vec3crd(66,67,68), Vec3crd(68,67,69), Vec3crd(68,69,70), Vec3crd(70,69,71), Vec3crd(70,71,72), Vec3crd(72,71,73), Vec3crd(72,73,74), Vec3crd(74,73,75), Vec3crd(74,75,76), Vec3crd(76,75,77), Vec3crd(76,77,78), Vec3crd(78,77,0), Vec3crd(78,0,2), Vec3crd(79,80,81), Vec3crd(81,80,82), Vec3crd(81,82,83), Vec3crd(83,82,84), Vec3crd(83,84,85), Vec3crd(85,84,86), Vec3crd(85,86,87), Vec3crd(87,86,88), Vec3crd(87,88,89), Vec3crd(89,88,90), Vec3crd(89,90,91), Vec3crd(91,90,92), Vec3crd(91,92,93), Vec3crd(93,92,94), Vec3crd(93,94,95), Vec3crd(95,94,96), Vec3crd(95,96,97), Vec3crd(97,96,98), Vec3crd(97,98,99), Vec3crd(99,98,100), Vec3crd(99,100,101), Vec3crd(101,100,102), Vec3crd(101,102,103), Vec3crd(103,102,104), Vec3crd(103,104,105), Vec3crd(105,104,106), Vec3crd(105,106,107), Vec3crd(107,106,108), Vec3crd(107,108,109), Vec3crd(109,108,110), Vec3crd(109,110,111), Vec3crd(111,110,112), Vec3crd(111,112,113), Vec3crd(113,112,114), Vec3crd(113,114,115), Vec3crd(115,114,116), Vec3crd(115,116,117), Vec3crd(117,116,118), Vec3crd(117,118,119), Vec3crd(119,118,120), Vec3crd(119,120,121), Vec3crd(121,120,122), Vec3crd(121,122,123), Vec3crd(123,122,124), Vec3crd(123,124,125), Vec3crd(125,124,126), Vec3crd(125,126,127), Vec3crd(127,126,128), Vec3crd(127,128,129), Vec3crd(129,128,130), Vec3crd(129,130,131), Vec3crd(131,130,132), Vec3crd(131,132,133), Vec3crd(133,132,134), Vec3crd(133,134,135), Vec3crd(135,134,136), Vec3crd(135,136,137), Vec3crd(137,136,138), Vec3crd(137,138,139), Vec3crd(139,138,140), Vec3crd(139,140,141), Vec3crd(141,140,142), Vec3crd(141,142,143), Vec3crd(143,142,144), Vec3crd(143,144,145), Vec3crd(145,144,146), Vec3crd(145,146,147), Vec3crd(147,146,148), Vec3crd(147,148,149), Vec3crd(149,148,150), Vec3crd(149,150,151), Vec3crd(151,150,152), Vec3crd(151,152,153), Vec3crd(153,152,154), Vec3crd(153,154,155), Vec3crd(155,154,156), Vec3crd(155,156,157), Vec3crd(157,156,79), Vec3crd(157,79,81), Vec3crd(57,110,108), Vec3crd(57,108,59), Vec3crd(59,108,106), Vec3crd(59,106,61), Vec3crd(61,106,104), Vec3crd(61,104,63), Vec3crd(63,104,102), Vec3crd(63,102,65), Vec3crd(65,102,100), Vec3crd(65,100,67), Vec3crd(67,100,98), Vec3crd(67,98,69), Vec3crd(69,98,96), Vec3crd(69,96,71), Vec3crd(71,96,94), Vec3crd(71,94,73), Vec3crd(73,94,92), Vec3crd(73,92,75), Vec3crd(75,92,90), Vec3crd(75,90,77), Vec3crd(77,90,88), Vec3crd(77,88,0), Vec3crd(0,88,86), Vec3crd(0,86,1), Vec3crd(1,86,84), Vec3crd(1,84,3), Vec3crd(3,84,82), Vec3crd(3,82,5), Vec3crd(5,82,80), Vec3crd(5,80,7), Vec3crd(7,80,79), Vec3crd(7,79,9), Vec3crd(9,79,156), Vec3crd(9,156,11), Vec3crd(11,156,154), Vec3crd(11,154,13), Vec3crd(13,154,152), Vec3crd(13,152,15), Vec3crd(15,152,150), Vec3crd(15,150,17), Vec3crd(17,150,148), Vec3crd(17,148,19), Vec3crd(19,148,146), Vec3crd(19,146,21), Vec3crd(21,146,144), Vec3crd(21,144,23), Vec3crd(23,144,142), Vec3crd(23,142,25), Vec3crd(25,142,140), Vec3crd(25,140,27), Vec3crd(27,140,138), Vec3crd(27,138,29), Vec3crd(29,138,136), Vec3crd(29,136,31), Vec3crd(33,31,134), Vec3crd(134,31,136), Vec3crd(33,134,132), Vec3crd(33,132,35), Vec3crd(35,132,130), Vec3crd(35,130,37), Vec3crd(37,130,128), Vec3crd(37,128,39), Vec3crd(39,128,126), Vec3crd(39,126,41), Vec3crd(41,126,124), Vec3crd(41,124,43), Vec3crd(43,124,122), Vec3crd(43,122,45), Vec3crd(45,122,120), Vec3crd(45,120,47), Vec3crd(47,120,118), Vec3crd(47,118,49), Vec3crd(49,118,116), Vec3crd(49,116,51), Vec3crd(51,116,114), Vec3crd(51,114,53), Vec3crd(55,53,112), Vec3crd(112,53,114), Vec3crd(57,55,110), Vec3crd(110,55,112), Vec3crd(30,135,137), Vec3crd(30,137,28), Vec3crd(28,137,139), Vec3crd(28,139,26), Vec3crd(26,139,141), Vec3crd(26,141,24), Vec3crd(24,141,143), Vec3crd(24,143,22), Vec3crd(22,143,145), Vec3crd(22,145,20), Vec3crd(20,145,147), Vec3crd(20,147,18), Vec3crd(18,147,149), Vec3crd(18,149,16), Vec3crd(16,149,151), Vec3crd(16,151,14), Vec3crd(14,151,153), Vec3crd(14,153,12), Vec3crd(12,153,155), Vec3crd(12,155,10), Vec3crd(10,155,157), Vec3crd(10,157,8), Vec3crd(8,157,81), Vec3crd(8,81,6), Vec3crd(6,81,83), Vec3crd(6,83,4), Vec3crd(4,83,85), Vec3crd(4,85,2), Vec3crd(2,85,87), Vec3crd(2,87,78), Vec3crd(78,87,89), Vec3crd(78,89,76), Vec3crd(76,89,91), Vec3crd(76,91,74), Vec3crd(74,91,93), Vec3crd(74,93,72), Vec3crd(72,93,95), Vec3crd(72,95,70), Vec3crd(70,95,97), Vec3crd(70,97,68), Vec3crd(68,97,99), Vec3crd(68,99,66), Vec3crd(66,99,101), Vec3crd(66,101,64), Vec3crd(64,101,103), Vec3crd(64,103,62), Vec3crd(62,103,105), Vec3crd(62,105,60), Vec3crd(60,105,107), Vec3crd(60,107,58), Vec3crd(58,107,109), Vec3crd(58,109,56), Vec3crd(30,32,135), Vec3crd(135,32,133), Vec3crd(52,113,115), Vec3crd(52,115,50), Vec3crd(50,115,117), Vec3crd(50,117,48), Vec3crd(48,117,119), Vec3crd(48,119,46), Vec3crd(46,119,121), Vec3crd(46,121,44), Vec3crd(44,121,123), Vec3crd(44,123,42), Vec3crd(42,123,125), Vec3crd(42,125,40), Vec3crd(40,125,127), Vec3crd(40,127,38), Vec3crd(38,127,129), Vec3crd(38,129,36), Vec3crd(36,129,131), Vec3crd(36,131,34), Vec3crd(34,131,133), Vec3crd(34,133,32), Vec3crd(52,54,113), Vec3crd(113,54,111), Vec3crd(54,56,111), Vec3crd(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) - }); - facets = std::vector({ - Vec3crd(0,1,2), Vec3crd(2,1,3), Vec3crd(1,0,4), Vec3crd(5,1,4), Vec3crd(6,2,7), Vec3crd(0,2,8), Vec3crd(0,8,9), Vec3crd(0,9,10), Vec3crd(0,10,11), Vec3crd(0,11,12), Vec3crd(0,12,13), Vec3crd(0,13,4), Vec3crd(13,14,4), Vec3crd(15,4,16), Vec3crd(17,4,15), Vec3crd(18,4,17), Vec3crd(19,4,20), Vec3crd(18,20,4), Vec3crd(21,2,22), Vec3crd(4,19,23), Vec3crd(4,23,7), Vec3crd(23,24,7), Vec3crd(22,2,25), Vec3crd(26,2,27), Vec3crd(28,29,7), Vec3crd(25,2,30), Vec3crd(29,31,7), Vec3crd(30,2,26), Vec3crd(31,32,7), Vec3crd(27,2,6), Vec3crd(32,6,7), Vec3crd(28,7,24), Vec3crd(33,2,21), Vec3crd(34,2,33), Vec3crd(35,2,34), Vec3crd(36,2,35), Vec3crd(8,2,36), Vec3crd(16,4,14), Vec3crd(2,3,7), Vec3crd(7,3,37), Vec3crd(38,1,5), Vec3crd(3,1,39), Vec3crd(3,39,40), Vec3crd(3,40,41), Vec3crd(42,38,5), Vec3crd(3,41,43), Vec3crd(3,43,44), Vec3crd(37,3,45), Vec3crd(37,45,46), Vec3crd(37,46,47), Vec3crd(48,49,5), Vec3crd(37,47,50), Vec3crd(49,42,5), Vec3crd(37,50,51), Vec3crd(37,51,52), Vec3crd(37,52,53), Vec3crd(37,53,54), Vec3crd(55,56,5), Vec3crd(37,54,57), Vec3crd(37,57,58), Vec3crd(59,60,5), Vec3crd(37,58,61), Vec3crd(37,62,5), Vec3crd(37,61,62), Vec3crd(62,59,5), Vec3crd(60,55,5), Vec3crd(63,1,38), Vec3crd(64,1,63), Vec3crd(65,1,64), Vec3crd(66,1,65), Vec3crd(67,1,66), Vec3crd(39,1,67), Vec3crd(44,45,3), Vec3crd(56,48,5), Vec3crd(5,4,7), Vec3crd(37,5,7), Vec3crd(41,40,36), Vec3crd(36,40,8), Vec3crd(39,9,40), Vec3crd(40,9,8), Vec3crd(43,41,35), Vec3crd(35,41,36), Vec3crd(44,43,34), Vec3crd(34,43,35), Vec3crd(33,45,44), Vec3crd(34,33,44), Vec3crd(21,46,45), Vec3crd(33,21,45), Vec3crd(22,47,46), Vec3crd(21,22,46), Vec3crd(25,50,47), Vec3crd(22,25,47), Vec3crd(30,51,50), Vec3crd(25,30,50), Vec3crd(26,52,51), Vec3crd(30,26,51), Vec3crd(27,53,52), Vec3crd(26,27,52), Vec3crd(6,54,53), Vec3crd(27,6,53), Vec3crd(32,57,54), Vec3crd(6,32,54), Vec3crd(31,58,57), Vec3crd(32,31,57), Vec3crd(29,61,58), Vec3crd(31,29,58), Vec3crd(28,62,61), Vec3crd(29,28,61), Vec3crd(59,62,28), Vec3crd(24,59,28), Vec3crd(60,59,24), Vec3crd(23,60,24), Vec3crd(55,60,23), Vec3crd(19,55,23), Vec3crd(55,19,56), Vec3crd(56,19,20), Vec3crd(56,20,48), Vec3crd(48,20,18), Vec3crd(48,18,49), Vec3crd(49,18,17), Vec3crd(49,17,42), Vec3crd(42,17,15), Vec3crd(42,15,38), Vec3crd(38,15,16), Vec3crd(38,16,63), Vec3crd(63,16,14), Vec3crd(63,14,64), Vec3crd(64,14,13), Vec3crd(64,13,65), Vec3crd(65,13,12), Vec3crd(65,12,66), Vec3crd(66,12,11), Vec3crd(66,11,67), Vec3crd(67,11,10), Vec3crd(67,10,39), Vec3crd(39,10,9) - }); + mesh = TriangleMesh( + { 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) }, + { Vec3crd(0,1,2), Vec3crd(2,1,3), Vec3crd(1,0,4), Vec3crd(5,1,4), Vec3crd(6,2,7), Vec3crd(0,2,8), Vec3crd(0,8,9), Vec3crd(0,9,10), Vec3crd(0,10,11), Vec3crd(0,11,12), Vec3crd(0,12,13), Vec3crd(0,13,4), Vec3crd(13,14,4), Vec3crd(15,4,16), Vec3crd(17,4,15), Vec3crd(18,4,17), Vec3crd(19,4,20), Vec3crd(18,20,4), Vec3crd(21,2,22), Vec3crd(4,19,23), Vec3crd(4,23,7), Vec3crd(23,24,7), Vec3crd(22,2,25), Vec3crd(26,2,27), Vec3crd(28,29,7), Vec3crd(25,2,30), Vec3crd(29,31,7), Vec3crd(30,2,26), Vec3crd(31,32,7), Vec3crd(27,2,6), Vec3crd(32,6,7), Vec3crd(28,7,24), Vec3crd(33,2,21), Vec3crd(34,2,33), Vec3crd(35,2,34), Vec3crd(36,2,35), Vec3crd(8,2,36), Vec3crd(16,4,14), Vec3crd(2,3,7), Vec3crd(7,3,37), Vec3crd(38,1,5), Vec3crd(3,1,39), Vec3crd(3,39,40), Vec3crd(3,40,41), Vec3crd(42,38,5), Vec3crd(3,41,43), Vec3crd(3,43,44), Vec3crd(37,3,45), Vec3crd(37,45,46), Vec3crd(37,46,47), Vec3crd(48,49,5), Vec3crd(37,47,50), Vec3crd(49,42,5), Vec3crd(37,50,51), Vec3crd(37,51,52), Vec3crd(37,52,53), Vec3crd(37,53,54), Vec3crd(55,56,5), Vec3crd(37,54,57), Vec3crd(37,57,58), Vec3crd(59,60,5), Vec3crd(37,58,61), Vec3crd(37,62,5), Vec3crd(37,61,62), Vec3crd(62,59,5), Vec3crd(60,55,5), Vec3crd(63,1,38), Vec3crd(64,1,63), Vec3crd(65,1,64), Vec3crd(66,1,65), Vec3crd(67,1,66), Vec3crd(39,1,67), Vec3crd(44,45,3), Vec3crd(56,48,5), Vec3crd(5,4,7), Vec3crd(37,5,7), Vec3crd(41,40,36), Vec3crd(36,40,8), Vec3crd(39,9,40), Vec3crd(40,9,8), Vec3crd(43,41,35), Vec3crd(35,41,36), Vec3crd(44,43,34), Vec3crd(34,43,35), Vec3crd(33,45,44), Vec3crd(34,33,44), Vec3crd(21,46,45), Vec3crd(33,21,45), Vec3crd(22,47,46), Vec3crd(21,22,46), Vec3crd(25,50,47), Vec3crd(22,25,47), Vec3crd(30,51,50), Vec3crd(25,30,50), Vec3crd(26,52,51), Vec3crd(30,26,51), Vec3crd(27,53,52), Vec3crd(26,27,52), Vec3crd(6,54,53), Vec3crd(27,6,53), Vec3crd(32,57,54), Vec3crd(6,32,54), Vec3crd(31,58,57), Vec3crd(32,31,57), Vec3crd(29,61,58), Vec3crd(31,29,58), Vec3crd(28,62,61), Vec3crd(29,28,61), Vec3crd(59,62,28), Vec3crd(24,59,28), Vec3crd(60,59,24), Vec3crd(23,60,24), Vec3crd(55,60,23), Vec3crd(19,55,23), Vec3crd(55,19,56), Vec3crd(56,19,20), Vec3crd(56,20,48), Vec3crd(48,20,18), Vec3crd(48,18,49), Vec3crd(49,18,17), Vec3crd(49,17,42), Vec3crd(42,17,15), Vec3crd(42,15,38), Vec3crd(38,15,16), Vec3crd(38,16,63), Vec3crd(63,16,14), Vec3crd(63,14,64), Vec3crd(64,14,13), Vec3crd(64,13,65), Vec3crd(65,13,12), Vec3crd(65,12,66), Vec3crd(66,12,11), Vec3crd(66,11,67), Vec3crd(67,11,10), Vec3crd(67,10,39), Vec3crd(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) - }); - facets = std::vector({ - Vec3crd(0,1,2), Vec3crd(1,0,3), Vec3crd(4,5,6), Vec3crd(5,4,7), Vec3crd(8,9,10), Vec3crd(9,11,12), Vec3crd(11,9,8), Vec3crd(13,14,15), Vec3crd(14,13,16), Vec3crd(17,2,1), Vec3crd(2,17,18), Vec3crd(19,11,20), Vec3crd(11,19,12), Vec3crd(17,21,18), Vec3crd(21,2,18), Vec3crd(2,21,22), Vec3crd(22,21,23), Vec3crd(8,22,23), Vec3crd(22,8,10), Vec3crd(24,25,26), Vec3crd(25,24,27), Vec3crd(23,1,8), Vec3crd(1,23,21), Vec3crd(1,21,17), Vec3crd(5,15,3), Vec3crd(15,5,7), Vec3crd(15,7,28), Vec3crd(28,7,26), Vec3crd(28,26,25), Vec3crd(8,14,11), Vec3crd(14,8,3), Vec3crd(3,8,1), Vec3crd(14,3,15), Vec3crd(11,14,20), Vec3crd(26,4,24), Vec3crd(4,26,7), Vec3crd(12,16,9), Vec3crd(16,12,19), Vec3crd(29,4,13), Vec3crd(4,29,24), Vec3crd(24,29,27), Vec3crd(9,22,10), Vec3crd(22,9,0), Vec3crd(0,9,16), Vec3crd(0,16,13), Vec3crd(0,13,6), Vec3crd(6,13,4), Vec3crd(2,22,0), Vec3crd(19,14,16), Vec3crd(14,19,20), Vec3crd(15,29,13), Vec3crd(29,25,27), Vec3crd(25,29,15), Vec3crd(25,15,28), Vec3crd(6,3,0), Vec3crd(3,6,5) - }); + mesh = TriangleMesh( + { 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) }, + { Vec3crd(0,1,2), Vec3crd(1,0,3), Vec3crd(4,5,6), Vec3crd(5,4,7), Vec3crd(8,9,10), Vec3crd(9,11,12), Vec3crd(11,9,8), Vec3crd(13,14,15), Vec3crd(14,13,16), Vec3crd(17,2,1), Vec3crd(2,17,18), Vec3crd(19,11,20), Vec3crd(11,19,12), Vec3crd(17,21,18), Vec3crd(21,2,18), Vec3crd(2,21,22), Vec3crd(22,21,23), Vec3crd(8,22,23), Vec3crd(22,8,10), Vec3crd(24,25,26), Vec3crd(25,24,27), Vec3crd(23,1,8), Vec3crd(1,23,21), Vec3crd(1,21,17), Vec3crd(5,15,3), Vec3crd(15,5,7), Vec3crd(15,7,28), Vec3crd(28,7,26), Vec3crd(28,26,25), Vec3crd(8,14,11), Vec3crd(14,8,3), Vec3crd(3,8,1), Vec3crd(14,3,15), Vec3crd(11,14,20), Vec3crd(26,4,24), Vec3crd(4,26,7), Vec3crd(12,16,9), Vec3crd(16,12,19), Vec3crd(29,4,13), Vec3crd(4,29,24), Vec3crd(24,29,27), Vec3crd(9,22,10), Vec3crd(22,9,0), Vec3crd(0,9,16), Vec3crd(0,16,13), Vec3crd(0,13,6), Vec3crd(6,13,4), Vec3crd(2,22,0), Vec3crd(19,14,16), Vec3crd(14,19,20), Vec3crd(15,29,13), Vec3crd(29,25,27), Vec3crd(25,29,15), Vec3crd(25,15,28), Vec3crd(6,3,0), Vec3crd(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) - }); - facets = std::vector({ - Vec3crd(0,1,2), Vec3crd(3,4,5), Vec3crd(6,7,8), Vec3crd(9,10,11), Vec3crd(12,2,1), Vec3crd(12,1,13), Vec3crd(14,15,16), Vec3crd(17,18,19), Vec3crd(20,21,22), Vec3crd(17,19,23), Vec3crd(24,25,26), Vec3crd(27,13,1), Vec3crd(28,25,29), Vec3crd(30,31,32), Vec3crd(28,33,34), Vec3crd(35,36,7), Vec3crd(37,38,39), Vec3crd(40,10,41), Vec3crd(42,43,44), Vec3crd(45,5,4), Vec3crd(46,47,48), Vec3crd(46,48,49), Vec3crd(45,4,50), Vec3crd(51,52,53), Vec3crd(51,54,55), Vec3crd(56,52,57), Vec3crd(58,59,60), Vec3crd(61,50,4), Vec3crd(62,63,64), Vec3crd(65,34,33), Vec3crd(66,67,42), Vec3crd(68,17,69), Vec3crd(70,71,22), Vec3crd(66,42,72), Vec3crd(73,16,15), Vec3crd(35,7,74), Vec3crd(75,76,54), Vec3crd(77,27,1), Vec3crd(78,32,31), Vec3crd(75,54,79), Vec3crd(80,26,25), Vec3crd(81,80,25), Vec3crd(82,83,48), Vec3crd(84,20,85), Vec3crd(81,25,86), Vec3crd(87,88,19), Vec3crd(0,89,1), Vec3crd(90,91,92), Vec3crd(90,10,93), Vec3crd(38,94,39), Vec3crd(94,95,39), Vec3crd(3,7,96), Vec3crd(97,15,98), Vec3crd(97,99,15), Vec3crd(92,91,100), Vec3crd(89,101,1), Vec3crd(102,39,95), Vec3crd(103,11,10), Vec3crd(104,96,7), Vec3crd(105,15,99), Vec3crd(106,61,4), Vec3crd(107,108,33), Vec3crd(76,55,54), Vec3crd(109,91,110), Vec3crd(111,23,19), Vec3crd(112,63,113), Vec3crd(114,115,48), Vec3crd(116,59,117), Vec3crd(118,20,119), Vec3crd(120,31,121), Vec3crd(122,44,43), Vec3crd(110,91,123), Vec3crd(124,125,126), Vec3crd(127,128,129), Vec3crd(127,130,124), Vec3crd(131,124,132), Vec3crd(126,133,134), Vec3crd(135,136,126), Vec3crd(137,138,127), Vec3crd(139,127,138), Vec3crd(128,140,141), Vec3crd(142,128,143), Vec3crd(144,140,145), Vec3crd(100,91,146), Vec3crd(147,148,134), Vec3crd(101,149,1), Vec3crd(102,150,39), Vec3crd(103,10,151), Vec3crd(145,140,152), Vec3crd(152,140,153), Vec3crd(148,154,134), Vec3crd(154,155,134), Vec3crd(156,15,105), Vec3crd(157,104,7), Vec3crd(36,8,7), Vec3crd(158,37,39), Vec3crd(159,19,88), Vec3crd(160,19,159), Vec3crd(161,59,58), Vec3crd(161,117,59), Vec3crd(162,31,30), Vec3crd(162,121,31), Vec3crd(163,43,164), Vec3crd(163,165,43), Vec3crd(166,167,43), Vec3crd(167,164,43), Vec3crd(168,57,52), Vec3crd(82,48,169), Vec3crd(114,170,171), Vec3crd(108,65,33), Vec3crd(64,63,112), Vec3crd(114,172,170), Vec3crd(160,173,170), Vec3crd(171,170,173), Vec3crd(172,174,170), Vec3crd(160,170,174), Vec3crd(175,176,177), Vec3crd(178,77,1), Vec3crd(179,31,120), Vec3crd(175,180,176), Vec3crd(181,182,176), Vec3crd(177,176,182), Vec3crd(180,183,176), Vec3crd(181,176,183), Vec3crd(184,42,67), Vec3crd(185,69,17), Vec3crd(160,111,19), Vec3crd(186,187,160), Vec3crd(188,189,114), Vec3crd(190,188,114), Vec3crd(114,48,191), Vec3crd(192,114,193), Vec3crd(194,160,195), Vec3crd(196,160,194), Vec3crd(197,198,181), Vec3crd(199,197,181), Vec3crd(122,43,165), Vec3crd(200,201,175), Vec3crd(202,175,203), Vec3crd(204,175,202), Vec3crd(205,119,20), Vec3crd(206,181,207), Vec3crd(208,209,15), Vec3crd(210,15,209), Vec3crd(211,10,9), Vec3crd(212,10,211), Vec3crd(213,214,215), Vec3crd(216,217,218), Vec3crd(219,14,17), Vec3crd(113,63,220), Vec3crd(221,222,48), Vec3crd(191,48,222), Vec3crd(22,223,20), Vec3crd(205,20,223), Vec3crd(224,40,42), Vec3crd(123,91,225), Vec3crd(214,226,215), Vec3crd(227,215,226), Vec3crd(218,217,228), Vec3crd(229,228,217), Vec3crd(215,230,213), Vec3crd(125,135,126), Vec3crd(217,216,231), Vec3crd(129,128,142), Vec3crd(216,213,232), Vec3crd(130,132,124), Vec3crd(213,216,233), Vec3crd(234,213,235), Vec3crd(236,227,237), Vec3crd(238,237,227), Vec3crd(239,240,216), Vec3crd(233,216,240), Vec3crd(241,242,229), Vec3crd(243,229,242), Vec3crd(215,227,244), Vec3crd(245,215,246), Vec3crd(217,247,229), Vec3crd(248,249,217), Vec3crd(232,213,250), Vec3crd(230,250,213), Vec3crd(133,147,134), Vec3crd(244,227,251), Vec3crd(236,252,227), Vec3crd(251,227,252), Vec3crd(231,216,253), Vec3crd(254,253,216), Vec3crd(141,140,144), Vec3crd(247,255,229), Vec3crd(241,229,256), Vec3crd(255,256,229), Vec3crd(257,241,258), Vec3crd(259,146,91), Vec3crd(260,261,236), Vec3crd(262,1,149), Vec3crd(263,264,241), Vec3crd(265,241,264), Vec3crd(266,236,267), Vec3crd(268,267,236), Vec3crd(49,48,83), Vec3crd(166,43,269), Vec3crd(270,271,272), Vec3crd(273,274,275), Vec3crd(276,274,277), Vec3crd(278,151,10), Vec3crd(279,280,272), Vec3crd(281,39,150), Vec3crd(272,282,279), Vec3crd(155,283,134), Vec3crd(274,276,284), Vec3crd(153,140,285), Vec3crd(286,276,287), Vec3crd(265,276,286), Vec3crd(288,289,279), Vec3crd(268,288,279), Vec3crd(290,291,272), Vec3crd(271,290,272), Vec3crd(292,274,293), Vec3crd(275,274,292), Vec3crd(294,265,295), Vec3crd(276,265,294), Vec3crd(296,297,268), Vec3crd(279,296,268), Vec3crd(241,265,298), Vec3crd(298,265,299), Vec3crd(236,300,268), Vec3crd(300,301,268), Vec3crd(107,33,78), Vec3crd(302,303,59), Vec3crd(304,305,279), Vec3crd(282,304,279), Vec3crd(306,276,307), Vec3crd(284,276,306), Vec3crd(185,17,73), Vec3crd(308,309,221), Vec3crd(158,39,70), Vec3crd(310,41,10), Vec3crd(15,311,208), Vec3crd(7,6,312), Vec3crd(313,314,6), Vec3crd(315,6,314), Vec3crd(316,208,317), Vec3crd(318,317,208), Vec3crd(258,241,319), Vec3crd(319,241,320), Vec3crd(261,321,236), Vec3crd(321,322,236), Vec3crd(6,315,323), Vec3crd(208,324,318), Vec3crd(270,325,318), Vec3crd(326,318,325), Vec3crd(327,328,315), Vec3crd(273,315,328), Vec3crd(118,329,20), Vec3crd(330,20,329), Vec3crd(331,332,25), Vec3crd(86,25,332), Vec3crd(333,334,52), Vec3crd(335,52,334), Vec3crd(115,336,48), Vec3crd(169,48,336), Vec3crd(62,106,4), Vec3crd(35,15,210), Vec3crd(35,337,15), Vec3crd(158,10,212), Vec3crd(158,310,10), Vec3crd(338,178,1), Vec3crd(339,59,116), Vec3crd(107,302,59), Vec3crd(66,22,340), Vec3crd(66,341,22), Vec3crd(185,221,342), Vec3crd(185,308,221), Vec3crd(75,31,179), Vec3crd(75,343,31), Vec3crd(166,20,330), Vec3crd(166,85,20), Vec3crd(81,52,335), Vec3crd(81,168,52), Vec3crd(82,19,344), Vec3crd(82,87,19), Vec3crd(108,339,345), Vec3crd(346,108,345), Vec3crd(64,347,348), Vec3crd(349,347,64), Vec3crd(178,109,350), Vec3crd(351,178,350), Vec3crd(179,352,353), Vec3crd(354,352,179), Vec3crd(355,208,356), Vec3crd(356,208,311), Vec3crd(357,358,6), Vec3crd(358,312,6), Vec3crd(68,22,21), Vec3crd(68,340,22), Vec3crd(221,48,47), Vec3crd(184,342,221), Vec3crd(359,270,360), Vec3crd(318,360,270), Vec3crd(361,362,273), Vec3crd(315,273,362), Vec3crd(272,102,270), Vec3crd(363,270,102), Vec3crd(274,273,103), Vec3crd(364,103,273), Vec3crd(21,19,18), Vec3crd(21,20,84), Vec3crd(184,46,42), Vec3crd(43,42,46), Vec3crd(12,22,71), Vec3crd(365,22,12), Vec3crd(14,98,15), Vec3crd(14,220,63), Vec3crd(40,93,10), Vec3crd(40,225,91), Vec3crd(45,221,309), Vec3crd(366,221,45), Vec3crd(313,367,212), Vec3crd(212,367,368), Vec3crd(36,369,367), Vec3crd(313,36,367), Vec3crd(316,37,367), Vec3crd(37,368,367), Vec3crd(210,367,369), Vec3crd(316,367,210), Vec3crd(362,370,315), Vec3crd(370,323,315), Vec3crd(360,318,371), Vec3crd(371,318,324), Vec3crd(372,331,159), Vec3crd(159,195,160), Vec3crd(373,115,56), Vec3crd(115,114,189), Vec3crd(52,56,161), Vec3crd(374,161,56), Vec3crd(25,28,331), Vec3crd(375,331,28), Vec3crd(376,333,163), Vec3crd(163,203,175), Vec3crd(377,118,24), Vec3crd(118,181,198), Vec3crd(25,24,162), Vec3crd(378,162,24), Vec3crd(52,51,333), Vec3crd(379,333,51), Vec3crd(167,380,381), Vec3crd(376,167,381), Vec3crd(377,381,330), Vec3crd(330,381,380), Vec3crd(335,381,382), Vec3crd(376,381,335), Vec3crd(373,383,169), Vec3crd(169,383,384), Vec3crd(168,385,383), Vec3crd(373,168,383), Vec3crd(372,87,383), Vec3crd(87,384,383), Vec3crd(377,80,381), Vec3crd(80,382,381), Vec3crd(86,383,385), Vec3crd(372,383,86), Vec3crd(106,348,347), Vec3crd(386,106,347), Vec3crd(375,65,346), Vec3crd(108,346,65), Vec3crd(64,112,349), Vec3crd(387,349,112), Vec3crd(171,190,114), Vec3crd(346,345,171), Vec3crd(374,190,345), Vec3crd(171,345,190), Vec3crd(349,172,347), Vec3crd(172,114,192), Vec3crd(386,347,192), Vec3crd(172,192,347), Vec3crd(173,160,196), Vec3crd(171,173,346), Vec3crd(375,346,196), Vec3crd(173,196,346), Vec3crd(172,349,174), Vec3crd(174,186,160), Vec3crd(387,186,349), Vec3crd(174,349,186), Vec3crd(64,348,62), Vec3crd(106,62,348), Vec3crd(108,107,339), Vec3crd(59,339,107), Vec3crd(374,345,116), Vec3crd(339,116,345), Vec3crd(76,353,352), Vec3crd(379,76,352), Vec3crd(388,77,351), Vec3crd(178,351,77), Vec3crd(179,120,354), Vec3crd(378,354,120), Vec3crd(177,200,175), Vec3crd(351,350,177), Vec3crd(389,200,350), Vec3crd(177,350,200), Vec3crd(354,180,352), Vec3crd(180,175,204), Vec3crd(379,352,204), Vec3crd(180,204,352), Vec3crd(182,181,206), Vec3crd(177,182,351), Vec3crd(388,351,206), Vec3crd(182,206,351), Vec3crd(180,354,183), Vec3crd(183,199,181), Vec3crd(378,199,354), Vec3crd(183,354,199), Vec3crd(91,109,338), Vec3crd(178,338,109), Vec3crd(76,75,353), Vec3crd(179,353,75), Vec3crd(389,350,110), Vec3crd(109,110,350), Vec3crd(390,391,392), Vec3crd(393,394,395), Vec3crd(224,122,389), Vec3crd(122,175,201), Vec3crd(365,388,205), Vec3crd(205,207,181), Vec3crd(66,340,396), Vec3crd(68,396,340), Vec3crd(184,396,342), Vec3crd(185,342,396), Vec3crd(66,396,67), Vec3crd(184,67,396), Vec3crd(68,69,396), Vec3crd(185,396,69), Vec3crd(219,111,387), Vec3crd(111,160,187), Vec3crd(366,386,191), Vec3crd(191,193,114), Vec3crd(150,272,280), Vec3crd(102,272,150), Vec3crd(151,277,274), Vec3crd(103,151,274), Vec3crd(161,374,117), Vec3crd(116,117,374), Vec3crd(366,61,386), Vec3crd(106,386,61), Vec3crd(111,187,387), Vec3crd(186,387,187), Vec3crd(56,188,374), Vec3crd(190,374,188), Vec3crd(191,386,193), Vec3crd(192,193,386), Vec3crd(331,375,194), Vec3crd(196,194,375), Vec3crd(28,34,375), Vec3crd(65,375,34), Vec3crd(219,387,113), Vec3crd(112,113,387), Vec3crd(224,389,123), Vec3crd(110,123,389), Vec3crd(51,55,379), Vec3crd(76,379,55), Vec3crd(24,197,378), Vec3crd(199,378,197), Vec3crd(122,201,389), Vec3crd(200,389,201), Vec3crd(333,379,202), Vec3crd(204,202,379), Vec3crd(205,388,207), Vec3crd(206,207,388), Vec3crd(365,27,388), Vec3crd(77,388,27), Vec3crd(162,378,121), Vec3crd(120,121,378), Vec3crd(162,30,25), Vec3crd(30,29,25), Vec3crd(51,53,54), Vec3crd(303,60,59), Vec3crd(28,29,33), Vec3crd(29,397,33), Vec3crd(161,58,52), Vec3crd(53,52,58), Vec3crd(21,84,19), Vec3crd(84,344,19), Vec3crd(46,49,43), Vec3crd(49,269,43), Vec3crd(208,316,209), Vec3crd(210,209,316), Vec3crd(327,313,211), Vec3crd(212,211,313), Vec3crd(36,35,369), Vec3crd(210,369,35), Vec3crd(37,158,368), Vec3crd(212,368,158), Vec3crd(6,8,313), Vec3crd(36,313,8), Vec3crd(326,38,316), Vec3crd(37,316,38), Vec3crd(392,391,398), Vec3crd(399,398,391), Vec3crd(394,400,395), Vec3crd(401,395,400), Vec3crd(390,214,391), Vec3crd(214,213,234), Vec3crd(393,395,218), Vec3crd(218,239,216), Vec3crd(402,230,403), Vec3crd(230,215,245), Vec3crd(125,124,131), Vec3crd(404,125,403), Vec3crd(405,406,231), Vec3crd(231,248,217), Vec3crd(129,137,127), Vec3crd(407,406,129), Vec3crd(130,127,139), Vec3crd(402,130,408), Vec3crd(194,195,331), Vec3crd(159,331,195), Vec3crd(115,189,56), Vec3crd(188,56,189), Vec3crd(14,219,220), Vec3crd(113,220,219), Vec3crd(45,50,366), Vec3crd(61,366,50), Vec3crd(221,366,222), Vec3crd(191,222,366), Vec3crd(17,23,219), Vec3crd(111,219,23), Vec3crd(118,198,24), Vec3crd(197,24,198), Vec3crd(202,203,333), Vec3crd(163,333,203), Vec3crd(40,224,225), Vec3crd(123,225,224), Vec3crd(12,13,365), Vec3crd(27,365,13), Vec3crd(22,365,223), Vec3crd(205,223,365), Vec3crd(42,44,224), Vec3crd(122,224,44), Vec3crd(399,391,234), Vec3crd(214,234,391), Vec3crd(401,239,395), Vec3crd(218,395,239), Vec3crd(214,390,226), Vec3crd(226,238,227), Vec3crd(218,228,393), Vec3crd(228,229,243), Vec3crd(401,399,233), Vec3crd(233,235,213), Vec3crd(392,409,390), Vec3crd(410,390,409), Vec3crd(394,393,411), Vec3crd(412,411,393), Vec3crd(402,403,131), Vec3crd(125,131,403), Vec3crd(405,137,406), Vec3crd(129,406,137), Vec3crd(405,408,139), Vec3crd(130,139,408), Vec3crd(230,245,403), Vec3crd(404,403,245), Vec3crd(231,406,248), Vec3crd(407,248,406), Vec3crd(232,254,216), Vec3crd(402,408,232), Vec3crd(413,404,244), Vec3crd(244,246,215), Vec3crd(414,247,407), Vec3crd(247,217,249), Vec3crd(133,126,136), Vec3crd(415,133,413), Vec3crd(141,143,128), Vec3crd(416,414,141), Vec3crd(410,238,390), Vec3crd(226,390,238), Vec3crd(412,393,243), Vec3crd(228,243,393), Vec3crd(233,399,235), Vec3crd(234,235,399), Vec3crd(237,260,236), Vec3crd(238,410,237), Vec3crd(417,260,410), Vec3crd(237,410,260), Vec3crd(239,401,240), Vec3crd(233,240,401), Vec3crd(242,241,257), Vec3crd(243,242,412), Vec3crd(418,412,257), Vec3crd(242,257,412), Vec3crd(401,419,399), Vec3crd(398,399,419), Vec3crd(417,410,420), Vec3crd(409,420,410), Vec3crd(400,421,401), Vec3crd(419,401,421), Vec3crd(418,422,412), Vec3crd(411,412,422), Vec3crd(413,135,404), Vec3crd(125,404,135), Vec3crd(414,407,142), Vec3crd(129,142,407), Vec3crd(130,402,132), Vec3crd(131,132,402), Vec3crd(133,136,413), Vec3crd(135,413,136), Vec3crd(423,147,415), Vec3crd(133,415,147), Vec3crd(137,405,138), Vec3crd(139,138,405), Vec3crd(141,414,143), Vec3crd(142,143,414), Vec3crd(424,416,144), Vec3crd(141,144,416), Vec3crd(405,254,408), Vec3crd(232,408,254), Vec3crd(244,404,246), Vec3crd(245,246,404), Vec3crd(247,249,407), Vec3crd(248,407,249), Vec3crd(232,250,402), Vec3crd(230,402,250), Vec3crd(415,413,251), Vec3crd(244,251,413), Vec3crd(252,236,266), Vec3crd(251,252,415), Vec3crd(423,415,266), Vec3crd(252,266,415), Vec3crd(231,253,405), Vec3crd(254,405,253), Vec3crd(416,255,414), Vec3crd(247,414,255), Vec3crd(256,263,241), Vec3crd(255,416,256), Vec3crd(424,263,416), Vec3crd(256,416,263), Vec3crd(257,258,418), Vec3crd(425,418,258), Vec3crd(260,417,261), Vec3crd(426,261,417), Vec3crd(422,418,427), Vec3crd(427,259,91), Vec3crd(420,428,417), Vec3crd(428,1,262), Vec3crd(147,423,148), Vec3crd(429,148,423), Vec3crd(263,424,264), Vec3crd(264,295,265), Vec3crd(266,267,423), Vec3crd(267,268,297), Vec3crd(144,145,424), Vec3crd(430,424,145), Vec3crd(49,431,269), Vec3crd(166,269,431), Vec3crd(82,431,83), Vec3crd(49,83,431), Vec3crd(84,85,431), Vec3crd(166,431,85), Vec3crd(82,344,431), Vec3crd(84,431,344), Vec3crd(432,278,90), Vec3crd(10,90,278), Vec3crd(433,0,281), Vec3crd(39,281,0), Vec3crd(362,361,434), Vec3crd(435,271,359), Vec3crd(270,359,271), Vec3crd(436,361,275), Vec3crd(273,275,361), Vec3crd(360,437,359), Vec3crd(277,287,276), Vec3crd(151,278,277), Vec3crd(280,279,289), Vec3crd(150,280,281), Vec3crd(436,438,439), Vec3crd(439,285,140), Vec3crd(90,92,432), Vec3crd(440,432,92), Vec3crd(282,272,291), Vec3crd(441,282,442), Vec3crd(284,293,274), Vec3crd(443,438,284), Vec3crd(278,432,286), Vec3crd(286,299,265), Vec3crd(281,288,433), Vec3crd(288,268,301), Vec3crd(0,433,89), Vec3crd(444,89,433), Vec3crd(435,445,442), Vec3crd(445,134,283), Vec3crd(439,446,436), Vec3crd(361,436,446), Vec3crd(442,290,435), Vec3crd(271,435,290), Vec3crd(438,436,292), Vec3crd(275,292,436), Vec3crd(445,435,447), Vec3crd(359,447,435), Vec3crd(286,287,278), Vec3crd(277,278,287), Vec3crd(288,281,289), Vec3crd(280,289,281), Vec3crd(145,152,430), Vec3crd(443,430,152), Vec3crd(148,429,154), Vec3crd(441,154,429), Vec3crd(424,430,294), Vec3crd(294,307,276), Vec3crd(423,296,429), Vec3crd(296,279,305), Vec3crd(425,440,100), Vec3crd(92,100,440), Vec3crd(290,442,291), Vec3crd(282,291,442), Vec3crd(292,293,438), Vec3crd(284,438,293), Vec3crd(298,320,241), Vec3crd(432,440,298), Vec3crd(300,236,322), Vec3crd(433,300,444), Vec3crd(426,101,444), Vec3crd(89,444,101), Vec3crd(107,448,302), Vec3crd(302,79,54), Vec3crd(78,31,343), Vec3crd(107,78,448), Vec3crd(75,79,448), Vec3crd(302,448,79), Vec3crd(78,343,448), Vec3crd(75,448,343), Vec3crd(427,418,259), Vec3crd(425,259,418), Vec3crd(428,262,417), Vec3crd(426,417,262), Vec3crd(437,449,359), Vec3crd(447,359,449), Vec3crd(434,361,450), Vec3crd(446,450,361), Vec3crd(32,33,397), Vec3crd(78,33,32), Vec3crd(53,303,54), Vec3crd(302,54,303), Vec3crd(152,153,443), Vec3crd(438,443,153), Vec3crd(429,304,441), Vec3crd(282,441,304), Vec3crd(430,443,306), Vec3crd(284,306,443), Vec3crd(154,441,155), Vec3crd(442,155,441), Vec3crd(298,299,432), Vec3crd(286,432,299), Vec3crd(300,433,301), Vec3crd(288,301,433), Vec3crd(185,451,308), Vec3crd(308,74,7), Vec3crd(73,15,337), Vec3crd(185,73,451), Vec3crd(35,74,451), Vec3crd(308,451,74), Vec3crd(73,337,451), Vec3crd(35,451,337), Vec3crd(158,452,310), Vec3crd(310,72,42), Vec3crd(70,22,341), Vec3crd(158,70,452), Vec3crd(66,72,452), Vec3crd(310,452,72), Vec3crd(70,341,452), Vec3crd(66,452,341), Vec3crd(313,327,314), Vec3crd(315,314,327), Vec3crd(316,317,326), Vec3crd(318,326,317), Vec3crd(15,156,311), Vec3crd(356,311,156), Vec3crd(7,312,157), Vec3crd(358,157,312), Vec3crd(211,9,327), Vec3crd(364,327,9), Vec3crd(38,326,94), Vec3crd(363,94,326), Vec3crd(294,295,424), Vec3crd(264,424,295), Vec3crd(296,423,297), Vec3crd(267,297,423), Vec3crd(262,149,426), Vec3crd(101,426,149), Vec3crd(258,319,425), Vec3crd(440,425,319), Vec3crd(261,426,321), Vec3crd(444,321,426), Vec3crd(259,425,146), Vec3crd(100,146,425), Vec3crd(306,307,430), Vec3crd(294,430,307), Vec3crd(304,429,305), Vec3crd(296,305,429), Vec3crd(319,320,440), Vec3crd(298,440,320), Vec3crd(321,444,322), Vec3crd(300,322,444), Vec3crd(445,283,442), Vec3crd(155,442,283), Vec3crd(439,438,285), Vec3crd(153,285,438), Vec3crd(17,68,18), Vec3crd(21,18,68), Vec3crd(46,184,47), Vec3crd(221,47,184), Vec3crd(102,95,363), Vec3crd(94,363,95), Vec3crd(9,11,364), Vec3crd(103,364,11), Vec3crd(6,323,357), Vec3crd(370,357,323), Vec3crd(371,324,355), Vec3crd(208,355,324), Vec3crd(270,363,325), Vec3crd(326,325,363), Vec3crd(327,364,328), Vec3crd(273,328,364), Vec3crd(0,2,39), Vec3crd(12,39,2), Vec3crd(90,93,91), Vec3crd(40,91,93), Vec3crd(14,16,17), Vec3crd(73,17,16), Vec3crd(45,309,7), Vec3crd(308,7,309), Vec3crd(12,71,39), Vec3crd(70,39,71), Vec3crd(40,41,42), Vec3crd(310,42,41), Vec3crd(97,98,63), Vec3crd(14,63,98), Vec3crd(3,5,7), Vec3crd(45,7,5), Vec3crd(118,377,329), Vec3crd(330,329,377), Vec3crd(331,372,332), Vec3crd(86,332,372), Vec3crd(333,376,334), Vec3crd(335,334,376), Vec3crd(115,373,336), Vec3crd(169,336,373), Vec3crd(167,166,380), Vec3crd(330,380,166), Vec3crd(80,81,382), Vec3crd(335,382,81), Vec3crd(86,385,81), Vec3crd(168,81,385), Vec3crd(169,384,82), Vec3crd(87,82,384), Vec3crd(159,88,372), Vec3crd(87,372,88), Vec3crd(163,164,376), Vec3crd(167,376,164), Vec3crd(24,26,377), Vec3crd(80,377,26), Vec3crd(56,57,373), Vec3crd(168,373,57), Vec3crd(32,397,30), Vec3crd(29,30,397), Vec3crd(58,60,53), Vec3crd(303,53,60), Vec3crd(205,181,119), Vec3crd(118,119,181), Vec3crd(163,175,165), Vec3crd(122,165,175), Vec3crd(453,454,455), Vec3crd(454,456,455), Vec3crd(457,455,456), Vec3crd(458,455,457), Vec3crd(459,455,458), Vec3crd(460,455,459), Vec3crd(461,462,463), Vec3crd(464,465,466), Vec3crd(467,468,469), Vec3crd(470,471,472), Vec3crd(465,473,474), Vec3crd(475,476,477), Vec3crd(478,479,480), Vec3crd(481,482,478), Vec3crd(483,484,481), Vec3crd(485,486,483), Vec3crd(487,488,485), Vec3crd(489,490,487), Vec3crd(491,492,489), Vec3crd(493,494,491), Vec3crd(495,496,493), Vec3crd(497,498,495), Vec3crd(499,500,497), Vec3crd(501,502,499), Vec3crd(503,504,501), Vec3crd(505,504,503), Vec3crd(506,504,505), Vec3crd(507,504,506), Vec3crd(508,504,507), Vec3crd(509,504,508), Vec3crd(510,504,509), Vec3crd(511,504,510), Vec3crd(512,504,511), Vec3crd(513,504,512), Vec3crd(514,504,513), Vec3crd(476,515,516), Vec3crd(517,518,519), Vec3crd(520,517,521), Vec3crd(518,522,523), Vec3crd(522,480,479), Vec3crd(524,525,526), Vec3crd(468,470,527), Vec3crd(525,467,528), Vec3crd(529,475,530), Vec3crd(531,532,533), Vec3crd(534,531,535), Vec3crd(536,537,538), Vec3crd(473,539,540), Vec3crd(539,536,541), Vec3crd(537,534,542), Vec3crd(471,520,543), Vec3crd(532,529,544), Vec3crd(545,524,546), Vec3crd(453,461,547), Vec3crd(463,464,548), Vec3crd(523,549,504), Vec3crd(527,550,551), Vec3crd(519,552,553), Vec3crd(521,554,555), Vec3crd(466,556,557), Vec3crd(469,558,559), Vec3crd(528,560,561), Vec3crd(477,562,563), Vec3crd(543,564,565), Vec3crd(535,566,567), Vec3crd(530,568,569), Vec3crd(540,570,571), Vec3crd(474,572,573), Vec3crd(542,574,575), Vec3crd(538,576,577), Vec3crd(541,578,579), Vec3crd(472,580,581), Vec3crd(526,582,583), Vec3crd(533,584,585), Vec3crd(544,586,587), Vec3crd(516,545,588), Vec3crd(588,589,590), Vec3crd(455,460,4), Vec3crd(591,592,63), Vec3crd(462,455,4), Vec3crd(592,547,63), Vec3crd(547,548,63), Vec3crd(465,462,4), Vec3crd(548,557,63), Vec3crd(127,124,501), Vec3crd(127,501,499), Vec3crd(505,503,124), Vec3crd(124,126,507), Vec3crd(124,507,506), Vec3crd(509,508,126), Vec3crd(126,134,512), Vec3crd(126,512,511), Vec3crd(510,509,126), Vec3crd(128,127,493), Vec3crd(128,493,491), Vec3crd(497,495,127), Vec3crd(489,487,128), Vec3crd(140,128,483), Vec3crd(140,483,481), Vec3crd(487,485,128), Vec3crd(478,480,140), Vec3crd(480,522,140), Vec3crd(514,513,134), Vec3crd(504,514,134), Vec3crd(551,581,437), Vec3crd(471,470,434), Vec3crd(445,447,555), Vec3crd(445,555,553), Vec3crd(134,445,553), Vec3crd(134,553,504), Vec3crd(446,439,518), Vec3crd(446,518,517), Vec3crd(439,140,522), Vec3crd(439,522,518), Vec3crd(515,476,358), Vec3crd(563,588,356), Vec3crd(557,573,63), Vec3crd(473,465,4), Vec3crd(437,360,559), Vec3crd(437,559,551), Vec3crd(360,371,561), Vec3crd(360,561,559), Vec3crd(362,434,470), Vec3crd(362,470,468), Vec3crd(370,362,468), Vec3crd(370,468,467), Vec3crd(499,497,127), Vec3crd(506,505,124), Vec3crd(495,493,127), Vec3crd(513,512,134), Vec3crd(481,478,140), Vec3crd(447,449,565), Vec3crd(447,565,555), Vec3crd(450,446,517), Vec3crd(450,517,520), Vec3crd(356,156,569), Vec3crd(356,569,563), Vec3crd(157,358,476), Vec3crd(157,476,475), Vec3crd(357,370,467), Vec3crd(357,467,525), Vec3crd(371,355,583), Vec3crd(371,583,561), Vec3crd(460,459,4), Vec3crd(63,62,593), Vec3crd(63,593,591), Vec3crd(62,4,459), Vec3crd(62,459,458), Vec3crd(532,531,104), Vec3crd(531,534,104), Vec3crd(567,585,105), Vec3crd(575,567,105), Vec3crd(4,3,539), Vec3crd(4,539,473), Vec3crd(536,539,3), Vec3crd(97,63,573), Vec3crd(97,573,571), Vec3crd(571,579,97), Vec3crd(99,97,579), Vec3crd(99,579,577), Vec3crd(105,99,577), Vec3crd(105,577,575), Vec3crd(96,104,534), Vec3crd(96,534,537), Vec3crd(3,96,537), Vec3crd(3,537,536), Vec3crd(503,501,124), Vec3crd(508,507,126), Vec3crd(491,489,128), Vec3crd(511,510,126), Vec3crd(485,483,128), Vec3crd(434,450,520), Vec3crd(434,520,471), Vec3crd(449,437,581), Vec3crd(449,581,565), Vec3crd(156,105,585), Vec3crd(156,585,587), Vec3crd(587,569,156), Vec3crd(104,157,529), Vec3crd(104,529,532), Vec3crd(475,529,157), Vec3crd(590,583,355), Vec3crd(355,356,588), Vec3crd(355,588,590), Vec3crd(358,357,524), Vec3crd(358,524,515), Vec3crd(525,524,357), Vec3crd(458,457,62), Vec3crd(457,593,62), Vec3crd(479,478,482), Vec3crd(479,504,549), Vec3crd(479,482,504), Vec3crd(482,481,484), Vec3crd(472,551,550), Vec3crd(581,551,472), Vec3crd(482,484,504), Vec3crd(484,483,486), Vec3crd(523,553,552), Vec3crd(504,553,523), Vec3crd(540,573,572), Vec3crd(571,573,540), Vec3crd(544,585,584), Vec3crd(587,585,544), Vec3crd(542,577,576), Vec3crd(575,577,542), Vec3crd(526,590,589), Vec3crd(583,590,526), Vec3crd(535,575,574), Vec3crd(567,575,535), Vec3crd(533,567,566), Vec3crd(585,567,533), Vec3crd(538,579,578), Vec3crd(577,579,538), Vec3crd(543,581,580), Vec3crd(565,581,543), Vec3crd(477,569,568), Vec3crd(563,569,477), Vec3crd(530,587,586), Vec3crd(569,587,530), Vec3crd(541,571,570), Vec3crd(579,571,541), Vec3crd(528,583,582), Vec3crd(561,583,528), Vec3crd(591,453,592), Vec3crd(547,592,453), Vec3crd(521,565,564), Vec3crd(555,565,521), Vec3crd(474,557,556), Vec3crd(573,557,474), Vec3crd(516,563,562), Vec3crd(588,563,516), Vec3crd(519,555,554), Vec3crd(553,555,519), Vec3crd(527,559,558), Vec3crd(551,559,527), Vec3crd(469,561,560), Vec3crd(559,561,469), Vec3crd(462,461,455), Vec3crd(453,455,461), Vec3crd(461,463,547), Vec3crd(548,547,463), Vec3crd(465,464,462), Vec3crd(463,462,464), Vec3crd(464,466,548), Vec3crd(557,548,466), Vec3crd(469,560,467), Vec3crd(528,467,560), Vec3crd(472,550,470), Vec3crd(527,470,550), Vec3crd(474,556,465), Vec3crd(466,465,556), Vec3crd(477,568,475), Vec3crd(530,475,568), Vec3crd(516,562,476), Vec3crd(477,476,562), Vec3crd(519,554,517), Vec3crd(521,517,554), Vec3crd(521,564,520), Vec3crd(543,520,564), Vec3crd(523,552,518), Vec3crd(519,518,552), Vec3crd(479,549,522), Vec3crd(523,522,549), Vec3crd(526,589,524), Vec3crd(589,546,524), Vec3crd(527,558,468), Vec3crd(469,468,558), Vec3crd(528,582,525), Vec3crd(526,525,582), Vec3crd(530,586,529), Vec3crd(544,529,586), Vec3crd(533,566,531), Vec3crd(535,531,566), Vec3crd(535,574,534), Vec3crd(542,534,574), Vec3crd(538,578,536), Vec3crd(541,536,578), Vec3crd(540,572,473), Vec3crd(474,473,572), Vec3crd(541,570,539), Vec3crd(540,539,570), Vec3crd(542,576,537), Vec3crd(538,537,576), Vec3crd(543,580,471), Vec3crd(472,471,580), Vec3crd(544,584,532), Vec3crd(533,532,584), Vec3crd(524,545,515), Vec3crd(516,515,545), Vec3crd(545,546,588), Vec3crd(589,588,546), Vec3crd(453,591,454), Vec3crd(593,454,591), Vec3crd(484,486,504), Vec3crd(486,485,488), Vec3crd(486,488,504), Vec3crd(488,487,490), Vec3crd(488,490,504), Vec3crd(490,489,492), Vec3crd(490,492,504), Vec3crd(492,491,494), Vec3crd(492,494,504), Vec3crd(494,493,496), Vec3crd(494,496,504), Vec3crd(496,495,498), Vec3crd(496,498,504), Vec3crd(498,497,500), Vec3crd(498,500,504), Vec3crd(500,499,502), Vec3crd(500,502,504), Vec3crd(501,504,502), Vec3crd(454,593,456), Vec3crd(457,456,593), Vec3crd(594,595,596), Vec3crd(597,598,594), Vec3crd(599,597,594), Vec3crd(600,599,594), Vec3crd(601,600,594), Vec3crd(602,601,594), Vec3crd(603,602,594), Vec3crd(604,603,594), Vec3crd(605,604,594), Vec3crd(606,607,608), Vec3crd(609,606,608), Vec3crd(610,609,608), Vec3crd(611,610,608), Vec3crd(612,611,608), Vec3crd(613,612,608), Vec3crd(614,613,608), Vec3crd(615,614,608), Vec3crd(616,615,608), Vec3crd(617,616,608), Vec3crd(618,617,608), Vec3crd(619,618,608), Vec3crd(620,619,608), Vec3crd(596,608,607), Vec3crd(595,594,598), Vec3crd(608,596,595), Vec3crd(605,594,91), Vec3crd(91,338,602), Vec3crd(91,602,603), Vec3crd(598,597,1), Vec3crd(594,596,91), Vec3crd(608,595,1), Vec3crd(595,598,1), Vec3crd(616,617,392), Vec3crd(610,611,394), Vec3crd(419,421,613), Vec3crd(419,613,614), Vec3crd(422,427,607), Vec3crd(422,607,606), Vec3crd(427,91,596), Vec3crd(427,596,607), Vec3crd(428,420,619), Vec3crd(428,619,620), Vec3crd(1,428,620), Vec3crd(1,620,608), Vec3crd(420,409,618), Vec3crd(420,618,619), Vec3crd(411,422,606), Vec3crd(411,606,609), Vec3crd(398,419,614), Vec3crd(398,614,615), Vec3crd(421,400,612), Vec3crd(421,612,613), Vec3crd(409,392,617), Vec3crd(409,617,618), Vec3crd(394,411,609), Vec3crd(394,609,610), Vec3crd(604,605,91), Vec3crd(338,1,599), Vec3crd(338,599,600), Vec3crd(392,398,615), Vec3crd(392,615,616), Vec3crd(400,394,611), Vec3crd(400,611,612), Vec3crd(603,604,91), Vec3crd(601,602,338), Vec3crd(597,599,1), Vec3crd(600,601,338) - }); + mesh = TriangleMesh( + { 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) }, + { Vec3crd(0,1,2), Vec3crd(3,4,5), Vec3crd(6,7,8), Vec3crd(9,10,11), Vec3crd(12,2,1), Vec3crd(12,1,13), Vec3crd(14,15,16), Vec3crd(17,18,19), Vec3crd(20,21,22), Vec3crd(17,19,23), Vec3crd(24,25,26), Vec3crd(27,13,1), Vec3crd(28,25,29), Vec3crd(30,31,32), Vec3crd(28,33,34), Vec3crd(35,36,7), Vec3crd(37,38,39), Vec3crd(40,10,41), Vec3crd(42,43,44), Vec3crd(45,5,4), Vec3crd(46,47,48), Vec3crd(46,48,49), Vec3crd(45,4,50), Vec3crd(51,52,53), Vec3crd(51,54,55), Vec3crd(56,52,57), Vec3crd(58,59,60), Vec3crd(61,50,4), Vec3crd(62,63,64), Vec3crd(65,34,33), Vec3crd(66,67,42), Vec3crd(68,17,69), Vec3crd(70,71,22), Vec3crd(66,42,72), Vec3crd(73,16,15), Vec3crd(35,7,74), Vec3crd(75,76,54), Vec3crd(77,27,1), Vec3crd(78,32,31), Vec3crd(75,54,79), Vec3crd(80,26,25), Vec3crd(81,80,25), Vec3crd(82,83,48), Vec3crd(84,20,85), Vec3crd(81,25,86), Vec3crd(87,88,19), Vec3crd(0,89,1), Vec3crd(90,91,92), Vec3crd(90,10,93), Vec3crd(38,94,39), Vec3crd(94,95,39), Vec3crd(3,7,96), Vec3crd(97,15,98), Vec3crd(97,99,15), Vec3crd(92,91,100), Vec3crd(89,101,1), Vec3crd(102,39,95), Vec3crd(103,11,10), Vec3crd(104,96,7), Vec3crd(105,15,99), Vec3crd(106,61,4), Vec3crd(107,108,33), Vec3crd(76,55,54), Vec3crd(109,91,110), Vec3crd(111,23,19), Vec3crd(112,63,113), Vec3crd(114,115,48), Vec3crd(116,59,117), Vec3crd(118,20,119), Vec3crd(120,31,121), Vec3crd(122,44,43), Vec3crd(110,91,123), Vec3crd(124,125,126), Vec3crd(127,128,129), Vec3crd(127,130,124), Vec3crd(131,124,132), Vec3crd(126,133,134), Vec3crd(135,136,126), Vec3crd(137,138,127), Vec3crd(139,127,138), Vec3crd(128,140,141), Vec3crd(142,128,143), Vec3crd(144,140,145), Vec3crd(100,91,146), Vec3crd(147,148,134), Vec3crd(101,149,1), Vec3crd(102,150,39), Vec3crd(103,10,151), Vec3crd(145,140,152), Vec3crd(152,140,153), Vec3crd(148,154,134), Vec3crd(154,155,134), Vec3crd(156,15,105), Vec3crd(157,104,7), Vec3crd(36,8,7), Vec3crd(158,37,39), Vec3crd(159,19,88), Vec3crd(160,19,159), Vec3crd(161,59,58), Vec3crd(161,117,59), Vec3crd(162,31,30), Vec3crd(162,121,31), Vec3crd(163,43,164), Vec3crd(163,165,43), Vec3crd(166,167,43), Vec3crd(167,164,43), Vec3crd(168,57,52), Vec3crd(82,48,169), Vec3crd(114,170,171), Vec3crd(108,65,33), Vec3crd(64,63,112), Vec3crd(114,172,170), Vec3crd(160,173,170), Vec3crd(171,170,173), Vec3crd(172,174,170), Vec3crd(160,170,174), Vec3crd(175,176,177), Vec3crd(178,77,1), Vec3crd(179,31,120), Vec3crd(175,180,176), Vec3crd(181,182,176), Vec3crd(177,176,182), Vec3crd(180,183,176), Vec3crd(181,176,183), Vec3crd(184,42,67), Vec3crd(185,69,17), Vec3crd(160,111,19), Vec3crd(186,187,160), Vec3crd(188,189,114), Vec3crd(190,188,114), Vec3crd(114,48,191), Vec3crd(192,114,193), Vec3crd(194,160,195), Vec3crd(196,160,194), Vec3crd(197,198,181), Vec3crd(199,197,181), Vec3crd(122,43,165), Vec3crd(200,201,175), Vec3crd(202,175,203), Vec3crd(204,175,202), Vec3crd(205,119,20), Vec3crd(206,181,207), Vec3crd(208,209,15), Vec3crd(210,15,209), Vec3crd(211,10,9), Vec3crd(212,10,211), Vec3crd(213,214,215), Vec3crd(216,217,218), Vec3crd(219,14,17), Vec3crd(113,63,220), Vec3crd(221,222,48), Vec3crd(191,48,222), Vec3crd(22,223,20), Vec3crd(205,20,223), Vec3crd(224,40,42), Vec3crd(123,91,225), Vec3crd(214,226,215), Vec3crd(227,215,226), Vec3crd(218,217,228), Vec3crd(229,228,217), Vec3crd(215,230,213), Vec3crd(125,135,126), Vec3crd(217,216,231), Vec3crd(129,128,142), Vec3crd(216,213,232), Vec3crd(130,132,124), Vec3crd(213,216,233), Vec3crd(234,213,235), Vec3crd(236,227,237), Vec3crd(238,237,227), Vec3crd(239,240,216), Vec3crd(233,216,240), Vec3crd(241,242,229), Vec3crd(243,229,242), Vec3crd(215,227,244), Vec3crd(245,215,246), Vec3crd(217,247,229), Vec3crd(248,249,217), Vec3crd(232,213,250), Vec3crd(230,250,213), Vec3crd(133,147,134), Vec3crd(244,227,251), Vec3crd(236,252,227), Vec3crd(251,227,252), Vec3crd(231,216,253), Vec3crd(254,253,216), Vec3crd(141,140,144), Vec3crd(247,255,229), Vec3crd(241,229,256), Vec3crd(255,256,229), Vec3crd(257,241,258), Vec3crd(259,146,91), Vec3crd(260,261,236), Vec3crd(262,1,149), Vec3crd(263,264,241), Vec3crd(265,241,264), Vec3crd(266,236,267), Vec3crd(268,267,236), Vec3crd(49,48,83), Vec3crd(166,43,269), Vec3crd(270,271,272), Vec3crd(273,274,275), Vec3crd(276,274,277), Vec3crd(278,151,10), Vec3crd(279,280,272), Vec3crd(281,39,150), Vec3crd(272,282,279), Vec3crd(155,283,134), Vec3crd(274,276,284), Vec3crd(153,140,285), Vec3crd(286,276,287), Vec3crd(265,276,286), Vec3crd(288,289,279), Vec3crd(268,288,279), Vec3crd(290,291,272), Vec3crd(271,290,272), Vec3crd(292,274,293), Vec3crd(275,274,292), Vec3crd(294,265,295), Vec3crd(276,265,294), Vec3crd(296,297,268), Vec3crd(279,296,268), Vec3crd(241,265,298), Vec3crd(298,265,299), Vec3crd(236,300,268), Vec3crd(300,301,268), Vec3crd(107,33,78), Vec3crd(302,303,59), Vec3crd(304,305,279), Vec3crd(282,304,279), Vec3crd(306,276,307), Vec3crd(284,276,306), Vec3crd(185,17,73), Vec3crd(308,309,221), Vec3crd(158,39,70), Vec3crd(310,41,10), Vec3crd(15,311,208), Vec3crd(7,6,312), Vec3crd(313,314,6), Vec3crd(315,6,314), Vec3crd(316,208,317), Vec3crd(318,317,208), Vec3crd(258,241,319), Vec3crd(319,241,320), Vec3crd(261,321,236), Vec3crd(321,322,236), Vec3crd(6,315,323), Vec3crd(208,324,318), Vec3crd(270,325,318), Vec3crd(326,318,325), Vec3crd(327,328,315), Vec3crd(273,315,328), Vec3crd(118,329,20), Vec3crd(330,20,329), Vec3crd(331,332,25), Vec3crd(86,25,332), Vec3crd(333,334,52), Vec3crd(335,52,334), Vec3crd(115,336,48), Vec3crd(169,48,336), Vec3crd(62,106,4), Vec3crd(35,15,210), Vec3crd(35,337,15), Vec3crd(158,10,212), Vec3crd(158,310,10), Vec3crd(338,178,1), Vec3crd(339,59,116), Vec3crd(107,302,59), Vec3crd(66,22,340), Vec3crd(66,341,22), Vec3crd(185,221,342), Vec3crd(185,308,221), Vec3crd(75,31,179), Vec3crd(75,343,31), Vec3crd(166,20,330), Vec3crd(166,85,20), Vec3crd(81,52,335), Vec3crd(81,168,52), Vec3crd(82,19,344), Vec3crd(82,87,19), Vec3crd(108,339,345), Vec3crd(346,108,345), Vec3crd(64,347,348), Vec3crd(349,347,64), Vec3crd(178,109,350), Vec3crd(351,178,350), Vec3crd(179,352,353), Vec3crd(354,352,179), Vec3crd(355,208,356), Vec3crd(356,208,311), Vec3crd(357,358,6), Vec3crd(358,312,6), Vec3crd(68,22,21), Vec3crd(68,340,22), Vec3crd(221,48,47), Vec3crd(184,342,221), Vec3crd(359,270,360), Vec3crd(318,360,270), Vec3crd(361,362,273), Vec3crd(315,273,362), Vec3crd(272,102,270), Vec3crd(363,270,102), Vec3crd(274,273,103), Vec3crd(364,103,273), Vec3crd(21,19,18), Vec3crd(21,20,84), Vec3crd(184,46,42), Vec3crd(43,42,46), Vec3crd(12,22,71), Vec3crd(365,22,12), Vec3crd(14,98,15), Vec3crd(14,220,63), Vec3crd(40,93,10), Vec3crd(40,225,91), Vec3crd(45,221,309), Vec3crd(366,221,45), Vec3crd(313,367,212), Vec3crd(212,367,368), Vec3crd(36,369,367), Vec3crd(313,36,367), Vec3crd(316,37,367), Vec3crd(37,368,367), Vec3crd(210,367,369), Vec3crd(316,367,210), Vec3crd(362,370,315), Vec3crd(370,323,315), Vec3crd(360,318,371), Vec3crd(371,318,324), Vec3crd(372,331,159), Vec3crd(159,195,160), Vec3crd(373,115,56), Vec3crd(115,114,189), Vec3crd(52,56,161), Vec3crd(374,161,56), Vec3crd(25,28,331), Vec3crd(375,331,28), Vec3crd(376,333,163), Vec3crd(163,203,175), Vec3crd(377,118,24), Vec3crd(118,181,198), Vec3crd(25,24,162), Vec3crd(378,162,24), Vec3crd(52,51,333), Vec3crd(379,333,51), Vec3crd(167,380,381), Vec3crd(376,167,381), Vec3crd(377,381,330), Vec3crd(330,381,380), Vec3crd(335,381,382), Vec3crd(376,381,335), Vec3crd(373,383,169), Vec3crd(169,383,384), Vec3crd(168,385,383), Vec3crd(373,168,383), Vec3crd(372,87,383), Vec3crd(87,384,383), Vec3crd(377,80,381), Vec3crd(80,382,381), Vec3crd(86,383,385), Vec3crd(372,383,86), Vec3crd(106,348,347), Vec3crd(386,106,347), Vec3crd(375,65,346), Vec3crd(108,346,65), Vec3crd(64,112,349), Vec3crd(387,349,112), Vec3crd(171,190,114), Vec3crd(346,345,171), Vec3crd(374,190,345), Vec3crd(171,345,190), Vec3crd(349,172,347), Vec3crd(172,114,192), Vec3crd(386,347,192), Vec3crd(172,192,347), Vec3crd(173,160,196), Vec3crd(171,173,346), Vec3crd(375,346,196), Vec3crd(173,196,346), Vec3crd(172,349,174), Vec3crd(174,186,160), Vec3crd(387,186,349), Vec3crd(174,349,186), Vec3crd(64,348,62), Vec3crd(106,62,348), Vec3crd(108,107,339), Vec3crd(59,339,107), Vec3crd(374,345,116), Vec3crd(339,116,345), Vec3crd(76,353,352), Vec3crd(379,76,352), Vec3crd(388,77,351), Vec3crd(178,351,77), Vec3crd(179,120,354), Vec3crd(378,354,120), Vec3crd(177,200,175), Vec3crd(351,350,177), Vec3crd(389,200,350), Vec3crd(177,350,200), Vec3crd(354,180,352), Vec3crd(180,175,204), Vec3crd(379,352,204), Vec3crd(180,204,352), Vec3crd(182,181,206), Vec3crd(177,182,351), Vec3crd(388,351,206), Vec3crd(182,206,351), Vec3crd(180,354,183), Vec3crd(183,199,181), Vec3crd(378,199,354), Vec3crd(183,354,199), Vec3crd(91,109,338), Vec3crd(178,338,109), Vec3crd(76,75,353), Vec3crd(179,353,75), Vec3crd(389,350,110), Vec3crd(109,110,350), Vec3crd(390,391,392), Vec3crd(393,394,395), Vec3crd(224,122,389), Vec3crd(122,175,201), Vec3crd(365,388,205), Vec3crd(205,207,181), Vec3crd(66,340,396), Vec3crd(68,396,340), Vec3crd(184,396,342), Vec3crd(185,342,396), Vec3crd(66,396,67), Vec3crd(184,67,396), Vec3crd(68,69,396), Vec3crd(185,396,69), Vec3crd(219,111,387), Vec3crd(111,160,187), Vec3crd(366,386,191), Vec3crd(191,193,114), Vec3crd(150,272,280), Vec3crd(102,272,150), Vec3crd(151,277,274), Vec3crd(103,151,274), Vec3crd(161,374,117), Vec3crd(116,117,374), Vec3crd(366,61,386), Vec3crd(106,386,61), Vec3crd(111,187,387), Vec3crd(186,387,187), Vec3crd(56,188,374), Vec3crd(190,374,188), Vec3crd(191,386,193), Vec3crd(192,193,386), Vec3crd(331,375,194), Vec3crd(196,194,375), Vec3crd(28,34,375), Vec3crd(65,375,34), Vec3crd(219,387,113), Vec3crd(112,113,387), Vec3crd(224,389,123), Vec3crd(110,123,389), Vec3crd(51,55,379), Vec3crd(76,379,55), Vec3crd(24,197,378), Vec3crd(199,378,197), Vec3crd(122,201,389), Vec3crd(200,389,201), Vec3crd(333,379,202), Vec3crd(204,202,379), Vec3crd(205,388,207), Vec3crd(206,207,388), Vec3crd(365,27,388), Vec3crd(77,388,27), Vec3crd(162,378,121), Vec3crd(120,121,378), Vec3crd(162,30,25), Vec3crd(30,29,25), Vec3crd(51,53,54), Vec3crd(303,60,59), Vec3crd(28,29,33), Vec3crd(29,397,33), Vec3crd(161,58,52), Vec3crd(53,52,58), Vec3crd(21,84,19), Vec3crd(84,344,19), Vec3crd(46,49,43), Vec3crd(49,269,43), Vec3crd(208,316,209), Vec3crd(210,209,316), Vec3crd(327,313,211), Vec3crd(212,211,313), Vec3crd(36,35,369), Vec3crd(210,369,35), Vec3crd(37,158,368), Vec3crd(212,368,158), Vec3crd(6,8,313), Vec3crd(36,313,8), Vec3crd(326,38,316), Vec3crd(37,316,38), Vec3crd(392,391,398), Vec3crd(399,398,391), Vec3crd(394,400,395), Vec3crd(401,395,400), Vec3crd(390,214,391), Vec3crd(214,213,234), Vec3crd(393,395,218), Vec3crd(218,239,216), Vec3crd(402,230,403), Vec3crd(230,215,245), Vec3crd(125,124,131), Vec3crd(404,125,403), Vec3crd(405,406,231), Vec3crd(231,248,217), Vec3crd(129,137,127), Vec3crd(407,406,129), Vec3crd(130,127,139), Vec3crd(402,130,408), Vec3crd(194,195,331), Vec3crd(159,331,195), Vec3crd(115,189,56), Vec3crd(188,56,189), Vec3crd(14,219,220), Vec3crd(113,220,219), Vec3crd(45,50,366), Vec3crd(61,366,50), Vec3crd(221,366,222), Vec3crd(191,222,366), Vec3crd(17,23,219), Vec3crd(111,219,23), Vec3crd(118,198,24), Vec3crd(197,24,198), Vec3crd(202,203,333), Vec3crd(163,333,203), Vec3crd(40,224,225), Vec3crd(123,225,224), Vec3crd(12,13,365), Vec3crd(27,365,13), Vec3crd(22,365,223), Vec3crd(205,223,365), Vec3crd(42,44,224), Vec3crd(122,224,44), Vec3crd(399,391,234), Vec3crd(214,234,391), Vec3crd(401,239,395), Vec3crd(218,395,239), Vec3crd(214,390,226), Vec3crd(226,238,227), Vec3crd(218,228,393), Vec3crd(228,229,243), Vec3crd(401,399,233), Vec3crd(233,235,213), Vec3crd(392,409,390), Vec3crd(410,390,409), Vec3crd(394,393,411), Vec3crd(412,411,393), Vec3crd(402,403,131), Vec3crd(125,131,403), Vec3crd(405,137,406), Vec3crd(129,406,137), Vec3crd(405,408,139), Vec3crd(130,139,408), Vec3crd(230,245,403), Vec3crd(404,403,245), Vec3crd(231,406,248), Vec3crd(407,248,406), Vec3crd(232,254,216), Vec3crd(402,408,232), Vec3crd(413,404,244), Vec3crd(244,246,215), Vec3crd(414,247,407), Vec3crd(247,217,249), Vec3crd(133,126,136), Vec3crd(415,133,413), Vec3crd(141,143,128), Vec3crd(416,414,141), Vec3crd(410,238,390), Vec3crd(226,390,238), Vec3crd(412,393,243), Vec3crd(228,243,393), Vec3crd(233,399,235), Vec3crd(234,235,399), Vec3crd(237,260,236), Vec3crd(238,410,237), Vec3crd(417,260,410), Vec3crd(237,410,260), Vec3crd(239,401,240), Vec3crd(233,240,401), Vec3crd(242,241,257), Vec3crd(243,242,412), Vec3crd(418,412,257), Vec3crd(242,257,412), Vec3crd(401,419,399), Vec3crd(398,399,419), Vec3crd(417,410,420), Vec3crd(409,420,410), Vec3crd(400,421,401), Vec3crd(419,401,421), Vec3crd(418,422,412), Vec3crd(411,412,422), Vec3crd(413,135,404), Vec3crd(125,404,135), Vec3crd(414,407,142), Vec3crd(129,142,407), Vec3crd(130,402,132), Vec3crd(131,132,402), Vec3crd(133,136,413), Vec3crd(135,413,136), Vec3crd(423,147,415), Vec3crd(133,415,147), Vec3crd(137,405,138), Vec3crd(139,138,405), Vec3crd(141,414,143), Vec3crd(142,143,414), Vec3crd(424,416,144), Vec3crd(141,144,416), Vec3crd(405,254,408), Vec3crd(232,408,254), Vec3crd(244,404,246), Vec3crd(245,246,404), Vec3crd(247,249,407), Vec3crd(248,407,249), Vec3crd(232,250,402), Vec3crd(230,402,250), Vec3crd(415,413,251), Vec3crd(244,251,413), Vec3crd(252,236,266), Vec3crd(251,252,415), Vec3crd(423,415,266), Vec3crd(252,266,415), Vec3crd(231,253,405), Vec3crd(254,405,253), Vec3crd(416,255,414), Vec3crd(247,414,255), Vec3crd(256,263,241), Vec3crd(255,416,256), Vec3crd(424,263,416), Vec3crd(256,416,263), Vec3crd(257,258,418), Vec3crd(425,418,258), Vec3crd(260,417,261), Vec3crd(426,261,417), Vec3crd(422,418,427), Vec3crd(427,259,91), Vec3crd(420,428,417), Vec3crd(428,1,262), Vec3crd(147,423,148), Vec3crd(429,148,423), Vec3crd(263,424,264), Vec3crd(264,295,265), Vec3crd(266,267,423), Vec3crd(267,268,297), Vec3crd(144,145,424), Vec3crd(430,424,145), Vec3crd(49,431,269), Vec3crd(166,269,431), Vec3crd(82,431,83), Vec3crd(49,83,431), Vec3crd(84,85,431), Vec3crd(166,431,85), Vec3crd(82,344,431), Vec3crd(84,431,344), Vec3crd(432,278,90), Vec3crd(10,90,278), Vec3crd(433,0,281), Vec3crd(39,281,0), Vec3crd(362,361,434), Vec3crd(435,271,359), Vec3crd(270,359,271), Vec3crd(436,361,275), Vec3crd(273,275,361), Vec3crd(360,437,359), Vec3crd(277,287,276), Vec3crd(151,278,277), Vec3crd(280,279,289), Vec3crd(150,280,281), Vec3crd(436,438,439), Vec3crd(439,285,140), Vec3crd(90,92,432), Vec3crd(440,432,92), Vec3crd(282,272,291), Vec3crd(441,282,442), Vec3crd(284,293,274), Vec3crd(443,438,284), Vec3crd(278,432,286), Vec3crd(286,299,265), Vec3crd(281,288,433), Vec3crd(288,268,301), Vec3crd(0,433,89), Vec3crd(444,89,433), Vec3crd(435,445,442), Vec3crd(445,134,283), Vec3crd(439,446,436), Vec3crd(361,436,446), Vec3crd(442,290,435), Vec3crd(271,435,290), Vec3crd(438,436,292), Vec3crd(275,292,436), Vec3crd(445,435,447), Vec3crd(359,447,435), Vec3crd(286,287,278), Vec3crd(277,278,287), Vec3crd(288,281,289), Vec3crd(280,289,281), Vec3crd(145,152,430), Vec3crd(443,430,152), Vec3crd(148,429,154), Vec3crd(441,154,429), Vec3crd(424,430,294), Vec3crd(294,307,276), Vec3crd(423,296,429), Vec3crd(296,279,305), Vec3crd(425,440,100), Vec3crd(92,100,440), Vec3crd(290,442,291), Vec3crd(282,291,442), Vec3crd(292,293,438), Vec3crd(284,438,293), Vec3crd(298,320,241), Vec3crd(432,440,298), Vec3crd(300,236,322), Vec3crd(433,300,444), Vec3crd(426,101,444), Vec3crd(89,444,101), Vec3crd(107,448,302), Vec3crd(302,79,54), Vec3crd(78,31,343), Vec3crd(107,78,448), Vec3crd(75,79,448), Vec3crd(302,448,79), Vec3crd(78,343,448), Vec3crd(75,448,343), Vec3crd(427,418,259), Vec3crd(425,259,418), Vec3crd(428,262,417), Vec3crd(426,417,262), Vec3crd(437,449,359), Vec3crd(447,359,449), Vec3crd(434,361,450), Vec3crd(446,450,361), Vec3crd(32,33,397), Vec3crd(78,33,32), Vec3crd(53,303,54), Vec3crd(302,54,303), Vec3crd(152,153,443), Vec3crd(438,443,153), Vec3crd(429,304,441), Vec3crd(282,441,304), Vec3crd(430,443,306), Vec3crd(284,306,443), Vec3crd(154,441,155), Vec3crd(442,155,441), Vec3crd(298,299,432), Vec3crd(286,432,299), Vec3crd(300,433,301), Vec3crd(288,301,433), Vec3crd(185,451,308), Vec3crd(308,74,7), Vec3crd(73,15,337), Vec3crd(185,73,451), Vec3crd(35,74,451), Vec3crd(308,451,74), Vec3crd(73,337,451), Vec3crd(35,451,337), Vec3crd(158,452,310), Vec3crd(310,72,42), Vec3crd(70,22,341), Vec3crd(158,70,452), Vec3crd(66,72,452), Vec3crd(310,452,72), Vec3crd(70,341,452), Vec3crd(66,452,341), Vec3crd(313,327,314), Vec3crd(315,314,327), Vec3crd(316,317,326), Vec3crd(318,326,317), Vec3crd(15,156,311), Vec3crd(356,311,156), Vec3crd(7,312,157), Vec3crd(358,157,312), Vec3crd(211,9,327), Vec3crd(364,327,9), Vec3crd(38,326,94), Vec3crd(363,94,326), Vec3crd(294,295,424), Vec3crd(264,424,295), Vec3crd(296,423,297), Vec3crd(267,297,423), Vec3crd(262,149,426), Vec3crd(101,426,149), Vec3crd(258,319,425), Vec3crd(440,425,319), Vec3crd(261,426,321), Vec3crd(444,321,426), Vec3crd(259,425,146), Vec3crd(100,146,425), Vec3crd(306,307,430), Vec3crd(294,430,307), Vec3crd(304,429,305), Vec3crd(296,305,429), Vec3crd(319,320,440), Vec3crd(298,440,320), Vec3crd(321,444,322), Vec3crd(300,322,444), Vec3crd(445,283,442), Vec3crd(155,442,283), Vec3crd(439,438,285), Vec3crd(153,285,438), Vec3crd(17,68,18), Vec3crd(21,18,68), Vec3crd(46,184,47), Vec3crd(221,47,184), Vec3crd(102,95,363), Vec3crd(94,363,95), Vec3crd(9,11,364), Vec3crd(103,364,11), Vec3crd(6,323,357), Vec3crd(370,357,323), Vec3crd(371,324,355), Vec3crd(208,355,324), Vec3crd(270,363,325), Vec3crd(326,325,363), Vec3crd(327,364,328), Vec3crd(273,328,364), Vec3crd(0,2,39), Vec3crd(12,39,2), Vec3crd(90,93,91), Vec3crd(40,91,93), Vec3crd(14,16,17), Vec3crd(73,17,16), Vec3crd(45,309,7), Vec3crd(308,7,309), Vec3crd(12,71,39), Vec3crd(70,39,71), Vec3crd(40,41,42), Vec3crd(310,42,41), Vec3crd(97,98,63), Vec3crd(14,63,98), Vec3crd(3,5,7), Vec3crd(45,7,5), Vec3crd(118,377,329), Vec3crd(330,329,377), Vec3crd(331,372,332), Vec3crd(86,332,372), Vec3crd(333,376,334), Vec3crd(335,334,376), Vec3crd(115,373,336), Vec3crd(169,336,373), Vec3crd(167,166,380), Vec3crd(330,380,166), Vec3crd(80,81,382), Vec3crd(335,382,81), Vec3crd(86,385,81), Vec3crd(168,81,385), Vec3crd(169,384,82), Vec3crd(87,82,384), Vec3crd(159,88,372), Vec3crd(87,372,88), Vec3crd(163,164,376), Vec3crd(167,376,164), Vec3crd(24,26,377), Vec3crd(80,377,26), Vec3crd(56,57,373), Vec3crd(168,373,57), Vec3crd(32,397,30), Vec3crd(29,30,397), Vec3crd(58,60,53), Vec3crd(303,53,60), Vec3crd(205,181,119), Vec3crd(118,119,181), Vec3crd(163,175,165), Vec3crd(122,165,175), Vec3crd(453,454,455), Vec3crd(454,456,455), Vec3crd(457,455,456), Vec3crd(458,455,457), Vec3crd(459,455,458), Vec3crd(460,455,459), Vec3crd(461,462,463), Vec3crd(464,465,466), Vec3crd(467,468,469), Vec3crd(470,471,472), Vec3crd(465,473,474), Vec3crd(475,476,477), Vec3crd(478,479,480), Vec3crd(481,482,478), Vec3crd(483,484,481), Vec3crd(485,486,483), Vec3crd(487,488,485), Vec3crd(489,490,487), Vec3crd(491,492,489), Vec3crd(493,494,491), Vec3crd(495,496,493), Vec3crd(497,498,495), Vec3crd(499,500,497), Vec3crd(501,502,499), Vec3crd(503,504,501), Vec3crd(505,504,503), Vec3crd(506,504,505), Vec3crd(507,504,506), Vec3crd(508,504,507), Vec3crd(509,504,508), Vec3crd(510,504,509), Vec3crd(511,504,510), Vec3crd(512,504,511), Vec3crd(513,504,512), Vec3crd(514,504,513), Vec3crd(476,515,516), Vec3crd(517,518,519), Vec3crd(520,517,521), Vec3crd(518,522,523), Vec3crd(522,480,479), Vec3crd(524,525,526), Vec3crd(468,470,527), Vec3crd(525,467,528), Vec3crd(529,475,530), Vec3crd(531,532,533), Vec3crd(534,531,535), Vec3crd(536,537,538), Vec3crd(473,539,540), Vec3crd(539,536,541), Vec3crd(537,534,542), Vec3crd(471,520,543), Vec3crd(532,529,544), Vec3crd(545,524,546), Vec3crd(453,461,547), Vec3crd(463,464,548), Vec3crd(523,549,504), Vec3crd(527,550,551), Vec3crd(519,552,553), Vec3crd(521,554,555), Vec3crd(466,556,557), Vec3crd(469,558,559), Vec3crd(528,560,561), Vec3crd(477,562,563), Vec3crd(543,564,565), Vec3crd(535,566,567), Vec3crd(530,568,569), Vec3crd(540,570,571), Vec3crd(474,572,573), Vec3crd(542,574,575), Vec3crd(538,576,577), Vec3crd(541,578,579), Vec3crd(472,580,581), Vec3crd(526,582,583), Vec3crd(533,584,585), Vec3crd(544,586,587), Vec3crd(516,545,588), Vec3crd(588,589,590), Vec3crd(455,460,4), Vec3crd(591,592,63), Vec3crd(462,455,4), Vec3crd(592,547,63), Vec3crd(547,548,63), Vec3crd(465,462,4), Vec3crd(548,557,63), Vec3crd(127,124,501), Vec3crd(127,501,499), Vec3crd(505,503,124), Vec3crd(124,126,507), Vec3crd(124,507,506), Vec3crd(509,508,126), Vec3crd(126,134,512), Vec3crd(126,512,511), Vec3crd(510,509,126), Vec3crd(128,127,493), Vec3crd(128,493,491), Vec3crd(497,495,127), Vec3crd(489,487,128), Vec3crd(140,128,483), Vec3crd(140,483,481), Vec3crd(487,485,128), Vec3crd(478,480,140), Vec3crd(480,522,140), Vec3crd(514,513,134), Vec3crd(504,514,134), Vec3crd(551,581,437), Vec3crd(471,470,434), Vec3crd(445,447,555), Vec3crd(445,555,553), Vec3crd(134,445,553), Vec3crd(134,553,504), Vec3crd(446,439,518), Vec3crd(446,518,517), Vec3crd(439,140,522), Vec3crd(439,522,518), Vec3crd(515,476,358), Vec3crd(563,588,356), Vec3crd(557,573,63), Vec3crd(473,465,4), Vec3crd(437,360,559), Vec3crd(437,559,551), Vec3crd(360,371,561), Vec3crd(360,561,559), Vec3crd(362,434,470), Vec3crd(362,470,468), Vec3crd(370,362,468), Vec3crd(370,468,467), Vec3crd(499,497,127), Vec3crd(506,505,124), Vec3crd(495,493,127), Vec3crd(513,512,134), Vec3crd(481,478,140), Vec3crd(447,449,565), Vec3crd(447,565,555), Vec3crd(450,446,517), Vec3crd(450,517,520), Vec3crd(356,156,569), Vec3crd(356,569,563), Vec3crd(157,358,476), Vec3crd(157,476,475), Vec3crd(357,370,467), Vec3crd(357,467,525), Vec3crd(371,355,583), Vec3crd(371,583,561), Vec3crd(460,459,4), Vec3crd(63,62,593), Vec3crd(63,593,591), Vec3crd(62,4,459), Vec3crd(62,459,458), Vec3crd(532,531,104), Vec3crd(531,534,104), Vec3crd(567,585,105), Vec3crd(575,567,105), Vec3crd(4,3,539), Vec3crd(4,539,473), Vec3crd(536,539,3), Vec3crd(97,63,573), Vec3crd(97,573,571), Vec3crd(571,579,97), Vec3crd(99,97,579), Vec3crd(99,579,577), Vec3crd(105,99,577), Vec3crd(105,577,575), Vec3crd(96,104,534), Vec3crd(96,534,537), Vec3crd(3,96,537), Vec3crd(3,537,536), Vec3crd(503,501,124), Vec3crd(508,507,126), Vec3crd(491,489,128), Vec3crd(511,510,126), Vec3crd(485,483,128), Vec3crd(434,450,520), Vec3crd(434,520,471), Vec3crd(449,437,581), Vec3crd(449,581,565), Vec3crd(156,105,585), Vec3crd(156,585,587), Vec3crd(587,569,156), Vec3crd(104,157,529), Vec3crd(104,529,532), Vec3crd(475,529,157), Vec3crd(590,583,355), Vec3crd(355,356,588), Vec3crd(355,588,590), Vec3crd(358,357,524), Vec3crd(358,524,515), Vec3crd(525,524,357), Vec3crd(458,457,62), Vec3crd(457,593,62), Vec3crd(479,478,482), Vec3crd(479,504,549), Vec3crd(479,482,504), Vec3crd(482,481,484), Vec3crd(472,551,550), Vec3crd(581,551,472), Vec3crd(482,484,504), Vec3crd(484,483,486), Vec3crd(523,553,552), Vec3crd(504,553,523), Vec3crd(540,573,572), Vec3crd(571,573,540), Vec3crd(544,585,584), Vec3crd(587,585,544), Vec3crd(542,577,576), Vec3crd(575,577,542), Vec3crd(526,590,589), Vec3crd(583,590,526), Vec3crd(535,575,574), Vec3crd(567,575,535), Vec3crd(533,567,566), Vec3crd(585,567,533), Vec3crd(538,579,578), Vec3crd(577,579,538), Vec3crd(543,581,580), Vec3crd(565,581,543), Vec3crd(477,569,568), Vec3crd(563,569,477), Vec3crd(530,587,586), Vec3crd(569,587,530), Vec3crd(541,571,570), Vec3crd(579,571,541), Vec3crd(528,583,582), Vec3crd(561,583,528), Vec3crd(591,453,592), Vec3crd(547,592,453), Vec3crd(521,565,564), Vec3crd(555,565,521), Vec3crd(474,557,556), Vec3crd(573,557,474), Vec3crd(516,563,562), Vec3crd(588,563,516), Vec3crd(519,555,554), Vec3crd(553,555,519), Vec3crd(527,559,558), Vec3crd(551,559,527), Vec3crd(469,561,560), Vec3crd(559,561,469), Vec3crd(462,461,455), Vec3crd(453,455,461), Vec3crd(461,463,547), Vec3crd(548,547,463), Vec3crd(465,464,462), Vec3crd(463,462,464), Vec3crd(464,466,548), Vec3crd(557,548,466), Vec3crd(469,560,467), Vec3crd(528,467,560), Vec3crd(472,550,470), Vec3crd(527,470,550), Vec3crd(474,556,465), Vec3crd(466,465,556), Vec3crd(477,568,475), Vec3crd(530,475,568), Vec3crd(516,562,476), Vec3crd(477,476,562), Vec3crd(519,554,517), Vec3crd(521,517,554), Vec3crd(521,564,520), Vec3crd(543,520,564), Vec3crd(523,552,518), Vec3crd(519,518,552), Vec3crd(479,549,522), Vec3crd(523,522,549), Vec3crd(526,589,524), Vec3crd(589,546,524), Vec3crd(527,558,468), Vec3crd(469,468,558), Vec3crd(528,582,525), Vec3crd(526,525,582), Vec3crd(530,586,529), Vec3crd(544,529,586), Vec3crd(533,566,531), Vec3crd(535,531,566), Vec3crd(535,574,534), Vec3crd(542,534,574), Vec3crd(538,578,536), Vec3crd(541,536,578), Vec3crd(540,572,473), Vec3crd(474,473,572), Vec3crd(541,570,539), Vec3crd(540,539,570), Vec3crd(542,576,537), Vec3crd(538,537,576), Vec3crd(543,580,471), Vec3crd(472,471,580), Vec3crd(544,584,532), Vec3crd(533,532,584), Vec3crd(524,545,515), Vec3crd(516,515,545), Vec3crd(545,546,588), Vec3crd(589,588,546), Vec3crd(453,591,454), Vec3crd(593,454,591), Vec3crd(484,486,504), Vec3crd(486,485,488), Vec3crd(486,488,504), Vec3crd(488,487,490), Vec3crd(488,490,504), Vec3crd(490,489,492), Vec3crd(490,492,504), Vec3crd(492,491,494), Vec3crd(492,494,504), Vec3crd(494,493,496), Vec3crd(494,496,504), Vec3crd(496,495,498), Vec3crd(496,498,504), Vec3crd(498,497,500), Vec3crd(498,500,504), Vec3crd(500,499,502), Vec3crd(500,502,504), Vec3crd(501,504,502), Vec3crd(454,593,456), Vec3crd(457,456,593), Vec3crd(594,595,596), Vec3crd(597,598,594), Vec3crd(599,597,594), Vec3crd(600,599,594), Vec3crd(601,600,594), Vec3crd(602,601,594), Vec3crd(603,602,594), Vec3crd(604,603,594), Vec3crd(605,604,594), Vec3crd(606,607,608), Vec3crd(609,606,608), Vec3crd(610,609,608), Vec3crd(611,610,608), Vec3crd(612,611,608), Vec3crd(613,612,608), Vec3crd(614,613,608), Vec3crd(615,614,608), Vec3crd(616,615,608), Vec3crd(617,616,608), Vec3crd(618,617,608), Vec3crd(619,618,608), Vec3crd(620,619,608), Vec3crd(596,608,607), Vec3crd(595,594,598), Vec3crd(608,596,595), Vec3crd(605,594,91), Vec3crd(91,338,602), Vec3crd(91,602,603), Vec3crd(598,597,1), Vec3crd(594,596,91), Vec3crd(608,595,1), Vec3crd(595,598,1), Vec3crd(616,617,392), Vec3crd(610,611,394), Vec3crd(419,421,613), Vec3crd(419,613,614), Vec3crd(422,427,607), Vec3crd(422,607,606), Vec3crd(427,91,596), Vec3crd(427,596,607), Vec3crd(428,420,619), Vec3crd(428,619,620), Vec3crd(1,428,620), Vec3crd(1,620,608), Vec3crd(420,409,618), Vec3crd(420,618,619), Vec3crd(411,422,606), Vec3crd(411,606,609), Vec3crd(398,419,614), Vec3crd(398,614,615), Vec3crd(421,400,612), Vec3crd(421,612,613), Vec3crd(409,392,617), Vec3crd(409,617,618), Vec3crd(394,411,609), Vec3crd(394,609,610), Vec3crd(604,605,91), Vec3crd(338,1,599), Vec3crd(338,599,600), Vec3crd(392,398,615), Vec3crd(392,615,616), Vec3crd(400,394,611), Vec3crd(400,611,612), Vec3crd(603,604,91), Vec3crd(601,602,338), Vec3crd(597,599,1), Vec3crd(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) - }); - facets = std::vector({ - Vec3crd(0,1,2), Vec3crd(0,3,1), Vec3crd(0,4,3), Vec3crd(5,6,7), Vec3crd(8,6,5), Vec3crd(2,9,0), Vec3crd(6,10,11), Vec3crd(12,13,14), Vec3crd(15,16,17), Vec3crd(18,16,15), Vec3crd(19,20,21), Vec3crd(22,23,24), Vec3crd(25,23,22), Vec3crd(26,23,25), Vec3crd(27,23,26), Vec3crd(28,23,27), Vec3crd(29,30,31), Vec3crd(29,32,30), Vec3crd(29,28,32), Vec3crd(33,28,29), Vec3crd(33,23,28), Vec3crd(21,23,33), Vec3crd(20,23,21), Vec3crd(34,35,36), Vec3crd(37,35,34), Vec3crd(38,35,37), Vec3crd(39,35,38), Vec3crd(40,35,39), Vec3crd(41,35,40), Vec3crd(42,35,41), Vec3crd(43,35,42), Vec3crd(44,35,43), Vec3crd(45,35,44), Vec3crd(46,35,45), Vec3crd(47,35,46), Vec3crd(48,35,47), Vec3crd(49,50,51), Vec3crd(52,48,47), Vec3crd(23,49,24), Vec3crd(53,54,55), Vec3crd(56,57,58), Vec3crd(59,57,56), Vec3crd(60,57,59), Vec3crd(61,57,60), Vec3crd(62,57,61), Vec3crd(63,57,62), Vec3crd(64,57,63), Vec3crd(65,57,64), Vec3crd(66,57,65), Vec3crd(13,57,66), Vec3crd(54,67,55), Vec3crd(68,69,70), Vec3crd(71,69,68), Vec3crd(72,69,71), Vec3crd(73,69,72), Vec3crd(74,69,73), Vec3crd(75,69,74), Vec3crd(76,69,75), Vec3crd(77,69,76), Vec3crd(67,69,77), Vec3crd(70,16,68), Vec3crd(70,17,16), Vec3crd(78,79,80), Vec3crd(81,79,78), Vec3crd(82,79,81), Vec3crd(83,79,82), Vec3crd(84,79,83), Vec3crd(85,79,84), Vec3crd(86,79,85), Vec3crd(87,79,86), Vec3crd(88,8,5), Vec3crd(11,7,6), Vec3crd(11,89,7), Vec3crd(11,9,89), Vec3crd(11,0,9), Vec3crd(55,90,53), Vec3crd(55,79,90), Vec3crd(55,80,79), Vec3crd(91,11,10), Vec3crd(92,69,12), Vec3crd(92,70,69), Vec3crd(34,93,37), Vec3crd(47,94,52), Vec3crd(47,95,94), Vec3crd(47,57,95), Vec3crd(47,58,57), Vec3crd(51,24,49), Vec3crd(21,35,19), Vec3crd(21,36,35), Vec3crd(14,92,12), Vec3crd(86,10,87), Vec3crd(86,91,10), Vec3crd(77,55,67), Vec3crd(66,14,13), Vec3crd(96,97,4), Vec3crd(98,99,100), Vec3crd(101,102,98), Vec3crd(103,101,98), Vec3crd(104,103,98), Vec3crd(105,106,107), Vec3crd(108,105,107), Vec3crd(109,108,107), Vec3crd(100,109,107), Vec3crd(110,111,112), Vec3crd(113,110,112), Vec3crd(114,115,116), Vec3crd(117,114,116), Vec3crd(118,119,120), Vec3crd(121,122,123), Vec3crd(124,121,123), Vec3crd(125,126,127), Vec3crd(128,129,130), Vec3crd(131,132,133), Vec3crd(71,131,133), Vec3crd(134,71,133), Vec3crd(135,134,133), Vec3crd(136,135,133), Vec3crd(137,138,139), Vec3crd(140,137,139), Vec3crd(141,140,139), Vec3crd(142,31,141), Vec3crd(142,141,139), Vec3crd(143,126,132), Vec3crd(144,145,146), Vec3crd(147,144,146), Vec3crd(127,147,146), Vec3crd(148,121,124), Vec3crd(149,148,124), Vec3crd(150,149,124), Vec3crd(151,150,124), Vec3crd(152,151,124), Vec3crd(153,152,124), Vec3crd(154,153,124), Vec3crd(155,154,124), Vec3crd(129,156,157), Vec3crd(130,129,157), Vec3crd(158,159,160), Vec3crd(161,158,160), Vec3crd(162,161,160), Vec3crd(163,162,160), Vec3crd(146,163,160), Vec3crd(164,165,166), Vec3crd(167,164,166), Vec3crd(168,169,170), Vec3crd(171,168,170), Vec3crd(139,171,170), Vec3crd(159,172,173), Vec3crd(123,174,142), Vec3crd(175,110,113), Vec3crd(173,175,113), Vec3crd(106,176,177), Vec3crd(178,106,177), Vec3crd(179,180,167), Vec3crd(112,179,167), Vec3crd(175,173,172), Vec3crd(119,118,181), Vec3crd(119,181,97), Vec3crd(119,97,96), Vec3crd(182,98,102), Vec3crd(182,102,183), Vec3crd(182,183,120), Vec3crd(182,120,119), Vec3crd(143,132,184), Vec3crd(184,185,143), Vec3crd(147,127,126), Vec3crd(174,123,122), Vec3crd(159,173,160), Vec3crd(126,125,133), Vec3crd(126,133,132), Vec3crd(186,187,188), Vec3crd(186,188,116), Vec3crd(186,116,115), Vec3crd(99,98,182), Vec3crd(109,100,99), Vec3crd(106,178,107), Vec3crd(114,117,177), Vec3crd(114,177,176), Vec3crd(128,130,187), Vec3crd(128,187,186), Vec3crd(135,136,157), Vec3crd(135,157,156), Vec3crd(163,146,145), Vec3crd(164,167,180), Vec3crd(179,112,111), Vec3crd(171,139,138), Vec3crd(189,155,166), Vec3crd(189,166,165), Vec3crd(149,150,93), Vec3crd(154,155,189), Vec3crd(31,142,174), Vec3crd(114,176,78), Vec3crd(81,78,176), Vec3crd(7,89,183), Vec3crd(89,9,120), Vec3crd(89,120,183), Vec3crd(78,80,114), Vec3crd(176,106,81), Vec3crd(88,5,103), Vec3crd(183,102,7), Vec3crd(118,120,9), Vec3crd(9,2,181), Vec3crd(9,181,118), Vec3crd(115,114,80), Vec3crd(82,81,106), Vec3crd(101,103,5), Vec3crd(102,101,5), Vec3crd(5,7,102), Vec3crd(97,181,2), Vec3crd(2,1,97), Vec3crd(1,3,97), Vec3crd(80,55,115), Vec3crd(172,159,59), Vec3crd(59,56,172), Vec3crd(3,4,97), Vec3crd(4,0,96), Vec3crd(105,108,82), Vec3crd(186,115,55), Vec3crd(82,106,105), Vec3crd(83,82,108), Vec3crd(60,59,159), Vec3crd(175,172,56), Vec3crd(119,96,0), Vec3crd(0,11,119), Vec3crd(108,109,84), Vec3crd(84,83,108), Vec3crd(55,77,186), Vec3crd(56,58,110), Vec3crd(56,110,175), Vec3crd(60,159,158), Vec3crd(11,91,182), Vec3crd(182,119,11), Vec3crd(91,86,182), Vec3crd(85,84,109), Vec3crd(86,85,99), Vec3crd(128,186,77), Vec3crd(58,111,110), Vec3crd(158,161,60), Vec3crd(26,25,137), Vec3crd(138,137,25), Vec3crd(99,182,86), Vec3crd(109,99,85), Vec3crd(77,76,128), Vec3crd(58,47,111), Vec3crd(61,60,161), Vec3crd(137,140,26), Vec3crd(27,26,140), Vec3crd(25,22,138), Vec3crd(129,128,76), Vec3crd(76,75,129), Vec3crd(75,74,129), Vec3crd(74,73,156), Vec3crd(73,72,135), Vec3crd(68,16,184), Vec3crd(68,184,132), Vec3crd(16,18,185), Vec3crd(161,162,62), Vec3crd(62,61,161), Vec3crd(179,111,47), Vec3crd(171,138,22), Vec3crd(156,129,74), Vec3crd(135,156,73), Vec3crd(134,135,72), Vec3crd(72,71,134), Vec3crd(68,132,131), Vec3crd(185,184,16), Vec3crd(18,15,185), Vec3crd(63,62,162), Vec3crd(28,27,140), Vec3crd(22,24,171), Vec3crd(71,68,131), Vec3crd(15,17,143), Vec3crd(15,143,185), Vec3crd(17,70,143), Vec3crd(70,92,126), Vec3crd(162,163,64), Vec3crd(64,63,162), Vec3crd(180,179,47), Vec3crd(47,46,180), Vec3crd(140,141,28), Vec3crd(168,171,24), Vec3crd(126,143,70), Vec3crd(92,14,147), Vec3crd(147,126,92), Vec3crd(14,66,144), Vec3crd(14,144,147), Vec3crd(65,64,163), Vec3crd(66,65,145), Vec3crd(46,45,180), Vec3crd(32,28,141), Vec3crd(24,51,168), Vec3crd(145,144,66), Vec3crd(163,145,65), Vec3crd(164,180,45), Vec3crd(45,44,164), Vec3crd(44,43,164), Vec3crd(43,42,165), Vec3crd(38,37,151), Vec3crd(150,151,37), Vec3crd(37,93,150), Vec3crd(141,31,30), Vec3crd(30,32,141), Vec3crd(169,168,51), Vec3crd(165,164,43), Vec3crd(189,165,42), Vec3crd(42,41,189), Vec3crd(40,39,152), Vec3crd(40,152,153), Vec3crd(151,152,39), Vec3crd(39,38,151), Vec3crd(93,34,149), Vec3crd(154,189,41), Vec3crd(153,154,41), Vec3crd(41,40,153), Vec3crd(148,149,34), Vec3crd(34,36,148), Vec3crd(36,21,121), Vec3crd(31,174,29), Vec3crd(121,148,36), Vec3crd(21,33,122), Vec3crd(21,122,121), Vec3crd(33,29,122), Vec3crd(174,122,29), Vec3crd(116,188,53), Vec3crd(104,98,10), Vec3crd(87,10,98), Vec3crd(98,100,87), Vec3crd(79,87,100), Vec3crd(79,100,107), Vec3crd(90,79,107), Vec3crd(90,107,178), Vec3crd(178,177,90), Vec3crd(53,90,177), Vec3crd(53,177,117), Vec3crd(117,116,53), Vec3crd(54,53,188), Vec3crd(54,188,187), Vec3crd(67,54,187), Vec3crd(67,187,130), Vec3crd(69,67,130), Vec3crd(69,130,157), Vec3crd(12,69,157), Vec3crd(12,157,136), Vec3crd(136,133,12), Vec3crd(12,133,125), Vec3crd(125,127,12), Vec3crd(13,12,127), Vec3crd(127,146,13), Vec3crd(57,13,146), Vec3crd(57,146,160), Vec3crd(95,57,160), Vec3crd(95,160,173), Vec3crd(173,113,95), Vec3crd(94,95,113), Vec3crd(113,112,94), Vec3crd(52,94,112), Vec3crd(48,52,112), Vec3crd(112,167,48), Vec3crd(35,48,167), Vec3crd(35,167,166), Vec3crd(19,35,166), Vec3crd(139,170,50), Vec3crd(50,49,139), Vec3crd(166,155,19), Vec3crd(20,19,155), Vec3crd(155,124,20), Vec3crd(23,20,124), Vec3crd(23,124,123), Vec3crd(49,23,123), Vec3crd(49,123,142), Vec3crd(142,139,49), Vec3crd(190,191,170), Vec3crd(192,191,190), Vec3crd(191,192,51), Vec3crd(191,51,50), Vec3crd(170,169,190), Vec3crd(169,51,192), Vec3crd(169,192,190), Vec3crd(170,191,50), Vec3crd(193,194,195), Vec3crd(196,197,198), Vec3crd(199,200,201), Vec3crd(198,202,203), Vec3crd(204,201,200), Vec3crd(205,204,200), Vec3crd(206,207,208), Vec3crd(206,208,205), Vec3crd(206,205,200), Vec3crd(207,206,209), Vec3crd(207,209,203), Vec3crd(207,203,202), Vec3crd(202,198,197), Vec3crd(197,196,210), Vec3crd(197,210,195), Vec3crd(197,195,194), Vec3crd(8,88,195), Vec3crd(8,195,210), Vec3crd(210,196,8), Vec3crd(196,198,8), Vec3crd(198,203,8), Vec3crd(203,209,8), Vec3crd(209,206,8), Vec3crd(206,200,8), Vec3crd(202,197,104), Vec3crd(207,202,104), Vec3crd(103,104,197), Vec3crd(103,197,194), Vec3crd(193,195,88), Vec3crd(88,103,194), Vec3crd(88,194,193), Vec3crd(200,199,8), Vec3crd(199,201,8), Vec3crd(204,205,6), Vec3crd(6,8,201), Vec3crd(6,201,204), Vec3crd(10,6,205), Vec3crd(10,205,208), Vec3crd(104,10,208), Vec3crd(104,208,207) - }); + mesh = TriangleMesh( + { 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) }, + { Vec3crd(0,1,2), Vec3crd(0,3,1), Vec3crd(0,4,3), Vec3crd(5,6,7), Vec3crd(8,6,5), Vec3crd(2,9,0), Vec3crd(6,10,11), Vec3crd(12,13,14), Vec3crd(15,16,17), Vec3crd(18,16,15), Vec3crd(19,20,21), Vec3crd(22,23,24), Vec3crd(25,23,22), Vec3crd(26,23,25), Vec3crd(27,23,26), Vec3crd(28,23,27), Vec3crd(29,30,31), Vec3crd(29,32,30), Vec3crd(29,28,32), Vec3crd(33,28,29), Vec3crd(33,23,28), Vec3crd(21,23,33), Vec3crd(20,23,21), Vec3crd(34,35,36), Vec3crd(37,35,34), Vec3crd(38,35,37), Vec3crd(39,35,38), Vec3crd(40,35,39), Vec3crd(41,35,40), Vec3crd(42,35,41), Vec3crd(43,35,42), Vec3crd(44,35,43), Vec3crd(45,35,44), Vec3crd(46,35,45), Vec3crd(47,35,46), Vec3crd(48,35,47), Vec3crd(49,50,51), Vec3crd(52,48,47), Vec3crd(23,49,24), Vec3crd(53,54,55), Vec3crd(56,57,58), Vec3crd(59,57,56), Vec3crd(60,57,59), Vec3crd(61,57,60), Vec3crd(62,57,61), Vec3crd(63,57,62), Vec3crd(64,57,63), Vec3crd(65,57,64), Vec3crd(66,57,65), Vec3crd(13,57,66), Vec3crd(54,67,55), Vec3crd(68,69,70), Vec3crd(71,69,68), Vec3crd(72,69,71), Vec3crd(73,69,72), Vec3crd(74,69,73), Vec3crd(75,69,74), Vec3crd(76,69,75), Vec3crd(77,69,76), Vec3crd(67,69,77), Vec3crd(70,16,68), Vec3crd(70,17,16), Vec3crd(78,79,80), Vec3crd(81,79,78), Vec3crd(82,79,81), Vec3crd(83,79,82), Vec3crd(84,79,83), Vec3crd(85,79,84), Vec3crd(86,79,85), Vec3crd(87,79,86), Vec3crd(88,8,5), Vec3crd(11,7,6), Vec3crd(11,89,7), Vec3crd(11,9,89), Vec3crd(11,0,9), Vec3crd(55,90,53), Vec3crd(55,79,90), Vec3crd(55,80,79), Vec3crd(91,11,10), Vec3crd(92,69,12), Vec3crd(92,70,69), Vec3crd(34,93,37), Vec3crd(47,94,52), Vec3crd(47,95,94), Vec3crd(47,57,95), Vec3crd(47,58,57), Vec3crd(51,24,49), Vec3crd(21,35,19), Vec3crd(21,36,35), Vec3crd(14,92,12), Vec3crd(86,10,87), Vec3crd(86,91,10), Vec3crd(77,55,67), Vec3crd(66,14,13), Vec3crd(96,97,4), Vec3crd(98,99,100), Vec3crd(101,102,98), Vec3crd(103,101,98), Vec3crd(104,103,98), Vec3crd(105,106,107), Vec3crd(108,105,107), Vec3crd(109,108,107), Vec3crd(100,109,107), Vec3crd(110,111,112), Vec3crd(113,110,112), Vec3crd(114,115,116), Vec3crd(117,114,116), Vec3crd(118,119,120), Vec3crd(121,122,123), Vec3crd(124,121,123), Vec3crd(125,126,127), Vec3crd(128,129,130), Vec3crd(131,132,133), Vec3crd(71,131,133), Vec3crd(134,71,133), Vec3crd(135,134,133), Vec3crd(136,135,133), Vec3crd(137,138,139), Vec3crd(140,137,139), Vec3crd(141,140,139), Vec3crd(142,31,141), Vec3crd(142,141,139), Vec3crd(143,126,132), Vec3crd(144,145,146), Vec3crd(147,144,146), Vec3crd(127,147,146), Vec3crd(148,121,124), Vec3crd(149,148,124), Vec3crd(150,149,124), Vec3crd(151,150,124), Vec3crd(152,151,124), Vec3crd(153,152,124), Vec3crd(154,153,124), Vec3crd(155,154,124), Vec3crd(129,156,157), Vec3crd(130,129,157), Vec3crd(158,159,160), Vec3crd(161,158,160), Vec3crd(162,161,160), Vec3crd(163,162,160), Vec3crd(146,163,160), Vec3crd(164,165,166), Vec3crd(167,164,166), Vec3crd(168,169,170), Vec3crd(171,168,170), Vec3crd(139,171,170), Vec3crd(159,172,173), Vec3crd(123,174,142), Vec3crd(175,110,113), Vec3crd(173,175,113), Vec3crd(106,176,177), Vec3crd(178,106,177), Vec3crd(179,180,167), Vec3crd(112,179,167), Vec3crd(175,173,172), Vec3crd(119,118,181), Vec3crd(119,181,97), Vec3crd(119,97,96), Vec3crd(182,98,102), Vec3crd(182,102,183), Vec3crd(182,183,120), Vec3crd(182,120,119), Vec3crd(143,132,184), Vec3crd(184,185,143), Vec3crd(147,127,126), Vec3crd(174,123,122), Vec3crd(159,173,160), Vec3crd(126,125,133), Vec3crd(126,133,132), Vec3crd(186,187,188), Vec3crd(186,188,116), Vec3crd(186,116,115), Vec3crd(99,98,182), Vec3crd(109,100,99), Vec3crd(106,178,107), Vec3crd(114,117,177), Vec3crd(114,177,176), Vec3crd(128,130,187), Vec3crd(128,187,186), Vec3crd(135,136,157), Vec3crd(135,157,156), Vec3crd(163,146,145), Vec3crd(164,167,180), Vec3crd(179,112,111), Vec3crd(171,139,138), Vec3crd(189,155,166), Vec3crd(189,166,165), Vec3crd(149,150,93), Vec3crd(154,155,189), Vec3crd(31,142,174), Vec3crd(114,176,78), Vec3crd(81,78,176), Vec3crd(7,89,183), Vec3crd(89,9,120), Vec3crd(89,120,183), Vec3crd(78,80,114), Vec3crd(176,106,81), Vec3crd(88,5,103), Vec3crd(183,102,7), Vec3crd(118,120,9), Vec3crd(9,2,181), Vec3crd(9,181,118), Vec3crd(115,114,80), Vec3crd(82,81,106), Vec3crd(101,103,5), Vec3crd(102,101,5), Vec3crd(5,7,102), Vec3crd(97,181,2), Vec3crd(2,1,97), Vec3crd(1,3,97), Vec3crd(80,55,115), Vec3crd(172,159,59), Vec3crd(59,56,172), Vec3crd(3,4,97), Vec3crd(4,0,96), Vec3crd(105,108,82), Vec3crd(186,115,55), Vec3crd(82,106,105), Vec3crd(83,82,108), Vec3crd(60,59,159), Vec3crd(175,172,56), Vec3crd(119,96,0), Vec3crd(0,11,119), Vec3crd(108,109,84), Vec3crd(84,83,108), Vec3crd(55,77,186), Vec3crd(56,58,110), Vec3crd(56,110,175), Vec3crd(60,159,158), Vec3crd(11,91,182), Vec3crd(182,119,11), Vec3crd(91,86,182), Vec3crd(85,84,109), Vec3crd(86,85,99), Vec3crd(128,186,77), Vec3crd(58,111,110), Vec3crd(158,161,60), Vec3crd(26,25,137), Vec3crd(138,137,25), Vec3crd(99,182,86), Vec3crd(109,99,85), Vec3crd(77,76,128), Vec3crd(58,47,111), Vec3crd(61,60,161), Vec3crd(137,140,26), Vec3crd(27,26,140), Vec3crd(25,22,138), Vec3crd(129,128,76), Vec3crd(76,75,129), Vec3crd(75,74,129), Vec3crd(74,73,156), Vec3crd(73,72,135), Vec3crd(68,16,184), Vec3crd(68,184,132), Vec3crd(16,18,185), Vec3crd(161,162,62), Vec3crd(62,61,161), Vec3crd(179,111,47), Vec3crd(171,138,22), Vec3crd(156,129,74), Vec3crd(135,156,73), Vec3crd(134,135,72), Vec3crd(72,71,134), Vec3crd(68,132,131), Vec3crd(185,184,16), Vec3crd(18,15,185), Vec3crd(63,62,162), Vec3crd(28,27,140), Vec3crd(22,24,171), Vec3crd(71,68,131), Vec3crd(15,17,143), Vec3crd(15,143,185), Vec3crd(17,70,143), Vec3crd(70,92,126), Vec3crd(162,163,64), Vec3crd(64,63,162), Vec3crd(180,179,47), Vec3crd(47,46,180), Vec3crd(140,141,28), Vec3crd(168,171,24), Vec3crd(126,143,70), Vec3crd(92,14,147), Vec3crd(147,126,92), Vec3crd(14,66,144), Vec3crd(14,144,147), Vec3crd(65,64,163), Vec3crd(66,65,145), Vec3crd(46,45,180), Vec3crd(32,28,141), Vec3crd(24,51,168), Vec3crd(145,144,66), Vec3crd(163,145,65), Vec3crd(164,180,45), Vec3crd(45,44,164), Vec3crd(44,43,164), Vec3crd(43,42,165), Vec3crd(38,37,151), Vec3crd(150,151,37), Vec3crd(37,93,150), Vec3crd(141,31,30), Vec3crd(30,32,141), Vec3crd(169,168,51), Vec3crd(165,164,43), Vec3crd(189,165,42), Vec3crd(42,41,189), Vec3crd(40,39,152), Vec3crd(40,152,153), Vec3crd(151,152,39), Vec3crd(39,38,151), Vec3crd(93,34,149), Vec3crd(154,189,41), Vec3crd(153,154,41), Vec3crd(41,40,153), Vec3crd(148,149,34), Vec3crd(34,36,148), Vec3crd(36,21,121), Vec3crd(31,174,29), Vec3crd(121,148,36), Vec3crd(21,33,122), Vec3crd(21,122,121), Vec3crd(33,29,122), Vec3crd(174,122,29), Vec3crd(116,188,53), Vec3crd(104,98,10), Vec3crd(87,10,98), Vec3crd(98,100,87), Vec3crd(79,87,100), Vec3crd(79,100,107), Vec3crd(90,79,107), Vec3crd(90,107,178), Vec3crd(178,177,90), Vec3crd(53,90,177), Vec3crd(53,177,117), Vec3crd(117,116,53), Vec3crd(54,53,188), Vec3crd(54,188,187), Vec3crd(67,54,187), Vec3crd(67,187,130), Vec3crd(69,67,130), Vec3crd(69,130,157), Vec3crd(12,69,157), Vec3crd(12,157,136), Vec3crd(136,133,12), Vec3crd(12,133,125), Vec3crd(125,127,12), Vec3crd(13,12,127), Vec3crd(127,146,13), Vec3crd(57,13,146), Vec3crd(57,146,160), Vec3crd(95,57,160), Vec3crd(95,160,173), Vec3crd(173,113,95), Vec3crd(94,95,113), Vec3crd(113,112,94), Vec3crd(52,94,112), Vec3crd(48,52,112), Vec3crd(112,167,48), Vec3crd(35,48,167), Vec3crd(35,167,166), Vec3crd(19,35,166), Vec3crd(139,170,50), Vec3crd(50,49,139), Vec3crd(166,155,19), Vec3crd(20,19,155), Vec3crd(155,124,20), Vec3crd(23,20,124), Vec3crd(23,124,123), Vec3crd(49,23,123), Vec3crd(49,123,142), Vec3crd(142,139,49), Vec3crd(190,191,170), Vec3crd(192,191,190), Vec3crd(191,192,51), Vec3crd(191,51,50), Vec3crd(170,169,190), Vec3crd(169,51,192), Vec3crd(169,192,190), Vec3crd(170,191,50), Vec3crd(193,194,195), Vec3crd(196,197,198), Vec3crd(199,200,201), Vec3crd(198,202,203), Vec3crd(204,201,200), Vec3crd(205,204,200), Vec3crd(206,207,208), Vec3crd(206,208,205), Vec3crd(206,205,200), Vec3crd(207,206,209), Vec3crd(207,209,203), Vec3crd(207,203,202), Vec3crd(202,198,197), Vec3crd(197,196,210), Vec3crd(197,210,195), Vec3crd(197,195,194), Vec3crd(8,88,195), Vec3crd(8,195,210), Vec3crd(210,196,8), Vec3crd(196,198,8), Vec3crd(198,203,8), Vec3crd(203,209,8), Vec3crd(209,206,8), Vec3crd(206,200,8), Vec3crd(202,197,104), Vec3crd(207,202,104), Vec3crd(103,104,197), Vec3crd(103,197,194), Vec3crd(193,195,88), Vec3crd(88,103,194), Vec3crd(88,194,193), Vec3crd(200,199,8), Vec3crd(199,201,8), Vec3crd(204,205,6), Vec3crd(6,8,201), Vec3crd(6,201,204), Vec3crd(10,6,205), Vec3crd(10,205,208), Vec3crd(104,10,208), Vec3crd(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) - }); - facets = std::vector({ - Vec3crd(0,1,2), Vec3crd(0,3,4), Vec3crd(3,1,4), Vec3crd(1,3,2), Vec3crd(3,0,2), Vec3crd(4,1,0) - }); + mesh = TriangleMesh( + { Vec3d(10,10,40), Vec3d(0,0,0), Vec3d(20,0,0), Vec3d(20,20,0), Vec3d(0,20,0) }, + { Vec3crd(0,1,2), Vec3crd(0,3,4), Vec3crd(3,1,4), Vec3crd(1,3,2), Vec3crd(3,0,2), Vec3crd(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) - }); - facets = std::vector({ - Vec3crd(0,1,2), Vec3crd(3,4,5), Vec3crd(6,4,0), Vec3crd(6,0,2), Vec3crd(2,1,5), Vec3crd(7,4,3), Vec3crd(1,3,5), Vec3crd(0,4,7), Vec3crd(4,6,8), Vec3crd(6,9,8), Vec3crd(4,8,10), Vec3crd(6,2,9), Vec3crd(2,11,9), Vec3crd(2,12,11), Vec3crd(2,5,12), Vec3crd(5,13,12), Vec3crd(5,14,13), Vec3crd(4,10,15), Vec3crd(5,4,14), Vec3crd(4,15,14), Vec3crd(7,16,17), Vec3crd(0,7,18), Vec3crd(7,17,18), Vec3crd(1,19,20), Vec3crd(1,0,19), Vec3crd(0,18,19), Vec3crd(7,3,21), Vec3crd(3,22,21), Vec3crd(7,21,16), Vec3crd(3,23,22), Vec3crd(3,1,23), Vec3crd(1,20,23), Vec3crd(24,25,26), Vec3crd(25,27,26), Vec3crd(25,28,27), Vec3crd(29,24,30), Vec3crd(24,31,30), Vec3crd(24,26,31), Vec3crd(32,29,33), Vec3crd(29,30,33), Vec3crd(32,33,34), Vec3crd(32,34,35), Vec3crd(25,32,28), Vec3crd(32,35,28), Vec3crd(36,37,24), Vec3crd(38,32,25), Vec3crd(29,32,36), Vec3crd(29,36,24), Vec3crd(24,37,25), Vec3crd(39,32,38), Vec3crd(37,38,25), Vec3crd(36,32,39), Vec3crd(39,40,41), Vec3crd(36,39,42), Vec3crd(39,41,42), Vec3crd(37,43,44), Vec3crd(37,36,43), Vec3crd(36,42,43), Vec3crd(39,38,45), Vec3crd(38,46,45), Vec3crd(39,45,40), Vec3crd(38,47,46), Vec3crd(38,37,47), Vec3crd(37,44,47), Vec3crd(16,8,9), Vec3crd(16,10,8), Vec3crd(10,16,15), Vec3crd(15,16,21), Vec3crd(22,15,21), Vec3crd(15,22,14), Vec3crd(22,23,14), Vec3crd(23,20,14), Vec3crd(17,16,9), Vec3crd(18,17,9), Vec3crd(19,18,9), Vec3crd(19,9,11), Vec3crd(19,11,20), Vec3crd(13,14,20), Vec3crd(20,11,12), Vec3crd(13,20,12), Vec3crd(41,40,30), Vec3crd(42,41,30), Vec3crd(43,42,30), Vec3crd(43,30,31), Vec3crd(43,31,44), Vec3crd(27,28,44), Vec3crd(44,31,26), Vec3crd(27,44,26), Vec3crd(40,33,30), Vec3crd(40,34,33), Vec3crd(34,40,35), Vec3crd(35,40,45), Vec3crd(46,35,45), Vec3crd(35,46,28), Vec3crd(46,47,28), Vec3crd(47,44,28) , - }); + mesh = TriangleMesh( + { 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) }, + { Vec3crd(0,1,2), Vec3crd(3,4,5), Vec3crd(6,4,0), Vec3crd(6,0,2), Vec3crd(2,1,5), Vec3crd(7,4,3), Vec3crd(1,3,5), Vec3crd(0,4,7), Vec3crd(4,6,8), Vec3crd(6,9,8), Vec3crd(4,8,10), Vec3crd(6,2,9), Vec3crd(2,11,9), Vec3crd(2,12,11), Vec3crd(2,5,12), Vec3crd(5,13,12), Vec3crd(5,14,13), Vec3crd(4,10,15), Vec3crd(5,4,14), Vec3crd(4,15,14), Vec3crd(7,16,17), Vec3crd(0,7,18), Vec3crd(7,17,18), Vec3crd(1,19,20), Vec3crd(1,0,19), Vec3crd(0,18,19), Vec3crd(7,3,21), Vec3crd(3,22,21), Vec3crd(7,21,16), Vec3crd(3,23,22), Vec3crd(3,1,23), Vec3crd(1,20,23), Vec3crd(24,25,26), Vec3crd(25,27,26), Vec3crd(25,28,27), Vec3crd(29,24,30), Vec3crd(24,31,30), Vec3crd(24,26,31), Vec3crd(32,29,33), Vec3crd(29,30,33), Vec3crd(32,33,34), Vec3crd(32,34,35), Vec3crd(25,32,28), Vec3crd(32,35,28), Vec3crd(36,37,24), Vec3crd(38,32,25), Vec3crd(29,32,36), Vec3crd(29,36,24), Vec3crd(24,37,25), Vec3crd(39,32,38), Vec3crd(37,38,25), Vec3crd(36,32,39), Vec3crd(39,40,41), Vec3crd(36,39,42), Vec3crd(39,41,42), Vec3crd(37,43,44), Vec3crd(37,36,43), Vec3crd(36,42,43), Vec3crd(39,38,45), Vec3crd(38,46,45), Vec3crd(39,45,40), Vec3crd(38,47,46), Vec3crd(38,37,47), Vec3crd(37,44,47), Vec3crd(16,8,9), Vec3crd(16,10,8), Vec3crd(10,16,15), Vec3crd(15,16,21), Vec3crd(22,15,21), Vec3crd(15,22,14), Vec3crd(22,23,14), Vec3crd(23,20,14), Vec3crd(17,16,9), Vec3crd(18,17,9), Vec3crd(19,18,9), Vec3crd(19,9,11), Vec3crd(19,11,20), Vec3crd(13,14,20), Vec3crd(20,11,12), Vec3crd(13,20,12), Vec3crd(41,40,30), Vec3crd(42,41,30), Vec3crd(43,42,30), Vec3crd(43,30,31), Vec3crd(43,31,44), Vec3crd(27,28,44), Vec3crd(44,31,26), Vec3crd(27,44,26), Vec3crd(40,33,30), Vec3crd(40,34,33), Vec3crd(34,40,35), Vec3crd(35,40,45), Vec3crd(46,35,45), Vec3crd(35,46,28), Vec3crd(46,47,28), Vec3crd(47,44,28) }); 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) - }); - facets = std::vector({ - Vec3crd(0,1,2), Vec3crd(3,4,5), Vec3crd(2,1,4), Vec3crd(2,4,3), Vec3crd(2,3,5), Vec3crd(2,5,0), Vec3crd(5,4,1), Vec3crd(5,1,0) - }); + mesh = TriangleMesh( + { 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) }, + { Vec3crd(0,1,2), Vec3crd(3,4,5), Vec3crd(2,1,4), Vec3crd(2,4,3), Vec3crd(2,3,5), Vec3crd(2,5,0), Vec3crd(5,4,1), Vec3crd(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) - }); - facets = std::vector({ - Vec3crd(0,1,2), Vec3crd(1,0,3), Vec3crd(2,1,4), Vec3crd(2,5,0), Vec3crd(0,6,3), Vec3crd(1,3,7), Vec3crd(1,8,4), Vec3crd(4,9,2), Vec3crd(10,5,2), Vec3crd(5,6,0), Vec3crd(6,11,3), Vec3crd(3,12,7), Vec3crd(7,8,1), Vec3crd(4,8,11), Vec3crd(4,11,9), Vec3crd(9,10,2), Vec3crd(10,13,5), Vec3crd(14,6,5), Vec3crd(9,11,6), Vec3crd(11,12,3), Vec3crd(12,8,7), Vec3crd(11,8,15), Vec3crd(13,10,9), Vec3crd(5,13,14), Vec3crd(14,13,6), Vec3crd(6,13,9), Vec3crd(15,12,11), Vec3crd(15,8,12) - }); + mesh = TriangleMesh( + { 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) }, + { Vec3crd(0,1,2), Vec3crd(1,0,3), Vec3crd(2,1,4), Vec3crd(2,5,0), Vec3crd(0,6,3), Vec3crd(1,3,7), Vec3crd(1,8,4), Vec3crd(4,9,2), Vec3crd(10,5,2), Vec3crd(5,6,0), Vec3crd(6,11,3), Vec3crd(3,12,7), Vec3crd(7,8,1), Vec3crd(4,8,11), Vec3crd(4,11,9), Vec3crd(9,10,2), Vec3crd(10,13,5), Vec3crd(14,6,5), Vec3crd(9,11,6), Vec3crd(11,12,3), Vec3crd(12,8,7), Vec3crd(11,8,15), Vec3crd(13,10,9), Vec3crd(5,13,14), Vec3crd(14,13,6), Vec3crd(6,13,9), Vec3crd(15,12,11), Vec3crd(15,8,12) }); 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) - }); - facets = std::vector({ - Vec3crd(0,1,2), Vec3crd(1,0,3), Vec3crd(1,3,4), Vec3crd(4,3,5), Vec3crd(2,6,7), Vec3crd(6,2,1), Vec3crd(7,6,5), Vec3crd(7,5,3), Vec3crd(5,8,9), Vec3crd(8,5,6), Vec3crd(10,11,12), Vec3crd(11,10,13), Vec3crd(14,8,15), Vec3crd(8,14,9), Vec3crd(2,16,17), Vec3crd(16,2,15), Vec3crd(15,2,14), Vec3crd(14,10,12), Vec3crd(10,14,7), Vec3crd(7,14,2), Vec3crd(16,18,19), Vec3crd(18,16,20), Vec3crd(20,16,1), Vec3crd(1,16,8), Vec3crd(8,16,15), Vec3crd(6,1,8), Vec3crd(3,11,13), Vec3crd(11,3,21), Vec3crd(21,3,18), Vec3crd(18,22,19), Vec3crd(22,18,0), Vec3crd(0,18,3), Vec3crd(16,22,17), Vec3crd(22,16,19), Vec3crd(2,22,0), Vec3crd(22,2,17), Vec3crd(5,23,4), Vec3crd(23,11,21), Vec3crd(11,23,12), Vec3crd(12,23,9), Vec3crd(9,23,5), Vec3crd(12,9,14), Vec3crd(23,18,20), Vec3crd(18,23,21), Vec3crd(10,3,13), Vec3crd(3,10,7), Vec3crd(1,23,20), Vec3crd(23,1,4) - }); + mesh = TriangleMesh( + { 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) }, + { Vec3crd(0,1,2), Vec3crd(1,0,3), Vec3crd(1,3,4), Vec3crd(4,3,5), Vec3crd(2,6,7), Vec3crd(6,2,1), Vec3crd(7,6,5), Vec3crd(7,5,3), Vec3crd(5,8,9), Vec3crd(8,5,6), Vec3crd(10,11,12), Vec3crd(11,10,13), Vec3crd(14,8,15), Vec3crd(8,14,9), Vec3crd(2,16,17), Vec3crd(16,2,15), Vec3crd(15,2,14), Vec3crd(14,10,12), Vec3crd(10,14,7), Vec3crd(7,14,2), Vec3crd(16,18,19), Vec3crd(18,16,20), Vec3crd(20,16,1), Vec3crd(1,16,8), Vec3crd(8,16,15), Vec3crd(6,1,8), Vec3crd(3,11,13), Vec3crd(11,3,21), Vec3crd(21,3,18), Vec3crd(18,22,19), Vec3crd(22,18,0), Vec3crd(0,18,3), Vec3crd(16,22,17), Vec3crd(22,16,19), Vec3crd(2,22,0), Vec3crd(22,2,17), Vec3crd(5,23,4), Vec3crd(23,11,21), Vec3crd(11,23,12), Vec3crd(12,23,9), Vec3crd(9,23,5), Vec3crd(12,9,14), Vec3crd(23,18,20), Vec3crd(18,23,21), Vec3crd(10,3,13), Vec3crd(3,10,7), Vec3crd(1,23,20), Vec3crd(23,1,4) }); 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) - }); - facets = std::vector({ - Vec3crd(0,1,2), Vec3crd(1,3,2), Vec3crd(3,4,5), Vec3crd(2,3,5), Vec3crd(6,0,2), Vec3crd(6,2,7), Vec3crd(5,8,7), Vec3crd(5,7,2), Vec3crd(9,10,8), Vec3crd(9,8,5), Vec3crd(9,0,6), Vec3crd(9,6,10), Vec3crd(9,11,1), Vec3crd(9,1,0), Vec3crd(3,1,11), Vec3crd(4,3,11), Vec3crd(5,11,9), Vec3crd(5,4,11), Vec3crd(12,10,6), Vec3crd(12,6,13), Vec3crd(6,7,14), Vec3crd(13,6,14), Vec3crd(7,8,15), Vec3crd(14,7,15), Vec3crd(15,8,10), Vec3crd(15,10,12), Vec3crd(12,13,14), Vec3crd(12,14,15) - }); + mesh = TriangleMesh( + { 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) }, + { Vec3crd(0,1,2), Vec3crd(1,3,2), Vec3crd(3,4,5), Vec3crd(2,3,5), Vec3crd(6,0,2), Vec3crd(6,2,7), Vec3crd(5,8,7), Vec3crd(5,7,2), Vec3crd(9,10,8), Vec3crd(9,8,5), Vec3crd(9,0,6), Vec3crd(9,6,10), Vec3crd(9,11,1), Vec3crd(9,1,0), Vec3crd(3,1,11), Vec3crd(4,3,11), Vec3crd(5,11,9), Vec3crd(5,4,11), Vec3crd(12,10,6), Vec3crd(12,6,13), Vec3crd(6,7,14), Vec3crd(13,6,14), Vec3crd(7,8,15), Vec3crd(14,7,15), Vec3crd(15,8,10), Vec3crd(15,10,12), Vec3crd(12,13,14), Vec3crd(12,14,15) }); 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) - }); - facets = std::vector({ - Vec3crd(0,1,2) , Vec3crd(2,1,3) , Vec3crd(4,0,5) , Vec3crd(4,1,0) , Vec3crd(6,4,7) , Vec3crd(7,4,5) , Vec3crd(4,8,1) , Vec3crd(0,2,5) , Vec3crd(5,2,9) , Vec3crd(2,10,9) , Vec3crd(10,3,11) , - Vec3crd(2,3,10) , Vec3crd(9,10,12) , Vec3crd(13,9,12) , Vec3crd(3,1,8) , Vec3crd(11,3,8) , Vec3crd(10,11,8) , Vec3crd(4,10,8) , Vec3crd(6,12,10) , Vec3crd(4,6,10) , - Vec3crd(7,13,12) , Vec3crd(6,7,12) , Vec3crd(7,5,9) , Vec3crd(13,7,9) - }); - break; + mesh = TriangleMesh( + { 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) }, + { Vec3crd(0,1,2), Vec3crd(2,1,3), Vec3crd(4,0,5), Vec3crd(4,1,0), Vec3crd(6,4,7), Vec3crd(7,4,5), Vec3crd(4,8,1), Vec3crd(0,2,5), Vec3crd(5,2,9), Vec3crd(2,10,9), Vec3crd(10,3,11), Vec3crd(2,3,10), Vec3crd(9,10,12), Vec3crd(13,9,12), Vec3crd(3,1,8), Vec3crd(11,3,8), Vec3crd(10,11,8), Vec3crd(4,10,8), Vec3crd(6,12,10), Vec3crd(4,6,10), Vec3crd(7,13,12), Vec3crd(6,7,12), Vec3crd(7,5,9), Vec3crd(13,7,9) }); + break; default: + throw std::invalid_argument("Slic3r::Test::mesh(): called with invalid mesh ID"); break; } - TriangleMesh _mesh; - if (vertices.size() == 0) { - switch(m) { - case TestMesh::cube_20x20x20: - _mesh = Slic3r::make_cube(20,20,20); - break; - case TestMesh::sphere_50mm: - _mesh = Slic3r::make_sphere(50, PI / 243.0); - break; - default: - break; - } - } else { - _mesh = TriangleMesh(vertices, facets); - } - _mesh.repair(); - return _mesh; + mesh.repair(); + return mesh; } static bool verbose_gcode() @@ -212,78 +153,105 @@ static bool verbose_gcode() return s == "1" || s == "on" || s == "yes"; } -std::shared_ptr init_print(std::initializer_list meshes, Slic3r::Model& model, std::shared_ptr _config, bool comments) +void init_print(std::vector &&meshes, Slic3r::Print &print, Slic3r::Model &model, const DynamicPrintConfig &config_in, bool comments) { - std::shared_ptr config(Slic3r::DynamicPrintConfig::new_from_defaults()); - config->apply(*_config); + DynamicPrintConfig config = DynamicPrintConfig::full_print_config(); + config.apply(config_in); if (verbose_gcode()) - config->set_key_value("gcode_comments", new ConfigOptionBool(true)); - - std::shared_ptr print {std::make_shared()}; - - for (const TestMesh &t : meshes) { - ModelObject *object = model.add_object(); - object->name += std::string(mesh_names.at(t)) + ".stl"; - object->add_volume(mesh(t)); - object->add_instance(); - } - - model.arrange_objects(PrintConfig::min_object_distance(config.get())); - model.center_instances_around_point(Slic3r::Vec2d(100,100)); - for (ModelObject *mo : model.objects) { - mo->ensure_on_bed(); - print->auto_assign_extruders(mo); - } - - print->apply(model, *config); - print->validate(); - print->set_status_silent(); - return print; -} - -std::shared_ptr init_print(std::initializer_list meshes, Slic3r::Model& model, std::shared_ptr _config, bool comments) -{ - std::shared_ptr config(Slic3r::DynamicPrintConfig::new_from_defaults()); - config->apply(*_config); - - if (verbose_gcode()) - config->set_key_value("gcode_comments", new ConfigOptionBool(true)); - - std::shared_ptr print { std::make_shared() }; + config.set_key_value("gcode_comments", new ConfigOptionBool(true)); for (const TriangleMesh &t : meshes) { ModelObject *object = model.add_object(); object->name += "object.stl"; - object->add_volume(t); + object->add_volume(std::move(t)); object->add_instance(); } - model.arrange_objects(PrintConfig::min_object_distance(config.get())); + model.arrange_objects(PrintConfig::min_object_distance(&config)); model.center_instances_around_point(Slic3r::Vec2d(100, 100)); for (ModelObject *mo : model.objects) { mo->ensure_on_bed(); - print->auto_assign_extruders(mo); + print.auto_assign_extruders(mo); } - print->apply(model, *config); - print->validate(); - print->set_status_silent(); - return print; + print.apply(model, config); + print.validate(); + print.set_status_silent(); } -std::string gcode(std::shared_ptr _print) +void init_print(std::initializer_list test_meshes, Slic3r::Print &print, Slic3r::Model &model, const Slic3r::DynamicPrintConfig &config_in, bool comments) +{ + std::vector triangle_meshes; + triangle_meshes.reserve(test_meshes.size()); + for (const TestMesh test_mesh : test_meshes) + triangle_meshes.emplace_back(mesh(test_mesh)); + init_print(std::move(triangle_meshes), print, model, config_in, comments); +} + +void init_print(std::initializer_list input_meshes, Slic3r::Print &print, Slic3r::Model &model, const DynamicPrintConfig &config_in, bool comments) +{ + std::vector triangle_meshes; + triangle_meshes.reserve(input_meshes.size()); + for (const TriangleMesh &input_mesh : input_meshes) + triangle_meshes.emplace_back(input_mesh); + init_print(std::move(triangle_meshes), print, model, config_in, comments); +} + +void init_print(std::initializer_list meshes, Slic3r::Print &print, Slic3r::Model &model, std::initializer_list config_items, bool comments) +{ + Slic3r::DynamicPrintConfig config = Slic3r::DynamicPrintConfig::full_print_config(); + config.set_deserialize(config_items); + init_print(meshes, print, model, config, comments); +} + +void init_print(std::initializer_list meshes, Slic3r::Print &print, Slic3r::Model &model, std::initializer_list config_items, bool comments) +{ + Slic3r::DynamicPrintConfig config = Slic3r::DynamicPrintConfig::full_print_config(); + config.set_deserialize(config_items); + init_print(meshes, print, model, config, comments); +} + +void init_and_process_print(std::initializer_list meshes, Slic3r::Print &print, const DynamicPrintConfig &config, bool comments) +{ + Slic3r::Model model; + init_print(meshes, print, model, config, comments); + print.process(); +} + +void init_and_process_print(std::initializer_list meshes, Slic3r::Print &print, const DynamicPrintConfig &config, bool comments) +{ + Slic3r::Model model; + init_print(meshes, print, model, config, comments); + print.process(); +} + +void init_and_process_print(std::initializer_list meshes, Slic3r::Print &print, std::initializer_list config_items, bool comments) +{ + Slic3r::Model model; + init_print(meshes, print, model, config_items, comments); + print.process(); +} + +void init_and_process_print(std::initializer_list meshes, Slic3r::Print &print, std::initializer_list config_items, bool comments) +{ + Slic3r::Model model; + init_print(meshes, print, model, config_items, comments); + print.process(); +} + +std::string gcode(Print & print) { boost::filesystem::path temp = boost::filesystem::unique_path(); - _print->set_status_silent(); - _print->process(); - _print->export_gcode(temp.string(), nullptr); + print.set_status_silent(); + print.process(); + print.export_gcode(temp.string(), nullptr); std::ifstream t(temp.string()); std::string str((std::istreambuf_iterator(t)), std::istreambuf_iterator()); boost::nowide::remove(temp.string().c_str()); return str; } -Slic3r::Model model(const std::string& model_name, TriangleMesh&& _mesh) +Slic3r::Model model(const std::string &model_name, TriangleMesh &&_mesh) { Slic3r::Model result; ModelObject *object = result.add_object(); @@ -293,35 +261,69 @@ Slic3r::Model model(const std::string& model_name, TriangleMesh&& _mesh) return result; } -void add_testmesh_to_model(Slic3r::Model& result, const std::string& model_name, TriangleMesh&& _mesh) +std::string slice(std::initializer_list meshes, const DynamicPrintConfig &config, bool comments) { - ModelObject *object = result.add_object(); - object->name += model_name + ".stl"; - object->add_volume(_mesh); - object->add_instance(); + Slic3r::Print print; + Slic3r::Model model; + init_print(meshes, print, model, config, comments); + return gcode(print); +} + +std::string slice(std::initializer_list meshes, const DynamicPrintConfig &config, bool comments) +{ + Slic3r::Print print; + Slic3r::Model model; + init_print(meshes, print, model, config, comments); + return gcode(print); +} + +std::string slice(std::initializer_list meshes, std::initializer_list config_items, bool comments) +{ + Slic3r::Print print; + Slic3r::Model model; + init_print(meshes, print, model, config_items, comments); + return gcode(print); +} + +std::string slice(std::initializer_list meshes, std::initializer_list config_items, bool comments) +{ + Slic3r::Print print; + Slic3r::Model model; + init_print(meshes, print, model, config_items, comments); + return gcode(print); } } } // namespace Slic3r::Test #include -SCENARIO("init_print functionality") { +SCENARIO("init_print functionality", "[test_data]") { GIVEN("A default config") { - std::shared_ptr config(Slic3r::DynamicPrintConfig::new_from_defaults()); - std::stringstream gcode; + Slic3r::DynamicPrintConfig config = Slic3r::DynamicPrintConfig::full_print_config(); WHEN("init_print is called with a single mesh.") { Slic3r::Model model; - auto print = Slic3r::Test::init_print({ Slic3r::Test::TestMesh::cube_20x20x20 }, model, config, true); - gcode.clear(); + Slic3r::Print print; + Slic3r::Test::init_print({ Slic3r::Test::TestMesh::cube_20x20x20 }, print, model, config, true); THEN("One mesh/printobject is in the resulting Print object.") { - REQUIRE(print->objects().size() == 1); + REQUIRE(print.objects().size() == 1); } - THEN("print->process() doesn't crash.") { - REQUIRE_NOTHROW(print->process()); + THEN("print.process() doesn't crash.") { + REQUIRE_NOTHROW(print.process()); } THEN("Export gcode functions outputs text.") { - REQUIRE(!Slic3r::Test::gcode(print).empty()); + REQUIRE(! Slic3r::Test::gcode(print).empty()); } +#if 0 + THEN("Embedded meshes exported") { + std::string path = "C:\\data\\temp\\embedded_meshes\\"; + for (auto kvp : Slic3r::Test::mesh_names) { + Slic3r::TriangleMesh m = mesh(kvp.first); + std::string name = kvp.second; + REQUIRE(Slic3r::store_stl((path + name + ".stl").c_str(), &m, true) == true); + REQUIRE(Slic3r::store_obj((path + name + ".obj").c_str(), &m) == true); + } + } +#endif } } } diff --git a/tests/fff_print/test_data.hpp b/tests/fff_print/test_data.hpp index e67e400f26..573ae58a5c 100644 --- a/tests/fff_print/test_data.hpp +++ b/tests/fff_print/test_data.hpp @@ -1,12 +1,12 @@ #ifndef SLIC3R_TEST_DATA_HPP #define SLIC3R_TEST_DATA_HPP -#include "libslic3r/Point.hpp" -#include "libslic3r/TriangleMesh.hpp" +#include "libslic3r/Config.hpp" #include "libslic3r/Geometry.hpp" #include "libslic3r/Model.hpp" +#include "libslic3r/Point.hpp" #include "libslic3r/Print.hpp" -#include "libslic3r/Config.hpp" +#include "libslic3r/TriangleMesh.hpp" #include @@ -61,15 +61,24 @@ bool _equiv(const T& a, const T& b) { return std::abs(a - b) < EPSILON; } template bool _equiv(const T& a, const T& b, double epsilon) { return abs(a - b) < epsilon; } -//Slic3r::Model model(const std::string& model_name, TestMesh m, Vec3d translate = Vec3d(0,0,0), Vec3d scale = Vec3d(1.0,1.0,1.0)); -//Slic3r::Model model(const std::string& model_name, TestMesh m, Vec3d translate = Vec3d(0,0,0), double scale = 1.0); - Slic3r::Model model(const std::string& model_name, TriangleMesh&& _mesh); +void init_print(std::vector &&meshes, Slic3r::Print &print, Slic3r::Model& model, const DynamicPrintConfig &config_in, bool comments = false); +void init_print(std::initializer_list meshes, Slic3r::Print &print, Slic3r::Model& model, const Slic3r::DynamicPrintConfig &config_in = Slic3r::DynamicPrintConfig::full_print_config(), bool comments = false); +void init_print(std::initializer_list meshes, Slic3r::Print &print, Slic3r::Model& model, const Slic3r::DynamicPrintConfig &config_in = Slic3r::DynamicPrintConfig::full_print_config(), bool comments = false); +void init_print(std::initializer_list meshes, Slic3r::Print &print, Slic3r::Model& model, std::initializer_list config_items, bool comments = false); +void init_print(std::initializer_list meshes, Slic3r::Print &print, Slic3r::Model& model, std::initializer_list config_items, bool comments = false); -std::shared_ptr init_print(std::initializer_list meshes, Slic3r::Model& model, std::shared_ptr _config = std::shared_ptr(Slic3r::DynamicPrintConfig::new_from_defaults()), bool comments = false); -std::shared_ptr init_print(std::initializer_list meshes, Slic3r::Model& model, std::shared_ptr _config = std::shared_ptr(Slic3r::DynamicPrintConfig::new_from_defaults()), bool comments = false); +void init_and_process_print(std::initializer_list meshes, Slic3r::Print &print, const DynamicPrintConfig& config, bool comments = false); +void init_and_process_print(std::initializer_list meshes, Slic3r::Print &print, const DynamicPrintConfig& config, bool comments = false); +void init_and_process_print(std::initializer_list meshes, Slic3r::Print &print, std::initializer_list config_items, bool comments = false); +void init_and_process_print(std::initializer_list meshes, Slic3r::Print &print, std::initializer_list config_items, bool comments = false); -std::string gcode(std::shared_ptr print); +std::string gcode(Print& print); + +std::string slice(std::initializer_list meshes, const DynamicPrintConfig &config, bool comments = false); +std::string slice(std::initializer_list meshes, const DynamicPrintConfig &config, bool comments = false); +std::string slice(std::initializer_list meshes, std::initializer_list config_items, bool comments = false); +std::string slice(std::initializer_list meshes, std::initializer_list config_items, bool comments = false); } } // namespace Slic3r::Test diff --git a/tests/fff_print/test_extrusion_entity.cpp b/tests/fff_print/test_extrusion_entity.cpp new file mode 100644 index 0000000000..9bef52a5c3 --- /dev/null +++ b/tests/fff_print/test_extrusion_entity.cpp @@ -0,0 +1,85 @@ +#include + +#include + +#include "libslic3r/ExtrusionEntityCollection.hpp" +#include "libslic3r/ExtrusionEntity.hpp" +#include "libslic3r/Point.hpp" +#include "libslic3r/libslic3r.h" + +#include "test_data.hpp" + +using namespace Slic3r; + +static inline Slic3r::Point random_point(float LO=-50, float HI=50) +{ + Vec2f pt = Vec2f(LO, LO) + (Vec2d(rand(), rand()) * (HI-LO) / RAND_MAX).cast(); + return pt.cast(); +} + +// build a sample extrusion entity collection with random start and end points. +static Slic3r::ExtrusionPath random_path(size_t length = 20, float LO = -50, float HI = 50) +{ + ExtrusionPath t {erPerimeter, 1.0, 1.0, 1.0}; + for (size_t j = 0; j < length; ++ j) + t.polyline.append(random_point(LO, HI)); + return t; +} + +static Slic3r::ExtrusionPaths random_paths(size_t count = 10, size_t length = 20, float LO = -50, float HI = 50) +{ + Slic3r::ExtrusionPaths p; + for (size_t i = 0; i < count; ++ i) + p.push_back(random_path(length, LO, HI)); + return p; +} + +SCENARIO("ExtrusionEntityCollection: Polygon flattening", "[ExtrusionEntity]") { + srand(0xDEADBEEF); // consistent seed for test reproducibility. + + // Generate one specific random path set and save it for later comparison + Slic3r::ExtrusionPaths nosort_path_set = random_paths(); + + Slic3r::ExtrusionEntityCollection sub_nosort; + sub_nosort.append(nosort_path_set); + sub_nosort.no_sort = true; + + Slic3r::ExtrusionEntityCollection sub_sort; + sub_sort.no_sort = false; + sub_sort.append(random_paths()); + + GIVEN("A Extrusion Entity Collection with a child that has one child that is marked as no-sort") { + Slic3r::ExtrusionEntityCollection sample; + Slic3r::ExtrusionEntityCollection output; + + sample.append(sub_sort); + sample.append(sub_nosort); + sample.append(sub_sort); + + WHEN("The EEC is flattened with default options (preserve_order=false)") { + output = sample.flatten(); + 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); + } + } + WHEN("The EEC is flattened with preservation (preserve_order=true)") { + output = sample.flatten(true); + 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); + } + 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) + if (e->is_collection()) { + 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()); + 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()); + } + } + } + } + } +} diff --git a/tests/fff_print/test_fill.cpp b/tests/fff_print/test_fill.cpp new file mode 100644 index 0000000000..ec8b44a0d5 --- /dev/null +++ b/tests/fff_print/test_fill.cpp @@ -0,0 +1,474 @@ +#include + +#include +#include + +#include "libslic3r/ClipperUtils.hpp" +#include "libslic3r/Fill/Fill.hpp" +#include "libslic3r/Flow.hpp" +#include "libslic3r/Geometry.hpp" +#include "libslic3r/Print.hpp" +#include "libslic3r/SVG.hpp" +#include "libslic3r/libslic3r.h" + +#include "test_data.hpp" + +using namespace Slic3r; + +bool test_if_solid_surface_filled(const ExPolygon& expolygon, double flow_spacing, double angle = 0, double density = 1.0); + +#if 0 +TEST_CASE("Fill: adjusted solid distance") { + int surface_width = 250; + int distance = Slic3r::Flow::solid_spacing(surface_width, 47); + REQUIRE(distance == Approx(50)); + REQUIRE(surface_width % distance == 0); +} +#endif + +TEST_CASE("Fill: Pattern Path Length", "[Fill]") { + std::unique_ptr filler(Slic3r::Fill::new_from_type("rectilinear")); + filler->angle = float(-(PI)/2.0); + FillParams fill_params; + filler->spacing = 5; + fill_params.dont_adjust = true; + //fill_params.endpoints_overlap = false; + fill_params.density = float(filler->spacing / 50.0); + + auto test = [&filler, &fill_params] (const ExPolygon& poly) -> Slic3r::Polylines { + Slic3r::Surface surface(stTop, poly); + return filler->fill_surface(&surface, fill_params); + }; + + SECTION("Square") { + Slic3r::Points test_set; + test_set.reserve(4); + std::vector points {Vec2d(0,0), Vec2d(100,0), Vec2d(100,100), Vec2d(0,100)}; + for (size_t i = 0; i < 4; ++i) { + std::transform(points.cbegin()+i, points.cend(), std::back_inserter(test_set), [] (const Vec2d& a) -> Point { return Point::new_scale(a.x(), a.y()); } ); + std::transform(points.cbegin(), points.cbegin()+i, std::back_inserter(test_set), [] (const Vec2d& a) -> Point { return Point::new_scale(a.x(), a.y()); } ); + Slic3r::Polylines paths = test(Slic3r::ExPolygon(test_set)); + REQUIRE(paths.size() == 1); // one continuous path + + // TODO: determine what the "Expected length" should be for rectilinear fill of a 100x100 polygon. + // This check only checks that it's above scale(3*100 + 2*50) + scaled_epsilon. + // ok abs($paths->[0]->length - scale(3*100 + 2*50)) - scaled_epsilon, 'path has expected length'; + REQUIRE(std::abs(paths[0].length() - static_cast(scale_(3*100 + 2*50))) - SCALED_EPSILON > 0); // path has expected length + + test_set.clear(); + } + } + SECTION("Diamond with endpoints on grid") { + std::vector points {Vec2d(0,0), Vec2d(100,0), Vec2d(150,50), Vec2d(100,100), Vec2d(0,100), Vec2d(-50,50)}; + Slic3r::Points test_set; + test_set.reserve(6); + std::transform(points.cbegin(), points.cend(), std::back_inserter(test_set), [] (const Vec2d& a) -> Point { return Point::new_scale(a.x(), a.y()); } ); + Slic3r::Polylines paths = test(Slic3r::ExPolygon(test_set)); + REQUIRE(paths.size() == 1); // one continuous path + } + + SECTION("Square with hole") { + std::vector square {Vec2d(0,0), Vec2d(100,0), Vec2d(100,100), Vec2d(0,100)}; + std::vector hole {Vec2d(25,25), Vec2d(75,25), Vec2d(75,75), Vec2d(25,75) }; + std::reverse(hole.begin(), hole.end()); + + Slic3r::Points test_hole; + Slic3r::Points test_square; + + std::transform(square.cbegin(), square.cend(), std::back_inserter(test_square), [] (const Vec2d& a) -> Point { return Point::new_scale(a.x(), a.y()); } ); + std::transform(hole.cbegin(), hole.cend(), std::back_inserter(test_hole), [] (const Vec2d& a) -> Point { return Point::new_scale(a.x(), a.y()); } ); + + for (double angle : {-(PI/2.0), -(PI/4.0), -(PI), PI/2.0, PI}) { + for (double spacing : {25.0, 5.0, 7.5, 8.5}) { + fill_params.density = float(filler->spacing / spacing); + filler->angle = float(angle); + ExPolygon e(test_square, test_hole); + Slic3r::Polylines paths = test(e); +#if 0 + { + BoundingBox bbox = get_extents(e); + SVG svg("c:\\data\\temp\\square_with_holes.svg", bbox); + svg.draw(e); + svg.draw(paths); + svg.Close(); + } +#endif + REQUIRE((paths.size() >= 1 && paths.size() <= 3)); + // paths don't cross hole + REQUIRE(diff_pl(paths, offset(e, float(SCALED_EPSILON*10))).size() == 0); + } + } + } + SECTION("Regression: Missing infill segments in some rare circumstances") { + filler->angle = float(PI/4.0); + fill_params.dont_adjust = false; + filler->spacing = 0.654498; + //filler->endpoints_overlap = unscale(359974); + fill_params.density = 1; + filler->layer_id = 66; + filler->z = 20.15; + + Slic3r::Points points {Point(25771516,14142125),Point(14142138,25771515),Point(2512749,14142131),Point(14142125,2512749)}; + Slic3r::Polylines paths = test(Slic3r::ExPolygon(points)); + REQUIRE(paths.size() == 1); // one continuous path + + // TODO: determine what the "Expected length" should be for rectilinear fill of a 100x100 polygon. + // This check only checks that it's above scale(3*100 + 2*50) + scaled_epsilon. + // ok abs($paths->[0]->length - scale(3*100 + 2*50)) - scaled_epsilon, 'path has expected length'; + REQUIRE(std::abs(paths[0].length() - static_cast(scale_(3*100 + 2*50))) - SCALED_EPSILON > 0); // path has expected length + } + + SECTION("Rotated Square") { + Slic3r::Points square { Point::new_scale(0,0), Point::new_scale(50,0), Point::new_scale(50,50), Point::new_scale(0,50)}; + Slic3r::ExPolygon expolygon(square); + std::unique_ptr filler(Slic3r::Fill::new_from_type("rectilinear")); + filler->bounding_box = get_extents(expolygon.contour); + filler->angle = 0; + + Surface surface(stTop, expolygon); + auto flow = Slic3r::Flow(0.69, 0.4, 0.50); + + FillParams fill_params; + fill_params.density = 1.0; + filler->spacing = flow.spacing(); + + for (auto angle : { 0.0, 45.0}) { + surface.expolygon.rotate(angle, Point(0,0)); + Polylines paths = filler->fill_surface(&surface, fill_params); + REQUIRE(paths.size() == 1); + } + } + SECTION("Solid surface fill") { + Slic3r::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) + }; + Slic3r::ExPolygon expolygon(points); + + REQUIRE(test_if_solid_surface_filled(expolygon, 0.55) == true); + for (size_t i = 0; i <= 20; ++i) + { + expolygon.scale(1.05); + REQUIRE(test_if_solid_surface_filled(expolygon, 0.55) == true); + } + } + SECTION("Solid surface fill") { + Slic3r::Points points { + Slic3r::Point(59515297,5422499),Slic3r::Point(59531249,5578697),Slic3r::Point(59695801,6123186), + Slic3r::Point(59965713,6630228),Slic3r::Point(60328214,7070685),Slic3r::Point(60773285,7434379), + Slic3r::Point(61274561,7702115),Slic3r::Point(61819378,7866770),Slic3r::Point(62390306,7924789), + Slic3r::Point(62958700,7866744),Slic3r::Point(63503012,7702244),Slic3r::Point(64007365,7434357), + Slic3r::Point(64449960,7070398),Slic3r::Point(64809327,6634999),Slic3r::Point(65082143,6123325), + Slic3r::Point(65245005,5584454),Slic3r::Point(65266967,5422499),Slic3r::Point(66267307,5422499), + Slic3r::Point(66269190,8310081),Slic3r::Point(66275379,17810072),Slic3r::Point(66277259,20697500), + Slic3r::Point(65267237,20697500),Slic3r::Point(65245004,20533538),Slic3r::Point(65082082,19994444), + Slic3r::Point(64811462,19488579),Slic3r::Point(64450624,19048208),Slic3r::Point(64012101,18686514), + Slic3r::Point(63503122,18415781),Slic3r::Point(62959151,18251378),Slic3r::Point(62453416,18198442), + Slic3r::Point(62390147,18197355),Slic3r::Point(62200087,18200576),Slic3r::Point(61813519,18252990), + Slic3r::Point(61274433,18415918),Slic3r::Point(60768598,18686517),Slic3r::Point(60327567,19047892), + Slic3r::Point(59963609,19493297),Slic3r::Point(59695865,19994587),Slic3r::Point(59531222,20539379), + Slic3r::Point(59515153,20697500),Slic3r::Point(58502480,20697500),Slic3r::Point(58502480,5422499) + }; + Slic3r::ExPolygon expolygon(points); + + REQUIRE(test_if_solid_surface_filled(expolygon, 0.55) == true); + REQUIRE(test_if_solid_surface_filled(expolygon, 0.55, PI/2.0) == true); + } + SECTION("Solid surface fill") { + Slic3r::Points points { + Point::new_scale(0,0),Point::new_scale(98,0),Point::new_scale(98,10), Point::new_scale(0,10) + }; + Slic3r::ExPolygon expolygon(points); + + REQUIRE(test_if_solid_surface_filled(expolygon, 0.5, 45.0, 0.99) == true); + } +} + +/* +{ + my $collection = Slic3r::Polyline::Collection->new( + Slic3r::Polyline->new([0,15], [0,18], [0,20]), + Slic3r::Polyline->new([0,10], [0,8], [0,5]), + ); + is_deeply + [ map $_->[Y], map @$_, @{$collection->chained_path_from(Slic3r::Point->new(0,30), 0)} ], + [20, 18, 15, 10, 8, 5], + 'chained path'; +} + +{ + my $collection = Slic3r::Polyline::Collection->new( + Slic3r::Polyline->new([4,0], [10,0], [15,0]), + Slic3r::Polyline->new([10,5], [15,5], [20,5]), + ); + is_deeply + [ map $_->[X], map @$_, @{$collection->chained_path_from(Slic3r::Point->new(30,0), 0)} ], + [reverse 4, 10, 15, 10, 15, 20], + 'chained path'; +} + +{ + my $collection = Slic3r::ExtrusionPath::Collection->new( + map Slic3r::ExtrusionPath->new(polyline => $_, role => 0, mm3_per_mm => 1), + Slic3r::Polyline->new([0,15], [0,18], [0,20]), + Slic3r::Polyline->new([0,10], [0,8], [0,5]), + ); + is_deeply + [ map $_->[Y], map @{$_->polyline}, @{$collection->chained_path_from(Slic3r::Point->new(0,30), 0)} ], + [20, 18, 15, 10, 8, 5], + 'chained path'; +} + +{ + my $collection = Slic3r::ExtrusionPath::Collection->new( + map Slic3r::ExtrusionPath->new(polyline => $_, role => 0, mm3_per_mm => 1), + Slic3r::Polyline->new([15,0], [10,0], [4,0]), + Slic3r::Polyline->new([10,5], [15,5], [20,5]), + ); + is_deeply + [ map $_->[X], map @{$_->polyline}, @{$collection->chained_path_from(Slic3r::Point->new(30,0), 0)} ], + [reverse 4, 10, 15, 10, 15, 20], + 'chained path'; +} + +for my $pattern (qw(rectilinear honeycomb hilbertcurve concentric)) { + my $config = Slic3r::Config->new_from_defaults; + $config->set('fill_pattern', $pattern); + $config->set('external_fill_pattern', $pattern); + $config->set('perimeters', 1); + $config->set('skirts', 0); + $config->set('fill_density', 20); + $config->set('layer_height', 0.05); + $config->set('perimeter_extruder', 1); + $config->set('infill_extruder', 2); + my $print = Slic3r::Test::init_print('20mm_cube', config => $config, scale => 2); + ok my $gcode = Slic3r::Test::gcode($print), "successful $pattern infill generation"; + my $tool = undef; + my @perimeter_points = my @infill_points = (); + Slic3r::GCode::Reader->new->parse($gcode, sub { + my ($self, $cmd, $args, $info) = @_; + + if ($cmd =~ /^T(\d+)/) { + $tool = $1; + } elsif ($cmd eq 'G1' && $info->{extruding} && $info->{dist_XY} > 0) { + if ($tool == $config->perimeter_extruder-1) { + push @perimeter_points, Slic3r::Point->new_scale($args->{X}, $args->{Y}); + } elsif ($tool == $config->infill_extruder-1) { + push @infill_points, Slic3r::Point->new_scale($args->{X}, $args->{Y}); + } + } + }); + my $convex_hull = convex_hull(\@perimeter_points); + ok !(defined first { !$convex_hull->contains_point($_) } @infill_points), "infill does not exceed perimeters ($pattern)"; +} + +{ + my $config = Slic3r::Config->new_from_defaults; + $config->set('infill_only_where_needed', 1); + $config->set('bottom_solid_layers', 0); + $config->set('infill_extruder', 2); + $config->set('infill_extrusion_width', 0.5); + $config->set('fill_density', 40); + $config->set('cooling', 0); # for preventing speeds from being altered + $config->set('first_layer_speed', '100%'); # for preventing speeds from being altered + + my $test = sub { + my $print = Slic3r::Test::init_print('pyramid', config => $config); + + my $tool = undef; + my @infill_extrusions = (); # array of polylines + Slic3r::GCode::Reader->new->parse(Slic3r::Test::gcode($print), sub { + my ($self, $cmd, $args, $info) = @_; + + if ($cmd =~ /^T(\d+)/) { + $tool = $1; + } elsif ($cmd eq 'G1' && $info->{extruding} && $info->{dist_XY} > 0) { + if ($tool == $config->infill_extruder-1) { + push @infill_extrusions, Slic3r::Line->new_scale( + [ $self->X, $self->Y ], + [ $info->{new_X}, $info->{new_Y} ], + ); + } + } + }); + return 0 if !@infill_extrusions; # prevent calling convex_hull() with no points + + my $convex_hull = convex_hull([ map $_->pp, map @$_, @infill_extrusions ]); + return unscale unscale sum(map $_->area, @{offset([$convex_hull], scale(+$config->infill_extrusion_width/2))}); + }; + + my $tolerance = 5; # mm^2 + + $config->set('solid_infill_below_area', 0); + ok $test->() < $tolerance, + 'no infill is generated when using infill_only_where_needed on a pyramid'; + + $config->set('solid_infill_below_area', 70); + ok abs($test->() - $config->solid_infill_below_area) < $tolerance, + 'infill is only generated under the forced solid shells'; +} + +{ + my $config = Slic3r::Config->new_from_defaults; + $config->set('skirts', 0); + $config->set('perimeters', 1); + $config->set('fill_density', 0); + $config->set('top_solid_layers', 0); + $config->set('bottom_solid_layers', 0); + $config->set('solid_infill_below_area', 20000000); + $config->set('solid_infill_every_layers', 2); + $config->set('perimeter_speed', 99); + $config->set('external_perimeter_speed', 99); + $config->set('cooling', 0); + $config->set('first_layer_speed', '100%'); + + my $print = Slic3r::Test::init_print('20mm_cube', config => $config); + my %layers_with_extrusion = (); + Slic3r::GCode::Reader->new->parse(Slic3r::Test::gcode($print), sub { + my ($self, $cmd, $args, $info) = @_; + + if ($cmd eq 'G1' && $info->{dist_XY} > 0 && $info->{extruding}) { + if (($args->{F} // $self->F) != $config->perimeter_speed*60) { + $layers_with_extrusion{$self->Z} = ($args->{F} // $self->F); + } + } + }); + + ok !%layers_with_extrusion, + "solid_infill_below_area and solid_infill_every_layers are ignored when fill_density is 0"; +} + +{ + my $config = Slic3r::Config->new_from_defaults; + $config->set('skirts', 0); + $config->set('perimeters', 3); + $config->set('fill_density', 0); + $config->set('layer_height', 0.2); + $config->set('first_layer_height', 0.2); + $config->set('nozzle_diameter', [0.35]); + $config->set('infill_extruder', 2); + $config->set('solid_infill_extruder', 2); + $config->set('infill_extrusion_width', 0.52); + $config->set('solid_infill_extrusion_width', 0.52); + $config->set('first_layer_extrusion_width', 0); + + my $print = Slic3r::Test::init_print('A', config => $config); + my %infill = (); # Z => [ Line, Line ... ] + my $tool = undef; + Slic3r::GCode::Reader->new->parse(Slic3r::Test::gcode($print), sub { + my ($self, $cmd, $args, $info) = @_; + + if ($cmd =~ /^T(\d+)/) { + $tool = $1; + } elsif ($cmd eq 'G1' && $info->{extruding} && $info->{dist_XY} > 0) { + if ($tool == $config->infill_extruder-1) { + my $z = 1 * $self->Z; + $infill{$z} ||= []; + push @{$infill{$z}}, Slic3r::Line->new_scale( + [ $self->X, $self->Y ], + [ $info->{new_X}, $info->{new_Y} ], + ); + } + } + }); + my $grow_d = scale($config->infill_extrusion_width)/2; + my $layer0_infill = union([ map @{$_->grow($grow_d)}, @{ $infill{0.2} } ]); + my $layer1_infill = union([ map @{$_->grow($grow_d)}, @{ $infill{0.4} } ]); + my $diff = diff($layer0_infill, $layer1_infill); + $diff = offset2_ex($diff, -$grow_d, +$grow_d); + $diff = [ grep { $_->area > 2*(($grow_d*2)**2) } @$diff ]; + is scalar(@$diff), 0, 'no missing parts in solid shell when fill_density is 0'; +} + +{ + # GH: #2697 + my $config = Slic3r::Config->new_from_defaults; + $config->set('perimeter_extrusion_width', 0.72); + $config->set('top_infill_extrusion_width', 0.1); + $config->set('infill_extruder', 2); # in order to distinguish infill + $config->set('solid_infill_extruder', 2); # in order to distinguish infill + + my $print = Slic3r::Test::init_print('20mm_cube', config => $config); + my %infill = (); # Z => [ Line, Line ... ] + my %other = (); # Z => [ Line, Line ... ] + my $tool = undef; + Slic3r::GCode::Reader->new->parse(Slic3r::Test::gcode($print), sub { + my ($self, $cmd, $args, $info) = @_; + + if ($cmd =~ /^T(\d+)/) { + $tool = $1; + } elsif ($cmd eq 'G1' && $info->{extruding} && $info->{dist_XY} > 0) { + my $z = 1 * $self->Z; + my $line = Slic3r::Line->new_scale( + [ $self->X, $self->Y ], + [ $info->{new_X}, $info->{new_Y} ], + ); + if ($tool == $config->infill_extruder-1) { + $infill{$z} //= []; + push @{$infill{$z}}, $line; + } else { + $other{$z} //= []; + push @{$other{$z}}, $line; + } + } + }); + my $top_z = max(keys %infill); + my $top_infill_grow_d = scale($config->top_infill_extrusion_width)/2; + my $top_infill = union([ map @{$_->grow($top_infill_grow_d)}, @{ $infill{$top_z} } ]); + my $perimeters_grow_d = scale($config->perimeter_extrusion_width)/2; + my $perimeters = union([ map @{$_->grow($perimeters_grow_d)}, @{ $other{$top_z} } ]); + my $covered = union_ex([ @$top_infill, @$perimeters ]); + my @holes = map @{$_->holes}, @$covered; + ok sum(map unscale unscale $_->area*-1, @holes) < 1, 'no gaps between top solid infill and perimeters'; +} +*/ + +bool test_if_solid_surface_filled(const ExPolygon& expolygon, double flow_spacing, double angle, double density) +{ + std::unique_ptr filler(Slic3r::Fill::new_from_type("rectilinear")); + filler->bounding_box = get_extents(expolygon.contour); + filler->angle = float(angle); + + Flow flow(flow_spacing, 0.4, flow_spacing); + filler->spacing = flow.spacing(); + + FillParams fill_params; + fill_params.density = float(density); + fill_params.dont_adjust = false; + + Surface surface(stBottom, expolygon); + Slic3r::Polylines paths = filler->fill_surface(&surface, fill_params); + + // 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 + float line_offset = float(scale_(filler->spacing / 2.0 + EPSILON)); + std::for_each(paths.begin(), paths.end(), [line_offset, &grown_paths] (const Slic3r::Polyline& p) { + polygons_append(grown_paths, offset(p, line_offset)); + }); + + // Shrink the initial expolygon a bit, this simulates the infill / perimeter overlap that we usually apply. + ExPolygons uncovered = diff_ex(offset(expolygon, - float(0.2 * scale_(flow_spacing))), grown_paths, true); + + // ignore very small dots + const double scaled_flow_spacing = std::pow(scale_(flow_spacing), 2); + uncovered.erase(std::remove_if(uncovered.begin(), uncovered.end(), [scaled_flow_spacing](const ExPolygon& poly) { return poly.area() < scaled_flow_spacing; }), uncovered.end()); + +#if 0 + if (! uncovered.empty()) { + BoundingBox bbox = get_extents(expolygon.contour); + bbox.merge(get_extents(uncovered)); + bbox.merge(get_extents(grown_paths)); + SVG svg("c:\\data\\temp\\test_if_solid_surface_filled.svg", bbox); + svg.draw(expolygon); + svg.draw(uncovered, "red"); + svg.Close(); + } +#endif + + return uncovered.empty(); // solid surface is fully filled +} diff --git a/tests/fff_print/test_flow.cpp b/tests/fff_print/test_flow.cpp index 36ff3c7e7b..dc14d96eee 100644 --- a/tests/fff_print/test_flow.cpp +++ b/tests/fff_print/test_flow.cpp @@ -18,22 +18,25 @@ using namespace Slic3r; SCENARIO("Extrusion width specifics", "[!mayfail]") { GIVEN("A config with a skirt, brim, some fill density, 3 perimeters, and 1 bottom solid layer and a 20mm cube mesh") { // this is a sharedptr - std::shared_ptr config(Slic3r::DynamicPrintConfig::new_from_defaults()); - config->opt_int("skirts") = 1; - config->opt_float("brim_width") = 2.; - config->opt_int("perimeters") = 3; - config->set_deserialize("fill_density", "40%"); - config->set_deserialize("first_layer_height", "100%"); + DynamicPrintConfig config = Slic3r::DynamicPrintConfig::full_print_config(); + config.set_deserialize({ + { "brim_width", 2 }, + { "skirts", 1 }, + { "perimeters", 3 }, + { "fill_density", "40%" }, + { "first_layer_height", "100%" } + }); WHEN("first layer width set to 2mm") { Slic3r::Model model; - config->set_deserialize("first_layer_extrusion_width", "2"); - std::shared_ptr print = Slic3r::Test::init_print({TestMesh::cube_20x20x20}, model, config); + config.set("first_layer_extrusion_width", 2); + Slic3r::Print print; + Slic3r::Test::init_print({TestMesh::cube_20x20x20}, print, model, config); std::vector E_per_mm_bottom; std::string gcode = Test::gcode(print); Slic3r::GCodeReader parser; - const double layer_height = config->opt_float("layer_height"); + const double layer_height = config.opt_float("layer_height"); parser.parse_buffer(gcode, [&E_per_mm_bottom, layer_height] (Slic3r::GCodeReader& self, const Slic3r::GCodeReader::GCodeLine& line) { if (self.z() == Approx(layer_height).margin(0.01)) { // only consider first layer diff --git a/tests/fff_print/test_model.cpp b/tests/fff_print/test_model.cpp new file mode 100644 index 0000000000..3378a83638 --- /dev/null +++ b/tests/fff_print/test_model.cpp @@ -0,0 +1,61 @@ +#include + +#include "libslic3r/libslic3r.h" +#include "libslic3r/Model.hpp" + +#include +#include + +#include "test_data.hpp" + +using namespace Slic3r; +using namespace Slic3r::Test; + +SCENARIO("Model construction", "[Model]") { + GIVEN("A Slic3r Model") { + Slic3r::Model model; + Slic3r::TriangleMesh sample_mesh = Slic3r::make_cube(20,20,20); + Slic3r::DynamicPrintConfig config = Slic3r::DynamicPrintConfig::full_print_config(); + Slic3r::Print print; + + WHEN("Model object is added") { + Slic3r::ModelObject *model_object = model.add_object(); + THEN("Model object list == 1") { + REQUIRE(model.objects.size() == 1); + } + model_object->add_volume(sample_mesh); + THEN("Model volume list == 1") { + REQUIRE(model_object->volumes.size() == 1); + } + THEN("Model volume is a part") { + REQUIRE(model_object->volumes.front()->is_model_part()); + } + THEN("Mesh is equivalent to input mesh.") { + REQUIRE(! sample_mesh.its.vertices.empty()); + const std::vector& mesh_vertices = model_object->volumes.front()->mesh().its.vertices; + Vec3f mesh_offset = model_object->volumes.front()->source.mesh_offset.cast(); + for (size_t i = 0; i < sample_mesh.its.vertices.size(); ++ i) { + const Vec3f &p1 = sample_mesh.its.vertices[i]; + const Vec3f p2 = mesh_vertices[i] + mesh_offset; + REQUIRE((p2 - p1).norm() < EPSILON); + } + } + model_object->add_instance(); + model.arrange_objects(PrintConfig::min_object_distance(&config)); + model.center_instances_around_point(Slic3r::Vec2d(100, 100)); + model_object->ensure_on_bed(); + print.auto_assign_extruders(model_object); + THEN("Print works?") { + print.set_status_silent(); + print.apply(model, config); + print.process(); + boost::filesystem::path temp = boost::filesystem::unique_path(); + print.export_gcode(temp.string(), nullptr); + REQUIRE(boost::filesystem::exists(temp)); + REQUIRE(boost::filesystem::is_regular_file(temp)); + REQUIRE(boost::filesystem::file_size(temp) > 0); + boost::nowide::remove(temp.string().c_str()); + } + } + } +} diff --git a/tests/fff_print/test_print.cpp b/tests/fff_print/test_print.cpp new file mode 100644 index 0000000000..484e6018ef --- /dev/null +++ b/tests/fff_print/test_print.cpp @@ -0,0 +1,127 @@ +#include + +#include "libslic3r/libslic3r.h" +#include "libslic3r/Print.hpp" + +#include "test_data.hpp" + +using namespace Slic3r; +using namespace Slic3r::Test; + +SCENARIO("PrintObject: Perimeter generation", "[PrintObject]") { + GIVEN("20mm cube and default config") { + WHEN("make_perimeters() is called") { + Slic3r::Print print; + Slic3r::Test::init_and_process_print({TestMesh::cube_20x20x20}, print, { { "fill_density", 0 } }); + const PrintObject &object = *print.objects().front(); + THEN("67 layers exist in the model") { + REQUIRE(object.layers().size() == 66); + } + THEN("Every layer in region 0 has 1 island of perimeters") { + for (const Layer *layer : object.layers()) + REQUIRE(layer->regions().front()->perimeters.entities.size() == 1); + } + THEN("Every layer in region 0 has 3 paths in its perimeters list.") { + for (const Layer *layer : object.layers()) + REQUIRE(layer->regions().front()->perimeters.items_count() == 3); + } + } + } +} + +SCENARIO("Print: Skirt generation", "[Print]") { + GIVEN("20mm cube and default config") { + WHEN("Skirts is set to 2 loops") { + Slic3r::Print print; + Slic3r::Test::init_and_process_print({TestMesh::cube_20x20x20}, print, { + { "skirt_height", 1 }, + { "skirt_distance", 1 }, + { "skirts", 2 } + }); + THEN("Skirt Extrusion collection has 2 loops in it") { + REQUIRE(print.skirt().items_count() == 2); + REQUIRE(print.skirt().flatten().entities.size() == 2); + } + } + } +} + +SCENARIO("Print: Changing number of solid surfaces does not cause all surfaces to become internal.", "[Print]") { + GIVEN("sliced 20mm cube and config with top_solid_surfaces = 2 and bottom_solid_surfaces = 1") { + Slic3r::DynamicPrintConfig config = Slic3r::DynamicPrintConfig::full_print_config(); + config.set_deserialize({ + { "top_solid_layers", 2 }, + { "bottom_solid_layers", 1 }, + { "layer_height", 0.5 }, // get a known number of layers + { "first_layer_height", 0.5 } + }); + Slic3r::Print print; + Slic3r::Model model; + Slic3r::Test::init_print({TestMesh::cube_20x20x20}, print, model, config); + // Precondition: Ensure that the model has 2 solid top layers (39, 38) + // and one solid bottom layer (0). + auto test_is_solid_infill = [&print](size_t obj_id, size_t layer_id) { + const Layer &layer = *(print.objects().at(obj_id)->get_layer((int)layer_id)); + // iterate over all of the regions in the layer + for (const LayerRegion *region : layer.regions()) { + // for each region, iterate over the fill surfaces + for (const Surface &surface : region->fill_surfaces.surfaces) + CHECK(surface.is_solid()); + } + }; + print.process(); + test_is_solid_infill(0, 0); // should be solid + test_is_solid_infill(0, 39); // should be solid + test_is_solid_infill(0, 38); // should be solid + WHEN("Model is re-sliced with top_solid_layers == 3") { + config.set("top_solid_layers", 3); + print.apply(model, config); + print.process(); + THEN("Print object does not have 0 solid bottom layers.") { + test_is_solid_infill(0, 0); + } + AND_THEN("Print object has 3 top solid layers") { + test_is_solid_infill(0, 39); + test_is_solid_infill(0, 38); + test_is_solid_infill(0, 37); + } + } + } +} + +SCENARIO("Print: Brim generation", "[Print]") { + GIVEN("20mm cube and default config, 1mm first layer width") { + WHEN("Brim is set to 3mm") { + Slic3r::Print print; + Slic3r::Test::init_and_process_print({TestMesh::cube_20x20x20}, print, { + { "first_layer_extrusion_width", 1 }, + { "brim_width", 3 } + }); + THEN("Brim Extrusion collection has 3 loops in it") { + REQUIRE(print.brim().items_count() == 3); + } + } + WHEN("Brim is set to 6mm") { + Slic3r::Print print; + Slic3r::Test::init_and_process_print({TestMesh::cube_20x20x20}, print, { + { "first_layer_extrusion_width", 1 }, + { "brim_width", 6 } + }); + THEN("Brim Extrusion collection has 6 loops in it") { + REQUIRE(print.brim().items_count() == 6); + } + } + WHEN("Brim is set to 6mm, extrusion width 0.5mm") { + Slic3r::Print print; + Slic3r::Test::init_and_process_print({TestMesh::cube_20x20x20}, print, { + { "first_layer_extrusion_width", 1 }, + { "brim_width", 6 }, + { "first_layer_extrusion_width", 0.5 } + }); + print.process(); + THEN("Brim Extrusion collection has 12 loops in it") { + REQUIRE(print.brim().items_count() == 14); + } + } + } +} diff --git a/tests/fff_print/test_printgcode.cpp b/tests/fff_print/test_printgcode.cpp new file mode 100644 index 0000000000..5f47cfb772 --- /dev/null +++ b/tests/fff_print/test_printgcode.cpp @@ -0,0 +1,270 @@ +#include + +#include "libslic3r/libslic3r.h" +#include "libslic3r/GCodeReader.hpp" + +#include "test_data.hpp" + +#include +#include + +using namespace Slic3r; +using namespace Slic3r::Test; + +std::regex perimeters_regex("G1 X[-0-9.]* Y[-0-9.]* E[-0-9.]* ; perimeter"); +std::regex infill_regex("G1 X[-0-9.]* Y[-0-9.]* E[-0-9.]* ; infill"); +std::regex skirt_regex("G1 X[-0-9.]* Y[-0-9.]* E[-0-9.]* ; skirt"); + +SCENARIO( "PrintGCode basic functionality", "[PrintGCode]") { + GIVEN("A default configuration and a print test object") { + WHEN("the output is executed with no support material") { + Slic3r::Print print; + Slic3r::Model model; + Slic3r::Test::init_print({TestMesh::cube_20x20x20}, print, model, { + { "layer_height", 0.2 }, + { "first_layer_height", 0.2 }, + { "first_layer_extrusion_width", 0 }, + { "gcode_comments", true }, + { "start_gcode", "" } + }); + std::string gcode = Slic3r::Test::gcode(print); + THEN("Some text output is generated.") { + REQUIRE(gcode.size() > 0); + } + THEN("Exported text contains slic3r version") { + REQUIRE(gcode.find(SLIC3R_VERSION) != std::string::npos); + } + //THEN("Exported text contains git commit id") { + // REQUIRE(gcode.find("; Git Commit") != std::string::npos); + // REQUIRE(gcode.find(SLIC3R_BUILD_ID) != std::string::npos); + //} + THEN("Exported text contains extrusion statistics.") { + REQUIRE(gcode.find("; external perimeters extrusion width") != std::string::npos); + REQUIRE(gcode.find("; perimeters extrusion width") != std::string::npos); + REQUIRE(gcode.find("; infill extrusion width") != std::string::npos); + REQUIRE(gcode.find("; solid infill extrusion width") != std::string::npos); + REQUIRE(gcode.find("; top infill extrusion width") != std::string::npos); + REQUIRE(gcode.find("; support material extrusion width") == std::string::npos); + REQUIRE(gcode.find("; first layer extrusion width") == std::string::npos); + } + THEN("Exported text does not contain cooling markers (they were consumed)") { + REQUIRE(gcode.find(";_EXTRUDE_SET_SPEED") == std::string::npos); + } + + THEN("GCode preamble is emitted.") { + REQUIRE(gcode.find("G21 ; set units to millimeters") != std::string::npos); + } + + THEN("Config options emitted for print config, default region config, default object config") { + REQUIRE(gcode.find("; first_layer_temperature") != std::string::npos); + REQUIRE(gcode.find("; layer_height") != std::string::npos); + REQUIRE(gcode.find("; fill_density") != std::string::npos); + } + THEN("Infill is emitted.") { + std::smatch has_match; + REQUIRE(std::regex_search(gcode, has_match, infill_regex)); + } + THEN("Perimeters are emitted.") { + std::smatch has_match; + REQUIRE(std::regex_search(gcode, has_match, perimeters_regex)); + } + THEN("Skirt is emitted.") { + std::smatch has_match; + REQUIRE(std::regex_search(gcode, has_match, skirt_regex)); + } + THEN("final Z height is 20mm") { + double final_z = 0.0; + GCodeReader reader; + reader.apply_config(print.config()); + reader.parse_buffer(gcode, [&final_z] (GCodeReader& self, const GCodeReader::GCodeLine& line) { + final_z = std::max(final_z, static_cast(self.z())); // record the highest Z point we reach + }); + REQUIRE(final_z == Approx(20.)); + } + } + WHEN("output is executed with complete objects and two differently-sized meshes") { + Slic3r::Print print; + Slic3r::Model model; + Slic3r::Test::init_print({TestMesh::cube_20x20x20,TestMesh::cube_20x20x20}, print, model, { + { "first_layer_extrusion_width", 0 }, + { "first_layer_height", 0.3 }, + { "layer_height", 0.2 }, + { "support_material", false }, + { "raft_layers", 0 }, + { "complete_objects", true }, + { "gcode_comments", true }, + { "between_objects_gcode", "; between-object-gcode" } + }); + std::string gcode = Slic3r::Test::gcode(print); + THEN("Some text output is generated.") { + REQUIRE(gcode.size() > 0); + } + THEN("Infill is emitted.") { + std::smatch has_match; + REQUIRE(std::regex_search(gcode, has_match, infill_regex)); + } + THEN("Perimeters are emitted.") { + std::smatch has_match; + REQUIRE(std::regex_search(gcode, has_match, perimeters_regex)); + } + THEN("Skirt is emitted.") { + std::smatch has_match; + REQUIRE(std::regex_search(gcode, has_match, skirt_regex)); + } + THEN("Between-object-gcode is emitted.") { + REQUIRE(gcode.find("; between-object-gcode") != std::string::npos); + } + THEN("final Z height is 20.1mm") { + double final_z = 0.0; + GCodeReader reader; + reader.apply_config(print.config()); + reader.parse_buffer(gcode, [&final_z] (GCodeReader& self, const GCodeReader::GCodeLine& line) { + final_z = std::max(final_z, static_cast(self.z())); // record the highest Z point we reach + }); + REQUIRE(final_z == Approx(20.1)); + } + THEN("Z height resets on object change") { + double final_z = 0.0; + bool reset = false; + GCodeReader reader; + reader.apply_config(print.config()); + reader.parse_buffer(gcode, [&final_z, &reset] (GCodeReader& self, const GCodeReader::GCodeLine& line) { + if (final_z > 0 && std::abs(self.z() - 0.3) < 0.01 ) { // saw higher Z before this, now it's lower + reset = true; + } else { + final_z = std::max(final_z, static_cast(self.z())); // record the highest Z point we reach + } + }); + REQUIRE(reset == true); + } + THEN("Shorter object is printed before taller object.") { + double final_z = 0.0; + bool reset = false; + GCodeReader reader; + reader.apply_config(print.config()); + reader.parse_buffer(gcode, [&final_z, &reset] (GCodeReader& self, const GCodeReader::GCodeLine& line) { + if (final_z > 0 && std::abs(self.z() - 0.3) < 0.01 ) { + reset = (final_z > 20.0); + } else { + final_z = std::max(final_z, static_cast(self.z())); // record the highest Z point we reach + } + }); + REQUIRE(reset == true); + } + } + WHEN("the output is executed with support material") { + std::string gcode = ::Test::slice({TestMesh::cube_20x20x20}, { + { "first_layer_extrusion_width", 0 }, + { "support_material", true }, + { "raft_layers", 3 }, + { "gcode_comments", true } + }); + THEN("Some text output is generated.") { + REQUIRE(gcode.size() > 0); + } + THEN("Exported text contains extrusion statistics.") { + REQUIRE(gcode.find("; external perimeters extrusion width") != std::string::npos); + REQUIRE(gcode.find("; perimeters extrusion width") != std::string::npos); + REQUIRE(gcode.find("; infill extrusion width") != std::string::npos); + REQUIRE(gcode.find("; solid infill extrusion width") != std::string::npos); + REQUIRE(gcode.find("; top infill extrusion width") != std::string::npos); + REQUIRE(gcode.find("; support material extrusion width") != std::string::npos); + REQUIRE(gcode.find("; first layer extrusion width") == std::string::npos); + } + THEN("Raft is emitted.") { + REQUIRE(gcode.find("; raft") != std::string::npos); + } + } + WHEN("the output is executed with a separate first layer extrusion width") { + std::string gcode = ::Test::slice({ TestMesh::cube_20x20x20 }, { + { "first_layer_extrusion_width", "0.5" } + }); + THEN("Some text output is generated.") { + REQUIRE(gcode.size() > 0); + } + THEN("Exported text contains extrusion statistics.") { + REQUIRE(gcode.find("; external perimeters extrusion width") != std::string::npos); + REQUIRE(gcode.find("; perimeters extrusion width") != std::string::npos); + REQUIRE(gcode.find("; infill extrusion width") != std::string::npos); + REQUIRE(gcode.find("; solid infill extrusion width") != std::string::npos); + REQUIRE(gcode.find("; top infill extrusion width") != std::string::npos); + REQUIRE(gcode.find("; support material extrusion width") == std::string::npos); + REQUIRE(gcode.find("; first layer extrusion width") != std::string::npos); + } + } + WHEN("Cooling is enabled and the fan is disabled.") { + std::string gcode = ::Test::slice({ TestMesh::cube_20x20x20 }, { + { "cooling", true }, + { "disable_fan_first_layers", 5 } + }); + THEN("GCode to disable fan is emitted."){ + REQUIRE(gcode.find("M107") != std::string::npos); + } + } + WHEN("end_gcode exists with layer_num and layer_z") { + std::string gcode = ::Test::slice({ TestMesh::cube_20x20x20 }, { + { "end_gcode", "; Layer_num [layer_num]\n; Layer_z [layer_z]" }, + { "layer_height", 0.1 }, + { "first_layer_height", 0.1 } + }); + THEN("layer_num and layer_z are processed in the end gcode") { + REQUIRE(gcode.find("; Layer_num 199") != std::string::npos); + REQUIRE(gcode.find("; Layer_z 20") != std::string::npos); + } + } + WHEN("current_extruder exists in start_gcode") { + { + std::string gcode = ::Test::slice({ TestMesh::cube_20x20x20 }, { + { "start_gcode", "; Extruder [current_extruder]" } + }); + THEN("current_extruder is processed in the start gcode and set for first extruder") { + REQUIRE(gcode.find("; Extruder 0") != std::string::npos); + } + } + { + DynamicPrintConfig config = DynamicPrintConfig::full_print_config(); + config.set_num_extruders(4); + config.set_deserialize({ + { "start_gcode", "; Extruder [current_extruder]" }, + { "infill_extruder", 2 }, + { "solid_infill_extruder", 2 }, + { "perimeter_extruder", 2 }, + { "support_material_extruder", 2 }, + { "support_material_interface_extruder", 2 } + }); + std::string gcode = Slic3r::Test::slice({TestMesh::cube_20x20x20}, config); + THEN("current_extruder is processed in the start gcode and set for second extruder") { + REQUIRE(gcode.find("; Extruder 1") != std::string::npos); + } + } + } + + WHEN("layer_num represents the layer's index from z=0") { + std::string gcode = ::Test::slice({ TestMesh::cube_20x20x20, TestMesh::cube_20x20x20 }, { + { "complete_objects", true }, + { "gcode_comments", true }, + { "layer_gcode", ";Layer:[layer_num] ([layer_z] mm)" }, + { "layer_height", 1.0 }, + { "first_layer_height", 1.0 } + }); + // End of the 1st object. + size_t pos = gcode.find(";Layer:19 "); + THEN("First and second object last layer is emitted") { + // First object + REQUIRE(pos != std::string::npos); + pos += 10; + REQUIRE(pos < gcode.size()); + double z = 0; + REQUIRE((sscanf(gcode.data() + pos, "(%lf mm)", &z) == 1)); + REQUIRE(z == Approx(20.)); + // Second object + pos = gcode.find(";Layer:39 ", pos); + REQUIRE(pos != std::string::npos); + pos += 10; + REQUIRE(pos < gcode.size()); + REQUIRE((sscanf(gcode.data() + pos, "(%lf mm)", &z) == 1)); + REQUIRE(z == Approx(20.)); + } + } + } +} diff --git a/tests/fff_print/test_printobject.cpp b/tests/fff_print/test_printobject.cpp new file mode 100644 index 0000000000..e7c441e8c9 --- /dev/null +++ b/tests/fff_print/test_printobject.cpp @@ -0,0 +1,88 @@ +#include + +#include "libslic3r/libslic3r.h" +#include "libslic3r/Print.hpp" + +#include "test_data.hpp" + +using namespace Slic3r; +using namespace Slic3r::Test; + +SCENARIO("PrintObject: object layer heights", "[PrintObject]") { + GIVEN("20mm cube and default initial config, initial layer height of 2mm") { + WHEN("generate_object_layers() is called for 2mm layer heights and nozzle diameter of 3mm") { + Slic3r::Print print; + Slic3r::Test::init_and_process_print({TestMesh::cube_20x20x20}, print, { + { "first_layer_height", 2 }, + { "layer_height", 2 }, + { "nozzle_diameter", 3 } + }); + const std::vector &layers = print.objects().front()->layers(); + THEN("The output vector has 10 entries") { + REQUIRE(layers.size() == 10); + } + AND_THEN("Each layer is approximately 2mm above the previous Z") { + coordf_t last = 0.0; + for (size_t i = 0; i < layers.size(); ++ i) { + REQUIRE((layers[i]->print_z - last) == Approx(2.0)); + last = layers[i]->print_z; + } + } + } + WHEN("generate_object_layers() is called for 10mm layer heights and nozzle diameter of 11mm") { + Slic3r::Print print; + Slic3r::Test::init_and_process_print({TestMesh::cube_20x20x20}, print, { + { "first_layer_height", 2 }, + { "layer_height", 10 }, + { "nozzle_diameter", 11 } + }); + const std::vector &layers = print.objects().front()->layers(); + THEN("The output vector has 3 entries") { + REQUIRE(layers.size() == 3); + } + AND_THEN("Layer 0 is at 2mm") { + REQUIRE(layers.front()->print_z == Approx(2.0)); + } + AND_THEN("Layer 1 is at 12mm") { + REQUIRE(layers[1]->print_z == Approx(12.0)); + } + } + WHEN("generate_object_layers() is called for 15mm layer heights and nozzle diameter of 16mm") { + Slic3r::Print print; + Slic3r::Test::init_and_process_print({TestMesh::cube_20x20x20}, print, { + { "first_layer_height", 2 }, + { "layer_height", 15 }, + { "nozzle_diameter", 16 } + }); + const std::vector &layers = print.objects().front()->layers(); + THEN("The output vector has 2 entries") { + REQUIRE(layers.size() == 2); + } + AND_THEN("Layer 0 is at 2mm") { + REQUIRE(layers[0]->print_z == Approx(2.0)); + } + AND_THEN("Layer 1 is at 17mm") { + REQUIRE(layers[1]->print_z == Approx(17.0)); + } + } +#if 0 + WHEN("generate_object_layers() is called for 15mm layer heights and nozzle diameter of 5mm") { + Slic3r::Print print; + Slic3r::Test::init_and_process_print({TestMesh::cube_20x20x20}, print, { + { "first_layer_height", 2 }, + { "layer_height", 15 }, + { "nozzle_diameter", 5 } + }); + const std::vector &layers = print.objects().front()->layers(); + THEN("The layer height is limited to 5mm.") { + CHECK(layers.size() == 5); + coordf_t last = 2.0; + for (size_t i = 1; i < layers.size(); i++) { + REQUIRE((layers[i]->print_z - last) == Approx(5.0)); + last = layers[i]->print_z; + } + } + } +#endif + } +} diff --git a/tests/fff_print/test_skirt_brim.cpp b/tests/fff_print/test_skirt_brim.cpp index 64c548d3f2..9fabb7aa67 100644 --- a/tests/fff_print/test_skirt_brim.cpp +++ b/tests/fff_print/test_skirt_brim.cpp @@ -12,251 +12,241 @@ using namespace Slic3r::Test; using namespace Slic3r; /// Helper method to find the tool used for the brim (always the first extrusion) -int get_brim_tool(std::string &gcode, Slic3r::GCodeReader& parser) { +static int get_brim_tool(const std::string &gcode) +{ int brim_tool = -1; int tool = -1; - - parser.parse_buffer(gcode, [&tool, &brim_tool] (Slic3r::GCodeReader& self, const Slic3r::GCodeReader::GCodeLine& line) - { - // if the command is a T command, set the the current tool - if (boost::starts_with(line.cmd(), "T")) { - tool = atoi(line.cmd().data() + 1); - } else if (line.cmd() == "G1" && line.extruding(self) && line.dist_XY(self) > 0 && brim_tool < 0) { - brim_tool = tool; - } - }); - + GCodeReader parser; + parser.parse_buffer(gcode, [&tool, &brim_tool] (Slic3r::GCodeReader &self, const Slic3r::GCodeReader::GCodeLine &line) + { + // if the command is a T command, set the the current tool + if (boost::starts_with(line.cmd(), "T")) { + tool = atoi(line.cmd().data() + 1); + } else if (line.cmd() == "G1" && line.extruding(self) && line.dist_XY(self) > 0 && brim_tool < 0) { + brim_tool = tool; + } + }); return brim_tool; } TEST_CASE("Skirt height is honored") { - std::shared_ptr config(Slic3r::DynamicPrintConfig::new_from_defaults()); - config->opt_int("skirts") = 1; - config->opt_int("skirt_height") = 5; - config->opt_int("perimeters") = 0; - config->opt_float("support_material_speed") = 99; + DynamicPrintConfig config = Slic3r::DynamicPrintConfig::full_print_config(); + config.set_deserialize({ + { "skirts", 1 }, + { "skirt_height", 5 }, + { "perimeters", 0 }, + { "support_material_speed", 99 }, + // avoid altering speeds unexpectedly + { "cooling", false }, + { "first_layer_speed", "100%" } + }); - // avoid altering speeds unexpectedly - config->set_deserialize("cooling", "0"); - config->set_deserialize("first_layer_speed", "100%"); - double support_speed = config->opt("support_material_speed")->value * MM_PER_MIN; + std::string gcode; + SECTION("printing a single object") { + gcode = Slic3r::Test::slice({TestMesh::cube_20x20x20}, config); + } + SECTION("printing multiple objects") { + gcode = Slic3r::Test::slice({TestMesh::cube_20x20x20, TestMesh::cube_20x20x20}, config); + } std::map layers_with_skirt; - std::string gcode; + double support_speed = config.opt("support_material_speed")->value * MM_PER_MIN; GCodeReader parser; - Slic3r::Model model; - - SECTION("printing a single object") { - auto print = Slic3r::Test::init_print({TestMesh::cube_20x20x20}, model, config); - gcode = Slic3r::Test::gcode(print); - } - - SECTION("printing multiple objects") { - auto print = Slic3r::Test::init_print({TestMesh::cube_20x20x20, TestMesh::cube_20x20x20}, model, config); - gcode = Slic3r::Test::gcode(print); - } - parser.parse_buffer(gcode, [&layers_with_skirt, &support_speed] (Slic3r::GCodeReader& self, const Slic3r::GCodeReader::GCodeLine& line) - { + parser.parse_buffer(gcode, [&layers_with_skirt, &support_speed] (Slic3r::GCodeReader &self, const Slic3r::GCodeReader::GCodeLine &line) { if (line.extruding(self) && self.f() == Approx(support_speed)) { layers_with_skirt[self.z()] = 1; } }); - - REQUIRE(layers_with_skirt.size() == (size_t)config->opt_int("skirt_height")); + REQUIRE(layers_with_skirt.size() == (size_t)config.opt_int("skirt_height")); } SCENARIO("Original Slic3r Skirt/Brim tests", "[!mayfail]") { - Slic3r::GCodeReader parser; - Slic3r::Model model; - std::string gcode; GIVEN("A default configuration") { - std::shared_ptr config(Slic3r::DynamicPrintConfig::new_from_defaults()); - config->set_num_extruders(4); - config->opt_float("support_material_speed") = 99; - config->set_deserialize("first_layer_height", "0.3"); - config->set_deserialize("gcode_comments", "1"); - - // avoid altering speeds unexpectedly - config->set_deserialize("cooling", "0"); - config->set_deserialize("first_layer_speed", "100%"); - // remove noise from top/solid layers - config->opt_int("top_solid_layers") = 0; - config->opt_int("bottom_solid_layers") = 1; + DynamicPrintConfig config = Slic3r::DynamicPrintConfig::full_print_config(); + config.set_num_extruders(4); + config.set_deserialize({ + { "support_material_speed", 99 }, + { "first_layer_height", 0.3 }, + { "gcode_comments", true }, + // avoid altering speeds unexpectedly + { "cooling", false }, + { "first_layer_speed", "100%" }, + // remove noise from top/solid layers + { "top_solid_layers", 0 }, + { "bottom_solid_layers", 1 } + }); WHEN("Brim width is set to 5") { - config->opt_int("perimeters") = 0; - config->opt_int("skirts") = 0; - config->opt_float("brim_width") = 5; - THEN("Brim is generated") { - auto print = Slic3r::Test::init_print({TestMesh::cube_20x20x20}, model, config); - gcode = Slic3r::Test::gcode(print); + config.set_deserialize({ + { "perimeters", 0 }, + { "skirts", 0 }, + { "brim_width", 5 } + }); + THEN("Brim is generated") { + std::string gcode = Slic3r::Test::slice({TestMesh::cube_20x20x20}, config); bool brim_generated = false; - double support_speed = config->opt("support_material_speed")->value * MM_PER_MIN; - parser.parse_buffer(gcode, [&brim_generated, support_speed] (Slic3r::GCodeReader& self, const Slic3r::GCodeReader::GCodeLine& line) - { - if (self.z() == Approx(0.3) || line.new_Z(self) == Approx(0.3)) { - if (line.extruding(self) && self.f() == Approx(support_speed)) { - brim_generated = true; - } + double support_speed = config.opt("support_material_speed")->value * MM_PER_MIN; + Slic3r::GCodeReader parser; + parser.parse_buffer(gcode, [&brim_generated, support_speed] (Slic3r::GCodeReader& self, const Slic3r::GCodeReader::GCodeLine& line) { + if (self.z() == Approx(0.3) || line.new_Z(self) == Approx(0.3)) { + if (line.extruding(self) && self.f() == Approx(support_speed)) { + brim_generated = true; } - }); + } + }); REQUIRE(brim_generated); } } WHEN("Skirt area is smaller than the brim") { - config->opt_int("skirts") = 1; - config->opt_float("brim_width") = 10; - auto print = Slic3r::Test::init_print({TestMesh::cube_20x20x20}, model, config); + config.set_deserialize({ + { "skirts", 1 }, + { "brim_width", 10} + }); THEN("Gcode generates") { - REQUIRE(! Slic3r::Test::gcode(print).empty()); + REQUIRE(! Slic3r::Test::slice({TestMesh::cube_20x20x20}, config).empty()); } } WHEN("Skirt height is 0 and skirts > 0") { - config->opt_int("skirts") = 2; - config->opt_int("skirt_height") = 0; - - auto print = Slic3r::Test::init_print({TestMesh::cube_20x20x20}, model, config); + config.set_deserialize({ + { "skirts", 2 }, + { "skirt_height", 0 } + }); THEN("Gcode generates") { - REQUIRE(! Slic3r::Test::gcode(print).empty()); + REQUIRE(! Slic3r::Test::slice({TestMesh::cube_20x20x20}, config).empty()); } } WHEN("Perimeter extruder = 2 and support extruders = 3") { - config->opt_int("skirts") = 0; - config->opt_float("brim_width") = 5; - config->opt_int("perimeter_extruder") = 2; - config->opt_int("support_material_extruder") = 3; THEN("Brim is printed with the extruder used for the perimeters of first object") { - auto print = Slic3r::Test::init_print({TestMesh::cube_20x20x20}, model, config); - gcode = Slic3r::Test::gcode(print); - int tool = get_brim_tool(gcode, parser); - REQUIRE(tool == config->opt_int("perimeter_extruder") - 1); + std::string gcode = Slic3r::Test::slice({TestMesh::cube_20x20x20}, { + { "skirts", 0 }, + { "brim_width", 5 }, + { "perimeter_extruder", 2 }, + { "support_material_extruder", 3 } + }); + int tool = get_brim_tool(gcode); + REQUIRE(tool == config.opt_int("perimeter_extruder") - 1); } } WHEN("Perimeter extruder = 2, support extruders = 3, raft is enabled") { - config->opt_int("skirts") = 0; - config->opt_float("brim_width") = 5; - config->opt_int("perimeter_extruder") = 2; - config->opt_int("support_material_extruder") = 3; - config->opt_int("raft_layers") = 1; THEN("brim is printed with same extruder as skirt") { - auto print = Slic3r::Test::init_print({TestMesh::cube_20x20x20}, model, config); - gcode = Slic3r::Test::gcode(print); - int tool = get_brim_tool(gcode, parser); - REQUIRE(tool == config->opt_int("support_material_extruder") - 1); + std::string gcode = Slic3r::Test::slice({TestMesh::cube_20x20x20}, { + { "skirts", 0 }, + { "brim_width", 5 }, + { "perimeter_extruder", 2 }, + { "support_material_extruder", 3 }, + { "raft_layers", 1 } + }); + int tool = get_brim_tool(gcode); + REQUIRE(tool == config.opt_int("support_material_extruder") - 1); } } WHEN("brim width to 1 with layer_width of 0.5") { - config->opt_int("skirts") = 0; - config->set_deserialize("first_layer_extrusion_width", "0.5"); - config->opt_float("brim_width") = 1; - + config.set_deserialize({ + { "skirts", 0 }, + { "first_layer_extrusion_width", 0.5 }, + { "brim_width", 1 } + }); THEN("2 brim lines") { - Slic3r::Model model; - auto print = Slic3r::Test::init_print({TestMesh::cube_20x20x20}, model, config); - print->process(); - REQUIRE(print->brim().entities.size() == 2); + Slic3r::Print print; + Slic3r::Test::init_and_process_print({TestMesh::cube_20x20x20}, print, config); + REQUIRE(print.brim().entities.size() == 2); } } #if 0 WHEN("brim ears on a square") { - config->opt_int("skirts") = 0); - config->set_deserialize("first_layer_extrusion_width", "0.5"); - config->opt_float("brim_width") = 1; - config->set("brim_ears", true); - config->set("brim_ears_max_angle", 91); - - Slic3r::Model model; - auto print = Slic3r::Test::init_print({TestMesh::cube_20x20x20}, model, config); - print->process(); - + config.set_deserialize({ + { "skirts", 0 }, + { "first_layer_extrusion_width", 0.5 }, + { "brim_width", 1 }, + { "brim_ears", 1 }, + { "brim_ears_max_angle", 91 } + }); + Slic3r::Print print; + Slic3r::Test::init_and_process_print({TestMesh::cube_20x20x20}, print, config); THEN("Four brim ears") { - REQUIRE(print->brim.size() == 4); + REQUIRE(print.brim().entities.size() == 4); } } WHEN("brim ears on a square but with a too small max angle") { - config->set("skirts", 0); - config->set("first_layer_extrusion_width", 0.5); - config->set("brim_width", 1); - config->set("brim_ears", true); - config->set("brim_ears_max_angle", 89); - + config.set_deserialize({ + { "skirts", 0 }, + { "first_layer_extrusion_width", 0.5 }, + { "brim_width", 1 }, + { "brim_ears", 1 }, + { "brim_ears_max_angle", 89 } + }); THEN("no brim") { - Slic3r::Model model; - auto print = Slic3r::Test::init_print({TestMesh::cube_20x20x20}, model, config); - print->process(); - REQUIRE(print->brim.size() == 0); + Slic3r::Print print; + Slic3r::Test::init_and_process_print({ TestMesh::cube_20x20x20 }, print, config); + REQUIRE(print.brim().entities.size() == 0); } } #endif WHEN("Object is plated with overhang support and a brim") { - config->opt_float("layer_height") = 0.4; - config->set_deserialize("first_layer_height", "0.4"); - config->opt_int("skirts") = 1; - config->opt_float("skirt_distance") = 0; - config->opt_float("support_material_speed") = 99; - config->opt_int("perimeter_extruder") = 1; - config->opt_int("support_material_extruder") = 2; - config->opt_int("infill_extruder") = 3; // ensure that a tool command gets emitted. - config->set_deserialize("cooling", "0"); // to prevent speeds to be altered - config->set_deserialize("first_layer_speed", "100%"); // to prevent speeds to be altered + config.set_deserialize({ + { "layer_height", 0.4 }, + { "first_layer_height", 0.4 }, + { "skirts", 1 }, + { "skirt_distance", 0 }, + { "support_material_speed", 99 }, + { "perimeter_extruder", 1 }, + { "support_material_extruder", 2 }, + { "infill_extruder", 3 }, // ensure that a tool command gets emitted. + { "cooling", false }, // to prevent speeds to be altered + { "first_layer_speed", "100%" }, // to prevent speeds to be altered + }); - Slic3r::Model model; - auto print = Slic3r::Test::init_print({TestMesh::overhang}, model, config); - print->process(); + THEN("overhang generates?") { + //FIXME does it make sense? + REQUIRE(! Slic3r::Test::slice({TestMesh::overhang}, config).empty()); + } - // config->set("support_material", true); // to prevent speeds to be altered + // config.set("support_material", true); // to prevent speeds to be altered THEN("skirt length is large enough to contain object with support") { - CHECK(config->opt_bool("support_material")); // test is not valid if support material is off - double skirt_length = 0.0; - Points extrusion_points; - int tool = -1; - - auto print = Slic3r::Test::init_print({TestMesh::cube_20x20x20}, model, config); - std::string gcode = Slic3r::Test::gcode(print); - - double support_speed = config->opt("support_material_speed")->value * MM_PER_MIN; - parser.parse_buffer(gcode, [config, &extrusion_points, &tool, &skirt_length, support_speed] (Slic3r::GCodeReader& self, const Slic3r::GCodeReader::GCodeLine& line) - { - // std::cerr << line.cmd() << "\n"; - if (boost::starts_with(line.cmd(), "T")) { - tool = atoi(line.cmd().data() + 1); - } else if (self.z() == Approx(config->opt("first_layer_height")->value)) { - // on first layer - if (line.extruding(self) && line.dist_XY(self) > 0) { - float speed = ( self.f() > 0 ? self.f() : line.new_F(self)); - // std::cerr << "Tool " << tool << "\n"; - if (speed == Approx(support_speed) && tool == config->opt_int("perimeter_extruder") - 1) { - // Skirt uses first material extruder, support material speed. - skirt_length += line.dist_XY(self); - } else { - extrusion_points.push_back(Slic3r::Point::new_scale(line.new_X(self), line.new_Y(self))); - } - } + CHECK(config.opt_bool("support_material")); // test is not valid if support material is off + std::string gcode = Slic3r::Test::slice({TestMesh::cube_20x20x20}, config); + double support_speed = config.opt("support_material_speed")->value * MM_PER_MIN; + double skirt_length = 0.0; + Points extrusion_points; + int tool = -1; + GCodeReader parser; + parser.parse_buffer(gcode, [config, &extrusion_points, &tool, &skirt_length, support_speed] (Slic3r::GCodeReader& self, const Slic3r::GCodeReader::GCodeLine& line) { + // std::cerr << line.cmd() << "\n"; + if (boost::starts_with(line.cmd(), "T")) { + tool = atoi(line.cmd().data() + 1); + } else if (self.z() == Approx(config.opt("first_layer_height")->value)) { + // on first layer + if (line.extruding(self) && line.dist_XY(self) > 0) { + float speed = ( self.f() > 0 ? self.f() : line.new_F(self)); + // std::cerr << "Tool " << tool << "\n"; + if (speed == Approx(support_speed) && tool == config.opt_int("perimeter_extruder") - 1) { + // Skirt uses first material extruder, support material speed. + skirt_length += line.dist_XY(self); + } else + extrusion_points.push_back(Slic3r::Point::new_scale(line.new_X(self), line.new_Y(self))); } - - if (self.z() == Approx(0.3) || line.new_Z(self) == Approx(0.3)) { - if (line.extruding(self) && self.f() == Approx(support_speed)) { - } + } + if (self.z() == Approx(0.3) || line.new_Z(self) == Approx(0.3)) { + if (line.extruding(self) && self.f() == Approx(support_speed)) { } - }); + } + }); Slic3r::Polygon convex_hull = Slic3r::Geometry::convex_hull(extrusion_points); double hull_perimeter = unscale(convex_hull.split_at_first_point().length()); REQUIRE(skirt_length > hull_perimeter); } } WHEN("Large minimum skirt length is used.") { - config->opt_float("min_skirt_length") = 20; - Slic3r::Model model; - auto print = Slic3r::Test::init_print({TestMesh::cube_20x20x20}, model, config); + config.set("min_skirt_length", 20); THEN("Gcode generation doesn't crash") { - REQUIRE(! Slic3r::Test::gcode(print).empty()); + REQUIRE(! Slic3r::Test::slice({TestMesh::cube_20x20x20}, config).empty()); } } } diff --git a/tests/fff_print/test_support_material.cpp b/tests/fff_print/test_support_material.cpp new file mode 100644 index 0000000000..0a38d138e6 --- /dev/null +++ b/tests/fff_print/test_support_material.cpp @@ -0,0 +1,233 @@ +#include + +#include "libslic3r/GCodeReader.hpp" + +#include "test_data.hpp" // get access to init_print, etc + +using namespace Slic3r::Test; +using namespace Slic3r; + +TEST_CASE("SupportMaterial: Three raft layers created", "[SupportMaterial]") +{ + Slic3r::Print print; + Slic3r::Test::init_and_process_print({ TestMesh::cube_20x20x20 }, print, { + { "support_material", 1 }, + { "raft_layers", 3 } + }); + REQUIRE(print.objects().front()->support_layers().size() == 3); +} + +SCENARIO("SupportMaterial: support_layers_z and contact_distance", "[SupportMaterial]") +{ + // Box h = 20mm, hole bottom at 5mm, hole height 10mm (top edge at 15mm). + TriangleMesh mesh = Slic3r::Test::mesh(Slic3r::Test::TestMesh::cube_with_hole); + mesh.rotate_x(float(M_PI / 2)); + + auto check = [](Slic3r::Print &print, bool &first_support_layer_height_ok, bool &layer_height_minimum_ok, bool &layer_height_maximum_ok, bool &top_spacing_ok) + { + const std::vector &support_layers = print.objects().front()->support_layers(); + + first_support_layer_height_ok = support_layers.front()->print_z == print.default_object_config().first_layer_height.value; + + layer_height_minimum_ok = true; + layer_height_maximum_ok = true; + double min_layer_height = print.config().min_layer_height.values.front(); + double max_layer_height = print.config().nozzle_diameter.values.front(); + if (print.config().max_layer_height.values.front() > EPSILON) + max_layer_height = std::min(max_layer_height, print.config().max_layer_height.values.front()); + for (size_t i = 1; i < support_layers.size(); ++ i) { + if (support_layers[i]->print_z - support_layers[i - 1]->print_z < min_layer_height - EPSILON) + layer_height_minimum_ok = false; + if (support_layers[i]->print_z - support_layers[i - 1]->print_z > max_layer_height + EPSILON) + layer_height_maximum_ok = false; + } + +#if 0 + double expected_top_spacing = print.default_object_config().layer_height + print.config().nozzle_diameter.get_at(0); + bool wrong_top_spacing = 0; + std::vector top_z { 1.1 }; + for (coordf_t top_z_el : top_z) { + // find layer index of this top surface. + size_t layer_id = -1; + for (size_t i = 0; i < support_z.size(); ++ i) { + if (abs(support_z[i] - top_z_el) < EPSILON) { + layer_id = i; + i = static_cast(support_z.size()); + } + } + + // check that first support layer above this top surface (or the next one) is spaced with nozzle diameter + if (abs(support_z[layer_id + 1] - support_z[layer_id] - expected_top_spacing) > EPSILON && + abs(support_z[layer_id + 2] - support_z[layer_id] - expected_top_spacing) > EPSILON) { + wrong_top_spacing = 1; + } + } + d = ! wrong_top_spacing; +#else + top_spacing_ok = true; +#endif + }; + + GIVEN("A print object having one modelObject") { + WHEN("First layer height = 0.4") { + Slic3r::Print print; + Slic3r::Test::init_and_process_print({ mesh }, print, { + { "support_material", 1 }, + { "layer_height", 0.2 }, + { "first_layer_height", 0.4 }, + }); + bool a, b, c, d; + check(print, a, b, c, d); + THEN("First layer height is honored") { REQUIRE(a == true); } + THEN("No null or negative support layers") { REQUIRE(b == true); } + THEN("No layers thicker than nozzle diameter") { REQUIRE(c == true); } +// THEN("Layers above top surfaces are spaced correctly") { REQUIRE(d == true); } + } + WHEN("Layer height = 0.2 and, first layer height = 0.3") { + Slic3r::Print print; + Slic3r::Test::init_and_process_print({ mesh }, print, { + { "support_material", 1 }, + { "layer_height", 0.2 }, + { "first_layer_height", 0.3 }, + }); + bool a, b, c, d; + check(print, a, b, c, d); + THEN("First layer height is honored") { REQUIRE(a == true); } + THEN("No null or negative support layers") { REQUIRE(b == true); } + THEN("No layers thicker than nozzle diameter") { REQUIRE(c == true); } +// THEN("Layers above top surfaces are spaced correctly") { REQUIRE(d == true); } + } + WHEN("Layer height = nozzle_diameter[0]") { + Slic3r::Print print; + Slic3r::Test::init_and_process_print({ mesh }, print, { + { "support_material", 1 }, + { "layer_height", 0.2 }, + { "first_layer_height", 0.3 }, + }); + bool a, b, c, d; + check(print, a, b, c, d); + THEN("First layer height is honored") { REQUIRE(a == true); } + THEN("No null or negative support layers") { REQUIRE(b == true); } + THEN("No layers thicker than nozzle diameter") { REQUIRE(c == true); } +// THEN("Layers above top surfaces are spaced correctly") { REQUIRE(d == true); } + } + } +} + +#if 0 +// Test 8. +TEST_CASE("SupportMaterial: forced support is generated", "[SupportMaterial]") +{ + // Create a mesh & modelObject. + TriangleMesh mesh = TriangleMesh::make_cube(20, 20, 20); + + Model model = Model(); + ModelObject *object = model.add_object(); + object->add_volume(mesh); + model.add_default_instances(); + model.align_instances_to_origin(); + + Print print = Print(); + + std::vector contact_z = {1.9}; + std::vector top_z = {1.1}; + print.default_object_config.support_material_enforce_layers = 100; + print.default_object_config.support_material = 0; + print.default_object_config.layer_height = 0.2; + print.default_object_config.set_deserialize("first_layer_height", "0.3"); + + print.add_model_object(model.objects[0]); + print.objects.front()->_slice(); + + SupportMaterial *support = print.objects.front()->_support_material(); + auto support_z = support->support_layers_z(contact_z, top_z, print.default_object_config.layer_height); + + bool check = true; + for (size_t i = 1; i < support_z.size(); i++) { + if (support_z[i] - support_z[i - 1] <= 0) + check = false; + } + + REQUIRE(check == true); +} + +// TODO +bool test_6_checks(Print& print) +{ + bool has_bridge_speed = true; + + // Pre-Processing. + PrintObject* print_object = print.objects.front(); + print_object->infill(); + SupportMaterial* support_material = print.objects.front()->_support_material(); + support_material->generate(print_object); + // TODO but not needed in test 6 (make brims and make skirts). + + // Exporting gcode. + // TODO validation found in Simple.pm + + + return has_bridge_speed; +} + +// Test 6. +SCENARIO("SupportMaterial: Checking bridge speed", "[SupportMaterial]") +{ + GIVEN("Print object") { + // Create a mesh & modelObject. + TriangleMesh mesh = TriangleMesh::make_cube(20, 20, 20); + + Model model = Model(); + ModelObject *object = model.add_object(); + object->add_volume(mesh); + model.add_default_instances(); + model.align_instances_to_origin(); + + Print print = Print(); + print.config.brim_width = 0; + print.config.skirts = 0; + print.config.skirts = 0; + print.default_object_config.support_material = 1; + print.default_region_config.top_solid_layers = 0; // so that we don't have the internal bridge over infill. + print.default_region_config.bridge_speed = 99; + print.config.cooling = 0; + print.config.set_deserialize("first_layer_speed", "100%"); + + WHEN("support_material_contact_distance = 0.2") { + print.default_object_config.support_material_contact_distance = 0.2; + print.add_model_object(model.objects[0]); + + bool check = test_6_checks(print); + REQUIRE(check == true); // bridge speed is used. + } + + WHEN("support_material_contact_distance = 0") { + print.default_object_config.support_material_contact_distance = 0; + print.add_model_object(model.objects[0]); + + bool check = test_6_checks(print); + REQUIRE(check == true); // bridge speed is not used. + } + + WHEN("support_material_contact_distance = 0.2 & raft_layers = 5") { + print.default_object_config.support_material_contact_distance = 0.2; + print.default_object_config.raft_layers = 5; + print.add_model_object(model.objects[0]); + + bool check = test_6_checks(print); + REQUIRE(check == true); // bridge speed is used. + } + + WHEN("support_material_contact_distance = 0 & raft_layers = 5") { + print.default_object_config.support_material_contact_distance = 0; + print.default_object_config.raft_layers = 5; + print.add_model_object(model.objects[0]); + + bool check = test_6_checks(print); + + REQUIRE(check == true); // bridge speed is not used. + } + } +} + +#endif diff --git a/tests/fff_print/test_trianglemesh.cpp b/tests/fff_print/test_trianglemesh.cpp index e24a77e7fd..9598a3c5ad 100644 --- a/tests/fff_print/test_trianglemesh.cpp +++ b/tests/fff_print/test_trianglemesh.cpp @@ -384,20 +384,21 @@ SCENARIO( "TriangleMeshSlicer: Cut behavior.") { #ifdef TEST_PERFORMANCE TEST_CASE("Regression test for issue #4486 - files take forever to slice") { TriangleMesh mesh; - std::shared_ptr config = Slic3r::DynamicPrintConfig::new_from_defaults(); + DynamicPrintConfig config = Slic3r::DynamicPrintConfig::full_print_config(); mesh.ReadSTLFile(std::string(testfile_dir) + "test_trianglemesh/4486/100_000.stl"); mesh.repair(); - config->set("layer_height", 500); - config->set("first_layer_height", 250); - config->set("nozzle_diameter", 500); + config.set("layer_height", 500); + config.set("first_layer_height", 250); + config.set("nozzle_diameter", 500); + Slic3r::Print print; Slic3r::Model model; - auto print = Slic3r::Test::init_print({mesh}, model, config); + Slic3r::Test::init_print({mesh}, print, model, config); - print->status_cb = [] (int ln, const std::string& msg) { Slic3r::Log::info("Print") << ln << " " << msg << "\n";}; + print.status_cb = [] (int ln, const std::string& msg) { Slic3r::Log::info("Print") << ln << " " << msg << "\n";}; - std::future fut = std::async([&print] () { print->process(); }); + std::future fut = std::async([&print] () { print.process(); }); std::chrono::milliseconds span {120000}; bool timedout {false}; if(fut.wait_for(span) == std::future_status::timeout) { @@ -411,21 +412,22 @@ TEST_CASE("Regression test for issue #4486 - files take forever to slice") { #ifdef BUILD_PROFILE TEST_CASE("Profile test for issue #4486 - files take forever to slice") { TriangleMesh mesh; - std::shared_ptr config = Slic3r::DynamicPrintConfig::new_from_defaults(); + DynamicPrintConfig config = Slic3r::DynamicPrintConfig::full_print_config(); mesh.ReadSTLFile(std::string(testfile_dir) + "test_trianglemesh/4486/10_000.stl"); mesh.repair(); - config->set("layer_height", 500); - config->set("first_layer_height", 250); - config->set("nozzle_diameter", 500); - config->set("fill_density", "5%"); + config.set("layer_height", 500); + config.set("first_layer_height", 250); + config.set("nozzle_diameter", 500); + config.set("fill_density", "5%"); + Slic3r::Print print; Slic3r::Model model; - auto print = Slic3r::Test::init_print({mesh}, model, config); + Slic3r::Test::init_print({mesh}, print, model, config); - print->status_cb = [] (int ln, const std::string& msg) { Slic3r::Log::info("Print") << ln << " " << msg << "\n";}; + print.status_cb = [] (int ln, const std::string& msg) { Slic3r::Log::info("Print") << ln << " " << msg << "\n";}; - print->process(); + print.process(); REQUIRE(true); diff --git a/tests/libslic3r/CMakeLists.txt b/tests/libslic3r/CMakeLists.txt index cfc7ea8338..e6f04d2828 100644 --- a/tests/libslic3r/CMakeLists.txt +++ b/tests/libslic3r/CMakeLists.txt @@ -1,6 +1,8 @@ get_filename_component(_TEST_NAME ${CMAKE_CURRENT_LIST_DIR} NAME) add_executable(${_TEST_NAME}_tests ${_TEST_NAME}_tests.cpp + test_3mf.cpp + test_config.cpp test_geometry.cpp test_polygon.cpp ) diff --git a/tests/libslic3r/test_3mf.cpp b/tests/libslic3r/test_3mf.cpp new file mode 100644 index 0000000000..0cde0b0dc8 --- /dev/null +++ b/tests/libslic3r/test_3mf.cpp @@ -0,0 +1,20 @@ +#include + +#include "libslic3r/Model.hpp" +#include "libslic3r/Format/3mf.hpp" + +using namespace Slic3r; + +SCENARIO("Reading 3mf file") { + GIVEN("umlauts in the path of the file") { + Slic3r::Model model; + WHEN("3mf model is read") { + std::string path = std::string(TEST_DATA_DIR) + "/test_3mf/Geräte/Büchse.3mf"; + DynamicPrintConfig config; + bool ret = Slic3r::load_3mf(path.c_str(), &config, &model, false); + THEN("load should succeed") { + REQUIRE(ret); + } + } + } +} diff --git a/tests/libslic3r/test_config.cpp b/tests/libslic3r/test_config.cpp new file mode 100644 index 0000000000..85055aa658 --- /dev/null +++ b/tests/libslic3r/test_config.cpp @@ -0,0 +1,203 @@ +#include + +#include "libslic3r/PrintConfig.hpp" + +using namespace Slic3r; + +SCENARIO("Generic config validation performs as expected.", "[Config]") { + GIVEN("A config generated from default options") { + Slic3r::DynamicPrintConfig config = Slic3r::DynamicPrintConfig::full_print_config(); + WHEN( "perimeter_extrusion_width is set to 250%, a valid value") { + config.set_deserialize("perimeter_extrusion_width", "250%"); + THEN( "The config is read as valid.") { + REQUIRE(config.validate().empty()); + } + } + WHEN( "perimeter_extrusion_width is set to -10, an invalid value") { + config.set("perimeter_extrusion_width", -10); + THEN( "Validate returns error") { + REQUIRE(! config.validate().empty()); + } + } + + WHEN( "perimeters is set to -10, an invalid value") { + config.set("perimeters", -10); + THEN( "Validate returns error") { + REQUIRE(! config.validate().empty()); + } + } + } +} + +SCENARIO("Config accessor functions perform as expected.", "[Config]") { + GIVEN("A config generated from default options") { + Slic3r::DynamicPrintConfig config = Slic3r::DynamicPrintConfig::full_print_config(); + WHEN("A boolean option is set to a boolean value") { + REQUIRE_NOTHROW(config.set("gcode_comments", true)); + THEN("The underlying value is set correctly.") { + REQUIRE(config.opt("gcode_comments")->getBool() == true); + } + } + WHEN("A boolean option is set to a string value representing a 0 or 1") { + CHECK_NOTHROW(config.set_deserialize("gcode_comments", "1")); + THEN("The underlying value is set correctly.") { + REQUIRE(config.opt("gcode_comments")->getBool() == true); + } + } + WHEN("A boolean option is set to a string value representing something other than 0 or 1") { + THEN("A BadOptionTypeException exception is thrown.") { + REQUIRE_THROWS_AS(config.set("gcode_comments", "Z"), BadOptionTypeException); + } + AND_THEN("Value is unchanged.") { + REQUIRE(config.opt("gcode_comments")->getBool() == false); + } + } + WHEN("A boolean option is set to an int value") { + THEN("A BadOptionTypeException exception is thrown.") { + REQUIRE_THROWS_AS(config.set("gcode_comments", 1), BadOptionTypeException); + } + } + WHEN("A numeric option is set from serialized string") { + config.set_deserialize("bed_temperature", "100"); + THEN("The underlying value is set correctly.") { + REQUIRE(config.opt("bed_temperature")->get_at(0) == 100); + } + } +#if 0 + //FIXME better design accessors for vector elements. + WHEN("An integer-based option is set through the integer interface") { + config.set("bed_temperature", 100); + THEN("The underlying value is set correctly.") { + REQUIRE(config.opt("bed_temperature")->get_at(0) == 100); + } + } +#endif + WHEN("An floating-point option is set through the integer interface") { + config.set("perimeter_speed", 10); + THEN("The underlying value is set correctly.") { + REQUIRE(config.opt("perimeter_speed")->getFloat() == 10.0); + } + } + WHEN("A floating-point option is set through the double interface") { + config.set("perimeter_speed", 5.5); + THEN("The underlying value is set correctly.") { + REQUIRE(config.opt("perimeter_speed")->getFloat() == 5.5); + } + } + WHEN("An integer-based option is set through the double interface") { + THEN("A BadOptionTypeException exception is thrown.") { + REQUIRE_THROWS_AS(config.set("bed_temperature", 5.5), BadOptionTypeException); + } + } + WHEN("A numeric option is set to a non-numeric value.") { + THEN("A BadOptionTypeException exception is thown.") { + REQUIRE_THROWS_AS(config.set_deserialize("perimeter_speed", "zzzz"), BadOptionTypeException); + } + THEN("The value does not change.") { + REQUIRE(config.opt("perimeter_speed")->getFloat() == 60.0); + } + } + WHEN("A string option is set through the string interface") { + config.set("printhost_apikey", "100"); + THEN("The underlying value is set correctly.") { + REQUIRE(config.opt("printhost_apikey")->value == "100"); + } + } + WHEN("A string option is set through the integer interface") { + config.set("printhost_apikey", 100); + THEN("The underlying value is set correctly.") { + REQUIRE(config.opt("printhost_apikey")->value == "100"); + } + } + WHEN("A string option is set through the double interface") { + config.set("printhost_apikey", 100.5); + THEN("The underlying value is set correctly.") { + REQUIRE(config.opt("printhost_apikey")->value == std::to_string(100.5)); + } + } + WHEN("A float or percent is set as a percent through the string interface.") { + config.set_deserialize("first_layer_extrusion_width", "100%"); + THEN("Value and percent flag are 100/true") { + auto tmp = config.opt("first_layer_extrusion_width"); + REQUIRE(tmp->percent == true); + REQUIRE(tmp->value == 100); + } + } + WHEN("A float or percent is set as a float through the string interface.") { + config.set_deserialize("first_layer_extrusion_width", "100"); + THEN("Value and percent flag are 100/false") { + auto tmp = config.opt("first_layer_extrusion_width"); + REQUIRE(tmp->percent == false); + REQUIRE(tmp->value == 100); + } + } + WHEN("A float or percent is set as a float through the int interface.") { + config.set("first_layer_extrusion_width", 100); + THEN("Value and percent flag are 100/false") { + auto tmp = config.opt("first_layer_extrusion_width"); + REQUIRE(tmp->percent == false); + REQUIRE(tmp->value == 100); + } + } + WHEN("A float or percent is set as a float through the double interface.") { + config.set("first_layer_extrusion_width", 100.5); + THEN("Value and percent flag are 100.5/false") { + auto tmp = config.opt("first_layer_extrusion_width"); + REQUIRE(tmp->percent == false); + REQUIRE(tmp->value == 100.5); + } + } + WHEN("An invalid option is requested during set.") { + THEN("A BadOptionTypeException exception is thrown.") { + REQUIRE_THROWS_AS(config.set("deadbeef_invalid_option", 1), UnknownOptionException); + REQUIRE_THROWS_AS(config.set("deadbeef_invalid_option", 1.0), UnknownOptionException); + REQUIRE_THROWS_AS(config.set("deadbeef_invalid_option", "1"), UnknownOptionException); + REQUIRE_THROWS_AS(config.set("deadbeef_invalid_option", true), UnknownOptionException); + } + } + + WHEN("An invalid option is requested during get.") { + THEN("A UnknownOptionException exception is thrown.") { + REQUIRE_THROWS_AS(config.option_throw("deadbeef_invalid_option", false), UnknownOptionException); + REQUIRE_THROWS_AS(config.option_throw("deadbeef_invalid_option", false), UnknownOptionException); + REQUIRE_THROWS_AS(config.option_throw("deadbeef_invalid_option", false), UnknownOptionException); + REQUIRE_THROWS_AS(config.option_throw("deadbeef_invalid_option", false), UnknownOptionException); + } + } + WHEN("An invalid option is requested during opt.") { + THEN("A UnknownOptionException exception is thrown.") { + REQUIRE_THROWS_AS(config.option_throw("deadbeef_invalid_option", false), UnknownOptionException); + REQUIRE_THROWS_AS(config.option_throw("deadbeef_invalid_option", false), UnknownOptionException); + REQUIRE_THROWS_AS(config.option_throw("deadbeef_invalid_option", false), UnknownOptionException); + REQUIRE_THROWS_AS(config.option_throw("deadbeef_invalid_option", false), UnknownOptionException); + } + } + + WHEN("getX called on an unset option.") { + THEN("The default is returned.") { + REQUIRE(config.opt_float("layer_height") == 0.3); + REQUIRE(config.opt_int("raft_layers") == 0); + REQUIRE(config.opt_bool("support_material") == false); + } + } + + WHEN("getFloat called on an option that has been set.") { + config.set("layer_height", 0.5); + THEN("The set value is returned.") { + REQUIRE(config.opt_float("layer_height") == 0.5); + } + } + } +} + +SCENARIO("Config ini load/save interface", "[Config]") { + WHEN("new_from_ini is called") { + Slic3r::DynamicPrintConfig config; + std::string path = std::string(TEST_DATA_DIR) + "/test_config/new_from_ini.ini"; + config.load_from_ini(path); + THEN("Config object contains ini file options.") { + REQUIRE(config.option_throw("filament_colour", false)->values.size() == 1); + REQUIRE(config.option_throw("filament_colour", false)->values.front() == "#ABCD"); + } + } +} diff --git a/xs/src/perlglue.cpp b/xs/src/perlglue.cpp index 463f7d21b2..c3cd7e6165 100644 --- a/xs/src/perlglue.cpp +++ b/xs/src/perlglue.cpp @@ -299,7 +299,7 @@ bool ConfigBase__set_deserialize(ConfigBase* THIS, const t_config_option_key &op size_t len; const char * c = SvPV(str, len); std::string value(c, len); - return THIS->set_deserialize(opt_key, value); + return THIS->set_deserialize_nothrow(opt_key, value); } void ConfigBase__set_ifndef(ConfigBase* THIS, const t_config_option_key &opt_key, SV* value, bool deserialize) diff --git a/xs/xsp/Config.xsp b/xs/xsp/Config.xsp index f5e6ffb05e..435dda5a28 100644 --- a/xs/xsp/Config.xsp +++ b/xs/xsp/Config.xsp @@ -8,7 +8,8 @@ %name{Slic3r::Config} class DynamicPrintConfig { DynamicPrintConfig(); ~DynamicPrintConfig(); - static DynamicPrintConfig* new_from_defaults(); + static DynamicPrintConfig* new_from_defaults() + %code{% RETVAL = DynamicPrintConfig::new_from_defaults_keys(FullPrintConfig::defaults().keys()); %}; static DynamicPrintConfig* new_from_defaults_keys(std::vector keys); DynamicPrintConfig* clone() %code{% RETVAL = new DynamicPrintConfig(*THIS); %}; DynamicPrintConfig* clone_only(std::vector keys)