
    j	1                         d dl Z d dlZd dlZddlmZ ddlmZ ddlmZ	 ddl
mZ ddlmZmZ dd	Zdd
Zd ZddZddZddZddZy)    N   )util)log)tol_path)fit_nsphere   )arcentitiesc                    t        |       dk  ryt        j                  | t        j                        } t	        | |      \  }}}t
        j                  ||z  cxk  rt
        j                  k  sn |rt        j                  d||z         y||z  }|t
        j                  kD  r"|rt        j                  dt        |             yt        j                  | d      }	t        j                  |	      }
|
|z  }|t
        j                  kD  j!                         r"|rt        j                  d	t        |             y|rD|t
        j"                  kD  j%                         dk  r t        j                  d
t        |             y|
|z  }|t
        j&                  kD  j!                         r"|rt        j                  dt        |             y| ddg   |	ddg   dz  z   }t        j(                  ||z
        }t        j(                  |	ddg         }t        j*                  t        j,                  t        j.                  ||                  }t        j*                  |t        j0                  dz  z
        j3                         }|t
        j4                  kD  r,|r)t        j                  dt        j6                  |             y||d}|S )a?  
    Fit a circle, and reject the fit if:
    * the radius is larger than tol.radius_min*scale or tol.radius_max*scale
    * any segment spans more than tol.seg_angle
    * any segment is longer than tol.seg_frac*scale
    * the fit deviates by more than tol.radius_frac*radius
    * the segments on the ends deviate from tangent by more than tol.tangent

    Parameters
    ---------
    points :  (n, d)
      List of points which represent a path
    prior :  (center, radius) tuple
      Best guess or None if unknown
    scale : float
      What is the overall scale of the set of points
    verbose : bool
     Output log.debug messages for the reasons
     for fit rejection only suggested for manual debugging

    Returns
    -----------
    if fit is acceptable:
        (center, radius) tuple
    else:
        None
       Ndtype)priorzcircle fit error: R %fzcircle fit error: fit %sr   axiszcircle fit error: angle %szfinal: angle %szcircle fit error: segment %sg      ?r   zcircle fit error: tangent %f)centerradius)lennp
asanyarrayfloat64r   tol
radius_min
radius_maxr   debugradius_fracstrdiffr   row_norm	seg_angleanyseg_angle_minsumseg_fracunitizeabsarccosdiagonal_dotpimaxtangentdegrees)pointsscaler   finalverboseCRr_deviationr_errorvectorssegmentanglescaledmid_ptradialendsr-   results                     B/DATA/.local/lib/python3.12/site-packages/trimesh/path/simplify.pyfit_circle_checkr@      s/   : 6{Q]]64F $F%8Aq+ >>QY8#..8II.E	: AoG II0#g,?ggf1%GmmG$G aKE""$II2CJ?%#+++002Q6		#SZ0 u_F""$II4c&kB QG_B 03 67F\\&1*%F<<B()DffRYYt00>?@GffWruuqy()--/GII4bjj6IJQ'FM    c                    t        j                  |       } t        |      }t         j                  j	                  | d   | d   z
        t
        j                  kD  ryt        j                  | d      }t        j                  | }t        j                  |dz
        t
        j                  kD  ryt        | |      }|yt        j                  di |}|S )a  
    Given a set of points, quickly determine if they represent
    a circle or not.

    Parameters
    -------------
    points : (n,2 ) float
      Points in space
    scale : float
      Scale of overall drawing
    verbose : bool
      Print all fit messages or not

    Returns
    -------------
    control: (3,2) float, points in space, OR
              None, if not a circle
    r   r   Nr         ?r0    )r   r   floatlinalgnormr   mergeptpdivider(   aspect_fracr@   r	   to_threepoint)r/   r0   r2   boxaspectCRcontrols          r?   	is_circlerR   h   s    * ]]6"F%LE 
yy~~fQi&*,-		9
&&a
 C YY_F	vvfslcoo- 
&	.B	z %"%GNrA   c                    t        j                  | t         j                        } t        |      }t	        | j
                        dk7  s| j
                  d   dk7  rt        d      t	        |       dk  r| j                         S | dd | dd z
  }t        j                  |      }|t        j                  kD  }t        j                  | d   | dd |   f      } ||   }||   }| dd | dd	 z
  j                  ddd   j                  }|dddfxx   dz  cc<   t        j                  |      }|t        j                  kD  }||xx   ||   j                  d
      z  cc<   t        j                  t        j                   ||dd             }t        j"                  ||dd z  ||dd z  fd      }	t        j$                  t	        |       t&              }
d|
dd |	d|z  k  <   | |
   }|S )ar  
    Given a set of points representing a path in space,
    merge points which are colinear.

    Parameters
    ----------
    points : (n, dimension) float
      Points in space
    scale : float
      Scale of drawing for precision

    Returns
    ----------
    merged : (j, d) float
      Points with colinear and duplicate
      points merged, where (j < n)
    r   r   r   zonly for 2D points!r   Nr   r   r   r   r   r   Fg-C6?)r   r   r   rF   r   shape
ValueErrorcopyr   r!   r   rI   vstackTreshaper(   r*   r,   onesbool)r/   r0   	directiondirection_normdirection_okperp	perp_normperp_nonzero
projectionprojection_ratiomaskmergeds               r?   merge_colinearrg      s   $ ]]64F%LE
6<<AaA!5.// 6{Q{{} qr
VCR[(I]]9-N!CII-L YYq	6!":l#;<=F,'I#L1N 12J$''"-//DAJ"Jd#Isyy(L)L199'BB ))$	#2?@Jvv	nQR(	(*~cr7J*JKRS 773v;d+D27D2J$,./D\FMrA   c                    ddl m}m} |t        |       }t	        j
                  |       } t        j                  j                  | d   | d   z
        t        j                  k  } || j                  ||      d   }t	        j                  dd|      }t	        j                   |||            }	|r!|	ddg   j                  d      }
|
|	d<   |
|	d<   |	S )a  
    Resample a path in space, smoothing along a b-spline.

    Parameters
    -----------
    points : (n, dimension) float
      Points in space
    smooth : float
      Smoothing distance
    count :  int or None
      Number of samples desired in output
    degree : int
      Degree of spline polynomial

    Returns
    ---------
    resampled : (count, dimension) float
      Points in space
    r   )splevsplprepr   )skg        rC   r   )scipy.interpolateri   rj   r   r   r   rG   rH   r   rI   rY   linspacecolumn_stackmean)r/   smoothcountdegreeri   rj   closedtpli	resampledshareds              r?   resample_splinery      s    ( 1}F]]6"FYY^^F1Ir
23cii?F
&((f
/
2C
Ce$Aa.IAr7#((a(0	!	"rA   c                    ddl m} |t        |       }|d}t        j                  | t        j
                        } t        j                  j                  | d   | d   z
        t        j                  k  } || j                  |      d   \  }}}t        j                  |      }t        j                  t        |            }|r'|ddg   j                  d      |d<   |dd }|d   |d<   t        j                  |||	      }	|	|fS )
a  
    Create a spline entity from a curve in space

    Parameters
    -----------
    points : (n, dimension) float
      Points in space
    smooth : float
      Smoothing distance
    count :  int or None
      Number of samples desired in result

    Returns
    ---------
    entity : entities.BSpline
      Entity object with points indexed at zero
    control : (m, dimension) float
      New vertices for entity
    r   )rj   NgMb`?r   r   )rk   r   )r/   knotsrt   )rm   rj   r   r   r   r   rG   rH   r   rI   rY   	transposearangerp   r
   BSpline)
r/   rq   rr   rj   rt   r{   rQ   _degreeindexentitys
             r?   points_to_spline_entityr      s    * *}F~]]64FYY^^F1Ir
23cii?F%fhh&9!<E7Gll7#GIIc'l#EaW%***2
#2,!Hb	U%GF7?rA   c           	         t        d | j                  D              rt        j                  d       | S t	        j
                  | j                        }t        j                         }t        j                         }| j                  }| j                  D ]  }t        ||      }|W|j                  t        j                  t        j                  d      t!        |      z   d             |j#                  |       it%        ||      }	t        j                  t!        |	            t!        |      z   }
|
d   |
d<   |j                  t        j&                  |
	             |j#                  |	         t)        |       ||t	        j
                  | j*                        |
      }|j,                  j/                  t        j                  t!        |            j1                  d      t        j2                  t!        |      t4              t        j6                  g       d       d|j,                  v r|j,                  j9                  d       ||_        |j                  j;                          |S )a  
    Merge colinear segments and fit circles.

    Parameters
    -----------
    drawing : Path2D
      Source geometry, will not be modified

    Returns
    -----------
    simplified : Path2D
      Original path but with some closed line-loops converted to circles
    c              3   N   K   | ]  }|j                   j                  d k7    yw)LineN)	__class____name__).0r   s     r?   	<genexpr>z!simplify_basic.<locals>.<genexpr>;  s$     
N=M66$$.=Ms   #%z3Skipping path containing entities other than `Line`rD   r   Tr/   rt   r   r   )r/   )r
   verticesmetadataprocessrT   r   )paths
path_validdanglingbounds)r#   r
   r   r   rW   deepcopy_cachecollectionsdequer0   discreterR   appendArcr   r}   r   extendrg   r   typer   cacheupdaterZ   r[   r\   arraypopid_set)drawingr   kwargsr   vertices_newentities_newr0   r   circler/   indexes
simplifieds               r?   simplify_basicr   ,  s    
NW=M=M
NN		GH MM'..)E $$&L$$&L MME $$851 BIIaL3|3D$DTR ' $HE:FiiF,s</@@G!!*GBKW =>') %. gw//0	J 
KKYYs<0199'B''#l"34@	
 5;;!JrA   c           	         g }g }| j                   }| j                  D ]  }t        |||      }|W|j                  t	        j
                  t        j                  d      t        |      z   d             |j                  |       jt        ||      \  }}	|xj                  t        |      z  c_        |j                  |	       |j                  |         t        |       ||      }
|
S )aJ  
    Replace discrete curves with b-spline or Arc and
    return the result as a new Path2D object.

    Parameters
    ------------
    path : trimesh.path.Path2D
      Input geometry
    smooth : float
      Distance to smooth

    Returns
    ------------
    simplified : Path2D
      Consists of Arc and BSpline entities
    )r0   r2   r   Tr   )rq   )r
   r   )r0   r   rR   r   r
   r   r   r}   r   r   r   r/   r   )pathrq   r2   new_verticesnew_entitiesr0   r   r   r   r   r   s              r?   simplify_spliner   ~  s    $ LLJJEMM85'B BIIaL3|3D$DTR ' 38FK\**H%F## "( d\LIJrA   )NFF)F)gMbP?Nr   )NN)NF)r   rW   numpyr    r   	constantsr   r   r   nspherer   r	   r
   r@   rR   rg   ry   r   r   r   rE   rA   r?   <module>r      sH         ' ! Xv+\?D$N*ZOd,rA   