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 575 points = []
576 576 for p in self.points:
577 577 coord.SetValue(p)
578   - cx, cy = coord.GetComputedDisplayValue(canvas.viewer.slice_data.renderer)
  578 + cx, cy = coord.GetComputedDisplayValue(canvas.evt_renderer)
579 579 # canvas.draw_circle((cx, cy), 2.5)
580 580 points.append((cx, cy))
581 581  
... ... @@ -835,7 +835,8 @@ class AngularMeasure(object):
835 835 points = []
836 836 for p in self.points:
837 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 840 # canvas.draw_circle((cx, cy), 2.5)
840 841 points.append((cx, cy))
841 842  
... ...
invesalius/data/viewer_slice.py
... ... @@ -148,15 +148,30 @@ class ContourMIPConfig(wx.Panel):
148 148  
149 149  
150 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 168 self._size = self.canvas_renderer.GetSize()
  169 + self.draw_list = []
155 170 self.gc = None
156 171 self.last_cam_modif_time = -1
157 172 self.modified = True
158 173 self._init_canvas()
159   - viewer.slice_data.renderer.AddObserver("StartEvent", self.OnPaint)
  174 + evt_renderer.AddObserver("StartEvent", self.OnPaint)
160 175  
161 176 def _init_canvas(self):
162 177 w, h = self._size
... ... @@ -203,7 +218,7 @@ class CanvasRendererCTX:
203 218 self._size = size
204 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 222 if (not self.modified) and cam_modif_time == self.last_cam_modif_time:
208 223 return
209 224  
... ... @@ -233,10 +248,8 @@ class CanvasRendererCTX:
233 248 gc.Scale(1, -1)
234 249  
235 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 253 modified = True
241 254  
242 255 gc.Destroy()
... ... @@ -250,6 +263,30 @@ class CanvasRendererCTX:
250 263 self._cv_image.Modified()
251 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 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 292 Draw a line from pos0 to pos1
... ... @@ -1224,7 +1261,7 @@ class Viewer(wx.Panel):
1224 1261 self.cam = self.slice_data.renderer.GetActiveCamera()
1225 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 1266 # Set the slice number to the last slice to ensure the camera if far
1230 1267 # enough to show all slices.
... ... @@ -1341,6 +1378,16 @@ class Viewer(wx.Panel):
1341 1378 self.interactor.Render()
1342 1379  
1343 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 1391 self.canvas.modified = True
1345 1392 self.interactor.Render()
1346 1393  
... ... @@ -1530,14 +1577,15 @@ class Viewer(wx.Panel):
1530 1577 for actor in self.actors_by_slice_number[index]:
1531 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 1590 if self.slice_._type_projection == const.PROJECTION_NORMAL:
1543 1591 self.slice_data.SetNumber(index)
... ...