예제 #1
0
class OrthoColoredRenderer(OrthoBaseRenderer, ColoredRenderer):
    terms = 'f', 'background_image', 'overdraw', 'num_channels'
    dterms = 'vc', 'ortho', 'bgcolor'

    def compute_r(self):
        return self.color_image

    def compute_dr_wrt(self, wrt):
        raise NotImplementedError

    def on_changed(self, which):
        if 'ortho' in which:
            w = self.ortho.width
            h = self.ortho.height
            self.glf = OsContext(np.int(w), np.int(h), typ=GL_FLOAT)
            _setup_ortho(self.glf, self.ortho.left.r, self.ortho.right.r,
                         self.ortho.bottom.r, self.ortho.top.r,
                         self.ortho.near, self.ortho.far, self.ortho.view_mtx)
            self.glf.Viewport(0, 0, w, h)
            self.glb = OsContext(np.int(w), np.int(h), typ=GL_UNSIGNED_BYTE)
            self.glb.Viewport(0, 0, w, h)
            _setup_ortho(self.glb, self.ortho.left.r, self.ortho.right.r,
                         self.ortho.bottom.r, self.ortho.top.r,
                         self.ortho.near, self.ortho.far, self.ortho.view_mtx)

        if not hasattr(self, 'num_channels'):
            self.num_channels = 3

        if not hasattr(self, 'bgcolor'):
            self.bgcolor = Ch(np.array([.5] * self.num_channels))
            which.add('bgcolor')

        if not hasattr(self, 'overdraw'):
            self.overdraw = True

        if 'bgcolor' in which:
            self.glf.ClearColor(self.bgcolor.r[0],
                                self.bgcolor.r[1 % self.num_channels],
                                self.bgcolor.r[2 % self.num_channels], 1.)

    @depends_on('f', 'ortho', 'vc')
    def boundarycolor_image(self):
        return self.draw_boundarycolor_image(with_vertex_colors=True)

    @depends_on('f', 'ortho')
    def boundary_images(self):
        self._call_on_changed()
        return draw_boundary_images(self.glb, self.v.r, self.f, self.vpe,
                                    self.fpe, self.ortho)

    @depends_on(terms + dterms)
    def color_image(self):
        return super(OrthoColoredRenderer, self).color_image

    @property
    def shape(self):
        return (self.ortho.height, self.ortho.width, 3)
예제 #2
0
class BoundaryRenderer(BaseRenderer):
    terms = 'f', 'frustum', 'num_channels'
    dterms = 'camera',

    @property
    def shape(self):
        return (self.frustum['height'], self.frustum['width'],
                self.num_channels)

    def compute_r(self):
        tmp = self.camera.r
        return self.color_image

    def compute_dr_wrt(self, wrt):
        if wrt is not self.camera:
            return None

        visibility = self.boundaryid_image
        shape = visibility.shape

        visible = np.nonzero(visibility.ravel() != 4294967295)[0]
        num_visible = len(visible)

        barycentric = self.barycentric_image

        return common.dImage_wrt_2dVerts(self.color_image, visible, visibility,
                                         barycentric, self.frustum['width'],
                                         self.frustum['height'],
                                         self.v.r.size / 3, self.vpe)

    def on_changed(self, which):
        if 'frustum' in which:
            w = self.frustum['width']
            h = self.frustum['height']
            self.glf = OsContext(w, h, typ=GL_FLOAT)
            self.glf.Viewport(0, 0, w, h)
            self.glb = OsContext(w, h, typ=GL_UNSIGNED_BYTE)
            self.glb.Viewport(0, 0, w, h)

        if 'frustum' in which or 'camera' in which:
            setup_camera(self.glb, self.camera, self.frustum)
            setup_camera(self.glf, self.camera, self.frustum)

        if not hasattr(self, 'overdraw'):
            self.overdraw = True

    @depends_on(terms + dterms)
    def color_image(self):
        self._call_on_changed()
        result = self.boundarybool_image.astype(np.float64)
        return np.dstack([result for i in range(self.num_channels)])
예제 #3
0
class DepthRenderer(BaseRenderer):
    terms = 'f', 'frustum', 'background_image', 'overdraw'
    dterms = 'camera', 'v'

    @property
    def shape(self):
        return (self.frustum['height'], self.frustum['width'])

    def compute_r(self):
        tmp = self.camera.r
        return self.depth_image.reshape(
            (self.frustum['height'], self.frustum['width']))

    def compute_dr_wrt(self, wrt):

        if wrt is not self.camera and wrt is not self.v:
            return None

        visibility = self.visibility_image
        visible = np.nonzero(visibility.ravel() != 4294967295)[0]
        barycentric = self.barycentric_image
        if wrt is self.camera:
            shape = visibility.shape
            depth = self.depth_image

            if self.overdraw:
                result1 = common.dImage_wrt_2dVerts_bnd(
                    depth, visible, visibility, barycentric,
                    self.frustum['width'], self.frustum['height'],
                    self.v.r.size / 3, self.f,
                    self.boundaryid_image != 4294967295)
            else:
                result1 = common.dImage_wrt_2dVerts(depth, visible, visibility,
                                                    barycentric,
                                                    self.frustum['width'],
                                                    self.frustum['height'],
                                                    self.v.r.size / 3, self.f)

            # result1 = common.dImage_wrt_2dVerts(depth, visible, visibility, barycentric, self.frustum['width'], self.frustum['height'], self.v.r.size/3, self.f)

            return result1

        elif wrt is self.v:

            IS = np.tile(col(visible), (1, 9)).ravel()
            JS = col(self.f[visibility.ravel()[visible]].ravel())
            JS = np.hstack((JS * 3, JS * 3 + 1, JS * 3 + 2)).ravel()

            # FIXME: there should be a faster way to get the camera axis.
            # But it should be carefully tested with distortion present!
            pts = np.array([[self.camera.c.r[0], self.camera.c.r[1], 2],
                            [self.camera.c.r[0], self.camera.c.r[1], 1]])
            pts = self.camera.unproject_points(pts)
            cam_axis = pts[0, :] - pts[1, :]

            if True:  # use barycentric coordinates (correct way)
                w = visibility.shape[1]
                pxs = np.asarray(visible % w, np.int32)
                pys = np.asarray(np.floor(np.floor(visible) / w), np.int32)
                bc0 = col(barycentric[pys, pxs, 0])
                bc1 = col(barycentric[pys, pxs, 1])
                bc2 = col(barycentric[pys, pxs, 2])
                bc = np.hstack(
                    (bc0, bc0, bc0, bc1, bc1, bc1, bc2, bc2, bc2)).ravel()
            else:  # each vert contributes equally (an approximation)
                bc = 1. / 3.

            data = np.tile(row(cam_axis), (IS.size / 3, 1)).ravel() * bc
            result2 = sp.csc_matrix(
                (data, (IS, JS)),
                shape=(self.frustum['height'] * self.frustum['width'],
                       self.v.r.size))
            return result2

    def on_changed(self, which):

        if 'frustum' in which:
            w = self.frustum['width']
            h = self.frustum['height']
            self.glf = OsContext(w, h, typ=GL_FLOAT)
            self.glf.Viewport(0, 0, w, h)
            self.glb = OsContext(w, h, typ=GL_UNSIGNED_BYTE)
            self.glb.Viewport(0, 0, w, h)

        if 'frustum' in which or 'camera' in which:
            setup_camera(self.glb, self.camera, self.frustum)
            setup_camera(self.glf, self.camera, self.frustum)

        if not hasattr(self, 'overdraw'):
            self.overdraw = True

        assert (self.v is self.camera.v)

    @depends_on(dterms + terms)
    def depth_image(self):
        self._call_on_changed()

        gl = self.glb
        gl.Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

        gl.PolygonMode(GL_FRONT_AND_BACK, GL_FILL)
        draw_noncolored_verts(gl, self.camera.v.r, self.f)
        result = np.asarray(deepcopy(gl.getDepth()), np.float64)

        if self.overdraw:
            gl.PolygonMode(GL_FRONT_AND_BACK, GL_LINE)
            draw_noncolored_verts(gl, self.camera.v.r, self.f)
            overdraw = np.asarray(deepcopy(gl.getDepth()), np.float64)
            gl.PolygonMode(GL_FRONT_AND_BACK, GL_FILL)
            boundarybool_image = self.boundarybool_image
            result = overdraw * boundarybool_image + result * (
                1 - boundarybool_image)

        if hasattr(self, 'background_image'):
            if False:  # has problems at boundaries, not sure why yet
                bg_px = self.visibility_image == 4294967295
                fg_px = 1 - bg_px
                result = bg_px * self.background_image + fg_px * result
            else:
                tmp = np.concatenate(
                    (np.atleast_3d(result), np.atleast_3d(
                        self.background_image)),
                    axis=2)
                result = np.min(tmp, axis=2)

        return result

    def getDepthMesh(self, depth_image=None):
        self._call_on_changed()  # make everything is up-to-date
        v = self.glb.getDepthCloud(depth_image)
        w = self.frustum['width']
        h = self.frustum['height']
        idxs = np.arange(w * h).reshape((h, w))

        # v0 is upperleft, v1 is upper right, v2 is lowerleft, v3 is lowerright
        v0 = col(idxs[:-1, :-1])
        v1 = col(idxs[:-1, 1:])
        v2 = col(idxs[1:, :-1])
        v3 = col(idxs[1:, 1:])

        f = np.hstack((v0, v1, v2, v1, v3, v2)).reshape((-1, 3))
        return v, f
예제 #4
0
class ColoredRenderer(BaseRenderer):
    terms = 'f', 'frustum', 'background_image', 'overdraw', 'num_channels'
    dterms = 'vc', 'camera', 'bgcolor'

    @property
    def shape(self):
        if not hasattr(self, 'num_channels'):
            self.num_channels = 3
        if self.num_channels > 1:
            return (self.frustum['height'], self.frustum['width'],
                    self.num_channels)
        else:
            return (self.frustum['height'], self.frustum['width'])

    def compute_r(self):
        tmp = self.camera.r
        return self.color_image  # .reshape((self.frustum['height'], self.frustum['width'], -1)).squeeze()

    def compute_dr_wrt(self, wrt):
        if wrt is not self.camera and wrt is not self.vc and wrt is not self.bgcolor:
            return None

        visibility = self.visibility_image

        shape = visibility.shape
        color = self.color_image

        visible = np.nonzero(visibility.ravel() != 4294967295)[0]
        num_visible = len(visible)

        barycentric = self.barycentric_image

        if wrt is self.camera:
            if self.overdraw:
                return common.dImage_wrt_2dVerts_bnd(
                    color, visible, visibility, barycentric,
                    self.frustum['width'], self.frustum['height'],
                    self.v.r.size / 3, self.f,
                    self.boundaryid_image != 4294967295)
            else:
                return common.dImage_wrt_2dVerts(color, visible, visibility,
                                                 barycentric,
                                                 self.frustum['width'],
                                                 self.frustum['height'],
                                                 self.v.r.size / 3, self.f)

        elif wrt is self.vc:
            return common.dr_wrt_vc(visible,
                                    visibility,
                                    self.f,
                                    barycentric,
                                    self.frustum,
                                    self.vc.size,
                                    num_channels=self.num_channels)

        elif wrt is self.bgcolor:
            return common.dr_wrt_bgcolor(visibility,
                                         self.frustum,
                                         num_channels=self.num_channels)

    def on_changed(self, which):
        if 'frustum' in which:
            w = self.frustum['width']
            h = self.frustum['height']
            self.glf = OsContext(w, h, typ=GL_FLOAT)
            self.glf.Viewport(0, 0, w, h)
            self.glb = OsContext(w, h, typ=GL_UNSIGNED_BYTE)
            self.glb.Viewport(0, 0, w, h)

        if 'frustum' in which or 'camera' in which:
            setup_camera(self.glb, self.camera, self.frustum)
            setup_camera(self.glf, self.camera, self.frustum)

        if not hasattr(self, 'num_channels'):
            self.num_channels = 3

        if not hasattr(self, 'bgcolor'):
            self.bgcolor = Ch(np.array([.5] * self.num_channels))
            which.add('bgcolor')

        if not hasattr(self, 'overdraw'):
            self.overdraw = True

        if 'bgcolor' in which or ('frustum' in which
                                  and hasattr(self, 'bgcolor')):
            self.glf.ClearColor(self.bgcolor.r[0],
                                self.bgcolor.r[1 % self.num_channels],
                                self.bgcolor.r[2 % self.num_channels], 1.)

    def flow_to(self, v_next, cam_next=None):
        return common.flow_to(self, v_next, cam_next)

    def filter_for_triangles(self, which_triangles):
        cim = self.color_image
        vim = self.visibility_image + 1
        arr = np.zeros(len(self.f) + 1)
        arr[which_triangles + 1] = 1

        relevant_pixels = arr[vim.ravel()]
        cim2 = cim.copy() * np.atleast_3d(relevant_pixels.reshape(vim.shape))
        relevant_pixels = np.nonzero(arr[vim.ravel()])[0]
        xs = relevant_pixels % vim.shape[1]
        ys = relevant_pixels / vim.shape[1]
        return cim2[np.min(ys):np.max(ys), np.min(xs):np.max(xs), :]

    @depends_on('f', 'camera', 'vc')
    def boundarycolor_image(self):
        return self.draw_boundarycolor_image(with_vertex_colors=True)

    def draw_color_image(self, gl):
        self._call_on_changed()
        gl.Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

        # use face colors if given
        # FIXME: this won't work for 2 channels
        draw_colored_verts(gl, self.v.r, self.f, self.vc.r)

        result = np.asarray(
            deepcopy(gl.getImage()[:, :, :self.num_channels].squeeze()),
            np.float64)

        if hasattr(self, 'background_image'):
            bg_px = np.tile(
                np.atleast_3d(self.visibility_image) == 4294967295,
                (1, 1, self.num_channels)).squeeze()
            fg_px = 1 - bg_px
            result = bg_px * self.background_image + fg_px * result

        return result

    @depends_on(dterms + terms)
    def color_image(self):
        gl = self.glf
        gl.PolygonMode(GL_FRONT_AND_BACK, GL_FILL)
        no_overdraw = self.draw_color_image(gl)

        if not self.overdraw:
            return no_overdraw

        gl.PolygonMode(GL_FRONT_AND_BACK, GL_LINE)
        overdraw = self.draw_color_image(gl)
        gl.PolygonMode(GL_FRONT_AND_BACK, GL_FILL)

        boundarybool_image = self.boundarybool_image
        if self.num_channels > 1:
            boundarybool_image = np.atleast_3d(boundarybool_image)
        return np.asarray((overdraw * boundarybool_image + no_overdraw *
                           (1 - boundarybool_image)),
                          order='C')

    @depends_on('f', 'frustum', 'camera')
    def boundary_images(self):
        self._call_on_changed()
        return draw_boundary_images(self.glb, self.v.r, self.f, self.vpe,
                                    self.fpe, self.camera)

    @depends_on(terms + dterms)
    def boundarycolor_image(self):
        self._call_on_changed()
        gl = self.glf
        colors = self.vc.r.reshape((-1, 3))[self.vpe.ravel()]
        gl.Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
        draw_colored_primitives(gl, self.v.r.reshape((-1, 3)), self.vpe,
                                colors)
        return np.asarray(deepcopy(gl.getImage()), np.float64)