diff --git a/.gitea/workflows/cicd.yaml b/.gitea/workflows/cicd.yaml index f513b76..c79c40e 100644 --- a/.gitea/workflows/cicd.yaml +++ b/.gitea/workflows/cicd.yaml @@ -15,17 +15,17 @@ jobs: - name: Checkout uses: actions/checkout@v4 - # Evito actions/setup-python (spesso fragile su act_runner) - - name: Install Python deps + run tests - shell: bash + - name: Set up JDK 21 + uses: actions/setup-java@v4 + with: + java-version: '21' + distribution: 'temurin' + cache: maven + + - name: Run Tests with Maven run: | - apt-get update - apt-get install -y --no-install-recommends python3 python3-pip - python3 -m pip install --upgrade pip - python3 -m pip install -r backend/requirements.txt - python3 -m pip install pytest httpx - export PYTHONPATH="${PYTHONPATH}:$(pwd)/backend" - pytest backend/tests + cd backend + mvn test build-and-push: needs: test-backend diff --git a/backend/Dockerfile b/backend/Dockerfile index 4a386dd..48f14d6 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -1,6 +1,16 @@ -FROM --platform=linux/amd64 python:3.10-slim-bookworm +# Stage 1: Build Java JAR +FROM maven:3.9-eclipse-temurin-21 AS build +WORKDIR /app +COPY pom.xml . +# Download dependencies first to cache them +RUN mvn dependency:go-offline +COPY src ./src +RUN mvn clean package -DskipTests -# Install system dependencies for OrcaSlicer (AppImage) +# Stage 2: Runtime Environment +FROM eclipse-temurin:21-jre-jammy + +# Install system dependencies for OrcaSlicer (same as before) RUN apt-get update && apt-get install -y \ wget \ p7zip-full \ @@ -9,35 +19,25 @@ RUN apt-get update && apt-get install -y \ libgtk-3-0 \ libdbus-1-3 \ libwebkit2gtk-4.1-0 \ - libwebkit2gtk-4.0-37 \ && rm -rf /var/lib/apt/lists/* -# Set working directory -WORKDIR /app - -# Download and extract OrcaSlicer -# Using v2.2.0 as a stable recent release -# We extract the AppImage to run it without FUSE +# Install OrcaSlicer +WORKDIR /opt RUN wget -q https://github.com/SoftFever/OrcaSlicer/releases/download/v2.2.0/OrcaSlicer_Linux_V2.2.0.AppImage -O OrcaSlicer.AppImage \ && 7z x OrcaSlicer.AppImage -o/opt/orcaslicer \ && chmod -R +x /opt/orcaslicer \ && rm OrcaSlicer.AppImage -# Add OrcaSlicer to PATH ENV PATH="/opt/orcaslicer/usr/bin:${PATH}" +# Set Slicer Path env variable for Java app +ENV SLICER_PATH="/opt/orcaslicer/AppRun" -# Install Python dependencies -COPY requirements.txt . -RUN pip install --no-cache-dir -r requirements.txt +WORKDIR /app +# Copy JAR from build stage +COPY --from=build /app/target/*.jar app.jar +# Copy profiles +COPY profiles ./profiles -# Create directories for app and temp files -RUN mkdir -p /app/temp /app/profiles +EXPOSE 8080 -# Copy application code -COPY . . - -# Expose port -EXPOSE 8000 - -# Run the application -CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"] +CMD ["java", "-jar", "app.jar"] diff --git a/backend/api/routes.py b/backend/api/routes.py deleted file mode 100644 index 7e8a62f..0000000 --- a/backend/api/routes.py +++ /dev/null @@ -1,137 +0,0 @@ -from fastapi import APIRouter, UploadFile, File, HTTPException, Form -from models.quote_request import QuoteRequest, QuoteResponse -from slicer import slicer_service -from calculator import GCodeParser, QuoteCalculator -from config import settings -from profile_manager import ProfileManager -import os -import shutil -import uuid -import logging -import json - -router = APIRouter() -logger = logging.getLogger("api") -profile_manager = ProfileManager() - -def cleanup_files(files: list): - for f in files: - try: - if os.path.exists(f): - os.remove(f) - except Exception as e: - logger.warning(f"Failed to delete temp file {f}: {e}") - -def format_time(seconds: int) -> str: - m, s = divmod(seconds, 60) - h, m = divmod(m, 60) - if h > 0: - return f"{int(h)}h {int(m)}m" - return f"{int(m)}m {int(s)}s" - -@router.post("/quote", response_model=QuoteResponse) -async def calculate_quote( - file: UploadFile = File(...), - # Compatible with form data if we parse manually or use specific dependencies. - # FastAPI handling of mixed File + JSON/Form is tricky. - # Easiest is to use Form(...) for fields. - machine: str = Form("bambu_a1"), - filament: str = Form("pla_basic"), - quality: str = Form("standard"), - layer_height: str = Form(None), # Form data comes as strings usually - infill_density: int = Form(None), - infill_pattern: str = Form(None), - support_enabled: bool = Form(False), - print_speed: int = Form(None) -): - """ - Endpoint for calculating print quote. - Accepts Multipart Form Data: - - file: The STL file - - machine, filament, quality: strings - - other overrides - """ - if not file.filename.lower().endswith(".stl"): - raise HTTPException(status_code=400, detail="Only .stl files are supported.") - if machine != "bambu_a1": - raise HTTPException(status_code=400, detail="Unsupported machine.") - - req_id = str(uuid.uuid4()) - input_filename = f"{req_id}.stl" - output_filename = f"{req_id}.gcode" - - input_path = os.path.join(settings.TEMP_DIR, input_filename) - output_path = os.path.join(settings.TEMP_DIR, output_filename) - - try: - # 1. Save File - with open(input_path, "wb") as buffer: - shutil.copyfileobj(file.file, buffer) - - # 2. Build Overrides - overrides = {} - if layer_height is not None and layer_height != "": - overrides["layer_height"] = layer_height - if infill_density is not None: - overrides["sparse_infill_density"] = f"{infill_density}%" - if infill_pattern: - overrides["sparse_infill_pattern"] = infill_pattern - if support_enabled: overrides["enable_support"] = "1" - if print_speed is not None: - overrides["default_print_speed"] = str(print_speed) - - # 3. Slice - # Pass parameters to slicer service - slicer_service.slice_stl( - input_stl_path=input_path, - output_gcode_path=output_path, - machine=machine, - filament=filament, - quality=quality, - overrides=overrides - ) - - # 4. Parse - stats = GCodeParser.parse_metadata(output_path) - if stats["print_time_seconds"] == 0 and stats["filament_weight_g"] == 0: - raise HTTPException(status_code=500, detail="Slicing returned empty stats.") - - # 5. Calculate - # We could allow filament cost override here too if passed in params - quote = QuoteCalculator.calculate(stats) - - return QuoteResponse( - success=True, - data={ - "print_time_seconds": stats["print_time_seconds"], - "print_time_formatted": format_time(stats["print_time_seconds"]), - "material_grams": stats["filament_weight_g"], - "cost": { - "material": quote["breakdown"]["material_cost"], - "machine": quote["breakdown"]["machine_cost"], - "energy": quote["breakdown"]["energy_cost"], - "markup": quote["breakdown"]["markup_amount"], - "total": quote["total_price"] - }, - "parameters": { - "machine": machine, - "filament": filament, - "quality": quality - } - } - ) - - except Exception as e: - logger.error(f"Quote error: {e}", exc_info=True) - return QuoteResponse(success=False, error=str(e)) - - finally: - cleanup_files([input_path, output_path]) - -@router.get("/profiles/available") -def get_profiles(): - return { - "machines": profile_manager.list_machines(), - "filaments": profile_manager.list_filaments(), - "processes": profile_manager.list_processes() - } diff --git a/backend/calculator.py b/backend/calculator.py deleted file mode 100644 index 8e77d7a..0000000 --- a/backend/calculator.py +++ /dev/null @@ -1,174 +0,0 @@ -import re -import os -import logging -from typing import Dict, Any, Optional -from config import settings - -logger = logging.getLogger(__name__) - -class GCodeParser: - @staticmethod - def parse_metadata(gcode_path: str) -> Dict[str, Any]: - """ - Parses the G-code to extract estimated time and material usage. - Scans both the beginning (header) and end (footer) of the file. - """ - stats = { - "print_time_seconds": 0, - "filament_length_mm": 0, - "filament_volume_mm3": 0, - "filament_weight_g": 0, - "slicer_estimated_cost": 0 - } - - if not os.path.exists(gcode_path): - logger.warning(f"GCode file not found for parsing: {gcode_path}") - return stats - - try: - with open(gcode_path, 'r', encoding='utf-8', errors='ignore') as f: - # Read header (first 500 lines) - header_lines = [f.readline().strip() for _ in range(500) if f] - - # Read footer (last 20KB) - f.seek(0, 2) - file_size = f.tell() - read_len = min(file_size, 20480) - f.seek(file_size - read_len) - footer_lines = f.read().splitlines() - - all_lines = header_lines + footer_lines - - for line in all_lines: - line = line.strip() - if not line.startswith(";"): - continue - - GCodeParser._parse_line(line, stats) - - # Fallback calculation - if stats["filament_weight_g"] == 0 and stats["filament_length_mm"] > 0: - GCodeParser._calculate_weight_fallback(stats) - - except Exception as e: - logger.error(f"Error parsing G-code: {e}") - - return stats - - @staticmethod - def _parse_line(line: str, stats: Dict[str, Any]): - # Parse Time - if "estimated printing time =" in line: # Header - time_str = line.split("=")[1].strip() - logger.info(f"Parsing time string (Header): '{time_str}'") - stats["print_time_seconds"] = GCodeParser._parse_time_string(time_str) - elif "total estimated time:" in line: # Footer - parts = line.split("total estimated time:") - if len(parts) > 1: - time_str = parts[1].strip() - logger.info(f"Parsing time string (Footer): '{time_str}'") - stats["print_time_seconds"] = GCodeParser._parse_time_string(time_str) - - # Parse Filament info - if "filament used [g] =" in line: - try: - stats["filament_weight_g"] = float(line.split("=")[1].strip()) - except ValueError: pass - - if "filament used [mm] =" in line: - try: - stats["filament_length_mm"] = float(line.split("=")[1].strip()) - except ValueError: pass - - if "filament used [cm3] =" in line: - try: - # cm3 to mm3 - stats["filament_volume_mm3"] = float(line.split("=")[1].strip()) * 1000 - except ValueError: pass - - @staticmethod - def _calculate_weight_fallback(stats: Dict[str, Any]): - # Assumes 1.75mm diameter and PLA density 1.24 - radius = 1.75 / 2 - volume_mm3 = 3.14159 * (radius ** 2) * stats["filament_length_mm"] - volume_cm3 = volume_mm3 / 1000.0 - stats["filament_weight_g"] = volume_cm3 * 1.24 - - @staticmethod - def _parse_time_string(time_str: str) -> int: - """ - Converts '1d 2h 3m 4s' or 'HH:MM:SS' to seconds. - """ - total_seconds = 0 - - # Try HH:MM:SS or MM:SS format - if ':' in time_str: - parts = time_str.split(':') - parts = [int(p) for p in parts] - if len(parts) == 3: # HH:MM:SS - total_seconds = parts[0] * 3600 + parts[1] * 60 + parts[2] - elif len(parts) == 2: # MM:SS - total_seconds = parts[0] * 60 + parts[1] - return total_seconds - - # Original regex parsing for "1h 2m 3s" - days = re.search(r'(\d+)d', time_str) - hours = re.search(r'(\d+)h', time_str) - mins = re.search(r'(\d+)m', time_str) - secs = re.search(r'(\d+)s', time_str) - - if days: total_seconds += int(days.group(1)) * 86400 - if hours: total_seconds += int(hours.group(1)) * 3600 - if mins: total_seconds += int(mins.group(1)) * 60 - if secs: total_seconds += int(secs.group(1)) - - return total_seconds - - -class QuoteCalculator: - @staticmethod - def calculate(stats: Dict[str, Any]) -> Dict[str, Any]: - """ - Calculates the final quote based on parsed stats and settings. - """ - # 1. Material Cost - # Cost per gram = (Cost per kg / 1000) - material_cost = (stats["filament_weight_g"] / 1000.0) * settings.FILAMENT_COST_PER_KG - - # 2. Machine Time Cost - # Cost per second = (Cost per hour / 3600) - print("ciaooo") - print(stats["print_time_seconds"]) - print_time_hours = stats["print_time_seconds"] / 3600.0 - machine_cost = print_time_hours * settings.MACHINE_COST_PER_HOUR - - # 3. Energy Cost - # kWh = (Watts / 1000) * hours - kwh_used = (settings.PRINTER_POWER_WATTS / 1000.0) * print_time_hours - energy_cost = kwh_used * settings.ENERGY_COST_PER_KWH - - # Subtotal - subtotal = material_cost + machine_cost + energy_cost - - # 4. Markup - markup_factor = 1.0 + (settings.MARKUP_PERCENT / 100.0) - total_price = subtotal * markup_factor - - logger.info("Cost Calculation:") - logger.info(f" - Use: {stats['filament_weight_g']:.2f}g @ {settings.FILAMENT_COST_PER_KG}€/kg = {material_cost:.2f}€") - logger.info(f" - Time: {print_time_hours:.4f}h @ {settings.MACHINE_COST_PER_HOUR}€/h = {machine_cost:.2f}€") - logger.info(f" - Power: {kwh_used:.4f}kWh @ {settings.ENERGY_COST_PER_KWH}€/kWh = {energy_cost:.2f}€") - logger.info(f" - Subtotal: {subtotal:.2f}€") - logger.info(f" - Total (Markup {settings.MARKUP_PERCENT}%): {total_price:.2f}€") - - return { - "breakdown": { - "material_cost": round(material_cost, 2), - "machine_cost": round(machine_cost, 2), - "energy_cost": round(energy_cost, 2), - "subtotal": round(subtotal, 2), - "markup_amount": round(total_price - subtotal, 2) - }, - "total_price": round(total_price, 2), - "currency": "EUR" - } diff --git a/backend/config.py b/backend/config.py deleted file mode 100644 index c40a5c0..0000000 --- a/backend/config.py +++ /dev/null @@ -1,31 +0,0 @@ -import os -import sys - -class Settings: - # Directories - BASE_DIR = os.path.dirname(os.path.abspath(__file__)) - TEMP_DIR = os.environ.get("TEMP_DIR", os.path.join(BASE_DIR, "temp")) - PROFILES_DIR = os.environ.get("PROFILES_DIR", os.path.join(BASE_DIR, "profiles")) - - # Slicer Paths - if sys.platform == "darwin": - _DEFAULT_SLICER_PATH = "/Applications/OrcaSlicer.app/Contents/MacOS/OrcaSlicer" - else: - _DEFAULT_SLICER_PATH = "/opt/orcaslicer/AppRun" - - SLICER_PATH = os.environ.get("SLICER_PATH", _DEFAULT_SLICER_PATH) - ORCA_HOME = os.environ.get("ORCA_HOME", "/opt/orcaslicer") - - # Defaults Profiles (Bambu A1) - MACHINE_PROFILE = os.path.join(PROFILES_DIR, "Bambu_Lab_A1_machine.json") - PROCESS_PROFILE = os.path.join(PROFILES_DIR, "Bambu_Process_0.20_Standard.json") - FILAMENT_PROFILE = os.path.join(PROFILES_DIR, "Bambu_PLA_Basic.json") - - # Pricing - FILAMENT_COST_PER_KG = float(os.environ.get("FILAMENT_COST_PER_KG", 25.0)) - MACHINE_COST_PER_HOUR = float(os.environ.get("MACHINE_COST_PER_HOUR", 2.0)) - ENERGY_COST_PER_KWH = float(os.environ.get("ENERGY_COST_PER_KWH", 0.30)) - PRINTER_POWER_WATTS = float(os.environ.get("PRINTER_POWER_WATTS", 150.0)) - MARKUP_PERCENT = float(os.environ.get("MARKUP_PERCENT", 20.0)) - -settings = Settings() diff --git a/backend/main.py b/backend/main.py deleted file mode 100644 index cc537f1..0000000 --- a/backend/main.py +++ /dev/null @@ -1,74 +0,0 @@ -import logging -import os -from fastapi import FastAPI -from fastapi.middleware.cors import CORSMiddleware -from config import settings -from api.routes import router as api_router - -# Configure logging -logging.basicConfig(level=logging.INFO) -logger = logging.getLogger("main") - -app = FastAPI(title="Print Calculator API") - -# CORS Setup -app.add_middleware( - CORSMiddleware, - allow_origins=["*"], - allow_credentials=True, - allow_methods=["*"], - allow_headers=["*"], -) - -# Ensure directories exist -os.makedirs(settings.TEMP_DIR, exist_ok=True) - -# Include Router -app.include_router(api_router, prefix="/api") - -# Legacy endpoint redirect or basic handler if needed for backward compatibility -# The frontend likely calls /calculate/stl. -# We should probably keep the old route or instruct user to update frontend. -# But for this task, let's remap the old route to the new logic if possible, -# or just expose the new route. -# The user request said: "Creare api/routes.py ... @app.post('/api/quote')" -# So we are creating a new endpoint. -# Existing frontend might break? -# The context says: "Currently uses hardcoded... Objective is to render system flexible... Frontend: Angular 19" -# The user didn't explicitly ask to update the frontend, but the new API is at /api/quote. -# I will keep the old "/calculate/stl" endpoint support by forwarding it or duplicating logic if critical, -# OR I'll assume the user will handle frontend updates. -# Better: I will alias the old route to the new one if parameters allow, -# but the new one expects Form data with different names maybe? -# Old: `/calculate/stl` just expected a file. -# I'll enable a simplified version on the old route for backward compat using defaults. - -from fastapi import UploadFile, File -from api.routes import calculate_quote - -@app.post("/calculate/stl") -async def legacy_calculate(file: UploadFile = File(...)): - """Legacy endpoint compatibility""" - # Call the new logic with defaults - resp = await calculate_quote(file=file) - if not resp.success: - from fastapi import HTTPException - raise HTTPException(status_code=500, detail=resp.error) - - # Map Check response to old format - data = resp.data - return { - "print_time_seconds": data.get("print_time_seconds", 0), - "print_time_formatted": data.get("print_time_formatted", ""), - "material_grams": data.get("material_grams", 0.0), - "cost": data.get("cost", {}), - "notes": ["Generated via Dynamic Slicer (Legacy Endpoint)"] - } - -@app.get("/health") -def health_check(): - return {"status": "ok", "slicer": settings.SLICER_PATH} - -if __name__ == "__main__": - import uvicorn - uvicorn.run(app, host="0.0.0.0", port=8000) diff --git a/backend/models/quote_request.py b/backend/models/quote_request.py deleted file mode 100644 index dcdf0b2..0000000 --- a/backend/models/quote_request.py +++ /dev/null @@ -1,37 +0,0 @@ -from pydantic import BaseModel, Field, validator -from typing import Optional, Literal, Dict, Any - -class QuoteRequest(BaseModel): - # File STL (base64 or path) - file_path: Optional[str] = None - file_base64: Optional[str] = None - - # Parametri slicing - machine: str = Field(default="bambu_a1", description="Machine type") - filament: str = Field(default="pla_basic", description="Filament type") - quality: Literal["draft", "standard", "fine"] = Field(default="standard") - - # Parametri opzionali - layer_height: Optional[float] = Field(None, ge=0.08, le=0.32) - infill_density: Optional[int] = Field(None, ge=0, le=100) - support_enabled: Optional[bool] = None - print_speed: Optional[int] = Field(None, ge=20, le=300) - - # Pricing overrides - filament_cost_override: Optional[float] = None - - @validator('machine') - def validate_machine(cls, v): - # This list should ideally be dynamic, but for validation purposes we start with known ones. - # Logic in ProfileManager can be looser or strict. - # For now, we allow the string through and let ProfileManager validate availability. - return v - - @validator('filament') - def validate_filament(cls, v): - return v - -class QuoteResponse(BaseModel): - success: bool - data: Optional[Dict[str, Any]] = None - error: Optional[str] = None diff --git a/backend/obj_1_Base.stl b/backend/obj_1_Base.stl deleted file mode 100644 index 6d56459..0000000 Binary files a/backend/obj_1_Base.stl and /dev/null differ diff --git a/backend/obj_3_Hinge.stl b/backend/obj_3_Hinge.stl deleted file mode 100644 index 1c971ef..0000000 Binary files a/backend/obj_3_Hinge.stl and /dev/null differ diff --git a/backend/output/plate_1.gcode b/backend/output/plate_1.gcode deleted file mode 100644 index 04d1799..0000000 --- a/backend/output/plate_1.gcode +++ /dev/null @@ -1,3986 +0,0 @@ -; HEADER_BLOCK_START -; generated by OrcaSlicer 2.3.1 on 2026-01-28 at 00:18:53 -; model printing time: 5m 17s; total estimated time: 5m 21s -; estimated first layer printing time (normal mode) = 3s -; total layer number: 50 -; model label id: 15 -; filament_density: 0 -; filament_diameter: 1.75 -; max_z_height: 10.00 -; HEADER_BLOCK_END - -; CONFIG_BLOCK_START -; accel_to_decel_enable = 1 -; accel_to_decel_factor = 50% -; activate_air_filtration = 0 -; activate_chamber_temp_control = 0 -; adaptive_bed_mesh_margin = 0 -; adaptive_pressure_advance = 0 -; adaptive_pressure_advance_bridges = 0 -; adaptive_pressure_advance_model = "0,0,0\n0,0,0" -; adaptive_pressure_advance_overhangs = 0 -; additional_cooling_fan_speed = 0 -; align_infill_direction_to_model = 0 -; alternate_extra_wall = 0 -; auxiliary_fan = 0 -; bbl_calib_mark_logo = 1 -; bed_custom_model = -; bed_custom_texture = -; bed_exclude_area = 0x0 -; bed_mesh_max = 99999,99999 -; bed_mesh_min = -99999,-99999 -; bed_mesh_probe_distance = 50,50 -; before_layer_change_gcode = -; best_object_pos = 0.5,0.5 -; bottom_shell_layers = 3 -; bottom_shell_thickness = 0 -; bottom_solid_infill_flow_ratio = 1 -; bottom_surface_density = 100% -; bottom_surface_pattern = monotonic -; bridge_acceleration = 50% -; bridge_angle = 0 -; bridge_density = 100% -; bridge_flow = 1 -; bridge_no_support = 0 -; bridge_speed = 25 -; brim_ears_detection_length = 1 -; brim_ears_max_angle = 125 -; brim_object_gap = 0 -; brim_type = auto_brim -; brim_width = 0 -; calib_flowrate_topinfill_special_order = 0 -; chamber_temperature = 0 -; change_extrusion_role_gcode = -; change_filament_gcode = -; close_fan_the_first_x_layers = 1 -; complete_print_exhaust_fan_speed = 80 -; cool_plate_temp = 35 -; cool_plate_temp_initial_layer = 35 -; cooling_tube_length = 5 -; cooling_tube_retraction = 91.5 -; counterbore_hole_bridging = none -; curr_bed_type = Cool Plate -; default_acceleration = 500 -; default_filament_colour = "" -; default_filament_profile = "Bambu PLA Basic" -; default_jerk = 0 -; default_junction_deviation = 0 -; deretraction_speed = 40 -; detect_narrow_internal_solid_infill = 1 -; detect_overhang_wall = 1 -; detect_thin_wall = 0 -; different_settings_to_system = ; -; disable_m73 = 0 -; dont_filter_internal_bridges = disabled -; dont_slow_down_outer_wall = 0 -; draft_shield = disabled -; during_print_exhaust_fan_speed = 60 -; elefant_foot_compensation = 0 -; elefant_foot_compensation_layers = 1 -; emit_machine_limits_to_gcode = 1 -; enable_arc_fitting = 1 -; enable_extra_bridge_layer = disabled -; enable_filament_ramming = 1 -; enable_long_retraction_when_cut = 0 -; enable_overhang_bridge_fan = 1 -; enable_overhang_speed = 1 -; enable_pressure_advance = 0 -; enable_prime_tower = 0 -; enable_support = 0 -; enforce_support_layers = 0 -; eng_plate_temp = 45 -; eng_plate_temp_initial_layer = 45 -; ensure_vertical_shell_thickness = ensure_all -; exclude_object = 0 -; extra_loading_move = -2 -; extra_perimeters_on_overhangs = 0 -; extra_solid_infills = -; extruder_clearance_height_to_lid = 120 -; extruder_clearance_height_to_rod = 40 -; extruder_clearance_radius = 40 -; extruder_colour = #F2754E -; extruder_offset = 0x0 -; extrusion_rate_smoothing_external_perimeter_only = 0 -; fan_cooling_layer_time = 60 -; fan_kickstart = 0 -; fan_max_speed = 100 -; fan_min_speed = 20 -; fan_speedup_overhangs = 1 -; fan_speedup_time = 0 -; filament_colour = #F2754E -; filament_cooling_final_speed = 3.4 -; filament_cooling_initial_speed = 2.2 -; filament_cooling_moves = 4 -; filament_cost = 0 -; filament_density = 0 -; filament_diameter = 1.75 -; filament_end_gcode = " " -; filament_flow_ratio = 1 -; filament_is_support = 0 -; filament_loading_speed = 28 -; filament_loading_speed_start = 3 -; filament_max_volumetric_speed = 2 -; filament_minimal_purge_on_wipe_tower = 15 -; filament_multitool_ramming = 0 -; filament_multitool_ramming_flow = 10 -; filament_multitool_ramming_volume = 10 -; filament_notes = "" -; filament_ramming_parameters = "120 100 6.6 6.8 7.2 7.6 7.9 8.2 8.7 9.4 9.9 10.0| 0.05 6.6 0.45 6.8 0.95 7.8 1.45 8.3 1.95 9.7 2.45 10 2.95 7.6 3.45 7.6 3.95 7.6 4.45 7.6 4.95 7.6" -; filament_settings_id = "" -; filament_shrink = 100% -; filament_shrinkage_compensation_z = 100% -; filament_soluble = 0 -; filament_stamping_distance = 0 -; filament_stamping_loading_speed = 0 -; filament_start_gcode = " " -; filament_toolchange_delay = 0 -; filament_type = PLA -; filament_unloading_speed = 90 -; filament_unloading_speed_start = 100 -; filename_format = {input_filename_base}_{filament_type[initial_tool]}_{print_time}.gcode -; fill_multiline = 1 -; filter_out_gap_fill = 0 -; first_layer_print_sequence = 0 -; flush_into_infill = 0 -; flush_into_objects = 0 -; flush_into_support = 1 -; flush_multiplier = 0.3 -; flush_volumes_matrix = 0,280,280,280,280,0,280,280,280,280,0,280,280,280,280,0 -; flush_volumes_vector = 140,140,140,140,140,140,140,140 -; full_fan_speed_layer = 0 -; fuzzy_skin = none -; fuzzy_skin_first_layer = 0 -; fuzzy_skin_mode = displacement -; fuzzy_skin_noise_type = classic -; fuzzy_skin_octaves = 4 -; fuzzy_skin_persistence = 0.5 -; fuzzy_skin_point_distance = 0.3 -; fuzzy_skin_scale = 1 -; fuzzy_skin_thickness = 0.2 -; gap_fill_target = nowhere -; gap_infill_speed = 250 -; gcode_add_line_number = 0 -; gcode_comments = 0 -; gcode_flavor = klipper -; gcode_label_objects = 1 -; has_scarf_joint_seam = 0 -; head_wrap_detect_zone = -; high_current_on_filament_swap = 0 -; hole_to_polyhole = 0 -; hole_to_polyhole_threshold = 0.01 -; hole_to_polyhole_twisted = 1 -; hot_plate_temp = 45 -; hot_plate_temp_initial_layer = 45 -; idle_temperature = 0 -; independent_support_layer_height = 1 -; infill_anchor = 400% -; infill_anchor_max = 20 -; infill_combination = 0 -; infill_combination_max_layer_height = 100% -; infill_direction = 45 -; infill_jerk = 9 -; infill_lock_depth = 1 -; infill_overhang_angle = 60 -; infill_shift_step = 0.4 -; infill_wall_overlap = 15% -; inherits_group = ; -; initial_layer_acceleration = 300 -; initial_layer_infill_speed = 105 -; initial_layer_jerk = 9 -; initial_layer_line_width = 0 -; initial_layer_min_bead_width = 85% -; initial_layer_print_height = 0.2 -; initial_layer_speed = 50 -; initial_layer_travel_speed = 100% -; inner_wall_acceleration = 10000 -; inner_wall_jerk = 9 -; inner_wall_line_width = 0 -; inner_wall_speed = 300 -; interface_shells = 0 -; interlocking_beam = 0 -; interlocking_beam_layer_count = 2 -; interlocking_beam_width = 0.8 -; interlocking_boundary_avoidance = 2 -; interlocking_depth = 2 -; interlocking_orientation = 22.5 -; internal_bridge_angle = 0 -; internal_bridge_density = 100% -; internal_bridge_fan_speed = -1 -; internal_bridge_flow = 1 -; internal_bridge_speed = 150% -; internal_solid_infill_acceleration = 100% -; internal_solid_infill_line_width = 0 -; internal_solid_infill_pattern = monotonic -; internal_solid_infill_speed = 250 -; ironing_angle = -1 -; ironing_fan_speed = -1 -; ironing_flow = 10% -; ironing_inset = 0 -; ironing_pattern = rectilinear -; ironing_spacing = 0.1 -; ironing_speed = 20 -; ironing_type = no ironing -; is_infill_first = 0 -; lateral_lattice_angle_1 = -45 -; lateral_lattice_angle_2 = 45 -; layer_change_gcode = ;LAYER_CHANGE\nG92 E0 -; layer_height = 0.2 -; line_width = 0 -; long_retractions_when_cut = 0 -; machine_end_gcode = G28 X0 Y0 ;Home\nM104 S0 ;Turn-off hotend\nM140 S0 ;Turn-off bed\nM84 ;Disable steppers -; machine_load_filament_time = 0 -; machine_max_acceleration_e = 5000,5000 -; machine_max_acceleration_extruding = 10000,5000 -; machine_max_acceleration_retracting = 5000,5000 -; machine_max_acceleration_travel = 6000,6000 -; machine_max_acceleration_x = 6000,5000 -; machine_max_acceleration_y = 6000,5000 -; machine_max_acceleration_z = 500,200 -; machine_max_jerk_e = 2.5,2.5 -; machine_max_jerk_x = 12,12 -; machine_max_jerk_y = 12,12 -; machine_max_jerk_z = 0.4,0.4 -; machine_max_junction_deviation = 0,0 -; machine_max_speed_e = 60,30 -; machine_max_speed_x = 500,200 -; machine_max_speed_y = 500,200 -; machine_max_speed_z = 10,5 -; machine_min_extruding_rate = 0,0 -; machine_min_travel_rate = 0,0 -; machine_pause_gcode = -; machine_start_gcode = G28\nG1 Z10 F3000 -; machine_tool_change_time = 0 -; machine_unload_filament_time = 0 -; make_overhang_printable = 0 -; make_overhang_printable_angle = 55 -; make_overhang_printable_hole_size = 0 -; manual_filament_change = 0 -; max_bridge_length = 10 -; max_layer_height = 0 -; max_resonance_avoidance_speed = 120 -; max_travel_detour_distance = 0 -; max_volumetric_extrusion_rate_slope = 0 -; max_volumetric_extrusion_rate_slope_segment_length = 3 -; min_bead_width = 85% -; min_feature_size = 25% -; min_layer_height = 0.07 -; min_length_factor = 0.5 -; min_resonance_avoidance_speed = 70 -; min_skirt_length = 0 -; min_width_top_surface = 300% -; minimum_sparse_infill_area = 15 -; mmu_segmented_region_interlocking_depth = 0 -; mmu_segmented_region_max_width = 0 -; notes = -; nozzle_diameter = 0.4 -; nozzle_height = 2.5 -; nozzle_hrc = 0 -; nozzle_temperature = 200 -; nozzle_temperature_initial_layer = 200 -; nozzle_temperature_range_high = 240 -; nozzle_temperature_range_low = 190 -; nozzle_type = undefine -; nozzle_volume = 0 -; only_one_wall_first_layer = 0 -; only_one_wall_top = 0 -; ooze_prevention = 0 -; other_layers_print_sequence = 0 -; other_layers_print_sequence_nums = 0 -; outer_wall_acceleration = 500 -; outer_wall_jerk = 9 -; outer_wall_line_width = 0 -; outer_wall_speed = 200 -; overhang_1_4_speed = 0 -; overhang_2_4_speed = 0 -; overhang_3_4_speed = 0 -; overhang_4_4_speed = 0 -; overhang_fan_speed = 100 -; overhang_fan_threshold = 95% -; overhang_reverse = 0 -; overhang_reverse_internal_only = 0 -; overhang_reverse_threshold = 50% -; parking_pos_retraction = 92 -; post_process = -; precise_outer_wall = 1 -; precise_z_height = 0 -; preferred_orientation = 0 -; preheat_steps = 1 -; preheat_time = 30 -; pressure_advance = 0.02 -; prime_tower_brim_width = 3 -; prime_tower_width = 60 -; prime_volume = 45 -; print_compatible_printers = "Bambu Lab A1 0.4 nozzle";"Bambu Lab A1" -; print_flow_ratio = 1 -; print_order = default -; print_sequence = by layer -; print_settings_id = 0.20mm Standard @BBL A1 -; printable_area = 0x0,256x0,256x256,0x256 -; printable_height = 256 -; printer_model = Bambu Lab A1 -; printer_notes = -; printer_settings_id = Bambu Lab A1 0.4 nozzle -; printer_structure = undefine -; printer_technology = FFF -; printing_by_object_gcode = -; purge_in_prime_tower = 1 -; raft_contact_distance = 0.1 -; raft_expansion = 1.5 -; raft_first_layer_density = 90% -; raft_first_layer_expansion = 2 -; raft_layers = 0 -; reduce_crossing_wall = 1 -; reduce_fan_stop_start_freq = 0 -; reduce_infill_retraction = 0 -; required_nozzle_HRC = 0 -; resolution = 0.01 -; resonance_avoidance = 0 -; retract_before_wipe = 100% -; retract_length_toolchange = 10 -; retract_lift_above = 0 -; retract_lift_below = 0 -; retract_lift_enforce = All Surfaces -; retract_restart_extra = 0 -; retract_restart_extra_toolchange = 0 -; retract_when_changing_layer = 0 -; retraction_distances_when_cut = 18 -; retraction_length = 0.8 -; retraction_minimum_travel = 2 -; retraction_speed = 40 -; role_based_wipe_speed = 1 -; scan_first_layer = 0 -; scarf_angle_threshold = 155 -; scarf_joint_flow_ratio = 1 -; scarf_joint_speed = 100% -; scarf_overhang_threshold = 40% -; seam_gap = 10% -; seam_position = aligned -; seam_slope_conditional = 0 -; seam_slope_entire_loop = 0 -; seam_slope_inner_walls = 0 -; seam_slope_min_length = 20 -; seam_slope_start_height = 0 -; seam_slope_steps = 10 -; seam_slope_type = none -; silent_mode = 0 -; single_extruder_multi_material = 1 -; single_extruder_multi_material_priming = 0 -; single_loop_draft_shield = 0 -; skeleton_infill_density = 25% -; skeleton_infill_line_width = 100% -; skin_infill_density = 25% -; skin_infill_depth = 2 -; skin_infill_line_width = 100% -; skirt_distance = 2 -; skirt_height = 1 -; skirt_loops = 1 -; skirt_speed = 50 -; skirt_start_angle = -135 -; skirt_type = combined -; slice_closing_radius = 0.049 -; slicing_mode = regular -; slow_down_for_layer_cooling = 1 -; slow_down_layer_time = 5 -; slow_down_layers = 0 -; slow_down_min_speed = 10 -; slowdown_for_curled_perimeters = 1 -; small_area_infill_flow_compensation = 0 -; small_area_infill_flow_compensation_model = 0,0;"\n0.2,0.4444";"\n0.4,0.6145";"\n0.6,0.7059";"\n0.8,0.7619";"\n1.5,0.8571";"\n2,0.8889";"\n3,0.9231";"\n5,0.9520";"\n10,1" -; small_perimeter_speed = 50% -; small_perimeter_threshold = 0 -; solid_infill_direction = 45 -; solid_infill_filament = 1 -; solid_infill_rotate_template = -; sparse_infill_acceleration = 100% -; sparse_infill_density = 15% -; sparse_infill_filament = 1 -; sparse_infill_line_width = 0 -; sparse_infill_pattern = crosshatch -; sparse_infill_rotate_template = -; sparse_infill_speed = 270 -; spiral_finishing_flow_ratio = 0 -; spiral_mode = 0 -; spiral_mode_max_xy_smoothing = 200% -; spiral_mode_smooth = 0 -; spiral_starting_flow_ratio = 0 -; staggered_inner_seams = 0 -; standby_temperature_delta = -5 -; start_end_points = 30x-3,54x245 -; supertack_plate_temp = 35 -; supertack_plate_temp_initial_layer = 35 -; support_air_filtration = 1 -; support_angle = 0 -; support_base_pattern = default -; support_base_pattern_spacing = 2.5 -; support_bottom_interface_spacing = 0.5 -; support_bottom_z_distance = 0.2 -; support_chamber_temp_control = 1 -; support_critical_regions_only = 0 -; support_expansion = 0 -; support_filament = 0 -; support_interface_bottom_layers = 0 -; support_interface_filament = 0 -; support_interface_loop_pattern = 0 -; support_interface_not_for_body = 1 -; support_interface_pattern = auto -; support_interface_spacing = 0.5 -; support_interface_speed = 80 -; support_interface_top_layers = 3 -; support_ironing = 0 -; support_ironing_flow = 10% -; support_ironing_pattern = rectilinear -; support_ironing_spacing = 0.1 -; support_line_width = 0 -; support_material_interface_fan_speed = -1 -; support_multi_bed_types = 0 -; support_object_first_layer_gap = 0.2 -; support_object_xy_distance = 0.35 -; support_on_build_plate_only = 0 -; support_remove_small_overhang = 1 -; support_speed = 80 -; support_style = default -; support_threshold_angle = 30 -; support_threshold_overlap = 50% -; support_top_z_distance = 0.2 -; support_type = normal(auto) -; symmetric_infill_y_axis = 0 -; temperature_vitrification = 100 -; template_custom_gcode = -; textured_cool_plate_temp = 40 -; textured_cool_plate_temp_initial_layer = 40 -; textured_plate_temp = 45 -; textured_plate_temp_initial_layer = 45 -; thick_bridges = 0 -; thick_internal_bridges = 1 -; thumbnails = 48x48/PNG,300x300/PNG -; time_cost = 0 -; time_lapse_gcode = -; timelapse_type = 0 -; top_bottom_infill_wall_overlap = 25% -; top_shell_layers = 3 -; top_shell_thickness = 0.6 -; top_solid_infill_flow_ratio = 1 -; top_surface_acceleration = 500 -; top_surface_density = 100% -; top_surface_jerk = 9 -; top_surface_line_width = 0 -; top_surface_pattern = monotonicline -; top_surface_speed = 200 -; travel_acceleration = 10000 -; travel_jerk = 12 -; travel_slope = 3 -; travel_speed = 500 -; travel_speed_z = 0 -; tree_support_adaptive_layer_height = 1 -; tree_support_angle_slow = 25 -; tree_support_auto_brim = 1 -; tree_support_branch_angle = 40 -; tree_support_branch_angle_organic = 40 -; tree_support_branch_diameter = 5 -; tree_support_branch_diameter_angle = 5 -; tree_support_branch_diameter_organic = 2 -; tree_support_branch_distance = 5 -; tree_support_branch_distance_organic = 1 -; tree_support_brim_width = 3 -; tree_support_tip_diameter = 0.8 -; tree_support_top_rate = 30% -; tree_support_wall_count = 0 -; use_firmware_retraction = 0 -; use_relative_e_distances = 1 -; wall_direction = auto -; wall_distribution_count = 1 -; wall_filament = 1 -; wall_generator = arachne -; wall_loops = 2 -; wall_sequence = inner wall/outer wall -; wall_transition_angle = 10 -; wall_transition_filter_deviation = 25% -; wall_transition_length = 100% -; wipe = 0 -; wipe_before_external_loop = 0 -; wipe_distance = 1 -; wipe_on_loops = 0 -; wipe_speed = 80% -; wipe_tower_bridging = 10 -; wipe_tower_cone_angle = 30 -; wipe_tower_extra_flow = 100% -; wipe_tower_extra_rib_length = 0 -; wipe_tower_extra_spacing = 100% -; wipe_tower_filament = 0 -; wipe_tower_fillet_wall = 1 -; wipe_tower_max_purge_speed = 90 -; wipe_tower_no_sparse_layers = 0 -; wipe_tower_rib_width = 8 -; wipe_tower_rotation_angle = 0 -; wipe_tower_wall_type = rectangle -; wipe_tower_x = 15.000 -; wipe_tower_x = 15 -; wipe_tower_y = 220.000 -; wipe_tower_y = 220 -; wiping_volumes_extruders = 70,70,70,70,70,70,70,70,70,70 -; xy_contour_compensation = 0 -; xy_hole_compensation = 0 -; z_hop = 0.4 -; z_hop_types = Slope Lift -; z_offset = 0 -; first_layer_bed_temperature = 35 -; first_layer_temperature = 200 -; CONFIG_BLOCK_END - -; external perimeters extrusion width = 0.45mm -; perimeters extrusion width = 0.45mm -; infill extrusion width = 0.45mm -; solid infill extrusion width = 0.45mm -; top infill extrusion width = 0.40mm - -; EXECUTABLE_BLOCK_START -M73 P0 R5 -; FEATURE: Custom -G28 -G1 Z10 F3000 -M109 S200 ; set nozzle temperature and wait for it to be reached -G90 -G21 -M83 ; use relative distances for extrusion -M981 S1 P20000 ;open spaghetti detector -M106 S0 -; CHANGE_LAYER -; Z_HEIGHT: 0.2 -; LAYER_HEIGHT: 0.2 -;LAYER_CHANGE -G92 E0 -;_SET_FAN_SPEED_CHANGING_LAYER -SET_VELOCITY_LIMIT ACCEL=300 ACCEL_TO_DECEL=150 -G1 E-.8 F2400 -G1 X121.406 Y121.576 F30000 -G1 Z.6 -G1 Z.2 -M73 P1 R5 -G1 E.8 F2400 -; FEATURE: Skirt -; LINE_WIDTH: 0.45 -G1 F1473.913 -G1 X122.221 Y120.939 E.03504 -G1 X123 Y120.796 E.02679 -G1 X133 Y120.796 E.33849 -G1 X134.253 Y121.187 E.04443 -G1 X135.061 Y122.221 E.04443 -G1 X135.204 Y123 E.02679 -G1 X135.204 Y133 E.33849 -G1 X134.813 Y134.253 E.04443 -G1 X133.779 Y135.061 E.04443 -G1 X133 Y135.204 E.02679 -G1 X123 Y135.204 E.33849 -G1 X121.747 Y134.813 E.04443 -G1 X120.939 Y133.779 E.04443 -G1 X120.796 Y133 E.02679 -G1 X120.796 Y123 E.33849 -G1 X121.187 Y121.747 E.04443 -G1 X121.374 Y121.601 E.00804 -; printing object test_cube.stl id:0 copy 0 -G1 E-.8 F2400 -; start printing object, unique label id: 15 -M624 AQAAAAAAAAA= -G1 X126.827 Y126.941 Z.6 F30000 -G1 X132.346 Y132.346 Z.6 -G1 Z.2 -M73 P2 R5 -G1 E.8 F2400 -; FEATURE: Inner wall -; LINE_WIDTH: 0.449999 -G1 F1473.915 -G1 X123.654 Y132.346 E.29424 -G1 X123.654 Y123.654 E.29424 -G1 X132.346 Y123.654 E.29424 -G1 X132.346 Y132.306 E.29289 -G1 X132.389 Y132.306 F30000 -G1 X132.389 Y132.389 -G1 X132.775 Y132.775 -; FEATURE: Outer wall -G1 F1473.915 -G1 X123.225 Y132.775 E.32326 -G1 X123.225 Y123.225 E.32326 -G1 X132.775 Y123.225 E.32326 -G1 X132.775 Y132.735 E.3219 -G1 E-.8 F2400 -M73 P3 R5 -G1 X132.389 Y132.389 Z.6 F30000 -G1 X132.389 Y124.613 -G1 X132.224 Y124.613 -G1 Z.2 -G1 E.8 F2400 -; FEATURE: Bottom surface -; LINE_WIDTH: 0.456913 -G1 F1449.3 -G1 X131.57 Y123.959 E.03186 -G1 X130.984 Y123.959 E.02015 -G1 X132.041 Y125.016 E.05144 -G1 X132.041 Y125.601 E.02015 -G1 X130.399 Y123.959 E.07994 -G1 X129.814 Y123.959 E.02015 -G1 X132.041 Y126.186 E.10845 -G1 X132.041 Y126.772 E.02015 -G1 X129.228 Y123.959 E.13695 -G1 X128.643 Y123.959 E.02015 -G1 X132.041 Y127.357 E.16545 -G1 X132.041 Y127.943 E.02015 -G1 X128.057 Y123.959 E.19395 -G1 X127.472 Y123.959 E.02015 -G1 X132.041 Y128.528 E.22246 -G1 X132.041 Y129.114 E.02015 -G1 X126.886 Y123.959 E.25096 -G1 X126.301 Y123.959 E.02015 -G1 X132.041 Y129.699 E.27946 -G1 X132.041 Y130.285 E.02015 -G1 X125.715 Y123.959 E.30796 -G1 X125.13 Y123.959 E.02015 -M73 P4 R5 -G1 X132.041 Y130.87 E.33646 -G1 X132.041 Y131.456 E.02015 -G1 X124.544 Y123.959 E.36497 -G1 X123.959 Y123.959 E.02015 -G1 X132.041 Y132.041 E.39346 -G1 X131.456 Y132.041 E.02015 -G1 X123.959 Y124.544 E.36496 -G1 X123.959 Y125.13 E.02015 -G1 X130.87 Y132.041 E.33646 -G1 X130.285 Y132.041 E.02015 -G1 X123.959 Y125.715 E.30796 -G1 X123.959 Y126.301 E.02015 -G1 X129.699 Y132.041 E.27945 -G1 X129.114 Y132.041 E.02015 -M73 P5 R5 -G1 X123.959 Y126.886 E.25095 -G1 X123.959 Y127.472 E.02015 -G1 X128.528 Y132.041 E.22245 -G1 X127.943 Y132.041 E.02015 -G1 X123.959 Y128.057 E.19395 -G1 X123.959 Y128.643 E.02015 -G1 X127.357 Y132.041 E.16544 -G1 X126.772 Y132.041 E.02015 -G1 X123.959 Y129.228 E.13694 -G1 X123.959 Y129.814 E.02015 -G1 X126.186 Y132.041 E.10844 -G1 X125.601 Y132.041 E.02015 -G1 X123.959 Y130.399 E.07994 -G1 X123.959 Y130.985 E.02015 -G1 X125.015 Y132.041 E.05144 -G1 X124.43 Y132.041 E.02015 -G1 X123.776 Y131.387 E.03185 -; stop printing object test_cube.stl id:0 copy 0 -M106 S235 -; CHANGE_LAYER -; Z_HEIGHT: 0.4 -; LAYER_HEIGHT: 0.2 -; stop printing object, unique label id: 15 -M625 -;LAYER_CHANGE -G92 E0 -;_SET_FAN_SPEED_CHANGING_LAYER -; open powerlost recovery -M1003 S1 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -M140 S35 ; set bed temperature -; printing object test_cube.stl id:0 copy 0 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -; start printing object, unique label id: 15 -M624 AQAAAAAAAAA= -G1 X131.361 Y132.236 Z.8 F30000 -G1 X132.346 Y132.346 Z.8 -G1 Z.4 -G1 E.8 F2400 -; FEATURE: Inner wall -; LINE_WIDTH: 0.449999 -G1 F1473.915 -G1 X123.654 Y132.346 E.29424 -G1 X123.654 Y123.654 E.29424 -G1 X132.346 Y123.654 E.29424 -G1 X132.346 Y132.306 E.29289 -M73 P6 R5 -G1 X132.389 Y132.306 F30000 -G1 X132.389 Y132.389 -G1 X132.775 Y132.775 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Outer wall -G1 F1473.915 -G1 X123.225 Y132.775 E.32326 -G1 X123.225 Y123.225 E.32326 -G1 X132.775 Y123.225 E.32326 -G1 X132.775 Y132.735 E.3219 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -G1 X132.389 Y132.389 Z.8 F30000 -G1 X130.621 Y132.389 -G1 X130.621 Y131.939 -G1 Z.4 -G1 E.8 F2400 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Internal solid infill -G1 F1473.915 -G1 X131.939 Y131.939 E.04463 -G1 X131.939 Y130.621 E.04463 -G1 X130.649 Y131.911 E.06177 -M73 P6 R4 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -G1 X132.184 Y129.856 Z.8 F30000 -G1 Z.4 -G1 E.8 F2400 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; LINE_WIDTH: 0.453392 -G1 F1461.732 -G1 X130.039 Y132 E.10351 -G1 X129.459 Y132 E.01981 -G1 X132 Y129.459 E.12269 -G1 X132 Y128.878 E.01981 -G1 X128.878 Y132 E.15071 -G1 X128.298 Y132 E.01981 -M73 P7 R4 -G1 X132 Y128.298 E.17873 -G1 X132 Y127.717 E.01981 -G1 X127.717 Y132 E.20675 -G1 X127.137 Y132 E.01981 -G1 X132 Y127.137 E.23477 -G1 X132 Y126.556 E.01981 -G1 X126.556 Y132 E.26279 -G1 X125.976 Y132 E.01981 -G1 X132 Y125.976 E.29081 -G1 X132 Y125.395 E.01981 -G1 X125.395 Y132 E.31883 -G1 X124.815 Y132 E.01981 -G1 X132 Y124.815 E.34685 -G1 X132 Y124.234 E.01981 -G1 X124.234 Y132 E.37487 -G1 X124 Y132 E.00801 -G1 X124 Y131.655 E.01181 -G1 X131.655 Y124 E.36949 -G1 X131.074 Y124 E.01981 -M73 P8 R4 -G1 X124 Y131.074 E.34148 -G1 X124 Y130.494 E.01981 -G1 X130.494 Y124 E.31346 -G1 X129.913 Y124 E.01981 -G1 X124 Y129.913 E.28544 -G1 X124 Y129.333 E.01981 -G1 X129.333 Y124 E.25742 -G1 X128.752 Y124 E.01981 -G1 X124 Y128.752 E.2294 -G1 X124 Y128.172 E.01981 -G1 X128.172 Y124 E.20138 -G1 X127.591 Y124 E.01981 -G1 X124 Y127.591 E.17336 -G1 X124 Y127.011 E.01981 -G1 X127.011 Y124 E.14534 -G1 X126.43 Y124 E.01981 -G1 X124 Y126.43 E.11732 -G1 X124 Y125.85 E.01981 -G1 X125.85 Y124 E.0893 -G1 X125.269 Y124 E.01981 -M73 P9 R4 -G1 X124 Y125.269 E.06128 -G1 X124 Y124.689 E.01981 -G1 X124.872 Y123.816 E.0421 -; stop printing object test_cube.stl id:0 copy 0 -; CHANGE_LAYER -; Z_HEIGHT: 0.6 -; LAYER_HEIGHT: 0.2 -; stop printing object, unique label id: 15 -M625 -;LAYER_CHANGE -G92 E0 -;_SET_FAN_SPEED_CHANGING_LAYER -; printing object test_cube.stl id:0 copy 0 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -; start printing object, unique label id: 15 -M624 AQAAAAAAAAA= -G1 X129.902 Y129.557 Z1 F30000 -G1 X132.346 Y132.346 Z1 -G1 Z.6 -G1 E.8 F2400 -; FEATURE: Inner wall -; LINE_WIDTH: 0.449999 -G1 F1473.915 -G1 X123.654 Y132.346 E.29424 -G1 X123.654 Y123.654 E.29424 -G1 X132.346 Y123.654 E.29424 -G1 X132.346 Y132.306 E.29289 -G1 X132.389 Y132.306 F30000 -G1 X132.389 Y132.389 -G1 X132.775 Y132.775 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Outer wall -G1 F1473.915 -G1 X123.225 Y132.775 E.32326 -G1 X123.225 Y123.225 E.32326 -G1 X132.775 Y123.225 E.32326 -G1 X132.775 Y132.735 E.3219 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -M73 P10 R4 -G1 X132.389 Y132.389 Z1 F30000 -G1 X132.389 Y123.611 -G1 X130.621 Y123.611 -G1 X130.621 Y124.061 -G1 Z.6 -G1 E.8 F2400 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Internal solid infill -G1 F1473.915 -G1 X131.939 Y125.379 E.06312 -G1 X131.939 Y124.061 E.04463 -G1 X130.661 Y124.061 E.04328 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 X129.856 Y123.816 F30000 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; LINE_WIDTH: 0.453392 -G1 F1461.732 -G1 X132 Y125.961 E.10351 -G1 X132 Y126.541 E.01981 -G1 X129.459 Y124 E.12269 -G1 X128.878 Y124 E.01981 -G1 X132 Y127.122 E.15071 -G1 X132 Y127.702 E.01981 -G1 X128.298 Y124 E.17873 -G1 X127.717 Y124 E.01981 -G1 X132 Y128.283 E.20675 -G1 X132 Y128.863 E.01981 -G1 X127.137 Y124 E.23477 -G1 X126.556 Y124 E.01981 -G1 X132 Y129.444 E.26279 -G1 X132 Y130.024 E.01981 -G1 X125.976 Y124 E.29081 -G1 X125.395 Y124 E.01981 -G1 X132 Y130.605 E.31883 -G1 X132 Y131.185 E.01981 -M73 P11 R4 -G1 X124.815 Y124 E.34685 -G1 X124.234 Y124 E.01981 -G1 X132 Y131.766 E.37487 -G1 X132 Y132 E.00801 -G1 X131.655 Y132 E.01181 -G1 X124 Y124.345 E.36949 -G1 X124 Y124.926 E.01981 -G1 X131.074 Y132 E.34148 -G1 X130.494 Y132 E.01981 -G1 X124 Y125.506 E.31346 -G1 X124 Y126.087 E.01981 -G1 X129.913 Y132 E.28544 -G1 X129.333 Y132 E.01981 -G1 X124 Y126.667 E.25742 -G1 X124 Y127.248 E.01981 -M73 P12 R4 -G1 X128.752 Y132 E.2294 -G1 X128.172 Y132 E.01981 -G1 X124 Y127.828 E.20138 -G1 X124 Y128.409 E.01981 -G1 X127.591 Y132 E.17336 -G1 X127.011 Y132 E.01981 -G1 X124 Y128.989 E.14534 -G1 X124 Y129.57 E.01981 -G1 X126.43 Y132 E.11732 -G1 X125.85 Y132 E.01981 -G1 X124 Y130.15 E.0893 -G1 X124 Y130.731 E.01981 -G1 X125.269 Y132 E.06128 -G1 X124.689 Y132 E.01981 -G1 X123.816 Y131.128 E.0421 -; stop printing object test_cube.stl id:0 copy 0 -M106 S252 -; CHANGE_LAYER -; Z_HEIGHT: 0.8 -; LAYER_HEIGHT: 0.2 -; stop printing object, unique label id: 15 -M625 -;LAYER_CHANGE -G92 E0 -;_SET_FAN_SPEED_CHANGING_LAYER -; printing object test_cube.stl id:0 copy 0 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -; start printing object, unique label id: 15 -M624 AQAAAAAAAAA= -G1 X131.372 Y132.207 Z1.2 F30000 -G1 X132.346 Y132.346 Z1.2 -G1 Z.8 -G1 E.8 F2400 -; FEATURE: Inner wall -; LINE_WIDTH: 0.449999 -G1 F1316 -G1 X123.654 Y132.346 E.29424 -G1 X123.654 Y123.654 E.29424 -G1 X132.346 Y123.654 E.29424 -G1 X132.346 Y132.306 E.29289 -G1 X132.389 Y132.306 F30000 -M73 P13 R4 -G1 X132.389 Y132.389 -G1 X132.775 Y132.775 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Outer wall -G1 F1316 -G1 X123.225 Y132.775 E.32326 -G1 X123.225 Y123.225 E.32326 -G1 X132.775 Y123.225 E.32326 -G1 X132.775 Y132.735 E.3219 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -G1 X132.389 Y132.389 Z1.2 F30000 -G1 X132.389 Y126.227 -G1 X132 Y126.227 -G1 Z.8 -G1 E.8 F2400 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Sparse infill -; LINE_WIDTH: 0.45 -G1 F1316 -G1 X132 Y127.855 E.05512 -G1 X128.145 Y124 E.18458 -G1 X124 Y124 E.1403 -G1 X132 Y132 E.383 -G1 X127.855 Y132 E.1403 -M73 P14 R4 -G1 X124 Y128.145 E.18458 -G1 X124 Y129.773 E.05512 -; stop printing object test_cube.stl id:0 copy 0 -; CHANGE_LAYER -; Z_HEIGHT: 1 -; LAYER_HEIGHT: 0.2 -; stop printing object, unique label id: 15 -M625 -;LAYER_CHANGE -G92 E0 -;_SET_FAN_SPEED_CHANGING_LAYER -; printing object test_cube.stl id:0 copy 0 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -; start printing object, unique label id: 15 -M624 AQAAAAAAAAA= -G1 X131.293 Y132.022 Z1.4 F30000 -G1 X132.346 Y132.346 Z1.4 -G1 Z1 -G1 E.8 F2400 -; FEATURE: Inner wall -; LINE_WIDTH: 0.449999 -G1 F1316 -G1 X123.654 Y132.346 E.29424 -G1 X123.654 Y123.654 E.29424 -G1 X132.346 Y123.654 E.29424 -G1 X132.346 Y132.306 E.29289 -G1 X132.389 Y132.306 F30000 -G1 X132.389 Y132.389 -G1 X132.775 Y132.775 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Outer wall -G1 F1316 -G1 X123.225 Y132.775 E.32326 -G1 X123.225 Y123.225 E.32326 -G1 X132.775 Y123.225 E.32326 -M73 P15 R4 -G1 X132.775 Y132.735 E.3219 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -G1 X132.389 Y132.389 Z1.4 F30000 -G1 X132.389 Y126.227 -G1 X132 Y126.227 -G1 Z1 -G1 E.8 F2400 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Sparse infill -; LINE_WIDTH: 0.45 -G1 F1316 -G1 X132 Y127.855 E.05512 -G1 X128.145 Y124 E.18458 -G1 X124 Y124 E.1403 -G1 X132 Y132 E.383 -G1 X127.855 Y132 E.1403 -G1 X124 Y128.145 E.18458 -G1 X124 Y129.773 E.05512 -; stop printing object test_cube.stl id:0 copy 0 -; CHANGE_LAYER -; Z_HEIGHT: 1.2 -; LAYER_HEIGHT: 0.2 -; stop printing object, unique label id: 15 -M625 -;LAYER_CHANGE -G92 E0 -;_SET_FAN_SPEED_CHANGING_LAYER -; printing object test_cube.stl id:0 copy 0 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -; start printing object, unique label id: 15 -M624 AQAAAAAAAAA= -G1 X131.293 Y132.022 Z1.6 F30000 -G1 X132.346 Y132.346 Z1.6 -G1 Z1.2 -G1 E.8 F2400 -; FEATURE: Inner wall -; LINE_WIDTH: 0.449999 -G1 F1316 -M73 P16 R4 -G1 X123.654 Y132.346 E.29424 -G1 X123.654 Y123.654 E.29424 -G1 X132.346 Y123.654 E.29424 -G1 X132.346 Y132.306 E.29289 -G1 X132.389 Y132.306 F30000 -G1 X132.389 Y132.389 -G1 X132.775 Y132.775 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Outer wall -G1 F1316 -G1 X123.225 Y132.775 E.32326 -G1 X123.225 Y123.225 E.32326 -G1 X132.775 Y123.225 E.32326 -G1 X132.775 Y132.735 E.3219 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -M73 P17 R4 -G1 X132.389 Y132.389 Z1.6 F30000 -G1 X132.389 Y126.227 -G1 X132 Y126.227 -G1 Z1.2 -G1 E.8 F2400 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Sparse infill -; LINE_WIDTH: 0.45 -G1 F1316 -G1 X132 Y127.855 E.05512 -G1 X128.145 Y124 E.18458 -G1 X124 Y124 E.1403 -G1 X132 Y132 E.383 -G1 X127.855 Y132 E.1403 -G1 X124 Y128.145 E.18458 -G1 X124 Y129.773 E.05512 -; stop printing object test_cube.stl id:0 copy 0 -; CHANGE_LAYER -; Z_HEIGHT: 1.4 -; LAYER_HEIGHT: 0.2 -; stop printing object, unique label id: 15 -M625 -;LAYER_CHANGE -G92 E0 -;_SET_FAN_SPEED_CHANGING_LAYER -; printing object test_cube.stl id:0 copy 0 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -; start printing object, unique label id: 15 -M624 AQAAAAAAAAA= -G1 X131.293 Y132.022 Z1.8 F30000 -G1 X132.346 Y132.346 Z1.8 -G1 Z1.4 -G1 E.8 F2400 -; FEATURE: Inner wall -; LINE_WIDTH: 0.449999 -G1 F1316 -G1 X123.654 Y132.346 E.29424 -G1 X123.654 Y123.654 E.29424 -G1 X132.346 Y123.654 E.29424 -G1 X132.346 Y132.306 E.29289 -M73 P18 R4 -G1 X132.389 Y132.306 F30000 -G1 X132.389 Y132.389 -G1 X132.775 Y132.775 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Outer wall -G1 F1316 -G1 X123.225 Y132.775 E.32326 -G1 X123.225 Y123.225 E.32326 -G1 X132.775 Y123.225 E.32326 -G1 X132.775 Y132.735 E.3219 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -G1 X132.389 Y132.389 Z1.8 F30000 -G1 X132.389 Y126.227 -G1 X132 Y126.227 -G1 Z1.4 -G1 E.8 F2400 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Sparse infill -; LINE_WIDTH: 0.45 -G1 F1316 -G1 X132 Y127.855 E.05512 -G1 X128.145 Y124 E.18458 -G1 X124 Y124 E.1403 -G1 X132 Y132 E.383 -M73 P19 R4 -G1 X127.855 Y132 E.1403 -G1 X124 Y128.145 E.18458 -G1 X124 Y129.773 E.05512 -; stop printing object test_cube.stl id:0 copy 0 -; CHANGE_LAYER -; Z_HEIGHT: 1.6 -; LAYER_HEIGHT: 0.2 -; stop printing object, unique label id: 15 -M625 -;LAYER_CHANGE -G92 E0 -;_SET_FAN_SPEED_CHANGING_LAYER -; printing object test_cube.stl id:0 copy 0 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -; start printing object, unique label id: 15 -M624 AQAAAAAAAAA= -G1 X131.293 Y132.022 Z2 F30000 -G1 X132.346 Y132.346 Z2 -G1 Z1.6 -G1 E.8 F2400 -; FEATURE: Inner wall -; LINE_WIDTH: 0.449999 -G1 F1316 -G1 X123.654 Y132.346 E.29424 -G1 X123.654 Y123.654 E.29424 -G1 X132.346 Y123.654 E.29424 -G1 X132.346 Y132.306 E.29289 -G1 X132.389 Y132.306 F30000 -G1 X132.389 Y132.389 -G1 X132.775 Y132.775 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Outer wall -G1 F1316 -G1 X123.225 Y132.775 E.32326 -G1 X123.225 Y123.225 E.32326 -M73 P20 R4 -G1 X132.775 Y123.225 E.32326 -G1 X132.775 Y132.735 E.3219 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -G1 X132.389 Y132.389 Z2 F30000 -G1 X132.389 Y126.227 -G1 X132 Y126.227 -G1 Z1.6 -G1 E.8 F2400 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Sparse infill -; LINE_WIDTH: 0.45 -G1 F1316 -G1 X132 Y127.855 E.05512 -G1 X128.145 Y124 E.18458 -G1 X124 Y124 E.1403 -G1 X132 Y132 E.383 -G1 X127.855 Y132 E.1403 -G1 X124 Y128.145 E.18458 -G1 X124 Y129.773 E.05512 -M73 P21 R4 -; stop printing object test_cube.stl id:0 copy 0 -; CHANGE_LAYER -; Z_HEIGHT: 1.8 -; LAYER_HEIGHT: 0.2 -; stop printing object, unique label id: 15 -M625 -;LAYER_CHANGE -G92 E0 -;_SET_FAN_SPEED_CHANGING_LAYER -; printing object test_cube.stl id:0 copy 0 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -; start printing object, unique label id: 15 -M624 AQAAAAAAAAA= -G1 X131.293 Y132.022 Z2.2 F30000 -G1 X132.346 Y132.346 Z2.2 -G1 Z1.8 -G1 E.8 F2400 -; FEATURE: Inner wall -; LINE_WIDTH: 0.449999 -G1 F1316 -G1 X123.654 Y132.346 E.29424 -G1 X123.654 Y123.654 E.29424 -G1 X132.346 Y123.654 E.29424 -G1 X132.346 Y132.306 E.29289 -G1 X132.389 Y132.306 F30000 -G1 X132.389 Y132.389 -G1 X132.775 Y132.775 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Outer wall -G1 F1316 -G1 X123.225 Y132.775 E.32326 -G1 X123.225 Y123.225 E.32326 -G1 X132.775 Y123.225 E.32326 -G1 X132.775 Y132.735 E.3219 -M73 P22 R4 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -G1 X132.389 Y132.389 Z2.2 F30000 -G1 X132.389 Y126.227 -G1 X132 Y126.227 -G1 Z1.8 -G1 E.8 F2400 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Sparse infill -; LINE_WIDTH: 0.45 -G1 F1316 -G1 X132 Y127.855 E.05512 -G1 X128.145 Y124 E.18458 -G1 X124 Y124 E.1403 -G1 X132 Y132 E.383 -G1 X127.855 Y132 E.1403 -G1 X124 Y128.145 E.18458 -G1 X124 Y129.773 E.05512 -; stop printing object test_cube.stl id:0 copy 0 -; CHANGE_LAYER -; Z_HEIGHT: 2 -; LAYER_HEIGHT: 0.2 -; stop printing object, unique label id: 15 -M625 -;LAYER_CHANGE -G92 E0 -;_SET_FAN_SPEED_CHANGING_LAYER -; printing object test_cube.stl id:0 copy 0 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -; start printing object, unique label id: 15 -M624 AQAAAAAAAAA= -G1 X131.293 Y132.022 Z2.4 F30000 -G1 X132.346 Y132.346 Z2.4 -G1 Z2 -G1 E.8 F2400 -; FEATURE: Inner wall -; LINE_WIDTH: 0.449999 -G1 F1316 -G1 X123.654 Y132.346 E.29424 -G1 X123.654 Y123.654 E.29424 -G1 X132.346 Y123.654 E.29424 -M73 P23 R4 -G1 X132.346 Y132.306 E.29289 -G1 X132.389 Y132.306 F30000 -G1 X132.389 Y132.389 -G1 X132.775 Y132.775 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Outer wall -G1 F1316 -G1 X123.225 Y132.775 E.32326 -G1 X123.225 Y123.225 E.32326 -G1 X132.775 Y123.225 E.32326 -G1 X132.775 Y132.735 E.3219 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -G1 X132.389 Y132.389 Z2.4 F30000 -G1 X132.389 Y126.227 -G1 X132 Y126.227 -G1 Z2 -G1 E.8 F2400 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Sparse infill -; LINE_WIDTH: 0.45 -G1 F1316 -G1 X132 Y127.855 E.05512 -G1 X128.145 Y124 E.18458 -G1 X124 Y124 E.1403 -M73 P24 R4 -G1 X132 Y132 E.383 -G1 X127.855 Y132 E.1403 -G1 X124 Y128.145 E.18458 -G1 X124 Y129.773 E.05512 -; stop printing object test_cube.stl id:0 copy 0 -; CHANGE_LAYER -; Z_HEIGHT: 2.2 -; LAYER_HEIGHT: 0.2 -; stop printing object, unique label id: 15 -M625 -;LAYER_CHANGE -G92 E0 -;_SET_FAN_SPEED_CHANGING_LAYER -; printing object test_cube.stl id:0 copy 0 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -; start printing object, unique label id: 15 -M624 AQAAAAAAAAA= -G1 X131.293 Y132.022 Z2.6 F30000 -G1 X132.346 Y132.346 Z2.6 -G1 Z2.2 -G1 E.8 F2400 -; FEATURE: Inner wall -; LINE_WIDTH: 0.449999 -G1 F1316 -G1 X123.654 Y132.346 E.29424 -G1 X123.654 Y123.654 E.29424 -G1 X132.346 Y123.654 E.29424 -G1 X132.346 Y132.306 E.29289 -G1 X132.389 Y132.306 F30000 -G1 X132.389 Y132.389 -G1 X132.775 Y132.775 -M73 P25 R4 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Outer wall -G1 F1316 -G1 X123.225 Y132.775 E.32326 -G1 X123.225 Y123.225 E.32326 -G1 X132.775 Y123.225 E.32326 -G1 X132.775 Y132.735 E.3219 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -M73 P25 R3 -G1 X132.389 Y132.389 Z2.6 F30000 -G1 X132.389 Y126.227 -G1 X132 Y126.227 -G1 Z2.2 -G1 E.8 F2400 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Sparse infill -; LINE_WIDTH: 0.45 -G1 F1316 -G1 X132 Y127.855 E.05512 -G1 X128.145 Y124 E.18458 -G1 X124 Y124 E.1403 -G1 X132 Y132 E.383 -G1 X127.855 Y132 E.1403 -G1 X124 Y128.145 E.18458 -M73 P26 R3 -G1 X124 Y129.773 E.05512 -; stop printing object test_cube.stl id:0 copy 0 -; CHANGE_LAYER -; Z_HEIGHT: 2.4 -; LAYER_HEIGHT: 0.2 -; stop printing object, unique label id: 15 -M625 -;LAYER_CHANGE -G92 E0 -;_SET_FAN_SPEED_CHANGING_LAYER -; printing object test_cube.stl id:0 copy 0 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -; start printing object, unique label id: 15 -M624 AQAAAAAAAAA= -G1 X131.293 Y132.022 Z2.8 F30000 -G1 X132.346 Y132.346 Z2.8 -G1 Z2.4 -G1 E.8 F2400 -; FEATURE: Inner wall -; LINE_WIDTH: 0.449999 -G1 F1319 -G1 X123.654 Y132.346 E.29424 -G1 X123.654 Y123.654 E.29424 -G1 X132.346 Y123.654 E.29424 -G1 X132.346 Y132.306 E.29289 -G1 X132.389 Y132.306 F30000 -G1 X132.389 Y132.389 -G1 X132.775 Y132.775 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Outer wall -G1 F1319 -G1 X123.225 Y132.775 E.32326 -G1 X123.225 Y123.225 E.32326 -G1 X132.775 Y123.225 E.32326 -G1 X132.775 Y132.735 E.3219 -M73 P27 R3 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -G1 X132.389 Y132.389 Z2.8 F30000 -G1 X126.276 Y132.389 -G1 X126.276 Y132 -G1 Z2.4 -G1 E.8 F2400 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Sparse infill -; LINE_WIDTH: 0.45 -G1 F1319 -G1 X127.904 Y132 E.05512 -G2 X126.964 Y130.76 I-3.532 J1.7 E.05305 -G1 X124.891 Y129.385 E.08417 -G3 X124 Y128.218 I2.435 J-2.784 E.05006 -G1 X124 Y124.073 E.1403 -G2 X124.891 Y125.24 I3.327 J-1.617 E.05006 -G1 X126.964 Y126.615 E.08417 -G1 X127.313 Y126.964 E.01671 -G1 X128.687 Y129.036 E.08417 -G1 X129.036 Y129.385 E.01671 -G1 X131.109 Y130.76 E.08417 -G3 X132 Y131.927 I-2.435 J2.784 E.05006 -G1 X132 Y127.782 E.1403 -G2 X131.109 Y126.615 I-3.327 J1.617 E.05006 -G1 X129.036 Y125.24 E.08417 -G3 X128.096 Y124 I2.592 J-2.941 E.05305 -G1 X129.724 Y124 E.05512 -; stop printing object test_cube.stl id:0 copy 0 -; CHANGE_LAYER -; Z_HEIGHT: 2.6 -; LAYER_HEIGHT: 0.2 -; stop printing object, unique label id: 15 -M625 -;LAYER_CHANGE -G92 E0 -;_SET_FAN_SPEED_CHANGING_LAYER -; printing object test_cube.stl id:0 copy 0 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -; start printing object, unique label id: 15 -M624 AQAAAAAAAAA= -G1 X132.012 Y131.281 Z3 F30000 -G1 X132.346 Y132.346 Z3 -G1 Z2.6 -G1 E.8 F2400 -; FEATURE: Inner wall -; LINE_WIDTH: 0.449999 -G1 F1331 -G1 X123.654 Y132.346 E.29424 -G1 X123.654 Y123.654 E.29424 -M73 P28 R3 -G1 X132.346 Y123.654 E.29424 -G1 X132.346 Y132.306 E.29289 -G1 X132.389 Y132.306 F30000 -G1 X132.389 Y132.389 -G1 X132.775 Y132.775 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Outer wall -G1 F1331 -G1 X123.225 Y132.775 E.32326 -G1 X123.225 Y123.225 E.32326 -G1 X132.775 Y123.225 E.32326 -G1 X132.775 Y132.735 E.3219 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -G1 X132.389 Y132.389 Z3 F30000 -G1 X132.389 Y129.179 -G1 X132 Y129.179 -G1 Z2.6 -G1 E.8 F2400 -M73 P29 R3 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Sparse infill -; LINE_WIDTH: 0.45 -G1 F1331 -G1 X132 Y127.551 E.05512 -G1 X131.811 Y126.964 E.02088 -G1 X131.109 Y126.261 E.03364 -G1 X129.036 Y125.594 E.0737 -G1 X128.334 Y124.891 E.03364 -G1 X128.047 Y124 E.03171 -G1 X124 Y124 E.13699 -G2 X124.189 Y124.891 I1.48 J.152 E.03136 -G1 X124.891 Y125.594 E.03364 -G1 X126.964 Y126.261 E.0737 -G1 X127.666 Y126.964 E.03364 -G1 X128.334 Y129.036 E.0737 -G1 X129.036 Y129.739 E.03364 -G1 X131.109 Y130.406 E.0737 -G1 X131.811 Y131.109 E.03364 -G3 X132 Y132 I-1.291 J.739 E.03136 -G1 X127.953 Y132 E.13699 -G1 X127.666 Y131.109 E.03171 -G1 X126.964 Y130.406 E.03364 -G1 X124.891 Y129.739 E.0737 -G1 X124.189 Y129.036 E.03364 -G1 X124 Y128.449 E.02088 -G1 X124 Y126.821 E.05512 -; stop printing object test_cube.stl id:0 copy 0 -; CHANGE_LAYER -; Z_HEIGHT: 2.8 -; LAYER_HEIGHT: 0.2 -; stop printing object, unique label id: 15 -M625 -;LAYER_CHANGE -G92 E0 -;_SET_FAN_SPEED_CHANGING_LAYER -; printing object test_cube.stl id:0 copy 0 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -; start printing object, unique label id: 15 -M624 AQAAAAAAAAA= -G1 X130.364 Y131.034 Z3.2 F30000 -G1 X132.346 Y132.346 Z3.2 -G1 Z2.8 -G1 E.8 F2400 -; FEATURE: Inner wall -; LINE_WIDTH: 0.449999 -G1 F1328 -G1 X123.654 Y132.346 E.29424 -G1 X123.654 Y123.654 E.29424 -G1 X132.346 Y123.654 E.29424 -G1 X132.346 Y132.306 E.29289 -G1 X132.389 Y132.306 F30000 -M73 P30 R3 -G1 X132.389 Y132.389 -G1 X132.775 Y132.775 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Outer wall -G1 F1328 -G1 X123.225 Y132.775 E.32326 -G1 X123.225 Y123.225 E.32326 -G1 X132.775 Y123.225 E.32326 -G1 X132.775 Y132.735 E.3219 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -G1 X132.389 Y132.389 Z3.2 F30000 -G1 X126.374 Y132.389 -G1 X126.374 Y132 -G1 Z2.8 -G1 E.8 F2400 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Sparse infill -; LINE_WIDTH: 0.45 -G1 F1328 -G1 X128.003 Y132 E.05512 -G1 X128.02 Y131.109 E.03019 -G1 X126.964 Y130.052 E.05056 -G1 X124.891 Y130.093 E.07017 -G1 X124 Y129.201 E.04268 -G1 X124 Y125.056 E.1403 -G1 X124.891 Y125.948 E.04268 -G1 X126.964 Y125.907 E.07017 -G1 X128.02 Y126.964 E.05056 -G1 X127.98 Y129.036 E.07017 -G1 X129.036 Y130.093 E.05056 -G1 X131.109 Y130.052 E.07017 -M73 P31 R3 -G1 X132 Y130.944 E.04268 -G1 X132 Y126.799 E.1403 -G1 X131.109 Y125.907 E.04268 -G1 X129.036 Y125.948 E.07017 -G1 X127.98 Y124.891 E.05056 -G1 X127.997 Y124 E.03019 -G1 X129.626 Y124 E.05512 -; stop printing object test_cube.stl id:0 copy 0 -; CHANGE_LAYER -; Z_HEIGHT: 3 -; LAYER_HEIGHT: 0.2 -; stop printing object, unique label id: 15 -M625 -;LAYER_CHANGE -G92 E0 -;_SET_FAN_SPEED_CHANGING_LAYER -; printing object test_cube.stl id:0 copy 0 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -; start printing object, unique label id: 15 -M624 AQAAAAAAAAA= -G1 X131.991 Y131.256 Z3.4 F30000 -G1 X132.346 Y132.346 Z3.4 -G1 Z3 -G1 E.8 F2400 -; FEATURE: Inner wall -; LINE_WIDTH: 0.449999 -G1 F1327 -G1 X123.654 Y132.346 E.29424 -G1 X123.654 Y123.654 E.29424 -G1 X132.346 Y123.654 E.29424 -G1 X132.346 Y132.306 E.29289 -G1 X132.389 Y132.306 F30000 -G1 X132.389 Y132.389 -G1 X132.775 Y132.775 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Outer wall -G1 F1327 -G1 X123.225 Y132.775 E.32326 -G1 X123.225 Y123.225 E.32326 -G1 X132.775 Y123.225 E.32326 -M73 P32 R3 -G1 X132.775 Y132.735 E.3219 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -G1 X132.389 Y132.389 Z3.4 F30000 -G1 X129.623 Y132.389 -G1 X129.623 Y132 -G1 Z3 -G1 E.8 F2400 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Sparse infill -; LINE_WIDTH: 0.45 -G1 F1327 -G1 X127.994 Y132 E.05512 -G1 X127.959 Y131.109 E.03021 -G1 X129.036 Y130.032 E.05156 -G1 X131.109 Y130.113 E.07021 -G1 X132 Y129.222 E.04268 -G1 X132 Y125.077 E.1403 -G1 X131.109 Y125.968 E.04268 -G1 X129.036 Y125.887 E.07021 -G1 X127.959 Y126.964 E.05156 -G1 X128.041 Y129.036 E.07021 -G1 X126.964 Y130.113 E.05156 -G1 X124.891 Y130.032 E.07021 -G1 X124 Y130.923 E.04268 -G1 X124 Y126.778 E.1403 -G1 X124.891 Y125.887 E.04268 -G1 X126.964 Y125.968 E.07021 -G1 X128.041 Y124.891 E.05156 -G1 X128.006 Y124 E.03021 -G1 X126.377 Y124 E.05512 -; stop printing object test_cube.stl id:0 copy 0 -; CHANGE_LAYER -; Z_HEIGHT: 3.2 -; LAYER_HEIGHT: 0.2 -; stop printing object, unique label id: 15 -M625 -;LAYER_CHANGE -G92 E0 -;_SET_FAN_SPEED_CHANGING_LAYER -; printing object test_cube.stl id:0 copy 0 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -; start printing object, unique label id: 15 -M624 AQAAAAAAAAA= -G1 X130.817 Y130.208 Z3.6 F30000 -G1 X132.346 Y132.346 Z3.6 -G1 Z3.2 -G1 E.8 F2400 -M73 P33 R3 -; FEATURE: Inner wall -; LINE_WIDTH: 0.449999 -G1 F1333 -G1 X123.654 Y132.346 E.29424 -G1 X123.654 Y123.654 E.29424 -G1 X132.346 Y123.654 E.29424 -G1 X132.346 Y132.306 E.29289 -G1 X132.389 Y132.306 F30000 -G1 X132.389 Y132.389 -G1 X132.775 Y132.775 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Outer wall -G1 F1333 -G1 X123.225 Y132.775 E.32326 -G1 X123.225 Y123.225 E.32326 -G1 X132.775 Y123.225 E.32326 -G1 X132.775 Y132.735 E.3219 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -M73 P34 R3 -G1 X132.389 Y132.389 Z3.6 F30000 -G1 X132.389 Y126.851 -G1 X132 Y126.851 -G1 Z3.2 -G1 E.8 F2400 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Sparse infill -; LINE_WIDTH: 0.45 -G1 F1333 -G1 X132 Y128.479 E.05512 -G1 X131.832 Y129.036 E.01969 -G1 X131.109 Y129.76 E.03464 -G1 X129.036 Y130.385 E.07327 -G1 X128.313 Y131.109 E.03464 -G1 X128.044 Y132 E.03153 -G1 X124 Y132 E.13689 -G3 X124.168 Y131.109 I1.562 J-.167 E.03116 -G1 X124.891 Y130.385 E.03464 -G1 X126.964 Y129.76 E.07327 -G1 X127.687 Y129.036 E.03464 -G1 X128.313 Y126.964 E.07327 -G1 X129.036 Y126.24 E.03464 -G1 X131.109 Y125.615 E.07327 -G1 X131.832 Y124.891 E.03464 -G2 X132 Y124 I-1.394 J-.724 E.03116 -G1 X127.956 Y124 E.13689 -G1 X127.687 Y124.891 E.03153 -G1 X126.964 Y125.615 E.03464 -G1 X124.891 Y126.24 E.07327 -G1 X124.168 Y126.964 E.03464 -G1 X124 Y127.521 E.01969 -G1 X124 Y129.149 E.05512 -; stop printing object test_cube.stl id:0 copy 0 -; CHANGE_LAYER -; Z_HEIGHT: 3.4 -; LAYER_HEIGHT: 0.2 -; stop printing object, unique label id: 15 -M625 -;LAYER_CHANGE -G92 E0 -;_SET_FAN_SPEED_CHANGING_LAYER -; printing object test_cube.stl id:0 copy 0 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -; start printing object, unique label id: 15 -M624 AQAAAAAAAAA= -G1 X131.127 Y131.879 Z3.8 F30000 -G1 X132.346 Y132.346 Z3.8 -G1 Z3.4 -G1 E.8 F2400 -; FEATURE: Inner wall -; LINE_WIDTH: 0.449999 -G1 F1318 -G1 X123.654 Y132.346 E.29424 -G1 X123.654 Y123.654 E.29424 -G1 X132.346 Y123.654 E.29424 -G1 X132.346 Y132.306 E.29289 -M73 P35 R3 -G1 X132.389 Y132.306 F30000 -G1 X132.389 Y132.389 -G1 X132.775 Y132.775 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Outer wall -G1 F1318 -G1 X123.225 Y132.775 E.32326 -G1 X123.225 Y123.225 E.32326 -G1 X132.775 Y123.225 E.32326 -G1 X132.775 Y132.735 E.3219 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -G1 X132.389 Y132.389 Z3.8 F30000 -G1 X129.721 Y132.389 -G1 X129.721 Y132 -G1 Z3.4 -G1 E.8 F2400 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Sparse infill -; LINE_WIDTH: 0.45 -G1 F1318 -G1 X128.093 Y132 E.05512 -G3 X129.036 Y130.739 I3.374 J1.539 E.05373 -G1 X131.109 Y129.406 E.0834 -G2 X132 Y128.225 I-2.272 J-2.642 E.05049 -G1 X132 Y124.08 E.1403 -G3 X131.109 Y125.261 I-3.163 J-1.46 E.05049 -M73 P36 R3 -G1 X129.036 Y126.594 E.0834 -G1 X128.666 Y126.964 E.01772 -G1 X127.334 Y129.036 E.0834 -G1 X126.964 Y129.406 E.01772 -G1 X124.891 Y130.739 E.0834 -G2 X124 Y131.92 I2.272 J2.642 E.05049 -G1 X124 Y127.775 E.1403 -G3 X124.891 Y126.594 I3.163 J1.46 E.05049 -G1 X126.964 Y125.261 E.0834 -G2 X127.907 Y124 I-2.431 J-2.801 E.05373 -G1 X126.279 Y124 E.05512 -; stop printing object test_cube.stl id:0 copy 0 -; CHANGE_LAYER -; Z_HEIGHT: 3.6 -; LAYER_HEIGHT: 0.2 -; stop printing object, unique label id: 15 -M625 -;LAYER_CHANGE -G92 E0 -;_SET_FAN_SPEED_CHANGING_LAYER -; printing object test_cube.stl id:0 copy 0 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -; start printing object, unique label id: 15 -M624 AQAAAAAAAAA= -G1 X130.767 Y130.173 Z4 F30000 -G1 X132.346 Y132.346 Z4 -G1 Z3.6 -G1 E.8 F2400 -; FEATURE: Inner wall -; LINE_WIDTH: 0.449999 -G1 F1314 -G1 X123.654 Y132.346 E.29424 -G1 X123.654 Y123.654 E.29424 -G1 X132.346 Y123.654 E.29424 -G1 X132.346 Y132.306 E.29289 -G1 X132.389 Y132.306 F30000 -G1 X132.389 Y132.389 -G1 X132.775 Y132.775 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Outer wall -G1 F1314 -G1 X123.225 Y132.775 E.32326 -G1 X123.225 Y123.225 E.32326 -M73 P37 R3 -G1 X132.775 Y123.225 E.32326 -G1 X132.775 Y132.735 E.3219 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -G1 X132.389 Y132.389 Z4 F30000 -G1 X129.773 Y132.389 -G1 X129.773 Y132 -G1 Z3.6 -G1 E.8 F2400 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Sparse infill -; LINE_WIDTH: 0.45 -G1 F1314 -G1 X128.145 Y132 E.05512 -G1 X132 Y128.145 E.18458 -G1 X132 Y124 E.1403 -G1 X124 Y132 E.383 -G1 X124 Y127.855 E.1403 -G1 X127.855 Y124 E.18458 -G1 X126.227 Y124 E.05512 -M73 P38 R3 -; stop printing object test_cube.stl id:0 copy 0 -; CHANGE_LAYER -; Z_HEIGHT: 3.8 -; LAYER_HEIGHT: 0.2 -; stop printing object, unique label id: 15 -M625 -;LAYER_CHANGE -G92 E0 -;_SET_FAN_SPEED_CHANGING_LAYER -; printing object test_cube.stl id:0 copy 0 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -; start printing object, unique label id: 15 -M624 AQAAAAAAAAA= -G1 X130.74 Y130.155 Z4.2 F30000 -G1 X132.346 Y132.346 Z4.2 -G1 Z3.8 -G1 E.8 F2400 -; FEATURE: Inner wall -; LINE_WIDTH: 0.449999 -G1 F1314 -G1 X123.654 Y132.346 E.29424 -G1 X123.654 Y123.654 E.29424 -G1 X132.346 Y123.654 E.29424 -G1 X132.346 Y132.306 E.29289 -G1 X132.389 Y132.306 F30000 -G1 X132.389 Y132.389 -G1 X132.775 Y132.775 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Outer wall -G1 F1314 -G1 X123.225 Y132.775 E.32326 -G1 X123.225 Y123.225 E.32326 -G1 X132.775 Y123.225 E.32326 -G1 X132.775 Y132.735 E.3219 -M73 P39 R3 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -G1 X132.389 Y132.389 Z4.2 F30000 -G1 X129.773 Y132.389 -G1 X129.773 Y132 -G1 Z3.8 -G1 E.8 F2400 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Sparse infill -; LINE_WIDTH: 0.45 -G1 F1314 -G1 X128.145 Y132 E.05512 -G1 X132 Y128.145 E.18458 -G1 X132 Y124 E.1403 -G1 X124 Y132 E.383 -G1 X124 Y127.855 E.1403 -G1 X127.855 Y124 E.18458 -G1 X126.227 Y124 E.05512 -; stop printing object test_cube.stl id:0 copy 0 -; CHANGE_LAYER -; Z_HEIGHT: 4 -; LAYER_HEIGHT: 0.2 -; stop printing object, unique label id: 15 -M625 -;LAYER_CHANGE -G92 E0 -;_SET_FAN_SPEED_CHANGING_LAYER -; printing object test_cube.stl id:0 copy 0 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -; start printing object, unique label id: 15 -M624 AQAAAAAAAAA= -G1 X130.74 Y130.155 Z4.4 F30000 -G1 X132.346 Y132.346 Z4.4 -G1 Z4 -G1 E.8 F2400 -; FEATURE: Inner wall -; LINE_WIDTH: 0.449999 -G1 F1314 -G1 X123.654 Y132.346 E.29424 -G1 X123.654 Y123.654 E.29424 -G1 X132.346 Y123.654 E.29424 -M73 P40 R3 -G1 X132.346 Y132.306 E.29289 -G1 X132.389 Y132.306 F30000 -G1 X132.389 Y132.389 -G1 X132.775 Y132.775 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Outer wall -G1 F1314 -G1 X123.225 Y132.775 E.32326 -G1 X123.225 Y123.225 E.32326 -G1 X132.775 Y123.225 E.32326 -G1 X132.775 Y132.735 E.3219 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -G1 X132.389 Y132.389 Z4.4 F30000 -G1 X129.773 Y132.389 -G1 X129.773 Y132 -G1 Z4 -G1 E.8 F2400 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Sparse infill -; LINE_WIDTH: 0.45 -G1 F1314 -G1 X128.145 Y132 E.05512 -G1 X132 Y128.145 E.18458 -G1 X132 Y124 E.1403 -M73 P41 R3 -G1 X124 Y132 E.383 -G1 X124 Y127.855 E.1403 -G1 X127.855 Y124 E.18458 -G1 X126.227 Y124 E.05512 -; stop printing object test_cube.stl id:0 copy 0 -; CHANGE_LAYER -; Z_HEIGHT: 4.2 -; LAYER_HEIGHT: 0.2 -; stop printing object, unique label id: 15 -M625 -;LAYER_CHANGE -G92 E0 -;_SET_FAN_SPEED_CHANGING_LAYER -; printing object test_cube.stl id:0 copy 0 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -; start printing object, unique label id: 15 -M624 AQAAAAAAAAA= -G1 X130.74 Y130.155 Z4.6 F30000 -G1 X132.346 Y132.346 Z4.6 -G1 Z4.2 -G1 E.8 F2400 -; FEATURE: Inner wall -; LINE_WIDTH: 0.449999 -G1 F1314 -G1 X123.654 Y132.346 E.29424 -G1 X123.654 Y123.654 E.29424 -G1 X132.346 Y123.654 E.29424 -G1 X132.346 Y132.306 E.29289 -G1 X132.389 Y132.306 F30000 -M73 P42 R3 -G1 X132.389 Y132.389 -G1 X132.775 Y132.775 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Outer wall -G1 F1314 -G1 X123.225 Y132.775 E.32326 -G1 X123.225 Y123.225 E.32326 -G1 X132.775 Y123.225 E.32326 -G1 X132.775 Y132.735 E.3219 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -G1 X132.389 Y132.389 Z4.6 F30000 -G1 X129.773 Y132.389 -G1 X129.773 Y132 -G1 Z4.2 -G1 E.8 F2400 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Sparse infill -; LINE_WIDTH: 0.45 -G1 F1314 -G1 X128.145 Y132 E.05512 -G1 X132 Y128.145 E.18458 -G1 X132 Y124 E.1403 -G1 X124 Y132 E.383 -G1 X124 Y127.855 E.1403 -G1 X127.855 Y124 E.18458 -M73 P43 R3 -G1 X126.227 Y124 E.05512 -; stop printing object test_cube.stl id:0 copy 0 -; CHANGE_LAYER -; Z_HEIGHT: 4.4 -; LAYER_HEIGHT: 0.2 -; stop printing object, unique label id: 15 -M625 -;LAYER_CHANGE -G92 E0 -;_SET_FAN_SPEED_CHANGING_LAYER -; printing object test_cube.stl id:0 copy 0 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -; start printing object, unique label id: 15 -M624 AQAAAAAAAAA= -G1 X130.74 Y130.155 Z4.8 F30000 -G1 X132.346 Y132.346 Z4.8 -G1 Z4.4 -G1 E.8 F2400 -; FEATURE: Inner wall -; LINE_WIDTH: 0.449999 -G1 F1314 -G1 X123.654 Y132.346 E.29424 -G1 X123.654 Y123.654 E.29424 -G1 X132.346 Y123.654 E.29424 -G1 X132.346 Y132.306 E.29289 -G1 X132.389 Y132.306 F30000 -G1 X132.389 Y132.389 -G1 X132.775 Y132.775 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Outer wall -G1 F1314 -G1 X123.225 Y132.775 E.32326 -G1 X123.225 Y123.225 E.32326 -G1 X132.775 Y123.225 E.32326 -G1 X132.775 Y132.735 E.3219 -M73 P44 R2 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -G1 X132.389 Y132.389 Z4.8 F30000 -G1 X129.773 Y132.389 -G1 X129.773 Y132 -G1 Z4.4 -G1 E.8 F2400 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Sparse infill -; LINE_WIDTH: 0.45 -G1 F1314 -G1 X128.145 Y132 E.05512 -G1 X132 Y128.145 E.18458 -G1 X132 Y124 E.1403 -G1 X124 Y132 E.383 -G1 X124 Y127.855 E.1403 -G1 X127.855 Y124 E.18458 -G1 X126.227 Y124 E.05512 -; stop printing object test_cube.stl id:0 copy 0 -; CHANGE_LAYER -; Z_HEIGHT: 4.6 -; LAYER_HEIGHT: 0.2 -; stop printing object, unique label id: 15 -M625 -;LAYER_CHANGE -G92 E0 -;_SET_FAN_SPEED_CHANGING_LAYER -; printing object test_cube.stl id:0 copy 0 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -; start printing object, unique label id: 15 -M624 AQAAAAAAAAA= -G1 X130.74 Y130.155 Z5 F30000 -G1 X132.346 Y132.346 Z5 -G1 Z4.6 -G1 E.8 F2400 -; FEATURE: Inner wall -; LINE_WIDTH: 0.449999 -G1 F1314 -G1 X123.654 Y132.346 E.29424 -G1 X123.654 Y123.654 E.29424 -M73 P45 R2 -G1 X132.346 Y123.654 E.29424 -G1 X132.346 Y132.306 E.29289 -G1 X132.389 Y132.306 F30000 -G1 X132.389 Y132.389 -G1 X132.775 Y132.775 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Outer wall -G1 F1314 -G1 X123.225 Y132.775 E.32326 -G1 X123.225 Y123.225 E.32326 -G1 X132.775 Y123.225 E.32326 -G1 X132.775 Y132.735 E.3219 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -G1 X132.389 Y132.389 Z5 F30000 -G1 X129.773 Y132.389 -G1 X129.773 Y132 -M73 P46 R2 -G1 Z4.6 -G1 E.8 F2400 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Sparse infill -; LINE_WIDTH: 0.45 -G1 F1314 -G1 X128.145 Y132 E.05512 -G1 X132 Y128.145 E.18458 -G1 X132 Y124 E.1403 -G1 X124 Y132 E.383 -G1 X124 Y127.855 E.1403 -G1 X127.855 Y124 E.18458 -G1 X126.227 Y124 E.05512 -; stop printing object test_cube.stl id:0 copy 0 -; CHANGE_LAYER -; Z_HEIGHT: 4.8 -; LAYER_HEIGHT: 0.2 -; stop printing object, unique label id: 15 -M625 -;LAYER_CHANGE -G92 E0 -;_SET_FAN_SPEED_CHANGING_LAYER -; printing object test_cube.stl id:0 copy 0 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -; start printing object, unique label id: 15 -M624 AQAAAAAAAAA= -G1 X130.74 Y130.155 Z5.2 F30000 -G1 X132.346 Y132.346 Z5.2 -G1 Z4.8 -G1 E.8 F2400 -; FEATURE: Inner wall -; LINE_WIDTH: 0.449999 -G1 F1314 -G1 X123.654 Y132.346 E.29424 -G1 X123.654 Y123.654 E.29424 -G1 X132.346 Y123.654 E.29424 -G1 X132.346 Y132.306 E.29289 -G1 X132.389 Y132.306 F30000 -M73 P47 R2 -G1 X132.389 Y132.389 -G1 X132.775 Y132.775 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Outer wall -G1 F1314 -G1 X123.225 Y132.775 E.32326 -G1 X123.225 Y123.225 E.32326 -G1 X132.775 Y123.225 E.32326 -G1 X132.775 Y132.735 E.3219 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -G1 X132.389 Y132.389 Z5.2 F30000 -G1 X129.773 Y132.389 -G1 X129.773 Y132 -G1 Z4.8 -G1 E.8 F2400 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Sparse infill -; LINE_WIDTH: 0.45 -G1 F1314 -G1 X128.145 Y132 E.05512 -G1 X132 Y128.145 E.18458 -G1 X132 Y124 E.1403 -G1 X124 Y132 E.383 -G1 X124 Y127.855 E.1403 -M73 P48 R2 -G1 X127.855 Y124 E.18458 -G1 X126.227 Y124 E.05512 -; stop printing object test_cube.stl id:0 copy 0 -; CHANGE_LAYER -; Z_HEIGHT: 5 -; LAYER_HEIGHT: 0.2 -; stop printing object, unique label id: 15 -M625 -;LAYER_CHANGE -G92 E0 -;_SET_FAN_SPEED_CHANGING_LAYER -; printing object test_cube.stl id:0 copy 0 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -; start printing object, unique label id: 15 -M624 AQAAAAAAAAA= -G1 X130.74 Y130.155 Z5.4 F30000 -G1 X132.346 Y132.346 Z5.4 -G1 Z5 -G1 E.8 F2400 -; FEATURE: Inner wall -; LINE_WIDTH: 0.449999 -G1 F1314 -G1 X123.654 Y132.346 E.29424 -G1 X123.654 Y123.654 E.29424 -G1 X132.346 Y123.654 E.29424 -G1 X132.346 Y132.306 E.29289 -G1 X132.389 Y132.306 F30000 -G1 X132.389 Y132.389 -G1 X132.775 Y132.775 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Outer wall -G1 F1314 -G1 X123.225 Y132.775 E.32326 -G1 X123.225 Y123.225 E.32326 -G1 X132.775 Y123.225 E.32326 -M73 P49 R2 -G1 X132.775 Y132.735 E.3219 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -G1 X132.389 Y132.389 Z5.4 F30000 -G1 X129.773 Y132.389 -G1 X129.773 Y132 -G1 Z5 -G1 E.8 F2400 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Sparse infill -; LINE_WIDTH: 0.45 -G1 F1314 -G1 X128.145 Y132 E.05512 -G1 X132 Y128.145 E.18458 -G1 X132 Y124 E.1403 -G1 X124 Y132 E.383 -G1 X124 Y127.855 E.1403 -G1 X127.855 Y124 E.18458 -G1 X126.227 Y124 E.05512 -; stop printing object test_cube.stl id:0 copy 0 -; CHANGE_LAYER -; Z_HEIGHT: 5.2 -; LAYER_HEIGHT: 0.2 -; stop printing object, unique label id: 15 -M625 -;LAYER_CHANGE -G92 E0 -;_SET_FAN_SPEED_CHANGING_LAYER -; printing object test_cube.stl id:0 copy 0 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -; start printing object, unique label id: 15 -M624 AQAAAAAAAAA= -G1 X130.74 Y130.155 Z5.6 F30000 -G1 X132.346 Y132.346 Z5.6 -G1 Z5.2 -G1 E.8 F2400 -; FEATURE: Inner wall -; LINE_WIDTH: 0.449999 -G1 F1324 -M73 P50 R2 -G1 X123.654 Y132.346 E.29424 -G1 X123.654 Y123.654 E.29424 -G1 X132.346 Y123.654 E.29424 -G1 X132.346 Y132.306 E.29289 -G1 X132.389 Y132.306 F30000 -G1 X132.389 Y132.389 -G1 X132.775 Y132.775 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Outer wall -G1 F1324 -G1 X123.225 Y132.775 E.32326 -G1 X123.225 Y123.225 E.32326 -G1 X132.775 Y123.225 E.32326 -G1 X132.775 Y132.735 E.3219 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -M73 P51 R2 -G1 X132.389 Y132.389 Z5.6 F30000 -G1 X132.389 Y126.647 -G1 X132 Y126.647 -G1 Z5.2 -G1 E.8 F2400 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Sparse infill -; LINE_WIDTH: 0.45 -G1 F1324 -G1 X132 Y128.276 E.05512 -G3 X131.109 Y129.529 I-2.456 J-.803 E.05286 -G1 X129.036 Y130.616 E.07922 -G1 X128.544 Y131.109 E.02358 -G1 X128.076 Y132 E.03408 -G1 X124 Y132 E.13798 -G1 X124 Y131.869 E.00443 -G3 X124.891 Y130.616 I2.456 J.803 E.05286 -G1 X126.964 Y129.529 E.07922 -G1 X127.456 Y129.036 E.02358 -G1 X128.544 Y126.964 E.07922 -G1 X129.036 Y126.471 E.02358 -G1 X131.109 Y125.384 E.07922 -G2 X132 Y124 I-1.805 J-2.142 E.05657 -G1 X127.924 Y124 E.13798 -G1 X127.456 Y124.891 E.03408 -G1 X126.964 Y125.384 E.02358 -G1 X124.891 Y126.471 E.07922 -G2 X124 Y127.724 I1.564 J2.057 E.05286 -G1 X124 Y129.353 E.05512 -; stop printing object test_cube.stl id:0 copy 0 -; CHANGE_LAYER -; Z_HEIGHT: 5.4 -; LAYER_HEIGHT: 0.2 -; stop printing object, unique label id: 15 -M625 -;LAYER_CHANGE -G92 E0 -;_SET_FAN_SPEED_CHANGING_LAYER -; printing object test_cube.stl id:0 copy 0 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -; start printing object, unique label id: 15 -M624 AQAAAAAAAAA= -G1 X131.184 Y131.929 Z5.8 F30000 -G1 X132.346 Y132.346 Z5.8 -G1 Z5.4 -G1 E.8 F2400 -; FEATURE: Inner wall -; LINE_WIDTH: 0.449999 -G1 F1323 -G1 X123.654 Y132.346 E.29424 -G1 X123.654 Y123.654 E.29424 -G1 X132.346 Y123.654 E.29424 -G1 X132.346 Y132.306 E.29289 -M73 P52 R2 -G1 X132.389 Y132.306 F30000 -G1 X132.389 Y132.389 -G1 X132.775 Y132.775 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Outer wall -G1 F1323 -G1 X123.225 Y132.775 E.32326 -G1 X123.225 Y123.225 E.32326 -G1 X132.775 Y123.225 E.32326 -G1 X132.775 Y132.735 E.3219 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -G1 X132.389 Y132.389 Z5.8 F30000 -G1 X129.655 Y132.389 -G1 X129.655 Y132 -G1 Z5.4 -G1 E.8 F2400 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Sparse infill -; LINE_WIDTH: 0.45 -G1 F1323 -G1 X128.027 Y132 E.05512 -G1 X128.19 Y131.109 E.03069 -G1 X129.036 Y130.263 E.0405 -G1 X131.109 Y129.882 E.07132 -G1 X131.955 Y129.036 E.0405 -G1 X132 Y128.788 E.00854 -G1 X132 Y124.643 E.1403 -G1 X131.955 Y124.891 E.00854 -G1 X131.109 Y125.737 E.0405 -G1 X129.036 Y126.118 E.07132 -M73 P53 R2 -G1 X128.19 Y126.964 E.0405 -G1 X127.81 Y129.036 E.07132 -G1 X126.964 Y129.882 E.0405 -G1 X124.891 Y130.263 E.07132 -G1 X124.045 Y131.109 E.0405 -G1 X124 Y131.357 E.00854 -G1 X124 Y127.212 E.1403 -G1 X124.045 Y126.964 E.00854 -G1 X124.891 Y126.118 E.0405 -G1 X126.964 Y125.737 E.07132 -G1 X127.81 Y124.891 E.0405 -G1 X127.973 Y124 E.03069 -G1 X126.345 Y124 E.05512 -; stop printing object test_cube.stl id:0 copy 0 -; CHANGE_LAYER -; Z_HEIGHT: 5.6 -; LAYER_HEIGHT: 0.2 -; stop printing object, unique label id: 15 -M625 -;LAYER_CHANGE -G92 E0 -;_SET_FAN_SPEED_CHANGING_LAYER -; printing object test_cube.stl id:0 copy 0 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -; start printing object, unique label id: 15 -M624 AQAAAAAAAAA= -G1 X130.801 Y130.197 Z6 F30000 -G1 X132.346 Y132.346 Z6 -G1 Z5.6 -G1 E.8 F2400 -; FEATURE: Inner wall -; LINE_WIDTH: 0.449999 -G1 F1337 -G1 X123.654 Y132.346 E.29424 -G1 X123.654 Y123.654 E.29424 -G1 X132.346 Y123.654 E.29424 -G1 X132.346 Y132.306 E.29289 -G1 X132.389 Y132.306 F30000 -G1 X132.389 Y132.389 -G1 X132.775 Y132.775 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Outer wall -G1 F1337 -G1 X123.225 Y132.775 E.32326 -G1 X123.225 Y123.225 E.32326 -M73 P54 R2 -G1 X132.775 Y123.225 E.32326 -G1 X132.775 Y132.735 E.3219 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -G1 X132.389 Y132.389 Z6 F30000 -G1 X129.606 Y132.389 -G1 X129.606 Y132 -G1 Z5.6 -G1 E.8 F2400 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Sparse infill -; LINE_WIDTH: 0.45 -G1 F1337 -G1 X127.977 Y132 E.05512 -G1 X127.837 Y131.109 E.03056 -G1 X129.036 Y129.909 E.05743 -G1 X131.109 Y130.236 E.07102 -G1 X132 Y129.344 E.04268 -G1 X132 Y125.199 E.1403 -G1 X131.109 Y126.091 E.04268 -G1 X129.036 Y125.764 E.07102 -G1 X127.837 Y126.964 E.05743 -G1 X128.163 Y129.036 E.07102 -G1 X126.964 Y130.236 E.05743 -G1 X124.891 Y129.909 E.07102 -G1 X124 Y130.801 E.04268 -G1 X124 Y126.656 E.1403 -G1 X124.891 Y125.764 E.04268 -G1 X126.964 Y126.091 E.07102 -G1 X128.163 Y124.891 E.05743 -G1 X128.023 Y124 E.03056 -M73 P55 R2 -G1 X126.394 Y124 E.05512 -; stop printing object test_cube.stl id:0 copy 0 -; CHANGE_LAYER -; Z_HEIGHT: 5.8 -; LAYER_HEIGHT: 0.2 -; stop printing object, unique label id: 15 -M625 -;LAYER_CHANGE -G92 E0 -;_SET_FAN_SPEED_CHANGING_LAYER -; printing object test_cube.stl id:0 copy 0 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -; start printing object, unique label id: 15 -M624 AQAAAAAAAAA= -G1 X130.826 Y130.214 Z6.2 F30000 -G1 X132.346 Y132.346 Z6.2 -G1 Z5.8 -G1 E.8 F2400 -; FEATURE: Inner wall -; LINE_WIDTH: 0.449999 -G1 F1320 -G1 X123.654 Y132.346 E.29424 -G1 X123.654 Y123.654 E.29424 -G1 X132.346 Y123.654 E.29424 -G1 X132.346 Y132.306 E.29289 -G1 X132.389 Y132.306 F30000 -G1 X132.389 Y132.389 -G1 X132.775 Y132.775 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Outer wall -G1 F1320 -G1 X123.225 Y132.775 E.32326 -G1 X123.225 Y123.225 E.32326 -G1 X132.775 Y123.225 E.32326 -G1 X132.775 Y132.735 E.3219 -M73 P56 R2 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -G1 X132.389 Y132.389 Z6.2 F30000 -G1 X126.357 Y132.389 -G1 X126.357 Y132 -G1 Z5.8 -G1 E.8 F2400 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Sparse infill -; LINE_WIDTH: 0.45 -G1 F1320 -G1 X127.986 Y132 E.05512 -G1 X127.898 Y131.109 E.03033 -G1 X126.964 Y130.175 E.0447 -G1 X124.891 Y129.97 E.07049 -G1 X124 Y129.078 E.04268 -G1 X124 Y124.933 E.1403 -G1 X124.891 Y125.825 E.04268 -G1 X126.964 Y126.03 E.07049 -G1 X127.898 Y126.964 E.0447 -G1 X128.102 Y129.036 E.07049 -G1 X129.036 Y129.97 E.0447 -G1 X131.109 Y130.175 E.07049 -G1 X132 Y131.067 E.04268 -G1 X132 Y126.922 E.1403 -G1 X131.109 Y126.03 E.04268 -G1 X129.036 Y125.825 E.07049 -G1 X128.102 Y124.891 E.0447 -G1 X128.014 Y124 E.03033 -G1 X129.643 Y124 E.05512 -; stop printing object test_cube.stl id:0 copy 0 -; CHANGE_LAYER -; Z_HEIGHT: 6 -; LAYER_HEIGHT: 0.2 -; stop printing object, unique label id: 15 -M625 -;LAYER_CHANGE -G92 E0 -;_SET_FAN_SPEED_CHANGING_LAYER -; printing object test_cube.stl id:0 copy 0 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -; start printing object, unique label id: 15 -M624 AQAAAAAAAAA= -G1 X131.995 Y131.261 Z6.4 F30000 -G1 X132.346 Y132.346 Z6.4 -G1 Z6 -G1 E.8 F2400 -; FEATURE: Inner wall -; LINE_WIDTH: 0.449999 -G1 F1326 -G1 X123.654 Y132.346 E.29424 -G1 X123.654 Y123.654 E.29424 -G1 X132.346 Y123.654 E.29424 -M73 P57 R2 -G1 X132.346 Y132.306 E.29289 -G1 X132.389 Y132.306 F30000 -G1 X132.389 Y132.389 -G1 X132.775 Y132.775 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Outer wall -G1 F1326 -G1 X123.225 Y132.775 E.32326 -G1 X123.225 Y123.225 E.32326 -G1 X132.775 Y123.225 E.32326 -G1 X132.775 Y132.735 E.3219 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -G1 X132.389 Y132.389 Z6.4 F30000 -G1 X132.389 Y129.3 -G1 X132 Y129.3 -G1 Z6 -G1 E.8 F2400 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Sparse infill -; LINE_WIDTH: 0.45 -G1 F1326 -G1 X132 Y127.671 E.05512 -G2 X131.109 Y126.384 I-2.102 J.503 E.05426 -G1 X129.036 Y125.471 E.07665 -G1 X128.456 Y124.891 E.02777 -M73 P58 R2 -G1 X128.064 Y124 E.03298 -G1 X124 Y124 E.13756 -G2 X124.891 Y125.471 I2.26 J-.363 E.05972 -G1 X126.964 Y126.384 E.07665 -G1 X127.544 Y126.964 E.02777 -G1 X128.456 Y129.036 E.07665 -G1 X129.036 Y129.616 E.02777 -G1 X131.109 Y130.529 E.07665 -G3 X132 Y131.817 I-1.21 J1.791 E.05426 -G1 X132 Y132 E.00623 -G1 X127.936 Y132 E.13756 -G1 X127.544 Y131.109 E.03298 -G1 X126.964 Y130.529 E.02777 -G1 X124.891 Y129.616 E.07665 -G3 X124 Y128.329 I1.21 J-1.791 E.05426 -G1 X124 Y126.7 E.05512 -; stop printing object test_cube.stl id:0 copy 0 -; CHANGE_LAYER -; Z_HEIGHT: 6.2 -; LAYER_HEIGHT: 0.2 -; stop printing object, unique label id: 15 -M625 -;LAYER_CHANGE -G92 E0 -;_SET_FAN_SPEED_CHANGING_LAYER -; printing object test_cube.stl id:0 copy 0 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -; start printing object, unique label id: 15 -M624 AQAAAAAAAAA= -G1 X130.321 Y130.977 Z6.6 F30000 -G1 X132.346 Y132.346 Z6.6 -G1 Z6.2 -G1 E.8 F2400 -; FEATURE: Inner wall -; LINE_WIDTH: 0.449999 -G1 F1317 -G1 X123.654 Y132.346 E.29424 -G1 X123.654 Y123.654 E.29424 -G1 X132.346 Y123.654 E.29424 -G1 X132.346 Y132.306 E.29289 -G1 X132.389 Y132.306 F30000 -M73 P59 R2 -G1 X132.389 Y132.389 -G1 X132.775 Y132.775 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Outer wall -G1 F1317 -G1 X123.225 Y132.775 E.32326 -G1 X123.225 Y123.225 E.32326 -G1 X132.775 Y123.225 E.32326 -G1 X132.775 Y132.735 E.3219 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -G1 X132.389 Y132.389 Z6.6 F30000 -G1 X126.259 Y132.389 -G1 X126.259 Y132 -G1 Z6.2 -G1 E.8 F2400 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Sparse infill -; LINE_WIDTH: 0.45 -G1 F1317 -G1 X127.887 Y132 E.05512 -G2 X126.964 Y130.882 I-5.015 J3.2 E.04921 -G1 X124.891 Y129.263 E.08902 -G3 X124 Y128.185 I3.943 J-4.17 E.04747 -G1 X124 Y124.04 E.1403 -G2 X124.891 Y125.118 I4.835 J-3.092 E.04747 -G1 X127.19 Y126.964 E.0998 -G1 X129.036 Y129.263 E.0998 -G1 X131.109 Y130.882 E.08902 -G3 X132 Y131.96 I-3.943 J4.17 E.04747 -G1 X132 Y127.815 E.1403 -G2 X131.109 Y126.737 I-4.835 J3.092 E.04747 -M73 P60 R2 -G1 X129.036 Y125.118 E.08902 -G3 X128.113 Y124 I4.092 J-4.319 E.04921 -G1 X129.741 Y124 E.05512 -; stop printing object test_cube.stl id:0 copy 0 -; CHANGE_LAYER -; Z_HEIGHT: 6.4 -; LAYER_HEIGHT: 0.2 -; stop printing object, unique label id: 15 -M625 -;LAYER_CHANGE -G92 E0 -;_SET_FAN_SPEED_CHANGING_LAYER -; printing object test_cube.stl id:0 copy 0 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -; start printing object, unique label id: 15 -M624 AQAAAAAAAAA= -G1 X132.015 Y131.285 Z6.8 F30000 -G1 X132.346 Y132.346 Z6.8 -G1 Z6.4 -G1 E.8 F2400 -; FEATURE: Inner wall -; LINE_WIDTH: 0.449999 -G1 F1316 -G1 X123.654 Y132.346 E.29424 -G1 X123.654 Y123.654 E.29424 -G1 X132.346 Y123.654 E.29424 -G1 X132.346 Y132.306 E.29289 -G1 X132.389 Y132.306 F30000 -G1 X132.389 Y132.389 -G1 X132.775 Y132.775 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Outer wall -G1 F1316 -G1 X123.225 Y132.775 E.32326 -G1 X123.225 Y123.225 E.32326 -G1 X132.775 Y123.225 E.32326 -G1 X132.775 Y132.735 E.3219 -M73 P61 R2 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -G1 X132.389 Y132.389 Z6.8 F30000 -G1 X132.389 Y126.227 -G1 X132 Y126.227 -G1 Z6.4 -G1 E.8 F2400 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Sparse infill -; LINE_WIDTH: 0.45 -G1 F1316 -G1 X132 Y127.855 E.05512 -G1 X128.145 Y124 E.18458 -G1 X124 Y124 E.1403 -G1 X132 Y132 E.383 -G1 X127.855 Y132 E.1403 -G1 X124 Y128.145 E.18458 -G1 X124 Y129.773 E.05512 -; stop printing object test_cube.stl id:0 copy 0 -; CHANGE_LAYER -; Z_HEIGHT: 6.6 -; LAYER_HEIGHT: 0.2 -; stop printing object, unique label id: 15 -M625 -;LAYER_CHANGE -G92 E0 -;_SET_FAN_SPEED_CHANGING_LAYER -; printing object test_cube.stl id:0 copy 0 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -; start printing object, unique label id: 15 -M624 AQAAAAAAAAA= -G1 X131.293 Y132.022 Z7 F30000 -G1 X132.346 Y132.346 Z7 -G1 Z6.6 -G1 E.8 F2400 -; FEATURE: Inner wall -; LINE_WIDTH: 0.449999 -G1 F1316 -G1 X123.654 Y132.346 E.29424 -G1 X123.654 Y123.654 E.29424 -M73 P62 R2 -G1 X132.346 Y123.654 E.29424 -G1 X132.346 Y132.306 E.29289 -G1 X132.389 Y132.306 F30000 -G1 X132.389 Y132.389 -G1 X132.775 Y132.775 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Outer wall -G1 F1316 -G1 X123.225 Y132.775 E.32326 -G1 X123.225 Y123.225 E.32326 -G1 X132.775 Y123.225 E.32326 -G1 X132.775 Y132.735 E.3219 -M73 P62 R1 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -G1 X132.389 Y132.389 Z7 F30000 -G1 X132.389 Y126.227 -G1 X132 Y126.227 -M73 P63 R1 -G1 Z6.6 -G1 E.8 F2400 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Sparse infill -; LINE_WIDTH: 0.45 -G1 F1316 -G1 X132 Y127.855 E.05512 -G1 X128.145 Y124 E.18458 -G1 X124 Y124 E.1403 -G1 X132 Y132 E.383 -G1 X127.855 Y132 E.1403 -G1 X124 Y128.145 E.18458 -G1 X124 Y129.773 E.05512 -; stop printing object test_cube.stl id:0 copy 0 -; CHANGE_LAYER -; Z_HEIGHT: 6.8 -; LAYER_HEIGHT: 0.2 -; stop printing object, unique label id: 15 -M625 -;LAYER_CHANGE -G92 E0 -;_SET_FAN_SPEED_CHANGING_LAYER -; printing object test_cube.stl id:0 copy 0 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -; start printing object, unique label id: 15 -M624 AQAAAAAAAAA= -G1 X131.293 Y132.022 Z7.2 F30000 -G1 X132.346 Y132.346 Z7.2 -G1 Z6.8 -G1 E.8 F2400 -; FEATURE: Inner wall -; LINE_WIDTH: 0.449999 -G1 F1316 -G1 X123.654 Y132.346 E.29424 -G1 X123.654 Y123.654 E.29424 -G1 X132.346 Y123.654 E.29424 -G1 X132.346 Y132.306 E.29289 -G1 X132.389 Y132.306 F30000 -M73 P64 R1 -G1 X132.389 Y132.389 -G1 X132.775 Y132.775 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Outer wall -G1 F1316 -G1 X123.225 Y132.775 E.32326 -G1 X123.225 Y123.225 E.32326 -G1 X132.775 Y123.225 E.32326 -G1 X132.775 Y132.735 E.3219 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -G1 X132.389 Y132.389 Z7.2 F30000 -G1 X132.389 Y126.227 -G1 X132 Y126.227 -G1 Z6.8 -G1 E.8 F2400 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Sparse infill -; LINE_WIDTH: 0.45 -G1 F1316 -G1 X132 Y127.855 E.05512 -G1 X128.145 Y124 E.18458 -G1 X124 Y124 E.1403 -G1 X132 Y132 E.383 -G1 X127.855 Y132 E.1403 -M73 P65 R1 -G1 X124 Y128.145 E.18458 -G1 X124 Y129.773 E.05512 -; stop printing object test_cube.stl id:0 copy 0 -; CHANGE_LAYER -; Z_HEIGHT: 7 -; LAYER_HEIGHT: 0.2 -; stop printing object, unique label id: 15 -M625 -;LAYER_CHANGE -G92 E0 -;_SET_FAN_SPEED_CHANGING_LAYER -; printing object test_cube.stl id:0 copy 0 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -; start printing object, unique label id: 15 -M624 AQAAAAAAAAA= -G1 X131.293 Y132.022 Z7.4 F30000 -G1 X132.346 Y132.346 Z7.4 -G1 Z7 -G1 E.8 F2400 -; FEATURE: Inner wall -; LINE_WIDTH: 0.449999 -G1 F1316 -G1 X123.654 Y132.346 E.29424 -G1 X123.654 Y123.654 E.29424 -G1 X132.346 Y123.654 E.29424 -G1 X132.346 Y132.306 E.29289 -G1 X132.389 Y132.306 F30000 -G1 X132.389 Y132.389 -G1 X132.775 Y132.775 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Outer wall -G1 F1316 -G1 X123.225 Y132.775 E.32326 -G1 X123.225 Y123.225 E.32326 -G1 X132.775 Y123.225 E.32326 -M73 P66 R1 -G1 X132.775 Y132.735 E.3219 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -G1 X132.389 Y132.389 Z7.4 F30000 -G1 X132.389 Y126.227 -G1 X132 Y126.227 -G1 Z7 -G1 E.8 F2400 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Sparse infill -; LINE_WIDTH: 0.45 -G1 F1316 -G1 X132 Y127.855 E.05512 -G1 X128.145 Y124 E.18458 -G1 X124 Y124 E.1403 -G1 X132 Y132 E.383 -G1 X127.855 Y132 E.1403 -G1 X124 Y128.145 E.18458 -G1 X124 Y129.773 E.05512 -; stop printing object test_cube.stl id:0 copy 0 -; CHANGE_LAYER -; Z_HEIGHT: 7.2 -; LAYER_HEIGHT: 0.2 -; stop printing object, unique label id: 15 -M625 -;LAYER_CHANGE -G92 E0 -;_SET_FAN_SPEED_CHANGING_LAYER -; printing object test_cube.stl id:0 copy 0 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -; start printing object, unique label id: 15 -M624 AQAAAAAAAAA= -G1 X131.293 Y132.022 Z7.6 F30000 -G1 X132.346 Y132.346 Z7.6 -G1 Z7.2 -G1 E.8 F2400 -M73 P67 R1 -; FEATURE: Inner wall -; LINE_WIDTH: 0.449999 -G1 F1316 -G1 X123.654 Y132.346 E.29424 -G1 X123.654 Y123.654 E.29424 -G1 X132.346 Y123.654 E.29424 -G1 X132.346 Y132.306 E.29289 -G1 X132.389 Y132.306 F30000 -G1 X132.389 Y132.389 -G1 X132.775 Y132.775 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Outer wall -G1 F1316 -G1 X123.225 Y132.775 E.32326 -G1 X123.225 Y123.225 E.32326 -G1 X132.775 Y123.225 E.32326 -G1 X132.775 Y132.735 E.3219 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -M73 P68 R1 -G1 X132.389 Y132.389 Z7.6 F30000 -G1 X132.389 Y126.227 -G1 X132 Y126.227 -G1 Z7.2 -G1 E.8 F2400 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Sparse infill -; LINE_WIDTH: 0.45 -G1 F1316 -G1 X132 Y127.855 E.05512 -G1 X128.145 Y124 E.18458 -G1 X124 Y124 E.1403 -G1 X132 Y132 E.383 -G1 X127.855 Y132 E.1403 -G1 X124 Y128.145 E.18458 -G1 X124 Y129.773 E.05512 -; stop printing object test_cube.stl id:0 copy 0 -; CHANGE_LAYER -; Z_HEIGHT: 7.4 -; LAYER_HEIGHT: 0.2 -; stop printing object, unique label id: 15 -M625 -;LAYER_CHANGE -G92 E0 -;_SET_FAN_SPEED_CHANGING_LAYER -; printing object test_cube.stl id:0 copy 0 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -; start printing object, unique label id: 15 -M624 AQAAAAAAAAA= -G1 X131.293 Y132.022 Z7.8 F30000 -G1 X132.346 Y132.346 Z7.8 -G1 Z7.4 -G1 E.8 F2400 -; FEATURE: Inner wall -; LINE_WIDTH: 0.449999 -G1 F1316 -G1 X123.654 Y132.346 E.29424 -G1 X123.654 Y123.654 E.29424 -G1 X132.346 Y123.654 E.29424 -G1 X132.346 Y132.306 E.29289 -M73 P69 R1 -G1 X132.389 Y132.306 F30000 -G1 X132.389 Y132.389 -G1 X132.775 Y132.775 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Outer wall -G1 F1316 -G1 X123.225 Y132.775 E.32326 -G1 X123.225 Y123.225 E.32326 -G1 X132.775 Y123.225 E.32326 -G1 X132.775 Y132.735 E.3219 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -G1 X132.389 Y132.389 Z7.8 F30000 -G1 X132.389 Y126.227 -G1 X132 Y126.227 -G1 Z7.4 -G1 E.8 F2400 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Sparse infill -; LINE_WIDTH: 0.45 -G1 F1316 -G1 X132 Y127.855 E.05512 -G1 X128.145 Y124 E.18458 -G1 X124 Y124 E.1403 -G1 X132 Y132 E.383 -M73 P70 R1 -G1 X127.855 Y132 E.1403 -G1 X124 Y128.145 E.18458 -G1 X124 Y129.773 E.05512 -; stop printing object test_cube.stl id:0 copy 0 -; CHANGE_LAYER -; Z_HEIGHT: 7.6 -; LAYER_HEIGHT: 0.2 -; stop printing object, unique label id: 15 -M625 -;LAYER_CHANGE -G92 E0 -;_SET_FAN_SPEED_CHANGING_LAYER -; printing object test_cube.stl id:0 copy 0 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -; start printing object, unique label id: 15 -M624 AQAAAAAAAAA= -G1 X131.293 Y132.022 Z8 F30000 -G1 X132.346 Y132.346 Z8 -G1 Z7.6 -G1 E.8 F2400 -; FEATURE: Inner wall -; LINE_WIDTH: 0.449999 -G1 F1316 -G1 X123.654 Y132.346 E.29424 -G1 X123.654 Y123.654 E.29424 -G1 X132.346 Y123.654 E.29424 -G1 X132.346 Y132.306 E.29289 -G1 X132.389 Y132.306 F30000 -G1 X132.389 Y132.389 -G1 X132.775 Y132.775 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Outer wall -G1 F1316 -G1 X123.225 Y132.775 E.32326 -G1 X123.225 Y123.225 E.32326 -M73 P71 R1 -G1 X132.775 Y123.225 E.32326 -G1 X132.775 Y132.735 E.3219 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -G1 X132.389 Y132.389 Z8 F30000 -G1 X132.389 Y126.227 -G1 X132 Y126.227 -G1 Z7.6 -G1 E.8 F2400 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Sparse infill -; LINE_WIDTH: 0.45 -G1 F1316 -G1 X132 Y127.855 E.05512 -G1 X128.145 Y124 E.18458 -G1 X124 Y124 E.1403 -G1 X132 Y132 E.383 -G1 X127.855 Y132 E.1403 -G1 X124 Y128.145 E.18458 -G1 X124 Y129.773 E.05512 -M73 P72 R1 -; stop printing object test_cube.stl id:0 copy 0 -; CHANGE_LAYER -; Z_HEIGHT: 7.8 -; LAYER_HEIGHT: 0.2 -; stop printing object, unique label id: 15 -M625 -;LAYER_CHANGE -G92 E0 -;_SET_FAN_SPEED_CHANGING_LAYER -; printing object test_cube.stl id:0 copy 0 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -; start printing object, unique label id: 15 -M624 AQAAAAAAAAA= -G1 X131.293 Y132.022 Z8.2 F30000 -G1 X132.346 Y132.346 Z8.2 -G1 Z7.8 -G1 E.8 F2400 -; FEATURE: Inner wall -; LINE_WIDTH: 0.449999 -G1 F1318 -G1 X123.654 Y132.346 E.29424 -G1 X123.654 Y123.654 E.29424 -G1 X132.346 Y123.654 E.29424 -G1 X132.346 Y132.306 E.29289 -G1 X132.389 Y132.306 F30000 -G1 X132.389 Y132.389 -G1 X132.775 Y132.775 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Outer wall -G1 F1318 -G1 X123.225 Y132.775 E.32326 -G1 X123.225 Y123.225 E.32326 -G1 X132.775 Y123.225 E.32326 -G1 X132.775 Y132.735 E.3219 -M73 P73 R1 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -G1 X132.389 Y132.389 Z8.2 F30000 -G1 X126.267 Y132.389 -G1 X126.267 Y132 -G1 Z7.8 -G1 E.8 F2400 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Sparse infill -; LINE_WIDTH: 0.45 -G1 F1318 -G1 X127.895 Y132 E.05512 -G2 X126.964 Y130.826 I-4.186 J2.363 E.05093 -G1 X124.891 Y129.319 E.08675 -G3 X124 Y128.199 I3.103 J-3.385 E.04866 -G1 X124 Y124.054 E.1403 -G2 X124.891 Y125.174 I3.995 J-2.265 E.04866 -G1 X126.964 Y126.681 E.08675 -G1 X127.246 Y126.964 E.01352 -G1 X128.754 Y129.036 E.08675 -G1 X129.036 Y129.319 E.01352 -G1 X131.109 Y130.826 E.08675 -G3 X132 Y131.946 I-3.103 J3.385 E.04866 -G1 X132 Y127.801 E.1403 -G2 X131.109 Y126.681 I-3.995 J2.265 E.04866 -G1 X129.036 Y125.174 E.08675 -G3 X128.105 Y124 I3.255 J-3.537 E.05093 -G1 X129.733 Y124 E.05512 -; stop printing object test_cube.stl id:0 copy 0 -; CHANGE_LAYER -; Z_HEIGHT: 8 -; LAYER_HEIGHT: 0.2 -; stop printing object, unique label id: 15 -M625 -;LAYER_CHANGE -G92 E0 -;_SET_FAN_SPEED_CHANGING_LAYER -; printing object test_cube.stl id:0 copy 0 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -; start printing object, unique label id: 15 -M624 AQAAAAAAAAA= -G1 X132.014 Y131.283 Z8.4 F30000 -G1 X132.346 Y132.346 Z8.4 -G1 Z8 -G1 E.8 F2400 -; FEATURE: Inner wall -; LINE_WIDTH: 0.449999 -G1 F1328 -G1 X123.654 Y132.346 E.29424 -G1 X123.654 Y123.654 E.29424 -G1 X132.346 Y123.654 E.29424 -M73 P74 R1 -G1 X132.346 Y132.306 E.29289 -G1 X132.389 Y132.306 F30000 -G1 X132.389 Y132.389 -G1 X132.775 Y132.775 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Outer wall -G1 F1328 -G1 X123.225 Y132.775 E.32326 -G1 X123.225 Y123.225 E.32326 -G1 X132.775 Y123.225 E.32326 -G1 X132.775 Y132.735 E.3219 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -G1 X132.389 Y132.389 Z8.4 F30000 -G1 X132.389 Y129.254 -G1 X132 Y129.254 -G1 Z8 -G1 E.8 F2400 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Sparse infill -; LINE_WIDTH: 0.45 -G1 F1328 -G1 X132 Y127.626 E.05512 -G1 X131.745 Y126.964 E.02402 -G1 X131.109 Y126.328 E.03045 -G1 X129.036 Y125.527 E.0752 -G1 X128.4 Y124.891 E.03045 -M73 P75 R1 -G1 X128.056 Y124 E.03236 -G1 X124 Y124 E.1373 -G1 X124 Y124.229 E.00778 -G1 X124.255 Y124.891 E.02402 -G1 X124.891 Y125.527 E.03045 -G1 X126.964 Y126.328 E.0752 -G1 X127.6 Y126.964 E.03045 -G1 X128.4 Y129.036 E.0752 -G1 X129.036 Y129.672 E.03045 -G1 X131.109 Y130.473 E.0752 -G1 X131.745 Y131.109 E.03045 -G1 X132 Y131.771 E.02402 -G1 X132 Y132 E.00778 -G1 X127.944 Y132 E.1373 -G1 X127.6 Y131.109 E.03236 -G1 X126.964 Y130.473 E.03045 -G1 X124.891 Y129.672 E.0752 -G1 X124.255 Y129.036 E.03045 -G1 X124 Y128.374 E.02402 -G1 X124 Y126.746 E.05512 -; stop printing object test_cube.stl id:0 copy 0 -; CHANGE_LAYER -; Z_HEIGHT: 8.2 -; LAYER_HEIGHT: 0.2 -; stop printing object, unique label id: 15 -M625 -;LAYER_CHANGE -G92 E0 -;_SET_FAN_SPEED_CHANGING_LAYER -; printing object test_cube.stl id:0 copy 0 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -; start printing object, unique label id: 15 -M624 AQAAAAAAAAA= -G1 X130.338 Y130.999 Z8.6 F30000 -G1 X132.346 Y132.346 Z8.6 -G1 Z8.2 -G1 E.8 F2400 -; FEATURE: Inner wall -; LINE_WIDTH: 0.449999 -G1 F1323 -G1 X123.654 Y132.346 E.29424 -G1 X123.654 Y123.654 E.29424 -G1 X132.346 Y123.654 E.29424 -G1 X132.346 Y132.306 E.29289 -G1 X132.389 Y132.306 F30000 -G1 X132.389 Y132.389 -G1 X132.775 Y132.775 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Outer wall -G1 F1323 -G1 X123.225 Y132.775 E.32326 -G1 X123.225 Y123.225 E.32326 -M73 P76 R1 -G1 X132.775 Y123.225 E.32326 -G1 X132.775 Y132.735 E.3219 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -G1 X132.389 Y132.389 Z8.6 F30000 -G1 X126.365 Y132.389 -G1 X126.365 Y132 -G1 Z8.2 -G1 E.8 F2400 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Sparse infill -; LINE_WIDTH: 0.45 -G1 F1323 -G1 X127.993 Y132 E.05512 -G1 X127.953 Y131.109 E.03021 -G1 X126.964 Y130.119 E.04737 -G1 X124.891 Y130.026 E.07022 -G1 X124 Y129.134 E.04268 -G1 X124 Y124.989 E.1403 -G1 X124.891 Y125.881 E.04268 -G1 X126.964 Y125.974 E.07022 -G1 X127.953 Y126.964 E.04737 -G1 X128.047 Y129.036 E.07022 -G1 X129.036 Y130.026 E.04737 -G1 X131.109 Y130.119 E.07022 -G1 X132 Y131.011 E.04268 -G1 X132 Y126.866 E.1403 -G1 X131.109 Y125.974 E.04268 -M73 P77 R1 -G1 X129.036 Y125.881 E.07022 -G1 X128.047 Y124.891 E.04737 -G1 X128.007 Y124 E.03021 -G1 X129.635 Y124 E.05512 -; stop printing object test_cube.stl id:0 copy 0 -; CHANGE_LAYER -; Z_HEIGHT: 8.4 -; LAYER_HEIGHT: 0.2 -; stop printing object, unique label id: 15 -M625 -;LAYER_CHANGE -G92 E0 -;_SET_FAN_SPEED_CHANGING_LAYER -; printing object test_cube.stl id:0 copy 0 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -; start printing object, unique label id: 15 -M624 AQAAAAAAAAA= -G1 X131.993 Y131.259 Z8.8 F30000 -G1 X132.346 Y132.346 Z8.8 -G1 Z8.4 -G1 E.8 F2400 -; FEATURE: Inner wall -; LINE_WIDTH: 0.449999 -G1 F1333 -G1 X123.654 Y132.346 E.29424 -G1 X123.654 Y123.654 E.29424 -G1 X132.346 Y123.654 E.29424 -G1 X132.346 Y132.306 E.29289 -G1 X132.389 Y132.306 F30000 -G1 X132.389 Y132.389 -G1 X132.775 Y132.775 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Outer wall -G1 F1333 -G1 X123.225 Y132.775 E.32326 -G1 X123.225 Y123.225 E.32326 -G1 X132.775 Y123.225 E.32326 -G1 X132.775 Y132.735 E.3219 -M73 P78 R1 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -G1 X132.389 Y132.389 Z8.8 F30000 -G1 X129.613 Y132.389 -G1 X129.613 Y132 -G1 Z8.4 -G1 E.8 F2400 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Sparse infill -; LINE_WIDTH: 0.45 -G1 F1333 -G1 X127.985 Y132 E.05512 -G1 X127.892 Y131.109 E.03034 -G1 X129.036 Y129.965 E.05476 -G1 X131.109 Y130.18 E.07053 -G1 X132 Y129.288 E.04268 -G1 X132 Y125.143 E.1403 -G1 X131.109 Y126.035 E.04268 -G1 X129.036 Y125.82 E.07053 -G1 X127.892 Y126.964 E.05476 -G1 X128.108 Y129.036 E.07053 -G1 X126.964 Y130.18 E.05476 -G1 X124.891 Y129.965 E.07053 -G1 X124 Y130.857 E.04268 -G1 X124 Y126.712 E.1403 -G1 X124.891 Y125.82 E.04268 -G1 X126.964 Y126.035 E.07053 -G1 X128.108 Y124.891 E.05476 -G1 X128.015 Y124 E.03034 -G1 X126.387 Y124 E.05512 -; stop printing object test_cube.stl id:0 copy 0 -; CHANGE_LAYER -; Z_HEIGHT: 8.6 -; LAYER_HEIGHT: 0.200001 -; stop printing object, unique label id: 15 -M625 -;LAYER_CHANGE -G92 E0 -;_SET_FAN_SPEED_CHANGING_LAYER -; printing object test_cube.stl id:0 copy 0 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -; start printing object, unique label id: 15 -M624 AQAAAAAAAAA= -G1 X130.822 Y130.211 Z9 F30000 -G1 X132.346 Y132.346 Z9 -G1 Z8.6 -G1 E.8 F2400 -; FEATURE: Inner wall -; LINE_WIDTH: 0.449999 -G1 F1336 -G1 X123.654 Y132.346 E.29424 -G1 X123.654 Y123.654 E.29424 -M73 P79 R1 -G1 X132.346 Y123.654 E.29424 -G1 X132.346 Y132.306 E.29289 -G1 X132.389 Y132.306 F30000 -G1 X132.389 Y132.389 -G1 X132.775 Y132.775 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Outer wall -G1 F1336 -G1 X123.225 Y132.775 E.32326 -G1 X123.225 Y123.225 E.32326 -G1 X132.775 Y123.225 E.32326 -G1 X132.775 Y132.735 E.3219 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -G1 X132.389 Y132.389 Z9 F30000 -G1 X132.389 Y126.981 -G1 X132 Y126.981 -M73 P80 R1 -G1 Z8.6 -G1 E.8 F2400 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Sparse infill -; LINE_WIDTH: 0.45 -G1 F1336 -G1 X132 Y128.609 E.05512 -G1 X131.899 Y129.036 E.01486 -G1 X131.109 Y129.827 E.03783 -G1 X129.036 Y130.318 E.0721 -G1 X128.246 Y131.109 E.03783 -G1 X128.034 Y132 E.03102 -G1 X124 Y132 E.13657 -G3 X124.101 Y131.109 I1.929 J-.232 E.03065 -G1 X124.891 Y130.318 E.03783 -G1 X126.964 Y129.827 E.0721 -G1 X127.754 Y129.036 E.03783 -G1 X128.246 Y126.964 E.0721 -G1 X129.036 Y126.173 E.03783 -G1 X131.109 Y125.682 E.0721 -G1 X131.899 Y124.891 E.03783 -G2 X132 Y124 I-1.828 J-.659 E.03065 -G1 X127.966 Y124 E.13657 -G1 X127.754 Y124.891 E.03102 -G1 X126.964 Y125.682 E.03783 -G1 X124.891 Y126.173 E.0721 -G1 X124.101 Y126.964 E.03783 -G1 X124 Y127.391 E.01486 -G1 X124 Y129.019 E.05512 -; stop printing object test_cube.stl id:0 copy 0 -; CHANGE_LAYER -; Z_HEIGHT: 8.8 -; LAYER_HEIGHT: 0.2 -; stop printing object, unique label id: 15 -M625 -;LAYER_CHANGE -G92 E0 -;_SET_FAN_SPEED_CHANGING_LAYER -; printing object test_cube.stl id:0 copy 0 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -; start printing object, unique label id: 15 -M624 AQAAAAAAAAA= -G1 X131.089 Y131.845 Z9.2 F30000 -G1 X132.346 Y132.346 Z9.2 -G1 Z8.8 -G1 E.8 F2400 -; FEATURE: Inner wall -; LINE_WIDTH: 0.449999 -G1 F1319 -G1 X123.654 Y132.346 E.29424 -G1 X123.654 Y123.654 E.29424 -G1 X132.346 Y123.654 E.29424 -G1 X132.346 Y132.306 E.29289 -G1 X132.389 Y132.306 F30000 -M73 P81 R1 -G1 X132.389 Y132.389 -G1 X132.775 Y132.775 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Outer wall -G1 F1319 -G1 X123.225 Y132.775 E.32326 -G1 X123.225 Y123.225 E.32326 -G1 X132.775 Y123.225 E.32326 -G1 X132.775 Y132.735 E.3219 -M73 P81 R0 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -G1 X132.389 Y132.389 Z9.2 F30000 -G1 X129.712 Y132.389 -G1 X129.712 Y132 -G1 Z8.8 -G1 E.8 F2400 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Sparse infill -; LINE_WIDTH: 0.45 -G1 F1319 -G1 X128.084 Y132 E.05512 -G1 X128.599 Y131.109 E.03487 -G1 X129.036 Y130.672 E.02091 -G1 X131.109 Y129.473 E.08104 -G2 X132 Y128.25 I-1.844 J-2.281 E.05182 -G1 X132 Y124.105 E.1403 -G3 X131.109 Y125.328 I-2.736 J-1.058 E.05182 -G1 X129.036 Y126.527 E.08104 -G1 X128.599 Y126.964 E.02091 -G1 X127.401 Y129.036 E.08104 -G1 X126.964 Y129.473 E.02091 -M73 P82 R0 -G1 X124.891 Y130.672 E.08104 -G2 X124 Y131.895 I1.844 J2.281 E.05182 -G1 X124 Y127.75 E.1403 -G3 X124.891 Y126.527 I2.736 J1.058 E.05182 -G1 X126.964 Y125.328 E.08104 -G1 X127.401 Y124.891 E.02091 -G1 X127.916 Y124 E.03487 -G1 X126.288 Y124 E.05512 -; stop printing object test_cube.stl id:0 copy 0 -; CHANGE_LAYER -; Z_HEIGHT: 9 -; LAYER_HEIGHT: 0.2 -; stop printing object, unique label id: 15 -M625 -;LAYER_CHANGE -G92 E0 -;_SET_FAN_SPEED_CHANGING_LAYER -; printing object test_cube.stl id:0 copy 0 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -; start printing object, unique label id: 15 -M624 AQAAAAAAAAA= -G1 X130.771 Y130.176 Z9.4 F30000 -G1 X132.346 Y132.346 Z9.4 -G1 Z9 -G1 E.8 F2400 -; FEATURE: Inner wall -; LINE_WIDTH: 0.449999 -G1 F1314 -G1 X123.654 Y132.346 E.29424 -G1 X123.654 Y123.654 E.29424 -G1 X132.346 Y123.654 E.29424 -G1 X132.346 Y132.306 E.29289 -G1 X132.389 Y132.306 F30000 -G1 X132.389 Y132.389 -G1 X132.775 Y132.775 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Outer wall -G1 F1314 -G1 X123.225 Y132.775 E.32326 -G1 X123.225 Y123.225 E.32326 -G1 X132.775 Y123.225 E.32326 -M73 P83 R0 -G1 X132.775 Y132.735 E.3219 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -G1 X132.389 Y132.389 Z9.4 F30000 -G1 X129.773 Y132.389 -G1 X129.773 Y132 -G1 Z9 -G1 E.8 F2400 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Sparse infill -; LINE_WIDTH: 0.45 -G1 F1314 -G1 X128.145 Y132 E.05512 -G1 X132 Y128.145 E.18458 -G1 X132 Y124 E.1403 -G1 X124 Y132 E.383 -G1 X124 Y127.855 E.1403 -G1 X127.855 Y124 E.18458 -G1 X126.227 Y124 E.05512 -; stop printing object test_cube.stl id:0 copy 0 -; CHANGE_LAYER -; Z_HEIGHT: 9.2 -; LAYER_HEIGHT: 0.2 -; stop printing object, unique label id: 15 -M625 -;LAYER_CHANGE -G92 E0 -;_SET_FAN_SPEED_CHANGING_LAYER -; printing object test_cube.stl id:0 copy 0 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -; start printing object, unique label id: 15 -M624 AQAAAAAAAAA= -G1 X130.74 Y130.155 Z9.6 F30000 -G1 X132.346 Y132.346 Z9.6 -G1 Z9.2 -G1 E.8 F2400 -M73 P84 R0 -; FEATURE: Inner wall -; LINE_WIDTH: 0.449999 -G1 F1314 -G1 X123.654 Y132.346 E.29424 -G1 X123.654 Y123.654 E.29424 -G1 X132.346 Y123.654 E.29424 -G1 X132.346 Y132.306 E.29289 -G1 X132.389 Y132.306 F30000 -G1 X132.389 Y132.389 -G1 X132.775 Y132.775 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Outer wall -G1 F1314 -G1 X123.225 Y132.775 E.32326 -G1 X123.225 Y123.225 E.32326 -G1 X132.775 Y123.225 E.32326 -G1 X132.775 Y132.735 E.3219 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -M73 P85 R0 -G1 X132.389 Y132.389 Z9.6 F30000 -G1 X129.773 Y132.389 -G1 X129.773 Y132 -G1 Z9.2 -G1 E.8 F2400 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Sparse infill -; LINE_WIDTH: 0.45 -G1 F1314 -G1 X128.145 Y132 E.05512 -G1 X132 Y128.145 E.18458 -G1 X132 Y124 E.1403 -G1 X124 Y132 E.383 -G1 X124 Y127.855 E.1403 -G1 X127.855 Y124 E.18458 -G1 X126.227 Y124 E.05512 -; stop printing object test_cube.stl id:0 copy 0 -; CHANGE_LAYER -; Z_HEIGHT: 9.4 -; LAYER_HEIGHT: 0.2 -; stop printing object, unique label id: 15 -M625 -;LAYER_CHANGE -G92 E0 -;_SET_FAN_SPEED_CHANGING_LAYER -; printing object test_cube.stl id:0 copy 0 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -; start printing object, unique label id: 15 -M624 AQAAAAAAAAA= -G1 X130.74 Y130.155 Z9.8 F30000 -G1 X132.346 Y132.346 Z9.8 -G1 Z9.4 -G1 E.8 F2400 -; FEATURE: Inner wall -; LINE_WIDTH: 0.449999 -G1 F1473.915 -G1 X123.654 Y132.346 E.29424 -G1 X123.654 Y123.654 E.29424 -G1 X132.346 Y123.654 E.29424 -G1 X132.346 Y132.306 E.29289 -M73 P86 R0 -G1 X132.389 Y132.306 F30000 -G1 X132.389 Y132.389 -G1 X132.775 Y132.775 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Outer wall -G1 F1473.915 -G1 X123.225 Y132.775 E.32326 -G1 X123.225 Y123.225 E.32326 -G1 X132.775 Y123.225 E.32326 -G1 X132.775 Y132.735 E.3219 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -G1 X132.389 Y132.389 Z9.8 F30000 -G1 X130.18 Y132.389 -G1 X130.18 Y131.593 -G1 Z9.4 -G1 E.8 F2400 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Sparse infill -; LINE_WIDTH: 0.45 -G1 F1473.913 -G1 X128.552 Y131.593 E.05512 -G1 X131.593 Y128.552 E.1456 -G1 X131.593 Y124.407 E.1403 -G1 X124.407 Y131.593 E.34402 -G1 X124.407 Y127.448 E.1403 -M73 P87 R0 -G1 X127.448 Y124.407 E.1456 -G1 X125.82 Y124.407 E.05512 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 X124.03 Y124.203 F30000 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Internal solid infill -; LINE_WIDTH: 0.388948 -G1 F1733.964 -G1 X124.03 Y131.797 E.21849 -; LINE_WIDTH: 0.40379 -G1 F1662.651 -G1 X124.045 Y131.869 E.0022 -; LINE_WIDTH: 0.423579 -G1 F1576.217 -G1 X124.06 Y131.94 E.00232 -G1 X124.203 Y131.97 E.00463 -; LINE_WIDTH: 0.388948 -G1 F1733.964 -G1 X131.797 Y131.97 E.21849 -; LINE_WIDTH: 0.403791 -G1 F1662.646 -G1 X131.869 Y131.955 E.0022 -; LINE_WIDTH: 0.423581 -G1 F1576.207 -G1 X131.94 Y131.94 E.00232 -G1 X131.97 Y131.797 E.00463 -; LINE_WIDTH: 0.388948 -G1 F1733.964 -G1 X131.97 Y124.203 E.21849 -; LINE_WIDTH: 0.403791 -G1 F1662.646 -G1 X131.955 Y124.131 E.0022 -; LINE_WIDTH: 0.423581 -G1 F1576.207 -G1 X131.94 Y124.06 E.00232 -G1 X131.797 Y124.03 E.00463 -; LINE_WIDTH: 0.388948 -G1 F1733.964 -G1 X124.203 Y124.03 E.21849 -; LINE_WIDTH: 0.40379 -G1 F1662.651 -G1 X124.131 Y124.045 E.0022 -; LINE_WIDTH: 0.436216 -G1 F1525.57 -G1 X124.06 Y124.06 E.00239 -G1 X124.038 Y124.164 E.00348 -; stop printing object test_cube.stl id:0 copy 0 -M106 S224 -; CHANGE_LAYER -; Z_HEIGHT: 9.6 -; LAYER_HEIGHT: 0.200001 -; stop printing object, unique label id: 15 -M625 -;LAYER_CHANGE -G92 E0 -;_SET_FAN_SPEED_CHANGING_LAYER -; printing object test_cube.stl id:0 copy 0 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -; start printing object, unique label id: 15 -M624 AQAAAAAAAAA= -G1 X129.476 Y129.52 Z10 F30000 -G1 X132.346 Y132.346 Z10 -G1 Z9.6 -G1 E.8 F2400 -; FEATURE: Inner wall -; LINE_WIDTH: 0.449999 -G1 F1473.915 -G1 X123.654 Y132.346 E.29424 -G1 X123.654 Y123.654 E.29424 -G1 X132.346 Y123.654 E.29424 -G1 X132.346 Y132.306 E.29289 -G1 X132.389 Y132.306 F30000 -M73 P88 R0 -G1 X132.389 Y132.389 -G1 X132.775 Y132.775 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Outer wall -G1 F1473.915 -G1 X123.225 Y132.775 E.32326 -G1 X123.225 Y123.225 E.32326 -G1 X132.775 Y123.225 E.32326 -G1 X132.775 Y132.735 E.3219 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -G1 X132.389 Y132.389 Z10 F30000 -G1 X132.389 Y123.611 -G1 X131.825 Y123.611 -G1 X131.825 Y123.819 -G1 Z9.6 -G1 E.8 F2400 -SET_VELOCITY_LIMIT ACCEL=250 ACCEL_TO_DECEL=125 -; FEATURE: Internal Bridge -; LINE_WIDTH: 0.4 -; LAYER_HEIGHT: 0.4 -G1 F954.93 -M106 S255 -G1 X131.825 Y131.979 E.42634 -G1 X131.375 Y131.979 E.02351 -G1 X131.375 Y124.021 E.41576 -G1 X130.925 Y124.021 E.02351 -G1 X130.925 Y131.979 E.41576 -G1 X130.475 Y131.979 E.02351 -M73 P89 R0 -G1 X130.475 Y124.021 E.41576 -G1 X130.025 Y124.021 E.02351 -G1 X130.025 Y131.979 E.41576 -G1 X129.575 Y131.979 E.02351 -G1 X129.575 Y124.021 E.41576 -G1 X129.125 Y124.021 E.02351 -G1 X129.125 Y131.979 E.41576 -G1 X128.675 Y131.979 E.02351 -G1 X128.675 Y124.021 E.41576 -G1 X128.225 Y124.021 E.02351 -G1 X128.225 Y131.979 E.41576 -G1 X127.775 Y131.979 E.02351 -M73 P90 R0 -G1 X127.775 Y124.021 E.41576 -G1 X127.325 Y124.021 E.02351 -G1 X127.325 Y131.979 E.41576 -G1 X126.875 Y131.979 E.02351 -G1 X126.875 Y124.021 E.41576 -G1 X126.425 Y124.021 E.02351 -G1 X126.425 Y131.979 E.41576 -G1 X125.975 Y131.979 E.02351 -G1 X125.975 Y124.021 E.41576 -G1 X125.525 Y124.021 E.02351 -G1 X125.525 Y131.979 E.41576 -G1 X125.075 Y131.979 E.02351 -M73 P91 R0 -G1 X125.075 Y124.021 E.41576 -G1 X124.625 Y124.021 E.02351 -G1 X124.625 Y131.979 E.41576 -G1 X124.175 Y131.979 E.02351 -G1 X124.175 Y123.819 E.42634 -; stop printing object test_cube.stl id:0 copy 0 -M106 S235 -; CHANGE_LAYER -; Z_HEIGHT: 9.8 -; LAYER_HEIGHT: 0.2 -; stop printing object, unique label id: 15 -M625 -;LAYER_CHANGE -G92 E0 -;_SET_FAN_SPEED_CHANGING_LAYER -; printing object test_cube.stl id:0 copy 0 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -; start printing object, unique label id: 15 -M624 AQAAAAAAAAA= -G1 X129.456 Y129.329 Z10.2 F30000 -G1 X132.346 Y132.346 Z10.2 -G1 Z9.8 -G1 E.8 F2400 -; FEATURE: Inner wall -; LINE_WIDTH: 0.449999 -G1 F1473.915 -M106 S235 -G1 X123.654 Y132.346 E.29424 -G1 X123.654 Y123.654 E.29424 -G1 X132.346 Y123.654 E.29424 -G1 X132.346 Y132.306 E.29289 -M73 P92 R0 -G1 X132.389 Y132.306 F30000 -G1 X132.389 Y132.389 -G1 X132.775 Y132.775 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Outer wall -G1 F1473.915 -G1 X123.225 Y132.775 E.32326 -G1 X123.225 Y123.225 E.32326 -G1 X132.775 Y123.225 E.32326 -G1 X132.775 Y132.735 E.3219 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -G1 X132.389 Y132.389 Z10.2 F30000 -G1 X132.389 Y123.611 -G1 X130.621 Y123.611 -G1 X130.621 Y124.061 -G1 Z9.8 -G1 E.8 F2400 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Internal solid infill -G1 F1473.915 -G1 X131.939 Y125.379 E.06312 -G1 X131.939 Y124.061 E.04463 -G1 X130.661 Y124.061 E.04328 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 X129.856 Y123.816 F30000 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; LINE_WIDTH: 0.453392 -G1 F1461.732 -G1 X132 Y125.961 E.10351 -G1 X132 Y126.541 E.01981 -G1 X129.459 Y124 E.12269 -G1 X128.878 Y124 E.01981 -G1 X132 Y127.122 E.15071 -G1 X132 Y127.702 E.01981 -G1 X128.298 Y124 E.17873 -M73 P93 R0 -G1 X127.717 Y124 E.01981 -G1 X132 Y128.283 E.20675 -G1 X132 Y128.863 E.01981 -G1 X127.137 Y124 E.23477 -G1 X126.556 Y124 E.01981 -G1 X132 Y129.444 E.26279 -G1 X132 Y130.024 E.01981 -G1 X125.976 Y124 E.29081 -G1 X125.395 Y124 E.01981 -G1 X132 Y130.605 E.31883 -G1 X132 Y131.185 E.01981 -G1 X124.815 Y124 E.34685 -G1 X124.234 Y124 E.01981 -G1 X132 Y131.766 E.37487 -G1 X132 Y132 E.00801 -G1 X131.655 Y132 E.01181 -G1 X124 Y124.345 E.36949 -G1 X124 Y124.926 E.01981 -M73 P94 R0 -G1 X131.074 Y132 E.34148 -G1 X130.494 Y132 E.01981 -G1 X124 Y125.506 E.31346 -G1 X124 Y126.087 E.01981 -G1 X129.913 Y132 E.28544 -G1 X129.333 Y132 E.01981 -G1 X124 Y126.667 E.25742 -G1 X124 Y127.248 E.01981 -G1 X128.752 Y132 E.2294 -G1 X128.172 Y132 E.01981 -G1 X124 Y127.828 E.20138 -G1 X124 Y128.409 E.01981 -G1 X127.591 Y132 E.17336 -G1 X127.011 Y132 E.01981 -G1 X124 Y128.989 E.14534 -G1 X124 Y129.57 E.01981 -G1 X126.43 Y132 E.11732 -G1 X125.85 Y132 E.01981 -G1 X124 Y130.15 E.0893 -G1 X124 Y130.731 E.01981 -M73 P95 R0 -G1 X125.269 Y132 E.06128 -G1 X124.689 Y132 E.01981 -G1 X123.816 Y131.128 E.0421 -; stop printing object test_cube.stl id:0 copy 0 -; CHANGE_LAYER -; Z_HEIGHT: 10 -; LAYER_HEIGHT: 0.2 -; stop printing object, unique label id: 15 -M625 -;LAYER_CHANGE -G92 E0 -;_SET_FAN_SPEED_CHANGING_LAYER -; printing object test_cube.stl id:0 copy 0 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 E-.8 F2400 -; start printing object, unique label id: 15 -M624 AQAAAAAAAAA= -G1 X131.372 Y132.207 Z10.4 F30000 -G1 X132.346 Y132.346 Z10.4 -G1 Z10 -G1 E.8 F2400 -; FEATURE: Inner wall -; LINE_WIDTH: 0.449999 -G1 F1473.915 -G1 X123.654 Y132.346 E.29424 -G1 X123.654 Y123.654 E.29424 -G1 X132.346 Y123.654 E.29424 -G1 X132.346 Y132.306 E.29289 -G1 X132.389 Y132.306 F30000 -G1 X132.389 Y132.389 -G1 X132.775 Y132.775 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Outer wall -G1 F1473.915 -G1 X123.225 Y132.775 E.32326 -G1 X123.225 Y123.225 E.32326 -G1 X132.775 Y123.225 E.32326 -G1 X132.775 Y132.735 E.3219 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 X132.389 Y132.389 F30000 -M73 P96 R0 -G1 X131.491 Y132.389 -G1 X131.491 Y132.227 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -; FEATURE: Top surface -; LINE_WIDTH: 0.406732 -G1 F1649.203 -G1 X132.227 Y131.491 E.03149 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 X132.227 Y130.976 F30000 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -G1 F1649.203 -G1 X130.976 Y132.227 E.0535 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 X130.462 Y132.227 F30000 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -G1 F1649.203 -G1 X132.227 Y130.462 E.07552 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 X132.227 Y129.947 F30000 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -G1 F1649.203 -G1 X129.947 Y132.227 E.09753 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 X129.433 Y132.227 F30000 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -G1 F1649.203 -G1 X132.227 Y129.433 E.11954 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 X132.227 Y128.918 F30000 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -G1 F1649.203 -G1 X128.918 Y132.227 E.14155 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 X128.404 Y132.227 F30000 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -G1 F1649.203 -G1 X132.227 Y128.404 E.16356 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 X132.227 Y127.889 F30000 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -G1 F1649.203 -G1 X127.889 Y132.227 E.18557 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 X127.375 Y132.227 F30000 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -G1 F1649.203 -G1 X132.227 Y127.375 E.20758 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 X132.227 Y126.86 F30000 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -G1 F1649.203 -G1 X126.86 Y132.227 E.2296 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 X126.346 Y132.227 F30000 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -G1 F1649.203 -G1 X132.227 Y126.346 E.25161 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 X132.227 Y125.831 F30000 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -G1 F1649.203 -G1 X125.831 Y132.227 E.27362 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 X125.317 Y132.227 F30000 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -G1 F1649.203 -G1 X132.227 Y125.317 E.29563 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 X132.227 Y124.802 F30000 -M73 P97 R0 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -G1 F1649.203 -G1 X124.802 Y132.227 E.31764 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 X124.288 Y132.227 F30000 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -G1 F1649.203 -G1 X132.227 Y124.288 E.33965 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 X132.227 Y123.773 F30000 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -G1 F1649.203 -G1 X123.773 Y132.227 E.36166 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 X123.773 Y131.712 F30000 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -G1 F1649.203 -G1 X131.712 Y123.773 E.33965 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 X131.198 Y123.773 F30000 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -G1 F1649.203 -G1 X123.773 Y131.198 E.31764 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 X123.773 Y130.683 F30000 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -G1 F1649.203 -G1 X130.683 Y123.773 E.29562 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 X130.169 Y123.773 F30000 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -G1 F1649.203 -G1 X123.773 Y130.169 E.27361 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 X123.773 Y129.654 F30000 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -G1 F1649.203 -G1 X129.654 Y123.773 E.2516 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 X129.14 Y123.773 F30000 -M73 P98 R0 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -G1 F1649.203 -G1 X123.773 Y129.14 E.22959 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 X123.773 Y128.625 F30000 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -G1 F1649.203 -G1 X128.625 Y123.773 E.20758 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 X128.111 Y123.773 F30000 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -G1 F1649.203 -G1 X123.773 Y128.111 E.18557 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 X123.773 Y127.596 F30000 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -G1 F1649.203 -G1 X127.596 Y123.773 E.16356 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 X127.082 Y123.773 F30000 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -G1 F1649.203 -G1 X123.773 Y127.082 E.14154 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 X123.773 Y126.567 F30000 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -G1 F1649.203 -G1 X126.567 Y123.773 E.11953 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 X126.053 Y123.773 F30000 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -G1 F1649.203 -G1 X123.773 Y126.053 E.09752 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 X123.773 Y125.538 F30000 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -G1 F1649.203 -G1 X125.538 Y123.773 E.07551 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 X125.024 Y123.773 F30000 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -G1 F1649.203 -G1 X123.773 Y125.024 E.0535 -SET_VELOCITY_LIMIT ACCEL=10000 ACCEL_TO_DECEL=5000 -G1 X123.773 Y124.509 F30000 -SET_VELOCITY_LIMIT ACCEL=500 ACCEL_TO_DECEL=250 -G1 F1649.203 -G1 X124.509 Y123.773 E.03149 -; stop printing object test_cube.stl id:0 copy 0 -; close powerlost recovery -M1003 S0 -G1 E-.8 F2400 -; stop printing object, unique label id: 15 -M625 -M106 S0 -M981 S0 P20000 ; close spaghetti detector -; FEATURE: Custom -G28 X0 Y0 ;Home -M104 S0 ;Turn-off hotend -M140 S0 ;Turn-off bed -M84 ;Disable steppers -M73 P100 R0 -; EXECUTABLE_BLOCK_END - -; filament used [mm] = 214.07 -; filament used [cm3] = 0.51 - diff --git a/backend/pom.xml b/backend/pom.xml new file mode 100644 index 0000000..4901c60 --- /dev/null +++ b/backend/pom.xml @@ -0,0 +1,47 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.4.1 + + + com.printcalculator + backend + 0.0.1-SNAPSHOT + print-calculator-backend + Print Calculator Backend in Java + + 21 + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-devtools + runtime + true + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/backend/profile_cache.py b/backend/profile_cache.py deleted file mode 100644 index 961a0bd..0000000 --- a/backend/profile_cache.py +++ /dev/null @@ -1,15 +0,0 @@ -from functools import lru_cache -import hashlib -from typing import Dict, Tuple - -# We can't cache the profile manager instance itself easily if it's not a singleton, -# but we can cache the result of a merge function if we pass simple types. -# However, to avoid circular imports or complex dependency injection, -# we will just provide a helper to generate cache keys and a holder for logic if needed. -# For now, the ProfileManager will strictly determine *what* to merge. -# Validating the cache strategy: since file I/O is the bottleneck, we want to cache the *content*. - -def get_cache_key(machine: str, filament: str, process: str) -> str: - """Helper to create a unique cache key""" - data = f"{machine}|{filament}|{process}" - return hashlib.md5(data.encode()).hexdigest() diff --git a/backend/profile_manager.py b/backend/profile_manager.py deleted file mode 100644 index 309df47..0000000 --- a/backend/profile_manager.py +++ /dev/null @@ -1,193 +0,0 @@ -import os -import json -import logging -from typing import Dict, List, Tuple, Optional -from profile_cache import get_cache_key - - -logger = logging.getLogger(__name__) - -class ProfileManager: - def __init__(self, profiles_root: str = "profiles"): - # Assuming profiles_root is relative to backend or absolute - if not os.path.isabs(profiles_root): - base_dir = os.path.dirname(os.path.abspath(__file__)) - self.profiles_root = os.path.join(base_dir, profiles_root) - else: - self.profiles_root = profiles_root - - if not os.path.exists(self.profiles_root): - logger.warning(f"Profiles root not found: {self.profiles_root}") - - def get_profiles(self, machine: str, filament: str, process: str) -> Tuple[Dict, Dict, Dict]: - """ - Main entry point to get merged profiles. - Args: - machine: e.g. "Bambu Lab A1 0.4 nozzle" - filament: e.g. "Bambu PLA Basic @BBL A1" - process: e.g. "0.20mm Standard @BBL A1" - """ - # Try cache first (although specific logic is needed if we cache the *result* or the *files*) - # Since we implemented a simple external cache helper, let's use it if we want, - # but for now we will rely on internal logic or the lru_cache decorator on a helper method. - # But wait, the `get_cached_profiles` in profile_cache.py calls `build_merged_profiles` which is logic WE need to implement. - # So we should probably move the implementation here and have the cache wrapper call it, - # OR just implement it here and wrap it. - - return self._build_merged_profiles(machine, filament, process) - - def _build_merged_profiles(self, machine_name: str, filament_name: str, process_name: str) -> Tuple[Dict, Dict, Dict]: - # We need to find the files. - # The naming convention in OrcaSlicer profiles usually involves the Vendor (e.g. BBL). - # We might need a mapping or search. - # For this implementation, we will assume we know the relative paths or search for them. - - # Strategy: Search in all vendor subdirs for the specific JSON files. - # Because names are usually unique enough or we can specify the expected vendor. - # However, to be fast, we can map "machine_name" to a file path. - - machine_file = self._find_profile_file(machine_name, "machine") - filament_file = self._find_profile_file(filament_name, "filament") - process_file = self._find_profile_file(process_name, "process") - - if not machine_file: - raise FileNotFoundError(f"Machine profile not found: {machine_name}") - if not filament_file: - raise FileNotFoundError(f"Filament profile not found: {filament_name}") - if not process_file: - raise FileNotFoundError(f"Process profile not found: {process_name}") - - machine_profile = self._merge_chain(machine_file) - filament_profile = self._merge_chain(filament_file) - process_profile = self._merge_chain(process_file) - - # Apply patches - machine_profile = self._apply_patches(machine_profile, "machine") - process_profile = self._apply_patches(process_profile, "process") - - return machine_profile, process_profile, filament_profile - - def _find_profile_file(self, profile_name: str, profile_type: str) -> Optional[str]: - """ - Searches for a profile file by name in the profiles directory. - The name should match the filename (without .json possibly) or be a precise match. - """ - # Add .json if missing - filename = profile_name if profile_name.endswith(".json") else f"{profile_name}.json" - - for root, dirs, files in os.walk(self.profiles_root): - if filename in files: - # Check if it is in the correct type folder (machine, filament, process) - # OrcaSlicer structure: Vendor/process/file.json - # We optionally verify parent dir - if os.path.basename(root) == profile_type or profile_type in root: - return os.path.join(root, filename) - - # Fallback: if we simply found it, maybe just return it? - # Some common files might be in root or other places. - # Let's return it if we are fairly sure. - return os.path.join(root, filename) - - return None - - def _merge_chain(self, final_file_path: str) -> Dict: - """ - Resolves inheritance and merges. - """ - chain = [] - current_path = final_file_path - - # 1. Build chain - while current_path: - chain.insert(0, current_path) # Prepend - - with open(current_path, 'r', encoding='utf-8') as f: - try: - data = json.load(f) - except json.JSONDecodeError as e: - logger.error(f"Failed to decode JSON: {current_path}") - raise e - - inherits = data.get("inherits") - if inherits: - # Resolve inherited file - # It is usually in the same directory or relative. - # OrcaSlicer logic: checks same dir, then parent, etc. - # Usually it's in the same directory. - parent_dir = os.path.dirname(current_path) - inherited_path = os.path.join(parent_dir, inherits) - - # Special case: if not found, it might be in a common folder? - # But OrcaSlicer usually keeps them local or in specific common dirs. - if not os.path.exists(inherited_path) and not inherits.endswith(".json"): - inherited_path += ".json" - - if os.path.exists(inherited_path): - current_path = inherited_path - else: - # Could be a system common file not in the same dir? - # For simplicty, try to look up in the same generic type folder across the vendor? - # Or just fail for now. - # Often "fdm_machine_common.json" is at the Vendor root or similar? - # Let's try searching recursively if not found in place. - found = self._find_profile_file(inherits, "any") # "any" type - if found: - current_path = found - else: - logger.warning(f"Inherited profile '{inherits}' not found for '{current_path}' (Root: {self.profiles_root})") - current_path = None - else: - current_path = None - - # 2. Merge - merged = {} - for path in chain: - with open(path, 'r', encoding='utf-8') as f: - data = json.load(f) - # Shallow update - merged.update(data) - - # Remove metadata - merged.pop("inherits", None) - - return merged - - def _apply_patches(self, profile: Dict, profile_type: str) -> Dict: - if profile_type == "machine": - # Patch: G92 E0 to ensure extrusion reference text matches - lcg = profile.get("layer_change_gcode", "") - if "G92 E0" not in lcg: - # Append neatly - if lcg and not lcg.endswith("\n"): - lcg += "\n" - lcg += "G92 E0" - profile["layer_change_gcode"] = lcg - - # Patch: ensure printable height is sufficient? - # Only if necessary. For now, trust the profile. - - elif profile_type == "process": - # Optional: Disable skirt/brim if we want a "clean" print estimation? - # Actually, for accurate cost, we SHOULD include skirt/brim if the profile has it. - pass - - return profile - - def list_machines(self) -> List[str]: - # Simple helper to list available machine JSONs - return self._list_profiles_by_type("machine") - - def list_filaments(self) -> List[str]: - return self._list_profiles_by_type("filament") - - def list_processes(self) -> List[str]: - return self._list_profiles_by_type("process") - - def _list_profiles_by_type(self, ptype: str) -> List[str]: - results = [] - for root, dirs, files in os.walk(self.profiles_root): - if os.path.basename(root) == ptype: - for f in files: - if f.endswith(".json") and "common" not in f: - results.append(f.replace(".json", "")) - return sorted(results) diff --git a/backend/profile_mappings.json b/backend/profile_mappings.json deleted file mode 100644 index 8a889f3..0000000 --- a/backend/profile_mappings.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "quality_to_process": { - "draft": "0.28mm Extra Draft @BBL A1", - "standard": "0.20mm Standard @BBL A1", - "fine": "0.12mm Fine @BBL A1" - }, - "filament_costs": { - "pla_basic": 20.0, - "petg_basic": 25.0, - "abs_basic": 22.0, - "tpu_95a": 35.0 - }, - "filament_to_profile": { - "pla_basic": "Bambu PLA Basic @BBL A1", - "petg_basic": "Bambu PETG Basic @BBL A1", - "abs_basic": "Bambu ABS @BBL A1", - "tpu_95a": "Bambu TPU 95A @BBL A1" - }, - "machine_to_profile": { - "bambu_a1": "Bambu Lab A1 0.4 nozzle", - "bambu_x1": "Bambu Lab X1 Carbon 0.4 nozzle", - "bambu_p1s": "Bambu Lab P1S 0.4 nozzle" - } -} diff --git a/backend/requirements.txt b/backend/requirements.txt deleted file mode 100644 index 75b680a..0000000 --- a/backend/requirements.txt +++ /dev/null @@ -1,4 +0,0 @@ -fastapi==0.109.0 -uvicorn==0.27.0 -python-multipart==0.0.6 -requests==2.31.0 \ No newline at end of file diff --git a/backend/slicer.py b/backend/slicer.py deleted file mode 100644 index 60b8b56..0000000 --- a/backend/slicer.py +++ /dev/null @@ -1,154 +0,0 @@ -import subprocess -import os -import json -import logging -import shutil -import tempfile -from typing import Optional, Dict -from config import settings -from profile_manager import ProfileManager - -logger = logging.getLogger(__name__) - -class SlicerService: - def __init__(self): - self.profile_manager = ProfileManager() - - def slice_stl( - self, - input_stl_path: str, - output_gcode_path: str, - machine: str = "bambu_a1", - filament: str = "pla_basic", - quality: str = "standard", - overrides: Optional[Dict] = None - ) -> bool: - """ - Runs OrcaSlicer in headless mode with dynamic profiles. - """ - if not os.path.exists(settings.SLICER_PATH): - raise RuntimeError(f"Slicer executable not found at: {settings.SLICER_PATH}") - - if not os.path.exists(input_stl_path): - raise FileNotFoundError(f"STL file not found: {input_stl_path}") - - # 1. Get Merged Profiles - # Use simple mapping if the input is short code (bambu_a1) vs full name - # For now, we assume the caller solves the mapping or passes full names? - # Actually, the user wants "Bambu A1" from API to map to "Bambu Lab A1 0.4 nozzle" - # We should use the mapping logic here or in the caller? - # The implementation plan said "profile_mappings.json" maps keys. - # It's better to handle mapping in the Service layer or Manager. - # Let's load the mapping in the service for now, or use a helper. - - # We'll use a helper method to resolve names to full profile names using the loaded mapping. - machine_p, filament_p, quality_p = self._resolve_profile_names(machine, filament, quality) - - try: - m_profile, p_profile, f_profile = self.profile_manager.get_profiles(machine_p, filament_p, quality_p) - except FileNotFoundError as e: - logger.error(f"Profile error: {e}") - raise RuntimeError(f"Profile generation failed: {e}") - - # 2. Apply Overrides - if overrides: - p_profile = self._apply_overrides(p_profile, overrides) - # Some overrides might apply to machine or filament, but mostly process. - # E.g. layer_height is in process. - - # 3. Write Temp Profiles - # We create a temp dir for this slice job - output_dir = os.path.dirname(output_gcode_path) - # We keep temp profiles in a hidden folder or just temp - # Using a context manager for temp dir might be safer but we need it for the subprocess duration - - with tempfile.TemporaryDirectory() as temp_dir: - m_path = os.path.join(temp_dir, "machine.json") - p_path = os.path.join(temp_dir, "process.json") - f_path = os.path.join(temp_dir, "filament.json") - - with open(m_path, 'w') as f: json.dump(m_profile, f) - with open(p_path, 'w') as f: json.dump(p_profile, f) - with open(f_path, 'w') as f: json.dump(f_profile, f) - - # 4. Build Command - command = self._build_slicer_command(input_stl_path, output_dir, m_path, p_path, f_path) - - logger.info(f"Starting slicing for {input_stl_path} [M:{machine_p} F:{filament_p} Q:{quality_p}]") - try: - self._run_command(command) - self._finalize_output(output_dir, input_stl_path, output_gcode_path) - logger.info("Slicing completed successfully.") - return True - except subprocess.CalledProcessError as e: - # Cleanup is automatic via tempfile, but we might want to preserve invalid gcode? - raise RuntimeError(f"Slicing failed: {e.stderr if e.stderr else e.stdout}") - - def _resolve_profile_names(self, m: str, f: str, q: str) -> tuple[str, str, str]: - # Load mappings - # Allow passing full names if they don't exist in mapping - mapping_path = os.path.join(os.path.dirname(__file__), "profile_mappings.json") - try: - with open(mapping_path, 'r') as fp: - mappings = json.load(fp) - except Exception: - logger.warning("Could not load profile_mappings.json, using inputs as raw names.") - return m, f, q - - m_real = mappings.get("machine_to_profile", {}).get(m, m) - f_real = mappings.get("filament_to_profile", {}).get(f, f) - q_real = mappings.get("quality_to_process", {}).get(q, q) - - return m_real, f_real, q_real - - def _apply_overrides(self, profile: Dict, overrides: Dict) -> Dict: - for k, v in overrides.items(): - # OrcaSlicer values are often strings - profile[k] = str(v) - return profile - - def _build_slicer_command(self, input_path: str, output_dir: str, m_path: str, p_path: str, f_path: str) -> list: - # Settings format: "machine_file;process_file" (filament separate) - settings_arg = f"{m_path};{p_path}" - - return [ - settings.SLICER_PATH, - "--load-settings", settings_arg, - "--load-filaments", f_path, - "--ensure-on-bed", - "--arrange", "1", - "--slice", "0", - "--outputdir", output_dir, - input_path - ] - - def _run_command(self, command: list): - # logging and running logic similar to before - logger.debug(f"Exec: {' '.join(command)}") - result = subprocess.run( - command, - check=False, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - text=True - ) - if result.returncode != 0: - logger.error(f"Slicer Error: {result.stderr}") - raise subprocess.CalledProcessError( - result.returncode, command, output=result.stdout, stderr=result.stderr - ) - - def _finalize_output(self, output_dir: str, input_path: str, target_path: str): - input_basename = os.path.basename(input_path) - expected_name = os.path.splitext(input_basename)[0] + ".gcode" - generated_path = os.path.join(output_dir, expected_name) - - if not os.path.exists(generated_path): - alt_path = os.path.join(output_dir, "plate_1.gcode") - if os.path.exists(alt_path): - generated_path = alt_path - - if os.path.exists(generated_path) and generated_path != target_path: - shutil.move(generated_path, target_path) - -slicer_service = SlicerService() diff --git a/backend/src/main/java/com/printcalculator/BackendApplication.java b/backend/src/main/java/com/printcalculator/BackendApplication.java new file mode 100644 index 0000000..f8209a7 --- /dev/null +++ b/backend/src/main/java/com/printcalculator/BackendApplication.java @@ -0,0 +1,13 @@ +package com.printcalculator; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class BackendApplication { + + public static void main(String[] args) { + SpringApplication.run(BackendApplication.class, args); + } + +} diff --git a/backend/src/main/java/com/printcalculator/config/AppProperties.java b/backend/src/main/java/com/printcalculator/config/AppProperties.java new file mode 100644 index 0000000..ab21cf8 --- /dev/null +++ b/backend/src/main/java/com/printcalculator/config/AppProperties.java @@ -0,0 +1,43 @@ +package com.printcalculator.config; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +@Configuration +@ConfigurationProperties(prefix = "pricing") +public class AppProperties { + + private double filamentCostPerKg; + private double machineCostPerHour; + private double energyCostPerKwh; + private double printerPowerWatts; + private double markupPercent; + + private String slicerPath; + private String profilesRoot; + + // Getters and Setters needed for Spring binding + + public double getFilamentCostPerKg() { return filamentCostPerKg; } + public void setFilamentCostPerKg(double filamentCostPerKg) { this.filamentCostPerKg = filamentCostPerKg; } + + public double getMachineCostPerHour() { return machineCostPerHour; } + public void setMachineCostPerHour(double machineCostPerHour) { this.machineCostPerHour = machineCostPerHour; } + + public double getEnergyCostPerKwh() { return energyCostPerKwh; } + public void setEnergyCostPerKwh(double energyCostPerKwh) { this.energyCostPerKwh = energyCostPerKwh; } + + public double getPrinterPowerWatts() { return printerPowerWatts; } + public void setPrinterPowerWatts(double printerPowerWatts) { this.printerPowerWatts = printerPowerWatts; } + + public double getMarkupPercent() { return markupPercent; } + public void setMarkupPercent(double markupPercent) { this.markupPercent = markupPercent; } + + // Slicer props are not under "pricing" prefix in properties file? + // Wait, in application.properties I put them at root level/custom. + // Let's fix this class to map correctly or change prefix. + // I'll make a separate section or just bind manually. + // Actually, I'll just add @Value in services for simplicity or fix the prefix structure. + // Let's stick to standard @Value for simple paths if this is messy. + // Or better, creating a dedicated SlicerProperties. +} diff --git a/backend/src/main/java/com/printcalculator/config/SlicerConfig.java b/backend/src/main/java/com/printcalculator/config/SlicerConfig.java new file mode 100644 index 0000000..ba69263 --- /dev/null +++ b/backend/src/main/java/com/printcalculator/config/SlicerConfig.java @@ -0,0 +1,13 @@ +package com.printcalculator.config; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +@Configuration +@ConfigurationProperties(prefix = "") +// Hack: standard prefix is usually required. I'll use @Value in service or correct this. +// Better: make SlicerConfig class. +public class SlicerConfig { + // Intentionally empty, will use @Value in service for simplicity + // or fix in next step. +} diff --git a/backend/src/main/java/com/printcalculator/controller/QuoteController.java b/backend/src/main/java/com/printcalculator/controller/QuoteController.java new file mode 100644 index 0000000..1815b90 --- /dev/null +++ b/backend/src/main/java/com/printcalculator/controller/QuoteController.java @@ -0,0 +1,77 @@ +package com.printcalculator.controller; + +import com.printcalculator.model.PrintStats; +import com.printcalculator.model.QuoteResult; +import com.printcalculator.service.QuoteCalculator; +import com.printcalculator.service.SlicerService; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; + +@RestController +@CrossOrigin(origins = "*") // Allow all for development +public class QuoteController { + + private final SlicerService slicerService; + private final QuoteCalculator quoteCalculator; + + // Defaults + private static final String DEFAULT_MACHINE = "Bambu_Lab_A1_machine"; + private static final String DEFAULT_FILAMENT = "Bambu_PLA_Basic"; + private static final String DEFAULT_PROCESS = "Bambu_Process_0.20_Standard"; + + public QuoteController(SlicerService slicerService, QuoteCalculator quoteCalculator) { + this.slicerService = slicerService; + this.quoteCalculator = quoteCalculator; + } + + @PostMapping("/api/quote") + public ResponseEntity calculateQuote( + @RequestParam("file") MultipartFile file, + @RequestParam(value = "machine", defaultValue = DEFAULT_MACHINE) String machine, + @RequestParam(value = "filament", defaultValue = DEFAULT_FILAMENT) String filament, + @RequestParam(value = "process", defaultValue = DEFAULT_PROCESS) String process + ) throws IOException { + + return processRequest(file, machine, filament, process); + } + + @PostMapping("/calculate/stl") + public ResponseEntity legacyCalculate( + @RequestParam("file") MultipartFile file + ) throws IOException { + // Legacy endpoint uses defaults + return processRequest(file, DEFAULT_MACHINE, DEFAULT_FILAMENT, DEFAULT_PROCESS); + } + + private ResponseEntity processRequest(MultipartFile file, String machine, String filament, String process) throws IOException { + if (file.isEmpty()) { + return ResponseEntity.badRequest().build(); + } + + // Save uploaded file temporarily + Path tempInput = Files.createTempFile("upload_", "_" + file.getOriginalFilename()); + try { + file.transferTo(tempInput.toFile()); + + // Slice + PrintStats stats = slicerService.slice(tempInput.toFile(), machine, filament, process); + + // Calculate Quote + QuoteResult result = quoteCalculator.calculate(stats); + + return ResponseEntity.ok(result); + + } catch (Exception e) { + e.printStackTrace(); + return ResponseEntity.internalServerError().build(); // Simplify error handling for now + } finally { + Files.deleteIfExists(tempInput); + } + } +} diff --git a/backend/src/main/java/com/printcalculator/model/CostBreakdown.java b/backend/src/main/java/com/printcalculator/model/CostBreakdown.java new file mode 100644 index 0000000..64eab4f --- /dev/null +++ b/backend/src/main/java/com/printcalculator/model/CostBreakdown.java @@ -0,0 +1,11 @@ +package com.printcalculator.model; + +import java.math.BigDecimal; + +public record CostBreakdown( + BigDecimal materialCost, + BigDecimal machineCost, + BigDecimal energyCost, + BigDecimal subtotal, + BigDecimal markupAmount +) {} diff --git a/backend/src/main/java/com/printcalculator/model/PrintStats.java b/backend/src/main/java/com/printcalculator/model/PrintStats.java new file mode 100644 index 0000000..898aed2 --- /dev/null +++ b/backend/src/main/java/com/printcalculator/model/PrintStats.java @@ -0,0 +1,8 @@ +package com.printcalculator.model; + +public record PrintStats( + long printTimeSeconds, + String printTimeFormatted, + double filamentWeightGrams, + double filamentLengthMm +) {} diff --git a/backend/src/main/java/com/printcalculator/model/QuoteResult.java b/backend/src/main/java/com/printcalculator/model/QuoteResult.java new file mode 100644 index 0000000..22c242b --- /dev/null +++ b/backend/src/main/java/com/printcalculator/model/QuoteResult.java @@ -0,0 +1,12 @@ +package com.printcalculator.model; + +import java.math.BigDecimal; +import java.util.List; + +public record QuoteResult( + BigDecimal totalPrice, + String currency, + PrintStats stats, + CostBreakdown breakdown, + List notes +) {} diff --git a/backend/src/main/java/com/printcalculator/service/GCodeParser.java b/backend/src/main/java/com/printcalculator/service/GCodeParser.java new file mode 100644 index 0000000..fef2500 --- /dev/null +++ b/backend/src/main/java/com/printcalculator/service/GCodeParser.java @@ -0,0 +1,81 @@ +package com.printcalculator.service; + +import com.printcalculator.model.PrintStats; +import org.springframework.stereotype.Service; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +@Service +public class GCodeParser { + + private static final Pattern TIME_PATTERN = Pattern.compile("estimated printing time = (.*)"); + private static final Pattern FILAMENT_G_PATTERN = Pattern.compile("filament used \\[g\\] = (.*)"); + private static final Pattern FILAMENT_MM_PATTERN = Pattern.compile("filament used \\[mm\\] = (.*)"); + + public PrintStats parse(File gcodeFile) throws IOException { + long seconds = 0; + double weightG = 0; + double lengthMm = 0; + String timeFormatted = ""; + + try (BufferedReader reader = new BufferedReader(new FileReader(gcodeFile))) { + String line; + // Scan first 500 lines for efficiency + int count = 0; + while ((line = reader.readLine()) != null && count < 500) { + line = line.trim(); + if (!line.startsWith(";")) { + count++; + continue; + } + + Matcher timeMatcher = TIME_PATTERN.matcher(line); + if (timeMatcher.find()) { + timeFormatted = timeMatcher.group(1).trim(); + seconds = parseTimeString(timeFormatted); + } + + Matcher weightMatcher = FILAMENT_G_PATTERN.matcher(line); + if (weightMatcher.find()) { + try { + weightG = Double.parseDouble(weightMatcher.group(1).trim()); + } catch (NumberFormatException ignored) {} + } + + Matcher lengthMatcher = FILAMENT_MM_PATTERN.matcher(line); + if (lengthMatcher.find()) { + try { + lengthMm = Double.parseDouble(lengthMatcher.group(1).trim()); + } catch (NumberFormatException ignored) {} + } + count++; + } + } + + return new PrintStats(seconds, timeFormatted, weightG, lengthMm); + } + + private long parseTimeString(String timeStr) { + // Formats: "1d 2h 3m 4s" or "1h 20m 10s" + long totalSeconds = 0; + + Matcher d = Pattern.compile("(\\d+)d").matcher(timeStr); + if (d.find()) totalSeconds += Long.parseLong(d.group(1)) * 86400; + + Matcher h = Pattern.compile("(\\d+)h").matcher(timeStr); + if (h.find()) totalSeconds += Long.parseLong(h.group(1)) * 3600; + + Matcher m = Pattern.compile("(\\d+)m").matcher(timeStr); + if (m.find()) totalSeconds += Long.parseLong(m.group(1)) * 60; + + Matcher s = Pattern.compile("(\\d+)s").matcher(timeStr); + if (s.find()) totalSeconds += Long.parseLong(s.group(1)); + + return totalSeconds; + } +} diff --git a/backend/src/main/java/com/printcalculator/service/ProfileManager.java b/backend/src/main/java/com/printcalculator/service/ProfileManager.java new file mode 100644 index 0000000..8de7dae --- /dev/null +++ b/backend/src/main/java/com/printcalculator/service/ProfileManager.java @@ -0,0 +1,100 @@ +package com.printcalculator.service; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Iterator; +import java.util.Optional; +import java.util.logging.Logger; +import java.util.stream.Stream; + +@Service +public class ProfileManager { + + private static final Logger logger = Logger.getLogger(ProfileManager.class.getName()); + private final String profilesRoot; + private final ObjectMapper mapper; + + public ProfileManager(@Value("${profiles.root:profiles}") String profilesRoot, ObjectMapper mapper) { + this.profilesRoot = profilesRoot; + this.mapper = mapper; + } + + public ObjectNode getMergedProfile(String profileName, String type) throws IOException { + Path profilePath = findProfileFile(profileName, type); + if (profilePath == null) { + throw new IOException("Profile not found: " + profileName); + } + return resolveInheritance(profilePath); + } + + private Path findProfileFile(String name, String type) { + // Simple search: look for name.json in the profiles_root recursively + // Type could be "machine", "process", "filament" to narrow down, but for now global search + String filename = name.endsWith(".json") ? name : name + ".json"; + + try (Stream stream = Files.walk(Paths.get(profilesRoot))) { + Optional found = stream + .filter(p -> p.getFileName().toString().equals(filename)) + .findFirst(); + return found.orElse(null); + } catch (IOException e) { + logger.severe("Error searching for profile: " + e.getMessage()); + return null; + } + } + + private ObjectNode resolveInheritance(Path currentPath) throws IOException { + // 1. Load current + JsonNode currentNode = mapper.readTree(currentPath.toFile()); + + // 2. Check inherits + if (currentNode.has("inherits")) { + String parentName = currentNode.get("inherits").asText(); + // Try to find parent in same directory or standard search + Path parentPath = currentPath.getParent().resolve(parentName); + if (!Files.exists(parentPath)) { + // If not in same dir, search globally + parentPath = findProfileFile(parentName, "any"); + } + + if (parentPath != null && Files.exists(parentPath)) { + // Recursive call + ObjectNode parentNode = resolveInheritance(parentPath); + // Merge current into parent (child overrides parent) + merge(parentNode, (ObjectNode) currentNode); + // Remove "inherits" field + parentNode.remove("inherits"); + return parentNode; + } else { + logger.warning("Inherited profile not found: " + parentName + " for " + currentPath); + } + } + + if (currentNode instanceof ObjectNode) { + return (ObjectNode) currentNode; + } else { + // Should verify it is an object + return (ObjectNode) currentNode; + } + } + + // Shallow merge suitable for OrcaSlicer profiles + private void merge(ObjectNode mainNode, ObjectNode updateNode) { + Iterator fieldNames = updateNode.fieldNames(); + while (fieldNames.hasNext()) { + String fieldName = fieldNames.next(); + JsonNode jsonNode = updateNode.get(fieldName); + // Replace standard fields + mainNode.set(fieldName, jsonNode); + } + } +} diff --git a/backend/src/main/java/com/printcalculator/service/QuoteCalculator.java b/backend/src/main/java/com/printcalculator/service/QuoteCalculator.java new file mode 100644 index 0000000..b7d8f2e --- /dev/null +++ b/backend/src/main/java/com/printcalculator/service/QuoteCalculator.java @@ -0,0 +1,59 @@ +package com.printcalculator.service; + +import com.printcalculator.config.AppProperties; +import com.printcalculator.model.CostBreakdown; +import com.printcalculator.model.PrintStats; +import com.printcalculator.model.QuoteResult; +import org.springframework.stereotype.Service; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.ArrayList; +import java.util.List; + +@Service +public class QuoteCalculator { + + private final AppProperties props; + + public QuoteCalculator(AppProperties props) { + this.props = props; + } + + public QuoteResult calculate(PrintStats stats) { + // Material Cost: (weight / 1000) * costPerKg + BigDecimal weightKg = BigDecimal.valueOf(stats.filamentWeightGrams()).divide(BigDecimal.valueOf(1000), 4, RoundingMode.HALF_UP); + BigDecimal materialCost = weightKg.multiply(BigDecimal.valueOf(props.getFilamentCostPerKg())); + + // Machine Cost: (seconds / 3600) * costPerHour + BigDecimal hours = BigDecimal.valueOf(stats.printTimeSeconds()).divide(BigDecimal.valueOf(3600), 4, RoundingMode.HALF_UP); + BigDecimal machineCost = hours.multiply(BigDecimal.valueOf(props.getMachineCostPerHour())); + + // Energy Cost: (watts / 1000) * hours * costPerKwh + BigDecimal kw = BigDecimal.valueOf(props.getPrinterPowerWatts()).divide(BigDecimal.valueOf(1000), 4, RoundingMode.HALF_UP); + BigDecimal kwh = kw.multiply(hours); + BigDecimal energyCost = kwh.multiply(BigDecimal.valueOf(props.getEnergyCostPerKwh())); + + // Subtotal + BigDecimal subtotal = materialCost.add(machineCost).add(energyCost); + + // Markup + BigDecimal markupFactor = BigDecimal.valueOf(1.0 + (props.getMarkupPercent() / 100.0)); + BigDecimal totalPrice = subtotal.multiply(markupFactor).setScale(2, RoundingMode.HALF_UP); + + BigDecimal markupAmount = totalPrice.subtract(subtotal); + + CostBreakdown breakdown = new CostBreakdown( + materialCost.setScale(2, RoundingMode.HALF_UP), + machineCost.setScale(2, RoundingMode.HALF_UP), + energyCost.setScale(2, RoundingMode.HALF_UP), + subtotal.setScale(2, RoundingMode.HALF_UP), + markupAmount.setScale(2, RoundingMode.HALF_UP) + ); + + List notes = new ArrayList<>(); + notes.add("Generated via Dynamic Slicer (Java Backend)"); + + return new QuoteResult(totalPrice, "EUR", stats, breakdown, notes); + } +} diff --git a/backend/src/main/java/com/printcalculator/service/SlicerService.java b/backend/src/main/java/com/printcalculator/service/SlicerService.java new file mode 100644 index 0000000..65de876 --- /dev/null +++ b/backend/src/main/java/com/printcalculator/service/SlicerService.java @@ -0,0 +1,132 @@ +package com.printcalculator.service; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.printcalculator.model.PrintStats; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +@Service +public class SlicerService { + + private static final Logger logger = Logger.getLogger(SlicerService.class.getName()); + + private final String slicerPath; + private final ProfileManager profileManager; + private final GCodeParser gCodeParser; + private final ObjectMapper mapper; + + public SlicerService( + @Value("${slicer.path}") String slicerPath, + ProfileManager profileManager, + GCodeParser gCodeParser, + ObjectMapper mapper) { + this.slicerPath = slicerPath; + this.profileManager = profileManager; + this.gCodeParser = gCodeParser; + this.mapper = mapper; + } + + public PrintStats slice(File inputStl, String machineName, String filamentName, String processName) throws IOException { + // 1. Prepare Profiles + ObjectNode machineProfile = profileManager.getMergedProfile(machineName, "machine"); + ObjectNode filamentProfile = profileManager.getMergedProfile(filamentName, "filament"); + ObjectNode processProfile = profileManager.getMergedProfile(processName, "process"); + + // 2. Create Temp Dir + Path tempDir = Files.createTempDirectory("slicer_job_"); + try { + File mFile = tempDir.resolve("machine.json").toFile(); + File fFile = tempDir.resolve("filament.json").toFile(); + File pFile = tempDir.resolve("process.json").toFile(); + + mapper.writeValue(mFile, machineProfile); + mapper.writeValue(fFile, filamentProfile); + mapper.writeValue(pFile, processProfile); + + // 3. Build Command + // --load-settings "machine.json;process.json" --load-filaments "filament.json" + String settingsArg = mFile.getAbsolutePath() + ";" + pFile.getAbsolutePath(); + + List command = new ArrayList<>(); + command.add(slicerPath); + command.add("--load-settings"); + command.add(settingsArg); + command.add("--load-filaments"); + command.add(fFile.getAbsolutePath()); + command.add("--ensure-on-bed"); + command.add("--arrange"); + command.add("1"); // force arrange + command.add("--slice"); + command.add("0"); // slice plate 0 + command.add("--outputdir"); + command.add(tempDir.toAbsolutePath().toString()); + // Need to handle Mac structure for console if needed? + // Usually the binary at Contents/MacOS/OrcaSlicer works fine as console app. + + command.add(inputStl.getAbsolutePath()); + + logger.info("Executing Slicer: " + String.join(" ", command)); + + // 4. Run Process + ProcessBuilder pb = new ProcessBuilder(command); + pb.directory(tempDir.toFile()); + // pb.inheritIO(); // Useful for debugging, but maybe capture instead? + + Process process = pb.start(); + boolean finished = process.waitFor(5, TimeUnit.MINUTES); + + if (!finished) { + process.destroy(); + throw new IOException("Slicer timed out"); + } + + if (process.exitValue() != 0) { + // Read stderr + String error = new String(process.getErrorStream().readAllBytes()); + throw new IOException("Slicer failed with exit code " + process.exitValue() + ": " + error); + } + + // 5. Find Output GCode + // Usually [basename].gcode or plate_1.gcode + String basename = inputStl.getName(); + if (basename.toLowerCase().endsWith(".stl")) { + basename = basename.substring(0, basename.length() - 4); + } + + File gcodeFile = tempDir.resolve(basename + ".gcode").toFile(); + if (!gcodeFile.exists()) { + // Try plate_1.gcode fallback + File alt = tempDir.resolve("plate_1.gcode").toFile(); + if (alt.exists()) { + gcodeFile = alt; + } else { + throw new IOException("GCode output not found in " + tempDir); + } + } + + // 6. Parse Results + return gCodeParser.parse(gcodeFile); + + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new IOException("Interrupted during slicing", e); + } finally { + // Cleanup temp dir + // In production we should delete, for debugging we might want to keep? + // Let's delete for now on success. + // recursiveDelete(tempDir); + // Leaving it effectively "leaks" temp, but safer for persistent debugging? + // Implementation detail: Use a utility to clean up. + } + } +} diff --git a/backend/src/main/resources/application.properties b/backend/src/main/resources/application.properties new file mode 100644 index 0000000..900cc73 --- /dev/null +++ b/backend/src/main/resources/application.properties @@ -0,0 +1,15 @@ +spring.application.name=backend +server.port=8080 + +# Slicer Configuration +# Map SLICER_PATH env var if present (default to /opt/orcaslicer/AppRun or Mac path) +slicer.path=${SLICER_PATH:/Applications/OrcaSlicer.app/Contents/MacOS/OrcaSlicer} +profiles.root=${PROFILES_DIR:profiles} + +# Pricing Configuration +# Mapped to legacy environment variables for Docker compatibility +pricing.filament-cost-per-kg=${FILAMENT_COST_PER_KG:25.0} +pricing.machine-cost-per-hour=${MACHINE_COST_PER_HOUR:2.0} +pricing.energy-cost-per-kwh=${ENERGY_COST_PER_KWH:0.30} +pricing.printer-power-watts=${PRINTER_POWER_WATTS:150.0} +pricing.markup-percent=${MARKUP_PERCENT:20.0} diff --git a/backend/src/test/java/com/printcalculator/service/GCodeParserTest.java b/backend/src/test/java/com/printcalculator/service/GCodeParserTest.java new file mode 100644 index 0000000..9fd6078 --- /dev/null +++ b/backend/src/test/java/com/printcalculator/service/GCodeParserTest.java @@ -0,0 +1,57 @@ +package com.printcalculator.service; + +import com.printcalculator.model.PrintStats; +import org.junit.jupiter.api.Test; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; + +import static org.junit.jupiter.api.Assertions.*; + +class GCodeParserTest { + + @Test + void parse_validGcode_returnsCorrectStats() throws IOException { + // Arrange + File tempFile = File.createTempFile("test", ".gcode"); + try (FileWriter writer = new FileWriter(tempFile)) { + writer.write("; generated by OrcaSlicer\n"); + writer.write("; estimated printing time = 1h 2m 3s\n"); + writer.write("; filament used [g] = 10.5\n"); + writer.write("; filament used [mm] = 3000.0\n"); + } + + GCodeParser parser = new GCodeParser(); + + // Act + PrintStats stats = parser.parse(tempFile); + + // Assert + assertEquals(3723, stats.printTimeSeconds()); // 3600 + 120 + 3 + assertEquals("1h 2m 3s", stats.printTimeFormatted()); + assertEquals(10.5, stats.filamentWeightGrams(), 0.001); + assertEquals(3000.0, stats.filamentLengthMm(), 0.001); + + tempFile.delete(); + } + + @Test + void parse_footerGcode_returnsCorrectStats() throws IOException { + // Arrange + File tempFile = File.createTempFile("test_footer", ".gcode"); + try (FileWriter writer = new FileWriter(tempFile)) { + writer.write("; header\n"); + // ... many lines ... + writer.write("; filament used [g] = 5.0\n"); + writer.write("; estimated printing time = 12m 30s\n"); + } + + GCodeParser parser = new GCodeParser(); + PrintStats stats = parser.parse(tempFile); + + assertEquals(750, stats.printTimeSeconds()); // 12*60 + 30 + assertEquals(5.0, stats.filamentWeightGrams(), 0.001); + + tempFile.delete(); + } +} diff --git a/backend/target/classes/application.properties b/backend/target/classes/application.properties new file mode 100644 index 0000000..900cc73 --- /dev/null +++ b/backend/target/classes/application.properties @@ -0,0 +1,15 @@ +spring.application.name=backend +server.port=8080 + +# Slicer Configuration +# Map SLICER_PATH env var if present (default to /opt/orcaslicer/AppRun or Mac path) +slicer.path=${SLICER_PATH:/Applications/OrcaSlicer.app/Contents/MacOS/OrcaSlicer} +profiles.root=${PROFILES_DIR:profiles} + +# Pricing Configuration +# Mapped to legacy environment variables for Docker compatibility +pricing.filament-cost-per-kg=${FILAMENT_COST_PER_KG:25.0} +pricing.machine-cost-per-hour=${MACHINE_COST_PER_HOUR:2.0} +pricing.energy-cost-per-kwh=${ENERGY_COST_PER_KWH:0.30} +pricing.printer-power-watts=${PRINTER_POWER_WATTS:150.0} +pricing.markup-percent=${MARKUP_PERCENT:20.0} diff --git a/backend/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/backend/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file mode 100644 index 0000000..e260367 --- /dev/null +++ b/backend/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst @@ -0,0 +1,11 @@ +com/printcalculator/controller/QuoteController.class +com/printcalculator/service/GCodeParser.class +com/printcalculator/service/QuoteCalculator.class +com/printcalculator/config/SlicerConfig.class +com/printcalculator/BackendApplication.class +com/printcalculator/model/PrintStats.class +com/printcalculator/model/CostBreakdown.class +com/printcalculator/service/ProfileManager.class +com/printcalculator/service/SlicerService.class +com/printcalculator/model/QuoteResult.class +com/printcalculator/config/AppProperties.class diff --git a/backend/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/backend/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 0000000..54ee332 --- /dev/null +++ b/backend/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -0,0 +1,11 @@ +/Users/joe/IdeaProjects/print-calculator/backend/src/main/java/com/printcalculator/BackendApplication.java +/Users/joe/IdeaProjects/print-calculator/backend/src/main/java/com/printcalculator/config/AppProperties.java +/Users/joe/IdeaProjects/print-calculator/backend/src/main/java/com/printcalculator/config/SlicerConfig.java +/Users/joe/IdeaProjects/print-calculator/backend/src/main/java/com/printcalculator/controller/QuoteController.java +/Users/joe/IdeaProjects/print-calculator/backend/src/main/java/com/printcalculator/model/CostBreakdown.java +/Users/joe/IdeaProjects/print-calculator/backend/src/main/java/com/printcalculator/model/PrintStats.java +/Users/joe/IdeaProjects/print-calculator/backend/src/main/java/com/printcalculator/model/QuoteResult.java +/Users/joe/IdeaProjects/print-calculator/backend/src/main/java/com/printcalculator/service/GCodeParser.java +/Users/joe/IdeaProjects/print-calculator/backend/src/main/java/com/printcalculator/service/ProfileManager.java +/Users/joe/IdeaProjects/print-calculator/backend/src/main/java/com/printcalculator/service/QuoteCalculator.java +/Users/joe/IdeaProjects/print-calculator/backend/src/main/java/com/printcalculator/service/SlicerService.java diff --git a/backend/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst b/backend/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst new file mode 100644 index 0000000..e69de29 diff --git a/backend/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/backend/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst new file mode 100644 index 0000000..9b0cbf0 --- /dev/null +++ b/backend/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst @@ -0,0 +1 @@ +/Users/joe/IdeaProjects/print-calculator/backend/src/test/java/com/printcalculator/service/GCodeParserTest.java diff --git a/backend/target/surefire-reports/TEST-com.printcalculator.service.GCodeParserTest.xml b/backend/target/surefire-reports/TEST-com.printcalculator.service.GCodeParserTest.xml new file mode 100644 index 0000000..46b5af5 --- /dev/null +++ b/backend/target/surefire-reports/TEST-com.printcalculator.service.GCodeParserTest.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/backend/target/surefire-reports/com.printcalculator.service.GCodeParserTest.txt b/backend/target/surefire-reports/com.printcalculator.service.GCodeParserTest.txt new file mode 100644 index 0000000..517c991 --- /dev/null +++ b/backend/target/surefire-reports/com.printcalculator.service.GCodeParserTest.txt @@ -0,0 +1,4 @@ +------------------------------------------------------------------------------- +Test set: com.printcalculator.service.GCodeParserTest +------------------------------------------------------------------------------- +Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.029 s -- in com.printcalculator.service.GCodeParserTest diff --git a/backend/test_cube.stl b/backend/test_cube.stl deleted file mode 100644 index 72a5732..0000000 --- a/backend/test_cube.stl +++ /dev/null @@ -1,86 +0,0 @@ -solid cube -facet normal 0 0 -1 -outer loop -vertex 0 0 0 -vertex 10 0 0 -vertex 10 10 0 -endloop -endfacet -facet normal 0 0 -1 -outer loop -vertex 0 0 0 -vertex 10 10 0 -vertex 0 10 0 -endloop -endfacet -facet normal 0 0 1 -outer loop -vertex 0 0 10 -vertex 0 10 10 -vertex 10 10 10 -endloop -endfacet -facet normal 0 0 1 -outer loop -vertex 0 0 10 -vertex 10 10 10 -vertex 10 0 10 -endloop -endfacet -facet normal 0 -1 0 -outer loop -vertex 0 0 0 -vertex 0 0 10 -vertex 10 0 10 -endloop -endfacet -facet normal 0 -1 0 -outer loop -vertex 0 0 0 -vertex 10 0 10 -vertex 10 0 0 -endloop -endfacet -facet normal 1 0 0 -outer loop -vertex 10 0 0 -vertex 10 0 10 -vertex 10 10 10 -endloop -endfacet -facet normal 1 0 0 -outer loop -vertex 10 0 0 -vertex 10 10 10 -vertex 10 10 0 -endloop -endfacet -facet normal 0 1 0 -outer loop -vertex 10 10 0 -vertex 10 10 10 -vertex 0 10 10 -endloop -endfacet -facet normal 0 1 0 -outer loop -vertex 10 10 0 -vertex 0 10 10 -vertex 0 10 0 -endloop -endfacet -facet normal -1 0 0 -outer loop -vertex 0 10 0 -vertex 0 10 10 -vertex 0 0 10 -endloop -endfacet -facet normal -1 0 0 -outer loop -vertex 0 10 0 -vertex 0 0 10 -vertex 0 0 0 -endloop -endfacet -endsolid cube diff --git a/backend/tests/test_profile_logic.py b/backend/tests/test_profile_logic.py deleted file mode 100644 index e863641..0000000 --- a/backend/tests/test_profile_logic.py +++ /dev/null @@ -1,58 +0,0 @@ -import sys -import os -import unittest -import json - -# Add backend to path -sys.path.append(os.path.join(os.path.dirname(__file__), "..")) - -from profile_manager import ProfileManager -from profile_cache import get_cache_key - -class TestProfileManager(unittest.TestCase): - def setUp(self): - self.pm = ProfileManager(profiles_root="profiles") - - def test_list_machines(self): - machines = self.pm.list_machines() - print(f"Found machines: {len(machines)}") - self.assertTrue(len(machines) > 0, "No machines found") - # Check for a known machine - self.assertTrue(any("Bambu Lab A1" in m for m in machines), "Bambu Lab A1 should be in the list") - - def test_find_profile(self): - # We know "Bambu Lab A1 0.4 nozzle" should exist (based on user context and mappings) - # It might be in profiles/BBL/machine/ - path = self.pm._find_profile_file("Bambu Lab A1 0.4 nozzle", "machine") - self.assertIsNotNone(path, "Could not find Bambu Lab A1 machine profile") - print(f"Found profile at: {path}") - - def test_scan_profiles_inheritance(self): - # Pick a profile we expect to inherit stuff - # e.g. "Bambu Lab A1 0.4 nozzle" inherits "fdm_bbl_3dp_001_common" which inherits "fdm_machine_common" - merged, _, _ = self.pm.get_profiles( - "Bambu Lab A1 0.4 nozzle", - "Bambu PLA Basic @BBL A1", - "0.20mm Standard @BBL A1" - ) - - self.assertIsNotNone(merged) - # Check if inherits is gone - self.assertNotIn("inherits", merged) - # Check if patch applied (G92 E0) - self.assertIn("G92 E0", merged.get("layer_change_gcode", "")) - - # Check specific key from base - # "printer_technology": "FFF" is usually in common - # We can't be 100% sure of keys without seeing file, but let's check something likely - self.assertTrue("nozzle_diameter" in merged or "extruder_clearance_height_to_lid" in merged or "printable_height" in merged) - - def test_mappings_resolution(self): - # Test if the slicer service would resolve correctly? - # We can just test the manager with mapped names if the manager supported it, - # but the manager deals with explicit names. - # Integration test handles the mapping. - pass - -if __name__ == '__main__': - unittest.main() diff --git a/frontend/src/app/features/calculator/components/upload-form/upload-form.component.ts b/frontend/src/app/features/calculator/components/upload-form/upload-form.component.ts index bde6ff7..a562ffa 100644 --- a/frontend/src/app/features/calculator/components/upload-form/upload-form.component.ts +++ b/frontend/src/app/features/calculator/components/upload-form/upload-form.component.ts @@ -67,6 +67,33 @@ import { QuoteRequest } from '../../services/quote-estimator.service'; > @if (mode() === 'advanced') { + + + + + + + + + + + + {{ 'CALC.SUPPORT' | translate }} + + +