
    {i1                     v   d dl mZ d dlmZ d dlZd dlZd dl	Z	d dl
m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 d dlZd dl
mZ 	 d d
eeej        f         fdZd!deeej        f         fdZ	 	 	 d"deeej        f         fdZd Zd#dZd$dZ d#dZ!	 d%dZ"	 	 	 	 	 d&dZ# ed          dfdZ$dS )'    N)Path)Dict)Slider)ListedColormapBoundaryNorm)displaygrayMeshT	mesh_datac                     | d         }| d         }t          j        |dddf         |dddf         |dddf         |dddf         |dddf         |dddf         |d|d|	          }|S )
zBConverts mesh data (vertices, triangles) to a Plotly Mesh3d trace.vertices	trianglesNr         gffffff?name)xyzijkcoloropacityr   	hoverinfo
showlegend)goMesh3d)r   r   r   r   r   r   traces          (/mnt/shared/vista-3d/utils/plot_utils.pymesh_to_plotlyr       s     $H+&II
111a4.
111a4.
111a4.
AAAqD/
AAAqD/
AAAqD/  E L    Point Cloudpcd_datac                     | d         }| d         dz  }t          j        |dddf         |dddf         |dddf         dt          d|d	
          |d|          }|S )zGConverts point cloud data (points, colors) to a Plotly Scatter3d trace.pointscolors   Nr   r   r   markers皙?)sizer   r   r   )r   r   r   modemarkerr   r   r   )r   	Scatter3ddict)r#   r   r   r%   r&   r   s         r   pcd_to_plotlyr/   )   s    hFh#%FL
A,
A,
A,&#666	 	 	E Lr!   yellow
Centerlinelineset_datac           
         | d         }| d         }g g g }}}|D ]}	||	d                  }
||	d                  }|                     |
d         |d         dg           |                     |
d         |d         dg           |                     |
d         |d         dg           t          j        |||dt          |d          |d	|
          }|S )zMConverts lineset data (points, lines) to a Plotly Scatter3d trace with lines.r%   linesr   r   Nr      )r   widthr   )r   r   r   r+   liner   r   r   )extendr   r-   r.   )r2   r   r   r   r%   r4   x_linesy_linesz_linesr7   p1p2r   s                r   lineset_to_plotlyr>   ;   s     (#F!E "BgWG - -DG_DG_1r!ud+,,,1r!ud+,,,1r!ud+,,,,L


Q'''	 	 	E Lr!   c                    | j         d         t          |          k    s'J t          d| j          d|j                                | dddf         }t          j        |          }g }g }|D ]v}||k    }| |         }||         }	t          |	          dk    r,t          j        |	          }
|                    ||
                    |                    |	|
                    wt          j        |          t          j        |          fS )a  
    Identify at each slice, the max diameter value.

    Args:
        points: np.array of x, y, z coordinates of vessel centerline in voxel space
        diameters: np.array of diameter values compute along points

    Returns:
        max_points: np.array of x, y, z coordinates of vessel centerline with unique z coordinates
        max_diams: np.array of diameter values compute along max_points
    r   zanumber of points coordinates and diameter value is inconsistent.
        Input shape is: points: z, diameters: Nr   )shapelen
ValueErrornpuniqueargmaxappendarray)r%   	diametersz_valsunique_z
max_points	max_diamsr   in_bin
bin_points	bin_diamsidx_maxs              r   bin_by_unique_zrQ   [   s)    <?c)nn,,,j	P!'	P 	P<EO	P 	P/ /,,,
 AAAqD\Fy  HJI 
- 
-1F^
f%	y>>Q)I&&*W-...7+,,,,8J)!4!444r!   c                    t          ||           \  }}t          j        d           |6t          j        t	          j        t          |                     | d           n t          j        |dddf         |d           |t          j        d           nt          j        d           t          j        d           t          j	        | d	           t          j
        d
           t          j                     t          j        |d
           t          |          d                    |                    d                     dz  }t          j        |d           t          j                     |S )a$  
    Plot diameter over vessel's centerline and save it to a file.

    Args:
        diameters: np.array, diameter across the centerline
        output_dir: str folder where to save the plot
        name: str, name of the vessel
        slice_ids: np.array, id for each diameter measure
    )
      )figsizeNz-or   zCenterline point indexzSlice coordinatezDiameter (mm)z Diameter Along CenterlineTexist_ok_ z.png   )dpi)rQ   pltfigureplotrC   arangerA   xlabelylabeltitlegridtight_layoutosmakedirsr   joinsplitsavefigclose)rH   
output_dirr   	slice_idsmax_pts_zbinmax_diam_valuesentire_file_paths          r   plot_diameterrp      sY    %4Iy$I$I!L/Jw3y>>**It<<<<aaad#_d;;;
+,,,,
%&&&JI111222HTNNNK
T****J''SXXdjjoo-F-F*L*L*LLK c**** IKKKr!   <   c                 B   t          j        |t           j                  }t           j                            |          dk    r#t          j        g dt           j                  }n"|t           j                            |          z  }t          j        ddt           j        z  |d          }t           j        t          j	        |          t          j
        |          t          j        |          f         |z  }t          j        g d|g          }d t          d	|          D             }|                    d|d	g           t          j                                        }t          j                            |          |_        t          j                            |          |_        |                                 t          j        g dt           j                  }	t          j        ||	          st          j        |	|          }
t           j                            |
          dk    rDt          j        ||	           rt          j        g d
          }
n9t          j        g d          }
n"|
t           j                            |
          z  }
t          j        t          j        t          j        |	|          dd                    }t          j                            |
|z            }|                    |d           |                    |            |S )a  
    Create a flat disc mesh centered at `center`, perpendicular to `normal`,
    with the specified `radius` and triangle resolution.

    Args:
        center: coordinates where to center the disk
        radius: disc radius
        normal: vector to which the disc should be normal to (i.e. tangent to centerline)
        resolution: the number of segments (or triangles) used to approximate the circular disc.

    Return:
        Open3D disc mesh
    )dtyper   )r   r   r   r   F)endpoint)r   r   r   c                     g | ]
}d ||dz   gS )r   r    ).0r   s     r   
<listcomp>z$create_flat_disc.<locals>.<listcomp>   s"    ===1!QA===r!   r   )r   r   r   )r   r   r   g      g      ?)center) rC   asarrayfloat64linalgnormrG   linspacepic_cossin
zeros_likevstackrangerF   o3dgeometryTriangleMeshutilityVector3dVectorr   Vector3iVectorr   compute_vertex_normalsallclosecrossarccosclipdot#get_rotation_matrix_from_axis_anglerotate	translate)ry   radiusnormal
resolutionanglescircle_pointsr   r   meshz_axisaxisangleRs                r   create_flat_discr      s    Zbj111F	y~~f"")))2:666")..((( [AIzEBBBF
bfVnnbfVnnbmF.C.CCDvM  y)))]344H==a(<(<===IaQ'(((<$$&&DK..x88DM[//	::DN!!! Xiiirz222F;vv&& )x''9>>$1$${6F7++ +x			**x			**BINN4(((D	"'"&"8"8$DDEEL<<TE\JJAi((( 	NN6Kr!   c                     t          j        | t           j        j                   |<t          j        t          j                            |dk    |          ddd           dS dS )z{
    Visualize slice.

    Args:
        image: 2D np.array to visualize
        mask: Optional 2D np.array to overlay
    cmapNr   jet      ?none)r   alphainterpolation)r\   imshowcmr	   rC   mamasked_where)imagemasks     r   visualize_slicer      sp     Ju36;''''
Etqy$// 		
 	
 	
 	
 	
 	
 r!   r5   皙?firstc                 F   |dk    r|pt          d| j        d         |          }n:|dk    r|pt          d| j        d         |          }nt          dt                    |D ]}|dk    r$t	          | |         dz  |||         nd           n-|dk    r't	          | d|f         dz  |
|d|f         nd           t          j        d	|            t          j        t          j                               t          j	        d
           t          j        |           dS )a  
    Visualize volume.

    Args:
        image: 3D np.array to visualize
        mask: Optional 3D np.array to overlay
        interval: int, interval between slices to be visualized
        pause_time=0.1: float, pause between slice visualization
        show_slices=None: Optional[List[int]]. If None, shows all slices at the interval rate, else shows the specified slices
        slice_dim="first", whether slices are in the 'first' or 'last' dimension of the volume.

    r   r   lastz'slice axis must be first or last. Used i  N.Slice T)wait)r   r@   rB   
slice_axisr   r\   rb   r   gcfclear_outputtimesleep)r   r   interval
pause_timeshow_slices	slice_dimns          r   visualize_scanr      sJ    G!GU1ek!nh%G%G	f		!HU1ek"ox%H%HBJOOO  E!HtO8HT!WWdSSSS &  c1f$d6Fd36llD   		,1,,		"""$''''
:# r!   c                 @   |X| 
J d            t          j        t          j        t          j        |                                           d                    n||L|
J d            t          j        t          j        t          j        |          d         d                    n|d}d |                                D             }t          |          dz   }|dk    rg d	}nd
|cxk     rdk    r?n n<t          j	        
                    d|          fdt          |          D             }nd|cxk     rdk    r?n n<t          j	        
                    d|          fdt          |          D             }n;t          j	        
                    d|          fdt          |          D             }t          |          }	t          t          j        d|dz             |	j                  }
t          j                    \  t          j        d           d d d d |f         }d d d d |f         }                    |d                              t           j                            |dk    |          |	|
d                              d|            t          j        g d          }t/          |ddj        d         dz
  |d           fd!}                    |           t          j                     d S )"Nz@scan_path cannot be None, please specify it or specify ct_volume)r   r   r   zJsegmentation_path cannot be None, please specify it or specify mask_volumenew_seg_scanr   c                 "    i | ]\  }}|d v	||S ))r   0rv   )rw   keyvalues      r   
<dictcomp>z)show_scan_with_slider.<locals>.<dictcomp><  s/       !sE%xBWBWsBWBWBWr!   r   rT   )whiteredbluegreen   rS   tab10c                 &    g | ]} |          S rv   rv   rw   r   	base_cmaps     r   rx   z)show_scan_with_slider.<locals>.<listcomp>G  !    9991))A,,999r!         tab20c                 &    g | ]} |          S rv   rv   r   s     r   rx   z)show_scan_with_slider.<locals>.<listcomp>J  r   r!   nipy_spectralc                 &    g | ]} |          S rv   rv   r   s     r   rx   z)show_scan_with_slider.<locals>.<listcomp>M  r   r!   g      r   g333333?)bottomr	   r   )r   r}   r   r   )r   g333333?r)   g?Slicer   z%0.0f)valinitvalfmtc                 f   t          	j                  }
d d d d |f         }d d d d |f         }                    |                               t          j                            |dk    |                                         d|            j                                         d S )Nr   r   )	intvalset_datarC   r   r   	set_titlecanvas	draw_idle)r   slice_indexc_ctc_maskaxfigimg_displayr   mask_displayslidervolumes       r   updatez%show_scan_with_slider.<locals>.updateg  s    &*ooaaaK'(aaaK'(T"""be001fEEFFF
+k++,,,
r!   )rC   flipud	transposenibload	get_fdataitemsrA   r\   r   get_cmapr   r   r   r_   Nsubplotssubplots_adjustr   r   r   r   axesr   r@   
on_changedshow)	scan_pathsegmentation_path	ct_volumect_masksegmentation_dict
init_slicelabel_to_name	n_classesr&   r   r}   r   r   	slider_axr   r   r   r   r   r   r   r   r   s                  @@@@@@@@r   show_scan_with_sliderr    s    !!N "!!2<(;(;(E(E(G(GSSTT))X *))yL!233NCYOO
 
 J %6%<%<%>%>  M M""Q&I A~~222	
Y				"					FOOGY77	9999i(8(8999	i				2					FOOGY77	9999i(8(8999FOOOY??	9999i(8(8999 &!!D	$	C88$&AAD lnnGCs####!!!QQQ
"#D!!!QQQ
"#F))Dv)..K99
6Q;//dS   L LL&*&&''' ///00I7Av|A2Jw  F	 	 	 	 	 	 	 	 	 	 	 fHJJJJJr!   
renderings	renderingc                    | d d df         }| d d df         }| d d df         }t          j        t          j        |||dt          d|d                              }|                    t          |          j         d	| t          d
ddd          t          dddd                     t          j        |d           |	                    t          |          t          |dz             z  d           d S )Nr   r   r   r(   Viridis)r*   r   
colorscale)r   r   r   r+   r,   )dataz - XYZr	  )xaxis_titleyaxis_titlezaxis_title
aspectmode   )lrbt)rb   scenemarginTrV   z.html)	auto_open)
r   Figurer-   r.   update_layoutr   r   re   rf   
write_html)r%   dest_dir	file_namer   r   r   r   s          r   render_point_cloudr  v  s@   qqq!tAqqq!tAqqq!tA
)\QaI>>>
 
 
  C h$4444#&
 
 
 a1R(((     K4((((NNXi'1222d      r!   )r	   r
   T)r"   T)r0   r1   T)N)rq   )Nr5   r   Nr   )NNNNN)%matplotlib.pyplotpyplotr\   pathlibr   numpyrC   open3dr   re   plotly.graph_objectsgraph_objectsr   typingr   matplotlib.widgetsr   matplotlib.colorsr   r   nibabelr   IPythonr   r   strndarrayr    r/   r>   rQ   rp   r   r   r   r  r  rv   r!   r   <module>r-     s<                       				 ! ! ! ! ! !       % % % % % % : : : : : : : :                  ! ! ! ! ! ! MQ CO$   . Dbj1    ( 		 sBJ'   @$5 $5 $5N" " " "J8 8 8 8x
 
 
 
& OV' ' ' 'V T T T Tn )-\(:(:k      r!   