
    ^j?                         d Z ddlmZ ddlmZ ddlmZmZ ddlZ	ddl
mZ ddlmZ erddlmZ  G d	 d
e      Zdee	j$                     dee	j&                     ddfdZ G d d      Zy)z0Python module to interface with wrapped meshfix.    )	find_spec)Path)TYPE_CHECKINGAnyN)NDArray)_meshfixPolyDatac                         e Zd Zd fd	Z xZS )InvalidMeshFixInputErrorc                 ,    |d}t         |   |       y )NzInvalid input. Please input a surface mesh, vertex and face arrays, or a file name. Note that pyvista is required when loading anything other than arrays.)super__init__)selfmessage	__class__s     J/opt/ringagent/.cad-venv/lib/python3.12/site-packages/pymeshfix/meshfix.pyr   z!InvalidMeshFixInputError.__init__   s!    ? 
 	!    )N)__name__
__module____qualname__r   __classcell__)r   s   @r   r   r      s    " "r   r   pointsfacesreturnr
   c                    t        d      t        d      ddlm} ddlm} ddlm} ddlm	} |j                  dk7  rt        d	       |       }| |_         |       j                         }t        j                  d|j                   d
z   |j"                  d
   t        j$                        } ||d|      }	 ||j'                         d|      }
 |       }|j)                  |	|
       |j+                  |       |S )a  
    Generate a polydata from a faces array containing no padding and all triangles.

    Parameters
    ----------
    points : np.ndarray
        Points array.
    faces : np.ndarray
        ``(n, 3)`` faces array.

    Returns
    -------
    PolyData
        New mesh.

    pyvista.corezCTo use this feature install pyvista with:

    `pip install pyvistar   r	   )numpy_to_vtk)vtkTypeInt32Array)vtkCellArray   z&Expected a two dimensional face array.   )dtypeF)deep
array_type)r   ModuleNotFoundErrorpyvista.core.pointsetr
   vtkmodules.util.numpy_supportr   vtkmodules.vtkCommonCorer   vtkmodules.vtkCommonDataModelr    ndim
ValueErrorr   GetDataTypenparangesizeshapeint32ravelSetDataSetPolys)r   r   r
   r   r   r    pdata	vtk_dtypeoffset
offset_vtk	faces_vtkcarrs               r   _polydata_from_facesr<      s    "  (!S
 	
 /:::zzQABBJEEL "#//1IYYq%**q.%++a.IFf5YGJU[[]9MI>DLLY'	NN4Lr   c                      e Zd ZdZdddefdZedefd       Zde	e
j                     d	e	e
j                     dd
fdZdee	e
j                     e	e
j                     f   fdZed$d       Zd$dZede	e
j                     fd       Zede	e
j                     fd       Zd%dedefdZ	 	 d&dededd
fdZd'dededefdZd(dZd(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fd!Zd%d"eez  fd#Zy
)+MeshFixa  Clean and tetrahedralize surface meshes using MeshFix.

    Parameters
    ----------
    args : pyvista.PolyData | (np.ndarray, np.ndarray) | pathlib.Path | str
        Either a pyvista surface mesh :class:`pyvista.PolyData` or a ``n x 3``
        vertex array and ``n x 3`` face array (indices of the triangles). Also
        supports reading directly from a file.
    verbose : bool, default: False
        Set this to ``True`` to enable additional output from MeshFix.

    Examples
    --------
    Create a meshfix object from a pyvista mesh.

    >>> from pyvista import examples
    >>> from pymeshfix import MeshFix
    >>> cow = examples.download_cow()
    >>> mfix = MeshFix(cow)

    Create a meshfix object from two numpy arrays. This example is incomplete
    as it does not contain the entire array.

    >>> import numpy as np
    >>> points = np.array(
    ...     [
    ...         [3.71636, 2.343387, 0.0],
    ...         [4.126565, 0.642027, 0.0],
    ...         [3.454971, 2.169877, 0.0],
    ...         ...,
    ...         [4.12616, 2.12093, 1.17252],
    ...         [4.133175, 2.175231, 1.259323],
    ...         [4.232341, 1.903079, 0.534362],
    ...     ],
    ...     dtype=float32,
    ... )
    >>> faces = np.array(
    ...     [
    ...         [210, 252, 251],
    ...         [250, 251, 252],
    ...         [201, 253, 210],
    ...         ...,
    ...         [1965, 2193, 2194],
    ...         [2391, 2398, 970],
    ...         [966, 961, 970],
    ...     ]
    ... )
    >>> mfix = MeshFix(points, faces)

    F)verboser?   c                   t        j                         | _        | j                  j                  |        t	        |      dk(  r
t               t        |d   t        j                        rOt	        |      dk7  st        |d   t        j                        st        d      | j                  |d   |d          yt        d      
t               ddlm} t        |d   |j                        r|j                  |d         }nft        |d   t         t"        f      rB|j%                  |d         }t        ||j                        s#t        dt'        |       d      t        d	      |j(                  j+                  t        j,                  d
      }|j.                  s|j1                         }|j2                  j5                  dd      j+                  t        j6                  d
      }| j                  ||       y)zInitialize meshfix.r   r!   r"   z?If first argument is an array, second argument must be an arrayr   Nz:Expected to load a `pyvista.PolyData` from file, but got ``z\Invalid input. Please input a pyvista.PolyData, vertex and face arrays, or a path to a file.Fcopy   )r   PyTMesh_mfix	set_quietlenr   
isinstancer.   ndarray	TypeErrorload_arraysr   pyvista.corecorer
   wrapr   strreadtyper   astypefloat64is_all_trianglestriangulate_connectivity_arrayreshaper2   )r   r?   argspvmeshvfs          r   r   zMeshFix.__init__~   s    %%'


[)t9>*,,d1grzz*4yA~ZQ%D abbT!Wd1g.(0.00%$q'2;;/wwtAw'DGdC[1wwtAw'!$42TUYZ^U_T``ab  /+  ""2::E":A (('')((00Q7>>rxxe>TAQ"r   r   c                 .    | j                   j                  S )z5Return the number of boundaries (holes) in this mesh.)rG   n_boundariesr   s    r   r`   zMeshFix.n_boundaries   s     zz&&&r   r]   r^   Nc                     | j                   j                  |j                  t        j                  d      |j                  t        j
                  d             y)a  
        Load triangular mesh from vertex and face numpy arrays.

        Both vertex and face arrays should be 2D arrays with each vertex
        containing XYZ data and each face containing three points.

        Parameters
        ----------
        v : np.ndarray[np.float64]
            ``(n, 3)`` vertex array.
        f : np.ndarray[np.int32]
            ``(m, 3)`` face array.

        Examples
        --------
        Create a meshfix object from two numpy arrays. This example is incomplete
        as it does not contain the entire array.

        >>> from pymeshfix import MeshFix
        >>> import numpy as np
        >>> points = np.array(
        ...     [
        ...         [3.71636, 2.343387, 0.0],
        ...         [4.126565, 0.642027, 0.0],
        ...         [3.454971, 2.169877, 0.0],
        ...         ...,
        ...         [4.12616, 2.12093, 1.17252],
        ...         [4.133175, 2.175231, 1.259323],
        ...         [4.232341, 1.903079, 0.534362],
        ...     ],
        ...     dtype=float32,
        ... )
        >>> faces = np.array(
        ...     [
        ...         [210, 252, 251],
        ...         [250, 251, 252],
        ...         [201, 253, 210],
        ...         ...,
        ...         [1965, 2193, 2194],
        ...         [2391, 2398, 970],
        ...         [966, 961, 970],
        ...     ]
        ... )
        >>> mfix = MeshFix(points, faces)

        FrB   N)rG   
load_arrayrT   r.   rU   r2   )r   r]   r^   s      r   rM   zMeshFix.load_arrays   s?    ^ 	

HHRZZeH,HHRXXEH*	
r   c                 6    | j                   j                         S )z
        Return the arrays from the mesh fix instance.

        Returns
        -------
        np.ndarray[np.float64]
            Array of points shaped ``(n, 3)``.
        np.ndarray[np.float64]
            Array of faces shaped ``(m, 3)``.

        )rG   return_arraysra   s    r   _return_arrayszMeshFix._return_arrays   s     zz''))r   c                 B    t        | j                  | j                        S )aY  
        Return the surface mesh.

        Returns
        -------
        pyvista.PolyData
            Surface mesh as a PolyData object.

        Examples
        --------
        Create a meshfix object from a pyvista mesh.

        >>> from pyvista import examples
        >>> from pymeshfix import MeshFix
        >>> cow = examples.download_cow()
        >>> mfix = MeshFix(cow)
        >>> mfix.mesh
        PolyData (0x7fa3c735f8e0)
          N Cells:    5804
          N Points:   2903
          N Strips:   0
          X Bounds:   -4.446e+00, 5.998e+00
          Y Bounds:   -3.637e+00, 2.760e+00
          Z Bounds:   -1.701e+00, 1.701e+00
          N Arrays:   0

        Access the underlying mesh and plot it.

        >>> mfix.mesh.plot()

        Access the underlying mesh and export it.

        >>> mfix.mesh.save("my_mesh.ply")

        )r<   r   r   ra   s    r   r\   zMeshFix.mesh   s    J $DKK<<r   c                 >    | j                   j                  ddd      S )zPExtract the boundaries of the holes in this mesh to a new PyVista mesh of lines.TF)boundary_edgesfeature_edgesmanifold_edges)r\   extract_feature_edgesra   s    r   extract_holeszMeshFix.extract_holes  s%    yy..uU / 
 	
r   c                 6    | j                   j                         S )a"  
        Return the points of the mesh.

        Returns
        -------
        numpy.ndarray
            The points of the mesh.

        Examples
        --------
        Generate a MeshFix object and return the points.

        >>> from pyvista import examples
        >>> from pymeshfix import MeshFix
        >>> cow = examples.download_cow()
        >>> mfix = MeshFix(cow)
        >>> mfix.points
        pyvista_ndarray([[3.71636 , 2.343387, 0.      ],
                         [4.126565, 0.642027, 0.      ],
                         [3.454971, 2.169877, 0.      ],
                         ...,
                         [4.12616 , 2.12093 , 1.17252 ],
                         [4.133175, 2.175231, 1.259323],
                         [4.232341, 1.903079, 0.534362]], dtype=float32)

        )rG   return_pointsra   s    r   r   zMeshFix.points  s    8 zz''))r   c                 6    | j                   j                         S )a  
        Return the indices of the faces of the mesh.

        Returns
        -------
        numpy.ndarray
            The points of the mesh.

        Examples
        --------
        Generate a MeshFix object and return the points.

        >>> from pyvista import examples
        >>> from pymeshfix import MeshFix
        >>> cow = examples.download_cow()
        >>> mfix = MeshFix(cow)
        >>> mfix.faces
        array([[ 210,  252,  251],
               [ 250,  251,  252],
               [ 201,  253,  210],
               ...,
               [1965, 2193, 2194],
               [2391, 2398,  970],
               [ 966,  961,  970]])

        )rG   return_facesra   s    r   r   zMeshFix.faces:  s    8 zz&&((r   
show_holeskwargsc                    	 ddl }|r| j                         }|j                  dd      }|j                  dd      }|j	                  |      }d|v r|j                  dd      |_         |j                  | j                  fd	d
i| |j                  r$|j                  |dd       |j                          |j                  |      S  | j                  j                  di |S # t        $ r t        d      w xY w)a  Plot the mesh.

        Parameters
        ----------
        show_holes : bool, default: True
            Shows boundaries.

        **kwargs : keyword arguments
            Additional keyword arguments.  See :func:`pyvista.plot`.

        Examples
        --------
        Load the example bunny mesh and plot it.

        >>> from pyvista import examples
        >>> from pymeshfix import MeshFix
        >>> mesh = examples.download_bunny()
        >>> mfix = MeshFix(mesh)
        >>> mfix.plot(show_holes=True)

        r   Nz#Install pyvista to use this feature
off_screenF
screenshot)ru   cposlabelr\   redges)rx   )rv    )pyvistar&   rm   popPlottercamera_positionadd_meshr\   n_points
add_legendshowplot)r   rr   rs   r[   rz   ru   rv   plotters           r   r   zMeshFix.plotX  s    ,	M  &&(EL%8JL$7JjjJj7G*0**VT*B'GTYY?f??~~  7 ;""$<<:<66tyy~~'''% # 	M%&KLL	Ms   C& &C;joincompremove_smallest_componentsc                     | j                   j                  dd       |r| j                   j                          |r| j                   j                          | j                   j	                          y)aK  
        Perform mesh repair using MeshFix's default repair process.

        Parameters
        ----------
        fill_holes : bool, default: True
            Call meshfix's internal ``fill_small_boundaries``.
        joincomp : bool, default: False
            Attempts to join nearby open components.
        remove_smallest_components : bool, default: True
            Remove all but the largest isolated component from the mesh before
            beginning the repair process.

        Notes
        -----
        Vertex and face arrays can be accessed from:

        * :attr:`Meshfix.points`
        * :attr:`Meshfix.faces`

        You can alternatively call individual repair functions if you desire
        specific fixes. For example :func:`MeshFix.fill_holes`.

        Examples
        --------
        Repair using the verbose option.

        >>> from pyvista import examples
        >>> from pymeshfix import MeshFix
        >>> mesh = examples.download_bunny()
        >>> mfix = MeshFix(mesh, verbose=True)
        >>> mfix.repair()
        >>> mfix.plot(show_holes=True)

        r   TN)rG   fill_small_boundariesjoin_closest_componentsr   clean)r   r   r   s      r   repairzMeshFix.repair  sO    P 	

((D1JJ..0%JJ113

r   n_edgesrefinec                 :    | j                   j                  ||      S )ae  
        Fill small boundary loops (holes) in the mesh.

        Parameters
        ----------
        nbe : int, default: 0
            Maximum number of boundary edges to fill. If 0, fill all.
        refine : bool, default: True
            Refine filled regions.

        Returns
        -------
        int
            Number of holes filled.

        )rG   r   )r   r   r   s      r   
fill_holeszMeshFix.fill_holes  s    " zz//@@r   c                 8    | j                   j                          y)z'Attempt to join nearby open components.N)rG   r   ra   s    r   r   zMeshFix.join_closest_components  s    

**,r   c                 8    | j                   j                          y)z/Remove all but the largest connected component.N)rG   r   ra   s    r   r   z"MeshFix.remove_smallest_components  s    

--/r   	max_itersinner_loopsc                 :    | j                   j                  ||      S )a  
        Remove degenerate triangles and self-intersections.

        Iteratively calls :func:`MeshFix.strong_degeneracy_removal` and
        :func:MeshFix.strong_intersection_removal to produce a clean mesh
        without degeneracies and intersections.  The two aforementioned methods
        are called up to max_iter times and each of them is called using
        'inner_loops' as a parameter.  Returns ``True`` only if the mesh could
        be completely cleaned.

        Parameters
        ----------
        max_iters

        )rG   r   )r   r   r   s      r   r   zMeshFix.clean  s      zz	;77r   max_iterc                 8    | j                   j                  |      S )a  
        Remove degenerate triangles.


        Parameters
        ----------
        max_iter : int, default: 3
            Maximum number of iterations to perform.

        Returns
        -------
        bool
            ``True`` when successful.

        )rG   strong_degeneracy_removalr   r   s     r   degeneracy_removalzMeshFix.degeneracy_removal  s      zz33H==r   c                 8    | j                   j                  |      S )a	  
        Remove self-intersecting triangles.

        Parameters
        ----------
        max_iter : int, default: 3
            Maximum number of iterations to perform.

        Returns
        -------
        bool
            ``True`` when successful.

        )rG   strong_intersection_removalr   s     r   intersection_removalzMeshFix.intersection_removal  s     zz55h??r   filenamec                 :    | j                   j                  ||      S )a  
        Write the points and faces as a surface mesh to disk using PyVista.

        This is a a simple wrapper for
        :pyvista:`pyvista.PolyData.save`.

        Parameters
        ----------
        filename : str
            Filename of mesh to be written. Filetype is inferred from
            the extension of the filename unless overridden with
            ftype. Generally one of the following types:

            - ``".ply"``
            - ``".stl"``
            - ``".vtk"``
        binary: bool, default: True
            Write the file using a binary writer. Binary files read and write
            much faster than ASCII.

        )r\   save)r   r   binarys      r   r   zMeshFix.save  s    , yy~~h//r   )r   r
   )T)FT)r   T)r   N)
   rE   )rE   ) r   r   r   __doc__boolr   propertyintr`   r   r.   rU   r2   rM   tuplerf   r\   rm   r   r   r   r   r   r   r   r   r   r   r   rQ   r   r   r{   r   r   r>   r>   J   s   1f /4 (#t (#T 'c ' '2
WRZZ0 2
WRXX5F 2
4 2
h*gbjj&97288;L&L M * $= $=L
 *

+ * *: )wrxx( ) ):*(t *(c *(\ +/-- %)- 
	-^A# A4 A3 A&-08s 8c 8$ 8$>3 >t >$@S @ @"0S4Z 0r   r>   )r   importlib.utilr   pathlibr   typingr   r   numpyr.   numpy.typingr   	pymeshfixr   r'   r
   rL   r   rU   r2   r<   r>   r{   r   r   <module>r      sf    6 $  %    ."y ",!4 ,WRXX=N ,S] ,^O0 O0r   