
    ^j                      U d Z ddlmZ ddlZddlZddlZddlZddlZddl	Z	ddl
mZmZ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mZ ddlZddlmZ ddl 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+m,Z,m-Z- ddl.m/Z/ ddl0m1Z1m2Z2m3Z3m4Z4 ddl5m6Z6m7Z7m8Z8 ddl9m:Z:m;Z;m<Z<m=Z=m>Z>m?Z?m@Z@mAZAmBZBmCZCmDZDmEZEmFZF ddlGmHZH ddlImJZJmKZKmLZL ddlMmNZN ddlOmPZP ddlQmRZRmSZSmTZTmUZUmVZV ddlWmXZXmYZYmZZZm[Z[m\Z\ erddl]m^Z^m_Z_m`Z`maZa  ede`      Zb ej                  d      j                   ej                                 ej                  d      ZfdZg eh ei eeg                  ZjdZkedz  Zldez  Zmejdz
  Znenf	 	 	 	 	 dId Zoenf	 	 	 	 	 dJd!Zpd" Zq G d# d$      Zreresetetf   z  esetetetf   z  eet   z  Zud%evd&<   	  G d' d(ew      Zx G d) d*ex+      Zy G d, d-      Zz G d. d/      Z{e|ese|eteiz  f   z  eseteiz  eteiz  eteiz  f   z  eseteiz  eteiz  eteiz  eteiz  f   z  eiz  eseieif   z  e{z  eKz  Z}d%evd0<    G d1 d2ej                        Z G d3 d4      Z G d5 d6ej                        Z G d7 d8      Z G d9 d:e      ZeZeesetetetf   z  Zd%evd;<   	  G d< d=e      Z G d> d?      Z G d@ dAew      Z G dB dCe+      Zeye{eeerdDZ	 dK	 	 	 	 	 	 	 	 	 dLdEZ G dF dGe      ZdMdHZy)Na  
build123d geometry

name: geometry.py
by:   Gumyr
date: March 2nd, 2023

desc:
    This python module contains geometric objects used by the topology.py
    module to form the build123d direct api.

license:

    Copyright 2023 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.

    )annotationsN)CallableIterableSequence)degreeslog10piprodradians)TYPE_CHECKINGAnyType	TypeAliasTypeVarcastoverload)
deprecated)Bnd_BoxBnd_OBB)	BRep_Tool)
BRepBndLib)BRepBuilderAPI_MakeFaceBRepBuilderAPI_Transform)	BRepGPropBRepGProp_Face)	BRepTools)Geom_BoundedSurfaceGeom_ElementarySurface	Geom_Line
Geom_Plane)GeomAPI_IntCSGeomAPI_IntSSGeomAPI_ProjectPointOnSurf)gp_Ax1gp_Ax2gp_Ax3gp_Dirgp_EulerSequencegp_GTrsfgp_Lingp_Plngp_Pntgp_Quaterniongp_Trsfgp_Vecgp_XYZ)GProp_GProps)Quantity_ColorQuantity_ColorRGBAQuantity_TypeOfColor)TopAbs_ShapeEnum)TopLoc_Location)TopoDSTopoDS_EdgeTopoDS_FaceTopoDS_ShapeTopoDS_Vertex)AlignAlign2DAlign3D	Extrinsic	Intrinsic   )EdgeFaceShapeVertex_ShapeT)bound	build123dgư>g{Gz?g     f@   c                ,    t        fd| D              S )z=Return a rounded tuple key for geometry equality and hashing.c              3  6   K   | ]  }t        |        y wNround).0valuedigitss     K/opt/ringagent/.cad-venv/lib/python3.12/site-packages/build123d/geometry.py	<genexpr>z_rounded_key.<locals>.<genexpr>i   s     :%uf%:s   )tuple)valuesrQ   s    `rR   _rounded_keyrV   e   s     :6:::    c                    | j                         | j                         | j                         | j                         g}|D ]+  }t	        |      t
        kD  s|dk  r|D cg c]  }|  }} n t        ||      S c c}w )z6Return a rounded quaternion key with a canonical sign.r   )XYZWabs	TOLERANCErV   )
quaternionrQ   
componentsrP   	components        rR   _canonical_quaternion_keyrb   l   sy     ,,.*,,.*,,.*,,.QJ u:	!qy:DEYyjE
E	
 
F++ Fs    
A;c                    d\  }}}}}| rt        | d   t              r| d   }nt        | d   t              r| d   }npt        | d   t              r| d   }nWt        | d   t        t
        f      rt	        | d         }n/t        | d   d      r| d   }nt        dt        | d                dj                  t        |j                               j                  g d            }|rt        d|       |j                  d|      }|j                  d	|      }|j                  d
|      }|j                  d|      }|j                  d|      }|||||fS )N)NNNNNr   wrappedzUnexpected argument type , )axisplanelocationvectorshapeUnexpected argument(s) rf   rg   ri   rh   rj   )
isinstanceAxisPlaneLocationVectorrT   hasattr
ValueErrortypejoinsetkeys
differenceget)argskwargsrf   rg   ri   rh   rj   unknown_argss           rR   _parse_intersect_argsr|   y   sL   +6(D%5d1gt$7DQ'GEQ*AwHQ&%1DG_FT!Wi(GE8d1gHII99FKKM%%&VWL 2<.ABB::fd#DJJw&EZZ&)Fzz*h/HJJw&E%//rW   c                     e Zd ZU dZded<   dZedBd       ZedCd       ZedDd       ZedEd       ZedFd	       Zed
        Zd Zd Ze	dGd       Z
e
j                  dHd       Z
e	dGd       Zej                  dHd       Ze	dGd       Zej                  dHd       Ze	dId       Z ed      dJd       Ze	dGd       ZdKdZdLdZdMdZdMdZdMdZdMdZdKdZdNdZdNdZdOd ZdNd!ZdPd"ZdPd#ZdPd$ZdLd%Z dQdRd'Z!dSd(Z"dTd)Z#dTd*Z$dUd+Z%dPd,Z&dGd-Z'dVd.Z(dWd/Z)dWd0Z*dWd1Z+dXd2Z,dYd3Z-dZd4Z.dQd[d5Z/dPd6Z0dPd7Z1d\d8Z2d]d9Z3d^d_d:Z4d`d;Z5edad<       Z6edbd=       Z6edcd>       Z6eddd?       Z6eded@       Z6dA Z6y&)frp   a  Create a 3-dimensional vector

    Args:
        x (float): x component
        y (float): y component
        z (float): z component
        vec (Vector |  Sequence(float) |  gp_Vec |  gp_Pnt |  gp_Dir |  gp_XYZ): vector
            representations

    Note that if no z value is provided it's assumed to be zero. If no values are provided
    the returned Vector has the value of 0, 0, 0.

    Attributes:
        wrapped (gp_Vec): the OCP vector object

    r/   _wrappedr   c                     y rL    selfrY   rZ   r[   s       rR   __init__zVector.__init__       rW   c                     y rL   r   )r   rY   rZ   s      rR   r   zVector.__init__   r   rW   c                     y rL   r   r   vs     rR   r   zVector.__init__   r   rW   c                     y rL   r   r   s     rR   r   zVector.__init__   r   rW   c                     y rL   r   r   s     rR   r   zVector.__init__   r   rW   c                     y rL   r   r   s    rR   r   zVector.__init__   r   rW   c           	     R   d| _         d\  }}}}dj                  t        |j                               j	                  g d            }|rt        d|       r[t        fdt        t                    D              r5t              }|dgt        ddt              z
        z  z  }|dd \  }}}n|t              d	k(  sd
|v rird   nd }	|j                  d
|	      }	t        |	t              r%t        |	j                  j!                               }nt#        |	d      rSt        |	j                  t$              r9t'        j(                  |	j                        }
t        |
j!                               }nt        |	t*        t,        f      rH	 |	D cg c]  }t/        |       }}t        |      dk  r|dgdt        |      z
  z  z  }t        |dd  }n\t        |	t        t2        t4        f      rt        |	j!                               }n't        |	t6              rt        |	      }nt1        d      |j                  d|      }|j                  d|      }|j                  d|      }|t        |||      n|}|| _        y c c}w # t0        t
        f$ r}t1        d      |d }~ww xY w)Nr   r   r   r   Nre   )r   rY   rZ   r[   rk   c              3  P   K   | ]  }t        |   t        t        f        y wrL   rl   intfloat)rO   iry   s     rR   rS   z"Vector.__init__.<locals>.<genexpr>   s      Ta
47S%L9Ts   #&           rA   r   rd   zExpected floatsz%Expected floats, OCC gp_, or iterablerY   rZ   r[   )vector_indexrt   ru   rv   rw   rr   allrangelenlistmaxrx   rl   rp   r/   rd   XYZrq   r;   r   Pnt_srT   r   r   	TypeErrorr,   r'   r0   r~   )r   ry   rz   xyzocp_vecr{   rU   	first_arg
geom_pointrP   excs    `           rR   r   zVector.__init__   sS   (1ayyV[[]!3!>!>?S!TU6|nEFFCT5TCSTT$ZFsec!a#d)m555FQqkGAq!Y!^sf}#'QTI

3	2I)V, !2!2!6!6!89I.:!!=4 '__Y->->?
 !12Ix'89@8ABueElBFB v;?seq3v;77F &1+.I'?@ 1Iv. + GHHJJsAJJsAJJsA%,_&Aq/'# C!:. @#$56C?@s*   J J%J J J&J!!J&c                Z    t        | j                  | j                  | j                  f      S rL   )iterrY   rZ   r[   r   s    rR   __iter__zVector.__iter__   s     TVVTVVTVV,--rW   c                6    | j                   j                         S )zGet x value)rd   rY   r   s    rR   rY   zVector.X        ||~~rW   c                :    | j                   j                  |       y)zSet x valueN)rd   SetXr   rP   s     rR   rY   zVector.X        	% rW   c                6    | j                   j                         S )zGet y value)rd   rZ   r   s    rR   rZ   zVector.Y  r   rW   c                :    | j                   j                  |       y)zSet y valueN)rd   SetYr   s     rR   rZ   zVector.Y  r   rW   c                6    | j                   j                         S )zGet z value)rd   r[   r   s    rR   r[   zVector.Z  r   rW   c                :    | j                   j                  |       y)zSet z valueN)rd   SetZr   s     rR   r[   zVector.Z  r   rW   c                    | j                   S )zOCCT objectr~   r   s    rR   rd   zVector.wrapped       }}rW   z]to_tuple is deprecated and will be removed in a future version.  Use 'tuple(Vector)' instead.c                H    | j                   | j                  | j                  fS )zReturn tuple equivalentrY   rZ   r[   r   s    rR   to_tuplezVector.to_tuple  s     ''rW   c                6    | j                   j                         S )zVector length)rd   	Magnituder   s    rR   lengthzVector.length$  s     ||%%''rW   c                ^    t        | j                  j                  |j                              S )zMathematical cross function)rp   rd   Crossedr   vecs     rR   crosszVector.cross)  s     dll**3;;788rW   c                L    | j                   j                  |j                         S )zMathematical dot function)rd   Dotr   s     rR   dotz
Vector.dot-  s    ||,,rW   c                *   t        |t              r0t        | j                  j                  |j                              }|S t        |t              r9t        | j                  j                  t        |      j                              }|S t        d      )z!Mathematical subtraction functionz5Only Vectors or tuples can be subtracted from Vectors)rl   rp   rd   
SubtractedrT   rr   r   r   results      rR   subz
Vector.sub1  st    c6"DLL33CKK@AF  U#DLL33F3K4G4GHIF  TUUrW   c                $    | j                  |      S )z#Mathematical subtraction operator -)r   r   s     rR   __sub__zVector.__sub__<      xx}rW   c                *   t        |t              r0t        | j                  j                  |j                              }|S t        |t              r9t        | j                  j                  t        |      j                              }|S t        d      )zMathematical addition functionz.Only Vectors or tuples can be added to Vectors)rl   rp   rd   AddedrT   rr   r   s      rR   addz
Vector.add@  st    c6"DLL..s{{;<F  U#DLL..vc{/B/BCDF  MNNrW   c                $    | j                  |      S )z Mathematical addition operator +)r   r   s     rR   __add__zVector.__add__K  r   rW   c                L    |dk(  rt        ddd      n|}| j                  |      S )z(Mathematical reverse addition operator +r   )rp   r   r   s     rR   __radd__zVector.__radd__O  s%    !$fQ1osxx}rW   c                J    t        | j                  j                  |            S )zMathematical multiply function)rp   rd   
Multipliedr   scales     rR   multiplyzVector.multiplyT  s    dll--e455rW   c                $    | j                  |      S z Mathematical multiply operator *r   r   s     rR   __mul__zVector.__mul__X      }}U##rW   c                *    | j                  d|z        S )z Mathematical division operator /      ?r   )r   denoms     rR   __truediv__zVector.__truediv__\  s    }}S5[))rW   c                $    | j                  |      S r   r   r   s     rR   __rmul__zVector.__rmul__`  r   rW   c                H    t        | j                  j                               S )zScale to length of 1)rp   rd   
Normalizedr   s    rR   
normalizedzVector.normalizedd  s    dll--/00rW   c                    | dz  S )zNReturn a vector with the same magnitude but pointing in the opposite direction      r   r   s    rR   reversezVector.reverseh  s    d{rW   c                    | S )zcenter

        Returns:
          The center of myself is myself.
          Provided so that vectors, vertices, and other shapes all support a
          common interface, when center() is requested for all objects on the
          stack.

        r   r   s    rR   centerzVector.centerl  s	     rW   c                Z    | j                   j                  |j                         t        z  S )zUnsigned angle between vectorsrd   AngleRAD2DEGr   s     rR   	get_anglezVector.get_anglex  s     ||!!#++.88rW   Nc                    |t        ddd      }n|j                  }| j                  j                  |j                  |      t        z  S )u~  Signed Angle Between Vectors

        Return the signed angle in degrees between two vectors with the given normal
        based on this math: angle = atan2((Va × Vb) ⋅ Vn, Va ⋅ Vb)

        Args:
            v (Vector): Second Vector
            normal (Vector, optional): normal direction. Defaults to None.

        Returns:
            float: Angle between vectors
        r   )r/   rd   AngleWithRefr   )r   r   normal	gp_normals       rR   get_signed_anglezVector.get_signed_angle|  s@     >q!R(II||((i@7JJrW   c                N    |j                   }|| j                  |      ||z  z  z  S )zReturns a new vector equal to the projection of this Vector onto the line
        represented by Vector <line>

        Args:
            line (Vector): project to this line

        Returns:
            Vector: Returns the projected vector.

        )r   r   )r   lineline_lengths      rR   project_to_linezVector.project_to_line  s*     kktxx~{)BCDDrW   c                T    |j                   j                  | j                               S )z2Minimum unsigned distance between vector and plane)rd   Distanceto_pntr   rg   s     rR   distance_to_planezVector.distance_to_plane  s    }}%%dkkm44rW   c                R    | |j                   z
  j                  |j                        S )z+Signed distance from plane to point vector.)originr   z_dirr   s     rR   signed_distance_from_planez!Vector.signed_distance_from_plane  s     u||#((55rW   c                    |j                   }|j                  }| || |z
  j                  |      |j                  dz  z  z  z
  S )zVector is projected onto the plane provided as input.

        Args:
          args: Plane object

        Returns the projected vector.
          plane: Plane:

        Returns:

           )r  r  r   r   )r   rg   baser   s       rR   project_to_planezVector.project_to_plane  sC     ||f$+!2!26!:fmmQ>N NOOOrW   c                    | dz  S )z#Flip direction of vector operator -r   r   r   s    rR   __neg__zVector.__neg__  s    byrW   c                    | j                   S )zVector length operator abs())r   r   s    rR   __abs__zVector.__abs__  s    {{rW   c                $    | j                  |      S zintersect vector with other &	intersectr   others     rR   __and__zVector.__and__      ~~e$$rW   c                J   dd}|r|d   nd}|dv rd|v r!t        |dd j                  d      d         }n	|dk(  rdnd} || j                  |      } || j                  |      } || j                  |      }d	|| d
d|| d
d|| d
dS t        t        |             S )zFormat Vectorc                B    t        |       t        kD  rt        | |      S dS )Nr   )r]   r^   rN   )r   	precisions     rR   
trim_floatz%Vector.__format__.<locals>.trim_float  s    *-a&9*<5I&E#ErW   r   Nfg.r        ( re   ))r   r   r  r   returnr   )r   splitrY   rZ   r[   strrT   )r   specr  	last_charr  r   r   r   s           rR   
__format__zVector.__format__  s    	F !%DH$	
"d{Sb	 4R 89	!*c!1Ar	4669-A4669-A4669-Aq$pj1dV0G*Bq$pj::5;rW   c                6    t        |       j                   | dS )zRepresent Vectorz.13g)rs   __name__r   s    rR   __repr__zVector.__repr__  s    t*%%&tDk22rW   c                    t        | d      dd j                  d      \  }}}t        |       j                   d| d| d| dS )	zDisplay Vectorz.6grA   r   re   z: (X=z, Y=z, Z=r!  )formatr#  rs   r)  )r   r   r   r   s       rR   __str__zVector.__str__  sP    u%a+11$71at*%%&eA3d1#T!A>>rW   c                p    t        |t              st        S | j                         |j                         k(  S )zVectors equal operator ==)rl   rp   NotImplemented_keyr  s     rR   __eq__zVector.__eq__  s)    %(!!yy{ejjl**rW   c                4    t        | j                               S )zHash of Vectorhashr0  r   s    rR   __hash__zVector.__hash__      DIIK  rW   c                Z    t        | j                  | j                  | j                  f      S z,Canonical key used for equality and hashing.)rV   rY   rZ   r[   r   s    rR   r0  zVector._key  s     TVVTVVTVV455rW   c                    t        t        | j                  |      t        | j                  |      t        | j                  |            S rL   )rp   rN   rY   rZ   r[   )r   ndigitss     rR   	__round__zVector.__round__  s7    $&&'"E$&&'$:E$&&'<R
 	
rW   c                X    t        | j                  | j                  | j                        S zReturn copy of selfrp   rY   rZ   r[   r   s    rR   __copy__zVector.__copy__      dffdffdff--rW   c                X    t        | j                  | j                  | j                        S zReturn deepcopy of selfr>  r   _memos     rR   __deepcopy__zVector.__deepcopy__  r@  rW   c                H    t        | j                  j                               S )zConvert to OCCT gp_Pnt object)r,   rd   r   r   s    rR   r   zVector.to_pnt      dll&&())rW   c                H    t        | j                  j                               S )zConvert to OCCT gp_Dir object)r'   rd   r   r   s    rR   to_dirzVector.to_dir   rG  rW   c                z   |s]| j                         }|j                  |j                  j                               }t	        t        |j                                     }|S | j                         }|j                  |j                  j                               }t	        t        |j                                     }|S )a;  Apply affine transformation

        Args:
            affine_transform (Matrix): affine transformation matrix
            is_direction (bool, optional): Should self be transformed as a vector or direction?
                Defaults to False (vector)

        Returns:
            Vector: transformed vector
        )r   Transformedrd   Trsfrp   r/   r   rI  )r   affine_transformis_directionpntpnt_treturn_valuegp_dirdir_ts           rR   	transformzVector.transform  s      ++-COO$4$<$<$A$A$CDE!&"56L  [[]F&&'7'?'?'D'D'FGE!&"56LrW   c                r    t        | j                  j                  |j                  t        |                  S )zRotate about axis

        Rotate about the given Axis by an angle in degrees

        Args:
            axis (Axis): Axis of rotation
            angle (float): angle in degrees

        Returns:
            Vector: rotated vector
        )rp   rd   Rotatedr   )r   rf   angles      rR   rotatezVector.rotate  s(     dll**4<<HIIrW   c                     y)z&Find intersection of vector and vectorNr   r   ri   s     rR   r  zVector.intersect*      rW   c                     y)z(Find intersection of vector and locationNr   r   rh   s     rR   r  zVector.intersect.  r[  rW   c                     y)z$Find intersection of vector and axisNr   r   rf   s     rR   r  zVector.intersect2  r[  rW   c                     y)z%Find intersection of vector and planeNr   r   s     rR   r  zVector.intersect6  r[  rW   c                     y)z%Find intersection of vector and shapeNr   r   rj   s     rR   r  zVector.intersect:  r[  rW   c                    t        |i |\  }}}}}||j                  |       S ||j                  |       S || |k(  r|S ||j                  |       S ||j                  |       S y)z9Find intersection of vector and geometric object or shapeN)r|   r  r   ry   rz   rf   rg   ri   rh   rj   s           rR   r  zVector.intersect>  s    /Dd/Uf/U,eVXu>>$''??4(($&.M%%d++??4((rW   rY   r   rZ   r   r[   r   )rY   r   rZ   r   )r   rp   )r   Sequence[float])r   z!gp_Vec | gp_Pnt | gp_Dir | gp_XYZr"  r   )rP   r   r"  None)r"  r/   )r"  tuple[float, float, float])r   rp   r"  rp   )r   rp   r"  r   )r   
VectorLiker"  rp   )r   r   r"  rp   )r   r   r"  rp   r"  rp   rL   )r   rp   r   Vector | Noner"  r   )r   rp   r"  rp   )rg   rn   r"  r   )rg   rn   r"  rp   )r  ,Axis | Location | Plane | VectorLike | Shaper"  r$  r  objectr"  boolr"  r   )r"  tuple[float, ...])r:  z
int | None)r"  r,   )r"  r'   )F)rM  MatrixrN  rq  r"  rp   )rf   rm   rW  r   r"  rp   ri   rj  r"  rl  )rh   ro   r"  rl  )rf   rm   r"  rl  )rg   rn   r"  rl  rj   rD   r"  zShape | None)7r)  
__module____qualname____doc____annotations___dimr   r   r   propertyrY   setterrZ   r[   rd   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-  r1  r5  r0  r;  r?  rE  r   rI  rT  rX  r  r   rW   rR   rp   rp      s   , D           ) V.     XX! !     XX! !     XX! !   	((	( ( (9-		
6$*$1
9K&E56P"% *3?
+!6

..**0J 5 5 7 7 3 3 4 4 4 4rW   rp   r   rj  c                  F    e Zd ZdZedd       Zedd       Zedd       Zy)AxisMetaz*Axis meta class to enable class propertiesc                     | dd      S )zX Axisr   r   r   rA   r   r   r   clss    rR   rY   z
AxisMeta.Xd       9i((rW   c                     | dd      S )zY Axisr  r   rA   r   r   r  s    rR   rZ   z
AxisMeta.Yi  r  rW   c                     | dd      S )zZ Axisr  r   r   rA   r   r  s    rR   r[   z
AxisMeta.Zn  r  rW   Nr"  rm   )r)  rw  rx  ry  r|  rY   rZ   r[   r   rW   rR   r  r  a  s?    4) ) ) ) ) )rW   r  c                  R   e Zd ZdZdZed-d       Zed.d       Zed/d       Zed0d       Zed1d       Zd2dZed	        Zed3d
       Z	e	j                  d4d       Z	ed3d       Zej                  d5d       Zed6d       Zd7dZd7dZd8dZd9dZd9dZd9dZd:dZd;dZd<dZ ed      d=d       Z	 	 d>	 	 	 	 	 	 	 d?dZd@dAdZd@dAdZd@dAdZd@dBdZdCdZd7d Zd7d!Z	 	 	 	 dDd"Z dEd#Z!dFd$Z"dGd%Z#edFd&       Z$edGd'       Z$edEd(       Z$edHd)       Z$edId*       Z$d+ Z$y,)Jrm   a#  Axis

    Axis defined by point and direction or by two points

    Args:
        origin (VectorLike): start point
        direction (VectorLike): direction
        end_point (VectorLike): point used with origin to define direction
        edge (Edge): origin & direction defined by start of edge
        location (Location): location to convert to axis

    Attributes:
        position (Vector): the global position of the axis origin
        direction (Vector): the normalized direction vector
        wrapped (gp_Ax1): the OCP axis object
    rA   c                     yzAxis: point and directionNr   )r   gp_ax1s     rR   r   zAxis.__init__  r[  rW   c                     y)zAxis from locationNr   r]  s     rR   r   zAxis.__init__  r[  rW   c                     yr  r   )r   r  	directions      rR   r   zAxis.__init__  r[  rW   c                    y)zAxis: point and end pointNr   )r   r  	end_points      rR   r   zAxis.__init__  r[  rW   c                     y)zAxis: start of EdgeNr   )r   edges     rR   r   zAxis.__init__  r[  rW   c           	        |j                  dd       }|j                  dd       }|j                  dd       }|j                  dd       }|j                  dd       }|j                  dd       }|r+t        ddj                  |j                                      t	        |      d	k(  r{|d
   }	t        |	t              r|	}nvt        |	t              r|	}nct        |	d      rt        |	j                  t              r|	}n:t        |	t        t        f      r|	}n!t        d|	       t	        |      dk(  r|\  }}|$|t        d      t        |      t        |      z
  }|t        |d      rt        |j                  t              st        d|       |j                  }
t        j                  |
t               t                     }t        j                   |
      \  }}t#               }t%               }|j'                  |||       t        |      }t        t)        |            }|)t*        j,                  j/                  |      j                  }|V	 t        |      }t        |      }t        |j1                         t)        t        |j3                                      }|| _        y t        |t              st        d|       || _        y # t4        $ r}t        d      |d }~ww xY w)Nr  r  r  r  r  rh   Unexpected argument(s): re   rA   r   rd   zUnrecognized single argument: r  z,Axis end_point cannot be used with directionzInvalid edge argument: zInvalid Axis parameterszInvalid Axis parameter: )poprr   rt   rv   r   rl   r$   ro   rq   rd   r8   rp   rT   r   Curve_sr   Range_sr,   r/   D1r'   rm   r[   locatedr   r   	Exceptionr~   )r   ry   rz   r  r  r  r  r  rh   argtopods_edgecurve	param_min_
origin_pnttangent_vecorigin_vectordirection_vectorr   s                      rR   r   zAxis.__init__  s    Hd+Hd+JJ{D1	JJ{D1	zz&$'::j$/ 7		&++-8P7QRSS t9>q'C#v&C*i(Z[-QC&%1 #A#!GHHY!^ $FI  $ !OPPy)F6N:I D),DLL+1V #:4&!ABB'+||K%%k57EGDE$,,[9LIqJ (KHHY
K8J'Fvk23I VV^^H-55F >E &v#))#4 !((*E"2"="="?@A !' FF+7x@AA &  E !:;DEs   AK 	K&K!!K&c                    | j                   S z
OCP objectr   r   s    rR   rd   zAxis.wrapped  r   rW   c                H    t        | j                  j                               S )z"The position or origin of the Axisrp   rd   ro   r   s    rR   positionzAxis.position       dll++-..rW   c                h    | j                   j                  t        |      j                                y)z&Set the position or origin of the AxisNrd   SetLocationrp   r   )r   r  s     rR   r  zAxis.position  s$     	  !1!8!8!:;rW   c                H    t        | j                  j                               S )z$The normalized direction of the Axis)rp   rd   	Directionr   s    rR   r  zAxis.direction  s     dll,,.//rW   c                h    | j                   j                  t        |      j                                y)zSet the direction of the AxisN)rd   SetDirectionrp   rI  )r   r  s     rR   r  zAxis.direction  s$     	!!&"3":":"<=rW   c                V    t        t        | j                  | j                              S )zReturn self as Locationr  r  )ro   rn   r  r  r   s    rR   rh   zAxis.location  s     T]]$..IJJrW   c                B    t        | j                  | j                        S r=  rm   r  r  r   s    rR   r?  zAxis.__copy__       DMM4>>22rW   c                B    t        | j                  | j                        S rB  r  rC  s     rR   rE  zAxis.__deepcopy__  r  rW   c                4    t        | j                               S )zHash of Axisr3  r   s    rR   r5  zAxis.__hash__  r6  rW   c                    |r|d   nd}|dv r%d| j                   | dd| j                  | ddS dt        | j                          dt        | j                         dS )zFormat Axisr   Nr  r  r   re   r!  )r  r  rT   r   r%  r&  s      rR   r'  zAxis.__format__  so     $DH$	
"t}}dV0G,Bt~~tf@W.EQGG5'(5+@*ACCrW   c                F    t        |       j                   | dt         dS )zRepresent Axisr  r  rs   r)  
TOL_DIGITSr   s    rR   r*  zAxis.__repr__  '    t*%%&tAj\?&;<<rW   c                    t        |       j                   d| j                  dt         dd| j                  dt         ddS )zDisplay Axis: (position=r  r  z, direction=r!  )rs   r)  r  r  r  r   s    rR   r-  zAxis.__str__  sU     Dz""# $qAo6l4>>RST^S__`Q`Baabd	
rW   c                p    t        |t              st        S | j                         |j                         k(  S rL   )rl   rm   r/  r0  r  s     rR   r1  zAxis.__eq__  s)    %&!!yy{ejjl**rW   c                j    | j                   j                         | j                  j                         fS r8  )r  r0  r  r   s    rR   r0  z	Axis._key$  s'    ""$dnn&9&9&;<<rW   c                    |j                   }| j                   }|j                  |j                               }t        |      S )zIrelocates self to a new location possibly changing position and direction)rd   rK  Transformationrm   )r   new_locationtop_locationself_gp_ax1
new_gp_ax1s        rR   r  zAxis.located(  s:    #++"ll(44\5P5P5RS
JrW   z[to_tuple is deprecated and will be removed in a future version.  Use 'Plane(Axis)' instead.c                D    t        | j                  | j                        S )zReturn self as Planer  )rn   r  r  r   s    rR   to_planezAxis.to_plane/  s     DMM@@rW   c                d    | j                   j                  |j                   |t        dz  z  |      S )a  are axes coaxial

        True if the angle between self and other is lower or equal to angular_tolerance and
        the distance between self and other is lower or equal to linear_tolerance.

        Args:
            other (Axis): axis to compare to
            angular_tolerance (float, optional): max angular deviation. Defaults to 1e-5.
            linear_tolerance (float, optional): max linear deviation. Defaults to 1e-5.

        Returns:
            bool: axes are coaxial
        rI   )rd   	IsCoaxialr	   )r   r  angular_tolerancelinear_tolerances       rR   
is_coaxialzAxis.is_coaxial7  s1    & ||%%MM,S9;K
 	
rW   c                b    | j                   j                  |j                   |t        dz  z        S )u  are axes normal

        Returns True if the direction of this and another axis are normal to each other. That is,
        if the angle between the two axes is equal to 90° within the angular_tolerance.

        Args:
            other (Axis): axis to compare to
            angular_tolerance (float, optional): max angular deviation. Defaults to 1e-5.

        Returns:
            bool: axes are normal
        rI   )rd   IsNormalr	   r   r  r  s      rR   	is_normalzAxis.is_normalN  s)     ||$$U]]4Ec4RSSrW   c                b    | j                   j                  |j                   |t        dz  z        S )u  are axes opposite

        Returns True if the direction of this and another axis are parallel with
        opposite orientation. That is, if the angle between the two axes is equal
        to 180° within the angular_tolerance.

        Args:
            other (Axis): axis to compare to
            angular_tolerance (float, optional): max angular deviation. Defaults to 1e-5.

        Returns:
            bool: axes are opposite
        rI   )rd   
IsOppositer	   r  s      rR   is_oppositezAxis.is_opposite]  *     ||&&u}}6G2PS86TUUrW   c                b    | j                   j                  |j                   |t        dz  z        S )u  are axes parallel

        Returns True if the direction of this and another axis are parallel with same
        orientation or opposite orientation. That is, if the angle between the two axes is
        equal to 0° or 180° within the angular_tolerance.

        Args:
            other (Axis): axis to compare to
            angular_tolerance (float, optional): max angular deviation. Defaults to 1e-5.

        Returns:
            bool: axes are parallel
        rI   )rd   
IsParallelr	   r  s      rR   is_parallelzAxis.is_parallelm  r  rW   c                Z   | j                  ||      rA| j                  |j                  z
  j                  | j                        }|j                  |kD  S | j                  |j                  z
  j                  | j                  j                  |j                              }t        |      |kD  S )a*  are axes skew

        Returns True if this axis and another axis are skew, meaning they are neither
        parallel nor coplanar. Two axes are skew if they do not lie in the same plane
        and never intersect.

        Mathematically, this means:

        - The axes are **not parallel** (the cross product of their direction vectors
          is nonzero).

        - The axes are **not coplanar** (the vector between their positions is not
          aligned with the plane spanned by their directions).

        If either condition is false (i.e., the axes are parallel or coplanar), they are
        not skew.

        Args:
            other (Axis): axis to compare to
            tolerance (float, optional): max deviation. Defaults to 1e-5.

        Returns:
            bool: axes are skew
        )r  r  r   r  r   r   r]   )r   r  	toleranceparallel_offsetcoplanaritys        rR   is_skewzAxis.is_skew}  s    2 E9-#}}u~~=DDT^^TO"))I55 }}u~~5::NN  1

 ;)++rW   c                Z    | j                   j                  |j                         t        z  S )u  calculate angle between axes

        Computes the angular value, in degrees, between the direction of self and other
        between 0° and 360°.

        Args:
            other (Axis): axis to compare to

        Returns:
            float: angle between axes
        r   r  s     rR   angle_betweenzAxis.angle_between  s"     ||!!%--07::rW   c                T     t        |       | j                  j                               S )z1Return a copy of self with the direction reversed)rs   rd   Reversedr   s    rR   r   zAxis.reverse  s     tDz$,,//122rW   c                "    | j                         S )zFlip direction operator -)r   r   s    rR   r
  zAxis.__neg__  s    ||~rW   c                $    | j                  |      S r  r  r  s     rR   r  zAxis.__and__       ~~e$$rW   c                >   | j                  |      r| S | j                  |      ryt        j                  g | j                        }t        j                  g | j
                        }t        j                  g |j                        }t        j                  g |j
                        }t        j                  || t        j                  ||      g      j                  }||z
  }t        j                  j                  ||d      d   \  }}	}	|||z  z   }
t        |
 S )z0Find intersection of this axis and another axis.N)rcondr   )r  r  nparrayr  r  r   Tlinalglstsqrp   )r   rf   p1d1p2d2system_of_equationsorigin_difft1r  intersection_points              rR   _intersect_axiszAxis._intersect_axis  s    ??4 K<<XX&&'XX''(XX&&'XX''( hhRC"b1A'BCEE2g99??#64?PQRSAq"r'\)**rW   c                    t        |      }|| j                  z
  }|j                  | j                        }| j                  |z  | j                  z   }||k(  r|S dS )z+Find intersection of this axis and a point.N)rp   r  r   r  )r   ri   vec_to_pointprojected_lengthprojected_vecs        rR   _intersect_vectorzAxis._intersect_vector  sX    -'++DNN;)99DMMI=0v:d:rW   c                    t        |      j                  }| j                  |j                        y|| j                  k(  r|S |j                  S )z.Find intersection of this axis and a location.N)rn   r  r  r  r  )r   rh   location_dirs      rR   _intersect_locationzAxis._intersect_location  sF    X,,>>(++,44>>)O   rW   c                     y)z$Find intersection of axis and vectorNr   rZ  s     rR   r  zAxis.intersect  r[  rW   c                     y)z&Find intersection of axis and locationNr   r]  s     rR   r  zAxis.intersect  r[  rW   c                     y)z"Find intersection of axis and axisNr   r_  s     rR   r  zAxis.intersect  r[  rW   c                     y)z#Find intersection of axis and planeNr   r   s     rR   r  zAxis.intersect  r[  rW   c                     y)z#Find intersection of axis and shapeNr   rb  s     rR   r  zAxis.intersect  r[  rW   c                    t        |i |\  }}}}}|| j                  |      S ||j                  |       S || j                  |      S || j	                  |      S ||j                  |       S y)z7Find intersection of axis and geometric object or shapeN)r|   r  r  r  r   rd  s           rR   r  zAxis.intersect  s    /Dd/Uf/U,eVXu''--??4(())&11++H55??4((rW   N)r  r$   r"  rh  rh   ro   r"  rh  )r  rj  r  rj  r"  rh  )r  rj  r  rj  r"  rh  )r  rB   r"  rh  ry   r   rz   r   r"  rh  rk  )r  rj  r  rj  r"  ro   r  rr  rn  ro  r"  z+tuple[tuple[float, ...], tuple[float, ...]])r  ro   r"  rn   )h㈵>r  )r  rm   r  r   r  r   r"  rq  )r  )r  rm   r  r   r"  rq  )r  rm   r  r   r"  rq  )r  rm   r"  r   )r  rm  r"  zVector | Location | Axis | Nonerf   rm   r"  Vector | Axis | Noneru  rh   ro   r"  Vector | Location | None)rg   rn   r"  r  rv  )%r)  rw  rx  ry  r{  r   r   r|  rd   r  r}  r  rh   r?  rE  r5  r'  r*  r-  r1  r0  r  r   r  r  r  r  r  r  r  r   r
  r  r  r  r   r  r   rW   rR   rm   rm   t  s0   " D( ( ! ! ( ( ( ( " "D'L   / / __< < 0 0 > > K K33!D=
+
=  	&A	A $("&	

 !
  	

 

.TV V %,N;3%A%	(%+&;! 3 3 5 5 1 1 2 2 2 2rW   rm   )	metaclassc                      e Zd ZdZedd       Ze	 d	 	 	 	 	 	 	 dd       Zd Zedd       Zedd       Zd Z	dd	Z
	 d	 	 	 	 	 dd
Zedd       Ze	 	 d	 	 	 	 	 	 	 dd       ZddZefddZddZy)BoundBoxzA BoundingBox for a Shapec                     y)z'Construct a bounding box from a Bnd_BoxNr   )r   bounding_boxs     rR   r   zBoundBox.__init__  r[  rW   Nc                     y)z,Construct a bounding box from a TopoDS_ShapeNr   )r   rj   r  optimals       rR   r   zBoundBox.__init__  r[  rW   c                (   |j                  dd       }|j                  dd       }|j                  dd       }|j                  dd      }|rt        ddj                  |             |r|t        |d   t              r|d   }nt        |d   t
              rz|d   }t        |      d	kD  r/t        |d	   t              r|d	   }n|d	   rt        d
|d	          t        |      dkD  rGt        |d   t              st        d|d          |d   }nt        ddj                  |             |rYt        j                  |       |t        n|}t	               }|rt        j                  ||       nt        j                  ||d       |j                         r
d\  }}}	}
}}n|j!                         \  }}}	}
}}|j                         rd n|| _        t%        |||	      | _        t%        |
||      | _        t%        |
|z
  ||z
  ||	z
        | _        y )Nr  rj   r  r  TUnexpected keyword arguments: re   r   rA   z-Second parameter must be a float or None not r  z#Third parameter must be a bool not Invalid positional arguments: )r   r   r   r   r   r   )r  r   rt   rl   r   r:   r   r   rq  r   Clean_sTOLr   AddOptimal_sAdd_sIsVoidGetrd   rp   minr   size)r   ry   rz   r  rj   r  r  x_miny_minz_minx_maxy_maxz_maxs                rR   r   zBoundBox.__init__  s   zz.$7

7D)JJ{D1	**Y- <TYYv=N<OPQQ #
47G(D#AwDG\2Qt9q=!$q'51$(G	a'KDQRG9U  t9q=%d1gt4'*MdSTgY(WXX"1gG"@4@Q RSSe$ !(i  #9L''|<  d; 7A4E5%u7C7G7G7I4E5%u+224t,%.%.55=%%-G	rW   c                f    t        | j                  D cg c]  }|t        kD  s| c}      S c c}w )zReturn the overall Lebesgue measure of the bounding box.

        - For 1D objects: length
        - For 2D objects: area
        - For 3D objects: volume
        )r
   r#  r^   )r   r   s     rR   measurezBoundBox.measureO  s'     		;1Q]Q;<<;s   ..c                V    | j                   y| j                   j                         dz  S )z/body diagonal length (i.e. object maximum size)r         ?rd   SquareExtentr   s    rR   diagonalzBoundBox.diagonalY  s)     <<||((*c11rW   c                   d| j                   j                   d| j                  j                   d| j                   j                   d| j                  j                   d| j                   j                   d| j                  j                   S )zDisplay bounding box parameterszbbox: z	 <= x <= re   z	 <= y <= z	 <= z <= )r"  rY   r   rZ   r[   r   s    rR   r*  zBoundBox.__repr__`  se     TXXZZL	$((**R

|9TXXZZLXZxxzzl)DHHJJ<1	
rW   c                :    | j                   | j                  z   dz  S )z!Return center of the bounding boxr  )r"  r   r   s    rR   r   zBoundBox.centerg  s    488#q((rW   c                   |t         n|}t               }|j                  |       | j                  |j	                  | j                         t        |t              r |j                  |  t        |      S t        |t              r |j                  |  t        |      S t        |t              r'|j                  |j	                  |j                         t        |      S )a  Returns a modified (expanded) bounding box

        obj can be one of several things:
            1. a 3-tuple corresponding to x,y, and z amounts to add
            2. a vector, containing the x,y,z values to add
            3. another bounding box, where a new box will be created that
               encloses both.

        This bounding box is not changed.

        Args:
          obj: tuple[float, float, float] | Vector | BoundBox]:
          tol: float:  (Default value = None)

        Returns:

        )
r  r   SetGaprd   Addrl   rT   Updaterp   r  )r   objtoltmps       rR   r   zBoundBox.addk  s    . [cci

3<<#GGDLL!c5!CJJ } V$CJJ } X&3;;+BGGCKK }rW   c                   | j                   j                  |j                   j                  k  r| j                  j                  |j                  j                  kD  r^| j                   j                  |j                   j                  k  r1| j                  j                  |j                  j                  kD  r| }|S |j                   j                  | j                   j                  k  r|j                  j                  | j                  j                  kD  r^|j                   j                  | j                   j                  k  r1|j                  j                  | j                  j                  kD  r|}|S d}|S )a  Compares bounding boxes

        Compares bounding boxes. Returns none if neither is inside the other.
        Returns the outer one if either is outside the other.

        BoundBox.is_inside works in 3d, but this is a 2d bounding box, so it
        doesn't work correctly plus, there was all kinds of rounding error in
        the built-in implementation i do not understand.

        Args:
          bb1: BoundBox:
          bb2: BoundBox:

        Returns:

        N)r"  rY   r   rZ   )bb1bb2r   s      rR   find_outside_box_2dzBoundBox.find_outside_box_2d  s    ( GGII		!		CGGII%		CGGII%		CGGII%F  GGII		!		CGGII%		CGGII%		CGGII%F  FrW   c                     | |||      S )a  Constructs a bounding box from a TopoDS_Shape

        Args:
            shape: TopoDS_Shape:
            tolerance: float:  (Default value = None)
            optimal: bool:  This algorithm builds precise bounding box (Default value = True)

        Returns:

        r   )r  rj   r  r  s       rR   from_topo_dszBoundBox.from_topo_ds  s    " 5)W--rW   c                4   |j                   j                  | j                   j                  kD  xr |j                   j                  | j                   j                  kD  xr |j                   j                  | j                   j                  kD  xr |j                  j                  | j                  j                  k  xr\ |j                  j                  | j                  j                  k  xr- |j                  j                  | j                  j                  k   S )zpIs the provided bounding box inside this one?

        Args:
          b2: BoundBox:

        Returns:

        )r"  rY   rZ   r[   r   )r   
second_boxs     rR   	is_insidezBoundBox.is_inside  s     NNtxxzz) .  488::-.  488::-.   488::-.   488::-	.
   488::-
 	
rW   c                    | j                   |j                   y| j                   j                  |j                         |k  S )a  Check if this bounding box overlaps with another.

        Args:
            other: BoundBox to check overlap with
            tolerance: Distance tolerance for overlap detection

        Returns:
            True if bounding boxes overlap (share any volume), False otherwise
        F)rd   r   )r   r  r  s      rR   overlapszBoundBox.overlaps  s8     <<5==#8||$$U]]3y@@rW   c                D    t        | j                  | j                  |      S )6Amount to move object to achieve the desired alignment)to_align_offsetr"  r   )r   aligns     rR   rG  zBoundBox.to_align_offset  s    txx599rW   )r  r   r"  rh  )NT)rj   r:   r  float | Noner  rq  r"  rh  rg  rk  rL   )r7  z.tuple[float, float, float] | Vector | BoundBoxr8  rI  r"  r  )r;  r  r<  r  r"  zBoundBox | None)rj   r:   r  rI  r  rq  r"  r  )rA  r  r"  rq  )r  r  r  r   r"  rq  )rH  Align2D | Align3Dr"  rp   )r)  rw  rx  ry  r   r   r|  r+  r0  r*  r   r   staticmethodr=  classmethodr?  rB  r^   rD  rG  r   rW   rR   r  r    s   #6 6 SW;!;.:;LP;	; ;
2Hh = = 2 2
) !%;% % 
	%N " "H  #'	..  . 	.
 
. .$
$ <E A:rW   r  c                      e Zd ZdZedd       Zeddd       Zeddd       Zeddd       Zd Zd ZddZdd	Zdd
Z	ddZ
e	 	 d	 	 	 	 	 	 	 dd       Zedd       Zedd       Zy)Colorz
    Color object based on OCCT Quantity_ColorRGBA.

    Attributes:
        wrapped (Quantity_ColorRGBA): the OCP color object
    c                     y)a  Color from ColorLike

        Args:
            color_like (ColorLike):
                name, ex: "red" or "#ff0000",
                name + alpha, ex: ("red", 0.5) or "#ff000080",
                rgb, ex: (1., 0., 0.),
                rgb + alpha, ex: (1., 0., 0., 0.5),
                hex, ex: 0xff0000,
                hex + alpha, ex: (0xff0000, 0x80),
                Color,
                Quantity_ColorRGBA
        Nr   )r   
color_likes     rR   r   zColor.__init__  r[  rW   c                     y)a  Color from name or hexadecimal string

        `CSS3 Color Names
            <https://en.wikipedia.org/wiki/Web_colors#Extended_colors>`

        `OCCT Color Names
            <https://dev.opencascade.org/doc/refman/html/_quantity___name_of_color_8hxx.html>`_

        Hexadecimal string may be RGB or RGBA format with leading "#"

        Args:
            name (str): color, e.g. "blue" or "#0000ff""
            alpha (float, optional): 0.0 <= alpha <= 1.0. Defaults to 1.0
        Nr   )r   namealphas      rR   r   zColor.__init__  r[  rW   c                     y)a	  Color from sRGB and Alpha values

        Args:
            red (float): 0.0 <= red <= 1.0
            green (float): 0.0 <= green <= 1.0
            blue (float): 0.0 <= blue <= 1.0
            alpha (float, optional): 0.0 <= alpha <= 1.0. Defaults to 1.0
        Nr   )r   redgreenbluerS  s        rR   r   zColor.__init__  r[  rW   c                     y)zColor from a hexadecimal color code with an optional alpha value

        Args:
            color_code (hexadecimal int): 0xRRGGBB
            alpha (hexadecimal int): 0x00 <= alpha as hex <= 0xFF
        Nr   )r   
color_coderS  s      rR   r   zColor.__init__#  r[  rW   c                   d | _         d\  }}}}}}||||f}	|j                  dd       }
|
|
f}|rt        |d   t              r|d   n|}d }|rQt	        |      dk\  r |||	      \  }}}}n3|d   xt
        d x\    |d   j                   | _         y  xt        d x\    |d   | _         y  xt        d x\     ||||f      \  }}|j                         }d|v rt        t        |dz        d	      }t	        |      d
k(  r|d   dz  }|d d }n5t	        |      dk(  r|dd }|d d }nt	        |      dvrt        d| d      	 |rt        |d      dz  }nH xt        d x\     ||||f      \  }}n+ t        d x\    |||	      \  }}}}n 	 t        d|       |
l|j                  d|      }|j                  d|      }|j                  d|      }|j                  d|      }|j                  d|      }|j                  d|      }|r||f}n|r||f}n||||f}|x  rL dk(  rG\  }}t        |t              r4t        |t        t        f      r t
        j                  |      \  }}}|}n x  rT dk(  rO\  }}t        |t              r<t        |t        t        f      r& t
        j                  |      \  }}}|dk7  r;|dz  }n5   r" dk(  r\  }}}}t!        d ||||fD              rn 	 t        d|       | j                   s.t#        |||t$        j&                        }t        ||      | _         y y # t        $ r}t        d|       |d }~ww xY w)N)r   r   r   r   NNrP  r   c                T     t         fdt        t                    D              S )Nc              3  N   K   | ]  }|t              k  r|   n|     y wrL   )r   )rO   r   abs     rR   rS   z8Color.__init__.<locals>.fill_defaults.<locals>.<genexpr><  s(     M!SV115Ms   "%)rT   r   r   )r]  r^  s   ``rR   fill_defaultsz%Color.__init__.<locals>.fill_defaults;  s    MuSV}MMMrW   r   r   #   r         r  	      )rc  rb  re  rd  "z)" is not a valid hexadecimal color value.   zInvald alpha hex string: zUnsupported color definition: rR  rY  rU  rV  rW  rS  rA   c              3  H   K   | ]  }t        |t        t        f        y wrL   r   )rO   cs     rR   rS   z!Color.__init__.<locals>.<genexpr>  s       201
1sEl+2    ")rd   rx   rl   rT   r   rN  r3   r$  stripr,  r   rr   r   r   _rgb_from_str_rgb_from_intr   r2   r4   Quantity_TOC_sRGB)r   ry   rz   rU  rV  rW  rS  rR  rY  default_rgbrP  r_  hex_aexcolor_formatr]  hexa	the_colors                     rR   r   zColor.__init__,  s   4T1UD%zE4/ ZZd3
!=D(a%847dD	N 4yA~*7k*J'UD%1g '+Aw ! .+-'+Aw . &3D4-&He#zz|$;$*3us{+;S$AE"4yA~(,Q!'+BQx!$Ta(,Qq	'+BQx!$T,!>&0&'v-V$W'" !"*#(,/rNT,AE% . ,9$U@S,T)
E 2?k2R/UD% !'*H(OPP ::fd+DL*=J**UC(CJJw.E::fd+DJJw.E %=L&.Le4L js3
1ucl8S#(#6#6t#< UD  js3
1ucl8S#(#6#6t#< UD6HE	 
 +*c 2695$5N2 /  + "@ OPP||&UD"6"H"HI .i?DL	 Y $. *&0&?w$G'"')!**s   L; ;	MMMc                    | j                   j                         j                  t        j                        \  }}}|||| j                   j                         f}d |D        S )Nc              3  4   K   | ]  }t        |d         yw)re  NrM   )rO   rP   s     rR   rS   z!Color.__iter__.<locals>.<genexpr>  s     7EeQ7   )rd   GetRGBValuesr4   rn  Alpha)r   rr  r^  	rgb_tuples        rR   r   zColor.__iter__  sR    ,,%%'../C/U/UV1a1dll0023	7Y77rW   c                $    t        t        |        S r=  rN  rT   r   s    rR   r?  zColor.__copy__      eDk""rW   c                $    t        t        |        S rB  r~  rC  s     rR   rE  zColor.__deepcopy__  r  rW   c           	        | j                   j                         j                  t        j                        }	 t        j                  |D cg c]  }t        |dz         c}      }d}t        |       j                   dt        t        |              d| d|j!                         S c c}w # t        $ rB | j                   j                         j                         }t        j                  |      }d}Y w xY w)zGenerate stringra  isnearz:  )rd   rx  ry  r4   rn  	webcolorsrgb_to_namerN   rr   Namer2   StringName_srs   r)  r$  rT   upper)r   rgbri  rR  	qualifierquantity_color_enums         rR   r-  zColor.__str__  s    ll!!#**+?+Q+QR	((#)FQ%C.)FGDI t*%%&bU4[)9(:!I;a

GWXX *G 	"&,,"5"5"7"<"<">!../BCDI		s$   B/ B*!	B/ *B/ /AC:9C:c                X    t        |       j                   t        t        |              S )zRepresent Color)rs   r)  r$  rT   r   s    rR   r*  zColor.__repr__  s&    t*%%&s5;'7&899rW   c                n   t        |t              r"d|cxk  rdk  sot        d       t        d      t        |t              r=|dk  rt        d      t	        t        |            dd }t        j                  | d   }nt        d      t        |t        t        f      rt        |      g|z  }n$t        |      }t        |      |k7  rt        d	      t        j                  ||dz   |d
      }t        ||      D cg c]'  \  }} | g t        j                  |dz  dd      | ) }	}}|	S c c}}w )u0  Generate a palette of evenly spaced colors.

        Creates a list of visually distinct colors suitable for representing
        discrete categories (such as different parts, assemblies, or data
        series). Colors are evenly spaced around the hue circle and share
        consistent lightness and saturation levels, resulting in balanced
        perceptual contrast across all hues.

        Produces palettes similar in appearance to the **Tableau 10** and **D3
        Category10** color sets—both widely recognized standards in data
        visualization for their clarity and accessibility. These values have
        been empirically chosen to maintain consistent perceived brightness
        across hues while avoiding overly vivid or dark colors.

        Args:
            color_count (int): Number of colors to generate.
            starting_hue (ColorLike | float): Either a Color-like object or
                a hue value in the range [0.0, 1.0] that defines the starting color.
            alpha (float | Iterable[float]): Alpha value(s) for the colors. Can be a
                single float or an iterable of length `color_count`.

        Returns:
            list[Color]: List of generated colors.

        Raises:
            ValueError: If starting_hue is out of range or alpha length mismatch.
        r   r   u+   Starting hue must be within range 0.0–1.0r   z+Starting color integer must be non-negativeNr   zAStarting hue must be a float in [0,1] or an integer color literalz-Number of alpha values must match color_countF)endpointg?g?)rl   r   rr   r   rT   rN  colorsys
rgb_to_hlsr   r   r   r  linspacezip
hls_to_rgb)
r  color_countstarting_huerS  r  alphashueshr]  colorss
             rR   categorical_setzColor.categorical_set  sG   H lE*,-#- !NOO . !NOOc*a !NOOl+,Ra0C#..4Q7LS 
 eeS\*El^k1F%[F6{k) !PQQ {{,,kE

 D&)
1 <$$QWdC8<!<
 

 
s    ,D1c                Z    t        | d      \  }}t        |d      \  }}|dz  |dz  |dz  fS )Ni      ra  )divmod)tripletrU  	remainderrV  rW  s        rR   rm  zColor._rgb_from_int  s;    0YY,tSy%#+tcz11rW   c                   d| vr	 t        j                  |       }nt        j                  |       }t        d t        |      D              S # t        $ rj}t               }t        j                  | |      }|st        | d      ||j                         |j                         |j                         fcY d }~S d }~ww xY w)Nr`  z4 is not defined as a named color in CSS3 or OCCT/X11c              3  &   K   | ]	  }|d z    yw)ra  Nr   )rO   r   s     rR   rS   z&Color._rgb_from_str.<locals>.<genexpr>  s     5QW5s   )
r  name_to_rgbrr   r2   ColorFromName_sRedGreenBlue
hex_to_rgbrT   )rR  r  r   colorexistss        rR   rl  zColor._rgb_from_str  s    d?B#//5  **40G5eGn555  B&('77eD$("VW 		U[[]EJJLAABs   A 	B?AB:4B?:B?N)rP  	ColorLike)r   )rR  r$  rS  r   )rU  r   rV  r   rW  r   rS  r   )ra  )rY  r   rS  r   )r"  rN  rn  )r   r   )r  r   r  zColorLike | floatrS  zfloat | Iterable[float]r"  zlist[Color])r  r   r"  ri  )rR  r$  r"  rT   )r)  rw  rx  ry  r   r   r   r?  rE  r-  r*  rL  r  rK  rm  rl  r   rW   rR   rN  rN    s             `@D8
##Y:  +.),	AA (A '	A
 
A AF 2 2
 6 6rW   rN  r  c                  2     e Zd ZdZ fdZed        Z xZS )GeomEncodera  
    A JSON encoder for build123d geometry objects.

    This class extends ``json.JSONEncoder`` to provide custom serialization for
    geometry objects such as Axis, Color, Location, Plane, and Vector. It converts
    each geometry object into a dictionary containing exactly one key that identifies
    the geometry type (e.g. ``"Axis"``, ``"Vector"``, etc.), paired with a tuple or
    list that represents the underlying data. Any other object types are handled by
    the standard encoder.

    The inverse decoding is performed by the ``geometry_hook`` static method, which
    expects the dictionary to have precisely one key from the known geometry types.
    It then uses a class registry (``CLASS_REGISTRY``) to look up and instantiate
    the appropriate class with the provided values.

    **Usage Example**::

        import json

        # Suppose we have some geometry objects:
        axis = Axis(position=(0, 0, 0), direction=(1, 0, 0))
        vector = Vector(0.0, 1.0, 2.0)

        data = {
            "my_axis": axis,
            "my_vector": vector
        }

        # Encode them to JSON:
        encoded_data = json.dumps(data, cls=GeomEncoder, indent=4)

        # Decode them back:
        decoded_data = json.loads(encoded_data, object_hook=GeomEncoder.geometry_hook)

    c                    t        |t              r,dt        |j                        t        |j                        fiS t        |t
              rdt        |      iS t        |t              r)t        |      }dt        |d         t        |d         fiS t        |t              r@dt        |j                        t        |j                        t        |j                        fiS t        |t              rdt        |      iS t        | 5  |      S )zEReturn a JSON-serializable representation of a known geometry object.rm   rN  ro   r   rA   rn   rp   )rl   rm   rT   r  r  rN  ro   rn   r  x_dirr  rp   superdefault)r   otup	__class__s      rR   r  zGeomEncoder.default=  s    aU1::.akk0BCDDaU1X&&a"(Cs1vc!f >??aeAHHouQWW~uQWW~NOOa eAh''wq!!rW   c                    t        | j                               dk7  rt        d|        | j                         D ]  \  }}t        |   | c S  y)z=Convert dictionaries back into geometry objects for decoding.rA   zInvalid geometry json object N)r   itemsrr   CLASS_REGISTRY)	json_dictkeyrP   s      rR   geometry_hookzGeomEncoder.geometry_hookM  sU     y !Q&<YKHII#//+ 	/JC!#&..	/rW   )r)  rw  rx  ry  r  rK  r  __classcell__r  s   @rR   r  r    s"    "H"  / /rW   r  c                  ^   e Zd ZdZi ej
                  ej                  ej                  ej                  ej                  ej                  ej                  ej                  ej                  ej                  ej                   ej"                  ej$                  ej&                  ej(                  ej*                  ej,                  ej.                  ej0                  ej2                  ej4                  ej6                  ej8                  ej:                  ej
                  ej>                  ej                  ej@                  ej                  ejB                  ej                  ejD                  ej                  ejF                  ej                   ejH                  ej$                  ejJ                  ej(                  ejL                  ej,                  ejN                  ej0                  ejP                  ej4                  ejR                  ej8                  ejT                  iZ+e,d3d       Z-e,d4d       Z-e,d5d6d       Z-e,	 d7	 	 	 	 	 d8d       Z-e,	 	 	 	 	 	 	 	 d9d       Z-e,d:d       Z-e,d;d	       Z-e,d<d
       Z-e,d=d       Z-e,	 	 	 	 	 	 	 	 d>d       Z-d?dZ-e.d@d       Z/e.dAd       Z0e0jb                  dBd       Z0e.dAd       Z2e2jb                  dCd       Z2e.dDd       Z3e.dDd       Z4e.dDd       Z5dEdZ6dEdZ7dEdZ8e,dFd       Z9e,dGd       Z9e,dHd       Z9	 	 	 	 dIdZ9dJdZ:dKdZ;dLdZ<dMd Z=d! Z>dEd"Z?	 	 	 	 dNd#Z@dAd$ZAdOd%ZB eCd&      dDd'       ZD eCd(      dPd)       ZEdQd*ZFdQd+ZGdQd,ZHe,dRd-       ZIe,dSd.       ZIe,dTd/       ZIe,dUd0       ZIe,dVd1       ZId2 ZIy)Wro   a^  Location in 3D space. Depending on usage can be absolute or relative.

    This class wraps the TopLoc_Location class from OCCT. It can be used to move Shape
    objects in both relative and absolute manner. It is the preferred type to locate objects
    in build123d.

    Attributes:
        wrapped (TopLoc_Location): the OCP location object

    c                     y)z(Location with no position or orientationNr   r   s    rR   r   zLocation.__init__}  r[  rW   c                     y)zLocation from LocationNr   r]  s     rR   r   zLocation.__init__  r[  rW   c                     y)zCLocation from position and rotation around z-axis by optional angleNr   )r   r  rW  s      rR   r   zLocation.__init__  r[  rW   Nc                     y)zDLocation from position and optional orientation (see Rotation class)Nr   )r   r  orientations      rR   r   zLocation.__init__  r[  rW   c                     y)zLocation from position and optional orientation (see Rotation class).
        Orientation determined by optional ordering, defaults to Intrinsic.XYZ
        Nr   )r   r  r  orderings       rR   r   zLocation.__init__  r[  rW   c                     y)z Location from location of Plane.Nr   r   s     rR   r   zLocation.__init__  r[  rW   c                     y)z:Location from location of Plane translated by plane_offsetNr   )r   rg   plane_offsets      rR   r   zLocation.__init__  r[  rW   c                     y)z.Location from low-level TopLoc_Location objectNr   )r   top_locs     rR   r   zLocation.__init__  r[  rW   c                     y)z&Location from low-level gp_Trsf objectNr   )r   gp_trsfs     rR   r   zLocation.__init__  r[  rW   c                     y)z=Location from position and rotation around direction by angleNr   )r   r  r  rW  s       rR   r   zLocation.__init__  r[  rW   c                l   d| _         |j                  dd       }|j                  dd       }|j                  dd       }|j                  dd       }|j                  dd       }|j                  dd       }|j                  dd       }	|j                  d	d       }
|j                  d
d       }|rt        ddj                  |             |r|t	        |d   t
              r|d   }ng|	 t	        |d   t        t        f      r|d   }	nE|
t	        |d   t              r|d   }
n)|t	        |d   t              r|d   }nt	        |d   t        t        f      rt        |d         }t        |      dkD  rFt	        |d   t        t        f      rt        |d         }nt	        |d   t        t        f      r|d   }t        |      dkD  rt	        |d   t        t        f      r-t	        |d   t        t        f      rt        |d         }|d   }n>t	        |d   t        t         f      r|d   }nt        d|d          t        d|       t               }t	        |t
              rwt#        |j$                  j'                         |j(                  j+                         |j,                  j+                               }|j/                  |       |j1                          nt	        |t              r|}n|Yt3        t5        ddd      |rt        |      j+                         nt7        ddd            }|j9                  |t;        |             nr|p|D cg c]  }t;        |       }}| j<                  j?                  |t@        jB                        }tE               } |jF                  |g|  |j9                  |       |r$|jI                  t        |      jJ                         t	        |	t              r|	jJ                  | _&        y t	        |
t              r|
| _&        y t        |      | _&        y c c}w )Nr   r  r  r  r  rW  rg   rh   r  r  r  re   rA   r  z-Third parameter must be a float or order not r  )'location_indexr  r   rt   rl   rn   ro   Rotationr6   r.   rp   r   r   r   r   r@   r?   r&   r  r   r  rI  r  SetTransformationInvertr$   r,   r'   SetRotationr   _rot_order_dictrx   r(   gp_Intrinsic_XYZr-   SetEulerAnglesSetTranslationPartrd   r~   )r   ry   rz   r  r  r  r  rW  rg   rh   r  r  trsfcsrf   r]  angles	rot_orderquats                      rR   r   zLocation.__init__  s     ::j$/jj5JJ{D1	::j$/

7D)

7D)::j$/**Y-**Y- <TYYv=N<OPQQ }DGU!;Q!ja8X:N&O7ZQ%Iq'ZQ%Aq'DGfh%78!$q'?t9q=!$q'FH+=>&,T!Wo#DGc5\: $Qt9q=!$q'FH+=>:Q#uD %+47O	 $Q#DGi-CD#'7'KDQRG9U   "@ GHH yeU###%""$""$B
 ""2&KKM)Dq!Q.7y!((*VAq!_D T75>2$*56Qgaj6F6,,00*;;I !?DD	3F3T"##F8$4$<$<= h)$,,DM1#DM+D1DM# 7s   P1c                    | j                   S r  r   r   s    rR   rd   zLocation.wrapped  r   rW   c                0    t        t        |       d         S )zjExtract Position component of self

        Returns:
          Vector: Position part of Location

        r   rp   rT   r   s    rR   r  zLocation.position       eDk!n%%rW   c                   t               }|j                  t        |      j                         t               }|j	                  | j                  j                         j                                t        ||z        | _        y)zpSet the position component of this Location

        Args:
            value (VectorLike): New position
        N)	r.   r  rp   rd   r  r  GetRotationr6   r~   )r   rP   trsf_positiontrsf_orientations       rR   r  zLocation.position  sa      	(()>)>?"9$$T\\%@%@%B%N%N%PQ'8H(HIrW   c                0    t        t        |       d         S )zyExtract orientation/rotation component of self

        Returns:
          Vector: orientation part of Location

        rA   r  r   s    rR   r  zLocation.orientation)  r  rW   c                   t         j                  }| j                  j                         j	                         }t               }|j                  t        |j                         |j                         |j                                      |D cg c]  }t        |       }}t               } |j                  | j                  |   g|  t               }|j                  |       t!        ||z        | _        yc c}w )zSet the orientation component of this Location

        Args:
            rotation (VectorLike): Intrinsic XYZ angles in degrees
        N)r@   r   rd   r  TranslationPartr.   r  r/   rY   rZ   r[   r   r-   r  r  r  r6   r~   )r   rotationr  position_xyzr  r]  r_   r  s           rR   r  zLocation.orientation3  s     ==||224DDF	((<>>#\^^%5|~~7GH	
 )111GAJ11"_
!
!!$"6"6x"@L8L"9$$Z0'8H(HI 2s   C:c                X    t        |       }t        |j                  |j                        S )z#Default X axis when used as a plane)rn   rm   r  r  r   s     rR   x_axiszLocation.x_axisI  "     dELL%++..rW   c                X    t        |       }t        |j                  |j                        S )z#Default Y axis when used as a plane)rn   rm   r  y_dirr   s     rR   y_axiszLocation.y_axisO  r  rW   c                X    t        |       }t        |j                  |j                        S )z#Default Z axis when used as a plane)rn   rm   r  r  r   s     rR   z_axiszLocation.z_axisU  r  rW   c                H    t        | j                  j                               S )zInverted location)ro   rd   Invertedr   s    rR   inversezLocation.inverse[  s    --/00rW   c                H    t        | j                  j                               S )zLib/copy.py shallow copyro   rd   r  r   s    rR   r?  zLocation.__copy___      33566rW   c                H    t        | j                  j                               S )zLib/copy.py deep copyr  rC  s     rR   rE  zLocation.__deepcopy__c  r  rW   c                     y rL   r   r  s     rR   r   zLocation.__mul__g      25rW   c                     y rL   r   r  s     rR   r   zLocation.__mul__j  s    47rW   c                     y rL   r   r  s     rR   r   zLocation.__mul__m  s    DGrW   c                B   t        |t              r"t        | j                  |j                  z        S 	 t        |      }t	        d |D              r0|D cg c]$  }t        | j                  |j                  z        & c}S 	 t        S c c}w # t
        $ r Y t        S w xY w)zCombine locationsc              3  <   K   | ]  }t        |t                y wrL   )rl   ro   )rO   r  s     rR   rS   z#Location.__mul__.<locals>.<genexpr>z  s     ;q:a*;s   )rl   ro   rd   r   r   r   r/  )r   r  otherslocs       rR   r   zLocation.__mul__p  s    
 eX&DLL5==899	%[F;F;;HNO!;<OO <  P 		s#   !B )B>B B 	BBc                J    t        | j                  j                  |            S rL   )ro   rd   Powered)r   exponents     rR   __pow__zLocation.__pow__  s    ,,X677rW   c                p    t        |t              st        S | j                         |j                         k(  S )zCompare Locations)rl   ro   r/  r0  r  s     rR   r1  zLocation.__eq__  s)    %*!!yy{ejjl**rW   c                4    t        | j                               S )zHash of Locationr3  r   s    rR   r5  zLocation.__hash__  r6  rW   c                    | j                   j                         j                         }| j                  j	                         t        |      fS r8  )rd   r  r  r  r0  rb   )r   r_   s     rR   r0  zLocation._key  s;    \\002>>@
""$&?
&KLLrW   c                   | j                   j                         }|j                         }|j                         }t	        |      }t	        t        t        |j                  t        j                                    }t        ||f      S rL   )rd   r  r  r  rp   mapr   GetEulerAnglesr(   r  r   r   transformationtransrotrv_transrv_rots         rR   r   zLocation.__iter__  sq    446..0((*!%=++,<,M,MNO
 Xv&''rW   c                ,    t        t        |              S )z=Flip the orientation without changing the position operator -)ro   rn   r   s    rR   r
  zLocation.__neg__  s    t%%rW   c                $    | j                  |      S )zintersect axis with other &r  r  s     rR   r  zLocation.__and__  r  rW   c                    | j                   S )z2Return center of the location - useful for sorting)r  r   s    rR   r   zLocation.center  s    }}rW   c                @   dd}| j                   |j                  z
  }|j                  |j                        }| j                   d|z  |j                  z  z
  }t	        |       } ||j
                  |      } ||j                  |      }t        t	        |||            S )u  
        Return a new Location mirrored across the given plane.

        This method reflects both the position and orientation of the current Location
        across the specified mirror_plane using affine vector mathematics.

        Due to the mathematical properties of reflection:
            - The true mirror of a right-handed coordinate system is a *left-handed* one.

        However, `build123d` requires all coordinate systems to be right-handed.
        Therefore, this implementation:
        - Reflects the X and Z directions across the mirror plane
        - Recomputes the Y direction as: `Y = X × Z`

        This ensures the resulting Location maintains a valid right-handed frame,
        while remaining as close as possible to the geometric mirror.

        Args:
            mirror_plane (Plane): The plane to mirror across.

        Returns:
            Location: A new mirrored Location that preserves right-handedness.
        c                ^    | d| j                  |j                        z  |j                  z  z
  S )Nr  )r   r  )r   plns     rR   
mirror_dirz#Location.mirror.<locals>.mirror_dir  s(    qAEE#)),-		999rW   r  r  r  r  )r   rp   r  rn   r"  rp   )r  r  r   r  rn   r  ro   )	r   mirror_planer  r  distancepos	loc_planemx_dirmz_dirs	            rR   mirrorzLocation.mirror  s    2	: ==<#6#66<< 2 23mma(l\-?-??? $K	IOO\:IOO\:SfEFFrW   z]to_axis is deprecated and will be removed in a future version.  Use 'Axis(Location)' instead.c                @    t         j                  j                  |       S )z!Convert the location into an Axis)rm   r[   r  r   s    rR   to_axiszLocation.to_axis  s     vv~~d##rW   z_to_tuple is deprecated and will be removed in a future version.  Use 'tuple(Location)' instead.c                :   | j                   j                         }|j                         }|j                         }|j	                         |j                         |j                         f}t        d |j                  t        j                        D              }||fS )z6Convert the location to a translation, rotation tuple.c              3  2   K   | ]  }t        |        y wrL   )r   )rO   r]  s     rR   rS   z$Location.to_tuple.<locals>.<genexpr>  s      3
GAJ3
s   )rd   r  r  r  rY   rZ   r[   rT   r	  r(   r  r
  s         rR   r   zLocation.to_tuple  s     446..0((*05	5779eggi/P-2 3
 # 2 23C3T3T U3
 .
 rW   c                    |r|d   nd}|dv r%d| j                   | dd| j                  | ddS dt        | j                          dt        | j                         dS )zFormat Locationr   Nr  r  r   re   r!  )r  r  rT   r  s      rR   r'  zLocation.__format__  ss     $DH$	
"t}}dV0G,Bt/?/?`w.GqII5'(51A1A+B*C1EErW   c                F    t        |       j                   | dt         dS )zRepresent Locationr  r  r  r   s    rR   r*  zLocation.__repr__  r  rW   c                    t        |       j                   d| j                  dt         dd| j                  dt         ddS )zDisplay Locationr  r  r  z, orientation=r!  )rs   r)  r  r  r  r   s    rR   r-  zLocation.__str__  sT     Dz""# $qAo6 7++Aj\?;1>	
rW   c                     y)z(Find intersection of location and vectorNr   rZ  s     rR   r  zLocation.intersect  r[  rW   c                     y)z*Find intersection of location and locationNr   r]  s     rR   r  zLocation.intersect  r[  rW   c                     y)z&Find intersection of location and axisNr   r_  s     rR   r  zLocation.intersect  r[  rW   c                     y)z'Find intersection of location and planeNr   r   s     rR   r  zLocation.intersect  r[  rW   c                     y)z'Find intersection of location and shapeNr   rb  s     rR   r  zLocation.intersect  r[  rW   c                $   t        |i |\  }}}}}||j                  |       S ||j                  |       S || j                  |k(  r|S dS |.| |k(  r| S | j                  |j                  k(  r| j                  S dS ||j                  |       S dS )z;Find intersection of location and geometric object or shapeN)r|   r  r  rd  s           rR   r  zLocation.intersect  s    /Dd/Uf/U,eVXu>>$''??4((!]]f46>$> 8#  '+mmx7H7H&HT]] OS ).(9ut$CtCrW   )r"  rh  r  )r   )r  rj  rW  r   r"  rh  rL   )r  rj  r  zRotationLike | Noner"  rh  )r  rj  r  RotationLiker  Extrinsic | Intrinsicr"  rh  )rg   rn   r"  rh  )rg   rn   r  rj  r"  rh  )r  r6   r"  rh  )r  r.   r"  rh  )r  rj  r  rj  rW  r   r"  rh  r  )r"  r6   rk  rP   rj  )r  rj  r  r
  r  rF   r"  rF   )r  ro   r"  ro   )r  zIterable[Location]r"  list[Location])r  zLocation | Iterable[Location]r"  Location | list[Location])r  r   r"  ro   ro  rr  r  )r  rm  r"  r  )r  rn   r"  ro   )r"  z=tuple[tuple[float, float, float], tuple[float, float, float]]rn  ru  r  )rf   rm   r"  r  )rg   rn   r"  r  rv  )Jr)  rw  rx  ry  r@   r   r(   r  XZYgp_Intrinsic_XZYYZXgp_Intrinsic_YZXYXZgp_Intrinsic_YXZZXYgp_Intrinsic_ZXYZYXgp_Intrinsic_ZYXXYXgp_Intrinsic_XYXXZXgp_Intrinsic_XZXYZYgp_Intrinsic_YZYYXYgp_Intrinsic_YXYZXZgp_Intrinsic_ZXZZYZgp_Intrinsic_ZYZr?   gp_Extrinsic_XYZgp_Extrinsic_XZYgp_Extrinsic_YZXgp_Extrinsic_YXZgp_Extrinsic_ZXYgp_Extrinsic_ZYXgp_Extrinsic_XYXgp_Extrinsic_XZXgp_Extrinsic_YZYgp_Extrinsic_YXYgp_Extrinsic_ZXZgp_Extrinsic_ZYZr  r   r   r|  rd   r  r}  r  r  r  r  r  r?  rE  r   r  r1  r5  r0  r   r
  r  r   r  r   r   r   r'  r*  r-  r  r   rW   rR   ro   ro   V  s;   	'88'88 	'88 	'88	
 	'88 	'88 	'88 	'88 	'88 	'88 	'88 	'88 	'88 	'88 	'88  	'88!" 	'88#$ 	'88'88'88'88'88'88'881O6 7 7 % % R R GKS"S1DS	S S
  " (	
 
  / / I I = = 5 5 L"L/9LBGL	L L
[2z   & & __
J 
J & & J J* / /
 / /
 / /
177 5 57 7G G2	" 8+!M
(&%A%	!%&GP 	)$	$ 	* 	 F=
 7 7 9 9 5 5 6 6 6 6DrW   ro   c                  *    e Zd ZdZddZedd       Zy)LocationEncodera  Custom JSON Encoder for Location values

    Example:

    .. code::

        data_dict = {
            "part1": {
                "joint_one": Location((1, 2, 3), (4, 5, 6)),
                "joint_two": Location((7, 8, 9), (10, 11, 12)),
            },
            "part2": {
                "joint_one": Location((13, 14, 15), (16, 17, 18)),
                "joint_two": Location((19, 20, 21), (22, 23, 24)),
            },
        }
        json_object = json.dumps(data_dict, indent=4, cls=LocationEncoder)
        with open("sample.json", "w") as outfile:
            outfile.write(json_object)
        with open("sample.json", "r") as infile:
            copy_data_dict = json.load(infile, object_hook=LocationEncoder.location_hook)

    c                    t        j                  dt        d       t        |t              st        d      d|j                         iS )zReturn a serializable objectUse GeomEncoder insteadr  
stacklevelz Only applies to Location objectsro   )warningswarnDeprecationWarningrl   ro   r   r   )r   r  s     rR   r  zLocationEncoder.defaultC  s<    /1CPQR!X&>??AJJL))rW   c                    t        j                  dt        d       d| v r2t        | d   D cg c]  }|D cg c]  }t	        |       c} c}} } | S c c}w c c}}w )zConvert Locations loaded from json to Location objects

        Example:
            read_json = json.load(infile, object_hook=LocationEncoder.location_hook)
        rW  r  rX  ro   )rZ  r[  r\  ro   r   )r7  r   r  s      rR   location_hookzLocationEncoder.location_hookJ  sT     	/1CPQRC
OLq21eAh2LMC
 3Ls   	A
A	A
A
N)r  ro   r"  dict)r"  r_  )r)  rw  rx  ry  r  rK  r^  r   rW   rR   rU  rU  *  s     0* 	 	rW   rU  c                      e Zd ZdZddZed        Zedd       Zedd       Zedd       Z	edd       Z
edd       Zedd	       Zedd
       Zedd       ZddZddZddZddZy)OrientedBoundBoxa}  
    An Oriented Bounding Box

    This class computes the oriented bounding box for a given build123d shape.
    It exposes properties such as the center, principal axis directions, the
    extents along these axes, and the full diagonal length of the box.

    Note: The axes of the oriented bounding box are arbitrary and may not be
    consistent across platforms or time.
    c                *   t        |t              r
|}|| _
        yt        |d      rMt        |j                  t              r3t               }t        j                  |j                  |d       || _
        yt        dt        |      j                         )a5  
        Create an oriented bounding box from either a precomputed Bnd_OBB or
        a build123d Shape (which wraps a TopoDS_Shape).

        Args:
            shape (Bnd_OBB | Shape): Either a precomputed Bnd_OBB or a build123d shape
                from which to compute the oriented bounding box.
        rd   TzExpected Bnd_OBB or Shape, got N)rl   r   rq   rd   r:   r   AddOBB_sr   rs   r)  r~   )r   rj   obbs      rR   r   zOrientedBoundBox.__init__c  s{     eW%C  UI&:emm\+R)CsD9  =d5k>R>R=STUUrW   c                    | j                   S r  r   r   s    rR   rd   zOrientedBoundBox.wrappedv  r   rW   c                   ddgddgddgg dg dg dt        t        j                  ddd            d	}| j                  d
z  }||j                  t
        k  |j                  t
        k  |j                  t
        k  f   }|D cg c]:  \  }}}t        ||j                  z  ||j                  z  ||j                  z        < }}}}|D cg c]  }| j                  j                  |       }	}|	S c c}}}w c c}w )a  
        Compute and return the unique corner points of the oriented bounding box
        in the coordinate system defined by the OBB's plane.

        For degenerate shapes (e.g. a line or a planar face), only the unique
        points are returned. For 2D shapes the corners are returned in an order
        that allows a polygon to be directly created from them.

        Returns:
            list[Vector]: The unique corner points.
        rA   rA   rA   rA   rA   r   rA   r   rA   r   rA   rA   )rg  rh  )rA   r   r   ri  )rg  rh  )r   rA   r   rj  )rg  ri  )r   r   rA   rj  )r   rA   ))TTF)TFT)FTT)TFF)FTF)FFT)FFFr-  )r   	itertoolsproductr#  rY   r^   rZ   r[   rp   rg   from_local_coords)
r   ordershsordersxsyszlocal_cornersri  cornerss
             rR   ru  zOrientedBoundBox.corners{  s    " #,Z!8"+Z!8"+Z!8"R"R"R#'	(9(9'7G(T#U
 YY_y("$$*:BDD9<LMNFK
 
8BBF29b244ibdd3
 
 =JJq4:://2JJ
 Ks   ?C2"C9c                <    | j                   j                         dz  S )z
        The full length of the body diagonal of the oriented bounding box,
        which represents the maximum size of the object.

        Returns:
            float: The diagonal length.
        r-  r.  r   s    rR   r0  zOrientedBoundBox.diagonal  s     ||((*c11rW   c                ,    t        | j                        S )z
        The Location of the center of the oriented bounding box.

        Returns:
            Location: center location
        )ro   rg   r   s    rR   rh   zOrientedBoundBox.location  s     

##rW   c                b    t        | j                         | j                  | j                        S )z
        The oriented coordinate system of the bounding box.

        Returns:
            Plane: The coordinate system defined by the center and primary
                   (X) and tertiary (Z) directions of the bounding box.
        r  )rn   r   x_directionz_directionr   s    rR   rg   zOrientedBoundBox.plane  s*     ;;=(8(8@P@P
 	
rW   c                    t        | j                  j                         | j                  j                         | j                  j	                               dz  S )z
        The full extents of the bounding box along its primary axes.

        Returns:
            Vector: The oriented size (full dimensions) of the box.
        g       @)rp   rd   XHSizeYHSizeZHSizer   s    rR   r#  zOrientedBoundBox.size  sD     4<<&&($,,*=*=*?ATATAVW	
rW   c                    | j                   j                         }dD cg c]  } t        ||              }}t        | S c c}w )z
        The primary (X) direction of the oriented bounding box.

        Returns:
            Vector: The X direction as a unit vector.
        r   )rd   
XDirectiongetattrrp   )r   x_direction_xyzattrcoordss       rR   ry  zOrientedBoundBox.x_direction  F     ,,113?NOt0'/402OOv P   Ac                    | j                   j                         }dD cg c]  } t        ||              }}t        | S c c}w )z
        The secondary (Y) direction of the oriented bounding box.

        Returns:
            Vector: The Y direction as a unit vector.
        r   )rd   
YDirectionr  rp   )r   y_direction_xyzr  r  s       rR   y_directionzOrientedBoundBox.y_direction  r  r  c                    | j                   j                         }dD cg c]  } t        ||              }}t        | S c c}w )z
        The tertiary (Z) direction of the oriented bounding box.

        Returns:
            Vector: The Z direction as a unit vector.
        r   )rd   
ZDirectionr  rp   )r   z_direction_xyzr  r  s       rR   rz  zOrientedBoundBox.z_direction  r  r  c                    | j                   j                         }dD cg c]  } t        ||              }}t        | S c c}w )z
        Compute and return the center point of the oriented bounding box.

        Returns:
            Vector: The center point of the box.
        r   )rd   Centerr  rp   )r   
center_xyzr  r  s       rR   r   zOrientedBoundBox.center  sF     \\((*
:IJ$+'*d+-JJv Kr  c                L    | j                   j                  |j                         S )a  
        Determine whether the given oriented bounding box is entirely contained
        within this bounding box.

        This method checks that every point of 'other' lies strictly within the
        boundaries of this box, according to the tolerance criteria inherent to the
        underlying OCCT implementation.

        Args:
            other (OrientedBoundBox): The bounding box to test for containment.

        Raises:
            ValueError: If the 'other' bounding box has an uninitialized (null) underlying geometry.

        Returns:
            bool: True if 'other' is completely inside this bounding box; otherwise, False.
        )rd   IsCompletelyInsider  s     rR   is_completely_insidez%OrientedBoundBox.is_completely_inside  s    $ ||..u}}==rW   c                T    | j                   j                  |j                               S )a  
        Determine whether a given point lies entirely outside this oriented bounding box.

        A point is considered outside if it is neither inside the box nor on its surface,
        based on the criteria defined by the OCCT implementation.

        Args:
            point (Vector): The point to test.

        Raises:
            ValueError: If the point's underlying geometry is not set (null).

        Returns:
            bool: True if the point is completely outside the bounding box; otherwise, False.
        )rd   IsOutr   )r   points     rR   
is_outsidezOrientedBoundBox.is_outside	  s      ||!!%,,.11rW   c                ^    d| j                         d| j                  d| j                  dS )NzOrientedBoundBox(center=z, size=z, plane=r!  )r   r#  rg   r   s    rR   r*  zOrientedBoundBox.__repr__#	  s4    &t{{}&7 8II=a9	
rW   N)rj   zBnd_OBB | Shape)r"  zlist[Vector]rg  r
  r  rk  )r  ra  r"  rq  )r  rp   r"  rq  rn  )r)  rw  rx  ry  r   r|  rd   ru  r0  rh   rg   r#  ry  r  rz  r   r  r  r*  r   rW   rR   ra  ra  W  s    	&   ! !F 2 2 $ $ 

 

 

 

 	 	 	 	 	 		>(2$
rW   ra  c                  z     e Zd ZdZe	 	 	 	 dd       Zedddej                  f	 	 	 	 	 	 	 dd       Z fdZ xZS )r  a[  Subclass of Location used only for object rotation

    Attributes:
        X (float): rotation in degrees about X axis
        Y (float): rotation in degrees about Y axis
        Z (float): rotation in degrees about Z axis
        optionally specify rotation ordering with Intrinsic or Extrinsic enums,
            defaults to Intrinsic.XYZ

    c                     yz}Subclass of Location used only for object rotation
        ordering is for order of rotations in Intrinsic or Extrinsic enumsNr   )r   r  r  s      rR   r   zRotation.__init__6	  r[  rW   r   c                     yr  r   )r   rY   rZ   r[   r  s        rR   r   zRotation.__init__?	  r[  rW   c                   t        d |D              st        d      g dg g }}}|rt        t        d |            }t        t        d |            }t        t        d |            }|rt        | }|rt	        |d         }t        |      dk  r!|j                  d	gdt        |      z
  z         t        t        d
 |            }t        t        d |            }|j                  d|d          |j                  d|d          |j                  d|d          |j                  d|r|d   nt        j                         |rt        | -  |d          y t        | -  d|d   |d   |d   f|d          y )Nc              3  $   K   | ]  }|d v  
 yw))rY   rZ   r[   r  r  Nr   )rO   r  s     rR   rS   z$Rotation.__init__.<locals>.<genexpr>K	  s     Tc3AATs   zInvalid key for Rotationr  c                .    t        | t        t        f      S rL   r   items    rR   <lambda>z#Rotation.__init__.<locals>.<lambda>O	  s    jU|.L rW   c                "    t        | t              S rL   )rl   rp   r  s    rR   r  z#Rotation.__init__.<locals>.<lambda>P	  s    z$/G rW   c                "    t        | t              S rL   )rl   rT   r  s    rR   r  z#Rotation.__init__.<locals>.<lambda>Q	  s    ju.E rW   r   r   r   c                "    t        | t              S rL   )rl   r  r  s    rR   r  z#Rotation.__init__.<locals>.<lambda>X	  s    D(1K rW   c                .    t        | t        t        f      S rL   )rl   r?   r@   r  s    rR   r  z#Rotation.__init__.<locals>.<lambda>Z	  s    Jti5K$L rW   rY   rZ   rA   r[   r  r  )r   r   r   filterrT   r   extend
setdefaultr@   r   r  r   )	r   ry   rz   r  	rotations	orderingsvectorstuplesr  s	           rR   r   zRotation.__init__J	  sg   TVTT677'0"b9	&!LdSTF6"GNOG&!EtLMFvwqz*6{Qseq3v;78V$KTRSILdSI 	#vay)#vay)#vay)*iilY]]SGYq\*GF3KfSkBF:DVrW   )r  r,  r  z&Extrinsic | Intrinsic == Intrinsic.XYZ)rY   r   rZ   r   r[   r   r  r-  )	r)  rw  rx  ry  r   r   r@   r   r  r  s   @rR   r  r  *	  s    	 NN 9N N  *3--NN N 	N
 (N N rW   r  r,  c                  Z     e Zd ZdZedd       Zedd       Zedd	d       Z fdZ xZS )
Posz%A position only sub-class of Locationc                     y)zPosition by VectorLikeNr   r   s     rR   r   zPos.__init__v	  r[  rW   c                     y)zPosition by VertexNr   r   s     rR   r   zPos.__init__z	  r[  rW   c                     y)zPosition by X, Y, ZNr   r   s       rR   r   zPos.__init__~	  r[  rW   c                   d\  }}}}|rQt        d |D              rt        |      \  }}}n/t        |      dk(  rt        |d         \  }}}nt        d|       |j	                  d|      }|j	                  d|      }|j	                  d|      }|j	                  d	t        |||            }|r+t        d
dj                  |j                                      ||\  }}}t        | %  t        |||             y )Nr   c              3  H   K   | ]  }t        |t        t        f        y wrL   )rl   r   r   )rO   r   s     rR   rS   zPos.__init__.<locals>.<genexpr>	  s     =1:a%.=rj  rA   r   zInvalid inputs to Pos rY   rZ   r[   r   r  re   )
r   rp   r   r   r  rr   rt   rv   r  r   )r   ry   rz   r   r   r   r   r  s          rR   r   zPos.__init__	  s    "
1a === ,1aTa a/1a"8 ?@@ JJsAJJsAJJsAJJsF1aO, 7		&++-8P7QRSS=GAq!1a)rW   )r   rj  )r   r   r  re  )r)  rw  rx  ry  r   r   r  r  s   @rR   r  r  s	  sJ    /% % ! ! " "* *rW   r  c                      e Zd ZdZed        Zedd       Zedd       Zd ZddZddZedd       Zedd	       Zd
 ZddZ	ddZ
ddZddZddZy)rt  a  A 3d , 4x4 transformation matrix.

    Used to move geometry in space.

    The provided "matrix" parameter may be None, a gp_GTrsf, or a nested list of
    values.

    If given a nested list, it is expected to be of the form:

        [[m11, m12, m13, m14],
         [m21, m22, m23, m24],
         [m31, m32, m33, m34]]

    A fourth row may be given, but it is expected to be: [0.0, 0.0, 0.0, 1.0]
    since this is a transform matrix.

    Attributes:
        wrapped (gp_GTrsf): the OCP transformation function
    c                     y rL   r   r   s    rR   r   zMatrix.__init__	  r   rW   c                     y rL   r   )r   r  s     rR   r   zMatrix.__init__	  r   rW   c                     y rL   r   )r   matrixs     rR   r   zMatrix.__init__	  r   rW   c                J   d }t               }|ret        |d   t               r|d   }nLt        |d   t              rt        |d         }n*t        |d   t              r|d   }nt	        |d    d      |j                  d|      }|j                  d|      }|r+t        ddj                  |j                                      |t        d |D              xr t        |      dv }|st	        d	t        |             t        |      d
k(  r+t        |d         dk7  rt        dt        |d                t        |d d       D ]R  \  }}	t        |	      D ]?  \  }
}t        |t        t        f      st	        d      |j!                  |dz   |
dz   |       A T || _        y )Nr   z is of an unexpected typer  r  r  re   c              3  \   K   | ]$  }t        |t              xr t        |      d k(   & yw)rc  N)rl   r   r   )rO   rows     rR   rS   z"Matrix.__init__.<locals>.<genexpr>	  s,      DGC*>CA>s   *,)r   rc  z<Matrix constructor requires 2d list of 4x3 or 4x4, but got: rc  r   )r   r   r   rA   z0Expected the last row to be [0,0,0,1], but got: z)Only float or int are valid in the matrixrA   )r)   rl   r.   r   r   r  rr   rt   rv   r   r   reprrT   	enumerater   r   SetValuerd   )r   ry   rz   default_matrixdefault_trsfr  r  valid_sizesr   r  jelements               rR   r   zMatrix.__init__	  s   z $q'8,#AwDGW-'Q0DGX.!%a47)+D EFF zz&,/Hn5 7		&++-8P7QRSS  KQ  (f+'  RSWX^S_R`a  Fq uVAY'7<'G FtFSTIFWX 
 $F2AJ/ 93"+C. 9JAw%gU|<'(STTMM!a%Q899 rW   c                    t               }|j                  |j                  t        |             | j                  t	        |      z  | _        y)z-General rotate about axis by angle in degreesN)r.   r  rd   r   r)   )r   rf   rW  news       rR   rX  zMatrix.rotate	  s3    igen5||hsm3rW   c                H    t        | j                  j                               S )zInvert Matrix)rt  rd   r  r   s    rR   r  zMatrix.inverse	  s    dll++-..rW   c                     y rL   r   r  s     rR   r   zMatrix.multiply	  r   rW   c                     y rL   r   r  s     rR   r   zMatrix.multiply	  r   rW   c                    t        |t              r|j                  |       S t        | j                  j                  |j                              S )zMatrix multiplication)rl   rp   rT  rt  rd   r   r  s     rR   r   zMatrix.multiply	  s9    eV$??4((dll--emm<==rW   c                2   | j                   }t        dd      D cg c],  }t        dd      D cg c]  }|j                  ||       c}. c}}g dgz   }t        d      D cg c]  }t        d      D ]
  }||   |     c}}S c c}w c c}}w c c}}w )z#Needed by the cqparts gltf exporterrA   rc  rb  r   r   r   r   )rd   r   Value)r   r  r   r  datas        rR   transposed_listzMatrix.transposed_list
  s     ||AFq!MA5A;7aAq!7M Q
 
 %*!H?qeAh?Q
?
??	 8M @s   BBB%BBc                H    t        | j                  j                               S r=  rt  rd   rL  r   s    rR   r?  zMatrix.__copy__
      dll'')**rW   c                H    t        | j                  j                               S rB  r  rC  s     rR   rE  zMatrix.__deepcopy__
  r  rW   c                &   t        |t              rt        |      dk7  rt        d      |\  }}d|cxk  rdk  rn nd|cxk  rdk  sn t        dt	        |             |dk  r$| j
                  j                  |dz   |dz         }|S g d|   }|S )zProvide Matrix[r, c] syntax for accessing individual values. The row
        and column parameters start at zero, which is consistent with most
        python libraries, but is counter to gp_GTrsf(), which is 1-indexed.
        r  z+Matrix subscript must provide (row, column)r   r   z&Out of bounds access into 4x4 matrix: rA   r  )rl   rT   r   
IndexErrorr  rd   r  )r   row_colr  colrQ  s        rR   __getitem__zMatrix.__getitem__
  s    
 '5)c'la.?JKKScQQ#]]Ed7m_UVV7<<--cAgsQw?L
  04LrW   c                v    | j                         dj                  fdt        d      D              }d| dS )zM
        Generate a valid python expression representing this Matrix
        z
,
        c              3  @   K   | ]  }t        |d d           y w)Nrc  )r$  )rO   r   matrix_transposeds     rR   rS   z"Matrix.__repr__.<locals>.<genexpr>/
  s"     'W,=add,C(D'Ws   rc  zMatrix([z]))r  rt   r   )r   
matrix_strr  s     @rR   r*  zMatrix.__repr__*
  s>     !002"'''WeTUh'WW
*R((rW   N)r  zgp_GTrsf | gp_Trsf)r  zSequence[Sequence[float]])rf   rm   rW  r   )r"  rt  )r  rp   r"  rp   )r  rt  r"  rt  )r"  rf  )r  ztuple[int, int]r"  r   rn  )r)  rw  rx  ry  r   r   rX  r  r   r  r?  rE  r  r*  r   rW   rR   rt  rt  	  s    (      -^4/    >@++$)rW   rt  c                      e Zd ZdZedd       Zedd       Zedd       Zedd       Zedd       Z	edd       Z
edd       Zedd	       Zedd
       Zedd       Zedd       Zedd       Zedd       Zy)	PlaneMetaz+Plane meta class to enable class propertiesc                    t        ddd      S )zXY Planer  r  r  rn   r  s    rR   XYzPlaneMeta.XY6
       Y	955rW   c                    t        ddd      S )zYZ Planer  r  r  r  r  s    rR   YZzPlaneMeta.YZ;
  r  rW   c                    t        ddd      S )zZX Planer  r  r  r  r  s    rR   ZXzPlaneMeta.ZX@
  r  rW   c                    t        ddd      S )zXZ Planer  r  r   r   r   r  r  s    rR   XZzPlaneMeta.XZE
       Y	:66rW   c                    t        ddd      S )zYX Planer  r  r   r   r   r  r  s    rR   YXzPlaneMeta.YXJ
  r  rW   c                    t        ddd      S )zZY Planer  r  r   r   r   r  r  s    rR   ZYzPlaneMeta.ZYO
  r  rW   c                    t        ddd      S )zFront Planer  r  r  r  r  s    rR   frontzPlaneMeta.frontT
  r  rW   c                    t        ddd      S )z
Back Planer  r  r  r  r  s    rR   backzPlaneMeta.backY
  s     Y
I66rW   c                    t        ddd      S )z
Left Planer  r  r  r  r  s    rR   leftzPlaneMeta.left^
  s     Y
J77rW   c                    t        ddd      S )zRight Planer  r  r  r  r  s    rR   rightzPlaneMeta.rightc
  r  rW   c                    t        ddd      S )z	Top Planer  r  r  r  r  s    rR   topzPlaneMeta.toph
  r  rW   c                    t        ddd      S )zBottom Planer  r  r  r  r  s    rR   bottomzPlaneMeta.bottomm
  r  rW   c                    t        ddd      S )zIsometric Planer  );f?r  r   )3Ey?g3Eyr  r  r  s    rR   	isometriczPlaneMeta.isometricr
  s     '1
 	
rW   Nr  )r)  rw  rx  ry  r|  r  r  r  r  r  r  r  r  r  r  r  r  r   r   rW   rR   r  r  3
  s   56 6 6 6 6 6 7 7 7 7 7 7 7 7 7 7 8 8 6 6 6 6 7 7 
 
rW   r  c                     e Zd ZdZed@d       Ze	 	 	 	 dAd       ZedBd       ZedCd       Ze	 	 dD	 	 	 	 	 	 	 dEd       Ze	 	 	 	 	 	 	 	 dFd       ZedGdHd	       ZedId
       ZedGdJd       ZdKdZe	dLd       Z
edMd       ZdNdZdOdZdOdZdPdZdQdZdRdZdOdZedSd       ZedTd       ZedUd       Z	 	 	 	 dVdZedWd       ZedXd       Z	 	 	 	 dYdZdZdZd[dZd[dZd[d ZdOd!Ze	d\d"       Zej6                  d]d#       Ze	d\d$       Ze	d\d%       Zej6                  d^d&       Ze	d\d'       Zej6                  d^d(       Zd_d)Z	 	 d`	 	 	 	 	 dad*Z dbd+Z!dbd,Z"e	d-        Z#e	d.        Z$e	dcd/       Z%ddd0Z&ded1Z'	 df	 	 	 dgd2Z(dhd3Z)did4Z*djd5Z+e,fdkd6Z-dld7Z.dmd8Z/dnd9Z0edod:       Z1ednd;       Z1edpd<       Z1edmd=       Z1edqd>       Z1d? Z1y)rrn   a	  Plane

    A plane is positioned in space with a coordinate system such that the plane is defined by
    the origin, x_dir (X direction), y_dir (Y direction), and z_dir (Z direction) of this coordinate
    system, which is the "local coordinate system" of the plane. The z_dir is a vector normal to the
    plane. The coordinate system is right-handed.

    A plane allows the use of local 2D coordinates, which are later converted to
    global, 3d coordinates when the operations are complete.

    Planes can be created from faces as workplanes for feature creation on objects.

    =========   ====== ======== ========
    Name        x_dir  y_dir    z_dir
    =========   ====== ======== ========
    XY           +x     +y       +z
    YZ           +y     +z       +x
    ZX           +z     +x       +y
    XZ           +x     +z       -y
    YX           +y     +x       -z
    ZY           +z     +y       -x
    front        +x     +z       -y
    back         -x     +z       +y
    left         -y     +z       -x
    right        +y     +z       +x
    top          +x     +y       +z
    bottom       +x     -y       -z
    isometric    +x+y   -x+y+z   +x+y-z
    =========   ====== ======== ========

    Args:
        gp_pln (gp_Pln): an OCCT plane object
        origin (tuple[float, float, float] | Vector): the origin in global coordinates
        x_dir (tuple[float, float, float] | Vector | None): an optional vector
            representing the X Direction. Defaults to None.
        y_dir (tuple[float, float, float] | Vector | None): optional Y direction.
            Mutually exclusive with z_dir. Requires x_dir.
        z_dir (tuple[float, float, float] | Vector | None): the normal direction
            for the plane. Defaults to (0, 0, 1).

    Attributes:
        origin (Vector): global position of local (0,0,0) point
        x_dir (Vector): x direction
        y_dir (Vector): y direction
        z_dir (Vector): z direction
        forward_transform (Matrix): forward location transformation matrix
        reverse_transform (Matrix): reverse location transformation matrix
        wrapped (gp_Pln): the OCP plane object

    Raises:
        ValueError: z_dir must be non null
        ValueError: y_dir must be non null
        ValueError: x_dir must be non null
        ValueError: the specified x_dir is not orthogonal to the provided normal
        ValueError: x_dir and y_dir must not be parallel
        ValueError: the specified x_dir is not orthogonal to the provided normal

    Returns:
        Plane: A plane

    c                    t               }t               }t        |t        j                  |             }|j                         \  }}t        |       j                  ||||       t        |      S )z.Find the normal at the center of a TopoDS_Face)	r,   r/   r#   r   	Surface_sLowerDistanceParametersr   Normalrp   )facegp_pntr   	projectoru_valv_vals         rR   get_topods_face_normalzPlane.get_topods_face_normal
  s^     .vy7J7J47PQ	 88:ut##E5&&Af~rW   c                Z   t        |       }t        d |D              rt        |      dfS t        |      dk7  rt	        d      	 |D cg c]  }t        |       }}|d   |d   z
  }|j                  |d   |d   z
        }|d   ||ffS c c}w # t
        $ r}t	        d      |d}~ww xY w)z@Parse a single positional argument as an origin or three points.c              3  H   K   | ]  }t        |t        t        f        y wrL   r   )rO   
coordinates     rR   rS   z7Plane._single_arg_as_origin_and_dirs.<locals>.<genexpr>
  s     T
z*sEl3Trj  Nr   z Expected three VectorLike pointsrA   r   r  )r   r   rp   r   r   r  r   )arg0arg0_sequencer  pointsr   r  r  s          rR   _single_arg_as_origin_and_dirsz$Plane._single_arg_as_origin_and_dirs
  s    
 T
TmTT-($..}">??	I1>?fUm?F? q	F1I%F1Iq	12ay5%.(( @ 	I>?SH	Is*   B 	BB B 	B*B%%B*c                     y)z!Return a plane from a OCCT gp_plnNr   )r   gp_plns     rR   r   zPlane.__init__
  r[  rW   c                     y)z&Return a plane defined by three pointsNr   )r   r  s     rR   r   zPlane.__init__
  r[  rW   Nc                     y)z1Return a new plane at origin with x_dir and z_dirNr   )r   r  r  r  s       rR   r   zPlane.__init__
  r[  rW   c                    y)z1Return a new plane at origin with x_dir and y_dirNr   )r   r  r  r  s       rR   r   zPlane.__init__
  r[  rW   c                     y)zoReturn a plane extending the face.
        Note: for non planar face this will return the underlying work planeNr   )r   r  r  s      rR   r   zPlane.__init__
  r[  rW   c                     y)z,Return a plane aligned with a given locationNr   r]  s     rR   r   zPlane.__init__
  r[  rW   c                     y)zPReturn a plane with the z_dir aligned with the axis and optional x_dir directionNr   )r   rf   r  s      rR   r   zPlane.__init__
  r[  rW   c                h   d}d|v }d|v }|j                  dd      }|j                  dd      }|j                  dd      }|j                  dd      }	|j                  d	d      }
|j                  d
d      }|j                  dd      }|j                  dd      }|rt        ddj                  |             |r?|d   }|t        |t              r|}n$|>t        |d      r2t        |j                  t              r|}|t        |      dkD  r|d   }n|t        |t              r|}n|	0t        |t              r |}	t        |      dkD  r	 t        |d         }n|
	 t        |      dk(  r+t        ||||f      s| j                  |      \  }
}||\  }}nt        |      }
|*t        |      dkD  rt        |d         j                         }t        |      dkD  rt        |d         j                         }|r)t        |t              sJ | j!                  |      | _        yd}d}d}|rYt%        j&                  |j                        }|j(                  st+        d      t-               }t/        j0                  |j                  |       t        |j3                               }t        |t4              r4t7               }t9               }t9               }|j;                  dd|||       n9t        |t<              sJ t9        |j?                         jA                               }|rt        |      n
t        |      }tC        t        |      d      }tD        jG                  |j                        }tC        t        |      d      }nI|rtI        tD        jJ                  j                  dddd      jM                         }|jO                  |j                         |jP                  }t%        j&                  |      }t        |t<              sJ t        |j?                         jA                               }tC        t        |      d      }tD        jG                  |      }tC        t        |      d      }n]|	r(|	jP                  }|t        |      nd}|	jR                  }n3|
&t        |
      }|rt        |      nd}t        |      }nt        |      |r|rt        d      ||t+        d      t        |      jT                  dk(  rt+        d      t        |      jT                  dk(  rt+        d      t        |      j                         }t        |      j                         }|jW                  |      }|jT                  dk(  rt+        d      |j                         }|jW                  |      j                         }|jW                  |      j                         }n|jT                  dk(  rt+        d      |j                         }|PtY        |j[                         |j]                               }t        |jA                               j                         }n<t        |      jT                  dk(  rt+        d      t        |      j                         }tY        |j[                         |j]                         |j]                               }| j!                  t	        |            | _        y# t        $ r}t        |      |d}~ww xY w# t        $ r  t        $ r}t        |      |d}~ww xY w)zICreate a plane from either an OCCT gp_pln, Face, Location, or coordinateszBExpected gp_Pln, Face, Location, Axis, VectorLike, or three pointsr  r  r  Nr  rh   rf   r  r  r  r  re   r   rd   rA   r  z,Planes can only be created from planar facesr-     r   r   z'Specify either y_dir or z_dir, not bothz.x_dir must be provided when y_dir is specifiedr   zx_dir must be non nullzy_dir must be non nullz$x_dir and y_dir must not be parallelzz_dir must be non null)/r  r   rt   rl   r+   rq   rd   r9   r   ro   rm   rp   r  anyr  r   _ensure_right_handedr~   r   r  	is_planarrr   r1   r   SurfaceProperties_sCentreOfMassr   r,   r/   r  r   Positionr  rN   rn   r  r   r  rC   Mover  r  r   r   r&   r   rI  )r   ry   rz   type_error_messagepassed_z_dirpassed_y_dir	arg_planearg_facearg_locationarg_axis
arg_origin	arg_x_dir	arg_y_dir	arg_z_dirr  r   single_arg_dirsr  r  r  surface
propertiesr  r  
face_x_dir	tangent_v	topo_facey_input	z_from_xyax3s                                 rR   r   zPlane.__init__  sc   
 Q 	 &(&(JJx.	::fd+zz*d3::fd+ZZ$/
JJw-	JJw-	JJw	2	<TYYv=N<OPQQ7D Zf%= 	 D),t||[9$TQ $QI%*T8*D#!jt&<t9q=E$*47O	 #A4yA~c"I|\J/ !??E 4
O +63B0Iy%+D\
 (SY]$*47O$>$>$@	4y1}$*47O$>$>$@	 i000 55i@DM))(*:*:;G%% !OPP%J))(*:*:JGJ3356F'#67#X
"H	

3UJ	B!'+ABBB#G$4$4$6$A$A$CD
)2F9%z8JE&-,E001A1ABE&-,E/  $T3df  NN<//0!**F)))4Gg'=>>>7++-88:;E&-,E00;E&-,E&&F)2)>F9%DE&&E#J'F)2F9%E9%E.//LEFF } !QRRe}##s* !9::i ''3. !9::5M,,.EY'224GG,I3& !GHH((*EKK&113EKK&113E||s" !9::$$&E}V]]_elln=s~~/0;;=%=''3.$%=>>u002V]]_ellnellnE11&+>_ % E'(:;DE& !   A#$67S@As1   [1 "B\ 1	\:\\\1 \,,\1c                    | j                   S )zThe OCP objectr   r   s    rR   rd   zPlane.wrapped  r   rW   c                >   | j                         j                         r| S t        j                  dd       t	        | j                         | j                         j                         | j                         j                               }t        t        |            S )z.Check for right handedness and fix if requiredz!Trying to set a left-handed planer   rX  )r"  DirectrZ  r[  r%   ro   rm   r  XAxisr+   r&   )r  ax2s     rR   r  zPlane._ensure_right_handed  sk     <<>  "J9aHS\\^SXXZ%9%9%;SYY[=R=R=TUfSk""rW   c                z    t        | j                  | j                  |z  z   | j                  | j                        S )z2Move the Plane by amount in the direction of z_dirr  )rn   r  r  r  )r   amounts     rR   offsetzPlane.offset  s0    ;;f!44DJJdjj
 	
rW   c                Z    t        t        | j                  j                                     S r=  rn   r+   rd   r"  r   s    rR   r?  zPlane.__copy__      VDLL113455rW   c                Z    t        t        | j                  j                                     S rB  rA  rC  s     rR   rE  zPlane.__deepcopy__  rB  rW   c                p    t        |t              st        S | j                         |j                         k(  S )zAre planes equal operator ==)rl   rn   r/  r0  r  s     rR   r1  zPlane.__eq__  s)    %'!!yy{ejjl**rW   c                4    t        | j                               S )zHash of Planer3  r   s    rR   r5  zPlane.__hash__  r6  rW   c                    | j                   j                         | j                  j                         | j                  j                         fS r8  )r  r0  r  r  r   s    rR   r0  z
Plane._key  s2      "DJJOO$5tzz7HIIrW   c                Z    t        | j                  | j                  | j                         S )z'Reverse z direction of plane operator -)rn   r  r  r  r   s    rR   r
  zPlane.__neg__  s    T[[$**tzzk::rW   c                     y rL   r   r  s     rR   r   zPlane.__mul__  r  rW   c                     y rL   r   r  s     rR   r   zPlane.__mul__  s    <?rW   c                     y rL   r   r  s     rR   r   zPlane.__mul__  s    LOrW   c                z   t        |t              rt        |       |z  S t        |t              rt        |       |j                  z  S 	 t	        |      }t        d |D              r8|D cg c],  }t        |       t        |t              r|j                  n|z  . c}S 	 t        S c c}w # t        $ r Y t        S w xY w)Nc              3  J   K   | ]  }t        |t        t        z          y wrL   )rl   ro   rn   )rO   r  s     rR   rS   z Plane.__mul__.<locals>.<genexpr>  s     K5:eX%56Ks   !#)rl   ro   rn   rh   r   r   r   r/  )r   r  r  s      rR   r   zPlane.__mul__  s     eX&D>E))eU#D>ENN22		%[FKFKK "(  TN)3E5)Au~~uN  L 
  		s$   !B) )1B$B) $B) )	B:9B:c                     y rL   r   r  s     rR   r   zPlane.__rmul__  r  rW   c                     y rL   r   r  s     rR   r   zPlane.__rmul__  s    JMrW   c                   t        |t        t        z        r| j                  |      S 	 t	        |      D cg c]  }| j                  |       c}S c c}w # t
        $ r)}t        t        |       j                   d|       |d }~wt        $ r Y nw xY wt        t        |       j                   dt        |      j                         )Nz cannot be multiplied by )	rl   ro   rn   movedall_location_likeNotAllLocationLikeErrorr   rs   r)  )r   r  r  es       rR   r   zPlane.__rmul__  s     eX-.::e$$	/@/GHDJJsOHHH& 	YtDz2233LQCPQWXX 		Dz""##<T%[=Q=Q<RS
 	
s.   A AA A 	B $BBBc                $    | j                  |      S )zintersect plane with other &r  r  s     rR   r  zPlane.__and__  r  rW   c                   |r|d   nd}|dv r6d| j                   | dd| j                  | dd| j                  | ddS dt        | j                          dt        | j                         dt        | j                         dS )zFormat Planer   Nr  r  r   re   r!  )r  r  r  rT   r  s      rR   r'  zPlane.__format__  s     $DH$	
"t{{D6'*"TZZ`w,?r$**dVSSGATTUVV5%&btzz):(;2eDJJ>O=PPQRRrW   c                F    t        |       j                   | dt         dS )zRepresent Planer  r  r  r   s    rR   r*  zPlane.__repr__  r  rW   c           
         t        |       j                   d| j                  dt         dd| j                  dt         dd| j
                  dt         ddS )zDisplay Planez
: (origin=r  r  z, x_dir=z, z_dir=r!  )rs   r)  r  r  r  r  r   s    rR   r-  zPlane.__str__  sk     Dz""# ${{1ZL/2 3ZZ*Q/ 0ZZ*Q/q2	
rW   c                    |  S )zReverse z direction of planer   r   s    rR   r   zPlane.reverse  s	    urW   c                H    t        | j                  j                               S )z&global position of local (0,0,0) pointr  r   s    rR   r  zPlane.origin  r  rW   c                h    | j                   j                  t        |      j                                y)zSet the Plane originNr  r   s     rR   r  zPlane.origin  s#     	  !5!5!78rW   c                d    t        | j                  j                         j                               S )z&Local Z direction normal to the plane.)rp   rd   rm   r  r   s    rR   r  zPlane.z_dir  s%     dll'')33566rW   c                d    t        | j                  j                         j                               S )zLocal X direction of the plane.)rp   rd   r;  r  r   s    rR   r  zPlane.x_dir$  %     dll((*44677rW   c                    | j                         }|j                  t        |      j                                | j                  j                  t        |             y)z'Set the local X direction of the plane.N)	to_gp_ax2SetXDirectionrp   rI  rd   SetPositionr&   r   r  r<  s      rR   r  zPlane.x_dir)  B     nn&+2245  -rW   c                d    t        | j                  j                         j                               S )zLocal Y direction of the plane.)rp   rd   YAxisr  r   s    rR   r  zPlane.y_dir0  r]  rW   c                    | j                         }|j                  t        |      j                                | j                  j                  t        |             y)z'Set the local Y direction of the plane.N)r_  SetYDirectionrp   rI  rd   ra  r&   rb  s      rR   r  zPlane.y_dir5  rc  rW   c                   t        |d      r|j                  t        d      t        |d      rt        |j                  t              rut        j                  |j                        }t        |j                         |j                         |j                               }| j                  |      st        | d      t        |t        t        f      r*t        |      }| j                  |      sgt        | d      t        |t              r2| j                  |      }t        |t              st        | d      |}nt        dt!        |             t#        || j$                  | j&                        S )aR  shift plane origin

        Creates a new plane with the origin moved within the plane to the point of intersection
        of the axis or at the given Vertex. The plane's x_dir and z_dir are unchanged.

        Args:
            locator (Axis | VectorLike | Vertex): Either Axis that intersects the new
                plane origin or Vertex within Plane.

        Raises:
            ValueError: Vertex isn't within plane
            ValueError: Point isn't within plane
            ValueError: Axis doesn't intersect plane

        Returns:
            Plane: plane with new origin

        rd   z#Can't shift origin to empty locatorz is not located within planez doesn't intersect the planezInvalid locate type: r  )rq   rd   rr   rl   r;   r   r   rp   rY   rZ   r[   containsrT   rm   r  r   rs   rn   r  r  )r   locatorr   
new_originintersections        rR   shift_originzPlane.shift_origin<  s)   & 7I&7??+BBCC7I&:goo}+U"9J


OJ==, G9,H!IJJ%1J==) G9,H!IJJ&>>'2LlF3 G9,H!IJJ%J3DM?CDDJdjj

KKrW   c                   |t         j                  }t        t        t	        |            \  }}}t               }|j                  t        j                  |   |||       t               }|j                  |       | j                         j                  |      }|j                  | j                  j                                t        t!        t#        |                  S )a  Returns a copy of this plane, rotated about the specified axes

        The origin of the workplane is unaffected by the rotation.

        Rotations are done in order x, y, z. If you need a different order,
        specify ordering. e.g. Intrinsic.ZYX changes rotation to
        (z angle, y angle, x angle) and rotates in that order.

        Args:
            rotation (VectorLike, optional): (x angle, y angle, z angle).
                Defaults to (0, 0, 0)
            ordering (Intrinsic |  Extrinsic, optional): order of rotations in
                Intrinsic or Extrinsic rotation mode. Defaults to Intrinsic.XYZ

        Returns:
            Plane: a copy of this plane rotated as requested.
        )r@   r   r  r   rp   r-   r  ro   r  r.   r  r_  rK  r  rd   rn   r+   r&   )	r   r  r  a1a2a3r_   trsf_rotationaxs	            rR   rotatedzPlane.rotatedc  s    .  }}H &"23
B"_
!!(":":8"Db"bQ	!!*-^^))-8
t||,,./VF2J'((rW   c                j    t        |t              r|j                  }t        | j                  |z        S )zChange the position & orientation of a copy of self by applying a relative location

        Args:
            loc (Location | Plane): relative change

        Returns:
            Plane: relocated plane
        )rl   rn   rh   r   r  s     rR   rP  zPlane.moved  s+     c5!,,CT]]S())rW   c                d    | j                  | j                  |      j                        | _        | S )zChange the position & orientation of self by applying a relative location

        Args:
            loc (Location | Plane): relative change

        Returns:
            Plane: relocated self
        )r  rP  rd   r~   rv  s     rR   movez
Plane.move  s)     11$**S/2I2IJrW   c                    t               }| j                         }t               }|j                  ||       t	        t        |            S )z&forward location transformation matrixr&   	to_gp_ax3r.   r  rt  r)   )r   global_coord_systemlocal_coord_system	forward_ts       rR   forward_transformzPlane.forward_transform  sB     %h!^^-I	##$79KLhy)**rW   c                    t               }| j                         }t               }|j                  ||       t	        t        |            S )z&reverse location transformation matrixrz  )r   r|  r}  	inverse_ts       rR   reverse_transformzPlane.reverse_transform  sB     %h!^^-I	##$68KLhy)**rW   c                    t        |       S )z7Return Location representing the origin and z direction)ro   r   s    rR   rh   zPlane.location  s     ~rW   c                6    | j                   j                         S )z"Return gp_Ax3 version of the plane)rd   r"  r   s    rR   r{  zPlane.to_gp_ax3  s    ||$$&&rW   c                R    | j                   j                         j                         S )z"Return gp_Ax2 version of the plane)rd   r"  Ax2r   s    rR   r_  zPlane.to_gp_ax2  s    ||$$&**,,rW   c                (   |r| j                   n| j                  }t        |t        t        f      rt	        |      j                  |      S t        |t              rt	        |j                  j                  |j                  j                  |j                  j                        }t	        |j                  j                  |j                  j                  |j                  j                        }|j                  |      }|j                  |      }t        t        | t        |       }t        |      S t        |d      r|j                  t!        d      t        |d      rzt        |j                  t"              r_t$        j&                  t(        j*                  t$        j,                  t(        j.                  t$        j0                  t(        j2                  t$        j4                  t(        j6                  t$        j8                  t(        j:                  t$        j<                  t(        j>                  t$        j@                  t(        jB                  i}	|j                  J 	 |	|j                  jE                            }
tI        jJ                  |d      } |
tM        |j                  |j                  jO                               jQ                               |_        |S t!        dtS        |       d      # tF        $ r}t!        d|       |d}~ww xY w)a  _to_from_local_coords

        Reposition the object relative to this plane

        Args:
            obj (VectorLike |  Shape |  BoundBox): an object to reposition. Note that
            type Any refers to all topological classes.
            to_from (bool, optional): direction of transformation. Defaults to True (to).

        Raises:
            ValueError: Unsupported object type

        Returns:
            an object of the same type, but repositioned to local coordinates
        rd   NzCant's reposition empty objectzUnknown object type zUnable to repositioned type z" with respect to local coordinates)*r  r  rl   rT   rp   rT  r  r"  rY   rZ   r[   r   r   r,   rq   rd   rr   r:   r5   TopAbs_VERTEXr7   rE   TopAbs_EDGErB   TopAbs_WIREWireTopAbs_FACErC   TopAbs_SHELLShellTopAbs_SOLIDSolidTopAbs_COMPOUNDCompound	ShapeTypeKeyErrorcopy_moduledeepcopyr   rL  rD   rs   )r   r7  to_fromtransform_matrixglobal_bottom_leftglobal_top_rightlocal_bottom_leftlocal_top_right
local_bboxdowncast_lut
f_downcastr   	new_shapes                rR   _to_from_local_coordszPlane._to_from_local_coords  sS   & 6=411$BXBXcE6?+#;(()9::c8$!'		37799cggii!H%cggiiCGGIIF 2 < <=M N.889IJO )*(J J''3	"s{{':=>>3	"z#++|'L
 !.. ,,fkk ,,fkk ,,fkk --v|| --v|| 00&//  ;;***H)#++*?*?*AB
  +33C>I *(KK!1!9!9!>!>!@%'!I
 *49+5WX
 	
  H #7u!=>CGHs    K4 4	L=LLc                &    | j                  |d      S )a1  Reposition the object relative to this plane

        Args:
            obj: VectorLike |  Shape |  BoundBox an object to reposition. Note that
            type Any refers to all topological classes.

        Returns:
            an object of the same type, but repositioned to local coordinates

        Tr  r   r7  s     rR   to_local_coordszPlane.to_local_coords  s     ))#t44rW   c                &    | j                  |d      S )a3  Reposition the object relative from this plane

        Args:
            obj: VectorLike |  Shape |  BoundBox an object to reposition. Note that
            type Any refers to all topological classes.

        Returns:
            an object of the same type, but repositioned to world coordinates

        Fr  r  s     rR   rm  zPlane.from_local_coords  s     ))#u55rW   c                    t               }|j                  | j                  j                         |j                  j                                t	        |      S )zAReturn a location representing the translation from self to other)r.   r  rd   r"  ro   )r   r  r  s      rR   location_betweenzPlane.location_between  sE     !((LL!!#U]]%;%;%=	
 ''rW   c                >   t        |t              rY| j                  j                  t	        |j
                  j                         |j                  j                               ||      }|S | j                  j                  t        |      j                         |      }|S )a5  contains

        Is this point or Axis fully contained in this plane?

        Args:
            obj (VectorLike | Axis): point or Axis to  evaluate
            tolerance (float, optional): comparison tolerance. Defaults to TOLERANCE.

        Returns:
            bool: self contains point or Axis

        )
rl   rm   rd   Containsr*   r  r   r  rI  rp   )r   r7  r  rQ  s       rR   ri  zPlane.contains$  s     c4 <<00s||**,cmm.B.B.DEL   <<001C1C1EyQLrW   c                   | j                  |      r|S t        |j                        }t        | j	                               }t        ||      }|j                         r-|j                         dk(  rt        |j                  d            S y)z,Find intersection of this plane and an axis.rA   N)
ri  r   rd   r    r{  r!   IsDoneNbPointsrp   Point)r   rf   	geom_line
geom_planeintersection_calculators        rR   r  zPlane._intersect_axis;  sw    ==Kdll+	 01
"/	:"F"))+0G0P0P0RVW0W177:;;rW   c                   | j                  |j                        r| j                  |j                  k(  r| S t        | j                        }t        |j                        }t        ||t              }|j                         rO|j                         dkD  r<|j                  d      }t        |t              sJ t        |j                               S y)z2Find intersection of this plane and another plane.r   rA   N)ri  r  r  r    rd   r"   r^   r  NbLinesLinerl   r   rm   r"  )r   rg   surface1surface2intersectorintersection_lines         rR   _intersect_planezPlane._intersect_planeH  s    ==&4::+DKdll+emm,#Hh	BK$7$7$9A$= + 0 0 3/;;;)22455rW   c                    t        |      }| j                  |j                        sy| j                  |j                  k(  r|S |j                  S )z/Find intersection of this plane and a location.N)rn   ri  r  r  )r   rh   location_planes      rR   r   zPlane._intersect_locationV  sC    x}}^223::---O$$$rW   c                     y)z%Find intersection of plane and vectorNr   rZ  s     rR   r  zPlane.intersect_  r[  rW   c                     y)z'Find intersection of plane and locationNr   r]  s     rR   r  zPlane.intersectc  r[  rW   c                     y)z#Find intersection of plane and axisNr   r_  s     rR   r  zPlane.intersectg  r[  rW   c                     y)z$Find intersection of plane and planeNr   r   s     rR   r  zPlane.intersectk  r[  rW   c                     y)z$Find intersection of plane and shapeNr   rb  s     rR   r  zPlane.intersecto  r[  rW   c                    t        |i |\  }}}}}|| j                  |      S || j                  |      S || j                  |      r|S || j	                  |      S ||j                  |       S y)z8Find intersection of plane and geometric object or shapeN)r|   r  r  ri  r   r  rd  s           rR   r  zPlane.intersects  s     0Ed/Uf/U,eVXu''--((//$--"7M++H55??4((rW   )r  r9   r"  rp   )r  r   r"  z+tuple[Vector, tuple[Vector, Vector] | None])r  r+   r"  rh  )r  zIterable[VectorLike]r"  rh  )Nr  )r  rj  r  VectorLike | Noner  rj  r"  rh  )r  rj  r  rj  r  rj  r"  rh  rL   )r  rC   r  r  r"  rh  r  )rf   rm   r  r  r"  rh  r  )r"  r+   )r  r+   )r>  r   r"  rn   r  )r  rp  rr  )r"  z>tuple[tuple[float, ...], tuple[float, ...], tuple[float, ...]]r/  )r  Location | Planer"  ro   )r  Iterable[Location | Plane]r"  r0  )r  -Location | Plane | Iterable[Location | Plane]r"  r1  )r  ro   r"  rn   )r  r  r"  zlist[Plane])r  r  r"  zPlane | list[Plane])r   rn   r  rm  rn  rk  r.  r	  )rj  zAxis | VectorLike | Vertexr"  rn   )r  N)r  rj  r  zExtrinsic | Intrinsic | Noner"  rn   )r  r  r"  rn   r
  )r"  r&   )r"  r%   )T)r7  VectorLike | Any | BoundBoxr  rq  )r7  r  )r7  ztuple | Vector | Any | BoundBox)r  rn   r"  ro   )r7  zVectorLike | Axisr  r   r"  rq  )rf   rm   r"  zAxis | Vector | None)rg   rn   r"  zAxis | Plane | Noner  ru  r  rv  )2r)  rw  rx  ry  rK  r  r  r   r   r|  rd   r  r?  r?  rE  r1  r5  r0  r
  r   r   r  r'  r*  r-  r   r  r}  r  r  r  rm  rt  rP  rx  r  r  rh   r{  r_  r  r  rm  r  r^   ri  r  r  r   r  r   rW   rR   rn   rn   |
  s   <~   ))	4) )& 0 0 5 5  $(%	@@ !@ 	@
 
@ @ @@ @
 @ 
@ @ P P ; ; _ _Y?v   # #
66+!J; 5 5? ?O OB	"& 5 5M M
B
	
%S=
 / / ]]9 9 7 7 8 8 \\. . 8 8 \\. .%LR  )15#)#) /#) 
	#)J*
 + + + +  '-
 AE?
.?
9=?
B56( CL .% 4 4 6 6 2 2 3 3 3 3rW   rn   )rm   rN  ro   rn   rp   c                   g }|t        |       t        |      z   dz  }||t        j                  u rt        ddd      S |t        j                  u rt        |        S |t        j                  u rt        |       S |t        j
                  u rt        |       S t        t        t        |      | ||      D ]  \  }}}}|t        j                  k(  r|j                  |        .|t        j
                  k(  r|j                  |        T|t        j                  k(  r|j                  |        z|t        j                  k(  s|j                  d        t        | S )rF  r  r   )	rp   r<   NONEMINMAXCENTERr  r  append)		min_point	max_pointrH  r   align_offset	alignment	min_coord	max_coordcenter_coords	            rR   rG  rG    s>    L~#fY&771<}+aA		y!!!		y!!!v9<E5	: #5	9i 		!
+%,,&.%))#
+%**$"# <  rW   c                  $     e Zd ZdZd fdZ xZS )rR  zRaised when an iterable contains objects that cannot be converted to Locations.

    The exception message lists the unique type names of the invalid objects.
    c           
     t    t         |   dj                  t        d t	        |      D                           y )Nre   c              3  4   K   | ]  }|j                     y wrL   )r)  )rO   ts     rR   rS   z3NotAllLocationLikeError.__init__.<locals>.<genexpr>  s     )O!**)Orw  )r  r   rt   sortedru   )r   wrong_typesr  s     rR   r   z NotAllLocationLikeError.__init__  s)    6)Oc+>N)O#OPQrW   )r  zIterable[Type[Any]]r"  rh  )r)  rw  rx  ry  r   r  r  s   @rR   rR  rR    s    
R RrW   rR  c                Z    t        |       } t        d | D              x}rt        |      | S )zReturns the items as a list unless any of them is not an instance of `Location | Plane`.
    Otherwise raises `NotAllLocationLikeError`.c              3     K   | ];  }t        |t        t        z        s"t        t        t
           t        |             = y wrL   )rl   ro   rn   r   r   r   rs   )rO   r  s     rR   rS   z$all_location_like.<locals>.<genexpr>  s6      $5 01 	T#YT
#s   AA)r   ru   rR  )r  r  s     rR   rQ  rQ    s@     KE   { 
 &k22LrW   )rU   zIterable[float]rQ   r   r"  rs  )r_   r-   rQ   r   r"  rs  rL   )
r  rj  r  rj  rH  rJ  r   r  r"  rp   )r  zIterable[Any]r"  zlist[Location | Plane])ry  
__future__r   r  copyr  rk  jsonloggingrZ  collections.abcr   r   r   mathr   r   r	   r
   r   typingr   r   r   r   r   r   r   numpyr  typing_extensionsr   r  OCP.Bndr   r   OCP.BRepr   OCP.BRepBndLibr   OCP.BRepBuilderAPIr   r   OCP.BRepGPropr   r   OCP.BRepToolsr   OCP.Geomr   r   r   r    OCP.GeomAPIr!   r"   r#   OCP.gpr$   r%   r&   r'   r(   r)   r*   r+   r,   r-   r.   r/   r0   	OCP.GPropr1   OCP.Quantityr2   r3   r4   
OCP.TopAbsr5   
OCP.TopLocr6   
OCP.TopoDSr7   r8   r9   r:   r;   build123d.build_enumsr<   r=   r>   r?   r@   topologyrB   rC   rD   rE   rF   	getLogger
addHandlerNullHandlerloggerr^   r]   r   r  r  DEG2RADr   GEOM_KEY_DIGITSrV   rb   r|   rp   rT   r   rj  rz  rs   r  rm   r  rN  r$  r  JSONEncoderr  ro   rU  ra  r  Rotr,  r  rt  r  rn   r  rG  r   rR  rQ  r   rW   rR   <module>r     s  : #       8 8 2 2 O O O  (  $  % P 3 # W W P P   " # Q Q ' & T T O O33iu-G   +  ) )*='*=*=*? @			;	'	U9%&'


u*
(q. ,;;;%(;; .=
,
,'*
,
,0@x xx U5%<  5u)<#==O I )t )&WX Wt^: ^:BX6 X6x CECKeck123 US[%#+us{: 

 CHo  	 
9 ;/$"" ;/|QD QDh*d&& *ZP
 P
f;x ;| "U5%+>%??i ?'*( '*TS) S)lF
 F
RKi K^  !%	#!#!#! #! 	#!
 #!LRi RrW   