Commit dca44b9bc7a095f9bf4d7f3f3e9edaf70fe16e4f

Authored by Thiago Franco de Moraes
Committed by GitHub
1 parent 011095a8
Exists in master

Now the Canvas does not have direct access to the measurements, it is responsibi…

…lity of the viewer to add to the canvas what it needs to render.(#43)

Better doc
The canvas does not have direct access to the measurements
More generic code. The canvas only receives the renderers not the viewer.
invesalius/data/measures.py
@@ -575,7 +575,7 @@ class LinearMeasure(object): @@ -575,7 +575,7 @@ class LinearMeasure(object):
575 points = [] 575 points = []
576 for p in self.points: 576 for p in self.points:
577 coord.SetValue(p) 577 coord.SetValue(p)
578 - cx, cy = coord.GetComputedDisplayValue(canvas.viewer.slice_data.renderer) 578 + cx, cy = coord.GetComputedDisplayValue(canvas.evt_renderer)
579 # canvas.draw_circle((cx, cy), 2.5) 579 # canvas.draw_circle((cx, cy), 2.5)
580 points.append((cx, cy)) 580 points.append((cx, cy))
581 581
@@ -835,7 +835,8 @@ class AngularMeasure(object): @@ -835,7 +835,8 @@ class AngularMeasure(object):
835 points = [] 835 points = []
836 for p in self.points: 836 for p in self.points:
837 coord.SetValue(p) 837 coord.SetValue(p)
838 - cx, cy = coord.GetComputedDisplayValue(canvas.viewer.slice_data.renderer) 838 + cx, cy = coord.GetComputedDoubleDisplayValue(canvas.evt_renderer)
  839 + print cx, cy
839 # canvas.draw_circle((cx, cy), 2.5) 840 # canvas.draw_circle((cx, cy), 2.5)
840 points.append((cx, cy)) 841 points.append((cx, cy))
841 842
invesalius/data/viewer_slice.py
@@ -148,15 +148,30 @@ class ContourMIPConfig(wx.Panel): @@ -148,15 +148,30 @@ class ContourMIPConfig(wx.Panel):
148 148
149 149
150 class CanvasRendererCTX: 150 class CanvasRendererCTX:
151 - def __init__(self, viewer):  
152 - self.viewer = viewer  
153 - self.canvas_renderer = viewer.slice_data.canvas_renderer 151 + def __init__(self, evt_renderer, canvas_renderer):
  152 + """
  153 + A Canvas to render over a vtktRenderer.
  154 +
  155 + Params:
  156 + evt_renderer: a vtkRenderer which this class is going to watch for
  157 + any render event to update the canvas content.
  158 + canvas_renderer: the vtkRenderer where the canvas is going to be
  159 + added.
  160 +
  161 + This class uses wx.GraphicsContext to render to a vtkImage.
  162 +
  163 + TODO: Verify why in Windows the color are strange when using transparency.
  164 + TODO: Add support to evento (ex. click on a square)
  165 + """
  166 + self.canvas_renderer = canvas_renderer
  167 + self.evt_renderer = evt_renderer
154 self._size = self.canvas_renderer.GetSize() 168 self._size = self.canvas_renderer.GetSize()
  169 + self.draw_list = []
155 self.gc = None 170 self.gc = None
156 self.last_cam_modif_time = -1 171 self.last_cam_modif_time = -1
157 self.modified = True 172 self.modified = True
158 self._init_canvas() 173 self._init_canvas()
159 - viewer.slice_data.renderer.AddObserver("StartEvent", self.OnPaint) 174 + evt_renderer.AddObserver("StartEvent", self.OnPaint)
160 175
161 def _init_canvas(self): 176 def _init_canvas(self):
162 w, h = self._size 177 w, h = self._size
@@ -203,7 +218,7 @@ class CanvasRendererCTX: @@ -203,7 +218,7 @@ class CanvasRendererCTX:
203 self._size = size 218 self._size = size
204 self._resize_canvas(w, h) 219 self._resize_canvas(w, h)
205 220
206 - cam_modif_time = self.viewer.cam.GetMTime() 221 + cam_modif_time = self.evt_renderer.GetActiveCamera().GetMTime()
207 if (not self.modified) and cam_modif_time == self.last_cam_modif_time: 222 if (not self.modified) and cam_modif_time == self.last_cam_modif_time:
208 return 223 return
209 224
@@ -233,10 +248,8 @@ class CanvasRendererCTX: @@ -233,10 +248,8 @@ class CanvasRendererCTX:
233 gc.Scale(1, -1) 248 gc.Scale(1, -1)
234 249
235 modified = False 250 modified = False
236 - for (m, mr) in self.viewer.measures.get(self.viewer.orientation, self.viewer.slice_data.number):  
237 - if not m.visible:  
238 - continue  
239 - mr.draw_to_canvas(gc, self) 251 + for d in self.draw_list:
  252 + d.draw_to_canvas(gc, self)
240 modified = True 253 modified = True
241 254
242 gc.Destroy() 255 gc.Destroy()
@@ -250,6 +263,30 @@ class CanvasRendererCTX: @@ -250,6 +263,30 @@ class CanvasRendererCTX:
250 self._cv_image.Modified() 263 self._cv_image.Modified()
251 self.modified = False 264 self.modified = False
252 265
  266 + def calc_text_size(self, text, font=None):
  267 + """
  268 + Given an unicode text and a font returns the width and height of the
  269 + rendered text in pixels.
  270 +
  271 + Params:
  272 + text: An unicode text.
  273 + font: An wxFont.
  274 +
  275 + Returns:
  276 + A tuple with width and height values in pixels
  277 + """
  278 + if self.gc is None:
  279 + return None
  280 + gc = self.gc
  281 +
  282 + if font is None:
  283 + font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
  284 +
  285 + _font = gc.CreateFont(font)
  286 + gc.SetFont(_font)
  287 + w, h = gc.GetTextExtent(text)
  288 + return w, h
  289 +
253 def draw_line(self, pos0, pos1, arrow_start=False, arrow_end=False, colour=(255, 0, 0, 128), width=2, style=wx.SOLID): 290 def draw_line(self, pos0, pos1, arrow_start=False, arrow_end=False, colour=(255, 0, 0, 128), width=2, style=wx.SOLID):
254 """ 291 """
255 Draw a line from pos0 to pos1 292 Draw a line from pos0 to pos1
@@ -1224,7 +1261,7 @@ class Viewer(wx.Panel): @@ -1224,7 +1261,7 @@ class Viewer(wx.Panel):
1224 self.cam = self.slice_data.renderer.GetActiveCamera() 1261 self.cam = self.slice_data.renderer.GetActiveCamera()
1225 self.__build_cross_lines() 1262 self.__build_cross_lines()
1226 1263
1227 - self.canvas = CanvasRendererCTX(self) 1264 + self.canvas = CanvasRendererCTX(self.slice_data.renderer, self.slice_data.canvas_renderer)
1228 1265
1229 # Set the slice number to the last slice to ensure the camera if far 1266 # Set the slice number to the last slice to ensure the camera if far
1230 # enough to show all slices. 1267 # enough to show all slices.
@@ -1341,6 +1378,16 @@ class Viewer(wx.Panel): @@ -1341,6 +1378,16 @@ class Viewer(wx.Panel):
1341 self.interactor.Render() 1378 self.interactor.Render()
1342 1379
1343 def UpdateCanvas(self, evt=None): 1380 def UpdateCanvas(self, evt=None):
  1381 + for (m, mr) in self.measures.get(self.orientation, self.slice_data.number):
  1382 + try:
  1383 + self.canvas.draw_list.remove(mr)
  1384 + except ValueError:
  1385 + pass
  1386 +
  1387 + for (m, mr) in self.measures.get(self.orientation, self.slice_data.number):
  1388 + if m.visible:
  1389 + self.canvas.draw_list.append(mr)
  1390 +
1344 self.canvas.modified = True 1391 self.canvas.modified = True
1345 self.interactor.Render() 1392 self.interactor.Render()
1346 1393
@@ -1530,14 +1577,15 @@ class Viewer(wx.Panel): @@ -1530,14 +1577,15 @@ class Viewer(wx.Panel):
1530 for actor in self.actors_by_slice_number[index]: 1577 for actor in self.actors_by_slice_number[index]:
1531 self.slice_data.renderer.AddActor(actor) 1578 self.slice_data.renderer.AddActor(actor)
1532 1579
1533 - # for (m, mr) in self.measures.get(self.orientation, self.slice_data.number):  
1534 - # for actor in mr.GetActors():  
1535 - # self.slice_data.renderer.RemoveActor(actor) 1580 + for (m, mr) in self.measures.get(self.orientation, self.slice_data.number):
  1581 + try:
  1582 + self.canvas.draw_list.remove(mr)
  1583 + except ValueError:
  1584 + pass
1536 1585
1537 - # for (m, mr) in self.measures.get(self.orientation, index):  
1538 - # mr.renderer = self.slice_data.renderer  
1539 - # for actor in mr.GetActors():  
1540 - # self.slice_data.renderer.AddActor(actor) 1586 + for (m, mr) in self.measures.get(self.orientation, index):
  1587 + if m.visible:
  1588 + self.canvas.draw_list.append(mr)
1541 1589
1542 if self.slice_._type_projection == const.PROJECTION_NORMAL: 1590 if self.slice_._type_projection == const.PROJECTION_NORMAL:
1543 self.slice_data.SetNumber(index) 1591 self.slice_data.SetNumber(index)