Skip to content

Commit

Permalink
getting there, miter limit not working, and needs to be sifted
Browse files Browse the repository at this point in the history
  • Loading branch information
oliverfunk committed Jun 18, 2024
1 parent 25a7132 commit b11bdb7
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 40 deletions.
51 changes: 24 additions & 27 deletions bluemira/geometry/_pyclipr_offset.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

import numpy as np
import numpy.typing as npt
import pyclipr
from pyclipr import ClipperOffset, EndType, JoinType

from bluemira.base.look_and_feel import bluemira_warn
from bluemira.geometry.coordinates import Coordinates, rotation_matrix_v1v2
Expand Down Expand Up @@ -86,25 +86,19 @@ def __init__(
self._coordinates = coordinates

# Create an offsetting object
pco = pyclipr.ClipperOffset()
pco = ClipperOffset()

pco.miterLimit = miter_limit
# pco.miterLimit = miter_limit
# Set the scale factor to convert to internal integer representation
pco.scaleFactor = 1000 # ?

match method:
case OffsetClipperMethodType.SQUARE:
pco.addPaths(
[clipr_path], pyclipr.JoinType.Square, pyclipr.EndType.Polygon
)
pco.addPaths([clipr_path], JoinType.Square, EndType.Polygon)
case OffsetClipperMethodType.ROUND:
pco.addPaths(
[clipr_path], pyclipr.JoinType.Round, pyclipr.EndType.Polygon
)
pco.addPaths([clipr_path], JoinType.Round, EndType.Polygon)
case OffsetClipperMethodType.MITER:
pco.addPaths(
[clipr_path], pyclipr.JoinType.Miter, pyclipr.EndType.Polygon
)
pco.addPaths([clipr_path], JoinType.Miter, EndType.Polygon)
self._pco = pco

@staticmethod
Expand All @@ -123,24 +117,34 @@ def _calculate_scale(path: np.ndarray, coordinates: Coordinates) -> float:
"Path is empty or only (0, 0)'s."
)

def _transform_offset_result(
self, result: list[npt.NDArray[np.float64]]
) -> list[Coordinates]:
def _transform_offset_result(self, result: npt.NDArray[np.float64]) -> Coordinates:
"""
Transforms the offset solution into a Coordinates object
"""
if not result:
if len(result) == 0 or np.all(result == 0):
raise GeometryError("Offset operation resulted in no geometry.")

com = self._coordinates.center_of_mass
norm_v = self._coordinates.normal_vector

res_coords_t = [pyclippath_to_coordinates(p) for p in result]
return [transform_coordinates_to_original(c, com, norm_v) for c in res_coords_t]
x, z = result.T

def perform(self, delta: float) -> list[Coordinates]:
res_coords_t = Coordinates({"x": x, "y": np.zeros(x.shape), "z": z})
return transform_coordinates_to_original(res_coords_t, com, norm_v)

def perform(self, delta: float) -> Coordinates:
delta = int(round(delta * self._coord_scale))
offset_result = self._pco.execute(delta)
if len(offset_result) == 1:
offset_result = offset_result[0]
elif len(offset_result) > 1:
bluemira_warn(
f"Offset operation with delta={delta} has produced multiple 'islands';"
" using the biggest one!"
)
offset_result = max(offset_result, key=len)
else:
raise GeometryError("Offset operation failed to produce any geometry.")
return self._transform_offset_result(offset_result)


Expand Down Expand Up @@ -179,14 +183,7 @@ def offset_clipper(
"""
tool = PyCliprOffsetter(coordinates, OffsetClipperMethodType(method), miter_limit)
result = tool.perform(delta)

if len(result) > 1:
bluemira_warn(
f"Offset operation with delta={delta} has produced multiple 'islands'; only"
" returning the biggest one!"
)

return result[0]
return result


def transform_coordinates_to_xz(
Expand Down
19 changes: 8 additions & 11 deletions conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,8 @@
"""

import os
from contextlib import suppress
from pathlib import Path
from unittest import mock

import matplotlib as mpl
import pytest

from bluemira.base.file import get_bluemira_path, try_get_bluemira_private_data_root
Expand Down Expand Up @@ -57,14 +54,14 @@ def pytest_configure(config):
"""
Configures pytest with the plotting and longrun command line options.
"""
if not config.getoption("--plotting-on"):
# We're not displaying plots so use a display-less backend
mpl.use("Agg")
# Disable CAD viewer by mocking out FreeCAD API's displayer.
# Note that if we use a new CAD backend, this must be changed.
with suppress(ImportError):
mock.patch("bluemira.codes._polyscope.ps").start()
mock.patch("bluemira.codes._freecadapi.show_cad").start()
# if not config.getoption("--plotting-on"):
# # We're not displaying plots so use a display-less backend
# mpl.use("Agg")
# # Disable CAD viewer by mocking out FreeCAD API's displayer.
# # Note that if we use a new CAD backend, this must be changed.
# with suppress(ImportError):
# mock.patch("bluemira.codes._polyscope.ps").start()
# mock.patch("bluemira.codes._freecadapi.show_cad").start()

options = {
"longrun": config.option.longrun,
Expand Down
5 changes: 3 additions & 2 deletions tests/geometry/test_pyclipper_offset.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
import pytest

from bluemira.base.file import get_bluemira_path
from bluemira.geometry._pyclipr_offset import offset_clipper
from bluemira.geometry._pyclipper_offset import offset_clipper
from bluemira.geometry._pyclipr_offset import offset_clipper as offset_clipper2
from bluemira.geometry.coordinates import Coordinates
from bluemira.geometry.error import GeometryError
from bluemira.geometry.tools import distance_to, make_polygon
Expand Down Expand Up @@ -63,7 +64,7 @@ def test_blanket_offset(self):
coordinates = Coordinates(data)
offsets = []
for m in ["miter", "square", "round"]: # round very slow...
offset_coordinates = offset_clipper(coordinates, 1.5, method=m)
offset_coordinates = offset_clipper2(coordinates, 1.5, method=m)
offsets.append(offset_coordinates)
# Too damn slow!!
# distance = self._calculate_offset(coordinates, offset_coordinates)
Expand Down

0 comments on commit b11bdb7

Please sign in to comment.