Commit 160fcc1f698b3818c4fa794007e190783f6337a9
1 parent
718f8735
Exists in
master
and in
68 other branches
ADD: Export surface in several formats and vtkImageData
Showing
4 changed files
with
115 additions
and
17 deletions
Show diff stats
invesalius/constants.py
| ... | ... | @@ -218,6 +218,10 @@ FILETYPE_RIB = wx.NewId() |
| 218 | 218 | FILETYPE_STL = wx.NewId() |
| 219 | 219 | FILETYPE_VRML = wx.NewId() |
| 220 | 220 | FILETYPE_OBJ = wx.NewId() |
| 221 | +FILETYPE_VTP = wx.NewId() | |
| 222 | +FILETYPE_PLY = wx.NewId() | |
| 223 | + | |
| 224 | +FILETYPE_IMAGEDATA = wx.NewId() | |
| 221 | 225 | |
| 222 | 226 | FILETYPE_BMP = wx.NewId() |
| 223 | 227 | FILETYPE_JPG = wx.NewId() | ... | ... |
invesalius/data/slice_.py
| ... | ... | @@ -4,6 +4,7 @@ import vtk |
| 4 | 4 | import wx.lib.pubsub as ps |
| 5 | 5 | |
| 6 | 6 | import constants as const |
| 7 | +import imagedata_utils as iu | |
| 7 | 8 | from mask import Mask |
| 8 | 9 | from project import Project |
| 9 | 10 | from utils import Singleton |
| ... | ... | @@ -60,6 +61,7 @@ class Slice(object): |
| 60 | 61 | 'Change colour table from background image') |
| 61 | 62 | |
| 62 | 63 | ps.Publisher().subscribe(self.InputImageWidget, 'Input Image in the widget') |
| 64 | + ps.Publisher().subscribe(self.OnExportMask,'Export mask to file') | |
| 63 | 65 | |
| 64 | 66 | def __set_current_mask_threshold_limits(self, pubsub_evt): |
| 65 | 67 | thresh_min = pubsub_evt.data[0] |
| ... | ... | @@ -544,3 +546,15 @@ class Slice(object): |
| 544 | 546 | imagedata_mask.Update() |
| 545 | 547 | |
| 546 | 548 | return imagedata_mask |
| 549 | + | |
| 550 | + | |
| 551 | + def OnExportMask(self, pubsub_evt): | |
| 552 | + #imagedata = self.current_mask.imagedata | |
| 553 | + imagedata = self.imagedata | |
| 554 | + filename, filetype = pubsub_evt.data | |
| 555 | + if (filetype == const.FILETYPE_IMAGEDATA): | |
| 556 | + iu.Export(imagedata, filename) | |
| 557 | + | |
| 558 | + | |
| 559 | + | |
| 560 | + | ... | ... |
invesalius/data/surface.py
| ... | ... | @@ -284,7 +284,11 @@ class SurfaceManager(): |
| 284 | 284 | |
| 285 | 285 | def OnExportSurface(self, pubsub_evt): |
| 286 | 286 | filename, filetype = pubsub_evt.data |
| 287 | - if filetype == const.FILETYPE_STL: | |
| 287 | + if (filetype == const.FILETYPE_STL) or\ | |
| 288 | + (filetype == const.FILETYPE_VTP): | |
| 289 | + | |
| 290 | + # First we identify all surfaces that are selected | |
| 291 | + # (if any) | |
| 288 | 292 | proj = prj.Project() |
| 289 | 293 | polydata_list = [] |
| 290 | 294 | for index in proj.surface_dict: |
| ... | ... | @@ -299,10 +303,24 @@ class SurfaceManager(): |
| 299 | 303 | else: |
| 300 | 304 | polydata = pu.Merge(polydata_list) |
| 301 | 305 | |
| 302 | - writer = vtk.vtkSTLWriter() | |
| 303 | - writer.SetFileTypeToBinary() | |
| 306 | + | |
| 307 | + # Having a polydata that represents all surfaces | |
| 308 | + # selected, we write it, according to filetype | |
| 309 | + if filetype == const.FILETYPE_STL: | |
| 310 | + writer = vtk.vtkSTLWriter() | |
| 311 | + writer.SetFileTypeToBinary() | |
| 312 | + elif filetype == const.FILETYPE_VTP: | |
| 313 | + writer = vtk.vtkXMLPolyDataWriter() | |
| 314 | + elif filetype == const.FILETYPE_IV: | |
| 315 | + writer = vtk.vtkIVWriter() | |
| 316 | + elif filetype == const.FILETYPE_PLY: | |
| 317 | + writer = vtk.vtkPLYWriter() | |
| 318 | + writer.SetFileTypeToBinary() | |
| 319 | + writer.SetDataByteOrderToLittleEndian() | |
| 320 | + #writer.SetColorModeToUniformCellColor() | |
| 321 | + #writer.SetColor(255, 0, 0) | |
| 322 | + | |
| 304 | 323 | writer.SetFileName(filename) |
| 305 | 324 | writer.SetInput(polydata) |
| 306 | 325 | writer.Write() |
| 307 | 326 | |
| 308 | - | ... | ... |
invesalius/gui/task_exporter.py
| ... | ... | @@ -28,26 +28,34 @@ import wx.lib.pubsub as ps |
| 28 | 28 | import constants as const |
| 29 | 29 | import project as proj |
| 30 | 30 | |
| 31 | +BTN_MASK = wx.NewId() | |
| 31 | 32 | BTN_PICTURE = wx.NewId() |
| 32 | 33 | BTN_SURFACE = wx.NewId() |
| 33 | 34 | BTN_REPORT = wx.NewId() |
| 34 | 35 | BTN_REQUEST_RP = wx.NewId() |
| 35 | 36 | |
| 36 | 37 | WILDCARD_SAVE_3D = "Inventor (*.iv)|*.iv|"\ |
| 38 | + "PLY (*.ply)|*.ply|"\ | |
| 37 | 39 | "Renderman (*.rib)|*.rib|"\ |
| 38 | 40 | "STL (*.stl)|*.stl|"\ |
| 39 | 41 | "VRML (*.vrml)|*.vrml|"\ |
| 42 | + "VTK PolyData (*.vtp)|*.vtp|"\ | |
| 40 | 43 | "Wavefront (*.obj)|*.obj" |
| 44 | + | |
| 41 | 45 | INDEX_TO_TYPE_3D = {0: const.FILETYPE_IV, |
| 42 | - 1: const.FILETYPE_RIB, | |
| 43 | - 2: const.FILETYPE_STL, | |
| 44 | - 3: const.FILETYPE_VRML, | |
| 45 | - 4: const.FILETYPE_OBJ} | |
| 46 | + 1: const.FILETYPE_PLY, | |
| 47 | + 2: const.FILETYPE_RIB, | |
| 48 | + 3: const.FILETYPE_STL, | |
| 49 | + 4: const.FILETYPE_VRML, | |
| 50 | + 5: const.FILETYPE_VTP, | |
| 51 | + 6: const.FILETYPE_OBJ} | |
| 46 | 52 | INDEX_TO_EXTENSION = {0: "iv", |
| 47 | - 1: "rib", | |
| 48 | - 2: "stl", | |
| 49 | - 3: "vrml", | |
| 50 | - 4: "obj"} | |
| 53 | + 1: "ply", | |
| 54 | + 2: "rib", | |
| 55 | + 3: "stl", | |
| 56 | + 4: "vrml", | |
| 57 | + 5: "vtp", | |
| 58 | + 6: "obj"} | |
| 51 | 59 | |
| 52 | 60 | WILDCARD_SAVE_2D = "BMP (*.bmp)|*.bmp|"\ |
| 53 | 61 | "JPEG (*.jpg)|*.jpg|"\ |
| ... | ... | @@ -62,6 +70,8 @@ INDEX_TO_TYPE_2D = {0: const.FILETYPE_BMP, |
| 62 | 70 | 4: const.FILETYPE_POV, |
| 63 | 71 | 5: const.FILETYPE_OBJ} |
| 64 | 72 | |
| 73 | +WILDCARD_SAVE_MASK = "VTK ImageData (*.vti)|*.vti" | |
| 74 | + | |
| 65 | 75 | |
| 66 | 76 | class TaskPanel(wx.Panel): |
| 67 | 77 | def __init__(self, parent): |
| ... | ... | @@ -109,6 +119,17 @@ class InnerTaskPanel(wx.Panel): |
| 109 | 119 | link_export_surface.Bind(hl.EVT_HYPERLINK_LEFT, |
| 110 | 120 | self.OnLinkExportSurface) |
| 111 | 121 | |
| 122 | + tooltip = wx.ToolTip("Export 3D mask (voxels)") | |
| 123 | + link_export_mask = hl.HyperLinkCtrl(self, -1,"Export mask...") | |
| 124 | + link_export_mask.SetUnderlines(False, False, False) | |
| 125 | + link_export_mask.SetColours("BLACK", "BLACK", "BLACK") | |
| 126 | + link_export_mask.SetToolTip(tooltip) | |
| 127 | + link_export_mask.AutoBrowse(False) | |
| 128 | + link_export_mask.UpdateLink() | |
| 129 | + link_export_mask.Bind(hl.EVT_HYPERLINK_LEFT, | |
| 130 | + self.OnLinkExportMask) | |
| 131 | + | |
| 132 | + | |
| 112 | 133 | #tooltip = wx.ToolTip("Request rapid prototyping services") |
| 113 | 134 | #link_request_rp = hl.HyperLinkCtrl(self,-1,"Request rapid prototyping...") |
| 114 | 135 | #link_request_rp.SetUnderlines(False, False, False) |
| ... | ... | @@ -136,14 +157,19 @@ class InnerTaskPanel(wx.Panel): |
| 136 | 157 | BMP_TAKE_PICTURE = wx.Bitmap(\ |
| 137 | 158 | "../icons/tool_photo_original.png", |
| 138 | 159 | wx.BITMAP_TYPE_PNG) |
| 160 | + BMP_EXPORT_MASK = wx.Bitmap("../icons/mask.png", | |
| 161 | + wx.BITMAP_TYPE_PNG) | |
| 139 | 162 | else: |
| 140 | 163 | BMP_EXPORT_SURFACE = wx.Bitmap("../icons/surface_export.png", |
| 141 | 164 | wx.BITMAP_TYPE_PNG) |
| 142 | 165 | BMP_TAKE_PICTURE = wx.Bitmap("../icons/tool_photo.png", |
| 143 | 166 | wx.BITMAP_TYPE_PNG) |
| 167 | + BMP_EXPORT_MASK = wx.Bitmap("../icons/mask_small.png", | |
| 168 | + wx.BITMAP_TYPE_PNG) | |
| 144 | 169 | |
| 145 | 170 | |
| 146 | - bmp_list = [BMP_TAKE_PICTURE, BMP_EXPORT_SURFACE] | |
| 171 | + bmp_list = [BMP_TAKE_PICTURE, BMP_EXPORT_SURFACE, | |
| 172 | + BMP_EXPORT_MASK] | |
| 147 | 173 | for bmp in bmp_list: |
| 148 | 174 | bmp.SetWidth(25) |
| 149 | 175 | bmp.SetHeight(25) |
| ... | ... | @@ -157,6 +183,9 @@ class InnerTaskPanel(wx.Panel): |
| 157 | 183 | button_surface = pbtn.PlateButton(self, BTN_SURFACE, "", |
| 158 | 184 | BMP_EXPORT_SURFACE, |
| 159 | 185 | style=button_style) |
| 186 | + button_mask = pbtn.PlateButton(self, BTN_MASK, "", | |
| 187 | + BMP_EXPORT_MASK, | |
| 188 | + style=button_style) | |
| 160 | 189 | #button_request_rp = pbtn.PlateButton(self, BTN_REQUEST_RP, "", |
| 161 | 190 | # BMP_IMPORT, style=button_style) |
| 162 | 191 | #button_report = pbtn.PlateButton(self, BTN_REPORT, "", |
| ... | ... | @@ -170,12 +199,14 @@ class InnerTaskPanel(wx.Panel): |
| 170 | 199 | flag_link = wx.EXPAND|wx.GROW|wx.LEFT|wx.TOP |
| 171 | 200 | flag_button = wx.EXPAND | wx.GROW |
| 172 | 201 | |
| 173 | - fixed_sizer = wx.FlexGridSizer(rows=2, cols=2, hgap=2, vgap=0) | |
| 202 | + fixed_sizer = wx.FlexGridSizer(rows=3, cols=2, hgap=2, vgap=0) | |
| 174 | 203 | fixed_sizer.AddGrowableCol(0, 1) |
| 175 | 204 | fixed_sizer.AddMany([ (link_export_picture, 1, flag_link, 3), |
| 176 | 205 | (button_picture, 0, flag_button), |
| 177 | 206 | (link_export_surface, 1, flag_link, 3), |
| 178 | - (button_surface, 0, flag_button)])#, | |
| 207 | + (button_surface, 0, flag_button),#])#, | |
| 208 | + (link_export_mask, 1, flag_link, 3), | |
| 209 | + (button_mask, 0, flag_button)]) | |
| 179 | 210 | #(link_report, 0, flag_link, 3), |
| 180 | 211 | #(button_report, 0, flag_button), |
| 181 | 212 | #(link_request_rp, 1, flag_link, 3), |
| ... | ... | @@ -193,8 +224,37 @@ class InnerTaskPanel(wx.Panel): |
| 193 | 224 | def OnLinkExportPicture(self, evt=None): |
| 194 | 225 | pass |
| 195 | 226 | |
| 227 | + def OnLinkExportMask(self, evt=None): | |
| 228 | + project = proj.Project() | |
| 229 | + print "OnLinkEportMask" | |
| 230 | + if sys.platform == 'win32': | |
| 231 | + project_name = project.name | |
| 232 | + else: | |
| 233 | + project_name = project.name+".vti" | |
| 234 | + | |
| 235 | + | |
| 236 | + dlg = wx.FileDialog(None, | |
| 237 | + "Save mask as...", # title | |
| 238 | + "", # last used directory | |
| 239 | + project_name, # filename | |
| 240 | + WILDCARD_SAVE_MASK, | |
| 241 | + wx.SAVE|wx.OVERWRITE_PROMPT) | |
| 242 | + dlg.SetFilterIndex(0) # default is VTI | |
| 243 | + | |
| 244 | + if dlg.ShowModal() == wx.ID_OK: | |
| 245 | + filename = dlg.GetPath() | |
| 246 | + print "filename", filename | |
| 247 | + extension = "vti" | |
| 248 | + if sys.platform != 'win32': | |
| 249 | + if filename.split(".")[-1] != extension: | |
| 250 | + filename = filename + "."+ extension | |
| 251 | + filetype = const.FILETYPE_IMAGEDATA | |
| 252 | + ps.Publisher().sendMessage('Export mask to file', | |
| 253 | + (filename, filetype)) | |
| 254 | + | |
| 196 | 255 | |
| 197 | 256 | def OnLinkExportSurface(self, evt=None): |
| 257 | + "OnLinkExportSurface" | |
| 198 | 258 | project = proj.Project() |
| 199 | 259 | n_surface = 0 |
| 200 | 260 | |
| ... | ... | @@ -215,7 +275,7 @@ class InnerTaskPanel(wx.Panel): |
| 215 | 275 | project_name, # filename |
| 216 | 276 | WILDCARD_SAVE_3D, |
| 217 | 277 | wx.SAVE|wx.OVERWRITE_PROMPT) |
| 218 | - dlg.SetFilterIndex(2) # default is STL | |
| 278 | + dlg.SetFilterIndex(3) # default is STL | |
| 219 | 279 | |
| 220 | 280 | if dlg.ShowModal() == wx.ID_OK: |
| 221 | 281 | filetype_index = dlg.GetFilterIndex() |
| ... | ... | @@ -252,5 +312,7 @@ class InnerTaskPanel(wx.Panel): |
| 252 | 312 | self.OnLinkExportSurface() |
| 253 | 313 | elif id == BTN_REPORT: |
| 254 | 314 | self.OnLinkReport() |
| 255 | - else: #elif id == BTN_REQUEST_RP: | |
| 315 | + elif id == BTN_REQUEST_RP: | |
| 256 | 316 | self.OnLinkRequestRP() |
| 317 | + else:# id == BTN_MASK: | |
| 318 | + self.OnLinkExportMask() | ... | ... |