Skip to content

Commit

Permalink
0.3.a2
Browse files Browse the repository at this point in the history
Ensure the EXCLUDE_OBJECT_DEFINE comes before any other GCode

This allows use of the defined objects in your PRINT_START macros

Move typing imports into TYPE_CHECKING blocks, which removes the
 need for installing typing_extensions or mypy_extensions at runtime
  • Loading branch information
kageurufu committed Sep 16, 2022
1 parent 3e45e34 commit dbd71f4
Show file tree
Hide file tree
Showing 10 changed files with 113 additions and 75 deletions.
15 changes: 11 additions & 4 deletions preprocess_cancellation/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,28 @@
* GCode with Marlin M486 tags
"""

from __future__ import annotations

import io
import logging
import os
import pathlib
import shutil
import tempfile
from typing import Any, Callable, Generator, Optional, TypeVar
from typing import TYPE_CHECKING

from .layers import LayerFilter
from .slicers import Preprocessor, identify_slicer_marker
from .slicers import identify_slicer_marker

logger = logging.getLogger(__name__)
if TYPE_CHECKING:
from typing import TYPE_CHECKING, Any, Callable, Generator, Optional, TypeVar

from .slicers import Preprocessor

PathLike = TypeVar("PathLike", str, pathlib.Path)

PathLike = TypeVar("PathLike", str, pathlib.Path)

logger = logging.getLogger(__name__)


def preprocess_pipe(infile: io.TextIOBase, **_kw: Any) -> Generator[str, None, None]:
Expand Down
28 changes: 16 additions & 12 deletions preprocess_cancellation/slicers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,30 @@

import io
import logging
from typing import Callable, Dict, Generator, Optional, Tuple

from mypy_extensions import Arg, DefaultNamedArg, NamedArg
from typing import TYPE_CHECKING

from ..layers import LayerFilter
from .cura import preprocess_cura_to_klipper
from .ideamaker import preprocess_ideamaker_to_klipper
from .m486 import preprocess_m486_to_klipper
from .slic3r import preprocess_slicer_to_klipper

logger = logging.getLogger(__name__)
if TYPE_CHECKING:
from typing import Callable, Dict, Generator, Optional, Tuple

from mypy_extensions import Arg, DefaultNamedArg, NamedArg

Preprocessor = Callable[
[
Arg(io.TextIOBase, "infile"),
DefaultNamedArg(bool, "use_shapely"),
NamedArg(LayerFilter, "layer_filter"),
],
Generator[str, None, None],
]
Preprocessor = Callable[
[
Arg(io.TextIOBase, "infile"),
DefaultNamedArg(bool, "use_shapely"),
NamedArg(LayerFilter, "layer_filter"),
],
Generator[str, None, None],
]


logger = logging.getLogger(__name__)


# Note:
Expand Down
5 changes: 4 additions & 1 deletion preprocess_cancellation/slicers/cura.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,15 @@ def preprocess_cura_to_klipper(

infile.seek(0)
for line in infile:
if line.strip() and not line.startswith(";"):
yield from exclude_object_header(known_objects.values())

yield line

if line.strip() and not line.startswith(";"):
break

# Inject custom marker
yield from exclude_object_header(known_objects.values())

current_object = None
for line in infile:
Expand Down
10 changes: 6 additions & 4 deletions preprocess_cancellation/slicers/ideamaker.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,15 @@ def preprocess_ideamaker_to_klipper(

current_object = None
for line in infile:
if line.strip() and not line.startswith(";"):
yield from exclude_object_header(known_objects.values())

yield line

if line.startswith(";TOTAL_NUM:"):
total_num = int(line.split(":")[1].strip())
assert total_num == len(known_objects)
yield from exclude_object_header(known_objects.values())
if line.strip() and not line.startswith(";"):
break

for line in infile:
if line.startswith(";PRINTING_ID:"):
printing_id = line.split(":")[1].strip()
if current_object:
Expand Down
17 changes: 11 additions & 6 deletions preprocess_cancellation/slicers/m486.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,16 +50,21 @@ def preprocess_m486_to_klipper(

infile.seek(0)
current_object = None
for line in infile:
if line.strip() and not line.startswith(";"):
yield from exclude_object_header(
[known_object for known_object in known_objects.values() if known_object.name != "-1"]
)

yield line

if line.strip() and not line.startswith(";"):
break

for line in infile:
if line.upper().startswith("M486"):
_, params = parse_gcode(line)

if "T" in params:
# Inject custom marker
yield from exclude_object_header(
[known_object for known_object in known_objects.values() if known_object.name != "-1"]
)

if "S" in params:
if current_object:
yield from exclude_object_end(current_object.name)
Expand Down
6 changes: 4 additions & 2 deletions preprocess_cancellation/slicers/slic3r.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,14 @@ def preprocess_slicer_to_klipper(

infile.seek(0)
for line in infile:
if line.strip() and not line.startswith(";"):
yield from exclude_object_header(known_objects.values())

yield line

if line.strip() and not line.startswith(";"):
break

yield from exclude_object_header(known_objects.values())

for line in infile:
yield line

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api"

[tool.poetry]
name = "preprocess_cancellation"
version = "0.3.a1"
version = "0.3.a2"
description = "GCode processor to add klipper exclude-object markers"
readme = "README.md"
authors = ["Franklyn Tackitt <[email protected]>"]
Expand Down
44 changes: 1 addition & 43 deletions tests/test_hulls.py
Original file line number Diff line number Diff line change
@@ -1,33 +1,9 @@
import math

from preprocess_cancellation.hulls import ShapelyHullTracker, SimpleHullTracker
from preprocess_cancellation.hulls import SimpleHullTracker
from preprocess_cancellation.types import Point


def test_shapely_hulls_simple():
hull_tracker = ShapelyHullTracker()

hull_tracker.add_point(Point(0.0, 0.0))
hull_tracker.add_point(Point(0.0, 1.0))
hull_tracker.add_point(Point(1.0, 1.0))
hull_tracker.add_point(Point(1.0, 0.0))

assert hull_tracker.exterior() == [(0.0, 0.0), (0.0, 1.0), (1.0, 1.0), (1.0, 0.0), (0.0, 0.0)]
assert hull_tracker.center() == (0.5, 0.5)


def test_shapely_hulls_rhombus():
hull_tracker = ShapelyHullTracker()

hull_tracker.add_point(Point(0.0, 5.0))
hull_tracker.add_point(Point(5.0, 10.0))
hull_tracker.add_point(Point(10.0, 5.0))
hull_tracker.add_point(Point(5.0, 0.0))

assert hull_tracker.exterior() == [(5.0, 0.0), (0.0, 5.0), (5.0, 10.0), (10.0, 5.0), (5.0, 0.0)]
assert hull_tracker.center() == (5.0, 5.0)


def test_plain_hulls_simple():
hull_tracker = SimpleHullTracker()
hull_tracker.add_point(Point(0.0, 0.0))
Expand Down Expand Up @@ -65,21 +41,3 @@ def test_plain_hulls_circle():

assert hull_tracker.exterior() == [(0.0, 0.0), (0.0, 10.0), (10.0, 10.0), (10.0, 0.0)]
assert hull_tracker.center() == (5.0, 5.0)


def test_shapely_hulls_circle():
hull_tracker = ShapelyHullTracker()
center = Point(5.0, 5.0)

for i in range(0, 360, 1):
hull_tracker.add_point(
Point(
center.x + 5 * math.cos(math.radians(i)),
center.y + 5 * math.sin(math.radians(i)),
)
)

# Yeah, its approxamitely a circle? All points are within 0.1mm of the expected circle
for x, y in hull_tracker.exterior():
assert 4.9 <= math.sqrt((5 - x) ** 2 + (5 - y) ** 2) <= 5.1
assert hull_tracker.center() == (5.0, 5.0)
55 changes: 55 additions & 0 deletions tests/test_hulls_shapely.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import math

import pytest

from preprocess_cancellation.hulls import ShapelyHullTracker
from preprocess_cancellation.types import Point

try:
import shapely.geometry # pylint: disable=unused-import
except ImportError:
pytest.skip("Requires shapely installed", allow_module_level=True)
except OSError:
pytest.skip("Requires libgeos installed", allow_module_level=True)


def test_shapely_hulls_simple():
hull_tracker = ShapelyHullTracker()

hull_tracker.add_point(Point(0.0, 0.0))
hull_tracker.add_point(Point(0.0, 1.0))
hull_tracker.add_point(Point(1.0, 1.0))
hull_tracker.add_point(Point(1.0, 0.0))

assert hull_tracker.exterior() == [(0.0, 0.0), (0.0, 1.0), (1.0, 1.0), (1.0, 0.0), (0.0, 0.0)]
assert hull_tracker.center() == (0.5, 0.5)


def test_shapely_hulls_rhombus():
hull_tracker = ShapelyHullTracker()

hull_tracker.add_point(Point(0.0, 5.0))
hull_tracker.add_point(Point(5.0, 10.0))
hull_tracker.add_point(Point(10.0, 5.0))
hull_tracker.add_point(Point(5.0, 0.0))

assert hull_tracker.exterior() == [(5.0, 0.0), (0.0, 5.0), (5.0, 10.0), (10.0, 5.0), (5.0, 0.0)]
assert hull_tracker.center() == (5.0, 5.0)


def test_shapely_hulls_circle():
hull_tracker = ShapelyHullTracker()
center = Point(5.0, 5.0)

for i in range(0, 360, 1):
hull_tracker.add_point(
Point(
center.x + 5 * math.cos(math.radians(i)),
center.y + 5 * math.sin(math.radians(i)),
)
)

# Yeah, its approxamitely a circle? All points are within 0.1mm of the expected circle
for x, y in hull_tracker.exterior():
assert 4.9 <= math.sqrt((5 - x) ** 2 + (5 - y) ** 2) <= 5.1
assert hull_tracker.center() == (5.0, 5.0)
6 changes: 4 additions & 2 deletions tests/test_preprocessor_with_shapely.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@
)

try:
import shapely # pylint: disable=unused-import
except ImportError:
import shapely.geometry # pylint: disable=unused-import
except (OSError, ImportError):
pytest.skip("Requires shapely installed", allow_module_level=True)
except OSError:
pytest.skip("Requires libgeos installed", allow_module_level=True)


gcode_path = pathlib.Path("./GCode")
Expand Down

0 comments on commit dbd71f4

Please sign in to comment.