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 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 test_duplicate(): lp = LsystemParameters() lp.set_color(0,Material((255,20,1))) lp.set_color(0,Material((20,255,1))) assert len(lp.get_colors()) == 1 lp.add('test', 1, category='test') lp.add('test', 1., category='test') assert len(lp.get_category_parameters('test')) == 1
def create_scene_from_mtg(mtg, leaf_material=None, stem_material=None, soil_material=None, colors=None): """ Returns a plantgl scene from an mtg. """ if colors is None: if leaf_material is None: leaf_material = Material(Color3(0, 180, 0)) if stem_material is None: stem_material = Material(Color3(0, 130, 0)) if soil_material is None: soil_material = Material(Color3(170, 85, 0)) # colors = g.property('color') geometries = mtg.property('geometry') greeness = mtg.property('is_green') labels = mtg.property('label') scene = Scene() 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) for vid, mesh in geometries.iteritems(): geom2shape(vid, mesh, scene, colors) return scene
def to_material(color_list): """ ('C0', (65,45,15)) -> Material(name='C0', ambient=Color3(65,45,15)) """ from openalea.plantgl.all import Material, Color3 material_list = [] for color in color_list: material = Material(color[0], Color3(*color[1][:3])) material.diffuse = color[2] material_list.append(material) return material_list
def isSimilarToDefaultTurtleMat(cmat, i): if cmat.isTexture() : return False nbdefault = len(defaultturtlecolorlist) if i >= nbdefault: defaultmat = Material('Color_'+str(i)) else: defaultmat = Material(defaultturtlecolorlist[i]) if cmat.isSimilar(defaultmat) and cmat.name == defaultmat.name: return True else: return False
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 colorListCode(colorlist = None, referencedir = None, indentation = '\t'): init_txt = '' if not colorlist is None and len(colorlist) > 0: defaultlist = PglTurtle().getColorList() nbdefault = len(defaultlist) nbcurrent = len(colorlist) firstcol = True defaultmat = Material('default') printer = PyStrPrinter() printer.pglnamespace = 'pgl' printer.indentation = indentation printer.indentation_increment = '\t' printer.line_between_object = 0 if referencedir: printer.reference_dir = referencedir for i in range(nbcurrent): cmat = colorlist[i] if ( (i >= nbdefault) or (cmat.isTexture()) or (not cmat.isSimilar(defaultlist[i])) or (cmat.name != defaultlist[i].name)): if cmat.isTexture() or not cmat.isSimilar(defaultmat): if firstcol : init_txt += indentation+"import openalea.plantgl.all as pgl\n" firstcol = False cmat.name = 'Color_'+str(i) cmat.apply(printer) init_txt += printer.str() printer.clear() init_txt += indentation+'context.turtle.setMaterial('+repr(i)+','+str(cmat.name)+')\n' return init_txt
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 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 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 test_param_creation(): lp = LsystemParameters() lp.set_color(0,Material((255,20,1))) texture = Texture2D(ImageTexture('image/bjunipc.png'),baseColor=(255,20,1,0)) lp.set_color(1,texture) lp.set_option('Module declaration',1) lp.set_option('Warning with sharp module',0) lp.add('test', 1, category='test') lp.add('testFloat', 1.2, category='test') lp.add('testbool',True,category='test2') lp.add('testcurve1',NurbsCurve2D([(0,0,1),(0,1,1),(1,1,1),(1,0,1)]), category='test') lp.add('testcurve2',BezierCurve2D([(0,0,1),(0,1,1),(1,1,1),(1,0,1)]), category='test') lp.add('testcurve3',Polyline2D([(0,0),(0,1),(1,1),(1,0)]), category='test2') lp.add_function('testfunc',NurbsCurve2D([(0,0,1),(0,1,1),(1,1,1),(1,0,1)]), category='test2') lp.add('testpatch',NurbsPatch([[(0,-0.5+j/3.,i/3.,1) for j in range(4)] for i in range(4)]), category='test2') lp.get_category_info('test')['visible'] = True lp.get_category_info('test2')['visible'] = True lp.check_validity() return lp
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 build_scene(mtg, position=(0, 0, 0), orientation=0, leaf_material=None, stem_material=None, soil_material=None, colors=None): """ Returns a plantgl scene from an mtg. """ if not isinstance(mtg, list): mtg = [mtg] if not isinstance(position, list): position = [position] if not isinstance(orientation, list): orientation = [orientation] if colors is None: if leaf_material is None: leaf_material = Material(Color3(0, 180, 0)) if stem_material is None: stem_material = Material(Color3(0, 130, 0)) if soil_material is None: soil_material = Material(Color3(170, 85, 0)) # colors = g.property('color') scene = Scene() 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) nump = [] count = 0 for i, (g, p, o) in enumerate(zip(cycle(mtg), position, cycle(orientation))): geometries = g.property('geometry') greeness = g.property('is_green') labels = g.property('label') for vid, mesh in geometries.items(): geom2shape(vid, mesh, scene, colors, p, o, vid + count) nump.append(i) count += len(g) return scene, nump
""" 3D Scene Maker from a tree and its specifications. Author: Christophe Pradal ([email protected]) """ from openalea.plantgl.all import (BezierPatch, Discretizer, Viewer, Scene, Shape, Material, Color3, Extrusion, Polyline, Point2Array, Point4Matrix, PointSet, Vector2, angle, AxisRotated, Oriented, Translated, Scaled, Vector3, EulerRotated, Vector4) brown = Material(Color3(120, 60, 10)) green = Material(Color3(4, 69, 4), diffuse=0.768116, specular=Color3(116, 116, 116)) green.name = "green_leaf" def bezier_leaf(): l = [] l.append([ Vector4(-0.00170203, 0.00487903, -0.00155362, 1), Vector4(-0.00946124, 0.0267487, 0.00857975, 1), Vector4(-0.0145598, 0.0310762, 0.0565383, 1), Vector4(-0.00422035, 0.0237428, 0.101953, 1) ]) l.append([ Vector4(3.9604e-05, 0.0019996, 5.60056e-06, 1), Vector4(-0.00466331, 0.00703859, 0.0339818, 1), Vector4(-0.00868596, 0.00523895, 0.076457, 1),
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 initialisationFunction(self,withall=True): header = "def "+LsysContext.InitialisationFunctionName+"(context):\n" init_txt = '' if withall: defaultlist = PglTurtle().getColorList() currentlist = self.lsystem.context().turtle.getColorList() nbdefault = len(defaultlist) nbcurrent = len(currentlist) firstcol = True defaultmat = Material('default') printer = PyStrPrinter() printer.pglnamespace = 'pgl' printer.indentation = '\t' printer.indentation_increment = '\t' printer.line_between_object = 0 if self.fname and len(self.fname) > 0: printer.reference_dir = os.path.abspath(os.path.dirname(self.getStrFname())) #print printer.reference_dir for i in xrange(nbcurrent): cmat = currentlist[i] if ( (i >= nbdefault) or (cmat.isTexture()) or (not cmat.isSimilar(defaultlist[i])) or (cmat.name != defaultlist[i].name)): if cmat.isTexture() or not cmat.isSimilar(defaultmat): if firstcol : init_txt += "\timport openalea.plantgl.all as pgl\n" firstcol = False cmat.name = 'Color_'+str(i) cmat.apply(printer) init_txt += printer.str() printer.clear() init_txt += '\tcontext.turtle.setMaterial('+repr(i)+','+str(cmat.name)+')\n' if not self.lsystem.context().is_animation_timestep_to_default(): init_txt += '\tcontext.animation_timestep = '+str(self.getTimeStep())+'\n' options = self.lsystem.context().options for i in xrange(len(options)): if not options[i].isToDefault(): init_txt += '\tcontext.options.setSelection('+repr(options[i].name)+','+str(options[i].selection)+')\n' if len(self.scalars): init_txt += '\tscalars = '+str([i.tostr() for i in self.scalars])+'\n' init_txt += '\tcontext["__scalars__"] = scalars\n' init_txt += '\tfor s in scalars:\n\t\tif not s[1] == "Category" : context[s[0]] = s[2]\n' def emptyparameterset(params): for panel,data in params: if len(data) > 0: return False return True if not emptyparameterset(self.visualparameters) : intialized_managers = {} panelid = 0 for panelinfo,objects in self.visualparameters: if panelinfo.get('active',True) or withall: for manager,obj in objects: if not intialized_managers.has_key(manager): intialized_managers[manager] = True init_txt += manager.initWriting('\t') init_txt += manager.writeObject(obj,'\t') init_txt += '\tpanel_'+str(panelid)+' = ('+repr(panelinfo)+',['+','.join(['('+repr(manager.typename)+','+manager.getName(obj)+')' for manager,obj in objects])+'])\n' panelid += 1 init_txt += '\tparameterset = [' panelid = 0 for panelinfo,objects in self.visualparameters: if panelinfo.get('active',True) or withall: init_txt += 'panel_'+str(panelid)+',' panelid += 1 init_txt += ']\n' if withall and self.keepCode_1_0_Compatibility: init_txt += '\tcontext["__functions__"] = [' for panelinfo,objects in self.visualparameters: if panelinfo.get('active',True): for manager,obj in objects: if manager.typename == 'Function': init_txt += '('+repr(manager.getName(obj))+','+manager.getName(obj)+'),' init_txt += ']\n' init_txt += '\tcontext["__curves__"] = [' for panelinfo,objects in self.visualparameters: if panelinfo.get('active',True): for manager,obj in objects: if manager.typename == 'Curve2D': init_txt += '('+repr(manager.getName(obj))+','+manager.getName(obj)+'),' init_txt += ']\n' init_txt += '\tcontext["__parameterset__"] = parameterset\n' for panelinfo,objects in self.visualparameters: if panelinfo.get('active',True): for manager,obj in objects: init_txt += '\tcontext["'+manager.getName(obj)+'"] = '+manager.writeObjectToLsysContext(obj) + '\n' if len(init_txt) > 0: return header+init_txt else: return ''
from openalea.plantgl.all import Polyline2D, Vector2, Material green = Material('green',(1,15,1),diffuse=10,specular=(0,0,0)) def interpolate(c1, c2, t): return Polyline2D([Vector2(pi1)*(1-t)+Vector2(pi2)*t for pi1,pi2 in zip(c1,c2)]) tip = 5 b = 1.5 fsize = 10 from numpy import exp growth_logistic = lambda ttime : fsize / (1. + exp(-(ttime-tip)/b )) def growth_rate(ttime): expt = exp(-(ttime-tip)/b) return fsize * expt / (b* (1. + expt)**2)