def geom2shape(vid, mesh, scene): shape = None if isinstance(mesh, list): for m in mesh: geom2shape(vid, m, scene) return if mesh is None: return if isinstance(mesh, Shape): shape = mesh mesh = mesh.geometry label = labels.get(vid) if colors: if ambient_only: shape = Shape(mesh, Material(ambient=Color3(* colors.get(vid, [0,0,0])), diffuse=0.0, specular=Color3(0,0,0))) else: shape = Shape(mesh, Material(Color3(* colors.get(vid, [0,0,0]) ))) elif not label: if not shape: shape = Shape(mesh) elif label.is_soil(): shape = Shape(mesh, soil_material) elif label.is_stem() and label.optical_id <= 1: shape = Shape(mesh, stem_material) elif label.is_stem() and label.optical_id > 1: shape = Shape(mesh, soil_material) elif label.is_leaf() and label.optical_id <= 1: shape = Shape(mesh, leaf_material) elif label.is_leaf() and label.optical_id > 1: shape = Shape(mesh, soil_material) shape.id = vid scene.add(shape)
def display(self, color=[190, 205, 205], add=False, transparency=0): from openalea.plantgl.all import Scene, Shape, Material, FaceSet, Viewer from random import randint s = Scene() for facedart in self.elements(2): lastdart = facedart positions = [] for dart in self.orderedorbit(facedart, [0, 1]): if self.alpha(0, dart) != lastdart: positions.append(self.get_position(dart)) lastdart = dart if color is None: mat = Material( (randint(0, 255), randint(0, 255), randint(0, 255)), transparency=transparency) else: mat = Material(tuple(color), diffuse=0.25, transparency=transparency) s.add( Shape(FaceSet(positions, [range(len(positions))]), mat, facedart)) if add: Viewer.add(s) else: Viewer.display(s)
def display(self, color=(190, 205, 205), add=False): """ Display the 2-cells of a 2-G-Map using the ordered orbit of its darts in PlantGL. For each face element, retrieve the position of its ordered face darts and add a FaceSet PlantGL object to the scene. Example : s += pgl.Shape(pgl.FaceSet( [[0,0,0],[1,0,0],[1,1,0],[0,1,0]], [[0,1,2,3]]) , pgl.Material((0,100,0))) # for a green square """ from openalea.plantgl.all import Scene, Shape, Material, FaceSet, Viewer from random import randint s = Scene() for facedart in self.elements(2): lastfart = facedart positions = [] for dart in self.oderedorbit(facedart, [0, 1]): if self.alpha(0, dart) != lastfart: positions.append(self.get_position(dart)) lastfart = dart if color is None: mat = Material( (randint(0, 255), randint(0, 255), randint(0, 255))) else: mat = Material(tuple(color), diffuse=0.25) s.add( Shape(FaceSet(positions, [range(len(positions))]), mat, facedart)) if add: Viewer.add(s) else: Viewer.display(s)
def plot_spline_crv(ctrls, pts): """ Parameters ========== - ctrl: control points - pts : evaluated points on the curve """ from openalea.plantgl.all import Scene, Shape, Material, FaceSet, Viewer, Polyline from random import randint scene = Scene() crv = Shape(geometry=Polyline(pts), appearance=Material((12, 12, 125))) scene.add(crv) ctrl = Shape(geometry=Polyline(ctrls), appearance=Material((12, 125, 12))) scene.add(ctrl) # To complete: Draw the control points and the line between each ones. Viewer.display(scene)
def test_triangle(): from openalea.plantgl.all import TriangleSet, Scene, Shape, Vector3 from openalea.plantgl.light import scene_irradiance points = [(0, 0, 0), (0, 0, sqrt(2)), (0, sqrt(2), 0)] triangles = Scene([Shape(TriangleSet(points, [list(range(3))]), id=8)]) lights = [(0, 0, 1)] res = scene_irradiance(triangles, lights, screenresolution=0.0005) print(res)
def plot_spline_surface(ctrl_net, points): """ Parameters ========== - ctrl_net : the net of control points (list of list) - points : a set of evaluated points (list of list) """ scene = Scene() n = len(points) m = len(points[0]) # Compute a mesh (i.e. TriangleSet) for the set of points pointList = [pt for rank in points for pt in rank] indexList = [] for i in range(n - 1): for j in range(m - 1): ii = i * m + j i1 = (ii, ii + 1, ii + m) i2 = (ii + 1, ii + m + 1, ii + m) indexList.append(i1) indexList.append(i2) surf = Shape(TriangleSet(pointList, indexList), appearance=Material((12, 125, 12))) scene.add(surf) # plot the control net n = len(ctrl_net) m = len(ctrl_net[0]) for pts in ctrl_net: crv = Shape(geometry=Polyline(pts), appearance=Material((125, 12, 12))) scene.add(crv) for pt in pts: scene.add(Shape(Translated(Vector3(pt), Sphere(radius=0.1)))) for i in range(m): pts = [ctrl_net[j][i] for j in range(n)] crv = Shape(geometry=Polyline(pts), appearance=Material((12, 12, 125))) scene.add(crv) Viewer.display(scene)
def to_js(scene): bbx = BoundingBox(scene) center = bbx.getCenter() objsize = norm(bbx.getSize()) code = template_code_begin.format(objcenter=(center.x, center.y, center.z), objsize=objsize, lightposition=tuple(center + (0, 0, 5 * objsize))) if isinstance(scene, Geometry): code += sh2js(Shape(scene, Material.DEFAULT_MATERIAL)) elif isinstance(scene, Shape): code += sh2js(scene) else: for sh in scene: code += sh2js(sh) code += template_code_end return code
def color_structures(fruiting_structures, mtg, scene): import matplotlib.pyplot as plt from openalea.plantgl.all import Material, Shape from random import randint, seed from numpy.random import seed as nseed seed(0) nseed(0) nbcolors = len(sum([inflos for inflos, gus in fruiting_structures], [])) #len(fruiting_structures) _colors = plt.get_cmap('jet', nbcolors) colors = lambda x: _colors(x) structures = dict() idmap = mtg.property('_axial_id') print('determine colors') colindex = determine_colorindex(fruiting_structures, mtg, scene) print(colindex) allinflos = [ lid for vid, lid in list(idmap.items()) if mtg.label(vid) == 'Inflorescence' ] for inflos, gus in fruiting_structures: i = colindex.pop(0) col = colors(i) mat = Material([int(c * 100) for c in col[:3]], 2) for j in inflos: structures[idmap[j]] = mat for j in gus: structures[idmap[j]] = mat print(col, inflos) definfmat = Material((50, 50, 50)) for inf in allinflos: if not inf in structures: structures[inf] = definfmat defmat = Material((0, 0, 0)) print('compute colored scene') nscene = Scene([ Shape(sh.geometry, structures.get(sh.id, defmat), sh.id, sh.parentId) for sh in scene ]) return nscene Viewer.display(nsc)
def leaf_shape(self, leaf, color, shape): s = shape # t= Transform4() # t.scale(Vector3(leaf.leaf_scale_x,leaf.leaf_scale,leaf.leaf_scale)) # t.rotate(leaf.matrix) # t.translate(leaf.point+self.position) # t.transform(s.pointList) # normal= leaf.matrix*Vector3(0,0,1) s = Scaled( Vector3(leaf.leaf_scale_x, leaf.leaf_scale, leaf.leaf_scale), s) x = leaf.matrix * Vector3(1, 0, 0) y = leaf.matrix * Vector3(0, 1, 0) s = Oriented(x, y, s) # a, e, r= uniform(-pi, pi), uniform(-pi,pi),uniform(-pi,pi) # s= EulerRotated(a,e,r, s) t = Translated(leaf.point + self.position, s) return Shape(t, color)
def geom2shape(vid, mesh, scene, colors, position, orientation, shape_id=None): shape = None if shape_id is None: shape_id = vid if isinstance(mesh, list): for m in mesh: geom2shape(vid, m, scene, colors, position, orientation) return if mesh is None: return if isinstance(mesh, Shape): shape = mesh mesh = mesh.geometry label = labels.get(vid) is_green = greeness.get(vid) mesh = Translated(position, AxisRotated((0, 0, 1), orientation, mesh)) if colors: shape = Shape(mesh, Material(Color3(*colors.get(vid, [0, 0, 0])))) elif not greeness: if not shape: shape = Shape(mesh) elif label.startswith('Stem') and is_green: shape = Shape(mesh, stem_material) elif label.startswith('Leaf') and is_green: shape = Shape(mesh, leaf_material) elif not is_green: shape = Shape(mesh, soil_material) shape.id = shape_id scene.add(shape)
def shapes(self, scale, polyline, radius): """ Compute the geometric objects from the spec. scale= 'polyline': tree skeleton is made by polylines. scale= 'axis': tree skeleton is made by generalized cylinder. scale= 'cylinder': tree skeleton is made by cylinders. scale= 'point': tree skeleton is made by set of points. """ p = polyline if scale == 'polyline': if self.position != Vector3(0, 0, 0): polyline = Translated(self.position, p) else: polyline = p return [Shape(polyline, self.color)] elif scale == 'axis' or scale == 'point': n = len(p) taper = 0.9 if n > 1: step = taper * (98 / 100.) / float(n) else: return [] r = [ Vector2(radius * (1. - i * step), radius * (1. - i * step)) for i in range(n) ] sweep = Extrusion(polyline, self.section, Point2Array(r)) sweep = Translated(self.position, sweep) if scale == 'point': d = Discretizer() sweep.apply(d) points = d.getDiscretization() return [Shape(PointSet(points.pointList), self.color)] else: return [Shape(sweep, self.color)] elif scale == 'cylinder': sweeps = [] n = len(polyline) taper = 0.9 if n > 1: step = taper / float(n) else: return [] r = [ Vector2(radius * (1. - i * step), radius * (1. - i * step)) for i in range(n) ] for i in range(n - 1): p1, p2 = polyline[i] + self.position, polyline[ i + 1] + self.position r1, r2 = r[i], r[i + 1] local_r = Point2Array([Vector2(r1), Vector2(r2)]) sweep = Extrusion(Polyline([p1, p2]), self.section, local_r) sweeps.append(Shape(sweep, self.color)) return sweeps
def irradiance_distribution(meteo, geo_location, irradiance_unit, time_zone='Europe/Paris', turtle_sectors='46', turtle_format='uoc', sun2scene=None, rotation_angle=0., icosphere_level=None): """Calculates irradiance distribution over a semi-hemisphere surrounding the plant [umol m-2 s-1]. Args: meteo (DataFrame): meteo data having the following columns: time (datetime): UTC time Tac (float): [°C] air temperature hs (float): (%) air relative humidity Rg or PPFD (float): respectively global [W m-2] or photosynthetic photon flux density [umol m-2 s-1] u (float): [m s-1] wind speed Ca (float): [ppm] CO2 concentration in the air Pa (float): [kPa] atmospheric pressure geo_location: tuple of (latitude [°], longitude [°], elevation [°]) irradiance_unit (str): unit of the irradiance flux density, one of ('Rg_Watt/m2', 'RgPAR_Watt/m2', 'PPFD_umol/m2/s') time_zone (str): a 'pytz.timezone' (e.g. 'Europe/Paris') turtle_sectors (str): number of turtle sectors (see :func:`turtle` from `sky_tools` package) turtle_format (str): format irradiance distribution, could be 'soc', or 'uoc' (see :func:`turtle` from `sky_tools` package for details) sun2scene (pgl.scene): if provided, a sun object (sphere) is added to it rotation_angle (float): [°] counter clockwise azimuth between the default X-axis direction (South) and real direction of X-axis icosphere_level (int): the level of refinement of the dual icosphere (see :func:`alinea.astk.icosphere.turtle_dome` for details) Returns: [umol m-2 s-1] tuple of tuples, cumulative irradiance flux densities distributed across the semi-hemisphere surrounding the plant (float) [-] diffuse-to-total irradiance ratio Notes: meteo data can consist of only one line (single event) or multiple lines. In the latter case, this function returns accumulated irradiance throughtout the entire periode with sun positions corresponding to each time step. TODO: replace by the icosphere procedure """ diffuse_ratio = [] nrj_sum = 0 for idate, date in enumerate(meteo.index): if irradiance_unit.split('_')[0] == 'PPFD': energy = meteo.loc[date, :].PPFD else: try: energy = meteo.loc[date, :].Rg except: raise TypeError( "'irradiance_unit' must be one of the following 'Rg_Watt/m2', 'RgPAR_Watt/m2' or'PPFD_umol/m2/s'." ) # First check: convert irradiance to W m-2 (Spitters method always gets energy flux as Rg Watt m-2) corr = e_conv_Wm2(irradiance_unit) energy = energy * corr # Second check: Convert to UTC datetime latitude, longitude, elevation = [geo_location[x] for x in range(3)] temperature = meteo.Tac.values[0] date_utc, lst = local2solar(date, latitude, longitude, time_zone, temperature) doy_utc = date_utc.timetuple().tm_yday hour_utc = date_utc.hour + date_utc.minute / 60. # R: Attention, ne renvoie pas exactement le même RdRsH que celui du noeud 'spitters_horaire' dans topvine. diffuse_ratio_hourly = RdRsH(energy, doy_utc, hour_utc, latitude) diffuse_ratio.append(diffuse_ratio_hourly * energy) nrj_sum += energy # Third and final check: it is always desirable to get energy as PPFD energy = energy * (0.48 * 4.6) irradiance_diff = diffuse_ratio_hourly * energy irradiance_dir = (1 - diffuse_ratio_hourly) * energy # diffuse irradiance if not icosphere_level: energy2, emission, direction, elevation, azimuth = turtle.turtle( sectors=turtle_sectors, format=turtle_format, energy=irradiance_diff) else: vert, fac = ico.turtle_dome(icosphere_level) direction = ico.sample_faces(vert, fac, iter=None, spheric=False).values() direction = [idirect[0] for idirect in direction] direction = map(lambda x: tuple(list(x[:2]) + [-x[2]]), direction) sky = list( zip( len(direction) * [irradiance_diff / len(direction)], direction)) # direct irradiance sun = Gensun.Gensun()(Rsun=irradiance_dir, DOY=doy_utc, heureTU=hour_utc, lat=latitude) sun = GetLightsSun.GetLightsSun(sun) sun_data = [(float(sun.split()[0]), (float(sun.split()[1]), float(sun.split()[2]), float(sun.split()[3])))] # diffuse irradiance (distributed over a dome) + direct irradiance (localized as point source(s)) source = sky.__add__(sun_data) source = [list(isource) for isource in source] try: for j in range(len(source) - 1): source_cum[j][0] += source[j][0] source_cum.append(source[-1]) except NameError: source_cum = [] for isource in source: source_cum.append([isource[0], isource[1]]) if date == meteo.index[-1]: source_cum = [tuple(isource) for isource in source_cum] # Rotate irradiance sources to cope with plant row orientation if rotation_angle != 0.: v_energy = [vec[0] for vec in source_cum] v_coord = [ tuple( vector_rotation(vec[1], (0., 0., 1.), deg2rad(rotation_angle))) for vec in source_cum ] source_cum = zip(v_energy, v_coord) # Add Sun to an existing pgl.scene if sun2scene != None: xSun, ySun, zSun = -500. * array( [source_cum[-1][1][i] for i in range(3)]) if zSun >= 0: ss = Translated(xSun, ySun, zSun, Sphere(20)) sun = Shape(ss, Material('yellow', Color3(255, 255, 0))) sun2scene.add(sun) Viewer.display(sun2scene) # Diffuse_ratio mean if nrj_sum > 0: diffuse_ratio = sum(diffuse_ratio) / nrj_sum else: diffuse_ratio = 1 # Filter black sources up to the penultimate (hsCaribu expect at least one source) source_cum = [v for v in source_cum if v[0] > 0] if len(source_cum) == 0: # night source_cum = [(0, (0, 0, -1))] return source_cum, diffuse_ratio
def geom2shape(vid, mesh, scene, colors): shape = None if isinstance(mesh, list): for m in mesh: geom2shape(vid, m, scene, colors) return if mesh is None: return if isinstance(mesh, Shape): shape = mesh mesh = mesh.geometry label = labels.get(vid) is_green = greeness.get(vid) if colors: shape = Shape(mesh, Material(Color3(*colors.get(vid, [0, 0, 0])))) elif not greeness: if not shape: shape = Shape(mesh) elif label.startswith('Stem') and is_green: shape = Shape(mesh, stem_material) elif label.startswith('Leaf') and is_green: shape = Shape(mesh, leaf_material) elif not is_green: shape = Shape(mesh, soil_material) shape.id = vid scene.add(shape)
def interpret(self, instanciation=True, colorproperty=None, bounds=None, colormap='jet'): import openalea.lpy as lpy from openalea.plantgl.all import PglTurtle, Scene, Group, Shape print 'Instanciation :', instanciation def smb_interpret(cmd, turtle): ls = lpy.Lstring(cmd) lpy.turtle_interpretation(ls, turtle) def transf_interpret(cmd, smb, turtle): ls = lpy.Lstring(cmd) #print 'interpret', ls, cmd turtle.push() sc = lpy.turtle_partial_interpretation(ls, turtle) turtle.customGeometry(smb) turtle.pop() def sc2group(sc): if len(sc) == 1: return sc[0].geometry return Group([sh.geometry for sh in sc]) def color_scene(sc, color): from openalea.plantgl.all import Discretizer, Scene d = Discretizer() for sh in sc: sh.geometry.apply(d) tr = d.result tr.colorList = [color for i in xrange(len(tr.indexList))] tr.colorPerVertex = False sh.geometry = tr geommap = dict() invorderednodes = [] if colorproperty: from openalea.plantgl.scenegraph.colormap import PglColorMap if type(colorproperty) == str: cproperty = self.node_property(colorproperty) else: cproperty = colorproperty if bounds: cmap = PglColorMap(bounds[0], bounds[1], colormap) else: cmap = PglColorMap(min(cproperty.values()), max(cproperty.values()), colormap) for node in self.postorder_node_traversal(): t = PglTurtle() #print node smb_interpret(self.geom(node), t) if colorproperty: color_scene(t.getScene(), cmap(cproperty[node])) if self.nb_children(node) > 0: for cchild, edgecmds in self.geomcommands[node][1].items(): for edgecmd in edgecmds: transf_interpret( edgecmd, geommap[cchild] if instanciation else geommap[cchild].deepcopy(), t) smb = sc2group(t.getScene()) smb.name = 'Shape_' + str(node) geommap[node] = smb t = PglTurtle() if colorproperty: return Scene([Shape(geommap[self.root], t.getColorList()[1])]) + cmap.pglrepr() else: return Scene([Shape(geommap[self.root], t.getColorList()[1])])