
    ^j                        U d Z ddlZddlZddlmc mZ ddlmZ ddlm	Z	m
Z
 ddlmZ ddlmZmZ ddlmZmZ ddlmZ dd	lmZ dd
lmZmZ ddlZddlZddlmZ ddlmZmZ ddl m!Z! ddl"m#Z# ddl$m%Z% ddl&m'Z'm(Z( ddl)m*Z* ddl)m+Z+ ddl,m-Z-m.Z.m/Z/m0Z0m1Z1 ddl2m3Z3 ddl4m5Z5m6Z6 ddl7m8Z8m9Z9 ddl:m;Z; ddl<m=Z= ddl>m?Z? ddl@mAZAmBZB ddlCmDZDmEZEmFZFmGZG ddlHmIZImJZJmKZKmLZLmMZM ddlNmOZO ej                  ej                  z  ej                  z  ej                  z  ZTeeUd<   	  G d d       ZV G d! d"e	      ZW G d# d$eW      ZX G d% d&e	      ZY G d' d(e	      ZZd) Z[d* Z\d+eAd,eAd-e]fd.Z^ G d/ d0      Z_ G d1 d2e_      Z` G d3 d4e_      Zay)5a  
build123d exporters

name: exporters.py
by:   JRMobley
date: March 19th, 2023

desc:
    This python module contains exporters for SVG and DXF file formats.

license:

    Copyright 2023 JRMobley

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

        http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.

    N)copy)Enumauto)BytesIO)PathLikefsdecode)Any	TypeAlias)cast)warn)CallableIterable)zoom)RGBaci2rgb)Vec2)BRepLib)BRepTools_WireExplorer)Geom_BezierCurveGeom_BSplineCurve)GeomConvert)%GeomConvert_BSplineCurveToBezierCurve)gp_Ax2gp_Dirgp_Pntgp_Vecgp_XYZ)HLRAlgo_Projector)HLRBRep_AlgoHLRBRep_HLRToShape)TopAbs_OrientationTopAbs_ShapeEnum)TopExp_Explorer)TopoDS)Self)UnitGeomType)	TOLERANCEColorVector
VectorLike)BoundBoxCompoundEdgeWireShapeUNITS_PER_METERPathSegmentc                   J    e Zd ZdZdddddddededz  d	ed
edededz  fdZy)DrawingzA base drawing objectN)   r6   )r   r   r6   T)look_at	look_fromlook_upwith_hiddenfocusshaper8   r9   r:   r;   r<   c                   t               }|j                  |j                         |rt        |      n|j	                         }t        |      j                         }	t        |      j                         j                  |	      }
t        |j                         |	j                         |
j                               }|t        ||      }nt        |      }|j                  |       |j                          |j                          t        |      }g }|j                         }|j!                         s|j#                  |       |j%                         }|j!                         s|j#                  |       |j'                         }|j!                         s|j#                  |       g }|rb|j)                         }|j!                         s|j#                  |       |j+                         }|j!                         s|j#                  |       |D ]  }t-        j.                  |t0                |D ]  }t-        j.                  |t0                t3        t5        t6        |            | _        t3        t5        t6        |            | _        y N)r   Addwrappedr*   center
normalizedcrossr   to_pntto_dirr   	ProjectorUpdateHider    	VCompoundIsNullappendRg1LineVCompoundOutLineVCompound	HCompoundOutLineHCompoundr   BuildCurves3d_sr(   r-   mapr0   visible_lineshidden_lines)selfr=   r8   r9   r:   r;   r<   hlrprojection_originprojection_dirprojection_xcoordinate_system	projector
hlr_shapesvisiblevisible_sharp_edgesvisible_smooth_edgesvisible_contour_edgeshiddenhidden_sharp_edgeshidden_contour_edgesels                         L/opt/ringagent/.cad-venv/lib/python3.12/site-packages/build123d/exporters.py__init__zDrawing.__init__U   s    n/6F7OELLN	*557g11399.I"$$&(=(=(?ATATAV
 )*;UCI)*;<Ii 


',
(224"))+NN./)::<#**,NN/0 * ; ; =$++-NN01!+!5!5!7%,,.01#-#>#>#@ '..023  	3B##B	2	3 	3B##B	2	3 &c%&9:$S%78    )	__name__
__module____qualname____doc__r0   r+   boolfloatrf    rg   re   r5   r5   R   se     &* *' "@9@9 d"	@9
 @9 @9 @9 t|@9rg   r5   c                        e Zd ZdZed        Zy)AutoNameEnumzCAn enum class that automatically sets members' value to their name.c                     | S r?   rn   )namestartcountlast_valuess       re   _generate_next_value_z"AutoNameEnum._generate_next_value_   s    rg   N)rh   ri   rj   rk   staticmethodrv   rn   rg   re   rp   rp      s    M rg   rp   c                      e Zd ZdZ e       Z e       Z e       Z e       Z e       Z	 e       Z
 e       Z e       Z e       Z e       Z e       Z e       Z e       Z e       Z e       Z e       Z e       Z e       Z e       Z e       Z e       Z e       Z e       Z e       Z e       ZdZdZdZ dZ!dZ"dZ#dZ$d	Z%d
Z&dZ'dZ(dZ)dZ*dZ+y)LineTypez
Line TypesACAD_ISO02W100ACAD_ISO03W100ACAD_ISO04W100ACAD_ISO05W100ACAD_ISO06W100ACAD_ISO07W100ACAD_ISO08W100ACAD_ISO09W100ACAD_ISO10W100ACAD_ISO11W100ACAD_ISO12W100ACAD_ISO13W100ACAD_ISO14W100ACAD_ISO15W100N),rh   ri   rj   rk   r   
CONTINUOUSBORDERBORDER2BORDERX2CENTERCENTER2CENTERX2DASHDOTDASHDOT2	DASHDOTX2DASHEDDASHED2DASHEDX2DIVIDEDIVIDE2DIVIDEX2DOTDOT2DOTX2HIDDENHIDDEN2HIDDENX2PHANTOMPHANTOM2	PHANTOMX2ISO_DASHISO_DASH_SPACEISO_LONG_DASH_DOTISO_LONG_DASH_DOUBLE_DOTISO_LONG_DASH_TRIPLE_DOTISO_DOTISO_LONG_DASH_SHORT_DASHISO_LONG_DASH_DOUBLE_SHORT_DASHISO_DASH_DOTISO_DOUBLE_DASH_DOTISO_DASH_DOUBLE_DOTISO_DOUBLE_DASH_DOUBLE_DOTISO_DASH_TRIPLE_DOTISO_DOUBLE_DASH_TRIPLE_DOTrn   rg   re   ry   ry      s   JVFfGvHVFfGvHfGvHIVFfGvHVFfGvH
&C6DFEVFfGvHfGvHIH%N(//G/&6##L**!1*!1rg   ry   c                   4    e Zd ZdZdZdZdZdZdZdZ	dZ
d	Zd
Zy)
ColorIndexColorsr6                        	   N)rh   ri   rj   rk   REDYELLOWGREENCYANBLUEMAGENTABLACKGRAY
LIGHT_GRAYrn   rg   re   r   r      s2    
CFEDDGEDJrg   r   c                        e Zd ZdZdZ	 dZ	 dZy)	DotLengthzBLine type dash pattern dot widths, expressed in tenths of an inch.        g{Gz?g?N)rh   ri   rj   rk   TRUE_DOTINKSCAPE_COMPATQCAD_IMPERIALrn   rg   re   r   r      s#    LHFO M;rg   r   c                      | D cg c]  }t        |       }}t        |      g| D cg c]  }|dz  	 }}|S c c}w c c}w )zPrepare an ANSI line pattern for ezdxf usage.
    Input pattern is specified in inches.
    Output is given in tenths of an inch, and the total pattern length
    is prepended to the list.
   abssumargslabs_argsresults       re   ansi_patternr      sK    
 !%%1A%H%!$X 6 671q2v7F7M &7   9>c                      | D cg c]  }t        |       }}t        |      g| D cg c]  }|dz  	 }}|S c c}w c c}w )zPrepare an ISO line pattern for ezdxf usage.
    Input pattern is specified in millimeters.
    Output is given in tenths of an inch, and the total pattern length
    is prepended to the list.RQ@r   r   s       re   iso_patternr      sK    
 !%%1A%H%#&x="84"89Qq4x9F9M &9r   	from_unitto_unitreturnc                 ,    t         |   t         |    z  }|S )zLReturn the multiplicative conversion factor to go from from_unit to to_unit.r1   )r   r   r   s      re   unit_conversion_scaler     s    W%	(BBFMrg   c                   :   e Zd ZdZdZej                  ZdZe	j                  Zi e	j                  j                  ddgfe	j                  j                  d eddddd	d      fe	j                  j                  d
 eddddd	d      fe	j                   j                  d eddddd	d      fe	j"                  j                  d edddd      fe	j$                  j                  d edddd      fe	j&                  j                  d edddd      fe	j(                  j                  d eddd	d      fe	j*                  j                  d eddd	d      fe	j,                  j                  d eddd	d      fe	j.                  j                  d edd      fe	j0                  j                  d edd      fe	j2                  j                  d edd      fe	j4                  j                  d eddd	dd	d      fe	j6                  j                  d eddd	dd	d      fe	j8                  j                  d eddd	dd	d      fe	j:                  j                  d  ed	d      fi e	j<                  j                  d! ed	d      fe	j>                  j                  d" ed	d      fe	j@                  j                  d# edd      fe	jB                  j                  d$ edd%      fe	jD                  j                  d& edd      fe	jF                  j                  d' edddddd      fe	jH                  j                  d( ed)ddddd      fe	jJ                  j                  d* edddddd      fe	jL                  j                  d+ e'd,d-      fe	jP                  j                  d. e'd,d/      fe	jR                  j                  d0 e'd1d-d	d-      fe	jT                  j                  d2 e'd1d-d	d-d	d-      fe	jV                  j                  d3 e'd1d-d	d-d	d-d	d-      fe	jX                  j                  d4 e'd	d-      fe	jZ                  j                  d5 e'd1d-d6d-      fe	j\                  j                  d7 e'd1d-d6d-d6d-      fe	j^                  j                  d8 e'd,d-d	d-      fe	j`                  j                  d9 e'd,d-d,d-d	d-      fe	jb                  j                  d: e'd,d-d	d-d	d-      fe	jd                  j                  d; e'd,d-d,d-d	d-d	d-      fe	jf                  j                  d< e'd,d-d	d-d	d-d	d-      fe	jh                  j                  d= e'd,d-d,d-d	d-d	d-d	d-
      fiZ5e6jn                  d>e6jp                  d?e6jr                  d@e6jt                  dAe6jv                  dBiZ<yC)DExport2Dz'Base class for 2D exporters (DXF, SVG).g&.>g
ףp=
?Solidr   z.Border __ __ . __ __ . __ __ . __ __ . __ __ .g      ?g      пr   z.Border (.5x) __.__.__.__.__.__.__.__.__.__.__.g      ?g      z-Border (2x) ____  ____  .  ____  ____  .  ___      ?g      z.Center ____ _ ____ _ ____ _ ____ _ ____ _ ____g      ?z.Center (.5x) ___ _ ___ _ ___ _ ___ _ ___ _ ___g      ?g      ?z-Center (2x) ________  __  ________  __  _____g      @z.Dash dot __ . __ . __ . __ . __ . __ . __ . __z-Dash dot (.5x) _._._._._._._._._._._._._._._.z,Dash dot (2x) ____  .  ____  .  ____  .  ___z/Dashed __ __ __ __ __ __ __ __ __ __ __ __ __ _z/Dashed (.5x) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ z-Dashed (2x) ____  ____  ____  ____  ____  ___z/Divide ____ . . ____ . . ____ . . ____ . . ____z.Divide (.5x) __..__..__..__..__..__..__..__.._z-Divide (2x) ________  .  .  ________  .  .  _z3Dot . . . . . . . . . . . . . . . . . . . . . . . .z2Dot (.5x) ........................................z1Dot (2x) .  .  .  .  .  .  .  .  .  .  .  .  .  .z0Hidden __ __ __ __ __ __ __ __ __ __ __ __ __ __z/Hidden (.5x) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ g      z/Hidden (2x) ____ ____ ____ ____ ____ ____ ____ z/Phantom ______  __  __  ______  __  __  ______ z-Phantom (.5x) ___ _ _ ___ _ _ ___ _ _ ___ _ _g      ?z-Phantom (2x) ____________    ____    ____   _z/ISO dash __ __ __ __ __ __ __ __ __ __ __ __ __   z/ISO dash space __    __    __    __    __    __iz/ISO long-dash dot ____ . ____ . ____ . ____ . _   z0ISO long-dash double-dot ____ .. ____ .. ____ . z/ISO long-dash triple-dot ____ ... ____ ... ____z0ISO dot . . . . . . . . . . . . . . . . . . . . z/ISO long-dash short-dash ____ __ ____ __ ____ _r   z/ISO long-dash double-short-dash ____ __ __ ____z0ISO dash dot __ . __ . __ . __ . __ . __ . __ . z0ISO double-dash dot __ __ . __ __ . __ __ . __ _z0ISO dash double-dot __ . . __ . . __ . . __ . . z0ISO double-dash double-dot __ __ . . __ __ . . _z0ISO dash triple-dot __ . . . __ . . . __ . . . _z0ISO double-dash triple-dot __ __ . . . __ __ . .g?g?r   gK7A?gd?N)=rh   ri   rj   rk   PARAMETRIC_TOLERANCEr   r   DEFAULT_COLOR_INDEXDEFAULT_LINE_WEIGHTry   r   DEFAULT_LINE_TYPEvaluer   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   LINETYPE_DEFSr&   INFTMMCMMLTYPE_SCALErn   rg   re   r   r     sh   1  $** ++Z!!GcU#3Z<eS%E: 
Z 	<vtVQ?!
Z 	;dCq$7"
Z 	<udE2 
Z$ 	<vuf5!
%Z, 	;dC."
-Z4 	<eQ.!
5Z< 	;vq&1"
=ZD 	  :dAt,#
EZL 	=e$ 
MZT 	=v&!
UZ\ 	;d#"
]Zd 	=eQq%8 
eZl 	<vq&!V<!
mZt 	;dAtQ5"
uZ| 	AE"
}ZD 	@F#
EZL 	?D!
MZT 	>v& 
UZ\ 	=(!
]Zd 	=e$"
eZl 	=udE4?!
mZt 	;vufE"
uZ| 	  ;dCsD9#
}ZD 	=B"
EZL 	%%=C (
MZT 	""((=B2&+
UZ\ 	))//>B2q"-2
]Zd 	))//=B2q"a42
eZl 	>2!
mZt 	))//=B2&2
uZ| 	0066=B2q"-9
}ZD 	##>B2&&
EZL 	$$**>BB2.-
 	$$**>B2q"--
 	++11>BB2q"54
 	$$**>B2q"a4-
 	++11>BB2q"a<4
mZM| 	Krg   r   c                      e Zd ZdZej
                  dej                  ej                  j                  ej                  ej                  j                  ej                  ej                  j                  ej                  ej                  j                  ej                  ej                  j                  iZej                  ej                  ej                  hZej                  ej                  dddfdedededz  dedz  dedz  f
d	Zdddd
dededz  dedz  dedz  def
dZdedefdZd deee   z  dedefdZd dedefdZ	 d!deez  ez  ez  defdZ de!e"z  e#z  e$z  de%fdZ&de'de(fdZ)de'de(fdZ*de'de(fdZ+de'fdZ,de'de(fdZ-e.j^                  e)e.j`                  e*e.jb                  e+e.jd                  e,iZ3de'de(fdZ4y)"	ExportDXFa~  
    The ExportDXF class provides functionality for exporting 2D shapes to DXF
    (Drawing Exchange Format) format. DXF is a widely used file format for
    exchanging CAD (Computer-Aided Design) data between different software
    applications.


    Args:
        version (str, optional): The DXF version to use for the output file.
            Defaults to ezdxf.DXF2013.
        unit (Unit, optional): The unit used for the exported DXF. It should be
            one of the Unit enums: Unit.MC, Unit.MM, Unit.CM,
            Unit.M, Unit.IN, or Unit.FT. Defaults to Unit.MM.
        color (Optional[ColorIndex], optional): The default color index for shapes.
            It can be specified as a ColorIndex enum or None.. Defaults to None.
        line_weight (Optional[float], optional): The default line weight
            (stroke width) for shapes, in millimeters. . Defaults to None.
        line_type (Optional[LineType], optional): e default line type for shapes.
            It should be a LineType enum or None.. Defaults to None.


    Example:

        .. code-block:: python

            exporter = ExportDXF(unit=Unit.MM, line_weight=0.5)
            exporter.add_layer("Layer 1", color=ColorIndex.RED, line_type=LineType.DASHED)
            exporter.add_shape(shape_object, layer="Layer 1")
            exporter.write("output.dxf")

    Raises:
        ValueError: unit not supported

       Nversionunitcolorline_weight	line_typec                 f   d| _         || j                  vrt        d|j                   d      |t        j
                  v r't        j                  t        j                     | _
        nd| _
        t        j                  || j                  |   d      | _        | j                  j                         | _        | j                  j                   j#                  d      }||j$                  |_        |t)        |dz        |j*                  _        |!| j/                  |      |j*                  _        y y )	Nr   zunit `z` not supported.r6   F)
dxfversionunitssetup0d   )_non_planar_point_count_UNITS_LOOKUP
ValueErrorrr   r   METRIC_UNITSr   r   r&   r   _linetype_scaleezdxfnew	_document
modelspace_modelspacelayersgetr   r   rounddxf
lineweight	_linetypelinetype)rU   r   r   r   r   r   default_layers          re   rf   zExportDXF.__init__  s    ()$t)))vdii[0@ABB9)))#+#7#7#@D #$D $$T*

  >>446--11#6"'++M"+0s1B+CM( )-	)BM& !rg   )r   r   r   rr   r   c                    i }|| j                  |      }||d<   ||j                  |d<   |t        |dz        |d<    | j                  j                  j
                  |fi | | S )a  add_layer

        Adds a new layer to the DXF export with the given properties.

        Args:
            name (str): The name of the layer definition. Must be unique among all layers.
            color (Optional[ColorIndex], optional): The color index for shapes on this layer.
                It can be specified as a ColorIndex enum or None. Defaults to None.
            line_weight (Optional[float], optional): The line weight (stroke width) for shapes
                on this layer, in millimeters. Defaults to None.
            line_type (Optional[LineType], optional): The line type for shapes on this layer.
                It should be a LineType enum or None. Defaults to None.

        Returns:
            Self: DXF document with additional layer
        r  r   r   r  )r  r   r
  r  r  add)rU   rr   r   r   r   kwargsr  s          re   	add_layerzExportDXF.add_layer  sx    4 "$ ~~i0H!)F:#kkF7O"#(s):#;F< !!!$1&1rg   c                 `   |j                   }|| j                  j                  vr|t        j                  v rgt        j                  j                  |      \  }}| j                  j                  j                  ||D cg c]  }| j                  |z   c}|       |S t        d      |S c c}w )zhEnsure that the specified LineType has been defined in the document,
        and return its string name.)rr   patterndescriptionzUnknown linetype `{linetype}`.)	r   r  	linetypesr   r   r	  r  r  r   )rU   r   r  descr  vs         re   r  zExportDXF._linetypeJ  s     ??4>>333 8111 ( 6 6 : :8 Dg((,,!?FG!T11A5G $ -   !!ABB Hs   =B+
r=   layerc                     t        |t              r| j                  ||       n|D ]  }| j                  ||        | j                  dkD  r/t	        d       t	        d       t	        d| j                   d       | S )a  add_shape

        Adds a shape to the specified layer.

        Args:
            shape (Shape | Iterable[Shape]): The shape or collection of shapes to be
                  added. It can be a single Shape object or an iterable of Shape objects.
            layer (str, optional): The name of the layer where the shape will be
                added. If not specified, the default layer will be used. Defaults to "".

        Returns:
            Self: Document with additional shape
        r   1WARNING, exporting non-planar shape to 2D format.%  This is probably not what you want.  # points found outside the XY plane.)
isinstancer0   _add_single_shaper   print)rU   r=   r  ss       re   	add_shapezExportDXF.add_shape^  s     eU#""5%0 1&&q%01''!+EF9:T1122UV rg   c                 d    i }|r||d<   |j                         D ]  }| j                  ||        y )Nr  )edges_convert_edge)rU   r=   r  
attributesedges        re   r!  zExportDXF._add_single_shapey  s9    
"'JwKKM 	1DtZ0	1rg   	file_nameascii_formatc                    t        j                  | j                         t        |t              s3t        |      }| j                  j                  ||rd       yd       y|rWt        j                  |dd      }	 | j                  j                  |d       |j                          |j                          y| j                  j                  |d       y# |j                          w xY w)ap  write

        Writes the DXF data to the specified file name.

        Args:
            file_name (PathLike |  str |  bytes | BytesIO): The file name (including path) where
                the DXF data will be written.
            ascii_format (bool, optional): Export the file as ASCII (True) or binary
                (False) DXF format. Defaults to True.
        ascbin)fmtutf-8 )encodingnewlineN)r   extentsr  r   r   r   r  saveasioTextIOWrapperwriteflushdetach)rU   r*  r+  text_streams       re   r8  zExportDXF.write  s    & 	T%%&)W- +INN!!),!RE!R ..$
)NN((%(@%%'&&($$YE$:  &&(s   >-C C,ptc                 |   t        |t        t        t        f      r1|j	                         |j                         |j                         }}}nBt        |t              rt        |      \  }}}n"t        dt        |      j                   d      t        |      dkD  r| xj                  dz  c_        t        ||      S )zYCreate a Vec2 from a gp_Pnt or Vector.
        This method also checks for points z != 0.z:Expected `gp_Pnt`, `gp_XYZ`, `gp_Vec`, or `Vector`.  Got ``.ư>r6   )r   r   r   r   XYZr*   tuple	TypeErrortyperh   r   r   r   )rU   r<  xyzs        re   _convert_pointzExportDXF._convert_point  s     b66623ttvrttvrttv!qAF#BiGAq!LTRTXM^M^L__ab  q6D=((A-(Aqzrg   r)  attribsc                     | j                   j                  | j                  |j                               | j                  |j	                               |       y)z.Converts a Line object into a DXF line entity.N)r  add_linerI  start_point	end_pointrU   r)  rJ  s      re   _convert_linezExportDXF._convert_line  sE    !! 0 0 23 01	
rg   c                 6   |j                         }|j                         }| j                  |j                               }|j	                         }|j                         r| j                  j                  |||       y|j                         j                         }|j                         j                         }t        ddd      j                  |t        ddd            }	|j                         }
|j                         }|j                         dkD  r3t!        j"                  |	|
z         }t!        j"                  |	|z         }d}n2t!        j"                  |	|
z
        }t!        j"                  |	|z
        }d}| j                  j%                  ||||||       y)z2Converts a Circle object into a DXF circle entity.r6   r   TFN)geom_adaptorCirclerI  LocationRadiusIsClosedr  
add_circleXAxis	DirectionAxisr   AngleWithRefFirstParameterLastParameterrB  mathdegreesadd_arc)rU   r)  rJ  curvecirclerB   radiusx_axisz_axisphiu1u2angle1angle2ccws                  re   _convert_circlezExportDXF._convert_circle  sD   !!#$$V__%67>>''@ \\^--/F[[],,.FAq/..vvaAGC%%'B$$&BxxzA~cBh/cBh/cBh/cBh/$$VVVVS'Rrg   c                 b   |j                         }|j                         }|j                         }|j                         }|j	                         }|t        |j                         j                               z  }|j                         j                         }	|	j                         dkD  r!|j                         }
|j                         }n"|j                          }
|j                          }| j                  j                  | j                  |      | j                  |      ||z  |
||       y)z5Converts an Ellipse object into a DXF ellipse entity.r   N)rR  EllipseMinorRadiusMajorRadiusrT  r   rX  rY  rZ  rB  r\  r]  r  add_ellipserI  )rU   r)  rJ  geomellipseminor_radiusmajor_radiusrB   
major_axismain_dirrs   ends               re   _convert_ellipsezExportDXF._convert_ellipse  s     ",,.**,**,!!#!F7==?+D+D+F$GG
<<>++-::<!'')E$$&C''))E&&((C$$'
+<'	
rg   c                 4   |j                         }|j                         }|j                         j                         }|j                         }|j	                         }t        j                  t        t        |      ||t        j                        }|r|j                  t        d| d      |j                  j                  j                         }|j                  |       |j!                         dz   }	t#        |j%                               }
|j'                         D cg c]  }| j)                  |       }}|j+                         r:t-        d|j/                         dz         D cg c]  }|j1                  |       c}nd}|j3                         r)|j5                         |j7                         z
  }||d| z  }t8        j:                  j=                  ||	|
|      }| j>                  jA                  |      jC                  |       yc c}w c c}w )z3Converts a BSpline object into a DXF spline entity.NEdge is empty .r6   )
dxfattribs)"
to_splinesrR  Curver\  r]  r   SplitBSplineCurve_stcastr   r   r   locationr   rA   Transformation	TransformDegreelistKnotSequencePolesrI  
IsRationalrangeNbPolesWeight
IsPeriodicNbKnotsLastUKnotIndexr  r^  BSpliner  
add_splineapply_construction_tool)rU   r)  rJ  adaptorra  rg  rh  splinetorderknotsppolesiweightspad
dxf_splines                    re   _convert_bsplinezExportDXF._convert_bspline  s   
   ##%%%'##%""$ 00#U+))	
 t}},~dV1566MM!!002!#V((*+17@A$$Q'@@   " (-Q0@10D'EF!V]]1F 	 .."V%:%:%<<CU4C[ EZZ''ueWE
##w#7OO	
 AFs   #H,Hc                 (    | j                  ||       y)z9Converts any other type of Edge object into a DXF entity.N)r  rO  s      re   _convert_otherzExportDXF._convert_other-  s    dG,rg   c                     |j                   }| j                  j                  |t        j                        } || ||       y r?   )	geom_type_CONVERTER_LOOKUPr	  r   r  )rU   r)  rJ  r  converts        re   r'  zExportDXF._convert_edge<  s5    NN	((,,Y	8P8PQdG$rg   )r1  )T)5rh   ri   rj   rk   r&   MCr   r  r   r   r   r   r   r   r  DXF2013strr   rm   ry   rf   r%   r  r  r0   r   r$  r!  r   bytesr   rl   r8  r   r   r   r*   r   rI  r.   dictrP  rl  ry  r  r  r'   LINECIRCLEELLIPSEBSPLINEr  r'  rn   rg   re   r   r     su   !L 	M 	L }}WW#'$(%)CC C D 	C
 T\C d?CH $($(%)'' D 	'
 T\' d?' 
'V8  (ux6 s D 61u 1S 1 "%;c>E)G3%; %;R&6!9F!B t "
$ 
 
SD S4 S8
T 
D 
4-
T -
b-4 -$ - 	}**	%$ % %rg   r   c                   `   e Zd ZdZeegej                  f   Ze	j                  de	j                  de	j                  diZ G d d      Ze	j                  ddd	d
dej                   ej"                  ej$                  ej(                  f
de	dededededeez  ez  dz  deez  ez  dz  dededeez  fdZdej                   ej"                  ej$                  ddedeez  ez  dz  deez  ez  dz  dededefdZ	 	 d:de e!e    z  dedefdZ"de dedefdZ#e$d e%d!ede&e   fd"       Z'd e%d!ede&e(   fd#Z)d e%d!edej                  fd$Z*d%e+e,z  de-fd&Z.d'ed!ede/j`                  fd(Z1d'ed!ede&e(   fd)Z2d'edej                  fd*Z3d'ed!ede&e(   fd+Z4d'edej                  fd,Z5d'ed!ede&e(   fd-Z6d'edej                  fd.Z7d'ed!ede&e(   fd/Z8d'edej                  fd0Z9d'ed!efd1Z:d'edej                  fd2Z;e<jz                  e2e<j|                  e4e<j~                  e6e<j                  e8iZAd'ed!ede&e(   fd3ZBe<jz                  e3e<j|                  e5e<j~                  e7e<j                  e9iZCd'edej                  fd4ZDdefd5ZE	 d;ded6eFdz  dej                  fd7ZGd8eHez  eIz  eJz  fd9ZKy)<	ExportSVGa  ExportSVG

    SVG file export functionality.

    The ExportSVG class provides functionality for exporting 2D shapes to SVG
    (Scalable Vector Graphics) format. SVG is a widely used vector graphics format
    that is supported by web browsers and various graphic editors.

    Args:
        unit (Unit, optional): The unit used for the exported SVG. It should be one of
            the Unit enums: Unit.MM, Unit.CM, or Unit.IN. Defaults to
            Unit.MM.
        scale (float, optional): The scaling factor applied to the exported SVG.
            Defaults to 1.
        margin (float, optional): The margin added around the exported shapes.
            Defaults to 0.
        fit_to_stroke (bool, optional): A boolean indicating whether the SVG view box
            should fit the strokes of the shapes. Defaults to True.
        precision (int, optional): The number of decimal places used for rounding
            coordinates in the SVG. Defaults to 6.
        fill_color (ColorIndex |  RGB |  None, optional): The default fill color
            for shapes. It can be specified as a ColorIndex, an RGB tuple, or None.
            Defaults to None.
        line_color (ColorIndex |  RGB |  None, optional): The default line color for
            shapes. It can be specified as a ColorIndex or an RGB tuple, or None.
            Defaults to Export2D.DEFAULT_COLOR_INDEX.
        line_weight (float, optional): The default line weight (stroke width) for
            shapes, in millimeters. Defaults to Export2D.DEFAULT_LINE_WEIGHT.
        line_type (LineType, optional): The default line type for shapes. It should be
            a LineType enum. Defaults to Export2D.DEFAULT_LINE_TYPE.
        dot_length (DotLength |  float, optional): The width of rendered dots in a
            Can be either a DotLength enum or a float value in tenths of an inch.
            Defaults to DotLength.INKSCAPE_COMPAT.


    Example:

        .. code-block:: python

            exporter = ExportSVG(unit=Unit.MM, line_weight=0.5)
            exporter.add_layer("Layer 1", fill_color=(255, 0, 0), line_color=(0, 0, 255))
            exporter.add_shape(shape_object, layer="Layer 1")
            exporter.write("output.svg")

    Raises:
        ValueError: Invalid unit.

    mmcminc            
       L    e Zd Zdedeez  ez  dz  deez  ez  dz  dedef
dZ	y)ExportSVG._Layerrr   
fill_colorN
line_colorr   r   c                     dt         t        z  t        z  t        z  d z  dt        d z  fd}|| _         ||      | _         ||      | _        || _        || _        g | _	        y )Ninput_colorr   c                 (   | xt         j                  k(  r t        dddd      }|S xxt         d x=\   } t        |j                        }|j                         \  }}}t        |||d      }|S   xxt        d x0\   } t        | }|j                         \  }}}t        |||d      }|S   xxt        d x(\   } |j                         \  }}}t        |||d      }|S   xxt        d x\   }	 |	}|S   d}|S 	 t        dt        |              )a  
                Convert various color representations into a `Color` object.

                This function takes an input color, which can be of type
                `ColorIndex`, `RGB`, `Color`, `tuple`, or `None`, and converts
                it into a `Color` object. If the input is `None`, the function
                returns `None`. It handles specific cases for
                `ColorIndex.BLACK` and other `ColorIndex` values using the
                `aci2rgb` function.

                Args:
                    input_color (ColorIndex | RGB | Color | tuple | None):
                        The input color to be converted.
                        - `ColorIndex`: A predefined color index from
                          `easydxf`. Special handling for `ColorIndex.BLACK`
                          ensures it maps to `RGB(0, 0, 0)` instead of the
                          default `aci2rgb` mapping to `RGB(255, 255, 255)`.
                        - `RGB`: A direct representation of red, green, and blue components.
                        - `Color`: An existing `Color` object.
                        - `tuple`: A tuple of RGB values (e.g., `(255, 0, 0)` for red).
                        - `None`: Represents no color.

                Returns:
                    Color | None: The converted `Color` object or `None` if the input was `None`.

                Raises:
                    ValueError: If the input color type is unsupported.

                Notes:
                    - The `easydxf` color indices BLACK and WHITE have the same value (7), and both
                    are mapped to `(255, 255, 255)` by the `aci2rgb()` function. This implementation
                    overrides the default mapping to prefer `(0, 0, 0)` for `ColorIndex.BLACK`.
                r   r   rn   NzUnsupported input type: )
r   r   r)   r   r   	to_floatsrC  r   r   rE  )
r  final_colorcolor_index	rgb_colorredgreenbluecolor_tuplergbr   s
             re   convert_colorz0ExportSVG._Layer.__init__.<locals>.convert_color  sI   J ")))&+Cc3&?0 #"/ 54$+K,=,=$>	+4+>+>+@(UD&+Cc&B& #"/ 5
 0/$'$5	+4+>+>+@(UD&+Cc&B #"% 0
 &+.==?(UD&+Cc&B #" & *)&+ #" * &* #" (+CDDUCV)WXXrg   )
r   r   r)   rC  rr   r  r  r   r   elements)rU   rr   r  r  r   r   r  s          re   rf   zExportSVG._Layer.__init__  sj    @#'#-5=D@#@#D DI+J7DO+J7DO*D&DN.0DMrg   )
rh   ri   rj   r  r   r   r)   rm   ry   rf   rn   rg   re   _Layerr    s[    O	1O	1 #S(5047O	1 #S(5047	O	1
 O	1  O	1rg   r  r6   r   Tr   Nr   scalemarginfit_to_stroke	precisionr  r  r   r   
dot_lengthc                 F   |t         j                  vr:t        ddj                  t         j                  j	                                d      || _        || _        || _        || _        || _	        |
| _
        d| _        i | _        d | _        | j                  d||||	       y )Nz#Invalid unit.  Supported units are z, r|  r   r1  rr   r  r  r   r   )r  _UNIT_STRINGr   joinvaluesr   r  r  r  r  r  r   _layers_boundsr  )rU   r   r  r  r  r  r  r  r   r   r  s              re   rf   zExportSVG.__init__  s     y---599Y33::<=>aA  	
*"$'($46(, 	!!# 	 	
rg   )r  r  r   r   rr   r   c                    || j                   v rt        d| d      |j                  t        j                  vrt        d|j                   d      t
        j                  |||||      }|| j                   |<   | S )a  add_layer

        Adds a new layer to the SVG export with the given properties.

        Args:
            name (str): The name of the layer. Must be unique among all layers.
            fill_color (ColorIndex |  RGB |  Color |  None, optional): The fill color for shapes
                on this layer. It can be specified as a ColorIndex, an RGB tuple,
                a Color, or None.  Defaults to None.
            line_color (ColorIndex |  RGB |  Color |  None, optional): The line color for shapes on
                this layer. It can be specified as a ColorIndex or an RGB tuple,
                a Color, or None.  Defaults to Export2D.DEFAULT_COLOR_INDEX.
            line_weight (float, optional): The line weight (stroke width) for shapes on
                this layer, in millimeters. Defaults to Export2D.DEFAULT_LINE_WEIGHT.
            line_type (LineType, optional): The line type for shapes on this layer.
                It should be a LineType enum. Defaults to Export2D.DEFAULT_LINE_TYPE.

        Raises:
            ValueError: Duplicate layer name
            ValueError: Unknown linetype

        Returns:
            Self: Drawing with an additional layer
        zDuplicate layer name 'z'.zUnknown linetype `r>  r  )r  r   r   r   r   r  r  )rU   rr   r  r  r   r   r  s          re   r  zExportSVG.add_layer  s    B 4<<5dV2>????("8"881)//1B"EFF  !!# ! 
 #Trg   r=   r  reverse_wiresc                     || j                   vrt        d| d      | j                   |   }t        |t              r| j	                  |||       y|D ]  }| j	                  |||        y)as  add_shape

        Adds a shape or a collection of shapes to the specified layer.

        Args:
            shape (Shape | Iterable[Shape]): The shape or collection of shapes to be
                  added. It can be a single Shape object or an iterable of Shape objects.
            layer (str, optional): The name of the layer where the shape(s) will be added.
                Defaults to "".
            reverse_wires (bool, optional): A boolean indicating whether the wires of the
                shape(s) should be in reversed direction. Defaults to False.

        Raises:
            ValueError: Undefined layer
        zUndefined layer: r|  N)r  r   r   r0   r!  )rU   r=   r  r  _layerr#  s         re   r$  zExportSVG.add_shape2  sr    * $0q9::e$eU#""5&-@ A&&q&-@Arg   c                 H   d| _         |j                         }| j                  r| j                  j                  |      n|| _        g }|j	                         }|D ]  }|j                         }|j                         }	dt        |	      k(  r| j                  ||      }
nt| j                  ||      }|	D ]%  }| j                  ||      }|j                  |       ' t        j                  | }t        j                  dd|j                         i      }
|j!                  |
        g }t#        |j$                  t&        j(                  t&        j*                        }|j-                         r^|j/                         }|j!                  t1        t3        j0                  |                   |j5                          |j-                         r^|D ]#  }|j!                  | j                  ||             % g }t#        |j$                  t&        j6                  t&        j(                        }|j-                         r^|j/                         }|j!                  t9        t3        j8                  |                   |j5                          |j-                         r^|D cg c]  }| j;                  |       }}|j                  |       |j<                  j                  |       | j                   dkD  r0t?        d       t?        d       t?        d| j                    d       y y c c}w )	Nr   pathd)ToFindToAvoidr  r  r  r  ) r   bounding_boxr  r  faces
outer_wireinner_wireslen_wire_element_wire_segmentsextendPTPathETElementr  rL   r#   rA   r"   TopAbs_WIRETopAbs_FACEMoreCurrentr/   r$   NextTopAbs_EDGEr.   _edge_elementr  r"  )rU   r=   r  r  bbr  r  faceouterinnerface_elementface_segmentsr  segments	face_pathloose_wiresexplorer	topo_wirewireloose_edges	topo_edger)  loose_edge_elementss                          re   r!  zExportSVG._add_single_shapeP  s   '($!/3||t||''+  	*DOO%E$$&ECJ  $11%G
 !% 3 3E= I 3A#221mDH!((23 GG]3	!zz&3	2FGOOL)%	*0 "MM#//$00

 mmo ((*ItFKK	$:;<MMO mmo
   	EDOOD..t]CD	E "MM#//$00

 mmo ((*ItFKK	$:;<MMO mmo
 EPPDt11$7PP+,h'''!+EF9:T1122UV ,	 Qs   Lr  reversec                    g }t        | j                        }|j                         rK|j                         }|j	                  t        |             |j                          |j                         rK|r|j                          |S r?   )r   rA   r  r  rL   r.   r  r  )r  r  r&  r  r  s        re   _wire_edgeszExportSVG._wire_edges  se     )$,,7mmo ((*ILLi)MMO mmo
 MMOrg   c                     t         j                  ||      }g }|D ]%  }| j                  ||      }|j                  |       ' |S r?   )r  r  _edge_segmentsr  )rU   r  r  r&  wire_segmentsr)  edge_segmentss          re   r  zExportSVG._wire_segments  sP    %%dG4+- 	0D //g>M  /	0 rg   c                 B   t         j                  ||      }t        |      dk(  r| j                  |d         }|S g }|D ]%  }| j	                  ||      }|j                  |       ' t        j                  | }t        j                  dd|j                         i      }|S )Nr6   r   r  r  )r  r  r  r  r  r  r  r  r  r  r  )	rU   r  r  r&  wire_elementr  r)  r  	wire_paths	            re   r  zExportSVG._wire_element  s    %%dG4u:?--eAh7L  02M 4 $ 3 3D' B$$]34 /I::fsIKKM.BCLrg   r<  c                     t        |t              r0|j                         |j                         |j	                         f}nVt        |t
              r$|j                  |j                  |j                  f}n"t        dt        |      j                   d      t         fd|D              \  }}}|dk7  r xj                  dz  c_
        t        ||      S )zCreate a complex point from a gp_Pnt or Vector.
        We are using complex because that is what svgpathtools wants.
        This method also checks for points z != 0.z%Expected `gp_Pnt` or `Vector`.  Got `r>  c              3   J   K   | ]  }t        |j                          y wr?   )r
  r  ).0r  rU   s     re   	<genexpr>z(ExportSVG._path_point.<locals>.<genexpr>  s     >Qa0>s    #r   r6   )r   r   r@  rA  rB  r*   rD  rE  rh   rC  r   complex)rU   r<  xyzrF  rG  rH  s   `     re   _path_pointzExportSVG._path_point  s     b&!$$&"$$&"$$&(CF#$$bdd"C7R8I8I7J"M  >#>>1a6((A-(q!}rg   r)  c                 ,   |j                         }|j                         }|j                         }|r||fn||f\  }}| j                  |j	                  |            }| j                  |j	                  |            }	t        j                  ||	      }
|
S r?   )rR  r\  r]  r  Valuer  Line)rU   r)  r  ra  fplpu0rg  p0p1r   s              re   _line_segmentzExportSVG._line_segment  s    !!#!!#  "$"b2r(Bekk"o.ekk"o.Rrg   c                 (    | j                  ||      gS r?   )r  rU   r)  r  s      re   _line_segmentszExportSVG._line_segments  s    ""4122rg   c           	      J   | j                  |d      }t        j                  dt        |j                  j
                        t        |j                  j                        t        |j                  j
                        t        |j                  j                        d      }|S )z0Converts a Line object into an SVG line element.Fr  line)x1y1x2y2)r  r  r  r  rs   realimagrx  )rU   r)  segmentr   s       re   _line_elementzExportSVG._line_element  s|    $$T5$9'--,,-'--,,-'++**+'++**+	
 rg   c           
         |j                   dk  rt        dd       g S |j                         }|j                         }|j	                         }|j                         j                         }|j                         j                         }|j                         }|j                         }	|	|z
  }
|
t        j                   k  xs |
t        j                  kD  }|j                         dkD  |z  }|r|	|fn||	f\  }}| j                  |j                  |            }| j                  |j                  |            }t        ||      }t        j                   t#        ddd      j%                  |t#        ddd                  }|j'                         r\| j                  |j                  ||z   dz              }t)        j*                  |||d||      t)        j*                  |||d||      g}|S t)        j*                  ||||||      g}|S )	Nr?  z@Skipping arc that is too small to export safely (length < 1e-6).r   
stacklevelr   r6   r   F)lengthr   rR  rS  rU  rX  rY  rZ  r\  r]  r^  pirB  r  r  r  r_  r   r[  rV  r  Arc)rU   r)  r  ra  rb  rc  rd  re  r  r  du	large_arcsweepr  rg  rs   rx  rotationmidwayr   s                       re   _circle_segmentszExportSVG._circle_segments  s   ;;R I!!#))+((*!!#  ""W477(]5TWW	a7*$"b2r(B  R1u{{2/(<<q!Q < <VVAqRS_ UV>>%%ekk27a-&@AFufhufEvvxsCF  ffUFHiLMFrg   c                    |j                   r|j                         }|j                         }|j                         }|j	                         }| j                  |      }t        j                  dt        |j                        t        |j                        t        |      d      }|S | j                  |d      }t        j                  | }	t        j                  dd|	j                         i      }|S )z4Converts a Circle object into an SVG circle element.rb  )cxcyrFr  r  r  )	is_closedrR  rS  rU  rT  r  r  r  r  r!  r"  r0  r  r  r  )
rU   r)  ra  rb  rc  rB   cr   arcsr  s
             re   _circle_elementzExportSVG._circle_element  s    >>%%'E\\^F]]_F__&F  (AZZQVVCKc&kRF  ((u(=D77D>DZZdffh8Frg   c           
      8   |j                   dk  rt        dd       g S |j                         }|j                         }|j	                         }|j                         }|j                         j                         }|j                         j                         }|j                         }	|j                         }
|
|	z
  }|t        j                   k  xs |t        j                  kD  }|j                         dkD  |z  }|r|
|	fn|	|
f\  }}| j                  |j                  |            }| j                  |j                  |            }t!        ||      }t        j"                  t%        ddd      j'                  |t%        ddd                  }|j)                         r\| j                  |j                  ||z   dz              }t+        j,                  |||d||      t+        j,                  |||d||      g}|S t+        j,                  ||||||      g}|S )	Nr?  zDSkipping ellipse that is too small to export safely (length < 1e-6).r   r&  r   r6   r   F)r(  r   rR  rn  ro  rp  rX  rY  rZ  r\  r]  r^  r)  rB  r  r  r  r_  r   r[  rV  r  r*  )rU   r)  r  ra  rs  rt  ru  rd  re  r  r  r+  r,  r-  r  rg  rs   rx  rc  r.  r/  r   s                         re   _ellipse_segmentszExportSVG._ellipse_segments+  s   ;;V I!!#--/**,**,**,))+!!#  ""W477(]5TWW	a7*$"b2r(B  R1u{{2/|4<<q!Q < <VVAqRS_ UV>>%%ekk27a-&@AFufhufEvvxsCF  ffUFHiLMFrg   c                     | j                  |d      }t        j                  | }t        j                  dd|j                         i      }|S )z7Converts an Ellipse object into an SVG ellipse element.Fr  r  r  )r:  r  r  r  r  r  )rU   r)  r7  r  r   s        re   _ellipse_elementzExportSVG._ellipse_elementM  sC    %%dE%:ww~FS$&&(O4rg   c                     |j                         }|j                         }|j                         j                         j                         }|j	                         }|j                         }|r|j                  t        d| d      |j                  j                  j                         }|j                  |       t        t        t        |      ||t        j                        }dt         dt"        dt$        f fd}	t'        d|j)                         dz         D 
cg c]  }
 |	|j+                  |
      |       }}
|r|j-                          |S c c}
w )Nr{  r|  bezierr  r   c                    | j                         D cg c]  }j                  |       c}}|r|j                          t        |      dk(  rt	        j
                  |d   |d         }|S t        |      dk(  r#t	        j                  |d   |d   |d         }|S t        |      dk(  r't	        j                  |d   |d   |d   |d         }|S t        d	| j                          d
      c c}w )Nr   r   r6   )rs   rx  r   )rs   controlrx  r   )rs   control1control2rx  u   Surprising Bézier of degree !)
r  r  r  r  r  r  QuadraticBezierCubicBezierr   r  )r>  r  r  r   rU   s       re   make_segmentz1ExportSVG._bspline_segments.<locals>.make_segmentq  s    .4lln=!!!$=A		1v{qt16 M Q1++!A$!!A$O M Q1A$1!!A$
 M !#@@QQR!STT >s   C1r6   )r~  rR  r  Copyr\  r]  r  r   rA   r  r  r   r  r   r   r   r   rl   r3   r  NbArcsr*  r  )rU   r)  r  r  r  rg  rh  r  	converterrF  r  r   s   `           re   _bspline_segmentszExportSVG._bspline_segmentsV  s=      ##%&&(--/##%""$ t}},~dV1566MM!!002 :#V,b"h6S6S
		!1 	D 	[ 	$ 1i..0145
 q)73
 
 NN
s   !Ec                     | j                  |d      }t        j                  | }t        j                  dd|j                         i      }|S )uP   Converts a BSpline object into an SVG path element representing a Bézier curve.Fr  r  r  )rJ  r  r  r  r  r  )rU   r)  r  r  r   s        re   _bspline_elementzExportSVG._bspline_element  sD    ))$)>ww!FS$&&(O4rg   c                 &    | j                  ||      S r?   )rJ  r  s      re   _other_segmentszExportSVG._other_segments  s     %%dG44rg   c                 $    | j                  |      S r?   )rL  )rU   r)  s     re   _other_elementzExportSVG._other_element  s     $$T**rg   c                    |st        d| d      |j                  j                         t        j                  k(  }|j
                  }| j                  j                  |t        j                        } || |||z        }|S )Nr{  r|  )
r   rA   Orientationr!   TopAbs_REVERSEDr  _SEGMENT_LOOKUPr	  r  rN  )rU   r)  r  edge_reversedr  r  r   s          re   r  zExportSVG._edge_segments  sv    ~dV15660026H6X6XXNN	''++Iy7P7PQ$g&=>rg   c                     |j                   }| j                  j                  |t        j                        } || |      }|S r?   )r  _ELEMENT_LOOKUPr	  r  rP  )rU   r)  r  elementr   s        re   r  zExportSVG._edge_element  s:    NN	&&**9i6N6NOt$rg   c           	      p   |j                   j                  }t        j                  |   \  }}t	        | j
                  t              r| j
                  j                  n| j
                  }t        |      }t        |      }t        d|      D ]9  }||   dk(  s|||<   ||dz
  xx   |dz  z  cc<   ||dz   |z  xx   |dz  z  cc<   ; t        j                  | j                     |j                  z  | j                  z  }|dd  D 	cg c]%  }	t        |t!        |	      z  | j"                         ' }
}	|
S c c}	w )Nr   r6   r   )r   r   r   r   r   r  r   r   r  r  r  r   r   r   r  r
  r   r  )rU   r  ltname_r  r  plenr  ltscaleer   s              re   _stroke_dasharrayzExportSVG._stroke_dasharray  s)   &&++F3
7 $//95 OO!! 	

 w-7|q$ 	1AqzQ
A!a%'Q$'1q50'		1 ''		2U5F5FFSHOPQPRT1U7SV+T^^<=>TT Us   *D3rJ  c                    dt         d z  dt        t        t        d z  f   fd}|i } ||j                        \  }}||d<   |||d<    ||j                        \  }}||d<   |r||d<   t        t        j                  | j                        | j                  z  }|j                  |z  }	|	 |d<   t        j                  d	|      }
|j                  r|
j                  d
|j                         |j                  t         j"                  ur2| j%                  |      }|
j                  ddj'                  |             |j(                  D ]  }|
j+                  |        |
S )Nr   r   c                     | ct        |       \  }}}}t        |dz        t        |dz        t        |dz        t        |d      f\  }}}}d| d| d| d}|dk  r| nd }||fS y)N   r   zrgb(,)r6   )noneN)rC  intr
  )r   r4  gbar  opacitys          re   _color_attribsz2ExportSVG._group_for_layer.<locals>._color_attribs  s     "5\
1a!!c'lCCL#a#g,aQRT
1aQCq1QCq)$%EQCtW~%!rg   fillzfill-opacitystrokezstroke-opacityzstroke-widthrg  idzstroke-dasharray )r)   rC  r  r  r  r   r&   r   r   r  r   r  r  rr   setr   ry   r   r_  r  r  rL   )rU   r  rJ  rk  rl  fill_opacityrm  stroke_opacitylwscalestroke_widthr   
dash_arrayrX  s                re   _group_for_layerzExportSVG._group_for_layer  sO   	"%$, 	"5cDj3I 	" ?G+E,<,<=l#&2GN#!/0@0@!A"(6G$%';djjH((72%1NC)::JJtUZZ(??("5"55//6JJJ)388J+?@~~ 	#GMM'"	# rg   r  c           	         | j                   }|t        d      | j                  }| j                  r2t	        d | j
                  j                         D              }||dz  z  }|| j                  z  }t        |j                  j                  |z
  | j                        }t        |j                  j                   |z
  | j                        }t        |j                  j                  d|z  z   | j                        }t        |j                  j                  d|z  z   | j                        }	||||	fD 
cg c]  }
t        |
       }}
t        || j                  z  | j                        }t        |	| j                  z  | j                        }| j                  j!                  | j"                  d      }t%        j&                  d| | | | dj)                  |      dd	d
      }t%        j&                  dddd      }|j+                  |       | j
                  j-                         D ]4  \  }}|j.                  s| j1                  |      }|j+                  |       6 t%        j2                  |      }t%        j4                  |d       t7        |t8              st;        |      }|j=                  |ddd       yc c}
w )zwrite

        Writes the SVG data to the specified file path.

        Args:
            path (PathLike | str | bytes | BytesIO): The file path where the
                SVG data will be written.
        NzNo shapes to export.c              3   4   K   | ]  }|j                     y wr?   )r   )r	  r   s     re   r
  z"ExportSVG.write.<locals>.<genexpr>  s     !OA!--!Os   r   r1  svgro  z1.1zhttp://www.w3.org/2000/svg)widthheightviewBoxr   xmlnsrg  zscale(1,-1)r
  )	transformzstroke-linecapr  r0  T)r2  xml_declarationdefault_namespace)r  r   r  r  maxr  r  r  r
  minr@  r  rA  sizer  r  r	  r   r  r  r  rL   itemsr  rv  ElementTreeindentr   r   r   r8  )rU   r  r  
doc_marginmax_line_weightview_margin	view_leftview_top
view_widthview_heightfview_box	doc_width
doc_heightdoc_unitry  container_groupr[  r  layer_groupxmls                        re   r8  zExportSVG.write  sX    \\:344[[
!!O9L9L9N!OOO/A--J 4::-26688)k14>>B	"&&(([0$..A27799q;6G
BGGIIK7H%.*k$RSqCFSS*tzz14>>B	;3T^^D
$$((B7jj%;xj1'L
388H- 5	
 ***")
 	

?#**, 	4HAu~~"33E:&&{3	4
 nnS!
		#t$(D>D 			$$RV	WI Ts   7K)r1  Fr?   )Lrh   ri   rj   rk   r   r.   r  r  
_Converterr&   r   r   r   r  r  r   r   r   r   r   r   rm   rl   rf  r   r   r)   ry   rf   r  r%   r  r0   r   r$  r!  rw   r/   r  r  r3   r  r  r   r*   r  r  r  r  r  r  r$  r0  r8  r:  r<  rJ  rL  rN  rP  r'   r  r  r  r  rT  r  rW  r  r_  r  rv  r   r  r   r8  rn   rg   re   r  r  G  s~   /d 4&"**,-J
 	LP1 P1p WW"6:6>6R6R%99&88(1(A(A#
#
 #
 	#

 #
 #
 $u,t3#
 $u,t3#
 #
 #
 %#
V 7;6>6R6R%99&88-- $u,t3	-
 $u,t3- - - 
-h #	Ax&A A 	A<Iu IV ID IZ $  $t*   4 $ 4;L $  "** fvo ' &$  "'' 34 3$ 34;L 3$ 2::  T D T+=N BD RZZ & d  T  d;>O  DT bjj 1d 1T 1d;>O 1fT bjj 5D 54 5
+4 +BJJ + 	~)++	O4 $ 4;L  	}**	O$ 2:: v 0 59$$&*Tk$	$P:X(S.507: :Xrg   r  )brk   r^  r6  xml.etree.ElementTreeetreer  r  r   enumr   r   r   osr   r   typingr	   r
   r   r  warningsr   collections.abcr   r   r  svgpathtoolsr  r   ezdxf.colorsr   r   
ezdxf.mathr   OCP.BRepLibr   OCP.BRepToolsr   OCP.Geomr   r   OCP.GeomConvertr   r   OCP.gpr   r   r   r   r   OCP.HLRAlgor   OCP.HLRBRepr   r    
OCP.TopAbsr!   r"   
OCP.TopExpr#   
OCP.TopoDSr$   typing_extensionsr%   build123d.build_enumsr&   r'   build123d.geometryr(   r)   r*   r+   build123d.topologyr,   r-   r.   r/   r0   build123d.build_commonr2   r  r*  rD  rE  r3   __annotations__r5   rp   ry   r   r   r   r   rm   r   r   r   r  rn   rg   re   <module>r     s;  @  	 " "    ! !    .    %   0 8 ' A 9 9 ) 8 ; &  " 0 C C  3266)B,>,>>OY O RC9 C9T4 +2| +2\ ; ;T D U q qpy% y%BoX oXrg   