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() | ... | ... |