
    j@                        d Z ddlZddlmZmZmZ ddlmZ ddl	m
Z
mZ ddlmZ ddlmZmZmZmZmZmZmZ d	efd
Zdee   dedee   fdZ	 	 	 d&d	edededee   deej0                     f
dZd'd	ededee   fdZd(d	ededefdZd)d	edefdZd*d	ededefdZ	 d+d	ededeej*                  eej*                     f   fdZ	 	 d,d	eded ed!efd"Z 	 	 	 d-d	eded#ee   d$ede!f
d%Z"y).z@
segments.py
--------------

Deal with (n, 2, 3) line segments.
    N   )geometrytransformationsutil)tol)
group_rowsunique_rows)union)	ArrayLikeIntegerNDArrayNumberOptionalUnionfloat64segmentsc                    t        j                  | t         j                        } t        j                  | d      st        d| j                        | dddf   }| dddf   |z
  }t        j                  |      }||j                  d      z  }t        j                  ||      }||j                  d      | z  z   }t        j                  |||z   f      }t        j                  |d	      \  }}||j                  d      z  }|||fS )
a6  
    For 3D line segments defined by two points, turn
    them in to an origin defined as the closest point along
    the line to the zero origin as well as a direction vector
    and start and end parameter.

    Parameters
    ------------
    segments : (n, 2, 3) float
       Line segments defined by start and end points

    Returns
    --------------
    origins : (n, 3) float
       Point on line closest to [0, 0, 0]
    vectors : (n, 3) float
       Unit line directions
    parameters : (n, 2) float
       Start and end distance pairs for each line
    dtype)r   )r      zincorrect segment shape!Nr      r   r   T)return_sign)np
asanyarrayr   r   is_shape
ValueErrorshaperow_normreshapediagonal_dotcolumn_stackvector_hemisphere)r   endpointvectorsvectors_normoffsetorigins
parameterssignss           B/DATA/.local/lib/python3.12/site-packages/trimesh/path/segments.pysegments_to_parametersr-      s    * }}XRZZ8H==?33X^^DD 1~Hq!tnx'G==)L|##G,,G x1F&..1WH<=G &&<*?!@AJ++GFNGU%--((JGZ''    r)   r&   r*   c           	         t        j                  | t         j                        } t        j                  |t         j                        }t        j                  |t         j                        }t        j                  | ||ddddf   z  z   | ||ddddf   z  z   f      }|j	                  dd| j
                  d   f      S )a  
    Convert a parametric line segment representation to
    a two point line segment representation

    Parameters
    ------------
    origins : (n, 3) float
       Line origin point
    vectors : (n, 3) float
       Unit line directions
    parameters : (n, 2) float
       Start and end distance pairs for each line

    Returns
    --------------
    segments : (n, 2, 3) float
       Line segments defined by start and end points
    r   Nr   r   r   )r   r   r   hstackr!   r   )r)   r&   r*   r   s       r,   parameters_to_segmentsr1   >   s    , mmG2::6GmmG2::6Gz<J yy	7Z2A2..	.'JqRSRTuDU:U0UVH RGMM!$4566r.   radiusanglelengthreturnc                 (   ddl m} t        |       \  }}}|j                  |      }|j	                  |d      }	t        j                  ||	         }
t        j                  t        j                  |
t        j                  |      t        j                  |
d|            }|	|   }|i|j                  \  }}t        j                  j                  | |   ddg dddf   | |   ddg d	ddf   z
  d
      j                  d      }|||k     }|S )a6  
    Find pairs of segments which are colinear.

    Parameters
    -------------
    segments : (n, 2, (2, 3)) float
      Two or three dimensional line segments
    radius
      Maximum radius line origins can differ
      and be considered colinear
    angle
      Maximum angle in radians segments can
      differ and still be considered colinear
    length
      If specified, will additionally require
      that pairs have a *vertex* within this distance.

    Returns
    ------------
    pairs : (m, 2) int
      Indexes of segments which are colinear
    r   )spatialndarray)routput_typeatol        N)r   r   r   r   )r   r   r   r   r   axisr   )scipyr7   r-   cKDTreequery_pairsr   vector_angler   
logical_orr   isclosepiTlinalgnormmin)r   r2   r3   r4   r7   r)   r&   _paramtreepairsanglesangle_okcolinearab
min_vertexs                   r,   colinear_pairsrT   `   s   8 
  6h?GWf ??7#D v9=E ""75>2F }}VRUU/fcPU1VH
 XH zz1 YY^^QK<*+hqk!\1:L.MMTU $ 

#1#+ 	
 J/0Or.   digitsc                    t        |       \  }}}|j                  d       t        t        j                  ||f      |      }|D cg c]-  }t        ||   ||   dddf   j                            d      / }}t        j                  t        ||      D cg c]  \  }}|dt        |        c}}      }	t        ||	   ||	   t        j                  |            S c c}w c c}}w )	a7  
    Clean up line segments by unioning the ranges of colinear segments.

    Parameters
    ------------
    segments : (n, 2, 2) or (n, 2, 3)
      Line segments in space.
    digits
      How many digits to consider.

    Returns
    -----------
    cleaned : (m, 2, 2) or (m, 2, 3)
      Where `m <= n`
    r   r>   rU   Nr   F)sort)r)   r&   r*   )r-   rX   r   r   r#   r
   argsortconcatenateziplenr1   vstack)
r   rU   r)   r&   paramgroupsgunionsuindexess
             r,   cleanrd      s    & 5X>GWe 
JJAJ '(:;FKF NTTVeE!HU1Xad^3356UCVFTnnc&&6IJ6Idaa#a&k6IJKG " ''*:ryyQWGX  UJs   2C!C&
pointsr<   c           	         t        j                  |t         j                        }t        j                  | t         j                        } | j                  d| j                  d   f      }| dddddf   | dddddf   z
  dz  j                  d      dz  }t        j                  t        |       t              }g }|D ]  }||z
  dz  j                  d      j                  d	      dz  }t        j                  t        j                  ||j                  d      |
      t        j                  |d|
      j                  d             }	|	j                         st        j                  ||	       }| |	   D ].  }
|j                  ||
d   g       |j                  ||
d   g       0  t        |      dkD  rt        j                  | |   |f      S | S )aK  
    Find any points that lie on a segment (not an endpoint)
    and then split that segment into two segments.

    We are basically going to find the distance between
    point and both segment vertex, and see if it is with
    tolerance of the segment length.

    Parameters
    --------------
    segments : (n, 2, (2, 3) float
      Line segments in space
    points : (n, (2, 3)) float
      Points in space
    atol : float
      Absolute tolerance for distances

    Returns
    -------------
    split : (n, 2, (3 | 3) float
      Line segments in space, split at vertices
    r   r   r   Nr   r   r>   g      ?r   r   r;   r=   )r   r   r   r!   r   sumonesr\   boollogical_andr   rE   anyappendr]   )r   re   r<   seg_flatr4   keepnew_segppairon_segsegs              r,   splitru      s   0 ]]64F}}XRZZ8HX^^A%6 78H 1a 8Aq!G#44:??Q?G3NF 773x=-DG 
 A!#((a(088ASH LLq!1=\\$$/333;;
 ::<>>$0D'3q6{+3q6{+ (% , 7|ayy(4.'233r.   c                    t        j                  | t         j                        } t        | j	                  d| j
                  d   f      |      d   j	                  d      }|j                  d       t        j                  t        |       t              }d|t        |      d	   <   d
||ddd	f   |dddf   k(  <   | |   }|S )a;  
    Find unique non-zero line segments.

    Parameters
    ------------
    segments : (n, 2, (2|3)) float
      Line segments in space
    digits : int
      How many digits to consider when merging vertices

    Returns
    -----------
    unique : (m, 2, (2|3)) float
      Segments with duplicates merged
    r   r   r   rW   r   rg   r>   Tr   FN)
r   r   r   r	   r!   r   rX   zerosr\   rj   )r   rU   inversemaskuniques        r,   rz   rz     s      }}XRZZ8H (**Bq0A+BCFS	gg  LLaL88CM.D$(DW	a	 !+0DA'!Q$-	'(d^FMr.   heightdouble_sidedc           	         t        j                  | t         j                        } t        j                  | d      st        d      t        j                  t        j                  | j                  d      d      j                  d      t        j                  d|d|gt        |             f      }t        j                  g dt        |       df      t        j                  t        |             j                  d	      d
z  z   j                  d      }|r*t        j                  |t        j                  |      f      }||fS )a  
    Extrude 2D line segments into 3D triangles.

    Parameters
    -------------
    segments : (n, 2, 2) float
      2D line segments
    height : float
      Distance to extrude along Z
    double_sided : bool
      If true, return 4 triangles per segment

    Returns
    -------------
    vertices : (n, 3) float
      Vertices in space
    faces : (n, 3) int
      Indices of vertices forming triangles
    r   r   r   r   zsegments shape incorrectrg   r   r   )r   r   r   r   r   r   r   r      )r   r   )r   r   r   r   r   r   r#   tiler!   r\   aranger]   fliplr)r   r{   r|   verticesfacess        r,   extruder   5  s    ( }}XRZZ8H==:.344 GGH$$W-q199'BGGQ6*CM:	
H 	"S]A$67
))CM
"
*
*7
3a
7	8gg 

 		5"))E"234U?r.   summedc                     t        j                  | t         j                        } t        j                  | dddddf   | dddddf   z
        }|r|j                         S |S )a3  
    Return the lengths of an array of line segments.

    Parameters
    -------------
    segments : (n, 2, 2) float
      2D line segments
    summed
      Return the total length, not the per-segment length.

    Returns
    -------------
    length
      Either total length or per-segment length.
    r   Nr   r   )r   r   r   r   r    rh   )r   r   normss      r,   r4   r4   a  sU    $ }}XRZZ8HMM(1a7+hq!Qw.??@Eyy{Lr.   maxlenreturn_indexreturn_countc           	         t        |      }t        j                  | t        j                        } t	        | j
                        dk7  rt        | j
                   d      | j
                  d   }| dddf   }| dddf   }||z
  }t        j                  t        j                  |      |z        j                  t        j                        }g }	g }
t        j                  }t        j                  t        j                  |j                         dz               }t        j                   |      D ]  }||k(  }||   |z  } |||dz         j#                  d|f       |t        j                  |dz         t	        |            j#                  d	      z  } |||   |dz         j#                  d|f      }||z   j#                  d|dz   |f      }|	j%                  |dd|d| f          |rwt        j&                  |      d   j#                  d	      }|
j)                  t        j*                  t	        |      |ft        j                        |z  j-                                t.        j0                  sFt3        | |   |      D ]A  \  }}t        j4                  |d   |d         sJ t        j4                  |d   |d         rAJ  t        j4                  t        j                  t        j                  |dz               |d|       rJ  t        j6                  |	      g}	t.        j0                  r/t        j8                  t;        |       t;        |	d         d
      sJ |r}t        j6                  |
      }
t.        j0                  rGt	        |
      t	        |	d         k(  sJ t=        |
      t=        t?        t	        |                   k(  sJ |	j)                  |
       |r|	j)                  |       t	        |	      dk(  r|	d   S |	S )a  
    Resample line segments until no segment
    is longer than maxlen.

    Parameters
    -------------
    segments : (n, 2, 2|3) float
      2D line segments
    maxlen : float
      The maximum length of a line segment
    return_index : bool
      Return the index of the source segment
    return_count : bool
      Return how many segments each original was split into

    Returns
    -------------
    resampled : (m, 2, 2|3) float
      Line segments where no segment is longer than maxlen
    index : (m,) int
      [OPTIONAL] The index of segments resampled came from
    count : (n,) int
      [OPTIONAL] The count of the original segments
    r   r   z != (n, 2, 2|3)r   Nr   r   r   r   gMbP?r;   ) floatr   arrayr   r\   r   r   ceilr   r    astypeint64r   stack_linesr   maxrz   r!   extendnonzerorm   ri   ravelr   strictr[   allcloserZ   rE   r4   setrange)r   r   r   r   	dimensionpt1pt2vecsplitsresultindexr   stacksru   ry   	incrementvopolyindex_originaloriginalrecons                         r,   resampler   z  sh   > 6]Fxx

3H
8>>aHNN+?;<<q!I 1a4.C
1a4.C
)CWWT]]3'&0188BF FE77Dbii

q(89:F 6"I%	EAI&..I?$IIeai #i.C

''
 TEAI&..I?AEAIy9: 	d1fVen,-.ZZ-a088ANLL#d)U+288<~MTTV :: $'x~t#<%{{8A;a999{{8B<r;;; $= ;;t//		%!)0DEvfu~VVVA #F nnV$%F
zzzz&*F6!9,=DIII u%::u:VAY///u:U3x=%9!::::ef
6{aayMr.   matrixmergec           	         t        j                  | d      } t        j                  | d      st	        d      |5t        j                  | j                  d      |      j                  d      } |rt        | |      } dj                  d	d
t        t        |            z   dz         } |t        |       z  j                  | j                          }|S )a  
    Convert (n, 2, 2) line segments to an SVG path string.

    Parameters
    ------------
    segments : (n, 2, 2) float
      Line segments to convert
    digits : int
      Number of digits to include in SVG string
    matrix : None or (3, 3) float
      Homogeneous 2D transformation to apply before export

    Returns
    -----------
    path : str
      SVG path string with one line per segment
      IE: 'M 0.1 0.2 L 10 12'
    T)copyr~   zonly for (n, 2, 2) segments!rg   )r   rW   zM_ _L_ __z{:0.zf})r   r   r   r   r   r   transform_pointsr!   rz   replacestrintr\   formatr   )r   rU   r   r   baser   s         r,   to_svgr     s    0 xxt,H==:.788 "33W%f

'*
 	 (62 c6CF,<#<t#CDD*dS]"**HNN,<=FMr.   ){Gz?r   N)
   )gh㈵>)   )F)T)FF)r   NT)#__doc__numpyr    r   r   r   	constantsr   groupingr   r	   intervalr
   typedr   r   r   r   r   r   r   r-   r1   r   rT   rd   ru   rz   rj   r   r4   r   r   r    r.   r,   <module>r      s    . .  .  Q Q Q*(Y *(Z7W7(17?Fw?O7H #	FFF F V	F
 RXXFR#I #w #8H #L?I ?y ? ?D!Y ! !H)i ) )t )Z )-!%
2::wrzz**+8 	qqq q 	ql "&	+++ Y+ 	+
 	+r.   