o
    :ήc                     @   sB   d dl Zd dlmZ ddlmZ dd Zdd Z			dd
dZ	dS )    N   )_marching_cubes_classic_cyc                 C   s   | j dkr	td|du rd|  |    }nt|}||  k s(||  kr,tdt|dkr6tdtj| tjdd} t	
| t|}t	|\}}t|}t|}t| || |||}|tj|  |fS )	zeLorensen et al. algorithm for marching cubes. See
    marching_cubes_classic for documentation.

       z$Input volume must have 3 dimensions.N      ?z/Surface level must be within volume data range.z'`spacing` must consist of three floats.C)dtypeorder)ndim
ValueErrorminmaxfloatlennparrayfloat64r   iterate_and_store_3dunpack_unique_vertsasarray_correct_mesh_orientationr_)volumelevelspacinggradient_direction	raw_facesvertsfaces r   N/tmp/pip-target-vg8gfxp4/lib/python/skimage/measure/_marching_cubes_classic.py_marching_cubes_classic   s(   


r    c                 C   s   | | }|dddddf |dddddf  }|dddddf |dddddf  }~t ||d jddd  d S )as  
    Compute surface area, given vertices & triangular faces

    Parameters
    ----------
    verts : (V, 3) array of floats
        Array containing (x, y, z) coordinates for V unique mesh vertices.
    faces : (F, 3) array of ints
        List of length-3 lists of integers, referencing vertex coordinates as
        provided in `verts`

    Returns
    -------
    area : float
        Surface area of mesh. Units now [coordinate units] ** 2.

    Notes
    -----
    The arguments expected by this function are the first two outputs from
    `skimage.measure.marching_cubes`. For unit correct output, ensure correct
    `spacing` was passed to `skimage.measure.marching_cubes`.

    This algorithm works properly only if the ``faces`` provided are all
    triangles.

    See Also
    --------
    skimage.measure.marching_cubes
    skimage.measure.marching_cubes_classic

    Nr   r      axisr   g       @)r   crosssum)r   r   actual_vertsabr   r   r   mesh_surface_area1   s
   !,,$r)         ?r+   r+   descentc                 C   s~  t | \}}}|dddddf |dddddf  }|dddddf |dddddf  }	|jddd j}
~t||
}t||
}t||
}t j|||f }|t j|d ddd ddt jf  }t ||	}|t j|d ddd ddt jf  }|| jdd}d|v r|dk 	 d }nd	|v r|dk	 d }nt
d
| | }||dddf ||< |S )aJ	  
    Correct orientations of mesh faces.

    Parameters
    ----------
    volume : (M, N, P) array of doubles
        Input data volume to find isosurfaces. Will be cast to `np.float64`.
    actual_verts : (F, 3, 3) array of floats
        Array with (face, vertex, coords) index coordinates.
    faces : (F, 3) array of ints
        List of length-3 lists of integers, referencing vertex coordinates as
        provided in `verts`.
    spacing : length-3 tuple of floats
        Voxel spacing in spatial dimensions corresponding to numpy array
        indexing dimensions (M, N, P) as in `volume`.
    gradient_direction : string
        Controls if the mesh was generated from an isosurface with gradient
        descent toward objects of interest (the default), or the opposite.
        The two options are:
        * descent : Object was greater than exterior
        * ascent : Exterior was greater than object

    Returns
    -------
    faces_corrected (F, 3) array of ints
        Corrected list of faces referencing vertex coordinates in `verts`.

    Notes
    -----
    Certain applications and mesh processing algorithms require all faces
    to be oriented in a consistent way. Generally, this means a normal vector
    points "out" of the meshed shapes. This algorithm corrects the output from
    `skimage.measure.marching_cubes_classic` by flipping the orientation of
    mis-oriented faces.

    Because marching cubes could be used to find isosurfaces either on
    gradient descent (where the desired object has greater values than the
    exterior) or ascent (where the desired object has lower values than the
    exterior), the ``gradient_direction`` kwarg allows the user to inform this
    algorithm which is correct. If the resulting mesh appears to be oriented
    completely incorrectly, try changing this option.

    The arguments expected by this function are the exact outputs from
    `skimage.measure.marching_cubes_classic` except `actual_verts`, which is an
    uncorrected version of the fancy indexing operation `verts[faces]`.
    Only `faces` is corrected and returned as the vertices do not change,
    only the order in which they are referenced.

    This algorithm assumes ``faces`` provided are exclusively triangles.

    See Also
    --------
    skimage.measure.marching_cubes_classic
    skimage.measure.mesh_surface_area

    Nr   r   r!   r"   g      @r   r,   ascentz:Incorrect input %s in `gradient_direction`, see docstring.)r   gradientr%   Tndimap_coordinatesc_newaxisr$   nonzeror
   copy)r   r&   r   r   r   grad_xgrad_ygrad_zr'   r(   	centroidsgrad_centroids_xgrad_centroids_ygrad_centroids_zgrad_centroidscrossesdotproductsindicesfaces_correctedr   r   r   r   [   sB   <,,
(r   )r*   r,   )
numpyr   scipy.ndimagendimager1    r   r    r)   r   r   r   r   r   <module>   s    ++