Manual merge of soc-2009-kazanbas branch:
authorArystanbek Dyussenov <arystan.d@gmail.com>
Tue, 22 Sep 2009 16:35:07 +0000 (16:35 +0000)
committerArystanbek Dyussenov <arystan.d@gmail.com>
Tue, 22 Sep 2009 16:35:07 +0000 (16:35 +0000)
* copied I/O scripts
* copied, modified rna_*_api.c and rna_*.c

I/O scripts not working yet due to slight BPY differences and RNA changes. Will fix them later.

Not merged changes:

* C unit testing integration, because it is clumsy
* scons cross-compiling, can be merged easily later

26 files changed:
1  2 
release/io/engine_render_pov.py
release/io/export_ply.py
release/io/export_x3d.py
release/ui/space_info.py
source/blender/blenkernel/BKE_anim.h
source/blender/blenkernel/intern/image.c
source/blender/blenkernel/intern/mesh.c
source/blender/editors/include/ED_mesh.h
source/blender/editors/mesh/editmesh_mods.c
source/blender/makesdna/DNA_object_types.h
source/blender/makesrna/intern/makesrna.c
source/blender/makesrna/intern/rna_action.c
source/blender/makesrna/intern/rna_action_api.c
source/blender/makesrna/intern/rna_armature.c
source/blender/makesrna/intern/rna_image.c
source/blender/makesrna/intern/rna_image_api.c
source/blender/makesrna/intern/rna_internal.h
source/blender/makesrna/intern/rna_material.c
source/blender/makesrna/intern/rna_mesh.c
source/blender/makesrna/intern/rna_mesh_api.c
source/blender/makesrna/intern/rna_object.c
source/blender/makesrna/intern/rna_object_api.c
source/blender/makesrna/intern/rna_pose.c
source/blender/makesrna/intern/rna_pose_api.c
source/blender/makesrna/intern/rna_scene_api.c
source/blender/python/intern/bpy_rna.c

@@@ -281,7 -281,7 +281,7 @@@ def write_pov(filename, scene=None, inf
                        me = ob.data
                        me_materials= me.materials
                        
--                      me = ob.create_render_mesh(scene)
++                      me = ob.create_mesh(True, 'RENDER')
                        
                        if not me:
                                continue
@@@ -78,7 -78,7 +78,7 @@@ def write(filename, scene, ob, 
        
        #mesh = BPyMesh.getMeshFromObject(ob, None, EXPORT_APPLY_MODIFIERS, False, scn) # XXX
        if EXPORT_APPLY_MODIFIERS:
--              mesh = ob.create_render_mesh(scene)
++              mesh = ob.create_mesh(True, 'PREVIEW')
        else:
                mesh = ob.data
        
index 0000000,3661d78..3e89a52
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,1239 +1,1239 @@@
 -# $Id$
+ #!BPY
+ """ Registration info for Blender menus:
+ Name: 'X3D Extensible 3D (.x3d)...'
+ Blender: 245
+ Group: 'Export'
+ Tooltip: 'Export selection to Extensible 3D file (.x3d)'
+ """
+ __author__ = ("Bart", "Campbell Barton")
+ __email__ = ["Bart, bart:neeneenee*de"]
+ __url__ = ["Author's (Bart) homepage, http://www.neeneenee.de/vrml"]
+ __version__ = "2006/01/17"
+ __bpydoc__ = """\
+ This script exports to X3D format.
+ Usage:
+ Run this script from "File->Export" menu.  A pop-up will ask whether you
+ want to export only selected or all relevant objects.
+ Known issues:<br>
+       Doesn't handle multiple materials (don't use material indices);<br>
+       Doesn't handle multiple UV textures on a single mesh (create a mesh for each texture);<br>
+       Can't get the texture array associated with material * not the UV ones;
+ """
++# $Id: export_x3d.py 23222 2009-09-14 14:55:49Z kazanbas $
+ #
+ #------------------------------------------------------------------------
+ # X3D exporter for blender 2.36 or above
+ #
+ # ***** BEGIN GPL LICENSE BLOCK *****
+ #
+ # This program is free software; you can redistribute it and/or
+ # modify it under the terms of the GNU General Public License
+ # as published by the Free Software Foundation; either version 2
+ # of the License, or (at your option) any later version.
+ #
+ # This program is distributed in the hope that it will be useful,
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ # GNU General Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License
+ # along with this program; if not, write to the Free Software Foundation,
+ # Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ #
+ # ***** END GPL LICENCE BLOCK *****
+ #
+ ####################################
+ # Library dependancies
+ ####################################
+ import math
+ import os
+ import bpy
+ import Mathutils
+ from export_3ds import create_derived_objects, free_derived_objects
+ # import Blender
+ # from Blender import Object, Lamp, Draw, Image, Text, sys, Mesh
+ # from Blender.Scene import Render
+ # import BPyObject
+ # import BPyMesh
+ # 
+ DEG2RAD=0.017453292519943295
+ MATWORLD= Mathutils.RotationMatrix(-90, 4, 'x')
+ ####################################
+ # Global Variables
+ ####################################
+ filename = ""
+ # filename = Blender.Get('filename')
+ _safeOverwrite = True
+ extension = ''
+ ##########################################################
+ # Functions for writing output file
+ ##########################################################
+ class x3d_class:
+       def __init__(self, filename):
+               #--- public you can change these ---
+               self.writingcolor = 0
+               self.writingtexture = 0
+               self.writingcoords = 0
+               self.proto = 1
+               self.matonly = 0
+               self.share = 0
+               self.billnode = 0
+               self.halonode = 0
+               self.collnode = 0
+               self.tilenode = 0
+               self.verbose=2   # level of verbosity in console 0-none, 1-some, 2-most
+               self.cp=3                 # decimals for material color values   0.000 - 1.000
+               self.vp=3                 # decimals for vertex coordinate values  0.000 - n.000
+               self.tp=3                 # decimals for texture coordinate values 0.000 - 1.000
+               self.it=3
+               
+               #--- class private don't touch ---
+               self.texNames={}   # dictionary of textureNames
+               self.matNames={}   # dictionary of materiaNames
+               self.meshNames={}   # dictionary of meshNames
+               self.indentLevel=0 # keeps track of current indenting
+               self.filename=filename
+               self.file = None
+               if filename.lower().endswith('.x3dz'):
+                       try:
+                               import gzip
+                               self.file = gzip.open(filename, "w")                            
+                       except:
+                               print("failed to import compression modules, exporting uncompressed")
+                               self.filename = filename[:-1] # remove trailing z
+               
+               if self.file == None:
+                       self.file = open(self.filename, "w")
+               self.bNav=0
+               self.nodeID=0
+               self.namesReserved=[ "Anchor","Appearance","Arc2D","ArcClose2D","AudioClip","Background","Billboard",
+                                                        "BooleanFilter","BooleanSequencer","BooleanToggle","BooleanTrigger","Box","Circle2D",
+                                                        "Collision","Color","ColorInterpolator","ColorRGBA","component","Cone","connect",
+                                                        "Contour2D","ContourPolyline2D","Coordinate","CoordinateDouble","CoordinateInterpolator",
+                                                        "CoordinateInterpolator2D","Cylinder","CylinderSensor","DirectionalLight","Disk2D",
+                                                        "ElevationGrid","EspduTransform","EXPORT","ExternProtoDeclare","Extrusion","field",
+                                                        "fieldValue","FillProperties","Fog","FontStyle","GeoCoordinate","GeoElevationGrid",
+                                                        "GeoLocationLocation","GeoLOD","GeoMetadata","GeoOrigin","GeoPositionInterpolator",
+                                                        "GeoTouchSensor","GeoViewpoint","Group","HAnimDisplacer","HAnimHumanoid","HAnimJoint",
+                                                        "HAnimSegment","HAnimSite","head","ImageTexture","IMPORT","IndexedFaceSet",
+                                                        "IndexedLineSet","IndexedTriangleFanSet","IndexedTriangleSet","IndexedTriangleStripSet",
+                                                        "Inline","IntegerSequencer","IntegerTrigger","IS","KeySensor","LineProperties","LineSet",
+                                                        "LoadSensor","LOD","Material","meta","MetadataDouble","MetadataFloat","MetadataInteger",
+                                                        "MetadataSet","MetadataString","MovieTexture","MultiTexture","MultiTextureCoordinate",
+                                                        "MultiTextureTransform","NavigationInfo","Normal","NormalInterpolator","NurbsCurve",
+                                                        "NurbsCurve2D","NurbsOrientationInterpolator","NurbsPatchSurface",
+                                                        "NurbsPositionInterpolator","NurbsSet","NurbsSurfaceInterpolator","NurbsSweptSurface",
+                                                        "NurbsSwungSurface","NurbsTextureCoordinate","NurbsTrimmedSurface","OrientationInterpolator",
+                                                        "PixelTexture","PlaneSensor","PointLight","PointSet","Polyline2D","Polypoint2D",
+                                                        "PositionInterpolator","PositionInterpolator2D","ProtoBody","ProtoDeclare","ProtoInstance",
+                                                        "ProtoInterface","ProximitySensor","ReceiverPdu","Rectangle2D","ROUTE","ScalarInterpolator",
+                                                        "Scene","Script","Shape","SignalPdu","Sound","Sphere","SphereSensor","SpotLight","StaticGroup",
+                                                        "StringSensor","Switch","Text","TextureBackground","TextureCoordinate","TextureCoordinateGenerator",
+                                                        "TextureTransform","TimeSensor","TimeTrigger","TouchSensor","Transform","TransmitterPdu",
+                                                        "TriangleFanSet","TriangleSet","TriangleSet2D","TriangleStripSet","Viewpoint","VisibilitySensor",
+                                                        "WorldInfo","X3D","XvlShell","VertexShader","FragmentShader","MultiShaderAppearance","ShaderAppearance" ]
+               self.namesStandard=[ "Empty","Empty.000","Empty.001","Empty.002","Empty.003","Empty.004","Empty.005",
+                                                        "Empty.006","Empty.007","Empty.008","Empty.009","Empty.010","Empty.011","Empty.012",
+                                                        "Scene.001","Scene.002","Scene.003","Scene.004","Scene.005","Scene.06","Scene.013",
+                                                        "Scene.006","Scene.007","Scene.008","Scene.009","Scene.010","Scene.011","Scene.012",
+                                                        "World","World.000","World.001","World.002","World.003","World.004","World.005" ]
+               self.namesFog=[ "","LINEAR","EXPONENTIAL","" ]
+ ##########################################################
+ # Writing nodes routines
+ ##########################################################
+       def writeHeader(self):
+               #bfile = sys.expandpath( Blender.Get('filename') ).replace('<', '&lt').replace('>', '&gt')
+               bfile = self.filename.replace('<', '&lt').replace('>', '&gt') # use outfile name
+               self.file.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
+               self.file.write("<!DOCTYPE X3D PUBLIC \"ISO//Web3D//DTD X3D 3.0//EN\" \"http://www.web3d.org/specifications/x3d-3.0.dtd\">\n")
+               self.file.write("<X3D version=\"3.0\" profile=\"Immersive\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema-instance\" xsd:noNamespaceSchemaLocation=\"http://www.web3d.org/specifications/x3d-3.0.xsd\">\n")
+               self.file.write("<head>\n")
+               self.file.write("\t<meta name=\"filename\" content=\"%s\" />\n" % os.path.basename(bfile))
+               # self.file.write("\t<meta name=\"filename\" content=\"%s\" />\n" % sys.basename(bfile))
+               self.file.write("\t<meta name=\"generator\" content=\"Blender %s\" />\n" % '2.5')
+               # self.file.write("\t<meta name=\"generator\" content=\"Blender %s\" />\n" % Blender.Get('version'))
+               self.file.write("\t<meta name=\"translator\" content=\"X3D exporter v1.55 (2006/01/17)\" />\n")
+               self.file.write("</head>\n")
+               self.file.write("<Scene>\n")
+       
+       # This functionality is poorly defined, disabling for now - campbell
+       '''
+       def writeInline(self):
+               inlines = Blender.Scene.Get()
+               allinlines = len(inlines)
+               if scene != inlines[0]:
+                       return
+               else:
+                       for i in xrange(allinlines):
+                               nameinline=inlines[i].name
+                               if (nameinline not in self.namesStandard) and (i > 0):
+                                       self.file.write("<Inline DEF=\"%s\" " % (self.cleanStr(nameinline)))
+                                       nameinline = nameinline+".x3d"
+                                       self.file.write("url=\"%s\" />" % nameinline)
+                                       self.file.write("\n\n")
+       
+       def writeScript(self):
+               textEditor = Blender.Text.Get() 
+               alltext = len(textEditor)
+               for i in xrange(alltext):
+                       nametext = textEditor[i].name
+                       nlines = textEditor[i].getNLines()
+                       if (self.proto == 1):
+                               if (nametext == "proto" or nametext == "proto.js" or nametext == "proto.txt") and (nlines != None):
+                                       nalllines = len(textEditor[i].asLines())
+                                       alllines = textEditor[i].asLines()
+                                       for j in xrange(nalllines):
+                                               self.writeIndented(alllines[j] + "\n")
+                       elif (self.proto == 0):
+                               if (nametext == "route" or nametext == "route.js" or nametext == "route.txt") and (nlines != None):
+                                       nalllines = len(textEditor[i].asLines())
+                                       alllines = textEditor[i].asLines()
+                                       for j in xrange(nalllines):
+                                               self.writeIndented(alllines[j] + "\n")
+               self.writeIndented("\n")
+       '''
+       
+       def writeViewpoint(self, ob, mat, scene):
+               context = scene.render_data
+               # context = scene.render
+               ratio = float(context.resolution_x)/float(context.resolution_y)
+               # ratio = float(context.imageSizeY())/float(context.imageSizeX())
+               lens = (360* (math.atan(ratio *16 / ob.data.lens) / math.pi))*(math.pi/180)
+               # lens = (360* (math.atan(ratio *16 / ob.data.getLens()) / math.pi))*(math.pi/180)
+               lens = min(lens, math.pi) 
+               
+               # get the camera location, subtract 90 degress from X to orient like X3D does
+               # mat = ob.matrixWorld - mat is now passed!
+               
+               loc = self.rotatePointForVRML(mat.translationPart())
+               rot = mat.toEuler()
+               rot = (((rot[0]-90)), rot[1], rot[2])
+               # rot = (((rot[0]-90)*DEG2RAD), rot[1]*DEG2RAD, rot[2]*DEG2RAD)
+               nRot = self.rotatePointForVRML( rot )
+               # convert to Quaternion and to Angle Axis
+               Q  = self.eulerToQuaternions(nRot[0], nRot[1], nRot[2])
+               Q1 = self.multiplyQuaternions(Q[0], Q[1])
+               Qf = self.multiplyQuaternions(Q1, Q[2])
+               angleAxis = self.quaternionToAngleAxis(Qf)
+               self.file.write("<Viewpoint DEF=\"%s\" " % (self.cleanStr(ob.name)))
+               self.file.write("description=\"%s\" " % (ob.name))
+               self.file.write("centerOfRotation=\"0 0 0\" ")
+               self.file.write("position=\"%3.2f %3.2f %3.2f\" " % (loc[0], loc[1], loc[2]))
+               self.file.write("orientation=\"%3.2f %3.2f %3.2f %3.2f\" " % (angleAxis[0], angleAxis[1], -angleAxis[2], angleAxis[3]))
+               self.file.write("fieldOfView=\"%.3f\" />\n\n" % (lens))
+       def writeFog(self, world):
+               if world:
+                       mtype = world.mist.falloff
+                       # mtype = world.getMistype()
+                       mparam = world.mist
+                       # mparam = world.getMist()
+                       grd = world.horizon_color
+                       # grd = world.getHor()
+                       grd0, grd1, grd2 = grd[0], grd[1], grd[2]
+               else:
+                       return
+               if (mtype == 'LINEAR' or mtype == 'INVERSE_QUADRATIC'):
+                       mtype = 1 if mtype == 'LINEAR' else 2
+               # if (mtype == 1 or mtype == 2):
+                       self.file.write("<Fog fogType=\"%s\" " % self.namesFog[mtype])                                          
+                       self.file.write("color=\"%s %s %s\" " % (round(grd0,self.cp), round(grd1,self.cp), round(grd2,self.cp)))
+                       self.file.write("visibilityRange=\"%s\" />\n\n" % round(mparam[2],self.cp))
+               else:
+                       return
+       
+       def writeNavigationInfo(self, scene):
+               self.file.write('<NavigationInfo headlight="FALSE" visibilityLimit="0.0" type=\'"EXAMINE","ANY"\' avatarSize="0.25, 1.75, 0.75" />\n')
+       
+       def writeSpotLight(self, ob, mtx, lamp, world):
+               safeName = self.cleanStr(ob.name)
+               if world:
+                       ambi = world.ambient_color
+                       # ambi = world.amb
+                       ambientIntensity = ((float(ambi[0] + ambi[1] + ambi[2]))/3)/2.5
+               else:
+                       ambi = 0
+                       ambientIntensity = 0
+               # compute cutoff and beamwidth
+               intensity=min(lamp.energy/1.75,1.0)
+               beamWidth=((lamp.spot_size*math.pi)/180.0)*.37;
+               # beamWidth=((lamp.spotSize*math.pi)/180.0)*.37;
+               cutOffAngle=beamWidth*1.3
+               dx,dy,dz=self.computeDirection(mtx)
+               # note -dx seems to equal om[3][0]
+               # note -dz seems to equal om[3][1]
+               # note  dy seems to equal om[3][2]
+               #location=(ob.matrixWorld*MATWORLD).translationPart() # now passed
+               location=(mtx*MATWORLD).translationPart()
+               
+               radius = lamp.distance*math.cos(beamWidth)
+               # radius = lamp.dist*math.cos(beamWidth)
+               self.file.write("<SpotLight DEF=\"%s\" " % safeName)
+               self.file.write("radius=\"%s\" " % (round(radius,self.cp)))
+               self.file.write("ambientIntensity=\"%s\" " % (round(ambientIntensity,self.cp)))
+               self.file.write("intensity=\"%s\" " % (round(intensity,self.cp)))
+               self.file.write("color=\"%s %s %s\" " % (round(lamp.color[0],self.cp), round(lamp.color[1],self.cp), round(lamp.color[2],self.cp)))
+               # self.file.write("color=\"%s %s %s\" " % (round(lamp.col[0],self.cp), round(lamp.col[1],self.cp), round(lamp.col[2],self.cp)))
+               self.file.write("beamWidth=\"%s\" " % (round(beamWidth,self.cp)))
+               self.file.write("cutOffAngle=\"%s\" " % (round(cutOffAngle,self.cp)))
+               self.file.write("direction=\"%s %s %s\" " % (round(dx,3),round(dy,3),round(dz,3)))
+               self.file.write("location=\"%s %s %s\" />\n\n" % (round(location[0],3), round(location[1],3), round(location[2],3)))
+               
+               
+       def writeDirectionalLight(self, ob, mtx, lamp, world):
+               safeName = self.cleanStr(ob.name)
+               if world:
+                       ambi = world.ambient_color
+                       # ambi = world.amb
+                       ambientIntensity = ((float(ambi[0] + ambi[1] + ambi[2]))/3)/2.5
+               else:
+                       ambi = 0
+                       ambientIntensity = 0
+               intensity=min(lamp.energy/1.75,1.0) 
+               (dx,dy,dz)=self.computeDirection(mtx)
+               self.file.write("<DirectionalLight DEF=\"%s\" " % safeName)
+               self.file.write("ambientIntensity=\"%s\" " % (round(ambientIntensity,self.cp)))
+               self.file.write("color=\"%s %s %s\" " % (round(lamp.color[0],self.cp), round(lamp.color[1],self.cp), round(lamp.color[2],self.cp)))
+               # self.file.write("color=\"%s %s %s\" " % (round(lamp.col[0],self.cp), round(lamp.col[1],self.cp), round(lamp.col[2],self.cp)))
+               self.file.write("intensity=\"%s\" " % (round(intensity,self.cp)))
+               self.file.write("direction=\"%s %s %s\" />\n\n" % (round(dx,4),round(dy,4),round(dz,4)))
+       def writePointLight(self, ob, mtx, lamp, world):
+               safeName = self.cleanStr(ob.name)
+               if world:
+                       ambi = world.ambient_color
+                       # ambi = world.amb
+                       ambientIntensity = ((float(ambi[0] + ambi[1] + ambi[2]))/3)/2.5
+               else:
+                       ambi = 0
+                       ambientIntensity = 0
+               
+               # location=(ob.matrixWorld*MATWORLD).translationPart() # now passed
+               location= (mtx*MATWORLD).translationPart()
+               
+               self.file.write("<PointLight DEF=\"%s\" " % safeName)
+               self.file.write("ambientIntensity=\"%s\" " % (round(ambientIntensity,self.cp)))
+               self.file.write("color=\"%s %s %s\" " % (round(lamp.color[0],self.cp), round(lamp.color[1],self.cp), round(lamp.color[2],self.cp)))
+               # self.file.write("color=\"%s %s %s\" " % (round(lamp.col[0],self.cp), round(lamp.col[1],self.cp), round(lamp.col[2],self.cp)))
+               self.file.write("intensity=\"%s\" " % (round( min(lamp.energy/1.75,1.0) ,self.cp)))
+               self.file.write("radius=\"%s\" " % lamp.distance )
+               # self.file.write("radius=\"%s\" " % lamp.dist )
+               self.file.write("location=\"%s %s %s\" />\n\n" % (round(location[0],3), round(location[1],3), round(location[2],3)))
+       '''
+       def writeNode(self, ob, mtx):
+               obname=str(ob.name)
+               if obname in self.namesStandard:
+                       return
+               else:
+                       dx,dy,dz = self.computeDirection(mtx)
+                       # location=(ob.matrixWorld*MATWORLD).translationPart()
+                       location=(mtx*MATWORLD).translationPart()
+                       self.writeIndented("<%s\n" % obname,1)
+                       self.writeIndented("direction=\"%s %s %s\"\n" % (round(dx,3),round(dy,3),round(dz,3)))
+                       self.writeIndented("location=\"%s %s %s\"\n" % (round(location[0],3), round(location[1],3), round(location[2],3)))
+                       self.writeIndented("/>\n",-1)
+                       self.writeIndented("\n")
+       '''
+       def secureName(self, name):
+               name = name + str(self.nodeID)
+               self.nodeID=self.nodeID+1
+               if len(name) <= 3:
+                       newname = "_" + str(self.nodeID)
+                       return "%s" % (newname)
+               else:
+                       for bad in ['"','#',"'",',','.','[','\\',']','{','}']:
+                               name=name.replace(bad,'_')
+                       if name in self.namesReserved:
+                               newname = name[0:3] + "_" + str(self.nodeID)
+                               return "%s" % (newname)
+                       elif name[0].isdigit():
+                               newname = "_" + name + str(self.nodeID)
+                               return "%s" % (newname)
+                       else:
+                               newname = name
+                               return "%s" % (newname)
+       def writeIndexedFaceSet(self, ob, mesh, mtx, world, EXPORT_TRI = False):
+               imageMap={}   # set of used images
+               sided={}          # 'one':cnt , 'two':cnt
+               vColors={}      # 'multi':1
+               meshName = self.cleanStr(ob.name)
+               
+               meshME = self.cleanStr(ob.data.name) # We dont care if its the mesh name or not
+               # meshME = self.cleanStr(ob.getData(mesh=1).name) # We dont care if its the mesh name or not
+               if len(mesh.faces) == 0: return
+               mode = []
+               # mode = 0
+               if mesh.active_uv_texture:
+               # if mesh.faceUV:
+                       for face in mesh.active_uv_texture.data:
+                       # for face in mesh.faces:
+                               if face.halo and 'HALO' not in mode:
+                                       mode += ['HALO']
+                               if face.billboard and 'BILLBOARD' not in mode:
+                                       mode += ['BILLBOARD']
+                               if face.object_color and 'OBJECT_COLOR' not in mode:
+                                       mode += ['OBJECT_COLOR']
+                               if face.collision and 'COLLISION' not in mode:
+                                       mode += ['COLLISION']
+                               # mode |= face.mode 
+               
+               if 'HALO' in mode and self.halonode == 0:
+               # if mode & Mesh.FaceModes.HALO and self.halonode == 0:
+                       self.writeIndented("<Billboard axisOfRotation=\"0 0 0\">\n",1)
+                       self.halonode = 1
+               elif 'BILLBOARD' in mode and self.billnode == 0:
+               # elif mode & Mesh.FaceModes.BILLBOARD and self.billnode == 0:
+                       self.writeIndented("<Billboard axisOfRotation=\"0 1 0\">\n",1)
+                       self.billnode = 1
+               elif 'OBJECT_COLOR' in mode and self.matonly == 0:
+               # elif mode & Mesh.FaceModes.OBCOL and self.matonly == 0:
+                       self.matonly = 1
+               # TF_TILES is marked as deprecated in DNA_meshdata_types.h
+               # elif mode & Mesh.FaceModes.TILES and self.tilenode == 0:
+               #       self.tilenode = 1
+               elif 'COLLISION' not in mode and self.collnode == 0:
+               # elif not mode & Mesh.FaceModes.DYNAMIC and self.collnode == 0:
+                       self.writeIndented("<Collision enabled=\"false\">\n",1)
+                       self.collnode = 1
+               
+               nIFSCnt=self.countIFSSetsNeeded(mesh, imageMap, sided, vColors)
+               
+               if nIFSCnt > 1:
+                       self.writeIndented("<Group DEF=\"%s%s\">\n" % ("G_", meshName),1)
+               
+               if 'two' in sided and sided['two'] > 0:
+                       bTwoSided=1
+               else:
+                       bTwoSided=0
+               # mtx = ob.matrixWorld * MATWORLD # mtx is now passed
+               mtx = mtx * MATWORLD
+               
+               loc= mtx.translationPart()
+               sca= mtx.scalePart()
+               quat = mtx.toQuat()
+               rot= quat.axis
+               self.writeIndented('<Transform DEF="%s" translation="%.6f %.6f %.6f" scale="%.6f %.6f %.6f" rotation="%.6f %.6f %.6f %.6f">\n' % \
+                                                  (meshName, loc[0], loc[1], loc[2], sca[0], sca[1], sca[2], rot[0], rot[1], rot[2], quat.angle) )
+               # self.writeIndented('<Transform DEF="%s" translation="%.6f %.6f %.6f" scale="%.6f %.6f %.6f" rotation="%.6f %.6f %.6f %.6f">\n' % \
+               #   (meshName, loc[0], loc[1], loc[2], sca[0], sca[1], sca[2], rot[0], rot[1], rot[2], quat.angle*DEG2RAD) )
+               self.writeIndented("<Shape>\n",1)
+               maters=mesh.materials
+               hasImageTexture=0
+               issmooth=0
+               if len(maters) > 0 or mesh.active_uv_texture:
+               # if len(maters) > 0 or mesh.faceUV:
+                       self.writeIndented("<Appearance>\n", 1)
+                       # right now this script can only handle a single material per mesh.
+                       if len(maters) >= 1:
+                               mat=maters[0]
+                               # matFlags = mat.getMode()
+                               if not mat.face_texture:
+                               # if not matFlags & Blender.Material.Modes['TEXFACE']:
+                                       self.writeMaterial(mat, self.cleanStr(mat.name,''), world)
+                                       # self.writeMaterial(mat, self.cleanStr(maters[0].name,''), world)
+                                       if len(maters) > 1:
+                                               print("Warning: mesh named %s has multiple materials" % meshName)
+                                               print("Warning: only one material per object handled")
+                       
+                               #-- textures
+                               face = None
+                               if mesh.active_uv_texture:
+                               # if mesh.faceUV:
+                                       for face in mesh.active_uv_texture.data:
+                                       # for face in mesh.faces:
+                                               if face.image:
+                                               # if (hasImageTexture == 0) and (face.image):
+                                                       self.writeImageTexture(face.image)
+                                                       # hasImageTexture=1  # keep track of face texture
+                                                       break
+                               if self.tilenode == 1 and face and face.image:
+                               # if self.tilenode == 1:
+                                       self.writeIndented("<TextureTransform   scale=\"%s %s\" />\n" % (face.image.xrep, face.image.yrep))
+                                       self.tilenode = 0
+                               self.writeIndented("</Appearance>\n", -1)
+               #-- IndexedFaceSet or IndexedLineSet
+               # user selected BOUNDS=1, SOLID=3, SHARED=4, or TEXTURE=5
+               ifStyle="IndexedFaceSet"
+               # look up mesh name, use it if available
+               if meshME in self.meshNames:
+                       self.writeIndented("<%s USE=\"ME_%s\">" % (ifStyle, meshME), 1)
+                       self.meshNames[meshME]+=1
+               else:
+                       if int(mesh.users) > 1:
+                               self.writeIndented("<%s DEF=\"ME_%s\" " % (ifStyle, meshME), 1)
+                               self.meshNames[meshME]=1
+                       else:
+                               self.writeIndented("<%s " % ifStyle, 1)
+                       
+                       if bTwoSided == 1:
+                               self.file.write("solid=\"false\" ")
+                       else:
+                               self.file.write("solid=\"true\" ")
+                       for face in mesh.faces:
+                               if face.smooth:
+                                        issmooth=1
+                                        break
+                       if issmooth==1:
+                               creaseAngle=(mesh.autosmooth_angle)*(math.pi/180.0)
+                               # creaseAngle=(mesh.degr)*(math.pi/180.0)
+                               self.file.write("creaseAngle=\"%s\" " % (round(creaseAngle,self.cp)))
+                       #--- output textureCoordinates if UV texture used
+                       if mesh.active_uv_texture:
+                       # if mesh.faceUV:
+                               if self.matonly == 1 and self.share == 1:
+                                       self.writeFaceColors(mesh)
+                               elif hasImageTexture == 1:
+                                       self.writeTextureCoordinates(mesh)
+                       #--- output coordinates
+                       self.writeCoordinates(ob, mesh, meshName, EXPORT_TRI)
+                       self.writingcoords = 1
+                       self.writingtexture = 1
+                       self.writingcolor = 1
+                       self.writeCoordinates(ob, mesh, meshName, EXPORT_TRI)
+                       
+                       #--- output textureCoordinates if UV texture used
+                       if mesh.active_uv_texture:
+                       # if mesh.faceUV:
+                               if hasImageTexture == 1:
+                                       self.writeTextureCoordinates(mesh)
+                               elif self.matonly == 1 and self.share == 1:
+                                       self.writeFaceColors(mesh)
+                       #--- output vertexColors
+               self.matonly = 0
+               self.share = 0
+               
+               self.writingcoords = 0
+               self.writingtexture = 0
+               self.writingcolor = 0
+               #--- output closing braces
+               self.writeIndented("</%s>\n" % ifStyle, -1)
+               self.writeIndented("</Shape>\n", -1)
+               self.writeIndented("</Transform>\n", -1)
+               if self.halonode == 1:
+                       self.writeIndented("</Billboard>\n", -1)
+                       self.halonode = 0
+               if self.billnode == 1:
+                       self.writeIndented("</Billboard>\n", -1)
+                       self.billnode = 0
+               if self.collnode == 1:
+                       self.writeIndented("</Collision>\n", -1)
+                       self.collnode = 0
+               if nIFSCnt > 1:
+                       self.writeIndented("</Group>\n", -1)
+               self.file.write("\n")
+       def writeCoordinates(self, ob, mesh, meshName, EXPORT_TRI = False):
+               # create vertex list and pre rotate -90 degrees X for VRML
+               
+               if self.writingcoords == 0:
+                       self.file.write('coordIndex="')
+                       for face in mesh.faces:
+                               fv = face.verts
+                               # fv = face.v
+                               
+                               if len(fv)==3:
+                               # if len(face)==3:
+                                       self.file.write("%i %i %i -1, " % (fv[0], fv[1], fv[2]))
+                                       # self.file.write("%i %i %i -1, " % (fv[0].index, fv[1].index, fv[2].index))
+                               else:
+                                       if EXPORT_TRI:
+                                               self.file.write("%i %i %i -1, " % (fv[0], fv[1], fv[2]))
+                                               # self.file.write("%i %i %i -1, " % (fv[0].index, fv[1].index, fv[2].index))
+                                               self.file.write("%i %i %i -1, " % (fv[0], fv[2], fv[3]))
+                                               # self.file.write("%i %i %i -1, " % (fv[0].index, fv[2].index, fv[3].index))
+                                       else:
+                                               self.file.write("%i %i %i %i -1, " % (fv[0], fv[1], fv[2], fv[3]))
+                                               # self.file.write("%i %i %i %i -1, " % (fv[0].index, fv[1].index, fv[2].index, fv[3].index))
+                       
+                       self.file.write("\">\n")
+               else:
+                       #-- vertices
+                       # mesh.transform(ob.matrixWorld)
+                       self.writeIndented("<Coordinate DEF=\"%s%s\" \n" % ("coord_",meshName), 1)
+                       self.file.write("\t\t\t\tpoint=\"")
+                       for v in mesh.verts:
+                               self.file.write("%.6f %.6f %.6f, " % tuple(v.co))
+                       self.file.write("\" />")
+                       self.writeIndented("\n", -1)
+       def writeTextureCoordinates(self, mesh):
+               texCoordList=[] 
+               texIndexList=[]
+               j=0
+               for face in mesh.active_uv_texture.data:
+               # for face in mesh.faces:
+                       uvs = [face.uv1, face.uv2, face.uv3, face.uv4] if face.verts[3] else [face.uv1, face.uv2, face.uv3]
+                       for uv in uvs:
+                       # for uv in face.uv:
+                               texIndexList.append(j)
+                               texCoordList.append(uv)
+                               j=j+1
+                       texIndexList.append(-1)
+               if self.writingtexture == 0:
+                       self.file.write("\n\t\t\ttexCoordIndex=\"")
+                       texIndxStr=""
+                       for i in range(len(texIndexList)):
+                               texIndxStr = texIndxStr + "%d, " % texIndexList[i]
+                               if texIndexList[i]==-1:
+                                       self.file.write(texIndxStr)
+                                       texIndxStr=""
+                       self.file.write("\"\n\t\t\t")
+               else:
+                       self.writeIndented("<TextureCoordinate point=\"", 1)
+                       for i in range(len(texCoordList)):
+                               self.file.write("%s %s, " % (round(texCoordList[i][0],self.tp), round(texCoordList[i][1],self.tp)))
+                       self.file.write("\" />")
+                       self.writeIndented("\n", -1)
+       def writeFaceColors(self, mesh):
+               if self.writingcolor == 0:
+                       self.file.write("colorPerVertex=\"false\" ")
+               elif mesh.active_vertex_color:
+               # else:
+                       self.writeIndented("<Color color=\"", 1)
+                       for face in mesh.active_vertex_color.data:
+                               c = face.color1
+                               if self.verbose > 2:
+                                       print("Debug: face.col r=%d g=%d b=%d" % (c[0], c[1], c[2]))
+                                       # print("Debug: face.col r=%d g=%d b=%d" % (c.r, c.g, c.b))
+                               aColor = self.rgbToFS(c)
+                               self.file.write("%s, " % aColor)
+                       # for face in mesh.faces:
+                       #       if face.col:
+                       #               c=face.col[0]
+                       #               if self.verbose > 2:
+                       #                       print("Debug: face.col r=%d g=%d b=%d" % (c.r, c.g, c.b))
+                       #               aColor = self.rgbToFS(c)
+                       #               self.file.write("%s, " % aColor)
+                       self.file.write("\" />")
+                       self.writeIndented("\n",-1)
+       
+       def writeMaterial(self, mat, matName, world):
+               # look up material name, use it if available
+               if matName in self.matNames:
+                       self.writeIndented("<Material USE=\"MA_%s\" />\n" % matName)
+                       self.matNames[matName]+=1
+                       return;
+               self.matNames[matName]=1
+               ambient = mat.ambient/3
+               # ambient = mat.amb/3
+               diffuseR, diffuseG, diffuseB = tuple(mat.diffuse_color)
+               # diffuseR, diffuseG, diffuseB = mat.rgbCol[0], mat.rgbCol[1],mat.rgbCol[2]
+               if world:
+                       ambi = world.ambient_color
+                       # ambi = world.getAmb()
+                       ambi0, ambi1, ambi2 = (ambi[0]*mat.ambient)*2, (ambi[1]*mat.ambient)*2, (ambi[2]*mat.ambient)*2
+                       # ambi0, ambi1, ambi2 = (ambi[0]*mat.amb)*2, (ambi[1]*mat.amb)*2, (ambi[2]*mat.amb)*2
+               else:
+                       ambi0, ambi1, ambi2 = 0, 0, 0
+               emisR, emisG, emisB = (diffuseR*mat.emit+ambi0)/2, (diffuseG*mat.emit+ambi1)/2, (diffuseB*mat.emit+ambi2)/2
+               shininess = mat.specular_hardness/512.0
+               # shininess = mat.hard/512.0
+               specR = (mat.specular_color[0]+0.001)/(1.25/(mat.specular_reflection+0.001))
+               # specR = (mat.specCol[0]+0.001)/(1.25/(mat.spec+0.001))
+               specG = (mat.specular_color[1]+0.001)/(1.25/(mat.specular_reflection+0.001))
+               # specG = (mat.specCol[1]+0.001)/(1.25/(mat.spec+0.001))
+               specB = (mat.specular_color[2]+0.001)/(1.25/(mat.specular_reflection+0.001))
+               # specB = (mat.specCol[2]+0.001)/(1.25/(mat.spec+0.001))
+               transp = 1-mat.alpha
+               # matFlags = mat.getMode()
+               if mat.shadeless:
+               # if matFlags & Blender.Material.Modes['SHADELESS']:
+                 ambient = 1
+                 shine = 1
+                 specR = emitR = diffuseR
+                 specG = emitG = diffuseG
+                 specB = emitB = diffuseB
+               self.writeIndented("<Material DEF=\"MA_%s\" " % matName, 1)
+               self.file.write("diffuseColor=\"%s %s %s\" " % (round(diffuseR,self.cp), round(diffuseG,self.cp), round(diffuseB,self.cp)))
+               self.file.write("specularColor=\"%s %s %s\" " % (round(specR,self.cp), round(specG,self.cp), round(specB,self.cp)))
+               self.file.write("emissiveColor=\"%s %s %s\" \n" % (round(emisR,self.cp), round(emisG,self.cp), round(emisB,self.cp)))
+               self.writeIndented("ambientIntensity=\"%s\" " % (round(ambient,self.cp)))
+               self.file.write("shininess=\"%s\" " % (round(shininess,self.cp)))
+               self.file.write("transparency=\"%s\" />" % (round(transp,self.cp)))
+               self.writeIndented("\n",-1)
+       def writeImageTexture(self, image):
+               name = image.name
+               filename = image.filename.split('/')[-1].split('\\')[-1]
+               if name in self.texNames:
+                       self.writeIndented("<ImageTexture USE=\"%s\" />\n" % self.cleanStr(name))
+                       self.texNames[name] += 1
+                       return
+               else:
+                       self.writeIndented("<ImageTexture DEF=\"%s\" " % self.cleanStr(name), 1)
+                       self.file.write("url=\"%s\" />" % name)
+                       self.writeIndented("\n",-1)
+                       self.texNames[name] = 1
+       def writeBackground(self, world, alltextures):
+               if world:       worldname = world.name
+               else:           return
+               blending = (world.blend_sky, world.paper_sky, world.real_sky)
+               # blending = world.getSkytype() 
+               grd = world.horizon_color
+               # grd = world.getHor()
+               grd0, grd1, grd2 = grd[0], grd[1], grd[2]
+               sky = world.zenith_color
+               # sky = world.getZen()
+               sky0, sky1, sky2 = sky[0], sky[1], sky[2]
+               mix0, mix1, mix2 = grd[0]+sky[0], grd[1]+sky[1], grd[2]+sky[2]
+               mix0, mix1, mix2 = mix0/2, mix1/2, mix2/2
+               self.file.write("<Background ")
+               if worldname not in self.namesStandard:
+                       self.file.write("DEF=\"%s\" " % self.secureName(worldname))
+               # No Skytype - just Hor color
+               if blending == (0, 0, 0):
+               # if blending == 0:
+                       self.file.write("groundColor=\"%s %s %s\" " % (round(grd0,self.cp), round(grd1,self.cp), round(grd2,self.cp)))
+                       self.file.write("skyColor=\"%s %s %s\" " % (round(grd0,self.cp), round(grd1,self.cp), round(grd2,self.cp)))
+               # Blend Gradient
+               elif blending == (1, 0, 0):
+               # elif blending == 1:
+                       self.file.write("groundColor=\"%s %s %s, " % (round(grd0,self.cp), round(grd1,self.cp), round(grd2,self.cp)))
+                       self.file.write("%s %s %s\" groundAngle=\"1.57, 1.57\" " %(round(mix0,self.cp), round(mix1,self.cp), round(mix2,self.cp)))
+                       self.file.write("skyColor=\"%s %s %s, " % (round(sky0,self.cp), round(sky1,self.cp), round(sky2,self.cp)))
+                       self.file.write("%s %s %s\" skyAngle=\"1.57, 1.57\" " %(round(mix0,self.cp), round(mix1,self.cp), round(mix2,self.cp)))
+               # Blend+Real Gradient Inverse
+               elif blending == (1, 0, 1):
+               # elif blending == 3:
+                       self.file.write("groundColor=\"%s %s %s, " % (round(sky0,self.cp), round(sky1,self.cp), round(sky2,self.cp)))
+                       self.file.write("%s %s %s\" groundAngle=\"1.57, 1.57\" " %(round(mix0,self.cp), round(mix1,self.cp), round(mix2,self.cp)))
+                       self.file.write("skyColor=\"%s %s %s, " % (round(grd0,self.cp), round(grd1,self.cp), round(grd2,self.cp)))
+                       self.file.write("%s %s %s\" skyAngle=\"1.57, 1.57\" " %(round(mix0,self.cp), round(mix1,self.cp), round(mix2,self.cp)))
+               # Paper - just Zen Color
+               elif blending == (0, 0, 1):
+               # elif blending == 4:
+                       self.file.write("groundColor=\"%s %s %s\" " % (round(sky0,self.cp), round(sky1,self.cp), round(sky2,self.cp)))
+                       self.file.write("skyColor=\"%s %s %s\" " % (round(sky0,self.cp), round(sky1,self.cp), round(sky2,self.cp)))
+               # Blend+Real+Paper - komplex gradient
+               elif blending == (1, 1, 1):
+               # elif blending == 7:
+                       self.writeIndented("groundColor=\"%s %s %s, " % (round(sky0,self.cp), round(sky1,self.cp), round(sky2,self.cp)))
+                       self.writeIndented("%s %s %s\" groundAngle=\"1.57, 1.57\" " %(round(grd0,self.cp), round(grd1,self.cp), round(grd2,self.cp)))
+                       self.writeIndented("skyColor=\"%s %s %s, " % (round(sky0,self.cp), round(sky1,self.cp), round(sky2,self.cp)))
+                       self.writeIndented("%s %s %s\" skyAngle=\"1.57, 1.57\" " %(round(grd0,self.cp), round(grd1,self.cp), round(grd2,self.cp)))
+               # Any Other two colors
+               else:
+                       self.file.write("groundColor=\"%s %s %s\" " % (round(grd0,self.cp), round(grd1,self.cp), round(grd2,self.cp)))
+                       self.file.write("skyColor=\"%s %s %s\" " % (round(sky0,self.cp), round(sky1,self.cp), round(sky2,self.cp)))
+               alltexture = len(alltextures)
+               for i in range(alltexture):
+                       tex = alltextures[i]
+                       if tex.type != 'IMAGE' or tex.image == None:
+                               continue
+                       namemat = tex.name
+                       # namemat = alltextures[i].name
+                       pic = tex.image
+                       # using .expandpath just in case, os.path may not expect //
+                       basename = os.path.basename(bpy.sys.expandpath(pic.filename))
+                       pic = alltextures[i].image
+                       # pic = alltextures[i].getImage()
+                       if (namemat == "back") and (pic != None):
+                               self.file.write("\n\tbackUrl=\"%s\" " % basename)
+                               # self.file.write("\n\tbackUrl=\"%s\" " % pic.filename.split('/')[-1].split('\\')[-1])
+                       elif (namemat == "bottom") and (pic != None):
+                               self.writeIndented("bottomUrl=\"%s\" " % basename)
+                               # self.writeIndented("bottomUrl=\"%s\" " % pic.filename.split('/')[-1].split('\\')[-1])
+                       elif (namemat == "front") and (pic != None):
+                               self.writeIndented("frontUrl=\"%s\" " % basename)
+                               # self.writeIndented("frontUrl=\"%s\" " % pic.filename.split('/')[-1].split('\\')[-1])
+                       elif (namemat == "left") and (pic != None):
+                               self.writeIndented("leftUrl=\"%s\" " % basename)
+                               # self.writeIndented("leftUrl=\"%s\" " % pic.filename.split('/')[-1].split('\\')[-1])
+                       elif (namemat == "right") and (pic != None):
+                               self.writeIndented("rightUrl=\"%s\" " % basename)
+                               # self.writeIndented("rightUrl=\"%s\" " % pic.filename.split('/')[-1].split('\\')[-1])
+                       elif (namemat == "top") and (pic != None):
+                               self.writeIndented("topUrl=\"%s\" " % basename)
+                               # self.writeIndented("topUrl=\"%s\" " % pic.filename.split('/')[-1].split('\\')[-1])
+               self.writeIndented("/>\n\n")
+ ##########################################################
+ # export routine
+ ##########################################################
+       def export(self, scene, world, alltextures,\
+                       EXPORT_APPLY_MODIFIERS = False,\
+                       EXPORT_TRI=                             False,\
+               ):
+               
+               print("Info: starting X3D export to " + self.filename + "...")
+               self.writeHeader()
+               # self.writeScript()
+               self.writeNavigationInfo(scene)
+               self.writeBackground(world, alltextures)
+               self.writeFog(world)
+               self.proto = 0
+               
+               
+               # # COPIED FROM OBJ EXPORTER
+               # if EXPORT_APPLY_MODIFIERS:
+               #       temp_mesh_name = '~tmp-mesh'
+               
+               #       # Get the container mesh. - used for applying modifiers and non mesh objects.
+               #       containerMesh = meshName = tempMesh = None
+               #       for meshName in Blender.NMesh.GetNames():
+               #               if meshName.startswith(temp_mesh_name):
+               #                       tempMesh = Mesh.Get(meshName)
+               #                       if not tempMesh.users:
+               #                               containerMesh = tempMesh
+               #       if not containerMesh:
+               #               containerMesh = Mesh.New(temp_mesh_name)
+               # -------------------------- 
+               
+               
+               for ob_main in [o for o in scene.objects if o.is_visible()]:
+               # for ob_main in scene.objects.context:
+                       free, derived = create_derived_objects(ob_main)
+                       if derived == None: continue
+                       for ob, ob_mat in derived:
+                       # for ob, ob_mat in BPyObject.getDerivedObjects(ob_main):
+                               objType=ob.type
+                               objName=ob.name
+                               self.matonly = 0
+                               if objType == "CAMERA":
+                               # if objType == "Camera":
+                                       self.writeViewpoint(ob, ob_mat, scene)
+                               elif objType in ("MESH", "CURVE", "SURF", "TEXT") :
+                               # elif objType in ("Mesh", "Curve", "Surf", "Text") :                           
+                                       if EXPORT_APPLY_MODIFIERS or objType != 'MESH':
+                                       # if  EXPORT_APPLY_MODIFIERS or objType != 'Mesh':
+                                               me = ob.create_mesh(EXPORT_APPLY_MODIFIERS, 'PREVIEW')
+                                               # me= BPyMesh.getMeshFromObject(ob, containerMesh, EXPORT_APPLY_MODIFIERS, False, scene)
+                                       else:
+                                               me = ob.data
+                                               # me = ob.getData(mesh=1)
+                                       
+                                       self.writeIndexedFaceSet(ob, me, ob_mat, world, EXPORT_TRI = EXPORT_TRI)
+                                       # free mesh created with create_mesh()
+                                       if me != ob.data:
+                                               bpy.data.remove_mesh(me)
+                               elif objType == "LAMP":
+                               # elif objType == "Lamp":
+                                       data= ob.data
+                                       datatype=data.type
+                                       if datatype == 'POINT':
+                                       # if datatype == Lamp.Types.Lamp:
+                                               self.writePointLight(ob, ob_mat, data, world)
+                                       elif datatype == 'SPOT':
+                                       # elif datatype == Lamp.Types.Spot:
+                                               self.writeSpotLight(ob, ob_mat, data, world)
+                                       elif datatype == 'SUN':
+                                       # elif datatype == Lamp.Types.Sun:
+                                               self.writeDirectionalLight(ob, ob_mat, data, world)
+                                       else:
+                                               self.writeDirectionalLight(ob, ob_mat, data, world)
+                               # do you think x3d could document what to do with dummy objects?
+                               #elif objType == "Empty" and objName != "Empty":
+                               #       self.writeNode(ob, ob_mat)
+                               else:
+                                       #print "Info: Ignoring [%s], object type [%s] not handle yet" % (object.name,object.getType)
+                                       pass
+                               
+                       if free:
+                               free_derived_objects(ob_main)
+                       
+               self.file.write("\n</Scene>\n</X3D>")
+               
+               # if EXPORT_APPLY_MODIFIERS:
+               #       if containerMesh:
+               #               containerMesh.verts = None
+               
+               self.cleanup()
+               
+ ##########################################################
+ # Utility methods
+ ##########################################################
+       def cleanup(self):
+               self.file.close()
+               self.texNames={}
+               self.matNames={}
+               self.indentLevel=0
+               print("Info: finished X3D export to %s\n" % self.filename)
+       def cleanStr(self, name, prefix='rsvd_'):
+               """cleanStr(name,prefix) - try to create a valid VRML DEF name from object name"""
+               newName=name[:]
+               if len(newName) == 0:
+                       self.nNodeID+=1
+                       return "%s%d" % (prefix, self.nNodeID)
+               
+               if newName in self.namesReserved:
+                       newName='%s%s' % (prefix,newName)
+               
+               if newName[0].isdigit():
+                       newName='%s%s' % ('_',newName)
+               for bad in [' ','"','#',"'",',','.','[','\\',']','{','}']:
+                       newName=newName.replace(bad,'_')
+               return newName
+       def countIFSSetsNeeded(self, mesh, imageMap, sided, vColors):
+               """
+               countIFFSetsNeeded() - should look at a blender mesh to determine
+               how many VRML IndexFaceSets or IndexLineSets are needed.  A
+               new mesh created under the following conditions:
+               
+                o - split by UV Textures / one per mesh
+                o - split by face, one sided and two sided
+                o - split by smooth and flat faces
+                o - split when faces only have 2 vertices * needs to be an IndexLineSet
+               """
+               
+               imageNameMap={}
+               faceMap={}
+               nFaceIndx=0
+               
+               if mesh.active_uv_texture:
+               # if mesh.faceUV:
+                       for face in mesh.active_uv_texture.data:
+                       # for face in mesh.faces:
+                               sidename='';
+                               if face.twoside:
+                               # if  face.mode & Mesh.FaceModes.TWOSIDE:
+                                       sidename='two'
+                               else:
+                                       sidename='one'
+                               
+                               if sidename in sided:
+                                       sided[sidename]+=1
+                               else:
+                                       sided[sidename]=1
+                               
+                               image = face.image
+                               if image:
+                                       faceName="%s_%s" % (face.image.name, sidename);
+                                       try:
+                                               imageMap[faceName].append(face)
+                                       except:
+                                               imageMap[faceName]=[face.image.name,sidename,face]
+                       if self.verbose > 2:
+                               for faceName in imageMap.keys():
+                                       ifs=imageMap[faceName]
+                                       print("Debug: faceName=%s image=%s, solid=%s facecnt=%d" % \
+                                                 (faceName, ifs[0], ifs[1], len(ifs)-2))
+               return len(imageMap)
+       
+       def faceToString(self,face):
+               print("Debug: face.flag=0x%x (bitflags)" % face.flag)
+               if face.sel:
+                       print("Debug: face.sel=true")
+               print("Debug: face.mode=0x%x (bitflags)" % face.mode)
+               if face.mode & Mesh.FaceModes.TWOSIDE:
+                       print("Debug: face.mode twosided")
+               print("Debug: face.transp=0x%x (enum)" % face.transp)
+               if face.transp == Mesh.FaceTranspModes.SOLID:
+                       print("Debug: face.transp.SOLID")
+               if face.image:
+                       print("Debug: face.image=%s" % face.image.name)
+               print("Debug: face.materialIndex=%d" % face.materialIndex) 
+       # XXX not used
+       # def getVertexColorByIndx(self, mesh, indx):
+       #       c = None
+       #       for face in mesh.faces:
+       #               j=0
+       #               for vertex in face.v:
+       #                       if vertex.index == indx:
+       #                               c=face.col[j]
+       #                               break
+       #                       j=j+1
+       #               if c: break
+       #       return c
+       def meshToString(self,mesh):
+               # print("Debug: mesh.hasVertexUV=%d" % mesh.vertexColors)
+               print("Debug: mesh.faceUV=%d" % (len(mesh.uv_textures) > 0))
+               # print("Debug: mesh.faceUV=%d" % mesh.faceUV)
+               print("Debug: mesh.hasVertexColours=%d" % (len(mesh.vertex_colors) > 0))
+               # print("Debug: mesh.hasVertexColours=%d" % mesh.hasVertexColours())
+               print("Debug: mesh.verts=%d" % len(mesh.verts))
+               print("Debug: mesh.faces=%d" % len(mesh.faces))
+               print("Debug: mesh.materials=%d" % len(mesh.materials))
+       def rgbToFS(self, c):
+               s="%s %s %s" % (round(c[0]/255.0,self.cp),
+                                               round(c[1]/255.0,self.cp),
+                                               round(c[2]/255.0,self.cp))
+               # s="%s %s %s" % (
+               #       round(c.r/255.0,self.cp),
+               #       round(c.g/255.0,self.cp),
+               #       round(c.b/255.0,self.cp))
+               return s
+       def computeDirection(self, mtx):
+               x,y,z=(0,-1.0,0) # point down
+               
+               ax,ay,az = (mtx*MATWORLD).toEuler()
+               
+               # ax *= DEG2RAD
+               # ay *= DEG2RAD
+               # az *= DEG2RAD
+               # rot X
+               x1=x
+               y1=y*math.cos(ax)-z*math.sin(ax)
+               z1=y*math.sin(ax)+z*math.cos(ax)
+               # rot Y
+               x2=x1*math.cos(ay)+z1*math.sin(ay)
+               y2=y1
+               z2=z1*math.cos(ay)-x1*math.sin(ay)
+               # rot Z
+               x3=x2*math.cos(az)-y2*math.sin(az)
+               y3=x2*math.sin(az)+y2*math.cos(az)
+               z3=z2
+               return [x3,y3,z3]
+               
+       # swap Y and Z to handle axis difference between Blender and VRML
+       #------------------------------------------------------------------------
+       def rotatePointForVRML(self, v):
+               x = v[0]
+               y = v[2]
+               z = -v[1]
+               
+               vrmlPoint=[x, y, z]
+               return vrmlPoint
+       # For writing well formed VRML code
+       #------------------------------------------------------------------------
+       def writeIndented(self, s, inc=0):
+               if inc < 1:
+                       self.indentLevel = self.indentLevel + inc
+               spaces=""
+               for x in range(self.indentLevel):
+                       spaces = spaces + "\t"
+               self.file.write(spaces + s)
+               if inc > 0:
+                       self.indentLevel = self.indentLevel + inc
+       # Converts a Euler to three new Quaternions
+       # Angles of Euler are passed in as radians
+       #------------------------------------------------------------------------
+       def eulerToQuaternions(self, x, y, z):
+               Qx = [math.cos(x/2), math.sin(x/2), 0, 0]
+               Qy = [math.cos(y/2), 0, math.sin(y/2), 0]
+               Qz = [math.cos(z/2), 0, 0, math.sin(z/2)]
+               
+               quaternionVec=[Qx,Qy,Qz]
+               return quaternionVec
+       
+       # Multiply two Quaternions together to get a new Quaternion
+       #------------------------------------------------------------------------
+       def multiplyQuaternions(self, Q1, Q2):
+               result = [((Q1[0] * Q2[0]) - (Q1[1] * Q2[1]) - (Q1[2] * Q2[2]) - (Q1[3] * Q2[3])),
+                                 ((Q1[0] * Q2[1]) + (Q1[1] * Q2[0]) + (Q1[2] * Q2[3]) - (Q1[3] * Q2[2])),
+                                 ((Q1[0] * Q2[2]) + (Q1[2] * Q2[0]) + (Q1[3] * Q2[1]) - (Q1[1] * Q2[3])),
+                                 ((Q1[0] * Q2[3]) + (Q1[3] * Q2[0]) + (Q1[1] * Q2[2]) - (Q1[2] * Q2[1]))]
+               
+               return result
+       
+       # Convert a Quaternion to an Angle Axis (ax, ay, az, angle)
+       # angle is in radians
+       #------------------------------------------------------------------------
+       def quaternionToAngleAxis(self, Qf):
+               scale = math.pow(Qf[1],2) + math.pow(Qf[2],2) + math.pow(Qf[3],2)
+               ax = Qf[1]
+               ay = Qf[2]
+               az = Qf[3]
+               if scale > .0001:
+                       ax/=scale
+                       ay/=scale
+                       az/=scale
+               
+               angle = 2 * math.acos(Qf[0])
+               
+               result = [ax, ay, az, angle]
+               return result
+ ##########################################################
+ # Callbacks, needed before Main
+ ##########################################################
+ def x3d_export(filename,
+                          context,
+                          EXPORT_APPLY_MODIFIERS=False,
+                          EXPORT_TRI=False,
+                          EXPORT_GZIP=False):
+       
+       if EXPORT_GZIP:
+               if not filename.lower().endswith('.x3dz'):
+                       filename = '.'.join(filename.split('.')[:-1]) + '.x3dz'
+       else:
+               if not filename.lower().endswith('.x3d'):
+                       filename = '.'.join(filename.split('.')[:-1]) + '.x3d'
+       
+       
+       scene = context.scene
+       # scene = Blender.Scene.GetCurrent()
+       world = scene.world
+       # XXX these are global textures while .Get() returned only scene's?
+       alltextures = bpy.data.textures
+       # alltextures = Blender.Texture.Get()
+       wrlexport=x3d_class(filename)
+       wrlexport.export(\
+               scene,\
+               world,\
+               alltextures,\
+               \
+               EXPORT_APPLY_MODIFIERS = EXPORT_APPLY_MODIFIERS,\
+               EXPORT_TRI = EXPORT_TRI,\
+               )
+ def x3d_export_ui(filename):
+       if not filename.endswith(extension):
+               filename += extension
+       #if _safeOverwrite and sys.exists(filename):
+       #       result = Draw.PupMenu("File Already Exists, Overwrite?%t|Yes%x1|No%x0")
+       #if(result != 1):
+       #       return
+       
+       # Get user options
+       EXPORT_APPLY_MODIFIERS = Draw.Create(1)
+       EXPORT_TRI = Draw.Create(0)
+       EXPORT_GZIP = Draw.Create( filename.lower().endswith('.x3dz') )
+       
+       # Get USER Options
+       pup_block = [\
+       ('Apply Modifiers', EXPORT_APPLY_MODIFIERS, 'Use transformed mesh data from each object.'),\
+       ('Triangulate', EXPORT_TRI, 'Triangulate quads.'),\
+       ('Compress', EXPORT_GZIP, 'GZip the resulting file, requires a full python install'),\
+       ]
+       if not Draw.PupBlock('Export...', pup_block):
+               return
+       Blender.Window.EditMode(0)
+       Blender.Window.WaitCursor(1)
+       
+       x3d_export(filename,\
+               EXPORT_APPLY_MODIFIERS = EXPORT_APPLY_MODIFIERS.val,\
+               EXPORT_TRI = EXPORT_TRI.val,\
+               EXPORT_GZIP = EXPORT_GZIP.val\
+       )
+       
+       Blender.Window.WaitCursor(0)
+ #########################################################
+ # main routine
+ #########################################################
+ # if __name__ == '__main__':
+ #     Blender.Window.FileSelector(x3d_export_ui,"Export X3D", Blender.Get('filename').replace('.blend', '.x3d'))
+ class EXPORT_OT_x3d(bpy.types.Operator):
+       '''
+       X3D Exporter
+       '''
+       __idname__ = "export.x3d"
+       __label__ = 'Export X3D'
+       
+       # List of operator properties, the attributes will be assigned
+       # to the class instance from the operator settings before calling.
+       __props__ = [
+               bpy.props.StringProperty(attr="filename", name="File Name", description="File name used for exporting the X3D file", maxlen=1024, default=""),
+               bpy.props.BoolProperty(attr="apply_modifiers", name="Apply Modifiers", description="Use transformed mesh data from each object.", default=True),
+               bpy.props.BoolProperty(attr="triangulate", name="Triangulate", description="Triangulate quads.", default=False),
+               bpy.props.BoolProperty(attr="compress", name="Compress", description="GZip the resulting file, requires a full python install.", default=False),
+       ]
+       
+       def execute(self, context):
+               x3d_export(self.filename, context, self.apply_modifiers, self.triangulate, self.compress)
+               return ('FINISHED',)
+       
+       def invoke(self, context, event):
+               wm = context.manager
+               wm.add_fileselect(self.__operator__)
+               return ('RUNNING_MODAL',)
+       
+       def poll(self, context): # Poll isnt working yet
+               print("Poll")
+               return context.active_object != None
+ bpy.ops.add(EXPORT_OT_x3d)
+ # NOTES
+ # - blender version is hardcoded 
@@@ -83,20 -76,24 +83,27 @@@ class INFO_MT_file_import(bpy.types.Men
  
        def draw(self, context):
                layout = self.layout
-               layout.itemL(text="Nothing yet")
 +              
+               layout.itemO("import.3ds", text="3DS")
+               layout.itemO("import.obj", text="OBJ")
 +
  class INFO_MT_file_export(bpy.types.Menu):
 -      __space_type__ = "INFO"
 +      __space_type__ = 'INFO'
        __label__ = "Export"
  
        def draw(self, context):
                layout = self.layout
  
+               layout.itemO("export.3ds", text="3DS")
+               layout.itemO("export.fbx", text="FBX")
+               layout.itemO("export.obj", text="OBJ")
                layout.itemO("export.ply", text="PLY")
+               layout.itemO("export.x3d", text="X3D")
 +
  class INFO_MT_file_external_data(bpy.types.Menu):
 -      __space_type__ = "INFO"
 +      __space_type__ = 'INFO'
        __label__ = "External Data"
  
        def draw(self, context):
Simple merge
@@@ -2175,3 -2165,102 +2175,103 @@@ void BKE_image_user_calc_imanr(ImageUse
        }
  }
  
+ /*
+   Produce image export path.
+   Fails returning 0 if image filename is empty or if destination path
+   matches image path (i.e. both are the same file).
+   Trailing slash in dest_dir is optional.
+   Logic:
+   - if an image is "below" current .blend file directory, rebuild the
+     same dir structure in dest_dir
+   For example //textures/foo/bar.png becomes
+   [dest_dir]/textures/foo/bar.png.
+   - if an image is not "below" current .blend file directory,
+   disregard it's path and copy it in the same directory where 3D file
+   goes.
+   For example //../foo/bar.png becomes [dest_dir]/bar.png.
+   This logic will help ensure that all image paths are relative and
+   that a user gets his images in one place. It'll also provide
+   consistent behaviour across exporters.
+  */
+ int BKE_get_image_export_path(struct Image *im, const char *dest_dir, char *abs, int abs_size, char *rel, int rel_size)
+ {
+       char path[FILE_MAX];
+       char dir[FILE_MAX];
+       char base[FILE_MAX];
+       char blend_dir[FILE_MAX];       /* directory, where current .blend file resides */
+       char dest_path[FILE_MAX];
+       char rel_dir[FILE_MAX];
+       int len;
+       if (abs)
+               abs[0]= 0;
+       if (rel)
+               rel[0]= 0;
+       BLI_split_dirfile_basic(G.sce, blend_dir, NULL);
+       if (!strlen(im->name)) {
+               if (G.f & G_DEBUG) printf("Invalid image type.\n");
+               return 0;
+       }
+       BLI_strncpy(path, im->name, sizeof(path));
+       /* expand "//" in filename and get absolute path */
+       BLI_convertstringcode(path, G.sce);
+       /* get the directory part */
+       BLI_split_dirfile_basic(path, dir, base);
+       len= strlen(blend_dir);
+       rel_dir[0] = 0;
+       /* if image is "below" current .blend file directory */
+       if (!strncmp(path, blend_dir, len)) {
+               /* if image is _in_ current .blend file directory */
+               if (!strcmp(dir, blend_dir)) {
+                       BLI_join_dirfile(dest_path, dest_dir, base);
+               }
+               /* "below" */
+               else {
+                       /* rel = image_path_dir - blend_dir */
+                       BLI_strncpy(rel_dir, dir + len, sizeof(rel_dir));
+                       BLI_join_dirfile(dest_path, dest_dir, rel_dir);
+                       BLI_join_dirfile(dest_path, dest_path, base);
+               }
+                       
+       }
+       /* image is out of current directory */
+       else {
+               BLI_join_dirfile(dest_path, dest_dir, base);
+       }
+       if (abs)
+               BLI_strncpy(abs, dest_path, abs_size);
+       if (rel) {
+               strncat(rel, rel_dir, rel_size);
+               strncat(rel, base, rel_size);
+       }
+       /* return 2 if src=dest */
+       if (!strcmp(path, dest_path)) {
+               if (G.f & G_DEBUG) printf("%s and %s are the same file\n", path, dest_path);
+               return 2;
+       }
+       return 1;
+ }
++
@@@ -542,7 -542,8 +542,8 @@@ void set_mesh(Object *ob, Mesh *me
        
        if(ob->type==OB_MESH) {
                old= ob->data;
-               old->id.us--;
 -              if (old) /* to make set_mesh work on objects created with add_only_object, i.e. having ob->data == NULL */
++              if (old)
+                       old->id.us--;
                ob->data= me;
                id_us_plus((ID *)me);
        }
@@@ -118,6 -118,7 +118,7 @@@ void               EM_select_face(struct EditFace *e
  void          EM_select_face_fgon(struct EditMesh *em, struct EditFace *efa, int val);
  void          EM_select_swap(struct EditMesh *em);
  void          EM_toggle_select_all(struct EditMesh *em);
 -void EM_select_all(struct EditMesh *em);
++void          EM_select_all(struct EditMesh *em);
  void          EM_selectmode_flush(struct EditMesh *em);
  void          EM_deselect_flush(struct EditMesh *em);
  void          EM_selectmode_set(struct EditMesh *em);
@@@ -239,10 -234,10 +239,11 @@@ typedef struct Object 
        unsigned int state;                     /* bit masks of game controllers that are active */
        unsigned int init_state;        /* bit masks of initial state as recorded by the users */
  
 -      int restore_mode;               /* Keep track of what mode to return to after edit mode exits */
 +      int pad2;
  
        ListBase gpulamp;               /* runtime, for lamps only */
 -      ListBase *duplilist;    /* only for internal use by RNA API functions. To get dupli list, use object_duplilist instead */
 +      ListBase pc_ids;
++      ListBase *duplilist;    /* for temporary dupli list storage, only for use by RNA API */
  } Object;
  
  /* Warning, this is not used anymore because hooks are now modifiers */
@@@ -1969,8 -1953,8 +1969,8 @@@ RNAProcessItem PROCESS_ITEMS[]= 
        {"rna_rna.c", NULL, RNA_def_rna},
        {"rna_ID.c", NULL, RNA_def_ID},
        {"rna_texture.c", NULL, RNA_def_texture},
-       {"rna_action.c", NULL, RNA_def_action},
+       {"rna_action.c", "rna_action_api.c", RNA_def_action},
 -      {"rna_animation.c", NULL, RNA_def_animation},
 +      {"rna_animation.c", "rna_animation_api.c", RNA_def_animation},
        {"rna_actuator.c", NULL, RNA_def_actuator},
        {"rna_armature.c", NULL, RNA_def_armature},
        {"rna_boid.c", NULL, RNA_def_boid},
        {"rna_curve.c", NULL, RNA_def_curve},
        {"rna_fcurve.c", NULL, RNA_def_fcurve},
        {"rna_fluidsim.c", NULL, RNA_def_fluidsim},
 +      {"rna_gpencil.c", NULL, RNA_def_gpencil},
        {"rna_group.c", NULL, RNA_def_group},
-       {"rna_image.c", NULL, RNA_def_image},
+       {"rna_image.c", "rna_image_api.c", RNA_def_image},
        {"rna_key.c", NULL, RNA_def_key},
        {"rna_lamp.c", NULL, RNA_def_lamp},
        {"rna_lattice.c", NULL, RNA_def_lattice},
index 0000000,11efa6d..991a825
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,75 +1,80 @@@
 - * Contributor(s): Blender Foundation
+ /**
+  * ***** BEGIN GPL LICENSE BLOCK *****
+  *
+  * This program is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU General Public License
+  * as published by the Free Software Foundation; either version 2
+  * of the License, or (at your option) any later version. 
+  *
+  * This program is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  * GNU General Public License for more details.
+  *
+  * You should have received a copy of the GNU General Public License
+  * along with this program; if not, write to the Free Software Foundation,
+  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+  *
+  * The Original Code is Copyright (C) 2009 Blender Foundation.
+  * All rights reserved.
+  *
+  * 
++ * Contributor(s): Arystanbek Dyussenov
+  *
+  * ***** END GPL LICENSE BLOCK *****
+  */
+ #include <stdlib.h>
+ #include <stdio.h>
+ #include <string.h>
+ #include <time.h>
+ #include "RNA_define.h"
+ #include "RNA_types.h"
+ #include "DNA_action_types.h"
+ #ifdef RNA_RUNTIME
+ #include "BKE_action.h"
+ #include "DNA_anim_types.h"
+ #include "DNA_curve_types.h"
++/* XXX disabled until RNA allows returning arrays */
++#if 0
+ /* return frame range of all curves (min, max) or (0, 1) if there are no keys */
+ int *rna_Action_get_frame_range(bAction *act, int *ret_length)
+ {
+       int *ret;
+       float start, end;
+       calc_action_range(act, &start, &end, 1);
+       *ret_length= 2;
+       ret= MEM_callocN(*ret_length * sizeof(int), "rna_Action_get_frame_range");
+       ret[0]= (int)start;
+       ret[1]= (int)end;
+       
+       return ret;
+ }
++#endif
+ #else
+ void RNA_api_action(StructRNA *srna)
+ {
++#if 0
+       FunctionRNA *func;
+       PropertyRNA *parm;
+       func= RNA_def_function(srna, "get_frame_range", "rna_Action_get_frame_range");
+       RNA_def_function_ui_description(func, "Get action frame range as a (min, max) tuple.");
+       parm= RNA_def_int_array(func, "frame_range", 1, NULL, 0, 0, "", "Action frame range.", 0, 0);
+       RNA_def_property_flag(parm, PROP_DYNAMIC_ARRAY);
+       RNA_def_function_return(func, parm);
++#endif
+ }
+ #endif
@@@ -74,76 -66,29 +74,99 @@@ static int rna_Image_dirty_get(PointerR
        return 0;
  }
  
 +static void rna_Image_source_update(bContext *C, PointerRNA *ptr)
 +{
 +      Image *ima= ptr->id.data;
 +      BKE_image_signal(ima, NULL, IMA_SIGNAL_SRC_CHANGE);
 +}
 +
 +static void rna_Image_fields_update(bContext *C, PointerRNA *ptr)
 +{
 +      Image *ima= ptr->id.data;
 +      ImBuf *ibuf;
 +
 +      ibuf= BKE_image_get_ibuf(ima, NULL);
 +
 +      if(ibuf) {
 +              short nr= 0;
 +
 +              if(!(ima->flag & IMA_FIELDS) && (ibuf->flags & IB_fields)) nr= 1;
 +              if((ima->flag & IMA_FIELDS) && !(ibuf->flags & IB_fields)) nr= 1;
 +
 +              if(nr)
 +                      BKE_image_signal(ima, NULL, IMA_SIGNAL_FREE);
 +      }
 +}
 +
 +static void rna_Image_reload_update(bContext *C, PointerRNA *ptr)
 +{
 +      Image *ima= ptr->id.data;
 +      BKE_image_signal(ima, NULL, IMA_SIGNAL_RELOAD);
 +      printf("reload %p\n", ima);
 +}
 +
 +static void rna_Image_generated_update(bContext *C, PointerRNA *ptr)
 +{
 +      Image *ima= ptr->id.data;
 +      BKE_image_signal(ima, NULL, IMA_SIGNAL_FREE);
 +}
 +
 +static void rna_ImageUser_update(bContext *C, PointerRNA *ptr)
 +{
 +    Scene *scene= CTX_data_scene(C);
 +      ImageUser *iuser= ptr->data;
 +
 +      BKE_image_user_calc_imanr(iuser, scene->r.cfra, 0);
 +}
 +
 +static EnumPropertyItem *rna_Image_source_itemf(bContext *C, PointerRNA *ptr, int *free)
 +{
 +      Image *ima= (Image*)ptr->data;
 +      EnumPropertyItem *item= NULL;
 +      int totitem= 0;
 +      
 +      if(C==NULL) /* needed for doc generation */
 +              return image_source_items;
 +      
 +      if(ima->source == IMA_SRC_VIEWER) {
 +              RNA_enum_items_add_value(&item, &totitem, image_source_items, IMA_SRC_VIEWER);
 +      }
 +      else {
 +              RNA_enum_items_add_value(&item, &totitem, image_source_items, IMA_SRC_FILE);
 +              RNA_enum_items_add_value(&item, &totitem, image_source_items, IMA_SRC_SEQUENCE);
 +              RNA_enum_items_add_value(&item, &totitem, image_source_items, IMA_SRC_MOVIE);
 +              RNA_enum_items_add_value(&item, &totitem, image_source_items, IMA_SRC_GENERATED);
 +      }
 +
 +      RNA_enum_item_end(&item, &totitem);
 +      *free= 1;
 +
 +      return item;
 +}
 +
+ static int rna_Image_has_data_get(PointerRNA *ptr)
+ {
+       Image *im= (Image*)ptr->data;
+       if (im->ibufs.first)
+               return 1;
+       return 0;
+ }
+ static int rna_Image_depth_get(PointerRNA *ptr)
+ {
+       Image *im= (Image*)ptr->data;
+       ImBuf *ibuf= BKE_image_get_ibuf(im, NULL);
+       if (!ibuf) return 0;
+       if (ibuf->rect_float)
+               return 128;
+       return ibuf->depth;
+ }
  #else
  
  static void rna_def_imageuser(BlenderRNA *brna)
index 0000000,fee379c..25c764b
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,82 +1,82 @@@
 - *
+ /**
 - * Contributor(s): Blender Foundation
++ * $Id$
+  * 
+  * ***** BEGIN GPL LICENSE BLOCK *****
+  *
+  * This program is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU General Public License
+  * as published by the Free Software Foundation; either version 2
+  * of the License, or (at your option) any later version. 
+  *
+  * This program is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  * GNU General Public License for more details.
+  *
+  * You should have received a copy of the GNU General Public License
+  * along with this program; if not, write to the Free Software Foundation,
+  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+  *
+  * The Original Code is Copyright (C) 2009 Blender Foundation.
+  * All rights reserved.
+  *
+  * 
++ * Contributor(s): Arystanbek Dyussenov
+  *
+  * ***** END GPL LICENSE BLOCK *****
+  */
+ #include <stdlib.h>
+ #include <stdio.h>
+ #include <string.h>
+ #include <time.h>
+ #include "RNA_define.h"
+ #include "RNA_types.h"
+ #include "DNA_object_types.h"
+ #ifdef RNA_RUNTIME
+ #include "BKE_utildefines.h"
+ #include "BKE_image.h"
+ #include "MEM_guardedalloc.h"
+ /*
+   User should check if returned path exists before copying a file there.
+   TODO: it would be better to return a (abs, rel) tuple.
+ */
+ static char *rna_Image_get_export_path(Image *image, char *dest_dir, int rel)
+ {
+       int length = FILE_MAX;
+       char *path= MEM_callocN(length, "image file path");
+       if (!BKE_get_image_export_path(image, dest_dir, rel ? NULL : path, length, rel ? path : NULL, length )) {
+               MEM_freeN(path);
+               return NULL;
+       }
+       return path;
+ }
+ #else
+ void RNA_api_image(StructRNA *srna)
+ {
+       FunctionRNA *func;
+       PropertyRNA *parm;
+       func= RNA_def_function(srna, "get_export_path", "rna_Image_get_export_path");
+       RNA_def_function_ui_description(func, "Produce image export path.");
+       parm= RNA_def_string(func, "dest_dir", "", 0, "", "Destination directory.");
+       RNA_def_property_flag(parm, PROP_REQUIRED);
+       parm= RNA_def_boolean(func, "get_rel_path", 1, "", "Return relative path if True.");
+       RNA_def_property_flag(parm, PROP_REQUIRED);
+       parm= RNA_def_string(func, "path", "", 0, "", "Absolute export path.");
+       RNA_def_function_return(func, parm);
+ }
+ #endif
@@@ -200,15 -197,16 +200,19 @@@ void rna_Mesh_update_draw(struct bConte
  
  /* API functions */
  
+ void RNA_api_action(StructRNA *srna);
+ void RNA_api_image(struct StructRNA *srna);
 +void RNA_api_keyingset(struct StructRNA *srna);
  void RNA_api_main(struct StructRNA *srna);
+ void RNA_api_material(StructRNA *srna);
  void RNA_api_mesh(struct StructRNA *srna);
  void RNA_api_object(struct StructRNA *srna);
- void RNA_api_scene(struct StructRNA *srna);
+ void RNA_api_scene(struct StructRNA *srna); 
 +void RNA_api_text(struct StructRNA *srna);
  void RNA_api_ui_layout(struct StructRNA *srna);
  void RNA_api_wm(struct StructRNA *srna);
  
++
  /* ID Properties */
  
  extern StringPropertyRNA rna_IDProperty_string;
@@@ -952,7 -872,16 +952,17 @@@ static void rna_def_medge(BlenderRNA *b
        prop= RNA_def_property(srna, "sharp", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "flag", ME_SHARP);
        RNA_def_property_ui_text(prop, "Sharp", "Sharp edge for the EdgeSplit modifier");
 +      RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
+       prop= RNA_def_property(srna, "loose", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "flag", ME_LOOSEEDGE);
+       RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+       RNA_def_property_ui_text(prop, "Loose", "Loose edge");
+       prop= RNA_def_property(srna, "fgon", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "flag", ME_FGON);
+       RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+       RNA_def_property_ui_text(prop, "Fgon", "Fgon edge");
  }
  
  static void rna_def_mface(BlenderRNA *brna)
        RNA_def_struct_path_func(srna, "rna_MeshFace_path");
        RNA_def_struct_ui_icon(srna, ICON_FACESEL);
  
 +      // XXX allows creating invalid meshes
        prop= RNA_def_property(srna, "verts", PROP_INT, PROP_UNSIGNED);
+       RNA_def_property_int_sdna(prop, NULL, "v1");
        RNA_def_property_array(prop, 4);
+       /*
        RNA_def_property_flag(prop, PROP_DYNAMIC);
        RNA_def_property_dynamic_array_funcs(prop, "rna_MeshFace_verts_get_length");
        RNA_def_property_int_funcs(prop, "rna_MeshFace_verts_get", "rna_MeshFace_verts_set", NULL);
+       */
        RNA_def_property_ui_text(prop, "Vertices", "Vertex indices");
 -      // XXX allows creating invalid meshes
  
        prop= RNA_def_property(srna, "material_index", PROP_INT, PROP_UNSIGNED);
        RNA_def_property_int_sdna(prop, NULL, "mat_nr");
@@@ -107,10 -117,26 +117,22 @@@ static void rna_Mesh_update(Mesh *mesh
  
        mesh_calc_normals(mesh->mvert, mesh->totvert, mesh->mface, mesh->totface, NULL);
  
 -      for(ob=bmain->object.first; ob; ob=ob->id.next) {
 -              if(ob->data == mesh) {
 -                      ob->recalc |= OB_RECALC_DATA;
 -                      WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob);
 -              }
 -      }
 +      DAG_id_flush_update(&mesh->id, OB_RECALC_DATA);
 +      WM_event_add_notifier(C, NC_GEOM|ND_DATA, mesh);
  }
  
+ static void rna_Mesh_transform(Mesh *me, float *mat)
+ {
+       /* TODO: old API transform had recalc_normals option */
+       int i;
+       MVert *mvert= me->mvert;
+       for(i= 0; i < me->totvert; i++, mvert++) {
+               Mat4MulVecfl((float (*)[4])mat, mvert->co);
+       }
+ }
  static void rna_Mesh_add_verts(Mesh *mesh, int len)
  {
        CustomData vdata;
@@@ -218,6 -291,11 +287,11 @@@ void RNA_api_mesh(StructRNA *srna
        FunctionRNA *func;
        PropertyRNA *parm;
  
 -      parm= RNA_def_float_matrix(func, "matrix", 16, NULL, 0.0f, 0.0f, "", "Matrix.", 0.0f, 0.0f);
+       func= RNA_def_function(srna, "transform", "rna_Mesh_transform");
+       RNA_def_function_ui_description(func, "Transform mesh vertices by a matrix.");
++      parm= RNA_def_float_matrix(func, "matrix", 4, 4, NULL, 0.0f, 0.0f, "", "Matrix.", 0.0f, 0.0f);
+       RNA_def_property_flag(parm, PROP_REQUIRED);
        func= RNA_def_function(srna, "add_geometry", "rna_Mesh_add_geometry");
        parm= RNA_def_int(func, "verts", 0, 0, INT_MAX, "Number", "Number of vertices to add.", 0, INT_MAX);
        RNA_def_property_flag(parm, PROP_REQUIRED);
@@@ -100,13 -84,18 +100,19 @@@ EnumPropertyItem object_type_items[] = 
  
  void rna_Object_update(bContext *C, PointerRNA *ptr)
  {
 -      DAG_object_flush_update(CTX_data_scene(C), ptr->id.data, OB_RECALC_OB);
 +      DAG_id_flush_update(ptr->id.data, OB_RECALC_OB);
  }
  
+ void rna_Object_matrix_update(bContext *C, PointerRNA *ptr)
+ {
+       ED_object_apply_obmat(ptr->id.data);
+       rna_Object_update(C, ptr);
+ }
  void rna_Object_update_data(bContext *C, PointerRNA *ptr)
  {
 -      DAG_object_flush_update(CTX_data_scene(C), ptr->id.data, OB_RECALC_DATA);
 +      DAG_id_flush_update(ptr->id.data, OB_RECALC_DATA);
 +      WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ptr->id.data);
  }
  
  static void rna_Object_dependency_update(bContext *C, PointerRNA *ptr)
@@@ -1210,8 -1206,9 +1216,9 @@@ static void rna_def_object(BlenderRNA *
        /* matrix */
        prop= RNA_def_property(srna, "matrix", PROP_FLOAT, PROP_MATRIX);
        RNA_def_property_float_sdna(prop, NULL, "obmat");
 -      RNA_def_property_array(prop, 16);
 +      RNA_def_property_multi_array(prop, 2, matrix_dimsize);
        RNA_def_property_ui_text(prop, "Matrix", "Transformation matrix.");
+       RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Object_matrix_update");
  
        /* collections */
        prop= RNA_def_property(srna, "constraints", PROP_COLLECTION, PROP_NONE);
@@@ -88,60 -109,224 +109,224 @@@ static Mesh *rna_Object_create_mesh(Obj
  #endif
  
                /* get updated display list, and convert to a mesh */
-               makeDispListCurveTypes( scene, tmpobj, 0 );
+               makeDispListCurveTypes( sce, tmpobj, 0 );
                nurbs_to_mesh( tmpobj );
-               /* nurbs_to_mesh changes the type tp a mesh, check it worked */
+               
+               /* nurbs_to_mesh changes the type to a mesh, check it worked */
                if (tmpobj->type != OB_MESH) {
-                       free_libblock_us( &(CTX_data_main(C)->object), tmpobj );
-                       printf("cant convert curve to mesh. Does the curve have any segments?" ); // XXX use report api
+                       free_libblock_us( &G.main->object, tmpobj );
+                       BKE_report(reports, RPT_ERROR, "cant convert curve to mesh. Does the curve have any segments?");
+                       return NULL;
                }
-               me = tmpobj->data;
-               free_libblock_us( &(CTX_data_main(C)->object), tmpobj );
-               break;
-       }
+               tmpmesh = tmpobj->data;
+               free_libblock_us( &G.main->object, tmpobj );
+               break;
        case OB_MBALL:
                /* metaballs don't have modifiers, so just convert to mesh */
-               ob = find_basis_mball(scene, ob);
-               /* todo, re-generatre for render-res */
-               // metaball_polygonize(scene, ob)
-               me = add_mesh("Mesh");
-               mball_to_mesh( &ob->disp, me );
+               ob = find_basis_mball( sce, ob );
+               tmpmesh = add_mesh("Mesh");
+               mball_to_mesh( &ob->disp, tmpmesh );
+               break;
+       case OB_MESH:
+               /* copies object and modifiers (but not the data) */
+               if (cage) {
+                       /* copies the data */
+                       tmpmesh = copy_mesh( ob->data );
+               /* if not getting the original caged mesh, get final derived mesh */
+               } else {
+                       /* Make a dummy mesh, saves copying */
+                       DerivedMesh *dm;
+                       /* CustomDataMask mask = CD_MASK_BAREMESH|CD_MASK_MTFACE|CD_MASK_MCOL; */
+                       CustomDataMask mask = CD_MASK_MESH; /* this seems more suitable, exporter,
+                                                                                                  for example, needs CD_MASK_MDEFORMVERT */
+                       
+                       /* Write the display mesh into the dummy mesh */
+                       if (render)
+                               dm = mesh_create_derived_render( sce, ob, mask );
+                       else
+                               dm = mesh_create_derived_view( sce, ob, mask );
+                       
+                       tmpmesh = add_mesh( "Mesh" );
+                       DM_to_mesh( dm, tmpmesh );
+                       dm->release( dm );
+               }
+               
                break;
-       case OB_MESH:
-       {
-               dm= mesh_create_derived_render(scene, ob, mask);
-               // dm= mesh_create_derived_view(scene, ob, mask);
+       default:
+               BKE_report(reports, RPT_ERROR, "Object does not have geometry data");
+               return NULL;
+       }
  
-               if(!dm)
-                       return NULL;
+       /* Copy materials to new mesh */
+       switch (ob->type) {
+       case OB_SURF:
+               tmpmesh->totcol = tmpcu->totcol;                
+               
+               /* free old material list (if it exists) and adjust user counts */
+               if( tmpcu->mat ) {
+                       for( i = tmpcu->totcol; i-- > 0; ) {
+                               /* are we an object material or data based? */
+                               if (ob->colbits & 1<<i) 
+                                       tmpmesh->mat[i] = ob->mat[i];
+                               else 
+                                       tmpmesh->mat[i] = tmpcu->mat[i];
+                               if (tmpmesh->mat[i]) 
+                                       tmpmesh->mat[i]->id.us++;
+                       }
+               }
+               break;
+ #if 0
+       /* Crashes when assigning the new material, not sure why */
+       case OB_MBALL:
+               tmpmb = (MetaBall *)ob->data;
+               tmpmesh->totcol = tmpmb->totcol;
+               
+               /* free old material list (if it exists) and adjust user counts */
+               if( tmpmb->mat ) {
+                       for( i = tmpmb->totcol; i-- > 0; ) {
+                               tmpmesh->mat[i] = tmpmb->mat[i]; /* CRASH HERE ??? */
+                               if (tmpmesh->mat[i]) {
+                                       tmpmb->mat[i]->id.us++;
+                               }
+                       }
+               }
+               break;
+ #endif
  
-               me= add_mesh("tmp_render_mesh");
-               me->id.us--; /* we don't assign it to anything */
-               DM_to_mesh(dm, me);
-               dm->release(dm);
+       case OB_MESH:
+               if (!cage) {
+                       Mesh *origmesh= ob->data;
+                       tmpmesh->flag= origmesh->flag;
+                       tmpmesh->mat = MEM_dupallocN(origmesh->mat);
+                       tmpmesh->totcol = origmesh->totcol;
+                       tmpmesh->smoothresh= origmesh->smoothresh;
+                       if( origmesh->mat ) {
+                               for( i = origmesh->totcol; i-- > 0; ) {
+                                       /* are we an object material or data based? */
+                                       if (ob->colbits & 1<<i)
+                                               tmpmesh->mat[i] = ob->mat[i];
+                                       else
+                                               tmpmesh->mat[i] = origmesh->mat[i];
+                                       if (tmpmesh->mat[i])
+                                               tmpmesh->mat[i]->id.us++;
+                               }
+                       }
+               }
                break;
+       } /* end copy materials */
+       /* we don't assign it to anything */
+       tmpmesh->id.us--;
+       
+       /* make sure materials get updated in objects */
+       test_object_materials( ( ID * ) tmpmesh );
+       return tmpmesh;
+ }
+ /* When no longer needed, duplilist should be freed with Object.free_duplilist */
+ static void rna_Object_create_duplilist(Object *ob, bContext *C, ReportList *reports)
+ {
+       if (!(ob->transflag & OB_DUPLI)) {
+               BKE_report(reports, RPT_ERROR, "Object does not have duplis.");
+               return;
+       }
+       /* free duplilist if a user forgets to */
+       if (ob->duplilist) {
+               BKE_reportf(reports, RPT_WARNING, "Object.dupli_list has not been freed.");
+               free_object_duplilist(ob->duplilist);
+               ob->duplilist= NULL;
+       }
+       ob->duplilist= object_duplilist(CTX_data_scene(C), ob);
+       /* ob->duplilist should now be freed with Object.free_duplilist */
+ }
+ static void rna_Object_free_duplilist(Object *ob, ReportList *reports)
+ {
+       if (ob->duplilist) {
+               free_object_duplilist(ob->duplilist);
+               ob->duplilist= NULL;
        }
-       default:
-               return NULL;
+ }
+ static void rna_Object_convert_to_triface(Object *ob, bContext *C, ReportList *reports, Scene *sce)
+ {
+       Mesh *me;
+       int ob_editing = CTX_data_edit_object(C) == ob;
+       if (ob->type != OB_MESH) {
+               BKE_report(reports, RPT_ERROR, "Object should be of type MESH.");
+               return;
        }
  
 -      DAG_object_flush_update(sce, ob, OB_RECALC_DATA);
+       me= (Mesh*)ob->data;
+       if (!ob_editing)
+               make_editMesh(sce, ob);
+       /* select all */
+       EM_select_all(me->edit_mesh);
+       convert_to_triface(me->edit_mesh, 0);
+       load_editMesh(sce, ob);
+       if (!ob_editing)
+               free_editMesh(me->edit_mesh);
 -      return add_defgroup_name(ob, group_name);
++      DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
+ }
+ static bDeformGroup *rna_Object_add_vertex_group(Object *ob, char *group_name)
+ {
 -      add_vert_to_defgroup(ob, def, vertex_index, weight, assignmode);
++      return ED_vgroup_add_name(ob, group_name);
+ }
+ static void rna_Object_add_vertex_to_group(Object *ob, int vertex_index, bDeformGroup *def, float weight, int assignmode)
+ {
+       /* creates dverts if needed */
++      ED_vgroup_vert_add(ob, def, vertex_index, weight, assignmode);
+ }
+ /* copied from old API Object.makeDisplayList (Object.c) */
+ static void rna_Object_make_display_list(Object *ob, bContext *C)
+ {
+       Scene *sce= CTX_data_scene(C);
  
-       {       /* update the material */
-               short i, *totcol =give_totcolp(ob);
+       if (ob->type == OB_FONT) {
+               Curve *cu = ob->data;
+               freedisplist(&cu->disp);
+               BKE_text_to_curve(sce, ob, CU_LEFT);
+       }
  
-               /* free the current material list */
-               if(me->mat)
-                       MEM_freeN((void *)me->mat);
 -      DAG_object_flush_update(sce, ob, OB_RECALC_DATA);
++      DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
+ }
  
-               me->mat= (Material **)MEM_callocN(sizeof(void *)*(*totcol), "matarray");
+ static Object *rna_Object_find_armature(Object *ob)
+ {
+       Object *ob_arm = NULL;
  
-               for(i=0; i<*totcol; i++) {
-                       Material *mat= give_current_material(ob, i+1);
-                       if(mat) {
-                               me->mat[i]= mat;
-                               mat->id.us++;
+       if (ob->type != OB_MESH) return NULL;
+       if (ob->parent && ob->partype == PARSKEL && ob->parent->type == OB_ARMATURE) {
+               ob_arm = ob->parent;
+       }
+       else {
+               ModifierData *mod = (ModifierData*)ob->modifiers.first;
+               while (mod) {
+                       if (mod->type == eModifierType_Armature) {
+                               ob_arm = ((ArmatureModifierData*)mod)->object;
                        }
+                       mod = mod->next;
                }
        }
  
@@@ -542,19 -409,20 +542,21 @@@ static void rna_def_pose_channel(Blende
        prop= RNA_def_property(srna, "rotation_mode", PROP_ENUM, PROP_NONE);
        RNA_def_property_enum_sdna(prop, NULL, "rotmode");
        RNA_def_property_enum_items(prop, prop_rotmode_items);
 +      RNA_def_property_enum_funcs(prop, NULL, "rna_PoseChannel_rotation_mode_set", NULL);
        RNA_def_property_ui_text(prop, "Rotation Mode", "");
 -      RNA_def_property_update(prop, NC_OBJECT|ND_POSE|ND_TRANSFORM, "rna_Pose_update");
 +      RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Pose_update");
  
        /* These three matrix properties await an implementation of the PROP_MATRIX subtype, which currently doesn't exist. */
- /*    prop= RNA_def_property(srna, "channel_matrix", PROP_FLOAT, PROP_MATRIX);
-       RNA_def_property_struct_type(prop, "chan_mat");
+       prop= RNA_def_property(srna, "channel_matrix", PROP_FLOAT, PROP_MATRIX);
+       RNA_def_property_float_sdna(prop, NULL, "chan_mat");
+       RNA_def_property_array(prop, 16);
        RNA_def_property_clear_flag(prop, PROP_EDITABLE);
-       RNA_def_property_ui_text(prop, "Channel Matrix", "4x4 matrix, before constraints.");*/
+       RNA_def_property_ui_text(prop, "Channel Matrix", "4x4 matrix, before constraints.");
  
        /* kaito says this should be not user-editable; I disagree; power users should be able to force this in python; he's the boss. */
- /*    prop= RNA_def_property(srna, "pose_matrix", PROP_FLOAT, PROP_MATRIX);
-       RNA_def_property_struct_type(prop, "pose_mat");
+       prop= RNA_def_property(srna, "pose_matrix", PROP_FLOAT, PROP_MATRIX);
+       RNA_def_property_float_sdna(prop, NULL, "pose_mat");
+       RNA_def_property_array(prop, 16);
        RNA_def_property_clear_flag(prop, PROP_EDITABLE); 
        RNA_def_property_ui_text(prop, "Pose Matrix", "Final 4x4 matrix for this channel.");
  
        prop= RNA_def_property(srna, "constraint_inverse_matrix", PROP_FLOAT, PROP_MATRIX);
        RNA_def_property_struct_type(prop, "constinv");
        RNA_def_property_clear_flag(prop, PROP_EDITABLE);
-       RNA_def_property_ui_text(prop, "Constraint Inverse Matrix", "4x4 matrix, defines transform from final position to unconstrained position."); */
+       RNA_def_property_ui_text(prop, "Constraint Inverse Matrix", "4x4 matrix, defines transform from final position to unconstrained position.");
+       */
        
 +      /* Head/Tail Coordinates (in Pose Space) - Automatically calculated... */
        prop= RNA_def_property(srna, "pose_head", PROP_FLOAT, PROP_TRANSLATION);
        RNA_def_property_clear_flag(prop, PROP_EDITABLE);
        RNA_def_property_ui_text(prop, "Pose Head Position", "Location of head of the channel's bone.");
@@@ -757,6 -554,6 +761,8 @@@ static void rna_def_pose(BlenderRNA *br
        RNA_def_property_int_funcs(prop, "rna_Pose_active_bone_group_index_get", "rna_Pose_active_bone_group_index_set", "rna_Pose_active_bone_group_index_range");
        RNA_def_property_ui_text(prop, "Active Bone Group Index", "Active index in bone groups array.");
        RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Pose_update");
++
++      /* RNA_api_pose(srna); */
  }
  
  void RNA_def_pose(BlenderRNA *brna)
index 0000000,42bb52d..40bb131
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,54 +1,56 @@@
+ /**
++ * $Id$
++ * 
+  * ***** BEGIN GPL LICENSE BLOCK *****
+  *
+  * This program is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU General Public License
+  * as published by the Free Software Foundation; either version 2
+  * of the License, or (at your option) any later version. 
+  *
+  * This program is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  * GNU General Public License for more details.
+  *
+  * You should have received a copy of the GNU General Public License
+  * along with this program; if not, write to the Free Software Foundation,
+  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+  *
+  * The Original Code is Copyright (C) 2009 Blender Foundation.
+  * All rights reserved.
+  *
+  * 
+  * Contributor(s): Blender Foundation
+  *
+  * ***** END GPL LICENSE BLOCK *****
+  */
+ #include <stdlib.h>
+ #include <stdio.h>
+ #include <string.h>
+ #include <time.h>
+ #include "RNA_define.h"
+ #include "RNA_types.h"
+ #include "DNA_object_types.h"
+ /* #include "BLO_sys_types.h" */
+ #ifdef RNA_RUNTIME
+ /* #include "DNA_anim_types.h" */
+ #include "DNA_action_types.h" /* bPose */
+ #else
+ void RNA_api_pose(StructRNA *srna)
+ {
+       /* FunctionRNA *func; */
+       /* PropertyRNA *parm; */
+ }
+ #endif
@@@ -1,5 -1,5 +1,5 @@@
  /**
-  * $Id:
 - * $Id: rna_object_api.c 21115 2009-06-23 19:17:59Z kazanbas $
++ * $Id$
   *
   * ***** BEGIN GPL LICENSE BLOCK *****
   *
@@@ -21,7 -21,7 +21,7 @@@
   * All rights reserved.
   *
   * 
-  * Contributor(s): Joshua Leung
 - * Contributor(s): Blender Foundation
++ * Contributor(s): Joshua Leung, Arystanbek Dyussenov
   *
   * ***** END GPL LICENSE BLOCK *****
   */
  
  #ifdef RNA_RUNTIME
  
 +#include "BKE_animsys.h"
+ #include "BKE_scene.h"
+ #include "BKE_depsgraph.h"
  
- // Scene API stuff from kazanbas branch here...
+ #include "ED_object.h"
  
+ #include "WM_api.h"
+ static void rna_Scene_add_object(Scene *sce, ReportList *reports, Object *ob)
+ {
+       Base *base= object_in_scene(ob, sce);
+       if (base) {
+               BKE_report(reports, RPT_ERROR, "Object is already in this scene.");
+               return;
+       }
+       base= scene_add_base(sce, ob);
+       ob->id.us++;
+       /* this is similar to what object_add_type and add_object do */
+       ob->lay= base->lay= sce->lay;
+       ob->recalc |= OB_RECALC;
+       DAG_scene_sort(sce);
+ }
+ static void rna_Scene_remove_object(Scene *sce, ReportList *reports, Object *ob)
+ {
+       Base *base= object_in_scene(ob, sce);
+       if (!base) {
+               BKE_report(reports, RPT_ERROR, "Object is not in this scene.");
+               return;
+       }
+       /* as long as ED_base_object_free_and_unlink calls free_libblock_us, we don't have to decrement ob->id.us */
+       ED_base_object_free_and_unlink(sce, base);
+ }
+ static void rna_Scene_set_frame(Scene *sce, bContext *C, int frame)
+ {
+       sce->r.cfra= frame;
+       CLAMP(sce->r.cfra, MINAFRAME, MAXFRAME);
+       scene_update_for_newframe(sce, (1<<20) - 1);
+       WM_event_add_notifier(C, NC_SCENE|ND_FRAME, sce);
+ }
  
 +static KeyingSet *rna_Scene_add_keying_set(Scene *sce, ReportList *reports, 
 +              char name[], int absolute, int insertkey_needed, int insertkey_visual)
 +{
 +      KeyingSet *ks= NULL;
 +      short flag=0, keyingflag=0;
 +      
 +      /* validate flags */
 +      if (absolute)
 +              flag |= KEYINGSET_ABSOLUTE;
 +      if (insertkey_needed)
 +              keyingflag |= INSERTKEY_NEEDED;
 +      if (insertkey_visual)
 +              keyingflag |= INSERTKEY_MATRIX;
 +              
 +      /* call the API func, and set the active keyingset index */
 +      ks= BKE_keyingset_add(&sce->keyingsets, name, flag, keyingflag);
 +      
 +      if (ks) {
 +              sce->active_keyingset= BLI_countlist(&sce->keyingsets);
 +              return ks;
 +      }
 +      else {
 +              BKE_report(reports, RPT_ERROR, "Keying Set could not be added.");
 +              return NULL;
 +      }
 +}
 +
  #else
  
  void RNA_api_scene(StructRNA *srna)
  {
        FunctionRNA *func;
        PropertyRNA *parm;
-       
-       // Scene API stuff from kazanbas branch here...
-       
+       func= RNA_def_function(srna, "add_object", "rna_Scene_add_object");
+       RNA_def_function_ui_description(func, "Add object to scene.");
+       RNA_def_function_flag(func, FUNC_USE_REPORTS);
+       parm= RNA_def_pointer(func, "object", "Object", "", "Object to add to scene.");
+       RNA_def_property_flag(parm, PROP_REQUIRED);
+       func= RNA_def_function(srna, "remove_object", "rna_Scene_remove_object");
+       RNA_def_function_ui_description(func, "Remove object from scene.");
+       RNA_def_function_flag(func, FUNC_USE_REPORTS);
+       parm= RNA_def_pointer(func, "object", "Object", "", "Object to remove from scene.");
+       RNA_def_property_flag(parm, PROP_REQUIRED);
+       func= RNA_def_function(srna, "set_frame", "rna_Scene_set_frame");
+       RNA_def_function_flag(func, FUNC_USE_CONTEXT);
+       RNA_def_function_ui_description(func, "Set scene frame updating all objects immediately.");
+       parm= RNA_def_int(func, "frame", 0, MINAFRAME, MAXFRAME, "", "Frame number to set.", MINAFRAME, MAXFRAME);
+       RNA_def_property_flag(parm, PROP_REQUIRED);
++
 +      /* Add Keying Set */
 +      func= RNA_def_function(srna, "add_keying_set", "rna_Scene_add_keying_set");
 +      RNA_def_function_ui_description(func, "Add a new Keying Set to Scene.");
 +      RNA_def_function_flag(func, FUNC_USE_REPORTS);
-               /* returns the new KeyingSet */
++      /* returns the new KeyingSet */
 +      parm= RNA_def_pointer(func, "keyingset", "KeyingSet", "", "Newly created Keying Set.");
-               RNA_def_function_return(func, parm);
-               /* name */
++      RNA_def_function_return(func, parm);
++      /* name */
 +      RNA_def_string(func, "name", "KeyingSet", 64, "Name", "Name of Keying Set");
-               /* flags */
++      /* flags */
 +      RNA_def_boolean(func, "absolute", 1, "Absolute", "Keying Set defines specific paths/settings to be keyframed (i.e. is not reliant on context info)");
-               /* keying flags */
++      /* keying flags */
 +      RNA_def_boolean(func, "insertkey_needed", 0, "Insert Keyframes - Only Needed", "Only insert keyframes where they're needed in the relevant F-Curves.");
 +      RNA_def_boolean(func, "insertkey_visual", 0, "Insert Keyframes - Visual", "Insert keyframes based on 'visual transforms'.");
  }
  
  #endif