
    ^jK,                    X   d Z ddlmZ ddlmZ ddlmZ ddlmZm	Z	 ddl
mZmZmZ ddlmZ ddlmZmZ dd	lmZmZmZmZmZmZmZmZmZ d
dej:                  f	 	 	 	 	 	 	 	 	 ddZdej>                  f	 	 	 	 	 ddZ dej>                  f	 	 	 	 	 ddZ!ddej>                  f	 	 	 	 	 	 	 ddZ"y)a  
Sketch Operations

name: operations_sketch.py
by:   Gumyr
date: March 21th 2023

desc:
    This python module contains operations (functions) that work on
    planar Sketches.

license:

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

    )annotations)Iterable)Voronoi)flatten_sequencevalidate_inputs)ModeSortBy
Transition)BuildSketch)PlaneVector)	CompoundCurveEdgeFace	ShapeListShellSketchWiretopo_explore_connected_edgesFd   c                X    t        j                  d      }t        | t              st	        d      t        |d|        | j                  t	        d      t        | | j                        }t        |      dk7  rt	        d      | g|z   }|D 	cg c]7  }|j                  t        |dz         D 	cg c]  }	|	|z  	 c}	      D ]  }| 9 }
}}}	|
D cg c]  }|j                  |j                  g }}t        |      j                  D cg c]
  }t        |  c} t!        d      t#               ft!        d      t#               ft!        d      t#               fg}t%               D ]k  \  }	}|D  cg c]  } | j'                  |       }} t)        |      d	z  t+        fd
|D              }||d   d   k  sR||	f|d<   |j-                  d        m t)         fd|D        t        ddd            d	z  }|D cg c]  }|j/                  |      d    }} j/                  |      d   }t)        |t        ddd            dz  }|d   |d   z
  j1                         }||z
  }|||j3                  |      z  z
  j1                         }t5        |||      }|D cg c]  }|j7                  |       }}g }|D ]2  }|t	        d      t        |t              sJ |j9                  |       4 |r|dz  |z
  }t        j:                  |d   ||d         }| j                  j=                         t        |       z
  t?        | g      z
  }tA        jB                  ||gz   |z         jE                  tF        jH                  d      }tK        |d   |dd       }| j                  jM                         d   jO                         |jO                         k7  r| }|"|jQ                  ||       t?               |_)        tU        |g      S c c}	w c c}	}}w c c}w c c}w c c} w c c}w c c}w )a  Sketch Operation: full_round

    Given an edge from a Face/Sketch, modify the face by replacing the given edge with the
    arc of the Voronoi largest empty circle that will fit within the Face.  This
    "rounds off" the end of the object.

    Args:
        edge (Edge): target Edge to remove
        invert (bool, optional): make the arc concave instead of convex. Defaults to False.
        voronoi_point_count (int, optional): number of points along each edge
            used to create the voronoi vertices as potential locations for the
            center of the largest empty circle. Defaults to 100.
        mode (Mode, optional): combination mode. Defaults to Mode.REPLACE.

    Raises:
        ValueError: Invalid geometry

    Returns:
        Sketch: the modified shape

    
full_roundzA single Edge must be providedNz!edge must be extracted from shape   z+Invalid geometry - 3 or more edges required   inf   c              3  :   K   | ]  }t        |z
          y wN)abs).0davg_distances     T/opt/ringagent/.cad-venv/lib/python3.12/site-packages/build123d/operations_sketch.py	<genexpr>zfull_round.<locals>.<genexpr>z   s     B1Q-.Bs   r   c                    | d   S )Nr    )xs    r$   <lambda>zfull_round.<locals>.<lambda>   s
    !A$     )keyc              3  .   K   | ]  \  }}|     y wr   r(   )r!   _ivoronoi_verticess      r$   r%   zfull_round.<locals>.<genexpr>   s     8TQa 8s   )originx_dirz_dirz&Invalid geometry to create the end arcT)reversemode)+r   _get_context
isinstancer   
ValueErrorr   topo_parentr   len	positionsrangeXYr   verticesr   floatint	enumeratedistance_tosummaxsortdistance_to_with_closest_points
normalizeddotr   splitappendmake_three_point_arcedgesr   r   combinesort_byr	   LENGTHr   faces	normal_at_add_to_contextpending_edgesr   )!edgeinvertvoronoi_point_countr6   contextconnected_edges
edge_groupevr/   voronoi_edge_pointspnumpy_style_pnts
best_three	distances
differencevoronoi_circle_centerconnected_edges_end_pointsmiddle_edge_arc_pointr1   r2   
to_arc_vecr3   	split_plntrimmed_connected_edgestyped_trimmed_connected_edgestrimmed_edgenew_arcother_edges
face_wirespending_facer#   r0   s!                                  @@r$   r   r   5   sx   6 #.":":<"HGdD!9::G\40<== 349I9IJO
?q FGG/)J  .34G!4K.LMQ$$M
  	
	  -@@qacc
@@,34D,E,N,NOq
O 
usu	usu	usu+J
 *+ 015?@TT%%a(@	@9~)B	BB
 
2q))(!_JrNOOO/0 	8Z8&Aq/JQN  !" 	
))*?@C" " !@@AVW	
 +VAq!_=AF'*-G-JJVVXE//J%*.."777CCEEV5>I;JKaqwwy1KK$&!/ ;EFF,---%,,\:	;  5 9<Q Q ''"1%"1%G 	 
&t
,	-
TF
	  %	1K?gfmmTg*  
1z!"~6L ",,.,2H2H2JJ$}48 ) <.!!w N	 AO A"$ Ls6    P2P>PPP3P>P"P'PNc                   t        j                  d      }| t        d t        |       D              }n||j                  }nt        d      |st        d      t        |d|       t        t        j                  |      d         }|j                         j                  dk  r| }|"|j                  ||       t               |_        t        t        |g      j                        S )a9  Sketch Operation: make_face

    Create a face from the given perimeter edges.

    Args:
        edges (Edge | Wire | Curve): perimeter edges that must combine into a
            single closed wire. Defaults to all sketch pending edges.
        mode (Mode, optional): combination mode. Defaults to Mode.ADD.
    	make_facec              3  |   K   | ]4  }t        |t        t        f      r|j                         n|gD ]  }|  6 y wr   )r8   r   r   rN   )r!   itemrV   s      r$   r%   zmake_face.<locals>.<genexpr>   sD       
)3D4-)Htf 
   
 
s   :<zNo objects to create a faceNo objects to create a hullr   r5   )r   r7   r   r   rU   r9   r   r   r   rO   rS   ZrT   r   r   wrapped)rN   r6   rY   outer_edgesro   s        r$   rq   rq      s     #.":":;"GG  
(/ 
 

 
	++677677G[+6[1!45L!!A%$}48 )(L>*2233r+   c                   t        j                  d      }| t        |       }nO|B|j                  }|j                  5|j                  |j                  j                                nt        d      |st        d      t        |d|       t        t        j                  |            }|j                         j                  dk  r| }|"|j                  ||       t               |_        t!        t#        |g      j$                        S )a  Sketch Operation: make_hull

    Create a face from the convex hull of the given edges

    Args:
        edges (Edge, optional): sequence of edges to hull. Defaults to all
            sketch pending edges.
        mode (Mode, optional): combination mode. Defaults to Mode.ADD.
    	make_hullrt   r   r5   )r   r7   r   rU   sketch_localextendrN   r9   r   r   r   make_convex_hullrS   ru   rT   r   r   r   rv   )rN   r6   rY   
hull_edgesro   s        r$   ry   ry      s     #.":":;"GG%e,
		**
+g2288:;677677G[*5--j9:L!!A%$}48 )(L>*2233r+   r   c                   t        j                  d      }| 2t        |       }|D cg c]  }|j                         D ]  }|  }}}n||j                  }nt        d      t        j                  |      }g }	|D ]W  }
|
j                  |d      }|	j                  t        j                  ||
t        j                        j                                Y |! |j                  |	d|i t!               |_        t#        |	      dkD  rt%        j&                  |	 n|	d   }t)        |t*              rt-        |      }|S t-        |j.                        }|S c c}}w )a  Sketch Operation: trace

    Convert edges, wires or pending edges into faces by sweeping a perpendicular line along them.

    Args:
        lines (Curve | Edge | Wire | Iterable[Curve | Edge | Wire]], optional): lines to
            trace. Defaults to sketch pending edges.
        line_width (float, optional): Defaults to 1.
        mode (Mode, optional): combination mode. Defaults to Mode.ADD.

    Raises:
        ValueError: No objects to trace

    Returns:
        Sketch: Traced lines
    tracezNo objects to tracer   )
transitionr6   r   )r   r7   r   rN   rU   r9   r   rO   perpendicular_liner{   r   sweepr
   RIGHTrR   rT   r   r;   r   fuser8   listr   rv   )lines
line_widthr6   rY   trace_lineslr\   trace_edgestrace_wires	new_facesto_trace	trace_pencombined_facesresults                 r$   r   r     sV   * #.":":7"CG&u-"-AQqwwyA!qAqAA		++.// ,,{+KI 
//
A>	KK	8
8H8HIOOQ	


 66 ) /2)nq.@TYY	*iPQlN nd+ 	~ 
 M N**+ 
 M5 Bs   E)
rV   r   rW   boolrX   rB   r6   r   returnztuple[Sketch, Vector, float])rN   z:Edge | Wire | Curve | Iterable[Edge | Wire | Curve] | Noner6   r   r   r   )rN   zEdge | Iterable[Edge] | Noner6   r   r   r   )r   z:Curve | Edge | Wire | Iterable[Curve | Edge | Wire] | Noner   rA   r6   r   r   r   )#__doc__
__future__r   collections.abcr   scipy.spatialr   build123d.build_commonr   r   build123d.build_enumsr   r	   r
   build123d.build_sketchr   build123d.geometryr   r   build123d.topologyr   r   r   r   r   r   r   r   r   REPLACEr   ADDrq   ry   r   r(   r+   r$   <module>r      s  : # $ ! D : : . ,
 
 
 "	N"
N"N" N" 	N"
 "N"d IM%4E%4
%4 %4R +/TXX#4'#46:#4#4N IM3E33 3 	3r+   