
    Og                        d Z ddlmZ ddlmZmZmZ ddlmZ ddl	m
Z
mZmZmZmZ erddlmZ ddlmZ  G d d	      Zy
)a	  
DXF R12 Splines
===============

DXF R12 supports 2d B-splines, but Autodesk do not document the usage in the
DXF Reference. The base entity for splines in DXF R12 is the POLYLINE entity.

Transformed Into 3D Space
-------------------------

The spline itself is always in a plane, but as any 2D entity, the spline can be
transformed into the 3D object by elevation, extrusion and thickness/width.

Open Quadratic Spline with Fit Vertices
-------------------------------------

Example: 2D_SPLINE_QUADRATIC.dxf
expected knot vector: open uniform
degree: 2
order: 3

POLYLINE:
flags (70): 4 = SPLINE_FIT_VERTICES_ADDED
smooth type (75): 5 = QUADRATIC_BSPLINE

Sequence of VERTEX
flags (70): SPLINE_VERTEX_CREATED = 8  # Spline vertex created by spline-fitting

This vertices are the curve vertices of the spline (fitted).

Frame control vertices appear after the curve vertices.

Sequence of VERTEX
flags (70): SPLINE_FRAME_CONTROL_POINT = 16

No control point at the starting point, but a control point at the end point,
last control point == last fit vertex

Closed Quadratic Spline with Fit Vertices
-----------------------------------------

Example: 2D_SPLINE_QUADRATIC_CLOSED.dxf
expected knot vector: closed uniform
degree: 2
order: 3

POLYLINE:
flags (70): 5 = CLOSED | SPLINE_FIT_VERTICES_ADDED
smooth type (75): 5 = QUADRATIC_BSPLINE

Sequence of VERTEX
flags (70): SPLINE_VERTEX_CREATED = 8  # Spline vertex created by spline-fitting

Frame control vertices appear after the curve vertices.

Sequence of VERTEX
flags (70): SPLINE_FRAME_CONTROL_POINT = 16


Open Cubic Spline with Fit Vertices
-----------------------------------

Example: 2D_SPLINE_CUBIC.dxf
expected knot vector: open uniform
degree: 3
order: 4

POLYLINE:
flags (70): 4 = SPLINE_FIT_VERTICES_ADDED
smooth type (75): 6 = CUBIC_BSPLINE

Sequence of VERTEX
flags (70): SPLINE_VERTEX_CREATED = 8  # Spline vertex created by spline-fitting

This vertices are the curve vertices of the spline (fitted).

Frame control vertices appear after the curve vertices.

Sequence of VERTEX
flags (70): SPLINE_FRAME_CONTROL_POINT = 16

No control point at the starting point, but a control point at the end point,
last control point == last fit vertex

Closed Curve With Extra Vertices Created
----------------------------------------

Example: 2D_FIT_CURVE_CLOSED.dxf

POLYLINE:
flags (70): 3 = CLOSED | CURVE_FIT_VERTICES_ADDED

Vertices with bulge values:

flags (70): 1 = EXTRA_VERTEX_CREATED
Vertex 70=0, Vertex 70=1, Vertex 70=0, Vertex 70=1

    )annotations)TYPE_CHECKINGIterableOptional)const)BSplineclosed_uniform_bsplineVec3UCSUVec)
BaseLayout)Polylinec                  \    e Zd ZdZ	 	 d	 	 	 	 	 ddZ	 d	 	 	 	 	 d	dZ	 	 	 d
	 	 	 	 	 	 	 ddZy)	R12Splinea  DXF R12 supports 2D B-splines, but Autodesk do not document the usage
    in the DXF Reference. The base entity for splines in DXF R12 is the POLYLINE
    entity. The spline itself is always in a plane, but as any 2D entity, the
    spline can be transformed into the 3D object by elevation and extrusion
    (:ref:`OCS`, :ref:`UCS`).

    This way it was possible to store the spline parameters in the DXF R12 file,
    to allow CAD applications to modify the spline parameters and rerender the
    B-spline afterward again as polyline approximation. Therefore, the result is
    not better than an approximation by the :class:`Spline` class, it is also
    just a POLYLINE entity, but maybe someone need exact this tool in the
    future.

    c                T    t        j                  |      | _        || _        || _        y)z
        Args:
            control_points: B-spline control frame vertices
            degree: degree of B-spline, only 2 and 3 is supported
            closed: ``True`` for closed curve

        N)r
   listcontrol_pointsdegreeclosed)selfr   r   r   s       [/var/www/html/public_html/myphp/venv/lib/python3.12/site-packages/ezdxf/render/r12spline.py__init__zR12Spline.__init__   s#     #ii7    Nc                    | j                   r%t        | j                  | j                  dz         }n$t	        | j                  | j                  dz         }|j                  |      }fd|D        }t        |      S )al  Approximate the B-spline by a polyline with `segments` line segments.
        If `ucs` is not ``None``, ucs defines an :class:`~ezdxf.math.UCS`, to
        transform the curve into :ref:`OCS`. The control points are placed
        xy-plane of the UCS, don't use z-axis coordinates, if so make sure all
        control points are in a plane parallel to the OCS base plane
        (UCS xy-plane), else the result is unpredictable and depends on the CAD
        application used to open the DXF file - it may crash.

        Args:
            segments: count of line segments for approximation, vertex count is
                `segments` + 1
            ucs: :class:`~ezdxf.math.UCS` definition, control points in ucs
                coordinates

        Returns:
            list of vertices in :class:`~ezdxf.math.OCS` as
            :class:`~ezdxf.math.Vec3` objects

           )orderc              3  @   K   | ]  }j                  |        y w)N)to_ocs).0vertexucss     r   	<genexpr>z(R12Spline.approximate.<locals>.<genexpr>   s     Bv

6*Bs   )r   r	   r   r   r   approximater   )r   segmentsr!   splineverticess     `  r   r#   zR12Spline.approximate   sn    , ;;+##4;;?F T00aHF%%h/?BBHH~r   c                   |j                  g |      }|j                  }| j                  r||j                  z  }||j                  _        | j                  dk(  r|j                  }n'| j                  dk(  r|j                  }nt        d      ||j                  _
        ||j                  |j                  _        |j                  | j                  ||      |j                  j                  t         j"                  d       | j$                  }|;t'        |j)                  |            }dd|d   j*                  f|j                  _        |j                  ||j                  j                  t         j.                  d       |S )aT  Renders the B-spline into `layout` as 2D :class:`~ezdxf.entities.Polyline`
        entity. Use an :class:`~ezdxf.math.UCS` to place the 2D spline in the
        3D space, see :meth:`approximate` for more information.

        Args:
            layout: :class:`~ezdxf.layouts.BaseLayout` object
            segments: count of line segments for approximation, vertex count is
                `segments` + 1
            ucs: :class:`~ezdxf.math.UCS` definition, control points in ucs
                coordinates.
            dxfattribs: DXF attributes for :class:`~ezdxf.entities.Polyline`

        )points
dxfattribs      zinvalid degree of spline)layerflags)r)   r   )add_polyline2dSPLINE_FIT_VERTICES_ADDEDr   CLOSEDdxfr-   r   QUADRATIC_BSPLINECUBIC_BSPLINE
ValueErrorsmooth_typeuz	extrusionappend_verticesr#   r,   r   VTX_SPLINE_VERTEX_CREATEDr   r   points_to_ocsz	elevationVTX_SPLINE_FRAME_CONTROL_POINT)	r   layoutr$   r!   r)   polyliner-   r5   r   s	            r   renderzR12Spline.render   s_   ( ((z(J22;;X__$E";;!"44K[[A"00K788#.  ?%(VVHLL" 	  Xs+!++88 	! 	
 ,,?!#"3"3N"CDN&'N1,=,?,?%@HLL"  !++== 	! 	
 r   )r*   T)r   zIterable[UVec]r   intr   bool)(   N)r$   rA   r!   Optional[UCS]returnz
list[UVec])rC   NN)r>   r   r$   rA   r!   rD   rE   r   )__name__
__module____qualname____doc__r   r#   r@    r   r   r   r   o   s    $ 	&  	$ 8<'4	H !;; ; 	; 
;r   r   N)rI   
__future__r   typingr   r   r   ezdxf.lldxfr   
ezdxf.mathr   r	   r
   r   r   ezdxf.layoutsr   ezdxf.entitiesr   r   rJ   r   r   <module>rQ      s5   aD # 4 4  G G('} }r   