melage 0.0.65__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- melage/__init__.py +16 -0
- melage/cli.py +4 -0
- melage/graphics/GLGraphicsItem.py +286 -0
- melage/graphics/GLViewWidget.py +595 -0
- melage/graphics/Transform3D.py +55 -0
- melage/graphics/__init__.py +8 -0
- melage/graphics/functions.py +101 -0
- melage/graphics/items/GLAxisItem.py +149 -0
- melage/graphics/items/GLGridItem.py +178 -0
- melage/graphics/items/GLPolygonItem.py +77 -0
- melage/graphics/items/GLScatterPlotItem.py +135 -0
- melage/graphics/items/GLVolumeItem.py +280 -0
- melage/graphics/items/GLVolumeItem_b.py +237 -0
- melage/graphics/items/__init__.py +0 -0
- melage/graphics/shaders.py +202 -0
- melage/main.py +270 -0
- melage/requirements22.txt +25 -0
- melage/requirements_old.txt +28 -0
- melage/resource/0circle.png +0 -0
- melage/resource/0circle_faded.png +0 -0
- melage/resource/3d.png +0 -0
- melage/resource/3d.psd +0 -0
- melage/resource/3dFaded.png +0 -0
- melage/resource/Eraser.png +0 -0
- melage/resource/EraserFaded.png +0 -0
- melage/resource/EraserX.png +0 -0
- melage/resource/EraserXFaded.png +0 -0
- melage/resource/Eraser_icon.svg +79 -0
- melage/resource/Hand.png +0 -0
- melage/resource/HandIcons_0.png +0 -0
- melage/resource/Hand_IX.png +0 -0
- melage/resource/Hand_IXFaded.png +0 -0
- melage/resource/Handsqueezed.png +0 -0
- melage/resource/Handwriting (copy).png +0 -0
- melage/resource/Handwriting.png +0 -0
- melage/resource/HandwritingMinus.png +0 -0
- melage/resource/HandwritingMinusX.png +0 -0
- melage/resource/HandwritingPlus.png +0 -0
- melage/resource/HandwritingPlusX.png +0 -0
- melage/resource/Move_icon.svg +8 -0
- melage/resource/PngItem_2422924.png +0 -0
- melage/resource/about.png +0 -0
- melage/resource/about_logo.png +0 -0
- melage/resource/about_logo0.png +0 -0
- melage/resource/action_check.png +0 -0
- melage/resource/action_check_OFF.png +0 -0
- melage/resource/arrow).png +0 -0
- melage/resource/arrow.png +0 -0
- melage/resource/arrowFaded.png +0 -0
- melage/resource/arrow_org.png +0 -0
- melage/resource/arrow_org.png.png +0 -0
- melage/resource/arrows.png +0 -0
- melage/resource/authors.mp4 +0 -0
- melage/resource/box.png +0 -0
- melage/resource/check-image-icon-0.jpg +0 -0
- melage/resource/circle.png +0 -0
- melage/resource/circle_faded.png +0 -0
- melage/resource/circle_or.png +0 -0
- melage/resource/close.png +0 -0
- melage/resource/close_bg.png +0 -0
- melage/resource/color/Simple.txt +18 -0
- melage/resource/color/Tissue.txt +24 -0
- melage/resource/color/Tissue12.txt +27 -0
- melage/resource/color/albert_LUT.txt +102 -0
- melage/resource/color/mcrib_LUT.txt +102 -0
- melage/resource/color/pediatric1.txt +29 -0
- melage/resource/color/pediatric1_old.txt +27 -0
- melage/resource/color/pediatric2.txt +87 -0
- melage/resource/color/pediatric3.txt +29 -0
- melage/resource/color/pediatrics (copy).csv +103 -0
- melage/resource/color/tissue_seg.txt +4 -0
- melage/resource/contour.png +0 -0
- melage/resource/contour.svg +2 -0
- melage/resource/contourFaded.png +0 -0
- melage/resource/contourX.png +0 -0
- melage/resource/contourXFaded.png +0 -0
- melage/resource/dti.png +0 -0
- melage/resource/dti0.png +0 -0
- melage/resource/dti222.png +0 -0
- melage/resource/dti_or.png +0 -0
- melage/resource/eco.png +0 -0
- melage/resource/eco22.png +0 -0
- melage/resource/eco_old.png +0 -0
- melage/resource/eco_or.png +0 -0
- melage/resource/eco_or2.png +0 -0
- melage/resource/eco_seg.png +0 -0
- melage/resource/eco_seg_old.png +0 -0
- melage/resource/export.png +0 -0
- melage/resource/hand-grab-icon-10.jpg +0 -0
- melage/resource/hand-grab-icon-25.jpg +0 -0
- melage/resource/info.png +0 -0
- melage/resource/line.png +0 -0
- melage/resource/linefaded.png +0 -0
- melage/resource/load.png +0 -0
- melage/resource/main.ico +0 -0
- melage/resource/manual_images/3D_rightc.png +0 -0
- melage/resource/manual_images/3D_rightc_goto.png +0 -0
- melage/resource/manual_images/3D_rightc_paint.png +0 -0
- melage/resource/manual_images/3D_rightc_paint_draw1.png +0 -0
- melage/resource/manual_images/3D_rightc_paint_draw2.png +0 -0
- melage/resource/manual_images/3D_rightc_paint_render.png +0 -0
- melage/resource/manual_images/3D_rightc_paint_render2.png +0 -0
- melage/resource/manual_images/3D_rightc_paint_render3.png +0 -0
- melage/resource/manual_images/3D_rightc_paint_render4.png +0 -0
- melage/resource/manual_images/3D_rightc_paint_render5.png +0 -0
- melage/resource/manual_images/3D_rightc_paint_render6.png +0 -0
- melage/resource/manual_images/3D_rightc_seg.png +0 -0
- melage/resource/manual_images/exit_toolbar.png +0 -0
- melage/resource/manual_images/load_image_file.png +0 -0
- melage/resource/manual_images/load_image_file_openp.png +0 -0
- melage/resource/manual_images/main_page.png +0 -0
- melage/resource/manual_images/menu_file.png +0 -0
- melage/resource/manual_images/menu_file_export.png +0 -0
- melage/resource/manual_images/menu_file_import.png +0 -0
- melage/resource/manual_images/menu_file_settings.png +0 -0
- melage/resource/manual_images/menu_file_ss.png +0 -0
- melage/resource/manual_images/open_save_load.png +0 -0
- melage/resource/manual_images/panning_toolbar.png +0 -0
- melage/resource/manual_images/segmentation_toolbar.png +0 -0
- melage/resource/manual_images/tab_mri.png +0 -0
- melage/resource/manual_images/tab_us.png +0 -0
- melage/resource/manual_images/tabs.png +0 -0
- melage/resource/manual_images/toolbar_tools.png +0 -0
- melage/resource/manual_images/tools_basic.png +0 -0
- melage/resource/manual_images/tools_bet.png +0 -0
- melage/resource/manual_images/tools_cs.png +0 -0
- melage/resource/manual_images/tools_deepbet.png +0 -0
- melage/resource/manual_images/tools_imageinfo.png +0 -0
- melage/resource/manual_images/tools_maskO.png +0 -0
- melage/resource/manual_images/tools_masking.png +0 -0
- melage/resource/manual_images/tools_n4b.png +0 -0
- melage/resource/manual_images/tools_resize.png +0 -0
- melage/resource/manual_images/tools_ruler.png +0 -0
- melage/resource/manual_images/tools_seg.png +0 -0
- melage/resource/manual_images/tools_threshold.png +0 -0
- melage/resource/manual_images/tools_tools.png +0 -0
- melage/resource/manual_images/widget_color.png +0 -0
- melage/resource/manual_images/widget_color_add.png +0 -0
- melage/resource/manual_images/widget_color_add2.png +0 -0
- melage/resource/manual_images/widget_color_additional.png +0 -0
- melage/resource/manual_images/widget_images.png +0 -0
- melage/resource/manual_images/widget_images2.png +0 -0
- melage/resource/manual_images/widget_images3.png +0 -0
- melage/resource/manual_images/widget_marker.png +0 -0
- melage/resource/manual_images/widget_mri.png +0 -0
- melage/resource/manual_images/widget_mri2.png +0 -0
- melage/resource/manual_images/widget_segintensity.png +0 -0
- melage/resource/manual_images/widget_tab_mutualview.png +0 -0
- melage/resource/manual_images/widget_tab_mutualview2.png +0 -0
- melage/resource/manual_images/widget_table.png +0 -0
- melage/resource/manual_images/widget_table2.png +0 -0
- melage/resource/manual_images/widget_us.png +0 -0
- melage/resource/melage_top.ico +0 -0
- melage/resource/melage_top.png +0 -0
- melage/resource/melage_top0.png +0 -0
- melage/resource/melage_top1.png +0 -0
- melage/resource/melage_top4.png +0 -0
- melage/resource/mri (copy).png +0 -0
- melage/resource/mri.png +0 -0
- melage/resource/mri0.png +0 -0
- melage/resource/mri000.png +0 -0
- melage/resource/mri22.png +0 -0
- melage/resource/mri_big.png +0 -0
- melage/resource/mri_old.png +0 -0
- melage/resource/mri_seg.png +0 -0
- melage/resource/mri_seg_old.png +0 -0
- melage/resource/new.png +0 -0
- melage/resource/open.png +0 -0
- melage/resource/open2.png +0 -0
- melage/resource/pan.png +0 -0
- melage/resource/pencil.png +0 -0
- melage/resource/pencilFaded.png +0 -0
- melage/resource/points.png +0 -0
- melage/resource/pointsFaded.png +0 -0
- melage/resource/rotate.png +0 -0
- melage/resource/ruler.png +0 -0
- melage/resource/rulerFaded.png +0 -0
- melage/resource/s.png +0 -0
- melage/resource/s.psd +0 -0
- melage/resource/save.png +0 -0
- melage/resource/saveas.png +0 -0
- melage/resource/seg_mri.png +0 -0
- melage/resource/seg_mri2.png +0 -0
- melage/resource/settings.png +0 -0
- melage/resource/synch.png +0 -0
- melage/resource/synchFaded.png +0 -0
- melage/resource/theme/rc/.keep +1 -0
- melage/resource/theme/rc/arrow_down.png +0 -0
- melage/resource/theme/rc/arrow_down@2x.png +0 -0
- melage/resource/theme/rc/arrow_down_disabled.png +0 -0
- melage/resource/theme/rc/arrow_down_disabled@2x.png +0 -0
- melage/resource/theme/rc/arrow_down_focus.png +0 -0
- melage/resource/theme/rc/arrow_down_focus@2x.png +0 -0
- melage/resource/theme/rc/arrow_down_pressed.png +0 -0
- melage/resource/theme/rc/arrow_down_pressed@2x.png +0 -0
- melage/resource/theme/rc/arrow_left.png +0 -0
- melage/resource/theme/rc/arrow_left@2x.png +0 -0
- melage/resource/theme/rc/arrow_left_disabled.png +0 -0
- melage/resource/theme/rc/arrow_left_disabled@2x.png +0 -0
- melage/resource/theme/rc/arrow_left_focus.png +0 -0
- melage/resource/theme/rc/arrow_left_focus@2x.png +0 -0
- melage/resource/theme/rc/arrow_left_pressed.png +0 -0
- melage/resource/theme/rc/arrow_left_pressed@2x.png +0 -0
- melage/resource/theme/rc/arrow_right.png +0 -0
- melage/resource/theme/rc/arrow_right@2x.png +0 -0
- melage/resource/theme/rc/arrow_right_disabled.png +0 -0
- melage/resource/theme/rc/arrow_right_disabled@2x.png +0 -0
- melage/resource/theme/rc/arrow_right_focus.png +0 -0
- melage/resource/theme/rc/arrow_right_focus@2x.png +0 -0
- melage/resource/theme/rc/arrow_right_pressed.png +0 -0
- melage/resource/theme/rc/arrow_right_pressed@2x.png +0 -0
- melage/resource/theme/rc/arrow_up.png +0 -0
- melage/resource/theme/rc/arrow_up@2x.png +0 -0
- melage/resource/theme/rc/arrow_up_disabled.png +0 -0
- melage/resource/theme/rc/arrow_up_disabled@2x.png +0 -0
- melage/resource/theme/rc/arrow_up_focus.png +0 -0
- melage/resource/theme/rc/arrow_up_focus@2x.png +0 -0
- melage/resource/theme/rc/arrow_up_pressed.png +0 -0
- melage/resource/theme/rc/arrow_up_pressed@2x.png +0 -0
- melage/resource/theme/rc/base_icon.png +0 -0
- melage/resource/theme/rc/base_icon@2x.png +0 -0
- melage/resource/theme/rc/base_icon_disabled.png +0 -0
- melage/resource/theme/rc/base_icon_disabled@2x.png +0 -0
- melage/resource/theme/rc/base_icon_focus.png +0 -0
- melage/resource/theme/rc/base_icon_focus@2x.png +0 -0
- melage/resource/theme/rc/base_icon_pressed.png +0 -0
- melage/resource/theme/rc/base_icon_pressed@2x.png +0 -0
- melage/resource/theme/rc/branch_closed.png +0 -0
- melage/resource/theme/rc/branch_closed@2x.png +0 -0
- melage/resource/theme/rc/branch_closed_disabled.png +0 -0
- melage/resource/theme/rc/branch_closed_disabled@2x.png +0 -0
- melage/resource/theme/rc/branch_closed_focus.png +0 -0
- melage/resource/theme/rc/branch_closed_focus@2x.png +0 -0
- melage/resource/theme/rc/branch_closed_pressed.png +0 -0
- melage/resource/theme/rc/branch_closed_pressed@2x.png +0 -0
- melage/resource/theme/rc/branch_end.png +0 -0
- melage/resource/theme/rc/branch_end@2x.png +0 -0
- melage/resource/theme/rc/branch_end_disabled.png +0 -0
- melage/resource/theme/rc/branch_end_disabled@2x.png +0 -0
- melage/resource/theme/rc/branch_end_focus.png +0 -0
- melage/resource/theme/rc/branch_end_focus@2x.png +0 -0
- melage/resource/theme/rc/branch_end_pressed.png +0 -0
- melage/resource/theme/rc/branch_end_pressed@2x.png +0 -0
- melage/resource/theme/rc/branch_line.png +0 -0
- melage/resource/theme/rc/branch_line@2x.png +0 -0
- melage/resource/theme/rc/branch_line_disabled.png +0 -0
- melage/resource/theme/rc/branch_line_disabled@2x.png +0 -0
- melage/resource/theme/rc/branch_line_focus.png +0 -0
- melage/resource/theme/rc/branch_line_focus@2x.png +0 -0
- melage/resource/theme/rc/branch_line_pressed.png +0 -0
- melage/resource/theme/rc/branch_line_pressed@2x.png +0 -0
- melage/resource/theme/rc/branch_more.png +0 -0
- melage/resource/theme/rc/branch_more@2x.png +0 -0
- melage/resource/theme/rc/branch_more_disabled.png +0 -0
- melage/resource/theme/rc/branch_more_disabled@2x.png +0 -0
- melage/resource/theme/rc/branch_more_focus.png +0 -0
- melage/resource/theme/rc/branch_more_focus@2x.png +0 -0
- melage/resource/theme/rc/branch_more_pressed.png +0 -0
- melage/resource/theme/rc/branch_more_pressed@2x.png +0 -0
- melage/resource/theme/rc/branch_open.png +0 -0
- melage/resource/theme/rc/branch_open@2x.png +0 -0
- melage/resource/theme/rc/branch_open_disabled.png +0 -0
- melage/resource/theme/rc/branch_open_disabled@2x.png +0 -0
- melage/resource/theme/rc/branch_open_focus.png +0 -0
- melage/resource/theme/rc/branch_open_focus@2x.png +0 -0
- melage/resource/theme/rc/branch_open_pressed.png +0 -0
- melage/resource/theme/rc/branch_open_pressed@2x.png +0 -0
- melage/resource/theme/rc/checkbox_checked.png +0 -0
- melage/resource/theme/rc/checkbox_checked0.png +0 -0
- melage/resource/theme/rc/checkbox_checked@2x.png +0 -0
- melage/resource/theme/rc/checkbox_checked@2x0.png +0 -0
- melage/resource/theme/rc/checkbox_checked@2x000.png.png +0 -0
- melage/resource/theme/rc/checkbox_checked_disabled.png +0 -0
- melage/resource/theme/rc/checkbox_checked_disabled0.png +0 -0
- melage/resource/theme/rc/checkbox_checked_disabled@2x.png +0 -0
- melage/resource/theme/rc/checkbox_checked_disabled@2x0.png +0 -0
- melage/resource/theme/rc/checkbox_checked_focus.png +0 -0
- melage/resource/theme/rc/checkbox_checked_focus0.png +0 -0
- melage/resource/theme/rc/checkbox_checked_focus@2x.png +0 -0
- melage/resource/theme/rc/checkbox_checked_focus@2x0.png +0 -0
- melage/resource/theme/rc/checkbox_checked_pressed.png +0 -0
- melage/resource/theme/rc/checkbox_checked_pressed0.png +0 -0
- melage/resource/theme/rc/checkbox_checked_pressed@2x.png +0 -0
- melage/resource/theme/rc/checkbox_checked_pressed@2x0.png +0 -0
- melage/resource/theme/rc/checkbox_indeterminate.png +0 -0
- melage/resource/theme/rc/checkbox_indeterminate@2x.png +0 -0
- melage/resource/theme/rc/checkbox_indeterminate_disabled.png +0 -0
- melage/resource/theme/rc/checkbox_indeterminate_disabled@2x.png +0 -0
- melage/resource/theme/rc/checkbox_indeterminate_focus.png +0 -0
- melage/resource/theme/rc/checkbox_indeterminate_focus@2x.png +0 -0
- melage/resource/theme/rc/checkbox_indeterminate_pressed.png +0 -0
- melage/resource/theme/rc/checkbox_indeterminate_pressed@2x.png +0 -0
- melage/resource/theme/rc/checkbox_unchecked.png +0 -0
- melage/resource/theme/rc/checkbox_unchecked0.png +0 -0
- melage/resource/theme/rc/checkbox_unchecked00.png +0 -0
- melage/resource/theme/rc/checkbox_unchecked@2x.png +0 -0
- melage/resource/theme/rc/checkbox_unchecked@2x0.png +0 -0
- melage/resource/theme/rc/checkbox_unchecked@2x00.png +0 -0
- melage/resource/theme/rc/checkbox_unchecked_disabled.png +0 -0
- melage/resource/theme/rc/checkbox_unchecked_disabled0.png +0 -0
- melage/resource/theme/rc/checkbox_unchecked_disabled00.png +0 -0
- melage/resource/theme/rc/checkbox_unchecked_disabled@2x.png +0 -0
- melage/resource/theme/rc/checkbox_unchecked_disabled@2x0.png +0 -0
- melage/resource/theme/rc/checkbox_unchecked_disabled@2x00.png +0 -0
- melage/resource/theme/rc/checkbox_unchecked_focus.png +0 -0
- melage/resource/theme/rc/checkbox_unchecked_focus0.png +0 -0
- melage/resource/theme/rc/checkbox_unchecked_focus00.png +0 -0
- melage/resource/theme/rc/checkbox_unchecked_focus@2x.png +0 -0
- melage/resource/theme/rc/checkbox_unchecked_focus@2x0.png +0 -0
- melage/resource/theme/rc/checkbox_unchecked_focus@2x00.png +0 -0
- melage/resource/theme/rc/checkbox_unchecked_pressed.png +0 -0
- melage/resource/theme/rc/checkbox_unchecked_pressed0.png +0 -0
- melage/resource/theme/rc/checkbox_unchecked_pressed00.png +0 -0
- melage/resource/theme/rc/checkbox_unchecked_pressed@2x.png +0 -0
- melage/resource/theme/rc/checkbox_unchecked_pressed@2x0.png +0 -0
- melage/resource/theme/rc/checkbox_unchecked_pressed@2x00.png +0 -0
- melage/resource/theme/rc/line_horizontal.png +0 -0
- melage/resource/theme/rc/line_horizontal@2x.png +0 -0
- melage/resource/theme/rc/line_horizontal_disabled.png +0 -0
- melage/resource/theme/rc/line_horizontal_disabled@2x.png +0 -0
- melage/resource/theme/rc/line_horizontal_focus.png +0 -0
- melage/resource/theme/rc/line_horizontal_focus@2x.png +0 -0
- melage/resource/theme/rc/line_horizontal_pressed.png +0 -0
- melage/resource/theme/rc/line_horizontal_pressed@2x.png +0 -0
- melage/resource/theme/rc/line_vertical.png +0 -0
- melage/resource/theme/rc/line_vertical@2x.png +0 -0
- melage/resource/theme/rc/line_vertical_disabled.png +0 -0
- melage/resource/theme/rc/line_vertical_disabled@2x.png +0 -0
- melage/resource/theme/rc/line_vertical_focus.png +0 -0
- melage/resource/theme/rc/line_vertical_focus@2x.png +0 -0
- melage/resource/theme/rc/line_vertical_pressed.png +0 -0
- melage/resource/theme/rc/line_vertical_pressed@2x.png +0 -0
- melage/resource/theme/rc/radio_checked.png +0 -0
- melage/resource/theme/rc/radio_checked@2x.png +0 -0
- melage/resource/theme/rc/radio_checked_disabled.png +0 -0
- melage/resource/theme/rc/radio_checked_disabled@2x.png +0 -0
- melage/resource/theme/rc/radio_checked_focus.png +0 -0
- melage/resource/theme/rc/radio_checked_focus@2x.png +0 -0
- melage/resource/theme/rc/radio_checked_pressed.png +0 -0
- melage/resource/theme/rc/radio_checked_pressed@2x.png +0 -0
- melage/resource/theme/rc/radio_unchecked.png +0 -0
- melage/resource/theme/rc/radio_unchecked@2x.png +0 -0
- melage/resource/theme/rc/radio_unchecked_disabled.png +0 -0
- melage/resource/theme/rc/radio_unchecked_disabled@2x.png +0 -0
- melage/resource/theme/rc/radio_unchecked_focus.png +0 -0
- melage/resource/theme/rc/radio_unchecked_focus@2x.png +0 -0
- melage/resource/theme/rc/radio_unchecked_pressed.png +0 -0
- melage/resource/theme/rc/radio_unchecked_pressed@2x.png +0 -0
- melage/resource/theme/rc/toolbar_move_horizontal.png +0 -0
- melage/resource/theme/rc/toolbar_move_horizontal@2x.png +0 -0
- melage/resource/theme/rc/toolbar_move_horizontal_disabled.png +0 -0
- melage/resource/theme/rc/toolbar_move_horizontal_disabled@2x.png +0 -0
- melage/resource/theme/rc/toolbar_move_horizontal_focus.png +0 -0
- melage/resource/theme/rc/toolbar_move_horizontal_focus@2x.png +0 -0
- melage/resource/theme/rc/toolbar_move_horizontal_pressed.png +0 -0
- melage/resource/theme/rc/toolbar_move_horizontal_pressed@2x.png +0 -0
- melage/resource/theme/rc/toolbar_move_vertical.png +0 -0
- melage/resource/theme/rc/toolbar_move_vertical@2x.png +0 -0
- melage/resource/theme/rc/toolbar_move_vertical_disabled.png +0 -0
- melage/resource/theme/rc/toolbar_move_vertical_disabled@2x.png +0 -0
- melage/resource/theme/rc/toolbar_move_vertical_focus.png +0 -0
- melage/resource/theme/rc/toolbar_move_vertical_focus@2x.png +0 -0
- melage/resource/theme/rc/toolbar_move_vertical_pressed.png +0 -0
- melage/resource/theme/rc/toolbar_move_vertical_pressed@2x.png +0 -0
- melage/resource/theme/rc/toolbar_separator_horizontal.png +0 -0
- melage/resource/theme/rc/toolbar_separator_horizontal@2x.png +0 -0
- melage/resource/theme/rc/toolbar_separator_horizontal_disabled.png +0 -0
- melage/resource/theme/rc/toolbar_separator_horizontal_disabled@2x.png +0 -0
- melage/resource/theme/rc/toolbar_separator_horizontal_focus.png +0 -0
- melage/resource/theme/rc/toolbar_separator_horizontal_focus@2x.png +0 -0
- melage/resource/theme/rc/toolbar_separator_horizontal_pressed.png +0 -0
- melage/resource/theme/rc/toolbar_separator_horizontal_pressed@2x.png +0 -0
- melage/resource/theme/rc/toolbar_separator_vertical.png +0 -0
- melage/resource/theme/rc/toolbar_separator_vertical@2x.png +0 -0
- melage/resource/theme/rc/toolbar_separator_vertical_disabled.png +0 -0
- melage/resource/theme/rc/toolbar_separator_vertical_disabled@2x.png +0 -0
- melage/resource/theme/rc/toolbar_separator_vertical_focus.png +0 -0
- melage/resource/theme/rc/toolbar_separator_vertical_focus@2x.png +0 -0
- melage/resource/theme/rc/toolbar_separator_vertical_pressed.png +0 -0
- melage/resource/theme/rc/toolbar_separator_vertical_pressed@2x.png +0 -0
- melage/resource/theme/rc/transparent.png +0 -0
- melage/resource/theme/rc/transparent@2x.png +0 -0
- melage/resource/theme/rc/transparent_disabled.png +0 -0
- melage/resource/theme/rc/transparent_disabled@2x.png +0 -0
- melage/resource/theme/rc/transparent_focus.png +0 -0
- melage/resource/theme/rc/transparent_focus@2x.png +0 -0
- melage/resource/theme/rc/transparent_pressed.png +0 -0
- melage/resource/theme/rc/transparent_pressed@2x.png +0 -0
- melage/resource/theme/rc/window_close.png +0 -0
- melage/resource/theme/rc/window_close@2x.png +0 -0
- melage/resource/theme/rc/window_close_disabled.png +0 -0
- melage/resource/theme/rc/window_close_disabled@2x.png +0 -0
- melage/resource/theme/rc/window_close_focus.png +0 -0
- melage/resource/theme/rc/window_close_focus@2x.png +0 -0
- melage/resource/theme/rc/window_close_pressed.png +0 -0
- melage/resource/theme/rc/window_close_pressed@2x.png +0 -0
- melage/resource/theme/rc/window_grip.png +0 -0
- melage/resource/theme/rc/window_grip@2x.png +0 -0
- melage/resource/theme/rc/window_grip_disabled.png +0 -0
- melage/resource/theme/rc/window_grip_disabled@2x.png +0 -0
- melage/resource/theme/rc/window_grip_focus.png +0 -0
- melage/resource/theme/rc/window_grip_focus@2x.png +0 -0
- melage/resource/theme/rc/window_grip_pressed.png +0 -0
- melage/resource/theme/rc/window_grip_pressed@2x.png +0 -0
- melage/resource/theme/rc/window_minimize.png +0 -0
- melage/resource/theme/rc/window_minimize@2x.png +0 -0
- melage/resource/theme/rc/window_minimize_disabled.png +0 -0
- melage/resource/theme/rc/window_minimize_disabled@2x.png +0 -0
- melage/resource/theme/rc/window_minimize_focus.png +0 -0
- melage/resource/theme/rc/window_minimize_focus@2x.png +0 -0
- melage/resource/theme/rc/window_minimize_pressed.png +0 -0
- melage/resource/theme/rc/window_minimize_pressed@2x.png +0 -0
- melage/resource/theme/rc/window_undock.png +0 -0
- melage/resource/theme/rc/window_undock@2x.png +0 -0
- melage/resource/theme/rc/window_undock_disabled.png +0 -0
- melage/resource/theme/rc/window_undock_disabled@2x.png +0 -0
- melage/resource/theme/rc/window_undock_focus.png +0 -0
- melage/resource/theme/rc/window_undock_focus@2x.png +0 -0
- melage/resource/theme/rc/window_undock_pressed.png +0 -0
- melage/resource/theme/rc/window_undock_pressed@2x.png +0 -0
- melage/resource/theme/style.qss +2223 -0
- melage/resource/tract.png +0 -0
- melage/resource/view1.png +0 -0
- melage/resource/view1_eco.png +0 -0
- melage/resource/view1_mri.png +0 -0
- melage/resource/view1_seg.png +0 -0
- melage/resource/view2.png +0 -0
- melage/resource/view2_seg.png +0 -0
- melage/resource/w.png +0 -0
- melage/resource/zoom_in.png +0 -0
- melage/resource/zoom_inFaded.png +0 -0
- melage/resource/zoom_out.png +0 -0
- melage/resource/zoom_outFaded.png +0 -0
- melage/some_notes.txt +3 -0
- melage/utils/DispalyIm.py +2788 -0
- melage/utils/GMM.py +720 -0
- melage/utils/Shaders_120.py +257 -0
- melage/utils/Shaders_330.py +314 -0
- melage/utils/Shaders_bu.py +314 -0
- melage/utils/__init__0.py +7 -0
- melage/utils/brain_extraction_helper.py +234 -0
- melage/utils/custom_QScrollBar.py +61 -0
- melage/utils/glScientific.py +1554 -0
- melage/utils/glScientific_bc.py +1585 -0
- melage/utils/readData.py +1061 -0
- melage/utils/registration.py +512 -0
- melage/utils/source_folder.py +18 -0
- melage/utils/utils.py +3808 -0
- melage/version.txt +1 -0
- melage/widgets/ApplyMask.py +212 -0
- melage/widgets/ChangeSystem.py +152 -0
- melage/widgets/DeepLModels/InfantSegment/Unet.py +464 -0
- melage/widgets/DeepLModels/NPP/dataset/mri_dataset_affine.py +149 -0
- melage/widgets/DeepLModels/NPP/models/checkpoints/npp_v1.pth.py +0 -0
- melage/widgets/DeepLModels/NPP/models/losses.py +146 -0
- melage/widgets/DeepLModels/NPP/models/model.py +272 -0
- melage/widgets/DeepLModels/NPP/models/utils.py +303 -0
- melage/widgets/DeepLModels/NPP/npp.py +116 -0
- melage/widgets/DeepLModels/NPP/requirements.txt +8 -0
- melage/widgets/DeepLModels/NPP/train/train.py +116 -0
- melage/widgets/DeepLModels/Unet3DAtt.py +657 -0
- melage/widgets/DeepLModels/Unet3D_basic.py +648 -0
- melage/widgets/DeepLModels/new_unet.py +652 -0
- melage/widgets/DeepLModels/new_unet_old.py +639 -0
- melage/widgets/DeepLModels/new_unet_old2.py +658 -0
- melage/widgets/HistImage.py +153 -0
- melage/widgets/ImageThresholding.py +222 -0
- melage/widgets/MaskOperations.py +147 -0
- melage/widgets/N4Dialog.py +241 -0
- melage/widgets/Segmentation/FCM.py +1553 -0
- melage/widgets/Segmentation/__init__.py +588 -0
- melage/widgets/Segmentation/utils.py +417 -0
- melage/widgets/SemiAutoSeg.py +666 -0
- melage/widgets/Synthstrip.py +141 -0
- melage/widgets/__init__0.py +5 -0
- melage/widgets/about.py +246 -0
- melage/widgets/activation.py +437 -0
- melage/widgets/activator.py +147 -0
- melage/widgets/be_dl.py +409 -0
- melage/widgets/be_dl_unet3d.py +441 -0
- melage/widgets/brain_extraction.py +855 -0
- melage/widgets/brain_extraction_dl.py +887 -0
- melage/widgets/brain_extraction_dl_bu.py +869 -0
- melage/widgets/colorwidget.py +100 -0
- melage/widgets/dockWidgets.py +2005 -0
- melage/widgets/enhanceImWidget.py +109 -0
- melage/widgets/fileDialog_widget.py +275 -0
- melage/widgets/iminfo.py +346 -0
- melage/widgets/mainwindow_widget.py +6775 -0
- melage/widgets/melageAbout.py +123 -0
- melage/widgets/openglWidgets.py +556 -0
- melage/widgets/registrationWidget.py +342 -0
- melage/widgets/repeat_widget.py +74 -0
- melage/widgets/screenshot_widget.py +138 -0
- melage/widgets/settings_widget.py +77 -0
- melage/widgets/tranformationWidget.py +275 -0
- melage-0.0.65.dist-info/METADATA +742 -0
- melage-0.0.65.dist-info/RECORD +501 -0
- melage-0.0.65.dist-info/WHEEL +5 -0
- melage-0.0.65.dist-info/entry_points.txt +2 -0
- melage-0.0.65.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,595 @@
|
|
|
1
|
+
|
|
2
|
+
from PyQt5 import QtCore, QtGui, QtWidgets
|
|
3
|
+
from PyQt5.QtWidgets import QOpenGLWidget
|
|
4
|
+
from OpenGL.GL import *
|
|
5
|
+
import numpy as np
|
|
6
|
+
from OpenGL.GLUT import *
|
|
7
|
+
from collections import defaultdict
|
|
8
|
+
from . import functions as fn
|
|
9
|
+
from PyQt5.QtCore import pyqtSignal
|
|
10
|
+
Vector = QtGui.QVector3D
|
|
11
|
+
ShareWidget = None
|
|
12
|
+
|
|
13
|
+
__AUTHOR__ = 'Bahram Jafrasteh'
|
|
14
|
+
"""
|
|
15
|
+
Inspiration from pyqtgraph https://github.com/pyqtgraph/pyqtgraph
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class GLViewWidget(QOpenGLWidget):
|
|
20
|
+
"""
|
|
21
|
+
Basic widget for displaying 3D data
|
|
22
|
+
- Rotation/scale controls
|
|
23
|
+
- Axis/grid display
|
|
24
|
+
- Export options
|
|
25
|
+
|
|
26
|
+
High-DPI displays: Qt5 should automatically detect the correct resolution.
|
|
27
|
+
For Qt4, specify the ``devicePixelRatio`` argument when initializing the
|
|
28
|
+
widget (usually this value is 1-2).
|
|
29
|
+
"""
|
|
30
|
+
el_az_dis = pyqtSignal(object)
|
|
31
|
+
def __init__(self, parent=None, devicePixelRatio=None):
|
|
32
|
+
global ShareWidget
|
|
33
|
+
|
|
34
|
+
if ShareWidget is None:
|
|
35
|
+
## create a dummy widget to allow sharing objects (textures, shaders, etc) between views
|
|
36
|
+
ShareWidget = QOpenGLWidget()
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
QtWidgets.QOpenGLWidget.__init__(self, parent)
|
|
40
|
+
|
|
41
|
+
self.setFocusPolicy(QtCore.Qt.ClickFocus)
|
|
42
|
+
self.opts = {
|
|
43
|
+
'devicePixelRatio': devicePixelRatio
|
|
44
|
+
}
|
|
45
|
+
self.reset()
|
|
46
|
+
self.items = defaultdict(list)
|
|
47
|
+
|
|
48
|
+
self.noRepeatKeys = [QtCore.Qt.Key_Right, QtCore.Qt.Key_Left, QtCore.Qt.Key_Up, QtCore.Qt.Key_Down, QtCore.Qt.Key_PageUp, QtCore.Qt.Key_PageDown]
|
|
49
|
+
self.keysPressed = {}
|
|
50
|
+
self.keyTimer = QtCore.QTimer()
|
|
51
|
+
self.keyTimer.timeout.connect(self.evalKeyState)
|
|
52
|
+
|
|
53
|
+
self.makeCurrent()
|
|
54
|
+
self.installEventFilter(self)
|
|
55
|
+
|
|
56
|
+
def reset(self):
|
|
57
|
+
"""
|
|
58
|
+
Initialize the widget state or reset the current state to the original state.
|
|
59
|
+
"""
|
|
60
|
+
self.opts['center'] = Vector(0,0,0) ## will always appear at the center of the widget
|
|
61
|
+
self.opts['distance'] = 10.0 ## distance of camera from center
|
|
62
|
+
self.opts['fov'] = 60 ## horizontal field of view in degrees
|
|
63
|
+
self.opts['elevation'] = 30 ## camera's angle of elevation in degrees
|
|
64
|
+
self.opts['azimuth'] = 45 ## camera's azimuthal angle in degrees
|
|
65
|
+
## (rotation around z-axis 0 points along x-axis)
|
|
66
|
+
self.opts['viewport'] = None ## glViewport params; None == whole widget
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def addItem(self, item, itemKey):
|
|
70
|
+
"""
|
|
71
|
+
By Bahram Jafrasteh
|
|
72
|
+
:param item:
|
|
73
|
+
:param itemKey:
|
|
74
|
+
:return:
|
|
75
|
+
"""
|
|
76
|
+
if itemKey in self.items:
|
|
77
|
+
self.removeItem(itemKey)
|
|
78
|
+
self.items[itemKey] = item
|
|
79
|
+
|
|
80
|
+
if hasattr(item, 'initializeGL'):
|
|
81
|
+
self.makeCurrent()
|
|
82
|
+
try:
|
|
83
|
+
item.initializeGL()
|
|
84
|
+
except:
|
|
85
|
+
self.checkOpenGLVersion('Error while adding item %s to GLViewWidget.' % str(item))
|
|
86
|
+
|
|
87
|
+
item._setView(self)
|
|
88
|
+
#print "set view", item, self, item.view()
|
|
89
|
+
self.update()
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def removeItem(self, itemKey):
|
|
95
|
+
"""
|
|
96
|
+
By Bahram Jafrasteh
|
|
97
|
+
Remove the item from the scene.
|
|
98
|
+
"""
|
|
99
|
+
#self.items.remove(item)
|
|
100
|
+
if itemKey not in self.items:
|
|
101
|
+
return
|
|
102
|
+
self.items[itemKey]._setView(None)
|
|
103
|
+
self.items.pop(itemKey)
|
|
104
|
+
#item._setView(None)
|
|
105
|
+
self.update()
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def clear(self):
|
|
109
|
+
"""
|
|
110
|
+
Remove all items from the scene.
|
|
111
|
+
"""
|
|
112
|
+
keys = []
|
|
113
|
+
for key in self.items.keys():
|
|
114
|
+
if key == 'xyz' or key == 'ax':
|
|
115
|
+
continue
|
|
116
|
+
item = self.items[key]
|
|
117
|
+
item._setView(None)
|
|
118
|
+
keys.append(key)
|
|
119
|
+
for key in keys:
|
|
120
|
+
self.items.pop(key)
|
|
121
|
+
#self.items = defaultdict(list)
|
|
122
|
+
self.update()
|
|
123
|
+
|
|
124
|
+
def initializeGL(self):
|
|
125
|
+
self.resizeGL(self.width(), self.height())
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def getViewport(self):
|
|
130
|
+
vp = self.opts['viewport']
|
|
131
|
+
dpr = self.devicePixelRatio()
|
|
132
|
+
if vp is None:
|
|
133
|
+
return (0, 0, int(self.width() * dpr), int(self.height() * dpr))
|
|
134
|
+
else:
|
|
135
|
+
return tuple([int(x * dpr) for x in vp])
|
|
136
|
+
|
|
137
|
+
def _updateScreen(self, screen):
|
|
138
|
+
"""
|
|
139
|
+
By Bahram Jafrasteh
|
|
140
|
+
:param screen:
|
|
141
|
+
:return:
|
|
142
|
+
"""
|
|
143
|
+
self._updatePixelRatio()
|
|
144
|
+
if screen is not None:
|
|
145
|
+
screen.physicalDotsPerInchChanged.connect(self._updatePixelRatio)
|
|
146
|
+
screen.logicalDotsPerInchChanged.connect(self._updatePixelRatio)
|
|
147
|
+
|
|
148
|
+
def _updatePixelRatio(self):
|
|
149
|
+
"""
|
|
150
|
+
By Bahram Jafrasteh
|
|
151
|
+
:return:
|
|
152
|
+
"""
|
|
153
|
+
event = QtGui.QResizeEvent(self.size(), self.size())
|
|
154
|
+
self.resizeEvent(event)
|
|
155
|
+
|
|
156
|
+
def showEvent(self, event):
|
|
157
|
+
"""
|
|
158
|
+
By Bahram Jafrasteh
|
|
159
|
+
:param event:
|
|
160
|
+
:return:
|
|
161
|
+
"""
|
|
162
|
+
window = self.window().windowHandle()
|
|
163
|
+
window.screenChanged.connect(self._updateScreen)
|
|
164
|
+
self._updateScreen(window.screen())
|
|
165
|
+
|
|
166
|
+
def mousePressEvent(self, ev):
|
|
167
|
+
"""
|
|
168
|
+
By Bahram Jafrasteh
|
|
169
|
+
:param ev:
|
|
170
|
+
:return:
|
|
171
|
+
"""
|
|
172
|
+
self.mousePos = ev.localPos()
|
|
173
|
+
|
|
174
|
+
self.showEvent(0)
|
|
175
|
+
z = glReadPixels(ev.x(), self.height() - ev.y(), 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT)[0][0]
|
|
176
|
+
|
|
177
|
+
per = np.array(self.m.copyDataTo()).reshape((4, 4)).transpose().flatten()
|
|
178
|
+
zFar = 0.5 * per[14] * (1.0 - ((per[10] - 1.0) / (per[10] + 1.0)))
|
|
179
|
+
zNear = zFar * (per[10] + 1.0) / (per[10] - 1.0)
|
|
180
|
+
|
|
181
|
+
ndcx = 2 * self.mousePos.x() / self.width() - 1
|
|
182
|
+
ndcy = 1 - 2 * self.mousePos.y() / self.height()
|
|
183
|
+
points = np.matmul(np.linalg.inv(self.mvpProj.reshape((4, 4)).transpose()), np.array([ndcx,ndcy, 2*z-1, 1]))
|
|
184
|
+
points /= points[3]
|
|
185
|
+
|
|
186
|
+
#self.point3dpos.emit(points)
|
|
187
|
+
print(points)
|
|
188
|
+
|
|
189
|
+
def devicePixelRatio(self):
|
|
190
|
+
dpr = self.opts['devicePixelRatio']
|
|
191
|
+
if dpr is not None:
|
|
192
|
+
return dpr
|
|
193
|
+
|
|
194
|
+
if hasattr(QOpenGLWidget, 'devicePixelRatio'):
|
|
195
|
+
return QOpenGLWidget.devicePixelRatio(self)
|
|
196
|
+
else:
|
|
197
|
+
return 1.0
|
|
198
|
+
|
|
199
|
+
def resizeGL(self, w, h):
|
|
200
|
+
pass
|
|
201
|
+
#glViewport(*self.getViewport())
|
|
202
|
+
#self.update()
|
|
203
|
+
|
|
204
|
+
def setProjection(self, region=None):
|
|
205
|
+
|
|
206
|
+
self.m = self.projectionMatrix(region)
|
|
207
|
+
self.a = self.viewMatrix()
|
|
208
|
+
|
|
209
|
+
ma = self.m * self.a
|
|
210
|
+
self.mvpProj = np.array(ma.copyDataTo()).reshape((4, 4)).transpose().flatten()
|
|
211
|
+
|
|
212
|
+
#m = self.projectionMatrix(region)
|
|
213
|
+
glMatrixMode(GL_PROJECTION)
|
|
214
|
+
glLoadIdentity()
|
|
215
|
+
a = np.array(self.m.copyDataTo()).reshape((4,4))
|
|
216
|
+
glMultMatrixf(a.transpose())
|
|
217
|
+
|
|
218
|
+
def projectionMatrix(self, region=None):
|
|
219
|
+
if region is None:
|
|
220
|
+
dpr = self.devicePixelRatio()
|
|
221
|
+
region = (0, 0, self.width() * dpr, self.height() * dpr)
|
|
222
|
+
|
|
223
|
+
x0, y0, w, h = self.getViewport()
|
|
224
|
+
dist = self.opts['distance']
|
|
225
|
+
fov = self.opts['fov']
|
|
226
|
+
nearClip = dist * 0.001
|
|
227
|
+
farClip = dist * 1000.
|
|
228
|
+
|
|
229
|
+
r = nearClip * np.tan(fov * 0.5 * np.pi / 180.)
|
|
230
|
+
t = r * h / w
|
|
231
|
+
|
|
232
|
+
## Note that X0 and width in these equations must be the values used in viewport
|
|
233
|
+
left = r * ((region[0]-x0) * (2.0/w) - 1)
|
|
234
|
+
right = r * ((region[0]+region[2]-x0) * (2.0/w) - 1)
|
|
235
|
+
bottom = t * ((region[1]-y0) * (2.0/h) - 1)
|
|
236
|
+
top = t * ((region[1]+region[3]-y0) * (2.0/h) - 1)
|
|
237
|
+
|
|
238
|
+
tr = QtGui.QMatrix4x4()
|
|
239
|
+
tr.frustum(left, right, bottom, top, nearClip, farClip)
|
|
240
|
+
return tr
|
|
241
|
+
|
|
242
|
+
def setModelview(self):
|
|
243
|
+
glMatrixMode(GL_MODELVIEW)
|
|
244
|
+
glLoadIdentity()
|
|
245
|
+
#self.a = self.viewMatrix()
|
|
246
|
+
a = np.array(self.a.copyDataTo()).reshape((4,4))
|
|
247
|
+
glMultMatrixf(a.transpose())
|
|
248
|
+
|
|
249
|
+
def viewMatrix(self):
|
|
250
|
+
tr = QtGui.QMatrix4x4()
|
|
251
|
+
tr.translate( 0.0, 0.0, -self.opts['distance'])
|
|
252
|
+
tr.rotate(self.opts['elevation']-90, 1, 0, 0)
|
|
253
|
+
tr.rotate(self.opts['azimuth']+90, 0, 0, -1)
|
|
254
|
+
center = self.opts['center']
|
|
255
|
+
tr.translate(-center.x(), -center.y(), -center.z())
|
|
256
|
+
return tr
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
def paintGL(self, region=None, viewport=None, useItemNames=False):
|
|
260
|
+
"""
|
|
261
|
+
viewport specifies the arguments to glViewport. If None, then we use self.opts['viewport']
|
|
262
|
+
region specifies the sub-region of self.opts['viewport'] that should be rendered.
|
|
263
|
+
Note that we may use viewport != self.opts['viewport'] when exporting.
|
|
264
|
+
"""
|
|
265
|
+
if viewport is None:
|
|
266
|
+
glViewport(*self.getViewport())
|
|
267
|
+
else:
|
|
268
|
+
glViewport(*viewport)
|
|
269
|
+
self.setProjection(region=region)
|
|
270
|
+
self.setModelview()
|
|
271
|
+
bgcolor = self.opts['bgcolor']
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_ACCUM_BUFFER_BIT)
|
|
275
|
+
#glClearColor(bgcolor[0], bgcolor[1], bgcolor[2], 0.5)
|
|
276
|
+
glClearColor(bgcolor[0], bgcolor[1], bgcolor[2], bgcolor[3])
|
|
277
|
+
|
|
278
|
+
self.drawItemTree(useItemNames=useItemNames)
|
|
279
|
+
|
|
280
|
+
def drawItemTree(self, item=None, useItemNames=False):
|
|
281
|
+
if item is None:
|
|
282
|
+
items = [self.items[key] for key in self.items.keys() if self.items[key].parentItem() is None]
|
|
283
|
+
else:
|
|
284
|
+
items = item.childItems()
|
|
285
|
+
items.append(item)
|
|
286
|
+
#items1 = [item for item in items if
|
|
287
|
+
# hasattr(item, 'sliceDensity')]
|
|
288
|
+
#items2 =[item for item in items if not hasattr(item, 'sliceDensity')]
|
|
289
|
+
items.sort(key=lambda a: a.depthValue())
|
|
290
|
+
|
|
291
|
+
#items= items1 + items2
|
|
292
|
+
|
|
293
|
+
for i in items:
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
if not i.visible():
|
|
297
|
+
continue
|
|
298
|
+
if i is item:
|
|
299
|
+
try:
|
|
300
|
+
glPushAttrib(GL_ALL_ATTRIB_BITS)
|
|
301
|
+
if useItemNames:
|
|
302
|
+
glLoadName(i._id)
|
|
303
|
+
self._itemNames[i._id] = i
|
|
304
|
+
i.paint()
|
|
305
|
+
except Exception as e:
|
|
306
|
+
#from .. import debug
|
|
307
|
+
#debug.printExc()
|
|
308
|
+
print(e)
|
|
309
|
+
msg = "Error while drawing item %s." % str(item)
|
|
310
|
+
ver = glGetString(GL_VERSION)
|
|
311
|
+
if ver is not None:
|
|
312
|
+
ver = ver.split()[0]
|
|
313
|
+
if int(ver.split(b'.')[0]) < 2:
|
|
314
|
+
print(msg + " The original exception is printed above; however, pyqtgraph requires OpenGL version 2.0 or greater for many of its 3D features and your OpenGL version is %s. Installing updated display drivers may resolve this issue." % ver)
|
|
315
|
+
else:
|
|
316
|
+
print(msg)
|
|
317
|
+
|
|
318
|
+
finally:
|
|
319
|
+
glPopAttrib()
|
|
320
|
+
else:
|
|
321
|
+
glMatrixMode(GL_MODELVIEW)
|
|
322
|
+
glPushMatrix()
|
|
323
|
+
try:
|
|
324
|
+
tr = i.transform()
|
|
325
|
+
a = np.array(tr.copyDataTo()).reshape((4,4))
|
|
326
|
+
glMultMatrixf(a.transpose())
|
|
327
|
+
self.drawItemTree(i, useItemNames=useItemNames)
|
|
328
|
+
finally:
|
|
329
|
+
glMatrixMode(GL_MODELVIEW)
|
|
330
|
+
glPopMatrix()
|
|
331
|
+
|
|
332
|
+
def setCameraPosition(self, pos=None, distance=None, elevation=None, azimuth=None, rotation=None):
|
|
333
|
+
"""
|
|
334
|
+
By Bahram Jafrasteh
|
|
335
|
+
:param pos:
|
|
336
|
+
:param distance:
|
|
337
|
+
:param elevation:
|
|
338
|
+
:param azimuth:
|
|
339
|
+
:param rotation:
|
|
340
|
+
:return:
|
|
341
|
+
"""
|
|
342
|
+
if pos is not None:
|
|
343
|
+
self.opts['center'] = pos
|
|
344
|
+
if distance is not None:
|
|
345
|
+
self.opts['distance'] = distance
|
|
346
|
+
if rotation is not None:
|
|
347
|
+
# set with quaternion
|
|
348
|
+
self.opts['rotation'] = rotation
|
|
349
|
+
else:
|
|
350
|
+
# set with elevation-azimuth, restored for compatibility
|
|
351
|
+
eu = self.opts['rotation'].toEulerAngles()
|
|
352
|
+
if azimuth is not None:
|
|
353
|
+
eu.setZ(-azimuth-90)
|
|
354
|
+
if elevation is not None:
|
|
355
|
+
eu.setX(elevation-90)
|
|
356
|
+
self.opts['rotation'] = QtGui.QQuaternion.fromEulerAngles(eu)
|
|
357
|
+
self.update()
|
|
358
|
+
|
|
359
|
+
def cameraPosition(self):
|
|
360
|
+
"""Return current position of camera based on center, dist, elevation, and azimuth"""
|
|
361
|
+
center = self.opts['center']
|
|
362
|
+
dist = self.opts['distance']
|
|
363
|
+
elev = self.opts['elevation'] * np.pi/180.
|
|
364
|
+
azim = self.opts['azimuth'] * np.pi/180.
|
|
365
|
+
|
|
366
|
+
pos = Vector(
|
|
367
|
+
center.x() + dist * np.cos(elev) * np.cos(azim),
|
|
368
|
+
center.y() + dist * np.cos(elev) * np.sin(azim),
|
|
369
|
+
center.z() + dist * np.sin(elev)
|
|
370
|
+
)
|
|
371
|
+
|
|
372
|
+
return pos
|
|
373
|
+
|
|
374
|
+
def orbit(self, azim, elev):
|
|
375
|
+
"""Orbits the camera around the center position. *azim* and *elev* are given in degrees."""
|
|
376
|
+
self.opts['azimuth'] += azim
|
|
377
|
+
self.opts['elevation'] = np.clip(self.opts['elevation'] + elev, -180, 180)
|
|
378
|
+
self.el_az_dis.emit([self.opts['elevation'], self.opts['azimuth'], self.opts['distance']])
|
|
379
|
+
self.update()
|
|
380
|
+
|
|
381
|
+
def pan(self, dx, dy, dz, relative='global'):
|
|
382
|
+
"""
|
|
383
|
+
Moves the center (look-at) position while holding the camera in place.
|
|
384
|
+
|
|
385
|
+
============== =======================================================
|
|
386
|
+
**Arguments:**
|
|
387
|
+
*dx* Distance to pan in x direction
|
|
388
|
+
*dy* Distance to pan in y direction
|
|
389
|
+
*dz* Distance to pan in z direction
|
|
390
|
+
*relative* String that determines the direction of dx,dy,dz.
|
|
391
|
+
If "global", then the global coordinate system is used.
|
|
392
|
+
If "view", then the z axis is aligned with the view
|
|
393
|
+
direction, and x and y axes are inthe plane of the
|
|
394
|
+
view: +x points right, +y points up.
|
|
395
|
+
If "view-upright", then x is in the global xy plane and
|
|
396
|
+
points to the right side of the view, y is in the
|
|
397
|
+
global xy plane and orthogonal to x, and z points in
|
|
398
|
+
the global z direction.
|
|
399
|
+
============== =======================================================
|
|
400
|
+
|
|
401
|
+
Distances are scaled roughly such that a value of 1.0 moves
|
|
402
|
+
by one pixel on screen.
|
|
403
|
+
|
|
404
|
+
Prior to version 0.11, *relative* was expected to be either True (x-aligned) or
|
|
405
|
+
False (global). These values are deprecated but still recognized.
|
|
406
|
+
"""
|
|
407
|
+
# for backward compatibility:
|
|
408
|
+
relative = {True: "view-upright", False: "global"}.get(relative, relative)
|
|
409
|
+
|
|
410
|
+
if relative == 'global':
|
|
411
|
+
self.opts['center'] += QtGui.QVector3D(dx, dy, dz)
|
|
412
|
+
elif relative == 'view-upright':
|
|
413
|
+
cPos = self.cameraPosition()
|
|
414
|
+
cVec = self.opts['center'] - cPos
|
|
415
|
+
dist = cVec.length() ## distance from camera to center
|
|
416
|
+
xDist = dist * 2. * np.tan(0.5 * self.opts['fov'] * np.pi / 180.) ## approx. width of view at distance of center point
|
|
417
|
+
xScale = xDist / self.width()
|
|
418
|
+
zVec = QtGui.QVector3D(0,0,1)
|
|
419
|
+
xVec = QtGui.QVector3D.crossProduct(zVec, cVec).normalized()
|
|
420
|
+
yVec = QtGui.QVector3D.crossProduct(xVec, zVec).normalized()
|
|
421
|
+
self.opts['center'] = self.opts['center'] + xVec * xScale * dx + yVec * xScale * dy + zVec * xScale * dz
|
|
422
|
+
elif relative == 'view':
|
|
423
|
+
# pan in plane of camera
|
|
424
|
+
elev = np.radians(self.opts['elevation'])
|
|
425
|
+
azim = np.radians(self.opts['azimuth'])
|
|
426
|
+
fov = np.radians(self.opts['fov'])
|
|
427
|
+
dist = (self.opts['center'] - self.cameraPosition()).length()
|
|
428
|
+
fov_factor = np.tan(fov / 2) * 2
|
|
429
|
+
scale_factor = dist * fov_factor / self.width()
|
|
430
|
+
z = scale_factor * np.cos(elev) * dy
|
|
431
|
+
x = scale_factor * (np.sin(azim) * dx - np.sin(elev) * np.cos(azim) * dy)
|
|
432
|
+
y = scale_factor * (np.cos(azim) * dx + np.sin(elev) * np.sin(azim) * dy)
|
|
433
|
+
self.opts['center'] += QtGui.QVector3D(x, -y, z)
|
|
434
|
+
else:
|
|
435
|
+
raise ValueError("relative argument must be global, view, or view-upright")
|
|
436
|
+
|
|
437
|
+
self.update()
|
|
438
|
+
|
|
439
|
+
def pixelSize(self, pos):
|
|
440
|
+
"""
|
|
441
|
+
Return the approximate size of a screen pixel at the location pos
|
|
442
|
+
Pos may be a Vector or an (N,3) array of locations
|
|
443
|
+
"""
|
|
444
|
+
cam = self.cameraPosition()
|
|
445
|
+
if isinstance(pos, np.ndarray):
|
|
446
|
+
cam = np.array(cam).reshape((1,)*(pos.ndim-1)+(3,))
|
|
447
|
+
dist = ((pos-cam)**2).sum(axis=-1)**0.5
|
|
448
|
+
else:
|
|
449
|
+
dist = (pos-cam).length()
|
|
450
|
+
xDist = dist * 2. * np.tan(0.5 * self.opts['fov'] * np.pi / 180.)
|
|
451
|
+
return xDist / self.width()
|
|
452
|
+
|
|
453
|
+
|
|
454
|
+
|
|
455
|
+
def mouseMoveEvent(self, ev):
|
|
456
|
+
diff = ev.pos() - self.mousePos
|
|
457
|
+
self.mousePos = ev.pos()
|
|
458
|
+
|
|
459
|
+
if ev.buttons() == QtCore.Qt.LeftButton:
|
|
460
|
+
if (ev.modifiers() & QtCore.Qt.ControlModifier):
|
|
461
|
+
self.pan(diff.x(), diff.y(), 0, relative='view')
|
|
462
|
+
else:
|
|
463
|
+
self.orbit(-diff.x(), diff.y())
|
|
464
|
+
elif ev.buttons() == QtCore.Qt.MidButton:
|
|
465
|
+
if (ev.modifiers() & QtCore.Qt.ControlModifier):
|
|
466
|
+
self.pan(diff.x(), 0, diff.y(), relative='view-upright')
|
|
467
|
+
else:
|
|
468
|
+
self.pan(diff.x(), diff.y(), 0, relative='view-upright')
|
|
469
|
+
self.el_az_dis.emit([self.opts['elevation'], self.opts['azimuth'], self.opts['distance']])
|
|
470
|
+
|
|
471
|
+
|
|
472
|
+
|
|
473
|
+
def wheelEvent(self, ev):
|
|
474
|
+
delta = 0
|
|
475
|
+
|
|
476
|
+
delta = ev.angleDelta().x()
|
|
477
|
+
if delta == 0:
|
|
478
|
+
delta = ev.angleDelta().y()
|
|
479
|
+
if (ev.modifiers() & QtCore.Qt.ControlModifier):
|
|
480
|
+
self.opts['fov'] *= 0.999**delta
|
|
481
|
+
else:
|
|
482
|
+
self.opts['distance'] *= 0.999**delta
|
|
483
|
+
self.update()
|
|
484
|
+
self.el_az_dis.emit([self.opts['elevation'], self.opts['azimuth'], self.opts['distance']])
|
|
485
|
+
|
|
486
|
+
def keyPressEvent(self, ev):
|
|
487
|
+
if ev.key() in self.noRepeatKeys:
|
|
488
|
+
ev.accept()
|
|
489
|
+
if ev.isAutoRepeat():
|
|
490
|
+
return
|
|
491
|
+
self.keysPressed[ev.key()] = 1
|
|
492
|
+
self.evalKeyState()
|
|
493
|
+
|
|
494
|
+
def keyReleaseEvent(self, ev):
|
|
495
|
+
if ev.key() in self.noRepeatKeys:
|
|
496
|
+
ev.accept()
|
|
497
|
+
if ev.isAutoRepeat():
|
|
498
|
+
return
|
|
499
|
+
try:
|
|
500
|
+
del self.keysPressed[ev.key()]
|
|
501
|
+
except:
|
|
502
|
+
self.keysPressed = {}
|
|
503
|
+
self.evalKeyState()
|
|
504
|
+
|
|
505
|
+
def evalKeyState(self):
|
|
506
|
+
speed = 1.0
|
|
507
|
+
if len(self.keysPressed) > 0:
|
|
508
|
+
for key in self.keysPressed:
|
|
509
|
+
if key == QtCore.Qt.Key_Right:
|
|
510
|
+
self.orbit(azim=-speed, elev=0)
|
|
511
|
+
elif key == QtCore.Qt.Key_Left:
|
|
512
|
+
self.orbit(azim=speed, elev=0)
|
|
513
|
+
elif key == QtCore.Qt.Key_Up:
|
|
514
|
+
self.orbit(azim=0, elev=-speed)
|
|
515
|
+
elif key == QtCore.Qt.Key_Down:
|
|
516
|
+
self.orbit(azim=0, elev=speed)
|
|
517
|
+
elif key == QtCore.Qt.Key_PageUp:
|
|
518
|
+
pass
|
|
519
|
+
elif key == QtCore.Qt.Key_PageDown:
|
|
520
|
+
pass
|
|
521
|
+
self.keyTimer.start(16)
|
|
522
|
+
else:
|
|
523
|
+
self.keyTimer.stop()
|
|
524
|
+
|
|
525
|
+
def checkOpenGLVersion(self, msg):
|
|
526
|
+
"""
|
|
527
|
+
Give exception additional context about version support.
|
|
528
|
+
|
|
529
|
+
Only to be called from within exception handler.
|
|
530
|
+
As this check is only performed on error,
|
|
531
|
+
unsupported versions might still work!
|
|
532
|
+
"""
|
|
533
|
+
|
|
534
|
+
# Check for unsupported version
|
|
535
|
+
verString = glGetString(GL_VERSION)
|
|
536
|
+
ver = verString.split()[0]
|
|
537
|
+
# If not OpenGL ES...
|
|
538
|
+
if str(ver.split(b'.')[0]).isdigit():
|
|
539
|
+
verNumber = int(ver.split(b'.')[0])
|
|
540
|
+
# ...and version is supported:
|
|
541
|
+
if verNumber >= 2:
|
|
542
|
+
# OpenGL version is fine, raise the original exception
|
|
543
|
+
raise
|
|
544
|
+
|
|
545
|
+
|
|
546
|
+
|
|
547
|
+
# Notify about unsupported version
|
|
548
|
+
raise Exception(
|
|
549
|
+
msg + "\n" + \
|
|
550
|
+
"pyqtgraph.opengl: Requires >= OpenGL 2.0 (not ES); Found %s" % verString
|
|
551
|
+
)
|
|
552
|
+
|
|
553
|
+
|
|
554
|
+
|
|
555
|
+
def setMaxCoords(self, maxCoord):
|
|
556
|
+
self.maxCoord = maxCoord
|
|
557
|
+
|
|
558
|
+
|
|
559
|
+
def renderText(self, text='', pos=(0,0,0), size=(1,1), rotation=(0,0,0)):
|
|
560
|
+
"""
|
|
561
|
+
By Bahram Jafrasteh
|
|
562
|
+
:param text: text to be printed
|
|
563
|
+
:param pos: 3d position of the text
|
|
564
|
+
:param size: width and height of the text
|
|
565
|
+
:param rotation: 3d rotation angles
|
|
566
|
+
:return: 3d text
|
|
567
|
+
"""
|
|
568
|
+
|
|
569
|
+
|
|
570
|
+
glutInit()
|
|
571
|
+
glPushMatrix()
|
|
572
|
+
|
|
573
|
+
|
|
574
|
+
width, height = size
|
|
575
|
+
#g = 0
|
|
576
|
+
glRotatef(rotation[0], 1, 0, 0)
|
|
577
|
+
glRotatef(rotation[1], 0, 1, 0)
|
|
578
|
+
glRotatef(rotation[2], 0, 0, 1)
|
|
579
|
+
glRasterPos3f(pos[0], pos[1], pos[2])
|
|
580
|
+
l = list(text)
|
|
581
|
+
|
|
582
|
+
|
|
583
|
+
|
|
584
|
+
for char in l:
|
|
585
|
+
glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_10, ord(char))
|
|
586
|
+
|
|
587
|
+
glTranslatef(width, 0, 0)
|
|
588
|
+
#glScale(10,10,10)
|
|
589
|
+
|
|
590
|
+
glPopMatrix()
|
|
591
|
+
return
|
|
592
|
+
|
|
593
|
+
|
|
594
|
+
|
|
595
|
+
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
from . import functions as fn
|
|
4
|
+
from PyQt5 import QtGui
|
|
5
|
+
import numpy as np
|
|
6
|
+
Vector = QtGui.QVector3D
|
|
7
|
+
|
|
8
|
+
"""
|
|
9
|
+
taken from pyqtgraph https://github.com/pyqtgraph/pyqtgraph
|
|
10
|
+
"""
|
|
11
|
+
class Transform3D(QtGui.QMatrix4x4):
|
|
12
|
+
"""
|
|
13
|
+
Extension of QMatrix4x4 with some helpful methods added.
|
|
14
|
+
"""
|
|
15
|
+
def __init__(self, *args):
|
|
16
|
+
if len(args) == 1:
|
|
17
|
+
if isinstance(args[0], (list, tuple, np.ndarray)):
|
|
18
|
+
args = [x for y in args[0] for x in y]
|
|
19
|
+
if len(args) != 16:
|
|
20
|
+
raise TypeError("Single argument to Transform3D must have 16 elements.")
|
|
21
|
+
elif isinstance(args[0], QtGui.QMatrix4x4):
|
|
22
|
+
args = list(args[0].copyDataTo())
|
|
23
|
+
|
|
24
|
+
QtGui.QMatrix4x4.__init__(self, *args)
|
|
25
|
+
|
|
26
|
+
def matrix(self, nd=3):
|
|
27
|
+
if nd == 3:
|
|
28
|
+
return np.array(self.copyDataTo()).reshape(4,4)
|
|
29
|
+
elif nd == 2:
|
|
30
|
+
m = np.array(self.copyDataTo()).reshape(4,4)
|
|
31
|
+
m[2] = m[3]
|
|
32
|
+
m[:,2] = m[:,3]
|
|
33
|
+
return m[:3,:3]
|
|
34
|
+
else:
|
|
35
|
+
raise Exception("Argument 'nd' must be 2 or 3")
|
|
36
|
+
|
|
37
|
+
def map(self, obj):
|
|
38
|
+
"""
|
|
39
|
+
Extends QMatrix4x4.map() to allow mapping (3, ...) arrays of coordinates
|
|
40
|
+
"""
|
|
41
|
+
if isinstance(obj, np.ndarray) and obj.shape[0] in (2,3):
|
|
42
|
+
if obj.ndim >= 2:
|
|
43
|
+
return fn.transformCoordinates(self, obj)
|
|
44
|
+
elif obj.ndim == 1:
|
|
45
|
+
v = QtGui.QMatrix4x4.map(self, Vector(obj))
|
|
46
|
+
return np.array([v.x(), v.y(), v.z()])[:obj.shape[0]]
|
|
47
|
+
elif isinstance(obj, (list, tuple)):
|
|
48
|
+
v = QtGui.QMatrix4x4.map(self, Vector(obj))
|
|
49
|
+
return type(obj)([v.x(), v.y(), v.z()])[:len(obj)]
|
|
50
|
+
else:
|
|
51
|
+
return QtGui.QMatrix4x4.map(self, obj)
|
|
52
|
+
|
|
53
|
+
def inverted(self):
|
|
54
|
+
inv, b = QtGui.QMatrix4x4.inverted(self)
|
|
55
|
+
return Transform3D(inv), b
|