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
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
def load_scene (filename) : sc = PGLScene() sc.read(filename) print("loaded",len(sc)) return sc_to_blender(sc)
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
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)