
    MikT                         S r SSKrSSKJr  SSKrSSKJr  SSKJrJ	r	J
r
Jr  SSKJr  SSKJr  SS	KJr  SS
KJr  SSKJrJr  SSKJr  SS jrS rS rSS jr   SS jrS rS rSS jr SS jr! " S S\5      r"g)z@
points.py
-------------

Functions dealing with (n, d) points.
    N)sha256)float64   )cachinggroupingtransformationsutil)tol)plane_transform)points_inertia)
Geometry3D)	ArrayLikeNDArray)VertexColorc                     [         R                  " U [        S9n Uc  U nOX-
  n[         R                  " XR                  5      [         R
                  R                  U5      -  nU$ )a(  
The minimum perpendicular distance of a point to a plane.

Parameters
-----------
points : (n, 3) float
  Points in space
plane_normal : (3,) float
  Unit normal vector
plane_origin : (3,) float
  Plane origin in space

Returns
------------
distances : (n,) float
  Distance from point to plane
dtype)np
asanyarrayr   dotTlinalgnorm)pointsplane_normalplane_originw	distancess        h/var/www/eduai.edurigo.com/storigo/production/storigo_env/lib/python3.13/site-packages/trimesh/points.pypoint_plane_distancer       sQ    $ ]]61F!|SS)BIINN<,HHI    c                     [         R                  R                  U 5      u  pn[        R                  " [         R
                  " X#5      5      nU$ )z
Returns an approximate vector representing the major
axis of the passed points.

Parameters
-------------
points : (n, dimension) float
  Points in space

Returns
-------------
axis : (dimension,) float
  Vector along approximate major axis
)r   r   svdr	   unitizer   )r   _USVaxiss        r   
major_axisr)   2   s5     yy}}V$HB1<<q%DKr!   c                    [         R                  " U [        S9n U R                  S:X  d  U R                  S:X  d   eU R                  S:X  a<  U R	                  SS9nXSSS24   -
  n[         R
                  " UR                  U5      nO2U R	                  SS9nXSS2SSS24   -
  nUR                  SS5      U-  n[         R                  R                  U5      S   S   nX4$ )	aH  
Fit a plane to points using SVD.

Parameters
---------
points : (n, 3) float or (p, n, 3,) float
  3D points in space
  Second option allows to simultaneously compute
  p centroids and normals

Returns
---------
C : (3,) float or (p, 3,) float
  Point on the plane
N : (3,) float or (p, 3,) float
  Unit normal vector of plane
r         r   r(   Nr   ).)
r   r   r   ndimmeanr   r   swapaxesr   r#   )r   CxMNs        r   	plane_fitr6   F   s    & ]]61F;;!v{{a///{{aKKQKtQwZFF133N KKQKq$z]"JJq!q 
		aG$A4Kr!   c           	      P   Uc&  US   US   US   * /n[         R                  " X$5      nO[        R                  " X#/5      u  p#[         R                  " S[         R                  " [         R
                  " X#5      5      -
  5      [        R                  :  a  [        S5      e[         R                  " X25      n[         R                  " XB5      nX-
  n[         R                  " [         R
                  " Xd5      [         R
                  " Xe5      5      nXR                  5       SSS2      $ )a  
Sorts a set of points radially (by angle) around an
axis specified by origin and normal vector.

Parameters
--------------
points : (n, 3) float
  Points in space
origin : (3,)  float
  Origin to sort around
normal : (3,)  float
  Vector to sort around
start : (3,) float
  Vector to specify start position in counter-clockwise
  order viewing in direction of normal, MUST not be
  parallel with normal

Returns
--------------
ordered : (n, 3) float
  Same as input points but reordered
Nr   r+   r   z#start must not parallel with normalr.   )r   crossr	   r$   absr   r
   zero
ValueErrorarctan2argsort)r   originnormalstartaxis0axis1vectorsangless           r   radial_sortrE   p   s    4 }F1Iq	z2'f_566!bffRVVF2334sxx?BCC''oGZZw.w0FGF.."4R4())r!   c                 d   [         R                  " [         R                  " U5      [        R                  :  5      (       a  [        S5      eUc  [        X!5      n[        R                  " X5      nUSS2SS[        U5      -
  24   nU(       a"  [         R                  R                  U5      nXg4$ U$ )a  
Project (n, 3) points onto a plane.

Parameters
-----------
points : (n, 3) float
  Points in space.
plane_normal : (3,) float
  Unit normal vector of plane
plane_origin : (3,)
  Origin point of plane
transform : None or (4, 4) float
  Homogeneous transform, if specified, normal+origin are overridden
return_transform : bool
  Returns the (4, 4) matrix used or not
return_planar : bool
  Return (n, 2) points rather than (n, 3) points
zNormal must be nonzero!Nr   r,   )r   allr9   r
   r:   	NameErrorr   r   transform_pointsintr   inv)r   r   r   	transformreturn_transformreturn_planartransformedpolygon_to_3Ds           r   project_to_planerQ      s    6 
vvbff\"SXX-..122#L?	!226EKaa#m*<&<!==>K		i0))r!   c                    SSK Jn  U" U 5      nUR                  USS9n[        R                  " UR                  5       [        U 5      S9nXT   R                  SS9nUR                  5       US[        R                  " [        U5      5      -  -      n[        R                  " [        U 5      [        S	9nS
X'   [        R                  (       a*  U" X   5      n	[        U	R                  U5      5      S:X  d   eX   U4$ )am  
Given an (n, m) array of points return a subset of
points where no point is closer than radius.

Parameters
------------
points : (n, dimension) float
  Points in space
radius : float
  Minimum radius between result points

Returns
------------
culled : (m, dimension) float
  Points in space
mask : (n,) bool
  Which points from the original points were returned
r   cKDTreendarray)output_type)	minlengthr   r-   r+   r   F)scipy.spatialrT   query_pairsr   bincountravellenargmaxarangeonesboolr
   strict)
r   radiusrT   treepairscountcolumnhighestmasktests
             r   remove_closerj      s    & &6?DV;E
 KKV=E
 \  a (F kkmFQ3v;)?%??@G 773v;d+DDM
zzv|$4##F+,111<r!   c                     SSK Jn  SSKJn  [        R
                  " U [        S9n U R                  SS9nSXU[        R                  :  '   X-  nU" Xa40 UD6u  pxXu-  n	U" U	5      n
U
R                  U SS9S   nX4$ )a  
Find k centroids that attempt to minimize the k- means problem:
https://en.wikipedia.org/wiki/Metric_k-center

Parameters
----------
points:  (n, d) float
  Points in space
k : int
  Number of centroids to compute
**kwargs : dict
  Passed directly to scipy.cluster.vq.kmeans

Returns
----------
centroids : (k, d) float
  Points in some space
labels: (n) int
  Indexes for which points belong to which centroid
r   )kmeansrS   r   r-   r   )k)scipy.cluster.vqrl   rX   rT   r   r   r   stdr
   r:   query)r   rm   kwargsrl   rT   
points_stdwhitenedcentroids_whitened_distortion	centroidsrc   labelss               r   k_meansrx      s    * (%]]61F#J()JCHH$%"H&,X&CF&C#"/I 9DZZ!Z$Q'Fr!   c                    [         R                  " U [        S9n [        U R                  5      S:w  a  [        S5      e[        U5      n[         R                  " [        U 5      [        S9nSX!'   [         R                  " [        U 5      [         R                  S9S-
  nXS'   [         R                  " [        U 5      S-
  [        S9n[         R                  " [        U 5      [         R                  S9n[         R                  " U R                  S   5      n[        [        U 5      S-
  5       HQ  nXU      n[         R                  " X   U-
  S-  U5      n	U	R                  5       n
XR   U
   nSX+'   XUS-   '   X   XG'   MS     US-  nX44$ )a9  
Find an ordering of points where each is visited and
the next point is the closest in euclidean distance,
and if there are multiple points with equal distance
go to an arbitrary one.

Assumes every point is visitable from every other point,
i.e. the travelling salesman problem on a fully connected
graph. It is not a MINIMUM traversal; rather it is a
"not totally goofy traversal, quickly." On random points
this traversal is often ~20x shorter than random ordering,
and executes on 1000 points in around 29ms on a 2014 i7.

Parameters
---------------
points : (n, dimension) float
  ND points in space
start : int
  The index of points we should start at

Returns
---------------
traversal : (n,) int
  Ordered traversal visiting every point
distances : (n - 1,) float
  The euclidean distance between points in traversal
r   r+   zpoints must be (n, dimension)!Fr   r   g      ?)r   r   r   r\   shaper;   rJ   r_   r`   zerosint64r^   ranger   argmin)r   r@   	unvisited	traversalr   
index_masksum_onesicurrentdist	min_index	successors               r   tspr     sX   : ]]61F
6<<A9:: JE F40II VBHH59IaLVq8I3v;bhh7J
 wwv||A'H 3v;?#1&
 vvv(72q8(C KKM	))4	$	$!a%	% $* #Ir!   c                    SSK Jn  SSKJn  [        R
                  " U [        S9n [        U R                  5      S:w  a  [        S5      eU R                  S   S:X  a:  UR                  5       nUR                  S	S
S9nUR                  " U R                  6   OEU R                  S   S:X  a  UR                  " U R                  6   O[        SU R                   35      eU(       a  UR                  5         gg)z
Plot an (n, 3) list of points using matplotlib

Parameters
-------------
points : (n, 3) float
  Points in space
show : bool
  If False, will not show until plt.show() is called
r   N)Axes3Dr   r+   zPoints must be (n, 2|3)!r   r,   o   3d)
projectionzpoints not 2D/3D: )matplotlib.pyplotpyplotmpl_toolkits.mplot3dr   r   r   r   r\   rz   r;   figureadd_subplotscatterr   show)r   r   pltr   figaxs         r   plot_pointsr   n  s     $+]]61F
6<<A344||A!jjl__ST_2


FHH	aA	VXX-fll^<==
 r!   c                      \ rS rSrSrS#S jrS rS r\S 5       r	\S 5       r
S	 rS
 r\S\\   4S j5       r\S\4S j5       rS rS r\S 5       r\S 5       r\S 5       r\R0                  S\\   4S j5       r\S\\   4S j5       r\R6                  S\4S j5       r\S 5       r\R6                  S 5       r\S 5       r\R6                  S 5       r\R0                  S 5       r\R0                  S 5       r S r!S r"S#S jr#S  r$S! r%S"r&g)$
PointCloudi  zA
Hold 3D points in an object which can be visualized
in a scene.
Nc                 $   [         R                  " 5       U l        [         R                  " U R                  R                  5      U l        0 U l        Ub  U R                  R                  U5        Xl        SU;   a  Uc  US   n[        X S9U l
        g)z
Load an array of points into a PointCloud object.

Parameters
-------------
vertices : (n, 3) float
  Points in space
colors : (n, 4) uint8 or None
  RGBA colors for each point
metadata : dict or None
  Metadata about points
Nvertex_colors)colorsobj)r   	DataStore_dataCache__hash___cachemetadataupdateverticesr   visual)selfr   r   r   rq   s        r   __init__PointCloud.__init__  sx     &&(
mmDJJ$7$78MM  * !f$O,F ":r!   c                 :    U R                   R                  " U0 UD6$ N)r   __setitem__r   argsrq   s      r   r   PointCloud.__setitem__      }}(($9&99r!   c                 :    U R                   R                  " U0 UD6$ r   )r   __getitem__r   s      r   r   PointCloud.__getitem__  r   r!   c                 .    U R                   R                  $ )z^
Get the shape of the pointcloud

Returns
----------
shape : (2,) int
  Shape of vertex array
)r   rz   r   s    r   rz   PointCloud.shape  s     }}"""r!   c                 2    [        U R                  5      S:H  $ )zg
Are there any vertices defined or not.

Returns
----------
empty : bool
  True if no vertices defined
r   )r\   r   r   s    r   is_emptyPointCloud.is_empty  s     4==!Q&&r!   c                 R   [        SS9n[        R                  " U R                  R                  5      UR                  l        [        R                  " U R
                  5      Ul        [        R                  " U R                  5      Ul        UR                  R                  5         U$ )a6  
Safely get a copy of the current point cloud.

Copied objects will have emptied caches to avoid memory
issues and so may be slow on initial operations until
caches are regenerated.

Current object will *not* have its cache cleared.

Returns
---------
copied : trimesh.PointCloud
  Copy of current point cloud
N)r   )	r   copydeepcopyr   datar   r   r   clear)r   copieds     r   r   PointCloud.copy  sp     T* !MM$**//: dkk2 --6 	r!   c                 6    U R                   R                  5       $ )z\
Get a hash of the current vertices.

Returns
----------
hash : str
  Hash of self.vertices
)r   r   r   s    r   hashPointCloud.hash  s     zz""$$r!   returnc                 6    U R                   R                  5       $ )z
Return a simple array representing this PointCloud
that can be used to identify identical arrays.

Returns
----------
identifier : (9,)
  A flat array of data representing the cloud.
)moment_inertiar[   r   s    r   
identifierPointCloud.identifier  s     ""((**r!   c                     [        U R                  S-  R                  5       R                  [        R
                  5      R                  5       5      R                  5       $ )zN
A hash of the PointCloud's identifier that can be used
to detect duplicates.
g     j@)r   r   roundastyper   r|   tobytes	hexdigestr   s    r   identifier_hashPointCloud.identifier_hash  sE     __s"))+22288<DDF

)+	r!   c                     [         R                  " U R                  5      u  pU R                  U   U l        U R                  b8  [	        U R                  5      [	        U5      :X  a  U R                  U   U l        ggg)z6
Merge vertices closer than tol.merge (default: 1e-8)
N)r   unique_rowsr   r   r\   )r   uniqueinverses      r   merge_verticesPointCloud.merge_vertices  se    
 #..t}}= f- ;;"s4;;'73w<'G++f-DK (H"r!   c                 N    [         R                  " U R                  US9U l        U $ )z
Apply a homogeneous transformation to the PointCloud
object in- place.

Parameters
--------------
transform : (4, 4) float
  Homogeneous transformation to apply to PointCloud
)matrix)r   rI   r   )r   rL   s     r   apply_transformPointCloud.apply_transform  s!     (88yYr!   c                     [         R                  " U R                  R                  SS9U R                  R	                  SS9/5      $ )zr
The axis aligned bounds of the PointCloud

Returns
------------
bounds : (2, 3) float
  Minimum, Maximum verteex
r   r-   )r   arrayr   minmaxr   s    r   boundsPointCloud.bounds+  s<     xx***2DMM4E4E14E4MNOOr!   c                 @    [         R                  " U R                  SS9$ )z{
The size of the axis aligned bounds

Returns
------------
extents : (3,) float
  Edge length of axis aligned bounding box
r   r-   )r   ptpr   r   s    r   extentsPointCloud.extents7  s     vvdkk**r!   c                 4    U R                   R                  SS9$ )z]
The mean vertex position

Returns
------------
centroid : (3,) float
  Mean vertex position
r   r-   )r   r0   r   s    r   centroidPointCloud.centroidC  s     }}!!q!))r!   c                 >    [        U R                  U R                  S9$ )N)r   weights)r   r   r   r   s    r   r   PointCloud.moment_inertiaO  s    T]]DLLIIr!   c                     U R                   R                  S5      nUcF  [        R                  " [	        U R
                  5      [        R                  S9nX R                   S'   U$ U$ )zp
If each point has a specific weight assigned to it.

Returns
-----------
weights : (n,)
  A per-vertex weight.
r   r   )r   getr   r_   r\   r   r   )r   r   r_   s      r   r   PointCloud.weightsS  sN     **..+?773t}}-RZZ@D$(JJy!Kr!   valuesc                     [         R                  " U[         R                  S9nUR                  U R                  S   4:w  a  [	        S5      eXR
                  S'   g)zw
Assign a weight to each point for later computation.

Parameters
-----------
values : (n,)
  Weights for each vertex.
r   r   zWeights must match vertices!r   N)r   r   r   rz   r;   r   r   r   s     r   r   r   e  sG     vRZZ8<<DJJqM++;<< &

9r!   c                 h    U R                   R                  S[        R                  " S[        S95      $ )ze
Vertices of the PointCloud

Returns
------------
vertices : (n, 3) float
  Points in the PointCloud
r   )r   r,   )rz   r   )r   r   r   r{   r   r   s    r   r   PointCloud.verticest  s$     zz~~j"((w*OPPr!   c                     Ub  [        U5      S:X  a&  U R                  R                  R                  SS5      $ [        R
                  " US[        S9U R                  S'   g)zm
Assign vertex values to the point cloud.

Parameters
--------------
values : (n, 3) float
  Points in space
Nr   r   r2   )orderr   )r\   r   r   popr   r   r   r   s     r   r   r     sJ     >S[A-::??&&z488!#vS!P

:r!   c                 .    U R                   R                  $ )zo
Stored per- point color

Returns
----------
colors : (len(self.vertices), 4) np.uint8
  Per- point RGBA color
r   r   r   s    r   r   PointCloud.colors  s     {{(((r!   c                 $    XR                   l        g r   r   )r   r   s     r   r   r     s    $(!r!   c                 p    SSK Jn  U" U R                  R                  [        R
                  5      5      nU$ )z
Return a scipy.spatial.cKDTree of the vertices of the mesh.
Not cached as this lead to observed memory issues and segfaults.

Returns
---------
tree : scipy.spatial.cKDTree
  Contains mesh.vertices
r   rS   )rX   rT   r   viewr   rU   )r   rT   rc   s      r   kdtreePointCloud.kdtree  s)     	*t}}))"**56r!   c                 D    SSK Jn  UR                  U R                  5      $ )z
A convex hull of every point.

Returns
-------------
convex_hull : trimesh.Trimesh
  A watertight mesh of the hull of the points
r   )convex) r   convex_hullr   )r   r   s     r   r  PointCloud.convex_hull  s     	!!$--00r!   c                     SSK Jn  U" U 5      $ )z|
A scene containing just the PointCloud

Returns
----------
scene : trimesh.Scene
  Scene object containing this PointCloud
r   )Scene)scene.scener  )r   r  s     r   scenePointCloud.scene  s     	'T{r!   c                 D    U R                  5       R                  " S0 UD6  g)z8
Open a viewer window displaying the current PointCloud
N )r  r   )r   rq   s     r   r   PointCloud.show  s     	

#F#r!   c                 $    SSK Jn  U" U 4XS.UD6$ )a  
Export the current pointcloud to a file object.
If file_obj is a filename, file will be written there.
Supported formats are xyz
Parameters
------------
file_obj: open writeable file object
  str, file name where to save the pointcloud
  None, if you would like this function to return the export blob
file_type: str
  Which file type to export as.
  If file name is passed this is not required
r   )export_mesh)file_obj	file_type)exchange.exportr  )r   r  r  rq   r  s        r   exportPointCloud.export  s     	14R(R6RRr!   c                 J    SSK Jn  U" U R                  XR                  40 UD6$ )a  
Find the the closest points and associated attributes from this PointCloud.
Parameters
------------
input_points : (n, 3) float
  Input query points
kwargs : dict
  Arguments for proximity.query_from_points
result : proximity.NearestQueryResult
    Result of the query.
r   )query_from_points)	proximityr  r   r   )r   input_pointsrq   r  s       r   rp   PointCloud.query  s!     	1 kkTVTTr!   c                 
   [        UR                  5      [        U R                  5      s=:X  a  S:X  a  O  OS nO[        UR                  5      S:X  a  / SQ/[        UR                  5      -  OUR                  n[        U R                  5      S:X  a  / SQ/[        U R                  5      -  OU R                  n[        R                  " XC45      n[        [        R                  " U R                  UR                  45      US9$ )Nr   )r   r   r      )r   r   )r\   r   r   r   vstackr   )r   otherr   other_colorsself_colorss        r   __add__PointCloud.__add__  s    u||DKK 05A5F u||$)   3u~~#66\\  t{{#q(   3t}}#55[[ 
 YY:;FYYu~~>?
 	
r!   )r   r   r   r   r   r   )NN)'__name__
__module____qualname____firstlineno____doc__r   r   r   propertyrz   r   r   r   r   r   r   strr   r   r   r   r   r   r   cache_decoratorr   r   setterr   r   r   r   r  r  r   r  rp   r  __static_attributes__r	  r!   r   r   r     s   
;8:: 	# 	# 	' 	'>	% 
+GG, 
+ 
+   . 	P 	P 	+ 	+ 	* 	* J 0 J J )  " ^^'i ' ' 	Q 	Q __Q Q 	) 	) ]]) )    1 1$S$U 
r!   r   r   )NFT)r   )T)#r#  r   hashlibr   numpyr   r   r   r   r   r   r	   	constantsr
   geometryr   inertiar   parentr   typedr   r   visual.colorr   r    r)   r6   rE   rQ   rj   rx   r   r   r   r	  r!   r   <module>r1     s~        6 6  % #  % %6('T'*\ 'T0f#LN bBv
 v
r!   