
    e{W                     .    d dl ZddlmZ  G d de      Zy)    N   )QtGuic                       e Zd ZdZddZd Zd Zd Zd dZd!dZ	d	 Z
d
 Zd Zd Zd Zd dZd dZd dZd dZd dZd dZd Zd Zd Zd Zd Zd Zd Zed"d       Zeddgddfd       Zy)#MeshDataa  
    Class for storing and operating on 3D mesh data. May contain:
    
      - list of vertex locations
      - list of edges
      - list of triangles
      - colors per vertex, edge, or tri
      - normals per vertex or tri
    
    This class handles conversion between the standard [list of vertexes, list of faces]
    format (suitable for use with glDrawElements) and 'indexed' [list of vertexes] format
    (suitable for use with glDrawArrays). It will automatically compute face normal
    vectors as well as averaged vertex normal vectors. 
    
    The class attempts to be as efficient as possible in caching conversion results and
    avoiding unnecessary conversions.
    Nc                 (   d| _         d| _        d| _        d| _        d| _        d| _        d| _        d| _        d| _        d| _	        d| _
        d| _        d| _        d| _        d| _        d| _        d| _        d| _        d| _        ||?| j'                  |d       || j)                  |d       || j+                  |d       yy| j'                  |       | j-                  |       || j)                  |       || j+                  |       yyy)a-  
        ==============  =====================================================
        **Arguments:**
        vertexes        (Nv, 3) array of vertex coordinates.
                        If faces is not specified, then this will instead be
                        interpreted as (Nf, 3, 3) array of coordinates.
        faces           (Nf, 3) array of indexes into the vertex array.
        edges           [not available yet]
        vertexColors    (Nv, 4) array of vertex colors.
                        If faces is not specified, then this will instead be
                        interpreted as (Nf, 3, 4) array of colors.
        faceColors      (Nf, 4) array of face colors.
        ==============  =====================================================
        
        All arguments are optional.
        Nfacesindexed)	_vertexes_vertexesIndexedByFaces_vertexesIndexedByEdges_faces_edges_vertexFaces_vertexEdges_vertexNormals_vertexNormalsIndexedByFaces_vertexColors_vertexColorsIndexedByFaces_vertexColorsIndexedByEdges_faceNormals_faceNormalsIndexedByFaces_faceColors_faceColorsIndexedByFaces_faceColorsIndexedByEdges_edgeColors_edgeColorsIndexedByEdgessetVertexessetVertexColorssetFaceColorssetFaces)selfvertexesr   edgesvertexColors
faceColorss         ;/usr/lib/python3/dist-packages/pyqtgraph/opengl/MeshData.py__init__zMeshData.__init__   sF   " '+$'+$    #,0)!+/(+/( !*.')-&)-&  )-&
 }  7 ;+((w(G)&&z7&C *   *e$+((6)&&z2 *      c                     | j                   S )zReturn an array (Nf, 3) of vertex indexes, three per triangular face in the mesh.
        
        If faces have not been computed for this mesh, the function returns None.
        )r   r"   s    r'   r   zMeshData.facesX   s    
 {{r)   c                 R    | j                   | j                          | j                   S )zDReturn an array (Nf, 3) of vertex indexes, two per edge in the mesh.)r   _computeEdgesr+   s    r'   r$   zMeshData.edges_   s"    ;; {{r)   c                 x    || _         d| _        d| _        d| _        | j	                          d| _        d| _        y)zSet the (Nf, 3) array of faces. Each rown in the array contains
        three indexes into the vertex array, specifying the three corners 
        of a triangular face.N)r   r   r   r   resetNormalsr   r   )r"   r   s     r'   r!   zMeshData.setFacese   s>      '+$+/()-&r)   c                    |4| j                   | j                  | j                          | j                   S |dk(  rF| j                  .| j                   "| j                   | j                            | _        | j                  S t	        d      )a4  Return an array (N,3) of the positions of vertexes in the mesh. 
        By default, each unique vertex appears only once in the array.
        If indexed is 'faces', then the array will instead contain three vertexes
        per face in the mesh (and a single vertex may appear more than once in the array).r   -Invalid indexing mode. Accepts: None, 'faces')r   r   _computeUnindexedVertexesr   	Exceptionr"   r
   s     r'   r#   zMeshData.vertexesq   s    
 ?~~%$*F*F*R..0>>!++38R/3~~djjl/K,///KLLr)   c                    |4|*t        j                  |t         j                        | _        d| _        nD|dk(  r4d| _        |6t        j                  |t         j                        | _        nt        d      |r| j                          yy)a.  
        Set the array (Nv, 3) of vertex coordinates.
        If indexed=='faces', then the data must have shape (Nf, 3, 3) and is
        assumed to be already indexed as a list of faces.
        This will cause any pre-existing normal vectors to be cleared
        unless resetNormals=False.
        Ndtyper   r1   )npascontiguousarrayfloat32r   r   r3   r/   )r"   vertsr
   r/   s       r'   r   zMeshData.setVertexes   s     ? !#!5!5e2::!N+/D(g!DN /1/C/CEQSQ[Q[/\,KLL r)   c                 <    d | _         d | _        d | _        d | _        y N)r   r   r   r   r+   s    r'   r/   zMeshData.resetNormals   s"    ",0) *.'r)   c                     | j                   duS )zGReturn True if this object already has vertex positions indexed by faceN)r   r+   s    r'   hasFaceIndexedDatazMeshData.hasFaceIndexedData   s    ++477r)   c                     | j                   d uS r=   )r   r+   s    r'   hasEdgeIndexedDatazMeshData.hasEdgeIndexedData   s    ++477r)   c                 \    | j                   | j                  | j                  fD ]  }| y y)z9Return True if this data set has vertex color informationTF)r   r   r   r"   vs     r'   hasVertexColorzMeshData.hasVertexColor   s7    $$d&F&FHhHhi 	A}	 r)   c                 \    | j                   | j                  | j                  fD ]  }| y y)z7Return True if this data set has face color informationTF)r   r   r   rC   s     r'   hasFaceColorzMeshData.hasFaceColor   s7    ""D$B$BDDbDbc 	A}	 r)   c                    | j                   O| j                  d      }t        j                  |dddf   |dddf   z
  |dddf   |dddf   z
        | _         || j                   S |dk(  r| j                  mt        j
                  | j                   j                  d   ddft        j                        }| j                   ddt        j                  ddf   |dd || _        | j                  S t        d	      )
z
        Return an array (Nf, 3) of normal vectors for each face.
        If indexed='faces', then instead return an indexed array
        (Nf, 3, 3)  (this is just the same array with each vector
        copied three times).
        Nr   r	      r   r      r6   r1   )
r   r#   r8   crossr   emptyshaper:   newaxisr3   )r"   r
   rD   normss       r'   faceNormalszMeshData.faceNormals   s     $g.A "1Q3!A#!A#q1v FD?$$$..6$"3"3"9"9!"<a!C2::V,,Qrzz!^<a27/222KLLr)   c                 ^   | j                   | j                         }| j                         }t        j                  | j
                  j                  t        j                        | _         t        | j
                  j                  d         D ]d  }||   }t        |      dk(  rd| j                   |<   &||   }|j                  d      }||dz  j                         dz  z  }|| j                   |<   f || j                   S |dk(  r| j                   | j                            S t        d      )	a  
        Return an array of normal vectors.
        By default, the array will be (N, 3) with one entry per unique vertex in the mesh.
        If indexed is 'faces', then the array will contain three normal vectors per face
        (and some vertexes may be repeated).
        r6   r   )r   r   r   )axisr   g      ?r   r1   )r   rP   vertexFacesr8   rL   r   rM   r:   rangelensumr   r3   )r"   r
   	faceNorms	vertFacesvindexr   rO   norms           r'   vertexNormalszMeshData.vertexNormals   s    &((*I((*I"$((4>>+?+?rzz"RD 4 4Q 78 3!&)u:?29D''/!%(yyay(q,,.2##F+3 ?&&&&&tzz|44KLLr)   c                     || j                   S |dk(  r:| j                  "| j                   | j                            | _        | j                  S t        d      )z
        Return an array (Nv, 4) of vertex colors.
        If indexed=='faces', then instead return an indexed array
        (Nf, 3, 4). 
        r   r1   )r   r   r   r3   r4   s     r'   r%   zMeshData.vertexColors   sZ     ?%%%//7373E3Edjjl3S0333KLLr)   c                     |2t        j                  |t         j                        | _        d| _        y|dk(  r2d| _        t        j                  |t         j                        | _        yt        d      )z
        Set the vertex color array (Nv, 4).
        If indexed=='faces', then the array will be interpreted
        as indexed and should have shape (Nf, 3, 4)
        Nr6   r   r1   )r8   r9   r:   r   r   r3   r"   colorsr
   s      r'   r   zMeshData.setVertexColors   sb     ?!#!5!5fBJJ!OD/3D,!%D/1/C/CFRTR\R\/]D,KLLr)   c                 r   || j                   S |dk(  r| j                  | j                   v| j                   j                  d   }t        j                  |ddf| j                   j
                        | _        | j                   j                  |dd      | j                  dd | j                  S t        d      )	z
        Return an array (Nf, 4) of face colors.
        If indexed=='faces', then instead return an indexed array
        (Nf, 3, 4)  (note this is just the same array with each color
        repeated three times). 
        Nr   r   rJ      r6   rI   r1   )r   r   rM   r8   rL   r7   reshaper3   )r"   r
   Nfs      r'   r&   zMeshData.faceColors  s     ?###--5$:J:J:V%%++A.132q!*DL\L\LbLb1c.484D4D4L4LRQRTU4V..q1111KLLr)   c                     |2t        j                  |t         j                        | _        d| _        y|dk(  r2d| _        t        j                  |t         j                        | _        yt        d      )z
        Set the face color array (Nf, 4).
        If indexed=='faces', then the array will be interpreted
        as indexed and should have shape (Nf, 3, 4)
        Nr6   r   r1   )r8   r9   r:   r   r   r3   r^   s      r'   r    zMeshData.setFaceColors  sb     ?!33F"**MD-1D*#D-/-A-A&PRPZPZ-[D*KLLr)   c                     | j                   | j                   j                  d   S | j                  | j                  j                  d   S y)z9
        Return the number of faces in the mesh.
        Nr   )r   rM   r   r+   s    r'   	faceCountzMeshData.faceCount#  sK     ;;";;$$Q''))5//55a88 6r)   c                     | j                   S r=   )r   r+   s    r'   
edgeColorszMeshData.edgeColors,  s    r)   c                 6   | j                   }i }t        j                  |j                  d d t        j                        | _        g | _        g | _        d | _        d | _	        t        |j                  d         D ]  }||   }t        |j                  d         D ]  }||   }t        |D cg c]  }t        |dz         c}      }|j                  |d       }	|	S| j                  j                  |       | j                  j                  g        t        | j                        dz
  }	|	||<   | j                  |	   j                  |       |	| j
                  ||f<     t        j                   | j                  t        j"                        | _        y c c}w )Nr   r6   r   g  ļBrI   )r   r8   rL   rM   uintr   r   r   r   r   rT   tupleroundgetappendrU   arrayr:   )
r"   r   r;   ifacejptxpt2indexs
             r'   r2   z"MeshData._computeUnindexedVertexes4  s]   
 ,,hhu{{2Abgg> "u{{1~& 	)A8D4::a=) )!WB7qU1T6]78		#t,=NN))"-%%,,R0/1E!&E#J!!%(//2#(AaC )	) $..

C 8s   +Fc                 \   | j                   t        t        | j                                     D cg c]  }g  c}| _         t        | j                  j
                  d         D ]6  }| j                  |   }|D ]   }| j                   |   j                  |       " 8 | j                   S c c}w )zf
        Return list mapping each vertex index to a list of face indexes that use the vertex.
        r   )r   rT   rU   r#   r   rM   rn   )r"   rp   rq   inds       r'   rS   zMeshData.vertexFacesZ  s     $-23t}}3G-H I ID4;;,,Q/0 5{{1~ 5C%%c*11!455     !Js   	B)c                    | j                         st        | j                        }t        j                  |dz  dt        j
                  dfg      }| j                  d d d df   |d   d| | j                  d d ddf   |d   |d|z   | j                  d d df   |d   | d df<   | j                  d d df   |d   | d df<   |d   d d df   |d   d d df   kD  }|d   |   d d d d df   |d   |<   t        j                  |      d   | _        y | j                  | j                  }t        j                  |j                  d   ddft        j
                        }|j                  d   }t        j                  |      dz  |d d ddf<   |d d ddf   dz   |d d ddf<   |d d ddf   |d d ddf<   |d d ddf   dz   |d d ddf<   |d d ddf   |d d ddf<   |d d ddf   |d d ddf<   || _        y t        d      )	NrJ   rp   r   r6   r   rI   z6MeshData cannot generate edges--no faces in this data.)r?   rU   r   r8   rL   rj   uniquer   r   rM   aranger3   )r"   nfr$   maskr;   s        r'   r-   zMeshData._computeEdgess  s&   &&(T[[!BHHRT3*;)<=E#{{1RaR40E#Jq"&++a!e"4E#Jr!B$!%QqS!1E#JstAv!%QqS!1E#JstAv :ac?U3Z!_4D$Sz$/$B$7E#Jt ))E*3/DK))500EHHekk!na3277CEQB99R=1,E!Aa%L 1Q<!+E!Aa%L 1Q<E!Aa%L 1Q<!+E!Aa%L 1Q<E!Aa%L 1Q<E!Aa%LDKTUUr)   c           
         ddl }| j                  ddg}ndg}| j                  |j                  d       n| j                  |j                  d       | j
                  |j                  d       n| j                  |j                  d	       t        |D cg c]  }|t        | |      f c}      }|j                  |      S c c}w )
z<Serialize this mesh to a string appropriate for disk storager   Nr   r   r   r   r   r   r   )
pickler   r   rn   r   r   r   dictgetattrdumps)r"   r   namesnstates        r'   savezMeshData.save  s    ;;" (+E./E)LL)--9LL67'LL'++7LL45E:qqq)*:;||E"" ;s   Cc                    ddl }|j                  |      }|D ]  }t        ||   t              r~t        ||   d   t        j
                        rC||   D cg c]1  }|j                         |j                         |j                         g3 c}||<   t        j                  ||         ||<   t        | |||           yc c}w )z9Restore the state of a mesh previously saved using save()r   N)r   loads
isinstancelistr   	QVector3Drt   yzr8   ro   setattr)r"   r   r   krD   s        r'   restorezMeshData.restore  s    U# 	'A%(D)eAhqk5??;?DQxH!qssu 5HE!H88E!H-aD!U1X&	'  Is   6B?      ?c                    t        j                  | dz   |dft              }t        j                  | dz         t         j                  z  | z  j                  | dz   d      }|t        j                  |      z  }|t        j                  |      z  |d<   t        j                  |      dz  t         j                  z  |z  j                  d|      }|rB|t         j                  |z  t        j                  | dz         j                  | dz   d      z  z   }|t        j                  |      z  |d<   |t        j                  |      z  |d<   |j                  | dz   |z  d      |dz
  |dz
    }t        j                  | |z  dz  dft         j                        }t        j                  |      j                  |d      t        j                  g dg      z   |z  t        j                  d	d	|gg      z   }	t        j                  |      j                  |d      t        j                  g d
g      z   |z  t        j                  |d	|gg      z   }
t        |       D ],  }||z  dz  }|	||z  z   ||||z    |
||z  z   |||z   ||dz  z    . |||  }|dz
  }||||k  <   ||z  }|j                  d	   dz
  }||||kD  <   t        ||      S )zn
        Return a MeshData instance with vertexes and faces computed
        for a spherical surface.
        rI   rJ   r6   .r   r   .r   .rI   r   rI   r   r   r   rI   rI   r#   r   )r8   rL   floatr|   pirb   sincosrj   ro   rT   rM   r   )rowscolsradiusoffsetr;   phisthr   rowtemplate1rowtemplate2rowstartvminvmaxs                  r'   spherezMeshData.sphere  s    $q&$*%8 yya 255(4/88aCRVVC[ s+eyy"RUU*T1::1dC		$q&(9(A(A$q&(KKLB266":~e266":~etAvtmQ/QayA $t)A+q)9400q9BHHi[<QQUYY]_]e]ehiklnrgsft]uu400q9BHHi[<QQUYY]_]e]ehlnoqugvfw]xx; 	IC$JNE&2S4Z&?E%d
#/;cDj/HE%*UDF^,	I dD5! Av eDj{{1~a eDje44r)   Fc                 J   t        j                  | dz   |dft              }t        |t              r||g}t        j
                  dt         j                  z  dt         j                  z  |z  |      j                  d|      }t        j
                  |d   |d   | dz   d      j                  | dz   d      }t        j
                  d|| dz   d      j                  | dz   d      |d<   |rB|t         j                  |z  t        j                  | dz         j                  | dz   d      z  z   }|t        j                  |      z  |d	<   |t        j                  |      z  |d
<   |j                  | dz   |z  d      }t        j                  | |z  dz  dft         j                        }t        j                  |      j                  |d      t        j                  g dg      z   |z  t        j                  dd|gg      z   }	t        j                  |      j                  |d      t        j                  g dg      z   |z  t        j                  |d|gg      z   }
t        |       D ],  }||z  dz  }|	||z  z   ||||z    |
||z  z   |||z   ||dz  z    . t        ||      S )z
        Return a MeshData instance with vertexes and faces computed
        for a cylindrical surface.
        The cylinder may be tapered with different radii at each end (truncated cone)
        rI   rJ   r6   r   r   T)numendpointr   r   r   r   r   r   )r8   rL   r   r   intlinspacer   rb   r|   r   r   rj   ro   rT   r   )r   r   r   lengthr   r;   r   rr   r   r   r   r   s                r'   cylinderzMeshData.cylinder  sm    $q&$*%8fc"f%F[[RUUQY$4d;CCAtLKKq	&)QFNNtTUvWXY{{1f$q&4HPPQUVWQWYZ[e		$q&(9(A(A$q&(KKLB266":~e266":~etAvtmQ/$t)A+q)9400q9BHHi[<QQUYY]_]e]ehiklnrgsft]uu400q9BHHi[<QQUYY]_]e]ehlnoqugvfw]xx; 	IC$JNE&2S4Z&?E%d
#/;cDj/HE%*UDF^,	I
 e44r)   )NNNNNr=   )NNT)r   T)__name__
__module____qualname____doc__r(   r   r$   r!   r#   r   r/   r?   rA   rE   rG   rP   r[   r%   r   r&   r    rf   rh   r2   rS   r-   r   r   staticmethodr   r    r)   r'   r   r      s    $=3~
.M  ,/88M,M8MMM$M9 DL
!2V@#*	' #5 #5J %(#Js5 5 5r)   r   )numpyr8   Qtr   objectr   r   r)   r'   <module>r      s     q5v q5r)   