diff --git a/CMakeLists.txt b/CMakeLists.txt index 1eabbad3c..cd44e06eb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -92,6 +92,10 @@ if (MSVC) # Disable STL4007: Many result_type typedefs and all argument_type, first_argument_type, and second_argument_type typedefs are deprecated in C++17. #FIXME Remove this line after eigen library adapts to the new C++17 adaptor rules. add_compile_options(-D_SILENCE_CXX17_ADAPTOR_TYPEDEFS_DEPRECATION_WARNING) + # Disable warnings on conversion from unsigned to signed (possible loss of data) + # C4244: 'conversion' conversion from 'type1' to 'type2', possible loss of data. An integer type is converted to a smaller integer type. + # C4267: The compiler detected a conversion from size_t to a smaller type. + add_compile_options(/wd4244 /wd4267) endif () if (MINGW) diff --git a/cmake/modules/FindTBB.cmake b/cmake/modules/FindTBB.cmake index c6bdec985..a7eafa545 100644 --- a/cmake/modules/FindTBB.cmake +++ b/cmake/modules/FindTBB.cmake @@ -302,7 +302,7 @@ if(NOT TBB_FOUND) IMPORTED_LOCATION ${TBB_LIBRARIES}) if(TBB_LIBRARIES_RELEASE AND TBB_LIBRARIES_DEBUG) set_target_properties(TBB::tbb PROPERTIES - INTERFACE_COMPILE_DEFINITIONS "${TBB_DEFINITIONS};$<$,$>:${TBB_DEFINITIONS_DEBUG}>;$<$:${TBB_DEFINITIONS_RELEASE}>" + INTERFACE_COMPILE_DEFINITIONS "${TBB_DEFINITIONS};$<$,$>:${TBB_DEFINITIONS_RELEASE}>;$<$:${TBB_DEFINITIONS_DEBUG}>" IMPORTED_LOCATION_DEBUG ${TBB_LIBRARIES_DEBUG} IMPORTED_LOCATION_RELWITHDEBINFO ${TBB_LIBRARIES_RELEASE} IMPORTED_LOCATION_RELEASE ${TBB_LIBRARIES_RELEASE} diff --git a/src/admesh/connect.cpp b/src/admesh/connect.cpp index c266c724c..e5491b1aa 100644 --- a/src/admesh/connect.cpp +++ b/src/admesh/connect.cpp @@ -532,7 +532,7 @@ void stl_remove_unconnected_facets(stl_file *stl) assert(false); } - if (facet_number < -- stl->stats.number_of_facets) { + if (facet_number < int(-- stl->stats.number_of_facets)) { // Removing a face, which was not the last one. // Copy the face and neighborship from the last face to facet_number. stl->facet_start[facet_number] = stl->facet_start[stl->stats.number_of_facets]; diff --git a/src/admesh/normals.cpp b/src/admesh/normals.cpp index a470d081d..3b677641f 100644 --- a/src/admesh/normals.cpp +++ b/src/admesh/normals.cpp @@ -198,7 +198,7 @@ void stl_fix_normal_directions(stl_file *stl) // pool.destroy(temp); } else { // If we ran out of facets to fix: All of the facets in this part have been fixed. ++ stl->stats.number_of_parts; - if (checked >= stl->stats.number_of_facets) + if (checked >= int(stl->stats.number_of_facets)) // All of the facets have been checked. Bail out. break; // There is another part here. Find it and continue. diff --git a/src/admesh/util.cpp b/src/admesh/util.cpp index 029e44a28..644fa1834 100644 --- a/src/admesh/util.cpp +++ b/src/admesh/util.cpp @@ -70,7 +70,7 @@ void stl_translate(stl_file *stl, float x, float y, float z) { stl_vertex new_min(x, y, z); stl_vertex shift = new_min - stl->stats.min; - for (int i = 0; i < stl->stats.number_of_facets; ++ i) + for (uint32_t i = 0; i < stl->stats.number_of_facets; ++ i) for (int j = 0; j < 3; ++ j) stl->facet_start[i].vertex[j] += shift; stl->stats.min = new_min; @@ -81,7 +81,7 @@ void stl_translate(stl_file *stl, float x, float y, float z) void stl_translate_relative(stl_file *stl, float x, float y, float z) { stl_vertex shift(x, y, z); - for (int i = 0; i < stl->stats.number_of_facets; ++ i) + for (uint32_t i = 0; i < stl->stats.number_of_facets; ++ i) for (int j = 0; j < 3; ++ j) stl->facet_start[i].vertex[j] += shift; stl->stats.min += shift; @@ -100,7 +100,7 @@ void stl_scale_versor(stl_file *stl, const stl_vertex &versor) if (stl->stats.volume > 0.0) stl->stats.volume *= versor(0) * versor(1) * versor(2); // Scale the mesh. - for (int i = 0; i < stl->stats.number_of_facets; ++ i) + for (uint32_t i = 0; i < stl->stats.number_of_facets; ++ i) for (int j = 0; j < 3; ++ j) stl->facet_start[i].vertex[j].array() *= s; } @@ -330,10 +330,10 @@ void stl_repair( increment = stl->stats.bounding_diameter / 10000.0; } - if (stl->stats.connected_facets_3_edge < stl->stats.number_of_facets) { + if (stl->stats.connected_facets_3_edge < int(stl->stats.number_of_facets)) { int last_edges_fixed = 0; for (int i = 0; i < iterations; ++ i) { - if (stl->stats.connected_facets_3_edge < stl->stats.number_of_facets) { + if (stl->stats.connected_facets_3_edge < int(stl->stats.number_of_facets)) { if (verbose_flag) printf("Checking nearby. Tolerance= %f Iteration=%d of %d...", tolerance, i + 1, iterations); stl_check_facets_nearby(stl, tolerance); @@ -351,7 +351,7 @@ void stl_repair( printf("All facets connected. No nearby check necessary.\n"); if (remove_unconnected_flag || fixall_flag || fill_holes_flag) { - if (stl->stats.connected_facets_3_edge < stl->stats.number_of_facets) { + if (stl->stats.connected_facets_3_edge < int(stl->stats.number_of_facets)) { if (verbose_flag) printf("Removing unconnected facets...\n"); stl_remove_unconnected_facets(stl); @@ -360,7 +360,7 @@ void stl_repair( } if (fill_holes_flag || fixall_flag) { - if (stl->stats.connected_facets_3_edge < stl->stats.number_of_facets) { + if (stl->stats.connected_facets_3_edge < int(stl->stats.number_of_facets)) { if (verbose_flag) printf("Filling holes...\n"); stl_fill_holes(stl); diff --git a/src/clipper/clipper.cpp b/src/clipper/clipper.cpp index be4cb4a6a..3c0057b22 100644 --- a/src/clipper/clipper.cpp +++ b/src/clipper/clipper.cpp @@ -3895,10 +3895,10 @@ double DistanceFromLineSqrd( const IntPoint& pt, const IntPoint& ln1, const IntPoint& ln2) { //The equation of a line in general form (Ax + By + C = 0) - //given 2 points (x¹,y¹) & (x²,y²) is ... - //(y¹ - y²)x + (x² - x¹)y + (y² - y¹)x¹ - (x² - x¹)y¹ = 0 - //A = (y¹ - y²); B = (x² - x¹); C = (y² - y¹)x¹ - (x² - x¹)y¹ - //perpendicular distance of point (x³,y³) = (Ax³ + By³ + C)/Sqrt(A² + B²) + //given 2 points (x¹,y¹) & (x²,y²) is ... + //(y¹ - y²)x + (x² - x¹)y + (y² - y¹)x¹ - (x² - x¹)y¹ = 0 + //A = (y¹ - y²); B = (x² - x¹); C = (y² - y¹)x¹ - (x² - x¹)y¹ + //perpendicular distance of point (x³,y³) = (Ax³ + By³ + C)/Sqrt(A² + B²) //see http://en.wikipedia.org/wiki/Perpendicular_distance double A = double(ln1.Y - ln2.Y); double B = double(ln2.X - ln1.X); diff --git a/src/libslic3r/Brim.cpp b/src/libslic3r/Brim.cpp index e3ffda122..d5ec0d928 100644 --- a/src/libslic3r/Brim.cpp +++ b/src/libslic3r/Brim.cpp @@ -380,7 +380,7 @@ ExtrusionEntityCollection make_brim(const Print &print, PrintTryCancel try_cance } #endif // BRIM_DEBUG_TO_SVG - all_loops = connect_brim_lines(std::move(all_loops), offset(islands_area_ex,SCALED_EPSILON), flow.scaled_spacing() * 2); + all_loops = connect_brim_lines(std::move(all_loops), offset(islands_area_ex, float(SCALED_EPSILON)), flow.scaled_spacing() * 2.f); #ifdef BRIM_DEBUG_TO_SVG { diff --git a/src/libslic3r/GCode/SeamPlacer.cpp b/src/libslic3r/GCode/SeamPlacer.cpp index 1778e0689..b57d4470b 100644 --- a/src/libslic3r/GCode/SeamPlacer.cpp +++ b/src/libslic3r/GCode/SeamPlacer.cpp @@ -15,7 +15,7 @@ static constexpr float ENFORCER_BLOCKER_PENALTY = 100; // In case there are custom enforcers/blockers, the loop polygon shall always have // sides smaller than this (so it isn't limited to original resolution). -static constexpr float MINIMAL_POLYGON_SIDE = scale_(0.2f); +static constexpr float MINIMAL_POLYGON_SIDE = scaled(0.2f); // When spAligned is active and there is a support enforcer, // add this penalty to its center. diff --git a/src/libslic3r/Geometry.hpp b/src/libslic3r/Geometry.hpp index 85f181b92..8b062276e 100644 --- a/src/libslic3r/Geometry.hpp +++ b/src/libslic3r/Geometry.hpp @@ -11,7 +11,16 @@ #include #define BOOST_VORONOI_USE_GMP 1 + +#ifdef _MSC_VER +// Suppress warning C4146 in include/gmp.h(2177,31): unary minus operator applied to unsigned type, result still unsigned +#pragma warning(push) +#pragma warning(disable : 4146) +#endif // _MSC_VER #include "boost/polygon/voronoi.hpp" +#ifdef _MSC_VER +#pragma warning(pop) +#endif // _MSC_VER namespace ClipperLib { class PolyNode; diff --git a/src/libslic3r/Layer.cpp b/src/libslic3r/Layer.cpp index 7a506e236..b974ff217 100644 --- a/src/libslic3r/Layer.cpp +++ b/src/libslic3r/Layer.cpp @@ -147,7 +147,8 @@ void Layer::make_perimeters() && config.perimeters == other_config.perimeters && config.perimeter_speed == other_config.perimeter_speed && config.external_perimeter_speed == other_config.external_perimeter_speed - && config.gap_fill_speed == other_config.gap_fill_speed + && (config.gap_fill_enabled ? config.gap_fill_speed.value : 0.) == + (other_config.gap_fill_enabled ? other_config.gap_fill_speed.value : 0.) && config.overhangs == other_config.overhangs && config.opt_serialize("perimeter_extrusion_width") == other_config.opt_serialize("perimeter_extrusion_width") && config.thin_walls == other_config.thin_walls diff --git a/src/libslic3r/PerimeterGenerator.cpp b/src/libslic3r/PerimeterGenerator.cpp index e367b6b1a..63b335740 100644 --- a/src/libslic3r/PerimeterGenerator.cpp +++ b/src/libslic3r/PerimeterGenerator.cpp @@ -305,7 +305,7 @@ void PerimeterGenerator::process() // internal flow which is unrelated. coord_t min_spacing = coord_t(perimeter_spacing * (1 - INSET_OVERLAP_TOLERANCE)); coord_t ext_min_spacing = coord_t(ext_perimeter_spacing * (1 - INSET_OVERLAP_TOLERANCE)); - bool has_gap_fill = this->config->gap_fill_speed.value > 0 && this->config->gap_fill_enabled.value; + bool has_gap_fill = this->config->gap_fill_enabled.value && this->config->gap_fill_speed.value > 0; // prepare grown lower layer slices for overhang detection if (this->lower_slices != NULL && this->config->overhangs) { @@ -316,10 +316,6 @@ void PerimeterGenerator::process() m_lower_slices_polygons = offset(*this->lower_slices, float(scale_(+nozzle_diameter/2))); } - // fuzzy skin configuration - double fuzzy_skin_thickness = scale_(this->config->fuzzy_skin_thickness); - double fuzzy_skin_point_dist = scale_(this->config->fuzzy_skin_point_dist); - // we need to process each island separately because we might have different // extra perimeters for each one for (const Surface &surface : this->slices->surfaces) { diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index 850512a5c..69b13376c 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -290,6 +290,12 @@ void Preset::normalize(DynamicPrintConfig &config) static_cast(opt)->values.resize(n, std::string()); } } + if (const auto *gap_fill_speed = config.option("gap_fill_speed", false); gap_fill_speed && gap_fill_speed->value <= 0.) { + // Legacy conversion. If the gap fill speed is zero, it means the gap fill is not enabled. + // Set the new gap_fill_enabled value, so that it will show up in the UI as disabled. + if (auto *gap_fill_enabled = config.option("gap_fill_enabled", false); gap_fill_enabled) + gap_fill_enabled->value = false; + } } std::string Preset::remove_invalid_keys(DynamicPrintConfig &config, const DynamicPrintConfig &default_config) @@ -406,7 +412,7 @@ const std::vector& Preset::print_options() "layer_height", "first_layer_height", "perimeters", "spiral_vase", "slice_closing_radius", "top_solid_layers", "top_solid_min_thickness", "bottom_solid_layers", "bottom_solid_min_thickness", "extra_perimeters", "ensure_vertical_shell_thickness", "avoid_crossing_perimeters", "thin_walls", "overhangs", - "seam_position", "external_perimeters_first", "gap_fill_enabled", "fill_density", "fill_pattern", "top_fill_pattern", "bottom_fill_pattern", + "seam_position", "external_perimeters_first", "fill_density", "fill_pattern", "top_fill_pattern", "bottom_fill_pattern", "infill_every_layers", "infill_only_where_needed", "solid_infill_every_layers", "fill_angle", "bridge_angle", "solid_infill_below_area", "only_retract_when_crossing_perimeters", "infill_first", "ironing", "ironing_type", "ironing_flowrate", "ironing_speed", "ironing_spacing", @@ -417,7 +423,7 @@ const std::vector& Preset::print_options() #endif /* HAS_PRESSURE_EQUALIZER */ "perimeter_speed", "small_perimeter_speed", "external_perimeter_speed", "infill_speed", "solid_infill_speed", "top_solid_infill_speed", "support_material_speed", "support_material_xy_spacing", "support_material_interface_speed", - "bridge_speed", "gap_fill_speed", "travel_speed", "first_layer_speed", "perimeter_acceleration", "infill_acceleration", + "bridge_speed", "gap_fill_speed", "gap_fill_enabled", "travel_speed", "first_layer_speed", "perimeter_acceleration", "infill_acceleration", "bridge_acceleration", "first_layer_acceleration", "default_acceleration", "skirts", "skirt_distance", "skirt_height", "draft_shield", "min_skirt_length", "brim_width", "brim_offset", "brim_type", "support_material", "support_material_auto", "support_material_threshold", "support_material_enforce_layers", "raft_layers", "support_material_pattern", "support_material_with_sheath", "support_material_spacing", diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 70b239d95..b494f7333 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -558,13 +558,6 @@ void PrintConfigDef::init_fff_params() def->mode = comExpert; def->set_default_value(new ConfigOptionBool(false)); - def = this->add("gap_fill_enabled", coBool); - def->label = L("Fill gaps"); - def->category = L("Layers and Perimeters"); - def->tooltip = L("Enables small gap fill."); - def->mode = comAdvanced; - def->set_default_value(new ConfigOptionBool(true)); - def = this->add("extra_perimeters", coBool); def->label = L("Extra perimeters if needed"); def->category = L("Layers and Perimeters"); @@ -1072,6 +1065,13 @@ void PrintConfigDef::init_fff_params() def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(0.8)); + def = this->add("gap_fill_enabled", coBool); + def->label = L("Fill gaps"); + def->category = L("Layers and Perimeters"); + def->tooltip = L("Enables filling of gaps between perimeters and between the inner most perimeters and infill."); + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionBool(true)); + def = this->add("gap_fill_speed", coFloat); def->label = L("Gap fill"); def->category = L("Speed"); diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index dcd833ac4..c205180d0 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -567,13 +567,13 @@ public: ConfigOptionFloatOrPercent external_perimeter_speed; ConfigOptionBool external_perimeters_first; ConfigOptionBool extra_perimeters; - ConfigOptionBool gap_fill_enabled; ConfigOptionFloat fill_angle; ConfigOptionPercent fill_density; ConfigOptionEnum fill_pattern; ConfigOptionEnum fuzzy_skin; ConfigOptionFloat fuzzy_skin_thickness; ConfigOptionFloat fuzzy_skin_point_dist; + ConfigOptionBool gap_fill_enabled; ConfigOptionFloat gap_fill_speed; ConfigOptionFloatOrPercent infill_anchor; ConfigOptionFloatOrPercent infill_anchor_max; @@ -624,13 +624,13 @@ protected: OPT_PTR(external_perimeter_speed); OPT_PTR(external_perimeters_first); OPT_PTR(extra_perimeters); - OPT_PTR(gap_fill_enabled); OPT_PTR(fill_angle); OPT_PTR(fill_density); OPT_PTR(fill_pattern); OPT_PTR(fuzzy_skin); OPT_PTR(fuzzy_skin_thickness); OPT_PTR(fuzzy_skin_point_dist); + OPT_PTR(gap_fill_enabled); OPT_PTR(gap_fill_speed); OPT_PTR(infill_anchor); OPT_PTR(infill_anchor_max); diff --git a/src/libslic3r/SLA/AGGRaster.hpp b/src/libslic3r/SLA/AGGRaster.hpp index 917f718e9..e7507378d 100644 --- a/src/libslic3r/SLA/AGGRaster.hpp +++ b/src/libslic3r/SLA/AGGRaster.hpp @@ -136,7 +136,7 @@ public: const TColor & background, GammaFn && gammafn) : m_resolution(res) - , m_pxdim_scaled(SCALING_FACTOR / pd.w_mm, SCALING_FACTOR / pd.h_mm) + , m_pxdim_scaled(SCALING_FACTOR, SCALING_FACTOR) , m_buf(res.pixels()) , m_rbuf(reinterpret_cast(m_buf.data()), unsigned(res.width_px), @@ -147,6 +147,9 @@ public: , m_renderer(m_raw_renderer) , m_trafo(trafo) { + // suppress false MSVC warning C4723: possible division by zero + m_pxdim_scaled.w_mm /= pd.w_mm; + m_pxdim_scaled.h_mm /= pd.h_mm; m_renderer.color(foreground); clear(background); diff --git a/src/libslic3r/SupportMaterial.cpp b/src/libslic3r/SupportMaterial.cpp index 8f653b99d..4da024344 100644 --- a/src/libslic3r/SupportMaterial.cpp +++ b/src/libslic3r/SupportMaterial.cpp @@ -1128,8 +1128,7 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::top_contact_ // Subtracting them as they are may leave unwanted narrow // residues of diff_polygons that would then be supported. diff_polygons = diff(diff_polygons, - offset(union_(to_polygons(std::move(blockers[layer_id]))), - 1000.*SCALED_EPSILON)); + offset(union_(to_polygons(std::move(blockers[layer_id]))), float(1000.*SCALED_EPSILON))); } #ifdef SLIC3R_DEBUG diff --git a/src/qhull/src/libqhull_r/geom2_r.c b/src/qhull/src/libqhull_r/geom2_r.c index 48addba1c..0345440be 100644 --- a/src/qhull/src/libqhull_r/geom2_r.c +++ b/src/qhull/src/libqhull_r/geom2_r.c @@ -2054,7 +2054,7 @@ pointT *qh_voronoi_center(qhT *qh, int dim, setT *points) { factor= qh_divzero(0.5, det, qh->MINdenom, &infinite); if (infinite) { for (k=dim; k--; ) - center[k]= qh_INFINITE; + center[k]= (float)qh_INFINITE; if (qh->IStracing) qh_printpoints(qh, qh->ferr, "qh_voronoi_center: at infinity for ", simplex); }else { diff --git a/src/slic3r/GUI/Jobs/ArrangeJob.cpp b/src/slic3r/GUI/Jobs/ArrangeJob.cpp index 32375f829..3f1207b47 100644 --- a/src/slic3r/GUI/Jobs/ArrangeJob.cpp +++ b/src/slic3r/GUI/Jobs/ArrangeJob.cpp @@ -152,7 +152,7 @@ void ArrangeJob::on_exception(const std::exception_ptr &eptr) } catch (libnest2d::GeometryException &) { show_error(m_plater, _(L("Could not arrange model objects! " "Some geometries may be invalid."))); - } catch (std::exception &e) { + } catch (std::exception &) { PlaterJob::on_exception(eptr); } } diff --git a/src/slic3r/GUI/PresetHints.cpp b/src/slic3r/GUI/PresetHints.cpp index 25bb1ec93..8621586f8 100644 --- a/src/slic3r/GUI/PresetHints.cpp +++ b/src/slic3r/GUI/PresetHints.cpp @@ -93,8 +93,7 @@ std::string PresetHints::maximum_volumetric_flow_description(const PresetBundle double bridge_flow_ratio = print_config.opt_float("bridge_flow_ratio"); double perimeter_speed = print_config.opt_float("perimeter_speed"); double external_perimeter_speed = print_config.get_abs_value("external_perimeter_speed", perimeter_speed); - double gap_fill_enabled = print_config.get_abs_value("gap_fill_enabled", gap_fill_enabled); - // double gap_fill_speed = print_config.opt_float("gap_fill_speed"); + // double gap_fill_speed = print_config.opt_bool("gap_fill_enabled") ? print_config.opt_float("gap_fill_speed") : 0.; double infill_speed = print_config.opt_float("infill_speed"); double small_perimeter_speed = print_config.get_abs_value("small_perimeter_speed", perimeter_speed); double solid_infill_speed = print_config.get_abs_value("solid_infill_speed", infill_speed); diff --git a/tests/fff_print/test_fill.cpp b/tests/fff_print/test_fill.cpp index c98cdcf43..222e94d99 100644 --- a/tests/fff_print/test_fill.cpp +++ b/tests/fff_print/test_fill.cpp @@ -126,7 +126,7 @@ TEST_CASE("Fill: Pattern Path Length", "[Fill]") { filler->angle = 0; Surface surface(stTop, expolygon); - auto flow = Slic3r::Flow(0.69, 0.4, 0.50); + auto flow = Slic3r::Flow(0.69f, 0.4f, 0.50f); FillParams fill_params; fill_params.density = 1.0; @@ -435,7 +435,7 @@ bool test_if_solid_surface_filled(const ExPolygon& expolygon, double flow_spacin filler->bounding_box = get_extents(expolygon.contour); filler->angle = float(angle); - Flow flow(flow_spacing, 0.4, flow_spacing); + Flow flow(float(flow_spacing), 0.4f, float(flow_spacing)); filler->spacing = flow.spacing(); FillParams fill_params; diff --git a/tests/sla_print/sla_supptgen_tests.cpp b/tests/sla_print/sla_supptgen_tests.cpp index ee9013a44..e160504de 100644 --- a/tests/sla_print/sla_supptgen_tests.cpp +++ b/tests/sla_print/sla_supptgen_tests.cpp @@ -12,7 +12,7 @@ TEST_CASE("Overhanging point should be supported", "[SupGen]") { // Pyramid with 45 deg slope TriangleMesh mesh = make_pyramid(10.f, 10.f); - mesh.rotate_y(PI); + mesh.rotate_y(float(PI)); mesh.require_shared_vertices(); mesh.WriteOBJFile("Pyramid.obj"); @@ -81,7 +81,7 @@ TEST_CASE("Overhanging edge should be supported", "[SupGen]") { float width = 10.f, depth = 10.f, height = 5.f; TriangleMesh mesh = make_prism(width, depth, height); - mesh.rotate_y(PI); // rotate on its back + mesh.rotate_y(float(PI)); // rotate on its back mesh.translate(0., 0., height); mesh.require_shared_vertices(); mesh.WriteOBJFile("Prism.obj");