Try Live
Add Docs
Rankings
Pricing
Docs
Install
Install
Docs
Pricing
More...
More...
Try Live
Rankings
Enterprise
Create API Key
Add Docs
CuraEngine
https://github.com/ultimaker/curaengine
Admin
CuraEngine is a powerful, fast and robust engine for converting 3D models into g-code instructions
...
Tokens:
16,455
Snippets:
140
Trust Score:
10
Update:
5 days ago
Context
Skills
Chat
Benchmark
71.8
Suggestions
Latest
Show doc for...
Code
Info
Show Results
Context Summary (auto-generated)
Raw
Copy
Link
# CuraEngine CuraEngine is a powerful, fast, and robust C++ console application for 3D printing GCode generation. Designed as a better and faster alternative to the Skeinforge Engine, it serves as the core slicing engine for the open source Cura project by UltiMaker. The engine takes 3D models as input and converts them into layer-by-layer G-code instructions that 3D printers can execute to produce physical objects. The slicing pipeline consists of five main stages: slicing (converting 3D mesh to 2D layers), generating areas (dividing layers into walls, skin, infill, and support regions), generating paths (filling areas with print lines), inserting commands (pre-heating/pre-cooling for multi-extruder prints), and G-code export. CuraEngine can be used as a standalone command-line tool or integrated into other applications via the Arcus communication protocol. It supports advanced features like adaptive layer heights, tree support, multiple infill patterns, and a plugin system for extensibility. ## Command Line Interface CuraEngine can be run from the command line to slice 3D models into G-code. It accepts a settings JSON file and 3D model files, producing G-code output suitable for 3D printers. ```bash # Display help information CuraEngine help # Basic slicing command with settings file CuraEngine slice -j /path/to/fdmprinter.def.json \ -l /path/to/model.stl \ -o /path/to/output.gcode # Slice with custom settings overrides CuraEngine slice -j /path/to/fdmprinter.def.json \ -s infill_sparse_density=20 \ -s layer_height=0.2 \ -s wall_line_count=3 \ -l /path/to/model.stl \ -o /path/to/output.gcode # Connect to Cura frontend via Arcus protocol ./CuraEngine connect 127.0.0.1:49674 ``` ## Building CuraEngine CuraEngine uses Conan for dependency management and CMake for building. The project requires C++20 support and various build tools depending on the platform. ```bash # Install Conan and configure pip install conan==2.7.1 conan config install https://github.com/ultimaker/conan-config.git conan profile detect --force # Clone repository git clone https://github.com/Ultimaker/CuraEngine.git cd CuraEngine # Install dependencies and build (Release) conan install . --build=missing --update cmake --preset conan-release cmake --build --preset conan-release # Build Debug version conan install . --build=missing --update -s build_type=Debug cmake --preset conan-debug cmake --build --preset conan-debug # Activate Conan run environment (Linux/macOS) source build/Release/generators/conanrun.sh # Activate Conan run environment (Windows PowerShell) .\build\generators\conanrun.sh ``` ## Application Singleton The `Application` class is the main entry point for CuraEngine, managing communication, slicing operations, and thread pools. It follows a singleton pattern and coordinates all slicing activities. ```cpp #include "Application.h" #include "communication/Communication.h" #include "Slice.h" // Access the application singleton cura::Application& app = cura::Application::getInstance(); // Start the application with command line arguments int main(int argc, char** argv) { cura::Application::getInstance().run(argc, argv); return 0; } // Access current slice data if (app.current_slice_) { cura::Scene& scene = app.current_slice_->scene; // Process scene data } // Start thread pool with specific number of workers app.startThreadPool(8); // 8 worker threads // Print help information app.printHelp(); ``` ## Settings System Settings are stored hierarchically in `Settings` instances associated with scene objects. The system supports inheritance from parent settings and type-safe value retrieval with template overloads. ```cpp #include "settings/Settings.h" #include "settings/types/Angle.h" #include "settings/types/Velocity.h" #include "Application.h" // Get settings from the current slice scene const cura::Settings& settings = cura::Application::getInstance().current_slice_->scene.settings; // Retrieve settings with type-safe templates AngleDegrees support_angle = settings.get<AngleDegrees>("support_angle"); // 0-360 degrees AngleRadians angle_radians = settings.get<AngleRadians>("support_angle"); // 0-tau radians coord_t layer_height = settings.get<coord_t>("layer_height"); // In microns Velocity print_speed = settings.get<Velocity>("speed_print"); double infill_density = settings.get<double>("infill_sparse_density"); size_t wall_count = settings.get<size_t>("wall_line_count"); // Add or modify settings cura::Settings my_settings; my_settings.add("layer_height", "200"); // 0.2mm in microns my_settings.add("infill_sparse_density", "20"); // 20% infill my_settings.add("wall_line_count", "3"); // Check if setting exists bool has_setting = settings.has("support_enable"); // Set parent for inheritance my_settings.setParent(&parent_settings); // Get all settings as command-line compatible string std::string all_settings = settings.getAllSettingsString(); ``` ## Slicer - 3D to 2D Conversion The `Slicer` class converts 3D mesh geometry into 2D layer cross-sections. It handles triangle-plane intersections, polygon stitching, and non-manifold mesh repair. ```cpp #include "slicer.h" #include "mesh.h" #include "settings/AdaptiveLayerHeights.h" // Create slicer for a mesh cura::Mesh* mesh = /* loaded mesh */; coord_t layer_thickness = 200; // 0.2mm in microns size_t slice_layer_count = 100; bool use_adaptive_layers = false; std::vector<cura::AdaptiveLayer>* adaptive_layers = nullptr; cura::SlicingTolerance tolerance = cura::SlicingTolerance::MIDDLE; coord_t initial_layer_thickness = 270; // 0.27mm cura::Slicer slicer( mesh, layer_thickness, slice_layer_count, use_adaptive_layers, adaptive_layers, tolerance, initial_layer_thickness ); // Access sliced layers for (const cura::SlicerLayer& layer : slicer.layers) { // layer.z_ contains the Z height in microns // layer.polygons_ contains closed polygon shapes // layer.open_polylines_ contains non-closed polylines double total_area = 0; for (const auto& polygon : layer.polygons_) { total_area += polygon.area(); } } ``` ## Geometric Types - Polygon and Shape CuraEngine uses fixed-point coordinates stored as 64-bit integers representing microns. The geometric base types include `Point2LL`, `Polygon`, `Shape`, and various polyline classes for 2D operations. ```cpp #include "geometry/Point2LL.h" #include "geometry/Polygon.h" #include "geometry/Shape.h" #include "geometry/OpenPolyline.h" // Create points (coordinates in microns, 1000 = 1mm) cura::Point2LL p1(0, 0); cura::Point2LL p2(10000, 0); // 10mm on X axis cura::Point2LL p3(10000, 10000); // 10mm x 10mm cura::Point2LL p4(0, 10000); // Create a polygon (implicitly closed) cura::Polygon square({p1, p2, p3, p4}, false); // false = implicitly closed // Calculate polygon properties double area = square.area(); // Area in square microns cura::Point2LL center = square.centerOfMass(); // Polygon offset operations (positive = outward, negative = inward) cura::Shape offset_result = square.offset(500); // Offset by 0.5mm // Create a shape from multiple polygons cura::Shape shape; shape.push_back(square); // Boolean operations on shapes cura::Shape other_shape = /* another shape */; cura::Shape union_result = shape.unionPolygons(other_shape); cura::Shape diff_result = shape.difference(other_shape); cura::Shape intersect_result = shape.intersection(other_shape); // Point-in-polygon test bool is_inside = shape.inside(cura::Point2LL(5000, 5000)); // Remove small areas (in mm^2) shape.removeSmallAreas(1.0, false); // Remove areas < 1mm^2, keep holes // Smooth polygon edges cura::Shape smoothed = shape.smooth(100); // Remove segments < 0.1mm ``` ## Infill Pattern Generation The `Infill` class generates various infill patterns for filling interior regions of printed objects. It supports patterns like lines, grid, triangles, gyroid, honeycomb, and more. ```cpp #include "infill.h" #include "geometry/Shape.h" #include "geometry/OpenLinesSet.h" #include "settings/Settings.h" // Define the area to fill with infill cura::Shape infill_area = /* area to fill */; // Create infill generator cura::Infill infill( cura::EFillMethod::LINES, // Pattern type true, // zig_zaggify - connect lines false, // connect_polygons infill_area, // Area to fill 400, // line_width (0.4mm) 2000, // line_distance (2mm for ~20% density) 100, // infill_overlap with walls 1, // infill_multiplier 45.0, // fill_angle in degrees 1000, // z height 0, // shift 50, // max_resolution 25 // max_deviation ); // Generate infill paths std::vector<cura::VariableWidthLines> toolpaths; cura::Shape result_polygons; cura::OpenLinesSet result_lines; cura::Settings settings; infill.generate( toolpaths, // Variable width paths (for walls) result_polygons, // Resulting closed polygons result_lines, // Resulting line segments settings, 0, // layer_idx cura::SectionType::INFILL ); // Available infill patterns: // EFillMethod::LINES - Simple parallel lines // EFillMethod::GRID - Rectangular grid // EFillMethod::TRIANGLES - Triangular pattern // EFillMethod::CUBIC - 3D cubic pattern // EFillMethod::GYROID - Gyroid surface pattern // EFillMethod::HONEYCOMB - Honeycomb hexagonal pattern // EFillMethod::CONCENTRIC - Concentric inward loops // EFillMethod::LIGHTNING - Minimal support structure ``` ## FffProcessor - Main Slicing Processor The `FffProcessor` singleton orchestrates the entire slicing process, managing G-code generation and polygon generation. It coordinates between the `FffGcodeWriter` and `FffPolygonGenerator` components. ```cpp #include "FffProcessor.h" #include "sliceDataStorage.h" // Get the processor singleton cura::FffProcessor* processor = cura::FffProcessor::getInstance(); // Set output target processor->setTargetFile("/path/to/output.gcode"); // Or use a stream std::ostringstream gcode_stream; processor->setTargetStream(&gcode_stream); // After slicing, get statistics // Get total filament used for each extruder (in mm^3) double filament_extruder_0 = processor->getTotalFilamentUsed(0); double filament_extruder_1 = processor->getTotalFilamentUsed(1); // Get print time estimates by feature type std::vector<cura::Duration> times = processor->getTotalPrintTimePerFeature(); // times contains: [none, inset0, insetX, skin, support, skirt, infill, ...] // Check if extruder is actually used bool extruder_used = processor->getExtruderActualUse(0); // Finalize and write end G-code processor->finalize(); ``` ## G-code Export Commands CuraEngine translates internal representations to G-code commands. The translation maps paths to movement commands with appropriate parameters for extrusion, temperature, and motion control. ```gcode ; Movement commands G0 X100.000 Y100.000 Z0.200 ; Travel move (no extrusion) G1 X150.000 Y100.000 E10.500 F1800 ; Print move with extrusion and feedrate ; Temperature control M104 S200 ; Set hotend temperature (no wait) M109 S200 ; Set hotend temperature and wait M140 S60 ; Set bed temperature (no wait) M190 S60 ; Set bed temperature and wait ; Fan control M106 S255 ; Fan on (0-255) M107 ; Fan off ; Motion settings M204 S3000 ; Set acceleration M205 X20 Y20 ; Set jerk ; Retraction (firmware-specific) G10 ; Retract filament G11 ; Unretract filament ; Or with direct E moves: G1 E-5.0 F2700 ; Retract 5mm G1 E5.0 F2700 ; Unretract 5mm ; E coordinate reset (for long prints) G92 E0 ; Reset E to 0 when exceeding 10000 ; Example layer start ;LAYER:5 ;HEIGHT:1.200 G0 Z1.200 ; Move to layer height ``` ## Arcus Communication Protocol CuraEngine communicates with the Cura frontend via the Arcus protocol using Protocol Buffers. The protocol defines messages for slicing requests, progress updates, and layer data transfer. ```protobuf // Slice request message (from Cura.proto) message Slice { repeated ObjectList object_lists = 1; // Mesh groups to print SettingList global_settings = 2; // Global print settings repeated Extruder extruders = 3; // Extruder settings repeated SettingExtruder limit_to_extruder = 4; repeated EnginePlugin engine_plugins = 5; } // Object definition message Object { int64 id = 1; bytes vertices = 2; // Float[3] array - vertex positions bytes normals = 3; // Float[3] array - vertex normals bytes indices = 4; // Int array - triangle indices repeated Setting settings = 5; string name = 6; } // Layer data for visualization message LayerOptimized { int32 id = 1; float height = 2; // Z position float thickness = 3; // Layer height repeated PathSegment path_segment = 4; } // Print time and material estimates message PrintTimeMaterialEstimates { float time_inset_0 = 2; // Outer wall time float time_inset_x = 3; // Inner wall time float time_skin = 4; // Top/bottom skin time float time_infill = 7; // Infill time float time_support = 5; // Support time float time_travel = 9; // Travel time repeated MaterialEstimates materialEstimates = 13; } ``` ## Plugin System CuraEngine supports a plugin architecture for extending functionality. Plugins can modify various stages of the slicing process through defined slot IDs. ```cpp // Plugin slot IDs (from Cura.proto) enum SlotID { SETTINGS_BROADCAST = 0; // Broadcast settings to plugins SIMPLIFY_MODIFY = 100; // Modify polygon simplification POSTPROCESS_MODIFY = 101; // Post-process G-code INFILL_MODIFY = 102; // Modify infill patterns GCODE_PATHS_MODIFY = 103; // Modify G-code paths INFILL_GENERATE = 200; // Generate custom infill } // Plugin registration message message EnginePlugin { SlotID id = 1; // Which slot this plugin uses string address = 2; // Plugin server address uint32 port = 3; // Plugin server port string plugin_name = 4; string plugin_version = 5; } // Enable plugins via Conan build options // conan install . -o enable_plugins=True -o enable_remote_plugins=True ``` ## Scene and Mesh Hierarchy The scene hierarchy organizes print data into mesh groups, extruders, and individual meshes. Each level can have its own settings that override parent settings. ```cpp #include "Scene.h" #include "MeshGroup.h" #include "mesh.h" #include "ExtruderTrain.h" // Access the current scene cura::Slice* slice = cura::Application::getInstance().current_slice_.get(); cura::Scene& scene = slice->scene; // Scene-level (global) settings const cura::Settings& global_settings = scene.settings; // Access extruders for (const cura::ExtruderTrain& extruder : scene.extruders) { coord_t nozzle_size = extruder.settings_.get<coord_t>("machine_nozzle_size"); // Each extruder has its own settings with scene as parent } // Process mesh groups (for one-at-a-time printing) for (cura::MeshGroup& mesh_group : scene.mesh_groups) { // Mesh group settings override scene settings const cura::Settings& group_settings = mesh_group.settings; // Access individual meshes for (cura::Mesh& mesh : mesh_group.meshes) { // Mesh settings override mesh group settings std::string mesh_name = mesh.mesh_name; size_t vertex_count = mesh.vertices.size(); size_t face_count = mesh.faces.size(); // Get mesh-specific settings bool is_support_mesh = mesh.settings.get<bool>("support_mesh"); } } ``` ## LayerPlan and Path Planning The `LayerPlan` class manages the printing plan for a single layer, including all extruder plans, travel moves, and extrusion paths with optimized ordering. ```cpp #include "LayerPlan.h" #include "ExtruderPlan.h" #include "pathPlanning/GCodePath.h" // LayerPlan contains multiple ExtruderPlans // Each ExtruderPlan contains GCodePaths // Path types in a layer (printing order): // 1. Prime blob (if first layer) // 2. Prime tower // 3. Skirt/Brim/Raft // 4. Ooze shield // 5. Draft shield // 6. Support // 7. For each part: // - Infill // - Inner walls // - Outer wall // - Gap fill (walls) // - Skin // - Gap fill (skin) // - Ironing // - Surface mode paths // GCodePath properties struct GCodePath { coord_t line_width; // Width of extrusion coord_t layer_thickness; // Height of layer Velocity speed; // Print speed Velocity acceleration; // Motion acceleration double flow; // Flow rate multiplier PrintFeatureType feature; // Type (wall, skin, infill, etc.) std::vector<Point2LL> points; // Path coordinates }; // Travel move optimization includes: // - Combing (avoiding crossing walls) // - Z-hop (lifting nozzle over obstacles) // - Retraction management // - Collision avoidance ``` CuraEngine is the ideal choice for developers building 3D printing applications, slicing software, or automated manufacturing systems. Its modular architecture allows integration at various levels - from using it as a complete command-line slicer to embedding specific components like the infill generator or geometric operations library. The engine excels at handling complex geometries, multi-extruder setups, and advanced features like tree support and adaptive layer heights. For production deployments, CuraEngine can be integrated via the Arcus protocol for real-time communication with graphical frontends, or used standalone for batch processing of 3D models. The plugin system enables customization of infill patterns, post-processing, and G-code modifications without modifying the core engine. Whether building a cloud slicing service, a custom 3D printer control system, or extending Cura itself, CuraEngine provides the robust foundation needed for professional 3D printing workflows.