def __init__(self, project): BaseViewWidget.__init__(self) self.project = project self.image_view_cache = { } self.pad_renderer = PadRender(self) self.dip_renderer = DIPRender(self) self.smd_renderer = SMDRender(self) self.trace_renderer = TraceRender(self) self.via_renderer = THRenderer(self) self.__via_project_batch = ViaBoardBatcher(self.via_renderer, self.project) self.text_batch = TextBatcher(self.gls.text) self.cmp_text_batch = ComponentTextBatcher(self, self.project, self.gls.text) self.poly_renderer = CachedPolygonRenderer(self) self.hairline_renderer = HairlineRenderer(self) self.passive_renderer = PassiveRender(self) # Initial view is a normalized 1-1-1 area. # Shift to be 10cm max self.viewState.transform = translate(-0.9, -0.9).dot(scale(1./100000))
class BoardViewWidget(BaseViewWidget): def __init__(self, project): BaseViewWidget.__init__(self) self.project = project self.image_view_cache = { } self.pad_renderer = PadRender(self) self.dip_renderer = DIPRender(self) self.smd_renderer = SMDRender(self) self.trace_renderer = TraceRender(self) self.via_renderer = THRenderer(self) self.__via_project_batch = ViaBoardBatcher(self.via_renderer, self.project) self.text_batch = TextBatcher(self.gls.text) self.cmp_text_batch = ComponentTextBatcher(self, self.project, self.gls.text) self.poly_renderer = CachedPolygonRenderer(self) self.hairline_renderer = HairlineRenderer(self) self.passive_renderer = PassiveRender(self) # Initial view is a normalized 1-1-1 area. # Shift to be 10cm max self.viewState.transform = translate(-0.9, -0.9).dot(scale(1./100000)) def text_color(self): return [1,1,1] def current_layer_hack(self): return self.viewState.current_layer def color_for_pad(self, pad): if pad.th_diam != 0: return [0.5, 0.5, 0.5] return self.color_for_layer(pad.layer) def color_for_trace(self, trace): return self.color_for_layer(trace.layer) def color_for_layer(self, layer): return list(layer.color) def sel_colormod(self, t, oldcolor): if t: return [1,1,1,1] return oldcolor def image_view_cache_load(self, il): key = id(il) if key not in self.image_view_cache: iv = ImageView(il) iv.initGL(self.gls) self.image_view_cache[key] = iv return self.image_view_cache[key] def reinit(self): self.pad_renderer.initializeGL(self, self.gls) self.dip_renderer.initializeGL(self.gls) self.smd_renderer.initializeGL(self.gls) self.trace_renderer.initializeGL(self.gls) self.via_renderer.initializeGL(self.gls) self.text_batch.initializeGL() self.cmp_text_batch.initializeGL() self.poly_renderer.initializeGL() self.hairline_renderer.initializeGL() for i in list(self.image_view_cache.values()): i.initGL() def getVisibleArtwork(self): objects = [] objects += self.project.artwork.vias objects += self.project.artwork.traces objects += self.project.artwork.polygons objects += self.project.artwork.airwires return objects def render_component(self, mat, cmp, render_mode=RENDER_STANDARD, render_hint=RENDER_HINT_NORMAL): if not self.layer_visible_m(cmp.on_layers()): return if isinstance(cmp, DIPComponent): self.dip_renderer.render(mat, cmp, render_mode, render_hint) elif isinstance(cmp, SMD4Component): self.smd_renderer.render(mat, cmp, render_mode, render_hint) elif isinstance(cmp, PassiveComponent): self.passive_renderer.render(mat, cmp, render_mode, render_hint) else: pass #raise TypeError("Can't render %s" % cmp) cm = mat.dot(cmp.matrix) for pad in cmp.get_pads(): pad_render_mode = render_mode if not pad.is_through() and not self.layer_visible(pad.layer): continue if pad in self.selectionList: pad_render_mode |= RENDER_SELECTED self.pad_renderer.render(cm, pad, pad_render_mode, render_hint) def _layer_visible(self, l): return l is self.viewState.current_layer or self.viewState.draw_other_layers def layer_visible(self, l): return self.__layer_visible_lut[l.number] def layer_visible_m(self, l): return self.viewState.current_layer in l or self.viewState.draw_other_layers def render(self): t_render_start = time.time() self.__layer_visible_lut = [self._layer_visible(i) for i in self.project.stackup.layers] # zero accuum buffers for restarts self.trace_renderer.restart() self.text_batch.restart() self.poly_renderer.restart() self.hairline_renderer.restart() # Two view modes - CAM and trace # CAM - all layers, SIDE-up # Trace - current layer + artwork (optional, other layers underneath) stackup_layer = self.viewState.current_layer if stackup_layer is None: return # Render all images down onto the layer with Timer() as il_timer: if self.viewState.show_images and (len(stackup_layer.imagelayers) > 0): images = list(stackup_layer.imagelayers) i = self.viewState.layer_permute % len(images) images_cycled = images[i:] + images[:i] for l in images_cycled: self.image_view_cache_load(l).render(self.viewState.glMatrix) # Now render features self.lt = time.time() GL.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA) artwork = self.getVisibleArtwork() # Build rendering batches with Timer() as t_aw: sx = set() for i in artwork: rs = RENDER_SELECTED if i in self.selectionList else 0 if isinstance(i, Trace): if self.layer_visible(i.layer): sx.add((i,rs)) elif isinstance(i, Polygon): if self.layer_visible(i.layer): self.poly_renderer.deferred(i, rs, RENDER_HINT_NORMAL) elif isinstance(i, Airwire): self.hairline_renderer.deferred(i.p0, i.p1, AIRWIRE_COLOR, None, RENDER_HINT_NORMAL) elif isinstance(i, Via): pass else: raise NotImplementedError() with Timer() as t_vt_gen: self.__via_project_batch.update_if_necessary(self.selectionList) with Timer() as t_tr_gen: for i,rs in sx: self.trace_renderer.deferred(i, rs, RENDER_HINT_NORMAL) with Timer() as cmp_timer: for cmp in self.project.artwork.components: render_state = 0 if cmp in self.selectionList: render_state |= RENDER_SELECTED self.render_component(self.viewState.glMatrix, cmp, render_state) with Timer() as t_cmp_gen: self.cmp_text_batch.update_if_necessary() with Timer() as other_timer: super(BoardViewWidget, self).render() def ly_order_func(layer): # We always draw the current layer last if layer is self.viewState.current_layer: return 1 return -layer.order with Timer() as gl_draw_timer: # Draw all the layers layers = sorted(self.project.stackup.layers, key=ly_order_func) t_tr_draw = Timer() t_tex_draw = Timer() for layer in layers: with t_tr_draw: self.trace_renderer.render_deferred_layer(self.viewState.glMatrix, layer) self.poly_renderer.render(self.viewState.glMatrix, layer) with t_tex_draw: self.text_batch.render(key=layer) self.hairline_renderer.render_group(self.viewState.glMatrix, layer) with Timer() as t_vt_draw: for i in self.project.stackup.via_pairs: self.__via_project_batch.render_viapair(self.viewState.glMatrix, i) # Final rendering # Render the non-layer text with t_tex_draw: self.cmp_text_batch.render_layer(self.viewState.glMatrix, SIDE.Top, False) self.cmp_text_batch.render_layer(self.viewState.glMatrix, SIDE.Bottom, False) self.text_batch.render() self.hairline_renderer.render_group(self.viewState.glMatrix, None) self.hairline_renderer.render_group(self.viewState.glWMatrix, "OVERLAY_VS") GL.glFinish() all_time = time.time() - t_render_start print("Render time all: %f ot: %f cmp: %f aw: %f (vt %f tr %f) gl: %f (vt: %f tr: %f tex: %f)" % ( all_time, other_timer.interval, cmp_timer.interval, t_aw.interval, t_vt_gen.interval, t_tr_gen.interval, gl_draw_timer.interval, t_vt_draw.interval, t_tr_draw.interval, t_tex_draw.interval))