Ë
    :vžjÇ/  ã                   ó  — d dl 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 ddlmZ dd	lmZ dd
lmZ ddlmZ 	 	 	 	 	 dd„Zdd„Zdd„Z	 dd„Z	 	 ddedededz  fd„Zd„ Zd„ Zy# e	$ rZ
ddlmZ  ee
«      ZeeecZZZY dZ
[
ŒldZ
[
ww xY w)é    Né   )Ú	ArrayLike)Ú
coo_matrixÚeye)Úspsolve)ÚExceptionWrapper)ÚgraphÚ	triangles)ÚTrimesh)Úindex_sparse©Úmass_properties)Úunitizec                 óv  — |€t        | «      }|r| j                  }| j                  }| j                  j	                  «       j                  t        j                  «      }| j                  j	                  «       j                  t        j                  «      }	|r,|j                  d   }
t        |
«      |t        |
«      |z
  z  z   }t        |«      D ]`  }|s|j                  |«      |z
  }|||z  z  }nt        |«      }|sŒ1t        j                  ||	   d¬«      d   }|z  dz  }|z
  |z  |z   }Œb || _        | S )a  
    Smooth a mesh in-place using laplacian smoothing.
    Articles
    1 - "Improved Laplacian Smoothing of Noisy Surface Meshes"
       J. Vollmer, R. Mencl, and H. Muller
    2 - "Implicit Fairing of Irregular Meshes using Diffusion
       and Curvature Flow". M. Desbrun,  M. Meyer,
       P. Schroder, A.H.B. Caltech
    Parameters
    ------------
    mesh : trimesh.Trimesh
    Mesh to be smoothed in place
    lamb : float
    Diffusion speed constant
    If   0.0, no diffusion
    If > 0.0, diffusion occurs
    implicit_time_integration: boolean
    if False: explicit time integration
        -lamb <= 1.0 - Stability Limit (Article 1)
    if True: implicit time integration
        -lamb no limit (Article 2)
    iterations : int
    Number of passes to run filter
    volume_constraint : bool
    If True, restore the initial volume after each iteration
    by rescaling about the mesh center of mass
    laplacian_operator : None or scipy.sparse.coo.coo_matrix
    Sparse matrix laplacian operator
    Will be autogenerated if None
    r   T©Úskip_inertiaÚvolumegUUUUUUÕ?)Úlaplacian_calculationr   Úcenter_massÚverticesÚcopyÚviewÚnpÚndarrayÚfacesÚshaper   ÚrangeÚdotr   r
   r   )ÚmeshÚlambÚ
iterationsÚimplicit_time_integrationÚvolume_constraintÚlaplacian_operatorÚvol_inir   r   r   ÚdlapÚAAÚ_indexr   Úvol_newÚscales                   úb/workspace/moltex-experiments/.pixi/envs/default/lib/python3.12/site-packages/trimesh/smoothing.pyÚfilter_laplacianr,      s>  € ðP Ð!Ü2°4Ó8Ðñ Ø—+‘+ˆØ×&Ñ&ˆð �}‰}×!Ñ!Ó#×(Ñ(¬¯©Ó4€HØ�J‰J�O‰OÓ×"Ñ"¤2§:¡:Ó.€Eñ !Ø!×'Ñ'¨Ñ*ˆÜ�‹Y˜¤ T£Ð-?Ñ!?Ñ@Ñ@ˆô ˜
Ö#ˆá(Ø$×(Ñ(¨Ó2°XÑ=ˆCØ˜˜s™
Ñ"‰Hô ˜r 8Ó,ˆHò ä×/Ñ/°¸±ÈdÔSØñˆGð ˜wÑ&¨IÑ6ˆEØ  ;Ñ.°%Ñ7¸+ÑE‰Hð% $ð* €D„MØ€Kó    c                 ó€  — |€t        | «      }| j                  j                  «       j                  t        j
                  «      }|j                  «       }t        |«      D ]T  }|j                  «       }|j                  |«      }|||z  d|z
  |z  z   z
  }	|||	z  d|z
  |j                  |	«      z  z   z  }ŒV || _        | S )aÖ  
    Smooth a mesh in-place using laplacian smoothing
    and Humphrey filtering.
    Articles
    "Improved Laplacian Smoothing of Noisy Surface Meshes"
    J. Vollmer, R. Mencl, and H. Muller
    Parameters
    ------------
    mesh : trimesh.Trimesh
      Mesh to be smoothed in place
    alpha : float
      Controls shrinkage, range is 0.0 - 1.0
      If 0.0, not considered
      If 1.0, no smoothing
    beta : float
      Controls how aggressive smoothing is
      If 0.0, no smoothing
      If 1.0, full aggressiveness
    iterations : int
      Number of passes to run filter
    laplacian_operator : None or scipy.sparse.coo.coo_matrix
      Sparse matrix laplacian operator
      Will be autogenerated if None
    ç      ð?©r   r   r   r   r   r   r   r   )
r   ÚalphaÚbetar!   r$   r   Úoriginalr(   Úvert_qÚvert_bs
             r+   Úfilter_humphreyr6   h   sÂ   € ð4 Ð!Ü2°4Ó8Ðð �}‰}×!Ñ!Ó#×(Ñ(¬¯©Ó4€Hà�}‰}‹€Hô ˜
Ö#ˆØ—‘“ˆØ%×)Ñ)¨(Ó3ˆØ˜U XÑ-°°u±ÀÑ0FÑFÑGˆØ�D˜6‘M S¨4¡ZÐ3E×3IÑ3IÈ&Ó3QÑ$QÑQÑQ‰ð	 $ð €D„MØ€Kr-   c                 ó  — |€t        | «      }| j                  j                  «       j                  t        j
                  «      }t        |«      D ]/  }|j                  |«      |z
  }|dz  dk(  r	|||z  z  }Œ(|||z  z  }Œ1 || _        | S )aœ  
    Smooth a mesh in-place using laplacian smoothing
    and taubin filtering.
    Articles
    "Improved Laplacian Smoothing of Noisy Surface Meshes"
    J. Vollmer, R. Mencl, and H. Muller
    Parameters
    ------------
    mesh : trimesh.Trimesh
      Mesh to be smoothed in place.
    lamb : float
      Controls shrinkage, range is 0.0 - 1.0
    nu : float
      Controls dilation, range is 0.0 - 1.0
      Nu shall be between 0.0 < 1.0/lambda - 1.0/nu < 0.1
    iterations : int
      Number of passes to run the filter
    laplacian_operator : None or scipy.sparse.coo.coo_matrix
      Sparse matrix laplacian operator
      Will be autogenerated if None
    é   r   r0   )r   r    Únur!   r$   r   Úindexr   s           r+   Úfilter_taubinr;   –   s“   € ð. Ð!Ü2°4Ó8Ðð �}‰}×!Ñ!Ó#×(Ñ(¬¯©Ó4€Hô �zÖ"ˆà ×$Ñ$ XÓ.°Ñ9ˆà�1‰9˜Š>Ø˜˜s™
Ñ"‰Hà˜˜S™Ñ ‰Hð #ð €D„MØ€Kr-   c                 ó°  — |€t        | «      }|r| j                  }| j                  j                  «       j	                  t
        j                  «      }| j                  j                  «       j	                  t
        j                  «      }dt        j                  | j                  «      dz  z  }t        |«      D �]  }	t        | «      }
|j                  |«      }||z
  }t        j                  |
|z  j                  t        j                  d«      «      «      }dt        j                  d|«      z  }t        j                  d|z  t        j                   d||z  t        j"                  |«      z  «      «      }|j                  |«      }||||z
  z  z  }|sŒÝt%        ||   d¬«      d	   }|	d
k(  rt'        |||
||«      }||
z  |z
  z  z  }�Œ || _        | S )aê  
    Smooth a mesh in-place using laplacian smoothing using a
    mutable diffusion laplacian.

    Articles
      Barroqueiro, B., Andrade-Campos, A., Dias-de-Oliveira,
      J., and Valente, R. (January 21, 2021).
      "Bridging between topology optimization and additive
       manufacturing via Laplacian smoothing." ASME. J. Mech. Des.


    Parameters
    ------------
    mesh : trimesh.Trimesh
      Mesh to be smoothed in place
    lamb : float
      Diffusion speed constant
      If   0.0, no diffusion
      If > 0.0, diffusion occurs
    iterations : int
      Number of passes to run filter
    laplacian_operator : None or scipy.sparse.coo.coo_matrix
      Sparse matrix laplacian operator
      Will be autogenerated if None
    g{®Gáz„?ç      à?)é   r   r/   gê-�™—q=gš™™™™™É?Tr   r   r   )r   r   r   r   r   r   r   r   ÚmaxÚ
area_facesr   Úget_vertices_normalsr   ÚabsÚonesÚmaximumÚminimumÚmeanr   Údilate_slope)r   r    r!   r#   r$   Úv_inir   r   Úepsr(   ÚnormalsÚqiÚpi_qiÚadilÚlamberr   ÚvolÚslopes                     r+   Úfilter_mut_dif_laplacianrQ   Â   sœ  € ð< Ð!Ü2°4Ó8Ðñ Ø—‘ˆð �}‰}×!Ñ!Ó#×(Ñ(¬¯©Ó4€HØ�J‰J�O‰OÓ×"Ñ"¤2§:¡:Ó.€EØ
”"—&‘&˜Ÿ™Ó)¨SÑ0Ñ
1€Cô ˜
×#ˆä& tÓ,ˆØ×#Ñ# HÓ-ˆØ˜2‘ˆä�v‰v�w ‘×+Ñ+¬B¯G©G°F«OÓ<Ó=ˆØ”R—Z‘Z  tÓ,Ñ,ˆÜ—‘˜C $™J¬¯
©
°3¸¸t¹ÄbÇgÁgÈdÃmÑ8SÓ(TÓUˆð !×$Ñ$ XÓ.ˆØ�F˜c H™nÑ-Ñ-ˆò Ü! (¨5¡/ÀÔEÀhÑOˆCØ˜Š{Ü$ X¨u°g¸sÀCÓH�Ø˜ %™¨5°3©;Ñ7Ñ7ŠHð' $ð, €D„Mà€Kr-   r   Úequal_weightÚpinned_verticesc                 óè  — |rùt        j                  | j                  «      }|�Ád|j                  t	        j
                  |j                  |«      <   t	        j                  |j                  |f«      |_        t	        j                  |j                  |f«      |_        t	        j                  |j                  t	        j                  t        |«      t        ¬«      f«      |_        ||j                  d¬«      z  }|S | j                  }|�|D ]  }|g||<   Œ
 | j                  j                  t        j                   «      }t	        j                  |«      }t	        j                  t#        |«      D ��cg c]  \  }}|gt        |«      z  ‘Œ c}}«      }	t	        j                  d«      }
t#        |«      D ��cg c]Q  \  }}dt	        j$                  dt	        j&                  t	        j(                  ||   ||   z
  dz  |
«      «      «      z  ‘ŒS }}}t	        j                  |D �cg c]  }||j                  «       z  ‘Œ c}«      }t+        ||	|fft        |«      gdz  ¬	«      }|S c c}}w c c}}w c c}w )
al  
    Calculate a sparse matrix for laplacian operations.

    Note that setting equal_weight to False significantly hampers performance.

    Parameters
    -------------
    mesh : trimesh.Trimesh
      Input geometry
    equal_weight : bool
      If True, all neighbors will be considered equally
      If False, all neighbors will be weighted by inverse distance
    pinned_vertices : None or list of ints
      If None, no vertices are pinned
      If list, vertices will be pinned, such that they will not be moved
    Returns
    ----------
    laplacian : scipy.sparse.coo.coo_matrix
      Laplacian operator
    F)Údtyper   )Úaxisr>   r/   g�íµ ÷Æ°>r8   )r   )r	   Úedges_to_cooÚedgesÚdatar   ÚisinÚrowÚconcatenateÚcolrC   ÚlenÚboolÚsumÚvertex_neighborsr   r   r   Ú	enumeraterD   Úsqrtr   r   )r   rR   rS   Ú	laplacianÚ	neighborsÚir   r]   Únr[   rC   ÚnormsrY   s                r+   r   r     s  € ñ2 Ü×&Ñ& t§z¡zÓ2ˆ	àÐ&àFKˆI�N‰Nœ2Ÿ7™7 9§=¡=°/ÓBÑCÜŸN™N¨I¯M©M¸?Ð+KÓLˆIŒMÜŸN™N¨I¯M©M¸?Ð+KÓLˆIŒMÜŸ^™^Ø—‘¤§¡¬¨_Ó)=ÄTÔ!JÐKóˆIŒNð  	§¡°1 Ó 5Ñ5ˆ	ðD Ðð= ×)Ñ)ˆ	ð Ð&Û$�Ø !˜s�	˜!’ð %ð —=‘=×%Ñ%¤b§j¡jÓ1ˆô �n‰n˜YÓ'ˆÜ�n‰n´yÀÔ7KÔLÑ7K©t¨q°!˜q˜c¤C¨£F›lÐ7KÒLÓMˆô �w‰w�q‹zˆô
 " )Ô,ô
ñ -‘��1ð Ü�j‰j˜œrŸw™w¤r§v¡v¨x¸©{¸XÀa¹[Ñ/HÈQÑ.NÐPTÓ'UÓVÓWóXà,ð 	ñ 
ô �~‰~±EÓ:±E¨q˜q 1§5¡5£7›{°EÑ:Ó;ˆô   s¨C jÐ1¼#¸h»-¸È1Ñ9LÔMˆ	àÐùó# Mùó
ùò ;s   Å2I#
Æ6AI)È"I/c                 ó¨   — | j                   }| j                  }| j                  }t        t	        |«      |«      j                  |«      }t        |«      S )z÷
    Compute Vertex normals using equal weighting of neighbors faces.
    Parameters
      -------------
      mesh : trimesh.Trimesh
        Input geometry
      Returns
      ----------
      vertices_normals: array
        Vertices normals
    )r   r   Úface_normalsr   r^   r   r   )r   r   r   rj   Úvert_normalss        r+   rA   rA   R  sK   € ð �}‰}€HØ�J‰J€Eð ×$Ñ$€Lô  ¤ H£¨uÓ5×9Ñ9¸,ÓG€Lä�<Ó Ð r-   c                 óH   — | ||z  z   }t        ||   d¬«      d   }|||z
  z  S )a¶  
    Get the derivate of dilation scalar by the volume variation by finite differences
    Thus, Vertices += vertex_normals*dilate_slope*(Initial_Volume - Srinked_Volume)
    Parameters
      -------------
      mesh : trimesh.Trimesh
        Input geometry
      vertices: mesh.vertices
      faces: mesh.faces
      normals: array
        vertices normals
      Returns
      ----------
      dilate_slope: float
        derivative
    Tr   r   r   )r   r   rJ   ÚvrI   Ú	vertices2Úv2s          r+   rG   rG   l  s7   € ð& ˜7 S™=Ñ(€IÜ	˜ 5Ñ)¸Ô	=¸hÑ	G€Bà�B˜‘FÑÐr-   )r=   é
   FTN)gš™™™™™¹?r=   rp   N)r=   r=   rp   N)r=   rp   TN)TN) Únumpyr   Útypedr   Úscipy.sparser   r   Úscipy.sparse.linalgr   ÚImportErrorÚEÚ
exceptionsr   ÚwrapperÚ r	   r
   Úbaser   Úgeometryr   r   Úutilr   r,   r6   r;   rQ   r_   r   rA   rG   © r-   r+   Ú<module>r~      sÄ   ðÛ å ð9ß,Ý+÷ Ý Ý "Ý &Ý ð
 
ØØ#ØØóPóf+ó\)ðZ OSóCðP Ø(,ñGØ
ðGàðGð  Ñ%óGòT!ó4øðI ò 9Ý,á˜qÓ!€GØ&¨°Ð€Cˆ•*ûð	9ús   ŒA' Á'BÁ,BÂB