def scene(self):
        """
		convert the database into a plantgl scene
		"""
        sc = Scene()
        for shp_id, shp in self.iteritems():
            shp.id = shp_id
            sc.add(shp)
        return sc
    def read(self, filename):
        """
		read a database (a bgeom file)
		"""
        sc = Scene()
        sc.read(filename)  #,'BGEOM')
        self.clear()
        for shp in sc:
            self[shp.id] = shp
Exemple #3
0
	def scene (self) :
		"""
		convert the database into a plantgl scene
		"""
		sc=Scene()
		for shp_id,shp in self.iteritems() :
			shp.id=shp_id
			sc.add(shp)
		return sc
Exemple #4
0
	def read (self, filename) :
		"""
		read a database (a bgeom file)
		"""
		sc=Scene()
		sc.read(filename)#,'BGEOM')
		self.clear()
		for shp in sc :
			self[shp.id]=shp
Exemple #5
0
def load_scene (filename) :
    sc = PGLScene()
    sc.read(filename)
    print("loaded",len(sc))
    
    return sc_to_blender(sc)
Exemple #6
0
def organs(scene, first_leaf_index=99, split_stem=False):
    """ Extract organs from a segmented mesh. """
    leaves = {}
    stems = {}

    def stem_shape(geom, color=(20, 130, 20)):
        return Shape(geom, Material(color))

    def leaf_shape(geom, color=None):
        if not color:
            color = np.random.randint(0, 255, 3).tolist()
        return Shape(geom, Material(color))

    for shape in scene:
        geom = shape.geometry
        shape_id = shape.id
        if shape_id < first_leaf_index:
            stems[shape_id] = stem_shape(geom)
            stems[shape_id].id = shape_id
        else:
            leaves[shape_id] = leaf_shape(geom)
            leaves[shape_id].id = shape_id

    # Group leaves
    # Idea: If two shapes share the same points, they belong to the same leaf

    group = {}
    queue = sorted(leaves)
    parents = {}
    while queue:
        leaf = queue.pop(0)
        if leaf not in group:
            group[leaf] = []

        for lid in queue:
            if lid in group[leaf]:
                continue
            if closed(leaves[leaf], leaves[lid]):
                group[leaf].append(lid)
                group.setdefault(lid, []).append(leaf)

    connected_components = {}
    visited = {}
    for leaf in group:
        if leaf in visited:
            continue
        neigh = [leaf]
        connected_components[leaf] = []
        while neigh:
            x = neigh.pop()
            if x in visited:
                continue
            connected_components[leaf].append(x)
            neigh.extend(group[x])
            visited[x] = True

    for leaf in connected_components:
        mat = leaves[leaf].appearance
        for lid in connected_components[leaf]:
            leaves[lid].appearance = mat

    # Group leaves
    bigstem = group_shapes(stems)

    group_leaves = {}
    for lid in connected_components:
        _leaves = dict((leaf_id, leaves[leaf_id])
                       for leaf_id in connected_components[lid])
        group_leaves[lid] = group_shapes(_leaves)
        group_leaves[lid].id = lid

    #leaves = group_leaves(connected_components, leaves)
    # Order leaves
    points = np.array(bigstem.geometry.pointList)
    coords = []
    for lid in group_leaves:
        sh = group_leaves[lid]
        frontier = points[intersect(sh, bigstem)]
        if len(frontier) == 0:
            print 'no frontier between leaf %d and stem'
            continue
        x, y, z = frontier.T
        coords.append((lid, z.min(), z.mean(), z.max()))

    sorted_coords = sorted(coords, key=lambda coord: coord[1])

    if not split_stem:
        k0 = min(list(stems))
        group_stems = {k0: bigstem}

        shapes = group_leaves.values()
        shapes.extend(group_stems.values())
        scene1 = Scene(shapes)

        return scene1, group_stems, group_leaves, sorted_coords

    # Group Stems
    # compute the z_min of each stem
    # then associate the stem id with the leaf
    stem_bbox = []
    for sid in stems:
        faces = np.array(stems[sid].geometry.indexList)
        pts = points[faces]
        x, y, z = pts.T
        stem_bbox.append((sid, z.min(), z.max()))

    stem_bbox = sorted(stem_bbox, key=lambda coord: coord[2])

    print "stem_box : ", stem_bbox
    print "sorted_coords : ", sorted_coords
    index = 0
    _stems = {}
    lid, lmin, lmean, lmax = sorted_coords.pop(0)
    for i in range(len(stem_bbox)):
        stem_id, smin, smax = stem_bbox[i]
        if smax <= lmin:
            _stems.setdefault(lid, []).append(stem_id)
            continue
        else:
            while sorted_coords and smax > lmin:
                lid, lmin, lmean, lmax = sorted_coords.pop(0)
            else:
                if not sorted_coords:
                    index = i
                    break
                else:
                    _stems.setdefault(lid, []).append(stem_id)
    if index != 0:
        # last stems are a leaf
        last_stems = dict((s[0], stems[s[0]]) for s in stem_bbox[index:])
        new_leaf_id = max(group_leaves.keys()) + 1
        sid = last_stems.keys()[0]
        last_stems[new_leaf_id] = last_stems[sid]
        del last_stems[sid]
        sh = group_shapes(last_stems, new_leaf_id)
        sh.id = new_leaf_id
        group_leaves[new_leaf_id] = sh

    print _stems

    group_stems = {}
    for lid in _stems:
        stem_shapes = dict((sid, stems[sid]) for sid in _stems[lid])
        group_stems[lid] = group_shapes(stem_shapes)
        group_stems[lid].id = lid

    shapes = group_leaves.values()
    shapes.extend(group_stems.values())
    scene1 = Scene(shapes)

    return scene1, group_stems, group_leaves, sorted_coords
Exemple #7
0
    def toScene(self):
        from math import ceil, floor, log
        from openalea.plantgl.scenegraph import Polyline2D, Polyline, PointSet, QuadSet, Text, Group, Translated, ScreenProjected, Material, Color3, Color4, Shape, Scene

        minx, maxx, miny, maxy = self.bbox()

        xext = maxx - minx
        yext = maxy - miny
        x2Dlength, y2Dlength = self.size

        projx = lambda x: self.position[0] + (x2Dlength * (x - minx) / xext)
        projy = lambda y: self.position[1] + (y2Dlength * (y - miny) / yext)
        projp = lambda p: (projx(p[0]), projy(p[1]))
        projp3 = lambda p: (projx(p[0]), projy(p[1]), 0)
        proj = lambda x, y: (projx(x), projy(y))

        if self.xtick is None:
            nbdigit = round(log(xext, 10))
            self.xtick = 10**(nbdigit - 1)
        if self.ytick is None:
            nbdigit = round(log(yext, 10))
            self.ytick = 10**(nbdigit - 1)

        result = []

        def toMaterial(c):
            if type(c) == Color4:
                return Material((c.red, c.green, c.blue), transparency=c.alpha)
            elif type(c) == Color3:
                return Material(c)
            else:
                m = Material((c[0], c[1], c[2]))
                if len(c) >= 4: m.transparency = c[3]
                return m

        def hasColorPerObject(c):
            if type(c) == Color3 or type(c) == Color4: return False
            return type(color[0]) != int

        def limit(p):
            x, y = p
            if y < miny: return (x, miny)
            if y > maxy: return (x, maxy)
            return p

        for curve, color, size in self.curves:
            curvedata = map(projp3, map(limit, curve))
            colorperobject = hasColorPerObject(color)
            result.append(
                Shape(
                    ScreenProjected(
                        Polyline(
                            curvedata,
                            width=size,
                            colorList=None if not colorperobject else color),
                        False),
                    toMaterial(color) if not colorperobject else Material(
                        (255, 0, 0))))

        for pointdata, color, size in self.points:
            pointdata = map(projp3,
                            filter(lambda p: miny <= p[1] < maxy, pointdata))
            colorperobject = hasColorPerObject(color)
            result.append(
                Shape(
                    ScreenProjected(
                        PointSet(
                            pointdata,
                            width=size,
                            colorList=None if not colorperobject else color),
                        False),
                    toMaterial(color) if not colorperobject else Material(
                        (255, 0, 0))))

        y0 = projy(miny)
        for values, color in self.boxplot:
            delta = abs(projx(values[0][0]) - projx(values[1][0])) / 2
            colorperobject = hasColorPerObject(color)
            for i, v in enumerate(values):
                if miny < v[1]:
                    if v[1] > maxy:
                        v = (v[0], maxy)
                    vx, vy = projp(v)
                    p1, p2, p3, p4 = (vx - delta, y0), (vx + delta,
                                                        y0), (vx + delta,
                                                              vy), (vx - delta,
                                                                    vy)
                    result.append(
                        Shape(
                            ScreenProjected(
                                QuadSet([(x, y, 0.0)
                                         for x, y in [p1, p2, p3, p4]],
                                        [range(4)]), False),
                            toMaterial(
                                color if not colorperobject else color[i])))
                    result.append(
                        Shape(
                            ScreenProjected(
                                Translated(
                                    0, 0, -0.01,
                                    Group([
                                        Polyline2D([pi, pj])
                                        for pi, pj in [(p1, p4), (
                                            p1, p2), (p2, p3), (p3, p4)]
                                    ])), False), toMaterial((0, 0, 0))))

        if miny <= 0 <= maxy:
            cxtick = ((minx // self.xtick) * self.xtick)
            if cxtick < minx: cxtick += self.xtick
            g = []
            while cxtick <= maxx:
                if cxtick != 0:
                    g.append(
                        Polyline2D([
                            (projx(cxtick), projy(0) - self.ticklength),
                            (projx(cxtick), projy(0) + self.ticklength)
                        ]))
                cxtick += self.xtick
            result.append(
                Shape(
                    ScreenProjected(
                        Group(g +
                              [Polyline2D([(proj(minx, 0)),
                                           (proj(maxx, 0))])]), False),
                    toMaterial((0, 255, 0))))

        if minx <= 0 <= maxx:
            cytick = ((miny // self.ytick) * self.ytick)
            if cytick < miny: cytick += self.ytick
            g = []
            while cytick <= maxy:
                if cytick != 0:
                    g.append(
                        Polyline2D([
                            (projx(0) - self.ticklength, projy(cytick)),
                            (projx(0) + self.ticklength, projy(cytick))
                        ]))
                cytick += self.ytick
            result.append(
                Shape(
                    ScreenProjected(
                        Group(g +
                              [Polyline2D([(proj(0, miny)),
                                           (proj(0, maxy))])]), False),
                    toMaterial((0, 0, 255))))

        xlabeldecal = 0.005
        ylabeldecal = 0.02
        xtagorient = -1 if maxy <= 0 else 1
        ytagorient = -1 if maxx <= 0 else 1

        result.append(
            Shape(
                Group([
                    ScreenProjected(
                        Translated(
                            projx(minx) - xlabeldecal / 2,
                            projy(miny) - xtagorient *
                            (2 * self.ticklength + xlabeldecal), 0,
                            Text(str(minx))), False),
                    ScreenProjected(
                        Translated(
                            projx(maxx) - xlabeldecal / 2,
                            projy(miny) - xtagorient *
                            (2 * self.ticklength + xlabeldecal), 0,
                            Text(str(maxx))), False),
                    ScreenProjected(
                        Translated(
                            projx(minx) - ytagorient *
                            (2 * self.ticklength + ylabeldecal),
                            projy(miny) - ylabeldecal / 2, 0, Text(str(miny))),
                        False),
                    ScreenProjected(
                        Translated(
                            projx(minx) - ytagorient *
                            (2 * self.ticklength + ylabeldecal),
                            projy(maxy) - ylabeldecal / 2, 0, Text(str(maxy))),
                        False)
                ]), toMaterial((0, 0, 0))))

        return Scene(result)