Ë
    Jÿi`,  ã                  óT  — 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mZmZmZmZmZmZ ddlmZmZ ddlmZmZ dd	lmZ d
dej8                  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)ÚModeÚSortBy)	ÚCompoundÚCurveÚEdgeÚFaceÚ	ShapeListÚWireÚSketchÚtopo_explore_connected_edgesÚtopo_explore_common_vertex)ÚVectorÚ	TOLERANCE)Úflatten_sequenceÚvalidate_inputs)ÚBuildSketchFéd   c                óâ	  ‡‡ — t        j                  d«      }t        | t        «      st	        d«      ‚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 ]w  \  }	}t        d«      D �	cg c]  }	||	   j'                  |«      ‘Œ }}	t)        |«      dz  Št+        ˆfd„|D «       «      }||d	   d
   k  sŒ^|	f|d	<   |j-                  d„ ¬«       Œy |D �cg c]  }|d   ‘Œ	 }}t)        ˆ fd„|D «       t        d
d
d
«      «      dz  }|D �cg c]  }|j/                  |«      d   ‘Œ }}| j/                  |«      d   }|r|dz  |z
  }t%        |«      D �	�cg c]  \  }	}|j1                  ||	   «      ‘Œ }}	}|D ]$  }d|cxk  rdk  rŒt	        d«      ‚ t	        d«      ‚ |D �cg c]  }t        t3        | |«      «      ‘Œ }}t%        |«      D �	�cg c]  \  }	}|j1                  ||	   «      ‘Œ }}	}t%        |«      D �	�cg c](  \  }	} |j4                  t7        d||	   z
  ||	   g«      Ž ‘Œ* }}	}g }t        d«      D ]ƒ  }	||	   j9                  d
«      ||	   j9                  d
«      z
  j:                  t<        k  r$|j?                  ||	   j9                  d«      «       Œa|j?                  ||	   j9                  d
«      «       Œ… t        j@                  |d
   ||d   «      }| j                  €tC        «       }n3| j                  jE                  «       t        | «      z
  tC        | g«      z
  }tG        jH                  ||gz   |z   «      jK                  tL        jN                  d¬«      }tQ        |d
   |dd «      }|�"|jS                  ||¬«       tC        «       |_*        tW        |g«      |jX                  |jZ                  fS c c}	w c c}	}}w c c}w c c}w 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, Vector, float): A tuple where the first value is the modified shape, the second the
        geometric center of the arc, and the third the radius of the arc

    Ú
full_roundzA single Edge must be providedé   z+Invalid geometry - 3 or more edges requiredé   Úinfé   c              3  ó:   •K  — | ]  }t        |‰z
  «      –— Œ y ­w©N)Úabs)Ú.0ÚdistÚavg_distances     €úl/workspace/moltex-experiments/.pixi/envs/default/lib/python3.12/site-packages/build123d/operations_sketch.pyÚ	<genexpr>zfull_round.<locals>.<genexpr>w   s   øè ø€ ÐI¹y°tœ#˜d \Ñ1×2¹yùs   ƒéÿÿÿÿ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   øè ø€ Ð7©, QÐ˜aÕ ©,ùs   ƒg      @g        g      ð?z&Invalid geometry to create the end arcNT)Úreverse©Úmode).r   Ú_get_contextÚ
isinstancer
   Ú
ValueErrorr   r   Útopo_parentÚlenÚ	positionsÚrangeÚXÚYr   Úverticesr   ÚfloatÚintÚ	enumerateÚdistance_toÚsumÚmaxÚsortÚdistance_to_with_closest_pointsÚparam_at_pointr   ÚtrimÚsortedÚposition_atÚlengthr   ÚappendÚmake_three_point_arcr   Úedgesr   ÚcombineÚsort_byr   ÚLENGTHr   Ú_add_to_contextÚpending_edgesr   Ú
arc_centerÚradius)!ÚedgeÚinvertÚvoronoi_point_countr1   ÚcontextÚconnected_edgesÚ
edge_groupÚeÚvr-   Úvoronoi_edge_pointsÚpÚnumpy_style_pntsÚ
best_threeÚ	distancesÚdifferencesr(   Úbest_indicesÚvoronoi_circle_centerÚconnected_edges_end_pointsÚmiddle_edge_arc_pointÚconnected_edges_end_paramsÚparamÚcommon_vertex_pointsÚcommon_vertex_paramsÚtrimmed_connected_edgesÚtrimmed_end_pointsÚnew_arcÚother_edgesÚ
face_wiresÚpending_facer"   r.   s!                                  @@r#   r   r   3   sh  ù€ ô8 #.×":Ñ":¸<Ó"H€Gä�dœDÔ!ÜÐ9Ó:Ð:Ü�G˜\¨4Ô0ô 3°4¸×9IÑ9IÓJ€OÜ
ˆ?Ó˜qÒ ÜÐFÓGÐGà�˜/Ñ)€Jñ õáˆAØ—‘Ü.3Ð4GÈ!Ñ4KÔ.LÓMÑ.L¨ˆQÐ$Ó$Ð.LÑMö
ˆAò 	
ð
ð 	
Øð ò ñ -@Ó@Ñ,? q˜Ÿ™˜aŸc™cš
Ð,?ÐÐ@Ü,3Ð4DÓ,E×,NÒ,NÓOÑ,N qœ š
Ð,NÑOÐô 
ˆu‹”s“uÐÜ	ˆu‹”s“uÐÜ	ˆu‹”s“uÐð+€Jô Ð*Ö+‰ˆˆ1Ü;@À¼8ÓD¹8°a�Z ‘]×.Ñ.¨qÕ1¸8ˆ	ÐDÜ˜9“~¨Ñ)ˆÜÓI¹yÓIÓIˆð ˜ B™¨Ñ*Ó*à)¨1Ð-ˆJ�r‰Nà�O‰O¡ˆOÕ/ð ,ñ #-Ó-¡*˜Q�A�a“D *€LÐ-äÓ7©,Ó7¼ÀÀ1Àa»ÓIÈCÑOð ñ !ó"á ˆAð 	
×)Ñ)Ð*?Ó@ÀÓCØ ð ð "ð !×@Ñ@ÐAVÓWØ	ñÐñ Ø 5¸Ñ 9Ð<QÑ QÐô ˜oÔ.ô"á.‰DˆAˆqð 	
×ÑÐ3°AÑ6Õ7Ø.ð ñ "ó ,ˆØ�UÔ ˜SÓ ÜÐEÓFÐFð !ÜÐEÓFÐFð ,ñ
 >MóÙ=L¸ŒÔ)¨$°Ó2Õ3¸_ð ð ô ?HÈÔ>XôÙ>X±d°a¸ˆ×ÑÐ-¨aÑ0Õ1Ð>Xð ñ ô ˜oÔ.ôá.‰DˆAˆqð 	ˆ�‰”˜Ð2°1Ñ5Ñ5Ð7QÐRSÑ7TÐUÓVÒWØ.ð ñ ð ÐÜ�1ŽXˆà# AÑ&×2Ñ2°1Ó5Ø˜aÑ ×,Ñ,¨QÓ/ñ0ç
‰&”9òð ×%Ñ%Ð&=¸aÑ&@×&LÑ&LÈQÓ&OÕPà×%Ñ%Ð&=¸aÑ&@×&LÑ&LÈQÓ&OÕPð ô ×'Ñ'Ø˜1ÑØØ˜1Ñó€Gð ×ÑÐÜ'0£{‰ð ×Ñ×"Ñ"Ó$Ü*¨4Ó0ñ1ä˜˜Óñ ð 	ô —‘Ø 7 )Ñ+¨kÑ9óç�gŒf�m‰m T€gÓ*ð ô ˜
 1™ z°!°" ~Ó6€LàÐØ×Ñ °4ÐÔ8Ü )£ˆÔô �<�.Ó! 7×#5Ñ#5°w·~±~ÐEÐEùòU Nùô	ùò AùÚOùò Eùò .ùò"ùó"ùòùóùó
sN   Á; R:ÂR5Â'R:Â?SÃ7SÅ%SÇSÈSÉSÊS ËS%Ë7-S+Ò5R:Nc                ó¸  — t        j                  d«      }| �t        | «      }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 )a
  Sketch Operation: make_face

    Create a face from the given perimeter edges.

    Args:
        edges (Edge): sequence of perimeter edges. Defaults to all
            sketch pending edges.
        mode (Mode, optional): combination mode. Defaults to Mode.ADD.
    Ú	make_facezNo objects to create a faceúNo objects to create a hullr   r0   )r   r2   r   rP   r4   r   r   r   rL   Ú	normal_atÚZrO   r   r   r   Úwrapped)rK   r1   rV   Úouter_edgesrn   s        r#   rp   rp   Ñ   sÍ   € ô #.×":Ñ":¸;Ó"G€GàÐÜ& uÓ-‰Ø	Ð	Ø×+Ñ+‰äÐ6Ó7Ð7ÙÜÐ6Ó7Ð7Ü�G˜[¨+Ô6äœŸ™ [Ó1°!Ñ4Ó5€LØ×ÑÓ×!Ñ! 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_hullrq   r   r0   )r   r2   r   rP   Úsketch_localÚextendrK   r4   r   r   r   Úmake_convex_hullrr   rs   rO   r   r   r   rt   )rK   r1   rV   Ú
hull_edgesrn   s        r#   rw   rw   ô   só   € ô #.×":Ñ":¸;Ó"G€GàÐÜ% 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                óh  — t        j                  d«      }| �2t        | «      }|D ��cg c]  }|j                  «       D ]  }|‘Œ Œ }}}n|�|j                  }nt        d«      ‚g }|D ]G  }	|	j                  |d«      }
|j                  t        j                  |
|	«      j                  «       «       ŒI |�! |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   r1   r   )r   r2   r   rK   rP   r4   Úperpendicular_linery   r   ÚsweepÚfacesrO   r   r6   Úfuser3   Úlistr   rt   )ÚlinesÚ
line_widthr1   rV   Útrace_linesÚlrY   Útrace_edgesÚ	new_facesrS   Ú	trace_penÚcombined_facesÚresults                r#   r}   r}     s3  € ô* #.×":Ñ":¸7Ó"C€GàÐÜ& uÓ-ˆÙ"-ÔA¡+˜Q°q·w±w¶y°!’q°y�q +ˆÒAØ	Ð	Ø×+Ñ+‰äÐ.Ó/Ð/à€IÛˆØ×+Ñ+¨J¸Ó:ˆ	Ø×ÑœŸ™ I¨tÓ4×:Ñ:Ó<Õ=ð ð ÐØˆ×Ñ Ð6°Ò6Ü )£ˆÔô /2°)«n¸qÒ.@”T—Y‘Y 	Ñ*ÀiÐPQÁl€Nô �n¤dÔ+ô 	ˆ~Óð ð
 €Mô �N×*Ñ*Ó+ð ð
 €Mùó+ Bs   ¨D.)
rS   r
   rT   ÚboolrU   r=   r1   r   Úreturnztuple[Sketch, Vector, float])rK   zEdge | Iterable[Edge] | Noner1   r   r�   r   )rƒ   z:Curve | Edge | Wire | Iterable[Curve | Edge | Wire] | Noner„   r<   r1   r   r�   r   )"Ú__doc__Ú
__future__r   Úcollections.abcr   Úscipy.spatialr   Úbuild123d.build_enumsr   r   Úbuild123d.topologyr   r	   r
   r   r   r   r   r   r   Úbuild123d.geometryr   r   Úbuild123d.build_commonr   r   Úbuild123d.build_sketchr   ÚREPLACEr   ÚADDrp   rw   r}   r'   r*   r#   Ú<module>r™      s  ðñõ: #å $Ý !ß .÷
÷ 
õ 
÷ 1ß DÝ .ð
 Ø"Ø—‘ð	[FØ
ð[Fàð[Fð ð[Fð ð	[Fð
 "ó[Fð~ +/¸T¿X¹Xð 4Ø'ð 4Ø6:ð 4àó 4ðH +/¸T¿X¹Xð#4Ø'ð#4Ø6:ð#4àó#4ðN IMØØ—‘ð.ØEð.àð.ð ð.ð ô	.r*   