Add PlantGL test code master
authorAndy Spencer <andy753421@gmail.com>
Mon, 3 Mar 2014 01:33:27 +0000 (01:33 +0000)
committerAndy Spencer <andy753421@gmail.com>
Mon, 3 Mar 2014 01:33:27 +0000 (01:33 +0000)
doc/links.txt
src/makefile [new file with mode: 0644]
src/plant.lpy [new file with mode: 0644]
src/test.py [new file with mode: 0755]

index 6d4d360..577a3da 100644 (file)
@@ -1,2 +1,5 @@
 UML Diagram:
   https://docs.google.com/a/g.ucla.edu/drawings/d/1VqDGhvkOAENNGSycoFwKZj1IVB1zyKaCH_UZjw4bISE/edit
+
+OpenAlea Docuemntation:
+  http://openalea.gforge.inria.fr/doc/openalea/doc/_build/html/index.html
diff --git a/src/makefile b/src/makefile
new file mode 100644 (file)
index 0000000..59b277d
--- /dev/null
@@ -0,0 +1,2 @@
+test:
+       python test.py plantgl
diff --git a/src/plant.lpy b/src/plant.lpy
new file mode 100644 (file)
index 0000000..0f828be
--- /dev/null
@@ -0,0 +1,532 @@
+from openalea.plantgl.all import *\r
+from math import * \r
+from random import *\r
+\r
+# Control of the surface details\r
+sepal_nb_segment = 10\r
+petal_nb_segment = 20\r
+stamen_nb_segment = 20\r
+carpel_nb_segment = 20\r
+leaf_nb_segment = 20\r
+\r
+# General variables\r
+\r
+leaf_color = 5\r
+phylangle = 137.5\r
+Rmax = 10      # Maximum number of leaves before making a flower\r
+indiam = 0.04  # Final internode diameter in cm\r
+inlen = 1.    # Final size of an internode length in cm\r
+\r
+receptacleHeight = 0.3 # scaling factor in cm: \r
+                   # defines the height of the flower receptacle\r
+                   # from its basis to the top\r
+receptacleWidth = 0.3  # scaling factor in cm:\r
+Ssize = 2.  # scaling factor for the flower organs\r
+\r
+\r
+T = 5.      # time for an apex to produce an internode\r
+T_IN = 5.   # time for internode growth\r
+T_F = 2.    # time to produce a flower internode\r
+dt = 1.     # time resolution (eg. = 1 day)\r
+eps = 0.0001   # time accuracy (time under eps is considered to be 0)\r
+\r
+# values of parameter thresholds that define the flower zones \r
+# on the flower receptacle \r
+pth=[0.0,.3,.8,.95,1.0] \r
+nbwhorls = [1,1,1,1] # nb of whorls in each flower zone\r
+dp = 0.01 # subdivision unit of the intervalle [0,1] for parameter p\r
+\r
+\r
+# parameters for random noise\r
+seed(0)\r
+insert_sepal_mu = 0.    # mean variation of the sepal insertion angle in degrees\r
+insert_sepal_sigma = 5. # std deviation\r
+insert_petal_mu = 0. \r
+insert_petal_sigma = 5. \r
+\r
+# Some quantities used for the ABC diagram\r
+step=.1\r
+diagrWidth= .1 # size param. for the ABC diagram\r
+diagrLen=1.\r
+\r
+\r
+# p is assumed to be comprised between 0 and 1\r
+# dp is assumed to be constant increment between 0 and 1\r
+# the normal is assumed to be orthogonal to p-dp,p+dp\r
+def computeNormal(curve,p,dp):\r
+  if p-dp < 0:\r
+    p2 = p+dp\r
+    y2 = curve(p2)\r
+    y = curve(p)\r
+    tanalpha = (y2-y)/(p2-p)\r
+  elif p+dp > 1:\r
+    p1 = p-dp\r
+    y1 = curve(p1)\r
+    y = curve(p)\r
+    tanalpha = (y-y1)/(p-p1)\r
+  else:\r
+    p1 = p-dp\r
+    p2 = p+dp\r
+    y1 = curve(p1)\r
+    y2 = curve(p2)\r
+    tanalpha = (y2-y1)/(p2-p1)\r
+  alpha = degrees(atan(tanalpha)) # tangent angle wrt p axis\r
+  normal = alpha+90 # the reference line for this angle is the horizontal line\r
+  return normal\r
+\r
+def petal_scaled_section(p):\r
+  return petal_section(p)*10.0\r
+  \r
+\r
+# Conventional colors\r
+ABCcolors= {'A': 9, 'B': 10,'C': 8, 'AB': 13, 'AC': 11, 'BC': 12, 'O': 2}\r
+# A conversion function\r
+def whorl2organ(whorlnumber):\r
+  if whorlnumber == 0 :\r
+    if GA: orgtype='A'\r
+    elif GC: orgtype='C'\r
+    else: orgtype='O'\r
+  elif whorlnumber == 1 :\r
+    if GA: \r
+      if GB:\r
+        orgtype='AB'\r
+      else:\r
+        orgtype='A'\r
+    elif GC:\r
+      if GB:\r
+        orgtype='BC'\r
+      else:\r
+        orgtype='C'\r
+    else: \r
+      orgtype='O'\r
+  elif whorlnumber ==2 :\r
+    if GB and GC: orgtype='BC'\r
+    elif GA and GB and (1-GC): orgtype='AB'\r
+    elif GC and (1-GB): orgtype='C'\r
+    elif GA and (1-GB) and (1-GC): orgtype='A'\r
+    else: orgtype='O'\r
+  elif whorlnumber == 3:\r
+    if GC: orgtype='C'\r
+    elif GA: orgtype='A'\r
+    else: orgtype='O'\r
+  \r
+  return orgtype\r
+# Depending on genetic background, actual "colors", i.e. organ types\r
+whorlcolors = [ABCcolors[i] for i in map(whorl2organ,range(4)) ]\r
+\r
+marker=0\r
+deg2rad = 2*3.141592654/360\r
+\r
+\r
+NB_steps = 250\r
+\r
+\r
+def Start():\r
+    seed(0)\r
+\r
+module A, AL, I, I2, FA, FI\r
+module Sepal, Petal, Stamen, Carpel, Leaf, LeafLet\r
+module OrgV1, OrgV2, OrgV3, OrgV4\r
+module diagr, Annulus\r
+\r
+##################### AXIOM ###############################################\r
+Axiom: SectionResolution(50) maybe_diagr \r
+\r
+derivation length: 250\r
+production:\r
+\r
+# ABC diagram displayed above the flower\r
+maybe_diagr:\r
+  if REPONSE:\r
+    produce f(5) diagr(0)\r
+  else : produce [SetGuide(AxisShape, Rmax*inlen)A(0,T)]\r
+\r
+\r
+## Diagrams \r
+diagr(t):\r
+  global marker\r
+  if t > 4:\r
+    produce @M(0,0,0)[SetGuide(AxisShape, Rmax*inlen)A(0,T)]\r
+  elif t<=1:\r
+    produce [&(90)f(.001)^(90);(0)@o(diagrLen)];(whorlcolors[0])[@o(t*diagrLen)]diagr(t+step/4.)\r
+  elif t<=2:\r
+    nproduce ;(whorlcolors[3])[^(90)f(.002)&(90)@o((t-1.)*diagrLen/2.)]diagr(t+step/4.)\r
+  elif t<=4 and GB:\r
+    nproduce [^(90)f(.1)&(90) ;(14) Annulus(30,(t/2.-1.)*diagrLen/2.+diagrLen/4.,((t-step/2.)/2.-1.)*diagrLen/2.+diagrLen/4.)]f(.0001)diagr(t+step/4.)\r
+\r
+\r
+Annulus(N,Radius,radius):\r
+  alp = 360./N\r
+  prop = radius/Radius\r
+  nproduce _(.01)f(radius)+(90-alp/2.) \r
+  for i in xrange(N):\r
+    nproduce +(alp)[{F(Radius*(alp*deg2rad))+(90.+alp/2.)F(Radius*(1.-prop))+(90-alp/2.)F(Radius*(alp*deg2rad)*prop+.001)+(90.-alp/2.)F(Radius*(1.-prop))}]f(Radius*(alp*deg2rad))\r
+\r
+\r
+\r
+# creates the main stem (leaves + flower)\r
+A(r,t):  \r
+  # r = rank, t = time left before producing a new internode\r
+  # produces a flower apex in state 1 initially\r
+  if r ==  Rmax or not(stemflag): produce I(0)FA(T_F) \r
+  elif t < eps : produce I(0)[EndGuide()/(phylangle*r)AL(0)]A(r+1,T)\r
+  else: produce A(r,t-dt)\r
+\r
+# internode\r
+I(t):\r
+  produce I(t+dt)\r
+\r
+# axillary leaf\r
+AL(t):\r
+  produce AL(t+dt)\r
+\r
+FI(state,len,width,t):\r
+  produce FI(state,len,width,t+dt)\r
+\r
+\r
+decomposition:\r
+maximum depth: 1\r
+\r
+# floral apex = Receptacle internodes + lateral organs. \r
+# p corresponds to relative height in the receptacle (flower profile): \r
+# (p ranges from 0 to 1)\r
+# State corresponds to zone (1=sepal,2=petal,3=stamen,4=carpel)\r
+\r
+FA(t): \r
+  p=0\r
+  for s in xrange(4): # loop on the states (=zones)\r
+    zone_size = pth[s+1]-pth[s] # height of the current zone\r
+    len = zone_size/nbwhorls[s] # length of an internode in this zone\r
+    for i in xrange(nbwhorls[s]):\r
+      p=p+len\r
+      w = receptacleProfile(p) # normalized width\r
+      len2 = len * receptacleHeight # scaling length\r
+      w2 = w * receptacleWidth  # and width\r
+      beta = computeNormal(receptacleProfile,p,dp)\r
+      #print "beta = ", beta\r
+      # FI is a receptacle internode\r
+      nproduce FI(s,len2,w2,0)[SetGuide()\r
+      if s == 0 and verticille_1 : # sepal only\r
+        for j in xrange(nb_sepal): \r
+          if noise : ran_insert = insert_sepal_mu + random()*insert_sepal_sigma # gauss(insert_sepal_mu,insert_sepal_sigma)\r
+          else: ran_insert = 0.\r
+          nproduce /(360/nb_sepal) [ ^(-90) f(w2) ^(90) ^(-beta+opening(p)*360+ran_insert) OrgV1] \r
+      if s == 1 and verticille_2: # petals only\r
+        for j in xrange(nb_petal): \r
+          if noise : ran_insert = insert_petal_mu + random()*insert_petal_sigma #gauss(insert_petal_mu,insert_petal_sigma)\r
+          else: ran_insert = 0.\r
+          nproduce /(360/nb_petal) [ ^(-90) f(w2) ^(90) ^(-beta+opening(p)*360+ran_insert) OrgV2] \r
+      if s == 2 and verticille_3: # stamen only\r
+        for j in xrange(nb_stamen): \r
+          nproduce /(360/nb_stamen) [ ^(-90) f(w2) ^(90) ^(-beta+opening(p)*360) OrgV3] \r
+      if s == 3 and verticille_4: # carpel only\r
+        for j in xrange(nb_carpel): \r
+          # print "j = ",j,"beta = ", beta, "p = ", p,"opening = ", opening(p)\r
+          nproduce /(360/nb_carpel) [ ^(-90) f(w2) ^(90) ^(beta-opening(p)*360) OrgV4]       \r
+      nproduce ] \r
+      if s == 0 and nb_sepal == 1 : nproduce /(phylangle)\r
+      elif s == 1 and nb_petal == 1 : nproduce /(phylangle)\r
+      elif s == 2 and nb_stamen == 1 : nproduce /(phylangle)\r
+      elif s == 3 and nb_carpel == 1 : nproduce /(phylangle)\r
+      # if a whorl (> 1 organ) shift by Pi/(2*N)\r
+      elif s == 0 : nproduce /(180/nb_sepal) \r
+      elif s == 1 : nproduce /(180/nb_petal) \r
+      elif s == 2 : nproduce /(180/nb_stamen) \r
+      elif s == 3 : nproduce /(180/nb_carpel) \r
+\r
+\r
+interpretation:\r
+maximum depth: 10\r
+\r
+# Internodes\r
+I(t):\r
+  if t <= T_IN: \r
+    percent_growth = t/T_IN\r
+    if percent_growth != 0.0:\r
+      produce _(indiam*percent_growth);(leaf_color)F(inlen*percent_growth)\r
+  else:\r
+    tt = 1.*(NB_steps-t)/NB_steps\r
+    produce _(indiam);(leaf_color)F(inlen*internodelen(tt))\r
+\r
+AL(t):\r
+  nproduce SetGuide()\r
+  if t <= T_IN: \r
+    percent_growth = t/T_IN\r
+    if percent_growth != 0.0:\r
+      produce ;(leaf_color)-(90)f(indiam*percent_growth)+(90)/(-90)^(-60) Leaf\r
+  else: produce ;(leaf_color)-(90)f(indiam)+(90)/(-90)^(-60)Leaf\r
+\r
+# Internodes composing the receptacle\r
+FI(state,len,width,t):\r
+  if show_ABC_colors:\r
+    orgtype = whorl2organ(state)\r
+    colo=ABCcolors[orgtype]\r
+  else :\r
+    colo = 2\r
+  produce ;(colo)F(len,width)\r
+\r
+# Organ definitions\r
+Sepal:\r
+  if sepalflag: \r
+    produce ;(2) ParametricSurface(sepal_nerve,sepal_section,sepal_width,sepal_length/10.,sepal_nb_segment,Ssize)\r
+  \r
+Petal:\r
+  if petalflag: \r
+    produce ,(3) ParametricSurface(petal_nerve,petal_section,petal_width,petal_length/10.,petal_nb_segment,Ssize)\r
+    \r
+Stamen:\r
+  if stamenflag: \r
+    produce ;(4) ParametricSurface(stamen_nerve,None,stamen_width,stamen_length/10.,stamen_nb_segment,Ssize)\r
+    \r
+Carpel:\r
+  if carpelflag: \r
+    nproduce ;(5) ParametricSurface(carpel_nerve,None,carpel_width,carpel_length/10.,carpel_nb_segment,Ssize)\r
+    for i in xrange(10): nproduce _(.001)[\(90)f(.01)]\r
+\r
+\r
+OrgV1 :\r
+  if GA: produce Sepal\r
+  elif GC: produce Carpel\r
+  else: produce None\r
+OrgV2 :\r
+  if GA: \r
+    if GB:\r
+      produce Petal\r
+    else:\r
+      produce Sepal\r
+  elif GC:\r
+    if GB:\r
+      produce Stamen\r
+    else:\r
+      produce Carpel\r
+  else: produce None\r
+OrgV3 :\r
+  if GB and GC: produce Stamen\r
+  elif GA and GB and (1-GC): produce f(.5)Petal\r
+  elif GC and (1-GB): produce Carpel\r
+  elif GA and (1-GB) and (1-GC): produce Sepal\r
+  else: produce None\r
+OrgV4 :\r
+  if GC: produce Carpel\r
+  elif GA: produce Sepal\r
+  else: produce None\r
+\r
+\r
+Leaf:\r
+  if leafflag: \r
+    produce F(0.3,0.02)LeafLet\r
+    #produce F(0.3,0.02)[+(90)LeafLet][-(90)LeafLet]F(0.3,0.02)[+(90)LeafLet][-(90)LeafLet]F(0.3,0.02)LeafLet\r
+    \r
+LeafLet --> ParametricSurface(leaf_nerve,leaf_section,leaf_width,leaf_length/10.,leaf_nb_segment,Ssize)\r
+\r
+ParametricSurface(axis,section,width,length,nb_segment,size):\r
+   dx = 1. / nb_segment\r
+   x = 0\r
+   nproduce [SetGuide(axis,length*size)  \r
+   if not section is None: nproduce SetContour(section) \r
+   nproduce _(width(0)) StartGC()\r
+   for i in xrange(nb_segment):\r
+     x = i*dx\r
+     nproduce F(size*dx*length,size*width(x+dx))\r
+   nproduce EndGC()]\r
+\r
+\r
+endlsystem\r
+###### INITIALISATION ######\r
+\r
+__lpy_code_version__ = 1.1\r
+\r
+def __initialiseContext__(context):\r
+       import openalea.plantgl.all as pgl\r
+       Color_1 = pgl.Material("Color_1" ,              ambient = (28,19,6) , \r
+               diffuse = 5.57143 , \r
+               specular = (50,50,50) , \r
+               emission = (9,9,9) , \r
+)\r
+       Color_1.name = "Color_1"\r
+       context.turtle.setMaterial(1,Color_1)\r
+       Color_2 = pgl.Material("Color_2" ,              ambient = (18,37,5) , \r
+               diffuse = 2.35135 , \r
+)\r
+       Color_2.name = "Color_2"\r
+       context.turtle.setMaterial(2,Color_2)\r
+       Color_3 = pgl.Material("Color_3" ,              ambient = (105,105,105) , \r
+               diffuse = 2.42857 , \r
+               specular = (42,42,42) , \r
+)\r
+       Color_3.name = "Color_3"\r
+       context.turtle.setMaterial(3,Color_3)\r
+       Color_4 = pgl.Material("Color_4" ,              ambient = (84,56,0) , \r
+               diffuse = 2.44048 , \r
+               specular = (32,32,32) , \r
+               emission = (26,26,26) , \r
+)\r
+       Color_4.name = "Color_4"\r
+       context.turtle.setMaterial(4,Color_4)\r
+       Color_5 = pgl.Material("Color_5" ,              ambient = (6,61,12) , \r
+               diffuse = 0.885246 , \r
+               specular = (124,124,124) , \r
+)\r
+       Color_5.name = "Color_5"\r
+       context.turtle.setMaterial(5,Color_5)\r
+       Color_6 = pgl.Material("Color_6" ,              ambient = (41,0,0) , \r
+               diffuse = 2.36585 , \r
+               specular = (92,8,8) , \r
+               emission = (45,0,0) , \r
+)\r
+       Color_6.name = "Color_6"\r
+       context.turtle.setMaterial(6,Color_6)\r
+       Color_8 = pgl.Material("Color_8" ,              ambient = (254,0,0) , \r
+               diffuse = 0.629921 , \r
+               specular = (255,0,0) , \r
+               emission = (255,0,0) , \r
+)\r
+       Color_8.name = "Color_8"\r
+       context.turtle.setMaterial(8,Color_8)\r
+       Color_9 = pgl.Material("Color_9" ,              ambient = (255,255,0) , \r
+               diffuse = 0.45098 , \r
+               specular = (104,104,104) , \r
+               emission = (255,255,0) , \r
+)\r
+       Color_9.name = "Color_9"\r
+       context.turtle.setMaterial(9,Color_9)\r
+       Color_10 = pgl.Material("Color_10" ,            ambient = (0,0,255) , \r
+               diffuse = 0.627451 , \r
+)\r
+       Color_10.name = "Color_10"\r
+       context.turtle.setMaterial(10,Color_10)\r
+       Color_11 = pgl.Material("Color_11" ,            ambient = (255,185,7) , \r
+               diffuse = 0 , \r
+               specular = (0,0,0) , \r
+               emission = (255,3,3) , \r
+)\r
+       Color_11.name = "Color_11"\r
+       context.turtle.setMaterial(11,Color_11)\r
+       Color_12 = pgl.Material("Color_12" ,            ambient = (255,0,255) , \r
+               diffuse = 0 , \r
+               specular = (0,0,0) , \r
+)\r
+       Color_12.name = "Color_12"\r
+       context.turtle.setMaterial(12,Color_12)\r
+       Color_13 = pgl.Material("Color_13" ,            ambient = (0,218,0) , \r
+               diffuse = 0 , \r
+               specular = (0,0,0) , \r
+)\r
+       Color_13.name = "Color_13"\r
+       context.turtle.setMaterial(13,Color_13)\r
+       Color_14 = pgl.Material("Color_14" ,            ambient = (0,0,255) , \r
+               diffuse = 0 , \r
+               specular = (0,0,0) , \r
+               transparency = 0.59 , \r
+)\r
+       Color_14.name = "Color_14"\r
+       context.turtle.setMaterial(14,Color_14)\r
+       Color_15 = pgl.Material("Color_15" ,            ambient = (0,0,255) , \r
+               diffuse = 0 , \r
+               specular = (0,0,0) , \r
+               emission = (0,0,255) , \r
+               transparency = 0.57 , \r
+)\r
+       Color_15.name = "Color_15"\r
+       context.turtle.setMaterial(15,Color_15)\r
+       context.options.setSelection('Warning with Turtle inconsistency',0)\r
+       scalars = [('nb_sepal', 4, 1, 20), ('nb_petal', 4, 1, 20), ('nb_stamen', 5, 1, 30), ('sepal_length', 5, 1, 30), ('petal_length', 7, 1, 30), ('stamen_length', 4, 1, 30), ('carpel_length', 4, 1, 30), ('leaf_length', 6, 1, 100), ('sepalflag', True, False, True), ('petalflag', True, False, True), ('stamenflag', True, False, True), ('carpelflag', True, False, True), ('leafflag', True, False, True), ('noise', True, False, True), ('nb_carpel', 1, 0, 100), ('GA', True, False, True), ('GB', True, False, True), ('GC', True, False, True), ('verticille_1', True, False, True), ('verticille_2', True, False, True), ('verticille_3', True, False, True), ('verticille_4', True, False, True), ('stemflag', True, False, True), ('REPONSE', False, False, True), ('show_ABC_colors', False, False, True)]\r
+       context["__scalars__"] = scalars\r
+       for n,v,mnv,mxv in scalars:\r
+               context[n] = v\r
+       import openalea.plantgl.all as pgl\r
+       sepal_width = pgl.NurbsCurve2D( \r
+           ctrlPointList = pgl.Point3Array([(0, 0.0342648, 1),(0.0549666, 0.231318, 1),(0.510107, 0.163966, 1),(0.917895, 0.180944, 1),(1, 0.0268255, 1)]) , \r
+           )\r
+       sepal_width.name = "sepal_width"\r
+       petal_width = pgl.NurbsCurve2D( \r
+           ctrlPointList = pgl.Point3Array([(0, 0.0865445, 1),(0.231908, 0.208539, 1),(0.473697, 0.283924, 1),(0.709594, 0.349294, 1),(0.921729, 0.32141, 1),(1, 0.0588625, 1),(1, 0.0249496, 1)]) , \r
+           )\r
+       petal_width.name = "petal_width"\r
+       carpel_width = pgl.NurbsCurve2D(        \r
+           ctrlPointList = pgl.Point3Array([(0, 0.0148928, 1),(0.314935, 0.0195945, 1),(0.5573, 0.016741, 1),(0.738597, 0.0186869, 1),(0.864667, 0.00214352, 1),(1, 0.0150678, 1)]) , \r
+           )\r
+       carpel_width.name = "carpel_width"\r
+       stamen_width = pgl.NurbsCurve2D(        \r
+           ctrlPointList = pgl.Point3Array([(0, 0.00326303, 1),(0.353705, 0.00323103, 1),(0.675292, 0.00559957, 1),(0.76987, 0.00208676, 1),(0.803953, 0.0145622, 1),(0.995983, 0.0120889, 1),(1, 0.00026951, 1)]) , \r
+           )\r
+       stamen_width.name = "stamen_width"\r
+       receptacleProfile = pgl.NurbsCurve2D(   \r
+           ctrlPointList = pgl.Point3Array([(0, 0.0118772, 1),(0.0483995, 0.147983, 1),(0.163483, 0.334726, 1),(0.310778, 0.395063, 1),(0.609005, 0.399069, 1),(0.810031, 0.34849, 1),(1, 0.111638, 1),(1, 0.0125388, 1)]) , \r
+           )\r
+       receptacleProfile.name = "receptacleProfile"\r
+       leaf_width = pgl.NurbsCurve2D(  \r
+           ctrlPointList = pgl.Point3Array([(0, 0.0557769, 1),(0.165729, 0.301414, 1),(0.53533, 0.298777, 1),(0.805128, 0.302951, 1),(1, 0.0358566, 1)]) , \r
+           )\r
+       leaf_width.name = "leaf_width"\r
+       opening = pgl.NurbsCurve2D(     \r
+           ctrlPointList = pgl.Point3Array([(0, 0.0109171, 1),(0.0777129, 0.420641, 1),(0.245081, 0.208734, 1),(0.417176, 0.202829, 1),(0.624831, 0.101988, 1),(0.823187, 0.0238984, 1),(0.929457, 0.0296022, 1),(1, 0.0281283, 1)]) , \r
+           )\r
+       opening.name = "opening"\r
+       internodelen = pgl.NurbsCurve2D(        \r
+           ctrlPointList = pgl.Point3Array([(0, 0.00938666, 1),(0.166719, 0.00561404, 1),(0.166719, 0.0116702, 1),(0.189386, 0.0576949, 1),(0.195085, 1.00485, 1),(0.199993, 0.988534, 1),(0.800502, 0.989881, 1),(1, 0.989703, 1)]) , \r
+           )\r
+       internodelen.name = "internodelen"\r
+       panel_0 = ({'active': True, 'visible': True, 'name': 'Functions'},[('Function',sepal_width),('Function',petal_width),('Function',carpel_width),('Function',stamen_width),('Function',receptacleProfile),('Function',leaf_width),('Function',opening),('Function',internodelen)])\r
+       import openalea.plantgl.all as pgl\r
+       sepal_nerve = pgl.NurbsCurve2D( \r
+           ctrlPointList = pgl.Point3Array([(0.00267378, 0.0913267, 1),(0.0350336, 0.00690934, 1),(0.152417, 0.000153156, 1),(0.995128, -0.000720531, 1),(1.00415, 0.0994233, 1)]) , \r
+           )\r
+       sepal_nerve.name = "sepal_nerve"\r
+       sepal_section = pgl.NurbsCurve2D(       \r
+           ctrlPointList = pgl.Point3Array([(-0.582092, 0.169143, 1),(-0.501529, 0.0149526, 1),(-0.164558, 0.00217632, 1),(0.19334, -0.00491485, 1),(0.55411, 0.00959401, 1),(0.593674, 0.167853, 1)]) , \r
+           )\r
+       sepal_section.name = "sepal_section"\r
+       petal_section = pgl.NurbsCurve2D(       \r
+           ctrlPointList = pgl.Point3Array([(-0.41272, 0.0925189, 1),(-0.207731, -0.00665554, 1),(0.171749, -0.00758484, 1),(0.369546, 0.0855328, 1)]) , \r
+           )\r
+       petal_section.name = "petal_section"\r
+       petal_nerve = pgl.NurbsCurve2D( \r
+           ctrlPointList = pgl.Point3Array([(-0.000642917, 0.000642897, 1),(0.182381, -0.00558217, 1),(0.379294, 0.0534718, 1),(0.582615, 0.204976, 1),(0.820263, 0.0804393, 1),(0.992836, 0.0312321, 1)]) , \r
+           )\r
+       petal_nerve.name = "petal_nerve"\r
+       stamen_nerve = pgl.NurbsCurve2D(        \r
+           ctrlPointList = pgl.Point3Array([(0.00267378, -0.0026738, 1),(0.133094, 0.0109457, 1),(0.259897, 0.0179014, 1),(0.332213, 0.0409697, 1),(0.399848, 0.0745133, 1)]) , \r
+           )\r
+       stamen_nerve.name = "stamen_nerve"\r
+       carpel_nerve = pgl.NurbsCurve2D(        \r
+           ctrlPointList = pgl.Point3Array([(0.00267378, -0.0026738, 1),(0.0490853, 0.00302744, 1),(0.130466, 0.00251888, 1),(0.677461, 0.0196475, 1),(1.00546, 0.0234969, 1)]) , \r
+           )\r
+       carpel_nerve.name = "carpel_nerve"\r
+       leaf_section = pgl.NurbsCurve2D(        \r
+           ctrlPointList = pgl.Point3Array([(-0.354412, 0.0971154, 1),(-0.13766, -0.0598824, 1),(0.129801, -0.0536486, 1),(0.370212, 0.0925605, 1)]) , \r
+           )\r
+       leaf_section.name = "leaf_section"\r
+       leaf_nerve = pgl.NurbsCurve2D(  \r
+           ctrlPointList = pgl.Point3Array([(0.00267378, -0.0026738, 1),(0.132394, 0.01432, 1),(0.2452, 0.0352875, 1),(0.397249, 0.00479208, 1),(0.500326, -0.0518791, 1)]) , \r
+           )\r
+       leaf_nerve.name = "leaf_nerve"\r
+       AxisShape = pgl.NurbsCurve2D(   \r
+           ctrlPointList = pgl.Point3Array([(-0.489325, 0.0330066, 1),(-0.25937, 0.0839531, 1),(0.104972, 0.0174484, 1),(0.409996, 0.0255427, 1)]) , \r
+           )\r
+       AxisShape.name = "AxisShape"\r
+       panel_1 = ({'active': True, 'visible': True, 'name': 'Curve2D'},[('Curve2D',sepal_nerve),('Curve2D',sepal_section),('Curve2D',petal_section),('Curve2D',petal_nerve),('Curve2D',stamen_nerve),('Curve2D',carpel_nerve),('Curve2D',leaf_section),('Curve2D',leaf_nerve),('Curve2D',AxisShape)])\r
+       parameterset = [panel_0,panel_1,]\r
+       context["__functions__"] = [('sepal_width',sepal_width),('petal_width',petal_width),('carpel_width',carpel_width),('stamen_width',stamen_width),('receptacleProfile',receptacleProfile),('leaf_width',leaf_width),('opening',opening),('internodelen',internodelen),]\r
+       context["__curves__"] = [('sepal_nerve',sepal_nerve),('sepal_section',sepal_section),('petal_section',petal_section),('petal_nerve',petal_nerve),('stamen_nerve',stamen_nerve),('carpel_nerve',carpel_nerve),('leaf_section',leaf_section),('leaf_nerve',leaf_nerve),('AxisShape',AxisShape),]\r
+       context["__parameterset__"] = parameterset\r
+       context["sepal_width"] = pgl.QuantisedFunction(sepal_width)\r
+       context["petal_width"] = pgl.QuantisedFunction(petal_width)\r
+       context["carpel_width"] = pgl.QuantisedFunction(carpel_width)\r
+       context["stamen_width"] = pgl.QuantisedFunction(stamen_width)\r
+       context["receptacleProfile"] = pgl.QuantisedFunction(receptacleProfile)\r
+       context["leaf_width"] = pgl.QuantisedFunction(leaf_width)\r
+       context["opening"] = pgl.QuantisedFunction(opening)\r
+       context["internodelen"] = pgl.QuantisedFunction(internodelen)\r
+       context["sepal_nerve"] = sepal_nerve\r
+       context["sepal_section"] = sepal_section\r
+       context["petal_section"] = petal_section\r
+       context["petal_nerve"] = petal_nerve\r
+       context["stamen_nerve"] = stamen_nerve\r
+       context["carpel_nerve"] = carpel_nerve\r
+       context["leaf_section"] = leaf_section\r
+       context["leaf_nerve"] = leaf_nerve\r
+       context["AxisShape"] = AxisShape\r
+__copyright__ = 'Virtual Plants Team'\r
+__institutes__ = 'INRIA'\r
+__authors__ = 'C. Godin\nF. Boudon'\r
diff --git a/src/test.py b/src/test.py
new file mode 100755 (executable)
index 0000000..3332487
--- /dev/null
@@ -0,0 +1,95 @@
+#!/bin/env python
+
+# Dependencies:
+#   PyQt4
+
+import sys
+
+from OpenGL.GL import *
+
+from PyQt4.Qt    import QApplication, QMainWindow, QLabel
+from PyQGLViewer import QGLViewer, Vec
+
+from openalea.lpy         import Lsystem
+from openalea.plantgl.all import Discretizer, GLRenderer
+
+# Qt Plant Viewer
+class Viewer(QGLViewer):
+    def __init__(self, lfile):
+        QGLViewer.__init__(self)
+
+        center   = Vec(0.16104, 0.00831, 2.53128)
+        position = Vec(4.74832, 4.66647, 8.79487)
+
+        self.discretizer = Discretizer()
+        self.renderer    = GLRenderer(self.discretizer)
+        self.lsystem     = Lsystem(lfile)
+        self.scene       = self.lsystem.sceneInterpretation(self.lsystem.iterate())
+
+        camera = self.camera()
+        camera.setRevolveAroundPoint(center)
+        camera.setPosition(position)
+        camera.setUpVector(Vec(0,0,1))
+        camera.lookAt(center)
+        camera.setSceneRadius(7)
+
+    def draw(self):
+        light_pos = list(self.camera().position())+[1.0]
+        light_dir = list(self.camera().viewDirection())+[1.0]
+
+        glEnable(GL_LIGHTING)
+        glEnable(GL_LIGHT0)
+
+        glLightfv(GL_LIGHT0, GL_POSITION,       light_pos)
+        glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, light_dir)
+        glLightfv(GL_LIGHT0, GL_AMBIENT,  (0.6,0.6,0.6,1.0))
+        glLightfv(GL_LIGHT0, GL_DIFFUSE,  (1.0,1.0,1.0,1.0))
+        glLightfv(GL_LIGHT0, GL_SPECULAR, (1.0,1.0,1.0,1.0))
+
+        if self.renderer.beginSceneList():
+            glEnable(GL_RESCALE_NORMAL)
+            self.scene.apply(self.renderer)
+            self.renderer.endSceneList()
+
+# Test Qt
+class TestQt:
+    def __init__(self, args):
+        self.args = args;
+
+    def run(self):
+        app  = QApplication(self.args)
+        win  = QMainWindow()
+        btn  = QLabel("Hello, World");
+
+        win.setCentralWidget(btn)
+        win.resize(800,600)
+        win.show()
+
+        app.exec_()
+
+# Test PlantGL
+class TestPlantGL:
+    def __init__(self, args):
+        self.args = args;
+
+    def run(self):
+        app  = QApplication(self.args)
+        win  = QMainWindow()
+        view = Viewer("plant.lpy");
+
+        win.setCentralWidget(view)
+        win.resize(800,600)
+        win.show()
+
+        app.exec_()
+
+# Main
+for test in sys.argv[1:]:
+
+    if test == 'qt':
+        qt = TestQt(sys.argv)
+        qt.run()
+
+    if test == 'plantgl' or test == 'pgl':
+        pgl = TestPlantGL(sys.argv)
+        pgl.run()