
    'j                       d dl mZ d dlmZmZmZmZmZ d dlZd dl	Z
d dlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ d dl m!Z! d dl"m#Z# ddl$m%Z% dd	l&m'Z' dd
l(m)Z)m*Z* erd dl"m#Z# d dl+m,Z, g dZ-dZ.dZ/dZ0dZ1dtdZ2dudZ3dvdZ4dwdZ5dddxd!Z6dyd#Z7	 	 dzd{d+Z8d|d/Z9d|d0Z:e.e/edd1d}d;Z;ddedd1d}d<Z<d$e.e/e0edd=d~d@Z=e.e/edd1d}dAZ>e.e/ddBddCZ?e.e/ddBddDZ@e0ddEddFZA	 dddJZBddMZCddOZD	 dddTZEdddWZFdXdYdZdd]ZGdd^ZHdd_ZIdddaZJddcZKddfZLddhZMdddjZNddlZOddmZP	 dddrZQdddsZRdS )    )annotations)TYPE_CHECKINGIterableIteratorOptionalSequenceN)Vec2Vec3UVecZ_AXISOCSUCSMatrix44BoundingBoxConstructionEllipsecubic_bezier_from_ellipseBezier4PBezier3PBSplinereverse_bezier_curvesbulge_to_arclinear_vertex_spacinginscribe_circle_tangent_lengthcubic_bezier_arc_parameterscubic_bezier_bboxquadratic_bezier_bbox)mapbox_earcut_2d)EntityQuery   )Path)Command)	converternesting)GenericLayoutType)bboxprecise_bboxfit_paths_into_boxtransform_pathstransform_paths_to_ocsrender_lwpolylinesrender_polylines2drender_polylines3drender_linesrender_hatchesrender_mpolygonsrender_splines_and_polylinesadd_bezier4padd_bezier3padd_ellipseadd_2d_polyline
add_splineto_multi_pathsingle_pathshave_close_control_verticeslines_to_curve3lines_to_curve4filletpolygonal_filletchamferchamfer2triangulateis_rectangular{Gz?   g-C6?g|=pathsIterable[Path]returnr    c                V    t                      }| D ]}|                    |           |S )zReturns a multi-path object from all given paths and their sub-paths.
    Ignores paths without any commands (empty paths).
    )r    extend_multi_path)rC   
multi_pathps      J/DATA/AppData/hermes/venv/lib/python3.11/site-packages/ezdxf/path/tools.pyr6   r6   U   s9     J ( ($$Q''''    c              #  `   K   | D ](}|j         r|                                E d{V  $|V  )dS )zBYields all given paths and their sub-paths as single path objects.N)has_sub_paths	sub_paths)rC   rI   s     rJ   r7   r7   _   sW        ? 	{{}}$$$$$$$$GGGG	 rK   mr   
list[Path]c                     fd| D             S )a  Transform multiple path objects at once by transformation
    matrix `m`. Returns a list of the transformed path objects.

    Args:
        paths: iterable of :class:`Path` or :class:`Path2d` objects
        m: transformation matrix of type :class:`~ezdxf.math.Matrix44`

    c                :    g | ]}|                               S  )	transform).0rI   rO   s     rJ   
<listcomp>z#transform_paths.<locals>.<listcomp>q   s#    ***qAKKNN***rK   rS   )rC   rO   s    `rJ   r(   r(   h   s     +***E****rK   ocsr   c                |    |j                                         }|                                 t          | |          S )a  Transform multiple :class:`Path` objects at once from WCS to OCS.
    Returns a list of the transformed :class:`Path` objects.

    Args:
        paths: iterable of :class:`Path` or :class:`Path2d` objects
        ocs: OCS transformation of type :class:`~ezdxf.math.OCS`

    )matrixcopy	transposer(   )rC   rW   ts      rJ   r)   r)   t   s2     	
AKKMMM5!$$$rK   Ffastr   c                   t                      }| D ]c}|r(|                    |                                           ,t          |          }|j        r!|                    |j        |j        f           d|S )uU  Returns the :class:`~ezdxf.math.BoundingBox` for the given paths.

    Args:
        paths: iterable of :class:`Path` or :class:`Path2d` objects
        fast: calculates the precise bounding box of Bèzier curves if
            ``False``, otherwise uses the control points of Bézier curves to
            determine their bounding box.

    )r   extendcontrol_verticesr&   has_dataextminextmax)rC   r^   boxrI   bbs        rJ   r%   r%      s{     --C 3 3 	3JJq))++,,,,aB{ 3

BIry1222JrK   pathc           	     N   t          |           dk    rt                      S | j        }|g}|                                 D ]V}|j        t
          j        k    r|                    |j                   n|j        t
          j	        k    rdt          t          ||j        |j        |j        f                    }|                    |j                   |                    |j                   n|j        t
          j        k    r^t#          t%          ||j        |j        f                    }|                    |j                   |                    |j                   n/|j        t
          j        k    r|                    |j                   |j        }Xt          |          S )zIReturns the precise :class:`~ezdxf.math.BoundingBox` for the given paths.r   )lenr   startcommandstyper!   LINE_TOappendend	CURVE4_TOr   r   ctrl1ctrl2rc   rd   	CURVE3_TOr   r   ctrlMOVE_TO)rg   rj   pointscmdrf   s        rJ   r&   r&      sa   
4yyA~~}}JEF}}  8w&&MM#'""""X***"%CIsw?@@ B MM")$$$MM")$$$$X***&x#'0J'K'KLLBMM")$$$MM")$$$$X((MM#'"""vrK   Tsizetuple[float, float, float]uniformbool
source_boxOptional[BoundingBox]c                   t          |           } t          |           dk    r| S |t          | d          }n|}|j        r|j        dk    r| S t          |          }|dk    st          |          dk     rt          d          |rt          |j        |          \  }}}nt          |j        |          \  }}}t          j        |||          }	t          | |	          S )a  Scale the given `paths` to fit into a box of the given `size`,
    so that all path vertices are inside these borders.
    If `source_box` is ``None`` the default source bounding box is calculated
    from the control points of the `paths`.

    `Note:` if the target size has a z-size of 0, the `paths` are
    projected into the xy-plane, same is true for the x-size, projects into
    the yz-plane and the y-size, projects into and xz-plane.

    Args:
        paths: iterable of :class:`~ezdxf.path.Path` objects
        size: target box size as tuple of x-, y- and z-size values
        uniform: ``True`` for uniform scaling
        source_box: pass precalculated source bounding box, or ``None`` to
            calculate the default source bounding box from the control vertices

    r   NTr]   )r   r   r   zinvalid target size)listri   r%   rb   rx   r
   min
ValueError_get_uniform_scaling_get_non_uniform_scalingr   scaler(   )
rC   rx   rz   r|   current_boxtarget_sizesxsyszrO   s
             rJ   r'   r'      s    . KKE
5zzQ5t,,,  ;#3y#@#@t**Ki3{#3#3a#7#7./// M)+*:KHH
B-k.>LL
Br2r""A5!$$$rK   current_sizer
   r   c                   d}t           j        }| j        |k    r|j        |k    r|j        | j        z  }t           j        }| j        |k    r|j        |k    r|j        | j        z  }t           j        }| j        |k    r|j        |k    r|j        | j        z  }t          |||          }|t           j        u rt          d          |j        |k    r|nd}|j        |k    r|nd}|j        |k    r|nd}|||fS )Nư>zinternal errorr   )mathinfxyzr   ArithmeticError)r   r   TOLscale_xscale_yscale_zuniform_scales          rJ   r   r      s
   
ChG~ 3 3-,.0hG~ 3 3-,.0hG~ 3 3-,.0'22M  .///*}s22mmG*}s22mmG*}s22mmGGW$$rK   c                    d}d}| j         |k    r|j         | j         z  }d}| j        |k    r|j        | j        z  }d}| j        |k    r|j        | j        z  }|||fS )Nr   g      ?)r   r   r   )r   r   r   r   r   r   s         rJ   r   r      st    
CG~-,.0G~-,.0G~-,.0GW$$rK   distancesegments	extrusion
dxfattribslayoutr$   r   floatr   intr   r   r   c          	         t          t          j        |||||                    }|D ]}|                     |           t	          |          S )uA  Render the given `paths` into `layout` as
    :class:`~ezdxf.entities.LWPolyline` entities.
    The `extrusion` vector is applied to all paths, all vertices are projected
    onto the plane normal to this extrusion vector. The default extrusion vector
    is the WCS z-axis. The plane elevation is the distance from the WCS origin
    to the start point of the first path.

    Args:
        layout: the modelspace, a paperspace layout or a block definition
        paths: iterable of :class:`Path` or :class:`Path2d` objects
        distance:  maximum distance, see :meth:`Path.flattening`
        segments: minimum segment count per Bézier curve
        extrusion: extrusion vector for all paths
        dxfattribs: additional DXF attribs

    Returns:
        created entities in an :class:`~ezdxf.query.EntityQuery` object

    r   )r   r"   to_lwpolylines
add_entityr   )r   rC   r   r   r   r   lwpolylines
lwpolylines           rJ   r*   r*     m    8  !	
 	
 	
 K " & &
*%%%%{###rK   c          	         t          t          j        |||||                    }|D ]}|                     |           t	          |          S )uA  Render the given `paths` into `layout` as 2D
    :class:`~ezdxf.entities.Polyline` entities.
    The `extrusion` vector is applied to all paths, all vertices are projected
    onto the plane normal to this extrusion vector.The default extrusion vector
    is the WCS z-axis. The plane elevation is the distance from the WCS origin
    to the start point of the first path.

    Args:
        layout: the modelspace, a paperspace layout or a block definition
        paths: iterable of :class:`Path` or :class:`Path2d` objects
        distance:  maximum distance, see :meth:`Path.flattening`
        segments: minimum segment count per Bézier curve
        extrusion: extrusion vector for all paths
        dxfattribs: additional DXF attribs

    Returns:
        created entities in an :class:`~ezdxf.query.EntityQuery` object

    r   )r   r"   to_polylines2dr   r   )r   rC   r   r   r   r   polylines2d
polyline2ds           rJ   r+   r+   -  r   rK   	edge_pathr   r   g1_tolr   r   r   r   c                   t          t          j        |||||||                    }|D ]}	|                     |	           t	          |          S )u/  Render the given `paths` into `layout` as
    :class:`~ezdxf.entities.Hatch` entities.
    The `extrusion` vector is applied to all paths, all vertices are projected
    onto the plane normal to this extrusion vector. The default extrusion vector
    is the WCS z-axis. The plane elevation is the distance from the WCS origin
    to the start point of the first path.

    Args:
        layout: the modelspace, a paperspace layout or a block definition
        paths: iterable of :class:`Path` or :class:`Path2d`  objects
        edge_path: ``True`` for edge paths build of LINE and SPLINE edges,
            ``False`` for only LWPOLYLINE paths as boundary paths
        distance:  maximum distance, see :meth:`Path.flattening`
        segments: minimum segment count per Bézier curve to flatten polyline paths
        g1_tol: tolerance for G1 continuity check to separate SPLINE edges
        extrusion: extrusion vector for all paths
        dxfattribs: additional DXF attribs

    Returns:
        created entities in an :class:`~ezdxf.query.EntityQuery` object

    r   )r   r"   
to_hatchesr   r   )
r   rC   r   r   r   r   r   r   hatcheshatchs
             rJ   r.   r.   W  st    B !	
 	
 	

 
G  ! !%    wrK   c          	         t          t          j        |||||                    }|D ]}|                     |           t	          |          S )u  Render the given `paths` into `layout` as
    :class:`~ezdxf.entities.MPolygon` entities. The MPOLYGON entity supports
    only polyline boundary paths. All curves will be approximated.

    The `extrusion` vector is applied to all paths, all vertices are projected
    onto the plane normal to this extrusion vector. The default extrusion vector
    is the WCS z-axis. The plane elevation is the distance from the WCS origin
    to the start point of the first path.

    Args:
        layout: the modelspace, a paperspace layout or a block definition
        paths: iterable of :class:`Path` or :class:`Path2d` objects
        distance:  maximum distance, see :meth:`Path.flattening`
        segments: minimum segment count per Bézier curve to flatten polyline paths
        extrusion: extrusion vector for all paths
        dxfattribs: additional DXF attribs

    Returns:
        created entities in an :class:`~ezdxf.query.EntityQuery` object

    r   )r   r"   to_mpolygonsr   r   )r   rC   r   r   r   r   polygonspolygons           rJ   r/   r/     sm    < !	
 	
 	
 H  # #'""""x   rK   r   r   r   c                   t          t          j        ||||                    }|D ]}|                     |           t	          |          S )u  Render the given `paths` into `layout` as 3D
    :class:`~ezdxf.entities.Polyline` entities.

    Args:
        layout: the modelspace, a paperspace layout or a block definition
        paths: iterable of :class:`Path`or :class:`Path2d` objects
        distance:  maximum distance, see :meth:`Path.flattening`
        segments: minimum segment count per Bézier curve
        dxfattribs: additional DXF attribs

    Returns:
        created entities in an :class:`~ezdxf.query.EntityQuery` object

    r   )r   r"   to_polylines3dr   r   )r   rC   r   r   r   polylines3d
polyline3ds          rJ   r,   r,     sj    .  !		
 	
 	
 K " & &
*%%%%{###rK   c                   t          t          j        ||||                    }|D ]}|                     |           t	          |          S )u  Render the given `paths` into `layout` as
    :class:`~ezdxf.entities.Line` entities.

    Args:
        layout: the modelspace, a paperspace layout or a block definition
        paths: iterable of :class:`Path`or :class:`Path2d` objects
        distance:  maximum distance, see :meth:`Path.flattening`
        segments: minimum segment count per Bézier curve
        dxfattribs: additional DXF attribs

    Returns:
        created entities in an :class:`~ezdxf.query.EntityQuery` object

    r   )r   r"   to_linesr   r   )r   rC   r   r   r   lineslines          rJ   r-   r-     sj    , !		
 	
 	
 E     $urK   r   r   c                   t          t          j        |||                    }|D ]}|                     |           t	          |          S )a  Render the given `paths` into `layout` as :class:`~ezdxf.entities.Spline`
    and 3D :class:`~ezdxf.entities.Polyline` entities.

    Args:
        layout: the modelspace, a paperspace layout or a block definition
        paths: iterable of :class:`Path`or :class:`Path2d` objects
        g1_tol: tolerance for G1 continuity check
        dxfattribs: additional DXF attribs

    Returns:
        created entities in an :class:`~ezdxf.query.EntityQuery` object

    r   )r   r"   to_splines_and_polylinesr   r   )r   rC   r   r   entitiesentitys         rJ   r0   r0     sg    ( *!	
 	
 	
 H  " "&!!!!x   rK   ellipser   Nonec                    t          |j                  dk     rdS t          |           dk    r|r|j        | _        t          | t          ||                     dS )u  Add an elliptical arc as multiple cubic Bèzier-curves to the given
    `path`, use :meth:`~ezdxf.math.ConstructionEllipse.from_arc` constructor
    of class :class:`~ezdxf.math.ConstructionEllipse` to add circular arcs.

    Auto-detect the connection point to the given `path`, if neither the start-
    nor the end point of the ellipse is close to the path end point, a line from
    the path end point to the ellipse start point will be added automatically
    (see :func:`add_bezier4p`).

    By default, the start of an **empty** path is set to the start point of
    the ellipse, setting argument `reset` to ``False`` prevents this
    behavior.

    Args:
        path: :class:`~ezdxf.path.Path` object
        ellipse: ellipse parameters as :class:`~ezdxf.math.ConstructionEllipse`
            object
        segments: count of Bèzier-curve segments, at least one segment for
            each quarter (pi/2), ``1`` for as few as possible.
        reset: set start point to start of ellipse if path is empty

    &.>Nr   )abs
param_spanri   start_pointrj   r1   r   )rg   r   r   resets       rJ   r3   r3     s]    2 7%%
4yyA~~%~(
0(CCDDDDDrK   curvesIterable[Bezier4P]c                    d}d}t          |          }t          |          sdS |d         j        d         }| j                            |          rt          |          }|D ]}|j        \  }}}}|                    | j                  s|                     |           |                    |||          r.|                    |||          r|                     |           |                     |||           dS )u;  Add multiple cubic Bèzier-curves to the given `path`.

    Auto-detect the connection point to the given `path`, if neither the start-
    nor the end point of the curves is close to the path end point, a line from
    the path end point to the start point of the first curve will be added
    automatically.

    V瞯<        Nrel_tolabs_tol)r   ri   control_pointsro   iscloser   line_to	curve4_to)	rg   r   r   r   ro   curverj   rq   rr   s	            rJ   r1   r1   ;  s%    GG&\\Fv;; 
*
#B
'Cx /&v.. . .#(#7 ueS}}TX&& 	 LL ===AA 	.ckk7G GR G
 G
 	. LLNN3u----. .rK   Iterable[Bezier3P]c                   d}d}t          |          }t          |          sdS |d         j        d         }| j                            |          rt          |          }|D ]}|j        \  }}}|                    | j        ||          s|                     |           |                    |||          s|                    |||          r|                     |           |                     ||           dS )u?  Add multiple quadratic Bèzier-curves to the given `path`.

    Auto-detect the connection point to the given `path`, if neither the start-
    nor the end point of the curves is close to the path end point, a line from
    the path end point to the start point of the first curve will be added
    automatically.

    r   r   Nr   r   )r   ri   r   ro   r   r   r   	curve3_to)rg   r   r   r   ro   r   rj   rt   s           rJ   r2   r2   \  s%    GG&\\Fv;; 
*
#B
'Cx /&v.. 
& 
& /tS}}TXw}HH 	 LL==w=@@ 	&CKK'7 EP E
 E
 	& LLNN3%%%%
& 
&rK   rv   Iterable[Sequence[float]]close	elevationc                "    d fd}t                     rt          d	          d
}d}|D ]c\  }	}
}t          |          dk     rd}t          |	|
          }|| _        |}|}9|r |||||           n                     |           |}|}d|r\ j                             j        t          d          s5|r | j         j        ||           n                      j                   |j	        s|r 
                    ||           d
S d
S )zYInternal API to add 2D polylines which may include bulges to an
    **empty** path.

    p1r
   p2bulger   r   r   c                   |                      |t          d          rd S t          j        |dz            }t	          | ||          \  }}}}|t          j        z  }|t          j        z  }||k    r|t          j        z  }t          t          j        |||dz                       }	g }
t          |          D ]}t          j        ||t          t          j        |	|                   t          j        |	|dz                                }|
                    t          t          |                               |
d         }|j        d         }|                     |t          d          rt#          |
          }
t%          |
           d S )Nr   r      r   )r   IS_CLOSE_TOLr   ceilr   taur   nplinspaceranger   from_arcr   degreesr`   r   r   r   r1   )r   r   r   r   num_bezcenterstart_angle	end_angleradiusanglesr   ir   curve0cp0rg   s                  rJ   bulge_toz!add_2d_polyline.<locals>.bulge_to  su   ::b,::: 	F)HqL))1=b"e1L1L.Y!DH,(	""!Ibk+y'A+FFGGw 	D 	DA)2VAY''VAE]++ G MM$8AABBCCCC#A&;;r<;;; 	3*622FT6"""""rK   zRequires an empty path.Nr   r   r   )r   r
   r   r
   r   r   r   r   )ri   r   r   r
   rj   r   r   ro   r   rT   to_wcs)rg   rv   r   rW   r   r   r   
prev_point
prev_bulger   r   r   points   `            rJ   r4   r4   |  sr   # # # # # #8 4yy 42333!%JJ  1eu::EQ

DJJJ 	 HZ
H====LL


 %TZ'',PQ'RR % 	%HTXtz:x@@@@LL$$$
} $	 $C#####$ $rK   spliner   c                    t          |           dk    r|r|                    d          | _        |j        dk    r-|j        s&|j        rd |                                D             }n|                    |          }t          | |           dS )u  Add a B-spline as multiple cubic Bèzier-curves.

    Non-rational B-splines of 3rd degree gets a perfect conversion to
    cubic Bézier curves with a minimal count of curve segments, all other
    B-spline require much more curve segments for approximation.

    Auto-detect the connection point to the given `path`, if neither the start-
    nor the end point of the B-spline is close to the path end point, a line
    from the path end point to the start point of the B-spline will be added
    automatically. (see :meth:`add_bezier4p`).

    By default, the start of an **empty** path is set to the start point of
    the spline, setting argument `reset` to ``False`` prevents this
    behavior.

    Args:
        path: :class:`~ezdxf.path.Path` object
        spline: B-spline parameters as :class:`~ezdxf.math.BSpline` object
        level: subdivision level of approximation segments
        reset: set start point to start of spline if path is empty

    r   r   c                ,    g | ]}t          |          S rS   )r   )rU   rv   s     rJ   rV   zadd_spline.<locals>.<listcomp>  s     OOOv(6""OOOrK   )levelN)	ri   r   rj   degreeis_rational
is_clampedbezier_decompositioncubic_bezier_approximationr1   )rg   r   r   r   r   s        rJ   r5   r5     s    . 4yyA~~%~\\!__
}&"49JOO1L1L1N1NOOO222??vrK   r   -q=r   abc                   t          fdt          |                                 |                                          D                       S )zBReturns ``True`` if the control vertices of given paths are close.c              3  N   K   | ]\  }}|                     |           V   dS )r   N)r   )rU   cp_acp_br   r   s      rJ   	<genexpr>z.have_close_control_vertices.<locals>.<genexpr>  sM        D$ 	T7G<<     rK   )allzipra   )r  r  r   r   s     ``rJ   r8   r8     se          a0022A4F4F4H4HII     rK   c                $    t          | d          S )u^   Replaces all lines by quadratic Bézier curves.
    Returns a new :class:`Path` instance.
    r   count_all_lines_to_curverg   s    rJ   r9   r9          t1----rK   c                $    t          | d          S )uZ   Replaces all lines by cubic Bézier curves.
    Returns a new :class:`Path` instance.
    rB   r  r  r  s    rJ   r:   r:     r  rK   r  c                   |dk    s|dk    sJ d|             |                                  }t          |          }|dk    rt                      S | j        }t          j        }t          | j                  }|D ]}|j        |k    r|                    |j                  r |dk    r|	                    |           |c S nt          ||j        |          }|dk    r$|                    |d         |d                    n@|                    |d         |d         |d                    n|	                    |           |j        }|S )	NrB   r   zinvalid count: r   r      )rt   )rq   rr   )rk   ri   r    rj   r!   rm   rl   r   ro   append_path_elementr   r   r   )	rg   r  cmdsrx   rj   r   new_pathrw   verticess	            rJ   r  r    sj   A::!%>u%>%>#==??Dt99DqyyvvJEoGDJH  8w}}SW%% 199 00555#OOO  1GGA::&&x{!&EEEE&& &qk&qk '     ((---OrK   tuple[Vec3, float, UCS]c                   | |z
                                   }||z
                                   }|                    |          s|                    |           rt          |                    |          }t	          |||          }|||z  z   }|                    |          }	|	                    |                                |          }
||
z   }t          ||
 |	          }|t          j        |z
  |fS )N)originuxuz)		normalizer   ZeroDivisionErrorangle_betweenr   crossr   r   pi)p0r   r   r   dir1dir2angletangent_lengtharc_start_pointlocal_z_axis
radius_vec
arc_centerucss                rJ   _get_local_fillet_ucsr1  %  s    G  DG  D||D  T\\4%00   t$$E3D$GGND>12O
 ::d##L##TE**44V<<J :-J
ZZKL
A
A
ACDGeOS00rK   Sequence[Vec3]r   c                   t          |           dk     rt          d          dk    rt          d           d t          | | dd                   D             }t          | d                   }t          ||dd                   D ]\  \  }}\  }}	 t	          |||          \  }}	}
n%# t
          $ r |                    |           Y Dw xY w|                    |           t          d|	          D ]Y}t          |
	                    fd|D                                 }|
                    |d	         |d         |d
                    Z|                    | d	                    |S )zReturns a :class:`Path` with circular fillets of given `radius` between
    straight line segments.

    Args:
        points: coordinates of the line segments
        radius: fillet radius

    r   )at least 3 not coincident points requiredr   invalid radius: c                    g | ]	\  }}||f
S rS   rS   rU   r'  r   s      rJ   rV   zfillet.<locals>.<listcomp>I       <<<&"bb"X<<<rK   r   Nc              3  "   K   | ]	}|z  V  
d S )NrS   )rU   vr   s     rJ   r  zfillet.<locals>.<genexpr>V  s'      0L0LV0L0L0L0L0L0LrK   r   r  )ri   r   r  r    r1  r#  r   r   tuplepoints_to_wcsr   )rv   r   r   rI   r'  r   r   p3r   r*  r0  params
bez_pointss    `           rJ   r;   r;   <  s    6{{QDEEE{{4F44555<<Cqrr
$;$;<<<EVAYA!%qrr33 F FR(2r	&;BB&O&O#K  	 	 	IIbMMMH	
 	
		+1!U;; 	F 	FFs000L0L0L0LV0L0L0LLLMMJKK
2
1z!}EEEE	F IIfRjHs   B..CCr*  c                |    t          d|          }t          t          | t          j        |z  z            d          S )NrB   r   )maxr   r   r   )r*  r  s     rJ   _segment_countrB  \  s3    5MMEs5DHu,-..222rK       c                   t          |           dk     rt          d          |dk    rt          d|           d t          | | dd                   D             }t          | d                   }t          ||dd                   D ]\  \  }}\  }}	 t	          ||||          \  }	}
}n%# t
          $ r |                    |           Y Dw xY wt          |
|          }|
|z  }t          |dz             D ]B}t          j
        ||z  |          }|                    |                    |                     C|                    | d                    |S )	a`  
    Returns a :class:`Path` with polygonal fillets of given `radius` between
    straight line segments. The `count` argument defines the vertex count of the
    fillet for a full circle.

    Args:
        points: coordinates of the line segments
        radius: fillet radius
        count: polygon vertex count for a full circle, minimum is 4

    r   r4  r   r5  c                    g | ]	\  }}||f
S rS   rS   r7  s      rJ   rV   z$polygonal_fillet.<locals>.<listcomp>q  r8  rK   r   Nr   )ri   r   r  r    r1  r#  r   rB  r   r
   
from_angler   )rv   r   r  r   rI   r'  r   r   r=  _r*  r0  r   deltar   r.  s                   rJ   r<   r<   a  s    6{{QDEEE{{4F44555<<Cqrr
$;$;<<<EVAYA!%qrr33 . .R(2r	1"b"fEEMAucc  	 	 	IIbMMMH	 "%// x!|$$ 	. 	.AUF;;JIIcjj,,----	. IIfRjHs   B--CClengthc                2   t          |           dk     rt          d          d t          | | dd                   D             }t          | d                   }t          ||dd                   D ]\  \  }}\  }}	 ||z
                                  }||z
                                  }	|                    |	          s|                    |	           rt          |                    |	          dz  }
t          |dz  t          j
        |
          z            }n%# t          $ r |                    |           Y w xY w|                    |||z  z              |                    ||	|z  z              
|                    | d                    |S )	z
    Returns a :class:`Path` with chamfers of given `length` between
    straight line segments.

    Args:
        points: coordinates of the line segments
        length: chamfer length

    r   r4  c                    g | ]	\  }}||f
S rS   rS   r7  s      rJ   rV   zchamfer.<locals>.<listcomp>  r8  rK   r   Nr   g       @r   )ri   r   r  r    r"  r   r#  r$  r   r   sinr   )rv   rI  r   rI   r'  r   r   r=  r(  r)  r*  r  s               rJ   r=   r=     s    6{{QDEEE<<Cqrr
$;$;<<<EVAYA!%qrr33 # #R(2r		G&&((DG&&((D||D!! (T\\4%%8%8 (''&&t,,s2EVc\TXe__455AA  	 	 	IIbMMMH	 	
		"q/"""			"q/""""IIfRjHs   ?BDE Ec                   t          |           dk     rt          d          d t          | | dd                   D             }t          | d                   }t          ||dd                   D ]\  \  }}\  }}	 ||z
                                  }	||z
                                  }
|	                    |
          s|	                    |
           rt          n%# t          $ r |                    |           Y w xY w|                    ||	|z  z              |                    ||
|z  z              |                    | d                    |S )aQ  
    Returns a :class:`Path` with chamfers at the given distances `a` and `b`
    from the segment points between straight line segments.

    Args:
        points: coordinates of the line segments
        a: distance of the chamfer start point to the segment point
        b: distance of the chamfer end point to the segment point

    r   z)at least 3 non-coincident points requiredc                    g | ]	\  }}||f
S rS   rS   r7  s      rJ   rV   zchamfer2.<locals>.<listcomp>  r8  rK   r   Nr   r   )ri   r   r  r    r"  r   r#  r   )rv   r  r  r   rI   r'  r   r   r=  r(  r)  s              rJ   r>   r>     sj    6{{QDEEE<<Cqrr
$;$;<<<EVAYA!%qrr33 # #R(2r	G&&((DG&&((D||D!! (T\\4%%8%8 (''(  	 	 	IIbMMMH	 	
		"q/"""			"q/""""IIfRjHs   >A CD D   max_sagittamin_segmentsIterator[Sequence[Vec2]]c              #     K   t          j        t          |                     D ]K}|d                                       }fd|dd         D             }t	          ||          E d{V  LdS )u  Tessellate nested 2D paths into triangle-faces. For 3D paths the
    projection onto the xy-plane will be triangulated.

    Args:
        paths: iterable of nested Path instances
        max_sagitta: maximum distance from the center of the curve to the
            center of the line segment between two approximation points to determine if
            a segment should be subdivided.
        min_segments: minimum segment count per Bézier curve

    r   c                <    g | ]}|                               S rS   )
flattening)rU   rI   rP  rQ  s     rJ   rV   ztriangulate.<locals>.<listcomp>  s'    NNNQk<88NNNrK   r   N)r#   group_pathsr7   rU  r   )rC   rP  rQ  r   exteriorholess    ``   rJ   r?   r?     s       &|E':':;; 5 51:((lCCNNNNN'!""+NNN#He44444444445 5rK   c                   |                                  }t          |          dk     rdS |d                             |d                   r|                                 t          |          dk    rdS |rC|d         |d         z
  }t	          |j                  dk     st	          |j                  dk     sdS |d                             |d                   }|d                             |d                   }t          j        ||          sdS |d                             |d                   }|d                             |d                   }t          j        ||          sdS |d                             |d                   }|d                             |d                   }t          j        ||          sdS d	S )
zReturns ``True`` if `path` is a rectangular quadrilateral (square or
    rectangle). If the argument `aligned` is ``True`` all sides of the
    quadrilateral have to be parallel to the x- and y-axis.
    rB   Fr   r   r   r  r  r   T)	ra   ri   r   popr   r   r   r   r   )rg   alignedrv   
first_sidev1v2s         rJ   r@   r@     s   
 ""$$F
6{{Quay$$ 


6{{au AY*
JL!!E))S->->-F-F5 
		F1I	&	&B			F1I	&	&B<B u			F1I	&	&B			F1I	&	&B<B u			F1I	&	&B			F1I	&	&B<B u4rK   )rC   rD   rE   r    )rC   rD   rE   rD   )rC   rD   rO   r   rE   rP   )rC   rD   rW   r   rE   rP   )rC   rD   rE   r   )rg   r    rE   r   )TN)
rC   rD   rx   ry   rz   r{   r|   r}   rE   rP   )r   r
   r   r
   )r   r$   rC   rD   r   r   r   r   r   r   rE   r   )r   r$   rC   rD   r   r{   r   r   r   r   r   r   r   r   rE   r   )
r   r$   rC   rD   r   r   r   r   rE   r   )r   r$   rC   rD   r   r   rE   r   )r   T)rg   r    r   r   rE   r   )rg   r    r   r   rE   r   )rg   r    r   r   rE   r   )r   )rg   r    rv   r   r   r{   rW   r   r   r   r   r   rE   r   )rB   T)rg   r    r   r   rE   r   )r  r    r  r    rE   r{   )rg   r    rE   r    )rB   )rg   r    r  r   rE   r    )rE   r  )rv   r2  r   r   rE   r    )r*  r   r  r   rE   r   )rC  )rv   r2  r   r   r  r   rE   r    )rv   r2  rI  r   rE   r    )rv   r2  r  r   r  r   rE   r    )rA   rO  )rC   rD   rP  r   rQ  r   rE   rR  )T)rg   r    rE   r{   )S
__future__r   typingr   r   r   r   r   r   numpyr   
ezdxf.mathr	   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   ezdxf.math.triangulationr   ezdxf.queryr   rg   r    rk   r!    r"   r#   ezdxf.eztypesr$   __all__MAX_DISTANCEMIN_SEGMENTSG1_TOLr   r6   r7   r(   r)   r%   r&   r'   r   r   r*   r+   r.   r/   r,   r-   r0   r3   r1   r2   r4   r5   r8   r9   r:   r  r1  r;   rB  r<   r=   r>   r?   r@   rS   rK   rJ   <module>rk     s   # " " " " "                                                             , 6 5 5 5 5 5 # # # # # #                             0''''''//////  > 	      	+ 	+ 	+ 	+% % % % ).      *   : (,	)% )% )% )% )%X% % % %*% % % %* # '$ '$ '$ '$ '$ '$\ '$ '$ '$ '$ '$ '$\ " .  .  .  .  .  . j # )! )! )! )! )! )!` # !$ !$ !$ !$ !$ !$P #            N ! ! ! ! ! !B AEE E E E E@. . . .B& & & &L G$ G$ G$ G$ G$T    D "&u     . . . .. . . .# # # # #L1 1 1 1.   @3 3 3 3
         F   @   @ KM5 5 5 5 5(" " " " " " "rK   