示例#1
0
 def from_fit_points(edge: SplineEdge, fit_points):
     tangents = None
     if edge.start_tangent and edge.end_tangent:
         tangents = (
             wcs_tangent(edge.start_tangent),
             wcs_tangent(edge.end_tangent),
         )
     return fit_points_to_cad_cv(  # only a degree of 3 is supported
         fit_points,
         tangents=tangents,
     )
示例#2
0
 def construction_tool(self) -> BSpline:
     """Returns the construction tool :class:`ezdxf.math.BSpline`."""
     if self.control_point_count():
         weights = self.weights if len(self.weights) else None
         knots = self.knots if len(self.knots) else None
         return BSpline(
             control_points=self.control_points,
             order=self.dxf.degree + 1,
             knots=knots,
             weights=weights,
         )
     elif self.fit_point_count():
         tangents = None
         if self.dxf.hasattr("start_tangent") and self.dxf.hasattr(
                 "end_tangent"):
             tangents = [self.dxf.start_tangent, self.dxf.end_tangent]
         # SPLINE from fit points has always a degree of 3!
         return fit_points_to_cad_cv(
             self.fit_points,
             tangents=tangents,
         )
     else:
         raise ValueError(
             "Construction tool requires control- or fit points.")
start_tangent = Vec3.from_deg_angle(100)
end_tangent = Vec3.from_deg_angle(-100)

# Create SPLINE defined by fit points only:
spline = msp.add_spline(
    points,
    degree=2,  # degree is ignored by BricsCAD and AutoCAD, both use degree=3
    dxfattribs={
        'layer': 'SPLINE from fit points by CAD applications',
        'color': 2
    })
spline.dxf.start_tangent = start_tangent
spline.dxf.end_tangent = end_tangent

# Create SPLINE defined by control vertices from fit points:
s = fit_points_to_cad_cv(points, tangents=[start_tangent, end_tangent])
msp.add_spline(dxfattribs={
    'color': 4,
    'layer': 'SPLINE from control vertices by ezdxf'
}).apply_construction_tool(s)

zoom.extents(msp)
doc.saveas(DIR / 'fit_points_to_cad_cv_with_tangents.dxf')

# ------------------------------------------------------------------------------
# SPLINE from fit points WITHOUT given end tangents.
# ------------------------------------------------------------------------------
# Cubic Bézier curve Interpolation:
#
# This works only for cubic B-splines (the most common used B-spline), and
# BricsCAD/AutoCAD allow only a degree of 2 or 3 for SPLINE entities defined
示例#4
0
def virtual_leader_entities(leader: 'Leader') -> Iterable['DXFGraphic']:
    # Source: https://atlight.github.io/formats/dxf-leader.html
    # GDAL: DXF LEADER implementation:
    # https://github.com/OSGeo/gdal/blob/master/gdal/ogr/ogrsf_frmts/dxf/ogrdxf_leader.cpp
    # LEADER DXF Reference:
    # http://help.autodesk.com/view/OARX/2018/ENU/?guid=GUID-396B2369-F89F-47D7-8223-8B7FB794F9F3
    from ezdxf.entities import DimStyleOverride
    assert leader.dxftype() == 'LEADER'

    vertices = Vector.list(leader.vertices)  # WCS
    if len(vertices) < 2:
        # This LEADER entities should be removed by the auditor if loaded or
        # ignored at exporting, if created by an ezdxf-user (log).
        raise ValueError('More than 1 vertex required.')
    dxf = leader.dxf
    doc = leader.doc

    # Some default values depend on the measurement system
    # 0/1 = imperial/metric
    if doc:
        measurement = doc.header.get('$MEASUREMENT', 0)
    else:
        measurement = 0

    # Set default styling attributes values:
    dimtad = 1
    dimgap = 0.625 if measurement else 0.0625
    dimscale = 1.0
    dimclrd = dxf.color
    dimltype = dxf.linetype
    dimlwd = dxf.lineweight
    override = None

    if doc:  # get styling attributes from associated DIMSTYLE and/or XDATA override
        override = DimStyleOverride(cast('Dimension', leader))
        dimtad = override.get('dimtad', dimtad)
        dimgap = override.get('dimgap', dimgap)
        dimscale = override.get('dimscale', dimscale)
        if dimscale == 0.0:  # special but unknown meaning
            dimscale = 1.0
        dimclrd = override.get('dimclrd', dimclrd)
        dimltype = override.get('dimltype', dimltype)
        dimlwd = override.get('dimlwd', dimlwd)

    text_width = dxf.text_width
    hook_line_vector = Vector(dxf.horizontal_direction)
    has_text_annotation = dxf.annotation_type == 0

    if has_text_annotation and dxf.has_hookline:
        if dxf.hookline_direction == 1:
            hook_line_vector = -hook_line_vector
        if dimtad != 0 and text_width > 0:
            vertices.append(vertices[-1] + hook_line_vector *
                            (dimgap * dimscale + text_width))

    dxfattribs = leader.graphic_properties()
    dxfattribs['color'] = dimclrd
    dxfattribs['linetype'] = dimltype
    dxfattribs['lineweight'] = dimlwd

    if dxfattribs.get('color') == BYBLOCK:
        dxfattribs['color'] = dxf.block_color

    if dxf.path_type == 1:  # Spline
        start_tangent = (vertices[1] - vertices[0])
        end_tangent = (vertices[-1] - vertices[-2])
        bspline = fit_points_to_cad_cv(vertices,
                                       degree=3,
                                       tangents=[start_tangent, end_tangent])
        # noinspection PyUnresolvedReferences
        spline = factory.new('SPLINE',
                             doc=doc).apply_construction_tool(bspline)
        yield spline
    else:
        attribs = dict(dxfattribs)
        prev = vertices[0]
        for vertex in vertices[1:]:
            attribs['start'] = prev
            attribs['end'] = vertex
            yield factory.new(dxftype='LINE', dxfattribs=attribs, doc=doc)
            prev = vertex

    if dxf.has_arrowhead and override:
        arrow_name = override.get('dimldrblk', '')
        if arrow_name is None:
            return
        size = override.get('dimasz',
                            2.5 if measurement else 0.1875) * dimscale
        rotation = (vertices[0] - vertices[1]).angle_deg
        if doc and arrow_name in doc.blocks:
            dxfattribs.update({
                'name': arrow_name,
                'insert': vertices[0],
                'rotation': rotation,
                'xscale': size,
                'yscale': size,
                'zscale': size,
            })
            # create a virtual block reference
            insert = factory.new('INSERT', dxfattribs=dxfattribs, doc=doc)
            yield from insert.virtual_entities()
        else:  # render standard arrows
            yield from ARROWS.virtual_entities(
                name=arrow_name,
                insert=vertices[0],
                size=size,
                rotation=rotation,
                dxfattribs=dxfattribs,
            )
示例#5
0
if USE_C_EXT is False:
    print('C-extension disabled or not available. (pypy3?)')
    print('Cython implementation == Python implementation.')
    CBasis = Basis
    CEvaluator = Evaluator
else:
    # Cython implementations:
    from ezdxf.acc.bspline import Basis as CBasis, Evaluator as CEvaluator

from ezdxf.render import random_3d_path
from ezdxf.math import fit_points_to_cad_cv, linspace

SPLINE_COUNT = 20
POINT_COUNT = 20
splines = [
    fit_points_to_cad_cv(random_3d_path(POINT_COUNT)) for _ in range(SPLINE_COUNT)
]


class PySpline:
    def __init__(self, bspline, weights=None):
        self.basis = Basis(bspline.knots(), bspline.order, bspline.count, weights)
        self.evaluator = Evaluator(self.basis, bspline.control_points)

    def point(self, u):
        return self.evaluator.point(u)

    def points(self, t):
        return self.evaluator.points(t)

    def derivative(self, u, n):
示例#6
0
if USE_C_EXT is False:
    print("C-extension disabled or not available. (pypy3?)")
    print("Cython implementation == Python implementation.")
    CBasis = Basis
    CEvaluator = Evaluator
else:
    # Cython implementations:
    from ezdxf.acc.bspline import Basis as CBasis, Evaluator as CEvaluator

from ezdxf.render import random_3d_path
from ezdxf.math import fit_points_to_cad_cv, linspace

SPLINE_COUNT = 20
POINT_COUNT = 20
splines = [
    fit_points_to_cad_cv(random_3d_path(POINT_COUNT))
    for _ in range(SPLINE_COUNT)
]


class PySpline:
    def __init__(self, bspline, weights=None):
        self.basis = Basis(bspline.knots(), bspline.order, bspline.count,
                           weights)
        self.evaluator = Evaluator(self.basis, bspline.control_points)

    def point(self, u):
        return self.evaluator.point(u)

    def points(self, t):
        return self.evaluator.points(t)