def compute_polyline(self): if self.polyline: return angle = 0 z = Vector3(0, 0, 1) x = Vector3(1, 0, 0) p1p2 = Vector3(0, 0, 1) pt = Vector3() pt1 = pt + p1p2 * self.length[0] poly = [pt, pt1] pt = pt1 assert len(self.curvature) == len(self.nodes) - 2 for i in range(1, len(self.nodes) - 1): p1p2 = rotate_Y(p1p2, self.curvature[i - 1]) pt = pt + p1p2 * self.length[i] poly.append(pt) points = Point3Array(poly) if self.transform: t = Transform4(self.transform) points = t.transform(points) self.polyline = Polyline(points)
def stars(leaves, g, direction=Vector3(1, 1, 1), up=Vector3(0, 0, 1), right=Vector3(1, 1, 1), beam_radius=.1): from openalea.plantik.tools.convex import cvxHull from openalea.plantgl.all import BoundingBox, Viewer, norm hull = cvxHull(leaves) lad = surface(leaves) / volume(hull) print lad bbx = BoundingBox(hull) pos = bbx.upperRightCorner interception = 0. for rshift in range(bbx.getSize().y / beam_radius): for upshift in range(bbx.getSize().z / beam_radius): sx = 1 sy = 1 print pos - rshift * right - upshift * up intersections = Viewer.frameGL.castRays( pos - rshift * right - upshift * up, direction, Vector3(0.5, 0., 0), Vector3(0, 0.5, 0), sx, sy) print intersections p = 1 for intersection in intersections.flatten(): length = norm(intersection.out - getattr(intersection, 'in')) length = 1 p *= exp(-g * lad(length)) interception += (1. - p) * beam_radius**beam_radius return interception / surface(leaves)
def lookAt(self, eyePosition3D, center3D, upVector3D): forward = Vector3(center3D) - Vector3(eyePosition3D) forward.normalize() upVector3D = Vector3(upVector3D) upVector3D.normalize() side = cross(forward, upVector3D) side.normalize() up = cross(side, forward) up.normalize() m = Matrix4(side, up, forward, -eyePosition3D) self.worldToCamera = m.inverse() return m
def sample(self): """ Reinitialize control to default value """ from openalea.plantgl.all import NurbsCurve2D, Point3Array, Vector3 curve = NurbsCurve2D(Point3Array([ Vector3(-0.5, 0, 1), Vector3(-0.166667, 0, 1), Vector3(0.166667, 0, 1), Vector3(0.5, 0, 1) ]), width=2) return curve
def read_mtg(fn='walnut.mtg', drf='walnut.drf'): g = read_mtg_file(fn) topdia = lambda x: g.property('TopDia').get(x) dressing_data = dresser.dressing_data_from_file(drf) pf = plantframe.PlantFrame(g, TopDiameter=topdia, DressingData=dressing_data) pf.propagate_constraints() diameters = pf.algo_diameter() toppositions = pf.points def botdiameter(g, topdiameter): botdiam = {} for vid, topdiam in topdiameter.iteritems(): if g.edge_type(vid) == '<': botdiam[vid] = topdiameter[g.parent(vid)] else: botdiam[vid] = topdiam return botdiam g.properties()['topdiameter'] = diameters g.properties()['bottomdiameter'] = botdiameter(g, diameters) g.properties()['tipposition'] = dict([ (k, Vector3(v)) for k, v in toppositions.iteritems() ]) g = flatten(g) return g
def read_mtg(fn='walnut.mtg', drf='walnut.drf'): fileName = ('/').join(os.path.abspath(__file__).split('/')[:-1]) fn = str(fileName) + "/" + fn drf = str(fileName) + "/" + drf g = read_mtg_file(fn) topdia = lambda x: g.property('TopDia').get(x) dressing_data = dresser.dressing_data_from_file(drf) pf = plantframe.PlantFrame(g, TopDiameter=topdia, DressingData=dressing_data) pf.propagate_constraints() diameters = pf.algo_diameter() toppositions = pf.points g.properties()['TopDiameter'] = diameters g.properties()['TopPosition'] = dict([ (k, Vector3(v)) for k, v in toppositions.iteritems() ]) g = flatten(g) return g
def test(): renderer = ZBufferRenderer(10, 10) print(renderer.setPerspective(30, 1, 0.1, 100)) print(renderer.lookAt(Vector3(1, 0, 1), (0, 0, 0), (0, 0, 1))) print(renderer.projectionMatrix) print(renderer.renderPoint((0, 0, 0))) renderer.view()
def color_MTG_Nitrogen(g, df, t, SCREENSHOT_DIRPATH): def color_map(N): if 0 <= N <= 0.5: # TODO: organe senescent (prendre prop) vid_colors = [150, 100, 0] elif 0.5 < N < 5: # Fvertes vid_colors = [int(255 - N * 51), int(255 - N * 20), 50] else: vid_colors = [0, 155, 0] return vid_colors def calculate_Total_Organic_Nitrogen(amino_acids, proteins, Nstruct): """Total amount of organic N (amino acids + proteins + Nstruct). :param float amino_acids: Amount of amino acids (µmol N) :param float proteins: Amount of proteins (µmol N) :param float Nstruct: Structural N mass (g) :return: Total amount of organic N (mg) :rtype: float """ return (amino_acids + proteins) * 14E-3 + Nstruct * 1E3 colors = {} groups_df = df.groupby(['plant', 'axis', 'metamer', 'organ', 'element']) for vid in g.components_at_scale(g.root, scale=5): pid = int(g.index(g.complex_at_scale(vid, scale=1))) axid = g.property('label')[g.complex_at_scale(vid, scale=2)] mid = int(g.index(g.complex_at_scale(vid, scale=3))) org = g.property('label')[g.complex_at_scale(vid, scale=4)] elid = g.property('label')[vid] id_map = (pid, axid, mid, org, elid) if id_map in groups_df.groups.keys(): N = (g.property('proteins')[vid] * 14E-3) / groups_df.get_group(id_map)['mstruct'].iloc[0] # N = (calculate_Total_Organic_Nitrogen(g.property('amino_acids')[vid], g.property('proteins')[vid], g.property('Nstruct')[vid])) / g.property('mstruct')[vid] colors[vid] = color_map(N) else: g.property('geometry')[vid] = None # plantgl s = to_plantgl(g, colors=colors)[0] Viewer.add(s) Viewer.camera.setPosition(Vector3(83.883, 12.3239, 93.4706)) Viewer.camera.lookAt(Vector3(0., 0, 50)) Viewer.saveSnapshot( os.path.join(SCREENSHOT_DIRPATH, 'Day_{}.png'.format(t / 24 + 1)))
def max_distance(pts, line): d_line = line.__normSquared__() max_dist = 0. index = 0 for i, pt in enumerate(pts): d = (Vector3(pt)^line).__normSquared__() if d > max_dist: max_dist = d index = i return index, max_dist/d_line
def transform_leaf(rotate, down_angle, z, pt): y = t_parent * Vector3(0, 1, 0) x = t_parent * Vector3(1, 0, 0) y = z ^ x x = y ^ z # print "z for leaf ", z x.normalize() y.normalize() r_rot = axisRotation(z, radians(rotate)) r_down = axisRotation(y, radians(down_angle)) new_x = r_rot * r_down * x new_y = r_rot * y transfo = Matrix4(BaseOrientation(new_x, new_y).getMatrix3()) # transfo[0,3]= pt.x # transfo[1,3]= pt.y # transfo[2,3]= pt.z return transfo
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 __init__(self, server, section, position=Vector3(0, 0, 0), color=brown, leaf=None): self.server = server self.color = color self.section = section self.leaf = leaf if not leaf: self.leaf = bezier_leaf() self._shapes = [] self.position = position
def read_mtg(fn = 'walnut.mtg' ,drf = 'walnut.drf'): g = read_mtg_file(fn) topdia = lambda x: g.property('TopDia').get(x) dressing_data = dresser.dressing_data_from_file(drf) pf = plantframe.PlantFrame(g, TopDiameter=topdia, DressingData = dressing_data) pf.propagate_constraints() diameters = pf.algo_diameter() toppositions = pf.points g.properties()['TopDiameter']=diameters g.properties()['TopPosition']= dict([ (k,Vector3(v)) for k,v in toppositions.items()]) g = flatten(g) return g
def geom(self): x = self.leaf_scale_x / 1.5 y = self.leaf_scale points = Point3Array([ Vector3(x / 2., 0, 0), Vector3(0, x / 4., 0), Vector3(0, y - x / 4., 0), Vector3(x / 2., y, 0), Vector3(x, y - x / 4., 0), Vector3(x, x / 4., 0) ]) indices = Index3Array([ Index3(0, 1, 5), Index3(1, 2, 5), Index3(2, 3, 4), Index3(2, 4, 5) ]) s = TriangleSet(points, indices) return s
def rotate_Y(v, angle): " Rotate a vector V around the x axis." mat = PlantGL.axisRotation(Vector3(0, 1, 0), radians(angle)) return mat * v
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 view(self): import matplotlib.pyplot as plt plt.imshow(self.image) plt.show() def nZ(z, znear, zfar): dz = float(zfar - znear) c1 = -2 * zfar * znear / dz c2 = (zfar + znear) / dz return ((-c2 * z) - c1) / (-z) def test(): renderer = ZBufferRenderer(10, 10) print(renderer.setPerspective(30, 1, 0.1, 100)) print(renderer.lookAt(Vector3(1, 0, 1), (0, 0, 0), (0, 0, 1))) print(renderer.projectionMatrix) print(renderer.renderPoint((0, 0, 0))) renderer.view() if __name__ == '__main__': renderer = ZBufferRenderer(100, 100) print(renderer.setPerspective(30, 1, 0.1, 100)) print(renderer.lookAt(Vector3(5, 0, 1), (0, 0, 0), (0, 0, 1))) print(renderer.projectionMatrix) renderer.renderPoint((0, 0, 0), (255, 0, 0), 3) renderer.renderLine((0, 0, -1), (0, 0, 1), (0, 255, 0)) renderer.view()
from math import sqrt from heapq import * from openalea.plantgl.all import Vector3 points = [ Vector3(*pt) for pt in zip(range(10), range(5) + range(5, 0, -1), [0] * 10) ] def max_distance(pts, line): d_line = line.__normSquared__() max_dist = 0. index = 0 for i, pt in enumerate(pts): d = (Vector3(pt) ^ line).__normSquared__() if d > max_dist: max_dist = d index = i return index, max_dist / d_line def distance(pt, p0, p1): line = p1 - p0 length = line.__normSquared__() d = ((pt - p0) ^ line).__normSquared__() d /= length return d
def projectPointToCameraPlane(self, position): p = Vector4(Vector3(position), 1) p = self.worldToCamera * p p = self.projectionMatrix * p if abs(p.w) > 1e-3: return p.project() return p
def createSurface(filename=None, ustride=10, vstride=10): """Reads a surface file and down sample data if required The format files follows the format specified in L-studio, an example is provided here below:: -0.75 0.75 -0.02 0.34 -0.01 1.00 CONTACT POINT X: 0.00 Y: 0.00 Z: 0.00 END POINT X: 0.00 Y: 0.00 Z: 0.00 HEADING X: 0.00 Y: 0.00 Z: 1.00 UP X: 0.00 Y: 1.00 Z: 0.00 SIZE: 1.00 patch TOP COLOR: 0 DIFFUSE: 0.00 BOTTOM COLOR: 0 DIFFUSE: 0.00 AL: ~ A: ~ AR: ~ L: ~ R: ~ BL: ~ B: ~ BR: ~ -0.01 -0.01 1.00 0.00 -0.02 0.99 0.00 -0.01 1.00 0.00 -0.01 1.00 -0.43 0.13 0.76 -0.16 0.34 0.27 0.21 0.34 0.27 0.43 0.12 0.76 -0.75 0.00 0.19 -0.25 0.00 0.19 0.25 0.00 0.19 0.75 0.00 0.19 -0.01 0.00 -0.01 -0.01 0.00 -0.01 0.00 0.00 -0.01 -0.01 0.00 -0.01 :param str filename: the filename of the surface data :param int ustride: number of points in u direction :param int vstride: number of points in v direction :: >>> stride_number = 4 >>> leaf_surface = createSurface('leaf_surface.s', stride_number, stride_number) then in Lpy:: >>> produce PglShape(leaf_surface, r) """ try: f = open(filename, 'r') except: raise ValueError('check the filename') assert type(ustride) == int assert type(vstride) == int # read header of the file f.readline() # read contact point v = f.readline().split() cpoint = Vector3(float(v[3]), float(v[5]), float(v[7])) # read end point f.readline() #read heading v = f.readline().split() heading = Vector3(float(v[2]), float(v[4]), float(v[6])) # read up v = f.readline().split() up = Vector3(float(v[2]), float(v[4]), float(v[6])) # read size v = f.readline().split() size = float(v[1]) # read name name = f.readline().split()[0] # read ctrl points for i in xrange(4): f.readline() ctrlpoints = [] for i in xrange(4): v = f.readline().split() row = [] for j in range(4): row.append( Vector4(float(v[j * 3]), float(v[j * 3 + 1]), float(v[j * 3 + 2]), 1)) ctrlpoints.append(row) smb = Scaled(size, BezierPatch(ctrlpoints, ustride, vstride)) smb.name = name return smb
from math import sqrt from heapq import * from openalea.plantgl.all import Vector3 points = [Vector3(*pt) for pt in zip(range(10), range(5)+range(5,0,-1), [0]*10)] def max_distance(pts, line): d_line = line.__normSquared__() max_dist = 0. index = 0 for i, pt in enumerate(pts): d = (Vector3(pt)^line).__normSquared__() if d > max_dist: max_dist = d index = i return index, max_dist/d_line def distance( pt, p0, p1): line = p1 - p0 length = line.__normSquared__() d = ((pt-p0) ^ line).__normSquared__() d /= length return d def cost( polyline, nb_points): nb_points += 2 n = len(polyline) pts = [ pt for pt in polyline ] _cost = []
def _surf(ind, pts): from openalea.plantgl.all import norm, cross, Vector3 A, B, C = [Vector3(pts[i]) for i in ind] return norm(cross(B - A, C - A)) / 2.0
def ucdir(uc, m): ucfpos = ucfirstpos(uc, m) if ucfpos is None: return None ucins = ucinsertionpos(uc, m) return Vector3(ucfpos) - ucins
def get_transformation(self, order, length, branching): assert (branching) pid = branching.axis_id poly = self.tree._properties["polyline"][pid] t = Matrix3(self.tree._properties["transform"][pid]) offset = branching.offset down = self.param.n_down_angle[order] down_angle = 0 if down[1] > 0: down_angle = value(down) else: parent_len = self.tree._properties["length"][pid] d = self.tree._properties["offset_length"][pid][offset] ratio = (parent_len - d) / (parent_len * (1 - self.param.base_size)) downV = down[1] * shape_ratio(0, 1 - 2 * shape_ratio(0, ratio)) down_angle = value((down[0], downV)) rotate = self.param.n_rotate[order - 1] # todo self.rotate[order] += value(rotate) self.rotate[order] = self.rotate[order] % 360 z = poly[offset] - poly[offset - 1] z.normalize() y = t * Vector3(0, 1, 0) x = t * Vector3(1, 0, 0) x.normalize() y.normalize() r_rot = axisRotation(z, radians(self.rotate[order])) r_down = axisRotation(y, radians(down_angle)) new_z = r_rot * r_down * z new_y = r_rot * y new_x = new_y ^ new_z transfo = Matrix4(BaseOrientation(new_x, new_y).getMatrix3()) # transfo = Matrix4(r_rot*r_down*t) # x = t * Vector3(1,0,0) # r_rot = axisRotation(z, radians(self.rotate[order])) # r_down = axisRotation(z^x, radians(down_angle)) # transfo = Matrix4(r_rot * r_down) # FIXME BIG BUG # euler = r_rot * r_down # z_old = t * Vector3(0,0,1) # y_old = t * Vector3(0,1,0) # z_rot = axisRotation(y_old, angle(z_old, z)) # x = z_rot * t * Vector3(1,0,0) # y = y_old # x.normalize() # y.normalize() # t = BaseOrientation(x,y).getMatrix3() # a,e,r= radians(self.rotate[order]), radians(down_angle), 0 # euler= eulerRotationZYX(Vector3(a,e,r)) # transfo= Matrix4(euler*t) # print degrees(a),degrees(e),degrees(r) # transfo= Transform4( Matrix4( euler ) ) # transfo.translate(poly[offset]) v = poly[offset] transfo[0, 3] = v.x transfo[1, 3] = v.y transfo[2, 3] = v.z return transfo
from math import sqrt from heapq import * from openalea.plantgl.all import Vector3 points = [ Vector3(*pt) for pt in zip(range(10), list(range(5)) + list(range(5, 0, -1)), [0] * 10) ] def max_distance(pts, line): d_line = line.__normSquared__() max_dist = 0. index = 0 for i, pt in enumerate(pts): d = (Vector3(pt) ^ line).__normSquared__() if d > max_dist: max_dist = d index = i return index, max_dist / d_line def distance(pt, p0, p1): line = p1 - p0 length = line.__normSquared__() d = ((pt - p0) ^ line).__normSquared__() d /= length return d