Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into refactor/improve-math…
Browse files Browse the repository at this point in the history
…-functions
  • Loading branch information
rburema committed Sep 4, 2024
2 parents d487aaa + 8868c17 commit c2b1ff2
Show file tree
Hide file tree
Showing 23 changed files with 341 additions and 131 deletions.
24 changes: 23 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ set(engine_SRCS # Except main.cpp.
src/communication/ArcusCommunication.cpp
src/communication/ArcusCommunicationPrivate.cpp
src/communication/CommandLine.cpp
src/communication/EmscriptenCommunication.cpp
src/communication/Listener.cpp

src/infill/ImageBasedDensityProvider.cpp
Expand Down Expand Up @@ -270,7 +271,28 @@ endif ()

if (CMAKE_CXX_PLATFORM_ID STREQUAL "emscripten")
message(STATUS "Building for Emscripten")
target_link_options(_CuraEngine PUBLIC -Wno-unused-command-line-argument -sINVOKE_RUN=0 -sEXPORT_NAME=CuraEngine -sEXPORTED_RUNTIME_METHODS=[callMain,FS] -sFORCE_FILESYSTEM=1 -sALLOW_MEMORY_GROWTH=1 -sEXPORT_ES6=1 -sMODULARIZE=1 -sSINGLE_FILE=1 -sENVIRONMENT=worker -sERROR_ON_UNDEFINED_SYMBOLS=0 -lembind --embind-emit-tsd CuraEngine.d.ts)
target_link_options(_CuraEngine
PUBLIC
"SHELL:-sINVOKE_RUN=0"
"SHELL:-sEXPORT_NAME=CuraEngine"
"SHELL:-sEXPORTED_RUNTIME_METHODS=[callMain,FS]"
"SHELL:-sFORCE_FILESYSTEM=1"
"SHELL:-sALLOW_MEMORY_GROWTH=1"
"SHELL:-sEXPORT_ES6=1"
"SHELL:-sMODULARIZE=1"
"SHELL:-sSINGLE_FILE=1"
"SHELL:-sENVIRONMENT=web"
"SHELL:-sERROR_ON_UNDEFINED_SYMBOLS=0"
"SHELL:-sWASM_BIGINT=1"
"SHELL:-sSTACK_SIZE=196608"
$<$<CONFIG:Debug>:SHELL:-sASSERTIONS=2>
$<$<CONFIG:Debug>:SHELL:-sSAFE_HEAP=1>
$<$<CONFIG:Debug>:SHELL:-sSTACK_OVERFLOW_CHECK=2>
$<$<CONFIG:Debug>:SHELL:-g3>
$<$<CONFIG:Debug>:SHELL:-gsource-map>
"SHELL:-lembind"
"SHELL:--embind-emit-tsd CuraEngine.d.ts"
)
endif ()

target_link_libraries(CuraEngine PRIVATE
Expand Down
5 changes: 3 additions & 2 deletions include/Application.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include <cassert>
#include <cstddef>
#include <memory>
#include <string>

#include "utils/NoCopy.h"
Expand Down Expand Up @@ -38,14 +39,14 @@ class Application : NoCopy
* can assume that it is safe to access this without checking whether it is
* initialised.
*/
Communication* communication_ = nullptr;
std::shared_ptr<Communication> communication_;

/*
* \brief The slice that is currently ongoing.
*
* If no slice has started yet, this will be a nullptr.
*/
Slice* current_slice_ = nullptr;
std::shared_ptr<Slice> current_slice_;

/*!
* \brief ThreadPool with lifetime tied to Application
Expand Down
13 changes: 6 additions & 7 deletions include/communication/CommandLine.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ using container_setting_map = std::unordered_map<std::string, setting_map>;
class CommandLine : public Communication
{
public:
CommandLine() = default;

/*
* \brief Construct a new communicator that interprets the command line to
* start a slice.
Expand Down Expand Up @@ -155,18 +157,15 @@ class CommandLine : public Communication
*/
void sliceNext() override;

private:
#ifdef __EMSCRIPTEN__
std::string progressHandler;
#endif

std::vector<std::filesystem::path> search_directories_;

protected:
/*
* \brief The command line arguments that the application was called with.
*/
std::vector<std::string> arguments_;

private:
std::vector<std::filesystem::path> search_directories_;

/*
* The last progress update that we output to stdcerr.
*/
Expand Down
65 changes: 65 additions & 0 deletions include/communication/EmscriptenCommunication.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// Copyright (c) 2024 UltiMaker
// CuraEngine is released under the terms of the AGPLv3 or higher

#ifndef EMSCRIPTENCOMMUNICATION_H
#define EMSCRIPTENCOMMUNICATION_H
#ifdef __EMSCRIPTEN__

#include "communication/CommandLine.h"

namespace cura
{

/**
* \class EmscriptenCommunication
* \brief A class for handling communication in an Emscripten environment.
*
* This class extends the CommandLine class and provides specific implementations
* for sending progress and handling slice information in an Emscripten environment.
*/
class EmscriptenCommunication : public CommandLine
{
private:
std::string progress_handler_; ///< Handler for progress messages.
std::string gcode_header_handler_; ///< Handler for getting the GCode handler.
std::string slice_info_handler_; ///< Handler for slice information messages.

/**
* \brief Creates a message containing slice information.
* \return A string containing the slice information message.
*/
[[nodiscard]] static std::string createSliceInfoMessage();

public:
/**
* \brief Constructor for EmscriptenCommunication.
* \param arguments A vector of strings containing the command line arguments.
*/
EmscriptenCommunication(const std::vector<std::string>& arguments);

/**
* \brief Sends the progress of the current operation.
* \param progress A double representing the progress percentage.
*/
void sendProgress(double progress) const override;

/**
* \brief Sends GcodeHeader
*/
void sendGCodePrefix(const std::string& prefix) const override;

/**
* \brief Initiates the slicing of the next item.
*/
void sliceNext() override;

bool isSequential() const override
{
return false;
}
};

} // namespace cura

#endif // __EMSCRIPTEN__
#endif // EMSCRIPTENCOMMUNICATION_H
27 changes: 27 additions & 0 deletions include/utils/string.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
#include <ctype.h>
#include <sstream> // ostringstream

#include <boost/archive/iterators/base64_from_binary.hpp>
#include <boost/archive/iterators/ostream_iterator.hpp>
#include <boost/archive/iterators/transform_width.hpp>
#include <spdlog/spdlog.h>

namespace cura
Expand All @@ -27,6 +30,30 @@ static inline int stringcasecompare(const char* a, const char* b)
return *a - *b;
}

// Convert string to base64 string.
// This function is useful to forward string through javascript even if they contain any special strings
//
[[maybe_unused]] static std::string convertTobase64(const std::string& input)
{
using namespace boost::archive::iterators;
// prepare the stream to hold the encoded data
std::stringstream output;

// encode data
typedef base64_from_binary<transform_width<std::string::const_iterator, 6, 8>> base64_enc;
std::copy(base64_enc(input.begin()), base64_enc(input.end()), ostream_iterator<char>(output));

// Retrieve the encoded string
std::string output_encoded = output.str();

// ensure padding if needed
size_t num = (3 - input.length() % 3) % 3;
for (size_t i = 0; i < num; i++)
{
output_encoded.push_back('=');
}
return output_encoded;
}
/*!
* Efficient conversion of micron integer type to millimeter string.
*
Expand Down
12 changes: 8 additions & 4 deletions src/Application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@
#include <spdlog/sinks/stdout_color_sinks.h>
#include <spdlog/spdlog.h>

#include "Slice.h"
#include "communication/ArcusCommunication.h" //To connect via Arcus to the front-end.
#include "communication/CommandLine.h" //To use the command line to slice stuff.
#include "communication/EmscriptenCommunication.h" // To use Emscripten to slice stuff.
#include "progress/Progress.h"
#include "utils/ThreadPool.h"
#include "utils/string.h" //For stringcasecompare.
Expand All @@ -45,7 +47,6 @@ Application::Application()

Application::~Application()
{
delete communication_;
delete thread_pool_;
}

Expand Down Expand Up @@ -100,7 +101,7 @@ void Application::connect()
}
}

ArcusCommunication* arcus_communication = new ArcusCommunication();
auto arcus_communication = std::make_shared<ArcusCommunication>();
arcus_communication->connect(ip, port);
communication_ = arcus_communication;
}
Expand Down Expand Up @@ -214,8 +215,11 @@ void Application::slice()
{
arguments.emplace_back(argv_[argument_index]);
}

communication_ = new CommandLine(arguments);
#ifdef __EMSCRIPTEN__
communication_ = std::make_shared<EmscriptenCommunication>(arguments);
#else
communication_ = std::make_shared<CommandLine>(arguments);
#endif
}

void Application::run(const size_t argc, char** argv)
Expand Down
2 changes: 1 addition & 1 deletion src/ConicalOverhang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ void ConicalOverhang::apply(Slicer* slicer, const Mesh& mesh)
const coord_t layer_thickness = mesh.settings_.get<coord_t>("layer_height");
coord_t max_dist_from_lower_layer = std::llround(tan_angle * static_cast<double>(layer_thickness)); // max dist which can be bridged

for (LayerIndex layer_nr = slicer->layers.size() - 2; static_cast<int>(layer_nr) >= 0; layer_nr--)
for (LayerIndex layer_nr = LayerIndex(slicer->layers.size()) - 2; layer_nr >= 0; layer_nr--)
{
SlicerLayer& layer = slicer->layers[static_cast<size_t>(layer_nr)];
SlicerLayer& layer_above = slicer->layers[static_cast<size_t>(layer_nr) + 1ul];
Expand Down
33 changes: 15 additions & 18 deletions src/FffGcodeWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -575,7 +575,7 @@ void FffGcodeWriter::processRaft(const SliceDataStorage& storage)
const size_t surface_extruder_nr = mesh_group_settings.get<ExtruderTrain&>("raft_surface_extruder_nr").extruder_nr_;

coord_t z = 0;
const LayerIndex initial_raft_layer_nr = -Raft::getTotalExtraLayers();
const LayerIndex initial_raft_layer_nr = -LayerIndex(Raft::getTotalExtraLayers());
const Settings& interface_settings = mesh_group_settings.get<ExtruderTrain&>("raft_interface_extruder_nr").settings_;
const size_t num_interface_layers = interface_settings.get<size_t>("raft_interface_layers");
const Settings& surface_settings = mesh_group_settings.get<ExtruderTrain&>("raft_surface_extruder_nr").settings_;
Expand Down Expand Up @@ -764,7 +764,7 @@ void FffGcodeWriter::processRaft(const SliceDataStorage& storage)

z += raft_interface_z_offset;

for (LayerIndex raft_interface_layer = 1; static_cast<size_t>(raft_interface_layer) <= num_interface_layers; ++raft_interface_layer)
for (LayerIndex raft_interface_layer = 1; raft_interface_layer <= LayerIndex(num_interface_layers); ++raft_interface_layer)
{ // raft interface layer
const LayerIndex layer_nr = initial_raft_layer_nr + raft_interface_layer;
z += interface_layer_height;
Expand Down Expand Up @@ -925,7 +925,7 @@ void FffGcodeWriter::processRaft(const SliceDataStorage& storage)

z += raft_surface_z_offset;

for (LayerIndex raft_surface_layer = 1; static_cast<size_t>(raft_surface_layer) <= num_surface_layers; raft_surface_layer++)
for (LayerIndex raft_surface_layer = 1; raft_surface_layer <= LayerIndex(num_surface_layers); raft_surface_layer++)
{ // raft surface layers
const LayerIndex layer_nr = initial_raft_layer_nr + 1 + num_interface_layers + raft_surface_layer - 1; // +1: 1 base layer
z += surface_layer_height;
Expand Down Expand Up @@ -1538,7 +1538,7 @@ void FffGcodeWriter::calculateExtruderOrderPerLayer(const SliceDataStorage& stor
extruder_order_per_layer.init(true, storage.print_layer_count);

const std::vector<bool> extruders_used = storage.getExtrudersUsed();
for (LayerIndex layer_nr = -Raft::getTotalExtraLayers(); layer_nr < static_cast<LayerIndex>(storage.print_layer_count); layer_nr++)
for (LayerIndex layer_nr = -LayerIndex(Raft::getTotalExtraLayers()); layer_nr < LayerIndex(storage.print_layer_count); layer_nr++)
{
std::vector<ExtruderUse> extruder_order = getUsedExtrudersOnLayer(storage, last_extruder, layer_nr, extruders_used);
extruder_order_per_layer.push_back(extruder_order);
Expand All @@ -1557,7 +1557,7 @@ void FffGcodeWriter::calculateExtruderOrderPerLayer(const SliceDataStorage& stor

void FffGcodeWriter::calculatePrimeLayerPerExtruder(const SliceDataStorage& storage)
{
LayerIndex first_print_layer = -Raft::getTotalExtraLayers();
LayerIndex first_print_layer = -LayerIndex(Raft::getTotalExtraLayers());
for (size_t extruder_nr = 0; extruder_nr < MAX_EXTRUDERS; ++extruder_nr)
{
if (getExtruderNeedPrimeBlobDuringFirstLayer(storage, extruder_nr))
Expand All @@ -1567,7 +1567,7 @@ void FffGcodeWriter::calculatePrimeLayerPerExtruder(const SliceDataStorage& stor
}
}

for (LayerIndex layer_nr = first_print_layer; layer_nr < static_cast<LayerIndex>(storage.print_layer_count); ++layer_nr)
for (LayerIndex layer_nr = first_print_layer; layer_nr < LayerIndex(storage.print_layer_count); ++layer_nr)
{
const std::vector<bool> used_extruders = storage.getExtrudersUsed(layer_nr);
for (size_t extruder_nr = 0; extruder_nr < used_extruders.size(); ++extruder_nr)
Expand All @@ -1591,7 +1591,7 @@ std::vector<ExtruderUse> FffGcodeWriter::getUsedExtrudersOnLayer(
assert(static_cast<int>(extruder_count) > 0);
std::vector<ExtruderUse> ret;
std::vector<bool> extruder_is_used_on_this_layer = storage.getExtrudersUsed(layer_nr);
const LayerIndex raft_base_layer_nr = -Raft::getTotalExtraLayers();
const LayerIndex raft_base_layer_nr = -LayerIndex(Raft::getTotalExtraLayers());
Raft::LayerType layer_type = Raft::getLayerType(layer_nr);

if (layer_type == Raft::RaftBase)
Expand Down Expand Up @@ -1827,8 +1827,7 @@ void FffGcodeWriter::addMeshPartToGCode(
added_something = added_something | processSkin(storage, gcode_layer, mesh, extruder_nr, mesh_config, part);

// After a layer part, make sure the nozzle is inside the comb boundary, so we do not retract on the perimeter.
if (added_something
&& (! mesh_group_settings.get<bool>("magic_spiralize") || gcode_layer.getLayerNr() < static_cast<LayerIndex>(mesh.settings.get<size_t>("initial_bottom_layers"))))
if (added_something && (! mesh_group_settings.get<bool>("magic_spiralize") || gcode_layer.getLayerNr() < LayerIndex(mesh.settings.get<size_t>("initial_bottom_layers"))))
{
coord_t innermost_wall_line_width = mesh.settings.get<coord_t>((mesh.settings.get<size_t>("wall_line_count") > 1) ? "wall_line_width_x" : "wall_line_width_0");
if (gcode_layer.getLayerNr() == 0)
Expand Down Expand Up @@ -2929,27 +2928,25 @@ bool FffGcodeWriter::processInsets(
bool spiralize = false;
if (Application::getInstance().current_slice_->scene.current_mesh_group->settings.get<bool>("magic_spiralize"))
{
const size_t initial_bottom_layers = mesh.settings.get<size_t>("initial_bottom_layers");
const int layer_nr = gcode_layer.getLayerNr();
if ((layer_nr < static_cast<LayerIndex>(initial_bottom_layers)
&& part.wall_toolpaths.empty()) // The bottom layers in spiralize mode are generated using the variable width paths
|| (layer_nr >= static_cast<LayerIndex>(initial_bottom_layers) && part.spiral_wall.empty())) // The rest of the layers in spiralize mode are using the spiral wall
const auto initial_bottom_layers = LayerIndex(mesh.settings.get<size_t>("initial_bottom_layers"));
const auto layer_nr = gcode_layer.getLayerNr();
if ((layer_nr < initial_bottom_layers && part.wall_toolpaths.empty()) // The bottom layers in spiralize mode are generated using the variable width paths
|| (layer_nr >= initial_bottom_layers && part.spiral_wall.empty())) // The rest of the layers in spiralize mode are using the spiral wall
{
// nothing to do
return false;
}
if (gcode_layer.getLayerNr() >= static_cast<LayerIndex>(initial_bottom_layers))
if (gcode_layer.getLayerNr() >= initial_bottom_layers)
{
spiralize = true;
}
if (spiralize && gcode_layer.getLayerNr() == static_cast<LayerIndex>(initial_bottom_layers)
&& extruder_nr == mesh.settings.get<ExtruderTrain&>("wall_0_extruder_nr").extruder_nr_)
if (spiralize && gcode_layer.getLayerNr() == initial_bottom_layers && extruder_nr == mesh.settings.get<ExtruderTrain&>("wall_0_extruder_nr").extruder_nr_)
{ // on the last normal layer first make the outer wall normally and then start a second outer wall from the same hight, but gradually moving upward
added_something = true;
gcode_layer.setIsInside(true); // going to print stuff inside print object
// start this first wall at the same vertex the spiral starts
const Polygon& spiral_inset = part.spiral_wall[0];
const size_t spiral_start_vertex = storage.spiralize_seam_vertex_indices[initial_bottom_layers];
const size_t spiral_start_vertex = storage.spiralize_seam_vertex_indices[static_cast<size_t>(initial_bottom_layers.value)];
if (spiral_start_vertex < spiral_inset.size())
{
gcode_layer.addTravel(spiral_inset[spiral_start_vertex]);
Expand Down
8 changes: 4 additions & 4 deletions src/FffPolygonGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -557,7 +557,7 @@ void FffPolygonGenerator::processInfillMesh(SliceDataStorage& storage, const siz
coord_t surface_line_width = mesh.settings.get<coord_t>("wall_line_width_0");

mesh.layer_nr_max_filled_layer = -1;
for (LayerIndex layer_idx = 0; layer_idx < static_cast<LayerIndex>(mesh.layers.size()); layer_idx++)
for (LayerIndex layer_idx = 0; layer_idx < LayerIndex(mesh.layers.size()); layer_idx++)
{
SliceLayer& layer = mesh.layers[layer_idx];

Expand Down Expand Up @@ -585,7 +585,7 @@ void FffPolygonGenerator::processInfillMesh(SliceDataStorage& storage, const siz
break; // all previous meshes have been processed
}
SliceMeshStorage& other_mesh = *storage.meshes[other_mesh_idx];
if (layer_idx >= static_cast<LayerIndex>(other_mesh.layers.size()))
if (layer_idx >= LayerIndex(other_mesh.layers.size()))
{ // there can be no interaction between the infill mesh and this other non-infill mesh
continue;
}
Expand Down Expand Up @@ -875,7 +875,7 @@ void FffPolygonGenerator::computePrintHeightStatistics(SliceDataStorage& storage
}
for (size_t extruder_nr = 0; extruder_nr < extruder_count; extruder_nr++)
{
for (LayerIndex layer_nr = static_cast<LayerIndex>(mesh.layers.size()) - 1; layer_nr > max_print_height_per_extruder[extruder_nr]; layer_nr--)
for (LayerIndex layer_nr = LayerIndex(mesh.layers.size()) - 1; layer_nr > max_print_height_per_extruder[extruder_nr]; layer_nr--)
{
if (mesh.getExtruderIsUsed(extruder_nr, layer_nr))
{
Expand Down Expand Up @@ -1097,7 +1097,7 @@ void FffPolygonGenerator::processFuzzyWalls(SliceMeshStorage& mesh)
return false;
};

for (LayerIndex layer_nr = start_layer_nr; layer_nr < mesh.layers.size(); layer_nr++)
for (LayerIndex layer_nr = start_layer_nr; layer_nr < LayerIndex(mesh.layers.size()); layer_nr++)
{
SliceLayer& layer = mesh.layers[layer_nr];
for (SliceLayerPart& part : layer.parts)
Expand Down
Loading

0 comments on commit c2b1ff2

Please sign in to comment.