
    ^j@                        U d Z ddlZddlZddlmZmZmZ ddlmZ ddl	m
Z
mZmZmZ ddlZddlmZ ddlmZmZmZmZmZmZ ddlmZ dd	lmZmZmZmZmZ dd
l m!Z!m"Z"m#Z#m$Z$m%Z%m&Z& ddl'm(Z(m)Z)m*Z* ddl+m,Z, ddl-m.Z.m/Z/m0Z0m1Z1m2Z2 dede"fdZ3dede(fdZ4dede#fdZ5d Z6dede$dz  fdZ7dede.e2z  dz  fdZ8dede1fdZ9dede.e2z  dz  fdZ:de;e<e=e=e=f      de>de=de?de.e2z  dz  f
dZ@de=de.fdZAdede0e.e2z     fdZBdefdZCdede.fd ZDdede*fd!ZEdede*fd"ZFeCe3e4e5eBe6e7e8eFe9e:eCeDeEeCd#ZGeHe?ef   eId$<   de;e/   fd%ZJde;e/   fd&ZKd'e?ez  ez  e
z  de0fd(ZLy))a  
build123d import dxf

name: import_dxf.py
by:   Gumyr
date: November 10th, 2024

desc:
    This python module imports a DXF file as build123d objects.

license:

    Copyright 2024 Gumyr

    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)BytesIOStringIO
TextIOBase)PathLike)BinaryIOCallableTextIOcast)
DXFGraphic)ArcEdgeEdgePathEllipseEdgeLineEdgePolylinePath
SplineEdge)	TextAlign)	TOLERANCEAxisPosVector
VectorLike)BSpline	CenterArcEllipticalCenterArcLine
SagittaArcSpline)CirclePolygonText)scale)EdgeShape	ShapeListVertexWireentityreturnc                     | j                  d      \  }}}||z
  dz   dz  }t        | j                  j                  | j                  j                  ||      S )zConvert ARC        v@)anglesr   dxfcenterradius)r'   start_endarc_sizes        M/opt/ringagent/.cad-venv/lib/python3.12/site-packages/build123d/import_dxf.pyprocess_arcr5   @   sN    MM!$ME1cee#u,HVZZ&&

(9(95(KK    c                     t        | j                  j                        j                         j	                  t        | j                  j                         S )zConvert CIRCLE)r   r-   r/   edgemovedr   r.   )r'   s    r4   process_circler:   G   s:    &**##$))+11#vzz7H7H2IJJr6   c                    | j                   j                  }| j                   j                  }|d   dz  |d   dz  z   dz  }|| j                   j                  z  }t	        j
                  t	        j                  |d   |d               }t	        j
                  | j                   j                        }t	        j
                  | j                   j                  | j                   j                  z
        }|dz   dz  }t        ||||||      S )zConvert ELLIPSEr         g      ?r+   r.   x_radiusy_radiusstart_angler3   rotation)
r-   r.   
major_axisratiomathdegreesatan2start_param	end_paramr   )r'   r.   rC   r?   r@   rB   rA   r3   s           r4   process_ellipserJ   L   s    ZZF&&J1"Z]a%77C?H&*****H||DJJz!}jmDEH,,vzz556K||FJJ006::3I3IIJH5 E)H r6   c                    | j                   j                  }t        | j                   j                        }| j                   j                  | j                   j
                  | j                   j                  dk7  r| j                   j                  ndf}| j                   j                  }| j                   j                  }| j                   j                  }| j                   j                  }| j                   j                  }	|j                  j                  |      }
t        |
j                  j                   j                        }g }|
D ]  }t!        ||      D ]  }t#        |      D ]  }t#        |      D ]  }t        ||z  ||	z  d      }t        |j$                  |d   z  |j&                  |d   z  |j(                  |d   z        j+                  t,        j(                  |      }|j/                  |       }t1        ||      }|j+                  t,        j(                  |      }|j/                  ||z         }|j3                  |           t5        |      S )zLProcess INSERT by referencing block definition and applying transformations.r   g      ?r=   r<   )r-   namer   insertxscaleyscalezscalerB   column_count	row_countcolumn_spacingrow_spacingblocksgetblock
base_point_process_entityrangeXYZrotater   	translater!   appendr$   )r'   doc
block_nameinsert_pointscale_factorsrotation_anglerQ   rR   rS   rT   rW   block_base_pointtransformed_entitiesblock_entityentity_object	row_indexcolumn_indexarray_offsettransformed_entitys                      r4   process_insertrn   a   s%   J&**++,L



#ZZ..!3

M
 ZZ((N::**L

$$IZZ..N**((K JJNN:&Eekkoo889  D,\3? 	DM"9- D	$),$7 DL#)$~5!K/$L
 $*$q)99$q)99$q)99$ fTVV^4	 ! *7)@)@BRAR)S&)./A=)Q&);)B)B*& *<)E)E$|3*& )//0BC+DD	DD4 )**r6   c                     t        | j                  j                   t        | j                  j                   }}||z
  j                  t
        k  rt        j                  dd       yt        ||      S )zConvert LINEzSkipping degenerate LINEr*   
stacklevelN)	r   r-   r0   r2   lengthr   warningswarnr   )r'   r0   r2   s      r4   process_lineru      sX    ))*FFJJNN,C3Ei'0Q?sr6   c                    | j                   j                  }	 |j                  }| j	                  d      }t        |      dk  rt        j                  dd       yt        || j                  |d      S # t        $ r |}Y \w xY w)zConvert LWPOLYLINExybr<   zSkipping degenerate LWPOLYLINEr*   rp   N
LWPOLYLINE)
r-   	elevationzAttributeError
get_pointslenrs   rt   _convert_bulge_polylineclosed)r'   ry   z_valuepointss       r4   process_lwpolyliner      sy    

$$I++ u%F
6{Q61E"66=='<PP  s   A3 3B Bc                 Z    | j                   j                  }t        |d   |d   |d         S )zConvert POINTr   r=   r<   )r-   locationr%   )r'   points     r4   process_pointr      s,    JJE%(E!HeAh//r6   c                 z   | j                         dk7  rt        d| j                                t        | j                        }t	        |      dk  rt        j                  dd       y|D cg c]  }t        t        |j                  j                  j                        t        t        |j                  j                  j                        t        t        |j                  j                  dd	            f }}|d	   j                  j                  j                  }t        || j                   |d
      S c c}w )z<Convert 2D POLYLINE - a collection of LINE and ARC segments.AcDb2dPolylinezUnsupported POLYLINE mode: r<   zSkipping degenerate POLYLINEr*   rp   Nbulger   POLYLINE)get_mode
ValueErrorlistverticesr}   rs   rt   r
   floatr-   r   xyrV   rz   r~   	is_closed)r'   r   vertexr   r   s        r4   process_polyliner      s    ,,6v7H6IJKKFOO$H
8}q4C  	 

++--.

++--.

w23	
F  qkoo&&((G"66+;+;WjQQs   /BD8r   r   r   labelc                 J   g }|rt        |       nt        |       dz
  }t        |      D ]  }| |   }| |dz   t        |       z     }|d   |d   |f}	|d   |d   |f}
t        |      dkD  r|d   nd}t        j                  |	|
      t        k  ret        |      t        k  rt        |	|
      }n)|t        j                  |	|
      z  dz  }t        |	|
|      }|j                  |        |st        j                  d| d       yt        |      dk(  r|d   S t        |      S )	zGConvert a 2D polyline described by vertices with optional bulge values.r=   r   r<   zSkipping degenerate r*   rp   Nedges)r}   rZ   rE   distr   absr   r   r`   rs   rt   r&   )r   r   r   r   r   segment_counti
start_dataend_datastart_point	end_pointr   r8   sagittas                 r4   r~   r~      s/    E#)CKs6{QM=! AY
1q5CK/0!!}jmW=a[(1+w7	!$Z1!4
1!99[),y8u:	!Y/DdiiY??!CGk9g>DT" ,UG4C
5zQQxer6   c           	      P   t        | t              rbt        | j                  j                  | j                  j
                  |f| j                  j                  | j                  j
                  |f      S t        | t              rv| j                  | j                  z
  }| j                  s| }t        | j                  j                  | j                  j
                  |f| j                  | j                  |      S t        | t              rt        | j                   j                  | j                   j
                  d      }|j"                  }t%        j&                  t%        j(                  |j*                  |j,                              }| j                  | j                  z
  }| j                  s| }t/        | j                  j                  | j                  j
                  |f||| j0                  z  | j                  ||      S t        | t2              rpt5        | j6                  D cg c]  }|d   |d   |f c}| j8                  | j:                  | j<                  r| j<                  ndt?        | j@                              S tC        dtE        |       jF                         c c}w )z7Convert a hatch edge-path edge into build123d geometry.)rA   r3   r   r>   r=   Ncontrol_pointsknotsdegreeweightsperiodiczUnsupported HATCH edge type: )$
isinstancer   r   r0   r   r   r2   r   	end_anglerA   ccwr   r.   r/   r   r   rC   rr   rE   rF   rG   r\   r[   r   rD   r   r   r   knot_valuesr   r   boolr   r   type__name__)r8   r   r3   rC   r?   rB   ps          r4   _convert_hatch_edger      s   $!ZZ\\4::<<1DHHJJ

G3T
 	
 $ >>D$4$44xx yH[[]]DKKMM73KK((	
 	
 $$DOO--t/@/@!D
$$<<

:<< FG>>D$4$44xx yH"KKMM4;;==':

*((
 	
 $
#;?;N;NOaQqT1Q41O"";;$(LLDLLd$--(
 	
 4T$Z5H5H4IJ
KK Ps   %J#c                    | j                   j                  }	 |j                  }t	               }| j
                  j                  | j                   j                        D ]  }t        |t              r#t        |j                  |j                  |d      }nt        |t              rF|j                  D cg c]  }t        ||       }}|slt!        |      dk(  r|d   nt#        |      }n.t%        j&                  dt)        |      j*                   d       ||j-                  |        |S # t        $ r |}Y w xY wc c}w )z=Convert HATCH by importing only its perimeter boundary paths.HATCHr=   r   r   z!Unsupported HATCH boundary path: r*   rp   )r-   ry   rz   r{   r$   pathsrendering_pathshatch_styler   r   r~   r   r   r   r   r   r}   r&   rs   rt   r   r   r`   )r'   ry   r   
boundariespathboundaryr8   r   s           r4   process_hatchr     s    

$$I++ *3J,,VZZ-C-CD (dL).t~~wH h'DHJJOD(w7OEO#&u:?uQx58IHMM3DJ4G4G3HIVW h'#(& /   Ps   D/ 1E/D>=D>c                     g }t        d      D ]S  }	 | j                  j                  d|       }|j                  |j                  |j
                  |j                  f       U t        | }|S # t        $ r Y  w xY w)z#Convert filled objects - i.e. Faces   v)	rZ   r-   rV   r`   r   r   rz   r{   r   )r'   r   r   r   polygon_objs        r4   process_solid_trace_3dfacer   1  s~     H1X 	ZZ^^asG,FOOVXXvxx:; 8$K  		s   AA..	A;:A;c                    t        | j                        }t        | j                        }t        | j                        }t        | j                        }| j
                  j                  }t        | j
                  j                  dz        }|r|rt        ||||r||      S d|      S | j
                  j                  d      }| j
                  j                  d      }|rd}	||||f}	t        |d|	iS t        d      )	zConvert SPLINEr<   Nr   start_tangentend_tangent tangentsz;Unsupported SPLINE entity: missing control points and knots)r   r   
fit_pointsr   r   r-   r   r   flagsr   rV   r   r   )
r'   r   r   r   r   r   r   r   r   r   s
             r4   process_spliner   C  s    &//0Nf''(JE6>>"GZZFFJJ$$q()H%)&G
 	
 -1
 	
 JJNN?3M**../K+-$)@%{3Hz5H55
R
SSr6   c           
         t         j                  t         j                  t         j                  t         j                  d}t         j                  t         j                  t         j
                  t         j                  t         j                  t         j                  d}| j                  j                  }| j                  j                  dk7  s| j                  j                  dk7  r1| j                  j                  d      r| j                  j                  }t        | j                  j                  | j                  j                  | j                  j                  dd      |j                  | j                  j                  t         j                        |j                  | j                  j                  t         j                        f      j!                  t#        |       S )zConvert TEXT.)r   r=   r<   r*   )r   r=   r<   r*   r      r   align_pointrB   	font_sizerB   
text_align)r   BOTTOMCENTERTOPLEFTRIGHTr-   rM   halignvalignhasattrr   r    textheightrV   r9   r   )r'   v_alignmenth_alignmentpositions       r4   process_textr   `  sC    ==	K >>??>>>>K zz  H

Q&**"3"3q"8fjj>P>P? ::))

**##
A.OOFJJ--y~~>OOFJJ--y/?/?@
	 eCNr6   c           
         t         j                  t         j                  ft         j                  t         j                  ft         j                  t         j                  ft         j                  t         j                  ft         j                  t         j                  ft         j                  t         j                  ft         j                  t         j
                  ft         j                  t         j
                  ft         j                  t         j
                  fd	}t        | d      r| j                         }n| j                  }t        || j                  j                  | j                  j                  dd      |j                  | j                  j                  t         j                  t         j                  f            j                  t        | j                  j                          S )zConvert MTEXT.)	r=   r<   r*   r   r            	   
plain_textrB   r   r   )r   r   TOPFIRSTLINEr   r   r   r   r   r   r    r-   char_heightrV   attachment_pointr9   r   rM   )r'   attachment_aligncontents      r4   process_mtextr     sN    NNI223i445OOY334NNI,,-i../OOY--.NNI,,-i../OOY--.
 v|$##%++**((
A.#''JJ''^^Y334
	 eC""#$%r6   )3DFACEARCCIRCLEELLIPSEr   INSERTLINErx   MTEXTPOINTr   SOLIDSPLINETEXTTRACEentity_dispatchc                     | g S t        | t              r| D cg c]  }||	 c}S t        | t              r| D cg c]  }||	 c}S | gS c c}w c c}w )z5Normalize handler results into a flat list of shapes.)r   r$   r   )
new_objectobjs     r4   _flatten_import_resultr     s[    	*i()=S_==*d#)=S_==< >=s   AAAAc                     | j                         }|t        vrt        j                  d| d       g S |dk(  rt        |   | |      }t	        |      S t        |   |       }t	        |      S )z?Convert a single DXF entity into zero or more build123d shapes.zUnable to convert r*   rp   r   )dxftyper   rs   rt   r   )r'   ra   r   r   s       r4   rY   rY     ss    nnGo%*7)4C	($W-fc:
 "*-- %W-f5
!*--r6   dxf_filec                    	 t        | t        t        f      rt        j                  |       }nt        | t
              rt        j                  |       }nt        | t              st        | d      rR| j                         }t        |t              r|j                  d      n|}t        j                  t        |            }n!t        dt        |       j                         g }|j#                         D ]  }|j%                  t'        ||              t)        |      S # t        j                  $ r}t!        d|        |d}~ww xY w)zImport shapes from a DXF file

    Args:
        dxf_file (str | PathLike | TextIO | BinaryIO): dxf file path or readable stream

    Raises:
        DXFStructureError: file not found

    Returns:
        ShapeList: build123d objects
    readlatin1zUnsupported DXF input type: zFailed to read N)r   strr   ezdxfreadfiler   r   r   r   bytesdecoder   	TypeErrorr   r   DXFStructureErrorr   
modelspaceextendrY   r$   )r   ra   datar   excbuild123d_objectsr'   s          r4   
import_dxfr    s   @hh0..*C*-**X&C'*gh.G==?D,6tU,C4;;x(D**Xd^,C:4>;R;R:STUU  .." ?  !=>? &'' "" @?8*56C?@s   C!D   E3EE)M__doc__rE   rs   ior   r   r   osr   typingr   r   r	   r
   r   ezdxf.entitiesr   ezdxf.entities.boundary_pathsr   r   r   r   r   r   build123d.build_enumsr   build123d.geometryr   r   r   r   r   build123d.objects_curver   r   r   r   r   r   build123d.objects_sketchr   r   r    build123d.operations_genericr!   build123d.topologyr"   r#   r$   r%   r&   r5   r:   rJ   rn   ru   r   r   r   r   tupler   r   r   r~   r   r   r   r   r   r   r   dict__annotations__r   rY   r  r   r6   r4   <module>r     sQ  8   , ,  3 3  %  , G G  ; : . C CL
 Ly LK: K& K
J +> */+d t Qz QdTkD.@ Q 0* 0 0RZ RD4K$,> R,ueU*+,6:EJSV	D[4@'Lu 'L 'LT* 4$;)? >z $T: T$ T:  D%* % %@ )$ ''(c8m$ &$u+ .DK .(x&08; (	 (r6   