def surfacescan(scene, density): result = [] for shape in scene: position = pgl.Vector3(0, 0, 0) heading = pgl.Vector3(0, 0, 1) geometry = shape.geometry while isinstance(geometry, pgl.Transformed): if isinstance(geometry, pgl.Translated): position = geometry.translation if isinstance(geometry, pgl.Oriented): heading = cross(geometry.primary, geometry.secondary) geometry = geometry.geometry if isinstance(geometry, pgl.Cylinder): for p in range( int((pi * (geometry.radius**2) * geometry.height) // density)): v = pgl.Vector3(random.rand() * 2 - 1, random.rand() * 2 - 1, random.rand() * 2 - 1) pos = position + \ pgl.Vector3(cross(heading, v)).normed() * (geometry.radius) point = pos + heading * random.rand() * geometry.height result.append(point) elif isinstance(geometry, pgl.Extrusion): result.append(geometry.axis) result = pgl.PointSet(result) return result
def cones(obj, **kwds): X_attr = kwds.get('X_attr', 'X') Y_attr = kwds.get('Y_attr', 'Y') pos_dist = kwds.get('dist', 'Distance') pos_az = kwds.get('az', 'Azimuth') circ_attr = kwds.get('circ_attr', 'Circonference') height_attr = kwds.get('height_attr', 'Haut') botHoup_attr = kwds.get('botHoup', 'BaseHoup') radiusHoup_prefix = kwds.get('radiusHoup_prefix', 'r_houp') radiusHoup = kwds.get('radiusHoup', None) wood = kwds.get('wood', True) rgb = kwds.get('rgb', None) spec_name = kwds.get('spec_name', 'houppier_mat') if not obj.__dict__.has_key("posX") and not obj.__dict__.has_key("posY"): try: r = obj.__dict__[pos_dist] a = obj.__dict__[pos_az] obj.posX = r * cos(radians(forest2geomAZ(a))) obj.posY = r * sin(radians(forest2geomAZ(a))) except KeyError: obj.posX = obj.__dict__[X_attr] obj.posY = obj.__dict__[Y_attr] ht = 100 * (obj.__dict__[height_attr] - obj.__dict__[botHoup_attr]) rd_kz = [k for k in obj.__dict__.keys() if radiusHoup_prefix in k] radii = [obj.__dict__[k] for k in rd_kz] if radiusHoup: if radiusHoup == 'Max': cone_radius = 1.0 * max(radii) else: cone_radius = obj.__dict__[radiusHoup] else: cone_radius = 1.0 * sum(radii) / len(radii) #cone_radius = ht/2. h = pgl.Translated( pgl.Vector3(obj.posX, obj.posY, obj.__dict__[botHoup_attr] * 100), pgl.Cone(cone_radius, ht, 1, 12)) tr = pgl.Translated( pgl.Vector3(obj.posX, obj.posY, 0), pgl.Cylinder(obj.__dict__[circ_attr] / (2 * pi), obj.__dict__[botHoup_attr] * 100 + ht * 0.1)) if rgb == None: s_h = pgl.Shape(h, stand_material(spec_name=spec_name)) else: r, g, b = rgb s_h = pgl.Shape(h, stand_material(r, g, b, spec_name)) s_tr = pgl.Shape( tr, stand_material(spec_name="trunk_mat"), ) # s_h.id*10 ) if wood: return (s_h, s_tr) else: return (s_h, )
def tgl(): return pgl.TriangleSet( pgl.Point3Array([ pgl.Vector3(1, 0, 0), pgl.Vector3(-0.2, 1, 0), pgl.Vector3(-0.2, -1, 0) ]), pgl.Index3Array([pgl.Index3(0, 1, 2)]))
def mangoLeaf(length = 1, alpha=0, color = __niceGreen): x = array(arange(0.1,length,0.1)) y = (-3/(length*5.)) * (x**2/length - x) cos = math.cos(math.radians(alpha/2.0)) sin = math.sin(math.radians(alpha/2.0)) list = [] idxList = [] for i in range(len(x)): list.append(pgl.Vector3(x[i],0,0)) list.append(pgl.Vector3(x[i],y[i]*cos,y[i]*sin)) list.append(pgl.Vector3(x[i],-y[i]*cos,y[i]*sin)) list.append(pgl.Vector3(0,0,0)) list.append(pgl.Vector3(length,0,0)) for i in range(len(x) -1): idxList.append(pgl.Index(3*(i+1), 3*(i+1)+1, 3*i+1, 3*i )) idxList.append(pgl.Index(3*i+2, 3*(i+1)+2, 3*(i+1), 3*i )) #idxList.append(pgl.Index(3*i,3*i+1,3*(i+1)+1, 3*(i+1))) #idxList.append(pgl.Index(3*i,3*(i+1),3*(i+1)+2,3*i+2)) idxList.append(pgl.Index(0, 1, len(list)-2 )) idxList.append(pgl.Index(2, 0, len(list)-2 )) idxList.append(pgl.Index(3*(len(x)-1)+1, 3*(len(x)-1), len(list)-1 )) idxList.append(pgl.Index(3*(len(x)-1), 3*(len(x)-1)+2, len(list)-1 )) #idxList.append(pgl.Index(len(list)-2, 1, 0)) #idxList.append(pgl.Index(len(list)-2, 0, 2)) #idxList.append(pgl.Index(len(list)-1, 3*(len(x)-1), 3*(len(x)-1)+1)) #idxList.append(pgl.Index(len(list)-1, 3*(len(x)-1)+2, 3*(len(x)-1))) #p3r = pgl.Point3Array(list) #ir = pgl.IndexArray(idxList) fs = pgl.FaceSet(list,idxList) return pgl.Shape(fs, color)
def leaf(**kwds): global __myLeaf if __myLeaf is None: __myLeaf = mangoLeaf(alpha=20) rp = rdm_pos((1, 1, 1)) rx, ry, rz = rp.x, rp.y, rp.z az, el, rl = rdm_orientation() x = kwds.get('x', rx) y = kwds.get('y', ry) z = kwds.get('z', rz) delta = kwds.get('rotz', az) phi = kwds.get('roty', el) psi = kwds.get('rotx', rl) size = kwds.get('len', 10.0) color = kwds.get('color', __niceGreen) if not size: size = 10.0 print "length is None, using 10 instead : small leaf" v = pgl.Vector3(x, y, z) #print "leaf size : ", size #sx = pgl.Vector3(4,1,1) * size/40. #scaled_geometry = pgl.Scaled(sx, pgl.Translated(pgl.Vector3(0.5,0,0), pgl.Disc(0.5, 6)) ) sx = pgl.Vector3(1, 1, 1) * size / 10. scaled_geometry = pgl.Scaled(sx, __myLeaf.geometry) rotated_geometry = pgl.EulerRotated(delta, phi, psi, scaled_geometry) tr = pgl.Translated(v, rotated_geometry) return pgl.Shape(tr, color)
def genericLeaf(allo_length, allo_surf, **kwds): if kwds.has_key('surface'): surface = kwds['surface'] length = math.sqrt(surface / (allo_length*allo_surf) ) else: length = kwds.get('length', 1) alpha = kwds.get('alpha', 0) color = kwds.get('color', __niceGreen) step = length/10. x = array(arange(step,length,step)) #begin and end are specific y = (-3.0*allo_length*allo_surf) * (x**2/length - x) cos = math.cos(math.radians(alpha/2.0)) sin = math.sin(math.radians(alpha/2.0)) list = [] idxList = [] for i in range(len(x)): list.append(pgl.Vector3(x[i],0,0)) list.append(pgl.Vector3(x[i],y[i]*cos,y[i]*sin)) list.append(pgl.Vector3(x[i],-y[i]*cos,y[i]*sin)) list.append(pgl.Vector3(0,0,0)) list.append(pgl.Vector3(length,0,0)) for i in range(len(x) -1): idxList.append(pgl.Index(3*(i+1), 3*(i+1)+1, 3*i+1, 3*i )) idxList.append(pgl.Index(3*i+2, 3*(i+1)+2, 3*(i+1), 3*i )) idxList.append(pgl.Index(0, 1, len(list)-2 )) idxList.append(pgl.Index(2, 0, len(list)-2 )) idxList.append(pgl.Index(3*(len(x)-1)+1, 3*(len(x)-1), len(list)-1 )) idxList.append(pgl.Index(3*(len(x)-1), 3*(len(x)-1)+2, len(list)-1 )) p3r = pgl.Point3Array(list) ir = pgl.IndexArray(idxList) fs = pgl.FaceSet(p3r, ir) return pgl.Shape(fs, color)
def generate_random_point(size=[1, 1, 1], distribution='uniform'): from random import uniform, gauss if distribution == 'uniform': return pgl.Vector3(uniform(-size[0], size[0]), uniform(-size[1], size[1]), uniform(-size[2], size[2])) elif distribution == 'gaussian': return pgl.Vector3(gauss(0, size[0] / 3.), gauss(0, size[1] / 3.), gauss(0, size[1] / 3.))
def arrow(x,y,z,length,az=0, el=0, radius=None, color=color(255,255,255),id=0): if radius==None: radius=length*0.05 rad_az = math.radians(az) rad_el = math.pi/2 - math.radians(el) v = pgl.Vector3( x, y, z ) c = pgl.Cylinder(radius, length*0.8, 10) con =pgl.Translated(pgl.Vector3(0,0,length*0.7), pgl.Cone(2*radius, length*0.3)) arr = pgl.Group([c,con]) dir_arr = pgl.EulerRotated(rad_az,rad_el,0,arr) tr_dir_arr = pgl.Translated(v,dir_arr) return pgl.Shape(tr_dir_arr, color, id)
def _common_init( self, **keys ): """ """ if "height" in keys: self._height = keys[ "height" ] else: self._height = pgl.norm( keys[ "axis" ] ) self._radius = keys[ "radius" ] self.shaft = pgl.Scaled(pgl.Vector3(1, 1, AARROW_SHAFT_PROPORTION), ACYLINDER_PRIMITIVE ) self.head = pgl.Translated(pgl.Vector3(0, 0, AARROW_SHAFT_PROPORTION), pgl.Scaled(pgl.Vector3( AARROW_HEAD_PROPORTION,AARROW_HEAD_PROPORTION,1-AARROW_SHAFT_PROPORTION), ACONE_PRIMITIVE) )
def _set_radius(self, radius=ACYLINDER_STANDARD_RADIUS): """Property helper method. """ if radius != self._radius: self._radius = radius self.scale = pgl.Vector3(2 * self._radius, 2 * self._radius, self._height)
def inflorescence(g, vid, turtle): """ HT: inflorescence Box (may change) parameters: ----------- g: is a current MTG vid: vertex id in the mtg turtle: openalea.pltgl.turtle return: ---------- for each HT in mtg return an object compose of cylender and a blue box. Shape of the box is dependent of the number of total flower and number of open flowers. """ t = colors_turtle(turtle) nid = g.node(vid) order = nid.order nb_flower = nid.FLWRNUMBER nb_flower_open = nid.FLWRNUMBER_OPEN t.setColor(2 + order) turtle.F(0.2) if nb_flower is None: nb_flower = 0.5 if nb_flower_open is None or nb_flower_open == 0: nb_flower_open = 0.5 cube = pgl.Box(0.05 * pgl.Vector3(1, 1, nb_flower_open / 4.)) tap = pgl.Tapered(3. / 20 * nb_flower, 3. / 20 * nb_flower_open, cube) turtle.customGeometry(tap)
def scene2grid(scene, gridSize): """ Convert a scene into a matrix-grid where non-zero values are the coresponding surface included in the coresponding voxel """ bbox = pgl.BoundingBox(scene) epsilon = pgl.Vector3(0.01, 0.01, 0.01) origin = bbox.lowerLeftCorner - epsilon step = (bbox.getSize() + epsilon) * 2 / (gridSize) """ getSize is a radius vector whereas gridSize is the voxel number desired per dimension, hence the gridSize must be *2 """ print "Bbox size : ", bbox.getSize() * 2 print "Step : ", step, " gridSize : ", gridSize grid = {} tgl_list = surfPerTriangle(scene) for tgl in tgl_list: pos = gridIndex(tgl[0] - origin, step) if grid.has_key(pos): grid[pos] += tgl[1] else: grid[pos] = tgl[1] print "nbTgl : ", len(tgl_list), " <---> nbVoxel : ", len(grid) kize = grid.keys() kize.sort() pts = [] mass = [] for k in kize: pts.append(list(k)) mass.append(grid[k]) return (pts, mass, step) #gridSize )
def weber_penn_markov(parameters, seed, position, p0, p1): if not parameters: return random.seed(seed) scene = Scene() client = Markov_Laws(parameters, p0, p1) server = tree_server.TreeServer(client) server.run() if not position: position = pgl.Vector3(0., 0., 0.) Vector2 = pgl.Vector2 p = [ Vector2(0.5, 0), Vector2(0, 0.5), Vector2(-0.5, 0), Vector2(0, -0.5), Vector2(0.5, 0) ] section = pgl.Polyline2D(p) geom = tree_geom.GeomEngine(server, section, position) scene = geom.scene('axis', scene) return scene,
def _set_height( self, height=ACYLINDER_STANDARD_HEIGHT): """Property helper method. """ #TODO think about norm(self._axis) height relation. Shouldn't it be updated? if height != self._height: self._height = height self.scale = pgl.Vector3( 2*self.radius, 2*self.radius, self._height )
def inflorescence(g, vid, turtle): """Generates the inflorescences HT: inflorescence Box (may change) for each HT in mtg return an object compose of cylender and a blue box. Shape of the box is dependent of the number of total flower and number of open flowers. :param g: MTG :type g: MTG :param vid: vid selected :type vid: int :param turtle: Turtle :type turtle: Turtle :return: for each HT in mtg return an object compose of cylender and a blue box. :rtype: [type] """ t = colors_turtle(turtle) nid = g.node(vid) order = nid.order nb_flower = nid.FLWRNUMBER nb_flower_open = nid.FLWRNUMBER_OPEN t.setColor(2+order) turtle.F(0.2) if nb_flower is None: nb_flower = 0.5 if nb_flower_open is None or nb_flower_open == 0: nb_flower_open = 0.5 cube = pgl.Box(0.05*pgl.Vector3(1,1,nb_flower_open/4.)) tap = pgl.Tapered(3./20*nb_flower, 3./20*nb_flower_open, cube) turtle.customGeometry(tap)
def transform4(matrix, shape): """ Return a shape transformed by a Matrix4. """ if matrix == None: matrix = pgl.Matrix4() scale, (a, e, r), translation = matrix.getTransformation2() if type(shape) is pgl.Cylinder and matrix != pgl.Matrix4(): #print "scale for cylinder is :", scale #print "scale.xyz = ", scale.x, scale.y, scale.z if round(scale.x, 1) == 1.0 and round(scale.y, 1) == 1.0 and round( scale.z, 1) == 1.0: shape = pgl.Translated(translation, pgl.EulerRotated(a, e, r, shape)) else: raise Exception, "Invalid transformation for cylinder!" elif type(shape) is pgl.Sphere: shape = pgl.Translated( translation, pgl.EulerRotated(a, e, r, pgl.Scaled(scale, shape))) elif type(shape) is pgl.BezierPatch: scale1 = pgl.Vector3(1, 1, 1) shape = pgl.Translated( translation, pgl.EulerRotated(a, e, r, pgl.Scaled(scale, pgl.Scaled(scale1, shape)))) else: shape = pgl.Translated( translation, pgl.EulerRotated(a, e, r, pgl.Scaled(scale, shape))) return shape
def center(pointList): """centre d'une liste de points""" v= pgl.Vector3(0,0,0) for pt in pointList: v += pt v /= len(pointList) return v
def disc( x,y,z, color=color( 30,10,140 ) ): v = pgl.Vector3( x, y, z ) d = pgl.Disc( 0.4, 5 ) azimuth, elevation, roll= rdm_orientation() rotated_geometry= pgl.EulerRotated(azimuth, elevation, roll, d) tr = pgl.Translated( v,rotated_geometry ) return pgl.Shape( tr, color )
def NURBSCurve(self, ctrlpoints, dimension, **kwds): ctrlpoints = str(ctrlpoints) ctrlpoints = [float(num) for num in ctrlpoints.split(",")] dimension = int(dimension) items, chunk = ctrlpoints, dimension pointArray = zip(*[iter(items)] * chunk) if (dimension == 2): v4array = [] for item in pointArray: v4array.append(pgl.Vector2(item)) parray = pgl.Point3Array(0) for item in v4array: parray.append(Vector3(item,1)) return (pgl.NurbsCurve2D(parray), None) elif (dimension == 3): v4array = [] for item in pointArray: v4array.append(pgl.Vector3(item)) parray = pgl.Point4Array(0) for item in v4array: parray.append(Vector4(item,1)) return (pgl.NurbsCurve(parray), None)
def getProjectionMatrix(forward, up = pgl.Vector3(0,0,1)): forward.normalize() up.normalize(); side = pgl.cross(up, forward); side.normalize(); up = pgl.cross(forward, side); up.normalize(); return pgl.Matrix3(side, up, forward).inverse()
def plotSkyTurtle(): pgl.Viewer.start() sc = pgl.Scene() for i in range(len(elevations)): pos = pgl.Vector3(pgl.Vector3.Spherical(30,radians(azimuths[i]),radians(90-elevations[i]))) sc += pgl.Shape(pgl.Translated(pos,pgl.Sphere(0.5)),pgl.Material(),i+1) pgl.Viewer.display(sc) return sc
def simplify(leaf, nb_points): xn, yn, sn, rn = leaf points = [pgl.Vector3(*pt) for pt in izip(xn, rn, yn)] pts = filter(None, cost(points, nb_points)) coords = ((pt.x, pt.y, pt.z) for pt in pts) x, r, y = map(array, izip(*coords)) s = curvilinear_abscisse(x, y) return x, y, s, r
def process_line(line): line = line.strip() if not line: return if line[0] == '#': return l = line.split() nb_polygon = int(l[-10]) assert nb_polygon == 3 coords = list(map(float, l[-9:])) label = l[2] if len(label) < 11: label = (12 - len(label)) * '0' + label triangle = (pgl.Vector3(*coords[:3]), pgl.Vector3(*coords[3:6]), pgl.Vector3(*coords[6:])) return label, triangle
def __init__(self, radius=absolute_shapes.ASPHERE_STANDARD_RADIUS, **keys): """Default constructior. """ keys.update({"radius": radius}) self._common_init(**keys) AIShape3D.__init__(self, scale=pgl.Vector3(2 * self.radius, 2 * self.radius, 2 * self.radius), geometry=absolute_shapes.ASPHERE_PRIMITIVE, **keys)
def Inflo_Primordia(g, vid, turtle): """ ht: Primordia inflorescence """ t = turtle #turtle.setColor(1) nid = g.node(vid) order = nid.order t.setColor(8 + order) turtle.F(0.1) cube = pgl.Box(0.02 * pgl.Vector3(1, 1, 1)) turtle.customGeometry(cube)
def to_geom_args(self, conversion=1.0, name=None, _as_obj=False): # pragma: lpy r"""Get arguments for creating a PlantGL geometry. Args: conversion (float, optional): Conversion factor that should be applied to the vertices. Defaults to 1.0. name (str, optional): Name that should be given to the created PlantGL symbol. Defaults to None and is ignored. Returns: tuple: Class, arguments and keyword arguments for PlantGL geometry. """ import openalea.plantgl.all as pgl kwargs = dict() # Add vertices obj_points = [] obj_colors = [] for v in self['vertices']: xarr = conversion * np.array([v[k] for k in ['x', 'y', 'z']]) obj_points.append( pgl.Vector3(np.float64(xarr[0]), np.float64(xarr[1]), np.float64(xarr[2]))) c = [v.get(k, None) for k in ['red', 'green', 'blue']] if None not in c: cast_type = int obj_colors.append( pgl.Color4(cast_type(c[0]), cast_type(c[1]), cast_type(c[2]), cast_type(1))) points = pgl.Point3Array(obj_points) if obj_colors: colors = pgl.Color4Array(obj_colors) kwargs['colorList'] = colors kwargs['colorPerVertex'] = True # Add indices obj_indices = [] index_class = pgl.Index array_class = pgl.IndexArray smb_class = pgl.FaceSet # index_class = pgl.Index3 # array_class = pgl.Index3Array # smb_class = pgl.TriangleSet for f in self['faces']: if _as_obj: f_int = [int(_f['vertex_index']) for _f in f] else: f_int = [int(_f) for _f in f['vertex_index']] obj_indices.append(index_class(*f_int)) indices = array_class(obj_indices) args = (points, indices) return smb_class, args, kwargs
def pgl_scene(g, flip=False): geometry = g.property('geometry') scene = pgl.Scene() for id in geometry: if not flip: sh = pgl.Shape(geometry[id]) else: sh = pgl.Shape(pgl.AxisRotated(pgl.Vector3(1, 0, 0), pi, geometry[id])) sh.id = id scene.add(sh) return scene
def __init__( self, radius=absolute_shapes.ACYLINDER_STANDARD_RADIUS, axis=absolute_shapes.ACYLINDER_STANDARD_AXIS, **keys ): """ Default constructor. """ #if keys.has_key("height"): # self._height = keys[ "height" ] #else: # self._height = pgl.norm( axis ) #self._radius = radius keys.update( {"radius": radius, "axis": axis} ) absolute_shapes.ACylinder._common_init( self, **keys ) AIShape3D.__init__( self, scale=pgl.Vector3(2*self.radius,2*self.radius,self.height), geometry=absolute_shapes.ACYLINDER_PRIMITIVE, **keys )
def add_sun(scene, sun, distance=5, radius=0.1): elevation, azimuth, luminance = sun colors = jet_colors(luminance) pgl_colors = [pgl.Material(pgl.Color3(r, g, b)) for r, g, b in colors] sph = pgl.Sphere(radius) #red = pgl.Material(pgl.Color3(150, 0, 0)) pos = cartesian(elevation, azimuth, distance) pgl_pos = [pgl.Vector3(*p) for p in pos] for i, vect in enumerate(pgl_pos): shape = pgl.Translated(vect, sph) scene.add(pgl.Shape(shape, pgl_colors[i])) return scene
def transform(self, mesh, face_up=False): x = self.getUp() if face_up: z = pgl.Vector3(0, 0, 1) else: z = self.getHeading() bo = pgl.BaseOrientation(x, z ^ x) matrix = pgl.Transform4(bo.getMatrix()) matrix.translate(self.getPosition()) # print 'Position ', turtle.getPosition() mesh = mesh.transform(matrix) return mesh