
    l0jN                         d Z ddlZddlZddlmZ ddlmZmZmZm	Z	 ddl
mZ ddlmZ ddlmZ dd	lmZ dd
Zd Zd ZddZ	 	 	 ddZd Zd ZddZddZ G d de          ZdS )z@
points.py
-------------

Functions dealing with (n, d) points.
    N)float64   )cachinggroupingtransformationsutil)tol)plane_transform)
Geometry3D)VertexColorc                     t          j        | t                    } || }n| |z
  }t          j        ||j                  t           j                            |          z  }|S )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        Q/home/wildlama/miniconda3/envs/lam/lib/python3.11/site-packages/trimesh/points.pypoint_plane_distancer      s[    $ ]6111F\!|QS))BINN<,H,HHI    c                     t           j                            |           \  }}}t          j        t          j        ||                    }|S )a  
    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%   /   s;     y}}V$$HB1<q!%%DKr   c                    t          j        | t                    } | j        dk    s| j        dk    sJ | j        dk    r@|                     d          }| |dddf         z
  }t          j        |j        |          }n>|                     d          }| |dddddf         z
  }t          j        d||          }t           j        	                    |          d         d	         }||fS )
a  
    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   zpnd, pnm->pdm).)
r   r   r   ndimmeanr   r   einsumr   r   )r   CxMNs        r   	plane_fitr2   C   s    & ]6111F;!v{a////{aKKQKQtQQQwZF13NN KKQKQqqq$z]"Ioq!,,
	aG$Aa4Kr   c           	      `   |.|d         |d         |d          g}t          j        ||          }nt          j        ||g          \  }}t          j        dt          j        t          j        ||                    z
            t          j        k     rt          d          t          j        ||          }t          j        ||          }| |z
  }t          j	        t          j        ||          t          j        ||                    }| |
                                ddd                  S )a4  
    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_sortrA   m   s   4 }F1Iq	z2''fe_556!bfRVFE2233344sx??BCCC''''voGZw..w0F0FGGF&..""44R4())r   FTc                 `   t          j        t          j        |          t          j        k               rt          d          |t          ||          }t          j        | |          }|ddddt          |          z
  f         }|r#t           j
                            |          }||fS |S )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   allr5   r	   r6   	NameErrorr
   r   transform_pointsintr   inv)r   r   r   	transformreturn_transformreturn_planartransformedpolygon_to_3Ds           r   project_to_planerM      s    6 
vbf\""SX-.. 31222#L,??	!269EEKaaaa#m*<*<&<!==>K *	i00M))r   c                 j   ddl m}  ||           }|                    |d          }t          j        |                                t          |                     }||                             d          }|                                |dt          j        t          |                    z  z            }t          j	        t          |           t          	          }d
||<   t          j        r9 || |                   }	t          |	                    |                    dk    sJ | |         |fS )a  
    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.spatialrP   query_pairsr   bincountravellenargmaxarangeonesboolr	   strict)
r   radiusrP   treepairscountcolumnhighestmasktests
             r   remove_closerf      s!   & &%%%%%76??DV;;E
 KV===E
 5\  a ((F kkmmFQ3v;;)?)?%??@G 73v;;d+++DDM
z 2wvd|$$4##F++,,1111$<r   c                 (   ddl m} ddlm} t	          j        | t                    } |                     d          }d||t          j	        k     <   | |z  } |||fi |\  }}||z  }	 ||	          }
|

                    | d          d         }|	|fS )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   )kmeansrO   r   r)   r   )k)scipy.cluster.vqrh   rT   rP   r   r   r   stdr	   r6   query)r   ri   kwargsrh   rP   
points_stdwhitenedcentroids_whitened_distortion	centroidsr_   labelss               r   k_meansrt      s    * ('''''%%%%%%]6111F##J()JzCH$%
"H&,fXq&C&CF&C&C#"Z/I 79DZZ!Z$$Q'Ffr   c                 ~   t          j        | t                    } t          | j                  dk    rt          d          t          |          }t          j        t          |           t                    }d||<   t          j	        t          |           t           j
                  dz
  }||d<   t          j	        t          |           dz
  t                    }t          j        t          |           t           j
                  }t          j        | j        d                   }t          t          |           dz
            D ]k}| ||                  }t          j        | |         |z
  dz  |          }	|	                                }
||         |
         }d||<   |||dz   <   |	|
         ||<   l|dz  }||fS )a  
    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   rX   shaper7   rF   r[   r\   zerosint64rZ   ranger   argmin)r   r<   	unvisited	traversalr   
index_masksum_onesicurrentdist	min_index	successors               r   tspr     s   : ]6111F
6<A9::: JJE F4000IIe VBH5559IIaLVq888I3v;;bh777J
 wv|A''H 3v;;?## ' '1&
 vvi(72q8(CC KKMM	y))4	$	)$	!a%I	! #Iir   c                    ddl m} ddlm} t	          j        | t                    } t          | j                  dk    rt          d          | j        d         dk    r;|
                                }|                    d	d
          } |j        | j          n8| j        d         dk    r |j        | j          nt          d| j                   |r|                                 dS dS )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   rX   rv   r7   figureadd_subplotscatterr   show)r   r   pltr   figaxs         r   plot_pointsr   k  s    $#####++++++]6111F
6<A3444|A!jjll__ST_22
FH	aA		VX<fl<<=== 




 r   c                   ~   e Zd ZdZddZd Zd Zed             Zed             Z	d Z
d	 Zd
 Zd Zd Zed             Zed             Zed             Zed             Zej        d             Zed             Zej        d             Zej        d             Zej        d             Zd Zd ZddZd Zd ZdS )
PointCloudzM
    Hold 3D points in an object which can be visualized
    in a scene.
    Nc                    t          j                    | _        t          j        | j        j                  | _        i | _        || j                            |           || _        d|v r
||d         }t          ||           | _
        dS )a2  
        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   rm   s        r   __init__zPointCloud.__init__  s     &((
mDJ$788M  *** !f$$O,F "T:::r   c                 &     | j         j        |i |S N)r   __setitem__r   argsrm   s      r   r   zPointCloud.__setitem__      (t}($9&999r   c                 &     | j         j        |i |S r   )r   __getitem__r   s      r   r   zPointCloud.__getitem__  r   r   c                     | j         j        S )z
        Get the shape of the pointcloud

        Returns
        ----------
        shape : (2,) int
          Shape of vertex array
        )r   rv   r   s    r   rv   zPointCloud.shape  s     }""r   c                 2    t          | j                  dk    S )z
        Are there any vertices defined or not.

        Returns
        ----------
        empty : bool
          True if no vertices defined
        r   )rX   r   r   s    r   is_emptyzPointCloud.is_empty  s     4=!!Q&&r   c                     t          d          }t          j        | j        j                  |j        _        t          j        | j                  |_        t          j        | j                  |_        |j                                         |S )a  
        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   zPointCloud.copy  ss     T*** !M$*/:: dk22 -66 	r   c                 4    | j                                         S )z
        Get a hash of the current vertices.

        Returns
        ----------
        hash : str
          Hash of self.vertices
        )r   r   r   s    r   hashzPointCloud.hash  s     z""$$$r   c                 4    | j                                         S )z
        Get a CRC hash of the current vertices.

        Returns
        ----------
        crc : int
          Hash of self.vertices
        )r   crcr   s    r   r   zPointCloud.crc  s     z~~r   c                     t          j        | j                  \  }}| j        |         | _        | j        9t	          | j                  t	          |          k    r| j        |         | _        dS dS dS )zF
        Merge vertices closer than tol.merge (default: 1e-8)
        N)r   unique_rowsr   r   rX   )r   uniqueinverses      r   merge_verticeszPointCloud.merge_vertices   sn    
 #.t}== f- ;"s4;'7'73w<<'G'G+f-DKKK #"'G'Gr   c                 F    t          j        | j        |          | _        | S )z
        Apply a homogeneous transformation to the PointCloud
        object in- place.

        Parameters
        --------------
        transform : (4, 4) float
          Homogeneous transformation to apply to PointCloud
        )matrix)r   rE   r   )r   rH   s     r   apply_transformzPointCloud.apply_transform  s"     (8yYYYr   c                     t          j        | j                            d          | j                            d          g          S )z
        The axis aligned bounds of the PointCloud

        Returns
        ------------
        bounds : (2, 3) float
          Minimum, Maximum verteex
        r   r)   )r   arrayr   minmaxr   s    r   boundszPointCloud.bounds  s?     x***22DM4E4E14E4M4MNOOOr   c                 8    t          j        | j        d          S )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   extentszPointCloud.extents'  s     vdk****r   c                 8    | j                             d          S )z
        The mean vertex position

        Returns
        ------------
        centroid : (3,) float
          Mean vertex position
        r   r)   )r   r,   r   s    r   centroidzPointCloud.centroid3  s     }!!q!)))r   c                 j    | j                             dt          j        dt                              S )z
        Vertices of the PointCloud

        Returns
        ------------
        vertices : (n, 3) float
          Points in the PointCloud
        r   )r   r(   )rv   r   )r   getr   rw   r   r   s    r   r   zPointCloud.vertices?  s)     z~~j"(w*O*O*OPPPr   c                     |t          |          dk    r | j        j                            dd          S t	          j        |dt                    | j        d<   dS )z
        Assign vertex values to the point cloud.

        Parameters
        --------------
        values : (n, 3) float
          Points in space
        Nr   r   r.   )orderr   )rX   r   r   popr   r   r   )r   valuess     r   r   zPointCloud.verticesK  sV     >S[[A--:?&&z4888!#vS!P!P!P
:r   c                     | j         j        S )z
        Stored per- point color

        Returns
        ----------
        colors : (len(self.vertices), 4) np.uint8
          Per- point RGBA color
        r   r   r   s    r   r   zPointCloud.colorsY  s     {((r   c                     || j         _        d S r   r   )r   r   s     r   r   zPointCloud.colorse  s    $(!!!r   c                 l    ddl m}  || j                            t          j                            }|S )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   rO   )rT   rP   r   viewr   rQ   )r   rP   r_   s      r   kdtreezPointCloud.kdtreei  s<     	*)))))wt}))"*5566r   c                 B    ddl m} |                    | j                  S )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   zPointCloud.convex_hullz  s,     	!!$-000r   c                 $    ddl m}  ||           S )z
        A scene containing just the PointCloud

        Returns
        ----------
        scene : trimesh.Scene
          Scene object containing this PointCloud
        r   )Scene)scene.scener   )r   r   s     r   scenezPointCloud.scene  s$     	'&&&&&uT{{r   c                 D     |                                  j        di | dS )zH
        Open a viewer window displaying the current PointCloud
        N )r   r   )r   rm   s     r   r   zPointCloud.show  s+     	

##F#####r   c                 &    ddl m}  || f||d|S )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   rm   r   s        r   exportzPointCloud.export  s5     	100000{4R(iRR6RRRr   c                 8    ddl m}  || j        || j        fi |S )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_pointsrm   r   s       r   rl   zPointCloud.query  s7     	100000  dkTTVTTTr   c                    t          |j                  t          | j                  cxk    rdk    rn nd }nt          |j                  dk    rg dgt          |j                  z  n|j        }t          | j                  dk    rg dgt          | j                  z  n| j        }t          j        ||f          }t          t          j        | j        |j        f          |          S )Nr   )r   r   r      )r   r   )rX   r   r   r   vstackr   )r   otherr   other_colorsself_colorss        r   __add__zPointCloud.__add__  s   u|DK 0 05555A55555FF u|$$))   3u~#6#666\  t{##q((   3t}#5#555[ 
 Y\:;;FYu~>??
 
 
 	
r   )NN)__name__
__module____qualname____doc__r   r   r   propertyrv   r   r   r   r   r   r   r   r   r   r   setterr   r   cache_decoratorr   r   r   r   r   rl   r   r   r   r   r   r     s0        
; ; ; ;8: : :: : : 	# 	# X	# 	' 	' X	'  >	% 	% 	%	  	  	 . . .   	P 	P X	P 	+ 	+ X	+ 	* 	* X	* 	Q 	Q X	Q _Q Q _Q 	) 	) X	) ]) ) ])     1 1 1  $ $ $S S S S$U U U 
 
 
 
 
r   r   r   )NFT)r   )T)r   r   numpyr   r   r   r   r   r   r   	constantsr	   geometryr
   parentr   visual.colorr   r   r%   r2   rA   rM   rf   rt   r   r   r   r   r   r   <module>r     s               6 6 6 6 6 6 6 6 6 6 6 6       % % % % % %       % % % % % %   6  (' ' 'T'* '* '* '*\ ' ' ' 'T0 0 0f# # #LN  N  N  N b   @E
 E
 E
 E
 E
 E
 E
 E
 E
 E
r   