Ejemplo n.º 1
0
    def render_as_fit_points(
        self,
        layout: "BaseLayout",
        degree: int = 3,
        method: str = "chord",
        dxfattribs: dict = None,
    ) -> None:
        """Render a B-spline as 2D/3D :class:`~ezdxf.entities.Polyline`, where
        the definition points are fit points.

           - 2D spline vertices uses: :meth:`~ezdxf.layouts.BaseLayout.add_polyline2d`
           - 3D spline vertices uses: :meth:`~ezdxf.layouts.BaseLayout.add_polyline3d`

        Args:
            layout: :class:`~ezdxf.layouts.BaseLayout` object
            degree: degree of B-spline (order = `degree` + 1)
            method: "uniform", "distance"/"chord", "centripetal"/"sqrt_chord" or
                "arc" calculation method for parameter t
            dxfattribs: DXF attributes for :class:`~ezdxf.entities.Polyline`

        """
        spline = global_bspline_interpolation(
            self.points, degree=degree, method=method
        )
        vertices = list(spline.approximate(self.segments))
        if any(vertex.z != 0.0 for vertex in vertices):
            layout.add_polyline3d(vertices, dxfattribs=dxfattribs)
        else:
            layout.add_polyline2d(vertices, dxfattribs=dxfattribs)
Ejemplo n.º 2
0
def spline_interpolation(
    vertices: Iterable["Vertex"],
    degree: int = 3,
    method: str = "chord",
    subdivide: int = 4,
) -> List[Vec3]:
    """B-spline interpolation, vertices are fit points for the spline
    definition.

    Only method 'uniform', yields vertices at fit points.

    Args:
        vertices: fit points
        degree: degree of B-spline
        method: "uniform", "chord"/"distance", "centripetal"/"sqrt_chord" or
            "arc" calculation method for parameter t
        subdivide: count of sub vertices + 1, e.g. 4 creates 3 sub-vertices

    Returns: list of vertices

    """
    vertices = list(vertices)
    spline = global_bspline_interpolation(
        vertices, degree=degree, method=method
    )
    return list(spline.approximate(segments=(len(vertices) - 1) * subdivide))
Ejemplo n.º 3
0
def test_check_values():
    test_points = [(0., 0.), (1., 2.), (3., 1.), (5., 3.)]
    spline = global_bspline_interpolation(test_points, degree=3,
                                          method='distance')
    result = list(spline.approximate(49))
    assert len(result) == 50
    for p1, p2 in zip(result, expected):
        assert isclose(p1[0], p2[0], abs_tol=1e-6)
        assert isclose(p1[1], p2[1], abs_tol=1e-6)
Ejemplo n.º 4
0
 def from_fit_points(edge, fit_points):
     tangents = None
     if edge.start_tangent and edge.end_tangent:
         tangents = (wcs(edge.start_tangent), wcs(edge.end_tangent))
     return global_bspline_interpolation(
         fit_points,
         degree=edge.degree,
         tangents=tangents,
     )
Ejemplo n.º 5
0
def export_path(path):
    doc = ezdxf.new()
    msp = doc.modelspace()
    bbox = BoundingBox(path)
    msp.add_polyline3d(path, dxfattribs={'layer': 'Path', 'color': 2})
    spline = msp.add_spline(dxfattribs={'layer': 'B-spline', 'color': 1})
    curve = global_bspline_interpolation(path)
    spline.apply_construction_tool(curve)
    doc.set_modelspace_vport(center=bbox.center, height=bbox.size[1])
    doc.saveas(DIR / 'path1.dxf')
Ejemplo n.º 6
0
def test_bspline_interpolation(fit_points):
    spline = global_bspline_interpolation(fit_points, degree=3)
    assert len(spline.control_points) == len(fit_points)
    assert spline.t_array[0] == 0.
    assert spline.t_array[-1] == 1.
    assert len(spline.t_array) == len(fit_points)

    t_points = [spline.point(t) for t in spline.t_array]
    for p1, p2 in zip(t_points, fit_points):
        assert p1 == p2
Ejemplo n.º 7
0
def test_bspline_interpolation(fit_points):
    spline = global_bspline_interpolation(fit_points, degree=3, method="chord")
    assert len(spline.control_points) == len(fit_points)

    t_array = list(create_t_vector(fit_points, "chord"))
    assert t_array[0] == 0.0
    assert t_array[-1] == 1.0
    assert len(t_array) == len(fit_points)

    t_points = [spline.point(t) for t in t_array]
    assert close_vectors(t_points, fit_points)
Ejemplo n.º 8
0
def test_bspline_interpolation(fit_points):
    spline = global_bspline_interpolation(fit_points, degree=3, method='chord')
    assert len(spline.control_points) == len(fit_points)
    
    t_array = list(create_t_vector(fit_points, 'chord'))
    assert t_array[0] == 0.
    assert t_array[-1] == 1.
    assert len(t_array) == len(fit_points)

    t_points = [spline.point(t) for t in t_array]
    for p1, p2 in zip(t_points, fit_points):
        assert p1 == p2
Ejemplo n.º 9
0
 def add_spline_control_frame(
     self,
     fit_points: Iterable[Tuple[float, float]],
     degree: int = 3,
     method: str = "distance",
 ) -> "SplineEdge":
     bspline = global_bspline_interpolation(
         fit_points=fit_points, degree=degree, method=method
     )
     return self.add_spline(
         fit_points=fit_points,
         control_points=bspline.control_points,
         knot_values=bspline.knots(),
     )
def test_from_ezdxf_bspline_to_nurbs_python_curve_non_rational():
    bspline = global_bspline_interpolation([(0, 0), (0, 10), (10, 10), (10, 0)], degree=3)

    # to NURBS-Python
    curve = bspline.to_nurbs_python_curve()
    assert curve.degree == 3
    assert len(curve.ctrlpts) == 4
    assert len(curve.knotvector) == 8  # count + order
    assert curve.rational is False

    # and back to ezdxf
    spline = BSpline.from_nurbs_python_curve(curve)
    assert spline.degree == 3
    assert len(spline.control_points) == 4
    assert len(spline.knots()) == 8  # count + order
Ejemplo n.º 11
0
def profile_bspline_interpolation(count, path):
    for _ in range(count):
        global_bspline_interpolation(path)
Ejemplo n.º 12
0
def test_bspline_interpolation_first_derivatives(fit_points):
    tangents = estimate_tangents(fit_points)
    spline = global_bspline_interpolation(fit_points, degree=3,
                                          tangents=tangents)
    assert len(spline.control_points) == 2 * len(fit_points)
Ejemplo n.º 13
0
for p, t in zip(data, tangents):
    msp.add_line(p,
                 p + t,
                 dxfattribs={
                     'color': 5,
                     'layer': f'Estimated tangents ({METHOD})'
                 })

# local interpolation: a normalized tangent vector for each data point is required,
s = local_cubic_bspline_interpolation(
    data, tangents=[t.normalize() for t in tangents])
# or set argument 'method' for automatic tangent estimation, default method is '5-points' interpolation
# s = local_cubic_bspline_interpolation(data, method=METHOD)
msp.add_spline(dxfattribs={
    'color': 3,
    'layer': f'Local interpolation ({METHOD})'
}).apply_construction_tool(s)

# global interpolation: take first and last vector from 'tangents' as start- and end tangent
m1, m2 = estimate_end_tangent_magnitude(data, method='chord')
s = global_bspline_interpolation(data,
                                 tangents=(tangents[0].normalize(m1),
                                           tangents[-1].normalize(m2)))
msp.add_spline(dxfattribs={
    'color': 4,
    'layer': f'Global interpolation ({METHOD})'
}).apply_construction_tool(s)

doc.set_modelspace_vport(5, center=(4, 1))
doc.saveas(DIR / f'sine-wave-{METHOD}.dxf')
    msp = doc.modelspace()
    msp.add_lwpolyline(points, dxfattribs={'color': 5, 'layer': 'frame'})
    for p in points:
        msp.add_circle(p,
                       radius=0.1,
                       dxfattribs={
                           'color': 1,
                           'layer': 'frame'
                       })
    return doc, msp


# 1. Fit points from DXF file: Interpolation without any constraints
doc, msp = setup()
# First spline defined by control vertices interpolated from given fit points
s = global_bspline_interpolation(points, degree=3)
msp.add_spline(dxfattribs={
    'color': 4,
    'layer': 'Global Curve Interpolation'
}).apply_construction_tool(s)
# Second spline defined only by fit points as reference, does not match the
# BricsCAD interpolation.
spline = msp.add_spline(points,
                        degree=3,
                        dxfattribs={
                            'layer': 'BricsCAD B-spline',
                            'color': 2
                        })

zoom.extents(msp)
doc.saveas(DIR / 'concept-0-fit-points-only.dxf')
Ejemplo n.º 15
0
# Copyright (c) 2020, Manfred Moitzi
# License: MIT License

import ezdxf
from pathlib import Path
import matplotlib.pyplot as plt
from ezdxf.addons.drawing import Frontend, RenderContext
from ezdxf.addons.drawing.matplotlib_backend import MatplotlibBackend
from ezdxf.math import global_bspline_interpolation

wave = [(0.0, 0.0), (0.897597901, 0.78183148), (1.79519580, 0.97492791),
        (2.69279370, 0.433883739), (3.59039160, -0.43388373),
        (4.48798950, -0.97492791), (5.38558740, -0.78183148),
        (6.28318530, 0.0)]

DIR = Path('~/Desktop/Outbox').expanduser()
FILE = 'wave'
doc = ezdxf.new()
msp = doc.modelspace()
s = global_bspline_interpolation(wave)
msp.add_spline(dxfattribs={'color': 2}).apply_construction_tool(s)

fig = plt.figure()
ax = fig.add_axes([0, 0, 1, 1])
backend = MatplotlibBackend(ax)
Frontend(RenderContext(doc), backend).draw_layout(msp)
fig.savefig(DIR / f'{FILE}.png', dpi=300)
Ejemplo n.º 16
0
# Copyright (c) 2020, Manfred Moitzi
# License: MIT License
from typing import Iterable
import time
import ezdxf
from pathlib import Path
import math
from ezdxf.math import global_bspline_interpolation, linspace
from ezdxf.render import random_3d_path

DIR = Path("~/Desktop/Outbox").expanduser()

path = list(random_3d_path(100, max_step_size=10, max_heading=math.pi * 0.8))
spline = global_bspline_interpolation(path)


def profile_bspline_point_new(count, spline):
    for _ in range(count):
        for t in linspace(0, 1.0, 100):
            spline.point(t)


def profile_bspline_derivatives_new(count, spline):
    for _ in range(count):
        list(spline.derivatives(t=linspace(0, 1.0, 100)))


def profile(text, func, *args):
    t0 = time.perf_counter()
    func(*args)
    t1 = time.perf_counter()